diff options
-rw-r--r-- | include/net/netns/x_tables.h | 1 | ||||
-rw-r--r-- | net/bridge/netfilter/ebtable_filter.c | 50 |
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; | |||
9 | struct netns_xt { | 9 | struct 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 | ||
53 | static struct ebt_table __frame_filter = | 53 | static 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 | }; |
62 | static struct ebt_table *frame_filter; | ||
63 | 62 | ||
64 | static unsigned int | 63 | static unsigned int |
65 | ebt_hook(unsigned int hook, struct sk_buff *skb, const struct net_device *in, | 64 | ebt_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 | |||
70 | static unsigned int | ||
71 | ebt_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 | ||
71 | static struct nf_hook_ops ebt_ops_filter[] __read_mostly = { | 77 | static 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 | ||
101 | static 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 | |||
109 | static void __net_exit frame_filter_net_exit(struct net *net) | ||
110 | { | ||
111 | ebt_unregister_table(net->xt.frame_filter); | ||
112 | } | ||
113 | |||
114 | static struct pernet_operations frame_filter_net_ops = { | ||
115 | .init = frame_filter_net_init, | ||
116 | .exit = frame_filter_net_exit, | ||
117 | }; | ||
118 | |||
95 | static int __init ebtable_filter_init(void) | 119 | static 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 | ||
108 | static void __exit ebtable_filter_fini(void) | 132 | static 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 | ||
114 | module_init(ebtable_filter_init); | 138 | module_init(ebtable_filter_init); |