brintos

brintos / linux-shallow public Read only

0
0
Text · 43.8 KiB · 60eb95a Raw
1747 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2 3#include <linux/if_bridge.h>4#include <linux/in.h>5#include <linux/list.h>6#include <linux/netdevice.h>7#include <linux/netlink.h>8#include <linux/rhashtable.h>9#include <linux/rhashtable-types.h>10#include <linux/rtnetlink.h>11#include <linux/skbuff.h>12#include <linux/types.h>13#include <net/netlink.h>14#include <net/vxlan.h>15 16#include "vxlan_private.h"17 18struct vxlan_mdb_entry_key {19	union vxlan_addr src;20	union vxlan_addr dst;21	__be32 vni;22};23 24struct vxlan_mdb_entry {25	struct rhash_head rhnode;26	struct list_head remotes;27	struct vxlan_mdb_entry_key key;28	struct hlist_node mdb_node;29	struct rcu_head rcu;30};31 32#define VXLAN_MDB_REMOTE_F_BLOCKED	BIT(0)33 34struct vxlan_mdb_remote {35	struct list_head list;36	struct vxlan_rdst __rcu *rd;37	u8 flags;38	u8 filter_mode;39	u8 rt_protocol;40	struct hlist_head src_list;41	struct rcu_head rcu;42};43 44#define VXLAN_SGRP_F_DELETE	BIT(0)45 46struct vxlan_mdb_src_entry {47	struct hlist_node node;48	union vxlan_addr addr;49	u8 flags;50};51 52struct vxlan_mdb_dump_ctx {53	long reserved;54	long entry_idx;55	long remote_idx;56};57 58struct vxlan_mdb_config_src_entry {59	union vxlan_addr addr;60	struct list_head node;61};62 63struct vxlan_mdb_config {64	struct vxlan_dev *vxlan;65	struct vxlan_mdb_entry_key group;66	struct list_head src_list;67	union vxlan_addr remote_ip;68	u32 remote_ifindex;69	__be32 remote_vni;70	__be16 remote_port;71	u16 nlflags;72	u8 flags;73	u8 filter_mode;74	u8 rt_protocol;75};76 77struct vxlan_mdb_flush_desc {78	union vxlan_addr remote_ip;79	__be32 src_vni;80	__be32 remote_vni;81	__be16 remote_port;82	u8 rt_protocol;83};84 85static const struct rhashtable_params vxlan_mdb_rht_params = {86	.head_offset = offsetof(struct vxlan_mdb_entry, rhnode),87	.key_offset = offsetof(struct vxlan_mdb_entry, key),88	.key_len = sizeof(struct vxlan_mdb_entry_key),89	.automatic_shrinking = true,90};91 92static int __vxlan_mdb_add(const struct vxlan_mdb_config *cfg,93			   struct netlink_ext_ack *extack);94static int __vxlan_mdb_del(const struct vxlan_mdb_config *cfg,95			   struct netlink_ext_ack *extack);96 97static void vxlan_br_mdb_entry_fill(const struct vxlan_dev *vxlan,98				    const struct vxlan_mdb_entry *mdb_entry,99				    const struct vxlan_mdb_remote *remote,100				    struct br_mdb_entry *e)101{102	const union vxlan_addr *dst = &mdb_entry->key.dst;103 104	memset(e, 0, sizeof(*e));105	e->ifindex = vxlan->dev->ifindex;106	e->state = MDB_PERMANENT;107 108	if (remote->flags & VXLAN_MDB_REMOTE_F_BLOCKED)109		e->flags |= MDB_FLAGS_BLOCKED;110 111	switch (dst->sa.sa_family) {112	case AF_INET:113		e->addr.u.ip4 = dst->sin.sin_addr.s_addr;114		e->addr.proto = htons(ETH_P_IP);115		break;116#if IS_ENABLED(CONFIG_IPV6)117	case AF_INET6:118		e->addr.u.ip6 = dst->sin6.sin6_addr;119		e->addr.proto = htons(ETH_P_IPV6);120		break;121#endif122	}123}124 125static int vxlan_mdb_entry_info_fill_srcs(struct sk_buff *skb,126					  const struct vxlan_mdb_remote *remote)127{128	struct vxlan_mdb_src_entry *ent;129	struct nlattr *nest;130 131	if (hlist_empty(&remote->src_list))132		return 0;133 134	nest = nla_nest_start(skb, MDBA_MDB_EATTR_SRC_LIST);135	if (!nest)136		return -EMSGSIZE;137 138	hlist_for_each_entry(ent, &remote->src_list, node) {139		struct nlattr *nest_ent;140 141		nest_ent = nla_nest_start(skb, MDBA_MDB_SRCLIST_ENTRY);142		if (!nest_ent)143			goto out_cancel_err;144 145		if (vxlan_nla_put_addr(skb, MDBA_MDB_SRCATTR_ADDRESS,146				       &ent->addr) ||147		    nla_put_u32(skb, MDBA_MDB_SRCATTR_TIMER, 0))148			goto out_cancel_err;149 150		nla_nest_end(skb, nest_ent);151	}152 153	nla_nest_end(skb, nest);154 155	return 0;156 157out_cancel_err:158	nla_nest_cancel(skb, nest);159	return -EMSGSIZE;160}161 162static int vxlan_mdb_entry_info_fill(const struct vxlan_dev *vxlan,163				     struct sk_buff *skb,164				     const struct vxlan_mdb_entry *mdb_entry,165				     const struct vxlan_mdb_remote *remote)166{167	struct vxlan_rdst *rd = rtnl_dereference(remote->rd);168	struct br_mdb_entry e;169	struct nlattr *nest;170 171	nest = nla_nest_start_noflag(skb, MDBA_MDB_ENTRY_INFO);172	if (!nest)173		return -EMSGSIZE;174 175	vxlan_br_mdb_entry_fill(vxlan, mdb_entry, remote, &e);176 177	if (nla_put_nohdr(skb, sizeof(e), &e) ||178	    nla_put_u32(skb, MDBA_MDB_EATTR_TIMER, 0))179		goto nest_err;180 181	if (!vxlan_addr_any(&mdb_entry->key.src) &&182	    vxlan_nla_put_addr(skb, MDBA_MDB_EATTR_SOURCE, &mdb_entry->key.src))183		goto nest_err;184 185	if (nla_put_u8(skb, MDBA_MDB_EATTR_RTPROT, remote->rt_protocol) ||186	    nla_put_u8(skb, MDBA_MDB_EATTR_GROUP_MODE, remote->filter_mode) ||187	    vxlan_mdb_entry_info_fill_srcs(skb, remote) ||188	    vxlan_nla_put_addr(skb, MDBA_MDB_EATTR_DST, &rd->remote_ip))189		goto nest_err;190 191	if (rd->remote_port && rd->remote_port != vxlan->cfg.dst_port &&192	    nla_put_u16(skb, MDBA_MDB_EATTR_DST_PORT,193			be16_to_cpu(rd->remote_port)))194		goto nest_err;195 196	if (rd->remote_vni != vxlan->default_dst.remote_vni &&197	    nla_put_u32(skb, MDBA_MDB_EATTR_VNI, be32_to_cpu(rd->remote_vni)))198		goto nest_err;199 200	if (rd->remote_ifindex &&201	    nla_put_u32(skb, MDBA_MDB_EATTR_IFINDEX, rd->remote_ifindex))202		goto nest_err;203 204	if ((vxlan->cfg.flags & VXLAN_F_COLLECT_METADATA) &&205	    mdb_entry->key.vni && nla_put_u32(skb, MDBA_MDB_EATTR_SRC_VNI,206					      be32_to_cpu(mdb_entry->key.vni)))207		goto nest_err;208 209	nla_nest_end(skb, nest);210 211	return 0;212 213nest_err:214	nla_nest_cancel(skb, nest);215	return -EMSGSIZE;216}217 218static int vxlan_mdb_entry_fill(const struct vxlan_dev *vxlan,219				struct sk_buff *skb,220				struct vxlan_mdb_dump_ctx *ctx,221				const struct vxlan_mdb_entry *mdb_entry)222{223	int remote_idx = 0, s_remote_idx = ctx->remote_idx;224	struct vxlan_mdb_remote *remote;225	struct nlattr *nest;226	int err = 0;227 228	nest = nla_nest_start_noflag(skb, MDBA_MDB_ENTRY);229	if (!nest)230		return -EMSGSIZE;231 232	list_for_each_entry(remote, &mdb_entry->remotes, list) {233		if (remote_idx < s_remote_idx)234			goto skip;235 236		err = vxlan_mdb_entry_info_fill(vxlan, skb, mdb_entry, remote);237		if (err)238			break;239skip:240		remote_idx++;241	}242 243	ctx->remote_idx = err ? remote_idx : 0;244	nla_nest_end(skb, nest);245	return err;246}247 248static int vxlan_mdb_fill(const struct vxlan_dev *vxlan, struct sk_buff *skb,249			  struct vxlan_mdb_dump_ctx *ctx)250{251	int entry_idx = 0, s_entry_idx = ctx->entry_idx;252	struct vxlan_mdb_entry *mdb_entry;253	struct nlattr *nest;254	int err = 0;255 256	nest = nla_nest_start_noflag(skb, MDBA_MDB);257	if (!nest)258		return -EMSGSIZE;259 260	hlist_for_each_entry(mdb_entry, &vxlan->mdb_list, mdb_node) {261		if (entry_idx < s_entry_idx)262			goto skip;263 264		err = vxlan_mdb_entry_fill(vxlan, skb, ctx, mdb_entry);265		if (err)266			break;267skip:268		entry_idx++;269	}270 271	ctx->entry_idx = err ? entry_idx : 0;272	nla_nest_end(skb, nest);273	return err;274}275 276int vxlan_mdb_dump(struct net_device *dev, struct sk_buff *skb,277		   struct netlink_callback *cb)278{279	struct vxlan_mdb_dump_ctx *ctx = (void *)cb->ctx;280	struct vxlan_dev *vxlan = netdev_priv(dev);281	struct br_port_msg *bpm;282	struct nlmsghdr *nlh;283	int err;284 285	ASSERT_RTNL();286 287	NL_ASSERT_DUMP_CTX_FITS(struct vxlan_mdb_dump_ctx);288 289	nlh = nlmsg_put(skb, NETLINK_CB(cb->skb).portid,290			cb->nlh->nlmsg_seq, RTM_NEWMDB, sizeof(*bpm),291			NLM_F_MULTI);292	if (!nlh)293		return -EMSGSIZE;294 295	bpm = nlmsg_data(nlh);296	memset(bpm, 0, sizeof(*bpm));297	bpm->family = AF_BRIDGE;298	bpm->ifindex = dev->ifindex;299 300	err = vxlan_mdb_fill(vxlan, skb, ctx);301 302	nlmsg_end(skb, nlh);303 304	cb->seq = vxlan->mdb_seq;305	nl_dump_check_consistent(cb, nlh);306 307	return err;308}309 310static const struct nla_policy311vxlan_mdbe_src_list_entry_pol[MDBE_SRCATTR_MAX + 1] = {312	[MDBE_SRCATTR_ADDRESS] = NLA_POLICY_RANGE(NLA_BINARY,313						  sizeof(struct in_addr),314						  sizeof(struct in6_addr)),315};316 317static const struct nla_policy318vxlan_mdbe_src_list_pol[MDBE_SRC_LIST_MAX + 1] = {319	[MDBE_SRC_LIST_ENTRY] = NLA_POLICY_NESTED(vxlan_mdbe_src_list_entry_pol),320};321 322static const struct netlink_range_validation vni_range = {323	.max = VXLAN_N_VID - 1,324};325 326static const struct nla_policy vxlan_mdbe_attrs_pol[MDBE_ATTR_MAX + 1] = {327	[MDBE_ATTR_SOURCE] = NLA_POLICY_RANGE(NLA_BINARY,328					      sizeof(struct in_addr),329					      sizeof(struct in6_addr)),330	[MDBE_ATTR_GROUP_MODE] = NLA_POLICY_RANGE(NLA_U8, MCAST_EXCLUDE,331						  MCAST_INCLUDE),332	[MDBE_ATTR_SRC_LIST] = NLA_POLICY_NESTED(vxlan_mdbe_src_list_pol),333	[MDBE_ATTR_RTPROT] = NLA_POLICY_MIN(NLA_U8, RTPROT_STATIC),334	[MDBE_ATTR_DST] = NLA_POLICY_RANGE(NLA_BINARY,335					   sizeof(struct in_addr),336					   sizeof(struct in6_addr)),337	[MDBE_ATTR_DST_PORT] = { .type = NLA_U16 },338	[MDBE_ATTR_VNI] = NLA_POLICY_FULL_RANGE(NLA_U32, &vni_range),339	[MDBE_ATTR_IFINDEX] = NLA_POLICY_MIN(NLA_S32, 1),340	[MDBE_ATTR_SRC_VNI] = NLA_POLICY_FULL_RANGE(NLA_U32, &vni_range),341};342 343static bool vxlan_mdb_is_valid_source(const struct nlattr *attr, __be16 proto,344				      struct netlink_ext_ack *extack)345{346	switch (proto) {347	case htons(ETH_P_IP):348		if (nla_len(attr) != sizeof(struct in_addr)) {349			NL_SET_ERR_MSG_MOD(extack, "IPv4 invalid source address length");350			return false;351		}352		if (ipv4_is_multicast(nla_get_in_addr(attr))) {353			NL_SET_ERR_MSG_MOD(extack, "IPv4 multicast source address is not allowed");354			return false;355		}356		break;357#if IS_ENABLED(CONFIG_IPV6)358	case htons(ETH_P_IPV6): {359		struct in6_addr src;360 361		if (nla_len(attr) != sizeof(struct in6_addr)) {362			NL_SET_ERR_MSG_MOD(extack, "IPv6 invalid source address length");363			return false;364		}365		src = nla_get_in6_addr(attr);366		if (ipv6_addr_is_multicast(&src)) {367			NL_SET_ERR_MSG_MOD(extack, "IPv6 multicast source address is not allowed");368			return false;369		}370		break;371	}372#endif373	default:374		NL_SET_ERR_MSG_MOD(extack, "Invalid protocol used with source address");375		return false;376	}377 378	return true;379}380 381static void vxlan_mdb_group_set(struct vxlan_mdb_entry_key *group,382				const struct br_mdb_entry *entry,383				const struct nlattr *source_attr)384{385	switch (entry->addr.proto) {386	case htons(ETH_P_IP):387		group->dst.sa.sa_family = AF_INET;388		group->dst.sin.sin_addr.s_addr = entry->addr.u.ip4;389		break;390#if IS_ENABLED(CONFIG_IPV6)391	case htons(ETH_P_IPV6):392		group->dst.sa.sa_family = AF_INET6;393		group->dst.sin6.sin6_addr = entry->addr.u.ip6;394		break;395#endif396	}397 398	if (source_attr)399		vxlan_nla_get_addr(&group->src, source_attr);400}401 402static bool vxlan_mdb_is_star_g(const struct vxlan_mdb_entry_key *group)403{404	return !vxlan_addr_any(&group->dst) && vxlan_addr_any(&group->src);405}406 407static bool vxlan_mdb_is_sg(const struct vxlan_mdb_entry_key *group)408{409	return !vxlan_addr_any(&group->dst) && !vxlan_addr_any(&group->src);410}411 412static int vxlan_mdb_config_src_entry_init(struct vxlan_mdb_config *cfg,413					   __be16 proto,414					   const struct nlattr *src_entry,415					   struct netlink_ext_ack *extack)416{417	struct nlattr *tb[MDBE_SRCATTR_MAX + 1];418	struct vxlan_mdb_config_src_entry *src;419	int err;420 421	err = nla_parse_nested(tb, MDBE_SRCATTR_MAX, src_entry,422			       vxlan_mdbe_src_list_entry_pol, extack);423	if (err)424		return err;425 426	if (NL_REQ_ATTR_CHECK(extack, src_entry, tb, MDBE_SRCATTR_ADDRESS))427		return -EINVAL;428 429	if (!vxlan_mdb_is_valid_source(tb[MDBE_SRCATTR_ADDRESS], proto,430				       extack))431		return -EINVAL;432 433	src = kzalloc(sizeof(*src), GFP_KERNEL);434	if (!src)435		return -ENOMEM;436 437	err = vxlan_nla_get_addr(&src->addr, tb[MDBE_SRCATTR_ADDRESS]);438	if (err)439		goto err_free_src;440 441	list_add_tail(&src->node, &cfg->src_list);442 443	return 0;444 445err_free_src:446	kfree(src);447	return err;448}449 450static void451vxlan_mdb_config_src_entry_fini(struct vxlan_mdb_config_src_entry *src)452{453	list_del(&src->node);454	kfree(src);455}456 457static int vxlan_mdb_config_src_list_init(struct vxlan_mdb_config *cfg,458					  __be16 proto,459					  const struct nlattr *src_list,460					  struct netlink_ext_ack *extack)461{462	struct vxlan_mdb_config_src_entry *src, *tmp;463	struct nlattr *src_entry;464	int rem, err;465 466	nla_for_each_nested(src_entry, src_list, rem) {467		err = vxlan_mdb_config_src_entry_init(cfg, proto, src_entry,468						      extack);469		if (err)470			goto err_src_entry_init;471	}472 473	return 0;474 475err_src_entry_init:476	list_for_each_entry_safe_reverse(src, tmp, &cfg->src_list, node)477		vxlan_mdb_config_src_entry_fini(src);478	return err;479}480 481static void vxlan_mdb_config_src_list_fini(struct vxlan_mdb_config *cfg)482{483	struct vxlan_mdb_config_src_entry *src, *tmp;484 485	list_for_each_entry_safe_reverse(src, tmp, &cfg->src_list, node)486		vxlan_mdb_config_src_entry_fini(src);487}488 489static int vxlan_mdb_config_attrs_init(struct vxlan_mdb_config *cfg,490				       const struct br_mdb_entry *entry,491				       const struct nlattr *set_attrs,492				       struct netlink_ext_ack *extack)493{494	struct nlattr *mdbe_attrs[MDBE_ATTR_MAX + 1];495	int err;496 497	err = nla_parse_nested(mdbe_attrs, MDBE_ATTR_MAX, set_attrs,498			       vxlan_mdbe_attrs_pol, extack);499	if (err)500		return err;501 502	if (NL_REQ_ATTR_CHECK(extack, set_attrs, mdbe_attrs, MDBE_ATTR_DST)) {503		NL_SET_ERR_MSG_MOD(extack, "Missing remote destination IP address");504		return -EINVAL;505	}506 507	if (mdbe_attrs[MDBE_ATTR_SOURCE] &&508	    !vxlan_mdb_is_valid_source(mdbe_attrs[MDBE_ATTR_SOURCE],509				       entry->addr.proto, extack))510		return -EINVAL;511 512	vxlan_mdb_group_set(&cfg->group, entry, mdbe_attrs[MDBE_ATTR_SOURCE]);513 514	/* rtnetlink code only validates that IPv4 group address is515	 * multicast.516	 */517	if (!vxlan_addr_is_multicast(&cfg->group.dst) &&518	    !vxlan_addr_any(&cfg->group.dst)) {519		NL_SET_ERR_MSG_MOD(extack, "Group address is not multicast");520		return -EINVAL;521	}522 523	if (vxlan_addr_any(&cfg->group.dst) &&524	    mdbe_attrs[MDBE_ATTR_SOURCE]) {525		NL_SET_ERR_MSG_MOD(extack, "Source cannot be specified for the all-zeros entry");526		return -EINVAL;527	}528 529	if (vxlan_mdb_is_sg(&cfg->group))530		cfg->filter_mode = MCAST_INCLUDE;531 532	if (mdbe_attrs[MDBE_ATTR_GROUP_MODE]) {533		if (!vxlan_mdb_is_star_g(&cfg->group)) {534			NL_SET_ERR_MSG_MOD(extack, "Filter mode can only be set for (*, G) entries");535			return -EINVAL;536		}537		cfg->filter_mode = nla_get_u8(mdbe_attrs[MDBE_ATTR_GROUP_MODE]);538	}539 540	if (mdbe_attrs[MDBE_ATTR_SRC_LIST]) {541		if (!vxlan_mdb_is_star_g(&cfg->group)) {542			NL_SET_ERR_MSG_MOD(extack, "Source list can only be set for (*, G) entries");543			return -EINVAL;544		}545		if (!mdbe_attrs[MDBE_ATTR_GROUP_MODE]) {546			NL_SET_ERR_MSG_MOD(extack, "Source list cannot be set without filter mode");547			return -EINVAL;548		}549		err = vxlan_mdb_config_src_list_init(cfg, entry->addr.proto,550						     mdbe_attrs[MDBE_ATTR_SRC_LIST],551						     extack);552		if (err)553			return err;554	}555 556	if (vxlan_mdb_is_star_g(&cfg->group) && list_empty(&cfg->src_list) &&557	    cfg->filter_mode == MCAST_INCLUDE) {558		NL_SET_ERR_MSG_MOD(extack, "Cannot add (*, G) INCLUDE with an empty source list");559		return -EINVAL;560	}561 562	if (mdbe_attrs[MDBE_ATTR_RTPROT])563		cfg->rt_protocol = nla_get_u8(mdbe_attrs[MDBE_ATTR_RTPROT]);564 565	err = vxlan_nla_get_addr(&cfg->remote_ip, mdbe_attrs[MDBE_ATTR_DST]);566	if (err) {567		NL_SET_ERR_MSG_MOD(extack, "Invalid remote destination address");568		goto err_src_list_fini;569	}570 571	if (mdbe_attrs[MDBE_ATTR_DST_PORT])572		cfg->remote_port =573			cpu_to_be16(nla_get_u16(mdbe_attrs[MDBE_ATTR_DST_PORT]));574 575	if (mdbe_attrs[MDBE_ATTR_VNI])576		cfg->remote_vni =577			cpu_to_be32(nla_get_u32(mdbe_attrs[MDBE_ATTR_VNI]));578 579	if (mdbe_attrs[MDBE_ATTR_IFINDEX]) {580		cfg->remote_ifindex =581			nla_get_s32(mdbe_attrs[MDBE_ATTR_IFINDEX]);582		if (!__dev_get_by_index(cfg->vxlan->net, cfg->remote_ifindex)) {583			NL_SET_ERR_MSG_MOD(extack, "Outgoing interface not found");584			err = -EINVAL;585			goto err_src_list_fini;586		}587	}588 589	if (mdbe_attrs[MDBE_ATTR_SRC_VNI])590		cfg->group.vni =591			cpu_to_be32(nla_get_u32(mdbe_attrs[MDBE_ATTR_SRC_VNI]));592 593	return 0;594 595err_src_list_fini:596	vxlan_mdb_config_src_list_fini(cfg);597	return err;598}599 600static int vxlan_mdb_config_init(struct vxlan_mdb_config *cfg,601				 struct net_device *dev, struct nlattr *tb[],602				 u16 nlmsg_flags,603				 struct netlink_ext_ack *extack)604{605	struct br_mdb_entry *entry = nla_data(tb[MDBA_SET_ENTRY]);606	struct vxlan_dev *vxlan = netdev_priv(dev);607 608	memset(cfg, 0, sizeof(*cfg));609	cfg->vxlan = vxlan;610	cfg->group.vni = vxlan->default_dst.remote_vni;611	INIT_LIST_HEAD(&cfg->src_list);612	cfg->nlflags = nlmsg_flags;613	cfg->filter_mode = MCAST_EXCLUDE;614	cfg->rt_protocol = RTPROT_STATIC;615	cfg->remote_vni = vxlan->default_dst.remote_vni;616	cfg->remote_port = vxlan->cfg.dst_port;617 618	if (entry->ifindex != dev->ifindex) {619		NL_SET_ERR_MSG_MOD(extack, "Port net device must be the VXLAN net device");620		return -EINVAL;621	}622 623	/* State is not part of the entry key and can be ignored on deletion624	 * requests.625	 */626	if ((nlmsg_flags & (NLM_F_CREATE | NLM_F_REPLACE)) &&627	    entry->state != MDB_PERMANENT) {628		NL_SET_ERR_MSG_MOD(extack, "MDB entry must be permanent");629		return -EINVAL;630	}631 632	if (entry->flags) {633		NL_SET_ERR_MSG_MOD(extack, "Invalid MDB entry flags");634		return -EINVAL;635	}636 637	if (entry->vid) {638		NL_SET_ERR_MSG_MOD(extack, "VID must not be specified");639		return -EINVAL;640	}641 642	if (entry->addr.proto != htons(ETH_P_IP) &&643	    entry->addr.proto != htons(ETH_P_IPV6)) {644		NL_SET_ERR_MSG_MOD(extack, "Group address must be an IPv4 / IPv6 address");645		return -EINVAL;646	}647 648	if (NL_REQ_ATTR_CHECK(extack, NULL, tb, MDBA_SET_ENTRY_ATTRS)) {649		NL_SET_ERR_MSG_MOD(extack, "Missing MDBA_SET_ENTRY_ATTRS attribute");650		return -EINVAL;651	}652 653	return vxlan_mdb_config_attrs_init(cfg, entry, tb[MDBA_SET_ENTRY_ATTRS],654					   extack);655}656 657static void vxlan_mdb_config_fini(struct vxlan_mdb_config *cfg)658{659	vxlan_mdb_config_src_list_fini(cfg);660}661 662static struct vxlan_mdb_entry *663vxlan_mdb_entry_lookup(struct vxlan_dev *vxlan,664		       const struct vxlan_mdb_entry_key *group)665{666	return rhashtable_lookup_fast(&vxlan->mdb_tbl, group,667				      vxlan_mdb_rht_params);668}669 670static struct vxlan_mdb_remote *671vxlan_mdb_remote_lookup(const struct vxlan_mdb_entry *mdb_entry,672			const union vxlan_addr *addr)673{674	struct vxlan_mdb_remote *remote;675 676	list_for_each_entry(remote, &mdb_entry->remotes, list) {677		struct vxlan_rdst *rd = rtnl_dereference(remote->rd);678 679		if (vxlan_addr_equal(addr, &rd->remote_ip))680			return remote;681	}682 683	return NULL;684}685 686static void vxlan_mdb_rdst_free(struct rcu_head *head)687{688	struct vxlan_rdst *rd = container_of(head, struct vxlan_rdst, rcu);689 690	dst_cache_destroy(&rd->dst_cache);691	kfree(rd);692}693 694static int vxlan_mdb_remote_rdst_init(const struct vxlan_mdb_config *cfg,695				      struct vxlan_mdb_remote *remote)696{697	struct vxlan_rdst *rd;698	int err;699 700	rd = kzalloc(sizeof(*rd), GFP_KERNEL);701	if (!rd)702		return -ENOMEM;703 704	err = dst_cache_init(&rd->dst_cache, GFP_KERNEL);705	if (err)706		goto err_free_rdst;707 708	rd->remote_ip = cfg->remote_ip;709	rd->remote_port = cfg->remote_port;710	rd->remote_vni = cfg->remote_vni;711	rd->remote_ifindex = cfg->remote_ifindex;712	rcu_assign_pointer(remote->rd, rd);713 714	return 0;715 716err_free_rdst:717	kfree(rd);718	return err;719}720 721static void vxlan_mdb_remote_rdst_fini(struct vxlan_rdst *rd)722{723	call_rcu(&rd->rcu, vxlan_mdb_rdst_free);724}725 726static int vxlan_mdb_remote_init(const struct vxlan_mdb_config *cfg,727				 struct vxlan_mdb_remote *remote)728{729	int err;730 731	err = vxlan_mdb_remote_rdst_init(cfg, remote);732	if (err)733		return err;734 735	remote->flags = cfg->flags;736	remote->filter_mode = cfg->filter_mode;737	remote->rt_protocol = cfg->rt_protocol;738	INIT_HLIST_HEAD(&remote->src_list);739 740	return 0;741}742 743static void vxlan_mdb_remote_fini(struct vxlan_dev *vxlan,744				  struct vxlan_mdb_remote *remote)745{746	WARN_ON_ONCE(!hlist_empty(&remote->src_list));747	vxlan_mdb_remote_rdst_fini(rtnl_dereference(remote->rd));748}749 750static struct vxlan_mdb_src_entry *751vxlan_mdb_remote_src_entry_lookup(const struct vxlan_mdb_remote *remote,752				  const union vxlan_addr *addr)753{754	struct vxlan_mdb_src_entry *ent;755 756	hlist_for_each_entry(ent, &remote->src_list, node) {757		if (vxlan_addr_equal(&ent->addr, addr))758			return ent;759	}760 761	return NULL;762}763 764static struct vxlan_mdb_src_entry *765vxlan_mdb_remote_src_entry_add(struct vxlan_mdb_remote *remote,766			       const union vxlan_addr *addr)767{768	struct vxlan_mdb_src_entry *ent;769 770	ent = kzalloc(sizeof(*ent), GFP_KERNEL);771	if (!ent)772		return NULL;773 774	ent->addr = *addr;775	hlist_add_head(&ent->node, &remote->src_list);776 777	return ent;778}779 780static void781vxlan_mdb_remote_src_entry_del(struct vxlan_mdb_src_entry *ent)782{783	hlist_del(&ent->node);784	kfree(ent);785}786 787static int788vxlan_mdb_remote_src_fwd_add(const struct vxlan_mdb_config *cfg,789			     const union vxlan_addr *addr,790			     struct netlink_ext_ack *extack)791{792	struct vxlan_mdb_config sg_cfg;793 794	memset(&sg_cfg, 0, sizeof(sg_cfg));795	sg_cfg.vxlan = cfg->vxlan;796	sg_cfg.group.src = *addr;797	sg_cfg.group.dst = cfg->group.dst;798	sg_cfg.group.vni = cfg->group.vni;799	INIT_LIST_HEAD(&sg_cfg.src_list);800	sg_cfg.remote_ip = cfg->remote_ip;801	sg_cfg.remote_ifindex = cfg->remote_ifindex;802	sg_cfg.remote_vni = cfg->remote_vni;803	sg_cfg.remote_port = cfg->remote_port;804	sg_cfg.nlflags = cfg->nlflags;805	sg_cfg.filter_mode = MCAST_INCLUDE;806	if (cfg->filter_mode == MCAST_EXCLUDE)807		sg_cfg.flags = VXLAN_MDB_REMOTE_F_BLOCKED;808	sg_cfg.rt_protocol = cfg->rt_protocol;809 810	return __vxlan_mdb_add(&sg_cfg, extack);811}812 813static void814vxlan_mdb_remote_src_fwd_del(struct vxlan_dev *vxlan,815			     const struct vxlan_mdb_entry_key *group,816			     const struct vxlan_mdb_remote *remote,817			     const union vxlan_addr *addr)818{819	struct vxlan_rdst *rd = rtnl_dereference(remote->rd);820	struct vxlan_mdb_config sg_cfg;821 822	memset(&sg_cfg, 0, sizeof(sg_cfg));823	sg_cfg.vxlan = vxlan;824	sg_cfg.group.src = *addr;825	sg_cfg.group.dst = group->dst;826	sg_cfg.group.vni = group->vni;827	INIT_LIST_HEAD(&sg_cfg.src_list);828	sg_cfg.remote_ip = rd->remote_ip;829 830	__vxlan_mdb_del(&sg_cfg, NULL);831}832 833static int834vxlan_mdb_remote_src_add(const struct vxlan_mdb_config *cfg,835			 struct vxlan_mdb_remote *remote,836			 const struct vxlan_mdb_config_src_entry *src,837			 struct netlink_ext_ack *extack)838{839	struct vxlan_mdb_src_entry *ent;840	int err;841 842	ent = vxlan_mdb_remote_src_entry_lookup(remote, &src->addr);843	if (!ent) {844		ent = vxlan_mdb_remote_src_entry_add(remote, &src->addr);845		if (!ent)846			return -ENOMEM;847	} else if (!(cfg->nlflags & NLM_F_REPLACE)) {848		NL_SET_ERR_MSG_MOD(extack, "Source entry already exists");849		return -EEXIST;850	}851 852	err = vxlan_mdb_remote_src_fwd_add(cfg, &ent->addr, extack);853	if (err)854		goto err_src_del;855 856	/* Clear flags in case source entry was marked for deletion as part of857	 * replace flow.858	 */859	ent->flags = 0;860 861	return 0;862 863err_src_del:864	vxlan_mdb_remote_src_entry_del(ent);865	return err;866}867 868static void vxlan_mdb_remote_src_del(struct vxlan_dev *vxlan,869				     const struct vxlan_mdb_entry_key *group,870				     const struct vxlan_mdb_remote *remote,871				     struct vxlan_mdb_src_entry *ent)872{873	vxlan_mdb_remote_src_fwd_del(vxlan, group, remote, &ent->addr);874	vxlan_mdb_remote_src_entry_del(ent);875}876 877static int vxlan_mdb_remote_srcs_add(const struct vxlan_mdb_config *cfg,878				     struct vxlan_mdb_remote *remote,879				     struct netlink_ext_ack *extack)880{881	struct vxlan_mdb_config_src_entry *src;882	struct vxlan_mdb_src_entry *ent;883	struct hlist_node *tmp;884	int err;885 886	list_for_each_entry(src, &cfg->src_list, node) {887		err = vxlan_mdb_remote_src_add(cfg, remote, src, extack);888		if (err)889			goto err_src_del;890	}891 892	return 0;893 894err_src_del:895	hlist_for_each_entry_safe(ent, tmp, &remote->src_list, node)896		vxlan_mdb_remote_src_del(cfg->vxlan, &cfg->group, remote, ent);897	return err;898}899 900static void vxlan_mdb_remote_srcs_del(struct vxlan_dev *vxlan,901				      const struct vxlan_mdb_entry_key *group,902				      struct vxlan_mdb_remote *remote)903{904	struct vxlan_mdb_src_entry *ent;905	struct hlist_node *tmp;906 907	hlist_for_each_entry_safe(ent, tmp, &remote->src_list, node)908		vxlan_mdb_remote_src_del(vxlan, group, remote, ent);909}910 911static size_t912vxlan_mdb_nlmsg_src_list_size(const struct vxlan_mdb_entry_key *group,913			      const struct vxlan_mdb_remote *remote)914{915	struct vxlan_mdb_src_entry *ent;916	size_t nlmsg_size;917 918	if (hlist_empty(&remote->src_list))919		return 0;920 921	/* MDBA_MDB_EATTR_SRC_LIST */922	nlmsg_size = nla_total_size(0);923 924	hlist_for_each_entry(ent, &remote->src_list, node) {925			      /* MDBA_MDB_SRCLIST_ENTRY */926		nlmsg_size += nla_total_size(0) +927			      /* MDBA_MDB_SRCATTR_ADDRESS */928			      nla_total_size(vxlan_addr_size(&group->dst)) +929			      /* MDBA_MDB_SRCATTR_TIMER */930			      nla_total_size(sizeof(u8));931	}932 933	return nlmsg_size;934}935 936static size_t937vxlan_mdb_nlmsg_remote_size(const struct vxlan_dev *vxlan,938			    const struct vxlan_mdb_entry *mdb_entry,939			    const struct vxlan_mdb_remote *remote)940{941	const struct vxlan_mdb_entry_key *group = &mdb_entry->key;942	struct vxlan_rdst *rd = rtnl_dereference(remote->rd);943	size_t nlmsg_size;944 945		     /* MDBA_MDB_ENTRY_INFO */946	nlmsg_size = nla_total_size(sizeof(struct br_mdb_entry)) +947		     /* MDBA_MDB_EATTR_TIMER */948		     nla_total_size(sizeof(u32));949 950	/* MDBA_MDB_EATTR_SOURCE */951	if (vxlan_mdb_is_sg(group))952		nlmsg_size += nla_total_size(vxlan_addr_size(&group->dst));953	/* MDBA_MDB_EATTR_RTPROT */954	nlmsg_size += nla_total_size(sizeof(u8));955	/* MDBA_MDB_EATTR_SRC_LIST */956	nlmsg_size += vxlan_mdb_nlmsg_src_list_size(group, remote);957	/* MDBA_MDB_EATTR_GROUP_MODE */958	nlmsg_size += nla_total_size(sizeof(u8));959	/* MDBA_MDB_EATTR_DST */960	nlmsg_size += nla_total_size(vxlan_addr_size(&rd->remote_ip));961	/* MDBA_MDB_EATTR_DST_PORT */962	if (rd->remote_port && rd->remote_port != vxlan->cfg.dst_port)963		nlmsg_size += nla_total_size(sizeof(u16));964	/* MDBA_MDB_EATTR_VNI */965	if (rd->remote_vni != vxlan->default_dst.remote_vni)966		nlmsg_size += nla_total_size(sizeof(u32));967	/* MDBA_MDB_EATTR_IFINDEX */968	if (rd->remote_ifindex)969		nlmsg_size += nla_total_size(sizeof(u32));970	/* MDBA_MDB_EATTR_SRC_VNI */971	if ((vxlan->cfg.flags & VXLAN_F_COLLECT_METADATA) && group->vni)972		nlmsg_size += nla_total_size(sizeof(u32));973 974	return nlmsg_size;975}976 977static size_t vxlan_mdb_nlmsg_size(const struct vxlan_dev *vxlan,978				   const struct vxlan_mdb_entry *mdb_entry,979				   const struct vxlan_mdb_remote *remote)980{981	return NLMSG_ALIGN(sizeof(struct br_port_msg)) +982	       /* MDBA_MDB */983	       nla_total_size(0) +984	       /* MDBA_MDB_ENTRY */985	       nla_total_size(0) +986	       /* Remote entry */987	       vxlan_mdb_nlmsg_remote_size(vxlan, mdb_entry, remote);988}989 990static int vxlan_mdb_nlmsg_fill(const struct vxlan_dev *vxlan,991				struct sk_buff *skb,992				const struct vxlan_mdb_entry *mdb_entry,993				const struct vxlan_mdb_remote *remote,994				int type)995{996	struct nlattr *mdb_nest, *mdb_entry_nest;997	struct br_port_msg *bpm;998	struct nlmsghdr *nlh;999 1000	nlh = nlmsg_put(skb, 0, 0, type, sizeof(*bpm), 0);1001	if (!nlh)1002		return -EMSGSIZE;1003 1004	bpm = nlmsg_data(nlh);1005	memset(bpm, 0, sizeof(*bpm));1006	bpm->family  = AF_BRIDGE;1007	bpm->ifindex = vxlan->dev->ifindex;1008 1009	mdb_nest = nla_nest_start_noflag(skb, MDBA_MDB);1010	if (!mdb_nest)1011		goto cancel;1012	mdb_entry_nest = nla_nest_start_noflag(skb, MDBA_MDB_ENTRY);1013	if (!mdb_entry_nest)1014		goto cancel;1015 1016	if (vxlan_mdb_entry_info_fill(vxlan, skb, mdb_entry, remote))1017		goto cancel;1018 1019	nla_nest_end(skb, mdb_entry_nest);1020	nla_nest_end(skb, mdb_nest);1021	nlmsg_end(skb, nlh);1022 1023	return 0;1024 1025cancel:1026	nlmsg_cancel(skb, nlh);1027	return -EMSGSIZE;1028}1029 1030static void vxlan_mdb_remote_notify(const struct vxlan_dev *vxlan,1031				    const struct vxlan_mdb_entry *mdb_entry,1032				    const struct vxlan_mdb_remote *remote,1033				    int type)1034{1035	struct net *net = dev_net(vxlan->dev);1036	struct sk_buff *skb;1037	int err = -ENOBUFS;1038 1039	skb = nlmsg_new(vxlan_mdb_nlmsg_size(vxlan, mdb_entry, remote),1040			GFP_KERNEL);1041	if (!skb)1042		goto errout;1043 1044	err = vxlan_mdb_nlmsg_fill(vxlan, skb, mdb_entry, remote, type);1045	if (err) {1046		kfree_skb(skb);1047		goto errout;1048	}1049 1050	rtnl_notify(skb, net, 0, RTNLGRP_MDB, NULL, GFP_KERNEL);1051	return;1052errout:1053	rtnl_set_sk_err(net, RTNLGRP_MDB, err);1054}1055 1056static int1057vxlan_mdb_remote_srcs_replace(const struct vxlan_mdb_config *cfg,1058			      const struct vxlan_mdb_entry *mdb_entry,1059			      struct vxlan_mdb_remote *remote,1060			      struct netlink_ext_ack *extack)1061{1062	struct vxlan_dev *vxlan = cfg->vxlan;1063	struct vxlan_mdb_src_entry *ent;1064	struct hlist_node *tmp;1065	int err;1066 1067	hlist_for_each_entry(ent, &remote->src_list, node)1068		ent->flags |= VXLAN_SGRP_F_DELETE;1069 1070	err = vxlan_mdb_remote_srcs_add(cfg, remote, extack);1071	if (err)1072		goto err_clear_delete;1073 1074	hlist_for_each_entry_safe(ent, tmp, &remote->src_list, node) {1075		if (ent->flags & VXLAN_SGRP_F_DELETE)1076			vxlan_mdb_remote_src_del(vxlan, &mdb_entry->key, remote,1077						 ent);1078	}1079 1080	return 0;1081 1082err_clear_delete:1083	hlist_for_each_entry(ent, &remote->src_list, node)1084		ent->flags &= ~VXLAN_SGRP_F_DELETE;1085	return err;1086}1087 1088static int vxlan_mdb_remote_replace(const struct vxlan_mdb_config *cfg,1089				    const struct vxlan_mdb_entry *mdb_entry,1090				    struct vxlan_mdb_remote *remote,1091				    struct netlink_ext_ack *extack)1092{1093	struct vxlan_rdst *new_rd, *old_rd = rtnl_dereference(remote->rd);1094	struct vxlan_dev *vxlan = cfg->vxlan;1095	int err;1096 1097	err = vxlan_mdb_remote_rdst_init(cfg, remote);1098	if (err)1099		return err;1100	new_rd = rtnl_dereference(remote->rd);1101 1102	err = vxlan_mdb_remote_srcs_replace(cfg, mdb_entry, remote, extack);1103	if (err)1104		goto err_rdst_reset;1105 1106	WRITE_ONCE(remote->flags, cfg->flags);1107	WRITE_ONCE(remote->filter_mode, cfg->filter_mode);1108	remote->rt_protocol = cfg->rt_protocol;1109	vxlan_mdb_remote_notify(vxlan, mdb_entry, remote, RTM_NEWMDB);1110 1111	vxlan_mdb_remote_rdst_fini(old_rd);1112 1113	return 0;1114 1115err_rdst_reset:1116	rcu_assign_pointer(remote->rd, old_rd);1117	vxlan_mdb_remote_rdst_fini(new_rd);1118	return err;1119}1120 1121static int vxlan_mdb_remote_add(const struct vxlan_mdb_config *cfg,1122				struct vxlan_mdb_entry *mdb_entry,1123				struct netlink_ext_ack *extack)1124{1125	struct vxlan_mdb_remote *remote;1126	int err;1127 1128	remote = vxlan_mdb_remote_lookup(mdb_entry, &cfg->remote_ip);1129	if (remote) {1130		if (!(cfg->nlflags & NLM_F_REPLACE)) {1131			NL_SET_ERR_MSG_MOD(extack, "Replace not specified and MDB remote entry already exists");1132			return -EEXIST;1133		}1134		return vxlan_mdb_remote_replace(cfg, mdb_entry, remote, extack);1135	}1136 1137	if (!(cfg->nlflags & NLM_F_CREATE)) {1138		NL_SET_ERR_MSG_MOD(extack, "Create not specified and entry does not exist");1139		return -ENOENT;1140	}1141 1142	remote = kzalloc(sizeof(*remote), GFP_KERNEL);1143	if (!remote)1144		return -ENOMEM;1145 1146	err = vxlan_mdb_remote_init(cfg, remote);1147	if (err) {1148		NL_SET_ERR_MSG_MOD(extack, "Failed to initialize remote MDB entry");1149		goto err_free_remote;1150	}1151 1152	err = vxlan_mdb_remote_srcs_add(cfg, remote, extack);1153	if (err)1154		goto err_remote_fini;1155 1156	list_add_rcu(&remote->list, &mdb_entry->remotes);1157	vxlan_mdb_remote_notify(cfg->vxlan, mdb_entry, remote, RTM_NEWMDB);1158 1159	return 0;1160 1161err_remote_fini:1162	vxlan_mdb_remote_fini(cfg->vxlan, remote);1163err_free_remote:1164	kfree(remote);1165	return err;1166}1167 1168static void vxlan_mdb_remote_del(struct vxlan_dev *vxlan,1169				 struct vxlan_mdb_entry *mdb_entry,1170				 struct vxlan_mdb_remote *remote)1171{1172	vxlan_mdb_remote_notify(vxlan, mdb_entry, remote, RTM_DELMDB);1173	list_del_rcu(&remote->list);1174	vxlan_mdb_remote_srcs_del(vxlan, &mdb_entry->key, remote);1175	vxlan_mdb_remote_fini(vxlan, remote);1176	kfree_rcu(remote, rcu);1177}1178 1179static struct vxlan_mdb_entry *1180vxlan_mdb_entry_get(struct vxlan_dev *vxlan,1181		    const struct vxlan_mdb_entry_key *group)1182{1183	struct vxlan_mdb_entry *mdb_entry;1184	int err;1185 1186	mdb_entry = vxlan_mdb_entry_lookup(vxlan, group);1187	if (mdb_entry)1188		return mdb_entry;1189 1190	mdb_entry = kzalloc(sizeof(*mdb_entry), GFP_KERNEL);1191	if (!mdb_entry)1192		return ERR_PTR(-ENOMEM);1193 1194	INIT_LIST_HEAD(&mdb_entry->remotes);1195	memcpy(&mdb_entry->key, group, sizeof(mdb_entry->key));1196	hlist_add_head(&mdb_entry->mdb_node, &vxlan->mdb_list);1197 1198	err = rhashtable_lookup_insert_fast(&vxlan->mdb_tbl,1199					    &mdb_entry->rhnode,1200					    vxlan_mdb_rht_params);1201	if (err)1202		goto err_free_entry;1203 1204	if (hlist_is_singular_node(&mdb_entry->mdb_node, &vxlan->mdb_list))1205		vxlan->cfg.flags |= VXLAN_F_MDB;1206 1207	return mdb_entry;1208 1209err_free_entry:1210	hlist_del(&mdb_entry->mdb_node);1211	kfree(mdb_entry);1212	return ERR_PTR(err);1213}1214 1215static void vxlan_mdb_entry_put(struct vxlan_dev *vxlan,1216				struct vxlan_mdb_entry *mdb_entry)1217{1218	if (!list_empty(&mdb_entry->remotes))1219		return;1220 1221	if (hlist_is_singular_node(&mdb_entry->mdb_node, &vxlan->mdb_list))1222		vxlan->cfg.flags &= ~VXLAN_F_MDB;1223 1224	rhashtable_remove_fast(&vxlan->mdb_tbl, &mdb_entry->rhnode,1225			       vxlan_mdb_rht_params);1226	hlist_del(&mdb_entry->mdb_node);1227	kfree_rcu(mdb_entry, rcu);1228}1229 1230static int __vxlan_mdb_add(const struct vxlan_mdb_config *cfg,1231			   struct netlink_ext_ack *extack)1232{1233	struct vxlan_dev *vxlan = cfg->vxlan;1234	struct vxlan_mdb_entry *mdb_entry;1235	int err;1236 1237	mdb_entry = vxlan_mdb_entry_get(vxlan, &cfg->group);1238	if (IS_ERR(mdb_entry))1239		return PTR_ERR(mdb_entry);1240 1241	err = vxlan_mdb_remote_add(cfg, mdb_entry, extack);1242	if (err)1243		goto err_entry_put;1244 1245	vxlan->mdb_seq++;1246 1247	return 0;1248 1249err_entry_put:1250	vxlan_mdb_entry_put(vxlan, mdb_entry);1251	return err;1252}1253 1254static int __vxlan_mdb_del(const struct vxlan_mdb_config *cfg,1255			   struct netlink_ext_ack *extack)1256{1257	struct vxlan_dev *vxlan = cfg->vxlan;1258	struct vxlan_mdb_entry *mdb_entry;1259	struct vxlan_mdb_remote *remote;1260 1261	mdb_entry = vxlan_mdb_entry_lookup(vxlan, &cfg->group);1262	if (!mdb_entry) {1263		NL_SET_ERR_MSG_MOD(extack, "Did not find MDB entry");1264		return -ENOENT;1265	}1266 1267	remote = vxlan_mdb_remote_lookup(mdb_entry, &cfg->remote_ip);1268	if (!remote) {1269		NL_SET_ERR_MSG_MOD(extack, "Did not find MDB remote entry");1270		return -ENOENT;1271	}1272 1273	vxlan_mdb_remote_del(vxlan, mdb_entry, remote);1274	vxlan_mdb_entry_put(vxlan, mdb_entry);1275 1276	vxlan->mdb_seq++;1277 1278	return 0;1279}1280 1281int vxlan_mdb_add(struct net_device *dev, struct nlattr *tb[], u16 nlmsg_flags,1282		  struct netlink_ext_ack *extack)1283{1284	struct vxlan_mdb_config cfg;1285	int err;1286 1287	ASSERT_RTNL();1288 1289	err = vxlan_mdb_config_init(&cfg, dev, tb, nlmsg_flags, extack);1290	if (err)1291		return err;1292 1293	err = __vxlan_mdb_add(&cfg, extack);1294 1295	vxlan_mdb_config_fini(&cfg);1296	return err;1297}1298 1299int vxlan_mdb_del(struct net_device *dev, struct nlattr *tb[],1300		  struct netlink_ext_ack *extack)1301{1302	struct vxlan_mdb_config cfg;1303	int err;1304 1305	ASSERT_RTNL();1306 1307	err = vxlan_mdb_config_init(&cfg, dev, tb, 0, extack);1308	if (err)1309		return err;1310 1311	err = __vxlan_mdb_del(&cfg, extack);1312 1313	vxlan_mdb_config_fini(&cfg);1314	return err;1315}1316 1317static const struct nla_policy1318vxlan_mdbe_attrs_del_bulk_pol[MDBE_ATTR_MAX + 1] = {1319	[MDBE_ATTR_RTPROT] = NLA_POLICY_MIN(NLA_U8, RTPROT_STATIC),1320	[MDBE_ATTR_DST] = NLA_POLICY_RANGE(NLA_BINARY,1321					   sizeof(struct in_addr),1322					   sizeof(struct in6_addr)),1323	[MDBE_ATTR_DST_PORT] = { .type = NLA_U16 },1324	[MDBE_ATTR_VNI] = NLA_POLICY_FULL_RANGE(NLA_U32, &vni_range),1325	[MDBE_ATTR_SRC_VNI] = NLA_POLICY_FULL_RANGE(NLA_U32, &vni_range),1326	[MDBE_ATTR_STATE_MASK] = NLA_POLICY_MASK(NLA_U8, MDB_PERMANENT),1327};1328 1329static int vxlan_mdb_flush_desc_init(struct vxlan_dev *vxlan,1330				     struct vxlan_mdb_flush_desc *desc,1331				     struct nlattr *tb[],1332				     struct netlink_ext_ack *extack)1333{1334	struct br_mdb_entry *entry = nla_data(tb[MDBA_SET_ENTRY]);1335	struct nlattr *mdbe_attrs[MDBE_ATTR_MAX + 1];1336	int err;1337 1338	if (entry->ifindex && entry->ifindex != vxlan->dev->ifindex) {1339		NL_SET_ERR_MSG_MOD(extack, "Invalid port net device");1340		return -EINVAL;1341	}1342 1343	if (entry->vid) {1344		NL_SET_ERR_MSG_MOD(extack, "VID must not be specified");1345		return -EINVAL;1346	}1347 1348	if (!tb[MDBA_SET_ENTRY_ATTRS])1349		return 0;1350 1351	err = nla_parse_nested(mdbe_attrs, MDBE_ATTR_MAX,1352			       tb[MDBA_SET_ENTRY_ATTRS],1353			       vxlan_mdbe_attrs_del_bulk_pol, extack);1354	if (err)1355		return err;1356 1357	if (mdbe_attrs[MDBE_ATTR_STATE_MASK]) {1358		u8 state_mask = nla_get_u8(mdbe_attrs[MDBE_ATTR_STATE_MASK]);1359 1360		if ((state_mask & MDB_PERMANENT) && !(entry->state & MDB_PERMANENT)) {1361			NL_SET_ERR_MSG_MOD(extack, "Only permanent MDB entries are supported");1362			return -EINVAL;1363		}1364	}1365 1366	if (mdbe_attrs[MDBE_ATTR_RTPROT])1367		desc->rt_protocol = nla_get_u8(mdbe_attrs[MDBE_ATTR_RTPROT]);1368 1369	if (mdbe_attrs[MDBE_ATTR_DST])1370		vxlan_nla_get_addr(&desc->remote_ip, mdbe_attrs[MDBE_ATTR_DST]);1371 1372	if (mdbe_attrs[MDBE_ATTR_DST_PORT])1373		desc->remote_port =1374			cpu_to_be16(nla_get_u16(mdbe_attrs[MDBE_ATTR_DST_PORT]));1375 1376	if (mdbe_attrs[MDBE_ATTR_VNI])1377		desc->remote_vni =1378			cpu_to_be32(nla_get_u32(mdbe_attrs[MDBE_ATTR_VNI]));1379 1380	if (mdbe_attrs[MDBE_ATTR_SRC_VNI])1381		desc->src_vni =1382			cpu_to_be32(nla_get_u32(mdbe_attrs[MDBE_ATTR_SRC_VNI]));1383 1384	return 0;1385}1386 1387static void vxlan_mdb_remotes_flush(struct vxlan_dev *vxlan,1388				    struct vxlan_mdb_entry *mdb_entry,1389				    const struct vxlan_mdb_flush_desc *desc)1390{1391	struct vxlan_mdb_remote *remote, *tmp;1392 1393	list_for_each_entry_safe(remote, tmp, &mdb_entry->remotes, list) {1394		struct vxlan_rdst *rd = rtnl_dereference(remote->rd);1395		__be32 remote_vni;1396 1397		if (desc->remote_ip.sa.sa_family &&1398		    !vxlan_addr_equal(&desc->remote_ip, &rd->remote_ip))1399			continue;1400 1401		/* Encapsulation is performed with source VNI if remote VNI1402		 * is not set.1403		 */1404		remote_vni = rd->remote_vni ? : mdb_entry->key.vni;1405		if (desc->remote_vni && desc->remote_vni != remote_vni)1406			continue;1407 1408		if (desc->remote_port && desc->remote_port != rd->remote_port)1409			continue;1410 1411		if (desc->rt_protocol &&1412		    desc->rt_protocol != remote->rt_protocol)1413			continue;1414 1415		vxlan_mdb_remote_del(vxlan, mdb_entry, remote);1416	}1417}1418 1419static void vxlan_mdb_flush(struct vxlan_dev *vxlan,1420			    const struct vxlan_mdb_flush_desc *desc)1421{1422	struct vxlan_mdb_entry *mdb_entry;1423	struct hlist_node *tmp;1424 1425	/* The removal of an entry cannot trigger the removal of another entry1426	 * since entries are always added to the head of the list.1427	 */1428	hlist_for_each_entry_safe(mdb_entry, tmp, &vxlan->mdb_list, mdb_node) {1429		if (desc->src_vni && desc->src_vni != mdb_entry->key.vni)1430			continue;1431 1432		vxlan_mdb_remotes_flush(vxlan, mdb_entry, desc);1433		/* Entry will only be removed if its remotes list is empty. */1434		vxlan_mdb_entry_put(vxlan, mdb_entry);1435	}1436}1437 1438int vxlan_mdb_del_bulk(struct net_device *dev, struct nlattr *tb[],1439		       struct netlink_ext_ack *extack)1440{1441	struct vxlan_dev *vxlan = netdev_priv(dev);1442	struct vxlan_mdb_flush_desc desc = {};1443	int err;1444 1445	ASSERT_RTNL();1446 1447	err = vxlan_mdb_flush_desc_init(vxlan, &desc, tb, extack);1448	if (err)1449		return err;1450 1451	vxlan_mdb_flush(vxlan, &desc);1452 1453	return 0;1454}1455 1456static const struct nla_policy vxlan_mdbe_attrs_get_pol[MDBE_ATTR_MAX + 1] = {1457	[MDBE_ATTR_SOURCE] = NLA_POLICY_RANGE(NLA_BINARY,1458					      sizeof(struct in_addr),1459					      sizeof(struct in6_addr)),1460	[MDBE_ATTR_SRC_VNI] = NLA_POLICY_FULL_RANGE(NLA_U32, &vni_range),1461};1462 1463static int vxlan_mdb_get_parse(struct net_device *dev, struct nlattr *tb[],1464			       struct vxlan_mdb_entry_key *group,1465			       struct netlink_ext_ack *extack)1466{1467	struct br_mdb_entry *entry = nla_data(tb[MDBA_GET_ENTRY]);1468	struct nlattr *mdbe_attrs[MDBE_ATTR_MAX + 1];1469	struct vxlan_dev *vxlan = netdev_priv(dev);1470	int err;1471 1472	memset(group, 0, sizeof(*group));1473	group->vni = vxlan->default_dst.remote_vni;1474 1475	if (!tb[MDBA_GET_ENTRY_ATTRS]) {1476		vxlan_mdb_group_set(group, entry, NULL);1477		return 0;1478	}1479 1480	err = nla_parse_nested(mdbe_attrs, MDBE_ATTR_MAX,1481			       tb[MDBA_GET_ENTRY_ATTRS],1482			       vxlan_mdbe_attrs_get_pol, extack);1483	if (err)1484		return err;1485 1486	if (mdbe_attrs[MDBE_ATTR_SOURCE] &&1487	    !vxlan_mdb_is_valid_source(mdbe_attrs[MDBE_ATTR_SOURCE],1488				       entry->addr.proto, extack))1489		return -EINVAL;1490 1491	vxlan_mdb_group_set(group, entry, mdbe_attrs[MDBE_ATTR_SOURCE]);1492 1493	if (mdbe_attrs[MDBE_ATTR_SRC_VNI])1494		group->vni =1495			cpu_to_be32(nla_get_u32(mdbe_attrs[MDBE_ATTR_SRC_VNI]));1496 1497	return 0;1498}1499 1500static struct sk_buff *1501vxlan_mdb_get_reply_alloc(const struct vxlan_dev *vxlan,1502			  const struct vxlan_mdb_entry *mdb_entry)1503{1504	struct vxlan_mdb_remote *remote;1505	size_t nlmsg_size;1506 1507	nlmsg_size = NLMSG_ALIGN(sizeof(struct br_port_msg)) +1508		     /* MDBA_MDB */1509		     nla_total_size(0) +1510		     /* MDBA_MDB_ENTRY */1511		     nla_total_size(0);1512 1513	list_for_each_entry(remote, &mdb_entry->remotes, list)1514		nlmsg_size += vxlan_mdb_nlmsg_remote_size(vxlan, mdb_entry,1515							  remote);1516 1517	return nlmsg_new(nlmsg_size, GFP_KERNEL);1518}1519 1520static int1521vxlan_mdb_get_reply_fill(const struct vxlan_dev *vxlan,1522			 struct sk_buff *skb,1523			 const struct vxlan_mdb_entry *mdb_entry,1524			 u32 portid, u32 seq)1525{1526	struct nlattr *mdb_nest, *mdb_entry_nest;1527	struct vxlan_mdb_remote *remote;1528	struct br_port_msg *bpm;1529	struct nlmsghdr *nlh;1530	int err;1531 1532	nlh = nlmsg_put(skb, portid, seq, RTM_NEWMDB, sizeof(*bpm), 0);1533	if (!nlh)1534		return -EMSGSIZE;1535 1536	bpm = nlmsg_data(nlh);1537	memset(bpm, 0, sizeof(*bpm));1538	bpm->family  = AF_BRIDGE;1539	bpm->ifindex = vxlan->dev->ifindex;1540	mdb_nest = nla_nest_start_noflag(skb, MDBA_MDB);1541	if (!mdb_nest) {1542		err = -EMSGSIZE;1543		goto cancel;1544	}1545	mdb_entry_nest = nla_nest_start_noflag(skb, MDBA_MDB_ENTRY);1546	if (!mdb_entry_nest) {1547		err = -EMSGSIZE;1548		goto cancel;1549	}1550 1551	list_for_each_entry(remote, &mdb_entry->remotes, list) {1552		err = vxlan_mdb_entry_info_fill(vxlan, skb, mdb_entry, remote);1553		if (err)1554			goto cancel;1555	}1556 1557	nla_nest_end(skb, mdb_entry_nest);1558	nla_nest_end(skb, mdb_nest);1559	nlmsg_end(skb, nlh);1560 1561	return 0;1562 1563cancel:1564	nlmsg_cancel(skb, nlh);1565	return err;1566}1567 1568int vxlan_mdb_get(struct net_device *dev, struct nlattr *tb[], u32 portid,1569		  u32 seq, struct netlink_ext_ack *extack)1570{1571	struct vxlan_dev *vxlan = netdev_priv(dev);1572	struct vxlan_mdb_entry *mdb_entry;1573	struct vxlan_mdb_entry_key group;1574	struct sk_buff *skb;1575	int err;1576 1577	ASSERT_RTNL();1578 1579	err = vxlan_mdb_get_parse(dev, tb, &group, extack);1580	if (err)1581		return err;1582 1583	mdb_entry = vxlan_mdb_entry_lookup(vxlan, &group);1584	if (!mdb_entry) {1585		NL_SET_ERR_MSG_MOD(extack, "MDB entry not found");1586		return -ENOENT;1587	}1588 1589	skb = vxlan_mdb_get_reply_alloc(vxlan, mdb_entry);1590	if (!skb)1591		return -ENOMEM;1592 1593	err = vxlan_mdb_get_reply_fill(vxlan, skb, mdb_entry, portid, seq);1594	if (err) {1595		NL_SET_ERR_MSG_MOD(extack, "Failed to fill MDB get reply");1596		goto free;1597	}1598 1599	return rtnl_unicast(skb, dev_net(dev), portid);1600 1601free:1602	kfree_skb(skb);1603	return err;1604}1605 1606struct vxlan_mdb_entry *vxlan_mdb_entry_skb_get(struct vxlan_dev *vxlan,1607						struct sk_buff *skb,1608						__be32 src_vni)1609{1610	struct vxlan_mdb_entry *mdb_entry;1611	struct vxlan_mdb_entry_key group;1612 1613	if (!is_multicast_ether_addr(eth_hdr(skb)->h_dest) ||1614	    is_broadcast_ether_addr(eth_hdr(skb)->h_dest))1615		return NULL;1616 1617	/* When not in collect metadata mode, 'src_vni' is zero, but MDB1618	 * entries are stored with the VNI of the VXLAN device.1619	 */1620	if (!(vxlan->cfg.flags & VXLAN_F_COLLECT_METADATA))1621		src_vni = vxlan->default_dst.remote_vni;1622 1623	memset(&group, 0, sizeof(group));1624	group.vni = src_vni;1625 1626	switch (skb->protocol) {1627	case htons(ETH_P_IP):1628		if (!pskb_may_pull(skb, sizeof(struct iphdr)))1629			return NULL;1630		group.dst.sa.sa_family = AF_INET;1631		group.dst.sin.sin_addr.s_addr = ip_hdr(skb)->daddr;1632		group.src.sa.sa_family = AF_INET;1633		group.src.sin.sin_addr.s_addr = ip_hdr(skb)->saddr;1634		break;1635#if IS_ENABLED(CONFIG_IPV6)1636	case htons(ETH_P_IPV6):1637		if (!pskb_may_pull(skb, sizeof(struct ipv6hdr)))1638			return NULL;1639		group.dst.sa.sa_family = AF_INET6;1640		group.dst.sin6.sin6_addr = ipv6_hdr(skb)->daddr;1641		group.src.sa.sa_family = AF_INET6;1642		group.src.sin6.sin6_addr = ipv6_hdr(skb)->saddr;1643		break;1644#endif1645	default:1646		return NULL;1647	}1648 1649	mdb_entry = vxlan_mdb_entry_lookup(vxlan, &group);1650	if (mdb_entry)1651		return mdb_entry;1652 1653	memset(&group.src, 0, sizeof(group.src));1654	mdb_entry = vxlan_mdb_entry_lookup(vxlan, &group);1655	if (mdb_entry)1656		return mdb_entry;1657 1658	/* No (S, G) or (*, G) found. Look up the all-zeros entry, but only if1659	 * the destination IP address is not link-local multicast since we want1660	 * to transmit such traffic together with broadcast and unknown unicast1661	 * traffic.1662	 */1663	switch (skb->protocol) {1664	case htons(ETH_P_IP):1665		if (ipv4_is_local_multicast(group.dst.sin.sin_addr.s_addr))1666			return NULL;1667		group.dst.sin.sin_addr.s_addr = 0;1668		break;1669#if IS_ENABLED(CONFIG_IPV6)1670	case htons(ETH_P_IPV6):1671		if (ipv6_addr_type(&group.dst.sin6.sin6_addr) &1672		    IPV6_ADDR_LINKLOCAL)1673			return NULL;1674		memset(&group.dst.sin6.sin6_addr, 0,1675		       sizeof(group.dst.sin6.sin6_addr));1676		break;1677#endif1678	default:1679		return NULL;1680	}1681 1682	return vxlan_mdb_entry_lookup(vxlan, &group);1683}1684 1685netdev_tx_t vxlan_mdb_xmit(struct vxlan_dev *vxlan,1686			   const struct vxlan_mdb_entry *mdb_entry,1687			   struct sk_buff *skb)1688{1689	struct vxlan_mdb_remote *remote, *fremote = NULL;1690	__be32 src_vni = mdb_entry->key.vni;1691 1692	list_for_each_entry_rcu(remote, &mdb_entry->remotes, list) {1693		struct sk_buff *skb1;1694 1695		if ((vxlan_mdb_is_star_g(&mdb_entry->key) &&1696		     READ_ONCE(remote->filter_mode) == MCAST_INCLUDE) ||1697		    (READ_ONCE(remote->flags) & VXLAN_MDB_REMOTE_F_BLOCKED))1698			continue;1699 1700		if (!fremote) {1701			fremote = remote;1702			continue;1703		}1704 1705		skb1 = skb_clone(skb, GFP_ATOMIC);1706		if (skb1)1707			vxlan_xmit_one(skb1, vxlan->dev, src_vni,1708				       rcu_dereference(remote->rd), false);1709	}1710 1711	if (fremote)1712		vxlan_xmit_one(skb, vxlan->dev, src_vni,1713			       rcu_dereference(fremote->rd), false);1714	else1715		kfree_skb(skb);1716 1717	return NETDEV_TX_OK;1718}1719 1720static void vxlan_mdb_check_empty(void *ptr, void *arg)1721{1722	WARN_ON_ONCE(1);1723}1724 1725int vxlan_mdb_init(struct vxlan_dev *vxlan)1726{1727	int err;1728 1729	err = rhashtable_init(&vxlan->mdb_tbl, &vxlan_mdb_rht_params);1730	if (err)1731		return err;1732 1733	INIT_HLIST_HEAD(&vxlan->mdb_list);1734 1735	return 0;1736}1737 1738void vxlan_mdb_fini(struct vxlan_dev *vxlan)1739{1740	struct vxlan_mdb_flush_desc desc = {};1741 1742	vxlan_mdb_flush(vxlan, &desc);1743	WARN_ON_ONCE(vxlan->cfg.flags & VXLAN_F_MDB);1744	rhashtable_free_and_destroy(&vxlan->mdb_tbl, vxlan_mdb_check_empty,1745				    NULL);1746}1747