X-Git-Url: http://ftp.safe.ca/?a=blobdiff_plain;f=net%2Fipv6%2Froute.c;h=d6fe7646a8ff7d8599c3565e6e6c9deb68732cef;hb=fbc44bf7177dfd61381da55405550b693943a432;hp=1473ee0a1f5135d02cd9cc2bab8ae5c8b37e1e88;hpb=d5fdd6babcfc2b0e6a8da1acf492a69fb54b4c47;p=safe%2Fjmp%2Flinux-2.6 diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 1473ee0..d6fe764 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -481,7 +481,7 @@ int rt6_route_rcv(struct net_device *dev, u8 *opt, int len, pref = rinfo->route_pref; if (pref == ICMPV6_ROUTER_PREF_INVALID) - pref = ICMPV6_ROUTER_PREF_MEDIUM; + return -EINVAL; lifetime = addrconf_timeout_fixup(ntohl(rinfo->lifetime), HZ); @@ -665,7 +665,7 @@ static struct rt6_info *rt6_alloc_cow(struct rt6_info *ort, struct in6_addr *dad net->ipv6.sysctl.ip6_rt_gc_elasticity = 1; net->ipv6.sysctl.ip6_rt_gc_min_interval = 0; - ip6_dst_gc(net->ipv6.ip6_dst_ops); + ip6_dst_gc(&net->ipv6.ip6_dst_ops); net->ipv6.sysctl.ip6_rt_gc_elasticity = saved_rt_elasticity; @@ -970,7 +970,7 @@ struct dst_entry *icmp6_dst_alloc(struct net_device *dev, if (unlikely(idev == NULL)) return NULL; - rt = ip6_dst_alloc(net->ipv6.ip6_dst_ops); + rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops); if (unlikely(rt == NULL)) { in6_dev_put(idev); goto out; @@ -1060,7 +1060,7 @@ static void icmp6_clean_all(int (*func)(struct rt6_info *rt, void *arg), static int ip6_dst_gc(struct dst_ops *ops) { unsigned long now = jiffies; - struct net *net = ops->dst_net; + struct net *net = container_of(ops, struct net, ipv6.ip6_dst_ops); int rt_min_interval = net->ipv6.sysctl.ip6_rt_gc_min_interval; int rt_max_size = net->ipv6.sysctl.ip6_rt_max_size; int rt_elasticity = net->ipv6.sysctl.ip6_rt_gc_elasticity; @@ -1154,7 +1154,7 @@ int ip6_route_add(struct fib6_config *cfg) goto out; } - rt = ip6_dst_alloc(net->ipv6.ip6_dst_ops); + rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops); if (rt == NULL) { err = -ENOMEM; @@ -1643,7 +1643,7 @@ out: static struct rt6_info * ip6_rt_copy(struct rt6_info *ort) { struct net *net = dev_net(ort->rt6i_dev); - struct rt6_info *rt = ip6_dst_alloc(net->ipv6.ip6_dst_ops); + struct rt6_info *rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops); if (rt) { rt->u.dst.input = ort->u.dst.input; @@ -1923,7 +1923,7 @@ struct rt6_info *addrconf_dst_alloc(struct inet6_dev *idev, int anycast) { struct net *net = dev_net(idev->dev); - struct rt6_info *rt = ip6_dst_alloc(net->ipv6.ip6_dst_ops); + struct rt6_info *rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops); struct neighbour *neigh; if (rt == NULL) @@ -2501,7 +2501,7 @@ static int rt6_stats_seq_show(struct seq_file *seq, void *v) net->ipv6.rt6_stats->fib_rt_alloc, net->ipv6.rt6_stats->fib_rt_entries, net->ipv6.rt6_stats->fib_rt_cache, - atomic_read(&net->ipv6.ip6_dst_ops->entries), + atomic_read(&net->ipv6.ip6_dst_ops.entries), net->ipv6.rt6_stats->fib_discarded_routes); return 0; @@ -2524,13 +2524,13 @@ static const struct file_operations rt6_stats_seq_fops = { #ifdef CONFIG_SYSCTL static -int ipv6_sysctl_rtcache_flush(ctl_table *ctl, int write, struct file * filp, +int ipv6_sysctl_rtcache_flush(ctl_table *ctl, int write, void __user *buffer, size_t *lenp, loff_t *ppos) { struct net *net = current->nsproxy->net_ns; int delay = net->ipv6.sysctl.flush_delay; if (write) { - proc_dointvec(ctl, write, filp, buffer, lenp, ppos); + proc_dointvec(ctl, write, buffer, lenp, ppos); fib6_run_gc(delay <= 0 ? ~0UL : (unsigned long)delay, net); return 0; } else @@ -2637,7 +2637,7 @@ struct ctl_table *ipv6_route_sysctl_init(struct net *net) if (table) { table[0].data = &net->ipv6.sysctl.flush_delay; - table[1].data = &net->ipv6.ip6_dst_ops->gc_thresh; + table[1].data = &net->ipv6.ip6_dst_ops.gc_thresh; table[2].data = &net->ipv6.sysctl.ip6_rt_max_size; table[3].data = &net->ipv6.sysctl.ip6_rt_gc_min_interval; table[4].data = &net->ipv6.sysctl.ip6_rt_gc_timeout; @@ -2655,12 +2655,8 @@ static int ip6_route_net_init(struct net *net) { int ret = -ENOMEM; - net->ipv6.ip6_dst_ops = kmemdup(&ip6_dst_ops_template, - sizeof(*net->ipv6.ip6_dst_ops), - GFP_KERNEL); - if (!net->ipv6.ip6_dst_ops) - goto out; - net->ipv6.ip6_dst_ops->dst_net = hold_net(net); + memcpy(&net->ipv6.ip6_dst_ops, &ip6_dst_ops_template, + sizeof(net->ipv6.ip6_dst_ops)); net->ipv6.ip6_null_entry = kmemdup(&ip6_null_entry_template, sizeof(*net->ipv6.ip6_null_entry), @@ -2669,7 +2665,7 @@ static int ip6_route_net_init(struct net *net) goto out_ip6_dst_ops; net->ipv6.ip6_null_entry->u.dst.path = (struct dst_entry *)net->ipv6.ip6_null_entry; - net->ipv6.ip6_null_entry->u.dst.ops = net->ipv6.ip6_dst_ops; + net->ipv6.ip6_null_entry->u.dst.ops = &net->ipv6.ip6_dst_ops; #ifdef CONFIG_IPV6_MULTIPLE_TABLES net->ipv6.ip6_prohibit_entry = kmemdup(&ip6_prohibit_entry_template, @@ -2679,7 +2675,7 @@ static int ip6_route_net_init(struct net *net) goto out_ip6_null_entry; net->ipv6.ip6_prohibit_entry->u.dst.path = (struct dst_entry *)net->ipv6.ip6_prohibit_entry; - net->ipv6.ip6_prohibit_entry->u.dst.ops = net->ipv6.ip6_dst_ops; + net->ipv6.ip6_prohibit_entry->u.dst.ops = &net->ipv6.ip6_dst_ops; net->ipv6.ip6_blk_hole_entry = kmemdup(&ip6_blk_hole_entry_template, sizeof(*net->ipv6.ip6_blk_hole_entry), @@ -2688,7 +2684,7 @@ static int ip6_route_net_init(struct net *net) goto out_ip6_prohibit_entry; net->ipv6.ip6_blk_hole_entry->u.dst.path = (struct dst_entry *)net->ipv6.ip6_blk_hole_entry; - net->ipv6.ip6_blk_hole_entry->u.dst.ops = net->ipv6.ip6_dst_ops; + net->ipv6.ip6_blk_hole_entry->u.dst.ops = &net->ipv6.ip6_dst_ops; #endif net->ipv6.sysctl.flush_delay = 0; @@ -2717,8 +2713,6 @@ out_ip6_null_entry: kfree(net->ipv6.ip6_null_entry); #endif out_ip6_dst_ops: - release_net(net->ipv6.ip6_dst_ops->dst_net); - kfree(net->ipv6.ip6_dst_ops); goto out; } @@ -2733,8 +2727,6 @@ static void ip6_route_net_exit(struct net *net) kfree(net->ipv6.ip6_prohibit_entry); kfree(net->ipv6.ip6_blk_hole_entry); #endif - release_net(net->ipv6.ip6_dst_ops->dst_net); - kfree(net->ipv6.ip6_dst_ops); } static struct pernet_operations ip6_route_net_ops = {