aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/netns/x_tables.h3
-rw-r--r--net/bridge/netfilter/ebtable_broute.c35
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
7struct ebt_table;
8
7struct netns_xt { 9struct 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
44static struct ebt_table __broute_table = 44static 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};
53static struct ebt_table *broute_table;
54 53
55static int ebt_broute(struct sk_buff *skb) 54static 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
65static 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
73static void __net_exit broute_net_exit(struct net *net)
74{
75 ebt_unregister_table(net->xt.broute_table);
76}
77
78static struct pernet_operations broute_net_ops = {
79 .init = broute_net_init,
80 .exit = broute_net_exit,
81};
82
66static int __init ebtable_broute_init(void) 83static 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
83module_init(ebtable_broute_init); 102module_init(ebtable_broute_init);