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