From: Pablo Neira Ayuso <pablo@netfilter.org>
To: netfilter-devel@vger.kernel.org
Cc: davem@davemloft.net, netdev@vger.kernel.org
Subject: [PATCH 19/38] netfilter: nf_conncount: Early exit in nf_conncount_lookup() and cleanup
Date: Fri, 20 Jul 2018 15:08:47 +0200 [thread overview]
Message-ID: <20180720130906.27687-20-pablo@netfilter.org> (raw)
In-Reply-To: <20180720130906.27687-1-pablo@netfilter.org>
From: Yi-Hung Wei <yihung.wei@gmail.com>
This patch is originally from Florian Westphal.
This patch does the following three tasks.
It applies the same early exit technique for nf_conncount_lookup().
Since now we keep the number of connections in 'struct nf_conncount_list',
we no longer need to return the count in nf_conncount_lookup().
Moreover, we expose the garbage collection function nf_conncount_gc_list()
for nft_connlimit.
Signed-off-by: Yi-Hung Wei <yihung.wei@gmail.com>
Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
include/net/netfilter/nf_conntrack_count.h | 11 +++++----
net/netfilter/nf_conncount.c | 38 +++++++++++++++++-------------
net/netfilter/nft_connlimit.c | 9 +++----
3 files changed, 33 insertions(+), 25 deletions(-)
diff --git a/include/net/netfilter/nf_conntrack_count.h b/include/net/netfilter/nf_conntrack_count.h
index e4884e0e4f69..dbec17f674b7 100644
--- a/include/net/netfilter/nf_conntrack_count.h
+++ b/include/net/netfilter/nf_conntrack_count.h
@@ -21,10 +21,10 @@ unsigned int nf_conncount_count(struct net *net,
const struct nf_conntrack_tuple *tuple,
const struct nf_conntrack_zone *zone);
-unsigned int nf_conncount_lookup(struct net *net, struct nf_conncount_list *list,
- const struct nf_conntrack_tuple *tuple,
- const struct nf_conntrack_zone *zone,
- bool *addit);
+void nf_conncount_lookup(struct net *net, struct nf_conncount_list *list,
+ const struct nf_conntrack_tuple *tuple,
+ const struct nf_conntrack_zone *zone,
+ bool *addit);
void nf_conncount_list_init(struct nf_conncount_list *list);
@@ -32,6 +32,9 @@ bool nf_conncount_add(struct nf_conncount_list *list,
const struct nf_conntrack_tuple *tuple,
const struct nf_conntrack_zone *zone);
+void nf_conncount_gc_list(struct net *net,
+ struct nf_conncount_list *list);
+
void nf_conncount_cache_free(struct nf_conncount_list *list);
#endif
diff --git a/net/netfilter/nf_conncount.c b/net/netfilter/nf_conncount.c
index 81b060adefef..7dfd9d5e6a3e 100644
--- a/net/netfilter/nf_conncount.c
+++ b/net/netfilter/nf_conncount.c
@@ -144,26 +144,29 @@ find_or_evict(struct net *net, struct nf_conncount_list *list,
return ERR_PTR(-EAGAIN);
}
-unsigned int nf_conncount_lookup(struct net *net,
- struct nf_conncount_list *list,
- const struct nf_conntrack_tuple *tuple,
- const struct nf_conntrack_zone *zone,
- bool *addit)
+void nf_conncount_lookup(struct net *net,
+ struct nf_conncount_list *list,
+ const struct nf_conntrack_tuple *tuple,
+ const struct nf_conntrack_zone *zone,
+ bool *addit)
{
const struct nf_conntrack_tuple_hash *found;
struct nf_conncount_tuple *conn, *conn_n;
struct nf_conn *found_ct;
- unsigned int length = 0;
+ unsigned int collect = 0;
+ /* best effort only */
*addit = tuple ? true : false;
/* check the saved connections */
list_for_each_entry_safe(conn, conn_n, &list->head, node) {
+ if (collect > CONNCOUNT_GC_MAX_NODES)
+ break;
+
found = find_or_evict(net, list, conn);
if (IS_ERR(found)) {
/* Not found, but might be about to be confirmed */
if (PTR_ERR(found) == -EAGAIN) {
- length++;
if (!tuple)
continue;
@@ -171,8 +174,8 @@ unsigned int nf_conncount_lookup(struct net *net,
nf_ct_zone_id(&conn->zone, conn->zone.dir) ==
nf_ct_zone_id(zone, zone->dir))
*addit = false;
- }
-
+ } else if (PTR_ERR(found) == -ENOENT)
+ collect++;
continue;
}
@@ -181,9 +184,10 @@ unsigned int nf_conncount_lookup(struct net *net,
if (tuple && nf_ct_tuple_equal(&conn->tuple, tuple) &&
nf_ct_zone_equal(found_ct, zone, zone->dir)) {
/*
- * Just to be sure we have it only once in the list.
* We should not see tuples twice unless someone hooks
* this into a table without "-p tcp --syn".
+ *
+ * Attempt to avoid a re-add in this case.
*/
*addit = false;
} else if (already_closed(found_ct)) {
@@ -193,14 +197,12 @@ unsigned int nf_conncount_lookup(struct net *net,
*/
nf_ct_put(found_ct);
conn_free(list, conn);
+ collect++;
continue;
}
nf_ct_put(found_ct);
- length++;
}
-
- return length;
}
EXPORT_SYMBOL_GPL(nf_conncount_lookup);
@@ -211,8 +213,8 @@ void nf_conncount_list_init(struct nf_conncount_list *list)
}
EXPORT_SYMBOL_GPL(nf_conncount_list_init);
-static void nf_conncount_gc_list(struct net *net,
- struct nf_conncount_list *list)
+void nf_conncount_gc_list(struct net *net,
+ struct nf_conncount_list *list)
{
const struct nf_conntrack_tuple_hash *found;
struct nf_conncount_tuple *conn, *conn_n;
@@ -244,6 +246,7 @@ static void nf_conncount_gc_list(struct net *net,
return;
}
}
+EXPORT_SYMBOL_GPL(nf_conncount_gc_list);
static void tree_nodes_free(struct rb_root *root,
struct nf_conncount_rb *gc_nodes[],
@@ -291,8 +294,9 @@ count_tree(struct net *net, struct rb_root *root,
/* same source network -> be counted! */
unsigned int count;
- count = nf_conncount_lookup(net, &rbconn->list, tuple,
- zone, &addit);
+ nf_conncount_lookup(net, &rbconn->list, tuple, zone,
+ &addit);
+ count = rbconn->list.count;
tree_nodes_free(root, gc_nodes, gc_count);
if (!addit)
diff --git a/net/netfilter/nft_connlimit.c b/net/netfilter/nft_connlimit.c
index 4f0491a36a1d..37c52ae06741 100644
--- a/net/netfilter/nft_connlimit.c
+++ b/net/netfilter/nft_connlimit.c
@@ -46,8 +46,9 @@ static inline void nft_connlimit_do_eval(struct nft_connlimit *priv,
}
spin_lock_bh(&priv->lock);
- count = nf_conncount_lookup(nft_net(pkt), &priv->list, tuple_ptr, zone,
- &addit);
+ nf_conncount_lookup(nft_net(pkt), &priv->list, tuple_ptr, zone,
+ &addit);
+ count = priv->list.count;
if (!addit)
goto out;
@@ -231,10 +232,10 @@ static void nft_connlimit_destroy_clone(const struct nft_ctx *ctx,
static bool nft_connlimit_gc(struct net *net, const struct nft_expr *expr)
{
struct nft_connlimit *priv = nft_expr_priv(expr);
- bool addit, ret;
+ bool ret;
spin_lock_bh(&priv->lock);
- nf_conncount_lookup(net, &priv->list, NULL, &nf_ct_zone_dflt, &addit);
+ nf_conncount_gc_list(net, &priv->list);
ret = list_empty(&priv->list.head);
spin_unlock_bh(&priv->lock);
--
2.11.0
next prev parent reply other threads:[~2018-07-20 13:57 UTC|newest]
Thread overview: 42+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-07-20 13:08 [PATCH 00/38] Netfilter/IPVS updates for net-next Pablo Neira Ayuso
2018-07-20 13:08 ` [PATCH 01/38] netfilter: nft_reject_bridge: remove unnecessary ttl set Pablo Neira Ayuso
2018-07-20 13:08 ` [PATCH 02/38] netfilter: flowtables: use fixed renew timeout on teardown Pablo Neira Ayuso
2018-07-20 13:20 ` Felix Fietkau
2018-07-20 13:32 ` Florian Westphal
2018-07-20 13:08 ` [PATCH 03/38] netfilter: nft_tproxy: Move nf_tproxy_assign_sock() to nf_tproxy.h Pablo Neira Ayuso
2018-07-20 13:08 ` [PATCH 04/38] netfilter: utils: move nf_ip_checksum* from ipv4 to utils Pablo Neira Ayuso
2018-07-20 13:08 ` [PATCH 05/38] netfilter: utils: move nf_ip6_checksum* from ipv6 " Pablo Neira Ayuso
2018-07-20 13:08 ` [PATCH 06/38] openvswitch: use nf_ct_get_tuplepr, invert_tuplepr Pablo Neira Ayuso
2018-07-20 13:08 ` [PATCH 07/38] netfilter: Kconfig: Make NETFILTER_XT_MATCH_SOCKET select NF_SOCKET_IPV4/6 Pablo Neira Ayuso
2018-07-20 13:08 ` [PATCH 08/38] netfilter: conntrack: remove ctnetlink callbacks from l3 protocol trackers Pablo Neira Ayuso
2018-07-20 13:08 ` [PATCH 09/38] netfilter: conntrack: remove pkt_to_tuple indirection " Pablo Neira Ayuso
2018-07-20 13:08 ` [PATCH 10/38] netfilter: conntrack: remove invert_tuple " Pablo Neira Ayuso
2018-07-20 13:08 ` [PATCH 11/38] netfilter: conntrack: remove get_l4proto " Pablo Neira Ayuso
2018-07-20 13:08 ` [PATCH 12/38] netfilter: conntrack: avoid calls to l4proto invert_tuple Pablo Neira Ayuso
2018-07-20 13:08 ` [PATCH 13/38] netfilter: conntrack: avoid l4proto pkt_to_tuple calls Pablo Neira Ayuso
2018-07-20 13:08 ` [PATCH 14/38] netfilter: conntrack: remove get_timeout() indirection Pablo Neira Ayuso
2018-07-20 13:08 ` [PATCH 15/38] netfilter: conntrack: remove l3proto abstraction Pablo Neira Ayuso
2018-07-20 13:08 ` [PATCH 16/38] netfilter: Kconfig: Change select IPv6 dependencies Pablo Neira Ayuso
2018-07-20 13:08 ` [PATCH 17/38] netfilter: nf_conncount: Early exit for garbage collection Pablo Neira Ayuso
2018-07-20 13:08 ` [PATCH 18/38] netfilter: nf_conncount: Switch to plain list Pablo Neira Ayuso
2018-07-20 13:08 ` Pablo Neira Ayuso [this message]
2018-07-20 13:08 ` [PATCH 20/38] netfilter: nf_conncount: Move locking into count_tree() Pablo Neira Ayuso
2018-07-20 13:08 ` [PATCH 21/38] netfilter: nf_conncount: Split insert and traversal Pablo Neira Ayuso
2018-07-20 13:08 ` [PATCH 22/38] netfilter: nf_conncount: Add list lock and gc worker, and RCU for init tree search Pablo Neira Ayuso
2018-07-20 13:08 ` [PATCH 23/38] netfilter: nf_conntrack: resolve clash for matching conntracks Pablo Neira Ayuso
2018-07-20 13:08 ` [PATCH 24/38] ipvs: provide just conn to ip_vs_state_name Pablo Neira Ayuso
2018-07-20 13:08 ` [PATCH 25/38] ipvs: add assured state for conn templates Pablo Neira Ayuso
2018-07-20 13:08 ` [PATCH 26/38] ipvs: drop conn templates under attack Pablo Neira Ayuso
2018-07-20 13:08 ` [PATCH 27/38] netfilter: Remove useless param helper of nf_ct_helper_ext_add Pablo Neira Ayuso
2018-07-20 13:08 ` [PATCH 28/38] netfilter: nf_tables: add and use helper for module autoload Pablo Neira Ayuso
2018-07-20 13:08 ` [PATCH 29/38] netfilter: nf_tables: make valid_genid callback mandatory Pablo Neira Ayuso
2018-07-20 13:08 ` [PATCH 30/38] netfilter: nf_tables: take module reference when starting a batch Pablo Neira Ayuso
2018-07-20 13:08 ` [PATCH 31/38] netfilter: nf_tables: avoid global info storage Pablo Neira Ayuso
2018-07-20 13:09 ` [PATCH 32/38] netfilter: nf_tables: use dedicated mutex to guard transactions Pablo Neira Ayuso
2018-07-20 13:09 ` [PATCH 33/38] netfilter: nf_osf: add nf_osf_match_one() Pablo Neira Ayuso
2018-07-20 13:09 ` [PATCH 34/38] netfilter: nf_osf: add struct nf_osf_hdr_ctx Pablo Neira Ayuso
2018-07-20 13:09 ` [PATCH 35/38] netfilter: nft_socket: Break evaluation if no socket found Pablo Neira Ayuso
2018-07-20 13:09 ` [PATCH 36/38] netfilter: nft_socket: Expose socket mark Pablo Neira Ayuso
2018-07-20 13:09 ` [PATCH 37/38] ipv6: remove dependency of nf_defrag_ipv6 on ipv6 module Pablo Neira Ayuso
2018-07-20 13:09 ` [PATCH 38/38] netfilter: nf_osf: add missing definitions to header file Pablo Neira Ayuso
2018-07-21 6:33 ` [PATCH 00/38] Netfilter/IPVS updates for net-next David Miller
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20180720130906.27687-20-pablo@netfilter.org \
--to=pablo@netfilter.org \
--cc=davem@davemloft.net \
--cc=netdev@vger.kernel.org \
--cc=netfilter-devel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).