aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/netns/x_tables.h1
-rw-r--r--net/bridge/netfilter/ebtable_filter.c50
2 files changed, 38 insertions, 13 deletions
diff --git a/include/net/netns/x_tables.h b/include/net/netns/x_tables.h
index 055e684d29b6..d258e16c894e 100644
--- a/include/net/netns/x_tables.h
+++ b/include/net/netns/x_tables.h
@@ -9,5 +9,6 @@ struct ebt_table;
9struct netns_xt { 9struct netns_xt {
10 struct list_head tables[NFPROTO_NUMPROTO]; 10 struct list_head tables[NFPROTO_NUMPROTO];
11 struct ebt_table *broute_table; 11 struct ebt_table *broute_table;
12 struct ebt_table *frame_filter;
12}; 13};
13#endif 14#endif
diff --git a/net/bridge/netfilter/ebtable_filter.c b/net/bridge/netfilter/ebtable_filter.c
index 596564c7aa58..2b2e8040a9c6 100644
--- a/net/bridge/netfilter/ebtable_filter.c
+++ b/net/bridge/netfilter/ebtable_filter.c
@@ -50,41 +50,47 @@ static int check(const struct ebt_table_info *info, unsigned int valid_hooks)
50 return 0; 50 return 0;
51} 51}
52 52
53static struct ebt_table __frame_filter = 53static struct ebt_table frame_filter =
54{ 54{
55 .name = "filter", 55 .name = "filter",
56 .table = &initial_table, 56 .table = &initial_table,
57 .valid_hooks = FILTER_VALID_HOOKS, 57 .valid_hooks = FILTER_VALID_HOOKS,
58 .lock = __RW_LOCK_UNLOCKED(__frame_filter.lock), 58 .lock = __RW_LOCK_UNLOCKED(frame_filter.lock),
59 .check = check, 59 .check = check,
60 .me = THIS_MODULE, 60 .me = THIS_MODULE,
61}; 61};
62static struct ebt_table *frame_filter;
63 62
64static unsigned int 63static unsigned int
65ebt_hook(unsigned int hook, struct sk_buff *skb, const struct net_device *in, 64ebt_in_hook(unsigned int hook, struct sk_buff *skb, const struct net_device *in,
66 const struct net_device *out, int (*okfn)(struct sk_buff *)) 65 const struct net_device *out, int (*okfn)(struct sk_buff *))
67{ 66{
68 return ebt_do_table(hook, skb, in, out, frame_filter); 67 return ebt_do_table(hook, skb, in, out, dev_net(in)->xt.frame_filter);
68}
69
70static unsigned int
71ebt_out_hook(unsigned int hook, struct sk_buff *skb, const struct net_device *in,
72 const struct net_device *out, int (*okfn)(struct sk_buff *))
73{
74 return ebt_do_table(hook, skb, in, out, dev_net(out)->xt.frame_filter);
69} 75}
70 76
71static struct nf_hook_ops ebt_ops_filter[] __read_mostly = { 77static struct nf_hook_ops ebt_ops_filter[] __read_mostly = {
72 { 78 {
73 .hook = ebt_hook, 79 .hook = ebt_in_hook,
74 .owner = THIS_MODULE, 80 .owner = THIS_MODULE,
75 .pf = PF_BRIDGE, 81 .pf = PF_BRIDGE,
76 .hooknum = NF_BR_LOCAL_IN, 82 .hooknum = NF_BR_LOCAL_IN,
77 .priority = NF_BR_PRI_FILTER_BRIDGED, 83 .priority = NF_BR_PRI_FILTER_BRIDGED,
78 }, 84 },
79 { 85 {
80 .hook = ebt_hook, 86 .hook = ebt_in_hook,
81 .owner = THIS_MODULE, 87 .owner = THIS_MODULE,
82 .pf = PF_BRIDGE, 88 .pf = PF_BRIDGE,
83 .hooknum = NF_BR_FORWARD, 89 .hooknum = NF_BR_FORWARD,
84 .priority = NF_BR_PRI_FILTER_BRIDGED, 90 .priority = NF_BR_PRI_FILTER_BRIDGED,
85 }, 91 },
86 { 92 {
87 .hook = ebt_hook, 93 .hook = ebt_out_hook,
88 .owner = THIS_MODULE, 94 .owner = THIS_MODULE,
89 .pf = PF_BRIDGE, 95 .pf = PF_BRIDGE,
90 .hooknum = NF_BR_LOCAL_OUT, 96 .hooknum = NF_BR_LOCAL_OUT,
@@ -92,23 +98,41 @@ static struct nf_hook_ops ebt_ops_filter[] __read_mostly = {
92 }, 98 },
93}; 99};
94 100
101static int __net_init frame_filter_net_init(struct net *net)
102{
103 net->xt.frame_filter = ebt_register_table(net, &frame_filter);
104 if (IS_ERR(net->xt.frame_filter))
105 return PTR_ERR(net->xt.frame_filter);
106 return 0;
107}
108
109static void __net_exit frame_filter_net_exit(struct net *net)
110{
111 ebt_unregister_table(net->xt.frame_filter);
112}
113
114static struct pernet_operations frame_filter_net_ops = {
115 .init = frame_filter_net_init,
116 .exit = frame_filter_net_exit,
117};
118
95static int __init ebtable_filter_init(void) 119static int __init ebtable_filter_init(void)
96{ 120{
97 int ret; 121 int ret;
98 122
99 frame_filter = ebt_register_table(&init_net, &__frame_filter); 123 ret = register_pernet_subsys(&frame_filter_net_ops);
100 if (IS_ERR(frame_filter)) 124 if (ret < 0)
101 return PTR_ERR(frame_filter); 125 return ret;
102 ret = nf_register_hooks(ebt_ops_filter, ARRAY_SIZE(ebt_ops_filter)); 126 ret = nf_register_hooks(ebt_ops_filter, ARRAY_SIZE(ebt_ops_filter));
103 if (ret < 0) 127 if (ret < 0)
104 ebt_unregister_table(frame_filter); 128 unregister_pernet_subsys(&frame_filter_net_ops);
105 return ret; 129 return ret;
106} 130}
107 131
108static void __exit ebtable_filter_fini(void) 132static void __exit ebtable_filter_fini(void)
109{ 133{
110 nf_unregister_hooks(ebt_ops_filter, ARRAY_SIZE(ebt_ops_filter)); 134 nf_unregister_hooks(ebt_ops_filter, ARRAY_SIZE(ebt_ops_filter));
111 ebt_unregister_table(frame_filter); 135 unregister_pernet_subsys(&frame_filter_net_ops);
112} 136}
113 137
114module_init(ebtable_filter_init); 138module_init(ebtable_filter_init);