// SPDX-License-Identifier: GPL-2.0-or-later
/*
 *	Forwarding database
 *	Linux ethernet bridge
 *
 *	Authors:
 *	Lennert Buytenhek		<buytenh@gnu.org>
 */

#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/rculist.h>
#include <linux/spinlock.h>
#include <linux/times.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/jhash.h>
#include <linux/random.h>
#include <linux/slab.h>
#include <linux/atomic.h>
#include <linux/unaligned.h>
#include <linux/if_vlan.h>
#include <net/switchdev.h>
#include <trace/events/bridge.h>
#include "br_private.h"

static const struct rhashtable_params br_fdb_rht_params = {
	.head_offset = offsetof(struct net_bridge_fdb_entry, rhnode),
	.key_offset = offsetof(struct net_bridge_fdb_entry, key),
	.key_len = sizeof(struct net_bridge_fdb_key),
	.automatic_shrinking = true,
};

static struct kmem_cache *br_fdb_cache __read_mostly;

int __init br_fdb_init(void)
{
	br_fdb_cache = KMEM_CACHE(net_bridge_fdb_entry, SLAB_HWCACHE_ALIGN);
	if (!br_fdb_cache)
		return -ENOMEM;

	return 0;
}

void br_fdb_fini(void)
{
	kmem_cache_destroy(br_fdb_cache);
}

int br_fdb_hash_init(struct net_bridge *br)
{
	return rhashtable_init(&br->fdb_hash_tbl, &br_fdb_rht_params);
}

void br_fdb_hash_fini(struct net_bridge *br)
{
	rhashtable_destroy(&br->fdb_hash_tbl);
}

/* if topology_changing then use forward_delay (default 15 sec)
 * otherwise keep longer (default 5 minutes)
 */
static inline unsigned long hold_time(const struct net_bridge *br)
{
	return br->topology_change ? br->forward_delay : br->ageing_time;
}

static inline int has_expired(const struct net_bridge *br,
				  const struct net_bridge_fdb_entry *fdb)
{
	return !test_bit(BR_FDB_STATIC, &fdb->flags) &&
	       !test_bit(BR_FDB_ADDED_BY_EXT_LEARN, &fdb->flags) &&
	       time_before_eq(READ_ONCE(fdb->updated) + hold_time(br), jiffies);
}

static int fdb_to_nud(const struct net_bridge *br,
		      const struct net_bridge_fdb_entry *fdb)
{
	if (test_bit(BR_FDB_LOCAL, &fdb->flags))
		return NUD_PERMANENT;
	else if (test_bit(BR_FDB_STATIC, &fdb->flags))
		return NUD_NOARP;
	else if (has_expired(br, fdb))
		return NUD_STALE;
	else
		return NUD_REACHABLE;
}

static int fdb_fill_info(struct sk_buff *skb, const struct net_bridge *br,
			 const struct net_bridge_fdb_entry *fdb,
			 u32 portid, u32 seq, int type, unsigned int flags)
{
	const struct net_bridge_port *dst = READ_ONCE(fdb->dst);
	unsigned long now = jiffies;
	struct nda_cacheinfo ci;
	struct nlmsghdr *nlh;
	struct ndmsg *ndm;
	u32 ext_flags = 0;

	nlh = nlmsg_put(skb, portid, seq, type, sizeof(*ndm), flags);
	if (nlh == NULL)
		return -EMSGSIZE;

	ndm = nlmsg_data(nlh);
	ndm->ndm_family	 = AF_BRIDGE;
	ndm->ndm_pad1    = 0;
	ndm->ndm_pad2    = 0;
	ndm->ndm_flags	 = 0;
	ndm->ndm_type	 = 0;
	ndm->ndm_ifindex = dst ? dst->dev->ifindex : br->dev->ifindex;
	ndm->ndm_state   = fdb_to_nud(br, fdb);

	if (test_bit(BR_FDB_OFFLOADED, &fdb->flags))
		ndm->ndm_flags |= NTF_OFFLOADED;
	if (test_bit(BR_FDB_ADDED_BY_EXT_LEARN, &fdb->flags))
		ndm->ndm_flags |= NTF_EXT_LEARNED;
	if (test_bit(BR_FDB_STICKY, &fdb->flags))
		ndm->ndm_flags |= NTF_STICKY;
	if (test_bit(BR_FDB_LOCKED, &fdb->flags))
		ext_flags |= NTF_EXT_LOCKED;

	if (nla_put(skb, NDA_LLADDR, ETH_ALEN, &fdb->key.addr))
		goto nla_put_failure;
	if (nla_put_u32(skb, NDA_MASTER, br->dev->ifindex))
		goto nla_put_failure;
	if (nla_put_u32(skb, NDA_FLAGS_EXT, ext_flags))
		goto nla_put_failure;

	ci.ndm_used	 = jiffies_to_clock_t(now - READ_ONCE(fdb->used));
	ci.ndm_confirmed = 0;
	ci.ndm_updated	 = jiffies_to_clock_t(now - READ_ONCE(fdb->updated));
	ci.ndm_refcnt	 = 0;
	if (nla_put(skb, NDA_CACHEINFO, sizeof(ci), &ci))
		goto nla_put_failure;

	if (fdb->key.vlan_id && nla_put(skb, NDA_VLAN, sizeof(u16),
					&fdb->key.vlan_id))
		goto nla_put_failure;

	if (test_bit(BR_FDB_NOTIFY, &fdb->flags)) {
		struct nlattr *nest = nla_nest_start(skb, NDA_FDB_EXT_ATTRS);
		u8 notify_bits = FDB_NOTIFY_BIT;

		if (!nest)
			goto nla_put_failure;
		if (test_bit(BR_FDB_NOTIFY_INACTIVE, &fdb->flags))
			notify_bits |= FDB_NOTIFY_INACTIVE_BIT;

		if (nla_put_u8(skb, NFEA_ACTIVITY_NOTIFY, notify_bits)) {
			nla_nest_cancel(skb, nest);
			goto nla_put_failure;
		}

		nla_nest_end(skb, nest);
	}

	nlmsg_end(skb, nlh);
	return 0;

nla_put_failure:
	nlmsg_cancel(skb, nlh);
	return -EMSGSIZE;
}

static inline size_t fdb_nlmsg_size(void)
{
	return NLMSG_ALIGN(sizeof(struct ndmsg))
		+ nla_total_size(ETH_ALEN) /* NDA_LLADDR */
		+ nla_total_size(sizeof(u32)) /* NDA_MASTER */
		+ nla_total_size(sizeof(u32)) /* NDA_FLAGS_EXT */
		+ nla_total_size(sizeof(u16)) /* NDA_VLAN */
		+ nla_total_size(sizeof(struct nda_cacheinfo))
		+ nla_total_size(0) /* NDA_FDB_EXT_ATTRS */
		+ nla_total_size(sizeof(u8)); /* NFEA_ACTIVITY_NOTIFY */
}

