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