aboutsummaryrefslogtreecommitdiffstats
path: root/net/netfilter
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2014-11-21 22:28:24 -0500
committerDavid S. Miller <davem@davemloft.net>2014-11-21 22:28:24 -0500
commit1459143386c5d868c87903b8d433a52cffcf3e66 (patch)
treee7878a550aaf6a3af5e84f4258bbcc3bbdd20fef /net/netfilter
parent53b15ef3c2a6bac8e3d9bb58c5689d731ed9593b (diff)
parent8a84e01e147f44111988f9d8ccd2eaa30215a0f2 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Conflicts: drivers/net/ieee802154/fakehard.c A bug fix went into 'net' for ieee802154/fakehard.c, which is removed in 'net-next'. Add build fix into the merge from Stephen Rothwell in openvswitch, the logging macros take a new initial 'log' argument, a new call was added in 'net' so when we merge that in here we have to explicitly add the new 'log' arg to it else the build fails. Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/netfilter')
-rw-r--r--net/netfilter/ipset/ip_set_core.c6
-rw-r--r--net/netfilter/ipvs/ip_vs_xmit.c2
-rw-r--r--net/netfilter/nf_conntrack_core.c14
-rw-r--r--net/netfilter/nf_tables_api.c24
-rw-r--r--net/netfilter/nfnetlink.c12
-rw-r--r--net/netfilter/nft_compat.c40
6 files changed, 41 insertions, 57 deletions
diff --git a/net/netfilter/ipset/ip_set_core.c b/net/netfilter/ipset/ip_set_core.c
index 86f9d76b1464..d259da3ce67a 100644
--- a/net/netfilter/ipset/ip_set_core.c
+++ b/net/netfilter/ipset/ip_set_core.c
@@ -1863,6 +1863,12 @@ ip_set_sockfn_get(struct sock *sk, int optval, void __user *user, int *len)
1863 if (*op < IP_SET_OP_VERSION) { 1863 if (*op < IP_SET_OP_VERSION) {
1864 /* Check the version at the beginning of operations */ 1864 /* Check the version at the beginning of operations */
1865 struct ip_set_req_version *req_version = data; 1865 struct ip_set_req_version *req_version = data;
1866
1867 if (*len < sizeof(struct ip_set_req_version)) {
1868 ret = -EINVAL;
1869 goto done;
1870 }
1871
1866 if (req_version->version != IPSET_PROTOCOL) { 1872 if (req_version->version != IPSET_PROTOCOL) {
1867 ret = -EPROTO; 1873 ret = -EPROTO;
1868 goto done; 1874 goto done;
diff --git a/net/netfilter/ipvs/ip_vs_xmit.c b/net/netfilter/ipvs/ip_vs_xmit.c
index 437a3663ad03..bd90bf8107da 100644
--- a/net/netfilter/ipvs/ip_vs_xmit.c
+++ b/net/netfilter/ipvs/ip_vs_xmit.c
@@ -846,6 +846,8 @@ ip_vs_prepare_tunneled_skb(struct sk_buff *skb, int skb_af,
846 new_skb = skb_realloc_headroom(skb, max_headroom); 846 new_skb = skb_realloc_headroom(skb, max_headroom);
847 if (!new_skb) 847 if (!new_skb)
848 goto error; 848 goto error;
849 if (skb->sk)
850 skb_set_owner_w(new_skb, skb->sk);
849 consume_skb(skb); 851 consume_skb(skb);
850 skb = new_skb; 852 skb = new_skb;
851 } 853 }
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index 5016a6929085..2c699757bccf 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -611,12 +611,16 @@ __nf_conntrack_confirm(struct sk_buff *skb)
611 */ 611 */
612 NF_CT_ASSERT(!nf_ct_is_confirmed(ct)); 612 NF_CT_ASSERT(!nf_ct_is_confirmed(ct));
613 pr_debug("Confirming conntrack %p\n", ct); 613 pr_debug("Confirming conntrack %p\n", ct);
614 /* We have to check the DYING flag inside the lock to prevent 614
615 a race against nf_ct_get_next_corpse() possibly called from 615 /* We have to check the DYING flag after unlink to prevent
616 user context, else we insert an already 'dead' hash, blocking 616 * a race against nf_ct_get_next_corpse() possibly called from
617 further use of that particular connection -JM */ 617 * user context, else we insert an already 'dead' hash, blocking
618 * further use of that particular connection -JM.
619 */
620 nf_ct_del_from_dying_or_unconfirmed_list(ct);
618 621
619 if (unlikely(nf_ct_is_dying(ct))) { 622 if (unlikely(nf_ct_is_dying(ct))) {
623 nf_ct_add_to_dying_list(ct);
620 nf_conntrack_double_unlock(hash, reply_hash); 624 nf_conntrack_double_unlock(hash, reply_hash);
621 local_bh_enable(); 625 local_bh_enable();
622 return NF_ACCEPT; 626 return NF_ACCEPT;
@@ -636,8 +640,6 @@ __nf_conntrack_confirm(struct sk_buff *skb)
636 zone == nf_ct_zone(nf_ct_tuplehash_to_ctrack(h))) 640 zone == nf_ct_zone(nf_ct_tuplehash_to_ctrack(h)))
637 goto out; 641 goto out;
638 642
639 nf_ct_del_from_dying_or_unconfirmed_list(ct);
640
641 /* Timer relative to confirmation time, not original 643 /* Timer relative to confirmation time, not original
642 setting time, otherwise we'd get timer wrap in 644 setting time, otherwise we'd get timer wrap in
643 weird delay cases. */ 645 weird delay cases. */
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index 11ab4b078f3b..66e8425dbfe7 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -3484,13 +3484,8 @@ static void nft_chain_commit_update(struct nft_trans *trans)
3484 } 3484 }
3485} 3485}
3486 3486
3487/* Schedule objects for release via rcu to make sure no packets are accesing 3487static void nf_tables_commit_release(struct nft_trans *trans)
3488 * removed rules.
3489 */
3490static void nf_tables_commit_release_rcu(struct rcu_head *rt)
3491{ 3488{
3492 struct nft_trans *trans = container_of(rt, struct nft_trans, rcu_head);
3493
3494 switch (trans->msg_type) { 3489 switch (trans->msg_type) {
3495 case NFT_MSG_DELTABLE: 3490 case NFT_MSG_DELTABLE:
3496 nf_tables_table_destroy(&trans->ctx); 3491 nf_tables_table_destroy(&trans->ctx);
@@ -3612,10 +3607,11 @@ static int nf_tables_commit(struct sk_buff *skb)
3612 } 3607 }
3613 } 3608 }
3614 3609
3610 synchronize_rcu();
3611
3615 list_for_each_entry_safe(trans, next, &net->nft.commit_list, list) { 3612 list_for_each_entry_safe(trans, next, &net->nft.commit_list, list) {
3616 list_del(&trans->list); 3613 list_del(&trans->list);
3617 trans->ctx.nla = NULL; 3614 nf_tables_commit_release(trans);
3618 call_rcu(&trans->rcu_head, nf_tables_commit_release_rcu);
3619 } 3615 }
3620 3616
3621 nf_tables_gen_notify(net, skb, NFT_MSG_NEWGEN); 3617 nf_tables_gen_notify(net, skb, NFT_MSG_NEWGEN);
@@ -3623,13 +3619,8 @@ static int nf_tables_commit(struct sk_buff *skb)
3623 return 0; 3619 return 0;
3624} 3620}
3625 3621
3626/* Schedule objects for release via rcu to make sure no packets are accesing 3622static void nf_tables_abort_release(struct nft_trans *trans)
3627 * aborted rules.
3628 */
3629static void nf_tables_abort_release_rcu(struct rcu_head *rt)
3630{ 3623{
3631 struct nft_trans *trans = container_of(rt, struct nft_trans, rcu_head);
3632
3633 switch (trans->msg_type) { 3624 switch (trans->msg_type) {
3634 case NFT_MSG_NEWTABLE: 3625 case NFT_MSG_NEWTABLE:
3635 nf_tables_table_destroy(&trans->ctx); 3626 nf_tables_table_destroy(&trans->ctx);
@@ -3725,11 +3716,12 @@ static int nf_tables_abort(struct sk_buff *skb)
3725 } 3716 }
3726 } 3717 }
3727 3718
3719 synchronize_rcu();
3720
3728 list_for_each_entry_safe_reverse(trans, next, 3721 list_for_each_entry_safe_reverse(trans, next,
3729 &net->nft.commit_list, list) { 3722 &net->nft.commit_list, list) {
3730 list_del(&trans->list); 3723 list_del(&trans->list);
3731 trans->ctx.nla = NULL; 3724 nf_tables_abort_release(trans);
3732 call_rcu(&trans->rcu_head, nf_tables_abort_release_rcu);
3733 } 3725 }
3734 3726
3735 return 0; 3727 return 0;
diff --git a/net/netfilter/nfnetlink.c b/net/netfilter/nfnetlink.c
index 6c5a915cfa75..13c2e17bbe27 100644
--- a/net/netfilter/nfnetlink.c
+++ b/net/netfilter/nfnetlink.c
@@ -47,6 +47,8 @@ static const int nfnl_group2type[NFNLGRP_MAX+1] = {
47 [NFNLGRP_CONNTRACK_EXP_NEW] = NFNL_SUBSYS_CTNETLINK_EXP, 47 [NFNLGRP_CONNTRACK_EXP_NEW] = NFNL_SUBSYS_CTNETLINK_EXP,
48 [NFNLGRP_CONNTRACK_EXP_UPDATE] = NFNL_SUBSYS_CTNETLINK_EXP, 48 [NFNLGRP_CONNTRACK_EXP_UPDATE] = NFNL_SUBSYS_CTNETLINK_EXP,
49 [NFNLGRP_CONNTRACK_EXP_DESTROY] = NFNL_SUBSYS_CTNETLINK_EXP, 49 [NFNLGRP_CONNTRACK_EXP_DESTROY] = NFNL_SUBSYS_CTNETLINK_EXP,
50 [NFNLGRP_NFTABLES] = NFNL_SUBSYS_NFTABLES,
51 [NFNLGRP_ACCT_QUOTA] = NFNL_SUBSYS_ACCT,
50}; 52};
51 53
52void nfnl_lock(__u8 subsys_id) 54void nfnl_lock(__u8 subsys_id)
@@ -464,7 +466,12 @@ static void nfnetlink_rcv(struct sk_buff *skb)
464static int nfnetlink_bind(int group) 466static int nfnetlink_bind(int group)
465{ 467{
466 const struct nfnetlink_subsystem *ss; 468 const struct nfnetlink_subsystem *ss;
467 int type = nfnl_group2type[group]; 469 int type;
470
471 if (group <= NFNLGRP_NONE || group > NFNLGRP_MAX)
472 return -EINVAL;
473
474 type = nfnl_group2type[group];
468 475
469 rcu_read_lock(); 476 rcu_read_lock();
470 ss = nfnetlink_get_subsys(type); 477 ss = nfnetlink_get_subsys(type);
@@ -514,6 +521,9 @@ static int __init nfnetlink_init(void)
514{ 521{
515 int i; 522 int i;
516 523
524 for (i = NFNLGRP_NONE + 1; i <= NFNLGRP_MAX; i++)
525 BUG_ON(nfnl_group2type[i] == NFNL_SUBSYS_NONE);
526
517 for (i=0; i<NFNL_SUBSYS_COUNT; i++) 527 for (i=0; i<NFNL_SUBSYS_COUNT; i++)
518 mutex_init(&table[i].mutex); 528 mutex_init(&table[i].mutex);
519 529
diff --git a/net/netfilter/nft_compat.c b/net/netfilter/nft_compat.c
index 9d6d6f60a80f..265e190f2218 100644
--- a/net/netfilter/nft_compat.c
+++ b/net/netfilter/nft_compat.c
@@ -21,45 +21,17 @@
21#include <linux/netfilter_ipv6/ip6_tables.h> 21#include <linux/netfilter_ipv6/ip6_tables.h>
22#include <net/netfilter/nf_tables.h> 22#include <net/netfilter/nf_tables.h>
23 23
24static const struct {
25 const char *name;
26 u8 type;
27} table_to_chaintype[] = {
28 { "filter", NFT_CHAIN_T_DEFAULT },
29 { "raw", NFT_CHAIN_T_DEFAULT },
30 { "security", NFT_CHAIN_T_DEFAULT },
31 { "mangle", NFT_CHAIN_T_ROUTE },
32 { "nat", NFT_CHAIN_T_NAT },
33 { },
34};
35
36static int nft_compat_table_to_chaintype(const char *table)
37{
38 int i;
39
40 for (i = 0; table_to_chaintype[i].name != NULL; i++) {
41 if (strcmp(table_to_chaintype[i].name, table) == 0)
42 return table_to_chaintype[i].type;
43 }
44
45 return -1;
46}
47
48static int nft_compat_chain_validate_dependency(const char *tablename, 24static int nft_compat_chain_validate_dependency(const char *tablename,
49 const struct nft_chain *chain) 25 const struct nft_chain *chain)
50{ 26{
51 enum nft_chain_type type;
52 const struct nft_base_chain *basechain; 27 const struct nft_base_chain *basechain;
53 28
54 if (!tablename || !(chain->flags & NFT_BASE_CHAIN)) 29 if (!tablename || !(chain->flags & NFT_BASE_CHAIN))
55 return 0; 30 return 0;
56 31
57 type = nft_compat_table_to_chaintype(tablename);
58 if (type < 0)
59 return -EINVAL;
60
61 basechain = nft_base_chain(chain); 32 basechain = nft_base_chain(chain);
62 if (basechain->type->type != type) 33 if (strcmp(tablename, "nat") == 0 &&
34 basechain->type->type != NFT_CHAIN_T_NAT)
63 return -EINVAL; 35 return -EINVAL;
64 36
65 return 0; 37 return 0;
@@ -117,7 +89,7 @@ nft_target_set_tgchk_param(struct xt_tgchk_param *par,
117 struct xt_target *target, void *info, 89 struct xt_target *target, void *info,
118 union nft_entry *entry, u8 proto, bool inv) 90 union nft_entry *entry, u8 proto, bool inv)
119{ 91{
120 par->net = &init_net; 92 par->net = ctx->net;
121 par->table = ctx->table->name; 93 par->table = ctx->table->name;
122 switch (ctx->afi->family) { 94 switch (ctx->afi->family) {
123 case AF_INET: 95 case AF_INET:
@@ -324,7 +296,7 @@ nft_match_set_mtchk_param(struct xt_mtchk_param *par, const struct nft_ctx *ctx,
324 struct xt_match *match, void *info, 296 struct xt_match *match, void *info,
325 union nft_entry *entry, u8 proto, bool inv) 297 union nft_entry *entry, u8 proto, bool inv)
326{ 298{
327 par->net = &init_net; 299 par->net = ctx->net;
328 par->table = ctx->table->name; 300 par->table = ctx->table->name;
329 switch (ctx->afi->family) { 301 switch (ctx->afi->family) {
330 case AF_INET: 302 case AF_INET:
@@ -374,7 +346,7 @@ nft_match_init(const struct nft_ctx *ctx, const struct nft_expr *expr,
374 union nft_entry e = {}; 346 union nft_entry e = {};
375 int ret; 347 int ret;
376 348
377 ret = nft_compat_chain_validate_dependency(match->name, ctx->chain); 349 ret = nft_compat_chain_validate_dependency(match->table, ctx->chain);
378 if (ret < 0) 350 if (ret < 0)
379 goto err; 351 goto err;
380 352
@@ -448,7 +420,7 @@ static int nft_match_validate(const struct nft_ctx *ctx,
448 if (!(hook_mask & match->hooks)) 420 if (!(hook_mask & match->hooks))
449 return -EINVAL; 421 return -EINVAL;
450 422
451 ret = nft_compat_chain_validate_dependency(match->name, 423 ret = nft_compat_chain_validate_dependency(match->table,
452 ctx->chain); 424 ctx->chain);
453 if (ret < 0) 425 if (ret < 0)
454 return ret; 426 return ret;