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