aboutsummaryrefslogtreecommitdiffstats
path: root/net/netfilter/nft_connlimit.c
diff options
context:
space:
mode:
authorFlorian Westphal <fw@strlen.de>2018-12-28 01:24:46 +0100
committerPablo Neira Ayuso <pablo@netfilter.org>2018-12-29 02:45:20 +0100
commitdf4a902509766897f7371fdfa4c3bf8bc321b55d (patch)
treed1c36526cc52fceae52d46a0eb5b5a3c7ffbf2de /net/netfilter/nft_connlimit.c
parentnetfilter: nf_conncount: restart search when nodes have been erased (diff)
downloadlinux-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.c14
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;