|
@@ -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;
|
|
@@ -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 = {
|