static void fdb_notify(struct net_bridge *br,
		       const struct net_bridge_fdb_entry *fdb, int type,
		       bool swdev_notify)
{
	struct net *net = dev_net(br->dev);
	struct sk_buff *skb;
	int err = -ENOBUFS;

	if (swdev_notify)
		br_switchdev_fdb_notify(br, fdb, type);

	skb = nlmsg_new(fdb_nlmsg_size(), GFP_ATOMIC);
	if (skb == NULL)
		goto errout;

	err = fdb_fill_info(skb, br, fdb, 0, 0, type, 0);
	if (err < 0) {
		/* -EMSGSIZE implies BUG in fdb_nlmsg_size() */
		WARN_ON(err == -EMSGSIZE);
		kfree_skb(skb);
		goto errout;
	}
	rtnl_notify(skb, net, 0, RTNLGRP_NEIGH, NULL, GFP_ATOMIC);
	return;
errout:
	rtnl_set_sk_err(net, RTNLGRP_NEIGH, err);
}

static struct net_bridge_fdb_entry *fdb_find_rcu(struct rhashtable *tbl,
						 const unsigned char *addr,
						 __u16 vid)
{
	struct net_bridge_fdb_key key;

	WARN_ON_ONCE(!rcu_read_lock_held());

	key.vlan_id = vid;
	memcpy(key.addr.addr, addr, sizeof(key.addr.addr));

	return rhashtable_lookup(tbl, &key, br_fdb_rht_params);
}

/* requires bridge hash_lock */
static struct net_bridge_fdb_entry *br_fdb_find(struct net_bridge *br,
						const unsigned char *addr,
						__u16 vid)
{
	struct net_bridge_fdb_entry *fdb;

	lockdep_assert_held_once(&br->hash_lock);

	rcu_read_lock();
	fdb = fdb_find_rcu(&br->fdb_hash_tbl, addr, vid);
	rcu_read_unlock();

	return fdb;
}

struct net_device *br_fdb_find_port(const struct net_device *br_dev,
				    const unsigned char *addr,
				    __u16 vid)
{
	const struct net_bridge_port *dst;
	struct net_bridge_fdb_entry *f;
	struct net_device *dev = NULL;
	struct net_bridge *br;

	ASSERT_RTNL();

	if (!netif_is_bridge_master(br_dev))
		return NULL;

	br = netdev_priv(br_dev);
	rcu_read_lock();
	f = br_fdb_find_rcu(br, addr, vid);
	if (f) {
		dst = READ_ONCE(f->dst);
		if (dst)
			dev = dst->dev;
	}
	rcu_read_unlock();

	return dev;
}
EXPORT_SYMBOL_GPL(br_fdb_find_port);

struct net_bridge_fdb_entry *br_fdb_find_rcu(struct net_bridge *br,
					     const unsigned char *addr,
					     __u16 vid)
{
	return fdb_find_rcu(&br->fdb_hash_tbl, addr, vid);
}

/* When a static FDB entry is added, the mac address from the entry is
 * added to the bridge private HW address list and all required ports
 * are then updated with the new information.
 * Called under RTNL.
 */
static void fdb_add_hw_addr(struct net_bridge *br, const unsigned char *addr)
{
	int err;
	struct net_bridge_port *p;

	ASSERT_RTNL();

	list_for_each_entry(p, &br->port_list, list) {
		if (!br_promisc_port(p)) {
			err = dev_uc_add(p->dev, addr);
			if (err)
				goto undo;
		}
	}

	return;
undo:
	list_for_each_entry_continue_reverse(p, &br->port_list, list) {
		if (!br_promisc_port(p))
			dev_uc_del(p->dev, addr);
	}
}

/* When a static FDB entry is deleted, the HW address from that entry is
 * also removed from the bridge private HW address list and updates all
 * the ports with needed information.
 * Called under RTNL.
 */
static void fdb_del_hw_addr(struct net_bridge *br, const unsigned char *addr)
{
	struct net_bridge_port *p;

	ASSERT_RTNL();

	list_for_each_entry(p, &br->port_list, list) {
		if (!br_promisc_port(p))
			dev_uc_del(p->dev, addr);
	}
}

static void fdb_delete(struct net_bridge *br, struct net_bridge_fdb_entry *f,
		       bool swdev_notify)
{
	trace_fdb_delete(br, f);

	if (test_bit(BR_FDB_STATIC, &f->flags))
		fdb_del_hw_addr(br, f->key.addr.addr);

	hlist_del_init_rcu(&f->fdb_node);
	rhashtable_remove_fast(&br->fdb_hash_tbl, &f->rhnode,
			       br_fdb_rht_params);
	if (test_and_clear_bit(BR_FDB_DYNAMIC_LEARNED, &f->flags))
		atomic_dec(&br->fdb_n_learned);
	fdb_notify(br, f, RTM_DELNEIGH, swdev_notify);
	kfree_rcu(f, rcu);
}

/* Delete a local entry if no other port had the same address.
 *
 * This function should only be called on entries with BR_FDB_LOCAL set,
 * so even with BR_FDB_ADDED_BY_USER cleared we never need to increase
 * the accounting for dynamically learned entries again.
 */
static void fdb_delete_local(struct net_bridge *br,
			     const struct net_bridge_port *p,
			     struct net_bridge_fdb_entry *f)
{
	const unsigned char *addr = f->key.addr.addr;
	struct net_bridge_vlan_group *vg;
	const struct net_bridge_vlan *v;
	struct net_bridge_port *op;
	u16 vid = f->key.vlan_id;

	/* Maybe another port has same hw addr? */
	list_for_each_entry(op, &br->port_list, list) {
		vg = nbp_vlan_group(op);
		if (op != p && ether_addr_equal(op->dev->dev_addr, addr) &&
		    (!vid || br_vlan_find(vg, vid))) {
			WRITE_ONCE(f->dst, op);
			clear_bit(BR_FDB_ADDED_BY_USER, &f->flags);
			return;
		}
	}

	vg = br_vlan_group(br);
	v = br_vlan_find(vg, vid);
	/* Maybe bridge device has same hw addr? */
	if (p && ether_addr_equal(br->dev->dev_addr, addr) &&
	    (!vid || (v && br_vlan_should_use(v)))) {
		WRITE_ONCE(f->dst, NULL);
		clear_bit(BR_FDB_ADDED_BY_USER, &f->flags);
		return;
	}

	fdb_delete(br, f, true);
}

void br_fdb_find_delete_local(struct net_bridge *br,
			      const struct net_bridge_port *p,
			      const unsigned char *addr, u16 vid)
{
	struct net_bridge_fdb_entry *f;

	spin_lock_bh(&br->hash_lock);
	f = br_fdb_find(br, addr, vid);
	if (f && test_bit(BR_FDB_LOCAL, &f->flags) &&
	    !test_bit(BR_FDB_ADDED_BY_USER, &f->flags) && f->dst == p)
		fdb_delete_local(br, p, f);
	spin_unlock_bh(&br->hash_lock);
}

