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