mac80211: fix vlan and optimise RX
[safe/jmp/linux-2.6] / net / ipv6 / route.c
index 1473ee0..d6fe764 100644 (file)
@@ -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 = {