diff options
author | Denis V. Lunev <den@openvz.org> | 2008-01-10 06:22:17 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-01-28 18:01:25 -0500 |
commit | 7b1a74fdbb9ec38a9780620fae25519fde4b21ee (patch) | |
tree | a8405f9a3e30cf6750d60aff16e555d4901ce57f /net | |
parent | dbb50165b512f6c9b7aae10af73ae5b6d811f4d0 (diff) |
[NETNS]: Refactor fib initialization so it can handle multiple namespaces.
This patch makes the fib to be initialized as a subsystem for the
network namespaces. The code does not handle several namespaces yet,
so in case of a creation of a network namespace, the
creation/initialization will not occur.
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>
Diffstat (limited to 'net')
-rw-r--r-- | net/ipv4/af_inet.c | 4 | ||||
-rw-r--r-- | net/ipv4/fib_frontend.c | 88 | ||||
-rw-r--r-- | net/ipv4/fib_hash.c | 6 | ||||
-rw-r--r-- | net/ipv4/fib_rules.c | 11 | ||||
-rw-r--r-- | net/ipv4/fib_trie.c | 6 |
5 files changed, 90 insertions, 25 deletions
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index d5b8cb1dad67..40ecaae7be32 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c | |||
@@ -1475,15 +1475,11 @@ static int __init ipv4_proc_init(void) | |||
1475 | goto out_tcp; | 1475 | goto out_tcp; |
1476 | if (udp4_proc_init()) | 1476 | if (udp4_proc_init()) |
1477 | goto out_udp; | 1477 | goto out_udp; |
1478 | if (fib_proc_init(&init_net)) | ||
1479 | goto out_fib; | ||
1480 | if (ip_misc_proc_init()) | 1478 | if (ip_misc_proc_init()) |
1481 | goto out_misc; | 1479 | goto out_misc; |
1482 | out: | 1480 | out: |
1483 | return rc; | 1481 | return rc; |
1484 | out_misc: | 1482 | out_misc: |
1485 | fib_proc_exit(&init_net); | ||
1486 | out_fib: | ||
1487 | udp4_proc_exit(); | 1483 | udp4_proc_exit(); |
1488 | out_udp: | 1484 | out_udp: |
1489 | tcp4_proc_exit(); | 1485 | tcp4_proc_exit(); |
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c index 1bb956b3be28..0484cae02736 100644 --- a/net/ipv4/fib_frontend.c +++ b/net/ipv4/fib_frontend.c | |||
@@ -59,7 +59,7 @@ struct fib_table *ip_fib_main_table; | |||
59 | #define FIB_TABLE_HASHSZ 1 | 59 | #define FIB_TABLE_HASHSZ 1 |
60 | static struct hlist_head fib_table_hash[FIB_TABLE_HASHSZ]; | 60 | static struct hlist_head fib_table_hash[FIB_TABLE_HASHSZ]; |
61 | 61 | ||
62 | static int __init fib4_rules_init(void) | 62 | static int __net_init fib4_rules_init(struct net *net) |
63 | { | 63 | { |
64 | ip_fib_local_table = fib_hash_init(RT_TABLE_LOCAL); | 64 | ip_fib_local_table = fib_hash_init(RT_TABLE_LOCAL); |
65 | if (ip_fib_local_table == NULL) | 65 | if (ip_fib_local_table == NULL) |
@@ -863,10 +863,18 @@ static void nl_fib_input(struct sk_buff *skb) | |||
863 | netlink_unicast(fibnl, skb, pid, MSG_DONTWAIT); | 863 | netlink_unicast(fibnl, skb, pid, MSG_DONTWAIT); |
864 | } | 864 | } |
865 | 865 | ||
866 | static void nl_fib_lookup_init(void) | 866 | static int nl_fib_lookup_init(struct net *net) |
867 | { | 867 | { |
868 | fibnl = netlink_kernel_create(&init_net, NETLINK_FIB_LOOKUP, 0, | 868 | fibnl = netlink_kernel_create(net, NETLINK_FIB_LOOKUP, 0, |
869 | nl_fib_input, NULL, THIS_MODULE); | 869 | nl_fib_input, NULL, THIS_MODULE); |
870 | if (fibnl == NULL) | ||
871 | return -EAFNOSUPPORT; | ||
872 | return 0; | ||
873 | } | ||
874 | |||
875 | static void nl_fib_lookup_exit(struct net *net) | ||
876 | { | ||
877 | sock_put(fibnl); | ||
870 | } | 878 | } |
871 | 879 | ||
872 | static void fib_disable_ip(struct net_device *dev, int force) | 880 | static void fib_disable_ip(struct net_device *dev, int force) |
@@ -949,22 +957,86 @@ static struct notifier_block fib_netdev_notifier = { | |||
949 | .notifier_call =fib_netdev_event, | 957 | .notifier_call =fib_netdev_event, |
950 | }; | 958 | }; |
951 | 959 | ||
952 | void __init ip_fib_init(void) | 960 | static int __net_init ip_fib_net_init(struct net *net) |
953 | { | 961 | { |
954 | unsigned int i; | 962 | unsigned int i; |
955 | 963 | ||
956 | for (i = 0; i < FIB_TABLE_HASHSZ; i++) | 964 | for (i = 0; i < FIB_TABLE_HASHSZ; i++) |
957 | INIT_HLIST_HEAD(&fib_table_hash[i]); | 965 | INIT_HLIST_HEAD(&fib_table_hash[i]); |
958 | 966 | ||
959 | BUG_ON(fib4_rules_init()); | 967 | return fib4_rules_init(net); |
968 | } | ||
960 | 969 | ||
961 | register_netdevice_notifier(&fib_netdev_notifier); | 970 | static void __net_exit ip_fib_net_exit(struct net *net) |
962 | register_inetaddr_notifier(&fib_inetaddr_notifier); | 971 | { |
963 | nl_fib_lookup_init(); | 972 | unsigned int i; |
973 | |||
974 | #ifdef CONFIG_IP_MULTIPLE_TABLES | ||
975 | fib4_rules_exit(net); | ||
976 | #endif | ||
977 | |||
978 | for (i = 0; i < FIB_TABLE_HASHSZ; i++) { | ||
979 | struct fib_table *tb; | ||
980 | struct hlist_head *head; | ||
981 | struct hlist_node *node, *tmp; | ||
964 | 982 | ||
983 | head = &fib_table_hash[i]; | ||
984 | hlist_for_each_entry_safe(tb, node, tmp, head, tb_hlist) { | ||
985 | hlist_del(node); | ||
986 | tb->tb_flush(tb); | ||
987 | kfree(tb); | ||
988 | } | ||
989 | } | ||
990 | } | ||
991 | |||
992 | static int __net_init fib_net_init(struct net *net) | ||
993 | { | ||
994 | int error; | ||
995 | |||
996 | error = 0; | ||
997 | if (net != &init_net) | ||
998 | goto out; | ||
999 | |||
1000 | error = ip_fib_net_init(net); | ||
1001 | if (error < 0) | ||
1002 | goto out; | ||
1003 | error = nl_fib_lookup_init(net); | ||
1004 | if (error < 0) | ||
1005 | goto out_nlfl; | ||
1006 | error = fib_proc_init(net); | ||
1007 | if (error < 0) | ||
1008 | goto out_proc; | ||
1009 | out: | ||
1010 | return error; | ||
1011 | |||
1012 | out_proc: | ||
1013 | nl_fib_lookup_exit(net); | ||
1014 | out_nlfl: | ||
1015 | ip_fib_net_exit(net); | ||
1016 | goto out; | ||
1017 | } | ||
1018 | |||
1019 | static void __net_exit fib_net_exit(struct net *net) | ||
1020 | { | ||
1021 | fib_proc_exit(net); | ||
1022 | nl_fib_lookup_exit(net); | ||
1023 | ip_fib_net_exit(net); | ||
1024 | } | ||
1025 | |||
1026 | static struct pernet_operations fib_net_ops = { | ||
1027 | .init = fib_net_init, | ||
1028 | .exit = fib_net_exit, | ||
1029 | }; | ||
1030 | |||
1031 | void __init ip_fib_init(void) | ||
1032 | { | ||
965 | rtnl_register(PF_INET, RTM_NEWROUTE, inet_rtm_newroute, NULL); | 1033 | rtnl_register(PF_INET, RTM_NEWROUTE, inet_rtm_newroute, NULL); |
966 | rtnl_register(PF_INET, RTM_DELROUTE, inet_rtm_delroute, NULL); | 1034 | rtnl_register(PF_INET, RTM_DELROUTE, inet_rtm_delroute, NULL); |
967 | rtnl_register(PF_INET, RTM_GETROUTE, NULL, inet_dump_fib); | 1035 | rtnl_register(PF_INET, RTM_GETROUTE, NULL, inet_dump_fib); |
1036 | |||
1037 | register_pernet_subsys(&fib_net_ops); | ||
1038 | register_netdevice_notifier(&fib_netdev_notifier); | ||
1039 | register_inetaddr_notifier(&fib_inetaddr_notifier); | ||
968 | } | 1040 | } |
969 | 1041 | ||
970 | EXPORT_SYMBOL(inet_addr_type); | 1042 | EXPORT_SYMBOL(inet_addr_type); |
diff --git a/net/ipv4/fib_hash.c b/net/ipv4/fib_hash.c index 8de21bc4947a..694a072d8090 100644 --- a/net/ipv4/fib_hash.c +++ b/net/ipv4/fib_hash.c | |||
@@ -746,11 +746,7 @@ static int fn_hash_dump(struct fib_table *tb, struct sk_buff *skb, struct netlin | |||
746 | return skb->len; | 746 | return skb->len; |
747 | } | 747 | } |
748 | 748 | ||
749 | #ifdef CONFIG_IP_MULTIPLE_TABLES | 749 | struct fib_table *fib_hash_init(u32 id) |
750 | struct fib_table * fib_hash_init(u32 id) | ||
751 | #else | ||
752 | struct fib_table * __init fib_hash_init(u32 id) | ||
753 | #endif | ||
754 | { | 750 | { |
755 | struct fib_table *tb; | 751 | struct fib_table *tb; |
756 | 752 | ||
diff --git a/net/ipv4/fib_rules.c b/net/ipv4/fib_rules.c index 0751734ecf41..1aae61c8ea6a 100644 --- a/net/ipv4/fib_rules.c +++ b/net/ipv4/fib_rules.c | |||
@@ -311,11 +311,11 @@ static int __init fib_default_rules_init(void) | |||
311 | return 0; | 311 | return 0; |
312 | } | 312 | } |
313 | 313 | ||
314 | int __init fib4_rules_init() | 314 | int __net_init fib4_rules_init(struct net *net) |
315 | { | 315 | { |
316 | int err; | 316 | int err; |
317 | 317 | ||
318 | fib_rules_register(&init_net, &fib4_rules_ops); | 318 | fib_rules_register(net, &fib4_rules_ops); |
319 | err = fib_default_rules_init(); | 319 | err = fib_default_rules_init(); |
320 | if (err < 0) | 320 | if (err < 0) |
321 | goto fail; | 321 | goto fail; |
@@ -323,6 +323,11 @@ int __init fib4_rules_init() | |||
323 | 323 | ||
324 | fail: | 324 | fail: |
325 | /* also cleans all rules already added */ | 325 | /* also cleans all rules already added */ |
326 | fib_rules_unregister(&init_net, &fib4_rules_ops); | 326 | fib_rules_unregister(net, &fib4_rules_ops); |
327 | return err; | 327 | return err; |
328 | } | 328 | } |
329 | |||
330 | void __net_exit fib4_rules_exit(struct net *net) | ||
331 | { | ||
332 | fib_rules_unregister(net, &fib4_rules_ops); | ||
333 | } | ||
diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c index 4bbfaeedf210..92b687e6a472 100644 --- a/net/ipv4/fib_trie.c +++ b/net/ipv4/fib_trie.c | |||
@@ -1956,11 +1956,7 @@ out: | |||
1956 | 1956 | ||
1957 | /* Fix more generic FIB names for init later */ | 1957 | /* Fix more generic FIB names for init later */ |
1958 | 1958 | ||
1959 | #ifdef CONFIG_IP_MULTIPLE_TABLES | 1959 | struct fib_table *fib_hash_init(u32 id) |
1960 | struct fib_table * fib_hash_init(u32 id) | ||
1961 | #else | ||
1962 | struct fib_table * __init fib_hash_init(u32 id) | ||
1963 | #endif | ||
1964 | { | 1960 | { |
1965 | struct fib_table *tb; | 1961 | struct fib_table *tb; |
1966 | struct trie *t; | 1962 | struct trie *t; |