@@ -3032,6 +3032,7 @@ struct vxlan_fdb_flush_desc {
u32 nhid;
__be32 vni;
__be16 port;
+ union vxlan_addr dst_ip;
};
static bool vxlan_fdb_is_default_entry(const struct vxlan_fdb *f,
@@ -3072,7 +3073,7 @@ static bool vxlan_fdb_flush_matches(const struct vxlan_fdb *f,
static bool
vxlan_fdb_flush_should_match_remotes(const struct vxlan_fdb_flush_desc *desc)
{
- return desc->vni || desc->port;
+ return desc->vni || desc->port || desc->dst_ip.sa.sa_family;
}
static bool
@@ -3085,6 +3086,10 @@ vxlan_fdb_flush_remote_matches(const struct vxlan_fdb_flush_desc *desc,
if (desc->port && rd->remote_port != desc->port)
return false;
+ if (desc->dst_ip.sa.sa_family &&
+ !vxlan_addr_equal(&rd->remote_ip, &desc->dst_ip))
+ return false;
+
return true;
}
@@ -3146,6 +3151,8 @@ static const struct nla_policy vxlan_del_bulk_policy[NDA_MAX + 1] = {
[NDA_NH_ID] = { .type = NLA_U32 },
[NDA_VNI] = { .type = NLA_U32 },
[NDA_PORT] = { .type = NLA_U16 },
+ [NDA_DST] = NLA_POLICY_RANGE(NLA_BINARY, sizeof(struct in_addr),
+ sizeof(struct in6_addr)),
[NDA_NDM_STATE_MASK] = { .type = NLA_U16 },
[NDA_NDM_FLAGS_MASK] = { .type = NLA_U8 },
};
@@ -3202,6 +3209,18 @@ static int vxlan_fdb_delete_bulk(struct nlmsghdr *nlh, struct net_device *dev,
if (tb[NDA_PORT])
desc.port = nla_get_be16(tb[NDA_PORT]);
+ if (tb[NDA_DST]) {
+ union vxlan_addr ip;
+
+ err = vxlan_nla_get_addr(&ip, tb[NDA_DST]);
+ if (err) {
+ NL_SET_ERR_MSG_ATTR(extack, tb[NDA_DST],
+ "Unsupported address family");
+ return err;
+ }
+ desc.dst_ip = ip;
+ }
+
vxlan_flush(vxlan, &desc);
return 0;