aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2017-07-18 15:01:39 -0400
committerDavid S. Miller <davem@davemloft.net>2017-07-18 15:01:39 -0400
commit3e16afd33f8fdad0a39586d670ade3cad67e1360 (patch)
tree7eea35bbdda174859e39c306d78f35b95a557048
parent0ddf3fb2c43d2e65aee5de158ed694ea11ef229d (diff)
parent36ac344e16e04e3e55e8fed7446095a6458c64e6 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf
Pablo Neira Ayuso says: ==================== Netfilter fixes for net The following patchset contains Netfilter fixes for your net tree, they are: 1) Missing netlink message sanity check in nfnetlink, patch from Mateusz Jurczyk. 2) We now have netfilter per-netns hooks, so let's kill global hook infrastructure, this infrastructure is known to be racy with netns. We don't care about out of tree modules. Patch from Florian Westphal. 3) find_appropriate_src() is buggy when colissions happens after the conversion of the nat bysource to rhashtable. Also from Florian. 4) Remove forward chain in nf_tables arp family, it's useless and it is causing quite a bit of confusion, from Florian Westphal. 5) nf_ct_remove_expect() is called with the wrong parameter, causing kernel oops, patch from Florian Westphal. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--include/linux/netfilter.h9
-rw-r--r--net/ipv4/netfilter/nf_tables_arp.c3
-rw-r--r--net/netfilter/core.c143
-rw-r--r--net/netfilter/nf_conntrack_expect.c2
-rw-r--r--net/netfilter/nf_nat_core.c17
-rw-r--r--net/netfilter/nfnetlink.c6
6 files changed, 14 insertions, 166 deletions
diff --git a/include/linux/netfilter.h b/include/linux/netfilter.h
index a4b97be30b28..22f081065d49 100644
--- a/include/linux/netfilter.h
+++ b/include/linux/netfilter.h
@@ -61,8 +61,6 @@ typedef unsigned int nf_hookfn(void *priv,
61 struct sk_buff *skb, 61 struct sk_buff *skb,
62 const struct nf_hook_state *state); 62 const struct nf_hook_state *state);
63struct nf_hook_ops { 63struct nf_hook_ops {
64 struct list_head list;
65
66 /* User fills in from here down. */ 64 /* User fills in from here down. */
67 nf_hookfn *hook; 65 nf_hookfn *hook;
68 struct net_device *dev; 66 struct net_device *dev;
@@ -160,13 +158,6 @@ int nf_register_net_hooks(struct net *net, const struct nf_hook_ops *reg,
160void nf_unregister_net_hooks(struct net *net, const struct nf_hook_ops *reg, 158void nf_unregister_net_hooks(struct net *net, const struct nf_hook_ops *reg,
161 unsigned int n); 159 unsigned int n);
162 160
163int nf_register_hook(struct nf_hook_ops *reg);
164void nf_unregister_hook(struct nf_hook_ops *reg);
165int nf_register_hooks(struct nf_hook_ops *reg, unsigned int n);
166void nf_unregister_hooks(struct nf_hook_ops *reg, unsigned int n);
167int _nf_register_hooks(struct nf_hook_ops *reg, unsigned int n);
168void _nf_unregister_hooks(struct nf_hook_ops *reg, unsigned int n);
169
170/* Functions to register get/setsockopt ranges (non-inclusive). You 161/* Functions to register get/setsockopt ranges (non-inclusive). You
171 need to check permissions yourself! */ 162 need to check permissions yourself! */
172int nf_register_sockopt(struct nf_sockopt_ops *reg); 163int nf_register_sockopt(struct nf_sockopt_ops *reg);
diff --git a/net/ipv4/netfilter/nf_tables_arp.c b/net/ipv4/netfilter/nf_tables_arp.c
index 805c8ddfe860..4bbc273b45e8 100644
--- a/net/ipv4/netfilter/nf_tables_arp.c
+++ b/net/ipv4/netfilter/nf_tables_arp.c
@@ -72,8 +72,7 @@ static const struct nf_chain_type filter_arp = {
72 .family = NFPROTO_ARP, 72 .family = NFPROTO_ARP,
73 .owner = THIS_MODULE, 73 .owner = THIS_MODULE,
74 .hook_mask = (1 << NF_ARP_IN) | 74 .hook_mask = (1 << NF_ARP_IN) |
75 (1 << NF_ARP_OUT) | 75 (1 << NF_ARP_OUT),
76 (1 << NF_ARP_FORWARD),
77}; 76};
78 77
79static int __init nf_tables_arp_init(void) 78static int __init nf_tables_arp_init(void)
diff --git a/net/netfilter/core.c b/net/netfilter/core.c
index 552d606e57ca..368610dbc3c0 100644
--- a/net/netfilter/core.c
+++ b/net/netfilter/core.c
@@ -227,114 +227,6 @@ void nf_unregister_net_hooks(struct net *net, const struct nf_hook_ops *reg,
227} 227}
228EXPORT_SYMBOL(nf_unregister_net_hooks); 228EXPORT_SYMBOL(nf_unregister_net_hooks);
229 229
230static LIST_HEAD(nf_hook_list);
231
232static int _nf_register_hook(struct nf_hook_ops *reg)
233{
234 struct net *net, *last;
235 int ret;
236
237 for_each_net(net) {
238 ret = nf_register_net_hook(net, reg);
239 if (ret && ret != -ENOENT)
240 goto rollback;
241 }
242 list_add_tail(&reg->list, &nf_hook_list);
243
244 return 0;
245rollback:
246 last = net;
247 for_each_net(net) {
248 if (net == last)
249 break;
250 nf_unregister_net_hook(net, reg);
251 }
252 return ret;
253}
254
255int nf_register_hook(struct nf_hook_ops *reg)
256{
257 int ret;
258
259 rtnl_lock();
260 ret = _nf_register_hook(reg);
261 rtnl_unlock();
262
263 return ret;
264}
265EXPORT_SYMBOL(nf_register_hook);
266
267static void _nf_unregister_hook(struct nf_hook_ops *reg)
268{
269 struct net *net;
270
271 list_del(&reg->list);
272 for_each_net(net)
273 nf_unregister_net_hook(net, reg);
274}
275
276void nf_unregister_hook(struct nf_hook_ops *reg)
277{
278 rtnl_lock();
279 _nf_unregister_hook(reg);
280 rtnl_unlock();
281}
282EXPORT_SYMBOL(nf_unregister_hook);
283
284int nf_register_hooks(struct nf_hook_ops *reg, unsigned int n)
285{
286 unsigned int i;
287 int err = 0;
288
289 for (i = 0; i < n; i++) {
290 err = nf_register_hook(&reg[i]);
291 if (err)
292 goto err;
293 }
294 return err;
295
296err:
297 if (i > 0)
298 nf_unregister_hooks(reg, i);
299 return err;
300}
301EXPORT_SYMBOL(nf_register_hooks);
302
303/* Caller MUST take rtnl_lock() */
304int _nf_register_hooks(struct nf_hook_ops *reg, unsigned int n)
305{
306 unsigned int i;
307 int err = 0;
308
309 for (i = 0; i < n; i++) {
310 err = _nf_register_hook(&reg[i]);
311 if (err)
312 goto err;
313 }
314 return err;
315
316err:
317 if (i > 0)
318 _nf_unregister_hooks(reg, i);
319 return err;
320}
321EXPORT_SYMBOL(_nf_register_hooks);
322
323void nf_unregister_hooks(struct nf_hook_ops *reg, unsigned int n)
324{
325 while (n-- > 0)
326 nf_unregister_hook(&reg[n]);
327}
328EXPORT_SYMBOL(nf_unregister_hooks);
329
330/* Caller MUST take rtnl_lock */
331void _nf_unregister_hooks(struct nf_hook_ops *reg, unsigned int n)
332{
333 while (n-- > 0)
334 _nf_unregister_hook(&reg[n]);
335}
336EXPORT_SYMBOL(_nf_unregister_hooks);
337
338/* Returns 1 if okfn() needs to be executed by the caller, 230/* Returns 1 if okfn() needs to be executed by the caller,
339 * -EPERM for NF_DROP, 0 otherwise. Caller must hold rcu_read_lock. */ 231 * -EPERM for NF_DROP, 0 otherwise. Caller must hold rcu_read_lock. */
340int nf_hook_slow(struct sk_buff *skb, struct nf_hook_state *state, 232int nf_hook_slow(struct sk_buff *skb, struct nf_hook_state *state,
@@ -450,37 +342,6 @@ void (*nf_nat_decode_session_hook)(struct sk_buff *, struct flowi *);
450EXPORT_SYMBOL(nf_nat_decode_session_hook); 342EXPORT_SYMBOL(nf_nat_decode_session_hook);
451#endif 343#endif
452 344
453static int nf_register_hook_list(struct net *net)
454{
455 struct nf_hook_ops *elem;
456 int ret;
457
458 rtnl_lock();
459 list_for_each_entry(elem, &nf_hook_list, list) {
460 ret = nf_register_net_hook(net, elem);
461 if (ret && ret != -ENOENT)
462 goto out_undo;
463 }
464 rtnl_unlock();
465 return 0;
466
467out_undo:
468 list_for_each_entry_continue_reverse(elem, &nf_hook_list, list)
469 nf_unregister_net_hook(net, elem);
470 rtnl_unlock();
471 return ret;
472}
473
474static void nf_unregister_hook_list(struct net *net)
475{
476 struct nf_hook_ops *elem;
477
478 rtnl_lock();
479 list_for_each_entry(elem, &nf_hook_list, list)
480 nf_unregister_net_hook(net, elem);
481 rtnl_unlock();
482}
483
484static int __net_init netfilter_net_init(struct net *net) 345static int __net_init netfilter_net_init(struct net *net)
485{ 346{
486 int i, h, ret; 347 int i, h, ret;
@@ -500,16 +361,12 @@ static int __net_init netfilter_net_init(struct net *net)
500 return -ENOMEM; 361 return -ENOMEM;