From: Amit Cohen <amcohen@nvidia.com>
To: netdev@vger.kernel.org
Cc: Petr Machata <petrm@nvidia.com>,
razor@blackwall.org, Amit Cohen <amcohen@nvidia.com>,
mlxsw@nvidia.com, dsahern@kernel.org,
bridge@lists.linux-foundation.org, idosch@nvidia.com,
linux-kselftest@vger.kernel.org, roopa@nvidia.com,
kuba@kernel.org, pabeni@redhat.com, shuah@kernel.org,
davem@davemloft.net
Subject: [Bridge] [PATCH net-next 07/11] vxlan: vxlan_core: Support FDB flushing by destination VNI
Date: Mon, 9 Oct 2023 13:06:14 +0300 [thread overview]
Message-ID: <20231009100618.2911374-8-amcohen@nvidia.com> (raw)
In-Reply-To: <20231009100618.2911374-1-amcohen@nvidia.com>
Add support for flush VXLAN FDB entries by destination VNI. FDB entry is
stored as {MAC, SRC_VNI} + remote. The destination VNI is an attribute
of the remote. For multicast entries, the VXLAN driver stores a linked list
of remotes for a given key.
In user space, each remote is represented as a separate entry, so when
flush is sent with filter of 'destination VNI', flush only the match
remotes. In case that there are no additional remotes, destroy the entry.
For example, the following are stored as one entry with several remotes:
$ bridge fdb show dev vx10
00:00:00:00:00:00 dst 192.1.1.1 vni 3000 self permanent
00:00:00:00:00:00 dst 192.1.1.1 vni 4000 self permanent
00:00:00:00:00:00 dst 192.1.1.1 vni 2000 self permanent
00:00:00:00:00:00 dst 192.1.1.2 vni 2000 self permanent
When user flush by VNI x, only the relevant remotes will be flushed:
$ bridge fdb flush dev vx10 vni 2000
$ bridge fdb show dev vx10
00:00:00:00:00:00 dst 192.1.1.1 vni 3000 self permanent
00:00:00:00:00:00 dst 192.1.1.1 vni 4000 self permanent
Signed-off-by: Amit Cohen <amcohen@nvidia.com>
Reviewed-by: Petr Machata <petrm@nvidia.com>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
---
drivers/net/vxlan/vxlan_core.c | 51 ++++++++++++++++++++++++++++++++++
1 file changed, 51 insertions(+)
diff --git a/drivers/net/vxlan/vxlan_core.c b/drivers/net/vxlan/vxlan_core.c
index ec7147409d99..f16328a0f9fe 100644
--- a/drivers/net/vxlan/vxlan_core.c
+++ b/drivers/net/vxlan/vxlan_core.c
@@ -3030,6 +3030,7 @@ struct vxlan_fdb_flush_desc {
unsigned long flags_mask;
__be32 src_vni;
u32 nhid;
+ __be32 vni;
};
static bool vxlan_fdb_is_default_entry(const struct vxlan_fdb *f,
@@ -3067,10 +3068,46 @@ static bool vxlan_fdb_flush_matches(const struct vxlan_fdb *f,
return true;
}
+static bool
+vxlan_fdb_flush_should_match_remotes(const struct vxlan_fdb_flush_desc *desc)
+{
+ return !!desc->vni;
+}
+
+static bool
+vxlan_fdb_flush_remote_matches(const struct vxlan_fdb_flush_desc *desc,
+ const struct vxlan_rdst *rd)
+{
+ if (desc->vni && rd->remote_vni != desc->vni)
+ return false;
+
+ return true;
+}
+
+static void
+vxlan_fdb_flush_match_remotes(struct vxlan_fdb *f, struct vxlan_dev *vxlan,
+ const struct vxlan_fdb_flush_desc *desc,
+ bool *p_destroy_fdb)
+{
+ bool remotes_flushed = false;
+ struct vxlan_rdst *rd, *tmp;
+
+ list_for_each_entry_safe(rd, tmp, &f->remotes, list) {
+ if (!vxlan_fdb_flush_remote_matches(desc, rd))
+ continue;
+
+ vxlan_fdb_dst_destroy(vxlan, f, rd, true);
+ remotes_flushed = true;
+ }
+
+ *p_destroy_fdb = remotes_flushed && list_empty(&f->remotes);
+}
+
/* Purge the forwarding table */
static void vxlan_flush(struct vxlan_dev *vxlan,
const struct vxlan_fdb_flush_desc *desc)
{
+ bool match_remotes = vxlan_fdb_flush_should_match_remotes(desc);
unsigned int h;
for (h = 0; h < FDB_HASH_SIZE; ++h) {
@@ -3084,6 +3121,16 @@ static void vxlan_flush(struct vxlan_dev *vxlan,
if (!vxlan_fdb_flush_matches(f, vxlan, desc))
continue;
+ if (match_remotes) {
+ bool destroy_fdb = false;
+
+ vxlan_fdb_flush_match_remotes(f, vxlan, desc,
+ &destroy_fdb);
+
+ if (!destroy_fdb)
+ continue;
+ }
+
vxlan_fdb_destroy(vxlan, f, true, true);
}
spin_unlock_bh(&vxlan->hash_lock[h]);
@@ -3093,6 +3140,7 @@ static void vxlan_flush(struct vxlan_dev *vxlan,
static const struct nla_policy vxlan_del_bulk_policy[NDA_MAX + 1] = {
[NDA_SRC_VNI] = { .type = NLA_U32 },
[NDA_NH_ID] = { .type = NLA_U32 },
+ [NDA_VNI] = { .type = NLA_U32 },
[NDA_NDM_STATE_MASK] = { .type = NLA_U16 },
[NDA_NDM_FLAGS_MASK] = { .type = NLA_U8 },
};
@@ -3143,6 +3191,9 @@ static int vxlan_fdb_delete_bulk(struct nlmsghdr *nlh, struct net_device *dev,
if (tb[NDA_NH_ID])
desc.nhid = nla_get_u32(tb[NDA_NH_ID]);
+ if (tb[NDA_VNI])
+ desc.vni = cpu_to_be32(nla_get_u32(tb[NDA_VNI]));
+
vxlan_flush(vxlan, &desc);
return 0;
--
2.40.1
next prev parent reply other threads:[~2023-10-09 10:06 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-10-09 10:06 [Bridge] [PATCH net-next 00/11] Extend VXLAN driver to support FDB flushing Amit Cohen
2023-10-09 10:06 ` [Bridge] [PATCH net-next 01/11] net: Handle bulk delete policy in bridge driver Amit Cohen
2023-10-09 10:06 ` [Bridge] [PATCH net-next 02/11] vxlan: vxlan_core: Make vxlan_flush() more generic for future use Amit Cohen
2023-10-09 10:06 ` [Bridge] [PATCH net-next 03/11] vxlan: vxlan_core: Do not skip default entry in vxlan_flush() by default Amit Cohen
2023-10-09 10:06 ` [Bridge] [PATCH net-next 04/11] vxlan: vxlan_core: Add support for FDB flush Amit Cohen
2023-10-09 10:06 ` [Bridge] [PATCH net-next 05/11] vxlan: vxlan_core: Support FDB flushing by source VNI Amit Cohen
2023-10-09 10:06 ` [Bridge] [PATCH net-next 06/11] vxlan: vxlan_core: Support FDB flushing by nexthop ID Amit Cohen
2023-10-09 10:06 ` Amit Cohen [this message]
2023-10-09 10:06 ` [Bridge] [PATCH net-next 08/11] vxlan: vxlan_core: Support FDB flushing by destination port Amit Cohen
2023-10-09 10:06 ` [Bridge] [PATCH net-next 09/11] vxlan: vxlan_core: Support FDB flushing by destination IP Amit Cohen
2023-10-09 10:06 ` [Bridge] [PATCH net-next 10/11] selftests: Add test cases for FDB flush with VXLAN device Amit Cohen
2023-10-09 10:06 ` [Bridge] [PATCH net-next 11/11] selftests: fdb_flush: Add test cases for FDB flush with bridge device Amit Cohen
2023-10-10 19:11 ` Scott Wadkins
2023-10-10 18:50 ` [Bridge] [PATCH net-next 00/11] Extend VXLAN driver to support FDB flushing Nikolay Aleksandrov
2023-10-13 9:10 ` patchwork-bot+netdevbpf
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=20231009100618.2911374-8-amcohen@nvidia.com \
--to=amcohen@nvidia.com \
--cc=bridge@lists.linux-foundation.org \
--cc=davem@davemloft.net \
--cc=dsahern@kernel.org \
--cc=idosch@nvidia.com \
--cc=kuba@kernel.org \
--cc=linux-kselftest@vger.kernel.org \
--cc=mlxsw@nvidia.com \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=petrm@nvidia.com \
--cc=razor@blackwall.org \
--cc=roopa@nvidia.com \
--cc=shuah@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