aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDenis V. Lunev <den@openvz.org>2008-01-10 06:28:24 -0500
committerDavid S. Miller <davem@davemloft.net>2008-01-28 18:01:31 -0500
commite4aef8aea31e6fc61b33a57120968a6e9824d138 (patch)
tree1d00d8b59e40336ff096311480cc703aab9dc5c1
parente4e4971c5f8b70daccdd401132a81b723dc8337e (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.h6
-rw-r--r--include/net/netns/ipv4.h2
-rw-r--r--net/ipv4/fib_frontend.c36
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
123extern 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 @@
8struct ctl_table_header; 8struct ctl_table_header;
9struct ipv4_devconf; 9struct ipv4_devconf;
10struct fib_rules_ops; 10struct fib_rules_ops;
11struct hlist_head;
11 12
12struct netns_ipv4 { 13struct 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
52static struct sock *fibnl; 52static struct sock *fibnl;
53struct 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
75fail: 74fail:
@@ -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
120static void fib_flush(void) 122static 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)
882static void fib_disable_ip(struct net_device *dev, int force) 888static 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
994static int __net_init fib_net_init(struct net *net) 1006static int __net_init fib_net_init(struct net *net)