blob: 2661dda1a92b3d950f43943892fd2b06f9b74926 [file] [log] [blame]
Thomas Gleixner2874c5f2019-05-27 08:55:01 +02001/* SPDX-License-Identifier: GPL-2.0-or-later */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002/*
3 * Linux ethernet bridge
4 *
5 * Authors:
6 * Lennert Buytenhek <buytenh@gnu.org>
Linus Torvalds1da177e2005-04-16 15:20:36 -07007 */
8
9#ifndef _BR_PRIVATE_H
10#define _BR_PRIVATE_H
11
12#include <linux/netdevice.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070013#include <linux/if_bridge.h>
Herbert Xu91d2c342010-06-10 16:12:50 +000014#include <linux/netpoll.h>
Eric Dumazet406818f2010-06-23 13:00:48 -070015#include <linux/u64_stats_sync.h>
Simon Wunderlich4adf0af2008-07-30 16:27:55 -070016#include <net/route.h>
Bernhard Thalerefb6de92015-05-30 15:30:16 +020017#include <net/ip6_fib.h>
Vlad Yasevich243a2e62013-02-13 12:00:09 +000018#include <linux/if_vlan.h>
Nikolay Aleksandrov2594e9062015-09-25 19:00:11 +020019#include <linux/rhashtable.h>
Reshetova, Elena25127752017-07-04 15:53:05 +030020#include <linux/refcount.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070021
22#define BR_HASH_BITS 8
23#define BR_HASH_SIZE (1 << BR_HASH_BITS)
24
25#define BR_HOLD_TIME (1*HZ)
26
27#define BR_PORT_BITS 10
28#define BR_MAX_PORTS (1<<BR_PORT_BITS)
29
Nikolay Aleksandrovd08c6bc2018-12-05 15:14:27 +020030#define BR_MULTICAST_DEFAULT_HASH_MAX 4096
Nikolay Aleksandrov99b40612021-12-27 19:21:15 +020031#define BR_MULTICAST_QUERY_INTVL_MIN msecs_to_jiffies(1000)
Nikolay Aleksandrovf83a1122021-12-27 19:21:16 +020032#define BR_MULTICAST_STARTUP_QUERY_INTVL_MIN BR_MULTICAST_QUERY_INTVL_MIN
Nikolay Aleksandrovd08c6bc2018-12-05 15:14:27 +020033
Tobias Waldekranz85826612021-07-21 19:24:00 +030034#define BR_HWDOM_MAX BITS_PER_LONG
35
Stephen Hemminger9cde0702007-03-21 14:22:44 -070036#define BR_VERSION "2.3"
37
stephen hemminger515853c2011-10-03 18:14:46 +000038/* Control of forwarding link local multicast */
39#define BR_GROUPFWD_DEFAULT 0
Bernhard Thaler784b58a2015-05-04 22:47:13 +020040/* Don't allow forwarding of control protocols like STP, MAC PAUSE and LACP */
Nikolay Aleksandrov5af48b52017-09-27 16:12:44 +030041enum {
42 BR_GROUPFWD_STP = BIT(0),
43 BR_GROUPFWD_MACPAUSE = BIT(1),
44 BR_GROUPFWD_LACP = BIT(2),
45};
46
47#define BR_GROUPFWD_RESTRICTED (BR_GROUPFWD_STP | BR_GROUPFWD_MACPAUSE | \
48 BR_GROUPFWD_LACP)
Toshiaki Makitaf2808d22014-06-10 20:59:24 +090049/* The Nearest Customer Bridge Group Address, 01-80-C2-00-00-[00,0B,0C,0D,0F] */
50#define BR_GROUPFWD_8021AD 0xB801u
stephen hemminger515853c2011-10-03 18:14:46 +000051
Stephen Hemminger9cde0702007-03-21 14:22:44 -070052/* Path to usermode spanning tree program */
53#define BR_STP_PROG "/sbin/bridge-stp"
Stephen Hemminger8cbb512e2005-12-21 19:01:30 -080054
Nikolay Aleksandrov31cbc39b2020-06-23 23:47:17 +030055#define BR_FDB_NOTIFY_SETTABLE_BITS (FDB_NOTIFY_BIT | FDB_NOTIFY_INACTIVE_BIT)
56
Linus Torvalds1da177e2005-04-16 15:20:36 -070057typedef struct bridge_id bridge_id;
58typedef struct mac_addr mac_addr;
59typedef __u16 port_id;
60
Nikolay Aleksandrov1c1cb6d2018-09-26 17:00:59 +030061struct bridge_id {
Linus Torvalds1da177e2005-04-16 15:20:36 -070062 unsigned char prio[2];
Joe Perchese5a727f2014-02-23 00:05:25 -080063 unsigned char addr[ETH_ALEN];
Linus Torvalds1da177e2005-04-16 15:20:36 -070064};
65
Nikolay Aleksandrov1c1cb6d2018-09-26 17:00:59 +030066struct mac_addr {
Joe Perchese5a727f2014-02-23 00:05:25 -080067 unsigned char addr[ETH_ALEN];
Linus Torvalds1da177e2005-04-16 15:20:36 -070068};
69
Linus Lüssingcc0fdd82013-08-30 17:28:17 +020070#ifdef CONFIG_BRIDGE_IGMP_SNOOPING
71/* our own querier */
Linus Lüssing90010b32014-06-07 18:26:26 +020072struct bridge_mcast_own_query {
Linus Lüssingcc0fdd82013-08-30 17:28:17 +020073 struct timer_list timer;
74 u32 startup_sent;
75};
76
77/* other querier */
Linus Lüssing90010b32014-06-07 18:26:26 +020078struct bridge_mcast_other_query {
Linus Lüssingcc0fdd82013-08-30 17:28:17 +020079 struct timer_list timer;
80 unsigned long delay_time;
81};
Linus Lüssingdc4eb532014-06-07 18:26:27 +020082
83/* selected querier */
84struct bridge_mcast_querier {
85 struct br_ip addr;
Nikolay Aleksandrovbb18ef82021-08-13 17:59:57 +030086 int port_ifidx;
Thomas Gleixnerf936bb42021-09-28 16:10:49 +020087 seqcount_spinlock_t seq;
Linus Lüssingdc4eb532014-06-07 18:26:27 +020088};
Nikolay Aleksandrov1080ab92016-06-28 16:57:06 +020089
90/* IGMP/MLD statistics */
91struct bridge_mcast_stats {
92 struct br_mcast_stats mstats;
93 struct u64_stats_sync syncp;
94};
Linus Lüssingcc0fdd82013-08-30 17:28:17 +020095#endif
96
Nikolay Aleksandrov96322332021-07-19 20:06:23 +030097/* net_bridge_mcast_port must be always defined due to forwarding stubs */
98struct net_bridge_mcast_port {
99#ifdef CONFIG_BRIDGE_IGMP_SNOOPING
100 struct net_bridge_port *port;
Nikolay Aleksandrov613d61d2021-07-19 20:06:26 +0300101 struct net_bridge_vlan *vlan;
Nikolay Aleksandrov96322332021-07-19 20:06:23 +0300102
103 struct bridge_mcast_own_query ip4_own_query;
104 struct timer_list ip4_mc_router_timer;
105 struct hlist_node ip4_rlist;
106#if IS_ENABLED(CONFIG_IPV6)
107 struct bridge_mcast_own_query ip6_own_query;
108 struct timer_list ip6_mc_router_timer;
109 struct hlist_node ip6_rlist;
110#endif /* IS_ENABLED(CONFIG_IPV6) */
111 unsigned char multicast_router;
112#endif /* CONFIG_BRIDGE_IGMP_SNOOPING */
113};
114
Nikolay Aleksandrovd3d065c2021-07-19 20:06:24 +0300115/* net_bridge_mcast must be always defined due to forwarding stubs */
116struct net_bridge_mcast {
117#ifdef CONFIG_BRIDGE_IGMP_SNOOPING
118 struct net_bridge *br;
Nikolay Aleksandrov613d61d2021-07-19 20:06:26 +0300119 struct net_bridge_vlan *vlan;
Nikolay Aleksandrovd3d065c2021-07-19 20:06:24 +0300120
121 u32 multicast_last_member_count;
122 u32 multicast_startup_query_count;
123
Nikolay Aleksandrov4d5b4e82021-08-10 18:29:28 +0300124 u8 multicast_querier;
Nikolay Aleksandrovd3d065c2021-07-19 20:06:24 +0300125 u8 multicast_igmp_version;
126 u8 multicast_router;
127#if IS_ENABLED(CONFIG_IPV6)
128 u8 multicast_mld_version;
129#endif
130 unsigned long multicast_last_member_interval;
131 unsigned long multicast_membership_interval;
132 unsigned long multicast_querier_interval;
133 unsigned long multicast_query_interval;
134 unsigned long multicast_query_response_interval;
135 unsigned long multicast_startup_query_interval;
136 struct hlist_head ip4_mc_router_list;
137 struct timer_list ip4_mc_router_timer;
138 struct bridge_mcast_other_query ip4_other_query;
139 struct bridge_mcast_own_query ip4_own_query;
140 struct bridge_mcast_querier ip4_querier;
141#if IS_ENABLED(CONFIG_IPV6)
142 struct hlist_head ip6_mc_router_list;
143 struct timer_list ip6_mc_router_timer;
144 struct bridge_mcast_other_query ip6_other_query;
145 struct bridge_mcast_own_query ip6_own_query;
146 struct bridge_mcast_querier ip6_querier;
147#endif /* IS_ENABLED(CONFIG_IPV6) */
148#endif /* CONFIG_BRIDGE_IGMP_SNOOPING */
149};
150
Roopa Prabhuefa53562017-01-31 22:59:54 -0800151struct br_tunnel_info {
Nikolay Aleksandrov58e20712021-06-10 15:04:10 +0300152 __be64 tunnel_id;
153 struct metadata_dst __rcu *tunnel_dst;
Roopa Prabhuefa53562017-01-31 22:59:54 -0800154};
155
Nikolay Aleksandrov9d332e69c2018-11-16 18:50:01 +0200156/* private vlan flags */
157enum {
158 BR_VLFLAG_PER_PORT_STATS = BIT(0),
Ido Schimmel27973792019-01-08 16:48:11 +0000159 BR_VLFLAG_ADDED_BY_SWITCHDEV = BIT(1),
Nikolay Aleksandrov7b54aaa2021-07-19 20:06:27 +0300160 BR_VLFLAG_MCAST_ENABLED = BIT(2),
161 BR_VLFLAG_GLOBAL_MCAST_ENABLED = BIT(3),
Nikolay Aleksandrov9d332e69c2018-11-16 18:50:01 +0200162};
163
Nikolay Aleksandrov2594e9062015-09-25 19:00:11 +0200164/**
165 * struct net_bridge_vlan - per-vlan entry
166 *
167 * @vnode: rhashtable member
168 * @vid: VLAN id
169 * @flags: bridge vlan flags
Nikolay Aleksandrov9d332e69c2018-11-16 18:50:01 +0200170 * @priv_flags: private (in-kernel) bridge vlan flags
Nikolay Aleksandrova580c762020-01-24 13:40:22 +0200171 * @state: STP state (e.g. blocking, learning, forwarding)
Nikolay Aleksandrov6dada9b2016-04-30 10:25:28 +0200172 * @stats: per-cpu VLAN statistics
Nikolay Aleksandrov2594e9062015-09-25 19:00:11 +0200173 * @br: if MASTER flag set, this points to a bridge struct
174 * @port: if MASTER flag unset, this points to a port struct
175 * @refcnt: if MASTER flag set, this is bumped for each port referencing it
176 * @brvlan: if MASTER flag unset, this points to the global per-VLAN context
177 * for this VLAN entry
Nikolay Aleksandrov613d61d2021-07-19 20:06:26 +0300178 * @br_mcast_ctx: if MASTER flag set, this is the global vlan multicast context
179 * @port_mcast_ctx: if MASTER flag unset, this is the per-port/vlan multicast
180 * context
Nikolay Aleksandrov2594e9062015-09-25 19:00:11 +0200181 * @vlist: sorted list of VLAN entries
182 * @rcu: used for entry destruction
183 *
184 * This structure is shared between the global per-VLAN entries contained in
185 * the bridge rhashtable and the local per-port per-VLAN entries contained in
186 * the port's rhashtable. The union entries should be interpreted depending on
187 * the entry flags that are set.
188 */
189struct net_bridge_vlan {
190 struct rhash_head vnode;
Roopa Prabhuefa53562017-01-31 22:59:54 -0800191 struct rhash_head tnode;
Nikolay Aleksandrov2594e9062015-09-25 19:00:11 +0200192 u16 vid;
193 u16 flags;
Nikolay Aleksandrov9d332e69c2018-11-16 18:50:01 +0200194 u16 priv_flags;
Nikolay Aleksandrova580c762020-01-24 13:40:22 +0200195 u8 state;
Heiner Kallweit281cc282020-11-17 21:25:42 +0100196 struct pcpu_sw_netstats __percpu *stats;
Vlad Yasevich243a2e62013-02-13 12:00:09 +0000197 union {
Nikolay Aleksandrov2594e9062015-09-25 19:00:11 +0200198 struct net_bridge *br;
199 struct net_bridge_port *port;
200 };
201 union {
Reshetova, Elena25127752017-07-04 15:53:05 +0300202 refcount_t refcnt;
Nikolay Aleksandrov2594e9062015-09-25 19:00:11 +0200203 struct net_bridge_vlan *brvlan;
204 };
Roopa Prabhuefa53562017-01-31 22:59:54 -0800205
206 struct br_tunnel_info tinfo;
207
Nikolay Aleksandrov613d61d2021-07-19 20:06:26 +0300208 union {
209 struct net_bridge_mcast br_mcast_ctx;
210 struct net_bridge_mcast_port port_mcast_ctx;
211 };
212
Nikolay Aleksandrov2594e9062015-09-25 19:00:11 +0200213 struct list_head vlist;
214
Vlad Yasevich243a2e62013-02-13 12:00:09 +0000215 struct rcu_head rcu;
Nikolay Aleksandrov2594e9062015-09-25 19:00:11 +0200216};
217
218/**
219 * struct net_bridge_vlan_group
220 *
221 * @vlan_hash: VLAN entry rhashtable
222 * @vlan_list: sorted VLAN entry list
223 * @num_vlans: number of total VLAN entries
Nikolay Aleksandrov77751ee2015-09-30 20:16:53 +0200224 * @pvid: PVID VLAN id
Nikolay Aleksandrova580c762020-01-24 13:40:22 +0200225 * @pvid_state: PVID's STP state (e.g. forwarding, learning, blocking)
Nikolay Aleksandrov2594e9062015-09-25 19:00:11 +0200226 *
227 * IMPORTANT: Be careful when checking if there're VLAN entries using list
228 * primitives because the bridge can have entries in its list which
229 * are just for global context but not for filtering, i.e. they have
230 * the master flag set but not the brentry flag. If you have to check
231 * if there're "real" entries in the bridge please test @num_vlans
232 */
233struct net_bridge_vlan_group {
234 struct rhashtable vlan_hash;
Roopa Prabhuefa53562017-01-31 22:59:54 -0800235 struct rhashtable tunnel_hash;
Nikolay Aleksandrov2594e9062015-09-25 19:00:11 +0200236 struct list_head vlan_list;
Vlad Yasevich6cbdcee2013-02-13 12:00:13 +0000237 u16 num_vlans;
Nikolay Aleksandrov77751ee2015-09-30 20:16:53 +0200238 u16 pvid;
Nikolay Aleksandrova580c762020-01-24 13:40:22 +0200239 u8 pvid_state;
Vlad Yasevich243a2e62013-02-13 12:00:09 +0000240};
241
Nikolay Aleksandrov6869c3b2019-10-29 13:45:53 +0200242/* bridge fdb flags */
243enum {
244 BR_FDB_LOCAL,
Nikolay Aleksandrov29e63ff2019-10-29 13:45:54 +0200245 BR_FDB_STATIC,
Nikolay Aleksandrove0458d92019-10-29 13:45:55 +0200246 BR_FDB_STICKY,
Nikolay Aleksandrovac3ca6a2019-10-29 13:45:56 +0200247 BR_FDB_ADDED_BY_USER,
Nikolay Aleksandrovb5cd9f72019-10-29 13:45:57 +0200248 BR_FDB_ADDED_BY_EXT_LEARN,
Nikolay Aleksandrovd38c6e32019-10-29 13:45:58 +0200249 BR_FDB_OFFLOADED,
Nikolay Aleksandrov31cbc39b2020-06-23 23:47:17 +0300250 BR_FDB_NOTIFY,
251 BR_FDB_NOTIFY_INACTIVE
Nikolay Aleksandrov6869c3b2019-10-29 13:45:53 +0200252};
253
Nikolay Aleksandroveb793582017-12-12 16:02:50 +0200254struct net_bridge_fdb_key {
255 mac_addr addr;
256 u16 vlan_id;
257};
258
Nikolay Aleksandrov1214628c2017-02-04 18:05:08 +0100259struct net_bridge_fdb_entry {
Nikolay Aleksandroveb793582017-12-12 16:02:50 +0200260 struct rhash_head rhnode;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700261 struct net_bridge_port *dst;
262
Nikolay Aleksandroveb793582017-12-12 16:02:50 +0200263 struct net_bridge_fdb_key key;
264 struct hlist_node fdb_node;
Nikolay Aleksandrov6869c3b2019-10-29 13:45:53 +0200265 unsigned long flags;
Nikolay Aleksandrov1214628c2017-02-04 18:05:08 +0100266
267 /* write-heavy members should not affect lookups */
268 unsigned long updated ____cacheline_aligned_in_smp;
269 unsigned long used;
270
Nikolay Aleksandrovb22fbf22015-08-27 14:19:20 -0700271 struct rcu_head rcu;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700272};
273
Elad Raz9d06b6d2016-02-03 09:57:05 +0100274#define MDB_PG_FLAGS_PERMANENT BIT(0)
275#define MDB_PG_FLAGS_OFFLOAD BIT(1)
Nikolay Aleksandrov3247b272019-07-30 15:20:41 +0300276#define MDB_PG_FLAGS_FAST_LEAVE BIT(2)
Nikolay Aleksandrov8266a042020-09-22 10:30:24 +0300277#define MDB_PG_FLAGS_STAR_EXCL BIT(3)
Nikolay Aleksandrov9116ffb2020-09-22 10:30:25 +0300278#define MDB_PG_FLAGS_BLOCKED BIT(4)
Elad Raz9d06b6d2016-02-03 09:57:05 +0100279
Nikolay Aleksandrov8b671772020-09-07 12:56:07 +0300280#define PG_SRC_ENT_LIMIT 32
281
282#define BR_SGRP_F_DELETE BIT(0)
283#define BR_SGRP_F_SEND BIT(1)
Nikolay Aleksandrovb0812362020-09-22 10:30:23 +0300284#define BR_SGRP_F_INSTALLED BIT(2)
Nikolay Aleksandrov8b671772020-09-07 12:56:07 +0300285
Nikolay Aleksandrove12cec62020-09-07 12:56:19 +0300286struct net_bridge_mcast_gc {
287 struct hlist_node gc_node;
288 void (*destroy)(struct net_bridge_mcast_gc *gc);
289};
290
Nikolay Aleksandrov8b671772020-09-07 12:56:07 +0300291struct net_bridge_group_src {
292 struct hlist_node node;
293
294 struct br_ip addr;
295 struct net_bridge_port_group *pg;
296 u8 flags;
Nikolay Aleksandrov438ef2d2020-09-07 12:56:09 +0300297 u8 src_query_rexmit_cnt;
Nikolay Aleksandrov8b671772020-09-07 12:56:07 +0300298 struct timer_list timer;
299
300 struct net_bridge *br;
Nikolay Aleksandrove12cec62020-09-07 12:56:19 +0300301 struct net_bridge_mcast_gc mcast_gc;
Nikolay Aleksandrov8b671772020-09-07 12:56:07 +0300302 struct rcu_head rcu;
303};
304
Nikolay Aleksandrov085b53c2020-09-22 10:30:22 +0300305struct net_bridge_port_group_sg_key {
Herbert Xueb1d1642010-02-27 19:41:45 +0000306 struct net_bridge_port *port;
YOSHIFUJI Hideaki8ef2a9a2010-04-18 12:42:07 +0900307 struct br_ip addr;
Nikolay Aleksandrov085b53c2020-09-22 10:30:22 +0300308};
309
310struct net_bridge_port_group {
311 struct net_bridge_port_group __rcu *next;
312 struct net_bridge_port_group_sg_key key;
Thomas Martitz206e73232020-06-25 14:26:03 +0200313 unsigned char eth_addr[ETH_ALEN] __aligned(2);
Elad Raz9d06b6d2016-02-03 09:57:05 +0100314 unsigned char flags;
Nikolay Aleksandrov8b671772020-09-07 12:56:07 +0300315 unsigned char filter_mode;
Nikolay Aleksandrov42c11cc2020-09-07 12:56:10 +0300316 unsigned char grp_query_rexmit_cnt;
Nikolay Aleksandrov8f8cb772020-09-22 10:30:21 +0300317 unsigned char rt_protocol;
Nikolay Aleksandrov6ec0d0e2020-09-07 12:56:05 +0300318
Nikolay Aleksandrov8b671772020-09-07 12:56:07 +0300319 struct hlist_head src_list;
320 unsigned int src_ents;
Nikolay Aleksandrov6ec0d0e2020-09-07 12:56:05 +0300321 struct timer_list timer;
Nikolay Aleksandrov42c11cc2020-09-07 12:56:10 +0300322 struct timer_list rexmit_timer;
Nikolay Aleksandrov6ec0d0e2020-09-07 12:56:05 +0300323 struct hlist_node mglist;
Nikolay Aleksandrov8f07b832021-01-20 16:51:54 +0200324 struct rb_root eht_set_tree;
325 struct rb_root eht_host_tree;
Nikolay Aleksandrov6ec0d0e2020-09-07 12:56:05 +0300326
Nikolay Aleksandrov085b53c2020-09-22 10:30:22 +0300327 struct rhash_head rhnode;
Nikolay Aleksandrove12cec62020-09-07 12:56:19 +0300328 struct net_bridge_mcast_gc mcast_gc;
Nikolay Aleksandrov6ec0d0e2020-09-07 12:56:05 +0300329 struct rcu_head rcu;
Herbert Xueb1d1642010-02-27 19:41:45 +0000330};
331
Nikolay Aleksandrov1c1cb6d2018-09-26 17:00:59 +0300332struct net_bridge_mdb_entry {
Nikolay Aleksandrov19e3a9c2018-12-05 15:14:24 +0200333 struct rhash_head rhnode;
Herbert Xueb1d1642010-02-27 19:41:45 +0000334 struct net_bridge *br;
Eric Dumazete8051682010-11-15 06:38:10 +0000335 struct net_bridge_port_group __rcu *ports;
YOSHIFUJI Hideaki8ef2a9a2010-04-18 12:42:07 +0900336 struct br_ip addr;
Andrew Lunnff0fd342017-11-09 23:10:57 +0100337 bool host_joined;
Nikolay Aleksandrov6ec0d0e2020-09-07 12:56:05 +0300338
339 struct timer_list timer;
Nikolay Aleksandrov19e3a9c2018-12-05 15:14:24 +0200340 struct hlist_node mdb_node;
Nikolay Aleksandrov6ec0d0e2020-09-07 12:56:05 +0300341
Nikolay Aleksandrove12cec62020-09-07 12:56:19 +0300342 struct net_bridge_mcast_gc mcast_gc;
Nikolay Aleksandrov6ec0d0e2020-09-07 12:56:05 +0300343 struct rcu_head rcu;
Herbert Xueb1d1642010-02-27 19:41:45 +0000344};
345
Nikolay Aleksandrov1f90c7f2017-02-04 18:05:06 +0100346struct net_bridge_port {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700347 struct net_bridge *br;
348 struct net_device *dev;
Eric Dumazetb2dcdc72021-12-06 17:30:29 -0800349 netdevice_tracker dev_tracker;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700350 struct list_head list;
351
Nikolay Aleksandrov1f90c7f2017-02-04 18:05:06 +0100352 unsigned long flags;
353#ifdef CONFIG_BRIDGE_VLAN_FILTERING
354 struct net_bridge_vlan_group __rcu *vlgrp;
355#endif
Nikolay Aleksandrov2756f682018-07-23 11:16:59 +0300356 struct net_bridge_port __rcu *backup_port;
Nikolay Aleksandrov1f90c7f2017-02-04 18:05:06 +0100357
Linus Torvalds1da177e2005-04-16 15:20:36 -0700358 /* STP */
359 u8 priority;
360 u8 state;
361 u16 port_no;
362 unsigned char topology_change_ack;
363 unsigned char config_pending;
364 port_id port_id;
365 port_id designated_port;
366 bridge_id designated_root;
367 bridge_id designated_bridge;
368 u32 path_cost;
369 u32 designated_cost;
stephen hemminger0c031502011-07-22 07:47:06 +0000370 unsigned long designated_age;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700371
372 struct timer_list forward_delay_timer;
373 struct timer_list hold_timer;
374 struct timer_list message_age_timer;
375 struct kobject kobj;
376 struct rcu_head rcu;
Fischer, Anna3982d3d2009-08-13 06:55:16 +0000377
Nikolay Aleksandrov96322332021-07-19 20:06:23 +0300378 struct net_bridge_mcast_port multicast_ctx;
379
Herbert Xueb1d1642010-02-27 19:41:45 +0000380#ifdef CONFIG_BRIDGE_IGMP_SNOOPING
Nikolay Aleksandrov96322332021-07-19 20:06:23 +0300381 struct bridge_mcast_stats __percpu *mcast_stats;
382
Nikolay Aleksandrov89268b02021-01-26 11:35:32 +0200383 u32 multicast_eht_hosts_limit;
384 u32 multicast_eht_hosts_cnt;
Herbert Xueb1d1642010-02-27 19:41:45 +0000385 struct hlist_head mglist;
Herbert Xueb1d1642010-02-27 19:41:45 +0000386#endif
Simon Arlotte0f43752010-05-10 09:31:11 +0000387
388#ifdef CONFIG_SYSFS
389 char sysfs_name[IFNAMSIZ];
390#endif
Herbert Xu91d2c342010-06-10 16:12:50 +0000391
392#ifdef CONFIG_NET_POLL_CONTROLLER
393 struct netpoll *np;
394#endif
Ido Schimmel6bc506b2016-08-25 18:42:37 +0200395#ifdef CONFIG_NET_SWITCHDEV
Tobias Waldekranzf7cf9722021-07-21 19:23:59 +0300396 /* Identifier used to group ports that share the same switchdev
397 * hardware domain.
398 */
399 int hwdom;
Vladimir Oltean2f5dc002021-07-21 19:24:01 +0300400 int offload_count;
401 struct netdev_phys_item_id ppid;
Ido Schimmel6bc506b2016-08-25 18:42:37 +0200402#endif
Nikolay Aleksandrov5af48b52017-09-27 16:12:44 +0300403 u16 group_fwd_mask;
Nikolay Aleksandrov2756f682018-07-23 11:16:59 +0300404 u16 backup_redirected_cnt;
Vivien Didelotde179962019-12-11 20:07:10 -0500405
406 struct bridge_stp_xstats stp_xstats;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700407};
408
Tyler Hicks705e0de2018-07-20 21:56:54 +0000409#define kobj_to_brport(obj) container_of(obj, struct net_bridge_port, kobj)
410
Vlad Yaseviche028e4b2014-05-16 09:59:16 -0400411#define br_auto_port(p) ((p)->flags & BR_AUTO_MASK)
Vlad Yasevichf3a6ddf2014-05-16 09:59:18 -0400412#define br_promisc_port(p) ((p)->flags & BR_PROMISC)
Vlad Yaseviche028e4b2014-05-16 09:59:16 -0400413
stephen hemmingerb5ed54e2010-11-15 06:38:13 +0000414static inline struct net_bridge_port *br_port_get_rcu(const struct net_device *dev)
415{
Hong Zhiguo716ec052013-09-14 22:42:28 +0800416 return rcu_dereference(dev->rx_handler_data);
stephen hemmingerb5ed54e2010-11-15 06:38:13 +0000417}
418
Hong Zhiguo1fb17542013-09-14 22:42:27 +0800419static inline struct net_bridge_port *br_port_get_rtnl(const struct net_device *dev)
stephen hemmingerb5ed54e2010-11-15 06:38:13 +0000420{
Julian Wiedmann35f861e2019-03-29 14:38:19 +0100421 return netif_is_bridge_port(dev) ?
Eric Dumazetec1e5612010-11-15 06:38:14 +0000422 rtnl_dereference(dev->rx_handler_data) : NULL;
stephen hemmingerb5ed54e2010-11-15 06:38:13 +0000423}
424
Arkadi Sharshevsky0baa10f2017-06-08 08:44:12 +0200425static inline struct net_bridge_port *br_port_get_rtnl_rcu(const struct net_device *dev)
426{
Julian Wiedmann35f861e2019-03-29 14:38:19 +0100427 return netif_is_bridge_port(dev) ?
Arkadi Sharshevsky0baa10f2017-06-08 08:44:12 +0200428 rcu_dereference_rtnl(dev->rx_handler_data) : NULL;
429}
430
Nikolay Aleksandrovae757672018-09-26 17:01:00 +0300431enum net_bridge_opts {
432 BROPT_VLAN_ENABLED,
433 BROPT_VLAN_STATS_ENABLED,
Nikolay Aleksandrov8df35102018-09-26 17:01:01 +0300434 BROPT_NF_CALL_IPTABLES,
435 BROPT_NF_CALL_IP6TABLES,
436 BROPT_NF_CALL_ARPTABLES,
Nikolay Aleksandrovbe3664a2018-09-26 17:01:02 +0300437 BROPT_GROUP_ADDR_SET,
Nikolay Aleksandrov13cefad2018-09-26 17:01:03 +0300438 BROPT_MULTICAST_ENABLED,
Nikolay Aleksandrov675779a2018-09-26 17:01:04 +0300439 BROPT_MULTICAST_QUERY_USE_IFADDR,
440 BROPT_MULTICAST_STATS_ENABLED,
441 BROPT_HAS_IPV6_ADDR,
Nikolay Aleksandrovc69c2cd2018-09-26 17:01:05 +0300442 BROPT_NEIGH_SUPPRESS_ENABLED,
Nikolay Aleksandrov3341d912018-09-26 17:01:06 +0300443 BROPT_MTU_SET_BY_USER,
Nikolay Aleksandrov9163a0f2018-10-12 13:41:16 +0300444 BROPT_VLAN_STATS_PER_PORT,
Nikolay Aleksandrov70e42722018-11-24 04:34:21 +0200445 BROPT_NO_LL_LEARN,
Mike Manning9c0ec2e2019-04-18 18:35:33 +0100446 BROPT_VLAN_BRIDGE_BINDING,
Nikolay Aleksandrovf4b70022021-07-19 20:06:28 +0300447 BROPT_MCAST_VLAN_SNOOPING_ENABLED,
Nikolay Aleksandrovae757672018-09-26 17:01:00 +0300448};
449
Nikolay Aleksandrov1f90c7f2017-02-04 18:05:06 +0100450struct net_bridge {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700451 spinlock_t lock;
Nikolay Aleksandrov1f90c7f2017-02-04 18:05:06 +0100452 spinlock_t hash_lock;
Henrik Bjoernlund90c628d2020-10-27 10:02:42 +0000453 struct hlist_head frame_type_list;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700454 struct net_device *dev;
Nikolay Aleksandrovae757672018-09-26 17:01:00 +0300455 unsigned long options;
Nikolay Aleksandrov1f90c7f2017-02-04 18:05:06 +0100456 /* These fields are accessed on each packet */
457#ifdef CONFIG_BRIDGE_VLAN_FILTERING
Nikolay Aleksandrov1f90c7f2017-02-04 18:05:06 +0100458 __be16 vlan_proto;
459 u16 default_pvid;
460 struct net_bridge_vlan_group __rcu *vlgrp;
461#endif
462
Nikolay Aleksandroveb793582017-12-12 16:02:50 +0200463 struct rhashtable fdb_hash_tbl;
Henrik Bjoernlund90c628d2020-10-27 10:02:42 +0000464 struct list_head port_list;
Pablo Neira Ayuso34666d42014-09-18 11:29:03 +0200465#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
Bernhard Thalerefb6de92015-05-30 15:30:16 +0200466 union {
467 struct rtable fake_rtable;
468 struct rt6_info fake_rt6_info;
469 };
Simon Wunderlich4adf0af2008-07-30 16:27:55 -0700470#endif
stephen hemminger515853c2011-10-03 18:14:46 +0000471 u16 group_fwd_mask;
Toshiaki Makitaf2808d22014-06-10 20:59:24 +0900472 u16 group_fwd_mask_required;
stephen hemminger515853c2011-10-03 18:14:46 +0000473
Linus Torvalds1da177e2005-04-16 15:20:36 -0700474 /* STP */
475 bridge_id designated_root;
476 bridge_id bridge_id;
Nikolay Aleksandrov1f90c7f2017-02-04 18:05:06 +0100477 unsigned char topology_change;
478 unsigned char topology_change_detected;
479 u16 root_port;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700480 unsigned long max_age;
481 unsigned long hello_time;
482 unsigned long forward_delay;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700483 unsigned long ageing_time;
Vivien Didelot34d8acd2016-12-10 13:44:29 -0500484 unsigned long bridge_max_age;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700485 unsigned long bridge_hello_time;
486 unsigned long bridge_forward_delay;
Vivien Didelot34d8acd2016-12-10 13:44:29 -0500487 unsigned long bridge_ageing_time;
Nikolay Aleksandrov35750b02018-09-26 17:01:07 +0300488 u32 root_path_cost;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700489
Stephen Hemmingerfda93d92006-03-20 22:59:21 -0800490 u8 group_addr[ETH_ALEN];
Stephen Hemminger9cde0702007-03-21 14:22:44 -0700491
492 enum {
493 BR_NO_STP, /* no spanning tree */
494 BR_KERNEL_STP, /* old STP in kernel */
495 BR_USER_STP, /* new RSTP in userspace */
496 } stp_enabled;
497
Nikolay Aleksandrovd3d065c2021-07-19 20:06:24 +0300498 struct net_bridge_mcast multicast_ctx;
499
Herbert Xueb1d1642010-02-27 19:41:45 +0000500#ifdef CONFIG_BRIDGE_IGMP_SNOOPING
Nikolay Aleksandrovd3d065c2021-07-19 20:06:24 +0300501 struct bridge_mcast_stats __percpu *mcast_stats;
Herbert Xueb1d1642010-02-27 19:41:45 +0000502
Herbert Xueb1d1642010-02-27 19:41:45 +0000503 u32 hash_max;
504
Nikolay Aleksandrov35750b02018-09-26 17:01:07 +0300505 spinlock_t multicast_lock;
Herbert Xueb1d1642010-02-27 19:41:45 +0000506
Nikolay Aleksandrov19e3a9c2018-12-05 15:14:24 +0200507 struct rhashtable mdb_hash_tbl;
Nikolay Aleksandrov085b53c2020-09-22 10:30:22 +0300508 struct rhashtable sg_port_tbl;
Nikolay Aleksandrov19e3a9c2018-12-05 15:14:24 +0200509
Nikolay Aleksandrove12cec62020-09-07 12:56:19 +0300510 struct hlist_head mcast_gc_list;
Nikolay Aleksandrov19e3a9c2018-12-05 15:14:24 +0200511 struct hlist_head mdb_list;
Herbert Xueb1d1642010-02-27 19:41:45 +0000512
Nikolay Aleksandrove12cec62020-09-07 12:56:19 +0300513 struct work_struct mcast_gc_work;
Herbert Xueb1d1642010-02-27 19:41:45 +0000514#endif
515
Linus Torvalds1da177e2005-04-16 15:20:36 -0700516 struct timer_list hello_timer;
517 struct timer_list tcn_timer;
518 struct timer_list topology_change_timer;
Nikolay Aleksandrovf7cdee82017-02-04 18:05:07 +0100519 struct delayed_work gc_work;
Greg Kroah-Hartman43b98c42007-12-17 15:54:39 -0400520 struct kobject *ifobj;
Vlad Yaseviche028e4b2014-05-16 09:59:16 -0400521 u32 auto_cnt;
Ido Schimmel6bc506b2016-08-25 18:42:37 +0200522
523#ifdef CONFIG_NET_SWITCHDEV
Tobias Waldekranzf7cf9722021-07-21 19:23:59 +0300524 /* Counter used to make sure that hardware domains get unique
525 * identifiers in case a bridge spans multiple switchdev instances.
526 */
527 int last_hwdom;
Tobias Waldekranz85826612021-07-21 19:24:00 +0300528 /* Bit mask of hardware domain numbers in use */
529 unsigned long busy_hwdoms;
Ido Schimmel6bc506b2016-08-25 18:42:37 +0200530#endif
Nikolay Aleksandroveb793582017-12-12 16:02:50 +0200531 struct hlist_head fdb_list;
Horatiu Vultur4b8d7d42020-04-26 15:22:00 +0200532
533#if IS_ENABLED(CONFIG_BRIDGE_MRP)
Horatiu Vultur0169b822020-11-06 22:50:49 +0100534 struct hlist_head mrp_list;
Horatiu Vultur4b8d7d42020-04-26 15:22:00 +0200535#endif
Henrik Bjoernlundf323aa52020-10-27 10:02:43 +0000536#if IS_ENABLED(CONFIG_BRIDGE_CFM)
537 struct hlist_head mep_list;
538#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700539};
540
Herbert Xu68b7c892010-02-27 19:41:40 +0000541struct br_input_skb_cb {
542 struct net_device *brdev;
Herbert Xu93fdd472014-10-05 12:00:22 +0800543
Pablo Neira Ayuso3c171f42019-05-29 13:25:37 +0200544 u16 frag_max_size;
YOSHIFUJI Hideaki / 吉藤英明32dec5d2010-03-15 21:51:18 +0000545#ifdef CONFIG_BRIDGE_IGMP_SNOOPING
Florian Westphalf12064d2019-04-11 16:36:40 +0200546 u8 igmp;
547 u8 mrouters_only:1;
YOSHIFUJI Hideaki / 吉藤英明32dec5d2010-03-15 21:51:18 +0000548#endif
Florian Westphalf12064d2019-04-11 16:36:40 +0200549 u8 proxyarp_replied:1;
550 u8 src_port_isolated:1;
Vlad Yasevich20adfa12014-09-12 16:26:16 -0400551#ifdef CONFIG_BRIDGE_VLAN_FILTERING
Florian Westphalf12064d2019-04-11 16:36:40 +0200552 u8 vlan_filtered:1;
Vlad Yasevich20adfa12014-09-12 16:26:16 -0400553#endif
Florian Westphal223fd0a2019-04-11 16:36:42 +0200554#ifdef CONFIG_NETFILTER_FAMILY_BRIDGE
555 u8 br_netfilter_broute:1;
556#endif
Ido Schimmel6bc506b2016-08-25 18:42:37 +0200557
558#ifdef CONFIG_NET_SWITCHDEV
Tobias Waldekranz47211192021-07-22 18:55:38 +0300559 /* Set if TX data plane offloading is used towards at least one
560 * hardware domain.
561 */
562 u8 tx_fwd_offload:1;
Tobias Waldekranzf7cf9722021-07-21 19:23:59 +0300563 /* The switchdev hardware domain from which this packet was received.
564 * If skb->offload_fwd_mark was set, then this packet was already
565 * forwarded by hardware to the other ports in the source hardware
566 * domain, otherwise it wasn't.
567 */
568 int src_hwdom;
Tobias Waldekranz47211192021-07-22 18:55:38 +0300569 /* Bit mask of hardware domains towards this packet has already been
570 * transmitted using the TX data plane offload.
571 */
572 unsigned long fwd_hwdoms;
Ido Schimmel6bc506b2016-08-25 18:42:37 +0200573#endif
Herbert Xu68b7c892010-02-27 19:41:40 +0000574};
575
576#define BR_INPUT_SKB_CB(__skb) ((struct br_input_skb_cb *)(__skb)->cb)
577
YOSHIFUJI Hideaki / 吉藤英明32dec5d2010-03-15 21:51:18 +0000578#ifdef CONFIG_BRIDGE_IGMP_SNOOPING
579# define BR_INPUT_SKB_CB_MROUTERS_ONLY(__skb) (BR_INPUT_SKB_CB(__skb)->mrouters_only)
580#else
581# define BR_INPUT_SKB_CB_MROUTERS_ONLY(__skb) (0)
582#endif
583
stephen hemminger28a16c92010-05-10 09:31:09 +0000584#define br_printk(level, br, format, args...) \
585 printk(level "%s: " format, (br)->dev->name, ##args)
586
587#define br_err(__br, format, args...) \
588 br_printk(KERN_ERR, __br, format, ##args)
589#define br_warn(__br, format, args...) \
590 br_printk(KERN_WARNING, __br, format, ##args)
591#define br_notice(__br, format, args...) \
592 br_printk(KERN_NOTICE, __br, format, ##args)
593#define br_info(__br, format, args...) \
594 br_printk(KERN_INFO, __br, format, ##args)
595
596#define br_debug(br, format, args...) \
597 pr_debug("%s: " format, (br)->dev->name, ##args)
598
Linus Torvalds1da177e2005-04-16 15:20:36 -0700599/* called under bridge lock */
600static inline int br_is_root_bridge(const struct net_bridge *br)
601{
602 return !memcmp(&br->bridge_id, &br->designated_root, 8);
603}
604
Nikolay Aleksandrov2594e9062015-09-25 19:00:11 +0200605/* check if a VLAN entry is global */
606static inline bool br_vlan_is_master(const struct net_bridge_vlan *v)
607{
608 return v->flags & BRIDGE_VLAN_INFO_MASTER;
609}
610
611/* check if a VLAN entry is used by the bridge */
612static inline bool br_vlan_is_brentry(const struct net_bridge_vlan *v)
613{
614 return v->flags & BRIDGE_VLAN_INFO_BRENTRY;
615}
616
Nikolay Aleksandrov6be144f2015-10-02 15:05:13 +0200617/* check if we should use the vlan entry, returns false if it's only context */
Nikolay Aleksandrov2594e9062015-09-25 19:00:11 +0200618static inline bool br_vlan_should_use(const struct net_bridge_vlan *v)
619{
620 if (br_vlan_is_master(v)) {
621 if (br_vlan_is_brentry(v))
622 return true;
623 else
624 return false;
625 }
626
627 return true;
628}
629
Nikolay Aleksandrov5d1fcaf2019-11-04 11:36:51 +0200630static inline bool nbp_state_should_learn(const struct net_bridge_port *p)
631{
632 return p->state == BR_STATE_LEARNING || p->state == BR_STATE_FORWARDING;
633}
634
Nikolay Aleksandrov8f4cc942020-01-14 19:56:08 +0200635static inline bool br_vlan_valid_id(u16 vid, struct netlink_ext_ack *extack)
Nikolay Aleksandrov5a46fac2020-01-14 19:56:07 +0200636{
Nikolay Aleksandrov8f4cc942020-01-14 19:56:08 +0200637 bool ret = vid > 0 && vid < VLAN_VID_MASK;
638
639 if (!ret)
640 NL_SET_ERR_MSG_MOD(extack, "Vlan id is invalid");
641
642 return ret;
Nikolay Aleksandrov5a46fac2020-01-14 19:56:07 +0200643}
644
645static inline bool br_vlan_valid_range(const struct bridge_vlan_info *cur,
Nikolay Aleksandrov8f4cc942020-01-14 19:56:08 +0200646 const struct bridge_vlan_info *last,
647 struct netlink_ext_ack *extack)
Nikolay Aleksandrov5a46fac2020-01-14 19:56:07 +0200648{
649 /* pvid flag is not allowed in ranges */
Nikolay Aleksandrov8f4cc942020-01-14 19:56:08 +0200650 if (cur->flags & BRIDGE_VLAN_INFO_PVID) {
651 NL_SET_ERR_MSG_MOD(extack, "Pvid isn't allowed in a range");
Nikolay Aleksandrov5a46fac2020-01-14 19:56:07 +0200652 return false;
Nikolay Aleksandrov8f4cc942020-01-14 19:56:08 +0200653 }
Nikolay Aleksandrov5a46fac2020-01-14 19:56:07 +0200654
655 /* when cur is the range end, check if:
656 * - it has range start flag
657 * - range ids are invalid (end is equal to or before start)
658 */
659 if (last) {
Nikolay Aleksandrov8f4cc942020-01-14 19:56:08 +0200660 if (cur->flags & BRIDGE_VLAN_INFO_RANGE_BEGIN) {
661 NL_SET_ERR_MSG_MOD(extack, "Found a new vlan range start while processing one");
Nikolay Aleksandrov5a46fac2020-01-14 19:56:07 +0200662 return false;
Nikolay Aleksandrov8f4cc942020-01-14 19:56:08 +0200663 } else if (!(cur->flags & BRIDGE_VLAN_INFO_RANGE_END)) {
664 NL_SET_ERR_MSG_MOD(extack, "Vlan range end flag is missing");
Nikolay Aleksandrov5a46fac2020-01-14 19:56:07 +0200665 return false;
Nikolay Aleksandrov8f4cc942020-01-14 19:56:08 +0200666 } else if (cur->vid <= last->vid) {
667 NL_SET_ERR_MSG_MOD(extack, "End vlan id is less than or equal to start vlan id");
668 return false;
669 }
670 }
671
672 /* check for required range flags */
673 if (!(cur->flags & (BRIDGE_VLAN_INFO_RANGE_BEGIN |
674 BRIDGE_VLAN_INFO_RANGE_END))) {
675 NL_SET_ERR_MSG_MOD(extack, "Both vlan range flags are missing");
676 return false;
Nikolay Aleksandrov5a46fac2020-01-14 19:56:07 +0200677 }
678
679 return true;
680}
681
Nikolay Aleksandrov2796d842021-08-20 15:42:55 +0300682static inline u8 br_vlan_multicast_router(const struct net_bridge_vlan *v)
683{
684 u8 mcast_router = MDB_RTR_TYPE_DISABLED;
685
686#ifdef CONFIG_BRIDGE_IGMP_SNOOPING
687 if (!br_vlan_is_master(v))
688 mcast_router = v->port_mcast_ctx.multicast_router;
689 else
690 mcast_router = v->br_mcast_ctx.multicast_router;
691#endif
692
693 return mcast_router;
694}
695
Nikolay Aleksandrovf5459232020-01-14 19:56:14 +0200696static inline int br_afspec_cmd_to_rtm(int cmd)
697{
698 switch (cmd) {
699 case RTM_SETLINK:
700 return RTM_NEWVLAN;
701 case RTM_DELLINK:
702 return RTM_DELVLAN;
703 }
704
705 return 0;
706}
707
Nikolay Aleksandrovae757672018-09-26 17:01:00 +0300708static inline int br_opt_get(const struct net_bridge *br,
709 enum net_bridge_opts opt)
710{
711 return test_bit(opt, &br->options);
712}
713
Nikolay Aleksandrova428afe2018-11-24 04:34:20 +0200714int br_boolopt_toggle(struct net_bridge *br, enum br_boolopt_id opt, bool on,
715 struct netlink_ext_ack *extack);
716int br_boolopt_get(const struct net_bridge *br, enum br_boolopt_id opt);
717int br_boolopt_multi_toggle(struct net_bridge *br,
718 struct br_boolopt_multi *bm,
719 struct netlink_ext_ack *extack);
720void br_boolopt_multi_get(const struct net_bridge *br,
721 struct br_boolopt_multi *bm);
Nikolay Aleksandrovae757672018-09-26 17:01:00 +0300722void br_opt_toggle(struct net_bridge *br, enum net_bridge_opts opt, bool on);
723
Linus Torvalds1da177e2005-04-16 15:20:36 -0700724/* br_device.c */
Joe Perches348662a2013-10-18 13:48:22 -0700725void br_dev_setup(struct net_device *dev);
726void br_dev_delete(struct net_device *dev, struct list_head *list);
727netdev_tx_t br_dev_xmit(struct sk_buff *skb, struct net_device *dev);
stephen hemmingercfb478d2010-05-10 09:31:08 +0000728#ifdef CONFIG_NET_POLL_CONTROLLER
Herbert Xu91d2c342010-06-10 16:12:50 +0000729static inline void br_netpoll_send_skb(const struct net_bridge_port *p,
730 struct sk_buff *skb)
731{
Eric Dumazetf78ed222020-05-07 09:32:21 -0700732 netpoll_send_skb(p->np, skb);
Herbert Xu91d2c342010-06-10 16:12:50 +0000733}
734
Eric W. Biedermana8779ec2014-03-27 15:36:38 -0700735int br_netpoll_enable(struct net_bridge_port *p);
Joe Perches348662a2013-10-18 13:48:22 -0700736void br_netpoll_disable(struct net_bridge_port *p);
Herbert Xu91d2c342010-06-10 16:12:50 +0000737#else
Herbert Xu9f70b0f2010-06-15 21:43:48 -0700738static inline void br_netpoll_send_skb(const struct net_bridge_port *p,
Herbert Xu91d2c342010-06-10 16:12:50 +0000739 struct sk_buff *skb)
740{
741}
742
Eric W. Biedermana8779ec2014-03-27 15:36:38 -0700743static inline int br_netpoll_enable(struct net_bridge_port *p)
Herbert Xu91d2c342010-06-10 16:12:50 +0000744{
745 return 0;
746}
747
748static inline void br_netpoll_disable(struct net_bridge_port *p)
749{
750}
stephen hemmingercfb478d2010-05-10 09:31:08 +0000751#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700752
753/* br_fdb.c */
Joe Perches348662a2013-10-18 13:48:22 -0700754int br_fdb_init(void);
755void br_fdb_fini(void);
Nikolay Aleksandroveb793582017-12-12 16:02:50 +0200756int br_fdb_hash_init(struct net_bridge *br);
757void br_fdb_hash_fini(struct net_bridge *br);
Joe Perches348662a2013-10-18 13:48:22 -0700758void br_fdb_flush(struct net_bridge *br);
Toshiaki Makita424bb9c2014-02-07 16:48:25 +0900759void br_fdb_find_delete_local(struct net_bridge *br,
760 const struct net_bridge_port *p,
761 const unsigned char *addr, u16 vid);
Joe Perches348662a2013-10-18 13:48:22 -0700762void br_fdb_changeaddr(struct net_bridge_port *p, const unsigned char *newaddr);
763void br_fdb_change_mac_address(struct net_bridge *br, const u8 *newaddr);
Nikolay Aleksandrovf7cdee82017-02-04 18:05:07 +0100764void br_fdb_cleanup(struct work_struct *work);
Joe Perches348662a2013-10-18 13:48:22 -0700765void br_fdb_delete_by_port(struct net_bridge *br,
Nikolay Aleksandrov1ea2d022015-06-23 05:28:16 -0700766 const struct net_bridge_port *p, u16 vid, int do_all);
Nikolay Aleksandrovbfd0aea2017-02-13 14:59:09 +0100767struct net_bridge_fdb_entry *br_fdb_find_rcu(struct net_bridge *br,
768 const unsigned char *addr,
769 __u16 vid);
Joe Perches348662a2013-10-18 13:48:22 -0700770int br_fdb_test_addr(struct net_device *dev, unsigned char *addr);
771int br_fdb_fillbuf(struct net_bridge *br, void *buf, unsigned long count,
772 unsigned long off);
Vladimir Olteanf6814fd2021-10-26 17:27:39 +0300773int br_fdb_add_local(struct net_bridge *br, struct net_bridge_port *source,
774 const unsigned char *addr, u16 vid);
Joe Perches348662a2013-10-18 13:48:22 -0700775void br_fdb_update(struct net_bridge *br, struct net_bridge_port *source,
Nikolay Aleksandrovbe0c5672019-11-01 14:46:37 +0200776 const unsigned char *addr, u16 vid, unsigned long flags);
John Fastabend77162022012-04-15 06:43:56 +0000777
Joe Perches348662a2013-10-18 13:48:22 -0700778int br_fdb_delete(struct ndmsg *ndm, struct nlattr *tb[],
Jiri Pirkof6f64242014-11-28 14:34:15 +0100779 struct net_device *dev, const unsigned char *addr, u16 vid);
Joe Perches348662a2013-10-18 13:48:22 -0700780int br_fdb_add(struct ndmsg *nlh, struct nlattr *tb[], struct net_device *dev,
Petr Machata87b09842019-01-16 23:06:50 +0000781 const unsigned char *addr, u16 vid, u16 nlh_flags,
782 struct netlink_ext_ack *extack);
Joe Perches348662a2013-10-18 13:48:22 -0700783int br_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb,
Roopa Prabhud2976532016-08-30 21:56:45 -0700784 struct net_device *dev, struct net_device *fdev, int *idx);
Roopa Prabhu47674562018-12-15 22:35:09 -0800785int br_fdb_get(struct sk_buff *skb, struct nlattr *tb[], struct net_device *dev,
786 const unsigned char *addr, u16 vid, u32 portid, u32 seq,
787 struct netlink_ext_ack *extack);
Vlad Yasevich8db24af2014-05-16 09:59:17 -0400788int br_fdb_sync_static(struct net_bridge *br, struct net_bridge_port *p);
789void br_fdb_unsync_static(struct net_bridge *br, struct net_bridge_port *p);
Jiri Pirko3aeb6612015-01-15 23:49:37 +0100790int br_fdb_external_learn_add(struct net_bridge *br, struct net_bridge_port *p,
Nikolay Aleksandrov45a68782021-08-10 14:00:10 +0300791 const unsigned char *addr, u16 vid,
Petr Machata161d82d2018-05-03 14:43:53 +0200792 bool swdev_notify);
Jiri Pirko3aeb6612015-01-15 23:49:37 +0100793int br_fdb_external_learn_del(struct net_bridge *br, struct net_bridge_port *p,
Petr Machata161d82d2018-05-03 14:43:53 +0200794 const unsigned char *addr, u16 vid,
795 bool swdev_notify);
Arkadi Sharshevsky9fe8bce2017-06-08 08:44:15 +0200796void br_fdb_offloaded_set(struct net_bridge *br, struct net_bridge_port *p,
Ido Schimmele9ba0fb2018-10-17 08:53:29 +0000797 const unsigned char *addr, u16 vid, bool offloaded);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700798
799/* br_forward.c */
Nikolay Aleksandrov8addd5e2016-08-31 15:36:51 +0200800enum br_pkt_type {
801 BR_PKT_UNICAST,
802 BR_PKT_MULTICAST,
803 BR_PKT_BROADCAST
804};
Eric W. Biederman0c4b51f2015-09-15 20:04:18 -0500805int br_dev_queue_push_xmit(struct net *net, struct sock *sk, struct sk_buff *skb);
Nikolay Aleksandrovb35c5f62016-07-14 06:10:01 +0300806void br_forward(const struct net_bridge_port *to, struct sk_buff *skb,
Nikolay Aleksandrov37b090e2016-07-14 06:10:02 +0300807 bool local_rcv, bool local_orig);
Eric W. Biederman0c4b51f2015-09-15 20:04:18 -0500808int br_forward_finish(struct net *net, struct sock *sk, struct sk_buff *skb);
Nikolay Aleksandrov37b090e2016-07-14 06:10:02 +0300809void br_flood(struct net_bridge *br, struct sk_buff *skb,
Nikolay Aleksandrov8addd5e2016-08-31 15:36:51 +0200810 enum br_pkt_type pkt_type, bool local_rcv, bool local_orig);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700811
Nikolay Aleksandrov7d850ab2018-05-24 11:56:48 +0300812/* return true if both source port and dest port are isolated */
813static inline bool br_skb_isolated(const struct net_bridge_port *to,
814 const struct sk_buff *skb)
815{
816 return BR_INPUT_SKB_CB(skb)->src_port_isolated &&
817 (to->flags & BR_ISOLATED);
818}
819
Linus Torvalds1da177e2005-04-16 15:20:36 -0700820/* br_if.c */
Nikolay Aleksandrovfaa1cd82018-05-03 13:47:24 +0300821void br_port_carrier_check(struct net_bridge_port *p, bool *notified);
Joe Perches348662a2013-10-18 13:48:22 -0700822int br_add_bridge(struct net *net, const char *name);
823int br_del_bridge(struct net *net, const char *name);
David Ahernca752be2017-10-04 17:48:50 -0700824int br_add_if(struct net_bridge *br, struct net_device *dev,
825 struct netlink_ext_ack *extack);
Joe Perches348662a2013-10-18 13:48:22 -0700826int br_del_if(struct net_bridge *br, struct net_device *dev);
Nikolay Aleksandrov804b8542018-03-30 13:46:19 +0300827void br_mtu_auto_adjust(struct net_bridge *br);
Joe Perches348662a2013-10-18 13:48:22 -0700828netdev_features_t br_features_recompute(struct net_bridge *br,
829 netdev_features_t features);
Vlad Yaseviche028e4b2014-05-16 09:59:16 -0400830void br_port_flags_change(struct net_bridge_port *port, unsigned long mask);
Vlad Yasevich2796d0c2014-05-16 09:59:20 -0400831void br_manage_promisc(struct net_bridge *br);
Nikolay Aleksandrov2756f682018-07-23 11:16:59 +0300832int nbp_backup_change(struct net_bridge_port *p, struct net_device *backup_dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700833
834/* br_input.c */
Eric W. Biederman0c4b51f2015-09-15 20:04:18 -0500835int br_handle_frame_finish(struct net *net, struct sock *sk, struct sk_buff *skb);
Vladimir Oltean9eb8eff2020-05-10 19:37:40 +0300836rx_handler_func_t *br_get_rx_handler(const struct net_device *dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700837
Henrik Bjoernlund90c628d2020-10-27 10:02:42 +0000838struct br_frame_type {
839 __be16 type;
840 int (*frame_handler)(struct net_bridge_port *port,
841 struct sk_buff *skb);
842 struct hlist_node list;
843};
844
845void br_add_frame(struct net_bridge *br, struct br_frame_type *ft);
846void br_del_frame(struct net_bridge *br, struct br_frame_type *ft);
847
Jiri Pirko859828c2013-12-05 16:27:37 +0100848static inline bool br_rx_handler_check_rcu(const struct net_device *dev)
849{
Vladimir Oltean9eb8eff2020-05-10 19:37:40 +0300850 return rcu_dereference(dev->rx_handler) == br_get_rx_handler(dev);
Jiri Pirko859828c2013-12-05 16:27:37 +0100851}
852
Petr Machata4d4fd362018-04-29 10:56:08 +0300853static inline bool br_rx_handler_check_rtnl(const struct net_device *dev)
854{
Vladimir Oltean9eb8eff2020-05-10 19:37:40 +0300855 return rcu_dereference_rtnl(dev->rx_handler) == br_get_rx_handler(dev);
Petr Machata4d4fd362018-04-29 10:56:08 +0300856}
857
Jiri Pirko859828c2013-12-05 16:27:37 +0100858static inline struct net_bridge_port *br_port_get_check_rcu(const struct net_device *dev)
859{
860 return br_rx_handler_check_rcu(dev) ? br_port_get_rcu(dev) : NULL;
861}
862
Petr Machata4d4fd362018-04-29 10:56:08 +0300863static inline struct net_bridge_port *
864br_port_get_check_rtnl(const struct net_device *dev)
865{
866 return br_rx_handler_check_rtnl(dev) ? br_port_get_rtnl_rcu(dev) : NULL;
867}
868
Linus Torvalds1da177e2005-04-16 15:20:36 -0700869/* br_ioctl.c */
Arnd Bergmann561d8352021-07-27 15:44:51 +0200870int br_dev_siocdevprivate(struct net_device *dev, struct ifreq *rq,
871 void __user *data, int cmd);
Arnd Bergmannad2f99a2021-07-27 15:45:16 +0200872int br_ioctl_stub(struct net *net, struct net_bridge *br, unsigned int cmd,
873 struct ifreq *ifr, void __user *uarg);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700874
Herbert Xueb1d1642010-02-27 19:41:45 +0000875/* br_multicast.c */
876#ifdef CONFIG_BRIDGE_IGMP_SNOOPING
Nikolay Aleksandrovf4b70022021-07-19 20:06:28 +0300877int br_multicast_rcv(struct net_bridge_mcast **brmctx,
878 struct net_bridge_mcast_port **pmctx,
879 struct net_bridge_vlan *vlan,
David S. Miller394efd12013-11-04 13:48:30 -0500880 struct sk_buff *skb, u16 vid);
Nikolay Aleksandrovadc47032021-07-19 20:06:25 +0300881struct net_bridge_mdb_entry *br_mdb_get(struct net_bridge_mcast *brmctx,
Joe Perches348662a2013-10-18 13:48:22 -0700882 struct sk_buff *skb, u16 vid);
Nikolay Aleksandrov1080ab92016-06-28 16:57:06 +0200883int br_multicast_add_port(struct net_bridge_port *port);
Joe Perches348662a2013-10-18 13:48:22 -0700884void br_multicast_del_port(struct net_bridge_port *port);
885void br_multicast_enable_port(struct net_bridge_port *port);
886void br_multicast_disable_port(struct net_bridge_port *port);
887void br_multicast_init(struct net_bridge *br);
Joseph Huang851d0a72020-12-04 18:56:28 -0500888void br_multicast_join_snoopers(struct net_bridge *br);
889void br_multicast_leave_snoopers(struct net_bridge *br);
Joe Perches348662a2013-10-18 13:48:22 -0700890void br_multicast_open(struct net_bridge *br);
891void br_multicast_stop(struct net_bridge *br);
Satish Ashoke10177a2015-07-15 07:16:51 -0700892void br_multicast_dev_del(struct net_bridge *br);
Nikolay Aleksandrovadc47032021-07-19 20:06:25 +0300893void br_multicast_flood(struct net_bridge_mdb_entry *mdst, struct sk_buff *skb,
894 struct net_bridge_mcast *brmctx,
895 bool local_rcv, bool local_orig);
Nikolay Aleksandrova97df082021-08-10 18:29:31 +0300896int br_multicast_set_router(struct net_bridge_mcast *brmctx, unsigned long val);
Nikolay Aleksandrova53581d2021-08-20 15:42:54 +0300897int br_multicast_set_port_router(struct net_bridge_mcast_port *pmctx,
898 unsigned long val);
Nikolay Aleksandrov2796d842021-08-20 15:42:55 +0300899int br_multicast_set_vlan_router(struct net_bridge_vlan *v, u8 mcast_router);
Florian Fainelliae1ea842021-04-14 22:22:57 +0300900int br_multicast_toggle(struct net_bridge *br, unsigned long val,
901 struct netlink_ext_ack *extack);
Nikolay Aleksandrov62938182021-08-10 18:29:30 +0300902int br_multicast_set_querier(struct net_bridge_mcast *brmctx, unsigned long val);
Joe Perches348662a2013-10-18 13:48:22 -0700903int br_multicast_set_hash_max(struct net_bridge *br, unsigned long val);
Nikolay Aleksandrovdf271cd2021-08-10 18:29:19 +0300904int br_multicast_set_igmp_version(struct net_bridge_mcast *brmctx,
905 unsigned long val);
Nikolay Aleksandrovaa2ae3e2016-11-21 13:03:25 +0100906#if IS_ENABLED(CONFIG_IPV6)
Nikolay Aleksandrovdf271cd2021-08-10 18:29:19 +0300907int br_multicast_set_mld_version(struct net_bridge_mcast *brmctx,
908 unsigned long val);
Nikolay Aleksandrovaa2ae3e2016-11-21 13:03:25 +0100909#endif
Joe Perches348662a2013-10-18 13:48:22 -0700910struct net_bridge_mdb_entry *
Nikolay Aleksandrov19e3a9c2018-12-05 15:14:24 +0200911br_mdb_ip_get(struct net_bridge *br, struct br_ip *dst);
Joe Perches348662a2013-10-18 13:48:22 -0700912struct net_bridge_mdb_entry *
Nikolay Aleksandrov19e3a9c2018-12-05 15:14:24 +0200913br_multicast_new_group(struct net_bridge *br, struct br_ip *group);
Joe Perches348662a2013-10-18 13:48:22 -0700914struct net_bridge_port_group *
915br_multicast_new_port_group(struct net_bridge_port *port, struct br_ip *group,
916 struct net_bridge_port_group __rcu *next,
Nikolay Aleksandrov8b671772020-09-07 12:56:07 +0300917 unsigned char flags, const unsigned char *src,
Nikolay Aleksandrov8f8cb772020-09-22 10:30:21 +0300918 u8 filter_mode, u8 rt_protocol);
Nikolay Aleksandrov19e3a9c2018-12-05 15:14:24 +0200919int br_mdb_hash_init(struct net_bridge *br);
920void br_mdb_hash_fini(struct net_bridge *br);
Nikolay Aleksandrov81f19832020-09-07 12:56:12 +0300921void br_mdb_notify(struct net_device *dev, struct net_bridge_mdb_entry *mp,
922 struct net_bridge_port_group *pg, int type);
Nikolay Aleksandrov1e9ca452021-07-19 20:06:33 +0300923void br_rtr_notify(struct net_device *dev, struct net_bridge_mcast_port *pmctx,
Satish Ashok949f1e32015-07-23 05:00:53 -0700924 int type);
Nikolay Aleksandrov681590b2020-09-07 12:56:06 +0300925void br_multicast_del_pg(struct net_bridge_mdb_entry *mp,
926 struct net_bridge_port_group *pg,
927 struct net_bridge_port_group __rcu **pp);
Nikolay Aleksandrovadc47032021-07-19 20:06:25 +0300928void br_multicast_count(struct net_bridge *br,
929 const struct net_bridge_port *p,
Nikolay Aleksandrova65056e2016-07-06 12:12:21 -0700930 const struct sk_buff *skb, u8 type, u8 dir);
Nikolay Aleksandrov1080ab92016-06-28 16:57:06 +0200931int br_multicast_init_stats(struct net_bridge *br);
Ido Schimmelb6fe0442017-04-10 14:59:27 +0300932void br_multicast_uninit_stats(struct net_bridge *br);
Nikolay Aleksandrov1080ab92016-06-28 16:57:06 +0200933void br_multicast_get_stats(const struct net_bridge *br,
934 const struct net_bridge_port *p,
935 struct br_mcast_stats *dest);
Nikolay Aleksandrov19e3a9c2018-12-05 15:14:24 +0200936void br_mdb_init(void);
937void br_mdb_uninit(void);
Nikolay Aleksandrov58d913a2021-07-21 17:01:27 +0300938void br_multicast_host_join(const struct net_bridge_mcast *brmctx,
939 struct net_bridge_mdb_entry *mp, bool notify);
Nikolay Aleksandrov1bc844e2019-08-17 14:22:13 +0300940void br_multicast_host_leave(struct net_bridge_mdb_entry *mp, bool notify);
Nikolay Aleksandrov8266a042020-09-22 10:30:24 +0300941void br_multicast_star_g_handle_mode(struct net_bridge_port_group *pg,
942 u8 filter_mode);
943void br_multicast_sg_add_exclude_ports(struct net_bridge_mdb_entry *star_mp,
944 struct net_bridge_port_group *sg);
Nikolay Aleksandrov474ddb32021-01-20 16:51:58 +0200945struct net_bridge_group_src *
946br_multicast_find_group_src(struct net_bridge_port_group *pg, struct br_ip *ip);
Nikolay Aleksandrovd5a10222021-01-20 16:52:03 +0200947void br_multicast_del_group_src(struct net_bridge_group_src *src,
948 bool fastleave);
Nikolay Aleksandrov613d61d2021-07-19 20:06:26 +0300949void br_multicast_ctx_init(struct net_bridge *br,
950 struct net_bridge_vlan *vlan,
951 struct net_bridge_mcast *brmctx);
952void br_multicast_ctx_deinit(struct net_bridge_mcast *brmctx);
953void br_multicast_port_ctx_init(struct net_bridge_port *port,
954 struct net_bridge_vlan *vlan,
955 struct net_bridge_mcast_port *pmctx);
956void br_multicast_port_ctx_deinit(struct net_bridge_mcast_port *pmctx);
Nikolay Aleksandrov7b54aaa2021-07-19 20:06:27 +0300957void br_multicast_toggle_one_vlan(struct net_bridge_vlan *vlan, bool on);
Nikolay Aleksandrovf4b70022021-07-19 20:06:28 +0300958int br_multicast_toggle_vlan_snooping(struct net_bridge *br, bool on,
959 struct netlink_ext_ack *extack);
Nikolay Aleksandrov9dee5722021-07-19 20:06:37 +0300960bool br_multicast_toggle_global_vlan(struct net_bridge_vlan *vlan, bool on);
Sridhar Samudrala85b35262010-03-01 09:53:04 +0000961
Nikolay Aleksandrovdc002872021-08-10 18:29:33 +0300962int br_rports_fill_info(struct sk_buff *skb,
963 const struct net_bridge_mcast *brmctx);
Nikolay Aleksandrovc7fa1d92021-08-13 18:00:00 +0300964int br_multicast_dump_querier_state(struct sk_buff *skb,
965 const struct net_bridge_mcast *brmctx,
966 int nest_attr);
967size_t br_multicast_querier_state_size(void);
Nikolay Aleksandrov05d6f382021-08-16 17:57:05 +0300968size_t br_rports_size(const struct net_bridge_mcast *brmctx);
Nikolay Aleksandrov99b40612021-12-27 19:21:15 +0200969void br_multicast_set_query_intvl(struct net_bridge_mcast *brmctx,
970 unsigned long val);
Nikolay Aleksandrovf83a1122021-12-27 19:21:16 +0200971void br_multicast_set_startup_query_intvl(struct net_bridge_mcast *brmctx,
972 unsigned long val);
Vladimir Oltean4e51bf42021-07-21 19:24:03 +0300973
Nikolay Aleksandrov955062b2020-10-29 01:38:31 +0200974static inline bool br_group_is_l2(const struct br_ip *group)
975{
976 return group->proto == 0;
977}
978
Cong Wangcfd56752012-12-11 22:23:08 +0000979#define mlock_dereference(X, br) \
980 rcu_dereference_protected(X, lockdep_is_held(&br->multicast_lock))
981
Linus Lüssing44ebb082021-05-13 15:20:44 +0200982static inline struct hlist_node *
Nikolay Aleksandrovadc47032021-07-19 20:06:25 +0300983br_multicast_get_first_rport_node(struct net_bridge_mcast *brmctx,
984 struct sk_buff *skb)
Nikolay Aleksandrovd3d065c2021-07-19 20:06:24 +0300985{
Linus Lüssinga3c02e72021-05-13 15:20:51 +0200986#if IS_ENABLED(CONFIG_IPV6)
987 if (skb->protocol == htons(ETH_P_IPV6))
Nikolay Aleksandrovd3d065c2021-07-19 20:06:24 +0300988 return rcu_dereference(hlist_first_rcu(&brmctx->ip6_mc_router_list));
Linus Lüssinga3c02e72021-05-13 15:20:51 +0200989#endif
Nikolay Aleksandrovd3d065c2021-07-19 20:06:24 +0300990 return rcu_dereference(hlist_first_rcu(&brmctx->ip4_mc_router_list));
Linus Lüssing44ebb082021-05-13 15:20:44 +0200991}
992
993static inline struct net_bridge_port *
Nikolay Aleksandrovd3d065c2021-07-19 20:06:24 +0300994br_multicast_rport_from_node_skb(struct hlist_node *rp, struct sk_buff *skb)
995{
Nikolay Aleksandrov96322332021-07-19 20:06:23 +0300996 struct net_bridge_mcast_port *mctx;
997
Linus Lüssinga3c02e72021-05-13 15:20:51 +0200998#if IS_ENABLED(CONFIG_IPV6)
999 if (skb->protocol == htons(ETH_P_IPV6))
Nikolay Aleksandrov96322332021-07-19 20:06:23 +03001000 mctx = hlist_entry_safe(rp, struct net_bridge_mcast_port,
1001 ip6_rlist);
1002 else
Linus Lüssinga3c02e72021-05-13 15:20:51 +02001003#endif
Nikolay Aleksandrov96322332021-07-19 20:06:23 +03001004 mctx = hlist_entry_safe(rp, struct net_bridge_mcast_port,
1005 ip4_rlist);
1006
1007 if (mctx)
1008 return mctx->port;
1009 else
1010 return NULL;
Linus Lüssing44ebb082021-05-13 15:20:44 +02001011}
1012
Nikolay Aleksandrovd3d065c2021-07-19 20:06:24 +03001013static inline bool br_ip4_multicast_is_router(struct net_bridge_mcast *brmctx)
Sridhar Samudrala85b35262010-03-01 09:53:04 +00001014{
Nikolay Aleksandrovd3d065c2021-07-19 20:06:24 +03001015 return timer_pending(&brmctx->ip4_mc_router_timer);
Linus Lüssing1a3065a2021-05-13 15:20:47 +02001016}
1017
Nikolay Aleksandrovd3d065c2021-07-19 20:06:24 +03001018static inline bool br_ip6_multicast_is_router(struct net_bridge_mcast *brmctx)
Linus Lüssing1a3065a2021-05-13 15:20:47 +02001019{
1020#if IS_ENABLED(CONFIG_IPV6)
Nikolay Aleksandrovd3d065c2021-07-19 20:06:24 +03001021 return timer_pending(&brmctx->ip6_mc_router_timer);
Linus Lüssing1a3065a2021-05-13 15:20:47 +02001022#else
1023 return false;
1024#endif
1025}
1026
1027static inline bool
Nikolay Aleksandrovadc47032021-07-19 20:06:25 +03001028br_multicast_is_router(struct net_bridge_mcast *brmctx, struct sk_buff *skb)
Linus Lüssing1a3065a2021-05-13 15:20:47 +02001029{
Nikolay Aleksandrovd3d065c2021-07-19 20:06:24 +03001030 switch (brmctx->multicast_router) {
Linus Lüssing1a3065a2021-05-13 15:20:47 +02001031 case MDB_RTR_TYPE_PERM:
1032 return true;
1033 case MDB_RTR_TYPE_TEMP_QUERY:
1034 if (skb) {
1035 if (skb->protocol == htons(ETH_P_IP))
Nikolay Aleksandrovd3d065c2021-07-19 20:06:24 +03001036 return br_ip4_multicast_is_router(brmctx);
Linus Lüssing1a3065a2021-05-13 15:20:47 +02001037 else if (skb->protocol == htons(ETH_P_IPV6))
Nikolay Aleksandrovd3d065c2021-07-19 20:06:24 +03001038 return br_ip6_multicast_is_router(brmctx);
Linus Lüssing1a3065a2021-05-13 15:20:47 +02001039 } else {
Nikolay Aleksandrovd3d065c2021-07-19 20:06:24 +03001040 return br_ip4_multicast_is_router(brmctx) ||
1041 br_ip6_multicast_is_router(brmctx);
Linus Lüssing1a3065a2021-05-13 15:20:47 +02001042 }
1043 fallthrough;
1044 default:
1045 return false;
1046 }
Sridhar Samudrala85b35262010-03-01 09:53:04 +00001047}
Linus Lüssingb00589a2013-08-01 01:06:20 +02001048
Linus Lüssingcc0fdd82013-08-30 17:28:17 +02001049static inline bool
Nikolay Aleksandrovadc47032021-07-19 20:06:25 +03001050__br_multicast_querier_exists(struct net_bridge_mcast *brmctx,
1051 struct bridge_mcast_other_query *querier,
1052 const bool is_ipv6)
Linus Lüssingb00589a2013-08-01 01:06:20 +02001053{
daniel0888d5f2016-06-24 12:35:18 +02001054 bool own_querier_enabled;
1055
Nikolay Aleksandrov62938182021-08-10 18:29:30 +03001056 if (brmctx->multicast_querier) {
Nikolay Aleksandrovadc47032021-07-19 20:06:25 +03001057 if (is_ipv6 && !br_opt_get(brmctx->br, BROPT_HAS_IPV6_ADDR))
daniel0888d5f2016-06-24 12:35:18 +02001058 own_querier_enabled = false;
1059 else
1060 own_querier_enabled = true;
1061 } else {
1062 own_querier_enabled = false;
1063 }
1064
Linus Lüssingcc0fdd82013-08-30 17:28:17 +02001065 return time_is_before_jiffies(querier->delay_time) &&
daniel0888d5f2016-06-24 12:35:18 +02001066 (own_querier_enabled || timer_pending(&querier->timer));
Linus Lüssingcc0fdd82013-08-30 17:28:17 +02001067}
1068
Nikolay Aleksandrovadc47032021-07-19 20:06:25 +03001069static inline bool br_multicast_querier_exists(struct net_bridge_mcast *brmctx,
Nikolay Aleksandrov955062b2020-10-29 01:38:31 +02001070 struct ethhdr *eth,
1071 const struct net_bridge_mdb_entry *mdb)
Linus Lüssingcc0fdd82013-08-30 17:28:17 +02001072{
1073 switch (eth->h_proto) {
1074 case (htons(ETH_P_IP)):
Nikolay Aleksandrovadc47032021-07-19 20:06:25 +03001075 return __br_multicast_querier_exists(brmctx,
1076 &brmctx->ip4_other_query, false);
Linus Lüssingcc0fdd82013-08-30 17:28:17 +02001077#if IS_ENABLED(CONFIG_IPV6)
1078 case (htons(ETH_P_IPV6)):
Nikolay Aleksandrovadc47032021-07-19 20:06:25 +03001079 return __br_multicast_querier_exists(brmctx,
1080 &brmctx->ip6_other_query, true);
Linus Lüssingcc0fdd82013-08-30 17:28:17 +02001081#endif
1082 default:
Nikolay Aleksandrov955062b2020-10-29 01:38:31 +02001083 return !!mdb && br_group_is_l2(&mdb->addr);
Linus Lüssingcc0fdd82013-08-30 17:28:17 +02001084 }
Linus Lüssingb00589a2013-08-01 01:06:20 +02001085}
Nikolay Aleksandrov1080ab92016-06-28 16:57:06 +02001086
Nikolay Aleksandrov88d4bd12020-09-22 10:30:19 +03001087static inline bool br_multicast_is_star_g(const struct br_ip *ip)
1088{
1089 switch (ip->proto) {
1090 case htons(ETH_P_IP):
1091 return ipv4_is_zeronet(ip->src.ip4);
1092#if IS_ENABLED(CONFIG_IPV6)
1093 case htons(ETH_P_IPV6):
1094 return ipv6_addr_any(&ip->src.ip6);
1095#endif
1096 default:
1097 return false;
1098 }
1099}
1100
Nikolay Aleksandrovadc47032021-07-19 20:06:25 +03001101static inline bool
1102br_multicast_should_handle_mode(const struct net_bridge_mcast *brmctx,
1103 __be16 proto)
Nikolay Aleksandrov8266a042020-09-22 10:30:24 +03001104{
1105 switch (proto) {
1106 case htons(ETH_P_IP):
Nikolay Aleksandrovadc47032021-07-19 20:06:25 +03001107 return !!(brmctx->multicast_igmp_version == 3);
Nikolay Aleksandrov8266a042020-09-22 10:30:24 +03001108#if IS_ENABLED(CONFIG_IPV6)
1109 case htons(ETH_P_IPV6):
Nikolay Aleksandrovadc47032021-07-19 20:06:25 +03001110 return !!(brmctx->multicast_mld_version == 2);
Nikolay Aleksandrov8266a042020-09-22 10:30:24 +03001111#endif
1112 default:
1113 return false;
1114 }
1115}
1116
Nikolay Aleksandrov1080ab92016-06-28 16:57:06 +02001117static inline int br_multicast_igmp_type(const struct sk_buff *skb)
1118{
1119 return BR_INPUT_SKB_CB(skb)->igmp;
1120}
Nikolay Aleksandrov42c11cc2020-09-07 12:56:10 +03001121
Nikolay Aleksandrovadc47032021-07-19 20:06:25 +03001122static inline unsigned long br_multicast_lmqt(const struct net_bridge_mcast *brmctx)
Nikolay Aleksandrov42c11cc2020-09-07 12:56:10 +03001123{
Nikolay Aleksandrovadc47032021-07-19 20:06:25 +03001124 return brmctx->multicast_last_member_interval *
1125 brmctx->multicast_last_member_count;
Nikolay Aleksandrov42c11cc2020-09-07 12:56:10 +03001126}
Nikolay Aleksandrov04368622020-09-07 12:56:14 +03001127
Nikolay Aleksandrovadc47032021-07-19 20:06:25 +03001128static inline unsigned long br_multicast_gmi(const struct net_bridge_mcast *brmctx)
Nikolay Aleksandrov04368622020-09-07 12:56:14 +03001129{
Nikolay Aleksandrovfac3cb82021-10-15 12:05:46 +03001130 return brmctx->multicast_membership_interval;
Nikolay Aleksandrov04368622020-09-07 12:56:14 +03001131}
Nikolay Aleksandrov7b54aaa2021-07-19 20:06:27 +03001132
1133static inline bool
1134br_multicast_ctx_is_vlan(const struct net_bridge_mcast *brmctx)
1135{
1136 return !!brmctx->vlan;
1137}
1138
1139static inline bool
1140br_multicast_port_ctx_is_vlan(const struct net_bridge_mcast_port *pmctx)
1141{
1142 return !!pmctx->vlan;
1143}
1144
1145static inline struct net_bridge_mcast *
1146br_multicast_port_ctx_get_global(const struct net_bridge_mcast_port *pmctx)
1147{
1148 if (!br_multicast_port_ctx_is_vlan(pmctx))
1149 return &pmctx->port->br->multicast_ctx;
1150 else
1151 return &pmctx->vlan->brvlan->br_mcast_ctx;
1152}
1153
1154static inline bool
1155br_multicast_ctx_vlan_global_disabled(const struct net_bridge_mcast *brmctx)
1156{
Nikolay Aleksandrov168fed92021-12-28 17:31:42 +02001157 return br_multicast_ctx_is_vlan(brmctx) &&
1158 (!br_opt_get(brmctx->br, BROPT_MCAST_VLAN_SNOOPING_ENABLED) ||
1159 !(brmctx->vlan->priv_flags & BR_VLFLAG_GLOBAL_MCAST_ENABLED));
Nikolay Aleksandrov7b54aaa2021-07-19 20:06:27 +03001160}
1161
1162static inline bool
1163br_multicast_ctx_vlan_disabled(const struct net_bridge_mcast *brmctx)
1164{
1165 return br_multicast_ctx_is_vlan(brmctx) &&
1166 !(brmctx->vlan->priv_flags & BR_VLFLAG_MCAST_ENABLED);
1167}
1168
1169static inline bool
1170br_multicast_port_ctx_vlan_disabled(const struct net_bridge_mcast_port *pmctx)
1171{
1172 return br_multicast_port_ctx_is_vlan(pmctx) &&
1173 !(pmctx->vlan->priv_flags & BR_VLFLAG_MCAST_ENABLED);
1174}
Nikolay Aleksandrov4cdd0d12021-07-19 20:06:31 +03001175
1176static inline bool
1177br_multicast_port_ctx_state_disabled(const struct net_bridge_mcast_port *pmctx)
1178{
1179 return pmctx->port->state == BR_STATE_DISABLED ||
1180 (br_multicast_port_ctx_is_vlan(pmctx) &&
1181 (br_multicast_port_ctx_vlan_disabled(pmctx) ||
1182 pmctx->vlan->state == BR_STATE_DISABLED));
1183}
1184
1185static inline bool
1186br_multicast_port_ctx_state_stopped(const struct net_bridge_mcast_port *pmctx)
1187{
1188 return br_multicast_port_ctx_state_disabled(pmctx) ||
1189 pmctx->port->state == BR_STATE_BLOCKING ||
1190 (br_multicast_port_ctx_is_vlan(pmctx) &&
1191 pmctx->vlan->state == BR_STATE_BLOCKING);
1192}
Nikolay Aleksandrovdf271cd2021-08-10 18:29:19 +03001193
1194static inline bool
Nikolay Aleksandrovdc002872021-08-10 18:29:33 +03001195br_rports_have_mc_router(const struct net_bridge_mcast *brmctx)
1196{
1197#if IS_ENABLED(CONFIG_IPV6)
1198 return !hlist_empty(&brmctx->ip4_mc_router_list) ||
1199 !hlist_empty(&brmctx->ip6_mc_router_list);
1200#else
1201 return !hlist_empty(&brmctx->ip4_mc_router_list);
1202#endif
1203}
1204
1205static inline bool
Nikolay Aleksandrovdf271cd2021-08-10 18:29:19 +03001206br_multicast_ctx_options_equal(const struct net_bridge_mcast *brmctx1,
1207 const struct net_bridge_mcast *brmctx2)
1208{
1209 return brmctx1->multicast_igmp_version ==
1210 brmctx2->multicast_igmp_version &&
Nikolay Aleksandrov931ba872021-08-10 18:29:20 +03001211 brmctx1->multicast_last_member_count ==
1212 brmctx2->multicast_last_member_count &&
Nikolay Aleksandrov50725f62021-08-10 18:29:21 +03001213 brmctx1->multicast_startup_query_count ==
1214 brmctx2->multicast_startup_query_count &&
Nikolay Aleksandrov77f6aba2021-08-10 18:29:22 +03001215 brmctx1->multicast_last_member_interval ==
1216 brmctx2->multicast_last_member_interval &&
Nikolay Aleksandrov2da0aea2021-08-10 18:29:23 +03001217 brmctx1->multicast_membership_interval ==
1218 brmctx2->multicast_membership_interval &&
Nikolay Aleksandrovcd9269d2021-08-10 18:29:24 +03001219 brmctx1->multicast_querier_interval ==
1220 brmctx2->multicast_querier_interval &&
Nikolay Aleksandrovd6c08ab2021-08-10 18:29:25 +03001221 brmctx1->multicast_query_interval ==
1222 brmctx2->multicast_query_interval &&
Nikolay Aleksandrov42521452021-08-10 18:29:26 +03001223 brmctx1->multicast_query_response_interval ==
1224 brmctx2->multicast_query_response_interval &&
Nikolay Aleksandrov941121e2021-08-10 18:29:27 +03001225 brmctx1->multicast_startup_query_interval ==
1226 brmctx2->multicast_startup_query_interval &&
Nikolay Aleksandrov62938182021-08-10 18:29:30 +03001227 brmctx1->multicast_querier == brmctx2->multicast_querier &&
Nikolay Aleksandrova97df082021-08-10 18:29:31 +03001228 brmctx1->multicast_router == brmctx2->multicast_router &&
Nikolay Aleksandrovdc002872021-08-10 18:29:33 +03001229 !br_rports_have_mc_router(brmctx1) &&
1230 !br_rports_have_mc_router(brmctx2) &&
Nikolay Aleksandrovdf271cd2021-08-10 18:29:19 +03001231#if IS_ENABLED(CONFIG_IPV6)
1232 brmctx1->multicast_mld_version ==
1233 brmctx2->multicast_mld_version &&
1234#endif
1235 true;
1236}
Nikolay Aleksandrovcb486ce2021-08-10 18:29:29 +03001237
1238static inline bool
1239br_multicast_ctx_matches_vlan_snooping(const struct net_bridge_mcast *brmctx)
1240{
1241 bool vlan_snooping_enabled;
1242
1243 vlan_snooping_enabled = !!br_opt_get(brmctx->br,
1244 BROPT_MCAST_VLAN_SNOOPING_ENABLED);
1245
1246 return !!(vlan_snooping_enabled == br_multicast_ctx_is_vlan(brmctx));
1247}
Herbert Xueb1d1642010-02-27 19:41:45 +00001248#else
Nikolay Aleksandrovf4b70022021-07-19 20:06:28 +03001249static inline int br_multicast_rcv(struct net_bridge_mcast **brmctx,
1250 struct net_bridge_mcast_port **pmctx,
1251 struct net_bridge_vlan *vlan,
Vlad Yasevich06499092013-10-28 15:45:07 -04001252 struct sk_buff *skb,
1253 u16 vid)
Herbert Xueb1d1642010-02-27 19:41:45 +00001254{
1255 return 0;
1256}
1257
Nikolay Aleksandrovadc47032021-07-19 20:06:25 +03001258static inline struct net_bridge_mdb_entry *br_mdb_get(struct net_bridge_mcast *brmctx,
Cong Wangfbca58a2013-03-07 03:05:33 +00001259 struct sk_buff *skb, u16 vid)
Herbert Xueb1d1642010-02-27 19:41:45 +00001260{
1261 return NULL;
1262}
1263
Nikolay Aleksandrov1080ab92016-06-28 16:57:06 +02001264static inline int br_multicast_add_port(struct net_bridge_port *port)
Herbert Xueb1d1642010-02-27 19:41:45 +00001265{
Nikolay Aleksandrov1080ab92016-06-28 16:57:06 +02001266 return 0;
Herbert Xueb1d1642010-02-27 19:41:45 +00001267}
1268
1269static inline void br_multicast_del_port(struct net_bridge_port *port)
1270{
1271}
1272
1273static inline void br_multicast_enable_port(struct net_bridge_port *port)
1274{
1275}
1276
1277static inline void br_multicast_disable_port(struct net_bridge_port *port)
1278{
1279}
1280
1281static inline void br_multicast_init(struct net_bridge *br)
1282{
1283}
1284
Joseph Huang851d0a72020-12-04 18:56:28 -05001285static inline void br_multicast_join_snoopers(struct net_bridge *br)
1286{
1287}
1288
1289static inline void br_multicast_leave_snoopers(struct net_bridge *br)
1290{
1291}
1292
Herbert Xueb1d1642010-02-27 19:41:45 +00001293static inline void br_multicast_open(struct net_bridge *br)
1294{
1295}
1296
1297static inline void br_multicast_stop(struct net_bridge *br)
1298{
1299}
Herbert Xu5cb5e942010-02-27 19:41:46 +00001300
Nikolay Aleksandrova7ce45a2015-07-20 23:03:45 +02001301static inline void br_multicast_dev_del(struct net_bridge *br)
1302{
1303}
1304
Nikolay Aleksandrov37b090e2016-07-14 06:10:02 +03001305static inline void br_multicast_flood(struct net_bridge_mdb_entry *mdst,
1306 struct sk_buff *skb,
Nikolay Aleksandrovadc47032021-07-19 20:06:25 +03001307 struct net_bridge_mcast *brmctx,
Nikolay Aleksandrov37b090e2016-07-14 06:10:02 +03001308 bool local_rcv, bool local_orig)
Herbert Xu5cb5e942010-02-27 19:41:46 +00001309{
1310}
1311
Nikolay Aleksandrovadc47032021-07-19 20:06:25 +03001312static inline bool br_multicast_is_router(struct net_bridge_mcast *brmctx,
Nikolay Aleksandrovbbc6f2c2021-05-14 10:32:33 +03001313 struct sk_buff *skb)
Herbert Xueb1d1642010-02-27 19:41:45 +00001314{
Gustavo A. R. Silva03aaa9e2018-01-18 17:37:45 -06001315 return false;
Herbert Xueb1d1642010-02-27 19:41:45 +00001316}
Nikolay Aleksandrov37b090e2016-07-14 06:10:02 +03001317
Nikolay Aleksandrovadc47032021-07-19 20:06:25 +03001318static inline bool br_multicast_querier_exists(struct net_bridge_mcast *brmctx,
Vladimir Olteanc43fd362020-11-01 02:08:45 +02001319 struct ethhdr *eth,
1320 const struct net_bridge_mdb_entry *mdb)
Linus Lüssingb00589a2013-08-01 01:06:20 +02001321{
1322 return false;
1323}
Nikolay Aleksandrov37b090e2016-07-14 06:10:02 +03001324
Rami Rosenfdb184d2013-01-03 13:30:43 +02001325static inline void br_mdb_init(void)
1326{
1327}
Nikolay Aleksandrov37b090e2016-07-14 06:10:02 +03001328
Rami Rosenfdb184d2013-01-03 13:30:43 +02001329static inline void br_mdb_uninit(void)
1330{
1331}
Nikolay Aleksandrov1080ab92016-06-28 16:57:06 +02001332
Nikolay Aleksandrov19e3a9c2018-12-05 15:14:24 +02001333static inline int br_mdb_hash_init(struct net_bridge *br)
1334{
1335 return 0;
1336}
1337
1338static inline void br_mdb_hash_fini(struct net_bridge *br)
1339{
1340}
1341
Nikolay Aleksandrov1080ab92016-06-28 16:57:06 +02001342static inline void br_multicast_count(struct net_bridge *br,
1343 const struct net_bridge_port *p,
Nikolay Aleksandrova65056e2016-07-06 12:12:21 -07001344 const struct sk_buff *skb,
1345 u8 type, u8 dir)
Nikolay Aleksandrov1080ab92016-06-28 16:57:06 +02001346{
1347}
1348
1349static inline int br_multicast_init_stats(struct net_bridge *br)
1350{
1351 return 0;
1352}
1353
Ido Schimmelb6fe0442017-04-10 14:59:27 +03001354static inline void br_multicast_uninit_stats(struct net_bridge *br)
1355{
1356}
1357
Nikolay Aleksandrov1080ab92016-06-28 16:57:06 +02001358static inline int br_multicast_igmp_type(const struct sk_buff *skb)
1359{
1360 return 0;
1361}
Nikolay Aleksandrov613d61d2021-07-19 20:06:26 +03001362
1363static inline void br_multicast_ctx_init(struct net_bridge *br,
1364 struct net_bridge_vlan *vlan,
1365 struct net_bridge_mcast *brmctx)
1366{
1367}
1368
1369static inline void br_multicast_ctx_deinit(struct net_bridge_mcast *brmctx)
1370{
1371}
1372
1373static inline void br_multicast_port_ctx_init(struct net_bridge_port *port,
1374 struct net_bridge_vlan *vlan,
1375 struct net_bridge_mcast_port *pmctx)
1376{
1377}
1378
1379static inline void br_multicast_port_ctx_deinit(struct net_bridge_mcast_port *pmctx)
1380{
1381}
Nikolay Aleksandrov7b54aaa2021-07-19 20:06:27 +03001382
1383static inline void br_multicast_toggle_one_vlan(struct net_bridge_vlan *vlan,
1384 bool on)
1385{
1386}
Nikolay Aleksandrovf4b70022021-07-19 20:06:28 +03001387
Nikolay Aleksandrovf4b70022021-07-19 20:06:28 +03001388static inline int br_multicast_toggle_vlan_snooping(struct net_bridge *br,
1389 bool on,
1390 struct netlink_ext_ack *extack)
1391{
1392 return -EOPNOTSUPP;
1393}
Nikolay Aleksandrov9dee5722021-07-19 20:06:37 +03001394
1395static inline bool br_multicast_toggle_global_vlan(struct net_bridge_vlan *vlan,
1396 bool on)
1397{
1398 return false;
1399}
Vladimir Oltean4e51bf42021-07-21 19:24:03 +03001400
Nikolay Aleksandrovdf271cd2021-08-10 18:29:19 +03001401static inline bool
1402br_multicast_ctx_options_equal(const struct net_bridge_mcast *brmctx1,
1403 const struct net_bridge_mcast *brmctx2)
1404{
1405 return true;
1406}
Sridhar Samudrala85b35262010-03-01 09:53:04 +00001407#endif
Herbert Xueb1d1642010-02-27 19:41:45 +00001408
Vlad Yasevich243a2e62013-02-13 12:00:09 +00001409/* br_vlan.c */
1410#ifdef CONFIG_BRIDGE_VLAN_FILTERING
Nikolay Aleksandrov77751ee2015-09-30 20:16:53 +02001411bool br_allowed_ingress(const struct net_bridge *br,
1412 struct net_bridge_vlan_group *vg, struct sk_buff *skb,
Nikolay Aleksandrovf4b70022021-07-19 20:06:28 +03001413 u16 *vid, u8 *state,
1414 struct net_bridge_vlan **vlan);
Nikolay Aleksandrov77751ee2015-09-30 20:16:53 +02001415bool br_allowed_egress(struct net_bridge_vlan_group *vg,
Joe Perches348662a2013-10-18 13:48:22 -07001416 const struct sk_buff *skb);
Toshiaki Makitae0d79682014-05-26 15:15:53 +09001417bool br_should_learn(struct net_bridge_port *p, struct sk_buff *skb, u16 *vid);
Joe Perches348662a2013-10-18 13:48:22 -07001418struct sk_buff *br_handle_vlan(struct net_bridge *br,
Roopa Prabhu11538d02017-01-31 22:59:55 -08001419 const struct net_bridge_port *port,
Nikolay Aleksandrov2594e9062015-09-25 19:00:11 +02001420 struct net_bridge_vlan_group *vg,
Joe Perches348662a2013-10-18 13:48:22 -07001421 struct sk_buff *skb);
Nikolay Aleksandrovf418af62017-10-27 13:19:37 +03001422int br_vlan_add(struct net_bridge *br, u16 vid, u16 flags,
Petr Machata169327d2018-12-12 17:02:50 +00001423 bool *changed, struct netlink_ext_ack *extack);
Joe Perches348662a2013-10-18 13:48:22 -07001424int br_vlan_delete(struct net_bridge *br, u16 vid);
1425void br_vlan_flush(struct net_bridge *br);
Nikolay Aleksandrov2594e9062015-09-25 19:00:11 +02001426struct net_bridge_vlan *br_vlan_find(struct net_bridge_vlan_group *vg, u16 vid);
Toshiaki Makita204177f2014-06-10 20:59:25 +09001427void br_recalculate_fwd_mask(struct net_bridge *br);
Vladimir Oltean9e781402021-02-13 22:43:16 +02001428int br_vlan_filter_toggle(struct net_bridge *br, unsigned long val,
1429 struct netlink_ext_ack *extack);
Vladimir Olteandcbdf132021-02-13 22:43:17 +02001430int __br_vlan_set_proto(struct net_bridge *br, __be16 proto,
1431 struct netlink_ext_ack *extack);
Vladimir Oltean9e781402021-02-13 22:43:16 +02001432int br_vlan_set_proto(struct net_bridge *br, unsigned long val,
1433 struct netlink_ext_ack *extack);
Nikolay Aleksandrov6dada9b2016-04-30 10:25:28 +02001434int br_vlan_set_stats(struct net_bridge *br, unsigned long val);
Nikolay Aleksandrov9163a0f2018-10-12 13:41:16 +03001435int br_vlan_set_stats_per_port(struct net_bridge *br, unsigned long val);
Vlad Yasevich5be5a2d2014-10-03 11:29:18 -04001436int br_vlan_init(struct net_bridge *br);
Vladimir Oltean9e781402021-02-13 22:43:16 +02001437int br_vlan_set_default_pvid(struct net_bridge *br, unsigned long val,
1438 struct netlink_ext_ack *extack);
Petr Machata169327d2018-12-12 17:02:50 +00001439int __br_vlan_set_default_pvid(struct net_bridge *br, u16 pvid,
1440 struct netlink_ext_ack *extack);
Nikolay Aleksandrovf418af62017-10-27 13:19:37 +03001441int nbp_vlan_add(struct net_bridge_port *port, u16 vid, u16 flags,
Petr Machata169327d2018-12-12 17:02:50 +00001442 bool *changed, struct netlink_ext_ack *extack);
Joe Perches348662a2013-10-18 13:48:22 -07001443int nbp_vlan_delete(struct net_bridge_port *port, u16 vid);
1444void nbp_vlan_flush(struct net_bridge_port *port);
Petr Machata169327d2018-12-12 17:02:50 +00001445int nbp_vlan_init(struct net_bridge_port *port, struct netlink_ext_ack *extack);
Nikolay Aleksandrov2594e9062015-09-25 19:00:11 +02001446int nbp_get_num_vlan_infos(struct net_bridge_port *p, u32 filter_mask);
Nikolay Aleksandrova60c0902016-04-30 10:25:29 +02001447void br_vlan_get_stats(const struct net_bridge_vlan *v,
Heiner Kallweit281cc282020-11-17 21:25:42 +01001448 struct pcpu_sw_netstats *stats);
Mike Manning9c0ec2e2019-04-18 18:35:33 +01001449void br_vlan_port_event(struct net_bridge_port *p, unsigned long event);
Nikolay Aleksandrov091adf92019-08-02 13:57:36 +03001450int br_vlan_bridge_event(struct net_device *dev, unsigned long event,
1451 void *ptr);
Nikolay Aleksandrov8dcea182020-01-14 19:56:09 +02001452void br_vlan_rtnl_init(void);
1453void br_vlan_rtnl_uninit(void);
Nikolay Aleksandrovcf5bddb2020-01-14 19:56:13 +02001454void br_vlan_notify(const struct net_bridge *br,
1455 const struct net_bridge_port *p,
1456 u16 vid, u16 vid_range,
1457 int cmd);
Nikolay Aleksandrova5d29ae2020-01-24 13:40:21 +02001458bool br_vlan_can_enter_range(const struct net_bridge_vlan *v_curr,
1459 const struct net_bridge_vlan *range_end);
Vlad Yasevicha37b85c2013-02-13 12:00:10 +00001460
Felix Fietkaubcf27662021-03-24 02:30:35 +01001461void br_vlan_fill_forward_path_pvid(struct net_bridge *br,
1462 struct net_device_path_ctx *ctx,
1463 struct net_device_path *path);
1464int br_vlan_fill_forward_path_mode(struct net_bridge *br,
1465 struct net_bridge_port *dst,
1466 struct net_device_path *path);
1467
Nikolay Aleksandrov2594e9062015-09-25 19:00:11 +02001468static inline struct net_bridge_vlan_group *br_vlan_group(
1469 const struct net_bridge *br)
Vlad Yasevicha37b85c2013-02-13 12:00:10 +00001470{
Nikolay Aleksandrov907b1e62015-10-12 21:47:02 +02001471 return rtnl_dereference(br->vlgrp);
Vlad Yasevicha37b85c2013-02-13 12:00:10 +00001472}
1473
Nikolay Aleksandrov2594e9062015-09-25 19:00:11 +02001474static inline struct net_bridge_vlan_group *nbp_vlan_group(
1475 const struct net_bridge_port *p)
Vlad Yasevicha37b85c2013-02-13 12:00:10 +00001476{
Nikolay Aleksandrov907b1e62015-10-12 21:47:02 +02001477 return rtnl_dereference(p->vlgrp);
1478}
1479
1480static inline struct net_bridge_vlan_group *br_vlan_group_rcu(
1481 const struct net_bridge *br)
1482{
1483 return rcu_dereference(br->vlgrp);
1484}
1485
1486static inline struct net_bridge_vlan_group *nbp_vlan_group_rcu(
1487 const struct net_bridge_port *p)
1488{
1489 return rcu_dereference(p->vlgrp);
Vlad Yasevicha37b85c2013-02-13 12:00:10 +00001490}
1491
1492/* Since bridge now depends on 8021Q module, but the time bridge sees the
1493 * skb, the vlan tag will always be present if the frame was tagged.
1494 */
1495static inline int br_vlan_get_tag(const struct sk_buff *skb, u16 *vid)
1496{
1497 int err = 0;
1498
Nikolay Aleksandrov2594e9062015-09-25 19:00:11 +02001499 if (skb_vlan_tag_present(skb)) {
Michał Mirosław5978f8a2018-11-09 00:18:03 +01001500 *vid = skb_vlan_tag_get_id(skb);
Nikolay Aleksandrov2594e9062015-09-25 19:00:11 +02001501 } else {
Vlad Yasevicha37b85c2013-02-13 12:00:10 +00001502 *vid = 0;
1503 err = -EINVAL;
1504 }
1505
1506 return err;
1507}
Vlad Yasevich78851982013-02-13 12:00:14 +00001508
Nikolay Aleksandrov77751ee2015-09-30 20:16:53 +02001509static inline u16 br_get_pvid(const struct net_bridge_vlan_group *vg)
Vlad Yasevich78851982013-02-13 12:00:14 +00001510{
Nikolay Aleksandrov77751ee2015-09-30 20:16:53 +02001511 if (!vg)
Vlad Yasevich5be5a2d2014-10-03 11:29:18 -04001512 return 0;
1513
Vlad Yasevich78851982013-02-13 12:00:14 +00001514 smp_rmb();
Nikolay Aleksandrov77751ee2015-09-30 20:16:53 +02001515 return vg->pvid;
Vlad Yasevich78851982013-02-13 12:00:14 +00001516}
1517
Nikolay Aleksandrov8dcea182020-01-14 19:56:09 +02001518static inline u16 br_vlan_flags(const struct net_bridge_vlan *v, u16 pvid)
1519{
1520 return v->vid == pvid ? v->flags | BRIDGE_VLAN_INFO_PVID : v->flags;
1521}
Vlad Yasevich243a2e62013-02-13 12:00:09 +00001522#else
Nikolay Aleksandrov77751ee2015-09-30 20:16:53 +02001523static inline bool br_allowed_ingress(const struct net_bridge *br,
1524 struct net_bridge_vlan_group *vg,
Vlad Yasevich78851982013-02-13 12:00:14 +00001525 struct sk_buff *skb,
Nikolay Aleksandrovf4b70022021-07-19 20:06:28 +03001526 u16 *vid, u8 *state,
1527 struct net_bridge_vlan **vlan)
1528
Vlad Yasevicha37b85c2013-02-13 12:00:10 +00001529{
Nikolay Aleksandrovf4b70022021-07-19 20:06:28 +03001530 *vlan = NULL;
Vlad Yasevicha37b85c2013-02-13 12:00:10 +00001531 return true;
1532}
1533
Nikolay Aleksandrov2594e9062015-09-25 19:00:11 +02001534static inline bool br_allowed_egress(struct net_bridge_vlan_group *vg,
Vlad Yasevich85f46c62013-02-13 12:00:11 +00001535 const struct sk_buff *skb)
1536{
1537 return true;
1538}
1539
Toshiaki Makitae0d79682014-05-26 15:15:53 +09001540static inline bool br_should_learn(struct net_bridge_port *p,
1541 struct sk_buff *skb, u16 *vid)
1542{
1543 return true;
1544}
1545
Vlad Yasevich78851982013-02-13 12:00:14 +00001546static inline struct sk_buff *br_handle_vlan(struct net_bridge *br,
Roopa Prabhu11538d02017-01-31 22:59:55 -08001547 const struct net_bridge_port *port,
Nikolay Aleksandrov2594e9062015-09-25 19:00:11 +02001548 struct net_bridge_vlan_group *vg,
Vlad Yasevich78851982013-02-13 12:00:14 +00001549 struct sk_buff *skb)
1550{
1551 return skb;
1552}
1553
Nikolay Aleksandrovf418af62017-10-27 13:19:37 +03001554static inline int br_vlan_add(struct net_bridge *br, u16 vid, u16 flags,
Petr Machata169327d2018-12-12 17:02:50 +00001555 bool *changed, struct netlink_ext_ack *extack)
Vlad Yasevich243a2e62013-02-13 12:00:09 +00001556{
Nikolay Aleksandrovf418af62017-10-27 13:19:37 +03001557 *changed = false;
Vlad Yasevich243a2e62013-02-13 12:00:09 +00001558 return -EOPNOTSUPP;
1559}
1560
1561static inline int br_vlan_delete(struct net_bridge *br, u16 vid)
1562{
1563 return -EOPNOTSUPP;
1564}
1565
1566static inline void br_vlan_flush(struct net_bridge *br)
1567{
1568}
1569
Toshiaki Makita204177f2014-06-10 20:59:25 +09001570static inline void br_recalculate_fwd_mask(struct net_bridge *br)
1571{
1572}
1573
Vlad Yasevich5be5a2d2014-10-03 11:29:18 -04001574static inline int br_vlan_init(struct net_bridge *br)
Toshiaki Makita8580e212014-06-10 20:59:23 +09001575{
Vlad Yasevich5be5a2d2014-10-03 11:29:18 -04001576 return 0;
Toshiaki Makita8580e212014-06-10 20:59:23 +09001577}
1578
Nikolay Aleksandrovf418af62017-10-27 13:19:37 +03001579static inline int nbp_vlan_add(struct net_bridge_port *port, u16 vid, u16 flags,
Petr Machata169327d2018-12-12 17:02:50 +00001580 bool *changed, struct netlink_ext_ack *extack)
Vlad Yasevich243a2e62013-02-13 12:00:09 +00001581{
Nikolay Aleksandrovf418af62017-10-27 13:19:37 +03001582 *changed = false;
Vlad Yasevich243a2e62013-02-13 12:00:09 +00001583 return -EOPNOTSUPP;
1584}
1585
1586static inline int nbp_vlan_delete(struct net_bridge_port *port, u16 vid)
1587{
1588 return -EOPNOTSUPP;
1589}
1590
1591static inline void nbp_vlan_flush(struct net_bridge_port *port)
1592{
1593}
1594
Nikolay Aleksandrov2594e9062015-09-25 19:00:11 +02001595static inline struct net_bridge_vlan *br_vlan_find(struct net_bridge_vlan_group *vg,
1596 u16 vid)
Vlad Yasevicha37b85c2013-02-13 12:00:10 +00001597{
1598 return NULL;
1599}
Vlad Yasevichbc9a25d2013-02-13 12:00:19 +00001600
Petr Machata169327d2018-12-12 17:02:50 +00001601static inline int nbp_vlan_init(struct net_bridge_port *port,
1602 struct netlink_ext_ack *extack)
Vlad Yasevich5be5a2d2014-10-03 11:29:18 -04001603{
1604 return 0;
1605}
1606
Vlad Yasevich78851982013-02-13 12:00:14 +00001607static inline u16 br_vlan_get_tag(const struct sk_buff *skb, u16 *tag)
Vlad Yasevicha37b85c2013-02-13 12:00:10 +00001608{
1609 return 0;
1610}
Nikolay Aleksandrov2594e9062015-09-25 19:00:11 +02001611
Nikolay Aleksandrov77751ee2015-09-30 20:16:53 +02001612static inline u16 br_get_pvid(const struct net_bridge_vlan_group *vg)
Vlad Yasevich78851982013-02-13 12:00:14 +00001613{
Vlad Yasevich3df6bf42014-10-03 11:29:17 -04001614 return 0;
Vlad Yasevich78851982013-02-13 12:00:14 +00001615}
Vlad Yasevich2796d0c2014-05-16 09:59:20 -04001616
Vladimir Oltean7a572962021-02-13 22:43:15 +02001617static inline int br_vlan_filter_toggle(struct net_bridge *br,
Vladimir Olteanc97f47e2021-02-15 23:09:12 +02001618 unsigned long val,
1619 struct netlink_ext_ack *extack)
Nikolay Aleksandrova7854032015-08-07 19:40:45 +03001620{
1621 return -EOPNOTSUPP;
1622}
Nikolay Aleksandrov2594e9062015-09-25 19:00:11 +02001623
1624static inline int nbp_get_num_vlan_infos(struct net_bridge_port *p,
1625 u32 filter_mask)
1626{
1627 return 0;
1628}
1629
Felix Fietkaubcf27662021-03-24 02:30:35 +01001630static inline void br_vlan_fill_forward_path_pvid(struct net_bridge *br,
1631 struct net_device_path_ctx *ctx,
1632 struct net_device_path *path)
1633{
1634}
1635
1636static inline int br_vlan_fill_forward_path_mode(struct net_bridge *br,
1637 struct net_bridge_port *dst,
1638 struct net_device_path *path)
1639{
1640 return 0;
1641}
1642
Nikolay Aleksandrov2594e9062015-09-25 19:00:11 +02001643static inline struct net_bridge_vlan_group *br_vlan_group(
1644 const struct net_bridge *br)
1645{
1646 return NULL;
1647}
1648
1649static inline struct net_bridge_vlan_group *nbp_vlan_group(
1650 const struct net_bridge_port *p)
1651{
1652 return NULL;
1653}
Nikolay Aleksandrov907b1e62015-10-12 21:47:02 +02001654
1655static inline struct net_bridge_vlan_group *br_vlan_group_rcu(
1656 const struct net_bridge *br)
1657{
1658 return NULL;
1659}
1660
1661static inline struct net_bridge_vlan_group *nbp_vlan_group_rcu(
1662 const struct net_bridge_port *p)
1663{
1664 return NULL;
1665}
Nikolay Aleksandrova60c0902016-04-30 10:25:29 +02001666
1667static inline void br_vlan_get_stats(const struct net_bridge_vlan *v,
Heiner Kallweit281cc282020-11-17 21:25:42 +01001668 struct pcpu_sw_netstats *stats)
Nikolay Aleksandrova60c0902016-04-30 10:25:29 +02001669{
1670}
Mike Manning9c0ec2e2019-04-18 18:35:33 +01001671
1672static inline void br_vlan_port_event(struct net_bridge_port *p,
1673 unsigned long event)
1674{
1675}
1676
Nikolay Aleksandrov091adf92019-08-02 13:57:36 +03001677static inline int br_vlan_bridge_event(struct net_device *dev,
1678 unsigned long event, void *ptr)
Mike Manning9c0ec2e2019-04-18 18:35:33 +01001679{
Nikolay Aleksandrov091adf92019-08-02 13:57:36 +03001680 return 0;
Mike Manning9c0ec2e2019-04-18 18:35:33 +01001681}
Nikolay Aleksandrov8dcea182020-01-14 19:56:09 +02001682
1683static inline void br_vlan_rtnl_init(void)
1684{
1685}
1686
1687static inline void br_vlan_rtnl_uninit(void)
1688{
1689}
Nikolay Aleksandrovcf5bddb2020-01-14 19:56:13 +02001690
1691static inline void br_vlan_notify(const struct net_bridge *br,
1692 const struct net_bridge_port *p,
1693 u16 vid, u16 vid_range,
1694 int cmd)
1695{
1696}
Nikolay Aleksandrov528ae842020-07-13 10:55:46 +03001697
1698static inline bool br_vlan_can_enter_range(const struct net_bridge_vlan *v_curr,
1699 const struct net_bridge_vlan *range_end)
1700{
1701 return true;
1702}
Vladimir Oltean4e51bf42021-07-21 19:24:03 +03001703
Vladimir Olteanc5f6e5e2021-10-27 19:21:15 +03001704static inline u16 br_vlan_flags(const struct net_bridge_vlan *v, u16 pvid)
1705{
1706 return 0;
1707}
1708
Vlad Yasevich243a2e62013-02-13 12:00:09 +00001709#endif
1710
Nikolay Aleksandrov7a53e712020-01-24 13:40:20 +02001711/* br_vlan_options.c */
1712#ifdef CONFIG_BRIDGE_VLAN_FILTERING
Nikolay Aleksandrov99f7c5e2020-03-17 14:08:33 +02001713bool br_vlan_opts_eq_range(const struct net_bridge_vlan *v_curr,
1714 const struct net_bridge_vlan *range_end);
Nikolay Aleksandrov7a53e712020-01-24 13:40:20 +02001715bool br_vlan_opts_fill(struct sk_buff *skb, const struct net_bridge_vlan *v);
1716size_t br_vlan_opts_nl_size(void);
Nikolay Aleksandrova5d29ae2020-01-24 13:40:21 +02001717int br_vlan_process_options(const struct net_bridge *br,
1718 const struct net_bridge_port *p,
1719 struct net_bridge_vlan *range_start,
1720 struct net_bridge_vlan *range_end,
1721 struct nlattr **tb,
1722 struct netlink_ext_ack *extack);
Nikolay Aleksandrov47ecd2d2021-07-19 20:06:34 +03001723int br_vlan_rtm_process_global_options(struct net_device *dev,
1724 const struct nlattr *attr,
1725 int cmd,
1726 struct netlink_ext_ack *extack);
Nikolay Aleksandrov743a53d2021-07-19 20:06:35 +03001727bool br_vlan_global_opts_can_enter_range(const struct net_bridge_vlan *v_curr,
1728 const struct net_bridge_vlan *r_end);
1729bool br_vlan_global_opts_fill(struct sk_buff *skb, u16 vid, u16 vid_range,
1730 const struct net_bridge_vlan *v_opts);
Nikolay Aleksandrova580c762020-01-24 13:40:22 +02001731
1732/* vlan state manipulation helpers using *_ONCE to annotate lock-free access */
1733static inline u8 br_vlan_get_state(const struct net_bridge_vlan *v)
1734{
1735 return READ_ONCE(v->state);
1736}
1737
1738static inline void br_vlan_set_state(struct net_bridge_vlan *v, u8 state)
1739{
1740 WRITE_ONCE(v->state, state);
1741}
1742
1743static inline u8 br_vlan_get_pvid_state(const struct net_bridge_vlan_group *vg)
1744{
1745 return READ_ONCE(vg->pvid_state);
1746}
1747
1748static inline void br_vlan_set_pvid_state(struct net_bridge_vlan_group *vg,
1749 u8 state)
1750{
1751 WRITE_ONCE(vg->pvid_state, state);
1752}
1753
1754/* learn_allow is true at ingress and false at egress */
1755static inline bool br_vlan_state_allowed(u8 state, bool learn_allow)
1756{
1757 switch (state) {
1758 case BR_STATE_LEARNING:
1759 return learn_allow;
1760 case BR_STATE_FORWARDING:
1761 return true;
1762 default:
1763 return false;
1764 }
1765}
Nikolay Aleksandrov7a53e712020-01-24 13:40:20 +02001766#endif
1767
Pablo Neira Ayuso1a4ba642015-03-10 10:27:18 +01001768struct nf_br_ops {
1769 int (*br_dev_xmit_hook)(struct sk_buff *skb);
1770};
1771extern const struct nf_br_ops __rcu *nf_br_ops;
1772
Linus Torvalds1da177e2005-04-16 15:20:36 -07001773/* br_netfilter.c */
Pablo Neira Ayuso34666d42014-09-18 11:29:03 +02001774#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
1775int br_nf_core_init(void);
1776void br_nf_core_fini(void);
Joe Perches348662a2013-10-18 13:48:22 -07001777void br_netfilter_rtable_init(struct net_bridge *);
Stephen Hemmingerc0909712006-05-25 15:59:33 -07001778#else
Pablo Neira Ayuso34666d42014-09-18 11:29:03 +02001779static inline int br_nf_core_init(void) { return 0; }
1780static inline void br_nf_core_fini(void) {}
Simon Wunderlich4adf0af2008-07-30 16:27:55 -07001781#define br_netfilter_rtable_init(x)
Stephen Hemmingerc0909712006-05-25 15:59:33 -07001782#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07001783
1784/* br_stp.c */
Florian Fainelli775dd692014-09-30 16:13:19 -07001785void br_set_state(struct net_bridge_port *p, unsigned int state);
Joe Perches348662a2013-10-18 13:48:22 -07001786struct net_bridge_port *br_get_port(struct net_bridge *br, u16 port_no);
1787void br_init_port(struct net_bridge_port *p);
1788void br_become_designated_port(struct net_bridge_port *p);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001789
Joe Perches348662a2013-10-18 13:48:22 -07001790void __br_set_forward_delay(struct net_bridge *br, unsigned long t);
1791int br_set_forward_delay(struct net_bridge *br, unsigned long x);
1792int br_set_hello_time(struct net_bridge *br, unsigned long x);
1793int br_set_max_age(struct net_bridge *br, unsigned long x);
Vivien Didelot82dd4332016-12-10 13:44:27 -05001794int __set_ageing_time(struct net_device *dev, unsigned long t);
Vivien Didelot9e0b27f2016-07-21 12:42:19 -04001795int br_set_ageing_time(struct net_bridge *br, clock_t ageing_time);
stephen hemminger14f98f22011-04-04 14:03:33 +00001796
1797
Linus Torvalds1da177e2005-04-16 15:20:36 -07001798/* br_stp_if.c */
Joe Perches348662a2013-10-18 13:48:22 -07001799void br_stp_enable_bridge(struct net_bridge *br);
1800void br_stp_disable_bridge(struct net_bridge *br);
Horatiu Vultur419dba8a2020-04-26 15:22:08 +02001801int br_stp_set_enabled(struct net_bridge *br, unsigned long val,
1802 struct netlink_ext_ack *extack);
Joe Perches348662a2013-10-18 13:48:22 -07001803void br_stp_enable_port(struct net_bridge_port *p);
1804void br_stp_disable_port(struct net_bridge_port *p);
1805bool br_stp_recalculate_bridge_id(struct net_bridge *br);
1806void br_stp_change_bridge_id(struct net_bridge *br, const unsigned char *a);
1807void br_stp_set_bridge_priority(struct net_bridge *br, u16 newprio);
1808int br_stp_set_port_priority(struct net_bridge_port *p, unsigned long newprio);
1809int br_stp_set_path_cost(struct net_bridge_port *p, unsigned long path_cost);
1810ssize_t br_show_bridge_id(char *buf, const struct bridge_id *id);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001811
1812/* br_stp_bpdu.c */
Patrick McHardy7c85fbf2008-07-05 21:25:56 -07001813struct stp_proto;
Joe Perches348662a2013-10-18 13:48:22 -07001814void br_stp_rcv(const struct stp_proto *proto, struct sk_buff *skb,
1815 struct net_device *dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001816
1817/* br_stp_timer.c */
Joe Perches348662a2013-10-18 13:48:22 -07001818void br_stp_timer_init(struct net_bridge *br);
1819void br_stp_port_timer_init(struct net_bridge_port *p);
1820unsigned long br_timer_value(const struct timer_list *timer);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001821
1822/* br.c */
Igor Maraviće6373c42011-12-12 02:58:25 +00001823#if IS_ENABLED(CONFIG_ATM_LANE)
Michał Mirosławda678292009-06-05 05:35:28 +00001824extern int (*br_fdb_test_addr_hook)(struct net_device *dev, unsigned char *addr);
1825#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07001826
Horatiu Vultur65369932020-04-26 15:22:07 +02001827/* br_mrp.c */
1828#if IS_ENABLED(CONFIG_BRIDGE_MRP)
1829int br_mrp_parse(struct net_bridge *br, struct net_bridge_port *p,
1830 struct nlattr *attr, int cmd, struct netlink_ext_ack *extack);
Horatiu Vultur65369932020-04-26 15:22:07 +02001831bool br_mrp_enabled(struct net_bridge *br);
1832void br_mrp_port_del(struct net_bridge *br, struct net_bridge_port *p);
Horatiu Vulturdf42ef222020-07-02 10:13:06 +02001833int br_mrp_fill_info(struct sk_buff *skb, struct net_bridge *br);
Horatiu Vultur65369932020-04-26 15:22:07 +02001834#else
1835static inline int br_mrp_parse(struct net_bridge *br, struct net_bridge_port *p,
1836 struct nlattr *attr, int cmd,
1837 struct netlink_ext_ack *extack)
1838{
1839 return -EOPNOTSUPP;
1840}
1841
Horatiu Vultur65369932020-04-26 15:22:07 +02001842static inline bool br_mrp_enabled(struct net_bridge *br)
1843{
Jason Yan8741e182020-05-06 14:16:16 +08001844 return false;
Horatiu Vultur65369932020-04-26 15:22:07 +02001845}
1846
1847static inline void br_mrp_port_del(struct net_bridge *br,
1848 struct net_bridge_port *p)
1849{
1850}
Horatiu Vulturdf42ef222020-07-02 10:13:06 +02001851
1852static inline int br_mrp_fill_info(struct sk_buff *skb, struct net_bridge *br)
1853{
1854 return 0;
1855}
1856
Horatiu Vultur65369932020-04-26 15:22:07 +02001857#endif
1858
Henrik Bjoernlund2be665c2020-10-27 10:02:48 +00001859/* br_cfm.c */
Henrik Bjoernlund86a14b72020-10-27 10:02:45 +00001860#if IS_ENABLED(CONFIG_BRIDGE_CFM)
Henrik Bjoernlund2be665c2020-10-27 10:02:48 +00001861int br_cfm_parse(struct net_bridge *br, struct net_bridge_port *p,
1862 struct nlattr *attr, int cmd, struct netlink_ext_ack *extack);
1863bool br_cfm_created(struct net_bridge *br);
Henrik Bjoernlund86a14b72020-10-27 10:02:45 +00001864void br_cfm_port_del(struct net_bridge *br, struct net_bridge_port *p);
Henrik Bjoernlund5e312fc2020-10-27 10:02:49 +00001865int br_cfm_config_fill_info(struct sk_buff *skb, struct net_bridge *br);
Henrik Bjoernlundb6d04252020-10-27 10:02:51 +00001866int br_cfm_status_fill_info(struct sk_buff *skb,
1867 struct net_bridge *br,
1868 bool getlink);
1869int br_cfm_mep_count(struct net_bridge *br, u32 *count);
1870int br_cfm_peer_mep_count(struct net_bridge *br, u32 *count);
Henrik Bjoernlund86a14b72020-10-27 10:02:45 +00001871#else
Henrik Bjoernlund2be665c2020-10-27 10:02:48 +00001872static inline int br_cfm_parse(struct net_bridge *br, struct net_bridge_port *p,
1873 struct nlattr *attr, int cmd,
1874 struct netlink_ext_ack *extack)
1875{
1876 return -EOPNOTSUPP;
1877}
1878
1879static inline bool br_cfm_created(struct net_bridge *br)
1880{
1881 return false;
1882}
1883
Henrik Bjoernlund86a14b72020-10-27 10:02:45 +00001884static inline void br_cfm_port_del(struct net_bridge *br,
1885 struct net_bridge_port *p)
1886{
1887}
Henrik Bjoernlund5e312fc2020-10-27 10:02:49 +00001888
1889static inline int br_cfm_config_fill_info(struct sk_buff *skb, struct net_bridge *br)
1890{
1891 return -EOPNOTSUPP;
1892}
Henrik Bjoernlunde77824d2020-10-27 10:02:50 +00001893
Henrik Bjoernlundb6d04252020-10-27 10:02:51 +00001894static inline int br_cfm_status_fill_info(struct sk_buff *skb,
1895 struct net_bridge *br,
1896 bool getlink)
1897{
1898 return -EOPNOTSUPP;
1899}
1900
1901static inline int br_cfm_mep_count(struct net_bridge *br, u32 *count)
1902{
Ivan Vecera829e0502021-10-28 17:58:35 +02001903 *count = 0;
Henrik Bjoernlundb6d04252020-10-27 10:02:51 +00001904 return -EOPNOTSUPP;
1905}
1906
1907static inline int br_cfm_peer_mep_count(struct net_bridge *br, u32 *count)
Henrik Bjoernlunde77824d2020-10-27 10:02:50 +00001908{
Ivan Vecera829e0502021-10-28 17:58:35 +02001909 *count = 0;
Henrik Bjoernlunde77824d2020-10-27 10:02:50 +00001910 return -EOPNOTSUPP;
1911}
Henrik Bjoernlund86a14b72020-10-27 10:02:45 +00001912#endif
1913
Stephen Hemminger11dc1f32006-05-25 16:00:12 -07001914/* br_netlink.c */
stephen hemminger149ddd82012-06-26 05:48:45 +00001915extern struct rtnl_link_ops br_link_ops;
Joe Perches348662a2013-10-18 13:48:22 -07001916int br_netlink_init(void);
1917void br_netlink_fini(void);
Nikolay Aleksandrov92899062017-11-01 12:18:13 +02001918void br_ifinfo_notify(int event, const struct net_bridge *br,
1919 const struct net_bridge_port *port);
Henrik Bjoernlundb6d04252020-10-27 10:02:51 +00001920void br_info_notify(int event, const struct net_bridge *br,
1921 const struct net_bridge_port *port, u32 filter);
Petr Machata2fd527b2018-12-12 17:02:48 +00001922int br_setlink(struct net_device *dev, struct nlmsghdr *nlmsg, u16 flags,
1923 struct netlink_ext_ack *extack);
Roopa Prabhuadd511b2015-01-29 22:40:12 -08001924int br_dellink(struct net_device *dev, struct nlmsghdr *nlmsg, u16 flags);
Joe Perches348662a2013-10-18 13:48:22 -07001925int br_getlink(struct sk_buff *skb, u32 pid, u32 seq, struct net_device *dev,
Nicolas Dichtel46c264d2015-04-28 18:33:49 +02001926 u32 filter_mask, int nlflags);
Nikolay Aleksandrovf26b2962020-01-14 19:56:10 +02001927int br_process_vlan_info(struct net_bridge *br,
1928 struct net_bridge_port *p, int cmd,
1929 struct bridge_vlan_info *vinfo_curr,
1930 struct bridge_vlan_info **vinfo_last,
1931 bool *changed,
1932 struct netlink_ext_ack *extack);
Stephen Hemminger11dc1f32006-05-25 16:00:12 -07001933
Linus Torvalds1da177e2005-04-16 15:20:36 -07001934#ifdef CONFIG_SYSFS
1935/* br_sysfs_if.c */
Emese Revfy52cf25d2010-01-19 02:58:23 +01001936extern const struct sysfs_ops brport_sysfs_ops;
Joe Perches348662a2013-10-18 13:48:22 -07001937int br_sysfs_addif(struct net_bridge_port *p);
1938int br_sysfs_renameif(struct net_bridge_port *p);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001939
1940/* br_sysfs_br.c */
Joe Perches348662a2013-10-18 13:48:22 -07001941int br_sysfs_addbr(struct net_device *dev);
1942void br_sysfs_delbr(struct net_device *dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001943
1944#else
1945
Lee Jones0cb2bbb2012-11-03 23:02:30 +01001946static inline int br_sysfs_addif(struct net_bridge_port *p) { return 0; }
1947static inline int br_sysfs_renameif(struct net_bridge_port *p) { return 0; }
1948static inline int br_sysfs_addbr(struct net_device *dev) { return 0; }
1949static inline void br_sysfs_delbr(struct net_device *dev) { return; }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001950#endif /* CONFIG_SYSFS */
1951
Ido Schimmel6bc506b2016-08-25 18:42:37 +02001952/* br_switchdev.c */
1953#ifdef CONFIG_NET_SWITCHDEV
Vladimir Oltean957e2232021-08-03 23:34:08 +03001954int br_switchdev_port_offload(struct net_bridge_port *p,
1955 struct net_device *dev, const void *ctx,
1956 struct notifier_block *atomic_nb,
1957 struct notifier_block *blocking_nb,
1958 bool tx_fwd_offload,
1959 struct netlink_ext_ack *extack);
1960
1961void br_switchdev_port_unoffload(struct net_bridge_port *p, const void *ctx,
1962 struct notifier_block *atomic_nb,
1963 struct notifier_block *blocking_nb);
1964
Tobias Waldekranz47211192021-07-22 18:55:38 +03001965bool br_switchdev_frame_uses_tx_fwd_offload(struct sk_buff *skb);
1966
Vladimir Olteanc5381152021-07-23 23:49:11 +03001967void br_switchdev_frame_set_offload_fwd_mark(struct sk_buff *skb);
1968
Tobias Waldekranz47211192021-07-22 18:55:38 +03001969void nbp_switchdev_frame_mark_tx_fwd_offload(const struct net_bridge_port *p,
1970 struct sk_buff *skb);
1971void nbp_switchdev_frame_mark_tx_fwd_to_hwdom(const struct net_bridge_port *p,
1972 struct sk_buff *skb);
Ido Schimmel6bc506b2016-08-25 18:42:37 +02001973void nbp_switchdev_frame_mark(const struct net_bridge_port *p,
1974 struct sk_buff *skb);
1975bool nbp_switchdev_allowed_egress(const struct net_bridge_port *p,
1976 const struct sk_buff *skb);
Arkadi Sharshevsky39222852017-06-08 08:44:11 +02001977int br_switchdev_set_port_flag(struct net_bridge_port *p,
1978 unsigned long flags,
Vladimir Oltean078bbb82021-02-12 17:15:53 +02001979 unsigned long mask,
1980 struct netlink_ext_ack *extack);
Tobias Waldekranz6eb38bf2021-06-29 17:06:45 +03001981void br_switchdev_fdb_notify(struct net_bridge *br,
1982 const struct net_bridge_fdb_entry *fdb, int type);
Vladimir Olteanae039352021-10-30 01:36:06 +03001983void br_switchdev_mdb_notify(struct net_device *dev,
1984 struct net_bridge_mdb_entry *mp,
1985 struct net_bridge_port_group *pg,
1986 int type);
Petr Machata169327d2018-12-12 17:02:50 +00001987int br_switchdev_port_vlan_add(struct net_device *dev, u16 vid, u16 flags,
1988 struct netlink_ext_ack *extack);
Petr Machatad66e4342018-05-30 02:56:03 +02001989int br_switchdev_port_vlan_del(struct net_device *dev, u16 vid);
Tobias Waldekranz85826612021-07-21 19:24:00 +03001990void br_switchdev_init(struct net_bridge *br);
Ido Schimmelf1c2edd2017-09-03 17:44:13 +03001991
1992static inline void br_switchdev_frame_unmark(struct sk_buff *skb)
1993{
1994 skb->offload_fwd_mark = 0;
1995}
Ido Schimmel6bc506b2016-08-25 18:42:37 +02001996#else
Vladimir Oltean957e2232021-08-03 23:34:08 +03001997static inline int
1998br_switchdev_port_offload(struct net_bridge_port *p,
1999 struct net_device *dev, const void *ctx,
2000 struct notifier_block *atomic_nb,
2001 struct notifier_block *blocking_nb,
2002 bool tx_fwd_offload,
2003 struct netlink_ext_ack *extack)
2004{
2005 return -EOPNOTSUPP;
2006}
2007
2008static inline void
2009br_switchdev_port_unoffload(struct net_bridge_port *p, const void *ctx,
2010 struct notifier_block *atomic_nb,
2011 struct notifier_block *blocking_nb)
2012{
2013}
2014
Tobias Waldekranz47211192021-07-22 18:55:38 +03002015static inline bool br_switchdev_frame_uses_tx_fwd_offload(struct sk_buff *skb)
2016{
2017 return false;
2018}
2019
Vladimir Olteanc5381152021-07-23 23:49:11 +03002020static inline void br_switchdev_frame_set_offload_fwd_mark(struct sk_buff *skb)
2021{
2022}
2023
Tobias Waldekranz47211192021-07-22 18:55:38 +03002024static inline void
2025nbp_switchdev_frame_mark_tx_fwd_offload(const struct net_bridge_port *p,
2026 struct sk_buff *skb)
2027{
2028}
2029
2030static inline void
2031nbp_switchdev_frame_mark_tx_fwd_to_hwdom(const struct net_bridge_port *p,
2032 struct sk_buff *skb)
2033{
2034}
2035
Ido Schimmel6bc506b2016-08-25 18:42:37 +02002036static inline void nbp_switchdev_frame_mark(const struct net_bridge_port *p,
2037 struct sk_buff *skb)
2038{
2039}
2040
2041static inline bool nbp_switchdev_allowed_egress(const struct net_bridge_port *p,
2042 const struct sk_buff *skb)
2043{
2044 return true;
2045}
Arkadi Sharshevsky39222852017-06-08 08:44:11 +02002046
2047static inline int br_switchdev_set_port_flag(struct net_bridge_port *p,
2048 unsigned long flags,
Vladimir Oltean078bbb82021-02-12 17:15:53 +02002049 unsigned long mask,
2050 struct netlink_ext_ack *extack)
Arkadi Sharshevsky39222852017-06-08 08:44:11 +02002051{
2052 return 0;
2053}
Arkadi Sharshevsky6b26b512017-06-08 08:44:14 +02002054
Petr Machatad66e4342018-05-30 02:56:03 +02002055static inline int br_switchdev_port_vlan_add(struct net_device *dev,
Petr Machata169327d2018-12-12 17:02:50 +00002056 u16 vid, u16 flags,
2057 struct netlink_ext_ack *extack)
Petr Machatad66e4342018-05-30 02:56:03 +02002058{
2059 return -EOPNOTSUPP;
2060}
2061
2062static inline int br_switchdev_port_vlan_del(struct net_device *dev, u16 vid)
2063{
2064 return -EOPNOTSUPP;
2065}
2066
Arkadi Sharshevsky6b26b512017-06-08 08:44:14 +02002067static inline void
Tobias Waldekranz6eb38bf2021-06-29 17:06:45 +03002068br_switchdev_fdb_notify(struct net_bridge *br,
2069 const struct net_bridge_fdb_entry *fdb, int type)
Arkadi Sharshevsky6b26b512017-06-08 08:44:14 +02002070{
2071}
Ido Schimmelf1c2edd2017-09-03 17:44:13 +03002072
Vladimir Olteanae039352021-10-30 01:36:06 +03002073static inline void br_switchdev_mdb_notify(struct net_device *dev,
2074 struct net_bridge_mdb_entry *mp,
2075 struct net_bridge_port_group *pg,
2076 int type)
2077{
2078}
2079
Ido Schimmelf1c2edd2017-09-03 17:44:13 +03002080static inline void br_switchdev_frame_unmark(struct sk_buff *skb)
2081{
2082}
Tobias Waldekranz85826612021-07-21 19:24:00 +03002083
Tobias Waldekranz85826612021-07-21 19:24:00 +03002084static inline void br_switchdev_init(struct net_bridge *br)
2085{
2086}
2087
Ido Schimmel6bc506b2016-08-25 18:42:37 +02002088#endif /* CONFIG_NET_SWITCHDEV */
2089
Roopa Prabhu057658c2017-10-06 22:12:38 -07002090/* br_arp_nd_proxy.c */
Roopa Prabhu821f1b22017-10-06 22:12:37 -07002091void br_recalculate_neigh_suppress_enabled(struct net_bridge *br);
Roopa Prabhu057658c2017-10-06 22:12:38 -07002092void br_do_proxy_suppress_arp(struct sk_buff *skb, struct net_bridge *br,
2093 u16 vid, struct net_bridge_port *p);
Roopa Prabhued842fa2017-10-06 22:12:39 -07002094void br_do_suppress_nd(struct sk_buff *skb, struct net_bridge *br,
2095 u16 vid, struct net_bridge_port *p, struct nd_msg *msg);
2096struct nd_msg *br_is_nd_neigh_msg(struct sk_buff *skb, struct nd_msg *m);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002097#endif