linux/net/bridge/br_fdb.c

// SPDX-License-Identifier: GPL-2.0-or-later
/*
 *	Forwarding database
 *	Linux ethernet bridge
 *
 *	Authors:
 *	Lennert Buytenhek		<[email protected]>
 */

#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 <asm/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 =;

static struct kmem_cache *br_fdb_cache __read_mostly;

int __init br_fdb_init(void)
{}

void br_fdb_fini(void)
{}

int br_fdb_hash_init(struct net_bridge *br)
{}

void br_fdb_hash_fini(struct net_bridge *br)
{}

/* 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)
{}

static inline int has_expired(const struct net_bridge *br,
				  const struct net_bridge_fdb_entry *fdb)
{}

static void fdb_rcu_free(struct rcu_head *head)
{}

static int fdb_to_nud(const struct net_bridge *br,
		      const struct net_bridge_fdb_entry *fdb)
{}

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)
{}

static inline size_t fdb_nlmsg_size(void)
{}

static void fdb_notify(struct net_bridge *br,
		       const struct net_bridge_fdb_entry *fdb, int type,
		       bool swdev_notify)
{}

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

/* 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_device *br_fdb_find_port(const struct net_device *br_dev,
				    const unsigned char *addr,
				    __u16 vid)
{}
EXPORT_SYMBOL_GPL();

struct net_bridge_fdb_entry *br_fdb_find_rcu(struct net_bridge *br,
					     const unsigned char *addr,
					     __u16 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)
{}

/* 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)
{}

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

/* 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)
{}

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

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)
{}

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

void br_fdb_changeaddr(struct net_bridge_port *p, const unsigned char *newaddr)
{}

void br_fdb_change_mac_address(struct net_bridge *br, const u8 *newaddr)
{}

void br_fdb_cleanup(struct work_struct *work)
{}

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)
{}

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

static unsigned long __ndm_state_to_fdb_flags(u16 ndm_state)
{}

static unsigned long __ndm_flags_to_fdb_flags(u8 ndm_flags)
{}

static int __fdb_flush_validate_ifindex(const struct net_bridge *br,
					int ifindex,
					struct netlink_ext_ack *extack)
{}

static const struct nla_policy br_fdb_del_bulk_policy[NDA_MAX + 1] =;

int br_fdb_delete_bulk(struct nlmsghdr *nlh, struct net_device *dev,
		       struct netlink_ext_ack *extack)
{}

/* 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)
{}

#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)
{}
#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)
{}

/* 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)
{}

/* returns true if the fdb was modified */
static bool __fdb_mark_active(struct net_bridge_fdb_entry *fdb)
{}

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

/* 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)
{}

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)
{}

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

/* 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[])
{}

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[],
			struct netlink_ext_ack *extack)
{}

static const struct nla_policy br_nda_fdb_pol[NFEA_MAX + 1] =;

/* 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,
	       struct netlink_ext_ack *extack)
{}

static int fdb_delete_by_addr_and_port(struct net_bridge *br,
				       const struct net_bridge_port *p,
				       const u8 *addr, u16 vlan)
{}

static int __br_fdb_delete(struct net_bridge *br,
			   const struct net_bridge_port *p,
			   const unsigned char *addr, u16 vid)
{}

/* 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,
		  struct netlink_ext_ack *extack)
{}

int br_fdb_sync_static(struct net_bridge *br, struct net_bridge_port *p)
{}

void br_fdb_unsync_static(struct net_bridge *br, struct net_bridge_port *p)
{}

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)
{}

int br_fdb_external_learn_del(struct net_bridge *br, struct net_bridge_port *p,
			      const unsigned char *addr, u16 vid,
			      bool swdev_notify)
{}

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

void br_fdb_clear_offload(const struct net_device *dev, u16 vid)
{}
EXPORT_SYMBOL_GPL();