static struct net_bridge_fdb_entry *fdb_create(struct net_bridge *br,
					       struct net_bridge_port *source,
					       const unsigned char *addr,
					       __u16 vid,
					       unsigned long flags)
{
	bool learned = !test_bit(BR_FDB_ADDED_BY_USER, &flags) &&
		       !test_bit(BR_FDB_LOCAL, &flags);
	u32 max_learned = READ_ONCE(br->fdb_max_learned);
	struct net_bridge_fdb_entry *fdb;
	int err;

	if (likely(learned)) {
		int n_learned = atomic_read(&br->fdb_n_learned);

		if (unlikely(max_learned && n_learned >= max_learned))
			return NULL;
		__set_bit(BR_FDB_DYNAMIC_LEARNED, &flags);
	}

	fdb = kmem_cache_alloc(br_fdb_cache, GFP_ATOMIC);
	if (!fdb)
		return NULL;

	memcpy(fdb->key.addr.addr, addr, ETH_ALEN);
	WRITE_ONCE(fdb->dst, source);
	fdb->key.vlan_id = vid;
	fdb->flags = flags;
	fdb->updated = fdb->used = jiffies;
	err = rhashtable_lookup_insert_fast(&br->fdb_hash_tbl, &fdb->rhnode,
					    br_fdb_rht_params);
	if (err) {
		kmem_cache_free(br_fdb_cache, fdb);
		return NULL;
	}

	if (likely(learned))
		atomic_inc(&br->fdb_n_learned);

	hlist_add_head_rcu(&fdb->fdb_node, &br->fdb_list);

	return fdb;
}

static int fdb_add_local(struct net_bridge *br, struct net_bridge_port *source,
			 const unsigned char *addr, u16 vid)
{
	struct net_bridge_fdb_entry *fdb;

	if (!is_valid_ether_addr(addr))
		return -EINVAL;

	fdb = br_fdb_find(br, addr, vid);
	if (fdb) {
		/* it is okay to have multiple ports with same
		 * address, just use the first one.
		 */
		if (test_bit(BR_FDB_LOCAL, &fdb->flags))
			return 0;
		br_warn(br, "adding interface %s with same address as a received packet (addr:%pM, vlan:%u)\n",
			source ? source->dev->name : br->dev->name, addr, vid);
		fdb_delete(br, fdb, true);
	}

	fdb = fdb_create(br, source, addr, vid,
			 BIT(BR_FDB_LOCAL) | BIT(BR_FDB_STATIC));
	if (!fdb)
		return -ENOMEM;

	fdb_add_hw_addr(br, addr);
	fdb_notify(br, fdb, RTM_NEWNEIGH, true);
	return 0;
}

void br_fdb_changeaddr(struct net_bridge_port *p, const unsigned char *newaddr)
{
	struct net_bridge_vlan_group *vg;
	struct net_bridge_fdb_entry *f;
	struct net_bridge *br = p->br;
	struct net_bridge_vlan *v;
	bool local_vlan_0;

	local_vlan_0 = br_opt_get(br, BROPT_FDB_LOCAL_VLAN_0);

	spin_lock_bh(&br->hash_lock);
	vg = nbp_vlan_group(p);
	hlist_for_each_entry(f, &br->fdb_list, fdb_node) {
		if (f->dst == p && test_bit(BR_FDB_LOCAL, &f->flags) &&
		    !test_bit(BR_FDB_ADDED_BY_USER, &f->flags)) {
			/* delete old one */
			fdb_delete_local(br, p, f);

			/* if this port has no vlan information configured, or
			 * local entries are only kept on VLAN 0, we can safely
			 * be done at this point.
			 */
			if (!vg || !vg->num_vlans || local_vlan_0)
				goto insert;
		}
	}

insert:
	/* insert new address,  may fail if invalid address or dup. */
	fdb_add_local(br, p, newaddr, 0);

	if (!vg || !vg->num_vlans || local_vlan_0)
		goto done;

	/* Now add entries for every VLAN configured on the port.
	 * This function runs under RTNL so the bitmap will not change
	 * from under us.
	 */
	list_for_each_entry(v, &vg->vlan_list, vlist)
		fdb_add_local(br, p, newaddr, v->vid);

done:
	spin_unlock_bh(&br->hash_lock);
}

void br_fdb_change_mac_address(struct net_bridge *br, const u8 *newaddr)
{
	struct net_bridge_vlan_group *vg;
	struct net_bridge_fdb_entry *f;
	struct net_bridge_vlan *v;
	bool local_vlan_0;

	local_vlan_0 = br_opt_get(br, BROPT_FDB_LOCAL_VLAN_0);

	spin_lock_bh(&br->hash_lock);

	/* If old entry was unassociated with any port, then delete it. */
	f = br_fdb_find(br, br->dev->dev_addr, 0);
	if (f && test_bit(BR_FDB_LOCAL, &f->flags) &&
	    !f->dst && !test_bit(BR_FDB_ADDED_BY_USER, &f->flags))
		fdb_delete_local(br, NULL, f);

	fdb_add_local(br, NULL, newaddr, 0);
	vg = br_vlan_group(br);
	if (!vg || !vg->num_vlans || local_vlan_0)
		goto out;
	/* Now remove and add entries for every VLAN configured on the
	 * bridge.  This function runs under RTNL so the bitmap will not
	 * change from under us.
	 */
	list_for_each_entry(v, &vg->vlan_list, vlist) {
		if (!br_vlan_should_use(v))
			continue;
		f = br_fdb_find(br, br->dev->dev_addr, v->vid);
		if (f && test_bit(BR_FDB_LOCAL, &f->flags) &&
		    !f->dst && !test_bit(BR_FDB_ADDED_BY_USER, &f->flags))
			fdb_delete_local(br, NULL, f);
		fdb_add_local(br, NULL, newaddr, v->vid);
	}
out:
	spin_unlock_bh(&br->hash_lock);
}

void br_fdb_cleanup(struct work_struct *work)
{
	struct net_bridge *br = container_of(work, struct net_bridge,
					     gc_work.work);
	struct net_bridge_fdb_entry *f = NULL;
	unsigned long delay = hold_time(br);
	unsigned long work_delay = delay;
	unsigned long now = jiffies;

	/* this part is tricky, in order to avoid blocking learning and
	 * consequently forwarding, we rely on rcu to delete objects with
	 * delayed freeing allowing us to continue traversing
	 */
	rcu_read_lock();
	hlist_for_each_entry_rcu(f, &br->fdb_list, fdb_node) {
		unsigned long this_timer = READ_ONCE(f->updated) + delay;

		if (test_bit(BR_FDB_STATIC, &f->flags) ||
		    test_bit(BR_FDB_ADDED_BY_EXT_LEARN, &f->flags)) {
			if (test_bit(BR_FDB_NOTIFY, &f->flags)) {
				if (time_after(this_timer, now))
					work_delay = min(work_delay,
							 this_timer - now);
				else if (!test_and_set_bit(BR_FDB_NOTIFY_INACTIVE,
							   &f->flags))
					fdb_notify(br, f, RTM_NEWNEIGH, false);
			}
			continue;
		}

		if (time_after(this_timer, now)) {
			work_delay = min(work_delay, this_timer - now);
		} else {
			spin_lock_bh(&br->hash_lock);
			if (!hlist_unhashed(&f->fdb_node))
				fdb_delete(br, f, true);
			spin_unlock_bh(&br->hash_lock);
		}
	}
	rcu_read_unlock();

	/* Cleanup minimum 10 milliseconds apart */
	work_delay = max_t(unsigned long, work_delay, msecs_to_jiffies(10));
	mod_delayed_work(system_long_wq, &br->gc_work, work_delay);
}

static void br_fdb_delete_locals_per_vlan_port(struct net_bridge *br,
					       struct net_bridge_port *p)
{
	struct net_bridge_vlan_group *vg;
	struct net_bridge_vlan *v;
	struct net_device *dev;

	if (p) {
		vg = nbp_vlan_group(p);
		dev = p->dev;
	} else {
		vg = br_vlan_group(br);
		dev = br->dev;
	}

