162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci *	Linux ethernet bridge
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci *	Authors:
662306a36Sopenharmony_ci *	Lennert Buytenhek		<buytenh@gnu.org>
762306a36Sopenharmony_ci */
862306a36Sopenharmony_ci
962306a36Sopenharmony_ci#ifndef _BR_PRIVATE_H
1062306a36Sopenharmony_ci#define _BR_PRIVATE_H
1162306a36Sopenharmony_ci
1262306a36Sopenharmony_ci#include <linux/netdevice.h>
1362306a36Sopenharmony_ci#include <linux/if_bridge.h>
1462306a36Sopenharmony_ci#include <linux/netpoll.h>
1562306a36Sopenharmony_ci#include <linux/u64_stats_sync.h>
1662306a36Sopenharmony_ci#include <net/route.h>
1762306a36Sopenharmony_ci#include <net/ip6_fib.h>
1862306a36Sopenharmony_ci#include <net/pkt_cls.h>
1962306a36Sopenharmony_ci#include <linux/if_vlan.h>
2062306a36Sopenharmony_ci#include <linux/rhashtable.h>
2162306a36Sopenharmony_ci#include <linux/refcount.h>
2262306a36Sopenharmony_ci
2362306a36Sopenharmony_ci#define BR_HASH_BITS 8
2462306a36Sopenharmony_ci#define BR_HASH_SIZE (1 << BR_HASH_BITS)
2562306a36Sopenharmony_ci
2662306a36Sopenharmony_ci#define BR_HOLD_TIME (1*HZ)
2762306a36Sopenharmony_ci
2862306a36Sopenharmony_ci#define BR_PORT_BITS	10
2962306a36Sopenharmony_ci#define BR_MAX_PORTS	(1<<BR_PORT_BITS)
3062306a36Sopenharmony_ci
3162306a36Sopenharmony_ci#define BR_MULTICAST_DEFAULT_HASH_MAX 4096
3262306a36Sopenharmony_ci#define BR_MULTICAST_QUERY_INTVL_MIN msecs_to_jiffies(1000)
3362306a36Sopenharmony_ci#define BR_MULTICAST_STARTUP_QUERY_INTVL_MIN BR_MULTICAST_QUERY_INTVL_MIN
3462306a36Sopenharmony_ci
3562306a36Sopenharmony_ci#define BR_HWDOM_MAX BITS_PER_LONG
3662306a36Sopenharmony_ci
3762306a36Sopenharmony_ci#define BR_VERSION	"2.3"
3862306a36Sopenharmony_ci
3962306a36Sopenharmony_ci/* Control of forwarding link local multicast */
4062306a36Sopenharmony_ci#define BR_GROUPFWD_DEFAULT	0
4162306a36Sopenharmony_ci/* Don't allow forwarding of control protocols like STP, MAC PAUSE and LACP */
4262306a36Sopenharmony_cienum {
4362306a36Sopenharmony_ci	BR_GROUPFWD_STP		= BIT(0),
4462306a36Sopenharmony_ci	BR_GROUPFWD_MACPAUSE	= BIT(1),
4562306a36Sopenharmony_ci	BR_GROUPFWD_LACP	= BIT(2),
4662306a36Sopenharmony_ci};
4762306a36Sopenharmony_ci
4862306a36Sopenharmony_ci#define BR_GROUPFWD_RESTRICTED (BR_GROUPFWD_STP | BR_GROUPFWD_MACPAUSE | \
4962306a36Sopenharmony_ci				BR_GROUPFWD_LACP)
5062306a36Sopenharmony_ci/* The Nearest Customer Bridge Group Address, 01-80-C2-00-00-[00,0B,0C,0D,0F] */
5162306a36Sopenharmony_ci#define BR_GROUPFWD_8021AD	0xB801u
5262306a36Sopenharmony_ci
5362306a36Sopenharmony_ci/* Path to usermode spanning tree program */
5462306a36Sopenharmony_ci#define BR_STP_PROG	"/sbin/bridge-stp"
5562306a36Sopenharmony_ci
5662306a36Sopenharmony_ci#define BR_FDB_NOTIFY_SETTABLE_BITS (FDB_NOTIFY_BIT | FDB_NOTIFY_INACTIVE_BIT)
5762306a36Sopenharmony_ci
5862306a36Sopenharmony_citypedef struct bridge_id bridge_id;
5962306a36Sopenharmony_citypedef struct mac_addr mac_addr;
6062306a36Sopenharmony_citypedef __u16 port_id;
6162306a36Sopenharmony_ci
6262306a36Sopenharmony_cistruct bridge_id {
6362306a36Sopenharmony_ci	unsigned char	prio[2];
6462306a36Sopenharmony_ci	unsigned char	addr[ETH_ALEN];
6562306a36Sopenharmony_ci};
6662306a36Sopenharmony_ci
6762306a36Sopenharmony_cistruct mac_addr {
6862306a36Sopenharmony_ci	unsigned char	addr[ETH_ALEN];
6962306a36Sopenharmony_ci};
7062306a36Sopenharmony_ci
7162306a36Sopenharmony_ci#ifdef CONFIG_BRIDGE_IGMP_SNOOPING
7262306a36Sopenharmony_ci/* our own querier */
7362306a36Sopenharmony_cistruct bridge_mcast_own_query {
7462306a36Sopenharmony_ci	struct timer_list	timer;
7562306a36Sopenharmony_ci	u32			startup_sent;
7662306a36Sopenharmony_ci};
7762306a36Sopenharmony_ci
7862306a36Sopenharmony_ci/* other querier */
7962306a36Sopenharmony_cistruct bridge_mcast_other_query {
8062306a36Sopenharmony_ci	struct timer_list		timer;
8162306a36Sopenharmony_ci	struct timer_list		delay_timer;
8262306a36Sopenharmony_ci};
8362306a36Sopenharmony_ci
8462306a36Sopenharmony_ci/* selected querier */
8562306a36Sopenharmony_cistruct bridge_mcast_querier {
8662306a36Sopenharmony_ci	struct br_ip addr;
8762306a36Sopenharmony_ci	int port_ifidx;
8862306a36Sopenharmony_ci	seqcount_spinlock_t seq;
8962306a36Sopenharmony_ci};
9062306a36Sopenharmony_ci
9162306a36Sopenharmony_ci/* IGMP/MLD statistics */
9262306a36Sopenharmony_cistruct bridge_mcast_stats {
9362306a36Sopenharmony_ci	struct br_mcast_stats mstats;
9462306a36Sopenharmony_ci	struct u64_stats_sync syncp;
9562306a36Sopenharmony_ci};
9662306a36Sopenharmony_ci
9762306a36Sopenharmony_cistruct br_mdb_src_entry {
9862306a36Sopenharmony_ci	struct br_ip			addr;
9962306a36Sopenharmony_ci};
10062306a36Sopenharmony_ci
10162306a36Sopenharmony_cistruct br_mdb_config {
10262306a36Sopenharmony_ci	struct net_bridge		*br;
10362306a36Sopenharmony_ci	struct net_bridge_port		*p;
10462306a36Sopenharmony_ci	struct br_mdb_entry		*entry;
10562306a36Sopenharmony_ci	struct br_ip			group;
10662306a36Sopenharmony_ci	bool				src_entry;
10762306a36Sopenharmony_ci	u8				filter_mode;
10862306a36Sopenharmony_ci	u16				nlflags;
10962306a36Sopenharmony_ci	struct br_mdb_src_entry		*src_entries;
11062306a36Sopenharmony_ci	int				num_src_entries;
11162306a36Sopenharmony_ci	u8				rt_protocol;
11262306a36Sopenharmony_ci};
11362306a36Sopenharmony_ci#endif
11462306a36Sopenharmony_ci
11562306a36Sopenharmony_ci/* net_bridge_mcast_port must be always defined due to forwarding stubs */
11662306a36Sopenharmony_cistruct net_bridge_mcast_port {
11762306a36Sopenharmony_ci#ifdef CONFIG_BRIDGE_IGMP_SNOOPING
11862306a36Sopenharmony_ci	struct net_bridge_port		*port;
11962306a36Sopenharmony_ci	struct net_bridge_vlan		*vlan;
12062306a36Sopenharmony_ci
12162306a36Sopenharmony_ci	struct bridge_mcast_own_query	ip4_own_query;
12262306a36Sopenharmony_ci	struct timer_list		ip4_mc_router_timer;
12362306a36Sopenharmony_ci	struct hlist_node		ip4_rlist;
12462306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_IPV6)
12562306a36Sopenharmony_ci	struct bridge_mcast_own_query	ip6_own_query;
12662306a36Sopenharmony_ci	struct timer_list		ip6_mc_router_timer;
12762306a36Sopenharmony_ci	struct hlist_node		ip6_rlist;
12862306a36Sopenharmony_ci#endif /* IS_ENABLED(CONFIG_IPV6) */
12962306a36Sopenharmony_ci	unsigned char			multicast_router;
13062306a36Sopenharmony_ci	u32				mdb_n_entries;
13162306a36Sopenharmony_ci	u32				mdb_max_entries;
13262306a36Sopenharmony_ci#endif /* CONFIG_BRIDGE_IGMP_SNOOPING */
13362306a36Sopenharmony_ci};
13462306a36Sopenharmony_ci
13562306a36Sopenharmony_ci/* net_bridge_mcast must be always defined due to forwarding stubs */
13662306a36Sopenharmony_cistruct net_bridge_mcast {
13762306a36Sopenharmony_ci#ifdef CONFIG_BRIDGE_IGMP_SNOOPING
13862306a36Sopenharmony_ci	struct net_bridge		*br;
13962306a36Sopenharmony_ci	struct net_bridge_vlan		*vlan;
14062306a36Sopenharmony_ci
14162306a36Sopenharmony_ci	u32				multicast_last_member_count;
14262306a36Sopenharmony_ci	u32				multicast_startup_query_count;
14362306a36Sopenharmony_ci
14462306a36Sopenharmony_ci	u8				multicast_querier;
14562306a36Sopenharmony_ci	u8				multicast_igmp_version;
14662306a36Sopenharmony_ci	u8				multicast_router;
14762306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_IPV6)
14862306a36Sopenharmony_ci	u8				multicast_mld_version;
14962306a36Sopenharmony_ci#endif
15062306a36Sopenharmony_ci	unsigned long			multicast_last_member_interval;
15162306a36Sopenharmony_ci	unsigned long			multicast_membership_interval;
15262306a36Sopenharmony_ci	unsigned long			multicast_querier_interval;
15362306a36Sopenharmony_ci	unsigned long			multicast_query_interval;
15462306a36Sopenharmony_ci	unsigned long			multicast_query_response_interval;
15562306a36Sopenharmony_ci	unsigned long			multicast_startup_query_interval;
15662306a36Sopenharmony_ci	struct hlist_head		ip4_mc_router_list;
15762306a36Sopenharmony_ci	struct timer_list		ip4_mc_router_timer;
15862306a36Sopenharmony_ci	struct bridge_mcast_other_query	ip4_other_query;
15962306a36Sopenharmony_ci	struct bridge_mcast_own_query	ip4_own_query;
16062306a36Sopenharmony_ci	struct bridge_mcast_querier	ip4_querier;
16162306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_IPV6)
16262306a36Sopenharmony_ci	struct hlist_head		ip6_mc_router_list;
16362306a36Sopenharmony_ci	struct timer_list		ip6_mc_router_timer;
16462306a36Sopenharmony_ci	struct bridge_mcast_other_query	ip6_other_query;
16562306a36Sopenharmony_ci	struct bridge_mcast_own_query	ip6_own_query;
16662306a36Sopenharmony_ci	struct bridge_mcast_querier	ip6_querier;
16762306a36Sopenharmony_ci#endif /* IS_ENABLED(CONFIG_IPV6) */
16862306a36Sopenharmony_ci#endif /* CONFIG_BRIDGE_IGMP_SNOOPING */
16962306a36Sopenharmony_ci};
17062306a36Sopenharmony_ci
17162306a36Sopenharmony_cistruct br_tunnel_info {
17262306a36Sopenharmony_ci	__be64				tunnel_id;
17362306a36Sopenharmony_ci	struct metadata_dst __rcu	*tunnel_dst;
17462306a36Sopenharmony_ci};
17562306a36Sopenharmony_ci
17662306a36Sopenharmony_ci/* private vlan flags */
17762306a36Sopenharmony_cienum {
17862306a36Sopenharmony_ci	BR_VLFLAG_PER_PORT_STATS = BIT(0),
17962306a36Sopenharmony_ci	BR_VLFLAG_ADDED_BY_SWITCHDEV = BIT(1),
18062306a36Sopenharmony_ci	BR_VLFLAG_MCAST_ENABLED = BIT(2),
18162306a36Sopenharmony_ci	BR_VLFLAG_GLOBAL_MCAST_ENABLED = BIT(3),
18262306a36Sopenharmony_ci	BR_VLFLAG_NEIGH_SUPPRESS_ENABLED = BIT(4),
18362306a36Sopenharmony_ci};
18462306a36Sopenharmony_ci
18562306a36Sopenharmony_ci/**
18662306a36Sopenharmony_ci * struct net_bridge_vlan - per-vlan entry
18762306a36Sopenharmony_ci *
18862306a36Sopenharmony_ci * @vnode: rhashtable member
18962306a36Sopenharmony_ci * @vid: VLAN id
19062306a36Sopenharmony_ci * @flags: bridge vlan flags
19162306a36Sopenharmony_ci * @priv_flags: private (in-kernel) bridge vlan flags
19262306a36Sopenharmony_ci * @state: STP state (e.g. blocking, learning, forwarding)
19362306a36Sopenharmony_ci * @stats: per-cpu VLAN statistics
19462306a36Sopenharmony_ci * @br: if MASTER flag set, this points to a bridge struct
19562306a36Sopenharmony_ci * @port: if MASTER flag unset, this points to a port struct
19662306a36Sopenharmony_ci * @refcnt: if MASTER flag set, this is bumped for each port referencing it
19762306a36Sopenharmony_ci * @brvlan: if MASTER flag unset, this points to the global per-VLAN context
19862306a36Sopenharmony_ci *          for this VLAN entry
19962306a36Sopenharmony_ci * @br_mcast_ctx: if MASTER flag set, this is the global vlan multicast context
20062306a36Sopenharmony_ci * @port_mcast_ctx: if MASTER flag unset, this is the per-port/vlan multicast
20162306a36Sopenharmony_ci *                  context
20262306a36Sopenharmony_ci * @msti: if MASTER flag set, this holds the VLANs MST instance
20362306a36Sopenharmony_ci * @vlist: sorted list of VLAN entries
20462306a36Sopenharmony_ci * @rcu: used for entry destruction
20562306a36Sopenharmony_ci *
20662306a36Sopenharmony_ci * This structure is shared between the global per-VLAN entries contained in
20762306a36Sopenharmony_ci * the bridge rhashtable and the local per-port per-VLAN entries contained in
20862306a36Sopenharmony_ci * the port's rhashtable. The union entries should be interpreted depending on
20962306a36Sopenharmony_ci * the entry flags that are set.
21062306a36Sopenharmony_ci */
21162306a36Sopenharmony_cistruct net_bridge_vlan {
21262306a36Sopenharmony_ci	struct rhash_head		vnode;
21362306a36Sopenharmony_ci	struct rhash_head		tnode;
21462306a36Sopenharmony_ci	u16				vid;
21562306a36Sopenharmony_ci	u16				flags;
21662306a36Sopenharmony_ci	u16				priv_flags;
21762306a36Sopenharmony_ci	u8				state;
21862306a36Sopenharmony_ci	struct pcpu_sw_netstats __percpu *stats;
21962306a36Sopenharmony_ci	union {
22062306a36Sopenharmony_ci		struct net_bridge	*br;
22162306a36Sopenharmony_ci		struct net_bridge_port	*port;
22262306a36Sopenharmony_ci	};
22362306a36Sopenharmony_ci	union {
22462306a36Sopenharmony_ci		refcount_t		refcnt;
22562306a36Sopenharmony_ci		struct net_bridge_vlan	*brvlan;
22662306a36Sopenharmony_ci	};
22762306a36Sopenharmony_ci
22862306a36Sopenharmony_ci	struct br_tunnel_info		tinfo;
22962306a36Sopenharmony_ci
23062306a36Sopenharmony_ci	union {
23162306a36Sopenharmony_ci		struct net_bridge_mcast		br_mcast_ctx;
23262306a36Sopenharmony_ci		struct net_bridge_mcast_port	port_mcast_ctx;
23362306a36Sopenharmony_ci	};
23462306a36Sopenharmony_ci
23562306a36Sopenharmony_ci	u16				msti;
23662306a36Sopenharmony_ci
23762306a36Sopenharmony_ci	struct list_head		vlist;
23862306a36Sopenharmony_ci
23962306a36Sopenharmony_ci	struct rcu_head			rcu;
24062306a36Sopenharmony_ci};
24162306a36Sopenharmony_ci
24262306a36Sopenharmony_ci/**
24362306a36Sopenharmony_ci * struct net_bridge_vlan_group
24462306a36Sopenharmony_ci *
24562306a36Sopenharmony_ci * @vlan_hash: VLAN entry rhashtable
24662306a36Sopenharmony_ci * @vlan_list: sorted VLAN entry list
24762306a36Sopenharmony_ci * @num_vlans: number of total VLAN entries
24862306a36Sopenharmony_ci * @pvid: PVID VLAN id
24962306a36Sopenharmony_ci * @pvid_state: PVID's STP state (e.g. forwarding, learning, blocking)
25062306a36Sopenharmony_ci *
25162306a36Sopenharmony_ci * IMPORTANT: Be careful when checking if there're VLAN entries using list
25262306a36Sopenharmony_ci *            primitives because the bridge can have entries in its list which
25362306a36Sopenharmony_ci *            are just for global context but not for filtering, i.e. they have
25462306a36Sopenharmony_ci *            the master flag set but not the brentry flag. If you have to check
25562306a36Sopenharmony_ci *            if there're "real" entries in the bridge please test @num_vlans
25662306a36Sopenharmony_ci */
25762306a36Sopenharmony_cistruct net_bridge_vlan_group {
25862306a36Sopenharmony_ci	struct rhashtable		vlan_hash;
25962306a36Sopenharmony_ci	struct rhashtable		tunnel_hash;
26062306a36Sopenharmony_ci	struct list_head		vlan_list;
26162306a36Sopenharmony_ci	u16				num_vlans;
26262306a36Sopenharmony_ci	u16				pvid;
26362306a36Sopenharmony_ci	u8				pvid_state;
26462306a36Sopenharmony_ci};
26562306a36Sopenharmony_ci
26662306a36Sopenharmony_ci/* bridge fdb flags */
26762306a36Sopenharmony_cienum {
26862306a36Sopenharmony_ci	BR_FDB_LOCAL,
26962306a36Sopenharmony_ci	BR_FDB_STATIC,
27062306a36Sopenharmony_ci	BR_FDB_STICKY,
27162306a36Sopenharmony_ci	BR_FDB_ADDED_BY_USER,
27262306a36Sopenharmony_ci	BR_FDB_ADDED_BY_EXT_LEARN,
27362306a36Sopenharmony_ci	BR_FDB_OFFLOADED,
27462306a36Sopenharmony_ci	BR_FDB_NOTIFY,
27562306a36Sopenharmony_ci	BR_FDB_NOTIFY_INACTIVE,
27662306a36Sopenharmony_ci	BR_FDB_LOCKED,
27762306a36Sopenharmony_ci};
27862306a36Sopenharmony_ci
27962306a36Sopenharmony_cistruct net_bridge_fdb_key {
28062306a36Sopenharmony_ci	mac_addr addr;
28162306a36Sopenharmony_ci	u16 vlan_id;
28262306a36Sopenharmony_ci};
28362306a36Sopenharmony_ci
28462306a36Sopenharmony_cistruct net_bridge_fdb_entry {
28562306a36Sopenharmony_ci	struct rhash_head		rhnode;
28662306a36Sopenharmony_ci	struct net_bridge_port		*dst;
28762306a36Sopenharmony_ci
28862306a36Sopenharmony_ci	struct net_bridge_fdb_key	key;
28962306a36Sopenharmony_ci	struct hlist_node		fdb_node;
29062306a36Sopenharmony_ci	unsigned long			flags;
29162306a36Sopenharmony_ci
29262306a36Sopenharmony_ci	/* write-heavy members should not affect lookups */
29362306a36Sopenharmony_ci	unsigned long			updated ____cacheline_aligned_in_smp;
29462306a36Sopenharmony_ci	unsigned long			used;
29562306a36Sopenharmony_ci
29662306a36Sopenharmony_ci	struct rcu_head			rcu;
29762306a36Sopenharmony_ci};
29862306a36Sopenharmony_ci
29962306a36Sopenharmony_cistruct net_bridge_fdb_flush_desc {
30062306a36Sopenharmony_ci	unsigned long			flags;
30162306a36Sopenharmony_ci	unsigned long			flags_mask;
30262306a36Sopenharmony_ci	int				port_ifindex;
30362306a36Sopenharmony_ci	u16				vlan_id;
30462306a36Sopenharmony_ci};
30562306a36Sopenharmony_ci
30662306a36Sopenharmony_ci#define MDB_PG_FLAGS_PERMANENT	BIT(0)
30762306a36Sopenharmony_ci#define MDB_PG_FLAGS_OFFLOAD	BIT(1)
30862306a36Sopenharmony_ci#define MDB_PG_FLAGS_FAST_LEAVE	BIT(2)
30962306a36Sopenharmony_ci#define MDB_PG_FLAGS_STAR_EXCL	BIT(3)
31062306a36Sopenharmony_ci#define MDB_PG_FLAGS_BLOCKED	BIT(4)
31162306a36Sopenharmony_ci
31262306a36Sopenharmony_ci#define PG_SRC_ENT_LIMIT	32
31362306a36Sopenharmony_ci
31462306a36Sopenharmony_ci#define BR_SGRP_F_DELETE	BIT(0)
31562306a36Sopenharmony_ci#define BR_SGRP_F_SEND		BIT(1)
31662306a36Sopenharmony_ci#define BR_SGRP_F_INSTALLED	BIT(2)
31762306a36Sopenharmony_ci#define BR_SGRP_F_USER_ADDED	BIT(3)
31862306a36Sopenharmony_ci
31962306a36Sopenharmony_cistruct net_bridge_mcast_gc {
32062306a36Sopenharmony_ci	struct hlist_node		gc_node;
32162306a36Sopenharmony_ci	void				(*destroy)(struct net_bridge_mcast_gc *gc);
32262306a36Sopenharmony_ci};
32362306a36Sopenharmony_ci
32462306a36Sopenharmony_cistruct net_bridge_group_src {
32562306a36Sopenharmony_ci	struct hlist_node		node;
32662306a36Sopenharmony_ci
32762306a36Sopenharmony_ci	struct br_ip			addr;
32862306a36Sopenharmony_ci	struct net_bridge_port_group	*pg;
32962306a36Sopenharmony_ci	u8				flags;
33062306a36Sopenharmony_ci	u8				src_query_rexmit_cnt;
33162306a36Sopenharmony_ci	struct timer_list		timer;
33262306a36Sopenharmony_ci
33362306a36Sopenharmony_ci	struct net_bridge		*br;
33462306a36Sopenharmony_ci	struct net_bridge_mcast_gc	mcast_gc;
33562306a36Sopenharmony_ci	struct rcu_head			rcu;
33662306a36Sopenharmony_ci};
33762306a36Sopenharmony_ci
33862306a36Sopenharmony_cistruct net_bridge_port_group_sg_key {
33962306a36Sopenharmony_ci	struct net_bridge_port		*port;
34062306a36Sopenharmony_ci	struct br_ip			addr;
34162306a36Sopenharmony_ci};
34262306a36Sopenharmony_ci
34362306a36Sopenharmony_cistruct net_bridge_port_group {
34462306a36Sopenharmony_ci	struct net_bridge_port_group __rcu *next;
34562306a36Sopenharmony_ci	struct net_bridge_port_group_sg_key key;
34662306a36Sopenharmony_ci	unsigned char			eth_addr[ETH_ALEN] __aligned(2);
34762306a36Sopenharmony_ci	unsigned char			flags;
34862306a36Sopenharmony_ci	unsigned char			filter_mode;
34962306a36Sopenharmony_ci	unsigned char			grp_query_rexmit_cnt;
35062306a36Sopenharmony_ci	unsigned char			rt_protocol;
35162306a36Sopenharmony_ci
35262306a36Sopenharmony_ci	struct hlist_head		src_list;
35362306a36Sopenharmony_ci	unsigned int			src_ents;
35462306a36Sopenharmony_ci	struct timer_list		timer;
35562306a36Sopenharmony_ci	struct timer_list		rexmit_timer;
35662306a36Sopenharmony_ci	struct hlist_node		mglist;
35762306a36Sopenharmony_ci	struct rb_root			eht_set_tree;
35862306a36Sopenharmony_ci	struct rb_root			eht_host_tree;
35962306a36Sopenharmony_ci
36062306a36Sopenharmony_ci	struct rhash_head		rhnode;
36162306a36Sopenharmony_ci	struct net_bridge_mcast_gc	mcast_gc;
36262306a36Sopenharmony_ci	struct rcu_head			rcu;
36362306a36Sopenharmony_ci};
36462306a36Sopenharmony_ci
36562306a36Sopenharmony_cistruct net_bridge_mdb_entry {
36662306a36Sopenharmony_ci	struct rhash_head		rhnode;
36762306a36Sopenharmony_ci	struct net_bridge		*br;
36862306a36Sopenharmony_ci	struct net_bridge_port_group __rcu *ports;
36962306a36Sopenharmony_ci	struct br_ip			addr;
37062306a36Sopenharmony_ci	bool				host_joined;
37162306a36Sopenharmony_ci
37262306a36Sopenharmony_ci	struct timer_list		timer;
37362306a36Sopenharmony_ci	struct hlist_node		mdb_node;
37462306a36Sopenharmony_ci
37562306a36Sopenharmony_ci	struct net_bridge_mcast_gc	mcast_gc;
37662306a36Sopenharmony_ci	struct rcu_head			rcu;
37762306a36Sopenharmony_ci};
37862306a36Sopenharmony_ci
37962306a36Sopenharmony_cistruct net_bridge_port {
38062306a36Sopenharmony_ci	struct net_bridge		*br;
38162306a36Sopenharmony_ci	struct net_device		*dev;
38262306a36Sopenharmony_ci	netdevice_tracker		dev_tracker;
38362306a36Sopenharmony_ci	struct list_head		list;
38462306a36Sopenharmony_ci
38562306a36Sopenharmony_ci	unsigned long			flags;
38662306a36Sopenharmony_ci#ifdef CONFIG_BRIDGE_VLAN_FILTERING
38762306a36Sopenharmony_ci	struct net_bridge_vlan_group	__rcu *vlgrp;
38862306a36Sopenharmony_ci#endif
38962306a36Sopenharmony_ci	struct net_bridge_port		__rcu *backup_port;
39062306a36Sopenharmony_ci	u32				backup_nhid;
39162306a36Sopenharmony_ci
39262306a36Sopenharmony_ci	/* STP */
39362306a36Sopenharmony_ci	u8				priority;
39462306a36Sopenharmony_ci	u8				state;
39562306a36Sopenharmony_ci	u16				port_no;
39662306a36Sopenharmony_ci	unsigned char			topology_change_ack;
39762306a36Sopenharmony_ci	unsigned char			config_pending;
39862306a36Sopenharmony_ci	port_id				port_id;
39962306a36Sopenharmony_ci	port_id				designated_port;
40062306a36Sopenharmony_ci	bridge_id			designated_root;
40162306a36Sopenharmony_ci	bridge_id			designated_bridge;
40262306a36Sopenharmony_ci	u32				path_cost;
40362306a36Sopenharmony_ci	u32				designated_cost;
40462306a36Sopenharmony_ci	unsigned long			designated_age;
40562306a36Sopenharmony_ci
40662306a36Sopenharmony_ci	struct timer_list		forward_delay_timer;
40762306a36Sopenharmony_ci	struct timer_list		hold_timer;
40862306a36Sopenharmony_ci	struct timer_list		message_age_timer;
40962306a36Sopenharmony_ci	struct kobject			kobj;
41062306a36Sopenharmony_ci	struct rcu_head			rcu;
41162306a36Sopenharmony_ci
41262306a36Sopenharmony_ci	struct net_bridge_mcast_port	multicast_ctx;
41362306a36Sopenharmony_ci
41462306a36Sopenharmony_ci#ifdef CONFIG_BRIDGE_IGMP_SNOOPING
41562306a36Sopenharmony_ci	struct bridge_mcast_stats	__percpu *mcast_stats;
41662306a36Sopenharmony_ci
41762306a36Sopenharmony_ci	u32				multicast_eht_hosts_limit;
41862306a36Sopenharmony_ci	u32				multicast_eht_hosts_cnt;
41962306a36Sopenharmony_ci	struct hlist_head		mglist;
42062306a36Sopenharmony_ci#endif
42162306a36Sopenharmony_ci
42262306a36Sopenharmony_ci#ifdef CONFIG_SYSFS
42362306a36Sopenharmony_ci	char				sysfs_name[IFNAMSIZ];
42462306a36Sopenharmony_ci#endif
42562306a36Sopenharmony_ci
42662306a36Sopenharmony_ci#ifdef CONFIG_NET_POLL_CONTROLLER
42762306a36Sopenharmony_ci	struct netpoll			*np;
42862306a36Sopenharmony_ci#endif
42962306a36Sopenharmony_ci#ifdef CONFIG_NET_SWITCHDEV
43062306a36Sopenharmony_ci	/* Identifier used to group ports that share the same switchdev
43162306a36Sopenharmony_ci	 * hardware domain.
43262306a36Sopenharmony_ci	 */
43362306a36Sopenharmony_ci	int				hwdom;
43462306a36Sopenharmony_ci	int				offload_count;
43562306a36Sopenharmony_ci	struct netdev_phys_item_id	ppid;
43662306a36Sopenharmony_ci#endif
43762306a36Sopenharmony_ci	u16				group_fwd_mask;
43862306a36Sopenharmony_ci	u16				backup_redirected_cnt;
43962306a36Sopenharmony_ci
44062306a36Sopenharmony_ci	struct bridge_stp_xstats	stp_xstats;
44162306a36Sopenharmony_ci};
44262306a36Sopenharmony_ci
44362306a36Sopenharmony_ci#define kobj_to_brport(obj)	container_of(obj, struct net_bridge_port, kobj)
44462306a36Sopenharmony_ci
44562306a36Sopenharmony_ci#define br_auto_port(p) ((p)->flags & BR_AUTO_MASK)
44662306a36Sopenharmony_ci#define br_promisc_port(p) ((p)->flags & BR_PROMISC)
44762306a36Sopenharmony_ci
44862306a36Sopenharmony_cistatic inline struct net_bridge_port *br_port_get_rcu(const struct net_device *dev)
44962306a36Sopenharmony_ci{
45062306a36Sopenharmony_ci	return rcu_dereference(dev->rx_handler_data);
45162306a36Sopenharmony_ci}
45262306a36Sopenharmony_ci
45362306a36Sopenharmony_cistatic inline struct net_bridge_port *br_port_get_rtnl(const struct net_device *dev)
45462306a36Sopenharmony_ci{
45562306a36Sopenharmony_ci	return netif_is_bridge_port(dev) ?
45662306a36Sopenharmony_ci		rtnl_dereference(dev->rx_handler_data) : NULL;
45762306a36Sopenharmony_ci}
45862306a36Sopenharmony_ci
45962306a36Sopenharmony_cistatic inline struct net_bridge_port *br_port_get_rtnl_rcu(const struct net_device *dev)
46062306a36Sopenharmony_ci{
46162306a36Sopenharmony_ci	return netif_is_bridge_port(dev) ?
46262306a36Sopenharmony_ci		rcu_dereference_rtnl(dev->rx_handler_data) : NULL;
46362306a36Sopenharmony_ci}
46462306a36Sopenharmony_ci
46562306a36Sopenharmony_cienum net_bridge_opts {
46662306a36Sopenharmony_ci	BROPT_VLAN_ENABLED,
46762306a36Sopenharmony_ci	BROPT_VLAN_STATS_ENABLED,
46862306a36Sopenharmony_ci	BROPT_NF_CALL_IPTABLES,
46962306a36Sopenharmony_ci	BROPT_NF_CALL_IP6TABLES,
47062306a36Sopenharmony_ci	BROPT_NF_CALL_ARPTABLES,
47162306a36Sopenharmony_ci	BROPT_GROUP_ADDR_SET,
47262306a36Sopenharmony_ci	BROPT_MULTICAST_ENABLED,
47362306a36Sopenharmony_ci	BROPT_MULTICAST_QUERY_USE_IFADDR,
47462306a36Sopenharmony_ci	BROPT_MULTICAST_STATS_ENABLED,
47562306a36Sopenharmony_ci	BROPT_HAS_IPV6_ADDR,
47662306a36Sopenharmony_ci	BROPT_NEIGH_SUPPRESS_ENABLED,
47762306a36Sopenharmony_ci	BROPT_MTU_SET_BY_USER,
47862306a36Sopenharmony_ci	BROPT_VLAN_STATS_PER_PORT,
47962306a36Sopenharmony_ci	BROPT_NO_LL_LEARN,
48062306a36Sopenharmony_ci	BROPT_VLAN_BRIDGE_BINDING,
48162306a36Sopenharmony_ci	BROPT_MCAST_VLAN_SNOOPING_ENABLED,
48262306a36Sopenharmony_ci	BROPT_MST_ENABLED,
48362306a36Sopenharmony_ci};
48462306a36Sopenharmony_ci
48562306a36Sopenharmony_cistruct net_bridge {
48662306a36Sopenharmony_ci	spinlock_t			lock;
48762306a36Sopenharmony_ci	spinlock_t			hash_lock;
48862306a36Sopenharmony_ci	struct hlist_head		frame_type_list;
48962306a36Sopenharmony_ci	struct net_device		*dev;
49062306a36Sopenharmony_ci	unsigned long			options;
49162306a36Sopenharmony_ci	/* These fields are accessed on each packet */
49262306a36Sopenharmony_ci#ifdef CONFIG_BRIDGE_VLAN_FILTERING
49362306a36Sopenharmony_ci	__be16				vlan_proto;
49462306a36Sopenharmony_ci	u16				default_pvid;
49562306a36Sopenharmony_ci	struct net_bridge_vlan_group	__rcu *vlgrp;
49662306a36Sopenharmony_ci#endif
49762306a36Sopenharmony_ci
49862306a36Sopenharmony_ci	struct rhashtable		fdb_hash_tbl;
49962306a36Sopenharmony_ci	struct list_head		port_list;
50062306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
50162306a36Sopenharmony_ci	union {
50262306a36Sopenharmony_ci		struct rtable		fake_rtable;
50362306a36Sopenharmony_ci		struct rt6_info		fake_rt6_info;
50462306a36Sopenharmony_ci	};
50562306a36Sopenharmony_ci#endif
50662306a36Sopenharmony_ci	u16				group_fwd_mask;
50762306a36Sopenharmony_ci	u16				group_fwd_mask_required;
50862306a36Sopenharmony_ci
50962306a36Sopenharmony_ci	/* STP */
51062306a36Sopenharmony_ci	bridge_id			designated_root;
51162306a36Sopenharmony_ci	bridge_id			bridge_id;
51262306a36Sopenharmony_ci	unsigned char			topology_change;
51362306a36Sopenharmony_ci	unsigned char			topology_change_detected;
51462306a36Sopenharmony_ci	u16				root_port;
51562306a36Sopenharmony_ci	unsigned long			max_age;
51662306a36Sopenharmony_ci	unsigned long			hello_time;
51762306a36Sopenharmony_ci	unsigned long			forward_delay;
51862306a36Sopenharmony_ci	unsigned long			ageing_time;
51962306a36Sopenharmony_ci	unsigned long			bridge_max_age;
52062306a36Sopenharmony_ci	unsigned long			bridge_hello_time;
52162306a36Sopenharmony_ci	unsigned long			bridge_forward_delay;
52262306a36Sopenharmony_ci	unsigned long			bridge_ageing_time;
52362306a36Sopenharmony_ci	u32				root_path_cost;
52462306a36Sopenharmony_ci
52562306a36Sopenharmony_ci	u8				group_addr[ETH_ALEN];
52662306a36Sopenharmony_ci
52762306a36Sopenharmony_ci	enum {
52862306a36Sopenharmony_ci		BR_NO_STP, 		/* no spanning tree */
52962306a36Sopenharmony_ci		BR_KERNEL_STP,		/* old STP in kernel */
53062306a36Sopenharmony_ci		BR_USER_STP,		/* new RSTP in userspace */
53162306a36Sopenharmony_ci	} stp_enabled;
53262306a36Sopenharmony_ci
53362306a36Sopenharmony_ci	struct net_bridge_mcast		multicast_ctx;
53462306a36Sopenharmony_ci
53562306a36Sopenharmony_ci#ifdef CONFIG_BRIDGE_IGMP_SNOOPING
53662306a36Sopenharmony_ci	struct bridge_mcast_stats	__percpu *mcast_stats;
53762306a36Sopenharmony_ci
53862306a36Sopenharmony_ci	u32				hash_max;
53962306a36Sopenharmony_ci
54062306a36Sopenharmony_ci	spinlock_t			multicast_lock;
54162306a36Sopenharmony_ci
54262306a36Sopenharmony_ci	struct rhashtable		mdb_hash_tbl;
54362306a36Sopenharmony_ci	struct rhashtable		sg_port_tbl;
54462306a36Sopenharmony_ci
54562306a36Sopenharmony_ci	struct hlist_head		mcast_gc_list;
54662306a36Sopenharmony_ci	struct hlist_head		mdb_list;
54762306a36Sopenharmony_ci
54862306a36Sopenharmony_ci	struct work_struct		mcast_gc_work;
54962306a36Sopenharmony_ci#endif
55062306a36Sopenharmony_ci
55162306a36Sopenharmony_ci	struct timer_list		hello_timer;
55262306a36Sopenharmony_ci	struct timer_list		tcn_timer;
55362306a36Sopenharmony_ci	struct timer_list		topology_change_timer;
55462306a36Sopenharmony_ci	struct delayed_work		gc_work;
55562306a36Sopenharmony_ci	struct kobject			*ifobj;
55662306a36Sopenharmony_ci	u32				auto_cnt;
55762306a36Sopenharmony_ci
55862306a36Sopenharmony_ci#ifdef CONFIG_NET_SWITCHDEV
55962306a36Sopenharmony_ci	/* Counter used to make sure that hardware domains get unique
56062306a36Sopenharmony_ci	 * identifiers in case a bridge spans multiple switchdev instances.
56162306a36Sopenharmony_ci	 */
56262306a36Sopenharmony_ci	int				last_hwdom;
56362306a36Sopenharmony_ci	/* Bit mask of hardware domain numbers in use */
56462306a36Sopenharmony_ci	unsigned long			busy_hwdoms;
56562306a36Sopenharmony_ci#endif
56662306a36Sopenharmony_ci	struct hlist_head		fdb_list;
56762306a36Sopenharmony_ci
56862306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_BRIDGE_MRP)
56962306a36Sopenharmony_ci	struct hlist_head		mrp_list;
57062306a36Sopenharmony_ci#endif
57162306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_BRIDGE_CFM)
57262306a36Sopenharmony_ci	struct hlist_head		mep_list;
57362306a36Sopenharmony_ci#endif
57462306a36Sopenharmony_ci};
57562306a36Sopenharmony_ci
57662306a36Sopenharmony_cistruct br_input_skb_cb {
57762306a36Sopenharmony_ci	struct net_device *brdev;
57862306a36Sopenharmony_ci
57962306a36Sopenharmony_ci	u16 frag_max_size;
58062306a36Sopenharmony_ci#ifdef CONFIG_BRIDGE_IGMP_SNOOPING
58162306a36Sopenharmony_ci	u8 igmp;
58262306a36Sopenharmony_ci	u8 mrouters_only:1;
58362306a36Sopenharmony_ci#endif
58462306a36Sopenharmony_ci	u8 proxyarp_replied:1;
58562306a36Sopenharmony_ci	u8 src_port_isolated:1;
58662306a36Sopenharmony_ci#ifdef CONFIG_BRIDGE_VLAN_FILTERING
58762306a36Sopenharmony_ci	u8 vlan_filtered:1;
58862306a36Sopenharmony_ci#endif
58962306a36Sopenharmony_ci#ifdef CONFIG_NETFILTER_FAMILY_BRIDGE
59062306a36Sopenharmony_ci	u8 br_netfilter_broute:1;
59162306a36Sopenharmony_ci#endif
59262306a36Sopenharmony_ci
59362306a36Sopenharmony_ci#ifdef CONFIG_NET_SWITCHDEV
59462306a36Sopenharmony_ci	/* Set if TX data plane offloading is used towards at least one
59562306a36Sopenharmony_ci	 * hardware domain.
59662306a36Sopenharmony_ci	 */
59762306a36Sopenharmony_ci	u8 tx_fwd_offload:1;
59862306a36Sopenharmony_ci	/* The switchdev hardware domain from which this packet was received.
59962306a36Sopenharmony_ci	 * If skb->offload_fwd_mark was set, then this packet was already
60062306a36Sopenharmony_ci	 * forwarded by hardware to the other ports in the source hardware
60162306a36Sopenharmony_ci	 * domain, otherwise it wasn't.
60262306a36Sopenharmony_ci	 */
60362306a36Sopenharmony_ci	int src_hwdom;
60462306a36Sopenharmony_ci	/* Bit mask of hardware domains towards this packet has already been
60562306a36Sopenharmony_ci	 * transmitted using the TX data plane offload.
60662306a36Sopenharmony_ci	 */
60762306a36Sopenharmony_ci	unsigned long fwd_hwdoms;
60862306a36Sopenharmony_ci#endif
60962306a36Sopenharmony_ci
61062306a36Sopenharmony_ci	u32 backup_nhid;
61162306a36Sopenharmony_ci};
61262306a36Sopenharmony_ci
61362306a36Sopenharmony_ci#define BR_INPUT_SKB_CB(__skb)	((struct br_input_skb_cb *)(__skb)->cb)
61462306a36Sopenharmony_ci
61562306a36Sopenharmony_ci#ifdef CONFIG_BRIDGE_IGMP_SNOOPING
61662306a36Sopenharmony_ci# define BR_INPUT_SKB_CB_MROUTERS_ONLY(__skb)	(BR_INPUT_SKB_CB(__skb)->mrouters_only)
61762306a36Sopenharmony_ci#else
61862306a36Sopenharmony_ci# define BR_INPUT_SKB_CB_MROUTERS_ONLY(__skb)	(0)
61962306a36Sopenharmony_ci#endif
62062306a36Sopenharmony_ci
62162306a36Sopenharmony_ci#define br_printk(level, br, format, args...)	\
62262306a36Sopenharmony_ci	printk(level "%s: " format, (br)->dev->name, ##args)
62362306a36Sopenharmony_ci
62462306a36Sopenharmony_ci#define br_err(__br, format, args...)			\
62562306a36Sopenharmony_ci	br_printk(KERN_ERR, __br, format, ##args)
62662306a36Sopenharmony_ci#define br_warn(__br, format, args...)			\
62762306a36Sopenharmony_ci	br_printk(KERN_WARNING, __br, format, ##args)
62862306a36Sopenharmony_ci#define br_notice(__br, format, args...)		\
62962306a36Sopenharmony_ci	br_printk(KERN_NOTICE, __br, format, ##args)
63062306a36Sopenharmony_ci#define br_info(__br, format, args...)			\
63162306a36Sopenharmony_ci	br_printk(KERN_INFO, __br, format, ##args)
63262306a36Sopenharmony_ci
63362306a36Sopenharmony_ci#define br_debug(br, format, args...)			\
63462306a36Sopenharmony_ci	pr_debug("%s: " format,  (br)->dev->name, ##args)
63562306a36Sopenharmony_ci
63662306a36Sopenharmony_ci/* called under bridge lock */
63762306a36Sopenharmony_cistatic inline int br_is_root_bridge(const struct net_bridge *br)
63862306a36Sopenharmony_ci{
63962306a36Sopenharmony_ci	return !memcmp(&br->bridge_id, &br->designated_root, 8);
64062306a36Sopenharmony_ci}
64162306a36Sopenharmony_ci
64262306a36Sopenharmony_ci/* check if a VLAN entry is global */
64362306a36Sopenharmony_cistatic inline bool br_vlan_is_master(const struct net_bridge_vlan *v)
64462306a36Sopenharmony_ci{
64562306a36Sopenharmony_ci	return v->flags & BRIDGE_VLAN_INFO_MASTER;
64662306a36Sopenharmony_ci}
64762306a36Sopenharmony_ci
64862306a36Sopenharmony_ci/* check if a VLAN entry is used by the bridge */
64962306a36Sopenharmony_cistatic inline bool br_vlan_is_brentry(const struct net_bridge_vlan *v)
65062306a36Sopenharmony_ci{
65162306a36Sopenharmony_ci	return v->flags & BRIDGE_VLAN_INFO_BRENTRY;
65262306a36Sopenharmony_ci}
65362306a36Sopenharmony_ci
65462306a36Sopenharmony_ci/* check if we should use the vlan entry, returns false if it's only context */
65562306a36Sopenharmony_cistatic inline bool br_vlan_should_use(const struct net_bridge_vlan *v)
65662306a36Sopenharmony_ci{
65762306a36Sopenharmony_ci	if (br_vlan_is_master(v)) {
65862306a36Sopenharmony_ci		if (br_vlan_is_brentry(v))
65962306a36Sopenharmony_ci			return true;
66062306a36Sopenharmony_ci		else
66162306a36Sopenharmony_ci			return false;
66262306a36Sopenharmony_ci	}
66362306a36Sopenharmony_ci
66462306a36Sopenharmony_ci	return true;
66562306a36Sopenharmony_ci}
66662306a36Sopenharmony_ci
66762306a36Sopenharmony_cistatic inline bool nbp_state_should_learn(const struct net_bridge_port *p)
66862306a36Sopenharmony_ci{
66962306a36Sopenharmony_ci	return p->state == BR_STATE_LEARNING || p->state == BR_STATE_FORWARDING;
67062306a36Sopenharmony_ci}
67162306a36Sopenharmony_ci
67262306a36Sopenharmony_cistatic inline bool br_vlan_valid_id(u16 vid, struct netlink_ext_ack *extack)
67362306a36Sopenharmony_ci{
67462306a36Sopenharmony_ci	bool ret = vid > 0 && vid < VLAN_VID_MASK;
67562306a36Sopenharmony_ci
67662306a36Sopenharmony_ci	if (!ret)
67762306a36Sopenharmony_ci		NL_SET_ERR_MSG_MOD(extack, "Vlan id is invalid");
67862306a36Sopenharmony_ci
67962306a36Sopenharmony_ci	return ret;
68062306a36Sopenharmony_ci}
68162306a36Sopenharmony_ci
68262306a36Sopenharmony_cistatic inline bool br_vlan_valid_range(const struct bridge_vlan_info *cur,
68362306a36Sopenharmony_ci				       const struct bridge_vlan_info *last,
68462306a36Sopenharmony_ci				       struct netlink_ext_ack *extack)
68562306a36Sopenharmony_ci{
68662306a36Sopenharmony_ci	/* pvid flag is not allowed in ranges */
68762306a36Sopenharmony_ci	if (cur->flags & BRIDGE_VLAN_INFO_PVID) {
68862306a36Sopenharmony_ci		NL_SET_ERR_MSG_MOD(extack, "Pvid isn't allowed in a range");
68962306a36Sopenharmony_ci		return false;
69062306a36Sopenharmony_ci	}
69162306a36Sopenharmony_ci
69262306a36Sopenharmony_ci	/* when cur is the range end, check if:
69362306a36Sopenharmony_ci	 *  - it has range start flag
69462306a36Sopenharmony_ci	 *  - range ids are invalid (end is equal to or before start)
69562306a36Sopenharmony_ci	 */
69662306a36Sopenharmony_ci	if (last) {
69762306a36Sopenharmony_ci		if (cur->flags & BRIDGE_VLAN_INFO_RANGE_BEGIN) {
69862306a36Sopenharmony_ci			NL_SET_ERR_MSG_MOD(extack, "Found a new vlan range start while processing one");
69962306a36Sopenharmony_ci			return false;
70062306a36Sopenharmony_ci		} else if (!(cur->flags & BRIDGE_VLAN_INFO_RANGE_END)) {
70162306a36Sopenharmony_ci			NL_SET_ERR_MSG_MOD(extack, "Vlan range end flag is missing");
70262306a36Sopenharmony_ci			return false;
70362306a36Sopenharmony_ci		} else if (cur->vid <= last->vid) {
70462306a36Sopenharmony_ci			NL_SET_ERR_MSG_MOD(extack, "End vlan id is less than or equal to start vlan id");
70562306a36Sopenharmony_ci			return false;
70662306a36Sopenharmony_ci		}
70762306a36Sopenharmony_ci	}
70862306a36Sopenharmony_ci
70962306a36Sopenharmony_ci	/* check for required range flags */
71062306a36Sopenharmony_ci	if (!(cur->flags & (BRIDGE_VLAN_INFO_RANGE_BEGIN |
71162306a36Sopenharmony_ci			    BRIDGE_VLAN_INFO_RANGE_END))) {
71262306a36Sopenharmony_ci		NL_SET_ERR_MSG_MOD(extack, "Both vlan range flags are missing");
71362306a36Sopenharmony_ci		return false;
71462306a36Sopenharmony_ci	}
71562306a36Sopenharmony_ci
71662306a36Sopenharmony_ci	return true;
71762306a36Sopenharmony_ci}
71862306a36Sopenharmony_ci
71962306a36Sopenharmony_cistatic inline u8 br_vlan_multicast_router(const struct net_bridge_vlan *v)
72062306a36Sopenharmony_ci{
72162306a36Sopenharmony_ci	u8 mcast_router = MDB_RTR_TYPE_DISABLED;
72262306a36Sopenharmony_ci
72362306a36Sopenharmony_ci#ifdef CONFIG_BRIDGE_IGMP_SNOOPING
72462306a36Sopenharmony_ci	if (!br_vlan_is_master(v))
72562306a36Sopenharmony_ci		mcast_router = v->port_mcast_ctx.multicast_router;
72662306a36Sopenharmony_ci	else
72762306a36Sopenharmony_ci		mcast_router = v->br_mcast_ctx.multicast_router;
72862306a36Sopenharmony_ci#endif
72962306a36Sopenharmony_ci
73062306a36Sopenharmony_ci	return mcast_router;
73162306a36Sopenharmony_ci}
73262306a36Sopenharmony_ci
73362306a36Sopenharmony_cistatic inline int br_afspec_cmd_to_rtm(int cmd)
73462306a36Sopenharmony_ci{
73562306a36Sopenharmony_ci	switch (cmd) {
73662306a36Sopenharmony_ci	case RTM_SETLINK:
73762306a36Sopenharmony_ci		return RTM_NEWVLAN;
73862306a36Sopenharmony_ci	case RTM_DELLINK:
73962306a36Sopenharmony_ci		return RTM_DELVLAN;
74062306a36Sopenharmony_ci	}
74162306a36Sopenharmony_ci
74262306a36Sopenharmony_ci	return 0;
74362306a36Sopenharmony_ci}
74462306a36Sopenharmony_ci
74562306a36Sopenharmony_cistatic inline int br_opt_get(const struct net_bridge *br,
74662306a36Sopenharmony_ci			     enum net_bridge_opts opt)
74762306a36Sopenharmony_ci{
74862306a36Sopenharmony_ci	return test_bit(opt, &br->options);
74962306a36Sopenharmony_ci}
75062306a36Sopenharmony_ci
75162306a36Sopenharmony_ciint br_boolopt_toggle(struct net_bridge *br, enum br_boolopt_id opt, bool on,
75262306a36Sopenharmony_ci		      struct netlink_ext_ack *extack);
75362306a36Sopenharmony_ciint br_boolopt_get(const struct net_bridge *br, enum br_boolopt_id opt);
75462306a36Sopenharmony_ciint br_boolopt_multi_toggle(struct net_bridge *br,
75562306a36Sopenharmony_ci			    struct br_boolopt_multi *bm,
75662306a36Sopenharmony_ci			    struct netlink_ext_ack *extack);
75762306a36Sopenharmony_civoid br_boolopt_multi_get(const struct net_bridge *br,
75862306a36Sopenharmony_ci			  struct br_boolopt_multi *bm);
75962306a36Sopenharmony_civoid br_opt_toggle(struct net_bridge *br, enum net_bridge_opts opt, bool on);
76062306a36Sopenharmony_ci
76162306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_NET_TC_SKB_EXT)
76262306a36Sopenharmony_cistatic inline void br_tc_skb_miss_set(struct sk_buff *skb, bool miss)
76362306a36Sopenharmony_ci{
76462306a36Sopenharmony_ci	struct tc_skb_ext *ext;
76562306a36Sopenharmony_ci
76662306a36Sopenharmony_ci	if (!tc_skb_ext_tc_enabled())
76762306a36Sopenharmony_ci		return;
76862306a36Sopenharmony_ci
76962306a36Sopenharmony_ci	ext = skb_ext_find(skb, TC_SKB_EXT);
77062306a36Sopenharmony_ci	if (ext) {
77162306a36Sopenharmony_ci		ext->l2_miss = miss;
77262306a36Sopenharmony_ci		return;
77362306a36Sopenharmony_ci	}
77462306a36Sopenharmony_ci	if (!miss)
77562306a36Sopenharmony_ci		return;
77662306a36Sopenharmony_ci	ext = tc_skb_ext_alloc(skb);
77762306a36Sopenharmony_ci	if (!ext)
77862306a36Sopenharmony_ci		return;
77962306a36Sopenharmony_ci	ext->l2_miss = true;
78062306a36Sopenharmony_ci}
78162306a36Sopenharmony_ci#else
78262306a36Sopenharmony_cistatic inline void br_tc_skb_miss_set(struct sk_buff *skb, bool miss)
78362306a36Sopenharmony_ci{
78462306a36Sopenharmony_ci}
78562306a36Sopenharmony_ci#endif
78662306a36Sopenharmony_ci
78762306a36Sopenharmony_ci/* br_device.c */
78862306a36Sopenharmony_civoid br_dev_setup(struct net_device *dev);
78962306a36Sopenharmony_civoid br_dev_delete(struct net_device *dev, struct list_head *list);
79062306a36Sopenharmony_cinetdev_tx_t br_dev_xmit(struct sk_buff *skb, struct net_device *dev);
79162306a36Sopenharmony_ci#ifdef CONFIG_NET_POLL_CONTROLLER
79262306a36Sopenharmony_cistatic inline void br_netpoll_send_skb(const struct net_bridge_port *p,
79362306a36Sopenharmony_ci				       struct sk_buff *skb)
79462306a36Sopenharmony_ci{
79562306a36Sopenharmony_ci	netpoll_send_skb(p->np, skb);
79662306a36Sopenharmony_ci}
79762306a36Sopenharmony_ci
79862306a36Sopenharmony_ciint br_netpoll_enable(struct net_bridge_port *p);
79962306a36Sopenharmony_civoid br_netpoll_disable(struct net_bridge_port *p);
80062306a36Sopenharmony_ci#else
80162306a36Sopenharmony_cistatic inline void br_netpoll_send_skb(const struct net_bridge_port *p,
80262306a36Sopenharmony_ci				       struct sk_buff *skb)
80362306a36Sopenharmony_ci{
80462306a36Sopenharmony_ci}
80562306a36Sopenharmony_ci
80662306a36Sopenharmony_cistatic inline int br_netpoll_enable(struct net_bridge_port *p)
80762306a36Sopenharmony_ci{
80862306a36Sopenharmony_ci	return 0;
80962306a36Sopenharmony_ci}
81062306a36Sopenharmony_ci
81162306a36Sopenharmony_cistatic inline void br_netpoll_disable(struct net_bridge_port *p)
81262306a36Sopenharmony_ci{
81362306a36Sopenharmony_ci}
81462306a36Sopenharmony_ci#endif
81562306a36Sopenharmony_ci
81662306a36Sopenharmony_ci/* br_fdb.c */
81762306a36Sopenharmony_ci#define FDB_FLUSH_IGNORED_NDM_FLAGS (NTF_MASTER | NTF_SELF)
81862306a36Sopenharmony_ci#define FDB_FLUSH_ALLOWED_NDM_STATES (NUD_PERMANENT | NUD_NOARP)
81962306a36Sopenharmony_ci#define FDB_FLUSH_ALLOWED_NDM_FLAGS (NTF_USE | NTF_EXT_LEARNED | \
82062306a36Sopenharmony_ci				     NTF_STICKY | NTF_OFFLOADED)
82162306a36Sopenharmony_ci
82262306a36Sopenharmony_ciint br_fdb_init(void);
82362306a36Sopenharmony_civoid br_fdb_fini(void);
82462306a36Sopenharmony_ciint br_fdb_hash_init(struct net_bridge *br);
82562306a36Sopenharmony_civoid br_fdb_hash_fini(struct net_bridge *br);
82662306a36Sopenharmony_civoid br_fdb_flush(struct net_bridge *br,
82762306a36Sopenharmony_ci		  const struct net_bridge_fdb_flush_desc *desc);
82862306a36Sopenharmony_civoid br_fdb_find_delete_local(struct net_bridge *br,
82962306a36Sopenharmony_ci			      const struct net_bridge_port *p,
83062306a36Sopenharmony_ci			      const unsigned char *addr, u16 vid);
83162306a36Sopenharmony_civoid br_fdb_changeaddr(struct net_bridge_port *p, const unsigned char *newaddr);
83262306a36Sopenharmony_civoid br_fdb_change_mac_address(struct net_bridge *br, const u8 *newaddr);
83362306a36Sopenharmony_civoid br_fdb_cleanup(struct work_struct *work);
83462306a36Sopenharmony_civoid br_fdb_delete_by_port(struct net_bridge *br,
83562306a36Sopenharmony_ci			   const struct net_bridge_port *p, u16 vid, int do_all);
83662306a36Sopenharmony_cistruct net_bridge_fdb_entry *br_fdb_find_rcu(struct net_bridge *br,
83762306a36Sopenharmony_ci					     const unsigned char *addr,
83862306a36Sopenharmony_ci					     __u16 vid);
83962306a36Sopenharmony_ciint br_fdb_test_addr(struct net_device *dev, unsigned char *addr);
84062306a36Sopenharmony_ciint br_fdb_fillbuf(struct net_bridge *br, void *buf, unsigned long count,
84162306a36Sopenharmony_ci		   unsigned long off);
84262306a36Sopenharmony_ciint br_fdb_add_local(struct net_bridge *br, struct net_bridge_port *source,
84362306a36Sopenharmony_ci		     const unsigned char *addr, u16 vid);
84462306a36Sopenharmony_civoid br_fdb_update(struct net_bridge *br, struct net_bridge_port *source,
84562306a36Sopenharmony_ci		   const unsigned char *addr, u16 vid, unsigned long flags);
84662306a36Sopenharmony_ci
84762306a36Sopenharmony_ciint br_fdb_delete(struct ndmsg *ndm, struct nlattr *tb[],
84862306a36Sopenharmony_ci		  struct net_device *dev, const unsigned char *addr, u16 vid,
84962306a36Sopenharmony_ci		  struct netlink_ext_ack *extack);
85062306a36Sopenharmony_ciint br_fdb_delete_bulk(struct ndmsg *ndm, struct nlattr *tb[],
85162306a36Sopenharmony_ci		       struct net_device *dev, u16 vid,
85262306a36Sopenharmony_ci		       struct netlink_ext_ack *extack);
85362306a36Sopenharmony_ciint br_fdb_add(struct ndmsg *nlh, struct nlattr *tb[], struct net_device *dev,
85462306a36Sopenharmony_ci	       const unsigned char *addr, u16 vid, u16 nlh_flags,
85562306a36Sopenharmony_ci	       struct netlink_ext_ack *extack);
85662306a36Sopenharmony_ciint br_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb,
85762306a36Sopenharmony_ci		struct net_device *dev, struct net_device *fdev, int *idx);
85862306a36Sopenharmony_ciint br_fdb_get(struct sk_buff *skb, struct nlattr *tb[], struct net_device *dev,
85962306a36Sopenharmony_ci	       const unsigned char *addr, u16 vid, u32 portid, u32 seq,
86062306a36Sopenharmony_ci	       struct netlink_ext_ack *extack);
86162306a36Sopenharmony_ciint br_fdb_sync_static(struct net_bridge *br, struct net_bridge_port *p);
86262306a36Sopenharmony_civoid br_fdb_unsync_static(struct net_bridge *br, struct net_bridge_port *p);
86362306a36Sopenharmony_ciint br_fdb_external_learn_add(struct net_bridge *br, struct net_bridge_port *p,
86462306a36Sopenharmony_ci			      const unsigned char *addr, u16 vid,
86562306a36Sopenharmony_ci			      bool locked, bool swdev_notify);
86662306a36Sopenharmony_ciint br_fdb_external_learn_del(struct net_bridge *br, struct net_bridge_port *p,
86762306a36Sopenharmony_ci			      const unsigned char *addr, u16 vid,
86862306a36Sopenharmony_ci			      bool swdev_notify);
86962306a36Sopenharmony_civoid br_fdb_offloaded_set(struct net_bridge *br, struct net_bridge_port *p,
87062306a36Sopenharmony_ci			  const unsigned char *addr, u16 vid, bool offloaded);
87162306a36Sopenharmony_ci
87262306a36Sopenharmony_ci/* br_forward.c */
87362306a36Sopenharmony_cienum br_pkt_type {
87462306a36Sopenharmony_ci	BR_PKT_UNICAST,
87562306a36Sopenharmony_ci	BR_PKT_MULTICAST,
87662306a36Sopenharmony_ci	BR_PKT_BROADCAST
87762306a36Sopenharmony_ci};
87862306a36Sopenharmony_ciint br_dev_queue_push_xmit(struct net *net, struct sock *sk, struct sk_buff *skb);
87962306a36Sopenharmony_civoid br_forward(const struct net_bridge_port *to, struct sk_buff *skb,
88062306a36Sopenharmony_ci		bool local_rcv, bool local_orig);
88162306a36Sopenharmony_ciint br_forward_finish(struct net *net, struct sock *sk, struct sk_buff *skb);
88262306a36Sopenharmony_civoid br_flood(struct net_bridge *br, struct sk_buff *skb,
88362306a36Sopenharmony_ci	      enum br_pkt_type pkt_type, bool local_rcv, bool local_orig,
88462306a36Sopenharmony_ci	      u16 vid);
88562306a36Sopenharmony_ci
88662306a36Sopenharmony_ci/* return true if both source port and dest port are isolated */
88762306a36Sopenharmony_cistatic inline bool br_skb_isolated(const struct net_bridge_port *to,
88862306a36Sopenharmony_ci				   const struct sk_buff *skb)
88962306a36Sopenharmony_ci{
89062306a36Sopenharmony_ci	return BR_INPUT_SKB_CB(skb)->src_port_isolated &&
89162306a36Sopenharmony_ci	       (to->flags & BR_ISOLATED);
89262306a36Sopenharmony_ci}
89362306a36Sopenharmony_ci
89462306a36Sopenharmony_ci/* br_if.c */
89562306a36Sopenharmony_civoid br_port_carrier_check(struct net_bridge_port *p, bool *notified);
89662306a36Sopenharmony_ciint br_add_bridge(struct net *net, const char *name);
89762306a36Sopenharmony_ciint br_del_bridge(struct net *net, const char *name);
89862306a36Sopenharmony_ciint br_add_if(struct net_bridge *br, struct net_device *dev,
89962306a36Sopenharmony_ci	      struct netlink_ext_ack *extack);
90062306a36Sopenharmony_ciint br_del_if(struct net_bridge *br, struct net_device *dev);
90162306a36Sopenharmony_civoid br_mtu_auto_adjust(struct net_bridge *br);
90262306a36Sopenharmony_cinetdev_features_t br_features_recompute(struct net_bridge *br,
90362306a36Sopenharmony_ci					netdev_features_t features);
90462306a36Sopenharmony_civoid br_port_flags_change(struct net_bridge_port *port, unsigned long mask);
90562306a36Sopenharmony_civoid br_manage_promisc(struct net_bridge *br);
90662306a36Sopenharmony_ciint nbp_backup_change(struct net_bridge_port *p, struct net_device *backup_dev);
90762306a36Sopenharmony_ci
90862306a36Sopenharmony_ci/* br_input.c */
90962306a36Sopenharmony_ciint br_handle_frame_finish(struct net *net, struct sock *sk, struct sk_buff *skb);
91062306a36Sopenharmony_cirx_handler_func_t *br_get_rx_handler(const struct net_device *dev);
91162306a36Sopenharmony_ci
91262306a36Sopenharmony_cistruct br_frame_type {
91362306a36Sopenharmony_ci	__be16			type;
91462306a36Sopenharmony_ci	int			(*frame_handler)(struct net_bridge_port *port,
91562306a36Sopenharmony_ci						 struct sk_buff *skb);
91662306a36Sopenharmony_ci	struct hlist_node	list;
91762306a36Sopenharmony_ci};
91862306a36Sopenharmony_ci
91962306a36Sopenharmony_civoid br_add_frame(struct net_bridge *br, struct br_frame_type *ft);
92062306a36Sopenharmony_civoid br_del_frame(struct net_bridge *br, struct br_frame_type *ft);
92162306a36Sopenharmony_ci
92262306a36Sopenharmony_cistatic inline bool br_rx_handler_check_rcu(const struct net_device *dev)
92362306a36Sopenharmony_ci{
92462306a36Sopenharmony_ci	return rcu_dereference(dev->rx_handler) == br_get_rx_handler(dev);
92562306a36Sopenharmony_ci}
92662306a36Sopenharmony_ci
92762306a36Sopenharmony_cistatic inline bool br_rx_handler_check_rtnl(const struct net_device *dev)
92862306a36Sopenharmony_ci{
92962306a36Sopenharmony_ci	return rcu_dereference_rtnl(dev->rx_handler) == br_get_rx_handler(dev);
93062306a36Sopenharmony_ci}
93162306a36Sopenharmony_ci
93262306a36Sopenharmony_cistatic inline struct net_bridge_port *br_port_get_check_rcu(const struct net_device *dev)
93362306a36Sopenharmony_ci{
93462306a36Sopenharmony_ci	return br_rx_handler_check_rcu(dev) ? br_port_get_rcu(dev) : NULL;
93562306a36Sopenharmony_ci}
93662306a36Sopenharmony_ci
93762306a36Sopenharmony_cistatic inline struct net_bridge_port *
93862306a36Sopenharmony_cibr_port_get_check_rtnl(const struct net_device *dev)
93962306a36Sopenharmony_ci{
94062306a36Sopenharmony_ci	return br_rx_handler_check_rtnl(dev) ? br_port_get_rtnl_rcu(dev) : NULL;
94162306a36Sopenharmony_ci}
94262306a36Sopenharmony_ci
94362306a36Sopenharmony_ci/* br_ioctl.c */
94462306a36Sopenharmony_ciint br_dev_siocdevprivate(struct net_device *dev, struct ifreq *rq,
94562306a36Sopenharmony_ci			  void __user *data, int cmd);
94662306a36Sopenharmony_ciint br_ioctl_stub(struct net *net, struct net_bridge *br, unsigned int cmd,
94762306a36Sopenharmony_ci		  struct ifreq *ifr, void __user *uarg);
94862306a36Sopenharmony_ci
94962306a36Sopenharmony_ci/* br_multicast.c */
95062306a36Sopenharmony_ci#ifdef CONFIG_BRIDGE_IGMP_SNOOPING
95162306a36Sopenharmony_ciint br_multicast_rcv(struct net_bridge_mcast **brmctx,
95262306a36Sopenharmony_ci		     struct net_bridge_mcast_port **pmctx,
95362306a36Sopenharmony_ci		     struct net_bridge_vlan *vlan,
95462306a36Sopenharmony_ci		     struct sk_buff *skb, u16 vid);
95562306a36Sopenharmony_cistruct net_bridge_mdb_entry *br_mdb_get(struct net_bridge_mcast *brmctx,
95662306a36Sopenharmony_ci					struct sk_buff *skb, u16 vid);
95762306a36Sopenharmony_ciint br_multicast_add_port(struct net_bridge_port *port);
95862306a36Sopenharmony_civoid br_multicast_del_port(struct net_bridge_port *port);
95962306a36Sopenharmony_civoid br_multicast_enable_port(struct net_bridge_port *port);
96062306a36Sopenharmony_civoid br_multicast_disable_port(struct net_bridge_port *port);
96162306a36Sopenharmony_civoid br_multicast_init(struct net_bridge *br);
96262306a36Sopenharmony_civoid br_multicast_join_snoopers(struct net_bridge *br);
96362306a36Sopenharmony_civoid br_multicast_leave_snoopers(struct net_bridge *br);
96462306a36Sopenharmony_civoid br_multicast_open(struct net_bridge *br);
96562306a36Sopenharmony_civoid br_multicast_stop(struct net_bridge *br);
96662306a36Sopenharmony_civoid br_multicast_dev_del(struct net_bridge *br);
96762306a36Sopenharmony_civoid br_multicast_flood(struct net_bridge_mdb_entry *mdst, struct sk_buff *skb,
96862306a36Sopenharmony_ci			struct net_bridge_mcast *brmctx,
96962306a36Sopenharmony_ci			bool local_rcv, bool local_orig);
97062306a36Sopenharmony_ciint br_multicast_set_router(struct net_bridge_mcast *brmctx, unsigned long val);
97162306a36Sopenharmony_ciint br_multicast_set_port_router(struct net_bridge_mcast_port *pmctx,
97262306a36Sopenharmony_ci				 unsigned long val);
97362306a36Sopenharmony_ciint br_multicast_set_vlan_router(struct net_bridge_vlan *v, u8 mcast_router);
97462306a36Sopenharmony_ciint br_multicast_toggle(struct net_bridge *br, unsigned long val,
97562306a36Sopenharmony_ci			struct netlink_ext_ack *extack);
97662306a36Sopenharmony_ciint br_multicast_set_querier(struct net_bridge_mcast *brmctx, unsigned long val);
97762306a36Sopenharmony_ciint br_multicast_set_igmp_version(struct net_bridge_mcast *brmctx,
97862306a36Sopenharmony_ci				  unsigned long val);
97962306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_IPV6)
98062306a36Sopenharmony_ciint br_multicast_set_mld_version(struct net_bridge_mcast *brmctx,
98162306a36Sopenharmony_ci				 unsigned long val);
98262306a36Sopenharmony_ci#endif
98362306a36Sopenharmony_cistruct net_bridge_mdb_entry *
98462306a36Sopenharmony_cibr_mdb_ip_get(struct net_bridge *br, struct br_ip *dst);
98562306a36Sopenharmony_cistruct net_bridge_mdb_entry *
98662306a36Sopenharmony_cibr_multicast_new_group(struct net_bridge *br, struct br_ip *group);
98762306a36Sopenharmony_cistruct net_bridge_port_group *
98862306a36Sopenharmony_cibr_multicast_new_port_group(struct net_bridge_port *port,
98962306a36Sopenharmony_ci			    const struct br_ip *group,
99062306a36Sopenharmony_ci			    struct net_bridge_port_group __rcu *next,
99162306a36Sopenharmony_ci			    unsigned char flags, const unsigned char *src,
99262306a36Sopenharmony_ci			    u8 filter_mode, u8 rt_protocol,
99362306a36Sopenharmony_ci			    struct netlink_ext_ack *extack);
99462306a36Sopenharmony_civoid br_multicast_del_port_group(struct net_bridge_port_group *p);
99562306a36Sopenharmony_ciint br_mdb_hash_init(struct net_bridge *br);
99662306a36Sopenharmony_civoid br_mdb_hash_fini(struct net_bridge *br);
99762306a36Sopenharmony_civoid br_mdb_notify(struct net_device *dev, struct net_bridge_mdb_entry *mp,
99862306a36Sopenharmony_ci		   struct net_bridge_port_group *pg, int type);
99962306a36Sopenharmony_civoid br_rtr_notify(struct net_device *dev, struct net_bridge_mcast_port *pmctx,
100062306a36Sopenharmony_ci		   int type);
100162306a36Sopenharmony_civoid br_multicast_del_pg(struct net_bridge_mdb_entry *mp,
100262306a36Sopenharmony_ci			 struct net_bridge_port_group *pg,
100362306a36Sopenharmony_ci			 struct net_bridge_port_group __rcu **pp);
100462306a36Sopenharmony_civoid br_multicast_count(struct net_bridge *br,
100562306a36Sopenharmony_ci			const struct net_bridge_port *p,
100662306a36Sopenharmony_ci			const struct sk_buff *skb, u8 type, u8 dir);
100762306a36Sopenharmony_ciint br_multicast_init_stats(struct net_bridge *br);
100862306a36Sopenharmony_civoid br_multicast_uninit_stats(struct net_bridge *br);
100962306a36Sopenharmony_civoid br_multicast_get_stats(const struct net_bridge *br,
101062306a36Sopenharmony_ci			    const struct net_bridge_port *p,
101162306a36Sopenharmony_ci			    struct br_mcast_stats *dest);
101262306a36Sopenharmony_ciu32 br_multicast_ngroups_get(const struct net_bridge_mcast_port *pmctx);
101362306a36Sopenharmony_civoid br_multicast_ngroups_set_max(struct net_bridge_mcast_port *pmctx, u32 max);
101462306a36Sopenharmony_ciu32 br_multicast_ngroups_get_max(const struct net_bridge_mcast_port *pmctx);
101562306a36Sopenharmony_ciint br_mdb_add(struct net_device *dev, struct nlattr *tb[], u16 nlmsg_flags,
101662306a36Sopenharmony_ci	       struct netlink_ext_ack *extack);
101762306a36Sopenharmony_ciint br_mdb_del(struct net_device *dev, struct nlattr *tb[],
101862306a36Sopenharmony_ci	       struct netlink_ext_ack *extack);
101962306a36Sopenharmony_ciint br_mdb_dump(struct net_device *dev, struct sk_buff *skb,
102062306a36Sopenharmony_ci		struct netlink_callback *cb);
102162306a36Sopenharmony_civoid br_multicast_host_join(const struct net_bridge_mcast *brmctx,
102262306a36Sopenharmony_ci			    struct net_bridge_mdb_entry *mp, bool notify);
102362306a36Sopenharmony_civoid br_multicast_host_leave(struct net_bridge_mdb_entry *mp, bool notify);
102462306a36Sopenharmony_civoid br_multicast_star_g_handle_mode(struct net_bridge_port_group *pg,
102562306a36Sopenharmony_ci				     u8 filter_mode);
102662306a36Sopenharmony_civoid br_multicast_sg_add_exclude_ports(struct net_bridge_mdb_entry *star_mp,
102762306a36Sopenharmony_ci				       struct net_bridge_port_group *sg);
102862306a36Sopenharmony_cistruct net_bridge_group_src *
102962306a36Sopenharmony_cibr_multicast_find_group_src(struct net_bridge_port_group *pg, struct br_ip *ip);
103062306a36Sopenharmony_cistruct net_bridge_group_src *
103162306a36Sopenharmony_cibr_multicast_new_group_src(struct net_bridge_port_group *pg,
103262306a36Sopenharmony_ci			   struct br_ip *src_ip);
103362306a36Sopenharmony_civoid __br_multicast_del_group_src(struct net_bridge_group_src *src);
103462306a36Sopenharmony_civoid br_multicast_del_group_src(struct net_bridge_group_src *src,
103562306a36Sopenharmony_ci				bool fastleave);
103662306a36Sopenharmony_civoid br_multicast_ctx_init(struct net_bridge *br,
103762306a36Sopenharmony_ci			   struct net_bridge_vlan *vlan,
103862306a36Sopenharmony_ci			   struct net_bridge_mcast *brmctx);
103962306a36Sopenharmony_civoid br_multicast_ctx_deinit(struct net_bridge_mcast *brmctx);
104062306a36Sopenharmony_civoid br_multicast_port_ctx_init(struct net_bridge_port *port,
104162306a36Sopenharmony_ci				struct net_bridge_vlan *vlan,
104262306a36Sopenharmony_ci				struct net_bridge_mcast_port *pmctx);
104362306a36Sopenharmony_civoid br_multicast_port_ctx_deinit(struct net_bridge_mcast_port *pmctx);
104462306a36Sopenharmony_civoid br_multicast_toggle_one_vlan(struct net_bridge_vlan *vlan, bool on);
104562306a36Sopenharmony_ciint br_multicast_toggle_vlan_snooping(struct net_bridge *br, bool on,
104662306a36Sopenharmony_ci				      struct netlink_ext_ack *extack);
104762306a36Sopenharmony_cibool br_multicast_toggle_global_vlan(struct net_bridge_vlan *vlan, bool on);
104862306a36Sopenharmony_ci
104962306a36Sopenharmony_ciint br_rports_fill_info(struct sk_buff *skb,
105062306a36Sopenharmony_ci			const struct net_bridge_mcast *brmctx);
105162306a36Sopenharmony_ciint br_multicast_dump_querier_state(struct sk_buff *skb,
105262306a36Sopenharmony_ci				    const struct net_bridge_mcast *brmctx,
105362306a36Sopenharmony_ci				    int nest_attr);
105462306a36Sopenharmony_cisize_t br_multicast_querier_state_size(void);
105562306a36Sopenharmony_cisize_t br_rports_size(const struct net_bridge_mcast *brmctx);
105662306a36Sopenharmony_civoid br_multicast_set_query_intvl(struct net_bridge_mcast *brmctx,
105762306a36Sopenharmony_ci				  unsigned long val);
105862306a36Sopenharmony_civoid br_multicast_set_startup_query_intvl(struct net_bridge_mcast *brmctx,
105962306a36Sopenharmony_ci					  unsigned long val);
106062306a36Sopenharmony_ci
106162306a36Sopenharmony_cistatic inline bool br_group_is_l2(const struct br_ip *group)
106262306a36Sopenharmony_ci{
106362306a36Sopenharmony_ci	return group->proto == 0;
106462306a36Sopenharmony_ci}
106562306a36Sopenharmony_ci
106662306a36Sopenharmony_ci#define mlock_dereference(X, br) \
106762306a36Sopenharmony_ci	rcu_dereference_protected(X, lockdep_is_held(&br->multicast_lock))
106862306a36Sopenharmony_ci
106962306a36Sopenharmony_cistatic inline struct hlist_node *
107062306a36Sopenharmony_cibr_multicast_get_first_rport_node(struct net_bridge_mcast *brmctx,
107162306a36Sopenharmony_ci				  struct sk_buff *skb)
107262306a36Sopenharmony_ci{
107362306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_IPV6)
107462306a36Sopenharmony_ci	if (skb->protocol == htons(ETH_P_IPV6))
107562306a36Sopenharmony_ci		return rcu_dereference(hlist_first_rcu(&brmctx->ip6_mc_router_list));
107662306a36Sopenharmony_ci#endif
107762306a36Sopenharmony_ci	return rcu_dereference(hlist_first_rcu(&brmctx->ip4_mc_router_list));
107862306a36Sopenharmony_ci}
107962306a36Sopenharmony_ci
108062306a36Sopenharmony_cistatic inline struct net_bridge_port *
108162306a36Sopenharmony_cibr_multicast_rport_from_node_skb(struct hlist_node *rp, struct sk_buff *skb)
108262306a36Sopenharmony_ci{
108362306a36Sopenharmony_ci	struct net_bridge_mcast_port *mctx;
108462306a36Sopenharmony_ci
108562306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_IPV6)
108662306a36Sopenharmony_ci	if (skb->protocol == htons(ETH_P_IPV6))
108762306a36Sopenharmony_ci		mctx = hlist_entry_safe(rp, struct net_bridge_mcast_port,
108862306a36Sopenharmony_ci					ip6_rlist);
108962306a36Sopenharmony_ci	else
109062306a36Sopenharmony_ci#endif
109162306a36Sopenharmony_ci		mctx = hlist_entry_safe(rp, struct net_bridge_mcast_port,
109262306a36Sopenharmony_ci					ip4_rlist);
109362306a36Sopenharmony_ci
109462306a36Sopenharmony_ci	if (mctx)
109562306a36Sopenharmony_ci		return mctx->port;
109662306a36Sopenharmony_ci	else
109762306a36Sopenharmony_ci		return NULL;
109862306a36Sopenharmony_ci}
109962306a36Sopenharmony_ci
110062306a36Sopenharmony_cistatic inline bool br_ip4_multicast_is_router(struct net_bridge_mcast *brmctx)
110162306a36Sopenharmony_ci{
110262306a36Sopenharmony_ci	return timer_pending(&brmctx->ip4_mc_router_timer);
110362306a36Sopenharmony_ci}
110462306a36Sopenharmony_ci
110562306a36Sopenharmony_cistatic inline bool br_ip6_multicast_is_router(struct net_bridge_mcast *brmctx)
110662306a36Sopenharmony_ci{
110762306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_IPV6)
110862306a36Sopenharmony_ci	return timer_pending(&brmctx->ip6_mc_router_timer);
110962306a36Sopenharmony_ci#else
111062306a36Sopenharmony_ci	return false;
111162306a36Sopenharmony_ci#endif
111262306a36Sopenharmony_ci}
111362306a36Sopenharmony_ci
111462306a36Sopenharmony_cistatic inline bool
111562306a36Sopenharmony_cibr_multicast_is_router(struct net_bridge_mcast *brmctx, struct sk_buff *skb)
111662306a36Sopenharmony_ci{
111762306a36Sopenharmony_ci	switch (brmctx->multicast_router) {
111862306a36Sopenharmony_ci	case MDB_RTR_TYPE_PERM:
111962306a36Sopenharmony_ci		return true;
112062306a36Sopenharmony_ci	case MDB_RTR_TYPE_TEMP_QUERY:
112162306a36Sopenharmony_ci		if (skb) {
112262306a36Sopenharmony_ci			if (skb->protocol == htons(ETH_P_IP))
112362306a36Sopenharmony_ci				return br_ip4_multicast_is_router(brmctx);
112462306a36Sopenharmony_ci			else if (skb->protocol == htons(ETH_P_IPV6))
112562306a36Sopenharmony_ci				return br_ip6_multicast_is_router(brmctx);
112662306a36Sopenharmony_ci		} else {
112762306a36Sopenharmony_ci			return br_ip4_multicast_is_router(brmctx) ||
112862306a36Sopenharmony_ci			       br_ip6_multicast_is_router(brmctx);
112962306a36Sopenharmony_ci		}
113062306a36Sopenharmony_ci		fallthrough;
113162306a36Sopenharmony_ci	default:
113262306a36Sopenharmony_ci		return false;
113362306a36Sopenharmony_ci	}
113462306a36Sopenharmony_ci}
113562306a36Sopenharmony_ci
113662306a36Sopenharmony_cistatic inline bool
113762306a36Sopenharmony_ci__br_multicast_querier_exists(struct net_bridge_mcast *brmctx,
113862306a36Sopenharmony_ci			      struct bridge_mcast_other_query *querier,
113962306a36Sopenharmony_ci			      const bool is_ipv6)
114062306a36Sopenharmony_ci{
114162306a36Sopenharmony_ci	bool own_querier_enabled;
114262306a36Sopenharmony_ci
114362306a36Sopenharmony_ci	if (brmctx->multicast_querier) {
114462306a36Sopenharmony_ci		if (is_ipv6 && !br_opt_get(brmctx->br, BROPT_HAS_IPV6_ADDR))
114562306a36Sopenharmony_ci			own_querier_enabled = false;
114662306a36Sopenharmony_ci		else
114762306a36Sopenharmony_ci			own_querier_enabled = true;
114862306a36Sopenharmony_ci	} else {
114962306a36Sopenharmony_ci		own_querier_enabled = false;
115062306a36Sopenharmony_ci	}
115162306a36Sopenharmony_ci
115262306a36Sopenharmony_ci	return !timer_pending(&querier->delay_timer) &&
115362306a36Sopenharmony_ci	       (own_querier_enabled || timer_pending(&querier->timer));
115462306a36Sopenharmony_ci}
115562306a36Sopenharmony_ci
115662306a36Sopenharmony_cistatic inline bool br_multicast_querier_exists(struct net_bridge_mcast *brmctx,
115762306a36Sopenharmony_ci					       struct ethhdr *eth,
115862306a36Sopenharmony_ci					       const struct net_bridge_mdb_entry *mdb)
115962306a36Sopenharmony_ci{
116062306a36Sopenharmony_ci	switch (eth->h_proto) {
116162306a36Sopenharmony_ci	case (htons(ETH_P_IP)):
116262306a36Sopenharmony_ci		return __br_multicast_querier_exists(brmctx,
116362306a36Sopenharmony_ci			&brmctx->ip4_other_query, false);
116462306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_IPV6)
116562306a36Sopenharmony_ci	case (htons(ETH_P_IPV6)):
116662306a36Sopenharmony_ci		return __br_multicast_querier_exists(brmctx,
116762306a36Sopenharmony_ci			&brmctx->ip6_other_query, true);
116862306a36Sopenharmony_ci#endif
116962306a36Sopenharmony_ci	default:
117062306a36Sopenharmony_ci		return !!mdb && br_group_is_l2(&mdb->addr);
117162306a36Sopenharmony_ci	}
117262306a36Sopenharmony_ci}
117362306a36Sopenharmony_ci
117462306a36Sopenharmony_cistatic inline bool br_multicast_is_star_g(const struct br_ip *ip)
117562306a36Sopenharmony_ci{
117662306a36Sopenharmony_ci	switch (ip->proto) {
117762306a36Sopenharmony_ci	case htons(ETH_P_IP):
117862306a36Sopenharmony_ci		return ipv4_is_zeronet(ip->src.ip4);
117962306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_IPV6)
118062306a36Sopenharmony_ci	case htons(ETH_P_IPV6):
118162306a36Sopenharmony_ci		return ipv6_addr_any(&ip->src.ip6);
118262306a36Sopenharmony_ci#endif
118362306a36Sopenharmony_ci	default:
118462306a36Sopenharmony_ci		return false;
118562306a36Sopenharmony_ci	}
118662306a36Sopenharmony_ci}
118762306a36Sopenharmony_ci
118862306a36Sopenharmony_cistatic inline bool
118962306a36Sopenharmony_cibr_multicast_should_handle_mode(const struct net_bridge_mcast *brmctx,
119062306a36Sopenharmony_ci				__be16 proto)
119162306a36Sopenharmony_ci{
119262306a36Sopenharmony_ci	switch (proto) {
119362306a36Sopenharmony_ci	case htons(ETH_P_IP):
119462306a36Sopenharmony_ci		return !!(brmctx->multicast_igmp_version == 3);
119562306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_IPV6)
119662306a36Sopenharmony_ci	case htons(ETH_P_IPV6):
119762306a36Sopenharmony_ci		return !!(brmctx->multicast_mld_version == 2);
119862306a36Sopenharmony_ci#endif
119962306a36Sopenharmony_ci	default:
120062306a36Sopenharmony_ci		return false;
120162306a36Sopenharmony_ci	}
120262306a36Sopenharmony_ci}
120362306a36Sopenharmony_ci
120462306a36Sopenharmony_cistatic inline int br_multicast_igmp_type(const struct sk_buff *skb)
120562306a36Sopenharmony_ci{
120662306a36Sopenharmony_ci	return BR_INPUT_SKB_CB(skb)->igmp;
120762306a36Sopenharmony_ci}
120862306a36Sopenharmony_ci
120962306a36Sopenharmony_cistatic inline unsigned long br_multicast_lmqt(const struct net_bridge_mcast *brmctx)
121062306a36Sopenharmony_ci{
121162306a36Sopenharmony_ci	return brmctx->multicast_last_member_interval *
121262306a36Sopenharmony_ci	       brmctx->multicast_last_member_count;
121362306a36Sopenharmony_ci}
121462306a36Sopenharmony_ci
121562306a36Sopenharmony_cistatic inline unsigned long br_multicast_gmi(const struct net_bridge_mcast *brmctx)
121662306a36Sopenharmony_ci{
121762306a36Sopenharmony_ci	return brmctx->multicast_membership_interval;
121862306a36Sopenharmony_ci}
121962306a36Sopenharmony_ci
122062306a36Sopenharmony_cistatic inline bool
122162306a36Sopenharmony_cibr_multicast_ctx_is_vlan(const struct net_bridge_mcast *brmctx)
122262306a36Sopenharmony_ci{
122362306a36Sopenharmony_ci	return !!brmctx->vlan;
122462306a36Sopenharmony_ci}
122562306a36Sopenharmony_ci
122662306a36Sopenharmony_cistatic inline bool
122762306a36Sopenharmony_cibr_multicast_port_ctx_is_vlan(const struct net_bridge_mcast_port *pmctx)
122862306a36Sopenharmony_ci{
122962306a36Sopenharmony_ci	return !!pmctx->vlan;
123062306a36Sopenharmony_ci}
123162306a36Sopenharmony_ci
123262306a36Sopenharmony_cistatic inline struct net_bridge_mcast *
123362306a36Sopenharmony_cibr_multicast_port_ctx_get_global(const struct net_bridge_mcast_port *pmctx)
123462306a36Sopenharmony_ci{
123562306a36Sopenharmony_ci	if (!br_multicast_port_ctx_is_vlan(pmctx))
123662306a36Sopenharmony_ci		return &pmctx->port->br->multicast_ctx;
123762306a36Sopenharmony_ci	else
123862306a36Sopenharmony_ci		return &pmctx->vlan->brvlan->br_mcast_ctx;
123962306a36Sopenharmony_ci}
124062306a36Sopenharmony_ci
124162306a36Sopenharmony_cistatic inline bool
124262306a36Sopenharmony_cibr_multicast_ctx_vlan_global_disabled(const struct net_bridge_mcast *brmctx)
124362306a36Sopenharmony_ci{
124462306a36Sopenharmony_ci	return br_multicast_ctx_is_vlan(brmctx) &&
124562306a36Sopenharmony_ci	       (!br_opt_get(brmctx->br, BROPT_MCAST_VLAN_SNOOPING_ENABLED) ||
124662306a36Sopenharmony_ci		!(brmctx->vlan->priv_flags & BR_VLFLAG_GLOBAL_MCAST_ENABLED));
124762306a36Sopenharmony_ci}
124862306a36Sopenharmony_ci
124962306a36Sopenharmony_cistatic inline bool
125062306a36Sopenharmony_cibr_multicast_ctx_vlan_disabled(const struct net_bridge_mcast *brmctx)
125162306a36Sopenharmony_ci{
125262306a36Sopenharmony_ci	return br_multicast_ctx_is_vlan(brmctx) &&
125362306a36Sopenharmony_ci	       !(brmctx->vlan->priv_flags & BR_VLFLAG_MCAST_ENABLED);
125462306a36Sopenharmony_ci}
125562306a36Sopenharmony_ci
125662306a36Sopenharmony_cistatic inline bool
125762306a36Sopenharmony_cibr_multicast_port_ctx_vlan_disabled(const struct net_bridge_mcast_port *pmctx)
125862306a36Sopenharmony_ci{
125962306a36Sopenharmony_ci	return br_multicast_port_ctx_is_vlan(pmctx) &&
126062306a36Sopenharmony_ci	       !(pmctx->vlan->priv_flags & BR_VLFLAG_MCAST_ENABLED);
126162306a36Sopenharmony_ci}
126262306a36Sopenharmony_ci
126362306a36Sopenharmony_cistatic inline bool
126462306a36Sopenharmony_cibr_multicast_port_ctx_state_disabled(const struct net_bridge_mcast_port *pmctx)
126562306a36Sopenharmony_ci{
126662306a36Sopenharmony_ci	return pmctx->port->state == BR_STATE_DISABLED ||
126762306a36Sopenharmony_ci	       (br_multicast_port_ctx_is_vlan(pmctx) &&
126862306a36Sopenharmony_ci		(br_multicast_port_ctx_vlan_disabled(pmctx) ||
126962306a36Sopenharmony_ci		 pmctx->vlan->state == BR_STATE_DISABLED));
127062306a36Sopenharmony_ci}
127162306a36Sopenharmony_ci
127262306a36Sopenharmony_cistatic inline bool
127362306a36Sopenharmony_cibr_multicast_port_ctx_state_stopped(const struct net_bridge_mcast_port *pmctx)
127462306a36Sopenharmony_ci{
127562306a36Sopenharmony_ci	return br_multicast_port_ctx_state_disabled(pmctx) ||
127662306a36Sopenharmony_ci	       pmctx->port->state == BR_STATE_BLOCKING ||
127762306a36Sopenharmony_ci	       (br_multicast_port_ctx_is_vlan(pmctx) &&
127862306a36Sopenharmony_ci		pmctx->vlan->state == BR_STATE_BLOCKING);
127962306a36Sopenharmony_ci}
128062306a36Sopenharmony_ci
128162306a36Sopenharmony_cistatic inline bool
128262306a36Sopenharmony_cibr_rports_have_mc_router(const struct net_bridge_mcast *brmctx)
128362306a36Sopenharmony_ci{
128462306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_IPV6)
128562306a36Sopenharmony_ci	return !hlist_empty(&brmctx->ip4_mc_router_list) ||
128662306a36Sopenharmony_ci	       !hlist_empty(&brmctx->ip6_mc_router_list);
128762306a36Sopenharmony_ci#else
128862306a36Sopenharmony_ci	return !hlist_empty(&brmctx->ip4_mc_router_list);
128962306a36Sopenharmony_ci#endif
129062306a36Sopenharmony_ci}
129162306a36Sopenharmony_ci
129262306a36Sopenharmony_cistatic inline bool
129362306a36Sopenharmony_cibr_multicast_ctx_options_equal(const struct net_bridge_mcast *brmctx1,
129462306a36Sopenharmony_ci			       const struct net_bridge_mcast *brmctx2)
129562306a36Sopenharmony_ci{
129662306a36Sopenharmony_ci	return brmctx1->multicast_igmp_version ==
129762306a36Sopenharmony_ci	       brmctx2->multicast_igmp_version &&
129862306a36Sopenharmony_ci	       brmctx1->multicast_last_member_count ==
129962306a36Sopenharmony_ci	       brmctx2->multicast_last_member_count &&
130062306a36Sopenharmony_ci	       brmctx1->multicast_startup_query_count ==
130162306a36Sopenharmony_ci	       brmctx2->multicast_startup_query_count &&
130262306a36Sopenharmony_ci	       brmctx1->multicast_last_member_interval ==
130362306a36Sopenharmony_ci	       brmctx2->multicast_last_member_interval &&
130462306a36Sopenharmony_ci	       brmctx1->multicast_membership_interval ==
130562306a36Sopenharmony_ci	       brmctx2->multicast_membership_interval &&
130662306a36Sopenharmony_ci	       brmctx1->multicast_querier_interval ==
130762306a36Sopenharmony_ci	       brmctx2->multicast_querier_interval &&
130862306a36Sopenharmony_ci	       brmctx1->multicast_query_interval ==
130962306a36Sopenharmony_ci	       brmctx2->multicast_query_interval &&
131062306a36Sopenharmony_ci	       brmctx1->multicast_query_response_interval ==
131162306a36Sopenharmony_ci	       brmctx2->multicast_query_response_interval &&
131262306a36Sopenharmony_ci	       brmctx1->multicast_startup_query_interval ==
131362306a36Sopenharmony_ci	       brmctx2->multicast_startup_query_interval &&
131462306a36Sopenharmony_ci	       brmctx1->multicast_querier == brmctx2->multicast_querier &&
131562306a36Sopenharmony_ci	       brmctx1->multicast_router == brmctx2->multicast_router &&
131662306a36Sopenharmony_ci	       !br_rports_have_mc_router(brmctx1) &&
131762306a36Sopenharmony_ci	       !br_rports_have_mc_router(brmctx2) &&
131862306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_IPV6)
131962306a36Sopenharmony_ci	       brmctx1->multicast_mld_version ==
132062306a36Sopenharmony_ci	       brmctx2->multicast_mld_version &&
132162306a36Sopenharmony_ci#endif
132262306a36Sopenharmony_ci	       true;
132362306a36Sopenharmony_ci}
132462306a36Sopenharmony_ci
132562306a36Sopenharmony_cistatic inline bool
132662306a36Sopenharmony_cibr_multicast_ctx_matches_vlan_snooping(const struct net_bridge_mcast *brmctx)
132762306a36Sopenharmony_ci{
132862306a36Sopenharmony_ci	bool vlan_snooping_enabled;
132962306a36Sopenharmony_ci
133062306a36Sopenharmony_ci	vlan_snooping_enabled = !!br_opt_get(brmctx->br,
133162306a36Sopenharmony_ci					     BROPT_MCAST_VLAN_SNOOPING_ENABLED);
133262306a36Sopenharmony_ci
133362306a36Sopenharmony_ci	return !!(vlan_snooping_enabled == br_multicast_ctx_is_vlan(brmctx));
133462306a36Sopenharmony_ci}
133562306a36Sopenharmony_ci#else
133662306a36Sopenharmony_cistatic inline int br_multicast_rcv(struct net_bridge_mcast **brmctx,
133762306a36Sopenharmony_ci				   struct net_bridge_mcast_port **pmctx,
133862306a36Sopenharmony_ci				   struct net_bridge_vlan *vlan,
133962306a36Sopenharmony_ci				   struct sk_buff *skb,
134062306a36Sopenharmony_ci				   u16 vid)
134162306a36Sopenharmony_ci{
134262306a36Sopenharmony_ci	return 0;
134362306a36Sopenharmony_ci}
134462306a36Sopenharmony_ci
134562306a36Sopenharmony_cistatic inline struct net_bridge_mdb_entry *br_mdb_get(struct net_bridge_mcast *brmctx,
134662306a36Sopenharmony_ci						      struct sk_buff *skb, u16 vid)
134762306a36Sopenharmony_ci{
134862306a36Sopenharmony_ci	return NULL;
134962306a36Sopenharmony_ci}
135062306a36Sopenharmony_ci
135162306a36Sopenharmony_cistatic inline int br_multicast_add_port(struct net_bridge_port *port)
135262306a36Sopenharmony_ci{
135362306a36Sopenharmony_ci	return 0;
135462306a36Sopenharmony_ci}
135562306a36Sopenharmony_ci
135662306a36Sopenharmony_cistatic inline void br_multicast_del_port(struct net_bridge_port *port)
135762306a36Sopenharmony_ci{
135862306a36Sopenharmony_ci}
135962306a36Sopenharmony_ci
136062306a36Sopenharmony_cistatic inline void br_multicast_enable_port(struct net_bridge_port *port)
136162306a36Sopenharmony_ci{
136262306a36Sopenharmony_ci}
136362306a36Sopenharmony_ci
136462306a36Sopenharmony_cistatic inline void br_multicast_disable_port(struct net_bridge_port *port)
136562306a36Sopenharmony_ci{
136662306a36Sopenharmony_ci}
136762306a36Sopenharmony_ci
136862306a36Sopenharmony_cistatic inline void br_multicast_init(struct net_bridge *br)
136962306a36Sopenharmony_ci{
137062306a36Sopenharmony_ci}
137162306a36Sopenharmony_ci
137262306a36Sopenharmony_cistatic inline void br_multicast_join_snoopers(struct net_bridge *br)
137362306a36Sopenharmony_ci{
137462306a36Sopenharmony_ci}
137562306a36Sopenharmony_ci
137662306a36Sopenharmony_cistatic inline void br_multicast_leave_snoopers(struct net_bridge *br)
137762306a36Sopenharmony_ci{
137862306a36Sopenharmony_ci}
137962306a36Sopenharmony_ci
138062306a36Sopenharmony_cistatic inline void br_multicast_open(struct net_bridge *br)
138162306a36Sopenharmony_ci{
138262306a36Sopenharmony_ci}
138362306a36Sopenharmony_ci
138462306a36Sopenharmony_cistatic inline void br_multicast_stop(struct net_bridge *br)
138562306a36Sopenharmony_ci{
138662306a36Sopenharmony_ci}
138762306a36Sopenharmony_ci
138862306a36Sopenharmony_cistatic inline void br_multicast_dev_del(struct net_bridge *br)
138962306a36Sopenharmony_ci{
139062306a36Sopenharmony_ci}
139162306a36Sopenharmony_ci
139262306a36Sopenharmony_cistatic inline void br_multicast_flood(struct net_bridge_mdb_entry *mdst,
139362306a36Sopenharmony_ci				      struct sk_buff *skb,
139462306a36Sopenharmony_ci				      struct net_bridge_mcast *brmctx,
139562306a36Sopenharmony_ci				      bool local_rcv, bool local_orig)
139662306a36Sopenharmony_ci{
139762306a36Sopenharmony_ci}
139862306a36Sopenharmony_ci
139962306a36Sopenharmony_cistatic inline bool br_multicast_is_router(struct net_bridge_mcast *brmctx,
140062306a36Sopenharmony_ci					  struct sk_buff *skb)
140162306a36Sopenharmony_ci{
140262306a36Sopenharmony_ci	return false;
140362306a36Sopenharmony_ci}
140462306a36Sopenharmony_ci
140562306a36Sopenharmony_cistatic inline bool br_multicast_querier_exists(struct net_bridge_mcast *brmctx,
140662306a36Sopenharmony_ci					       struct ethhdr *eth,
140762306a36Sopenharmony_ci					       const struct net_bridge_mdb_entry *mdb)
140862306a36Sopenharmony_ci{
140962306a36Sopenharmony_ci	return false;
141062306a36Sopenharmony_ci}
141162306a36Sopenharmony_ci
141262306a36Sopenharmony_cistatic inline int br_mdb_add(struct net_device *dev, struct nlattr *tb[],
141362306a36Sopenharmony_ci			     u16 nlmsg_flags, struct netlink_ext_ack *extack)
141462306a36Sopenharmony_ci{
141562306a36Sopenharmony_ci	return -EOPNOTSUPP;
141662306a36Sopenharmony_ci}
141762306a36Sopenharmony_ci
141862306a36Sopenharmony_cistatic inline int br_mdb_del(struct net_device *dev, struct nlattr *tb[],
141962306a36Sopenharmony_ci			     struct netlink_ext_ack *extack)
142062306a36Sopenharmony_ci{
142162306a36Sopenharmony_ci	return -EOPNOTSUPP;
142262306a36Sopenharmony_ci}
142362306a36Sopenharmony_ci
142462306a36Sopenharmony_cistatic inline int br_mdb_dump(struct net_device *dev, struct sk_buff *skb,
142562306a36Sopenharmony_ci			      struct netlink_callback *cb)
142662306a36Sopenharmony_ci{
142762306a36Sopenharmony_ci	return 0;
142862306a36Sopenharmony_ci}
142962306a36Sopenharmony_ci
143062306a36Sopenharmony_cistatic inline int br_mdb_hash_init(struct net_bridge *br)
143162306a36Sopenharmony_ci{
143262306a36Sopenharmony_ci	return 0;
143362306a36Sopenharmony_ci}
143462306a36Sopenharmony_ci
143562306a36Sopenharmony_cistatic inline void br_mdb_hash_fini(struct net_bridge *br)
143662306a36Sopenharmony_ci{
143762306a36Sopenharmony_ci}
143862306a36Sopenharmony_ci
143962306a36Sopenharmony_cistatic inline void br_multicast_count(struct net_bridge *br,
144062306a36Sopenharmony_ci				      const struct net_bridge_port *p,
144162306a36Sopenharmony_ci				      const struct sk_buff *skb,
144262306a36Sopenharmony_ci				      u8 type, u8 dir)
144362306a36Sopenharmony_ci{
144462306a36Sopenharmony_ci}
144562306a36Sopenharmony_ci
144662306a36Sopenharmony_cistatic inline int br_multicast_init_stats(struct net_bridge *br)
144762306a36Sopenharmony_ci{
144862306a36Sopenharmony_ci	return 0;
144962306a36Sopenharmony_ci}
145062306a36Sopenharmony_ci
145162306a36Sopenharmony_cistatic inline void br_multicast_uninit_stats(struct net_bridge *br)
145262306a36Sopenharmony_ci{
145362306a36Sopenharmony_ci}
145462306a36Sopenharmony_ci
145562306a36Sopenharmony_cistatic inline int br_multicast_igmp_type(const struct sk_buff *skb)
145662306a36Sopenharmony_ci{
145762306a36Sopenharmony_ci	return 0;
145862306a36Sopenharmony_ci}
145962306a36Sopenharmony_ci
146062306a36Sopenharmony_cistatic inline void br_multicast_ctx_init(struct net_bridge *br,
146162306a36Sopenharmony_ci					 struct net_bridge_vlan *vlan,
146262306a36Sopenharmony_ci					 struct net_bridge_mcast *brmctx)
146362306a36Sopenharmony_ci{
146462306a36Sopenharmony_ci}
146562306a36Sopenharmony_ci
146662306a36Sopenharmony_cistatic inline void br_multicast_ctx_deinit(struct net_bridge_mcast *brmctx)
146762306a36Sopenharmony_ci{
146862306a36Sopenharmony_ci}
146962306a36Sopenharmony_ci
147062306a36Sopenharmony_cistatic inline void br_multicast_port_ctx_init(struct net_bridge_port *port,
147162306a36Sopenharmony_ci					      struct net_bridge_vlan *vlan,
147262306a36Sopenharmony_ci					      struct net_bridge_mcast_port *pmctx)
147362306a36Sopenharmony_ci{
147462306a36Sopenharmony_ci}
147562306a36Sopenharmony_ci
147662306a36Sopenharmony_cistatic inline void br_multicast_port_ctx_deinit(struct net_bridge_mcast_port *pmctx)
147762306a36Sopenharmony_ci{
147862306a36Sopenharmony_ci}
147962306a36Sopenharmony_ci
148062306a36Sopenharmony_cistatic inline void br_multicast_toggle_one_vlan(struct net_bridge_vlan *vlan,
148162306a36Sopenharmony_ci						bool on)
148262306a36Sopenharmony_ci{
148362306a36Sopenharmony_ci}
148462306a36Sopenharmony_ci
148562306a36Sopenharmony_cistatic inline int br_multicast_toggle_vlan_snooping(struct net_bridge *br,
148662306a36Sopenharmony_ci						    bool on,
148762306a36Sopenharmony_ci						    struct netlink_ext_ack *extack)
148862306a36Sopenharmony_ci{
148962306a36Sopenharmony_ci	return -EOPNOTSUPP;
149062306a36Sopenharmony_ci}
149162306a36Sopenharmony_ci
149262306a36Sopenharmony_cistatic inline bool br_multicast_toggle_global_vlan(struct net_bridge_vlan *vlan,
149362306a36Sopenharmony_ci						   bool on)
149462306a36Sopenharmony_ci{
149562306a36Sopenharmony_ci	return false;
149662306a36Sopenharmony_ci}
149762306a36Sopenharmony_ci
149862306a36Sopenharmony_cistatic inline bool
149962306a36Sopenharmony_cibr_multicast_ctx_options_equal(const struct net_bridge_mcast *brmctx1,
150062306a36Sopenharmony_ci			       const struct net_bridge_mcast *brmctx2)
150162306a36Sopenharmony_ci{
150262306a36Sopenharmony_ci	return true;
150362306a36Sopenharmony_ci}
150462306a36Sopenharmony_ci#endif
150562306a36Sopenharmony_ci
150662306a36Sopenharmony_ci/* br_vlan.c */
150762306a36Sopenharmony_ci#ifdef CONFIG_BRIDGE_VLAN_FILTERING
150862306a36Sopenharmony_cibool br_allowed_ingress(const struct net_bridge *br,
150962306a36Sopenharmony_ci			struct net_bridge_vlan_group *vg, struct sk_buff *skb,
151062306a36Sopenharmony_ci			u16 *vid, u8 *state,
151162306a36Sopenharmony_ci			struct net_bridge_vlan **vlan);
151262306a36Sopenharmony_cibool br_allowed_egress(struct net_bridge_vlan_group *vg,
151362306a36Sopenharmony_ci		       const struct sk_buff *skb);
151462306a36Sopenharmony_cibool br_should_learn(struct net_bridge_port *p, struct sk_buff *skb, u16 *vid);
151562306a36Sopenharmony_cistruct sk_buff *br_handle_vlan(struct net_bridge *br,
151662306a36Sopenharmony_ci			       const struct net_bridge_port *port,
151762306a36Sopenharmony_ci			       struct net_bridge_vlan_group *vg,
151862306a36Sopenharmony_ci			       struct sk_buff *skb);
151962306a36Sopenharmony_ciint br_vlan_add(struct net_bridge *br, u16 vid, u16 flags,
152062306a36Sopenharmony_ci		bool *changed, struct netlink_ext_ack *extack);
152162306a36Sopenharmony_ciint br_vlan_delete(struct net_bridge *br, u16 vid);
152262306a36Sopenharmony_civoid br_vlan_flush(struct net_bridge *br);
152362306a36Sopenharmony_cistruct net_bridge_vlan *br_vlan_find(struct net_bridge_vlan_group *vg, u16 vid);
152462306a36Sopenharmony_civoid br_recalculate_fwd_mask(struct net_bridge *br);
152562306a36Sopenharmony_ciint br_vlan_filter_toggle(struct net_bridge *br, unsigned long val,
152662306a36Sopenharmony_ci			  struct netlink_ext_ack *extack);
152762306a36Sopenharmony_ciint __br_vlan_set_proto(struct net_bridge *br, __be16 proto,
152862306a36Sopenharmony_ci			struct netlink_ext_ack *extack);
152962306a36Sopenharmony_ciint br_vlan_set_proto(struct net_bridge *br, unsigned long val,
153062306a36Sopenharmony_ci		      struct netlink_ext_ack *extack);
153162306a36Sopenharmony_ciint br_vlan_set_stats(struct net_bridge *br, unsigned long val);
153262306a36Sopenharmony_ciint br_vlan_set_stats_per_port(struct net_bridge *br, unsigned long val);
153362306a36Sopenharmony_ciint br_vlan_init(struct net_bridge *br);
153462306a36Sopenharmony_ciint br_vlan_set_default_pvid(struct net_bridge *br, unsigned long val,
153562306a36Sopenharmony_ci			     struct netlink_ext_ack *extack);
153662306a36Sopenharmony_ciint __br_vlan_set_default_pvid(struct net_bridge *br, u16 pvid,
153762306a36Sopenharmony_ci			       struct netlink_ext_ack *extack);
153862306a36Sopenharmony_ciint nbp_vlan_add(struct net_bridge_port *port, u16 vid, u16 flags,
153962306a36Sopenharmony_ci		 bool *changed, struct netlink_ext_ack *extack);
154062306a36Sopenharmony_ciint nbp_vlan_delete(struct net_bridge_port *port, u16 vid);
154162306a36Sopenharmony_civoid nbp_vlan_flush(struct net_bridge_port *port);
154262306a36Sopenharmony_ciint nbp_vlan_init(struct net_bridge_port *port, struct netlink_ext_ack *extack);
154362306a36Sopenharmony_ciint nbp_get_num_vlan_infos(struct net_bridge_port *p, u32 filter_mask);
154462306a36Sopenharmony_civoid br_vlan_get_stats(const struct net_bridge_vlan *v,
154562306a36Sopenharmony_ci		       struct pcpu_sw_netstats *stats);
154662306a36Sopenharmony_civoid br_vlan_port_event(struct net_bridge_port *p, unsigned long event);
154762306a36Sopenharmony_ciint br_vlan_bridge_event(struct net_device *dev, unsigned long event,
154862306a36Sopenharmony_ci			 void *ptr);
154962306a36Sopenharmony_civoid br_vlan_rtnl_init(void);
155062306a36Sopenharmony_civoid br_vlan_rtnl_uninit(void);
155162306a36Sopenharmony_civoid br_vlan_notify(const struct net_bridge *br,
155262306a36Sopenharmony_ci		    const struct net_bridge_port *p,
155362306a36Sopenharmony_ci		    u16 vid, u16 vid_range,
155462306a36Sopenharmony_ci		    int cmd);
155562306a36Sopenharmony_cibool br_vlan_can_enter_range(const struct net_bridge_vlan *v_curr,
155662306a36Sopenharmony_ci			     const struct net_bridge_vlan *range_end);
155762306a36Sopenharmony_ci
155862306a36Sopenharmony_civoid br_vlan_fill_forward_path_pvid(struct net_bridge *br,
155962306a36Sopenharmony_ci				    struct net_device_path_ctx *ctx,
156062306a36Sopenharmony_ci				    struct net_device_path *path);
156162306a36Sopenharmony_ciint br_vlan_fill_forward_path_mode(struct net_bridge *br,
156262306a36Sopenharmony_ci				   struct net_bridge_port *dst,
156362306a36Sopenharmony_ci				   struct net_device_path *path);
156462306a36Sopenharmony_ci
156562306a36Sopenharmony_cistatic inline struct net_bridge_vlan_group *br_vlan_group(
156662306a36Sopenharmony_ci					const struct net_bridge *br)
156762306a36Sopenharmony_ci{
156862306a36Sopenharmony_ci	return rtnl_dereference(br->vlgrp);
156962306a36Sopenharmony_ci}
157062306a36Sopenharmony_ci
157162306a36Sopenharmony_cistatic inline struct net_bridge_vlan_group *nbp_vlan_group(
157262306a36Sopenharmony_ci					const struct net_bridge_port *p)
157362306a36Sopenharmony_ci{
157462306a36Sopenharmony_ci	return rtnl_dereference(p->vlgrp);
157562306a36Sopenharmony_ci}
157662306a36Sopenharmony_ci
157762306a36Sopenharmony_cistatic inline struct net_bridge_vlan_group *br_vlan_group_rcu(
157862306a36Sopenharmony_ci					const struct net_bridge *br)
157962306a36Sopenharmony_ci{
158062306a36Sopenharmony_ci	return rcu_dereference(br->vlgrp);
158162306a36Sopenharmony_ci}
158262306a36Sopenharmony_ci
158362306a36Sopenharmony_cistatic inline struct net_bridge_vlan_group *nbp_vlan_group_rcu(
158462306a36Sopenharmony_ci					const struct net_bridge_port *p)
158562306a36Sopenharmony_ci{
158662306a36Sopenharmony_ci	return rcu_dereference(p->vlgrp);
158762306a36Sopenharmony_ci}
158862306a36Sopenharmony_ci
158962306a36Sopenharmony_ci/* Since bridge now depends on 8021Q module, but the time bridge sees the
159062306a36Sopenharmony_ci * skb, the vlan tag will always be present if the frame was tagged.
159162306a36Sopenharmony_ci */
159262306a36Sopenharmony_cistatic inline int br_vlan_get_tag(const struct sk_buff *skb, u16 *vid)
159362306a36Sopenharmony_ci{
159462306a36Sopenharmony_ci	int err = 0;
159562306a36Sopenharmony_ci
159662306a36Sopenharmony_ci	if (skb_vlan_tag_present(skb)) {
159762306a36Sopenharmony_ci		*vid = skb_vlan_tag_get_id(skb);
159862306a36Sopenharmony_ci	} else {
159962306a36Sopenharmony_ci		*vid = 0;
160062306a36Sopenharmony_ci		err = -EINVAL;
160162306a36Sopenharmony_ci	}
160262306a36Sopenharmony_ci
160362306a36Sopenharmony_ci	return err;
160462306a36Sopenharmony_ci}
160562306a36Sopenharmony_ci
160662306a36Sopenharmony_cistatic inline u16 br_get_pvid(const struct net_bridge_vlan_group *vg)
160762306a36Sopenharmony_ci{
160862306a36Sopenharmony_ci	if (!vg)
160962306a36Sopenharmony_ci		return 0;
161062306a36Sopenharmony_ci
161162306a36Sopenharmony_ci	smp_rmb();
161262306a36Sopenharmony_ci	return vg->pvid;
161362306a36Sopenharmony_ci}
161462306a36Sopenharmony_ci
161562306a36Sopenharmony_cistatic inline u16 br_vlan_flags(const struct net_bridge_vlan *v, u16 pvid)
161662306a36Sopenharmony_ci{
161762306a36Sopenharmony_ci	return v->vid == pvid ? v->flags | BRIDGE_VLAN_INFO_PVID : v->flags;
161862306a36Sopenharmony_ci}
161962306a36Sopenharmony_ci#else
162062306a36Sopenharmony_cistatic inline bool br_allowed_ingress(const struct net_bridge *br,
162162306a36Sopenharmony_ci				      struct net_bridge_vlan_group *vg,
162262306a36Sopenharmony_ci				      struct sk_buff *skb,
162362306a36Sopenharmony_ci				      u16 *vid, u8 *state,
162462306a36Sopenharmony_ci				      struct net_bridge_vlan **vlan)
162562306a36Sopenharmony_ci
162662306a36Sopenharmony_ci{
162762306a36Sopenharmony_ci	*vlan = NULL;
162862306a36Sopenharmony_ci	return true;
162962306a36Sopenharmony_ci}
163062306a36Sopenharmony_ci
163162306a36Sopenharmony_cistatic inline bool br_allowed_egress(struct net_bridge_vlan_group *vg,
163262306a36Sopenharmony_ci				     const struct sk_buff *skb)
163362306a36Sopenharmony_ci{
163462306a36Sopenharmony_ci	return true;
163562306a36Sopenharmony_ci}
163662306a36Sopenharmony_ci
163762306a36Sopenharmony_cistatic inline bool br_should_learn(struct net_bridge_port *p,
163862306a36Sopenharmony_ci				   struct sk_buff *skb, u16 *vid)
163962306a36Sopenharmony_ci{
164062306a36Sopenharmony_ci	return true;
164162306a36Sopenharmony_ci}
164262306a36Sopenharmony_ci
164362306a36Sopenharmony_cistatic inline struct sk_buff *br_handle_vlan(struct net_bridge *br,
164462306a36Sopenharmony_ci					     const struct net_bridge_port *port,
164562306a36Sopenharmony_ci					     struct net_bridge_vlan_group *vg,
164662306a36Sopenharmony_ci					     struct sk_buff *skb)
164762306a36Sopenharmony_ci{
164862306a36Sopenharmony_ci	return skb;
164962306a36Sopenharmony_ci}
165062306a36Sopenharmony_ci
165162306a36Sopenharmony_cistatic inline int br_vlan_add(struct net_bridge *br, u16 vid, u16 flags,
165262306a36Sopenharmony_ci			      bool *changed, struct netlink_ext_ack *extack)
165362306a36Sopenharmony_ci{
165462306a36Sopenharmony_ci	*changed = false;
165562306a36Sopenharmony_ci	return -EOPNOTSUPP;
165662306a36Sopenharmony_ci}
165762306a36Sopenharmony_ci
165862306a36Sopenharmony_cistatic inline int br_vlan_delete(struct net_bridge *br, u16 vid)
165962306a36Sopenharmony_ci{
166062306a36Sopenharmony_ci	return -EOPNOTSUPP;
166162306a36Sopenharmony_ci}
166262306a36Sopenharmony_ci
166362306a36Sopenharmony_cistatic inline void br_vlan_flush(struct net_bridge *br)
166462306a36Sopenharmony_ci{
166562306a36Sopenharmony_ci}
166662306a36Sopenharmony_ci
166762306a36Sopenharmony_cistatic inline void br_recalculate_fwd_mask(struct net_bridge *br)
166862306a36Sopenharmony_ci{
166962306a36Sopenharmony_ci}
167062306a36Sopenharmony_ci
167162306a36Sopenharmony_cistatic inline int br_vlan_init(struct net_bridge *br)
167262306a36Sopenharmony_ci{
167362306a36Sopenharmony_ci	return 0;
167462306a36Sopenharmony_ci}
167562306a36Sopenharmony_ci
167662306a36Sopenharmony_cistatic inline int nbp_vlan_add(struct net_bridge_port *port, u16 vid, u16 flags,
167762306a36Sopenharmony_ci			       bool *changed, struct netlink_ext_ack *extack)
167862306a36Sopenharmony_ci{
167962306a36Sopenharmony_ci	*changed = false;
168062306a36Sopenharmony_ci	return -EOPNOTSUPP;
168162306a36Sopenharmony_ci}
168262306a36Sopenharmony_ci
168362306a36Sopenharmony_cistatic inline int nbp_vlan_delete(struct net_bridge_port *port, u16 vid)
168462306a36Sopenharmony_ci{
168562306a36Sopenharmony_ci	return -EOPNOTSUPP;
168662306a36Sopenharmony_ci}
168762306a36Sopenharmony_ci
168862306a36Sopenharmony_cistatic inline void nbp_vlan_flush(struct net_bridge_port *port)
168962306a36Sopenharmony_ci{
169062306a36Sopenharmony_ci}
169162306a36Sopenharmony_ci
169262306a36Sopenharmony_cistatic inline struct net_bridge_vlan *br_vlan_find(struct net_bridge_vlan_group *vg,
169362306a36Sopenharmony_ci						   u16 vid)
169462306a36Sopenharmony_ci{
169562306a36Sopenharmony_ci	return NULL;
169662306a36Sopenharmony_ci}
169762306a36Sopenharmony_ci
169862306a36Sopenharmony_cistatic inline int nbp_vlan_init(struct net_bridge_port *port,
169962306a36Sopenharmony_ci				struct netlink_ext_ack *extack)
170062306a36Sopenharmony_ci{
170162306a36Sopenharmony_ci	return 0;
170262306a36Sopenharmony_ci}
170362306a36Sopenharmony_ci
170462306a36Sopenharmony_cistatic inline u16 br_vlan_get_tag(const struct sk_buff *skb, u16 *tag)
170562306a36Sopenharmony_ci{
170662306a36Sopenharmony_ci	return 0;
170762306a36Sopenharmony_ci}
170862306a36Sopenharmony_ci
170962306a36Sopenharmony_cistatic inline u16 br_get_pvid(const struct net_bridge_vlan_group *vg)
171062306a36Sopenharmony_ci{
171162306a36Sopenharmony_ci	return 0;
171262306a36Sopenharmony_ci}
171362306a36Sopenharmony_ci
171462306a36Sopenharmony_cistatic inline int br_vlan_filter_toggle(struct net_bridge *br,
171562306a36Sopenharmony_ci					unsigned long val,
171662306a36Sopenharmony_ci					struct netlink_ext_ack *extack)
171762306a36Sopenharmony_ci{
171862306a36Sopenharmony_ci	return -EOPNOTSUPP;
171962306a36Sopenharmony_ci}
172062306a36Sopenharmony_ci
172162306a36Sopenharmony_cistatic inline int nbp_get_num_vlan_infos(struct net_bridge_port *p,
172262306a36Sopenharmony_ci					 u32 filter_mask)
172362306a36Sopenharmony_ci{
172462306a36Sopenharmony_ci	return 0;
172562306a36Sopenharmony_ci}
172662306a36Sopenharmony_ci
172762306a36Sopenharmony_cistatic inline void br_vlan_fill_forward_path_pvid(struct net_bridge *br,
172862306a36Sopenharmony_ci						  struct net_device_path_ctx *ctx,
172962306a36Sopenharmony_ci						  struct net_device_path *path)
173062306a36Sopenharmony_ci{
173162306a36Sopenharmony_ci}
173262306a36Sopenharmony_ci
173362306a36Sopenharmony_cistatic inline int br_vlan_fill_forward_path_mode(struct net_bridge *br,
173462306a36Sopenharmony_ci						 struct net_bridge_port *dst,
173562306a36Sopenharmony_ci						 struct net_device_path *path)
173662306a36Sopenharmony_ci{
173762306a36Sopenharmony_ci	return 0;
173862306a36Sopenharmony_ci}
173962306a36Sopenharmony_ci
174062306a36Sopenharmony_cistatic inline struct net_bridge_vlan_group *br_vlan_group(
174162306a36Sopenharmony_ci					const struct net_bridge *br)
174262306a36Sopenharmony_ci{
174362306a36Sopenharmony_ci	return NULL;
174462306a36Sopenharmony_ci}
174562306a36Sopenharmony_ci
174662306a36Sopenharmony_cistatic inline struct net_bridge_vlan_group *nbp_vlan_group(
174762306a36Sopenharmony_ci					const struct net_bridge_port *p)
174862306a36Sopenharmony_ci{
174962306a36Sopenharmony_ci	return NULL;
175062306a36Sopenharmony_ci}
175162306a36Sopenharmony_ci
175262306a36Sopenharmony_cistatic inline struct net_bridge_vlan_group *br_vlan_group_rcu(
175362306a36Sopenharmony_ci					const struct net_bridge *br)
175462306a36Sopenharmony_ci{
175562306a36Sopenharmony_ci	return NULL;
175662306a36Sopenharmony_ci}
175762306a36Sopenharmony_ci
175862306a36Sopenharmony_cistatic inline struct net_bridge_vlan_group *nbp_vlan_group_rcu(
175962306a36Sopenharmony_ci					const struct net_bridge_port *p)
176062306a36Sopenharmony_ci{
176162306a36Sopenharmony_ci	return NULL;
176262306a36Sopenharmony_ci}
176362306a36Sopenharmony_ci
176462306a36Sopenharmony_cistatic inline void br_vlan_get_stats(const struct net_bridge_vlan *v,
176562306a36Sopenharmony_ci				     struct pcpu_sw_netstats *stats)
176662306a36Sopenharmony_ci{
176762306a36Sopenharmony_ci}
176862306a36Sopenharmony_ci
176962306a36Sopenharmony_cistatic inline void br_vlan_port_event(struct net_bridge_port *p,
177062306a36Sopenharmony_ci				      unsigned long event)
177162306a36Sopenharmony_ci{
177262306a36Sopenharmony_ci}
177362306a36Sopenharmony_ci
177462306a36Sopenharmony_cistatic inline int br_vlan_bridge_event(struct net_device *dev,
177562306a36Sopenharmony_ci				       unsigned long event, void *ptr)
177662306a36Sopenharmony_ci{
177762306a36Sopenharmony_ci	return 0;
177862306a36Sopenharmony_ci}
177962306a36Sopenharmony_ci
178062306a36Sopenharmony_cistatic inline void br_vlan_rtnl_init(void)
178162306a36Sopenharmony_ci{
178262306a36Sopenharmony_ci}
178362306a36Sopenharmony_ci
178462306a36Sopenharmony_cistatic inline void br_vlan_rtnl_uninit(void)
178562306a36Sopenharmony_ci{
178662306a36Sopenharmony_ci}
178762306a36Sopenharmony_ci
178862306a36Sopenharmony_cistatic inline void br_vlan_notify(const struct net_bridge *br,
178962306a36Sopenharmony_ci				  const struct net_bridge_port *p,
179062306a36Sopenharmony_ci				  u16 vid, u16 vid_range,
179162306a36Sopenharmony_ci				  int cmd)
179262306a36Sopenharmony_ci{
179362306a36Sopenharmony_ci}
179462306a36Sopenharmony_ci
179562306a36Sopenharmony_cistatic inline bool br_vlan_can_enter_range(const struct net_bridge_vlan *v_curr,
179662306a36Sopenharmony_ci					   const struct net_bridge_vlan *range_end)
179762306a36Sopenharmony_ci{
179862306a36Sopenharmony_ci	return true;
179962306a36Sopenharmony_ci}
180062306a36Sopenharmony_ci
180162306a36Sopenharmony_cistatic inline u16 br_vlan_flags(const struct net_bridge_vlan *v, u16 pvid)
180262306a36Sopenharmony_ci{
180362306a36Sopenharmony_ci	return 0;
180462306a36Sopenharmony_ci}
180562306a36Sopenharmony_ci
180662306a36Sopenharmony_ci#endif
180762306a36Sopenharmony_ci
180862306a36Sopenharmony_ci/* br_vlan_options.c */
180962306a36Sopenharmony_ci#ifdef CONFIG_BRIDGE_VLAN_FILTERING
181062306a36Sopenharmony_cibool br_vlan_opts_eq_range(const struct net_bridge_vlan *v_curr,
181162306a36Sopenharmony_ci			   const struct net_bridge_vlan *range_end);
181262306a36Sopenharmony_cibool br_vlan_opts_fill(struct sk_buff *skb, const struct net_bridge_vlan *v,
181362306a36Sopenharmony_ci		       const struct net_bridge_port *p);
181462306a36Sopenharmony_cisize_t br_vlan_opts_nl_size(void);
181562306a36Sopenharmony_ciint br_vlan_process_options(const struct net_bridge *br,
181662306a36Sopenharmony_ci			    const struct net_bridge_port *p,
181762306a36Sopenharmony_ci			    struct net_bridge_vlan *range_start,
181862306a36Sopenharmony_ci			    struct net_bridge_vlan *range_end,
181962306a36Sopenharmony_ci			    struct nlattr **tb,
182062306a36Sopenharmony_ci			    struct netlink_ext_ack *extack);
182162306a36Sopenharmony_ciint br_vlan_rtm_process_global_options(struct net_device *dev,
182262306a36Sopenharmony_ci				       const struct nlattr *attr,
182362306a36Sopenharmony_ci				       int cmd,
182462306a36Sopenharmony_ci				       struct netlink_ext_ack *extack);
182562306a36Sopenharmony_cibool br_vlan_global_opts_can_enter_range(const struct net_bridge_vlan *v_curr,
182662306a36Sopenharmony_ci					 const struct net_bridge_vlan *r_end);
182762306a36Sopenharmony_cibool br_vlan_global_opts_fill(struct sk_buff *skb, u16 vid, u16 vid_range,
182862306a36Sopenharmony_ci			      const struct net_bridge_vlan *v_opts);
182962306a36Sopenharmony_ci
183062306a36Sopenharmony_ci/* vlan state manipulation helpers using *_ONCE to annotate lock-free access */
183162306a36Sopenharmony_cistatic inline u8 br_vlan_get_state(const struct net_bridge_vlan *v)
183262306a36Sopenharmony_ci{
183362306a36Sopenharmony_ci	return READ_ONCE(v->state);
183462306a36Sopenharmony_ci}
183562306a36Sopenharmony_ci
183662306a36Sopenharmony_cistatic inline void br_vlan_set_state(struct net_bridge_vlan *v, u8 state)
183762306a36Sopenharmony_ci{
183862306a36Sopenharmony_ci	WRITE_ONCE(v->state, state);
183962306a36Sopenharmony_ci}
184062306a36Sopenharmony_ci
184162306a36Sopenharmony_cistatic inline u8 br_vlan_get_pvid_state(const struct net_bridge_vlan_group *vg)
184262306a36Sopenharmony_ci{
184362306a36Sopenharmony_ci	return READ_ONCE(vg->pvid_state);
184462306a36Sopenharmony_ci}
184562306a36Sopenharmony_ci
184662306a36Sopenharmony_cistatic inline void br_vlan_set_pvid_state(struct net_bridge_vlan_group *vg,
184762306a36Sopenharmony_ci					  u8 state)
184862306a36Sopenharmony_ci{
184962306a36Sopenharmony_ci	WRITE_ONCE(vg->pvid_state, state);
185062306a36Sopenharmony_ci}
185162306a36Sopenharmony_ci
185262306a36Sopenharmony_ci/* learn_allow is true at ingress and false at egress */
185362306a36Sopenharmony_cistatic inline bool br_vlan_state_allowed(u8 state, bool learn_allow)
185462306a36Sopenharmony_ci{
185562306a36Sopenharmony_ci	switch (state) {
185662306a36Sopenharmony_ci	case BR_STATE_LEARNING:
185762306a36Sopenharmony_ci		return learn_allow;
185862306a36Sopenharmony_ci	case BR_STATE_FORWARDING:
185962306a36Sopenharmony_ci		return true;
186062306a36Sopenharmony_ci	default:
186162306a36Sopenharmony_ci		return false;
186262306a36Sopenharmony_ci	}
186362306a36Sopenharmony_ci}
186462306a36Sopenharmony_ci#endif
186562306a36Sopenharmony_ci
186662306a36Sopenharmony_ci/* br_mst.c */
186762306a36Sopenharmony_ci#ifdef CONFIG_BRIDGE_VLAN_FILTERING
186862306a36Sopenharmony_ciDECLARE_STATIC_KEY_FALSE(br_mst_used);
186962306a36Sopenharmony_cistatic inline bool br_mst_is_enabled(struct net_bridge *br)
187062306a36Sopenharmony_ci{
187162306a36Sopenharmony_ci	return static_branch_unlikely(&br_mst_used) &&
187262306a36Sopenharmony_ci		br_opt_get(br, BROPT_MST_ENABLED);
187362306a36Sopenharmony_ci}
187462306a36Sopenharmony_ci
187562306a36Sopenharmony_ciint br_mst_set_state(struct net_bridge_port *p, u16 msti, u8 state,
187662306a36Sopenharmony_ci		     struct netlink_ext_ack *extack);
187762306a36Sopenharmony_ciint br_mst_vlan_set_msti(struct net_bridge_vlan *v, u16 msti);
187862306a36Sopenharmony_civoid br_mst_vlan_init_state(struct net_bridge_vlan *v);
187962306a36Sopenharmony_ciint br_mst_set_enabled(struct net_bridge *br, bool on,
188062306a36Sopenharmony_ci		       struct netlink_ext_ack *extack);
188162306a36Sopenharmony_cisize_t br_mst_info_size(const struct net_bridge_vlan_group *vg);
188262306a36Sopenharmony_ciint br_mst_fill_info(struct sk_buff *skb,
188362306a36Sopenharmony_ci		     const struct net_bridge_vlan_group *vg);
188462306a36Sopenharmony_ciint br_mst_process(struct net_bridge_port *p, const struct nlattr *mst_attr,
188562306a36Sopenharmony_ci		   struct netlink_ext_ack *extack);
188662306a36Sopenharmony_ci#else
188762306a36Sopenharmony_cistatic inline bool br_mst_is_enabled(struct net_bridge *br)
188862306a36Sopenharmony_ci{
188962306a36Sopenharmony_ci	return false;
189062306a36Sopenharmony_ci}
189162306a36Sopenharmony_ci
189262306a36Sopenharmony_cistatic inline int br_mst_set_state(struct net_bridge_port *p, u16 msti,
189362306a36Sopenharmony_ci				   u8 state, struct netlink_ext_ack *extack)
189462306a36Sopenharmony_ci{
189562306a36Sopenharmony_ci	return -EOPNOTSUPP;
189662306a36Sopenharmony_ci}
189762306a36Sopenharmony_ci
189862306a36Sopenharmony_cistatic inline int br_mst_set_enabled(struct net_bridge *br, bool on,
189962306a36Sopenharmony_ci				     struct netlink_ext_ack *extack)
190062306a36Sopenharmony_ci{
190162306a36Sopenharmony_ci	return -EOPNOTSUPP;
190262306a36Sopenharmony_ci}
190362306a36Sopenharmony_ci
190462306a36Sopenharmony_cistatic inline size_t br_mst_info_size(const struct net_bridge_vlan_group *vg)
190562306a36Sopenharmony_ci{
190662306a36Sopenharmony_ci	return 0;
190762306a36Sopenharmony_ci}
190862306a36Sopenharmony_ci
190962306a36Sopenharmony_cistatic inline int br_mst_fill_info(struct sk_buff *skb,
191062306a36Sopenharmony_ci				   const struct net_bridge_vlan_group *vg)
191162306a36Sopenharmony_ci{
191262306a36Sopenharmony_ci	return -EOPNOTSUPP;
191362306a36Sopenharmony_ci}
191462306a36Sopenharmony_ci
191562306a36Sopenharmony_cistatic inline int br_mst_process(struct net_bridge_port *p,
191662306a36Sopenharmony_ci				 const struct nlattr *mst_attr,
191762306a36Sopenharmony_ci				 struct netlink_ext_ack *extack)
191862306a36Sopenharmony_ci{
191962306a36Sopenharmony_ci	return -EOPNOTSUPP;
192062306a36Sopenharmony_ci}
192162306a36Sopenharmony_ci#endif
192262306a36Sopenharmony_ci
192362306a36Sopenharmony_cistruct nf_br_ops {
192462306a36Sopenharmony_ci	int (*br_dev_xmit_hook)(struct sk_buff *skb);
192562306a36Sopenharmony_ci};
192662306a36Sopenharmony_ciextern const struct nf_br_ops __rcu *nf_br_ops;
192762306a36Sopenharmony_ci
192862306a36Sopenharmony_ci/* br_netfilter.c */
192962306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
193062306a36Sopenharmony_ciint br_nf_core_init(void);
193162306a36Sopenharmony_civoid br_nf_core_fini(void);
193262306a36Sopenharmony_civoid br_netfilter_rtable_init(struct net_bridge *);
193362306a36Sopenharmony_ci#else
193462306a36Sopenharmony_cistatic inline int br_nf_core_init(void) { return 0; }
193562306a36Sopenharmony_cistatic inline void br_nf_core_fini(void) {}
193662306a36Sopenharmony_ci#define br_netfilter_rtable_init(x)
193762306a36Sopenharmony_ci#endif
193862306a36Sopenharmony_ci
193962306a36Sopenharmony_ci/* br_stp.c */
194062306a36Sopenharmony_civoid br_set_state(struct net_bridge_port *p, unsigned int state);
194162306a36Sopenharmony_cistruct net_bridge_port *br_get_port(struct net_bridge *br, u16 port_no);
194262306a36Sopenharmony_civoid br_init_port(struct net_bridge_port *p);
194362306a36Sopenharmony_civoid br_become_designated_port(struct net_bridge_port *p);
194462306a36Sopenharmony_ci
194562306a36Sopenharmony_civoid __br_set_forward_delay(struct net_bridge *br, unsigned long t);
194662306a36Sopenharmony_ciint br_set_forward_delay(struct net_bridge *br, unsigned long x);
194762306a36Sopenharmony_ciint br_set_hello_time(struct net_bridge *br, unsigned long x);
194862306a36Sopenharmony_ciint br_set_max_age(struct net_bridge *br, unsigned long x);
194962306a36Sopenharmony_ciint __set_ageing_time(struct net_device *dev, unsigned long t);
195062306a36Sopenharmony_ciint br_set_ageing_time(struct net_bridge *br, clock_t ageing_time);
195162306a36Sopenharmony_ci
195262306a36Sopenharmony_ci
195362306a36Sopenharmony_ci/* br_stp_if.c */
195462306a36Sopenharmony_civoid br_stp_enable_bridge(struct net_bridge *br);
195562306a36Sopenharmony_civoid br_stp_disable_bridge(struct net_bridge *br);
195662306a36Sopenharmony_ciint br_stp_set_enabled(struct net_bridge *br, unsigned long val,
195762306a36Sopenharmony_ci		       struct netlink_ext_ack *extack);
195862306a36Sopenharmony_civoid br_stp_enable_port(struct net_bridge_port *p);
195962306a36Sopenharmony_civoid br_stp_disable_port(struct net_bridge_port *p);
196062306a36Sopenharmony_cibool br_stp_recalculate_bridge_id(struct net_bridge *br);
196162306a36Sopenharmony_civoid br_stp_change_bridge_id(struct net_bridge *br, const unsigned char *a);
196262306a36Sopenharmony_civoid br_stp_set_bridge_priority(struct net_bridge *br, u16 newprio);
196362306a36Sopenharmony_ciint br_stp_set_port_priority(struct net_bridge_port *p, unsigned long newprio);
196462306a36Sopenharmony_ciint br_stp_set_path_cost(struct net_bridge_port *p, unsigned long path_cost);
196562306a36Sopenharmony_cissize_t br_show_bridge_id(char *buf, const struct bridge_id *id);
196662306a36Sopenharmony_ci
196762306a36Sopenharmony_ci/* br_stp_bpdu.c */
196862306a36Sopenharmony_cistruct stp_proto;
196962306a36Sopenharmony_civoid br_stp_rcv(const struct stp_proto *proto, struct sk_buff *skb,
197062306a36Sopenharmony_ci		struct net_device *dev);
197162306a36Sopenharmony_ci
197262306a36Sopenharmony_ci/* br_stp_timer.c */
197362306a36Sopenharmony_civoid br_stp_timer_init(struct net_bridge *br);
197462306a36Sopenharmony_civoid br_stp_port_timer_init(struct net_bridge_port *p);
197562306a36Sopenharmony_ciunsigned long br_timer_value(const struct timer_list *timer);
197662306a36Sopenharmony_ci
197762306a36Sopenharmony_ci/* br.c */
197862306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_ATM_LANE)
197962306a36Sopenharmony_ciextern int (*br_fdb_test_addr_hook)(struct net_device *dev, unsigned char *addr);
198062306a36Sopenharmony_ci#endif
198162306a36Sopenharmony_ci
198262306a36Sopenharmony_ci/* br_mrp.c */
198362306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_BRIDGE_MRP)
198462306a36Sopenharmony_ciint br_mrp_parse(struct net_bridge *br, struct net_bridge_port *p,
198562306a36Sopenharmony_ci		 struct nlattr *attr, int cmd, struct netlink_ext_ack *extack);
198662306a36Sopenharmony_cibool br_mrp_enabled(struct net_bridge *br);
198762306a36Sopenharmony_civoid br_mrp_port_del(struct net_bridge *br, struct net_bridge_port *p);
198862306a36Sopenharmony_ciint br_mrp_fill_info(struct sk_buff *skb, struct net_bridge *br);
198962306a36Sopenharmony_ci#else
199062306a36Sopenharmony_cistatic inline int br_mrp_parse(struct net_bridge *br, struct net_bridge_port *p,
199162306a36Sopenharmony_ci			       struct nlattr *attr, int cmd,
199262306a36Sopenharmony_ci			       struct netlink_ext_ack *extack)
199362306a36Sopenharmony_ci{
199462306a36Sopenharmony_ci	return -EOPNOTSUPP;
199562306a36Sopenharmony_ci}
199662306a36Sopenharmony_ci
199762306a36Sopenharmony_cistatic inline bool br_mrp_enabled(struct net_bridge *br)
199862306a36Sopenharmony_ci{
199962306a36Sopenharmony_ci	return false;
200062306a36Sopenharmony_ci}
200162306a36Sopenharmony_ci
200262306a36Sopenharmony_cistatic inline void br_mrp_port_del(struct net_bridge *br,
200362306a36Sopenharmony_ci				   struct net_bridge_port *p)
200462306a36Sopenharmony_ci{
200562306a36Sopenharmony_ci}
200662306a36Sopenharmony_ci
200762306a36Sopenharmony_cistatic inline int br_mrp_fill_info(struct sk_buff *skb, struct net_bridge *br)
200862306a36Sopenharmony_ci{
200962306a36Sopenharmony_ci	return 0;
201062306a36Sopenharmony_ci}
201162306a36Sopenharmony_ci
201262306a36Sopenharmony_ci#endif
201362306a36Sopenharmony_ci
201462306a36Sopenharmony_ci/* br_cfm.c */
201562306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_BRIDGE_CFM)
201662306a36Sopenharmony_ciint br_cfm_parse(struct net_bridge *br, struct net_bridge_port *p,
201762306a36Sopenharmony_ci		 struct nlattr *attr, int cmd, struct netlink_ext_ack *extack);
201862306a36Sopenharmony_cibool br_cfm_created(struct net_bridge *br);
201962306a36Sopenharmony_civoid br_cfm_port_del(struct net_bridge *br, struct net_bridge_port *p);
202062306a36Sopenharmony_ciint br_cfm_config_fill_info(struct sk_buff *skb, struct net_bridge *br);
202162306a36Sopenharmony_ciint br_cfm_status_fill_info(struct sk_buff *skb,
202262306a36Sopenharmony_ci			    struct net_bridge *br,
202362306a36Sopenharmony_ci			    bool getlink);
202462306a36Sopenharmony_ciint br_cfm_mep_count(struct net_bridge *br, u32 *count);
202562306a36Sopenharmony_ciint br_cfm_peer_mep_count(struct net_bridge *br, u32 *count);
202662306a36Sopenharmony_ci#else
202762306a36Sopenharmony_cistatic inline int br_cfm_parse(struct net_bridge *br, struct net_bridge_port *p,
202862306a36Sopenharmony_ci			       struct nlattr *attr, int cmd,
202962306a36Sopenharmony_ci			       struct netlink_ext_ack *extack)
203062306a36Sopenharmony_ci{
203162306a36Sopenharmony_ci	return -EOPNOTSUPP;
203262306a36Sopenharmony_ci}
203362306a36Sopenharmony_ci
203462306a36Sopenharmony_cistatic inline bool br_cfm_created(struct net_bridge *br)
203562306a36Sopenharmony_ci{
203662306a36Sopenharmony_ci	return false;
203762306a36Sopenharmony_ci}
203862306a36Sopenharmony_ci
203962306a36Sopenharmony_cistatic inline void br_cfm_port_del(struct net_bridge *br,
204062306a36Sopenharmony_ci				   struct net_bridge_port *p)
204162306a36Sopenharmony_ci{
204262306a36Sopenharmony_ci}
204362306a36Sopenharmony_ci
204462306a36Sopenharmony_cistatic inline int br_cfm_config_fill_info(struct sk_buff *skb, struct net_bridge *br)
204562306a36Sopenharmony_ci{
204662306a36Sopenharmony_ci	return -EOPNOTSUPP;
204762306a36Sopenharmony_ci}
204862306a36Sopenharmony_ci
204962306a36Sopenharmony_cistatic inline int br_cfm_status_fill_info(struct sk_buff *skb,
205062306a36Sopenharmony_ci					  struct net_bridge *br,
205162306a36Sopenharmony_ci					  bool getlink)
205262306a36Sopenharmony_ci{
205362306a36Sopenharmony_ci	return -EOPNOTSUPP;
205462306a36Sopenharmony_ci}
205562306a36Sopenharmony_ci
205662306a36Sopenharmony_cistatic inline int br_cfm_mep_count(struct net_bridge *br, u32 *count)
205762306a36Sopenharmony_ci{
205862306a36Sopenharmony_ci	*count = 0;
205962306a36Sopenharmony_ci	return -EOPNOTSUPP;
206062306a36Sopenharmony_ci}
206162306a36Sopenharmony_ci
206262306a36Sopenharmony_cistatic inline int br_cfm_peer_mep_count(struct net_bridge *br, u32 *count)
206362306a36Sopenharmony_ci{
206462306a36Sopenharmony_ci	*count = 0;
206562306a36Sopenharmony_ci	return -EOPNOTSUPP;
206662306a36Sopenharmony_ci}
206762306a36Sopenharmony_ci#endif
206862306a36Sopenharmony_ci
206962306a36Sopenharmony_ci/* br_netlink.c */
207062306a36Sopenharmony_ciextern struct rtnl_link_ops br_link_ops;
207162306a36Sopenharmony_ciint br_netlink_init(void);
207262306a36Sopenharmony_civoid br_netlink_fini(void);
207362306a36Sopenharmony_civoid br_ifinfo_notify(int event, const struct net_bridge *br,
207462306a36Sopenharmony_ci		      const struct net_bridge_port *port);
207562306a36Sopenharmony_civoid br_info_notify(int event, const struct net_bridge *br,
207662306a36Sopenharmony_ci		    const struct net_bridge_port *port, u32 filter);
207762306a36Sopenharmony_ciint br_setlink(struct net_device *dev, struct nlmsghdr *nlmsg, u16 flags,
207862306a36Sopenharmony_ci	       struct netlink_ext_ack *extack);
207962306a36Sopenharmony_ciint br_dellink(struct net_device *dev, struct nlmsghdr *nlmsg, u16 flags);
208062306a36Sopenharmony_ciint br_getlink(struct sk_buff *skb, u32 pid, u32 seq, struct net_device *dev,
208162306a36Sopenharmony_ci	       u32 filter_mask, int nlflags);
208262306a36Sopenharmony_ciint br_process_vlan_info(struct net_bridge *br,
208362306a36Sopenharmony_ci			 struct net_bridge_port *p, int cmd,
208462306a36Sopenharmony_ci			 struct bridge_vlan_info *vinfo_curr,
208562306a36Sopenharmony_ci			 struct bridge_vlan_info **vinfo_last,
208662306a36Sopenharmony_ci			 bool *changed,
208762306a36Sopenharmony_ci			 struct netlink_ext_ack *extack);
208862306a36Sopenharmony_ci
208962306a36Sopenharmony_ci#ifdef CONFIG_SYSFS
209062306a36Sopenharmony_ci/* br_sysfs_if.c */
209162306a36Sopenharmony_ciextern const struct sysfs_ops brport_sysfs_ops;
209262306a36Sopenharmony_ciint br_sysfs_addif(struct net_bridge_port *p);
209362306a36Sopenharmony_ciint br_sysfs_renameif(struct net_bridge_port *p);
209462306a36Sopenharmony_ci
209562306a36Sopenharmony_ci/* br_sysfs_br.c */
209662306a36Sopenharmony_ciint br_sysfs_addbr(struct net_device *dev);
209762306a36Sopenharmony_civoid br_sysfs_delbr(struct net_device *dev);
209862306a36Sopenharmony_ci
209962306a36Sopenharmony_ci#else
210062306a36Sopenharmony_ci
210162306a36Sopenharmony_cistatic inline int br_sysfs_addif(struct net_bridge_port *p) { return 0; }
210262306a36Sopenharmony_cistatic inline int br_sysfs_renameif(struct net_bridge_port *p) { return 0; }
210362306a36Sopenharmony_cistatic inline int br_sysfs_addbr(struct net_device *dev) { return 0; }
210462306a36Sopenharmony_cistatic inline void br_sysfs_delbr(struct net_device *dev) { return; }
210562306a36Sopenharmony_ci#endif /* CONFIG_SYSFS */
210662306a36Sopenharmony_ci
210762306a36Sopenharmony_ci/* br_switchdev.c */
210862306a36Sopenharmony_ci#ifdef CONFIG_NET_SWITCHDEV
210962306a36Sopenharmony_ciint br_switchdev_port_offload(struct net_bridge_port *p,
211062306a36Sopenharmony_ci			      struct net_device *dev, const void *ctx,
211162306a36Sopenharmony_ci			      struct notifier_block *atomic_nb,
211262306a36Sopenharmony_ci			      struct notifier_block *blocking_nb,
211362306a36Sopenharmony_ci			      bool tx_fwd_offload,
211462306a36Sopenharmony_ci			      struct netlink_ext_ack *extack);
211562306a36Sopenharmony_ci
211662306a36Sopenharmony_civoid br_switchdev_port_unoffload(struct net_bridge_port *p, const void *ctx,
211762306a36Sopenharmony_ci				 struct notifier_block *atomic_nb,
211862306a36Sopenharmony_ci				 struct notifier_block *blocking_nb);
211962306a36Sopenharmony_ci
212062306a36Sopenharmony_ciint br_switchdev_port_replay(struct net_bridge_port *p,
212162306a36Sopenharmony_ci			     struct net_device *dev, const void *ctx,
212262306a36Sopenharmony_ci			     struct notifier_block *atomic_nb,
212362306a36Sopenharmony_ci			     struct notifier_block *blocking_nb,
212462306a36Sopenharmony_ci			     struct netlink_ext_ack *extack);
212562306a36Sopenharmony_ci
212662306a36Sopenharmony_cibool br_switchdev_frame_uses_tx_fwd_offload(struct sk_buff *skb);
212762306a36Sopenharmony_ci
212862306a36Sopenharmony_civoid br_switchdev_frame_set_offload_fwd_mark(struct sk_buff *skb);
212962306a36Sopenharmony_ci
213062306a36Sopenharmony_civoid nbp_switchdev_frame_mark_tx_fwd_offload(const struct net_bridge_port *p,
213162306a36Sopenharmony_ci					     struct sk_buff *skb);
213262306a36Sopenharmony_civoid nbp_switchdev_frame_mark_tx_fwd_to_hwdom(const struct net_bridge_port *p,
213362306a36Sopenharmony_ci					      struct sk_buff *skb);
213462306a36Sopenharmony_civoid nbp_switchdev_frame_mark(const struct net_bridge_port *p,
213562306a36Sopenharmony_ci			      struct sk_buff *skb);
213662306a36Sopenharmony_cibool nbp_switchdev_allowed_egress(const struct net_bridge_port *p,
213762306a36Sopenharmony_ci				  const struct sk_buff *skb);
213862306a36Sopenharmony_ciint br_switchdev_set_port_flag(struct net_bridge_port *p,
213962306a36Sopenharmony_ci			       unsigned long flags,
214062306a36Sopenharmony_ci			       unsigned long mask,
214162306a36Sopenharmony_ci			       struct netlink_ext_ack *extack);
214262306a36Sopenharmony_civoid br_switchdev_fdb_notify(struct net_bridge *br,
214362306a36Sopenharmony_ci			     const struct net_bridge_fdb_entry *fdb, int type);
214462306a36Sopenharmony_civoid br_switchdev_mdb_notify(struct net_device *dev,
214562306a36Sopenharmony_ci			     struct net_bridge_mdb_entry *mp,
214662306a36Sopenharmony_ci			     struct net_bridge_port_group *pg,
214762306a36Sopenharmony_ci			     int type);
214862306a36Sopenharmony_ciint br_switchdev_port_vlan_add(struct net_device *dev, u16 vid, u16 flags,
214962306a36Sopenharmony_ci			       bool changed, struct netlink_ext_ack *extack);
215062306a36Sopenharmony_ciint br_switchdev_port_vlan_del(struct net_device *dev, u16 vid);
215162306a36Sopenharmony_civoid br_switchdev_init(struct net_bridge *br);
215262306a36Sopenharmony_ci
215362306a36Sopenharmony_cistatic inline void br_switchdev_frame_unmark(struct sk_buff *skb)
215462306a36Sopenharmony_ci{
215562306a36Sopenharmony_ci	skb->offload_fwd_mark = 0;
215662306a36Sopenharmony_ci}
215762306a36Sopenharmony_ci#else
215862306a36Sopenharmony_cistatic inline int
215962306a36Sopenharmony_cibr_switchdev_port_offload(struct net_bridge_port *p,
216062306a36Sopenharmony_ci			  struct net_device *dev, const void *ctx,
216162306a36Sopenharmony_ci			  struct notifier_block *atomic_nb,
216262306a36Sopenharmony_ci			  struct notifier_block *blocking_nb,
216362306a36Sopenharmony_ci			  bool tx_fwd_offload,
216462306a36Sopenharmony_ci			  struct netlink_ext_ack *extack)
216562306a36Sopenharmony_ci{
216662306a36Sopenharmony_ci	return -EOPNOTSUPP;
216762306a36Sopenharmony_ci}
216862306a36Sopenharmony_ci
216962306a36Sopenharmony_cistatic inline void
217062306a36Sopenharmony_cibr_switchdev_port_unoffload(struct net_bridge_port *p, const void *ctx,
217162306a36Sopenharmony_ci			    struct notifier_block *atomic_nb,
217262306a36Sopenharmony_ci			    struct notifier_block *blocking_nb)
217362306a36Sopenharmony_ci{
217462306a36Sopenharmony_ci}
217562306a36Sopenharmony_ci
217662306a36Sopenharmony_cistatic inline int
217762306a36Sopenharmony_cibr_switchdev_port_replay(struct net_bridge_port *p,
217862306a36Sopenharmony_ci			 struct net_device *dev, const void *ctx,
217962306a36Sopenharmony_ci			 struct notifier_block *atomic_nb,
218062306a36Sopenharmony_ci			 struct notifier_block *blocking_nb,
218162306a36Sopenharmony_ci			 struct netlink_ext_ack *extack)
218262306a36Sopenharmony_ci{
218362306a36Sopenharmony_ci	return -EOPNOTSUPP;
218462306a36Sopenharmony_ci}
218562306a36Sopenharmony_ci
218662306a36Sopenharmony_cistatic inline bool br_switchdev_frame_uses_tx_fwd_offload(struct sk_buff *skb)
218762306a36Sopenharmony_ci{
218862306a36Sopenharmony_ci	return false;
218962306a36Sopenharmony_ci}
219062306a36Sopenharmony_ci
219162306a36Sopenharmony_cistatic inline void br_switchdev_frame_set_offload_fwd_mark(struct sk_buff *skb)
219262306a36Sopenharmony_ci{
219362306a36Sopenharmony_ci}
219462306a36Sopenharmony_ci
219562306a36Sopenharmony_cistatic inline void
219662306a36Sopenharmony_cinbp_switchdev_frame_mark_tx_fwd_offload(const struct net_bridge_port *p,
219762306a36Sopenharmony_ci					struct sk_buff *skb)
219862306a36Sopenharmony_ci{
219962306a36Sopenharmony_ci}
220062306a36Sopenharmony_ci
220162306a36Sopenharmony_cistatic inline void
220262306a36Sopenharmony_cinbp_switchdev_frame_mark_tx_fwd_to_hwdom(const struct net_bridge_port *p,
220362306a36Sopenharmony_ci					 struct sk_buff *skb)
220462306a36Sopenharmony_ci{
220562306a36Sopenharmony_ci}
220662306a36Sopenharmony_ci
220762306a36Sopenharmony_cistatic inline void nbp_switchdev_frame_mark(const struct net_bridge_port *p,
220862306a36Sopenharmony_ci					    struct sk_buff *skb)
220962306a36Sopenharmony_ci{
221062306a36Sopenharmony_ci}
221162306a36Sopenharmony_ci
221262306a36Sopenharmony_cistatic inline bool nbp_switchdev_allowed_egress(const struct net_bridge_port *p,
221362306a36Sopenharmony_ci						const struct sk_buff *skb)
221462306a36Sopenharmony_ci{
221562306a36Sopenharmony_ci	return true;
221662306a36Sopenharmony_ci}
221762306a36Sopenharmony_ci
221862306a36Sopenharmony_cistatic inline int br_switchdev_set_port_flag(struct net_bridge_port *p,
221962306a36Sopenharmony_ci					     unsigned long flags,
222062306a36Sopenharmony_ci					     unsigned long mask,
222162306a36Sopenharmony_ci					     struct netlink_ext_ack *extack)
222262306a36Sopenharmony_ci{
222362306a36Sopenharmony_ci	return 0;
222462306a36Sopenharmony_ci}
222562306a36Sopenharmony_ci
222662306a36Sopenharmony_cistatic inline int br_switchdev_port_vlan_add(struct net_device *dev, u16 vid,
222762306a36Sopenharmony_ci					     u16 flags, bool changed,
222862306a36Sopenharmony_ci					     struct netlink_ext_ack *extack)
222962306a36Sopenharmony_ci{
223062306a36Sopenharmony_ci	return -EOPNOTSUPP;
223162306a36Sopenharmony_ci}
223262306a36Sopenharmony_ci
223362306a36Sopenharmony_cistatic inline int br_switchdev_port_vlan_del(struct net_device *dev, u16 vid)
223462306a36Sopenharmony_ci{
223562306a36Sopenharmony_ci	return -EOPNOTSUPP;
223662306a36Sopenharmony_ci}
223762306a36Sopenharmony_ci
223862306a36Sopenharmony_cistatic inline void
223962306a36Sopenharmony_cibr_switchdev_fdb_notify(struct net_bridge *br,
224062306a36Sopenharmony_ci			const struct net_bridge_fdb_entry *fdb, int type)
224162306a36Sopenharmony_ci{
224262306a36Sopenharmony_ci}
224362306a36Sopenharmony_ci
224462306a36Sopenharmony_cistatic inline void br_switchdev_mdb_notify(struct net_device *dev,
224562306a36Sopenharmony_ci					   struct net_bridge_mdb_entry *mp,
224662306a36Sopenharmony_ci					   struct net_bridge_port_group *pg,
224762306a36Sopenharmony_ci					   int type)
224862306a36Sopenharmony_ci{
224962306a36Sopenharmony_ci}
225062306a36Sopenharmony_ci
225162306a36Sopenharmony_cistatic inline void br_switchdev_frame_unmark(struct sk_buff *skb)
225262306a36Sopenharmony_ci{
225362306a36Sopenharmony_ci}
225462306a36Sopenharmony_ci
225562306a36Sopenharmony_cistatic inline void br_switchdev_init(struct net_bridge *br)
225662306a36Sopenharmony_ci{
225762306a36Sopenharmony_ci}
225862306a36Sopenharmony_ci
225962306a36Sopenharmony_ci#endif /* CONFIG_NET_SWITCHDEV */
226062306a36Sopenharmony_ci
226162306a36Sopenharmony_ci/* br_arp_nd_proxy.c */
226262306a36Sopenharmony_civoid br_recalculate_neigh_suppress_enabled(struct net_bridge *br);
226362306a36Sopenharmony_civoid br_do_proxy_suppress_arp(struct sk_buff *skb, struct net_bridge *br,
226462306a36Sopenharmony_ci			      u16 vid, struct net_bridge_port *p);
226562306a36Sopenharmony_civoid br_do_suppress_nd(struct sk_buff *skb, struct net_bridge *br,
226662306a36Sopenharmony_ci		       u16 vid, struct net_bridge_port *p, struct nd_msg *msg);
226762306a36Sopenharmony_cistruct nd_msg *br_is_nd_neigh_msg(struct sk_buff *skb, struct nd_msg *m);
226862306a36Sopenharmony_cibool br_is_neigh_suppress_enabled(const struct net_bridge_port *p, u16 vid);
226962306a36Sopenharmony_ci#endif
2270