Commit ac0db4dd authored by Amit Cohen's avatar Amit Cohen Committed by David S. Miller

vxlan: vxlan_core: Support FDB flushing by destination port

Add support for flush VXLAN FDB entries by destination port. FDB entry
is stored as {MAC, SRC_VNI} + remote. The destination port 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 port', 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 port 1111 vni 2000 self permanent
00:00:00:00:00:00 dst 192.1.1.1 port 1111 vni 3000 self permanent
00:00:00:00:00:00 dst 192.1.1.1 port 2222 vni 2000 self permanent
00:00:00:00:00:00 dst 192.1.1.1 vni 3000 self permanent

When user flush by port x, only the relevant remotes will be flushed:
$ bridge fdb flush dev vx10 port 1111

$ bridge fdb show dev vx10
00:00:00:00:00:00 dst 192.1.1.1 port 2222 vni 2000 self permanent
00:00:00:00:00:00 dst 192.1.1.1 vni 3000 self permanent
Signed-off-by: default avatarAmit Cohen <amcohen@nvidia.com>
Reviewed-by: default avatarIdo Schimmel <idosch@nvidia.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent c499fccb
...@@ -3031,6 +3031,7 @@ struct vxlan_fdb_flush_desc { ...@@ -3031,6 +3031,7 @@ struct vxlan_fdb_flush_desc {
__be32 src_vni; __be32 src_vni;
u32 nhid; u32 nhid;
__be32 vni; __be32 vni;
__be16 port;
}; };
static bool vxlan_fdb_is_default_entry(const struct vxlan_fdb *f, static bool vxlan_fdb_is_default_entry(const struct vxlan_fdb *f,
...@@ -3071,7 +3072,7 @@ static bool vxlan_fdb_flush_matches(const struct vxlan_fdb *f, ...@@ -3071,7 +3072,7 @@ static bool vxlan_fdb_flush_matches(const struct vxlan_fdb *f,
static bool static bool
vxlan_fdb_flush_should_match_remotes(const struct vxlan_fdb_flush_desc *desc) vxlan_fdb_flush_should_match_remotes(const struct vxlan_fdb_flush_desc *desc)
{ {
return !!desc->vni; return desc->vni || desc->port;
} }
static bool static bool
...@@ -3081,6 +3082,9 @@ vxlan_fdb_flush_remote_matches(const struct vxlan_fdb_flush_desc *desc, ...@@ -3081,6 +3082,9 @@ vxlan_fdb_flush_remote_matches(const struct vxlan_fdb_flush_desc *desc,
if (desc->vni && rd->remote_vni != desc->vni) if (desc->vni && rd->remote_vni != desc->vni)
return false; return false;
if (desc->port && rd->remote_port != desc->port)
return false;
return true; return true;
} }
...@@ -3141,6 +3145,7 @@ static const struct nla_policy vxlan_del_bulk_policy[NDA_MAX + 1] = { ...@@ -3141,6 +3145,7 @@ static const struct nla_policy vxlan_del_bulk_policy[NDA_MAX + 1] = {
[NDA_SRC_VNI] = { .type = NLA_U32 }, [NDA_SRC_VNI] = { .type = NLA_U32 },
[NDA_NH_ID] = { .type = NLA_U32 }, [NDA_NH_ID] = { .type = NLA_U32 },
[NDA_VNI] = { .type = NLA_U32 }, [NDA_VNI] = { .type = NLA_U32 },
[NDA_PORT] = { .type = NLA_U16 },
[NDA_NDM_STATE_MASK] = { .type = NLA_U16 }, [NDA_NDM_STATE_MASK] = { .type = NLA_U16 },
[NDA_NDM_FLAGS_MASK] = { .type = NLA_U8 }, [NDA_NDM_FLAGS_MASK] = { .type = NLA_U8 },
}; };
...@@ -3194,6 +3199,9 @@ static int vxlan_fdb_delete_bulk(struct nlmsghdr *nlh, struct net_device *dev, ...@@ -3194,6 +3199,9 @@ static int vxlan_fdb_delete_bulk(struct nlmsghdr *nlh, struct net_device *dev,
if (tb[NDA_VNI]) if (tb[NDA_VNI])
desc.vni = cpu_to_be32(nla_get_u32(tb[NDA_VNI])); desc.vni = cpu_to_be32(nla_get_u32(tb[NDA_VNI]));
if (tb[NDA_PORT])
desc.port = nla_get_be16(tb[NDA_PORT]);
vxlan_flush(vxlan, &desc); vxlan_flush(vxlan, &desc);
return 0; return 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment