diff options
author | Florian Westphal <fw@strlen.de> | 2018-12-28 01:24:46 +0100 |
---|---|---|
committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2018-12-29 02:45:20 +0100 |
commit | df4a902509766897f7371fdfa4c3bf8bc321b55d (patch) | |
tree | d1c36526cc52fceae52d46a0eb5b5a3c7ffbf2de /net/netfilter/nft_connlimit.c | |
parent | netfilter: nf_conncount: restart search when nodes have been erased (diff) | |
download | linux-dev-df4a902509766897f7371fdfa4c3bf8bc321b55d.tar.xz linux-dev-df4a902509766897f7371fdfa4c3bf8bc321b55d.zip |
netfilter: nf_conncount: merge lookup and add functions
'lookup' is always followed by 'add'.
Merge both and make the list-walk part of nf_conncount_add().
This also avoids one unneeded unlock/re-lock pair.
Extra care needs to be taken in count_tree, as we only hold rcu
read lock, i.e. we can only insert to an existing tree node after
acquiring its lock and making sure it has a nonzero count.
As a zero count should be rare, just fall back to insert_tree()
(which acquires tree lock).
This issue and its solution were pointed out by Shawn Bohrer
during patch review.
Reviewed-by: Shawn Bohrer <sbohrer@cloudflare.com>
Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'net/netfilter/nft_connlimit.c')
-rw-r--r-- | net/netfilter/nft_connlimit.c | 14 |
1 files changed, 3 insertions, 11 deletions
diff --git a/net/netfilter/nft_connlimit.c b/net/netfilter/nft_connlimit.c index b90d96ba4a12..af1497ab9464 100644 --- a/net/netfilter/nft_connlimit.c +++ b/net/netfilter/nft_connlimit.c @@ -30,7 +30,6 @@ static inline void nft_connlimit_do_eval(struct nft_connlimit *priv, enum ip_conntrack_info ctinfo; const struct nf_conn *ct; unsigned int count; - bool addit; tuple_ptr = &tuple; @@ -44,19 +43,12 @@ static inline void nft_connlimit_do_eval(struct nft_connlimit *priv, return; } - nf_conncount_lookup(nft_net(pkt), &priv->list, tuple_ptr, zone, - &addit); - count = priv->list.count; - - if (!addit) - goto out; - - if (nf_conncount_add(&priv->list, tuple_ptr, zone) == NF_CONNCOUNT_ERR) { + if (nf_conncount_add(nft_net(pkt), &priv->list, tuple_ptr, zone)) { regs->verdict.code = NF_DROP; return; } - count++; -out: + + count = priv->list.count; if ((count > priv->limit) ^ priv->invert) { regs->verdict.code = NFT_BREAK; |