	if (!vg)
		return;

	list_for_each_entry(v, &vg->vlan_list, vlist)
		br_fdb_find_delete_local(br, p, dev->dev_addr, v->vid);
}

static void br_fdb_delete_locals_per_vlan(struct net_bridge *br)
{
	struct net_bridge_port *p;

	ASSERT_RTNL();

	list_for_each_entry(p, &br->port_list, list)
		br_fdb_delete_locals_per_vlan_port(br, p);

	br_fdb_delete_locals_per_vlan_port(br, NULL);
}

static int br_fdb_insert_locals_per_vlan_port(struct net_bridge *br,
					      struct net_bridge_port *p,
					      struct netlink_ext_ack *extack)
{
	struct net_bridge_vlan_group *vg;
	struct net_bridge_vlan *v;
	struct net_device *dev;
	int err;

	if (p) {
		vg = nbp_vlan_group(p);
		dev = p->dev;
	} else {
		vg = br_vlan_group(br);
		dev = br->dev;
	}

	if (!vg)
		return 0;

	list_for_each_entry(v, &vg->vlan_list, vlist) {
		if (!br_vlan_should_use(v))
			continue;

		err = br_fdb_add_local(br, p, dev->dev_addr, v->vid);
		if (err)
			return err;
	}

	return 0;
}

static int br_fdb_insert_locals_per_vlan(struct net_bridge *br,
					 struct netlink_ext_ack *extack)
{
	struct net_bridge_port *p;
	int err;

	ASSERT_RTNL();

	list_for_each_entry(p, &br->port_list, list) {
		err = br_fdb_insert_locals_per_vlan_port(br, p, extack);
		if (err)
			goto rollback;
	}

	err = br_fdb_insert_locals_per_vlan_port(br, NULL, extack);
	if (err)
		goto rollback;

	return 0;

rollback:
	NL_SET_ERR_MSG_MOD(extack, "fdb_local_vlan_0 toggle: FDB entry insertion failed");
	br_fdb_delete_locals_per_vlan(br);
	return err;
}

int br_fdb_toggle_local_vlan_0(struct net_bridge *br, bool on,
			       struct netlink_ext_ack *extack)
{
	if (!on)
		return br_fdb_insert_locals_per_vlan(br, extack);

	br_fdb_delete_locals_per_vlan(br);
	return 0;
}

static bool __fdb_flush_matches(const struct net_bridge *br,
				const struct net_bridge_fdb_entry *f,
				const struct net_bridge_fdb_flush_desc *desc)
{
	const struct net_bridge_port *dst = READ_ONCE(f->dst);
	int port_ifidx = dst ? dst->dev->ifindex : br->dev->ifindex;

	if (desc->vlan_id && desc->vlan_id != f->key.vlan_id)
		return false;
	if (desc->port_ifindex && desc->port_ifindex != port_ifidx)
		return false;
	if (desc->flags_mask && (f->flags & desc->flags_mask) != desc->flags)
		return false;

	return true;
}

/* Flush forwarding database entries matching the description */
void br_fdb_flush(struct net_bridge *br,
		  const struct net_bridge_fdb_flush_desc *desc)
{
	struct net_bridge_fdb_entry *f;

	rcu_read_lock();
	hlist_for_each_entry_rcu(f, &br->fdb_list, fdb_node) {
		if (!__fdb_flush_matches(br, f, desc))
			continue;

		spin_lock_bh(&br->hash_lock);
		if (!hlist_unhashed(&f->fdb_node))
			fdb_delete(br, f, true);
		spin_unlock_bh(&br->hash_lock);
	}
	rcu_read_unlock();
}

static unsigned long __ndm_state_to_fdb_flags(u16 ndm_state)
{
	unsigned long flags = 0;

	if (ndm_state & NUD_PERMANENT)
		__set_bit(BR_FDB_LOCAL, &flags);
	if (ndm_state & NUD_NOARP)
		__set_bit(BR_FDB_STATIC, &flags);

	return flags;
}

static unsigned long __ndm_flags_to_fdb_flags(u8 ndm_flags)
{
	unsigned long flags = 0;

	if (ndm_flags & NTF_USE)
		__set_bit(BR_FDB_ADDED_BY_USER, &flags);
	if (ndm_flags & NTF_EXT_LEARNED)
		__set_bit(BR_FDB_ADDED_BY_EXT_LEARN, &flags);
	if (ndm_flags & NTF_OFFLOADED)
		__set_bit(BR_FDB_OFFLOADED, &flags);
	if (ndm_flags & NTF_STICKY)
		__set_bit(BR_FDB_STICKY, &flags);

	return flags;
}

static int __fdb_flush_validate_ifindex(const struct net_bridge *br,
					int ifindex,
					struct netlink_ext_ack *extack)
{
	const struct net_device *dev;

	dev = __dev_get_by_index(dev_net(br->dev), ifindex);
	if (!dev) {
		NL_SET_ERR_MSG_MOD(extack, "Unknown flush device ifindex");
		return -ENODEV;
	}
	if (!netif_is_bridge_master(dev) && !netif_is_bridge_port(dev)) {
		NL_SET_ERR_MSG_MOD(extack, "Flush device is not a bridge or bridge port");
		return -EINVAL;
	}
	if (netif_is_bridge_master(dev) && dev != br->dev) {
		NL_SET_ERR_MSG_MOD(extack,
				   "Flush bridge device does not match target bridge device");
		return -EINVAL;
	}
	if (netif_is_bridge_port(dev)) {
		struct net_bridge_port *p = br_port_get_rtnl(dev);

		if (p->br != br) {
			NL_SET_ERR_MSG_MOD(extack, "Port belongs to a different bridge device");
			return -EINVAL;
		}
	}

	return 0;
}

static const struct nla_policy br_fdb_del_bulk_policy[NDA_MAX + 1] = {
	[NDA_VLAN]	= NLA_POLICY_RANGE(NLA_U16, 1, VLAN_N_VID - 2),
	[NDA_IFINDEX]	= NLA_POLICY_MIN(NLA_S32, 1),
	[NDA_NDM_STATE_MASK]	= { .type = NLA_U16 },
	[NDA_NDM_FLAGS_MASK]	= { .type = NLA_U8 },
};

int br_fdb_delete_bulk(struct nlmsghdr *nlh, struct net_device *dev,
		       struct netlink_ext_ack *extack)
{
	struct net_bridge_fdb_flush_desc desc = {};
	struct ndmsg *ndm = nlmsg_data(nlh);
	struct net_bridge_port *p = NULL;
	struct nlattr *tb[NDA_MAX + 1];
	struct net_bridge *br;
	u8 ndm_flags;
	int err;

	ndm_flags = ndm->ndm_flags & ~FDB_FLUSH_IGNORED_NDM_FLAGS;

	err = nlmsg_parse(nlh, sizeof(*ndm), tb, NDA_MAX,
			  br_fdb_del_bulk_policy, extack);
	if (err)
		return err;

	if (netif_is_bridge_master(dev)) {
		br = netdev_priv(dev);
	} else {
		p = br_port_get_rtnl(dev);
		if (!p) {
			NL_SET_ERR_MSG_MOD(extack, "Device is not a bridge port");
			return -EINVAL;
		}
		br = p->br;
	}

