diff options
author | Denis V. Lunev <den@openvz.org> | 2008-01-10 06:28:24 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-01-28 18:01:31 -0500 |
commit | e4aef8aea31e6fc61b33a57120968a6e9824d138 (patch) | |
tree | 1d00d8b59e40336ff096311480cc703aab9dc5c1 | |
parent | e4e4971c5f8b70daccdd401132a81b723dc8337e (diff) |
[NETNS]: Place fib tables into netns.
The preparatory work has been done. All we need is to substitute
fib_table_hash with net->ipv4.fib_table_hash. Netns context is
available when required.
Acked-by: Benjamin Thery <benjamin.thery@bull.net>
Acked-by: Daniel Lezcano <dlezcano@fr.ibm.com>
Signed-off-by: Denis V. Lunev <den@openvz.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | include/net/ip_fib.h | 6 | ||||
-rw-r--r-- | include/net/netns/ipv4.h | 2 | ||||
-rw-r--r-- | net/ipv4/fib_frontend.c | 36 |
3 files changed, 28 insertions, 16 deletions
diff --git a/include/net/ip_fib.h b/include/net/ip_fib.h index dfb95d732aa5..025b225181e1 100644 --- a/include/net/ip_fib.h +++ b/include/net/ip_fib.h | |||
@@ -120,8 +120,6 @@ struct fib_result_nl { | |||
120 | int err; | 120 | int err; |
121 | }; | 121 | }; |
122 | 122 | ||
123 | extern struct hlist_head fib_table_hash[]; | ||
124 | |||
125 | #ifdef CONFIG_IP_ROUTE_MULTIPATH | 123 | #ifdef CONFIG_IP_ROUTE_MULTIPATH |
126 | 124 | ||
127 | #define FIB_RES_NH(res) ((res).fi->fib_nh[(res).nh_sel]) | 125 | #define FIB_RES_NH(res) ((res).fi->fib_nh[(res).nh_sel]) |
@@ -170,8 +168,8 @@ static inline struct fib_table *fib_get_table(struct net *net, u32 id) | |||
170 | struct hlist_head *ptr; | 168 | struct hlist_head *ptr; |
171 | 169 | ||
172 | ptr = id == RT_TABLE_LOCAL ? | 170 | ptr = id == RT_TABLE_LOCAL ? |
173 | &fib_table_hash[TABLE_LOCAL_INDEX] : | 171 | &net->ipv4.fib_table_hash[TABLE_LOCAL_INDEX] : |
174 | &fib_table_hash[TABLE_MAIN_INDEX]; | 172 | &net->ipv4.fib_table_hash[TABLE_MAIN_INDEX]; |
175 | return hlist_entry(ptr->first, struct fib_table, tb_hlist); | 173 | return hlist_entry(ptr->first, struct fib_table, tb_hlist); |
176 | } | 174 | } |
177 | 175 | ||
diff --git a/include/net/netns/ipv4.h b/include/net/netns/ipv4.h index a7bd5d83e43e..2dd31937d022 100644 --- a/include/net/netns/ipv4.h +++ b/include/net/netns/ipv4.h | |||
@@ -8,6 +8,7 @@ | |||
8 | struct ctl_table_header; | 8 | struct ctl_table_header; |
9 | struct ipv4_devconf; | 9 | struct ipv4_devconf; |
10 | struct fib_rules_ops; | 10 | struct fib_rules_ops; |
11 | struct hlist_head; | ||
11 | 12 | ||
12 | struct netns_ipv4 { | 13 | struct netns_ipv4 { |
13 | #ifdef CONFIG_SYSCTL | 14 | #ifdef CONFIG_SYSCTL |
@@ -18,5 +19,6 @@ struct netns_ipv4 { | |||
18 | #ifdef CONFIG_IP_MULTIPLE_TABLES | 19 | #ifdef CONFIG_IP_MULTIPLE_TABLES |
19 | struct fib_rules_ops *rules_ops; | 20 | struct fib_rules_ops *rules_ops; |
20 | #endif | 21 | #endif |
22 | struct hlist_head *fib_table_hash; | ||
21 | }; | 23 | }; |
22 | #endif | 24 | #endif |
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c index 90aa05f47f8e..7fe54a3c168b 100644 --- a/net/ipv4/fib_frontend.c +++ b/net/ipv4/fib_frontend.c | |||
@@ -50,7 +50,6 @@ | |||
50 | #define FFprint(a...) printk(KERN_DEBUG a) | 50 | #define FFprint(a...) printk(KERN_DEBUG a) |
51 | 51 | ||
52 | static struct sock *fibnl; | 52 | static struct sock *fibnl; |
53 | struct hlist_head fib_table_hash[FIB_TABLE_HASHSZ]; | ||
54 | 53 | ||
55 | #ifndef CONFIG_IP_MULTIPLE_TABLES | 54 | #ifndef CONFIG_IP_MULTIPLE_TABLES |
56 | 55 | ||
@@ -67,9 +66,9 @@ static int __net_init fib4_rules_init(struct net *net) | |||
67 | goto fail; | 66 | goto fail; |
68 | 67 | ||
69 | hlist_add_head_rcu(&local_table->tb_hlist, | 68 | hlist_add_head_rcu(&local_table->tb_hlist, |
70 | &fib_table_hash[TABLE_LOCAL_INDEX]); | 69 | &net->ipv4.fib_table_hash[TABLE_LOCAL_INDEX]); |
71 | hlist_add_head_rcu(&main_table->tb_hlist, | 70 | hlist_add_head_rcu(&main_table->tb_hlist, |
72 | &fib_table_hash[TABLE_MAIN_INDEX]); | 71 | &net->ipv4.fib_table_hash[TABLE_MAIN_INDEX]); |
73 | return 0; | 72 | return 0; |
74 | 73 | ||
75 | fail: | 74 | fail: |
@@ -92,7 +91,7 @@ struct fib_table *fib_new_table(struct net *net, u32 id) | |||
92 | if (!tb) | 91 | if (!tb) |
93 | return NULL; | 92 | return NULL; |
94 | h = id & (FIB_TABLE_HASHSZ - 1); | 93 | h = id & (FIB_TABLE_HASHSZ - 1); |
95 | hlist_add_head_rcu(&tb->tb_hlist, &fib_table_hash[h]); | 94 | hlist_add_head_rcu(&tb->tb_hlist, &net->ipv4.fib_table_hash[h]); |
96 | return tb; | 95 | return tb; |
97 | } | 96 | } |
98 | 97 | ||
@@ -100,13 +99,16 @@ struct fib_table *fib_get_table(struct net *net, u32 id) | |||
100 | { | 99 | { |
101 | struct fib_table *tb; | 100 | struct fib_table *tb; |
102 | struct hlist_node *node; | 101 | struct hlist_node *node; |
102 | struct hlist_head *head; | ||
103 | unsigned int h; | 103 | unsigned int h; |
104 | 104 | ||
105 | if (id == 0) | 105 | if (id == 0) |
106 | id = RT_TABLE_MAIN; | 106 | id = RT_TABLE_MAIN; |
107 | h = id & (FIB_TABLE_HASHSZ - 1); | 107 | h = id & (FIB_TABLE_HASHSZ - 1); |
108 | |||
108 | rcu_read_lock(); | 109 | rcu_read_lock(); |
109 | hlist_for_each_entry_rcu(tb, node, &fib_table_hash[h], tb_hlist) { | 110 | head = &net->ipv4.fib_table_hash[h]; |
111 | hlist_for_each_entry_rcu(tb, node, head, tb_hlist) { | ||
110 | if (tb->tb_id == id) { | 112 | if (tb->tb_id == id) { |
111 | rcu_read_unlock(); | 113 | rcu_read_unlock(); |
112 | return tb; | 114 | return tb; |
@@ -117,15 +119,17 @@ struct fib_table *fib_get_table(struct net *net, u32 id) | |||
117 | } | 119 | } |
118 | #endif /* CONFIG_IP_MULTIPLE_TABLES */ | 120 | #endif /* CONFIG_IP_MULTIPLE_TABLES */ |
119 | 121 | ||
120 | static void fib_flush(void) | 122 | static void fib_flush(struct net *net) |
121 | { | 123 | { |
122 | int flushed = 0; | 124 | int flushed = 0; |
123 | struct fib_table *tb; | 125 | struct fib_table *tb; |
124 | struct hlist_node *node; | 126 | struct hlist_node *node; |
127 | struct hlist_head *head; | ||
125 | unsigned int h; | 128 | unsigned int h; |
126 | 129 | ||
127 | for (h = 0; h < FIB_TABLE_HASHSZ; h++) { | 130 | for (h = 0; h < FIB_TABLE_HASHSZ; h++) { |
128 | hlist_for_each_entry(tb, node, &fib_table_hash[h], tb_hlist) | 131 | head = &net->ipv4.fib_table_hash[h]; |
132 | hlist_for_each_entry(tb, node, head, tb_hlist) | ||
129 | flushed += tb->tb_flush(tb); | 133 | flushed += tb->tb_flush(tb); |
130 | } | 134 | } |
131 | 135 | ||
@@ -620,6 +624,7 @@ static int inet_dump_fib(struct sk_buff *skb, struct netlink_callback *cb) | |||
620 | unsigned int e = 0, s_e; | 624 | unsigned int e = 0, s_e; |
621 | struct fib_table *tb; | 625 | struct fib_table *tb; |
622 | struct hlist_node *node; | 626 | struct hlist_node *node; |
627 | struct hlist_head *head; | ||
623 | int dumped = 0; | 628 | int dumped = 0; |
624 | 629 | ||
625 | if (net != &init_net) | 630 | if (net != &init_net) |
@@ -634,7 +639,8 @@ static int inet_dump_fib(struct sk_buff *skb, struct netlink_callback *cb) | |||
634 | 639 | ||
635 | for (h = s_h; h < FIB_TABLE_HASHSZ; h++, s_e = 0) { | 640 | for (h = s_h; h < FIB_TABLE_HASHSZ; h++, s_e = 0) { |
636 | e = 0; | 641 | e = 0; |
637 | hlist_for_each_entry(tb, node, &fib_table_hash[h], tb_hlist) { | 642 | head = &net->ipv4.fib_table_hash[h]; |
643 | hlist_for_each_entry(tb, node, head, tb_hlist) { | ||
638 | if (e < s_e) | 644 | if (e < s_e) |
639 | goto next; | 645 | goto next; |
640 | if (dumped) | 646 | if (dumped) |
@@ -797,7 +803,7 @@ static void fib_del_ifaddr(struct in_ifaddr *ifa) | |||
797 | for stray nexthop entries, then ignite fib_flush. | 803 | for stray nexthop entries, then ignite fib_flush. |
798 | */ | 804 | */ |
799 | if (fib_sync_down(ifa->ifa_local, NULL, 0)) | 805 | if (fib_sync_down(ifa->ifa_local, NULL, 0)) |
800 | fib_flush(); | 806 | fib_flush(&init_net); |
801 | } | 807 | } |
802 | } | 808 | } |
803 | #undef LOCAL_OK | 809 | #undef LOCAL_OK |
@@ -882,7 +888,7 @@ static void nl_fib_lookup_exit(struct net *net) | |||
882 | static void fib_disable_ip(struct net_device *dev, int force) | 888 | static void fib_disable_ip(struct net_device *dev, int force) |
883 | { | 889 | { |
884 | if (fib_sync_down(0, dev, force)) | 890 | if (fib_sync_down(0, dev, force)) |
885 | fib_flush(); | 891 | fib_flush(&init_net); |
886 | rt_cache_flush(0); | 892 | rt_cache_flush(0); |
887 | arp_ifdown(dev); | 893 | arp_ifdown(dev); |
888 | } | 894 | } |
@@ -963,8 +969,13 @@ static int __net_init ip_fib_net_init(struct net *net) | |||
963 | { | 969 | { |
964 | unsigned int i; | 970 | unsigned int i; |
965 | 971 | ||
972 | net->ipv4.fib_table_hash = kzalloc( | ||
973 | sizeof(struct hlist_head)*FIB_TABLE_HASHSZ, GFP_KERNEL); | ||
974 | if (net->ipv4.fib_table_hash == NULL) | ||
975 | return -ENOMEM; | ||
976 | |||
966 | for (i = 0; i < FIB_TABLE_HASHSZ; i++) | 977 | for (i = 0; i < FIB_TABLE_HASHSZ; i++) |
967 | INIT_HLIST_HEAD(&fib_table_hash[i]); | 978 | INIT_HLIST_HEAD(&net->ipv4.fib_table_hash[i]); |
968 | 979 | ||
969 | return fib4_rules_init(net); | 980 | return fib4_rules_init(net); |
970 | } | 981 | } |
@@ -982,13 +993,14 @@ static void __net_exit ip_fib_net_exit(struct net *net) | |||
982 | struct hlist_head *head; | 993 | struct hlist_head *head; |
983 | struct hlist_node *node, *tmp; | 994 | struct hlist_node *node, *tmp; |
984 | 995 | ||
985 | head = &fib_table_hash[i]; | 996 | head = &net->ipv4.fib_table_hash[i]; |
986 | hlist_for_each_entry_safe(tb, node, tmp, head, tb_hlist) { | 997 | hlist_for_each_entry_safe(tb, node, tmp, head, tb_hlist) { |
987 | hlist_del(node); | 998 | hlist_del(node); |
988 | tb->tb_flush(tb); | 999 | tb->tb_flush(tb); |
989 | kfree(tb); | 1000 | kfree(tb); |
990 | } | 1001 | } |
991 | } | 1002 | } |
1003 | kfree(net->ipv4.fib_table_hash); | ||
992 | } | 1004 | } |
993 | 1005 | ||
994 | static int __net_init fib_net_init(struct net *net) | 1006 | static int __net_init fib_net_init(struct net *net) |