From: Florian Westphal <fw@strlen.de>
To: <netfilter-devel@vger.kernel.org>
Cc: lorenzo@kernel.org, <netdev@vger.kernel.org>,
Florian Westphal <fw@strlen.de>
Subject: [PATCH nf-next 8/8] netfilter: nf_tables: permit duplicate flowtable mappings
Date: Tue, 21 Nov 2023 13:27:51 +0100 [thread overview]
Message-ID: <20231121122800.13521-9-fw@strlen.de> (raw)
In-Reply-To: <20231121122800.13521-1-fw@strlen.de>
The core ensures that no duplicate mapping (net_device x is always
assigned to exactly one flowtable, or none at all) exists.
Only exception: its assigned to a flowtable that is going away
in this transaction.
Therefore relax the existing check to permit the duplicate
entry, it is only temporary.
The existing entry will shadow the new one until the transaction
is committed (old entry is removed) or aborted (new entry is removed).
Signed-off-by: Florian Westphal <fw@strlen.de>
---
net/netfilter/nf_flow_table_offload.c | 36 +++++++++++++++++++++++----
1 file changed, 31 insertions(+), 5 deletions(-)
diff --git a/net/netfilter/nf_flow_table_offload.c b/net/netfilter/nf_flow_table_offload.c
index 9ec7aa4ad2e5..b6503fd45871 100644
--- a/net/netfilter/nf_flow_table_offload.c
+++ b/net/netfilter/nf_flow_table_offload.c
@@ -49,13 +49,14 @@ static int nf_flowtable_by_dev_insert(struct nf_flowtable *ft,
{
unsigned long key = (unsigned long)dev;
struct flow_offload_xdp *cur;
+ bool duplicate = false;
int err = 0;
mutex_lock(&nf_xdp_hashtable_lock);
hash_for_each_possible(nf_xdp_hashtable, cur, hnode, key) {
if (key != cur->net_device_addr)
continue;
- err = -EEXIST;
+ duplicate = true;
break;
}
@@ -67,7 +68,20 @@ static int nf_flowtable_by_dev_insert(struct nf_flowtable *ft,
new->net_device_addr = key;
new->ft = ft;
- hash_add_rcu(nf_xdp_hashtable, &new->hnode, key);
+ if (duplicate) {
+ u32 index = hash_min(key, HASH_BITS(nf_xdp_hashtable));
+
+ /* nf_tables_api.c makes sure that only a single flowtable
+ * has this device.
+ *
+ * Only exception: the flowtable is about to be removed.
+ * Thus we tolerate the duplicated entry, the 'old' entry
+ * will be unhashed after the transaction completes.
+ */
+ hlist_add_tail_rcu(&new->hnode, &nf_xdp_hashtable[index]);
+ } else {
+ hash_add_rcu(nf_xdp_hashtable, &new->hnode, key);
+ }
} else {
err = -ENOMEM;
}
@@ -80,7 +94,8 @@ static int nf_flowtable_by_dev_insert(struct nf_flowtable *ft,
return err;
}
-static void nf_flowtable_by_dev_remove(const struct net_device *dev)
+static void nf_flowtable_by_dev_remove(const struct nf_flowtable *ft,
+ const struct net_device *dev)
{
unsigned long key = (unsigned long)dev;
struct flow_offload_xdp *cur;
@@ -92,6 +107,17 @@ static void nf_flowtable_by_dev_remove(const struct net_device *dev)
if (key != cur->net_device_addr)
continue;
+ /* duplicate entry, happens when current transaction
+ * removes flowtable f1 and adds flowtable f2, where both
+ * have *dev assigned to them.
+ *
+ * nf_tables_api.c makes sure that at most one
+ * flowtable,dev pair with 'xdp' flag enabled can exist
+ * in the same generation.
+ */
+ if (cur->ft != ft)
+ continue;
+
hash_del_rcu(&cur->hnode);
kfree_rcu(cur, rcuhead);
found = true;
@@ -1280,7 +1306,7 @@ static int nf_flow_offload_xdp_setup(struct nf_flowtable *flowtable,
case FLOW_BLOCK_BIND:
return nf_flowtable_by_dev_insert(flowtable, dev);
case FLOW_BLOCK_UNBIND:
- nf_flowtable_by_dev_remove(dev);
+ nf_flowtable_by_dev_remove(flowtable, dev);
return 0;
}
@@ -1297,7 +1323,7 @@ static void nf_flow_offload_xdp_cancel(struct nf_flowtable *flowtable,
switch (cmd) {
case FLOW_BLOCK_BIND:
- nf_flowtable_by_dev_remove(dev);
+ nf_flowtable_by_dev_remove(flowtable, dev);
return;
case FLOW_BLOCK_UNBIND:
/* We do not re-bind in case hw offload would report error
--
2.41.0
next prev parent reply other threads:[~2023-11-21 12:28 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-11-21 12:27 [PATCH nf-next 0/8] netfilter: make nf_flowtable lifetime differ from container struct Florian Westphal
2023-11-21 12:27 ` [PATCH nf-next 1/8] netfilter: flowtable: move nf_flowtable out of container structures Florian Westphal
2023-11-23 13:52 ` Simon Horman
2023-11-23 14:10 ` Florian Westphal
2023-11-25 8:26 ` Simon Horman
2023-11-25 8:36 ` Simon Horman
2023-11-21 12:27 ` [PATCH nf-next 2/8] netfilter: nf_flowtable: replace init callback with a create one Florian Westphal
2023-11-21 12:27 ` [PATCH nf-next 3/8] netfilter: nf_flowtable: make free a real free function Florian Westphal
2023-11-21 12:27 ` [PATCH nf-next 4/8] netfilter: nf_flowtable: delay flowtable release a second time Florian Westphal
2023-11-21 12:27 ` [PATCH nf-next 5/8] netfilter: nf_tables: reject flowtable hw offload for same device Florian Westphal
2023-11-21 12:27 ` [PATCH nf-next 6/8] netfilter: nf_tables: add xdp offload flag Florian Westphal
2023-11-21 12:27 ` [PATCH nf-next 7/8] netfilter: nf_tables: add flowtable map for xdp offload Florian Westphal
2023-11-21 14:25 ` Lorenzo Bianconi
2023-11-24 10:59 ` Toke Høiland-Jørgensen
2023-11-30 13:53 ` Florian Westphal
2023-11-30 14:17 ` Toke Høiland-Jørgensen
2023-11-21 12:27 ` Florian Westphal [this message]
2023-11-24 9:50 ` [PATCH nf-next 0/8] netfilter: make nf_flowtable lifetime differ from container struct Pablo Neira Ayuso
2023-11-24 9:55 ` Florian Westphal
2023-11-24 10:10 ` Pablo Neira Ayuso
2023-11-24 10:16 ` Florian Westphal
2023-11-24 10:48 ` Toke Høiland-Jørgensen
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=20231121122800.13521-9-fw@strlen.de \
--to=fw@strlen.de \
--cc=lorenzo@kernel.org \
--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).