	if (tb[NDA_VLAN])
		desc.vlan_id = nla_get_u16(tb[NDA_VLAN]);

	if (ndm_flags & ~FDB_FLUSH_ALLOWED_NDM_FLAGS) {
		NL_SET_ERR_MSG(extack, "Unsupported fdb flush ndm flag bits set");
		return -EINVAL;
	}
	if (ndm->ndm_state & ~FDB_FLUSH_ALLOWED_NDM_STATES) {
		NL_SET_ERR_MSG(extack, "Unsupported fdb flush ndm state bits set");
		return -EINVAL;
	}

	desc.flags |= __ndm_state_to_fdb_flags(ndm->ndm_state);
	desc.flags |= __ndm_flags_to_fdb_flags(ndm_flags);
	if (tb[NDA_NDM_STATE_MASK]) {
		u16 ndm_state_mask = nla_get_u16(tb[NDA_NDM_STATE_MASK]);

		desc.flags_mask |= __ndm_state_to_fdb_flags(ndm_state_mask);
	}
	if (tb[NDA_NDM_FLAGS_MASK]) {
		u8 ndm_flags_mask = nla_get_u8(tb[NDA_NDM_FLAGS_MASK]);

		desc.flags_mask |= __ndm_flags_to_fdb_flags(ndm_flags_mask);
	}
	if (tb[NDA_IFINDEX]) {
		int ifidx = nla_get_s32(tb[NDA_IFINDEX]);

		err = __fdb_flush_validate_ifindex(br, ifidx, extack);
		if (err)
			return err;
		desc.port_ifindex = ifidx;
	} else if (p) {
		/* flush was invoked with port device and NTF_MASTER */
		desc.port_ifindex = p->dev->ifindex;
	}

	br_debug(br, "flushing port ifindex: %d vlan id: %u flags: 0x%lx flags mask: 0x%lx\n",
		 desc.port_ifindex, desc.vlan_id, desc.flags, desc.flags_mask);

	br_fdb_flush(br, &desc);

	return 0;
}

/* Flush all entries referring to a specific port.
 * if do_all is set also flush static entries
 * if vid is set delete all entries that match the vlan_id
 */
void br_fdb_delete_by_port(struct net_bridge *br,
			   const struct net_bridge_port *p,
			   u16 vid,
			   int do_all)
{
	struct net_bridge_fdb_entry *f;
	struct hlist_node *tmp;

	spin_lock_bh(&br->hash_lock);
	hlist_for_each_entry_safe(f, tmp, &br->fdb_list, fdb_node) {
		if (f->dst != p)
			continue;

		if (!do_all)
			if (test_bit(BR_FDB_STATIC, &f->flags) ||
			    (test_bit(BR_FDB_ADDED_BY_EXT_LEARN, &f->flags) &&
			     !test_bit(BR_FDB_OFFLOADED, &f->flags)) ||
			    (vid && f->key.vlan_id != vid))
				continue;

		if (test_bit(BR_FDB_LOCAL, &f->flags))
			fdb_delete_local(br, p, f);
		else
			fdb_delete(br, f, true);
	}
	spin_unlock_bh(&br->hash_lock);
}

#if IS_ENABLED(CONFIG_ATM_LANE)
/* Interface used by ATM LANE hook to test
 * if an addr is on some other bridge port */
int br_fdb_test_addr(struct net_device *dev, unsigned char *addr)
{
	struct net_bridge_fdb_entry *fdb;
	struct net_bridge_port *port;
	int ret;

	rcu_read_lock();
	port = br_port_get_rcu(dev);
	if (!port)
		ret = 0;
	else {
		const struct net_bridge_port *dst = NULL;

		fdb = br_fdb_find_rcu(port->br, addr, 0);
		if (fdb)
			dst = READ_ONCE(fdb->dst);

		ret = dst && dst->dev != dev &&
		      dst->state == BR_STATE_FORWARDING;
	}
	rcu_read_unlock();

	return ret;
}
#endif /* CONFIG_ATM_LANE */

/*
 * Fill buffer with forwarding table records in
 * the API format.
 */
int br_fdb_fillbuf(struct net_bridge *br, void *buf,
		   unsigned long maxnum, unsigned long skip)
{
	const struct net_bridge_port *dst;
	struct net_bridge_fdb_entry *f;
	struct __fdb_entry *fe = buf;
	unsigned long delta;
	int num = 0;

	memset(buf, 0, maxnum*sizeof(struct __fdb_entry));

	rcu_read_lock();
	hlist_for_each_entry_rcu(f, &br->fdb_list, fdb_node) {
		if (num >= maxnum)
			break;

		if (has_expired(br, f))
			continue;

		/* ignore pseudo entry for local MAC address */
		dst = READ_ONCE(f->dst);
		if (!dst)
			continue;

		if (skip) {
			--skip;
			continue;
		}

		/* convert from internal format to API */
		memcpy(fe->mac_addr, f->key.addr.addr, ETH_ALEN);

		/* due to ABI compat need to split into hi/lo */
		fe->port_no = dst->port_no;
		fe->port_hi = dst->port_no >> 8;

		fe->is_local = test_bit(BR_FDB_LOCAL, &f->flags);
		if (!test_bit(BR_FDB_STATIC, &f->flags)) {
			delta = jiffies - READ_ONCE(f->updated);
			fe->ageing_timer_value =
				jiffies_delta_to_clock_t(delta);
		}
		++fe;
		++num;
	}
	rcu_read_unlock();

	return num;
}

/* Add entry for local address of interface */
int br_fdb_add_local(struct net_bridge *br, struct net_bridge_port *source,
		     const unsigned char *addr, u16 vid)
{
	int ret;

	spin_lock_bh(&br->hash_lock);
	ret = fdb_add_local(br, source, addr, vid);
	spin_unlock_bh(&br->hash_lock);
	return ret;
}

/* returns true if the fdb was modified */
static bool __fdb_mark_active(struct net_bridge_fdb_entry *fdb)
{
	return !!(test_bit(BR_FDB_NOTIFY_INACTIVE, &fdb->flags) &&
		  test_and_clear_bit(BR_FDB_NOTIFY_INACTIVE, &fdb->flags));
}

