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 rather small patches but fixing several outstanding bugs in nf_conntrack and nf_tables, as well as minor problems with missing SYNPROXY header uapi installation: 1) Oneliner not to leak conntrack kmemcache on module removal, this problem was introduced in the previous merge window, patch from Florian Westphal. 2) Two fixes for insufficient ruleset loop validation, one due to incorrect flag check in nf_tables_bind_set() and another related to silly wrong generation mask logic from the walk path, from Liping Zhang. 3) Fix double-free of anonymous sets on error, this fix simplifies the code to let the abort path take care of releasing the set object, also from Liping Zhang. 4) The introduction of helper function for transactions broke the skip inactive rules logic from the nft_do_chain(), again from Liping Zhang. 5) Two patches to install uapi xt_SYNPROXY.h header and calm down kbuild robot due to missing #include <linux/types.h>. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
695ef16cd0
|
@ -167,6 +167,7 @@ struct nft_set_elem {
|
|||
|
||||
struct nft_set;
|
||||
struct nft_set_iter {
|
||||
u8 genmask;
|
||||
unsigned int count;
|
||||
unsigned int skip;
|
||||
int err;
|
||||
|
|
|
@ -33,6 +33,7 @@ header-y += xt_NFLOG.h
|
|||
header-y += xt_NFQUEUE.h
|
||||
header-y += xt_RATEEST.h
|
||||
header-y += xt_SECMARK.h
|
||||
header-y += xt_SYNPROXY.h
|
||||
header-y += xt_TCPMSS.h
|
||||
header-y += xt_TCPOPTSTRIP.h
|
||||
header-y += xt_TEE.h
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
#ifndef _XT_SYNPROXY_H
|
||||
#define _XT_SYNPROXY_H
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
#define XT_SYNPROXY_OPT_MSS 0x01
|
||||
#define XT_SYNPROXY_OPT_WSCALE 0x02
|
||||
#define XT_SYNPROXY_OPT_SACK_PERM 0x04
|
||||
|
|
|
@ -1544,6 +1544,8 @@ void nf_conntrack_cleanup_end(void)
|
|||
nf_conntrack_tstamp_fini();
|
||||
nf_conntrack_acct_fini();
|
||||
nf_conntrack_expect_fini();
|
||||
|
||||
kmem_cache_destroy(nf_conntrack_cachep);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -2946,24 +2946,20 @@ int nf_tables_bind_set(const struct nft_ctx *ctx, struct nft_set *set,
|
|||
* jumps are already validated for that chain.
|
||||
*/
|
||||
list_for_each_entry(i, &set->bindings, list) {
|
||||
if (binding->flags & NFT_SET_MAP &&
|
||||
if (i->flags & NFT_SET_MAP &&
|
||||
i->chain == binding->chain)
|
||||
goto bind;
|
||||
}
|
||||
|
||||
iter.genmask = nft_genmask_next(ctx->net);
|
||||
iter.skip = 0;
|
||||
iter.count = 0;
|
||||
iter.err = 0;
|
||||
iter.fn = nf_tables_bind_check_setelem;
|
||||
|
||||
set->ops->walk(ctx, set, &iter);
|
||||
if (iter.err < 0) {
|
||||
/* Destroy anonymous sets if binding fails */
|
||||
if (set->flags & NFT_SET_ANONYMOUS)
|
||||
nf_tables_set_destroy(ctx, set);
|
||||
|
||||
if (iter.err < 0)
|
||||
return iter.err;
|
||||
}
|
||||
}
|
||||
bind:
|
||||
binding->chain = ctx->chain;
|
||||
|
@ -3192,12 +3188,13 @@ static int nf_tables_dump_set(struct sk_buff *skb, struct netlink_callback *cb)
|
|||
if (nest == NULL)
|
||||
goto nla_put_failure;
|
||||
|
||||
args.cb = cb;
|
||||
args.skb = skb;
|
||||
args.iter.skip = cb->args[0];
|
||||
args.iter.count = 0;
|
||||
args.iter.err = 0;
|
||||
args.iter.fn = nf_tables_dump_setelem;
|
||||
args.cb = cb;
|
||||
args.skb = skb;
|
||||
args.iter.genmask = nft_genmask_cur(ctx.net);
|
||||
args.iter.skip = cb->args[0];
|
||||
args.iter.count = 0;
|
||||
args.iter.err = 0;
|
||||
args.iter.fn = nf_tables_dump_setelem;
|
||||
set->ops->walk(&ctx, set, &args.iter);
|
||||
|
||||
nla_nest_end(skb, nest);
|
||||
|
@ -4284,6 +4281,7 @@ static int nf_tables_check_loops(const struct nft_ctx *ctx,
|
|||
binding->chain != chain)
|
||||
continue;
|
||||
|
||||
iter.genmask = nft_genmask_next(ctx->net);
|
||||
iter.skip = 0;
|
||||
iter.count = 0;
|
||||
iter.err = 0;
|
||||
|
|
|
@ -143,7 +143,7 @@ nft_do_chain(struct nft_pktinfo *pkt, void *priv)
|
|||
list_for_each_entry_continue_rcu(rule, &chain->rules, list) {
|
||||
|
||||
/* This rule is not active, skip. */
|
||||
if (unlikely(rule->genmask & (1 << gencursor)))
|
||||
if (unlikely(rule->genmask & gencursor))
|
||||
continue;
|
||||
|
||||
rulenum++;
|
||||
|
|
|
@ -189,7 +189,6 @@ static void nft_hash_walk(const struct nft_ctx *ctx, const struct nft_set *set,
|
|||
struct nft_hash_elem *he;
|
||||
struct rhashtable_iter hti;
|
||||
struct nft_set_elem elem;
|
||||
u8 genmask = nft_genmask_cur(read_pnet(&set->pnet));
|
||||
int err;
|
||||
|
||||
err = rhashtable_walk_init(&priv->ht, &hti, GFP_KERNEL);
|
||||
|
@ -218,7 +217,7 @@ static void nft_hash_walk(const struct nft_ctx *ctx, const struct nft_set *set,
|
|||
goto cont;
|
||||
if (nft_set_elem_expired(&he->ext))
|
||||
goto cont;
|
||||
if (!nft_set_elem_active(&he->ext, genmask))
|
||||
if (!nft_set_elem_active(&he->ext, iter->genmask))
|
||||
goto cont;
|
||||
|
||||
elem.priv = he;
|
||||
|
|
|
@ -211,7 +211,6 @@ static void nft_rbtree_walk(const struct nft_ctx *ctx,
|
|||
struct nft_rbtree_elem *rbe;
|
||||
struct nft_set_elem elem;
|
||||
struct rb_node *node;
|
||||
u8 genmask = nft_genmask_cur(read_pnet(&set->pnet));
|
||||
|
||||
spin_lock_bh(&nft_rbtree_lock);
|
||||
for (node = rb_first(&priv->root); node != NULL; node = rb_next(node)) {
|
||||
|
@ -219,7 +218,7 @@ static void nft_rbtree_walk(const struct nft_ctx *ctx,
|
|||
|
||||
if (iter->count < iter->skip)
|
||||
goto cont;
|
||||
if (!nft_set_elem_active(&rbe->ext, genmask))
|
||||
if (!nft_set_elem_active(&rbe->ext, iter->genmask))
|
||||
goto cont;
|
||||
|
||||
elem.priv = rbe;
|
||||
|
|
Loading…
Reference in New Issue