diff options
author | Alexey Dobriyan <adobriyan@gmail.com> | 2009-08-28 21:34:49 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-09-01 20:40:31 -0400 |
commit | 86393e52c3f1e2f6be18383f6ecdbcdc5727d545 (patch) | |
tree | f5c688c0cb5292143478249f807c4b2372f69dfd | |
parent | 885a136c52a8871175477baf3903e1c38751b35a (diff) |
netns: embed ip6_dst_ops directly
struct net::ipv6.ip6_dst_ops is separatedly dynamically allocated,
but there is no fundamental reason for it. Embed it directly into
struct netns_ipv6.
For that:
* move struct dst_ops into separate header to fix circular dependencies
I honestly tried not to, it's pretty impossible to do other way
* drop dynamical allocation, allocate together with netns
For a change, remove struct dst_ops::dst_net, it's deducible
by using container_of() given dst_ops pointer.
Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | include/net/dst.h | 23 | ||||
-rw-r--r-- | include/net/dst_ops.h | 28 | ||||
-rw-r--r-- | include/net/netns/ipv6.h | 3 | ||||
-rw-r--r-- | net/ipv6/route.c | 34 |
4 files changed, 44 insertions, 44 deletions
diff --git a/include/net/dst.h b/include/net/dst.h index 7fc409c19b37..5a900ddcf10d 100644 --- a/include/net/dst.h +++ b/include/net/dst.h | |||
@@ -8,6 +8,7 @@ | |||
8 | #ifndef _NET_DST_H | 8 | #ifndef _NET_DST_H |
9 | #define _NET_DST_H | 9 | #define _NET_DST_H |
10 | 10 | ||
11 | #include <net/dst_ops.h> | ||
11 | #include <linux/netdevice.h> | 12 | #include <linux/netdevice.h> |
12 | #include <linux/rtnetlink.h> | 13 | #include <linux/rtnetlink.h> |
13 | #include <linux/rcupdate.h> | 14 | #include <linux/rcupdate.h> |
@@ -102,28 +103,6 @@ struct dst_entry | |||
102 | }; | 103 | }; |
103 | }; | 104 | }; |
104 | 105 | ||
105 | |||
106 | struct dst_ops | ||
107 | { | ||
108 | unsigned short family; | ||
109 | __be16 protocol; | ||
110 | unsigned gc_thresh; | ||
111 | |||
112 | int (*gc)(struct dst_ops *ops); | ||
113 | struct dst_entry * (*check)(struct dst_entry *, __u32 cookie); | ||
114 | void (*destroy)(struct dst_entry *); | ||
115 | void (*ifdown)(struct dst_entry *, | ||
116 | struct net_device *dev, int how); | ||
117 | struct dst_entry * (*negative_advice)(struct dst_entry *); | ||
118 | void (*link_failure)(struct sk_buff *); | ||
119 | void (*update_pmtu)(struct dst_entry *dst, u32 mtu); | ||
120 | int (*local_out)(struct sk_buff *skb); | ||
121 | |||
122 | atomic_t entries; | ||
123 | struct kmem_cache *kmem_cachep; | ||
124 | struct net *dst_net; | ||
125 | }; | ||
126 | |||
127 | #ifdef __KERNEL__ | 106 | #ifdef __KERNEL__ |
128 | 107 | ||
129 | static inline u32 | 108 | static inline u32 |
diff --git a/include/net/dst_ops.h b/include/net/dst_ops.h new file mode 100644 index 000000000000..d1ff9b7e99b8 --- /dev/null +++ b/include/net/dst_ops.h | |||
@@ -0,0 +1,28 @@ | |||
1 | #ifndef _NET_DST_OPS_H | ||
2 | #define _NET_DST_OPS_H | ||
3 | #include <linux/types.h> | ||
4 | |||
5 | struct dst_entry; | ||
6 | struct kmem_cachep; | ||
7 | struct net_device; | ||
8 | struct sk_buff; | ||
9 | |||
10 | struct dst_ops { | ||
11 | unsigned short family; | ||
12 | __be16 protocol; | ||
13 | unsigned gc_thresh; | ||
14 | |||
15 | int (*gc)(struct dst_ops *ops); | ||
16 | struct dst_entry * (*check)(struct dst_entry *, __u32 cookie); | ||
17 | void (*destroy)(struct dst_entry *); | ||
18 | void (*ifdown)(struct dst_entry *, | ||
19 | struct net_device *dev, int how); | ||
20 | struct dst_entry * (*negative_advice)(struct dst_entry *); | ||
21 | void (*link_failure)(struct sk_buff *); | ||
22 | void (*update_pmtu)(struct dst_entry *dst, u32 mtu); | ||
23 | int (*local_out)(struct sk_buff *skb); | ||
24 | |||
25 | atomic_t entries; | ||
26 | struct kmem_cache *kmem_cachep; | ||
27 | }; | ||
28 | #endif | ||
diff --git a/include/net/netns/ipv6.h b/include/net/netns/ipv6.h index afab4e4cbac7..dfeb2d7c425b 100644 --- a/include/net/netns/ipv6.h +++ b/include/net/netns/ipv6.h | |||
@@ -6,6 +6,7 @@ | |||
6 | 6 | ||
7 | #ifndef __NETNS_IPV6_H__ | 7 | #ifndef __NETNS_IPV6_H__ |
8 | #define __NETNS_IPV6_H__ | 8 | #define __NETNS_IPV6_H__ |
9 | #include <net/dst_ops.h> | ||
9 | 10 | ||
10 | struct ctl_table_header; | 11 | struct ctl_table_header; |
11 | 12 | ||
@@ -42,7 +43,7 @@ struct netns_ipv6 { | |||
42 | struct timer_list ip6_fib_timer; | 43 | struct timer_list ip6_fib_timer; |
43 | struct hlist_head *fib_table_hash; | 44 | struct hlist_head *fib_table_hash; |
44 | struct fib6_table *fib6_main_tbl; | 45 | struct fib6_table *fib6_main_tbl; |
45 | struct dst_ops *ip6_dst_ops; | 46 | struct dst_ops ip6_dst_ops; |
46 | unsigned int ip6_rt_gc_expire; | 47 | unsigned int ip6_rt_gc_expire; |
47 | unsigned long ip6_rt_last_gc; | 48 | unsigned long ip6_rt_last_gc; |
48 | #ifdef CONFIG_IPV6_MULTIPLE_TABLES | 49 | #ifdef CONFIG_IPV6_MULTIPLE_TABLES |
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 1473ee0a1f51..9ccfef345560 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c | |||
@@ -665,7 +665,7 @@ static struct rt6_info *rt6_alloc_cow(struct rt6_info *ort, struct in6_addr *dad | |||
665 | net->ipv6.sysctl.ip6_rt_gc_elasticity = 1; | 665 | net->ipv6.sysctl.ip6_rt_gc_elasticity = 1; |
666 | net->ipv6.sysctl.ip6_rt_gc_min_interval = 0; | 666 | net->ipv6.sysctl.ip6_rt_gc_min_interval = 0; |
667 | 667 | ||
668 | ip6_dst_gc(net->ipv6.ip6_dst_ops); | 668 | ip6_dst_gc(&net->ipv6.ip6_dst_ops); |
669 | 669 | ||
670 | net->ipv6.sysctl.ip6_rt_gc_elasticity = | 670 | net->ipv6.sysctl.ip6_rt_gc_elasticity = |
671 | saved_rt_elasticity; | 671 | saved_rt_elasticity; |
@@ -970,7 +970,7 @@ struct dst_entry *icmp6_dst_alloc(struct net_device *dev, | |||
970 | if (unlikely(idev == NULL)) | 970 | if (unlikely(idev == NULL)) |
971 | return NULL; | 971 | return NULL; |
972 | 972 | ||
973 | rt = ip6_dst_alloc(net->ipv6.ip6_dst_ops); | 973 | rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops); |
974 | if (unlikely(rt == NULL)) { | 974 | if (unlikely(rt == NULL)) { |
975 | in6_dev_put(idev); | 975 | in6_dev_put(idev); |
976 | goto out; | 976 | goto out; |
@@ -1060,7 +1060,7 @@ static void icmp6_clean_all(int (*func)(struct rt6_info *rt, void *arg), | |||
1060 | static int ip6_dst_gc(struct dst_ops *ops) | 1060 | static int ip6_dst_gc(struct dst_ops *ops) |
1061 | { | 1061 | { |
1062 | unsigned long now = jiffies; | 1062 | unsigned long now = jiffies; |
1063 | struct net *net = ops->dst_net; | 1063 | struct net *net = container_of(ops, struct net, ipv6.ip6_dst_ops); |
1064 | int rt_min_interval = net->ipv6.sysctl.ip6_rt_gc_min_interval; | 1064 | int rt_min_interval = net->ipv6.sysctl.ip6_rt_gc_min_interval; |
1065 | int rt_max_size = net->ipv6.sysctl.ip6_rt_max_size; | 1065 | int rt_max_size = net->ipv6.sysctl.ip6_rt_max_size; |
1066 | int rt_elasticity = net->ipv6.sysctl.ip6_rt_gc_elasticity; | 1066 | int rt_elasticity = net->ipv6.sysctl.ip6_rt_gc_elasticity; |
@@ -1154,7 +1154,7 @@ int ip6_route_add(struct fib6_config *cfg) | |||
1154 | goto out; | 1154 | goto out; |
1155 | } | 1155 | } |
1156 | 1156 | ||
1157 | rt = ip6_dst_alloc(net->ipv6.ip6_dst_ops); | 1157 | rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops); |
1158 | 1158 | ||
1159 | if (rt == NULL) { | 1159 | if (rt == NULL) { |
1160 | err = -ENOMEM; | 1160 | err = -ENOMEM; |
@@ -1643,7 +1643,7 @@ out: | |||
1643 | static struct rt6_info * ip6_rt_copy(struct rt6_info *ort) | 1643 | static struct rt6_info * ip6_rt_copy(struct rt6_info *ort) |
1644 | { | 1644 | { |
1645 | struct net *net = dev_net(ort->rt6i_dev); | 1645 | struct net *net = dev_net(ort->rt6i_dev); |
1646 | struct rt6_info *rt = ip6_dst_alloc(net->ipv6.ip6_dst_ops); | 1646 | struct rt6_info *rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops); |
1647 | 1647 | ||
1648 | if (rt) { | 1648 | if (rt) { |
1649 | rt->u.dst.input = ort->u.dst.input; | 1649 | rt->u.dst.input = ort->u.dst.input; |
@@ -1923,7 +1923,7 @@ struct rt6_info *addrconf_dst_alloc(struct inet6_dev *idev, | |||
1923 | int anycast) | 1923 | int anycast) |
1924 | { | 1924 | { |
1925 | struct net *net = dev_net(idev->dev); | 1925 | struct net *net = dev_net(idev->dev); |
1926 | struct rt6_info *rt = ip6_dst_alloc(net->ipv6.ip6_dst_ops); | 1926 | struct rt6_info *rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops); |
1927 | struct neighbour *neigh; | 1927 | struct neighbour *neigh; |
1928 | 1928 | ||
1929 | if (rt == NULL) | 1929 | if (rt == NULL) |
@@ -2501,7 +2501,7 @@ static int rt6_stats_seq_show(struct seq_file *seq, void *v) | |||
2501 | net->ipv6.rt6_stats->fib_rt_alloc, | 2501 | net->ipv6.rt6_stats->fib_rt_alloc, |
2502 | net->ipv6.rt6_stats->fib_rt_entries, | 2502 | net->ipv6.rt6_stats->fib_rt_entries, |
2503 | net->ipv6.rt6_stats->fib_rt_cache, | 2503 | net->ipv6.rt6_stats->fib_rt_cache, |
2504 | atomic_read(&net->ipv6.ip6_dst_ops->entries), | 2504 | atomic_read(&net->ipv6.ip6_dst_ops.entries), |
2505 | net->ipv6.rt6_stats->fib_discarded_routes); | 2505 | net->ipv6.rt6_stats->fib_discarded_routes); |
2506 | 2506 | ||
2507 | return 0; | 2507 | return 0; |
@@ -2637,7 +2637,7 @@ struct ctl_table *ipv6_route_sysctl_init(struct net *net) | |||
2637 | 2637 | ||
2638 | if (table) { | 2638 | if (table) { |
2639 | table[0].data = &net->ipv6.sysctl.flush_delay; | 2639 | table[0].data = &net->ipv6.sysctl.flush_delay; |
2640 | table[1].data = &net->ipv6.ip6_dst_ops->gc_thresh; | 2640 | table[1].data = &net->ipv6.ip6_dst_ops.gc_thresh; |
2641 | table[2].data = &net->ipv6.sysctl.ip6_rt_max_size; | 2641 | table[2].data = &net->ipv6.sysctl.ip6_rt_max_size; |
2642 | table[3].data = &net->ipv6.sysctl.ip6_rt_gc_min_interval; | 2642 | table[3].data = &net->ipv6.sysctl.ip6_rt_gc_min_interval; |
2643 | table[4].data = &net->ipv6.sysctl.ip6_rt_gc_timeout; | 2643 | table[4].data = &net->ipv6.sysctl.ip6_rt_gc_timeout; |
@@ -2655,12 +2655,8 @@ static int ip6_route_net_init(struct net *net) | |||
2655 | { | 2655 | { |
2656 | int ret = -ENOMEM; | 2656 | int ret = -ENOMEM; |
2657 | 2657 | ||
2658 | net->ipv6.ip6_dst_ops = kmemdup(&ip6_dst_ops_template, | 2658 | memcpy(&net->ipv6.ip6_dst_ops, &ip6_dst_ops_template, |
2659 | sizeof(*net->ipv6.ip6_dst_ops), | 2659 | sizeof(net->ipv6.ip6_dst_ops)); |
2660 | GFP_KERNEL); | ||
2661 | if (!net->ipv6.ip6_dst_ops) | ||
2662 | goto out; | ||
2663 | net->ipv6.ip6_dst_ops->dst_net = hold_net(net); | ||
2664 | 2660 | ||
2665 | net->ipv6.ip6_null_entry = kmemdup(&ip6_null_entry_template, | 2661 | net->ipv6.ip6_null_entry = kmemdup(&ip6_null_entry_template, |
2666 | sizeof(*net->ipv6.ip6_null_entry), | 2662 | sizeof(*net->ipv6.ip6_null_entry), |
@@ -2669,7 +2665,7 @@ static int ip6_route_net_init(struct net *net) | |||
2669 | goto out_ip6_dst_ops; | 2665 | goto out_ip6_dst_ops; |
2670 | net->ipv6.ip6_null_entry->u.dst.path = | 2666 | net->ipv6.ip6_null_entry->u.dst.path = |
2671 | (struct dst_entry *)net->ipv6.ip6_null_entry; | 2667 | (struct dst_entry *)net->ipv6.ip6_null_entry; |
2672 | net->ipv6.ip6_null_entry->u.dst.ops = net->ipv6.ip6_dst_ops; | 2668 | net->ipv6.ip6_null_entry->u.dst.ops = &net->ipv6.ip6_dst_ops; |
2673 | 2669 | ||
2674 | #ifdef CONFIG_IPV6_MULTIPLE_TABLES | 2670 | #ifdef CONFIG_IPV6_MULTIPLE_TABLES |
2675 | net->ipv6.ip6_prohibit_entry = kmemdup(&ip6_prohibit_entry_template, | 2671 | net->ipv6.ip6_prohibit_entry = kmemdup(&ip6_prohibit_entry_template, |
@@ -2679,7 +2675,7 @@ static int ip6_route_net_init(struct net *net) | |||
2679 | goto out_ip6_null_entry; | 2675 | goto out_ip6_null_entry; |
2680 | net->ipv6.ip6_prohibit_entry->u.dst.path = | 2676 | net->ipv6.ip6_prohibit_entry->u.dst.path = |
2681 | (struct dst_entry *)net->ipv6.ip6_prohibit_entry; | 2677 | (struct dst_entry *)net->ipv6.ip6_prohibit_entry; |
2682 | net->ipv6.ip6_prohibit_entry->u.dst.ops = net->ipv6.ip6_dst_ops; | 2678 | net->ipv6.ip6_prohibit_entry->u.dst.ops = &net->ipv6.ip6_dst_ops; |
2683 | 2679 | ||
2684 | net->ipv6.ip6_blk_hole_entry = kmemdup(&ip6_blk_hole_entry_template, | 2680 | net->ipv6.ip6_blk_hole_entry = kmemdup(&ip6_blk_hole_entry_template, |
2685 | sizeof(*net->ipv6.ip6_blk_hole_entry), | 2681 | sizeof(*net->ipv6.ip6_blk_hole_entry), |
@@ -2688,7 +2684,7 @@ static int ip6_route_net_init(struct net *net) | |||
2688 | goto out_ip6_prohibit_entry; | 2684 | goto out_ip6_prohibit_entry; |
2689 | net->ipv6.ip6_blk_hole_entry->u.dst.path = | 2685 | net->ipv6.ip6_blk_hole_entry->u.dst.path = |
2690 | (struct dst_entry *)net->ipv6.ip6_blk_hole_entry; | 2686 | (struct dst_entry *)net->ipv6.ip6_blk_hole_entry; |
2691 | net->ipv6.ip6_blk_hole_entry->u.dst.ops = net->ipv6.ip6_dst_ops; | 2687 | net->ipv6.ip6_blk_hole_entry->u.dst.ops = &net->ipv6.ip6_dst_ops; |
2692 | #endif | 2688 | #endif |
2693 | 2689 | ||
2694 | net->ipv6.sysctl.flush_delay = 0; | 2690 | net->ipv6.sysctl.flush_delay = 0; |
@@ -2717,8 +2713,6 @@ out_ip6_null_entry: | |||
2717 | kfree(net->ipv6.ip6_null_entry); | 2713 | kfree(net->ipv6.ip6_null_entry); |
2718 | #endif | 2714 | #endif |
2719 | out_ip6_dst_ops: | 2715 | out_ip6_dst_ops: |
2720 | release_net(net->ipv6.ip6_dst_ops->dst_net); | ||
2721 | kfree(net->ipv6.ip6_dst_ops); | ||
2722 | goto out; | 2716 | goto out; |
2723 | } | 2717 | } |
2724 | 2718 | ||
@@ -2733,8 +2727,6 @@ static void ip6_route_net_exit(struct net *net) | |||
2733 | kfree(net->ipv6.ip6_prohibit_entry); | 2727 | kfree(net->ipv6.ip6_prohibit_entry); |
2734 | kfree(net->ipv6.ip6_blk_hole_entry); | 2728 | kfree(net->ipv6.ip6_blk_hole_entry); |
2735 | #endif | 2729 | #endif |
2736 | release_net(net->ipv6.ip6_dst_ops->dst_net); | ||
2737 | kfree(net->ipv6.ip6_dst_ops); | ||
2738 | } | 2730 | } |
2739 | 2731 | ||
2740 | static struct pernet_operations ip6_route_net_ops = { | 2732 | static struct pernet_operations ip6_route_net_ops = { |