void br_fdb_update(struct net_bridge *br, struct net_bridge_port *source,
		   const unsigned char *addr, u16 vid, unsigned long flags)
{
	struct net_bridge_fdb_entry *fdb;

	/* some users want to always flood. */
	if (hold_time(br) == 0)
		return;

	fdb = fdb_find_rcu(&br->fdb_hash_tbl, addr, vid);
	if (likely(fdb)) {
		/* attempt to update an entry for a local interface */
		if (unlikely(test_bit(BR_FDB_LOCAL, &fdb->flags))) {
			if (net_ratelimit())
				br_warn(br, "received packet on %s with own address as source address (addr:%pM, vlan:%u)\n",
					source->dev->name, addr, vid);
		} else {
			unsigned long now = jiffies;
			bool fdb_modified = false;

			if (now != READ_ONCE(fdb->updated)) {
				WRITE_ONCE(fdb->updated, now);
				fdb_modified = __fdb_mark_active(fdb);
			}

			/* fastpath: update of existing entry */
			if (unlikely(source != READ_ONCE(fdb->dst) &&
				     !test_bit(BR_FDB_STICKY, &fdb->flags))) {
				br_switchdev_fdb_notify(br, fdb, RTM_DELNEIGH);
				WRITE_ONCE(fdb->dst, source);
				fdb_modified = true;
				/* Take over HW learned entry */
				if (unlikely(test_bit(BR_FDB_ADDED_BY_EXT_LEARN,
						      &fdb->flags)))
					clear_bit(BR_FDB_ADDED_BY_EXT_LEARN,
						  &fdb->flags);
				/* Clear locked flag when roaming to an
				 * unlocked port.
				 */
				if (unlikely(test_bit(BR_FDB_LOCKED, &fdb->flags)))
					clear_bit(BR_FDB_LOCKED, &fdb->flags);
			}

			if (unlikely(test_bit(BR_FDB_ADDED_BY_USER, &flags))) {
				set_bit(BR_FDB_ADDED_BY_USER, &fdb->flags);
				if (test_and_clear_bit(BR_FDB_DYNAMIC_LEARNED,
						       &fdb->flags))
					atomic_dec(&br->fdb_n_learned);
			}
			if (unlikely(fdb_modified)) {
				trace_br_fdb_update(br, source, addr, vid, flags);
				fdb_notify(br, fdb, RTM_NEWNEIGH, true);
			}
		}
	} else {
		spin_lock(&br->hash_lock);
		fdb = fdb_create(br, source, addr, vid, flags);
		if (fdb) {
			trace_br_fdb_update(br, source, addr, vid, flags);
			fdb_notify(br, fdb, RTM_NEWNEIGH, true);
		}
		/* else  we lose race and someone else inserts
		 * it first, don't bother updating
		 */
		spin_unlock(&br->hash_lock);
	}
}

/* Dump information about entries, in response to GETNEIGH */
int br_fdb_dump(struct sk_buff *skb,
		struct netlink_callback *cb,
		struct net_device *dev,
		struct net_device *filter_dev,
		int *idx)
{
	struct ndo_fdb_dump_context *ctx = (void *)cb->ctx;
	struct net_bridge *br = netdev_priv(dev);
	struct net_bridge_fdb_entry *f;
	int err = 0;

	if (!netif_is_bridge_master(dev))
		return err;

	if (!filter_dev) {
		err = ndo_dflt_fdb_dump(skb, cb, dev, NULL, idx);
		if (err < 0)
			return err;
	}

	rcu_read_lock();
	hlist_for_each_entry_rcu(f, &br->fdb_list, fdb_node) {
		const struct net_bridge_port *dst = READ_ONCE(f->dst);

		if (*idx < ctx->fdb_idx)
			goto skip;
		if (filter_dev && (!dst || dst->dev != filter_dev)) {
			if (filter_dev != dev)
				goto skip;
			/* !f->dst is a special case for bridge
			 * It means the MAC belongs to the bridge
			 * Therefore need a little more filtering
			 * we only want to dump the !f->dst case
			 */
			if (dst)
				goto skip;
		}
		if (!filter_dev && dst)
			goto skip;

		err = fdb_fill_info(skb, br, f,
				    NETLINK_CB(cb->skb).portid,
				    cb->nlh->nlmsg_seq,
				    RTM_NEWNEIGH,
				    NLM_F_MULTI);
		if (err < 0)
			break;
skip:
		*idx += 1;
	}
	rcu_read_unlock();

	return err;
}

int br_fdb_get(struct sk_buff *skb,
	       struct nlattr *tb[],
	       struct net_device *dev,
	       const unsigned char *addr,
	       u16 vid, u32 portid, u32 seq,
	       struct netlink_ext_ack *extack)
{
	struct net_bridge *br = netdev_priv(dev);
	struct net_bridge_fdb_entry *f;
	int err = 0;

	rcu_read_lock();
	f = br_fdb_find_rcu(br, addr, vid);
	if (!f) {
		NL_SET_ERR_MSG(extack, "Fdb entry not found");
		err = -ENOENT;
		goto errout;
	}

	err = fdb_fill_info(skb, br, f, portid, seq,
			    RTM_NEWNEIGH, 0);
errout:
	rcu_read_unlock();
	return err;
}

/* returns true if the fdb is modified */
static bool fdb_handle_notify(struct net_bridge_fdb_entry *fdb, u8 notify)
{
	bool modified = false;

	/* allow to mark an entry as inactive, usually done on creation */
	if ((notify & FDB_NOTIFY_INACTIVE_BIT) &&
	    !test_and_set_bit(BR_FDB_NOTIFY_INACTIVE, &fdb->flags))
		modified = true;

	if ((notify & FDB_NOTIFY_BIT) &&
	    !test_and_set_bit(BR_FDB_NOTIFY, &fdb->flags)) {
		/* enabled activity tracking */
		modified = true;
	} else if (!(notify & FDB_NOTIFY_BIT) &&
		   test_and_clear_bit(BR_FDB_NOTIFY, &fdb->flags)) {
		/* disabled activity tracking, clear notify state */
		clear_bit(BR_FDB_NOTIFY_INACTIVE, &fdb->flags);
		modified = true;
	}

	return modified;
}

/* Update (create or replace) forwarding database entry */
static int fdb_add_entry(struct net_bridge *br, struct net_bridge_port *source,
			 const u8 *addr, struct ndmsg *ndm, u16 flags, u16 vid,
			 struct nlattr *nfea_tb[])
{
	bool is_sticky = !!(ndm->ndm_flags & NTF_STICKY);
	bool refresh = !nfea_tb[NFEA_DONT_REFRESH];
	struct net_bridge_fdb_entry *fdb;
	u16 state = ndm->ndm_state;
	bool modified = false;
	u8 notify = 0;

	/* If the port cannot learn allow only local and static entries */
	if (source && !(state & NUD_PERMANENT) && !(state & NUD_NOARP) &&
	    !(source->state == BR_STATE_LEARNING ||
	      source->state == BR_STATE_FORWARDING))
		return -EPERM;

	if (!source && !(state & NUD_PERMANENT)) {
		pr_info("bridge: RTM_NEWNEIGH %s without NUD_PERMANENT\n",
			br->dev->name);
		return -EINVAL;
	}

	if (is_sticky && (state & NUD_PERMANENT))
		return -EINVAL;

	if (nfea_tb[NFEA_ACTIVITY_NOTIFY]) {
		notify = nla_get_u8(nfea_tb[NFEA_ACTIVITY_NOTIFY]);
		if ((notify & ~BR_FDB_NOTIFY_SETTABLE_BITS) ||
		    (notify & BR_FDB_NOTIFY_SETTABLE_BITS) == FDB_NOTIFY_INACTIVE_BIT)
			return -EINVAL;
	}

	fdb = br_fdb_find(br, addr, vid);
	if (fdb == NULL) {
		if (!(flags & NLM_F_CREATE))
			return -ENOENT;

		fdb = fdb_create(br, source, addr, vid,
				 BIT(BR_FDB_ADDED_BY_USER));
		if (!fdb)
			return -ENOMEM;

		modified = true;
	} else {
		if (flags & NLM_F_EXCL)
			return -EEXIST;

		if (READ_ONCE(fdb->dst) != source) {
			WRITE_ONCE(fdb->dst, source);
			modified = true;
		}

		set_bit(BR_FDB_ADDED_BY_USER, &fdb->flags);
		if (test_and_clear_bit(BR_FDB_DYNAMIC_LEARNED, &fdb->flags))
			atomic_dec(&br->fdb_n_learned);
	}

