diff options
-rw-r--r-- | include/net/netns/x_tables.h | 3 | ||||
-rw-r--r-- | net/bridge/netfilter/ebtable_broute.c | 35 |
2 files changed, 30 insertions, 8 deletions
diff --git a/include/net/netns/x_tables.h b/include/net/netns/x_tables.h index b8093971ccb4..055e684d29b6 100644 --- a/include/net/netns/x_tables.h +++ b/include/net/netns/x_tables.h | |||
@@ -4,7 +4,10 @@ | |||
4 | #include <linux/list.h> | 4 | #include <linux/list.h> |
5 | #include <linux/netfilter.h> | 5 | #include <linux/netfilter.h> |
6 | 6 | ||
7 | struct ebt_table; | ||
8 | |||
7 | struct netns_xt { | 9 | struct netns_xt { |
8 | struct list_head tables[NFPROTO_NUMPROTO]; | 10 | struct list_head tables[NFPROTO_NUMPROTO]; |
11 | struct ebt_table *broute_table; | ||
9 | }; | 12 | }; |
10 | #endif | 13 | #endif |
diff --git a/net/bridge/netfilter/ebtable_broute.c b/net/bridge/netfilter/ebtable_broute.c index 3277d682dfcf..8604dfc1fc3b 100644 --- a/net/bridge/netfilter/ebtable_broute.c +++ b/net/bridge/netfilter/ebtable_broute.c | |||
@@ -41,33 +41,52 @@ static int check(const struct ebt_table_info *info, unsigned int valid_hooks) | |||
41 | return 0; | 41 | return 0; |
42 | } | 42 | } |
43 | 43 | ||
44 | static struct ebt_table __broute_table = | 44 | static struct ebt_table broute_table = |
45 | { | 45 | { |
46 | .name = "broute", | 46 | .name = "broute", |
47 | .table = &initial_table, | 47 | .table = &initial_table, |
48 | .valid_hooks = 1 << NF_BR_BROUTING, | 48 | .valid_hooks = 1 << NF_BR_BROUTING, |
49 | .lock = __RW_LOCK_UNLOCKED(__broute_table.lock), | 49 | .lock = __RW_LOCK_UNLOCKED(broute_table.lock), |
50 | .check = check, | 50 | .check = check, |
51 | .me = THIS_MODULE, | 51 | .me = THIS_MODULE, |
52 | }; | 52 | }; |
53 | static struct ebt_table *broute_table; | ||
54 | 53 | ||
55 | static int ebt_broute(struct sk_buff *skb) | 54 | static int ebt_broute(struct sk_buff *skb) |
56 | { | 55 | { |
57 | int ret; | 56 | int ret; |
58 | 57 | ||
59 | ret = ebt_do_table(NF_BR_BROUTING, skb, skb->dev, NULL, | 58 | ret = ebt_do_table(NF_BR_BROUTING, skb, skb->dev, NULL, |
60 | broute_table); | 59 | dev_net(skb->dev)->xt.broute_table); |
61 | if (ret == NF_DROP) | 60 | if (ret == NF_DROP) |
62 | return 1; /* route it */ | 61 | return 1; /* route it */ |
63 | return 0; /* bridge it */ | 62 | return 0; /* bridge it */ |
64 | } | 63 | } |
65 | 64 | ||
65 | static int __net_init broute_net_init(struct net *net) | ||
66 | { | ||
67 | net->xt.broute_table = ebt_register_table(net, &broute_table); | ||
68 | if (IS_ERR(net->xt.broute_table)) | ||
69 | return PTR_ERR(net->xt.broute_table); | ||
70 | return 0; | ||
71 | } | ||
72 | |||
73 | static void __net_exit broute_net_exit(struct net *net) | ||
74 | { | ||
75 | ebt_unregister_table(net->xt.broute_table); | ||
76 | } | ||
77 | |||
78 | static struct pernet_operations broute_net_ops = { | ||
79 | .init = broute_net_init, | ||
80 | .exit = broute_net_exit, | ||
81 | }; | ||
82 | |||
66 | static int __init ebtable_broute_init(void) | 83 | static int __init ebtable_broute_init(void) |
67 | { | 84 | { |
68 | broute_table = ebt_register_table(&init_net, &__broute_table); | 85 | int ret; |
69 | if (IS_ERR(broute_table)) | 86 | |
70 | return PTR_ERR(broute_table); | 87 | ret = register_pernet_subsys(&broute_net_ops); |
88 | if (ret < 0) | ||
89 | return ret; | ||
71 | /* see br_input.c */ | 90 | /* see br_input.c */ |
72 | rcu_assign_pointer(br_should_route_hook, ebt_broute); | 91 | rcu_assign_pointer(br_should_route_hook, ebt_broute); |
73 | return 0; | 92 | return 0; |
@@ -77,7 +96,7 @@ static void __exit ebtable_broute_fini(void) | |||
77 | { | 96 | { |
78 | rcu_assign_pointer(br_should_route_hook, NULL); | 97 | rcu_assign_pointer(br_should_route_hook, NULL); |
79 | synchronize_net(); | 98 | synchronize_net(); |
80 | ebt_unregister_table(broute_table); | 99 | unregister_pernet_subsys(&broute_net_ops); |
81 | } | 100 | } |
82 | 101 | ||
83 | module_init(ebtable_broute_init); | 102 | module_init(ebtable_broute_init); |