Commit | Line | Data |
---|---|---|
2874c5fd | 1 | /* SPDX-License-Identifier: GPL-2.0-or-later */ |
1da177e4 LT |
2 | /* |
3 | * Linux ethernet bridge | |
4 | * | |
5 | * Authors: | |
6 | * Lennert Buytenhek <buytenh@gnu.org> | |
1da177e4 LT |
7 | */ |
8 | ||
9 | #ifndef _BR_PRIVATE_H | |
10 | #define _BR_PRIVATE_H | |
11 | ||
12 | #include <linux/netdevice.h> | |
1da177e4 | 13 | #include <linux/if_bridge.h> |
91d2c34a | 14 | #include <linux/netpoll.h> |
406818ff | 15 | #include <linux/u64_stats_sync.h> |
4adf0af6 | 16 | #include <net/route.h> |
efb6de9b | 17 | #include <net/ip6_fib.h> |
7b4858df | 18 | #include <net/pkt_cls.h> |
243a2e63 | 19 | #include <linux/if_vlan.h> |
2594e906 | 20 | #include <linux/rhashtable.h> |
25127759 | 21 | #include <linux/refcount.h> |
1da177e4 LT |
22 | |
23 | #define BR_HASH_BITS 8 | |
24 | #define BR_HASH_SIZE (1 << BR_HASH_BITS) | |
25 | ||
26 | #define BR_HOLD_TIME (1*HZ) | |
27 | ||
28 | #define BR_PORT_BITS 10 | |
29 | #define BR_MAX_PORTS (1<<BR_PORT_BITS) | |
30 | ||
d08c6bc0 | 31 | #define BR_MULTICAST_DEFAULT_HASH_MAX 4096 |
99b40610 | 32 | #define BR_MULTICAST_QUERY_INTVL_MIN msecs_to_jiffies(1000) |
f83a112b | 33 | #define BR_MULTICAST_STARTUP_QUERY_INTVL_MIN BR_MULTICAST_QUERY_INTVL_MIN |
d08c6bc0 | 34 | |
85826610 TW |
35 | #define BR_HWDOM_MAX BITS_PER_LONG |
36 | ||
9cde0708 SH |
37 | #define BR_VERSION "2.3" |
38 | ||
515853cc | 39 | /* Control of forwarding link local multicast */ |
40 | #define BR_GROUPFWD_DEFAULT 0 | |
784b58a3 | 41 | /* Don't allow forwarding of control protocols like STP, MAC PAUSE and LACP */ |
5af48b59 NA |
42 | enum { |
43 | BR_GROUPFWD_STP = BIT(0), | |
44 | BR_GROUPFWD_MACPAUSE = BIT(1), | |
45 | BR_GROUPFWD_LACP = BIT(2), | |
46 | }; | |
47 | ||
48 | #define BR_GROUPFWD_RESTRICTED (BR_GROUPFWD_STP | BR_GROUPFWD_MACPAUSE | \ | |
49 | BR_GROUPFWD_LACP) | |
f2808d22 TM |
50 | /* The Nearest Customer Bridge Group Address, 01-80-C2-00-00-[00,0B,0C,0D,0F] */ |
51 | #define BR_GROUPFWD_8021AD 0xB801u | |
515853cc | 52 | |
9cde0708 SH |
53 | /* Path to usermode spanning tree program */ |
54 | #define BR_STP_PROG "/sbin/bridge-stp" | |
8cbb512e | 55 | |
31cbc39b NA |
56 | #define BR_FDB_NOTIFY_SETTABLE_BITS (FDB_NOTIFY_BIT | FDB_NOTIFY_INACTIVE_BIT) |
57 | ||
1da177e4 LT |
58 | typedef struct bridge_id bridge_id; |
59 | typedef struct mac_addr mac_addr; | |
60 | typedef __u16 port_id; | |
61 | ||
1c1cb6d0 | 62 | struct bridge_id { |
1da177e4 | 63 | unsigned char prio[2]; |
e5a727f6 | 64 | unsigned char addr[ETH_ALEN]; |
1da177e4 LT |
65 | }; |
66 | ||
1c1cb6d0 | 67 | struct mac_addr { |
e5a727f6 | 68 | unsigned char addr[ETH_ALEN]; |
1da177e4 LT |
69 | }; |
70 | ||
cc0fdd80 LL |
71 | #ifdef CONFIG_BRIDGE_IGMP_SNOOPING |
72 | /* our own querier */ | |
90010b36 | 73 | struct bridge_mcast_own_query { |
cc0fdd80 LL |
74 | struct timer_list timer; |
75 | u32 startup_sent; | |
76 | }; | |
77 | ||
78 | /* other querier */ | |
90010b36 | 79 | struct bridge_mcast_other_query { |
cc0fdd80 | 80 | struct timer_list timer; |
f5c3eb4b | 81 | struct timer_list delay_timer; |
cc0fdd80 | 82 | }; |
dc4eb53a LL |
83 | |
84 | /* selected querier */ | |
85 | struct bridge_mcast_querier { | |
86 | struct br_ip addr; | |
bb18ef8e | 87 | int port_ifidx; |
f936bb42 | 88 | seqcount_spinlock_t seq; |
dc4eb53a | 89 | }; |
1080ab95 NA |
90 | |
91 | /* IGMP/MLD statistics */ | |
92 | struct bridge_mcast_stats { | |
93 | struct br_mcast_stats mstats; | |
94 | struct u64_stats_sync syncp; | |
95 | }; | |
cb453926 | 96 | |
b1c8fec8 IS |
97 | struct br_mdb_src_entry { |
98 | struct br_ip addr; | |
99 | }; | |
100 | ||
cb453926 IS |
101 | struct br_mdb_config { |
102 | struct net_bridge *br; | |
103 | struct net_bridge_port *p; | |
104 | struct br_mdb_entry *entry; | |
105 | struct br_ip group; | |
079afd66 | 106 | bool src_entry; |
b1c8fec8 | 107 | u8 filter_mode; |
61f21835 | 108 | u16 nlflags; |
b1c8fec8 IS |
109 | struct br_mdb_src_entry *src_entries; |
110 | int num_src_entries; | |
1d7b66a7 | 111 | u8 rt_protocol; |
cb453926 | 112 | }; |
cc0fdd80 LL |
113 | #endif |
114 | ||
9632233e NA |
115 | /* net_bridge_mcast_port must be always defined due to forwarding stubs */ |
116 | struct net_bridge_mcast_port { | |
117 | #ifdef CONFIG_BRIDGE_IGMP_SNOOPING | |
118 | struct net_bridge_port *port; | |
613d61db | 119 | struct net_bridge_vlan *vlan; |
9632233e NA |
120 | |
121 | struct bridge_mcast_own_query ip4_own_query; | |
122 | struct timer_list ip4_mc_router_timer; | |
123 | struct hlist_node ip4_rlist; | |
124 | #if IS_ENABLED(CONFIG_IPV6) | |
125 | struct bridge_mcast_own_query ip6_own_query; | |
126 | struct timer_list ip6_mc_router_timer; | |
127 | struct hlist_node ip6_rlist; | |
128 | #endif /* IS_ENABLED(CONFIG_IPV6) */ | |
129 | unsigned char multicast_router; | |
b57e8d87 PM |
130 | u32 mdb_n_entries; |
131 | u32 mdb_max_entries; | |
9632233e NA |
132 | #endif /* CONFIG_BRIDGE_IGMP_SNOOPING */ |
133 | }; | |
134 | ||
d3d065c0 NA |
135 | /* net_bridge_mcast must be always defined due to forwarding stubs */ |
136 | struct net_bridge_mcast { | |
137 | #ifdef CONFIG_BRIDGE_IGMP_SNOOPING | |
138 | struct net_bridge *br; | |
613d61db | 139 | struct net_bridge_vlan *vlan; |
d3d065c0 NA |
140 | |
141 | u32 multicast_last_member_count; | |
142 | u32 multicast_startup_query_count; | |
143 | ||
4d5b4e84 | 144 | u8 multicast_querier; |
d3d065c0 NA |
145 | u8 multicast_igmp_version; |
146 | u8 multicast_router; | |
147 | #if IS_ENABLED(CONFIG_IPV6) | |
148 | u8 multicast_mld_version; | |
149 | #endif | |
150 | unsigned long multicast_last_member_interval; | |
151 | unsigned long multicast_membership_interval; | |
152 | unsigned long multicast_querier_interval; | |
153 | unsigned long multicast_query_interval; | |
154 | unsigned long multicast_query_response_interval; | |
155 | unsigned long multicast_startup_query_interval; | |
156 | struct hlist_head ip4_mc_router_list; | |
157 | struct timer_list ip4_mc_router_timer; | |
158 | struct bridge_mcast_other_query ip4_other_query; | |
159 | struct bridge_mcast_own_query ip4_own_query; | |
160 | struct bridge_mcast_querier ip4_querier; | |
161 | #if IS_ENABLED(CONFIG_IPV6) | |
162 | struct hlist_head ip6_mc_router_list; | |
163 | struct timer_list ip6_mc_router_timer; | |
164 | struct bridge_mcast_other_query ip6_other_query; | |
165 | struct bridge_mcast_own_query ip6_own_query; | |
166 | struct bridge_mcast_querier ip6_querier; | |
167 | #endif /* IS_ENABLED(CONFIG_IPV6) */ | |
168 | #endif /* CONFIG_BRIDGE_IGMP_SNOOPING */ | |
169 | }; | |
170 | ||
efa5356b | 171 | struct br_tunnel_info { |
58e20717 NA |
172 | __be64 tunnel_id; |
173 | struct metadata_dst __rcu *tunnel_dst; | |
efa5356b RP |
174 | }; |
175 | ||
9d332e69 NA |
176 | /* private vlan flags */ |
177 | enum { | |
178 | BR_VLFLAG_PER_PORT_STATS = BIT(0), | |
27973793 | 179 | BR_VLFLAG_ADDED_BY_SWITCHDEV = BIT(1), |
7b54aaaf NA |
180 | BR_VLFLAG_MCAST_ENABLED = BIT(2), |
181 | BR_VLFLAG_GLOBAL_MCAST_ENABLED = BIT(3), | |
a714e3ec | 182 | BR_VLFLAG_NEIGH_SUPPRESS_ENABLED = BIT(4), |
9d332e69 NA |
183 | }; |
184 | ||
2594e906 NA |
185 | /** |
186 | * struct net_bridge_vlan - per-vlan entry | |
187 | * | |
188 | * @vnode: rhashtable member | |
bcc1f84e | 189 | * @tnode: rhashtable member |
2594e906 NA |
190 | * @vid: VLAN id |
191 | * @flags: bridge vlan flags | |
9d332e69 | 192 | * @priv_flags: private (in-kernel) bridge vlan flags |
a580c76d | 193 | * @state: STP state (e.g. blocking, learning, forwarding) |
6dada9b1 | 194 | * @stats: per-cpu VLAN statistics |
2594e906 NA |
195 | * @br: if MASTER flag set, this points to a bridge struct |
196 | * @port: if MASTER flag unset, this points to a port struct | |
197 | * @refcnt: if MASTER flag set, this is bumped for each port referencing it | |
198 | * @brvlan: if MASTER flag unset, this points to the global per-VLAN context | |
199 | * for this VLAN entry | |
bcc1f84e | 200 | * @tinfo: bridge tunnel info |
613d61db NA |
201 | * @br_mcast_ctx: if MASTER flag set, this is the global vlan multicast context |
202 | * @port_mcast_ctx: if MASTER flag unset, this is the per-port/vlan multicast | |
203 | * context | |
ec7328b5 | 204 | * @msti: if MASTER flag set, this holds the VLANs MST instance |
2594e906 NA |
205 | * @vlist: sorted list of VLAN entries |
206 | * @rcu: used for entry destruction | |
207 | * | |
208 | * This structure is shared between the global per-VLAN entries contained in | |
209 | * the bridge rhashtable and the local per-port per-VLAN entries contained in | |
210 | * the port's rhashtable. The union entries should be interpreted depending on | |
211 | * the entry flags that are set. | |
212 | */ | |
213 | struct net_bridge_vlan { | |
214 | struct rhash_head vnode; | |
efa5356b | 215 | struct rhash_head tnode; |
2594e906 NA |
216 | u16 vid; |
217 | u16 flags; | |
9d332e69 | 218 | u16 priv_flags; |
a580c76d | 219 | u8 state; |
281cc284 | 220 | struct pcpu_sw_netstats __percpu *stats; |
243a2e63 | 221 | union { |
2594e906 NA |
222 | struct net_bridge *br; |
223 | struct net_bridge_port *port; | |
224 | }; | |
225 | union { | |
25127759 | 226 | refcount_t refcnt; |
2594e906 NA |
227 | struct net_bridge_vlan *brvlan; |
228 | }; | |
efa5356b RP |
229 | |
230 | struct br_tunnel_info tinfo; | |
231 | ||
613d61db NA |
232 | union { |
233 | struct net_bridge_mcast br_mcast_ctx; | |
234 | struct net_bridge_mcast_port port_mcast_ctx; | |
235 | }; | |
236 | ||
ec7328b5 TW |
237 | u16 msti; |
238 | ||
2594e906 NA |
239 | struct list_head vlist; |
240 | ||
243a2e63 | 241 | struct rcu_head rcu; |
2594e906 NA |
242 | }; |
243 | ||
244 | /** | |
245 | * struct net_bridge_vlan_group | |
246 | * | |
247 | * @vlan_hash: VLAN entry rhashtable | |
248 | * @vlan_list: sorted VLAN entry list | |
249 | * @num_vlans: number of total VLAN entries | |
77751ee8 | 250 | * @pvid: PVID VLAN id |
a580c76d | 251 | * @pvid_state: PVID's STP state (e.g. forwarding, learning, blocking) |
2594e906 NA |
252 | * |
253 | * IMPORTANT: Be careful when checking if there're VLAN entries using list | |
254 | * primitives because the bridge can have entries in its list which | |
255 | * are just for global context but not for filtering, i.e. they have | |
256 | * the master flag set but not the brentry flag. If you have to check | |
257 | * if there're "real" entries in the bridge please test @num_vlans | |
258 | */ | |
259 | struct net_bridge_vlan_group { | |
260 | struct rhashtable vlan_hash; | |
efa5356b | 261 | struct rhashtable tunnel_hash; |
2594e906 | 262 | struct list_head vlan_list; |
6cbdceeb | 263 | u16 num_vlans; |
77751ee8 | 264 | u16 pvid; |
a580c76d | 265 | u8 pvid_state; |
243a2e63 VY |
266 | }; |
267 | ||
6869c3b0 NA |
268 | /* bridge fdb flags */ |
269 | enum { | |
270 | BR_FDB_LOCAL, | |
29e63fff | 271 | BR_FDB_STATIC, |
e0458d9a | 272 | BR_FDB_STICKY, |
ac3ca6af | 273 | BR_FDB_ADDED_BY_USER, |
b5cd9f7c | 274 | BR_FDB_ADDED_BY_EXT_LEARN, |
d38c6e3d | 275 | BR_FDB_OFFLOADED, |
31cbc39b | 276 | BR_FDB_NOTIFY, |
a35ec8e3 HS |
277 | BR_FDB_NOTIFY_INACTIVE, |
278 | BR_FDB_LOCKED, | |
bdb4dfda | 279 | BR_FDB_DYNAMIC_LEARNED, |
6869c3b0 NA |
280 | }; |
281 | ||
eb793583 NA |
282 | struct net_bridge_fdb_key { |
283 | mac_addr addr; | |
284 | u16 vlan_id; | |
285 | }; | |
286 | ||
1214628c | 287 | struct net_bridge_fdb_entry { |
eb793583 | 288 | struct rhash_head rhnode; |
1da177e4 LT |
289 | struct net_bridge_port *dst; |
290 | ||
eb793583 NA |
291 | struct net_bridge_fdb_key key; |
292 | struct hlist_node fdb_node; | |
6869c3b0 | 293 | unsigned long flags; |
1214628c NA |
294 | |
295 | /* write-heavy members should not affect lookups */ | |
296 | unsigned long updated ____cacheline_aligned_in_smp; | |
297 | unsigned long used; | |
298 | ||
b22fbf22 | 299 | struct rcu_head rcu; |
1da177e4 LT |
300 | }; |
301 | ||
1f78ee14 NA |
302 | struct net_bridge_fdb_flush_desc { |
303 | unsigned long flags; | |
304 | unsigned long flags_mask; | |
305 | int port_ifindex; | |
306 | u16 vlan_id; | |
307 | }; | |
308 | ||
9d06b6d8 ER |
309 | #define MDB_PG_FLAGS_PERMANENT BIT(0) |
310 | #define MDB_PG_FLAGS_OFFLOAD BIT(1) | |
3247b272 | 311 | #define MDB_PG_FLAGS_FAST_LEAVE BIT(2) |
8266a049 | 312 | #define MDB_PG_FLAGS_STAR_EXCL BIT(3) |
9116ffbf | 313 | #define MDB_PG_FLAGS_BLOCKED BIT(4) |
9d06b6d8 | 314 | |
8b671779 NA |
315 | #define PG_SRC_ENT_LIMIT 32 |
316 | ||
317 | #define BR_SGRP_F_DELETE BIT(0) | |
318 | #define BR_SGRP_F_SEND BIT(1) | |
b0812368 | 319 | #define BR_SGRP_F_INSTALLED BIT(2) |
a01ecb17 | 320 | #define BR_SGRP_F_USER_ADDED BIT(3) |
8b671779 | 321 | |
e12cec65 NA |
322 | struct net_bridge_mcast_gc { |
323 | struct hlist_node gc_node; | |
324 | void (*destroy)(struct net_bridge_mcast_gc *gc); | |
325 | }; | |
326 | ||
8b671779 NA |
327 | struct net_bridge_group_src { |
328 | struct hlist_node node; | |
329 | ||
330 | struct br_ip addr; | |
331 | struct net_bridge_port_group *pg; | |
332 | u8 flags; | |
438ef2d0 | 333 | u8 src_query_rexmit_cnt; |
8b671779 NA |
334 | struct timer_list timer; |
335 | ||
336 | struct net_bridge *br; | |
e12cec65 | 337 | struct net_bridge_mcast_gc mcast_gc; |
8b671779 NA |
338 | struct rcu_head rcu; |
339 | }; | |
340 | ||
085b53c8 | 341 | struct net_bridge_port_group_sg_key { |
eb1d1641 | 342 | struct net_bridge_port *port; |
8ef2a9a5 | 343 | struct br_ip addr; |
085b53c8 NA |
344 | }; |
345 | ||
346 | struct net_bridge_port_group { | |
347 | struct net_bridge_port_group __rcu *next; | |
348 | struct net_bridge_port_group_sg_key key; | |
206e7323 | 349 | unsigned char eth_addr[ETH_ALEN] __aligned(2); |
9d06b6d8 | 350 | unsigned char flags; |
8b671779 | 351 | unsigned char filter_mode; |
42c11ccf | 352 | unsigned char grp_query_rexmit_cnt; |
8f8cb77e | 353 | unsigned char rt_protocol; |
6ec0d0ee | 354 | |
8b671779 NA |
355 | struct hlist_head src_list; |
356 | unsigned int src_ents; | |
6ec0d0ee | 357 | struct timer_list timer; |
42c11ccf | 358 | struct timer_list rexmit_timer; |
6ec0d0ee | 359 | struct hlist_node mglist; |
8f07b831 NA |
360 | struct rb_root eht_set_tree; |
361 | struct rb_root eht_host_tree; | |
6ec0d0ee | 362 | |
085b53c8 | 363 | struct rhash_head rhnode; |
e12cec65 | 364 | struct net_bridge_mcast_gc mcast_gc; |
6ec0d0ee | 365 | struct rcu_head rcu; |
eb1d1641 HX |
366 | }; |
367 | ||
1c1cb6d0 | 368 | struct net_bridge_mdb_entry { |
19e3a9c9 | 369 | struct rhash_head rhnode; |
eb1d1641 | 370 | struct net_bridge *br; |
e8051688 | 371 | struct net_bridge_port_group __rcu *ports; |
8ef2a9a5 | 372 | struct br_ip addr; |
ff0fd34e | 373 | bool host_joined; |
6ec0d0ee NA |
374 | |
375 | struct timer_list timer; | |
19e3a9c9 | 376 | struct hlist_node mdb_node; |
6ec0d0ee | 377 | |
e12cec65 | 378 | struct net_bridge_mcast_gc mcast_gc; |
6ec0d0ee | 379 | struct rcu_head rcu; |
eb1d1641 HX |
380 | }; |
381 | ||
1f90c7f3 | 382 | struct net_bridge_port { |
1da177e4 LT |
383 | struct net_bridge *br; |
384 | struct net_device *dev; | |
b2dcdc7f | 385 | netdevice_tracker dev_tracker; |
1da177e4 LT |
386 | struct list_head list; |
387 | ||
1f90c7f3 NA |
388 | unsigned long flags; |
389 | #ifdef CONFIG_BRIDGE_VLAN_FILTERING | |
390 | struct net_bridge_vlan_group __rcu *vlgrp; | |
391 | #endif | |
2756f68c | 392 | struct net_bridge_port __rcu *backup_port; |
29cfb2aa | 393 | u32 backup_nhid; |
1f90c7f3 | 394 | |
1da177e4 LT |
395 | /* STP */ |
396 | u8 priority; | |
397 | u8 state; | |
398 | u16 port_no; | |
399 | unsigned char topology_change_ack; | |
400 | unsigned char config_pending; | |
401 | port_id port_id; | |
402 | port_id designated_port; | |
403 | bridge_id designated_root; | |
404 | bridge_id designated_bridge; | |
405 | u32 path_cost; | |
406 | u32 designated_cost; | |
0c03150e | 407 | unsigned long designated_age; |
1da177e4 LT |
408 | |
409 | struct timer_list forward_delay_timer; | |
410 | struct timer_list hold_timer; | |
411 | struct timer_list message_age_timer; | |
412 | struct kobject kobj; | |
413 | struct rcu_head rcu; | |
3982d3d2 | 414 | |
9632233e NA |
415 | struct net_bridge_mcast_port multicast_ctx; |
416 | ||
eb1d1641 | 417 | #ifdef CONFIG_BRIDGE_IGMP_SNOOPING |
9632233e NA |
418 | struct bridge_mcast_stats __percpu *mcast_stats; |
419 | ||
89268b05 NA |
420 | u32 multicast_eht_hosts_limit; |
421 | u32 multicast_eht_hosts_cnt; | |
eb1d1641 | 422 | struct hlist_head mglist; |
eb1d1641 | 423 | #endif |
e0f43752 SA |
424 | |
425 | #ifdef CONFIG_SYSFS | |
426 | char sysfs_name[IFNAMSIZ]; | |
427 | #endif | |
91d2c34a HX |
428 | |
429 | #ifdef CONFIG_NET_POLL_CONTROLLER | |
430 | struct netpoll *np; | |
431 | #endif | |
6bc506b4 | 432 | #ifdef CONFIG_NET_SWITCHDEV |
f7cf972f TW |
433 | /* Identifier used to group ports that share the same switchdev |
434 | * hardware domain. | |
435 | */ | |
436 | int hwdom; | |
2f5dc00f VO |
437 | int offload_count; |
438 | struct netdev_phys_item_id ppid; | |
6bc506b4 | 439 | #endif |
5af48b59 | 440 | u16 group_fwd_mask; |
2756f68c | 441 | u16 backup_redirected_cnt; |
de179966 VD |
442 | |
443 | struct bridge_stp_xstats stp_xstats; | |
1da177e4 LT |
444 | }; |
445 | ||
705e0dea TH |
446 | #define kobj_to_brport(obj) container_of(obj, struct net_bridge_port, kobj) |
447 | ||
e028e4b8 | 448 | #define br_auto_port(p) ((p)->flags & BR_AUTO_MASK) |
f3a6ddf1 | 449 | #define br_promisc_port(p) ((p)->flags & BR_PROMISC) |
e028e4b8 | 450 | |
b5ed54e9 | 451 | static inline struct net_bridge_port *br_port_get_rcu(const struct net_device *dev) |
452 | { | |
716ec052 | 453 | return rcu_dereference(dev->rx_handler_data); |
b5ed54e9 | 454 | } |
455 | ||
1fb1754a | 456 | static inline struct net_bridge_port *br_port_get_rtnl(const struct net_device *dev) |
b5ed54e9 | 457 | { |
35f861e3 | 458 | return netif_is_bridge_port(dev) ? |
ec1e5610 | 459 | rtnl_dereference(dev->rx_handler_data) : NULL; |
b5ed54e9 | 460 | } |
461 | ||
0baa10ff AS |
462 | static inline struct net_bridge_port *br_port_get_rtnl_rcu(const struct net_device *dev) |
463 | { | |
35f861e3 | 464 | return netif_is_bridge_port(dev) ? |
0baa10ff AS |
465 | rcu_dereference_rtnl(dev->rx_handler_data) : NULL; |
466 | } | |
467 | ||
ae75767e NA |
468 | enum net_bridge_opts { |
469 | BROPT_VLAN_ENABLED, | |
470 | BROPT_VLAN_STATS_ENABLED, | |
8df3510f NA |
471 | BROPT_NF_CALL_IPTABLES, |
472 | BROPT_NF_CALL_IP6TABLES, | |
473 | BROPT_NF_CALL_ARPTABLES, | |
be3664a0 | 474 | BROPT_GROUP_ADDR_SET, |
13cefad2 | 475 | BROPT_MULTICAST_ENABLED, |
675779ad NA |
476 | BROPT_MULTICAST_QUERY_USE_IFADDR, |
477 | BROPT_MULTICAST_STATS_ENABLED, | |
478 | BROPT_HAS_IPV6_ADDR, | |
c69c2cd4 | 479 | BROPT_NEIGH_SUPPRESS_ENABLED, |
3341d917 | 480 | BROPT_MTU_SET_BY_USER, |
9163a0fc | 481 | BROPT_VLAN_STATS_PER_PORT, |
70e4272b | 482 | BROPT_NO_LL_LEARN, |
9c0ec2e7 | 483 | BROPT_VLAN_BRIDGE_BINDING, |
f4b7002a | 484 | BROPT_MCAST_VLAN_SNOOPING_ENABLED, |
ec7328b5 | 485 | BROPT_MST_ENABLED, |
ae75767e NA |
486 | }; |
487 | ||
1f90c7f3 | 488 | struct net_bridge { |
1da177e4 | 489 | spinlock_t lock; |
1f90c7f3 | 490 | spinlock_t hash_lock; |
90c628dd | 491 | struct hlist_head frame_type_list; |
1da177e4 | 492 | struct net_device *dev; |
ae75767e | 493 | unsigned long options; |
1f90c7f3 NA |
494 | /* These fields are accessed on each packet */ |
495 | #ifdef CONFIG_BRIDGE_VLAN_FILTERING | |
1f90c7f3 NA |
496 | __be16 vlan_proto; |
497 | u16 default_pvid; | |
498 | struct net_bridge_vlan_group __rcu *vlgrp; | |
499 | #endif | |
500 | ||
eb793583 | 501 | struct rhashtable fdb_hash_tbl; |
90c628dd | 502 | struct list_head port_list; |
34666d46 | 503 | #if IS_ENABLED(CONFIG_BRIDGE_NETFILTER) |
efb6de9b BT |
504 | union { |
505 | struct rtable fake_rtable; | |
506 | struct rt6_info fake_rt6_info; | |
507 | }; | |
4adf0af6 | 508 | #endif |
515853cc | 509 | u16 group_fwd_mask; |
f2808d22 | 510 | u16 group_fwd_mask_required; |
515853cc | 511 | |
1da177e4 LT |
512 | /* STP */ |
513 | bridge_id designated_root; | |
514 | bridge_id bridge_id; | |
1f90c7f3 NA |
515 | unsigned char topology_change; |
516 | unsigned char topology_change_detected; | |
517 | u16 root_port; | |
1da177e4 LT |
518 | unsigned long max_age; |
519 | unsigned long hello_time; | |
520 | unsigned long forward_delay; | |
1da177e4 | 521 | unsigned long ageing_time; |
34d8acd8 | 522 | unsigned long bridge_max_age; |
1da177e4 LT |
523 | unsigned long bridge_hello_time; |
524 | unsigned long bridge_forward_delay; | |
34d8acd8 | 525 | unsigned long bridge_ageing_time; |
35750b0b | 526 | u32 root_path_cost; |
1da177e4 | 527 | |
fda93d92 | 528 | u8 group_addr[ETH_ALEN]; |
9cde0708 SH |
529 | |
530 | enum { | |
531 | BR_NO_STP, /* no spanning tree */ | |
532 | BR_KERNEL_STP, /* old STP in kernel */ | |
533 | BR_USER_STP, /* new RSTP in userspace */ | |
534 | } stp_enabled; | |
535 | ||
d3d065c0 NA |
536 | struct net_bridge_mcast multicast_ctx; |
537 | ||
eb1d1641 | 538 | #ifdef CONFIG_BRIDGE_IGMP_SNOOPING |
d3d065c0 | 539 | struct bridge_mcast_stats __percpu *mcast_stats; |
eb1d1641 | 540 | |
eb1d1641 HX |
541 | u32 hash_max; |
542 | ||
35750b0b | 543 | spinlock_t multicast_lock; |
eb1d1641 | 544 | |
19e3a9c9 | 545 | struct rhashtable mdb_hash_tbl; |
085b53c8 | 546 | struct rhashtable sg_port_tbl; |
19e3a9c9 | 547 | |
e12cec65 | 548 | struct hlist_head mcast_gc_list; |
19e3a9c9 | 549 | struct hlist_head mdb_list; |
eb1d1641 | 550 | |
e12cec65 | 551 | struct work_struct mcast_gc_work; |
eb1d1641 HX |
552 | #endif |
553 | ||
1da177e4 LT |
554 | struct timer_list hello_timer; |
555 | struct timer_list tcn_timer; | |
556 | struct timer_list topology_change_timer; | |
f7cdee8a | 557 | struct delayed_work gc_work; |
43b98c4a | 558 | struct kobject *ifobj; |
e028e4b8 | 559 | u32 auto_cnt; |
6bc506b4 | 560 | |
bdb4dfda JN |
561 | atomic_t fdb_n_learned; |
562 | u32 fdb_max_learned; | |
563 | ||
6bc506b4 | 564 | #ifdef CONFIG_NET_SWITCHDEV |
f7cf972f TW |
565 | /* Counter used to make sure that hardware domains get unique |
566 | * identifiers in case a bridge spans multiple switchdev instances. | |
567 | */ | |
568 | int last_hwdom; | |
85826610 TW |
569 | /* Bit mask of hardware domain numbers in use */ |
570 | unsigned long busy_hwdoms; | |
6bc506b4 | 571 | #endif |
eb793583 | 572 | struct hlist_head fdb_list; |
4b8d7d4c HV |
573 | |
574 | #if IS_ENABLED(CONFIG_BRIDGE_MRP) | |
0169b820 | 575 | struct hlist_head mrp_list; |
4b8d7d4c | 576 | #endif |
f323aa54 HB |
577 | #if IS_ENABLED(CONFIG_BRIDGE_CFM) |
578 | struct hlist_head mep_list; | |
579 | #endif | |
1da177e4 LT |
580 | }; |
581 | ||
68b7c895 HX |
582 | struct br_input_skb_cb { |
583 | struct net_device *brdev; | |
93fdd47e | 584 | |
3c171f49 | 585 | u16 frag_max_size; |
32dec5dd | 586 | #ifdef CONFIG_BRIDGE_IGMP_SNOOPING |
f12064d1 FW |
587 | u8 igmp; |
588 | u8 mrouters_only:1; | |
32dec5dd | 589 | #endif |
f12064d1 FW |
590 | u8 proxyarp_replied:1; |
591 | u8 src_port_isolated:1; | |
751de201 | 592 | u8 promisc:1; |
20adfa1a | 593 | #ifdef CONFIG_BRIDGE_VLAN_FILTERING |
f12064d1 | 594 | u8 vlan_filtered:1; |
20adfa1a | 595 | #endif |
223fd0ad FW |
596 | #ifdef CONFIG_NETFILTER_FAMILY_BRIDGE |
597 | u8 br_netfilter_broute:1; | |
598 | #endif | |
6bc506b4 IS |
599 | |
600 | #ifdef CONFIG_NET_SWITCHDEV | |
47211192 TW |
601 | /* Set if TX data plane offloading is used towards at least one |
602 | * hardware domain. | |
603 | */ | |
604 | u8 tx_fwd_offload:1; | |
f7cf972f TW |
605 | /* The switchdev hardware domain from which this packet was received. |
606 | * If skb->offload_fwd_mark was set, then this packet was already | |
607 | * forwarded by hardware to the other ports in the source hardware | |
608 | * domain, otherwise it wasn't. | |
609 | */ | |
610 | int src_hwdom; | |
47211192 TW |
611 | /* Bit mask of hardware domains towards this packet has already been |
612 | * transmitted using the TX data plane offload. | |
613 | */ | |
614 | unsigned long fwd_hwdoms; | |
6bc506b4 | 615 | #endif |
29cfb2aa IS |
616 | |
617 | u32 backup_nhid; | |
68b7c895 HX |
618 | }; |
619 | ||
620 | #define BR_INPUT_SKB_CB(__skb) ((struct br_input_skb_cb *)(__skb)->cb) | |
621 | ||
32dec5dd YH |
622 | #ifdef CONFIG_BRIDGE_IGMP_SNOOPING |
623 | # define BR_INPUT_SKB_CB_MROUTERS_ONLY(__skb) (BR_INPUT_SKB_CB(__skb)->mrouters_only) | |
624 | #else | |
625 | # define BR_INPUT_SKB_CB_MROUTERS_ONLY(__skb) (0) | |
626 | #endif | |
627 | ||
28a16c97 | 628 | #define br_printk(level, br, format, args...) \ |
629 | printk(level "%s: " format, (br)->dev->name, ##args) | |
630 | ||
631 | #define br_err(__br, format, args...) \ | |
632 | br_printk(KERN_ERR, __br, format, ##args) | |
633 | #define br_warn(__br, format, args...) \ | |
634 | br_printk(KERN_WARNING, __br, format, ##args) | |
635 | #define br_notice(__br, format, args...) \ | |
636 | br_printk(KERN_NOTICE, __br, format, ##args) | |
637 | #define br_info(__br, format, args...) \ | |
638 | br_printk(KERN_INFO, __br, format, ##args) | |
639 | ||
640 | #define br_debug(br, format, args...) \ | |
641 | pr_debug("%s: " format, (br)->dev->name, ##args) | |
642 | ||
1da177e4 LT |
643 | /* called under bridge lock */ |
644 | static inline int br_is_root_bridge(const struct net_bridge *br) | |
645 | { | |
646 | return !memcmp(&br->bridge_id, &br->designated_root, 8); | |
647 | } | |
648 | ||
2594e906 NA |
649 | /* check if a VLAN entry is global */ |
650 | static inline bool br_vlan_is_master(const struct net_bridge_vlan *v) | |
651 | { | |
652 | return v->flags & BRIDGE_VLAN_INFO_MASTER; | |
653 | } | |
654 | ||
655 | /* check if a VLAN entry is used by the bridge */ | |
656 | static inline bool br_vlan_is_brentry(const struct net_bridge_vlan *v) | |
657 | { | |
658 | return v->flags & BRIDGE_VLAN_INFO_BRENTRY; | |
659 | } | |
660 | ||
6be144f6 | 661 | /* check if we should use the vlan entry, returns false if it's only context */ |
2594e906 NA |
662 | static inline bool br_vlan_should_use(const struct net_bridge_vlan *v) |
663 | { | |
664 | if (br_vlan_is_master(v)) { | |
665 | if (br_vlan_is_brentry(v)) | |
666 | return true; | |
667 | else | |
668 | return false; | |
669 | } | |
670 | ||
671 | return true; | |
672 | } | |
673 | ||
5d1fcaf3 NA |
674 | static inline bool nbp_state_should_learn(const struct net_bridge_port *p) |
675 | { | |
676 | return p->state == BR_STATE_LEARNING || p->state == BR_STATE_FORWARDING; | |
677 | } | |
678 | ||
8f4cc940 | 679 | static inline bool br_vlan_valid_id(u16 vid, struct netlink_ext_ack *extack) |
5a46facb | 680 | { |
8f4cc940 NA |
681 | bool ret = vid > 0 && vid < VLAN_VID_MASK; |
682 | ||
683 | if (!ret) | |
684 | NL_SET_ERR_MSG_MOD(extack, "Vlan id is invalid"); | |
685 | ||
686 | return ret; | |
5a46facb NA |
687 | } |
688 | ||
689 | static inline bool br_vlan_valid_range(const struct bridge_vlan_info *cur, | |
8f4cc940 NA |
690 | const struct bridge_vlan_info *last, |
691 | struct netlink_ext_ack *extack) | |
5a46facb NA |
692 | { |
693 | /* pvid flag is not allowed in ranges */ | |
8f4cc940 NA |
694 | if (cur->flags & BRIDGE_VLAN_INFO_PVID) { |
695 | NL_SET_ERR_MSG_MOD(extack, "Pvid isn't allowed in a range"); | |
5a46facb | 696 | return false; |
8f4cc940 | 697 | } |
5a46facb NA |
698 | |
699 | /* when cur is the range end, check if: | |
700 | * - it has range start flag | |
701 | * - range ids are invalid (end is equal to or before start) | |
702 | */ | |
703 | if (last) { | |
8f4cc940 NA |
704 | if (cur->flags & BRIDGE_VLAN_INFO_RANGE_BEGIN) { |
705 | NL_SET_ERR_MSG_MOD(extack, "Found a new vlan range start while processing one"); | |
5a46facb | 706 | return false; |
8f4cc940 NA |
707 | } else if (!(cur->flags & BRIDGE_VLAN_INFO_RANGE_END)) { |
708 | NL_SET_ERR_MSG_MOD(extack, "Vlan range end flag is missing"); | |
5a46facb | 709 | return false; |
8f4cc940 NA |
710 | } else if (cur->vid <= last->vid) { |
711 | NL_SET_ERR_MSG_MOD(extack, "End vlan id is less than or equal to start vlan id"); | |
712 | return false; | |
713 | } | |
714 | } | |
715 | ||
716 | /* check for required range flags */ | |
717 | if (!(cur->flags & (BRIDGE_VLAN_INFO_RANGE_BEGIN | | |
718 | BRIDGE_VLAN_INFO_RANGE_END))) { | |
719 | NL_SET_ERR_MSG_MOD(extack, "Both vlan range flags are missing"); | |
720 | return false; | |
5a46facb NA |
721 | } |
722 | ||
723 | return true; | |
724 | } | |
725 | ||
2796d846 NA |
726 | static inline u8 br_vlan_multicast_router(const struct net_bridge_vlan *v) |
727 | { | |
728 | u8 mcast_router = MDB_RTR_TYPE_DISABLED; | |
729 | ||
730 | #ifdef CONFIG_BRIDGE_IGMP_SNOOPING | |
731 | if (!br_vlan_is_master(v)) | |
732 | mcast_router = v->port_mcast_ctx.multicast_router; | |
733 | else | |
734 | mcast_router = v->br_mcast_ctx.multicast_router; | |
735 | #endif | |
736 | ||
737 | return mcast_router; | |
738 | } | |
739 | ||
f545923b NA |
740 | static inline int br_afspec_cmd_to_rtm(int cmd) |
741 | { | |
742 | switch (cmd) { | |
743 | case RTM_SETLINK: | |
744 | return RTM_NEWVLAN; | |
745 | case RTM_DELLINK: | |
746 | return RTM_DELVLAN; | |
747 | } | |
748 | ||
749 | return 0; | |
750 | } | |
751 | ||
ae75767e NA |
752 | static inline int br_opt_get(const struct net_bridge *br, |
753 | enum net_bridge_opts opt) | |
754 | { | |
755 | return test_bit(opt, &br->options); | |
756 | } | |
757 | ||
a428afe8 NA |
758 | int br_boolopt_toggle(struct net_bridge *br, enum br_boolopt_id opt, bool on, |
759 | struct netlink_ext_ack *extack); | |
760 | int br_boolopt_get(const struct net_bridge *br, enum br_boolopt_id opt); | |
761 | int br_boolopt_multi_toggle(struct net_bridge *br, | |
762 | struct br_boolopt_multi *bm, | |
763 | struct netlink_ext_ack *extack); | |
764 | void br_boolopt_multi_get(const struct net_bridge *br, | |
765 | struct br_boolopt_multi *bm); | |
ae75767e NA |
766 | void br_opt_toggle(struct net_bridge *br, enum net_bridge_opts opt, bool on); |
767 | ||
7b4858df IS |
768 | #if IS_ENABLED(CONFIG_NET_TC_SKB_EXT) |
769 | static inline void br_tc_skb_miss_set(struct sk_buff *skb, bool miss) | |
770 | { | |
771 | struct tc_skb_ext *ext; | |
772 | ||
773 | if (!tc_skb_ext_tc_enabled()) | |
774 | return; | |
775 | ||
776 | ext = skb_ext_find(skb, TC_SKB_EXT); | |
777 | if (ext) { | |
778 | ext->l2_miss = miss; | |
779 | return; | |
780 | } | |
781 | if (!miss) | |
782 | return; | |
783 | ext = tc_skb_ext_alloc(skb); | |
784 | if (!ext) | |
785 | return; | |
786 | ext->l2_miss = true; | |
787 | } | |
788 | #else | |
789 | static inline void br_tc_skb_miss_set(struct sk_buff *skb, bool miss) | |
790 | { | |
791 | } | |
792 | #endif | |
793 | ||
1da177e4 | 794 | /* br_device.c */ |
348662a1 JP |
795 | void br_dev_setup(struct net_device *dev); |
796 | void br_dev_delete(struct net_device *dev, struct list_head *list); | |
797 | netdev_tx_t br_dev_xmit(struct sk_buff *skb, struct net_device *dev); | |
cfb478da | 798 | #ifdef CONFIG_NET_POLL_CONTROLLER |
91d2c34a HX |
799 | static inline void br_netpoll_send_skb(const struct net_bridge_port *p, |
800 | struct sk_buff *skb) | |
801 | { | |
f78ed220 | 802 | netpoll_send_skb(p->np, skb); |
91d2c34a HX |
803 | } |
804 | ||
a8779ec1 | 805 | int br_netpoll_enable(struct net_bridge_port *p); |
348662a1 | 806 | void br_netpoll_disable(struct net_bridge_port *p); |
cfb478da | 807 | #else |
9f70b0fc | 808 | static inline void br_netpoll_send_skb(const struct net_bridge_port *p, |
91d2c34a HX |
809 | struct sk_buff *skb) |
810 | { | |
811 | } | |
cfb478da | 812 | |
a8779ec1 | 813 | static inline int br_netpoll_enable(struct net_bridge_port *p) |
91d2c34a HX |
814 | { |
815 | return 0; | |
816 | } | |
817 | ||
818 | static inline void br_netpoll_disable(struct net_bridge_port *p) | |
819 | { | |
820 | } | |
cfb478da | 821 | #endif |
1da177e4 LT |
822 | |
823 | /* br_fdb.c */ | |
564445fb NA |
824 | #define FDB_FLUSH_IGNORED_NDM_FLAGS (NTF_MASTER | NTF_SELF) |
825 | #define FDB_FLUSH_ALLOWED_NDM_STATES (NUD_PERMANENT | NUD_NOARP) | |
826 | #define FDB_FLUSH_ALLOWED_NDM_FLAGS (NTF_USE | NTF_EXT_LEARNED | \ | |
827 | NTF_STICKY | NTF_OFFLOADED) | |
828 | ||
348662a1 JP |
829 | int br_fdb_init(void); |
830 | void br_fdb_fini(void); | |
eb793583 NA |
831 | int br_fdb_hash_init(struct net_bridge *br); |
832 | void br_fdb_hash_fini(struct net_bridge *br); | |
1f78ee14 NA |
833 | void br_fdb_flush(struct net_bridge *br, |
834 | const struct net_bridge_fdb_flush_desc *desc); | |
424bb9c9 TM |
835 | void br_fdb_find_delete_local(struct net_bridge *br, |
836 | const struct net_bridge_port *p, | |
837 | const unsigned char *addr, u16 vid); | |
348662a1 JP |
838 | void br_fdb_changeaddr(struct net_bridge_port *p, const unsigned char *newaddr); |
839 | void br_fdb_change_mac_address(struct net_bridge *br, const u8 *newaddr); | |
f7cdee8a | 840 | void br_fdb_cleanup(struct work_struct *work); |
348662a1 | 841 | void br_fdb_delete_by_port(struct net_bridge *br, |
1ea2d020 | 842 | const struct net_bridge_port *p, u16 vid, int do_all); |
bfd0aeac NA |
843 | struct net_bridge_fdb_entry *br_fdb_find_rcu(struct net_bridge *br, |
844 | const unsigned char *addr, | |
845 | __u16 vid); | |
348662a1 JP |
846 | int br_fdb_test_addr(struct net_device *dev, unsigned char *addr); |
847 | int br_fdb_fillbuf(struct net_bridge *br, void *buf, unsigned long count, | |
848 | unsigned long off); | |
f6814fdc VO |
849 | int br_fdb_add_local(struct net_bridge *br, struct net_bridge_port *source, |
850 | const unsigned char *addr, u16 vid); | |
348662a1 | 851 | void br_fdb_update(struct net_bridge *br, struct net_bridge_port *source, |
be0c5677 | 852 | const unsigned char *addr, u16 vid, unsigned long flags); |
348662a1 JP |
853 | |
854 | int br_fdb_delete(struct ndmsg *ndm, struct nlattr *tb[], | |
ca4567f1 AM |
855 | struct net_device *dev, const unsigned char *addr, u16 vid, |
856 | struct netlink_ext_ack *extack); | |
38985e8c | 857 | int br_fdb_delete_bulk(struct nlmsghdr *nlh, struct net_device *dev, |
edaef191 | 858 | struct netlink_ext_ack *extack); |
348662a1 | 859 | int br_fdb_add(struct ndmsg *nlh, struct nlattr *tb[], struct net_device *dev, |
87b0984e PM |
860 | const unsigned char *addr, u16 vid, u16 nlh_flags, |
861 | struct netlink_ext_ack *extack); | |
348662a1 | 862 | int br_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb, |
d297653d | 863 | struct net_device *dev, struct net_device *fdev, int *idx); |
47674562 RP |
864 | int br_fdb_get(struct sk_buff *skb, struct nlattr *tb[], struct net_device *dev, |
865 | const unsigned char *addr, u16 vid, u32 portid, u32 seq, | |
866 | struct netlink_ext_ack *extack); | |
8db24af7 VY |
867 | int br_fdb_sync_static(struct net_bridge *br, struct net_bridge_port *p); |
868 | void br_fdb_unsync_static(struct net_bridge *br, struct net_bridge_port *p); | |
3aeb6617 | 869 | int br_fdb_external_learn_add(struct net_bridge *br, struct net_bridge_port *p, |
45a68787 | 870 | const unsigned char *addr, u16 vid, |
27fabd02 | 871 | bool locked, bool swdev_notify); |
3aeb6617 | 872 | int br_fdb_external_learn_del(struct net_bridge *br, struct net_bridge_port *p, |
161d82de PM |
873 | const unsigned char *addr, u16 vid, |
874 | bool swdev_notify); | |
9fe8bcec | 875 | void br_fdb_offloaded_set(struct net_bridge *br, struct net_bridge_port *p, |
e9ba0fbc | 876 | const unsigned char *addr, u16 vid, bool offloaded); |
1da177e4 LT |
877 | |
878 | /* br_forward.c */ | |
8addd5e7 NA |
879 | enum br_pkt_type { |
880 | BR_PKT_UNICAST, | |
881 | BR_PKT_MULTICAST, | |
882 | BR_PKT_BROADCAST | |
883 | }; | |
0c4b51f0 | 884 | int br_dev_queue_push_xmit(struct net *net, struct sock *sk, struct sk_buff *skb); |
b35c5f63 | 885 | void br_forward(const struct net_bridge_port *to, struct sk_buff *skb, |
37b090e6 | 886 | bool local_rcv, bool local_orig); |
0c4b51f0 | 887 | int br_forward_finish(struct net *net, struct sock *sk, struct sk_buff *skb); |
37b090e6 | 888 | void br_flood(struct net_bridge *br, struct sk_buff *skb, |
e408336a IS |
889 | enum br_pkt_type pkt_type, bool local_rcv, bool local_orig, |
890 | u16 vid); | |
1da177e4 | 891 | |
7d850abd NA |
892 | /* return true if both source port and dest port are isolated */ |
893 | static inline bool br_skb_isolated(const struct net_bridge_port *to, | |
894 | const struct sk_buff *skb) | |
895 | { | |
896 | return BR_INPUT_SKB_CB(skb)->src_port_isolated && | |
897 | (to->flags & BR_ISOLATED); | |
898 | } | |
899 | ||
1da177e4 | 900 | /* br_if.c */ |
faa1cd82 | 901 | void br_port_carrier_check(struct net_bridge_port *p, bool *notified); |
348662a1 JP |
902 | int br_add_bridge(struct net *net, const char *name); |
903 | int br_del_bridge(struct net *net, const char *name); | |
ca752be0 DA |
904 | int br_add_if(struct net_bridge *br, struct net_device *dev, |
905 | struct netlink_ext_ack *extack); | |
348662a1 | 906 | int br_del_if(struct net_bridge *br, struct net_device *dev); |
804b854d | 907 | void br_mtu_auto_adjust(struct net_bridge *br); |
348662a1 JP |
908 | netdev_features_t br_features_recompute(struct net_bridge *br, |
909 | netdev_features_t features); | |
e028e4b8 | 910 | void br_port_flags_change(struct net_bridge_port *port, unsigned long mask); |
2796d0c6 | 911 | void br_manage_promisc(struct net_bridge *br); |
2756f68c | 912 | int nbp_backup_change(struct net_bridge_port *p, struct net_device *backup_dev); |
1da177e4 LT |
913 | |
914 | /* br_input.c */ | |
0c4b51f0 | 915 | int br_handle_frame_finish(struct net *net, struct sock *sk, struct sk_buff *skb); |
9eb8eff0 | 916 | rx_handler_func_t *br_get_rx_handler(const struct net_device *dev); |
1da177e4 | 917 | |
90c628dd HB |
918 | struct br_frame_type { |
919 | __be16 type; | |
920 | int (*frame_handler)(struct net_bridge_port *port, | |
921 | struct sk_buff *skb); | |
922 | struct hlist_node list; | |
923 | }; | |
924 | ||
925 | void br_add_frame(struct net_bridge *br, struct br_frame_type *ft); | |
926 | void br_del_frame(struct net_bridge *br, struct br_frame_type *ft); | |
927 | ||
859828c0 JP |
928 | static inline bool br_rx_handler_check_rcu(const struct net_device *dev) |
929 | { | |
9eb8eff0 | 930 | return rcu_dereference(dev->rx_handler) == br_get_rx_handler(dev); |
859828c0 JP |
931 | } |
932 | ||
4d4fd361 PM |
933 | static inline bool br_rx_handler_check_rtnl(const struct net_device *dev) |
934 | { | |
9eb8eff0 | 935 | return rcu_dereference_rtnl(dev->rx_handler) == br_get_rx_handler(dev); |
4d4fd361 PM |
936 | } |
937 | ||
859828c0 JP |
938 | static inline struct net_bridge_port *br_port_get_check_rcu(const struct net_device *dev) |
939 | { | |
940 | return br_rx_handler_check_rcu(dev) ? br_port_get_rcu(dev) : NULL; | |
941 | } | |
942 | ||
4d4fd361 PM |
943 | static inline struct net_bridge_port * |
944 | br_port_get_check_rtnl(const struct net_device *dev) | |
945 | { | |
946 | return br_rx_handler_check_rtnl(dev) ? br_port_get_rtnl_rcu(dev) : NULL; | |
947 | } | |
948 | ||
1da177e4 | 949 | /* br_ioctl.c */ |
561d8352 AB |
950 | int br_dev_siocdevprivate(struct net_device *dev, struct ifreq *rq, |
951 | void __user *data, int cmd); | |
ad2f99ae AB |
952 | int br_ioctl_stub(struct net *net, struct net_bridge *br, unsigned int cmd, |
953 | struct ifreq *ifr, void __user *uarg); | |
1da177e4 | 954 | |
eb1d1641 HX |
955 | /* br_multicast.c */ |
956 | #ifdef CONFIG_BRIDGE_IGMP_SNOOPING | |
f4b7002a NA |
957 | int br_multicast_rcv(struct net_bridge_mcast **brmctx, |
958 | struct net_bridge_mcast_port **pmctx, | |
959 | struct net_bridge_vlan *vlan, | |
394efd19 | 960 | struct sk_buff *skb, u16 vid); |
6d0259dd IS |
961 | struct net_bridge_mdb_entry * |
962 | br_mdb_entry_skb_get(struct net_bridge_mcast *brmctx, struct sk_buff *skb, | |
963 | u16 vid); | |
1080ab95 | 964 | int br_multicast_add_port(struct net_bridge_port *port); |
348662a1 JP |
965 | void br_multicast_del_port(struct net_bridge_port *port); |
966 | void br_multicast_enable_port(struct net_bridge_port *port); | |
967 | void br_multicast_disable_port(struct net_bridge_port *port); | |
968 | void br_multicast_init(struct net_bridge *br); | |
851d0a73 JH |
969 | void br_multicast_join_snoopers(struct net_bridge *br); |
970 | void br_multicast_leave_snoopers(struct net_bridge *br); | |
348662a1 JP |
971 | void br_multicast_open(struct net_bridge *br); |
972 | void br_multicast_stop(struct net_bridge *br); | |
e10177ab | 973 | void br_multicast_dev_del(struct net_bridge *br); |
adc47037 NA |
974 | void br_multicast_flood(struct net_bridge_mdb_entry *mdst, struct sk_buff *skb, |
975 | struct net_bridge_mcast *brmctx, | |
976 | bool local_rcv, bool local_orig); | |
a97df080 | 977 | int br_multicast_set_router(struct net_bridge_mcast *brmctx, unsigned long val); |
a53581d5 NA |
978 | int br_multicast_set_port_router(struct net_bridge_mcast_port *pmctx, |
979 | unsigned long val); | |
2796d846 | 980 | int br_multicast_set_vlan_router(struct net_bridge_vlan *v, u8 mcast_router); |
ae1ea84b FF |
981 | int br_multicast_toggle(struct net_bridge *br, unsigned long val, |
982 | struct netlink_ext_ack *extack); | |
62938182 | 983 | int br_multicast_set_querier(struct net_bridge_mcast *brmctx, unsigned long val); |
df271cd6 NA |
984 | int br_multicast_set_igmp_version(struct net_bridge_mcast *brmctx, |
985 | unsigned long val); | |
aa2ae3e7 | 986 | #if IS_ENABLED(CONFIG_IPV6) |
df271cd6 NA |
987 | int br_multicast_set_mld_version(struct net_bridge_mcast *brmctx, |
988 | unsigned long val); | |
aa2ae3e7 | 989 | #endif |
348662a1 | 990 | struct net_bridge_mdb_entry * |
19e3a9c9 | 991 | br_mdb_ip_get(struct net_bridge *br, struct br_ip *dst); |
348662a1 | 992 | struct net_bridge_mdb_entry * |
19e3a9c9 | 993 | br_multicast_new_group(struct net_bridge *br, struct br_ip *group); |
348662a1 | 994 | struct net_bridge_port_group * |
f86c3e2c IS |
995 | br_multicast_new_port_group(struct net_bridge_port *port, |
996 | const struct br_ip *group, | |
348662a1 | 997 | struct net_bridge_port_group __rcu *next, |
8b671779 | 998 | unsigned char flags, const unsigned char *src, |
60977a0c PM |
999 | u8 filter_mode, u8 rt_protocol, |
1000 | struct netlink_ext_ack *extack); | |
976b3858 | 1001 | void br_multicast_del_port_group(struct net_bridge_port_group *p); |
19e3a9c9 NA |
1002 | int br_mdb_hash_init(struct net_bridge *br); |
1003 | void br_mdb_hash_fini(struct net_bridge *br); | |
81f19838 NA |
1004 | void br_mdb_notify(struct net_device *dev, struct net_bridge_mdb_entry *mp, |
1005 | struct net_bridge_port_group *pg, int type); | |
1e9ca456 | 1006 | void br_rtr_notify(struct net_device *dev, struct net_bridge_mcast_port *pmctx, |
949f1e39 | 1007 | int type); |
681590bd NA |
1008 | void br_multicast_del_pg(struct net_bridge_mdb_entry *mp, |
1009 | struct net_bridge_port_group *pg, | |
1010 | struct net_bridge_port_group __rcu **pp); | |
adc47037 NA |
1011 | void br_multicast_count(struct net_bridge *br, |
1012 | const struct net_bridge_port *p, | |
a65056ec | 1013 | const struct sk_buff *skb, u8 type, u8 dir); |
1080ab95 | 1014 | int br_multicast_init_stats(struct net_bridge *br); |
b6fe0440 | 1015 | void br_multicast_uninit_stats(struct net_bridge *br); |
1080ab95 NA |
1016 | void br_multicast_get_stats(const struct net_bridge *br, |
1017 | const struct net_bridge_port *p, | |
1018 | struct br_mcast_stats *dest); | |
a1aee20d PM |
1019 | u32 br_multicast_ngroups_get(const struct net_bridge_mcast_port *pmctx); |
1020 | void br_multicast_ngroups_set_max(struct net_bridge_mcast_port *pmctx, u32 max); | |
1021 | u32 br_multicast_ngroups_get_max(const struct net_bridge_mcast_port *pmctx); | |
cc7f5022 IS |
1022 | int br_mdb_add(struct net_device *dev, struct nlattr *tb[], u16 nlmsg_flags, |
1023 | struct netlink_ext_ack *extack); | |
1024 | int br_mdb_del(struct net_device *dev, struct nlattr *tb[], | |
1025 | struct netlink_ext_ack *extack); | |
a6acb535 IS |
1026 | int br_mdb_del_bulk(struct net_device *dev, struct nlattr *tb[], |
1027 | struct netlink_ext_ack *extack); | |
cc7f5022 IS |
1028 | int br_mdb_dump(struct net_device *dev, struct sk_buff *skb, |
1029 | struct netlink_callback *cb); | |
68b380a3 IS |
1030 | int br_mdb_get(struct net_device *dev, struct nlattr *tb[], u32 portid, u32 seq, |
1031 | struct netlink_ext_ack *extack); | |
58d913a3 NA |
1032 | void br_multicast_host_join(const struct net_bridge_mcast *brmctx, |
1033 | struct net_bridge_mdb_entry *mp, bool notify); | |
1bc844ee | 1034 | void br_multicast_host_leave(struct net_bridge_mdb_entry *mp, bool notify); |
8266a049 NA |
1035 | void br_multicast_star_g_handle_mode(struct net_bridge_port_group *pg, |
1036 | u8 filter_mode); | |
1037 | void br_multicast_sg_add_exclude_ports(struct net_bridge_mdb_entry *star_mp, | |
1038 | struct net_bridge_port_group *sg); | |
474ddb37 NA |
1039 | struct net_bridge_group_src * |
1040 | br_multicast_find_group_src(struct net_bridge_port_group *pg, struct br_ip *ip); | |
fd0c6961 IS |
1041 | struct net_bridge_group_src * |
1042 | br_multicast_new_group_src(struct net_bridge_port_group *pg, | |
1043 | struct br_ip *src_ip); | |
083e3534 | 1044 | void __br_multicast_del_group_src(struct net_bridge_group_src *src); |
d5a10222 NA |
1045 | void br_multicast_del_group_src(struct net_bridge_group_src *src, |
1046 | bool fastleave); | |
613d61db NA |
1047 | void br_multicast_ctx_init(struct net_bridge *br, |
1048 | struct net_bridge_vlan *vlan, | |
1049 | struct net_bridge_mcast *brmctx); | |
1050 | void br_multicast_ctx_deinit(struct net_bridge_mcast *brmctx); | |
1051 | void br_multicast_port_ctx_init(struct net_bridge_port *port, | |
1052 | struct net_bridge_vlan *vlan, | |
1053 | struct net_bridge_mcast_port *pmctx); | |
1054 | void br_multicast_port_ctx_deinit(struct net_bridge_mcast_port *pmctx); | |
7b54aaaf | 1055 | void br_multicast_toggle_one_vlan(struct net_bridge_vlan *vlan, bool on); |
f4b7002a NA |
1056 | int br_multicast_toggle_vlan_snooping(struct net_bridge *br, bool on, |
1057 | struct netlink_ext_ack *extack); | |
9dee572c | 1058 | bool br_multicast_toggle_global_vlan(struct net_bridge_vlan *vlan, bool on); |
85b35269 | 1059 | |
dc002875 NA |
1060 | int br_rports_fill_info(struct sk_buff *skb, |
1061 | const struct net_bridge_mcast *brmctx); | |
c7fa1d9b NA |
1062 | int br_multicast_dump_querier_state(struct sk_buff *skb, |
1063 | const struct net_bridge_mcast *brmctx, | |
1064 | int nest_attr); | |
1065 | size_t br_multicast_querier_state_size(void); | |
05d6f38e | 1066 | size_t br_rports_size(const struct net_bridge_mcast *brmctx); |
99b40610 NA |
1067 | void br_multicast_set_query_intvl(struct net_bridge_mcast *brmctx, |
1068 | unsigned long val); | |
f83a112b NA |
1069 | void br_multicast_set_startup_query_intvl(struct net_bridge_mcast *brmctx, |
1070 | unsigned long val); | |
4e51bf44 | 1071 | |
955062b0 NA |
1072 | static inline bool br_group_is_l2(const struct br_ip *group) |
1073 | { | |
1074 | return group->proto == 0; | |
1075 | } | |
1076 | ||
cfd56754 CW |
1077 | #define mlock_dereference(X, br) \ |
1078 | rcu_dereference_protected(X, lockdep_is_held(&br->multicast_lock)) | |
1079 | ||
44ebb081 | 1080 | static inline struct hlist_node * |
adc47037 NA |
1081 | br_multicast_get_first_rport_node(struct net_bridge_mcast *brmctx, |
1082 | struct sk_buff *skb) | |
d3d065c0 | 1083 | { |
a3c02e76 LL |
1084 | #if IS_ENABLED(CONFIG_IPV6) |
1085 | if (skb->protocol == htons(ETH_P_IPV6)) | |
d3d065c0 | 1086 | return rcu_dereference(hlist_first_rcu(&brmctx->ip6_mc_router_list)); |
a3c02e76 | 1087 | #endif |
d3d065c0 | 1088 | return rcu_dereference(hlist_first_rcu(&brmctx->ip4_mc_router_list)); |
44ebb081 LL |
1089 | } |
1090 | ||
1091 | static inline struct net_bridge_port * | |
d3d065c0 NA |
1092 | br_multicast_rport_from_node_skb(struct hlist_node *rp, struct sk_buff *skb) |
1093 | { | |
9632233e NA |
1094 | struct net_bridge_mcast_port *mctx; |
1095 | ||
a3c02e76 LL |
1096 | #if IS_ENABLED(CONFIG_IPV6) |
1097 | if (skb->protocol == htons(ETH_P_IPV6)) | |
9632233e NA |
1098 | mctx = hlist_entry_safe(rp, struct net_bridge_mcast_port, |
1099 | ip6_rlist); | |
1100 | else | |
a3c02e76 | 1101 | #endif |
9632233e NA |
1102 | mctx = hlist_entry_safe(rp, struct net_bridge_mcast_port, |
1103 | ip4_rlist); | |
1104 | ||
1105 | if (mctx) | |
1106 | return mctx->port; | |
1107 | else | |
1108 | return NULL; | |
44ebb081 LL |
1109 | } |
1110 | ||
d3d065c0 | 1111 | static inline bool br_ip4_multicast_is_router(struct net_bridge_mcast *brmctx) |
85b35269 | 1112 | { |
d3d065c0 | 1113 | return timer_pending(&brmctx->ip4_mc_router_timer); |
1a3065a2 LL |
1114 | } |
1115 | ||
d3d065c0 | 1116 | static inline bool br_ip6_multicast_is_router(struct net_bridge_mcast *brmctx) |
1a3065a2 LL |
1117 | { |
1118 | #if IS_ENABLED(CONFIG_IPV6) | |
d3d065c0 | 1119 | return timer_pending(&brmctx->ip6_mc_router_timer); |
1a3065a2 LL |
1120 | #else |
1121 | return false; | |
1122 | #endif | |
1123 | } | |
1124 | ||
1125 | static inline bool | |
adc47037 | 1126 | br_multicast_is_router(struct net_bridge_mcast *brmctx, struct sk_buff *skb) |
1a3065a2 | 1127 | { |
d3d065c0 | 1128 | switch (brmctx->multicast_router) { |
1a3065a2 LL |
1129 | case MDB_RTR_TYPE_PERM: |
1130 | return true; | |
1131 | case MDB_RTR_TYPE_TEMP_QUERY: | |
1132 | if (skb) { | |
1133 | if (skb->protocol == htons(ETH_P_IP)) | |
d3d065c0 | 1134 | return br_ip4_multicast_is_router(brmctx); |
1a3065a2 | 1135 | else if (skb->protocol == htons(ETH_P_IPV6)) |
d3d065c0 | 1136 | return br_ip6_multicast_is_router(brmctx); |
1a3065a2 | 1137 | } else { |
d3d065c0 NA |
1138 | return br_ip4_multicast_is_router(brmctx) || |
1139 | br_ip6_multicast_is_router(brmctx); | |
1a3065a2 LL |
1140 | } |
1141 | fallthrough; | |
1142 | default: | |
1143 | return false; | |
1144 | } | |
85b35269 | 1145 | } |
b00589af | 1146 | |
cc0fdd80 | 1147 | static inline bool |
adc47037 NA |
1148 | __br_multicast_querier_exists(struct net_bridge_mcast *brmctx, |
1149 | struct bridge_mcast_other_query *querier, | |
1150 | const bool is_ipv6) | |
b00589af | 1151 | { |
0888d5f3 | 1152 | bool own_querier_enabled; |
1153 | ||
62938182 | 1154 | if (brmctx->multicast_querier) { |
adc47037 | 1155 | if (is_ipv6 && !br_opt_get(brmctx->br, BROPT_HAS_IPV6_ADDR)) |
0888d5f3 | 1156 | own_querier_enabled = false; |
1157 | else | |
1158 | own_querier_enabled = true; | |
1159 | } else { | |
1160 | own_querier_enabled = false; | |
1161 | } | |
1162 | ||
f5c3eb4b | 1163 | return !timer_pending(&querier->delay_timer) && |
0888d5f3 | 1164 | (own_querier_enabled || timer_pending(&querier->timer)); |
cc0fdd80 LL |
1165 | } |
1166 | ||
adc47037 | 1167 | static inline bool br_multicast_querier_exists(struct net_bridge_mcast *brmctx, |
955062b0 NA |
1168 | struct ethhdr *eth, |
1169 | const struct net_bridge_mdb_entry *mdb) | |
cc0fdd80 LL |
1170 | { |
1171 | switch (eth->h_proto) { | |
1172 | case (htons(ETH_P_IP)): | |
adc47037 NA |
1173 | return __br_multicast_querier_exists(brmctx, |
1174 | &brmctx->ip4_other_query, false); | |
cc0fdd80 LL |
1175 | #if IS_ENABLED(CONFIG_IPV6) |
1176 | case (htons(ETH_P_IPV6)): | |
adc47037 NA |
1177 | return __br_multicast_querier_exists(brmctx, |
1178 | &brmctx->ip6_other_query, true); | |
cc0fdd80 LL |
1179 | #endif |
1180 | default: | |
955062b0 | 1181 | return !!mdb && br_group_is_l2(&mdb->addr); |
cc0fdd80 | 1182 | } |
b00589af | 1183 | } |
1080ab95 | 1184 | |
88d4bd18 NA |
1185 | static inline bool br_multicast_is_star_g(const struct br_ip *ip) |
1186 | { | |
1187 | switch (ip->proto) { | |
1188 | case htons(ETH_P_IP): | |
1189 | return ipv4_is_zeronet(ip->src.ip4); | |
1190 | #if IS_ENABLED(CONFIG_IPV6) | |
1191 | case htons(ETH_P_IPV6): | |
1192 | return ipv6_addr_any(&ip->src.ip6); | |
1193 | #endif | |
1194 | default: | |
1195 | return false; | |
1196 | } | |
1197 | } | |
1198 | ||
adc47037 NA |
1199 | static inline bool |
1200 | br_multicast_should_handle_mode(const struct net_bridge_mcast *brmctx, | |
1201 | __be16 proto) | |
8266a049 NA |
1202 | { |
1203 | switch (proto) { | |
1204 | case htons(ETH_P_IP): | |
adc47037 | 1205 | return !!(brmctx->multicast_igmp_version == 3); |
8266a049 NA |
1206 | #if IS_ENABLED(CONFIG_IPV6) |
1207 | case htons(ETH_P_IPV6): | |
adc47037 | 1208 | return !!(brmctx->multicast_mld_version == 2); |
8266a049 NA |
1209 | #endif |
1210 | default: | |
1211 | return false; | |
1212 | } | |
1213 | } | |
1214 | ||
1080ab95 NA |
1215 | static inline int br_multicast_igmp_type(const struct sk_buff *skb) |
1216 | { | |
1217 | return BR_INPUT_SKB_CB(skb)->igmp; | |
1218 | } | |
42c11ccf | 1219 | |
adc47037 | 1220 | static inline unsigned long br_multicast_lmqt(const struct net_bridge_mcast *brmctx) |
42c11ccf | 1221 | { |
adc47037 NA |
1222 | return brmctx->multicast_last_member_interval * |
1223 | brmctx->multicast_last_member_count; | |
42c11ccf | 1224 | } |
0436862e | 1225 | |
adc47037 | 1226 | static inline unsigned long br_multicast_gmi(const struct net_bridge_mcast *brmctx) |
0436862e | 1227 | { |
fac3cb82 | 1228 | return brmctx->multicast_membership_interval; |
0436862e | 1229 | } |
7b54aaaf NA |
1230 | |
1231 | static inline bool | |
1232 | br_multicast_ctx_is_vlan(const struct net_bridge_mcast *brmctx) | |
1233 | { | |
1234 | return !!brmctx->vlan; | |
1235 | } | |
1236 | ||
1237 | static inline bool | |
1238 | br_multicast_port_ctx_is_vlan(const struct net_bridge_mcast_port *pmctx) | |
1239 | { | |
1240 | return !!pmctx->vlan; | |
1241 | } | |
1242 | ||
1243 | static inline struct net_bridge_mcast * | |
1244 | br_multicast_port_ctx_get_global(const struct net_bridge_mcast_port *pmctx) | |
1245 | { | |
1246 | if (!br_multicast_port_ctx_is_vlan(pmctx)) | |
1247 | return &pmctx->port->br->multicast_ctx; | |
1248 | else | |
1249 | return &pmctx->vlan->brvlan->br_mcast_ctx; | |
1250 | } | |
1251 | ||
1252 | static inline bool | |
1253 | br_multicast_ctx_vlan_global_disabled(const struct net_bridge_mcast *brmctx) | |
1254 | { | |
168fed98 NA |
1255 | return br_multicast_ctx_is_vlan(brmctx) && |
1256 | (!br_opt_get(brmctx->br, BROPT_MCAST_VLAN_SNOOPING_ENABLED) || | |
1257 | !(brmctx->vlan->priv_flags & BR_VLFLAG_GLOBAL_MCAST_ENABLED)); | |
7b54aaaf NA |
1258 | } |
1259 | ||
1260 | static inline bool | |
1261 | br_multicast_ctx_vlan_disabled(const struct net_bridge_mcast *brmctx) | |
1262 | { | |
1263 | return br_multicast_ctx_is_vlan(brmctx) && | |
1264 | !(brmctx->vlan->priv_flags & BR_VLFLAG_MCAST_ENABLED); | |
1265 | } | |
1266 | ||
1267 | static inline bool | |
1268 | br_multicast_port_ctx_vlan_disabled(const struct net_bridge_mcast_port *pmctx) | |
1269 | { | |
1270 | return br_multicast_port_ctx_is_vlan(pmctx) && | |
1271 | !(pmctx->vlan->priv_flags & BR_VLFLAG_MCAST_ENABLED); | |
1272 | } | |
4cdd0d10 NA |
1273 | |
1274 | static inline bool | |
1275 | br_multicast_port_ctx_state_disabled(const struct net_bridge_mcast_port *pmctx) | |
1276 | { | |
1277 | return pmctx->port->state == BR_STATE_DISABLED || | |
1278 | (br_multicast_port_ctx_is_vlan(pmctx) && | |
1279 | (br_multicast_port_ctx_vlan_disabled(pmctx) || | |
1280 | pmctx->vlan->state == BR_STATE_DISABLED)); | |
1281 | } | |
1282 | ||
1283 | static inline bool | |
1284 | br_multicast_port_ctx_state_stopped(const struct net_bridge_mcast_port *pmctx) | |
1285 | { | |
1286 | return br_multicast_port_ctx_state_disabled(pmctx) || | |
1287 | pmctx->port->state == BR_STATE_BLOCKING || | |
1288 | (br_multicast_port_ctx_is_vlan(pmctx) && | |
1289 | pmctx->vlan->state == BR_STATE_BLOCKING); | |
1290 | } | |
df271cd6 | 1291 | |
dc002875 NA |
1292 | static inline bool |
1293 | br_rports_have_mc_router(const struct net_bridge_mcast *brmctx) | |
1294 | { | |
1295 | #if IS_ENABLED(CONFIG_IPV6) | |
1296 | return !hlist_empty(&brmctx->ip4_mc_router_list) || | |
1297 | !hlist_empty(&brmctx->ip6_mc_router_list); | |
1298 | #else | |
1299 | return !hlist_empty(&brmctx->ip4_mc_router_list); | |
1300 | #endif | |
1301 | } | |
1302 | ||
df271cd6 NA |
1303 | static inline bool |
1304 | br_multicast_ctx_options_equal(const struct net_bridge_mcast *brmctx1, | |
1305 | const struct net_bridge_mcast *brmctx2) | |
1306 | { | |
1307 | return brmctx1->multicast_igmp_version == | |
1308 | brmctx2->multicast_igmp_version && | |
931ba87d NA |
1309 | brmctx1->multicast_last_member_count == |
1310 | brmctx2->multicast_last_member_count && | |
50725f6e NA |
1311 | brmctx1->multicast_startup_query_count == |
1312 | brmctx2->multicast_startup_query_count && | |
77f6abab NA |
1313 | brmctx1->multicast_last_member_interval == |
1314 | brmctx2->multicast_last_member_interval && | |
2da0aea2 NA |
1315 | brmctx1->multicast_membership_interval == |
1316 | brmctx2->multicast_membership_interval && | |
cd9269d4 NA |
1317 | brmctx1->multicast_querier_interval == |
1318 | brmctx2->multicast_querier_interval && | |
d6c08aba NA |
1319 | brmctx1->multicast_query_interval == |
1320 | brmctx2->multicast_query_interval && | |
42521450 NA |
1321 | brmctx1->multicast_query_response_interval == |
1322 | brmctx2->multicast_query_response_interval && | |
941121ee NA |
1323 | brmctx1->multicast_startup_query_interval == |
1324 | brmctx2->multicast_startup_query_interval && | |
62938182 | 1325 | brmctx1->multicast_querier == brmctx2->multicast_querier && |
a97df080 | 1326 | brmctx1->multicast_router == brmctx2->multicast_router && |
dc002875 NA |
1327 | !br_rports_have_mc_router(brmctx1) && |
1328 | !br_rports_have_mc_router(brmctx2) && | |
df271cd6 NA |
1329 | #if IS_ENABLED(CONFIG_IPV6) |
1330 | brmctx1->multicast_mld_version == | |
1331 | brmctx2->multicast_mld_version && | |
1332 | #endif | |
1333 | true; | |
1334 | } | |
cb486ce9 NA |
1335 | |
1336 | static inline bool | |
1337 | br_multicast_ctx_matches_vlan_snooping(const struct net_bridge_mcast *brmctx) | |
1338 | { | |
1339 | bool vlan_snooping_enabled; | |
1340 | ||
1341 | vlan_snooping_enabled = !!br_opt_get(brmctx->br, | |
1342 | BROPT_MCAST_VLAN_SNOOPING_ENABLED); | |
1343 | ||
1344 | return !!(vlan_snooping_enabled == br_multicast_ctx_is_vlan(brmctx)); | |
1345 | } | |
eb1d1641 | 1346 | #else |
f4b7002a NA |
1347 | static inline int br_multicast_rcv(struct net_bridge_mcast **brmctx, |
1348 | struct net_bridge_mcast_port **pmctx, | |
1349 | struct net_bridge_vlan *vlan, | |
06499098 VY |
1350 | struct sk_buff *skb, |
1351 | u16 vid) | |
eb1d1641 HX |
1352 | { |
1353 | return 0; | |
1354 | } | |
1355 | ||
6d0259dd IS |
1356 | static inline struct net_bridge_mdb_entry * |
1357 | br_mdb_entry_skb_get(struct net_bridge_mcast *brmctx, struct sk_buff *skb, | |
1358 | u16 vid) | |
eb1d1641 HX |
1359 | { |
1360 | return NULL; | |
1361 | } | |
1362 | ||
1080ab95 | 1363 | static inline int br_multicast_add_port(struct net_bridge_port *port) |
eb1d1641 | 1364 | { |
1080ab95 | 1365 | return 0; |
eb1d1641 HX |
1366 | } |
1367 | ||
1368 | static inline void br_multicast_del_port(struct net_bridge_port *port) | |
1369 | { | |
1370 | } | |
1371 | ||
1372 | static inline void br_multicast_enable_port(struct net_bridge_port *port) | |
1373 | { | |
1374 | } | |
1375 | ||
1376 | static inline void br_multicast_disable_port(struct net_bridge_port *port) | |
1377 | { | |
1378 | } | |
1379 | ||
1380 | static inline void br_multicast_init(struct net_bridge *br) | |
1381 | { | |
1382 | } | |
1383 | ||
851d0a73 JH |
1384 | static inline void br_multicast_join_snoopers(struct net_bridge *br) |
1385 | { | |
1386 | } | |
1387 | ||
1388 | static inline void br_multicast_leave_snoopers(struct net_bridge *br) | |
eb1d1641 HX |
1389 | { |
1390 | } | |
1391 | ||
1392 | static inline void br_multicast_open(struct net_bridge *br) | |
1393 | { | |
1394 | } | |
1395 | ||
1396 | static inline void br_multicast_stop(struct net_bridge *br) | |
1397 | { | |
1398 | } | |
5cb5e947 | 1399 | |
a7ce45a7 NA |
1400 | static inline void br_multicast_dev_del(struct net_bridge *br) |
1401 | { | |
1402 | } | |
1403 | ||
37b090e6 NA |
1404 | static inline void br_multicast_flood(struct net_bridge_mdb_entry *mdst, |
1405 | struct sk_buff *skb, | |
adc47037 | 1406 | struct net_bridge_mcast *brmctx, |
37b090e6 | 1407 | bool local_rcv, bool local_orig) |
5cb5e947 HX |
1408 | { |
1409 | } | |
1410 | ||
adc47037 | 1411 | static inline bool br_multicast_is_router(struct net_bridge_mcast *brmctx, |
bbc6f2cc | 1412 | struct sk_buff *skb) |
eb1d1641 | 1413 | { |
03aaa9e2 | 1414 | return false; |
eb1d1641 | 1415 | } |
37b090e6 | 1416 | |
adc47037 | 1417 | static inline bool br_multicast_querier_exists(struct net_bridge_mcast *brmctx, |
c43fd36f VO |
1418 | struct ethhdr *eth, |
1419 | const struct net_bridge_mdb_entry *mdb) | |
b00589af LL |
1420 | { |
1421 | return false; | |
1422 | } | |
37b090e6 | 1423 | |
cc7f5022 IS |
1424 | static inline int br_mdb_add(struct net_device *dev, struct nlattr *tb[], |
1425 | u16 nlmsg_flags, struct netlink_ext_ack *extack) | |
c009de10 IS |
1426 | { |
1427 | return -EOPNOTSUPP; | |
1428 | } | |
1429 | ||
cc7f5022 IS |
1430 | static inline int br_mdb_del(struct net_device *dev, struct nlattr *tb[], |
1431 | struct netlink_ext_ack *extack) | |
c009de10 IS |
1432 | { |
1433 | return -EOPNOTSUPP; | |
1434 | } | |
1435 | ||
a6acb535 IS |
1436 | static inline int br_mdb_del_bulk(struct net_device *dev, struct nlattr *tb[], |
1437 | struct netlink_ext_ack *extack) | |
1438 | { | |
1439 | return -EOPNOTSUPP; | |
1440 | } | |
1441 | ||
cc7f5022 IS |
1442 | static inline int br_mdb_dump(struct net_device *dev, struct sk_buff *skb, |
1443 | struct netlink_callback *cb) | |
c009de10 IS |
1444 | { |
1445 | return 0; | |
1446 | } | |
1447 | ||
68b380a3 IS |
1448 | static inline int br_mdb_get(struct net_device *dev, struct nlattr *tb[], |
1449 | u32 portid, u32 seq, | |
1450 | struct netlink_ext_ack *extack) | |
1451 | { | |
1452 | return -EOPNOTSUPP; | |
1453 | } | |
1454 | ||
19e3a9c9 NA |
1455 | static inline int br_mdb_hash_init(struct net_bridge *br) |
1456 | { | |
1457 | return 0; | |
1458 | } | |
1459 | ||
1460 | static inline void br_mdb_hash_fini(struct net_bridge *br) | |
1461 | { | |
1462 | } | |
1463 | ||
1080ab95 NA |
1464 | static inline void br_multicast_count(struct net_bridge *br, |
1465 | const struct net_bridge_port *p, | |
a65056ec NA |
1466 | const struct sk_buff *skb, |
1467 | u8 type, u8 dir) | |
1080ab95 NA |
1468 | { |
1469 | } | |
1470 | ||
1471 | static inline int br_multicast_init_stats(struct net_bridge *br) | |
1472 | { | |
1473 | return 0; | |
1474 | } | |
1475 | ||
b6fe0440 IS |
1476 | static inline void br_multicast_uninit_stats(struct net_bridge *br) |
1477 | { | |
1478 | } | |
1479 | ||
1080ab95 NA |
1480 | static inline int br_multicast_igmp_type(const struct sk_buff *skb) |
1481 | { | |
1482 | return 0; | |
1483 | } | |
613d61db NA |
1484 | |
1485 | static inline void br_multicast_ctx_init(struct net_bridge *br, | |
1486 | struct net_bridge_vlan *vlan, | |
1487 | struct net_bridge_mcast *brmctx) | |
1488 | { | |
1489 | } | |
1490 | ||
1491 | static inline void br_multicast_ctx_deinit(struct net_bridge_mcast *brmctx) | |
1492 | { | |
1493 | } | |
1494 | ||
1495 | static inline void br_multicast_port_ctx_init(struct net_bridge_port *port, | |
1496 | struct net_bridge_vlan *vlan, | |
1497 | struct net_bridge_mcast_port *pmctx) | |
1498 | { | |
1499 | } | |
1500 | ||
1501 | static inline void br_multicast_port_ctx_deinit(struct net_bridge_mcast_port *pmctx) | |
1502 | { | |
1503 | } | |
7b54aaaf NA |
1504 | |
1505 | static inline void br_multicast_toggle_one_vlan(struct net_bridge_vlan *vlan, | |
1506 | bool on) | |
1507 | { | |
1508 | } | |
f4b7002a | 1509 | |
f4b7002a NA |
1510 | static inline int br_multicast_toggle_vlan_snooping(struct net_bridge *br, |
1511 | bool on, | |
1512 | struct netlink_ext_ack *extack) | |
1513 | { | |
1514 | return -EOPNOTSUPP; | |
1515 | } | |
9dee572c NA |
1516 | |
1517 | static inline bool br_multicast_toggle_global_vlan(struct net_bridge_vlan *vlan, | |
1518 | bool on) | |
1519 | { | |
1520 | return false; | |
1521 | } | |
4e51bf44 | 1522 | |
df271cd6 NA |
1523 | static inline bool |
1524 | br_multicast_ctx_options_equal(const struct net_bridge_mcast *brmctx1, | |
1525 | const struct net_bridge_mcast *brmctx2) | |
1526 | { | |
1527 | return true; | |
1528 | } | |
85b35269 | 1529 | #endif |
eb1d1641 | 1530 | |
243a2e63 VY |
1531 | /* br_vlan.c */ |
1532 | #ifdef CONFIG_BRIDGE_VLAN_FILTERING | |
77751ee8 NA |
1533 | bool br_allowed_ingress(const struct net_bridge *br, |
1534 | struct net_bridge_vlan_group *vg, struct sk_buff *skb, | |
f4b7002a NA |
1535 | u16 *vid, u8 *state, |
1536 | struct net_bridge_vlan **vlan); | |
77751ee8 | 1537 | bool br_allowed_egress(struct net_bridge_vlan_group *vg, |
348662a1 | 1538 | const struct sk_buff *skb); |
e0d7968a | 1539 | bool br_should_learn(struct net_bridge_port *p, struct sk_buff *skb, u16 *vid); |
348662a1 | 1540 | struct sk_buff *br_handle_vlan(struct net_bridge *br, |
11538d03 | 1541 | const struct net_bridge_port *port, |
2594e906 | 1542 | struct net_bridge_vlan_group *vg, |
348662a1 | 1543 | struct sk_buff *skb); |
f418af63 | 1544 | int br_vlan_add(struct net_bridge *br, u16 vid, u16 flags, |
169327d5 | 1545 | bool *changed, struct netlink_ext_ack *extack); |
348662a1 JP |
1546 | int br_vlan_delete(struct net_bridge *br, u16 vid); |
1547 | void br_vlan_flush(struct net_bridge *br); | |
2594e906 | 1548 | struct net_bridge_vlan *br_vlan_find(struct net_bridge_vlan_group *vg, u16 vid); |
204177f3 | 1549 | void br_recalculate_fwd_mask(struct net_bridge *br); |
9e781401 VO |
1550 | int br_vlan_filter_toggle(struct net_bridge *br, unsigned long val, |
1551 | struct netlink_ext_ack *extack); | |
dcbdf135 VO |
1552 | int __br_vlan_set_proto(struct net_bridge *br, __be16 proto, |
1553 | struct netlink_ext_ack *extack); | |
9e781401 VO |
1554 | int br_vlan_set_proto(struct net_bridge *br, unsigned long val, |
1555 | struct netlink_ext_ack *extack); | |
6dada9b1 | 1556 | int br_vlan_set_stats(struct net_bridge *br, unsigned long val); |
9163a0fc | 1557 | int br_vlan_set_stats_per_port(struct net_bridge *br, unsigned long val); |
5be5a2df | 1558 | int br_vlan_init(struct net_bridge *br); |
9e781401 VO |
1559 | int br_vlan_set_default_pvid(struct net_bridge *br, unsigned long val, |
1560 | struct netlink_ext_ack *extack); | |
169327d5 PM |
1561 | int __br_vlan_set_default_pvid(struct net_bridge *br, u16 pvid, |
1562 | struct netlink_ext_ack *extack); | |
f418af63 | 1563 | int nbp_vlan_add(struct net_bridge_port *port, u16 vid, u16 flags, |
169327d5 | 1564 | bool *changed, struct netlink_ext_ack *extack); |
348662a1 JP |
1565 | int nbp_vlan_delete(struct net_bridge_port *port, u16 vid); |
1566 | void nbp_vlan_flush(struct net_bridge_port *port); | |
169327d5 | 1567 | int nbp_vlan_init(struct net_bridge_port *port, struct netlink_ext_ack *extack); |
2594e906 | 1568 | int nbp_get_num_vlan_infos(struct net_bridge_port *p, u32 filter_mask); |
a60c0903 | 1569 | void br_vlan_get_stats(const struct net_bridge_vlan *v, |
281cc284 | 1570 | struct pcpu_sw_netstats *stats); |
9c0ec2e7 | 1571 | void br_vlan_port_event(struct net_bridge_port *p, unsigned long event); |
091adf9b NA |
1572 | int br_vlan_bridge_event(struct net_device *dev, unsigned long event, |
1573 | void *ptr); | |
8dcea187 NA |
1574 | void br_vlan_rtnl_init(void); |
1575 | void br_vlan_rtnl_uninit(void); | |
cf5bddb9 NA |
1576 | void br_vlan_notify(const struct net_bridge *br, |
1577 | const struct net_bridge_port *p, | |
1578 | u16 vid, u16 vid_range, | |
1579 | int cmd); | |
a5d29ae2 NA |
1580 | bool br_vlan_can_enter_range(const struct net_bridge_vlan *v_curr, |
1581 | const struct net_bridge_vlan *range_end); | |
a37b85c9 | 1582 | |
bcf2766b FF |
1583 | void br_vlan_fill_forward_path_pvid(struct net_bridge *br, |
1584 | struct net_device_path_ctx *ctx, | |
1585 | struct net_device_path *path); | |
1586 | int br_vlan_fill_forward_path_mode(struct net_bridge *br, | |
1587 | struct net_bridge_port *dst, | |
1588 | struct net_device_path *path); | |
1589 | ||
2594e906 NA |
1590 | static inline struct net_bridge_vlan_group *br_vlan_group( |
1591 | const struct net_bridge *br) | |
a37b85c9 | 1592 | { |
907b1e6e | 1593 | return rtnl_dereference(br->vlgrp); |
a37b85c9 VY |
1594 | } |
1595 | ||
2594e906 NA |
1596 | static inline struct net_bridge_vlan_group *nbp_vlan_group( |
1597 | const struct net_bridge_port *p) | |
a37b85c9 | 1598 | { |
907b1e6e NA |
1599 | return rtnl_dereference(p->vlgrp); |
1600 | } | |
1601 | ||
1602 | static inline struct net_bridge_vlan_group *br_vlan_group_rcu( | |
1603 | const struct net_bridge *br) | |
1604 | { | |
1605 | return rcu_dereference(br->vlgrp); | |
1606 | } | |
1607 | ||
1608 | static inline struct net_bridge_vlan_group *nbp_vlan_group_rcu( | |
1609 | const struct net_bridge_port *p) | |
1610 | { | |
1611 | return rcu_dereference(p->vlgrp); | |
a37b85c9 VY |
1612 | } |
1613 | ||
1614 | /* Since bridge now depends on 8021Q module, but the time bridge sees the | |
1615 | * skb, the vlan tag will always be present if the frame was tagged. | |
1616 | */ | |
1617 | static inline int br_vlan_get_tag(const struct sk_buff *skb, u16 *vid) | |
1618 | { | |
1619 | int err = 0; | |
1620 | ||
2594e906 | 1621 | if (skb_vlan_tag_present(skb)) { |
5978f8a9 | 1622 | *vid = skb_vlan_tag_get_id(skb); |
2594e906 | 1623 | } else { |
a37b85c9 VY |
1624 | *vid = 0; |
1625 | err = -EINVAL; | |
1626 | } | |
1627 | ||
1628 | return err; | |
1629 | } | |
78851988 | 1630 | |
77751ee8 | 1631 | static inline u16 br_get_pvid(const struct net_bridge_vlan_group *vg) |
2594e906 | 1632 | { |
77751ee8 | 1633 | if (!vg) |
2594e906 NA |
1634 | return 0; |
1635 | ||
1636 | smp_rmb(); | |
77751ee8 | 1637 | return vg->pvid; |
78851988 VY |
1638 | } |
1639 | ||
8dcea187 NA |
1640 | static inline u16 br_vlan_flags(const struct net_bridge_vlan *v, u16 pvid) |
1641 | { | |
1642 | return v->vid == pvid ? v->flags | BRIDGE_VLAN_INFO_PVID : v->flags; | |
1643 | } | |
243a2e63 | 1644 | #else |
77751ee8 NA |
1645 | static inline bool br_allowed_ingress(const struct net_bridge *br, |
1646 | struct net_bridge_vlan_group *vg, | |
78851988 | 1647 | struct sk_buff *skb, |
f4b7002a NA |
1648 | u16 *vid, u8 *state, |
1649 | struct net_bridge_vlan **vlan) | |
1650 | ||
a37b85c9 | 1651 | { |
f4b7002a | 1652 | *vlan = NULL; |
a37b85c9 VY |
1653 | return true; |
1654 | } | |
1655 | ||
2594e906 | 1656 | static inline bool br_allowed_egress(struct net_bridge_vlan_group *vg, |
85f46c6b VY |
1657 | const struct sk_buff *skb) |
1658 | { | |
1659 | return true; | |
1660 | } | |
1661 | ||
e0d7968a TM |
1662 | static inline bool br_should_learn(struct net_bridge_port *p, |
1663 | struct sk_buff *skb, u16 *vid) | |
1664 | { | |
1665 | return true; | |
1666 | } | |
1667 | ||
78851988 | 1668 | static inline struct sk_buff *br_handle_vlan(struct net_bridge *br, |
11538d03 | 1669 | const struct net_bridge_port *port, |
2594e906 | 1670 | struct net_bridge_vlan_group *vg, |
78851988 VY |
1671 | struct sk_buff *skb) |
1672 | { | |
1673 | return skb; | |
1674 | } | |
1675 | ||
f418af63 | 1676 | static inline int br_vlan_add(struct net_bridge *br, u16 vid, u16 flags, |
169327d5 | 1677 | bool *changed, struct netlink_ext_ack *extack) |
243a2e63 | 1678 | { |
f418af63 | 1679 | *changed = false; |
243a2e63 VY |
1680 | return -EOPNOTSUPP; |
1681 | } | |
1682 | ||
1683 | static inline int br_vlan_delete(struct net_bridge *br, u16 vid) | |
1684 | { | |
1685 | return -EOPNOTSUPP; | |
1686 | } | |
1687 | ||
1688 | static inline void br_vlan_flush(struct net_bridge *br) | |
1689 | { | |
1690 | } | |
1691 | ||
204177f3 TM |
1692 | static inline void br_recalculate_fwd_mask(struct net_bridge *br) |
1693 | { | |
1694 | } | |
1695 | ||
5be5a2df | 1696 | static inline int br_vlan_init(struct net_bridge *br) |
8580e211 | 1697 | { |
5be5a2df | 1698 | return 0; |
8580e211 TM |
1699 | } |
1700 | ||
f418af63 | 1701 | static inline int nbp_vlan_add(struct net_bridge_port *port, u16 vid, u16 flags, |
169327d5 | 1702 | bool *changed, struct netlink_ext_ack *extack) |
243a2e63 | 1703 | { |
f418af63 | 1704 | *changed = false; |
243a2e63 VY |
1705 | return -EOPNOTSUPP; |
1706 | } | |
1707 | ||
1708 | static inline int nbp_vlan_delete(struct net_bridge_port *port, u16 vid) | |
1709 | { | |
1710 | return -EOPNOTSUPP; | |
1711 | } | |
1712 | ||
1713 | static inline void nbp_vlan_flush(struct net_bridge_port *port) | |
1714 | { | |
1715 | } | |
1716 | ||
2594e906 NA |
1717 | static inline struct net_bridge_vlan *br_vlan_find(struct net_bridge_vlan_group *vg, |
1718 | u16 vid) | |
a37b85c9 VY |
1719 | { |
1720 | return NULL; | |
1721 | } | |
1722 | ||
169327d5 PM |
1723 | static inline int nbp_vlan_init(struct net_bridge_port *port, |
1724 | struct netlink_ext_ack *extack) | |
bc9a25d2 | 1725 | { |
2594e906 | 1726 | return 0; |
bc9a25d2 VY |
1727 | } |
1728 | ||
2594e906 | 1729 | static inline u16 br_vlan_get_tag(const struct sk_buff *skb, u16 *tag) |
5be5a2df VY |
1730 | { |
1731 | return 0; | |
1732 | } | |
1733 | ||
77751ee8 | 1734 | static inline u16 br_get_pvid(const struct net_bridge_vlan_group *vg) |
78851988 | 1735 | { |
3df6bf45 | 1736 | return 0; |
78851988 | 1737 | } |
2796d0c6 | 1738 | |
7a572964 | 1739 | static inline int br_vlan_filter_toggle(struct net_bridge *br, |
c97f47e3 VO |
1740 | unsigned long val, |
1741 | struct netlink_ext_ack *extack) | |
a7854037 NA |
1742 | { |
1743 | return -EOPNOTSUPP; | |
1744 | } | |
2594e906 NA |
1745 | |
1746 | static inline int nbp_get_num_vlan_infos(struct net_bridge_port *p, | |
1747 | u32 filter_mask) | |
1748 | { | |
1749 | return 0; | |
1750 | } | |
1751 | ||
bcf2766b FF |
1752 | static inline void br_vlan_fill_forward_path_pvid(struct net_bridge *br, |
1753 | struct net_device_path_ctx *ctx, | |
1754 | struct net_device_path *path) | |
1755 | { | |
1756 | } | |
1757 | ||
1758 | static inline int br_vlan_fill_forward_path_mode(struct net_bridge *br, | |
1759 | struct net_bridge_port *dst, | |
1760 | struct net_device_path *path) | |
1761 | { | |
1762 | return 0; | |
1763 | } | |
1764 | ||
2594e906 NA |
1765 | static inline struct net_bridge_vlan_group *br_vlan_group( |
1766 | const struct net_bridge *br) | |
1767 | { | |
1768 | return NULL; | |
1769 | } | |
1770 | ||
1771 | static inline struct net_bridge_vlan_group *nbp_vlan_group( | |
1772 | const struct net_bridge_port *p) | |
1773 | { | |
1774 | return NULL; | |
1775 | } | |
907b1e6e NA |
1776 | |
1777 | static inline struct net_bridge_vlan_group *br_vlan_group_rcu( | |
1778 | const struct net_bridge *br) | |
1779 | { | |
1780 | return NULL; | |
1781 | } | |
1782 | ||
1783 | static inline struct net_bridge_vlan_group *nbp_vlan_group_rcu( | |
1784 | const struct net_bridge_port *p) | |
1785 | { | |
1786 | return NULL; | |
1787 | } | |
a60c0903 NA |
1788 | |
1789 | static inline void br_vlan_get_stats(const struct net_bridge_vlan *v, | |
281cc284 | 1790 | struct pcpu_sw_netstats *stats) |
a60c0903 NA |
1791 | { |
1792 | } | |
9c0ec2e7 MM |
1793 | |
1794 | static inline void br_vlan_port_event(struct net_bridge_port *p, | |
1795 | unsigned long event) | |
1796 | { | |
1797 | } | |
1798 | ||
091adf9b NA |
1799 | static inline int br_vlan_bridge_event(struct net_device *dev, |
1800 | unsigned long event, void *ptr) | |
9c0ec2e7 | 1801 | { |
091adf9b | 1802 | return 0; |
9c0ec2e7 | 1803 | } |
8dcea187 NA |
1804 | |
1805 | static inline void br_vlan_rtnl_init(void) | |
1806 | { | |
1807 | } | |
1808 | ||
1809 | static inline void br_vlan_rtnl_uninit(void) | |
1810 | { | |
1811 | } | |
cf5bddb9 NA |
1812 | |
1813 | static inline void br_vlan_notify(const struct net_bridge *br, | |
1814 | const struct net_bridge_port *p, | |
1815 | u16 vid, u16 vid_range, | |
1816 | int cmd) | |
1817 | { | |
1818 | } | |
528ae84a NA |
1819 | |
1820 | static inline bool br_vlan_can_enter_range(const struct net_bridge_vlan *v_curr, | |
1821 | const struct net_bridge_vlan *range_end) | |
1822 | { | |
1823 | return true; | |
1824 | } | |
4e51bf44 | 1825 | |
c5f6e5eb VO |
1826 | static inline u16 br_vlan_flags(const struct net_bridge_vlan *v, u16 pvid) |
1827 | { | |
1828 | return 0; | |
1829 | } | |
1830 | ||
243a2e63 VY |
1831 | #endif |
1832 | ||
7a53e718 NA |
1833 | /* br_vlan_options.c */ |
1834 | #ifdef CONFIG_BRIDGE_VLAN_FILTERING | |
99f7c5e0 NA |
1835 | bool br_vlan_opts_eq_range(const struct net_bridge_vlan *v_curr, |
1836 | const struct net_bridge_vlan *range_end); | |
a1aee20d PM |
1837 | bool br_vlan_opts_fill(struct sk_buff *skb, const struct net_bridge_vlan *v, |
1838 | const struct net_bridge_port *p); | |
7a53e718 | 1839 | size_t br_vlan_opts_nl_size(void); |
a5d29ae2 NA |
1840 | int br_vlan_process_options(const struct net_bridge *br, |
1841 | const struct net_bridge_port *p, | |
1842 | struct net_bridge_vlan *range_start, | |
1843 | struct net_bridge_vlan *range_end, | |
1844 | struct nlattr **tb, | |
1845 | struct netlink_ext_ack *extack); | |
47ecd2db NA |
1846 | int br_vlan_rtm_process_global_options(struct net_device *dev, |
1847 | const struct nlattr *attr, | |
1848 | int cmd, | |
1849 | struct netlink_ext_ack *extack); | |
743a53d9 NA |
1850 | bool br_vlan_global_opts_can_enter_range(const struct net_bridge_vlan *v_curr, |
1851 | const struct net_bridge_vlan *r_end); | |
1852 | bool br_vlan_global_opts_fill(struct sk_buff *skb, u16 vid, u16 vid_range, | |
1853 | const struct net_bridge_vlan *v_opts); | |
a580c76d NA |
1854 | |
1855 | /* vlan state manipulation helpers using *_ONCE to annotate lock-free access */ | |
1856 | static inline u8 br_vlan_get_state(const struct net_bridge_vlan *v) | |
1857 | { | |
1858 | return READ_ONCE(v->state); | |
1859 | } | |
1860 | ||
1861 | static inline void br_vlan_set_state(struct net_bridge_vlan *v, u8 state) | |
1862 | { | |
1863 | WRITE_ONCE(v->state, state); | |
1864 | } | |
1865 | ||
1866 | static inline u8 br_vlan_get_pvid_state(const struct net_bridge_vlan_group *vg) | |
1867 | { | |
1868 | return READ_ONCE(vg->pvid_state); | |
1869 | } | |
1870 | ||
1871 | static inline void br_vlan_set_pvid_state(struct net_bridge_vlan_group *vg, | |
1872 | u8 state) | |
1873 | { | |
1874 | WRITE_ONCE(vg->pvid_state, state); | |
1875 | } | |
1876 | ||
1877 | /* learn_allow is true at ingress and false at egress */ | |
1878 | static inline bool br_vlan_state_allowed(u8 state, bool learn_allow) | |
1879 | { | |
1880 | switch (state) { | |
1881 | case BR_STATE_LEARNING: | |
1882 | return learn_allow; | |
1883 | case BR_STATE_FORWARDING: | |
1884 | return true; | |
1885 | default: | |
1886 | return false; | |
1887 | } | |
1888 | } | |
7a53e718 NA |
1889 | #endif |
1890 | ||
ec7328b5 TW |
1891 | /* br_mst.c */ |
1892 | #ifdef CONFIG_BRIDGE_VLAN_FILTERING | |
1893 | DECLARE_STATIC_KEY_FALSE(br_mst_used); | |
1894 | static inline bool br_mst_is_enabled(struct net_bridge *br) | |
1895 | { | |
1896 | return static_branch_unlikely(&br_mst_used) && | |
1897 | br_opt_get(br, BROPT_MST_ENABLED); | |
1898 | } | |
1899 | ||
1900 | int br_mst_set_state(struct net_bridge_port *p, u16 msti, u8 state, | |
1901 | struct netlink_ext_ack *extack); | |
8c678d60 | 1902 | int br_mst_vlan_set_msti(struct net_bridge_vlan *v, u16 msti); |
ec7328b5 TW |
1903 | void br_mst_vlan_init_state(struct net_bridge_vlan *v); |
1904 | int br_mst_set_enabled(struct net_bridge *br, bool on, | |
1905 | struct netlink_ext_ack *extack); | |
122c2948 TW |
1906 | size_t br_mst_info_size(const struct net_bridge_vlan_group *vg); |
1907 | int br_mst_fill_info(struct sk_buff *skb, | |
1908 | const struct net_bridge_vlan_group *vg); | |
1909 | int br_mst_process(struct net_bridge_port *p, const struct nlattr *mst_attr, | |
1910 | struct netlink_ext_ack *extack); | |
ec7328b5 TW |
1911 | #else |
1912 | static inline bool br_mst_is_enabled(struct net_bridge *br) | |
1913 | { | |
1914 | return false; | |
1915 | } | |
1916 | ||
1917 | static inline int br_mst_set_state(struct net_bridge_port *p, u16 msti, | |
1918 | u8 state, struct netlink_ext_ack *extack) | |
1919 | { | |
1920 | return -EOPNOTSUPP; | |
1921 | } | |
1922 | ||
1923 | static inline int br_mst_set_enabled(struct net_bridge *br, bool on, | |
1924 | struct netlink_ext_ack *extack) | |
1925 | { | |
1926 | return -EOPNOTSUPP; | |
1927 | } | |
122c2948 TW |
1928 | |
1929 | static inline size_t br_mst_info_size(const struct net_bridge_vlan_group *vg) | |
1930 | { | |
1931 | return 0; | |
1932 | } | |
1933 | ||
1934 | static inline int br_mst_fill_info(struct sk_buff *skb, | |
1935 | const struct net_bridge_vlan_group *vg) | |
1936 | { | |
1937 | return -EOPNOTSUPP; | |
1938 | } | |
1939 | ||
1940 | static inline int br_mst_process(struct net_bridge_port *p, | |
1941 | const struct nlattr *mst_attr, | |
1942 | struct netlink_ext_ack *extack) | |
1943 | { | |
1944 | return -EOPNOTSUPP; | |
1945 | } | |
ec7328b5 TW |
1946 | #endif |
1947 | ||
1a4ba64d PNA |
1948 | struct nf_br_ops { |
1949 | int (*br_dev_xmit_hook)(struct sk_buff *skb); | |
1950 | }; | |
1951 | extern const struct nf_br_ops __rcu *nf_br_ops; | |
1952 | ||
1da177e4 | 1953 | /* br_netfilter.c */ |
34666d46 PNA |
1954 | #if IS_ENABLED(CONFIG_BRIDGE_NETFILTER) |
1955 | int br_nf_core_init(void); | |
1956 | void br_nf_core_fini(void); | |
348662a1 | 1957 | void br_netfilter_rtable_init(struct net_bridge *); |
c0909713 | 1958 | #else |
34666d46 PNA |
1959 | static inline int br_nf_core_init(void) { return 0; } |
1960 | static inline void br_nf_core_fini(void) {} | |
4adf0af6 | 1961 | #define br_netfilter_rtable_init(x) |
c0909713 | 1962 | #endif |
1da177e4 LT |
1963 | |
1964 | /* br_stp.c */ | |
775dd692 | 1965 | void br_set_state(struct net_bridge_port *p, unsigned int state); |
348662a1 JP |
1966 | struct net_bridge_port *br_get_port(struct net_bridge *br, u16 port_no); |
1967 | void br_init_port(struct net_bridge_port *p); | |
1968 | void br_become_designated_port(struct net_bridge_port *p); | |
1da177e4 | 1969 | |
348662a1 JP |
1970 | void __br_set_forward_delay(struct net_bridge *br, unsigned long t); |
1971 | int br_set_forward_delay(struct net_bridge *br, unsigned long x); | |
1972 | int br_set_hello_time(struct net_bridge *br, unsigned long x); | |
1973 | int br_set_max_age(struct net_bridge *br, unsigned long x); | |
82dd4332 | 1974 | int __set_ageing_time(struct net_device *dev, unsigned long t); |
9e0b27fe | 1975 | int br_set_ageing_time(struct net_bridge *br, clock_t ageing_time); |
14f98f25 | 1976 | |
1977 | ||
1da177e4 | 1978 | /* br_stp_if.c */ |
348662a1 JP |
1979 | void br_stp_enable_bridge(struct net_bridge *br); |
1980 | void br_stp_disable_bridge(struct net_bridge *br); | |
419dba8a HV |
1981 | int br_stp_set_enabled(struct net_bridge *br, unsigned long val, |
1982 | struct netlink_ext_ack *extack); | |
348662a1 JP |
1983 | void br_stp_enable_port(struct net_bridge_port *p); |
1984 | void br_stp_disable_port(struct net_bridge_port *p); | |
1985 | bool br_stp_recalculate_bridge_id(struct net_bridge *br); | |
1986 | void br_stp_change_bridge_id(struct net_bridge *br, const unsigned char *a); | |
1987 | void br_stp_set_bridge_priority(struct net_bridge *br, u16 newprio); | |
1988 | int br_stp_set_port_priority(struct net_bridge_port *p, unsigned long newprio); | |
1989 | int br_stp_set_path_cost(struct net_bridge_port *p, unsigned long path_cost); | |
1990 | ssize_t br_show_bridge_id(char *buf, const struct bridge_id *id); | |
1da177e4 LT |
1991 | |
1992 | /* br_stp_bpdu.c */ | |
7c85fbf0 | 1993 | struct stp_proto; |
348662a1 JP |
1994 | void br_stp_rcv(const struct stp_proto *proto, struct sk_buff *skb, |
1995 | struct net_device *dev); | |
1da177e4 LT |
1996 | |
1997 | /* br_stp_timer.c */ | |
348662a1 JP |
1998 | void br_stp_timer_init(struct net_bridge *br); |
1999 | void br_stp_port_timer_init(struct net_bridge_port *p); | |
2000 | unsigned long br_timer_value(const struct timer_list *timer); | |
1da177e4 LT |
2001 | |
2002 | /* br.c */ | |
e6373c4c | 2003 | #if IS_ENABLED(CONFIG_ATM_LANE) |
da678292 MM |
2004 | extern int (*br_fdb_test_addr_hook)(struct net_device *dev, unsigned char *addr); |
2005 | #endif | |
1da177e4 | 2006 | |
65369933 HV |
2007 | /* br_mrp.c */ |
2008 | #if IS_ENABLED(CONFIG_BRIDGE_MRP) | |
2009 | int br_mrp_parse(struct net_bridge *br, struct net_bridge_port *p, | |
2010 | struct nlattr *attr, int cmd, struct netlink_ext_ack *extack); | |
65369933 HV |
2011 | bool br_mrp_enabled(struct net_bridge *br); |
2012 | void br_mrp_port_del(struct net_bridge *br, struct net_bridge_port *p); | |
df42ef22 | 2013 | int br_mrp_fill_info(struct sk_buff *skb, struct net_bridge *br); |
65369933 HV |
2014 | #else |
2015 | static inline int br_mrp_parse(struct net_bridge *br, struct net_bridge_port *p, | |
2016 | struct nlattr *attr, int cmd, | |
2017 | struct netlink_ext_ack *extack) | |
2018 | { | |
2019 | return -EOPNOTSUPP; | |
2020 | } | |
2021 | ||
65369933 HV |
2022 | static inline bool br_mrp_enabled(struct net_bridge *br) |
2023 | { | |
8741e184 | 2024 | return false; |
65369933 HV |
2025 | } |
2026 | ||
2027 | static inline void br_mrp_port_del(struct net_bridge *br, | |
2028 | struct net_bridge_port *p) | |
2029 | { | |
2030 | } | |
df42ef22 HV |
2031 | |
2032 | static inline int br_mrp_fill_info(struct sk_buff *skb, struct net_bridge *br) | |
2033 | { | |
2034 | return 0; | |
2035 | } | |
2036 | ||
65369933 HV |
2037 | #endif |
2038 | ||
2be665c3 | 2039 | /* br_cfm.c */ |
86a14b79 | 2040 | #if IS_ENABLED(CONFIG_BRIDGE_CFM) |
2be665c3 HB |
2041 | int br_cfm_parse(struct net_bridge *br, struct net_bridge_port *p, |
2042 | struct nlattr *attr, int cmd, struct netlink_ext_ack *extack); | |
2043 | bool br_cfm_created(struct net_bridge *br); | |
86a14b79 | 2044 | void br_cfm_port_del(struct net_bridge *br, struct net_bridge_port *p); |
5e312fc0 | 2045 | int br_cfm_config_fill_info(struct sk_buff *skb, struct net_bridge *br); |
b6d0425b HB |
2046 | int br_cfm_status_fill_info(struct sk_buff *skb, |
2047 | struct net_bridge *br, | |
2048 | bool getlink); | |
2049 | int br_cfm_mep_count(struct net_bridge *br, u32 *count); | |
2050 | int br_cfm_peer_mep_count(struct net_bridge *br, u32 *count); | |
86a14b79 | 2051 | #else |
2be665c3 HB |
2052 | static inline int br_cfm_parse(struct net_bridge *br, struct net_bridge_port *p, |
2053 | struct nlattr *attr, int cmd, | |
2054 | struct netlink_ext_ack *extack) | |
2055 | { | |
2056 | return -EOPNOTSUPP; | |
2057 | } | |
2058 | ||
2059 | static inline bool br_cfm_created(struct net_bridge *br) | |
2060 | { | |
2061 | return false; | |
2062 | } | |
2063 | ||
86a14b79 HB |
2064 | static inline void br_cfm_port_del(struct net_bridge *br, |
2065 | struct net_bridge_port *p) | |
2066 | { | |
2067 | } | |
5e312fc0 HB |
2068 | |
2069 | static inline int br_cfm_config_fill_info(struct sk_buff *skb, struct net_bridge *br) | |
2070 | { | |
2071 | return -EOPNOTSUPP; | |
2072 | } | |
e77824d8 | 2073 | |
b6d0425b HB |
2074 | static inline int br_cfm_status_fill_info(struct sk_buff *skb, |
2075 | struct net_bridge *br, | |
2076 | bool getlink) | |
2077 | { | |
2078 | return -EOPNOTSUPP; | |
2079 | } | |
2080 | ||
2081 | static inline int br_cfm_mep_count(struct net_bridge *br, u32 *count) | |
2082 | { | |
829e050e | 2083 | *count = 0; |
b6d0425b HB |
2084 | return -EOPNOTSUPP; |
2085 | } | |
2086 | ||
2087 | static inline int br_cfm_peer_mep_count(struct net_bridge *br, u32 *count) | |
e77824d8 | 2088 | { |
829e050e | 2089 | *count = 0; |
e77824d8 HB |
2090 | return -EOPNOTSUPP; |
2091 | } | |
86a14b79 HB |
2092 | #endif |
2093 | ||
11dc1f36 | 2094 | /* br_netlink.c */ |
149ddd83 | 2095 | extern struct rtnl_link_ops br_link_ops; |
348662a1 JP |
2096 | int br_netlink_init(void); |
2097 | void br_netlink_fini(void); | |
92899063 NA |
2098 | void br_ifinfo_notify(int event, const struct net_bridge *br, |
2099 | const struct net_bridge_port *port); | |
b6d0425b HB |
2100 | void br_info_notify(int event, const struct net_bridge *br, |
2101 | const struct net_bridge_port *port, u32 filter); | |
2fd527b7 PM |
2102 | int br_setlink(struct net_device *dev, struct nlmsghdr *nlmsg, u16 flags, |
2103 | struct netlink_ext_ack *extack); | |
add511b3 | 2104 | int br_dellink(struct net_device *dev, struct nlmsghdr *nlmsg, u16 flags); |
348662a1 | 2105 | int br_getlink(struct sk_buff *skb, u32 pid, u32 seq, struct net_device *dev, |
46c264da | 2106 | u32 filter_mask, int nlflags); |
f26b2965 NA |
2107 | int br_process_vlan_info(struct net_bridge *br, |
2108 | struct net_bridge_port *p, int cmd, | |
2109 | struct bridge_vlan_info *vinfo_curr, | |
2110 | struct bridge_vlan_info **vinfo_last, | |
2111 | bool *changed, | |
2112 | struct netlink_ext_ack *extack); | |
11dc1f36 | 2113 | |
1da177e4 LT |
2114 | #ifdef CONFIG_SYSFS |
2115 | /* br_sysfs_if.c */ | |
52cf25d0 | 2116 | extern const struct sysfs_ops brport_sysfs_ops; |
348662a1 JP |
2117 | int br_sysfs_addif(struct net_bridge_port *p); |
2118 | int br_sysfs_renameif(struct net_bridge_port *p); | |
1da177e4 LT |
2119 | |
2120 | /* br_sysfs_br.c */ | |
348662a1 JP |
2121 | int br_sysfs_addbr(struct net_device *dev); |
2122 | void br_sysfs_delbr(struct net_device *dev); | |
1da177e4 LT |
2123 | |
2124 | #else | |
2125 | ||
0cb2bbbe LJ |
2126 | static inline int br_sysfs_addif(struct net_bridge_port *p) { return 0; } |
2127 | static inline int br_sysfs_renameif(struct net_bridge_port *p) { return 0; } | |
2128 | static inline int br_sysfs_addbr(struct net_device *dev) { return 0; } | |
2129 | static inline void br_sysfs_delbr(struct net_device *dev) { return; } | |
1da177e4 LT |
2130 | #endif /* CONFIG_SYSFS */ |
2131 | ||
6bc506b4 IS |
2132 | /* br_switchdev.c */ |
2133 | #ifdef CONFIG_NET_SWITCHDEV | |
957e2235 VO |
2134 | int br_switchdev_port_offload(struct net_bridge_port *p, |
2135 | struct net_device *dev, const void *ctx, | |
2136 | struct notifier_block *atomic_nb, | |
2137 | struct notifier_block *blocking_nb, | |
2138 | bool tx_fwd_offload, | |
2139 | struct netlink_ext_ack *extack); | |
2140 | ||
2141 | void br_switchdev_port_unoffload(struct net_bridge_port *p, const void *ctx, | |
2142 | struct notifier_block *atomic_nb, | |
2143 | struct notifier_block *blocking_nb); | |
2144 | ||
f2e2857b PM |
2145 | int br_switchdev_port_replay(struct net_bridge_port *p, |
2146 | struct net_device *dev, const void *ctx, | |
2147 | struct notifier_block *atomic_nb, | |
2148 | struct notifier_block *blocking_nb, | |
2149 | struct netlink_ext_ack *extack); | |
2150 | ||
47211192 TW |
2151 | bool br_switchdev_frame_uses_tx_fwd_offload(struct sk_buff *skb); |
2152 | ||
c5381154 VO |
2153 | void br_switchdev_frame_set_offload_fwd_mark(struct sk_buff *skb); |
2154 | ||
47211192 TW |
2155 | void nbp_switchdev_frame_mark_tx_fwd_offload(const struct net_bridge_port *p, |
2156 | struct sk_buff *skb); | |
2157 | void nbp_switchdev_frame_mark_tx_fwd_to_hwdom(const struct net_bridge_port *p, | |
2158 | struct sk_buff *skb); | |
6bc506b4 IS |
2159 | void nbp_switchdev_frame_mark(const struct net_bridge_port *p, |
2160 | struct sk_buff *skb); | |
2161 | bool nbp_switchdev_allowed_egress(const struct net_bridge_port *p, | |
2162 | const struct sk_buff *skb); | |
3922285d AS |
2163 | int br_switchdev_set_port_flag(struct net_bridge_port *p, |
2164 | unsigned long flags, | |
078bbb85 VO |
2165 | unsigned long mask, |
2166 | struct netlink_ext_ack *extack); | |
6eb38bf8 TW |
2167 | void br_switchdev_fdb_notify(struct net_bridge *br, |
2168 | const struct net_bridge_fdb_entry *fdb, int type); | |
ae039350 VO |
2169 | void br_switchdev_mdb_notify(struct net_device *dev, |
2170 | struct net_bridge_mdb_entry *mp, | |
2171 | struct net_bridge_port_group *pg, | |
2172 | int type); | |
169327d5 | 2173 | int br_switchdev_port_vlan_add(struct net_device *dev, u16 vid, u16 flags, |
8d23a54f | 2174 | bool changed, struct netlink_ext_ack *extack); |
d66e4348 | 2175 | int br_switchdev_port_vlan_del(struct net_device *dev, u16 vid); |
85826610 | 2176 | void br_switchdev_init(struct net_bridge *br); |
f1c2eddf IS |
2177 | |
2178 | static inline void br_switchdev_frame_unmark(struct sk_buff *skb) | |
2179 | { | |
2180 | skb->offload_fwd_mark = 0; | |
2181 | } | |
6bc506b4 | 2182 | #else |
957e2235 VO |
2183 | static inline int |
2184 | br_switchdev_port_offload(struct net_bridge_port *p, | |
2185 | struct net_device *dev, const void *ctx, | |
2186 | struct notifier_block *atomic_nb, | |
2187 | struct notifier_block *blocking_nb, | |
2188 | bool tx_fwd_offload, | |
2189 | struct netlink_ext_ack *extack) | |
2190 | { | |
2191 | return -EOPNOTSUPP; | |
2192 | } | |
2193 | ||
2194 | static inline void | |
2195 | br_switchdev_port_unoffload(struct net_bridge_port *p, const void *ctx, | |
2196 | struct notifier_block *atomic_nb, | |
2197 | struct notifier_block *blocking_nb) | |
2198 | { | |
2199 | } | |
2200 | ||
f2e2857b PM |
2201 | static inline int |
2202 | br_switchdev_port_replay(struct net_bridge_port *p, | |
2203 | struct net_device *dev, const void *ctx, | |
2204 | struct notifier_block *atomic_nb, | |
2205 | struct notifier_block *blocking_nb, | |
2206 | struct netlink_ext_ack *extack) | |
2207 | { | |
2208 | return -EOPNOTSUPP; | |
2209 | } | |
2210 | ||
47211192 TW |
2211 | static inline bool br_switchdev_frame_uses_tx_fwd_offload(struct sk_buff *skb) |
2212 | { | |
2213 | return false; | |
2214 | } | |
2215 | ||
c5381154 VO |
2216 | static inline void br_switchdev_frame_set_offload_fwd_mark(struct sk_buff *skb) |
2217 | { | |
2218 | } | |
2219 | ||
47211192 TW |
2220 | static inline void |
2221 | nbp_switchdev_frame_mark_tx_fwd_offload(const struct net_bridge_port *p, | |
2222 | struct sk_buff *skb) | |
2223 | { | |
2224 | } | |
2225 | ||
2226 | static inline void | |
2227 | nbp_switchdev_frame_mark_tx_fwd_to_hwdom(const struct net_bridge_port *p, | |
2228 | struct sk_buff *skb) | |
2229 | { | |
2230 | } | |
2231 | ||
6bc506b4 IS |
2232 | static inline void nbp_switchdev_frame_mark(const struct net_bridge_port *p, |
2233 | struct sk_buff *skb) | |
2234 | { | |
2235 | } | |
2236 | ||
2237 | static inline bool nbp_switchdev_allowed_egress(const struct net_bridge_port *p, | |
2238 | const struct sk_buff *skb) | |
2239 | { | |
2240 | return true; | |
2241 | } | |
3922285d AS |
2242 | |
2243 | static inline int br_switchdev_set_port_flag(struct net_bridge_port *p, | |
2244 | unsigned long flags, | |
078bbb85 VO |
2245 | unsigned long mask, |
2246 | struct netlink_ext_ack *extack) | |
3922285d AS |
2247 | { |
2248 | return 0; | |
2249 | } | |
6b26b51b | 2250 | |
8d23a54f VO |
2251 | static inline int br_switchdev_port_vlan_add(struct net_device *dev, u16 vid, |
2252 | u16 flags, bool changed, | |
169327d5 | 2253 | struct netlink_ext_ack *extack) |
d66e4348 PM |
2254 | { |
2255 | return -EOPNOTSUPP; | |
2256 | } | |
2257 | ||
2258 | static inline int br_switchdev_port_vlan_del(struct net_device *dev, u16 vid) | |
2259 | { | |
2260 | return -EOPNOTSUPP; | |
2261 | } | |
2262 | ||
6b26b51b | 2263 | static inline void |
6eb38bf8 TW |
2264 | br_switchdev_fdb_notify(struct net_bridge *br, |
2265 | const struct net_bridge_fdb_entry *fdb, int type) | |
6b26b51b AS |
2266 | { |
2267 | } | |
f1c2eddf | 2268 | |
ae039350 VO |
2269 | static inline void br_switchdev_mdb_notify(struct net_device *dev, |
2270 | struct net_bridge_mdb_entry *mp, | |
2271 | struct net_bridge_port_group *pg, | |
2272 | int type) | |
2273 | { | |
2274 | } | |
2275 | ||
f1c2eddf IS |
2276 | static inline void br_switchdev_frame_unmark(struct sk_buff *skb) |
2277 | { | |
2278 | } | |
85826610 | 2279 | |
85826610 TW |
2280 | static inline void br_switchdev_init(struct net_bridge *br) |
2281 | { | |
2282 | } | |
2283 | ||
6bc506b4 IS |
2284 | #endif /* CONFIG_NET_SWITCHDEV */ |
2285 | ||
057658cb | 2286 | /* br_arp_nd_proxy.c */ |
821f1b21 | 2287 | void br_recalculate_neigh_suppress_enabled(struct net_bridge *br); |
057658cb RP |
2288 | void br_do_proxy_suppress_arp(struct sk_buff *skb, struct net_bridge *br, |
2289 | u16 vid, struct net_bridge_port *p); | |
ed842fae RP |
2290 | void br_do_suppress_nd(struct sk_buff *skb, struct net_bridge *br, |
2291 | u16 vid, struct net_bridge_port *p, struct nd_msg *msg); | |
2292 | struct nd_msg *br_is_nd_neigh_msg(struct sk_buff *skb, struct nd_msg *m); | |
3aca683e | 2293 | bool br_is_neigh_suppress_enabled(const struct net_bridge_port *p, u16 vid); |
1da177e4 | 2294 | #endif |