	if (fdb_to_nud(br, fdb) != state) {
		if (state & NUD_PERMANENT) {
			set_bit(BR_FDB_LOCAL, &fdb->flags);
			if (!test_and_set_bit(BR_FDB_STATIC, &fdb->flags))
				fdb_add_hw_addr(br, addr);
		} else if (state & NUD_NOARP) {
			clear_bit(BR_FDB_LOCAL, &fdb->flags);
			if (!test_and_set_bit(BR_FDB_STATIC, &fdb->flags))
				fdb_add_hw_addr(br, addr);
		} else {
			clear_bit(BR_FDB_LOCAL, &fdb->flags);
			if (test_and_clear_bit(BR_FDB_STATIC, &fdb->flags))
				fdb_del_hw_addr(br, addr);
		}

		modified = true;
	}

	if (is_sticky != test_bit(BR_FDB_STICKY, &fdb->flags)) {
		change_bit(BR_FDB_STICKY, &fdb->flags);
		modified = true;
	}

	if (test_and_clear_bit(BR_FDB_LOCKED, &fdb->flags))
		modified = true;

	if (fdb_handle_notify(fdb, notify))
		modified = true;

	WRITE_ONCE(fdb->used, jiffies);
	if (modified) {
		if (refresh)
			WRITE_ONCE(fdb->updated, jiffies);
		fdb_notify(br, fdb, RTM_NEWNEIGH, true);
	}

	return 0;
}

static int __br_fdb_add(struct ndmsg *ndm, struct net_bridge *br,
			struct net_bridge_port *p, const unsigned char *addr,
			u16 nlh_flags, u16 vid, struct nlattr *nfea_tb[],
			bool *notified, struct netlink_ext_ack *extack)
{
	int err = 0;

	if (ndm->ndm_flags & NTF_USE) {
		if (!p) {
			pr_info("bridge: RTM_NEWNEIGH %s with NTF_USE is not supported\n",
				br->dev->name);
			return -EINVAL;
		}
		if (!nbp_state_should_learn(p))
			return 0;

		local_bh_disable();
		rcu_read_lock();
		br_fdb_update(br, p, addr, vid, BIT(BR_FDB_ADDED_BY_USER));
		rcu_read_unlock();
		local_bh_enable();
	} else if (ndm->ndm_flags & NTF_EXT_LEARNED) {
		if (!p && !(ndm->ndm_state & NUD_PERMANENT)) {
			NL_SET_ERR_MSG_MOD(extack,
					   "FDB entry towards bridge must be permanent");
			return -EINVAL;
		}
		err = br_fdb_external_learn_add(br, p, addr, vid, false, true);
	} else {
		spin_lock_bh(&br->hash_lock);
		err = fdb_add_entry(br, p, addr, ndm, nlh_flags, vid, nfea_tb);
		spin_unlock_bh(&br->hash_lock);
	}

	if (!err)
		*notified = true;
	return err;
}

static const struct nla_policy br_nda_fdb_pol[NFEA_MAX + 1] = {
	[NFEA_ACTIVITY_NOTIFY]	= { .type = NLA_U8 },
	[NFEA_DONT_REFRESH]	= { .type = NLA_FLAG },
};

/* Add new permanent fdb entry with RTM_NEWNEIGH */
int br_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
	       struct net_device *dev,
	       const unsigned char *addr, u16 vid, u16 nlh_flags,
	       bool *notified, struct netlink_ext_ack *extack)
{
	struct nlattr *nfea_tb[NFEA_MAX + 1], *attr;
	struct net_bridge_vlan_group *vg;
	struct net_bridge_port *p = NULL;
	struct net_bridge_vlan *v;
	struct net_bridge *br = NULL;
	u32 ext_flags = 0;
	int err = 0;

	trace_br_fdb_add(ndm, dev, addr, vid, nlh_flags);

	if (!(ndm->ndm_state & (NUD_PERMANENT|NUD_NOARP|NUD_REACHABLE))) {
		pr_info("bridge: RTM_NEWNEIGH with invalid state %#x\n", ndm->ndm_state);
		return -EINVAL;
	}

	if (is_zero_ether_addr(addr)) {
		pr_info("bridge: RTM_NEWNEIGH with invalid ether address\n");
		return -EINVAL;
	}

	if (netif_is_bridge_master(dev)) {
		br = netdev_priv(dev);
		vg = br_vlan_group(br);
	} else {
		p = br_port_get_rtnl(dev);
		if (!p) {
			pr_info("bridge: RTM_NEWNEIGH %s not a bridge port\n",
				dev->name);
			return -EINVAL;
		}
		br = p->br;
		vg = nbp_vlan_group(p);
	}

	if (tb[NDA_FLAGS_EXT])
		ext_flags = nla_get_u32(tb[NDA_FLAGS_EXT]);

	if (ext_flags & NTF_EXT_LOCKED) {
		NL_SET_ERR_MSG_MOD(extack, "Cannot add FDB entry with \"locked\" flag set");
		return -EINVAL;
	}

	if (tb[NDA_FDB_EXT_ATTRS]) {
		attr = tb[NDA_FDB_EXT_ATTRS];
		err = nla_parse_nested(nfea_tb, NFEA_MAX, attr,
				       br_nda_fdb_pol, extack);
		if (err)
			return err;
	} else {
		memset(nfea_tb, 0, sizeof(struct nlattr *) * (NFEA_MAX + 1));
	}

	if (vid) {
		v = br_vlan_find(vg, vid);
		if (!v || !br_vlan_should_use(v)) {
			pr_info("bridge: RTM_NEWNEIGH with unconfigured vlan %d on %s\n", vid, dev->name);
			return -EINVAL;
		}

		/* VID was specified, so use it. */
		err = __br_fdb_add(ndm, br, p, addr, nlh_flags, vid, nfea_tb,
				   notified, extack);
	} else {
		err = __br_fdb_add(ndm, br, p, addr, nlh_flags, 0, nfea_tb,
				   notified, extack);
		if (err || !vg || !vg->num_vlans)
			goto out;

		/* We have vlans configured on this port and user didn't
		 * specify a VLAN.  To be nice, add/update entry for every
		 * vlan on this port.
		 */
		list_for_each_entry(v, &vg->vlan_list, vlist) {
			if (!br_vlan_should_use(v))
				continue;
			err = __br_fdb_add(ndm, br, p, addr, nlh_flags, v->vid,
					   nfea_tb, notified, extack);
			if (err)
				goto out;
		}
	}

out:
	return err;
}

static int fdb_delete_by_addr_and_port(struct net_bridge *br,
				       const struct net_bridge_port *p,
				       const u8 *addr, u16 vlan, bool *notified)
{
	struct net_bridge_fdb_entry *fdb;

	fdb = br_fdb_find(br, addr, vlan);
	if (!fdb || READ_ONCE(fdb->dst) != p)
		return -ENOENT;

	fdb_delete(br, fdb, true);
	*notified = true;

	return 0;
}

static int __br_fdb_delete(struct net_bridge *br,
			   const struct net_bridge_port *p,
			   const unsigned char *addr, u16 vid, bool *notified)
{
	int err;

	spin_lock_bh(&br->hash_lock);
	err = fdb_delete_by_addr_and_port(br, p, addr, vid, notified);
	spin_unlock_bh(&br->hash_lock);

	return err;
}

