blob: 4ed7f11042e87e14316a755ab17cafbf552df94c [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 Aleksandrovd08c6bc2018-12-05 15:14:27 +020032
Tobias Waldekranz85826612021-07-21 19:24:00 +030033#define BR_HWDOM_MAX BITS_PER_LONG
34
Stephen Hemminger9cde0702007-03-21 14:22:44 -070035#define BR_VERSION "2.3"
36
stephen hemminger515853c2011-10-03 18:14:46 +000037/* Control of forwarding link local multicast */
38#define BR_GROUPFWD_DEFAULT 0
Bernhard Thaler784b58a2015-05-04 22:47:13 +020039/* Don't allow forwarding of control protocols like STP, MAC PAUSE and LACP */
Nikolay Aleksandrov5af48b52017-09-27 16:12:44 +030040enum {
41 BR_GROUPFWD_STP = BIT(0),
42 BR_GROUPFWD_MACPAUSE = BIT(1),
43 BR_GROUPFWD_LACP = BIT(2),
44};
45
46#define BR_GROUPFWD_RESTRICTED (BR_GROUPFWD_STP | BR_GROUPFWD_MACPAUSE | \
47 BR_GROUPFWD_LACP)
Toshiaki Makitaf2808d22014-06-10 20:59:24 +090048/* The Nearest Customer Bridge Group Address, 01-80-C2-00-00-[00,0B,0C,0D,0F] */
49#define BR_GROUPFWD_8021AD 0xB801u
stephen hemminger515853c2011-10-03 18:14:46 +000050
Stephen Hemminger9cde0702007-03-21 14:22:44 -070051/* Path to usermode spanning tree program */
52#define BR_STP_PROG "/sbin/bridge-stp"
Stephen Hemminger8cbb512e2005-12-21 19:01:30 -080053
Nikolay Aleksandrov31cbc39b2020-06-23 23:47:17 +030054#define BR_FDB_NOTIFY_SETTABLE_BITS (FDB_NOTIFY_BIT | FDB_NOTIFY_INACTIVE_BIT)
55
Linus Torvalds1da177e2005-04-16 15:20:36 -070056typedef struct bridge_id bridge_id;
57typedef struct mac_addr mac_addr;
58typedef __u16 port_id;
59
Nikolay Aleksandrov1c1cb6d2018-09-26 17:00:59 +030060struct bridge_id {
Linus Torvalds1da177e2005-04-16 15:20:36 -070061 unsigned char prio[2];
Joe Perchese5a727f2014-02-23 00:05:25 -080062 unsigned char addr[ETH_ALEN];
Linus Torvalds1da177e2005-04-16 15:20:36 -070063};
64
Nikolay Aleksandrov1c1cb6d2018-09-26 17:00:59 +030065struct mac_addr {
Joe Perchese5a727f2014-02-23 00:05:25 -080066 unsigned char addr[ETH_ALEN];
Linus Torvalds1da177e2005-04-16 15:20:36 -070067};
68
Linus Lüssingcc0fdd82013-08-30 17:28:17 +020069#ifdef CONFIG_BRIDGE_IGMP_SNOOPING
70/* our own querier */
Linus Lüssing90010b32014-06-07 18:26:26 +020071struct bridge_mcast_own_query {
Linus Lüssingcc0fdd82013-08-30 17:28:17 +020072 struct timer_list timer;
73 u32 startup_sent;
74};
75
76/* other querier */
Linus Lüssing90010b32014-06-07 18:26:26 +020077struct bridge_mcast_other_query {
Linus Lüssingcc0fdd82013-08-30 17:28:17 +020078 struct timer_list timer;
79 unsigned long delay_time;
80};
Linus Lüssingdc4eb532014-06-07 18:26:27 +020081
82/* selected querier */
83struct bridge_mcast_querier {
84 struct br_ip addr;
Nikolay Aleksandrovbb18ef82021-08-13 17:59:57 +030085 int port_ifidx;
Thomas Gleixnerf936bb42021-09-28 16:10:49 +020086 seqcount_spinlock_t seq;
Linus Lüssingdc4eb532014-06-07 18:26:27 +020087};
Nikolay Aleksandrov1080ab92016-06-28 16:57:06 +020088
89/* IGMP/MLD statistics */
90struct bridge_mcast_stats {
91 struct br_mcast_stats mstats;
92 struct u64_stats_sync syncp;
93};
Linus Lüssingcc0fdd82013-08-30 17:28:17 +020094#endif
95
Nikolay Aleksandrov96322332021-07-19 20:06:23 +030096/* net_bridge_mcast_port must be always defined due to forwarding stubs */
97struct net_bridge_mcast_port {
98#ifdef CONFIG_BRIDGE_IGMP_SNOOPING
99 struct net_bridge_port *port;
Nikolay Aleksandrov613d61d2021-07-19 20:06:26 +0300100 struct net_bridge_vlan *vlan;
Nikolay Aleksandrov96322332021-07-19 20:06:23 +0300101
102 struct bridge_mcast_own_query ip4_own_query;
103 struct timer_list ip4_mc_router_timer;
104 struct hlist_node ip4_rlist;
105#if IS_ENABLED(CONFIG_IPV6)
106 struct bridge_mcast_own_query ip6_own_query;
107 struct timer_list ip6_mc_router_timer;
108 struct hlist_node ip6_rlist;
109#endif /* IS_ENABLED(CONFIG_IPV6) */
110 unsigned char multicast_router;
111#endif /* CONFIG_BRIDGE_IGMP_SNOOPING */
112};
113
Nikolay Aleksandrovd3d065c2021-07-19 20:06:24 +0300114/* net_bridge_mcast must be always defined due to forwarding stubs */
115struct net_bridge_mcast {
116#ifdef CONFIG_BRIDGE_IGMP_SNOOPING
117 struct net_bridge *br;
Nikolay Aleksandrov613d61d2021-07-19 20:06:26 +0300118 struct net_bridge_vlan *vlan;
Nikolay Aleksandrovd3d065c2021-07-19 20:06:24 +0300119
120 u32 multicast_last_member_count;
121 u32 multicast_startup_query_count;
122
Nikolay Aleksandrov4d5b4e82021-08-10 18:29:28 +0300123 u8 multicast_querier;
Nikolay Aleksandrovd3d065c2021-07-19 20:06:24 +0300124 u8 multicast_igmp_version;
125 u8 multicast_router;
126#if IS_ENABLED(CONFIG_IPV6)
127 u8 multicast_mld_version;
128#endif
129 unsigned long multicast_last_member_interval;
130 unsigned long multicast_membership_interval;
131 unsigned long multicast_querier_interval;
132 unsigned long multicast_query_interval;
133 unsigned long multicast_query_response_interval;
134 unsigned long multicast_startup_query_interval;
135 struct hlist_head ip4_mc_router_list;
136 struct timer_list ip4_mc_router_timer;
137 struct bridge_mcast_other_query ip4_other_query;
138 struct bridge_mcast_own_query ip4_own_query;
139 struct bridge_mcast_querier ip4_querier;
140#if IS_ENABLED(CONFIG_IPV6)
141 struct hlist_head ip6_mc_router_list;
142 struct timer_list ip6_mc_router_timer;
143 struct bridge_mcast_other_query ip6_other_query;
144 struct bridge_mcast_own_query ip6_own_query;
145 struct bridge_mcast_querier ip6_querier;
146#endif /* IS_ENABLED(CONFIG_IPV6) */
147#endif /* CONFIG_BRIDGE_IGMP_SNOOPING */
148};
149
Roopa Prabhuefa53562017-01-31 22:59:54 -0800150struct br_tunnel_info {
Nikolay Aleksandrov58e20712021-06-10 15:04:10 +0300151 __be64 tunnel_id;
152 struct metadata_dst __rcu *tunnel_dst;
Roopa Prabhuefa53562017-01-31 22:59:54 -0800153};
154
Nikolay Aleksandrov9d332e69c2018-11-16 18:50:01 +0200155/* private vlan flags */
156enum {
157 BR_VLFLAG_PER_PORT_STATS = BIT(0),
Ido Schimmel27973792019-01-08 16:48:11 +0000158 BR_VLFLAG_ADDED_BY_SWITCHDEV = BIT(1),
Nikolay Aleksandrov7b54aaa2021-07-19 20:06:27 +0300159 BR_VLFLAG_MCAST_ENABLED = BIT(2),
160 BR_VLFLAG_GLOBAL_MCAST_ENABLED = BIT(3),
Nikolay Aleksandrov9d332e69c2018-11-16 18:50:01 +0200161};
162
Nikolay Aleksandrov2594e9062015-09-25 19:00:11 +0200163/**
164 * struct net_bridge_vlan - per-vlan entry
165 *
166 * @vnode: rhashtable member
167 * @vid: VLAN id
168 * @flags: bridge vlan flags
Nikolay Aleksandrov9d332e69c2018-11-16 18:50:01 +0200169 * @priv_flags: private (in-kernel) bridge vlan flags
Nikolay Aleksandrova580c762020-01-24 13:40:22 +0200170 * @state: STP state (e.g. blocking, learning, forwarding)
Nikolay Aleksandrov6dada9b2016-04-30 10:25:28 +0200171 * @stats: per-cpu VLAN statistics
Nikolay Aleksandrov2594e9062015-09-25 19:00:11 +0200172 * @br: if MASTER flag set, this points to a bridge struct
173 * @port: if MASTER flag unset, this points to a port struct
174 * @refcnt: if MASTER flag set, this is bumped for each port referencing it
175 * @brvlan: if MASTER flag unset, this points to the global per-VLAN context
176 * for this VLAN entry
Nikolay Aleksandrov613d61d2021-07-19 20:06:26 +0300177 * @br_mcast_ctx: if MASTER flag set, this is the global vlan multicast context
178 * @port_mcast_ctx: if MASTER flag unset, this is the per-port/vlan multicast
179 * context
Nikolay Aleksandrov2594e9062015-09-25 19:00:11 +0200180 * @vlist: sorted list of VLAN entries
181 * @rcu: used for entry destruction
182 *
183 * This structure is shared between the global per-VLAN entries contained in
184 * the bridge rhashtable and the local per-port per-VLAN entries contained in
185 * the port's rhashtable. The union entries should be interpreted depending on
186 * the entry flags that are set.
187 */
188struct net_bridge_vlan {
189 struct rhash_head vnode;
Roopa Prabhuefa53562017-01-31 22:59:54 -0800190 struct rhash_head tnode;
Nikolay Aleksandrov2594e9062015-09-25 19:00:11 +0200191 u16 vid;
192 u16 flags;
Nikolay Aleksandrov9d332e69c2018-11-16 18:50:01 +0200193 u16 priv_flags;
Nikolay Aleksandrova580c762020-01-24 13:40:22 +0200194 u8 state;
Heiner Kallweit281cc282020-11-17 21:25:42 +0100195 struct pcpu_sw_netstats __percpu *stats;
Vlad Yasevich243a2e62013-02-13 12:00:09 +0000196 union {
Nikolay Aleksandrov2594e9062015-09-25 19:00:11 +0200197 struct net_bridge *br;
198 struct net_bridge_port *port;
199 };
200 union {
Reshetova, Elena25127752017-07-04 15:53:05 +0300201 refcount_t refcnt;
Nikolay Aleksandrov2594e9062015-09-25 19:00:11 +0200202 struct net_bridge_vlan *brvlan;
203 };
Roopa Prabhuefa53562017-01-31 22:59:54 -0800204
205 struct br_tunnel_info tinfo;
206
Nikolay Aleksandrov613d61d2021-07-19 20:06:26 +0300207 union {
208 struct net_bridge_mcast br_mcast_ctx;
209 struct net_bridge_mcast_port port_mcast_ctx;
210 };
211
Nikolay Aleksandrov2594e9062015-09-25 19:00:11 +0200212 struct list_head vlist;
213
Vlad Yasevich243a2e62013-02-13 12:00:09 +0000214 struct rcu_head rcu;
Nikolay Aleksandrov2594e9062015-09-25 19:00:11 +0200215};
216
217/**
218 * struct net_bridge_vlan_group
219 *
220 * @vlan_hash: VLAN entry rhashtable
221 * @vlan_list: sorted VLAN entry list
222 * @num_vlans: number of total VLAN entries
Nikolay Aleksandrov77751ee2015-09-30 20:16:53 +0200223 * @pvid: PVID VLAN id
Nikolay Aleksandrova580c762020-01-24 13:40:22 +0200224 * @pvid_state: PVID's STP state (e.g. forwarding, learning, blocking)
Nikolay Aleksandrov2594e9062015-09-25 19:00:11 +0200225 *
226 * IMPORTANT: Be careful when checking if there're VLAN entries using list
227 * primitives because the bridge can have entries in its list which
228 * are just for global context but not for filtering, i.e. they have
229 * the master flag set but not the brentry flag. If you have to check
230 * if there're "real" entries in the bridge please test @num_vlans
231 */
232struct net_bridge_vlan_group {
233 struct rhashtable vlan_hash;
Roopa Prabhuefa53562017-01-31 22:59:54 -0800234 struct rhashtable tunnel_hash;
Nikolay Aleksandrov2594e9062015-09-25 19:00:11 +0200235 struct list_head vlan_list;
Vlad Yasevich6cbdcee2013-02-13 12:00:13 +0000236 u16 num_vlans;
Nikolay Aleksandrov77751ee2015-09-30 20:16:53 +0200237 u16 pvid;
Nikolay Aleksandrova580c762020-01-24 13:40:22 +0200238 u8 pvid_state;
Vlad Yasevich243a2e62013-02-13 12:00:09 +0000239};
240
Nikolay Aleksandrov6869c3b2019-10-29 13:45:53 +0200241/* bridge fdb flags */
242enum {
243 BR_FDB_LOCAL,
Nikolay Aleksandrov29e63ff2019-10-29 13:45:54 +0200244 BR_FDB_STATIC,
Nikolay Aleksandrove0458d92019-10-29 13:45:55 +0200245 BR_FDB_STICKY,
Nikolay Aleksandrovac3ca6a2019-10-29 13:45:56 +0200246 BR_FDB_ADDED_BY_USER,
Nikolay Aleksandrovb5cd9f72019-10-29 13:45:57 +0200247 BR_FDB_ADDED_BY_EXT_LEARN,
Nikolay Aleksandrovd38c6e32019-10-29 13:45:58 +0200248 BR_FDB_OFFLOADED,
Nikolay Aleksandrov31cbc39b2020-06-23 23:47:17 +0300249 BR_FDB_NOTIFY,
250 BR_FDB_NOTIFY_INACTIVE
Nikolay Aleksandrov6869c3b2019-10-29 13:45:53 +0200251};
252
Nikolay Aleksandroveb793582017-12-12 16:02:50 +0200253struct net_bridge_fdb_key {
254 mac_addr addr;
255 u16 vlan_id;
256};
257
Nikolay Aleksandrov1214628c2017-02-04 18:05:08 +0100258struct net_bridge_fdb_entry {
Nikolay Aleksandroveb793582017-12-12 16:02:50 +0200259 struct rhash_head rhnode;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700260 struct net_bridge_port *dst;
261
Nikolay Aleksandroveb793582017-12-12 16:02:50 +0200262 struct net_bridge_fdb_key key;
263 struct hlist_node fdb_node;
Nikolay Aleksandrov6869c3b2019-10-29 13:45:53 +0200264 unsigned long flags;
Nikolay Aleksandrov1214628c2017-02-04 18:05:08 +0100265
266 /* write-heavy members should not affect lookups */
267 unsigned long updated ____cacheline_aligned_in_smp;
268 unsigned long used;
269
Nikolay Aleksandrovb22fbf22015-08-27 14:19:20 -0700270 struct rcu_head rcu;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700271};
272
Elad Raz9d06b6d2016-02-03 09:57:05 +0100273#define MDB_PG_FLAGS_PERMANENT BIT(0)
274#define MDB_PG_FLAGS_OFFLOAD BIT(1)
Nikolay Aleksandrov3247b272019-07-30 15:20:41 +0300275#define MDB_PG_FLAGS_FAST_LEAVE BIT(2)
Nikolay Aleksandrov8266a042020-09-22 10:30:24 +0300276#define MDB_PG_FLAGS_STAR_EXCL BIT(3)
Nikolay Aleksandrov9116ffb2020-09-22 10:30:25 +0300277#define MDB_PG_FLAGS_BLOCKED BIT(4)
Elad Raz9d06b6d2016-02-03 09:57:05 +0100278
Nikolay Aleksandrov8b671772020-09-07 12:56:07 +0300279#define PG_SRC_ENT_LIMIT 32
280
281#define BR_SGRP_F_DELETE BIT(0)
282#define BR_SGRP_F_SEND BIT(1)
Nikolay Aleksandrovb0812362020-09-22 10:30:23 +0300283#define BR_SGRP_F_INSTALLED BIT(2)
Nikolay Aleksandrov8b671772020-09-07 12:56:07 +0300284
Nikolay Aleksandrove12cec62020-09-07 12:56:19 +0300285struct net_bridge_mcast_gc {
286 struct hlist_node gc_node;
287 void (*destroy)(struct net_bridge_mcast_gc *gc);
288};
289
Nikolay Aleksandrov8b671772020-09-07 12:56:07 +0300290struct net_bridge_group_src {
291 struct hlist_node node;
292
293 struct br_ip addr;
294 struct net_bridge_port_group *pg;
295 u8 flags;
Nikolay Aleksandrov438ef2d2020-09-07 12:56:09 +0300296 u8 src_query_rexmit_cnt;
Nikolay Aleksandrov8b671772020-09-07 12:56:07 +0300297 struct timer_list timer;
298
299 struct net_bridge *br;
Nikolay Aleksandrove12cec62020-09-07 12:56:19 +0300300 struct net_bridge_mcast_gc mcast_gc;
Nikolay Aleksandrov8b671772020-09-07 12:56:07 +0300301 struct rcu_head rcu;
302};
303
Nikolay Aleksandrov085b53c2020-09-22 10:30:22 +0300304struct net_bridge_port_group_sg_key {
Herbert Xueb1d1642010-02-27 19:41:45 +0000305 struct net_bridge_port *port;
YOSHIFUJI Hideaki8ef2a9a2010-04-18 12:42:07 +0900306 struct br_ip addr;
Nikolay Aleksandrov085b53c2020-09-22 10:30:22 +0300307};
308
309struct net_bridge_port_group {
310 struct net_bridge_port_group __rcu *next;
311 struct net_bridge_port_group_sg_key key;
Thomas Martitz206e73232020-06-25 14:26:03 +0200312 unsigned char eth_addr[ETH_ALEN] __aligned(2);
Elad Raz9d06b6d2016-02-03 09:57:05 +0100313 unsigned char flags;
Nikolay Aleksandrov8b671772020-09-07 12:56:07 +0300314 unsigned char filter_mode;
Nikolay Aleksandrov42c11cc2020-09-07 12:56:10 +0300315 unsigned char grp_query_rexmit_cnt;
Nikolay Aleksandrov8f8cb772020-09-22 10:30:21 +0300316 unsigned char rt_protocol;
Nikolay Aleksandrov6ec0d0e2020-09-07 12:56:05 +0300317
Nikolay Aleksandrov8b671772020-09-07 12:56:07 +0300318 struct hlist_head src_list;
319 unsigned int src_ents;
Nikolay Aleksandrov6ec0d0e2020-09-07 12:56:05 +0300320 struct timer_list timer;
Nikolay Aleksandrov42c11cc2020-09-07 12:56:10 +0300321 struct timer_list rexmit_timer;
Nikolay Aleksandrov6ec0d0e2020-09-07 12:56:05 +0300322 struct hlist_node mglist;
Nikolay Aleksandrov8f07b832021-01-20 16:51:54 +0200323 struct rb_root eht_set_tree;
324 struct rb_root eht_host_tree;
Nikolay Aleksandrov6ec0d0e2020-09-07 12:56:05 +0300325
Nikolay Aleksandrov085b53c2020-09-22 10:30:22 +0300326 struct rhash_head rhnode;
Nikolay Aleksandrove12cec62020-09-07 12:56:19 +0300327 struct net_bridge_mcast_gc mcast_gc;
Nikolay Aleksandrov6ec0d0e2020-09-07 12:56:05 +0300328 struct rcu_head rcu;
Herbert Xueb1d1642010-02-27 19:41:45 +0000329};
330
Nikolay Aleksandrov1c1cb6d2018-09-26 17:00:59 +0300331struct net_bridge_mdb_entry {
Nikolay Aleksandrov19e3a9c2018-12-05 15:14:24 +0200332 struct rhash_head rhnode;
Herbert Xueb1d1642010-02-27 19:41:45 +0000333 struct net_bridge *br;
Eric Dumazete8051682010-11-15 06:38:10 +0000334 struct net_bridge_port_group __rcu *ports;
YOSHIFUJI Hideaki8ef2a9a2010-04-18 12:42:07 +0900335 struct br_ip addr;
Andrew Lunnff0fd342017-11-09 23:10:57 +0100336 bool host_joined;
Nikolay Aleksandrov6ec0d0e2020-09-07 12:56:05 +0300337
338 struct timer_list timer;
Nikolay Aleksandrov19e3a9c2018-12-05 15:14:24 +0200339 struct hlist_node mdb_node;
Nikolay Aleksandrov6ec0d0e2020-09-07 12:56:05 +0300340
Nikolay Aleksandrove12cec62020-09-07 12:56:19 +0300341 struct net_bridge_mcast_gc mcast_gc;
Nikolay Aleksandrov6ec0d0e2020-09-07 12:56:05 +0300342 struct rcu_head rcu;
Herbert Xueb1d1642010-02-27 19:41:45 +0000343};
344
Nikolay Aleksandrov1f90c7f2017-02-04 18:05:06 +0100345struct net_bridge_port {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700346 struct net_bridge *br;
347 struct net_device *dev;
348 struct list_head list;
349
Nikolay Aleksandrov1f90c7f2017-02-04 18:05:06 +0100350 unsigned long flags;
351#ifdef CONFIG_BRIDGE_VLAN_FILTERING
352 struct net_bridge_vlan_group __rcu *vlgrp;
353#endif
Nikolay Aleksandrov2756f682018-07-23 11:16:59 +0300354 struct net_bridge_port __rcu *backup_port;
Nikolay Aleksandrov1f90c7f2017-02-04 18:05:06 +0100355
Linus Torvalds1da177e2005-04-16 15:20:36 -0700356 /* STP */
357 u8 priority;
358 u8 state;
359 u16 port_no;
360 unsigned char topology_change_ack;
361 unsigned char config_pending;
362 port_id port_id;
363 port_id designated_port;
364 bridge_id designated_root;
365 bridge_id designated_bridge;
366 u32 path_cost;
367 u32 designated_cost;
stephen hemminger0c031502011-07-22 07:47:06 +0000368 unsigned long designated_age;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700369
370 struct timer_list forward_delay_timer;
371 struct timer_list hold_timer;
372 struct timer_list message_age_timer;
373 struct kobject kobj;
374 struct rcu_head rcu;
Fischer, Anna3982d3d2009-08-13 06:55:16 +0000375
Nikolay Aleksandrov96322332021-07-19 20:06:23 +0300376 struct net_bridge_mcast_port multicast_ctx;
377
Herbert Xueb1d1642010-02-27 19:41:45 +0000378#ifdef CONFIG_BRIDGE_IGMP_SNOOPING
Nikolay Aleksandrov96322332021-07-19 20:06:23 +0300379 struct bridge_mcast_stats __percpu *mcast_stats;
380
Nikolay Aleksandrov89268b02021-01-26 11:35:32 +0200381 u32 multicast_eht_hosts_limit;
382 u32 multicast_eht_hosts_cnt;
Herbert Xueb1d1642010-02-27 19:41:45 +0000383 struct hlist_head mglist;
Herbert Xueb1d1642010-02-27 19:41:45 +0000384#endif
Simon Arlotte0f43752010-05-10 09:31:11 +0000385
386#ifdef CONFIG_SYSFS
387 char sysfs_name[IFNAMSIZ];
388#endif
Herbert Xu91d2c342010-06-10 16:12:50 +0000389
390#ifdef CONFIG_NET_POLL_CONTROLLER
391 struct netpoll *np;
392#endif
Ido Schimmel6bc506b2016-08-25 18:42:37 +0200393#ifdef CONFIG_NET_SWITCHDEV
Tobias Waldekranzf7cf9722021-07-21 19:23:59 +0300394 /* Identifier used to group ports that share the same switchdev
395 * hardware domain.
396 */
397 int hwdom;
Vladimir Oltean2f5dc002021-07-21 19:24:01 +0300398 int offload_count;
399 struct netdev_phys_item_id ppid;
Ido Schimmel6bc506b2016-08-25 18:42:37 +0200400#endif
Nikolay Aleksandrov5af48b52017-09-27 16:12:44 +0300401 u16 group_fwd_mask;
Nikolay Aleksandrov2756f682018-07-23 11:16:59 +0300402 u16 backup_redirected_cnt;
Vivien Didelotde179962019-12-11 20:07:10 -0500403
404 struct bridge_stp_xstats stp_xstats;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700405};
406
Tyler Hicks705e0de2018-07-20 21:56:54 +0000407#define kobj_to_brport(obj) container_of(obj, struct net_bridge_port, kobj)
408
Vlad Yaseviche028e4b2014-05-16 09:59:16 -0400409#define br_auto_port(p) ((p)->flags & BR_AUTO_MASK)
Vlad Yasevichf3a6ddf2014-05-16 09:59:18 -0400410#define br_promisc_port(p) ((p)->flags & BR_PROMISC)
Vlad Yaseviche028e4b2014-05-16 09:59:16 -0400411
stephen hemmingerb5ed54e2010-11-15 06:38:13 +0000412static inline struct net_bridge_port *br_port_get_rcu(const struct net_device *dev)
413{
Hong Zhiguo716ec052013-09-14 22:42:28 +0800414 return rcu_dereference(dev->rx_handler_data);
stephen hemmingerb5ed54e2010-11-15 06:38:13 +0000415}
416
Hong Zhiguo1fb17542013-09-14 22:42:27 +0800417static inline struct net_bridge_port *br_port_get_rtnl(const struct net_device *dev)
stephen hemmingerb5ed54e2010-11-15 06:38:13 +0000418{
Julian Wiedmann35f861e2019-03-29 14:38:19 +0100419 return netif_is_bridge_port(dev) ?
Eric Dumazetec1e5612010-11-15 06:38:14 +0000420 rtnl_dereference(dev->rx_handler_data) : NULL;
stephen hemmingerb5ed54e2010-11-15 06:38:13 +0000421}
422
Arkadi Sharshevsky0baa10f2017-06-08 08:44:12 +0200423static inline struct net_bridge_port *br_port_get_rtnl_rcu(const struct net_device *dev)
424{
Julian Wiedmann35f861e2019-03-29 14:38:19 +0100425 return netif_is_bridge_port(dev) ?
Arkadi Sharshevsky0baa10f2017-06-08 08:44:12 +0200426 rcu_dereference_rtnl(dev->rx_handler_data) : NULL;
427}
428
Nikolay Aleksandrovae757672018-09-26 17:01:00 +0300429enum net_bridge_opts {
430 BROPT_VLAN_ENABLED,
431 BROPT_VLAN_STATS_ENABLED,
Nikolay Aleksandrov8df35102018-09-26 17:01:01 +0300432 BROPT_NF_CALL_IPTABLES,
433 BROPT_NF_CALL_IP6TABLES,
434 BROPT_NF_CALL_ARPTABLES,
Nikolay Aleksandrovbe3664a2018-09-26 17:01:02 +0300435 BROPT_GROUP_ADDR_SET,
Nikolay Aleksandrov13cefad2018-09-26 17:01:03 +0300436 BROPT_MULTICAST_ENABLED,
Nikolay Aleksandrov675779a2018-09-26 17:01:04 +0300437 BROPT_MULTICAST_QUERY_USE_IFADDR,
438 BROPT_MULTICAST_STATS_ENABLED,
439 BROPT_HAS_IPV6_ADDR,
Nikolay Aleksandrovc69c2cd2018-09-26 17:01:05 +0300440 BROPT_NEIGH_SUPPRESS_ENABLED,
Nikolay Aleksandrov3341d912018-09-26 17:01:06 +0300441 BROPT_MTU_SET_BY_USER,
Nikolay Aleksandrov9163a0f2018-10-12 13:41:16 +0300442 BROPT_VLAN_STATS_PER_PORT,
Nikolay Aleksandrov70e42722018-11-24 04:34:21 +0200443 BROPT_NO_LL_LEARN,
Mike Manning9c0ec2e2019-04-18 18:35:33 +0100444 BROPT_VLAN_BRIDGE_BINDING,
Nikolay Aleksandrovf4b70022021-07-19 20:06:28 +0300445 BROPT_MCAST_VLAN_SNOOPING_ENABLED,
Nikolay Aleksandrovae757672018-09-26 17:01:00 +0300446};
447
Nikolay Aleksandrov1f90c7f2017-02-04 18:05:06 +0100448struct net_bridge {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700449 spinlock_t lock;
Nikolay Aleksandrov1f90c7f2017-02-04 18:05:06 +0100450 spinlock_t hash_lock;
Henrik Bjoernlund90c628d2020-10-27 10:02:42 +0000451 struct hlist_head frame_type_list;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700452 struct net_device *dev;
Nikolay Aleksandrovae757672018-09-26 17:01:00 +0300453 unsigned long options;
Nikolay Aleksandrov1f90c7f2017-02-04 18:05:06 +0100454 /* These fields are accessed on each packet */
455#ifdef CONFIG_BRIDGE_VLAN_FILTERING
Nikolay Aleksandrov1f90c7f2017-02-04 18:05:06 +0100456 __be16 vlan_proto;
457 u16 default_pvid;
458 struct net_bridge_vlan_group __rcu *vlgrp;
459#endif
460
Nikolay Aleksandroveb793582017-12-12 16:02:50 +0200461 struct rhashtable fdb_hash_tbl;
Henrik Bjoernlund90c628d2020-10-27 10:02:42 +0000462 struct list_head port_list;
Pablo Neira Ayuso34666d42014-09-18 11:29:03 +0200463#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
Bernhard Thalerefb6de92015-05-30 15:30:16 +0200464 union {
465 struct rtable fake_rtable;
466 struct rt6_info fake_rt6_info;
467 };
Simon Wunderlich4adf0af2008-07-30 16:27:55 -0700468#endif
stephen hemminger515853c2011-10-03 18:14:46 +0000469 u16 group_fwd_mask;
Toshiaki Makitaf2808d22014-06-10 20:59:24 +0900470 u16 group_fwd_mask_required;
stephen hemminger515853c2011-10-03 18:14:46 +0000471
Linus Torvalds1da177e2005-04-16 15:20:36 -0700472 /* STP */
473 bridge_id designated_root;
474 bridge_id bridge_id;
Nikolay Aleksandrov1f90c7f2017-02-04 18:05:06 +0100475 unsigned char topology_change;
476 unsigned char topology_change_detected;
477 u16 root_port;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700478 unsigned long max_age;
479 unsigned long hello_time;
480 unsigned long forward_delay;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700481 unsigned long ageing_time;
Vivien Didelot34d8acd2016-12-10 13:44:29 -0500482 unsigned long bridge_max_age;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700483 unsigned long bridge_hello_time;
484 unsigned long bridge_forward_delay;
Vivien Didelot34d8acd2016-12-10 13:44:29 -0500485 unsigned long bridge_ageing_time;
Nikolay Aleksandrov35750b02018-09-26 17:01:07 +0300486 u32 root_path_cost;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700487
Stephen Hemmingerfda93d92006-03-20 22:59:21 -0800488 u8 group_addr[ETH_ALEN];
Stephen Hemminger9cde0702007-03-21 14:22:44 -0700489
490 enum {
491 BR_NO_STP, /* no spanning tree */
492 BR_KERNEL_STP, /* old STP in kernel */
493 BR_USER_STP, /* new RSTP in userspace */
494 } stp_enabled;
495
Nikolay Aleksandrovd3d065c2021-07-19 20:06:24 +0300496 struct net_bridge_mcast multicast_ctx;
497
Herbert Xueb1d1642010-02-27 19:41:45 +0000498#ifdef CONFIG_BRIDGE_IGMP_SNOOPING
Nikolay Aleksandrovd3d065c2021-07-19 20:06:24 +0300499 struct bridge_mcast_stats __percpu *mcast_stats;
Herbert Xueb1d1642010-02-27 19:41:45 +0000500
Herbert Xueb1d1642010-02-27 19:41:45 +0000501 u32 hash_max;
502
Nikolay Aleksandrov35750b02018-09-26 17:01:07 +0300503 spinlock_t multicast_lock;
Herbert Xueb1d1642010-02-27 19:41:45 +0000504
Nikolay Aleksandrov19e3a9c2018-12-05 15:14:24 +0200505 struct rhashtable mdb_hash_tbl;
Nikolay Aleksandrov085b53c2020-09-22 10:30:22 +0300506 struct rhashtable sg_port_tbl;
Nikolay Aleksandrov19e3a9c2018-12-05 15:14:24 +0200507
Nikolay Aleksandrove12cec62020-09-07 12:56:19 +0300508 struct hlist_head mcast_gc_list;
Nikolay Aleksandrov19e3a9c2018-12-05 15:14:24 +0200509 struct hlist_head mdb_list;
Herbert Xueb1d1642010-02-27 19:41:45 +0000510
Nikolay Aleksandrove12cec62020-09-07 12:56:19 +0300511 struct work_struct mcast_gc_work;
Herbert Xueb1d1642010-02-27 19:41:45 +0000512#endif
513
Linus Torvalds1da177e2005-04-16 15:20:36 -0700514 struct timer_list hello_timer;
515 struct timer_list tcn_timer;
516 struct timer_list topology_change_timer;
Nikolay Aleksandrovf7cdee82017-02-04 18:05:07 +0100517 struct delayed_work gc_work;
Greg Kroah-Hartman43b98c42007-12-17 15:54:39 -0400518 struct kobject *ifobj;
Vlad Yaseviche028e4b2014-05-16 09:59:16 -0400519 u32 auto_cnt;
Ido Schimmel6bc506b2016-08-25 18:42:37 +0200520
521#ifdef CONFIG_NET_SWITCHDEV
Tobias Waldekranzf7cf9722021-07-21 19:23:59 +0300522 /* Counter used to make sure that hardware domains get unique
523 * identifiers in case a bridge spans multiple switchdev instances.
524 */
525 int last_hwdom;
Tobias Waldekranz85826612021-07-21 19:24:00 +0300526 /* Bit mask of hardware domain numbers in use */
527 unsigned long busy_hwdoms;
Ido Schimmel6bc506b2016-08-25 18:42:37 +0200528#endif
Nikolay Aleksandroveb793582017-12-12 16:02:50 +0200529 struct hlist_head fdb_list;
Horatiu Vultur4b8d7d42020-04-26 15:22:00 +0200530
531#if IS_ENABLED(CONFIG_BRIDGE_MRP)
Horatiu Vultur0169b822020-11-06 22:50:49 +0100532 struct hlist_head mrp_list;
Horatiu Vultur4b8d7d42020-04-26 15:22:00 +0200533#endif
Henrik Bjoernlundf323aa52020-10-27 10:02:43 +0000534#if IS_ENABLED(CONFIG_BRIDGE_CFM)
535 struct hlist_head mep_list;
536#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700537};
538
Herbert Xu68b7c892010-02-27 19:41:40 +0000539struct br_input_skb_cb {
540 struct net_device *brdev;
Herbert Xu93fdd472014-10-05 12:00:22 +0800541
Pablo Neira Ayuso3c171f42019-05-29 13:25:37 +0200542 u16 frag_max_size;
YOSHIFUJI Hideaki / 吉藤英明32dec5d2010-03-15 21:51:18 +0000543#ifdef CONFIG_BRIDGE_IGMP_SNOOPING
Florian Westphalf12064d2019-04-11 16:36:40 +0200544 u8 igmp;
545 u8 mrouters_only:1;
YOSHIFUJI Hideaki / 吉藤英明32dec5d2010-03-15 21:51:18 +0000546#endif
Florian Westphalf12064d2019-04-11 16:36:40 +0200547 u8 proxyarp_replied:1;
548 u8 src_port_isolated:1;
Vlad Yasevich20adfa12014-09-12 16:26:16 -0400549#ifdef CONFIG_BRIDGE_VLAN_FILTERING
Florian Westphalf12064d2019-04-11 16:36:40 +0200550 u8 vlan_filtered:1;
Vlad Yasevich20adfa12014-09-12 16:26:16 -0400551#endif
Florian Westphal223fd0a2019-04-11 16:36:42 +0200552#ifdef CONFIG_NETFILTER_FAMILY_BRIDGE
553 u8 br_netfilter_broute:1;
554#endif
Ido Schimmel6bc506b2016-08-25 18:42:37 +0200555
556#ifdef CONFIG_NET_SWITCHDEV
Tobias Waldekranz47211192021-07-22 18:55:38 +0300557 /* Set if TX data plane offloading is used towards at least one
558 * hardware domain.
559 */
560 u8 tx_fwd_offload:1;
Tobias Waldekranzf7cf9722021-07-21 19:23:59 +0300561 /* The switchdev hardware domain from which this packet was received.
562 * If skb->offload_fwd_mark was set, then this packet was already
563 * forwarded by hardware to the other ports in the source hardware
564 * domain, otherwise it wasn't.
565 */
566 int src_hwdom;
Tobias Waldekranz47211192021-07-22 18:55:38 +0300567 /* Bit mask of hardware domains towards this packet has already been
568 * transmitted using the TX data plane offload.
569 */
570 unsigned long fwd_hwdoms;
Ido Schimmel6bc506b2016-08-25 18:42:37 +0200571#endif
Herbert Xu68b7c892010-02-27 19:41:40 +0000572};
573
574#define BR_INPUT_SKB_CB(__skb) ((struct br_input_skb_cb *)(__skb)->cb)
575
YOSHIFUJI Hideaki / 吉藤英明32dec5d2010-03-15 21:51:18 +0000576#ifdef CONFIG_BRIDGE_IGMP_SNOOPING
577# define BR_INPUT_SKB_CB_MROUTERS_ONLY(__skb) (BR_INPUT_SKB_CB(__skb)->mrouters_only)
578#else
579# define BR_INPUT_SKB_CB_MROUTERS_ONLY(__skb) (0)
580#endif
581
stephen hemminger28a16c92010-05-10 09:31:09 +0000582#define br_printk(level, br, format, args...) \
583 printk(level "%s: " format, (br)->dev->name, ##args)
584
585#define br_err(__br, format, args...) \
586 br_printk(KERN_ERR, __br, format, ##args)
587#define br_warn(__br, format, args...) \
588 br_printk(KERN_WARNING, __br, format, ##args)
589#define br_notice(__br, format, args...) \
590 br_printk(KERN_NOTICE, __br, format, ##args)
591#define br_info(__br, format, args...) \
592 br_printk(KERN_INFO, __br, format, ##args)
593
594#define br_debug(br, format, args...) \
595 pr_debug("%s: " format, (br)->dev->name, ##args)
596
Linus Torvalds1da177e2005-04-16 15:20:36 -0700597/* called under bridge lock */
598static inline int br_is_root_bridge(const struct net_bridge *br)
599{
600 return !memcmp(&br->bridge_id, &br->designated_root, 8);
601}
602
Nikolay Aleksandrov2594e9062015-09-25 19:00:11 +0200603/* check if a VLAN entry is global */
604static inline bool br_vlan_is_master(const struct net_bridge_vlan *v)
605{
606 return v->flags & BRIDGE_VLAN_INFO_MASTER;
607}
608
609/* check if a VLAN entry is used by the bridge */
610static inline bool br_vlan_is_brentry(const struct net_bridge_vlan *v)
611{
612 return v->flags & BRIDGE_VLAN_INFO_BRENTRY;
613}
614
Nikolay Aleksandrov6be144f2015-10-02 15:05:13 +0200615/* check if we should use the vlan entry, returns false if it's only context */
Nikolay Aleksandrov2594e9062015-09-25 19:00:11 +0200616static inline bool br_vlan_should_use(const struct net_bridge_vlan *v)
617{
618 if (br_vlan_is_master(v)) {
619 if (br_vlan_is_brentry(v))
620 return true;
621 else
622 return false;
623 }
624
625 return true;
626}
627
Nikolay Aleksandrov5d1fcaf2019-11-04 11:36:51 +0200628static inline bool nbp_state_should_learn(const struct net_bridge_port *p)
629{
630 return p->state == BR_STATE_LEARNING || p->state == BR_STATE_FORWARDING;
631}
632
Nikolay Aleksandrov8f4cc942020-01-14 19:56:08 +0200633static inline bool br_vlan_valid_id(u16 vid, struct netlink_ext_ack *extack)
Nikolay Aleksandrov5a46fac2020-01-14 19:56:07 +0200634{
Nikolay Aleksandrov8f4cc942020-01-14 19:56:08 +0200635 bool ret = vid > 0 && vid < VLAN_VID_MASK;
636
637 if (!ret)
638 NL_SET_ERR_MSG_MOD(extack, "Vlan id is invalid");
639
640 return ret;
Nikolay Aleksandrov5a46fac2020-01-14 19:56:07 +0200641}
642
643static inline bool br_vlan_valid_range(const struct bridge_vlan_info *cur,
Nikolay Aleksandrov8f4cc942020-01-14 19:56:08 +0200644 const struct bridge_vlan_info *last,
645 struct netlink_ext_ack *extack)
Nikolay Aleksandrov5a46fac2020-01-14 19:56:07 +0200646{
647 /* pvid flag is not allowed in ranges */
Nikolay Aleksandrov8f4cc942020-01-14 19:56:08 +0200648 if (cur->flags & BRIDGE_VLAN_INFO_PVID) {
649 NL_SET_ERR_MSG_MOD(extack, "Pvid isn't allowed in a range");
Nikolay Aleksandrov5a46fac2020-01-14 19:56:07 +0200650 return false;
Nikolay Aleksandrov8f4cc942020-01-14 19:56:08 +0200651 }
Nikolay Aleksandrov5a46fac2020-01-14 19:56:07 +0200652
653 /* when cur is the range end, check if:
654 * - it has range start flag
655 * - range ids are invalid (end is equal to or before start)
656 */
657 if (last) {
Nikolay Aleksandrov8f4cc942020-01-14 19:56:08 +0200658 if (cur->flags & BRIDGE_VLAN_INFO_RANGE_BEGIN) {
659 NL_SET_ERR_MSG_MOD(extack, "Found a new vlan range start while processing one");
Nikolay Aleksandrov5a46fac2020-01-14 19:56:07 +0200660 return false;
Nikolay Aleksandrov8f4cc942020-01-14 19:56:08 +0200661 } else if (!(cur->flags & BRIDGE_VLAN_INFO_RANGE_END)) {
662 NL_SET_ERR_MSG_MOD(extack, "Vlan range end flag is missing");
Nikolay Aleksandrov5a46fac2020-01-14 19:56:07 +0200663 return false;
Nikolay Aleksandrov8f4cc942020-01-14 19:56:08 +0200664 } else if (cur->vid <= last->vid) {
665 NL_SET_ERR_MSG_MOD(extack, "End vlan id is less than or equal to start vlan id");
666 return false;
667 }
668 }
669
670 /* check for required range flags */
671 if (!(cur->flags & (BRIDGE_VLAN_INFO_RANGE_BEGIN |
672 BRIDGE_VLAN_INFO_RANGE_END))) {
673 NL_SET_ERR_MSG_MOD(extack, "Both vlan range flags are missing");
674 return false;
Nikolay Aleksandrov5a46fac2020-01-14 19:56:07 +0200675 }
676
677 return true;
678}
679
Nikolay Aleksandrov2796d842021-08-20 15:42:55 +0300680static inline u8 br_vlan_multicast_router(const struct net_bridge_vlan *v)
681{
682 u8 mcast_router = MDB_RTR_TYPE_DISABLED;
683
684#ifdef CONFIG_BRIDGE_IGMP_SNOOPING
685 if (!br_vlan_is_master(v))
686 mcast_router = v->port_mcast_ctx.multicast_router;
687 else
688 mcast_router = v->br_mcast_ctx.multicast_router;
689#endif
690
691 return mcast_router;
692}
693
Nikolay Aleksandrovf5459232020-01-14 19:56:14 +0200694static inline int br_afspec_cmd_to_rtm(int cmd)
695{
696 switch (cmd) {
697 case RTM_SETLINK:
698 return RTM_NEWVLAN;
699 case RTM_DELLINK:
700 return RTM_DELVLAN;
701 }
702
703 return 0;
704}
705
Nikolay Aleksandrovae757672018-09-26 17:01:00 +0300706static inline int br_opt_get(const struct net_bridge *br,
707 enum net_bridge_opts opt)
708{
709 return test_bit(opt, &br->options);
710}
711
Nikolay Aleksandrova428afe2018-11-24 04:34:20 +0200712int br_boolopt_toggle(struct net_bridge *br, enum br_boolopt_id opt, bool on,
713 struct netlink_ext_ack *extack);
714int br_boolopt_get(const struct net_bridge *br, enum br_boolopt_id opt);
715int br_boolopt_multi_toggle(struct net_bridge *br,
716 struct br_boolopt_multi *bm,
717 struct netlink_ext_ack *extack);
718void br_boolopt_multi_get(const struct net_bridge *br,
719 struct br_boolopt_multi *bm);
Nikolay Aleksandrovae757672018-09-26 17:01:00 +0300720void br_opt_toggle(struct net_bridge *br, enum net_bridge_opts opt, bool on);
721
Linus Torvalds1da177e2005-04-16 15:20:36 -0700722/* br_device.c */
Joe Perches348662a2013-10-18 13:48:22 -0700723void br_dev_setup(struct net_device *dev);
724void br_dev_delete(struct net_device *dev, struct list_head *list);
725netdev_tx_t br_dev_xmit(struct sk_buff *skb, struct net_device *dev);
stephen hemmingercfb478d2010-05-10 09:31:08 +0000726#ifdef CONFIG_NET_POLL_CONTROLLER
Herbert Xu91d2c342010-06-10 16:12:50 +0000727static inline void br_netpoll_send_skb(const struct net_bridge_port *p,
728 struct sk_buff *skb)
729{
Eric Dumazetf78ed222020-05-07 09:32:21 -0700730 netpoll_send_skb(p->np, skb);
Herbert Xu91d2c342010-06-10 16:12:50 +0000731}
732
Eric W. Biedermana8779ec2014-03-27 15:36:38 -0700733int br_netpoll_enable(struct net_bridge_port *p);
Joe Perches348662a2013-10-18 13:48:22 -0700734void br_netpoll_disable(struct net_bridge_port *p);
Herbert Xu91d2c342010-06-10 16:12:50 +0000735#else
Herbert Xu9f70b0f2010-06-15 21:43:48 -0700736static inline void br_netpoll_send_skb(const struct net_bridge_port *p,
Herbert Xu91d2c342010-06-10 16:12:50 +0000737 struct sk_buff *skb)
738{
739}
740
Eric W. Biedermana8779ec2014-03-27 15:36:38 -0700741static inline int br_netpoll_enable(struct net_bridge_port *p)
Herbert Xu91d2c342010-06-10 16:12:50 +0000742{
743 return 0;
744}
745
746static inline void br_netpoll_disable(struct net_bridge_port *p)
747{
748}
stephen hemmingercfb478d2010-05-10 09:31:08 +0000749#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700750
751/* br_fdb.c */
Joe Perches348662a2013-10-18 13:48:22 -0700752int br_fdb_init(void);
753void br_fdb_fini(void);
Nikolay Aleksandroveb793582017-12-12 16:02:50 +0200754int br_fdb_hash_init(struct net_bridge *br);
755void br_fdb_hash_fini(struct net_bridge *br);
Joe Perches348662a2013-10-18 13:48:22 -0700756void br_fdb_flush(struct net_bridge *br);
Toshiaki Makita424bb9c2014-02-07 16:48:25 +0900757void br_fdb_find_delete_local(struct net_bridge *br,
758 const struct net_bridge_port *p,
759 const unsigned char *addr, u16 vid);
Joe Perches348662a2013-10-18 13:48:22 -0700760void br_fdb_changeaddr(struct net_bridge_port *p, const unsigned char *newaddr);
761void br_fdb_change_mac_address(struct net_bridge *br, const u8 *newaddr);
Nikolay Aleksandrovf7cdee82017-02-04 18:05:07 +0100762void br_fdb_cleanup(struct work_struct *work);
Joe Perches348662a2013-10-18 13:48:22 -0700763void br_fdb_delete_by_port(struct net_bridge *br,
Nikolay Aleksandrov1ea2d022015-06-23 05:28:16 -0700764 const struct net_bridge_port *p, u16 vid, int do_all);
Nikolay Aleksandrovbfd0aea2017-02-13 14:59:09 +0100765struct net_bridge_fdb_entry *br_fdb_find_rcu(struct net_bridge *br,
766 const unsigned char *addr,
767 __u16 vid);
Joe Perches348662a2013-10-18 13:48:22 -0700768int br_fdb_test_addr(struct net_device *dev, unsigned char *addr);
769int br_fdb_fillbuf(struct net_bridge *br, void *buf, unsigned long count,
770 unsigned long off);
Vladimir Olteanf6814fd2021-10-26 17:27:39 +0300771int br_fdb_add_local(struct net_bridge *br, struct net_bridge_port *source,
772 const unsigned char *addr, u16 vid);
Joe Perches348662a2013-10-18 13:48:22 -0700773void br_fdb_update(struct net_bridge *br, struct net_bridge_port *source,
Nikolay Aleksandrovbe0c5672019-11-01 14:46:37 +0200774 const unsigned char *addr, u16 vid, unsigned long flags);
John Fastabend77162022012-04-15 06:43:56 +0000775
Joe Perches348662a2013-10-18 13:48:22 -0700776int br_fdb_delete(struct ndmsg *ndm, struct nlattr *tb[],
Jiri Pirkof6f64242014-11-28 14:34:15 +0100777 struct net_device *dev, const unsigned char *addr, u16 vid);
Joe Perches348662a2013-10-18 13:48:22 -0700778int br_fdb_add(struct ndmsg *nlh, struct nlattr *tb[], struct net_device *dev,
Petr Machata87b09842019-01-16 23:06:50 +0000779 const unsigned char *addr, u16 vid, u16 nlh_flags,
780 struct netlink_ext_ack *extack);
Joe Perches348662a2013-10-18 13:48:22 -0700781int br_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb,
Roopa Prabhud2976532016-08-30 21:56:45 -0700782 struct net_device *dev, struct net_device *fdev, int *idx);
Roopa Prabhu47674562018-12-15 22:35:09 -0800783int br_fdb_get(struct sk_buff *skb, struct nlattr *tb[], struct net_device *dev,
784 const unsigned char *addr, u16 vid, u32 portid, u32 seq,
785 struct netlink_ext_ack *extack);
Vlad Yasevich8db24af2014-05-16 09:59:17 -0400786int br_fdb_sync_static(struct net_bridge *br, struct net_bridge_port *p);
787void br_fdb_unsync_static(struct net_bridge *br, struct net_bridge_port *p);
Jiri Pirko3aeb6612015-01-15 23:49:37 +0100788int br_fdb_external_learn_add(struct net_bridge *br, struct net_bridge_port *p,
Nikolay Aleksandrov45a68782021-08-10 14:00:10 +0300789 const unsigned char *addr, u16 vid,
Petr Machata161d82d2018-05-03 14:43:53 +0200790 bool swdev_notify);
Jiri Pirko3aeb6612015-01-15 23:49:37 +0100791int br_fdb_external_learn_del(struct net_bridge *br, struct net_bridge_port *p,
Petr Machata161d82d2018-05-03 14:43:53 +0200792 const unsigned char *addr, u16 vid,
793 bool swdev_notify);
Arkadi Sharshevsky9fe8bce2017-06-08 08:44:15 +0200794void br_fdb_offloaded_set(struct net_bridge *br, struct net_bridge_port *p,
Ido Schimmele9ba0fb2018-10-17 08:53:29 +0000795 const unsigned char *addr, u16 vid, bool offloaded);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700796
797/* br_forward.c */
Nikolay Aleksandrov8addd5e2016-08-31 15:36:51 +0200798enum br_pkt_type {
799 BR_PKT_UNICAST,
800 BR_PKT_MULTICAST,
801 BR_PKT_BROADCAST
802};
Eric W. Biederman0c4b51f2015-09-15 20:04:18 -0500803int br_dev_queue_push_xmit(struct net *net, struct sock *sk, struct sk_buff *skb);
Nikolay Aleksandrovb35c5f62016-07-14 06:10:01 +0300804void br_forward(const struct net_bridge_port *to, struct sk_buff *skb,
Nikolay Aleksandrov37b090e2016-07-14 06:10:02 +0300805 bool local_rcv, bool local_orig);
Eric W. Biederman0c4b51f2015-09-15 20:04:18 -0500806int br_forward_finish(struct net *net, struct sock *sk, struct sk_buff *skb);
Nikolay Aleksandrov37b090e2016-07-14 06:10:02 +0300807void br_flood(struct net_bridge *br, struct sk_buff *skb,
Nikolay Aleksandrov8addd5e2016-08-31 15:36:51 +0200808 enum br_pkt_type pkt_type, bool local_rcv, bool local_orig);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700809
Nikolay Aleksandrov7d850ab2018-05-24 11:56:48 +0300810/* return true if both source port and dest port are isolated */
811static inline bool br_skb_isolated(const struct net_bridge_port *to,
812 const struct sk_buff *skb)
813{
814 return BR_INPUT_SKB_CB(skb)->src_port_isolated &&
815 (to->flags & BR_ISOLATED);
816}
817
Linus Torvalds1da177e2005-04-16 15:20:36 -0700818/* br_if.c */
Nikolay Aleksandrovfaa1cd82018-05-03 13:47:24 +0300819void br_port_carrier_check(struct net_bridge_port *p, bool *notified);
Joe Perches348662a2013-10-18 13:48:22 -0700820int br_add_bridge(struct net *net, const char *name);
821int br_del_bridge(struct net *net, const char *name);
David Ahernca752be2017-10-04 17:48:50 -0700822int br_add_if(struct net_bridge *br, struct net_device *dev,
823 struct netlink_ext_ack *extack);
Joe Perches348662a2013-10-18 13:48:22 -0700824int br_del_if(struct net_bridge *br, struct net_device *dev);
Nikolay Aleksandrov804b8542018-03-30 13:46:19 +0300825void br_mtu_auto_adjust(struct net_bridge *br);
Joe Perches348662a2013-10-18 13:48:22 -0700826netdev_features_t br_features_recompute(struct net_bridge *br,
827 netdev_features_t features);
Vlad Yaseviche028e4b2014-05-16 09:59:16 -0400828void br_port_flags_change(struct net_bridge_port *port, unsigned long mask);
Vlad Yasevich2796d0c2014-05-16 09:59:20 -0400829void br_manage_promisc(struct net_bridge *br);
Nikolay Aleksandrov2756f682018-07-23 11:16:59 +0300830int nbp_backup_change(struct net_bridge_port *p, struct net_device *backup_dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700831
832/* br_input.c */
Eric W. Biederman0c4b51f2015-09-15 20:04:18 -0500833int br_handle_frame_finish(struct net *net, struct sock *sk, struct sk_buff *skb);
Vladimir Oltean9eb8eff2020-05-10 19:37:40 +0300834rx_handler_func_t *br_get_rx_handler(const struct net_device *dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700835
Henrik Bjoernlund90c628d2020-10-27 10:02:42 +0000836struct br_frame_type {
837 __be16 type;
838 int (*frame_handler)(struct net_bridge_port *port,
839 struct sk_buff *skb);
840 struct hlist_node list;
841};
842
843void br_add_frame(struct net_bridge *br, struct br_frame_type *ft);
844void br_del_frame(struct net_bridge *br, struct br_frame_type *ft);
845
Jiri Pirko859828c2013-12-05 16:27:37 +0100846static inline bool br_rx_handler_check_rcu(const struct net_device *dev)
847{
Vladimir Oltean9eb8eff2020-05-10 19:37:40 +0300848 return rcu_dereference(dev->rx_handler) == br_get_rx_handler(dev);
Jiri Pirko859828c2013-12-05 16:27:37 +0100849}
850
Petr Machata4d4fd362018-04-29 10:56:08 +0300851static inline bool br_rx_handler_check_rtnl(const struct net_device *dev)
852{
Vladimir Oltean9eb8eff2020-05-10 19:37:40 +0300853 return rcu_dereference_rtnl(dev->rx_handler) == br_get_rx_handler(dev);
Petr Machata4d4fd362018-04-29 10:56:08 +0300854}
855
Jiri Pirko859828c2013-12-05 16:27:37 +0100856static inline struct net_bridge_port *br_port_get_check_rcu(const struct net_device *dev)
857{
858 return br_rx_handler_check_rcu(dev) ? br_port_get_rcu(dev) : NULL;
859}
860
Petr Machata4d4fd362018-04-29 10:56:08 +0300861static inline struct net_bridge_port *
862br_port_get_check_rtnl(const struct net_device *dev)
863{
864 return br_rx_handler_check_rtnl(dev) ? br_port_get_rtnl_rcu(dev) : NULL;
865}
866
Linus Torvalds1da177e2005-04-16 15:20:36 -0700867/* br_ioctl.c */
Arnd Bergmann561d8352021-07-27 15:44:51 +0200868int br_dev_siocdevprivate(struct net_device *dev, struct ifreq *rq,
869 void __user *data, int cmd);
Arnd Bergmannad2f99a2021-07-27 15:45:16 +0200870int br_ioctl_stub(struct net *net, struct net_bridge *br, unsigned int cmd,
871 struct ifreq *ifr, void __user *uarg);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700872
Herbert Xueb1d1642010-02-27 19:41:45 +0000873/* br_multicast.c */
874#ifdef CONFIG_BRIDGE_IGMP_SNOOPING
Nikolay Aleksandrovf4b70022021-07-19 20:06:28 +0300875int br_multicast_rcv(struct net_bridge_mcast **brmctx,
876 struct net_bridge_mcast_port **pmctx,
877 struct net_bridge_vlan *vlan,
David S. Miller394efd12013-11-04 13:48:30 -0500878 struct sk_buff *skb, u16 vid);
Nikolay Aleksandrovadc47032021-07-19 20:06:25 +0300879struct net_bridge_mdb_entry *br_mdb_get(struct net_bridge_mcast *brmctx,
Joe Perches348662a2013-10-18 13:48:22 -0700880 struct sk_buff *skb, u16 vid);
Nikolay Aleksandrov1080ab92016-06-28 16:57:06 +0200881int br_multicast_add_port(struct net_bridge_port *port);
Joe Perches348662a2013-10-18 13:48:22 -0700882void br_multicast_del_port(struct net_bridge_port *port);
883void br_multicast_enable_port(struct net_bridge_port *port);
884void br_multicast_disable_port(struct net_bridge_port *port);
885void br_multicast_init(struct net_bridge *br);
Joseph Huang851d0a72020-12-04 18:56:28 -0500886void br_multicast_join_snoopers(struct net_bridge *br);
887void br_multicast_leave_snoopers(struct net_bridge *br);
Joe Perches348662a2013-10-18 13:48:22 -0700888void br_multicast_open(struct net_bridge *br);
889void br_multicast_stop(struct net_bridge *br);
Satish Ashoke10177a2015-07-15 07:16:51 -0700890void br_multicast_dev_del(struct net_bridge *br);
Nikolay Aleksandrovadc47032021-07-19 20:06:25 +0300891void br_multicast_flood(struct net_bridge_mdb_entry *mdst, struct sk_buff *skb,
892 struct net_bridge_mcast *brmctx,
893 bool local_rcv, bool local_orig);
Nikolay Aleksandrova97df082021-08-10 18:29:31 +0300894int br_multicast_set_router(struct net_bridge_mcast *brmctx, unsigned long val);
Nikolay Aleksandrova53581d2021-08-20 15:42:54 +0300895int br_multicast_set_port_router(struct net_bridge_mcast_port *pmctx,
896 unsigned long val);
Nikolay Aleksandrov2796d842021-08-20 15:42:55 +0300897int br_multicast_set_vlan_router(struct net_bridge_vlan *v, u8 mcast_router);
Florian Fainelliae1ea842021-04-14 22:22:57 +0300898int br_multicast_toggle(struct net_bridge *br, unsigned long val,
899 struct netlink_ext_ack *extack);
Nikolay Aleksandrov62938182021-08-10 18:29:30 +0300900int br_multicast_set_querier(struct net_bridge_mcast *brmctx, unsigned long val);
Joe Perches348662a2013-10-18 13:48:22 -0700901int br_multicast_set_hash_max(struct net_bridge *br, unsigned long val);
Nikolay Aleksandrovdf271cd2021-08-10 18:29:19 +0300902int br_multicast_set_igmp_version(struct net_bridge_mcast *brmctx,
903 unsigned long val);
Nikolay Aleksandrovaa2ae3e2016-11-21 13:03:25 +0100904#if IS_ENABLED(CONFIG_IPV6)
Nikolay Aleksandrovdf271cd2021-08-10 18:29:19 +0300905int br_multicast_set_mld_version(struct net_bridge_mcast *brmctx,
906 unsigned long val);
Nikolay Aleksandrovaa2ae3e2016-11-21 13:03:25 +0100907#endif
Joe Perches348662a2013-10-18 13:48:22 -0700908struct net_bridge_mdb_entry *
Nikolay Aleksandrov19e3a9c2018-12-05 15:14:24 +0200909br_mdb_ip_get(struct net_bridge *br, struct br_ip *dst);
Joe Perches348662a2013-10-18 13:48:22 -0700910struct net_bridge_mdb_entry *
Nikolay Aleksandrov19e3a9c2018-12-05 15:14:24 +0200911br_multicast_new_group(struct net_bridge *br, struct br_ip *group);
Joe Perches348662a2013-10-18 13:48:22 -0700912struct net_bridge_port_group *
913br_multicast_new_port_group(struct net_bridge_port *port, struct br_ip *group,
914 struct net_bridge_port_group __rcu *next,
Nikolay Aleksandrov8b671772020-09-07 12:56:07 +0300915 unsigned char flags, const unsigned char *src,
Nikolay Aleksandrov8f8cb772020-09-22 10:30:21 +0300916 u8 filter_mode, u8 rt_protocol);
Nikolay Aleksandrov19e3a9c2018-12-05 15:14:24 +0200917int br_mdb_hash_init(struct net_bridge *br);
918void br_mdb_hash_fini(struct net_bridge *br);
Nikolay Aleksandrov81f19832020-09-07 12:56:12 +0300919void br_mdb_notify(struct net_device *dev, struct net_bridge_mdb_entry *mp,
920 struct net_bridge_port_group *pg, int type);
Nikolay Aleksandrov1e9ca452021-07-19 20:06:33 +0300921void br_rtr_notify(struct net_device *dev, struct net_bridge_mcast_port *pmctx,
Satish Ashok949f1e32015-07-23 05:00:53 -0700922 int type);
Nikolay Aleksandrov681590b2020-09-07 12:56:06 +0300923void br_multicast_del_pg(struct net_bridge_mdb_entry *mp,
924 struct net_bridge_port_group *pg,
925 struct net_bridge_port_group __rcu **pp);
Nikolay Aleksandrovadc47032021-07-19 20:06:25 +0300926void br_multicast_count(struct net_bridge *br,
927 const struct net_bridge_port *p,
Nikolay Aleksandrova65056e2016-07-06 12:12:21 -0700928 const struct sk_buff *skb, u8 type, u8 dir);
Nikolay Aleksandrov1080ab92016-06-28 16:57:06 +0200929int br_multicast_init_stats(struct net_bridge *br);
Ido Schimmelb6fe0442017-04-10 14:59:27 +0300930void br_multicast_uninit_stats(struct net_bridge *br);
Nikolay Aleksandrov1080ab92016-06-28 16:57:06 +0200931void br_multicast_get_stats(const struct net_bridge *br,
932 const struct net_bridge_port *p,
933 struct br_mcast_stats *dest);
Nikolay Aleksandrov19e3a9c2018-12-05 15:14:24 +0200934void br_mdb_init(void);
935void br_mdb_uninit(void);
Nikolay Aleksandrov58d913a2021-07-21 17:01:27 +0300936void br_multicast_host_join(const struct net_bridge_mcast *brmctx,
937 struct net_bridge_mdb_entry *mp, bool notify);
Nikolay Aleksandrov1bc844e2019-08-17 14:22:13 +0300938void br_multicast_host_leave(struct net_bridge_mdb_entry *mp, bool notify);
Nikolay Aleksandrov8266a042020-09-22 10:30:24 +0300939void br_multicast_star_g_handle_mode(struct net_bridge_port_group *pg,
940 u8 filter_mode);
941void br_multicast_sg_add_exclude_ports(struct net_bridge_mdb_entry *star_mp,
942 struct net_bridge_port_group *sg);
Nikolay Aleksandrov474ddb32021-01-20 16:51:58 +0200943struct net_bridge_group_src *
944br_multicast_find_group_src(struct net_bridge_port_group *pg, struct br_ip *ip);
Nikolay Aleksandrovd5a10222021-01-20 16:52:03 +0200945void br_multicast_del_group_src(struct net_bridge_group_src *src,
946 bool fastleave);
Nikolay Aleksandrov613d61d2021-07-19 20:06:26 +0300947void br_multicast_ctx_init(struct net_bridge *br,
948 struct net_bridge_vlan *vlan,
949 struct net_bridge_mcast *brmctx);
950void br_multicast_ctx_deinit(struct net_bridge_mcast *brmctx);
951void br_multicast_port_ctx_init(struct net_bridge_port *port,
952 struct net_bridge_vlan *vlan,
953 struct net_bridge_mcast_port *pmctx);
954void br_multicast_port_ctx_deinit(struct net_bridge_mcast_port *pmctx);
Nikolay Aleksandrov7b54aaa2021-07-19 20:06:27 +0300955void br_multicast_toggle_one_vlan(struct net_bridge_vlan *vlan, bool on);
Nikolay Aleksandrovf4b70022021-07-19 20:06:28 +0300956int br_multicast_toggle_vlan_snooping(struct net_bridge *br, bool on,
957 struct netlink_ext_ack *extack);
Nikolay Aleksandrov9dee5722021-07-19 20:06:37 +0300958bool br_multicast_toggle_global_vlan(struct net_bridge_vlan *vlan, bool on);
Sridhar Samudrala85b35262010-03-01 09:53:04 +0000959
Nikolay Aleksandrovdc002872021-08-10 18:29:33 +0300960int br_rports_fill_info(struct sk_buff *skb,
961 const struct net_bridge_mcast *brmctx);
Nikolay Aleksandrovc7fa1d92021-08-13 18:00:00 +0300962int br_multicast_dump_querier_state(struct sk_buff *skb,
963 const struct net_bridge_mcast *brmctx,
964 int nest_attr);
965size_t br_multicast_querier_state_size(void);
Nikolay Aleksandrov05d6f382021-08-16 17:57:05 +0300966size_t br_rports_size(const struct net_bridge_mcast *brmctx);
Nikolay Aleksandrov99b40612021-12-27 19:21:15 +0200967void br_multicast_set_query_intvl(struct net_bridge_mcast *brmctx,
968 unsigned long val);
Vladimir Oltean4e51bf42021-07-21 19:24:03 +0300969
Nikolay Aleksandrov955062b2020-10-29 01:38:31 +0200970static inline bool br_group_is_l2(const struct br_ip *group)
971{
972 return group->proto == 0;
973}
974
Cong Wangcfd56752012-12-11 22:23:08 +0000975#define mlock_dereference(X, br) \
976 rcu_dereference_protected(X, lockdep_is_held(&br->multicast_lock))
977
Linus Lüssing44ebb082021-05-13 15:20:44 +0200978static inline struct hlist_node *
Nikolay Aleksandrovadc47032021-07-19 20:06:25 +0300979br_multicast_get_first_rport_node(struct net_bridge_mcast *brmctx,
980 struct sk_buff *skb)
Nikolay Aleksandrovd3d065c2021-07-19 20:06:24 +0300981{
Linus Lüssinga3c02e72021-05-13 15:20:51 +0200982#if IS_ENABLED(CONFIG_IPV6)
983 if (skb->protocol == htons(ETH_P_IPV6))
Nikolay Aleksandrovd3d065c2021-07-19 20:06:24 +0300984 return rcu_dereference(hlist_first_rcu(&brmctx->ip6_mc_router_list));
Linus Lüssinga3c02e72021-05-13 15:20:51 +0200985#endif
Nikolay Aleksandrovd3d065c2021-07-19 20:06:24 +0300986 return rcu_dereference(hlist_first_rcu(&brmctx->ip4_mc_router_list));
Linus Lüssing44ebb082021-05-13 15:20:44 +0200987}
988
989static inline struct net_bridge_port *
Nikolay Aleksandrovd3d065c2021-07-19 20:06:24 +0300990br_multicast_rport_from_node_skb(struct hlist_node *rp, struct sk_buff *skb)
991{
Nikolay Aleksandrov96322332021-07-19 20:06:23 +0300992 struct net_bridge_mcast_port *mctx;
993
Linus Lüssinga3c02e72021-05-13 15:20:51 +0200994#if IS_ENABLED(CONFIG_IPV6)
995 if (skb->protocol == htons(ETH_P_IPV6))
Nikolay Aleksandrov96322332021-07-19 20:06:23 +0300996 mctx = hlist_entry_safe(rp, struct net_bridge_mcast_port,
997 ip6_rlist);
998 else
Linus Lüssinga3c02e72021-05-13 15:20:51 +0200999#endif
Nikolay Aleksandrov96322332021-07-19 20:06:23 +03001000 mctx = hlist_entry_safe(rp, struct net_bridge_mcast_port,
1001 ip4_rlist);
1002
1003 if (mctx)
1004 return mctx->port;
1005 else
1006 return NULL;
Linus Lüssing44ebb082021-05-13 15:20:44 +02001007}
1008
Nikolay Aleksandrovd3d065c2021-07-19 20:06:24 +03001009static inline bool br_ip4_multicast_is_router(struct net_bridge_mcast *brmctx)
Sridhar Samudrala85b35262010-03-01 09:53:04 +00001010{
Nikolay Aleksandrovd3d065c2021-07-19 20:06:24 +03001011 return timer_pending(&brmctx->ip4_mc_router_timer);
Linus Lüssing1a3065a2021-05-13 15:20:47 +02001012}
1013
Nikolay Aleksandrovd3d065c2021-07-19 20:06:24 +03001014static inline bool br_ip6_multicast_is_router(struct net_bridge_mcast *brmctx)
Linus Lüssing1a3065a2021-05-13 15:20:47 +02001015{
1016#if IS_ENABLED(CONFIG_IPV6)
Nikolay Aleksandrovd3d065c2021-07-19 20:06:24 +03001017 return timer_pending(&brmctx->ip6_mc_router_timer);
Linus Lüssing1a3065a2021-05-13 15:20:47 +02001018#else
1019 return false;
1020#endif
1021}
1022
1023static inline bool
Nikolay Aleksandrovadc47032021-07-19 20:06:25 +03001024br_multicast_is_router(struct net_bridge_mcast *brmctx, struct sk_buff *skb)
Linus Lüssing1a3065a2021-05-13 15:20:47 +02001025{
Nikolay Aleksandrovd3d065c2021-07-19 20:06:24 +03001026 switch (brmctx->multicast_router) {
Linus Lüssing1a3065a2021-05-13 15:20:47 +02001027 case MDB_RTR_TYPE_PERM:
1028 return true;
1029 case MDB_RTR_TYPE_TEMP_QUERY:
1030 if (skb) {
1031 if (skb->protocol == htons(ETH_P_IP))
Nikolay Aleksandrovd3d065c2021-07-19 20:06:24 +03001032 return br_ip4_multicast_is_router(brmctx);
Linus Lüssing1a3065a2021-05-13 15:20:47 +02001033 else if (skb->protocol == htons(ETH_P_IPV6))
Nikolay Aleksandrovd3d065c2021-07-19 20:06:24 +03001034 return br_ip6_multicast_is_router(brmctx);
Linus Lüssing1a3065a2021-05-13 15:20:47 +02001035 } else {
Nikolay Aleksandrovd3d065c2021-07-19 20:06:24 +03001036 return br_ip4_multicast_is_router(brmctx) ||
1037 br_ip6_multicast_is_router(brmctx);
Linus Lüssing1a3065a2021-05-13 15:20:47 +02001038 }
1039 fallthrough;
1040 default:
1041 return false;
1042 }
Sridhar Samudrala85b35262010-03-01 09:53:04 +00001043}
Linus Lüssingb00589a2013-08-01 01:06:20 +02001044
Linus Lüssingcc0fdd82013-08-30 17:28:17 +02001045static inline bool
Nikolay Aleksandrovadc47032021-07-19 20:06:25 +03001046__br_multicast_querier_exists(struct net_bridge_mcast *brmctx,
1047 struct bridge_mcast_other_query *querier,
1048 const bool is_ipv6)
Linus Lüssingb00589a2013-08-01 01:06:20 +02001049{
daniel0888d5f2016-06-24 12:35:18 +02001050 bool own_querier_enabled;
1051
Nikolay Aleksandrov62938182021-08-10 18:29:30 +03001052 if (brmctx->multicast_querier) {
Nikolay Aleksandrovadc47032021-07-19 20:06:25 +03001053 if (is_ipv6 && !br_opt_get(brmctx->br, BROPT_HAS_IPV6_ADDR))
daniel0888d5f2016-06-24 12:35:18 +02001054 own_querier_enabled = false;
1055 else
1056 own_querier_enabled = true;
1057 } else {
1058 own_querier_enabled = false;
1059 }
1060
Linus Lüssingcc0fdd82013-08-30 17:28:17 +02001061 return time_is_before_jiffies(querier->delay_time) &&
daniel0888d5f2016-06-24 12:35:18 +02001062 (own_querier_enabled || timer_pending(&querier->timer));
Linus Lüssingcc0fdd82013-08-30 17:28:17 +02001063}
1064
Nikolay Aleksandrovadc47032021-07-19 20:06:25 +03001065static inline bool br_multicast_querier_exists(struct net_bridge_mcast *brmctx,
Nikolay Aleksandrov955062b2020-10-29 01:38:31 +02001066 struct ethhdr *eth,
1067 const struct net_bridge_mdb_entry *mdb)
Linus Lüssingcc0fdd82013-08-30 17:28:17 +02001068{
1069 switch (eth->h_proto) {
1070 case (htons(ETH_P_IP)):
Nikolay Aleksandrovadc47032021-07-19 20:06:25 +03001071 return __br_multicast_querier_exists(brmctx,
1072 &brmctx->ip4_other_query, false);
Linus Lüssingcc0fdd82013-08-30 17:28:17 +02001073#if IS_ENABLED(CONFIG_IPV6)
1074 case (htons(ETH_P_IPV6)):
Nikolay Aleksandrovadc47032021-07-19 20:06:25 +03001075 return __br_multicast_querier_exists(brmctx,
1076 &brmctx->ip6_other_query, true);
Linus Lüssingcc0fdd82013-08-30 17:28:17 +02001077#endif
1078 default:
Nikolay Aleksandrov955062b2020-10-29 01:38:31 +02001079 return !!mdb && br_group_is_l2(&mdb->addr);
Linus Lüssingcc0fdd82013-08-30 17:28:17 +02001080 }
Linus Lüssingb00589a2013-08-01 01:06:20 +02001081}
Nikolay Aleksandrov1080ab92016-06-28 16:57:06 +02001082
Nikolay Aleksandrov88d4bd12020-09-22 10:30:19 +03001083static inline bool br_multicast_is_star_g(const struct br_ip *ip)
1084{
1085 switch (ip->proto) {
1086 case htons(ETH_P_IP):
1087 return ipv4_is_zeronet(ip->src.ip4);
1088#if IS_ENABLED(CONFIG_IPV6)
1089 case htons(ETH_P_IPV6):
1090 return ipv6_addr_any(&ip->src.ip6);
1091#endif
1092 default:
1093 return false;
1094 }
1095}
1096
Nikolay Aleksandrovadc47032021-07-19 20:06:25 +03001097static inline bool
1098br_multicast_should_handle_mode(const struct net_bridge_mcast *brmctx,
1099 __be16 proto)
Nikolay Aleksandrov8266a042020-09-22 10:30:24 +03001100{
1101 switch (proto) {
1102 case htons(ETH_P_IP):
Nikolay Aleksandrovadc47032021-07-19 20:06:25 +03001103 return !!(brmctx->multicast_igmp_version == 3);
Nikolay Aleksandrov8266a042020-09-22 10:30:24 +03001104#if IS_ENABLED(CONFIG_IPV6)
1105 case htons(ETH_P_IPV6):
Nikolay Aleksandrovadc47032021-07-19 20:06:25 +03001106 return !!(brmctx->multicast_mld_version == 2);
Nikolay Aleksandrov8266a042020-09-22 10:30:24 +03001107#endif
1108 default:
1109 return false;
1110 }
1111}
1112
Nikolay Aleksandrov1080ab92016-06-28 16:57:06 +02001113static inline int br_multicast_igmp_type(const struct sk_buff *skb)
1114{
1115 return BR_INPUT_SKB_CB(skb)->igmp;
1116}
Nikolay Aleksandrov42c11cc2020-09-07 12:56:10 +03001117
Nikolay Aleksandrovadc47032021-07-19 20:06:25 +03001118static inline unsigned long br_multicast_lmqt(const struct net_bridge_mcast *brmctx)
Nikolay Aleksandrov42c11cc2020-09-07 12:56:10 +03001119{
Nikolay Aleksandrovadc47032021-07-19 20:06:25 +03001120 return brmctx->multicast_last_member_interval *
1121 brmctx->multicast_last_member_count;
Nikolay Aleksandrov42c11cc2020-09-07 12:56:10 +03001122}
Nikolay Aleksandrov04368622020-09-07 12:56:14 +03001123
Nikolay Aleksandrovadc47032021-07-19 20:06:25 +03001124static inline unsigned long br_multicast_gmi(const struct net_bridge_mcast *brmctx)
Nikolay Aleksandrov04368622020-09-07 12:56:14 +03001125{
Nikolay Aleksandrovfac3cb82021-10-15 12:05:46 +03001126 return brmctx->multicast_membership_interval;
Nikolay Aleksandrov04368622020-09-07 12:56:14 +03001127}
Nikolay Aleksandrov7b54aaa2021-07-19 20:06:27 +03001128
1129static inline bool
1130br_multicast_ctx_is_vlan(const struct net_bridge_mcast *brmctx)
1131{
1132 return !!brmctx->vlan;
1133}
1134
1135static inline bool
1136br_multicast_port_ctx_is_vlan(const struct net_bridge_mcast_port *pmctx)
1137{
1138 return !!pmctx->vlan;
1139}
1140
1141static inline struct net_bridge_mcast *
1142br_multicast_port_ctx_get_global(const struct net_bridge_mcast_port *pmctx)
1143{
1144 if (!br_multicast_port_ctx_is_vlan(pmctx))
1145 return &pmctx->port->br->multicast_ctx;
1146 else
1147 return &pmctx->vlan->brvlan->br_mcast_ctx;
1148}
1149
1150static inline bool
1151br_multicast_ctx_vlan_global_disabled(const struct net_bridge_mcast *brmctx)
1152{
Nikolay Aleksandrovf4b70022021-07-19 20:06:28 +03001153 return br_opt_get(brmctx->br, BROPT_MCAST_VLAN_SNOOPING_ENABLED) &&
1154 br_multicast_ctx_is_vlan(brmctx) &&
Nikolay Aleksandrov7b54aaa2021-07-19 20:06:27 +03001155 !(brmctx->vlan->priv_flags & BR_VLFLAG_GLOBAL_MCAST_ENABLED);
1156}
1157
1158static inline bool
1159br_multicast_ctx_vlan_disabled(const struct net_bridge_mcast *brmctx)
1160{
1161 return br_multicast_ctx_is_vlan(brmctx) &&
1162 !(brmctx->vlan->priv_flags & BR_VLFLAG_MCAST_ENABLED);
1163}
1164
1165static inline bool
1166br_multicast_port_ctx_vlan_disabled(const struct net_bridge_mcast_port *pmctx)
1167{
1168 return br_multicast_port_ctx_is_vlan(pmctx) &&
1169 !(pmctx->vlan->priv_flags & BR_VLFLAG_MCAST_ENABLED);
1170}
Nikolay Aleksandrov4cdd0d12021-07-19 20:06:31 +03001171
1172static inline bool
1173br_multicast_port_ctx_state_disabled(const struct net_bridge_mcast_port *pmctx)
1174{
1175 return pmctx->port->state == BR_STATE_DISABLED ||
1176 (br_multicast_port_ctx_is_vlan(pmctx) &&
1177 (br_multicast_port_ctx_vlan_disabled(pmctx) ||
1178 pmctx->vlan->state == BR_STATE_DISABLED));
1179}
1180
1181static inline bool
1182br_multicast_port_ctx_state_stopped(const struct net_bridge_mcast_port *pmctx)
1183{
1184 return br_multicast_port_ctx_state_disabled(pmctx) ||
1185 pmctx->port->state == BR_STATE_BLOCKING ||
1186 (br_multicast_port_ctx_is_vlan(pmctx) &&
1187 pmctx->vlan->state == BR_STATE_BLOCKING);
1188}
Nikolay Aleksandrovdf271cd2021-08-10 18:29:19 +03001189
1190static inline bool
Nikolay Aleksandrovdc002872021-08-10 18:29:33 +03001191br_rports_have_mc_router(const struct net_bridge_mcast *brmctx)
1192{
1193#if IS_ENABLED(CONFIG_IPV6)
1194 return !hlist_empty(&brmctx->ip4_mc_router_list) ||
1195 !hlist_empty(&brmctx->ip6_mc_router_list);
1196#else
1197 return !hlist_empty(&brmctx->ip4_mc_router_list);
1198#endif
1199}
1200
1201static inline bool
Nikolay Aleksandrovdf271cd2021-08-10 18:29:19 +03001202br_multicast_ctx_options_equal(const struct net_bridge_mcast *brmctx1,
1203 const struct net_bridge_mcast *brmctx2)
1204{
1205 return brmctx1->multicast_igmp_version ==
1206 brmctx2->multicast_igmp_version &&
Nikolay Aleksandrov931ba872021-08-10 18:29:20 +03001207 brmctx1->multicast_last_member_count ==
1208 brmctx2->multicast_last_member_count &&
Nikolay Aleksandrov50725f62021-08-10 18:29:21 +03001209 brmctx1->multicast_startup_query_count ==
1210 brmctx2->multicast_startup_query_count &&
Nikolay Aleksandrov77f6aba2021-08-10 18:29:22 +03001211 brmctx1->multicast_last_member_interval ==
1212 brmctx2->multicast_last_member_interval &&
Nikolay Aleksandrov2da0aea2021-08-10 18:29:23 +03001213 brmctx1->multicast_membership_interval ==
1214 brmctx2->multicast_membership_interval &&
Nikolay Aleksandrovcd9269d2021-08-10 18:29:24 +03001215 brmctx1->multicast_querier_interval ==
1216 brmctx2->multicast_querier_interval &&
Nikolay Aleksandrovd6c08ab2021-08-10 18:29:25 +03001217 brmctx1->multicast_query_interval ==
1218 brmctx2->multicast_query_interval &&
Nikolay Aleksandrov42521452021-08-10 18:29:26 +03001219 brmctx1->multicast_query_response_interval ==
1220 brmctx2->multicast_query_response_interval &&
Nikolay Aleksandrov941121e2021-08-10 18:29:27 +03001221 brmctx1->multicast_startup_query_interval ==
1222 brmctx2->multicast_startup_query_interval &&
Nikolay Aleksandrov62938182021-08-10 18:29:30 +03001223 brmctx1->multicast_querier == brmctx2->multicast_querier &&
Nikolay Aleksandrova97df082021-08-10 18:29:31 +03001224 brmctx1->multicast_router == brmctx2->multicast_router &&
Nikolay Aleksandrovdc002872021-08-10 18:29:33 +03001225 !br_rports_have_mc_router(brmctx1) &&
1226 !br_rports_have_mc_router(brmctx2) &&
Nikolay Aleksandrovdf271cd2021-08-10 18:29:19 +03001227#if IS_ENABLED(CONFIG_IPV6)
1228 brmctx1->multicast_mld_version ==
1229 brmctx2->multicast_mld_version &&
1230#endif
1231 true;
1232}
Nikolay Aleksandrovcb486ce2021-08-10 18:29:29 +03001233
1234static inline bool
1235br_multicast_ctx_matches_vlan_snooping(const struct net_bridge_mcast *brmctx)
1236{
1237 bool vlan_snooping_enabled;
1238
1239 vlan_snooping_enabled = !!br_opt_get(brmctx->br,
1240 BROPT_MCAST_VLAN_SNOOPING_ENABLED);
1241
1242 return !!(vlan_snooping_enabled == br_multicast_ctx_is_vlan(brmctx));
1243}
Herbert Xueb1d1642010-02-27 19:41:45 +00001244#else
Nikolay Aleksandrovf4b70022021-07-19 20:06:28 +03001245static inline int br_multicast_rcv(struct net_bridge_mcast **brmctx,
1246 struct net_bridge_mcast_port **pmctx,
1247 struct net_bridge_vlan *vlan,
Vlad Yasevich06499092013-10-28 15:45:07 -04001248 struct sk_buff *skb,
1249 u16 vid)
Herbert Xueb1d1642010-02-27 19:41:45 +00001250{
1251 return 0;
1252}
1253
Nikolay Aleksandrovadc47032021-07-19 20:06:25 +03001254static inline struct net_bridge_mdb_entry *br_mdb_get(struct net_bridge_mcast *brmctx,
Cong Wangfbca58a2013-03-07 03:05:33 +00001255 struct sk_buff *skb, u16 vid)
Herbert Xueb1d1642010-02-27 19:41:45 +00001256{
1257 return NULL;
1258}
1259
Nikolay Aleksandrov1080ab92016-06-28 16:57:06 +02001260static inline int br_multicast_add_port(struct net_bridge_port *port)
Herbert Xueb1d1642010-02-27 19:41:45 +00001261{
Nikolay Aleksandrov1080ab92016-06-28 16:57:06 +02001262 return 0;
Herbert Xueb1d1642010-02-27 19:41:45 +00001263}
1264
1265static inline void br_multicast_del_port(struct net_bridge_port *port)
1266{
1267}
1268
1269static inline void br_multicast_enable_port(struct net_bridge_port *port)
1270{
1271}
1272
1273static inline void br_multicast_disable_port(struct net_bridge_port *port)
1274{
1275}
1276
1277static inline void br_multicast_init(struct net_bridge *br)
1278{
1279}
1280
Joseph Huang851d0a72020-12-04 18:56:28 -05001281static inline void br_multicast_join_snoopers(struct net_bridge *br)
1282{
1283}
1284
1285static inline void br_multicast_leave_snoopers(struct net_bridge *br)
1286{
1287}
1288
Herbert Xueb1d1642010-02-27 19:41:45 +00001289static inline void br_multicast_open(struct net_bridge *br)
1290{
1291}
1292
1293static inline void br_multicast_stop(struct net_bridge *br)
1294{
1295}
Herbert Xu5cb5e942010-02-27 19:41:46 +00001296
Nikolay Aleksandrova7ce45a2015-07-20 23:03:45 +02001297static inline void br_multicast_dev_del(struct net_bridge *br)
1298{
1299}
1300
Nikolay Aleksandrov37b090e2016-07-14 06:10:02 +03001301static inline void br_multicast_flood(struct net_bridge_mdb_entry *mdst,
1302 struct sk_buff *skb,
Nikolay Aleksandrovadc47032021-07-19 20:06:25 +03001303 struct net_bridge_mcast *brmctx,
Nikolay Aleksandrov37b090e2016-07-14 06:10:02 +03001304 bool local_rcv, bool local_orig)
Herbert Xu5cb5e942010-02-27 19:41:46 +00001305{
1306}
1307
Nikolay Aleksandrovadc47032021-07-19 20:06:25 +03001308static inline bool br_multicast_is_router(struct net_bridge_mcast *brmctx,
Nikolay Aleksandrovbbc6f2c2021-05-14 10:32:33 +03001309 struct sk_buff *skb)
Herbert Xueb1d1642010-02-27 19:41:45 +00001310{
Gustavo A. R. Silva03aaa9e2018-01-18 17:37:45 -06001311 return false;
Herbert Xueb1d1642010-02-27 19:41:45 +00001312}
Nikolay Aleksandrov37b090e2016-07-14 06:10:02 +03001313
Nikolay Aleksandrovadc47032021-07-19 20:06:25 +03001314static inline bool br_multicast_querier_exists(struct net_bridge_mcast *brmctx,
Vladimir Olteanc43fd362020-11-01 02:08:45 +02001315 struct ethhdr *eth,
1316 const struct net_bridge_mdb_entry *mdb)
Linus Lüssingb00589a2013-08-01 01:06:20 +02001317{
1318 return false;
1319}
Nikolay Aleksandrov37b090e2016-07-14 06:10:02 +03001320
Rami Rosenfdb184d2013-01-03 13:30:43 +02001321static inline void br_mdb_init(void)
1322{
1323}
Nikolay Aleksandrov37b090e2016-07-14 06:10:02 +03001324
Rami Rosenfdb184d2013-01-03 13:30:43 +02001325static inline void br_mdb_uninit(void)
1326{
1327}
Nikolay Aleksandrov1080ab92016-06-28 16:57:06 +02001328
Nikolay Aleksandrov19e3a9c2018-12-05 15:14:24 +02001329static inline int br_mdb_hash_init(struct net_bridge *br)
1330{
1331 return 0;
1332}
1333
1334static inline void br_mdb_hash_fini(struct net_bridge *br)
1335{
1336}
1337
Nikolay Aleksandrov1080ab92016-06-28 16:57:06 +02001338static inline void br_multicast_count(struct net_bridge *br,
1339 const struct net_bridge_port *p,
Nikolay Aleksandrova65056e2016-07-06 12:12:21 -07001340 const struct sk_buff *skb,
1341 u8 type, u8 dir)
Nikolay Aleksandrov1080ab92016-06-28 16:57:06 +02001342{
1343}
1344
1345static inline int br_multicast_init_stats(struct net_bridge *br)
1346{
1347 return 0;
1348}
1349
Ido Schimmelb6fe0442017-04-10 14:59:27 +03001350static inline void br_multicast_uninit_stats(struct net_bridge *br)
1351{
1352}
1353
Nikolay Aleksandrov1080ab92016-06-28 16:57:06 +02001354static inline int br_multicast_igmp_type(const struct sk_buff *skb)
1355{
1356 return 0;
1357}
Nikolay Aleksandrov613d61d2021-07-19 20:06:26 +03001358
1359static inline void br_multicast_ctx_init(struct net_bridge *br,
1360 struct net_bridge_vlan *vlan,
1361 struct net_bridge_mcast *brmctx)
1362{
1363}
1364
1365static inline void br_multicast_ctx_deinit(struct net_bridge_mcast *brmctx)
1366{
1367}
1368
1369static inline void br_multicast_port_ctx_init(struct net_bridge_port *port,
1370 struct net_bridge_vlan *vlan,
1371 struct net_bridge_mcast_port *pmctx)
1372{
1373}
1374
1375static inline void br_multicast_port_ctx_deinit(struct net_bridge_mcast_port *pmctx)
1376{
1377}
Nikolay Aleksandrov7b54aaa2021-07-19 20:06:27 +03001378
1379static inline void br_multicast_toggle_one_vlan(struct net_bridge_vlan *vlan,
1380 bool on)
1381{
1382}
Nikolay Aleksandrovf4b70022021-07-19 20:06:28 +03001383
Nikolay Aleksandrovf4b70022021-07-19 20:06:28 +03001384static inline int br_multicast_toggle_vlan_snooping(struct net_bridge *br,
1385 bool on,
1386 struct netlink_ext_ack *extack)
1387{
1388 return -EOPNOTSUPP;
1389}
Nikolay Aleksandrov9dee5722021-07-19 20:06:37 +03001390
1391static inline bool br_multicast_toggle_global_vlan(struct net_bridge_vlan *vlan,
1392 bool on)
1393{
1394 return false;
1395}
Vladimir Oltean4e51bf42021-07-21 19:24:03 +03001396
Nikolay Aleksandrovdf271cd2021-08-10 18:29:19 +03001397static inline bool
1398br_multicast_ctx_options_equal(const struct net_bridge_mcast *brmctx1,
1399 const struct net_bridge_mcast *brmctx2)
1400{
1401 return true;
1402}
Sridhar Samudrala85b35262010-03-01 09:53:04 +00001403#endif
Herbert Xueb1d1642010-02-27 19:41:45 +00001404
Vlad Yasevich243a2e62013-02-13 12:00:09 +00001405/* br_vlan.c */
1406#ifdef CONFIG_BRIDGE_VLAN_FILTERING
Nikolay Aleksandrov77751ee2015-09-30 20:16:53 +02001407bool br_allowed_ingress(const struct net_bridge *br,
1408 struct net_bridge_vlan_group *vg, struct sk_buff *skb,
Nikolay Aleksandrovf4b70022021-07-19 20:06:28 +03001409 u16 *vid, u8 *state,
1410 struct net_bridge_vlan **vlan);
Nikolay Aleksandrov77751ee2015-09-30 20:16:53 +02001411bool br_allowed_egress(struct net_bridge_vlan_group *vg,
Joe Perches348662a2013-10-18 13:48:22 -07001412 const struct sk_buff *skb);
Toshiaki Makitae0d79682014-05-26 15:15:53 +09001413bool br_should_learn(struct net_bridge_port *p, struct sk_buff *skb, u16 *vid);
Joe Perches348662a2013-10-18 13:48:22 -07001414struct sk_buff *br_handle_vlan(struct net_bridge *br,
Roopa Prabhu11538d02017-01-31 22:59:55 -08001415 const struct net_bridge_port *port,
Nikolay Aleksandrov2594e9062015-09-25 19:00:11 +02001416 struct net_bridge_vlan_group *vg,
Joe Perches348662a2013-10-18 13:48:22 -07001417 struct sk_buff *skb);
Nikolay Aleksandrovf418af62017-10-27 13:19:37 +03001418int br_vlan_add(struct net_bridge *br, u16 vid, u16 flags,
Petr Machata169327d2018-12-12 17:02:50 +00001419 bool *changed, struct netlink_ext_ack *extack);
Joe Perches348662a2013-10-18 13:48:22 -07001420int br_vlan_delete(struct net_bridge *br, u16 vid);
1421void br_vlan_flush(struct net_bridge *br);
Nikolay Aleksandrov2594e9062015-09-25 19:00:11 +02001422struct net_bridge_vlan *br_vlan_find(struct net_bridge_vlan_group *vg, u16 vid);
Toshiaki Makita204177f2014-06-10 20:59:25 +09001423void br_recalculate_fwd_mask(struct net_bridge *br);
Vladimir Oltean9e781402021-02-13 22:43:16 +02001424int br_vlan_filter_toggle(struct net_bridge *br, unsigned long val,
1425 struct netlink_ext_ack *extack);
Vladimir Olteandcbdf132021-02-13 22:43:17 +02001426int __br_vlan_set_proto(struct net_bridge *br, __be16 proto,
1427 struct netlink_ext_ack *extack);
Vladimir Oltean9e781402021-02-13 22:43:16 +02001428int br_vlan_set_proto(struct net_bridge *br, unsigned long val,
1429 struct netlink_ext_ack *extack);
Nikolay Aleksandrov6dada9b2016-04-30 10:25:28 +02001430int br_vlan_set_stats(struct net_bridge *br, unsigned long val);
Nikolay Aleksandrov9163a0f2018-10-12 13:41:16 +03001431int br_vlan_set_stats_per_port(struct net_bridge *br, unsigned long val);
Vlad Yasevich5be5a2d2014-10-03 11:29:18 -04001432int br_vlan_init(struct net_bridge *br);
Vladimir Oltean9e781402021-02-13 22:43:16 +02001433int br_vlan_set_default_pvid(struct net_bridge *br, unsigned long val,
1434 struct netlink_ext_ack *extack);
Petr Machata169327d2018-12-12 17:02:50 +00001435int __br_vlan_set_default_pvid(struct net_bridge *br, u16 pvid,
1436 struct netlink_ext_ack *extack);
Nikolay Aleksandrovf418af62017-10-27 13:19:37 +03001437int nbp_vlan_add(struct net_bridge_port *port, u16 vid, u16 flags,
Petr Machata169327d2018-12-12 17:02:50 +00001438 bool *changed, struct netlink_ext_ack *extack);
Joe Perches348662a2013-10-18 13:48:22 -07001439int nbp_vlan_delete(struct net_bridge_port *port, u16 vid);
1440void nbp_vlan_flush(struct net_bridge_port *port);
Petr Machata169327d2018-12-12 17:02:50 +00001441int nbp_vlan_init(struct net_bridge_port *port, struct netlink_ext_ack *extack);
Nikolay Aleksandrov2594e9062015-09-25 19:00:11 +02001442int nbp_get_num_vlan_infos(struct net_bridge_port *p, u32 filter_mask);
Nikolay Aleksandrova60c0902016-04-30 10:25:29 +02001443void br_vlan_get_stats(const struct net_bridge_vlan *v,
Heiner Kallweit281cc282020-11-17 21:25:42 +01001444 struct pcpu_sw_netstats *stats);
Mike Manning9c0ec2e2019-04-18 18:35:33 +01001445void br_vlan_port_event(struct net_bridge_port *p, unsigned long event);
Nikolay Aleksandrov091adf92019-08-02 13:57:36 +03001446int br_vlan_bridge_event(struct net_device *dev, unsigned long event,
1447 void *ptr);
Nikolay Aleksandrov8dcea182020-01-14 19:56:09 +02001448void br_vlan_rtnl_init(void);
1449void br_vlan_rtnl_uninit(void);
Nikolay Aleksandrovcf5bddb2020-01-14 19:56:13 +02001450void br_vlan_notify(const struct net_bridge *br,
1451 const struct net_bridge_port *p,
1452 u16 vid, u16 vid_range,
1453 int cmd);
Nikolay Aleksandrova5d29ae2020-01-24 13:40:21 +02001454bool br_vlan_can_enter_range(const struct net_bridge_vlan *v_curr,
1455 const struct net_bridge_vlan *range_end);
Vlad Yasevicha37b85c2013-02-13 12:00:10 +00001456
Felix Fietkaubcf27662021-03-24 02:30:35 +01001457void br_vlan_fill_forward_path_pvid(struct net_bridge *br,
1458 struct net_device_path_ctx *ctx,
1459 struct net_device_path *path);
1460int br_vlan_fill_forward_path_mode(struct net_bridge *br,
1461 struct net_bridge_port *dst,
1462 struct net_device_path *path);
1463
Nikolay Aleksandrov2594e9062015-09-25 19:00:11 +02001464static inline struct net_bridge_vlan_group *br_vlan_group(
1465 const struct net_bridge *br)
Vlad Yasevicha37b85c2013-02-13 12:00:10 +00001466{
Nikolay Aleksandrov907b1e62015-10-12 21:47:02 +02001467 return rtnl_dereference(br->vlgrp);
Vlad Yasevicha37b85c2013-02-13 12:00:10 +00001468}
1469
Nikolay Aleksandrov2594e9062015-09-25 19:00:11 +02001470static inline struct net_bridge_vlan_group *nbp_vlan_group(
1471 const struct net_bridge_port *p)
Vlad Yasevicha37b85c2013-02-13 12:00:10 +00001472{
Nikolay Aleksandrov907b1e62015-10-12 21:47:02 +02001473 return rtnl_dereference(p->vlgrp);
1474}
1475
1476static inline struct net_bridge_vlan_group *br_vlan_group_rcu(
1477 const struct net_bridge *br)
1478{
1479 return rcu_dereference(br->vlgrp);
1480}
1481
1482static inline struct net_bridge_vlan_group *nbp_vlan_group_rcu(
1483 const struct net_bridge_port *p)
1484{
1485 return rcu_dereference(p->vlgrp);
Vlad Yasevicha37b85c2013-02-13 12:00:10 +00001486}
1487
1488/* Since bridge now depends on 8021Q module, but the time bridge sees the
1489 * skb, the vlan tag will always be present if the frame was tagged.
1490 */
1491static inline int br_vlan_get_tag(const struct sk_buff *skb, u16 *vid)
1492{
1493 int err = 0;
1494
Nikolay Aleksandrov2594e9062015-09-25 19:00:11 +02001495 if (skb_vlan_tag_present(skb)) {
Michał Mirosław5978f8a2018-11-09 00:18:03 +01001496 *vid = skb_vlan_tag_get_id(skb);
Nikolay Aleksandrov2594e9062015-09-25 19:00:11 +02001497 } else {
Vlad Yasevicha37b85c2013-02-13 12:00:10 +00001498 *vid = 0;
1499 err = -EINVAL;
1500 }
1501
1502 return err;
1503}
Vlad Yasevich78851982013-02-13 12:00:14 +00001504
Nikolay Aleksandrov77751ee2015-09-30 20:16:53 +02001505static inline u16 br_get_pvid(const struct net_bridge_vlan_group *vg)
Vlad Yasevich78851982013-02-13 12:00:14 +00001506{
Nikolay Aleksandrov77751ee2015-09-30 20:16:53 +02001507 if (!vg)
Vlad Yasevich5be5a2d2014-10-03 11:29:18 -04001508 return 0;
1509
Vlad Yasevich78851982013-02-13 12:00:14 +00001510 smp_rmb();
Nikolay Aleksandrov77751ee2015-09-30 20:16:53 +02001511 return vg->pvid;
Vlad Yasevich78851982013-02-13 12:00:14 +00001512}
1513
Nikolay Aleksandrov8dcea182020-01-14 19:56:09 +02001514static inline u16 br_vlan_flags(const struct net_bridge_vlan *v, u16 pvid)
1515{
1516 return v->vid == pvid ? v->flags | BRIDGE_VLAN_INFO_PVID : v->flags;
1517}
Vlad Yasevich243a2e62013-02-13 12:00:09 +00001518#else
Nikolay Aleksandrov77751ee2015-09-30 20:16:53 +02001519static inline bool br_allowed_ingress(const struct net_bridge *br,
1520 struct net_bridge_vlan_group *vg,
Vlad Yasevich78851982013-02-13 12:00:14 +00001521 struct sk_buff *skb,
Nikolay Aleksandrovf4b70022021-07-19 20:06:28 +03001522 u16 *vid, u8 *state,
1523 struct net_bridge_vlan **vlan)
1524
Vlad Yasevicha37b85c2013-02-13 12:00:10 +00001525{
Nikolay Aleksandrovf4b70022021-07-19 20:06:28 +03001526 *vlan = NULL;
Vlad Yasevicha37b85c2013-02-13 12:00:10 +00001527 return true;
1528}
1529
Nikolay Aleksandrov2594e9062015-09-25 19:00:11 +02001530static inline bool br_allowed_egress(struct net_bridge_vlan_group *vg,
Vlad Yasevich85f46c62013-02-13 12:00:11 +00001531 const struct sk_buff *skb)
1532{
1533 return true;
1534}
1535
Toshiaki Makitae0d79682014-05-26 15:15:53 +09001536static inline bool br_should_learn(struct net_bridge_port *p,
1537 struct sk_buff *skb, u16 *vid)
1538{
1539 return true;
1540}
1541
Vlad Yasevich78851982013-02-13 12:00:14 +00001542static inline struct sk_buff *br_handle_vlan(struct net_bridge *br,
Roopa Prabhu11538d02017-01-31 22:59:55 -08001543 const struct net_bridge_port *port,
Nikolay Aleksandrov2594e9062015-09-25 19:00:11 +02001544 struct net_bridge_vlan_group *vg,
Vlad Yasevich78851982013-02-13 12:00:14 +00001545 struct sk_buff *skb)
1546{
1547 return skb;
1548}
1549
Nikolay Aleksandrovf418af62017-10-27 13:19:37 +03001550static inline int br_vlan_add(struct net_bridge *br, u16 vid, u16 flags,
Petr Machata169327d2018-12-12 17:02:50 +00001551 bool *changed, struct netlink_ext_ack *extack)
Vlad Yasevich243a2e62013-02-13 12:00:09 +00001552{
Nikolay Aleksandrovf418af62017-10-27 13:19:37 +03001553 *changed = false;
Vlad Yasevich243a2e62013-02-13 12:00:09 +00001554 return -EOPNOTSUPP;
1555}
1556
1557static inline int br_vlan_delete(struct net_bridge *br, u16 vid)
1558{
1559 return -EOPNOTSUPP;
1560}
1561
1562static inline void br_vlan_flush(struct net_bridge *br)
1563{
1564}
1565
Toshiaki Makita204177f2014-06-10 20:59:25 +09001566static inline void br_recalculate_fwd_mask(struct net_bridge *br)
1567{
1568}
1569
Vlad Yasevich5be5a2d2014-10-03 11:29:18 -04001570static inline int br_vlan_init(struct net_bridge *br)
Toshiaki Makita8580e212014-06-10 20:59:23 +09001571{
Vlad Yasevich5be5a2d2014-10-03 11:29:18 -04001572 return 0;
Toshiaki Makita8580e212014-06-10 20:59:23 +09001573}
1574
Nikolay Aleksandrovf418af62017-10-27 13:19:37 +03001575static inline int nbp_vlan_add(struct net_bridge_port *port, u16 vid, u16 flags,
Petr Machata169327d2018-12-12 17:02:50 +00001576 bool *changed, struct netlink_ext_ack *extack)
Vlad Yasevich243a2e62013-02-13 12:00:09 +00001577{
Nikolay Aleksandrovf418af62017-10-27 13:19:37 +03001578 *changed = false;
Vlad Yasevich243a2e62013-02-13 12:00:09 +00001579 return -EOPNOTSUPP;
1580}
1581
1582static inline int nbp_vlan_delete(struct net_bridge_port *port, u16 vid)
1583{
1584 return -EOPNOTSUPP;
1585}
1586
1587static inline void nbp_vlan_flush(struct net_bridge_port *port)
1588{
1589}
1590
Nikolay Aleksandrov2594e9062015-09-25 19:00:11 +02001591static inline struct net_bridge_vlan *br_vlan_find(struct net_bridge_vlan_group *vg,
1592 u16 vid)
Vlad Yasevicha37b85c2013-02-13 12:00:10 +00001593{
1594 return NULL;
1595}
Vlad Yasevichbc9a25d2013-02-13 12:00:19 +00001596
Petr Machata169327d2018-12-12 17:02:50 +00001597static inline int nbp_vlan_init(struct net_bridge_port *port,
1598 struct netlink_ext_ack *extack)
Vlad Yasevich5be5a2d2014-10-03 11:29:18 -04001599{
1600 return 0;
1601}
1602
Vlad Yasevich78851982013-02-13 12:00:14 +00001603static inline u16 br_vlan_get_tag(const struct sk_buff *skb, u16 *tag)
Vlad Yasevicha37b85c2013-02-13 12:00:10 +00001604{
1605 return 0;
1606}
Nikolay Aleksandrov2594e9062015-09-25 19:00:11 +02001607
Nikolay Aleksandrov77751ee2015-09-30 20:16:53 +02001608static inline u16 br_get_pvid(const struct net_bridge_vlan_group *vg)
Vlad Yasevich78851982013-02-13 12:00:14 +00001609{
Vlad Yasevich3df6bf42014-10-03 11:29:17 -04001610 return 0;
Vlad Yasevich78851982013-02-13 12:00:14 +00001611}
Vlad Yasevich2796d0c2014-05-16 09:59:20 -04001612
Vladimir Oltean7a572962021-02-13 22:43:15 +02001613static inline int br_vlan_filter_toggle(struct net_bridge *br,
Vladimir Olteanc97f47e2021-02-15 23:09:12 +02001614 unsigned long val,
1615 struct netlink_ext_ack *extack)
Nikolay Aleksandrova7854032015-08-07 19:40:45 +03001616{
1617 return -EOPNOTSUPP;
1618}
Nikolay Aleksandrov2594e9062015-09-25 19:00:11 +02001619
1620static inline int nbp_get_num_vlan_infos(struct net_bridge_port *p,
1621 u32 filter_mask)
1622{
1623 return 0;
1624}
1625
Felix Fietkaubcf27662021-03-24 02:30:35 +01001626static inline void br_vlan_fill_forward_path_pvid(struct net_bridge *br,
1627 struct net_device_path_ctx *ctx,
1628 struct net_device_path *path)
1629{
1630}
1631
1632static inline int br_vlan_fill_forward_path_mode(struct net_bridge *br,
1633 struct net_bridge_port *dst,
1634 struct net_device_path *path)
1635{
1636 return 0;
1637}
1638
Nikolay Aleksandrov2594e9062015-09-25 19:00:11 +02001639static inline struct net_bridge_vlan_group *br_vlan_group(
1640 const struct net_bridge *br)
1641{
1642 return NULL;
1643}
1644
1645static inline struct net_bridge_vlan_group *nbp_vlan_group(
1646 const struct net_bridge_port *p)
1647{
1648 return NULL;
1649}
Nikolay Aleksandrov907b1e62015-10-12 21:47:02 +02001650
1651static inline struct net_bridge_vlan_group *br_vlan_group_rcu(
1652 const struct net_bridge *br)
1653{
1654 return NULL;
1655}
1656
1657static inline struct net_bridge_vlan_group *nbp_vlan_group_rcu(
1658 const struct net_bridge_port *p)
1659{
1660 return NULL;
1661}
Nikolay Aleksandrova60c0902016-04-30 10:25:29 +02001662
1663static inline void br_vlan_get_stats(const struct net_bridge_vlan *v,
Heiner Kallweit281cc282020-11-17 21:25:42 +01001664 struct pcpu_sw_netstats *stats)
Nikolay Aleksandrova60c0902016-04-30 10:25:29 +02001665{
1666}
Mike Manning9c0ec2e2019-04-18 18:35:33 +01001667
1668static inline void br_vlan_port_event(struct net_bridge_port *p,
1669 unsigned long event)
1670{
1671}
1672
Nikolay Aleksandrov091adf92019-08-02 13:57:36 +03001673static inline int br_vlan_bridge_event(struct net_device *dev,
1674 unsigned long event, void *ptr)
Mike Manning9c0ec2e2019-04-18 18:35:33 +01001675{
Nikolay Aleksandrov091adf92019-08-02 13:57:36 +03001676 return 0;
Mike Manning9c0ec2e2019-04-18 18:35:33 +01001677}
Nikolay Aleksandrov8dcea182020-01-14 19:56:09 +02001678
1679static inline void br_vlan_rtnl_init(void)
1680{
1681}
1682
1683static inline void br_vlan_rtnl_uninit(void)
1684{
1685}
Nikolay Aleksandrovcf5bddb2020-01-14 19:56:13 +02001686
1687static inline void br_vlan_notify(const struct net_bridge *br,
1688 const struct net_bridge_port *p,
1689 u16 vid, u16 vid_range,
1690 int cmd)
1691{
1692}
Nikolay Aleksandrov528ae842020-07-13 10:55:46 +03001693
1694static inline bool br_vlan_can_enter_range(const struct net_bridge_vlan *v_curr,
1695 const struct net_bridge_vlan *range_end)
1696{
1697 return true;
1698}
Vladimir Oltean4e51bf42021-07-21 19:24:03 +03001699
Vladimir Olteanc5f6e5e2021-10-27 19:21:15 +03001700static inline u16 br_vlan_flags(const struct net_bridge_vlan *v, u16 pvid)
1701{
1702 return 0;
1703}
1704
Vlad Yasevich243a2e62013-02-13 12:00:09 +00001705#endif
1706
Nikolay Aleksandrov7a53e712020-01-24 13:40:20 +02001707/* br_vlan_options.c */
1708#ifdef CONFIG_BRIDGE_VLAN_FILTERING
Nikolay Aleksandrov99f7c5e2020-03-17 14:08:33 +02001709bool br_vlan_opts_eq_range(const struct net_bridge_vlan *v_curr,
1710 const struct net_bridge_vlan *range_end);
Nikolay Aleksandrov7a53e712020-01-24 13:40:20 +02001711bool br_vlan_opts_fill(struct sk_buff *skb, const struct net_bridge_vlan *v);
1712size_t br_vlan_opts_nl_size(void);
Nikolay Aleksandrova5d29ae2020-01-24 13:40:21 +02001713int br_vlan_process_options(const struct net_bridge *br,
1714 const struct net_bridge_port *p,
1715 struct net_bridge_vlan *range_start,
1716 struct net_bridge_vlan *range_end,
1717 struct nlattr **tb,
1718 struct netlink_ext_ack *extack);
Nikolay Aleksandrov47ecd2d2021-07-19 20:06:34 +03001719int br_vlan_rtm_process_global_options(struct net_device *dev,
1720 const struct nlattr *attr,
1721 int cmd,
1722 struct netlink_ext_ack *extack);
Nikolay Aleksandrov743a53d2021-07-19 20:06:35 +03001723bool br_vlan_global_opts_can_enter_range(const struct net_bridge_vlan *v_curr,
1724 const struct net_bridge_vlan *r_end);
1725bool br_vlan_global_opts_fill(struct sk_buff *skb, u16 vid, u16 vid_range,
1726 const struct net_bridge_vlan *v_opts);
Nikolay Aleksandrova580c762020-01-24 13:40:22 +02001727
1728/* vlan state manipulation helpers using *_ONCE to annotate lock-free access */
1729static inline u8 br_vlan_get_state(const struct net_bridge_vlan *v)
1730{
1731 return READ_ONCE(v->state);
1732}
1733
1734static inline void br_vlan_set_state(struct net_bridge_vlan *v, u8 state)
1735{
1736 WRITE_ONCE(v->state, state);
1737}
1738
1739static inline u8 br_vlan_get_pvid_state(const struct net_bridge_vlan_group *vg)
1740{
1741 return READ_ONCE(vg->pvid_state);
1742}
1743
1744static inline void br_vlan_set_pvid_state(struct net_bridge_vlan_group *vg,
1745 u8 state)
1746{
1747 WRITE_ONCE(vg->pvid_state, state);
1748}
1749
1750/* learn_allow is true at ingress and false at egress */
1751static inline bool br_vlan_state_allowed(u8 state, bool learn_allow)
1752{
1753 switch (state) {
1754 case BR_STATE_LEARNING:
1755 return learn_allow;
1756 case BR_STATE_FORWARDING:
1757 return true;
1758 default:
1759 return false;
1760 }
1761}
Nikolay Aleksandrov7a53e712020-01-24 13:40:20 +02001762#endif
1763
Pablo Neira Ayuso1a4ba642015-03-10 10:27:18 +01001764struct nf_br_ops {
1765 int (*br_dev_xmit_hook)(struct sk_buff *skb);
1766};
1767extern const struct nf_br_ops __rcu *nf_br_ops;
1768
Linus Torvalds1da177e2005-04-16 15:20:36 -07001769/* br_netfilter.c */
Pablo Neira Ayuso34666d42014-09-18 11:29:03 +02001770#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
1771int br_nf_core_init(void);
1772void br_nf_core_fini(void);
Joe Perches348662a2013-10-18 13:48:22 -07001773void br_netfilter_rtable_init(struct net_bridge *);
Stephen Hemmingerc0909712006-05-25 15:59:33 -07001774#else
Pablo Neira Ayuso34666d42014-09-18 11:29:03 +02001775static inline int br_nf_core_init(void) { return 0; }
1776static inline void br_nf_core_fini(void) {}
Simon Wunderlich4adf0af2008-07-30 16:27:55 -07001777#define br_netfilter_rtable_init(x)
Stephen Hemmingerc0909712006-05-25 15:59:33 -07001778#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07001779
1780/* br_stp.c */
Florian Fainelli775dd692014-09-30 16:13:19 -07001781void br_set_state(struct net_bridge_port *p, unsigned int state);
Joe Perches348662a2013-10-18 13:48:22 -07001782struct net_bridge_port *br_get_port(struct net_bridge *br, u16 port_no);
1783void br_init_port(struct net_bridge_port *p);
1784void br_become_designated_port(struct net_bridge_port *p);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001785
Joe Perches348662a2013-10-18 13:48:22 -07001786void __br_set_forward_delay(struct net_bridge *br, unsigned long t);
1787int br_set_forward_delay(struct net_bridge *br, unsigned long x);
1788int br_set_hello_time(struct net_bridge *br, unsigned long x);
1789int br_set_max_age(struct net_bridge *br, unsigned long x);
Vivien Didelot82dd4332016-12-10 13:44:27 -05001790int __set_ageing_time(struct net_device *dev, unsigned long t);
Vivien Didelot9e0b27f2016-07-21 12:42:19 -04001791int br_set_ageing_time(struct net_bridge *br, clock_t ageing_time);
stephen hemminger14f98f22011-04-04 14:03:33 +00001792
1793
Linus Torvalds1da177e2005-04-16 15:20:36 -07001794/* br_stp_if.c */
Joe Perches348662a2013-10-18 13:48:22 -07001795void br_stp_enable_bridge(struct net_bridge *br);
1796void br_stp_disable_bridge(struct net_bridge *br);
Horatiu Vultur419dba8a2020-04-26 15:22:08 +02001797int br_stp_set_enabled(struct net_bridge *br, unsigned long val,
1798 struct netlink_ext_ack *extack);
Joe Perches348662a2013-10-18 13:48:22 -07001799void br_stp_enable_port(struct net_bridge_port *p);
1800void br_stp_disable_port(struct net_bridge_port *p);
1801bool br_stp_recalculate_bridge_id(struct net_bridge *br);
1802void br_stp_change_bridge_id(struct net_bridge *br, const unsigned char *a);
1803void br_stp_set_bridge_priority(struct net_bridge *br, u16 newprio);
1804int br_stp_set_port_priority(struct net_bridge_port *p, unsigned long newprio);
1805int br_stp_set_path_cost(struct net_bridge_port *p, unsigned long path_cost);
1806ssize_t br_show_bridge_id(char *buf, const struct bridge_id *id);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001807
1808/* br_stp_bpdu.c */
Patrick McHardy7c85fbf2008-07-05 21:25:56 -07001809struct stp_proto;
Joe Perches348662a2013-10-18 13:48:22 -07001810void br_stp_rcv(const struct stp_proto *proto, struct sk_buff *skb,
1811 struct net_device *dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001812
1813/* br_stp_timer.c */
Joe Perches348662a2013-10-18 13:48:22 -07001814void br_stp_timer_init(struct net_bridge *br);
1815void br_stp_port_timer_init(struct net_bridge_port *p);
1816unsigned long br_timer_value(const struct timer_list *timer);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001817
1818/* br.c */
Igor Maraviće6373c42011-12-12 02:58:25 +00001819#if IS_ENABLED(CONFIG_ATM_LANE)
Michał Mirosławda678292009-06-05 05:35:28 +00001820extern int (*br_fdb_test_addr_hook)(struct net_device *dev, unsigned char *addr);
1821#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07001822
Horatiu Vultur65369932020-04-26 15:22:07 +02001823/* br_mrp.c */
1824#if IS_ENABLED(CONFIG_BRIDGE_MRP)
1825int br_mrp_parse(struct net_bridge *br, struct net_bridge_port *p,
1826 struct nlattr *attr, int cmd, struct netlink_ext_ack *extack);
Horatiu Vultur65369932020-04-26 15:22:07 +02001827bool br_mrp_enabled(struct net_bridge *br);
1828void br_mrp_port_del(struct net_bridge *br, struct net_bridge_port *p);
Horatiu Vulturdf42ef222020-07-02 10:13:06 +02001829int br_mrp_fill_info(struct sk_buff *skb, struct net_bridge *br);
Horatiu Vultur65369932020-04-26 15:22:07 +02001830#else
1831static inline int br_mrp_parse(struct net_bridge *br, struct net_bridge_port *p,
1832 struct nlattr *attr, int cmd,
1833 struct netlink_ext_ack *extack)
1834{
1835 return -EOPNOTSUPP;
1836}
1837
Horatiu Vultur65369932020-04-26 15:22:07 +02001838static inline bool br_mrp_enabled(struct net_bridge *br)
1839{
Jason Yan8741e182020-05-06 14:16:16 +08001840 return false;
Horatiu Vultur65369932020-04-26 15:22:07 +02001841}
1842
1843static inline void br_mrp_port_del(struct net_bridge *br,
1844 struct net_bridge_port *p)
1845{
1846}
Horatiu Vulturdf42ef222020-07-02 10:13:06 +02001847
1848static inline int br_mrp_fill_info(struct sk_buff *skb, struct net_bridge *br)
1849{
1850 return 0;
1851}
1852
Horatiu Vultur65369932020-04-26 15:22:07 +02001853#endif
1854
Henrik Bjoernlund2be665c2020-10-27 10:02:48 +00001855/* br_cfm.c */
Henrik Bjoernlund86a14b72020-10-27 10:02:45 +00001856#if IS_ENABLED(CONFIG_BRIDGE_CFM)
Henrik Bjoernlund2be665c2020-10-27 10:02:48 +00001857int br_cfm_parse(struct net_bridge *br, struct net_bridge_port *p,
1858 struct nlattr *attr, int cmd, struct netlink_ext_ack *extack);
1859bool br_cfm_created(struct net_bridge *br);
Henrik Bjoernlund86a14b72020-10-27 10:02:45 +00001860void br_cfm_port_del(struct net_bridge *br, struct net_bridge_port *p);
Henrik Bjoernlund5e312fc2020-10-27 10:02:49 +00001861int br_cfm_config_fill_info(struct sk_buff *skb, struct net_bridge *br);
Henrik Bjoernlundb6d04252020-10-27 10:02:51 +00001862int br_cfm_status_fill_info(struct sk_buff *skb,
1863 struct net_bridge *br,
1864 bool getlink);
1865int br_cfm_mep_count(struct net_bridge *br, u32 *count);
1866int br_cfm_peer_mep_count(struct net_bridge *br, u32 *count);
Henrik Bjoernlund86a14b72020-10-27 10:02:45 +00001867#else
Henrik Bjoernlund2be665c2020-10-27 10:02:48 +00001868static inline int br_cfm_parse(struct net_bridge *br, struct net_bridge_port *p,
1869 struct nlattr *attr, int cmd,
1870 struct netlink_ext_ack *extack)
1871{
1872 return -EOPNOTSUPP;
1873}
1874
1875static inline bool br_cfm_created(struct net_bridge *br)
1876{
1877 return false;
1878}
1879
Henrik Bjoernlund86a14b72020-10-27 10:02:45 +00001880static inline void br_cfm_port_del(struct net_bridge *br,
1881 struct net_bridge_port *p)
1882{
1883}
Henrik Bjoernlund5e312fc2020-10-27 10:02:49 +00001884
1885static inline int br_cfm_config_fill_info(struct sk_buff *skb, struct net_bridge *br)
1886{
1887 return -EOPNOTSUPP;
1888}
Henrik Bjoernlunde77824d2020-10-27 10:02:50 +00001889
Henrik Bjoernlundb6d04252020-10-27 10:02:51 +00001890static inline int br_cfm_status_fill_info(struct sk_buff *skb,
1891 struct net_bridge *br,
1892 bool getlink)
1893{
1894 return -EOPNOTSUPP;
1895}
1896
1897static inline int br_cfm_mep_count(struct net_bridge *br, u32 *count)
1898{
Ivan Vecera829e0502021-10-28 17:58:35 +02001899 *count = 0;
Henrik Bjoernlundb6d04252020-10-27 10:02:51 +00001900 return -EOPNOTSUPP;
1901}
1902
1903static inline int br_cfm_peer_mep_count(struct net_bridge *br, u32 *count)
Henrik Bjoernlunde77824d2020-10-27 10:02:50 +00001904{
Ivan Vecera829e0502021-10-28 17:58:35 +02001905 *count = 0;
Henrik Bjoernlunde77824d2020-10-27 10:02:50 +00001906 return -EOPNOTSUPP;
1907}
Henrik Bjoernlund86a14b72020-10-27 10:02:45 +00001908#endif
1909
Stephen Hemminger11dc1f32006-05-25 16:00:12 -07001910/* br_netlink.c */
stephen hemminger149ddd82012-06-26 05:48:45 +00001911extern struct rtnl_link_ops br_link_ops;
Joe Perches348662a2013-10-18 13:48:22 -07001912int br_netlink_init(void);
1913void br_netlink_fini(void);
Nikolay Aleksandrov92899062017-11-01 12:18:13 +02001914void br_ifinfo_notify(int event, const struct net_bridge *br,
1915 const struct net_bridge_port *port);
Henrik Bjoernlundb6d04252020-10-27 10:02:51 +00001916void br_info_notify(int event, const struct net_bridge *br,
1917 const struct net_bridge_port *port, u32 filter);
Petr Machata2fd527b2018-12-12 17:02:48 +00001918int br_setlink(struct net_device *dev, struct nlmsghdr *nlmsg, u16 flags,
1919 struct netlink_ext_ack *extack);
Roopa Prabhuadd511b2015-01-29 22:40:12 -08001920int br_dellink(struct net_device *dev, struct nlmsghdr *nlmsg, u16 flags);
Joe Perches348662a2013-10-18 13:48:22 -07001921int br_getlink(struct sk_buff *skb, u32 pid, u32 seq, struct net_device *dev,
Nicolas Dichtel46c264d2015-04-28 18:33:49 +02001922 u32 filter_mask, int nlflags);
Nikolay Aleksandrovf26b2962020-01-14 19:56:10 +02001923int br_process_vlan_info(struct net_bridge *br,
1924 struct net_bridge_port *p, int cmd,
1925 struct bridge_vlan_info *vinfo_curr,
1926 struct bridge_vlan_info **vinfo_last,
1927 bool *changed,
1928 struct netlink_ext_ack *extack);
Stephen Hemminger11dc1f32006-05-25 16:00:12 -07001929
Linus Torvalds1da177e2005-04-16 15:20:36 -07001930#ifdef CONFIG_SYSFS
1931/* br_sysfs_if.c */
Emese Revfy52cf25d2010-01-19 02:58:23 +01001932extern const struct sysfs_ops brport_sysfs_ops;
Joe Perches348662a2013-10-18 13:48:22 -07001933int br_sysfs_addif(struct net_bridge_port *p);
1934int br_sysfs_renameif(struct net_bridge_port *p);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001935
1936/* br_sysfs_br.c */
Joe Perches348662a2013-10-18 13:48:22 -07001937int br_sysfs_addbr(struct net_device *dev);
1938void br_sysfs_delbr(struct net_device *dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001939
1940#else
1941
Lee Jones0cb2bbb2012-11-03 23:02:30 +01001942static inline int br_sysfs_addif(struct net_bridge_port *p) { return 0; }
1943static inline int br_sysfs_renameif(struct net_bridge_port *p) { return 0; }
1944static inline int br_sysfs_addbr(struct net_device *dev) { return 0; }
1945static inline void br_sysfs_delbr(struct net_device *dev) { return; }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001946#endif /* CONFIG_SYSFS */
1947
Ido Schimmel6bc506b2016-08-25 18:42:37 +02001948/* br_switchdev.c */
1949#ifdef CONFIG_NET_SWITCHDEV
Vladimir Oltean957e2232021-08-03 23:34:08 +03001950int br_switchdev_port_offload(struct net_bridge_port *p,
1951 struct net_device *dev, const void *ctx,
1952 struct notifier_block *atomic_nb,
1953 struct notifier_block *blocking_nb,
1954 bool tx_fwd_offload,
1955 struct netlink_ext_ack *extack);
1956
1957void br_switchdev_port_unoffload(struct net_bridge_port *p, const void *ctx,
1958 struct notifier_block *atomic_nb,
1959 struct notifier_block *blocking_nb);
1960
Tobias Waldekranz47211192021-07-22 18:55:38 +03001961bool br_switchdev_frame_uses_tx_fwd_offload(struct sk_buff *skb);
1962
Vladimir Olteanc5381152021-07-23 23:49:11 +03001963void br_switchdev_frame_set_offload_fwd_mark(struct sk_buff *skb);
1964
Tobias Waldekranz47211192021-07-22 18:55:38 +03001965void nbp_switchdev_frame_mark_tx_fwd_offload(const struct net_bridge_port *p,
1966 struct sk_buff *skb);
1967void nbp_switchdev_frame_mark_tx_fwd_to_hwdom(const struct net_bridge_port *p,
1968 struct sk_buff *skb);
Ido Schimmel6bc506b2016-08-25 18:42:37 +02001969void nbp_switchdev_frame_mark(const struct net_bridge_port *p,
1970 struct sk_buff *skb);
1971bool nbp_switchdev_allowed_egress(const struct net_bridge_port *p,
1972 const struct sk_buff *skb);
Arkadi Sharshevsky39222852017-06-08 08:44:11 +02001973int br_switchdev_set_port_flag(struct net_bridge_port *p,
1974 unsigned long flags,
Vladimir Oltean078bbb82021-02-12 17:15:53 +02001975 unsigned long mask,
1976 struct netlink_ext_ack *extack);
Tobias Waldekranz6eb38bf2021-06-29 17:06:45 +03001977void br_switchdev_fdb_notify(struct net_bridge *br,
1978 const struct net_bridge_fdb_entry *fdb, int type);
Vladimir Olteanae039352021-10-30 01:36:06 +03001979void br_switchdev_mdb_notify(struct net_device *dev,
1980 struct net_bridge_mdb_entry *mp,
1981 struct net_bridge_port_group *pg,
1982 int type);
Petr Machata169327d2018-12-12 17:02:50 +00001983int br_switchdev_port_vlan_add(struct net_device *dev, u16 vid, u16 flags,
1984 struct netlink_ext_ack *extack);
Petr Machatad66e4342018-05-30 02:56:03 +02001985int br_switchdev_port_vlan_del(struct net_device *dev, u16 vid);
Tobias Waldekranz85826612021-07-21 19:24:00 +03001986void br_switchdev_init(struct net_bridge *br);
Ido Schimmelf1c2edd2017-09-03 17:44:13 +03001987
1988static inline void br_switchdev_frame_unmark(struct sk_buff *skb)
1989{
1990 skb->offload_fwd_mark = 0;
1991}
Ido Schimmel6bc506b2016-08-25 18:42:37 +02001992#else
Vladimir Oltean957e2232021-08-03 23:34:08 +03001993static inline int
1994br_switchdev_port_offload(struct net_bridge_port *p,
1995 struct net_device *dev, const void *ctx,
1996 struct notifier_block *atomic_nb,
1997 struct notifier_block *blocking_nb,
1998 bool tx_fwd_offload,
1999 struct netlink_ext_ack *extack)
2000{
2001 return -EOPNOTSUPP;
2002}
2003
2004static inline void
2005br_switchdev_port_unoffload(struct net_bridge_port *p, const void *ctx,
2006 struct notifier_block *atomic_nb,
2007 struct notifier_block *blocking_nb)
2008{
2009}
2010
Tobias Waldekranz47211192021-07-22 18:55:38 +03002011static inline bool br_switchdev_frame_uses_tx_fwd_offload(struct sk_buff *skb)
2012{
2013 return false;
2014}
2015
Vladimir Olteanc5381152021-07-23 23:49:11 +03002016static inline void br_switchdev_frame_set_offload_fwd_mark(struct sk_buff *skb)
2017{
2018}
2019
Tobias Waldekranz47211192021-07-22 18:55:38 +03002020static inline void
2021nbp_switchdev_frame_mark_tx_fwd_offload(const struct net_bridge_port *p,
2022 struct sk_buff *skb)
2023{
2024}
2025
2026static inline void
2027nbp_switchdev_frame_mark_tx_fwd_to_hwdom(const struct net_bridge_port *p,
2028 struct sk_buff *skb)
2029{
2030}
2031
Ido Schimmel6bc506b2016-08-25 18:42:37 +02002032static inline void nbp_switchdev_frame_mark(const struct net_bridge_port *p,
2033 struct sk_buff *skb)
2034{
2035}
2036
2037static inline bool nbp_switchdev_allowed_egress(const struct net_bridge_port *p,
2038 const struct sk_buff *skb)
2039{
2040 return true;
2041}
Arkadi Sharshevsky39222852017-06-08 08:44:11 +02002042
2043static inline int br_switchdev_set_port_flag(struct net_bridge_port *p,
2044 unsigned long flags,
Vladimir Oltean078bbb82021-02-12 17:15:53 +02002045 unsigned long mask,
2046 struct netlink_ext_ack *extack)
Arkadi Sharshevsky39222852017-06-08 08:44:11 +02002047{
2048 return 0;
2049}
Arkadi Sharshevsky6b26b512017-06-08 08:44:14 +02002050
Petr Machatad66e4342018-05-30 02:56:03 +02002051static inline int br_switchdev_port_vlan_add(struct net_device *dev,
Petr Machata169327d2018-12-12 17:02:50 +00002052 u16 vid, u16 flags,
2053 struct netlink_ext_ack *extack)
Petr Machatad66e4342018-05-30 02:56:03 +02002054{
2055 return -EOPNOTSUPP;
2056}
2057
2058static inline int br_switchdev_port_vlan_del(struct net_device *dev, u16 vid)
2059{
2060 return -EOPNOTSUPP;
2061}
2062
Arkadi Sharshevsky6b26b512017-06-08 08:44:14 +02002063static inline void
Tobias Waldekranz6eb38bf2021-06-29 17:06:45 +03002064br_switchdev_fdb_notify(struct net_bridge *br,
2065 const struct net_bridge_fdb_entry *fdb, int type)
Arkadi Sharshevsky6b26b512017-06-08 08:44:14 +02002066{
2067}
Ido Schimmelf1c2edd2017-09-03 17:44:13 +03002068
Vladimir Olteanae039352021-10-30 01:36:06 +03002069static inline void br_switchdev_mdb_notify(struct net_device *dev,
2070 struct net_bridge_mdb_entry *mp,
2071 struct net_bridge_port_group *pg,
2072 int type)
2073{
2074}
2075
Ido Schimmelf1c2edd2017-09-03 17:44:13 +03002076static inline void br_switchdev_frame_unmark(struct sk_buff *skb)
2077{
2078}
Tobias Waldekranz85826612021-07-21 19:24:00 +03002079
Tobias Waldekranz85826612021-07-21 19:24:00 +03002080static inline void br_switchdev_init(struct net_bridge *br)
2081{
2082}
2083
Ido Schimmel6bc506b2016-08-25 18:42:37 +02002084#endif /* CONFIG_NET_SWITCHDEV */
2085
Roopa Prabhu057658c2017-10-06 22:12:38 -07002086/* br_arp_nd_proxy.c */
Roopa Prabhu821f1b22017-10-06 22:12:37 -07002087void br_recalculate_neigh_suppress_enabled(struct net_bridge *br);
Roopa Prabhu057658c2017-10-06 22:12:38 -07002088void br_do_proxy_suppress_arp(struct sk_buff *skb, struct net_bridge *br,
2089 u16 vid, struct net_bridge_port *p);
Roopa Prabhued842fa2017-10-06 22:12:39 -07002090void br_do_suppress_nd(struct sk_buff *skb, struct net_bridge *br,
2091 u16 vid, struct net_bridge_port *p, struct nd_msg *msg);
2092struct nd_msg *br_is_nd_neigh_msg(struct sk_buff *skb, struct nd_msg *m);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002093#endif