/* Remove neighbor entry with RTM_DELNEIGH */
int br_fdb_delete(struct ndmsg *ndm, struct nlattr *tb[],
		  struct net_device *dev,
		  const unsigned char *addr, u16 vid, bool *notified,
		  struct netlink_ext_ack *extack)
{
	struct net_bridge_vlan_group *vg;
	struct net_bridge_port *p = NULL;
	struct net_bridge *br;
	int err;

	if (netif_is_bridge_master(dev)) {
		br = netdev_priv(dev);
		vg = br_vlan_group(br);
	} else {
		p = br_port_get_rtnl(dev);
		if (!p) {
			pr_info("bridge: RTM_DELNEIGH %s not a bridge port\n",
				dev->name);
			return -EINVAL;
		}
		vg = nbp_vlan_group(p);
		br = p->br;
	}

	if (vid) {
		err = __br_fdb_delete(br, p, addr, vid, notified);
	} else {
		struct net_bridge_vlan *v;

		err = -ENOENT;
		err &= __br_fdb_delete(br, p, addr, 0, notified);
		if (!vg || !vg->num_vlans)
			return err;

		list_for_each_entry(v, &vg->vlan_list, vlist) {
			if (!br_vlan_should_use(v))
				continue;
			err &= __br_fdb_delete(br, p, addr, v->vid, notified);
		}
	}

	return err;
}

int br_fdb_sync_static(struct net_bridge *br, struct net_bridge_port *p)
{
	struct net_bridge_fdb_entry *f, *tmp;
	int err = 0;

	ASSERT_RTNL();

	/* the key here is that static entries change only under rtnl */
	rcu_read_lock();
	hlist_for_each_entry_rcu(f, &br->fdb_list, fdb_node) {
		/* We only care for static entries */
		if (!test_bit(BR_FDB_STATIC, &f->flags))
			continue;
		err = dev_uc_add(p->dev, f->key.addr.addr);
		if (err)
			goto rollback;
	}
done:
	rcu_read_unlock();

	return err;

rollback:
	hlist_for_each_entry_rcu(tmp, &br->fdb_list, fdb_node) {
		/* We only care for static entries */
		if (!test_bit(BR_FDB_STATIC, &tmp->flags))
			continue;
		if (tmp == f)
			break;
		dev_uc_del(p->dev, tmp->key.addr.addr);
	}

	goto done;
}

void br_fdb_unsync_static(struct net_bridge *br, struct net_bridge_port *p)
{
	struct net_bridge_fdb_entry *f;

	ASSERT_RTNL();

	rcu_read_lock();
	hlist_for_each_entry_rcu(f, &br->fdb_list, fdb_node) {
		/* We only care for static entries */
		if (!test_bit(BR_FDB_STATIC, &f->flags))
			continue;

		dev_uc_del(p->dev, f->key.addr.addr);
	}
	rcu_read_unlock();
}

int br_fdb_external_learn_add(struct net_bridge *br, struct net_bridge_port *p,
			      const unsigned char *addr, u16 vid, bool locked,
			      bool swdev_notify)
{
	struct net_bridge_fdb_entry *fdb;
	bool modified = false;
	int err = 0;

	trace_br_fdb_external_learn_add(br, p, addr, vid);

	if (locked && (!p || !(p->flags & BR_PORT_MAB)))
		return -EINVAL;

	spin_lock_bh(&br->hash_lock);

	fdb = br_fdb_find(br, addr, vid);
	if (!fdb) {
		unsigned long flags = BIT(BR_FDB_ADDED_BY_EXT_LEARN);

		if (swdev_notify)
			flags |= BIT(BR_FDB_ADDED_BY_USER);

		if (!p)
			flags |= BIT(BR_FDB_LOCAL);

		if (locked)
			flags |= BIT(BR_FDB_LOCKED);

		fdb = fdb_create(br, p, addr, vid, flags);
		if (!fdb) {
			err = -ENOMEM;
			goto err_unlock;
		}
		fdb_notify(br, fdb, RTM_NEWNEIGH, swdev_notify);
	} else {
		if (locked &&
		    (!test_bit(BR_FDB_LOCKED, &fdb->flags) ||
		     READ_ONCE(fdb->dst) != p)) {
			err = -EINVAL;
			goto err_unlock;
		}

		WRITE_ONCE(fdb->updated, jiffies);

		if (READ_ONCE(fdb->dst) != p) {
			WRITE_ONCE(fdb->dst, p);
			modified = true;
		}

		if (test_and_set_bit(BR_FDB_ADDED_BY_EXT_LEARN, &fdb->flags)) {
			/* Refresh entry */
			WRITE_ONCE(fdb->used, jiffies);
		} else {
			modified = true;
		}

		if (locked != test_bit(BR_FDB_LOCKED, &fdb->flags)) {
			change_bit(BR_FDB_LOCKED, &fdb->flags);
			modified = true;
		}

		if (swdev_notify)
			set_bit(BR_FDB_ADDED_BY_USER, &fdb->flags);

		if (!p)
			set_bit(BR_FDB_LOCAL, &fdb->flags);

		if ((swdev_notify || !p) &&
		    test_and_clear_bit(BR_FDB_DYNAMIC_LEARNED, &fdb->flags))
			atomic_dec(&br->fdb_n_learned);

		if (modified)
			fdb_notify(br, fdb, RTM_NEWNEIGH, swdev_notify);
	}

err_unlock:
	spin_unlock_bh(&br->hash_lock);

	return err;
}

int br_fdb_external_learn_del(struct net_bridge *br, struct net_bridge_port *p,
			      const unsigned char *addr, u16 vid,
			      bool swdev_notify)
{
	struct net_bridge_fdb_entry *fdb;
	int err = 0;

	spin_lock_bh(&br->hash_lock);

	fdb = br_fdb_find(br, addr, vid);
	if (fdb && test_bit(BR_FDB_ADDED_BY_EXT_LEARN, &fdb->flags))
		fdb_delete(br, fdb, swdev_notify);
	else
		err = -ENOENT;

	spin_unlock_bh(&br->hash_lock);

	return err;
}

void br_fdb_offloaded_set(struct net_bridge *br, struct net_bridge_port *p,
			  const unsigned char *addr, u16 vid, bool offloaded)
{
	struct net_bridge_fdb_entry *fdb;

	spin_lock_bh(&br->hash_lock);

	fdb = br_fdb_find(br, addr, vid);
	if (fdb && offloaded != test_bit(BR_FDB_OFFLOADED, &fdb->flags))
		change_bit(BR_FDB_OFFLOADED, &fdb->flags);

	spin_unlock_bh(&br->hash_lock);
}

void br_fdb_clear_offload(const struct net_device *dev, u16 vid)
{
	struct net_bridge_fdb_entry *f;
	struct net_bridge_port *p;

	ASSERT_RTNL();

	p = br_port_get_rtnl(dev);
	if (!p)
		return;

	spin_lock_bh(&p->br->hash_lock);
	hlist_for_each_entry(f, &p->br->fdb_list, fdb_node) {
		if (f->dst == p && f->key.vlan_id == vid)
			clear_bit(BR_FDB_OFFLOADED, &f->flags);
	}
	spin_unlock_bh(&p->br->hash_lock);
}
EXPORT_SYMBOL_GPL(br_fdb_clear_offload);
