.. | .. |
---|
| 1 | +/* SPDX-License-Identifier: GPL-2.0-or-later */ |
---|
1 | 2 | /* |
---|
2 | 3 | * Linux ethernet bridge |
---|
3 | 4 | * |
---|
4 | 5 | * Authors: |
---|
5 | 6 | * Lennert Buytenhek <buytenh@gnu.org> |
---|
6 | | - * |
---|
7 | | - * This program is free software; you can redistribute it and/or |
---|
8 | | - * modify it under the terms of the GNU General Public License |
---|
9 | | - * as published by the Free Software Foundation; either version |
---|
10 | | - * 2 of the License, or (at your option) any later version. |
---|
11 | 7 | */ |
---|
12 | 8 | |
---|
13 | 9 | #ifndef _BR_PRIVATE_H |
---|
.. | .. |
---|
31 | 27 | #define BR_PORT_BITS 10 |
---|
32 | 28 | #define BR_MAX_PORTS (1<<BR_PORT_BITS) |
---|
33 | 29 | |
---|
| 30 | +#define BR_MULTICAST_DEFAULT_HASH_MAX 4096 |
---|
| 31 | + |
---|
34 | 32 | #define BR_VERSION "2.3" |
---|
35 | 33 | |
---|
36 | 34 | /* Control of forwarding link local multicast */ |
---|
.. | .. |
---|
50 | 48 | /* Path to usermode spanning tree program */ |
---|
51 | 49 | #define BR_STP_PROG "/sbin/bridge-stp" |
---|
52 | 50 | |
---|
| 51 | +#define BR_FDB_NOTIFY_SETTABLE_BITS (FDB_NOTIFY_BIT | FDB_NOTIFY_INACTIVE_BIT) |
---|
| 52 | + |
---|
53 | 53 | typedef struct bridge_id bridge_id; |
---|
54 | 54 | typedef struct mac_addr mac_addr; |
---|
55 | 55 | typedef __u16 port_id; |
---|
56 | 56 | |
---|
57 | | -struct bridge_id |
---|
58 | | -{ |
---|
| 57 | +struct bridge_id { |
---|
59 | 58 | unsigned char prio[2]; |
---|
60 | 59 | unsigned char addr[ETH_ALEN]; |
---|
61 | 60 | }; |
---|
62 | 61 | |
---|
63 | | -struct mac_addr |
---|
64 | | -{ |
---|
| 62 | +struct mac_addr { |
---|
65 | 63 | unsigned char addr[ETH_ALEN]; |
---|
66 | 64 | }; |
---|
67 | 65 | |
---|
.. | .. |
---|
104 | 102 | struct metadata_dst __rcu *tunnel_dst; |
---|
105 | 103 | }; |
---|
106 | 104 | |
---|
| 105 | +/* private vlan flags */ |
---|
| 106 | +enum { |
---|
| 107 | + BR_VLFLAG_PER_PORT_STATS = BIT(0), |
---|
| 108 | + BR_VLFLAG_ADDED_BY_SWITCHDEV = BIT(1), |
---|
| 109 | +}; |
---|
| 110 | + |
---|
107 | 111 | /** |
---|
108 | 112 | * struct net_bridge_vlan - per-vlan entry |
---|
109 | 113 | * |
---|
110 | 114 | * @vnode: rhashtable member |
---|
111 | 115 | * @vid: VLAN id |
---|
112 | 116 | * @flags: bridge vlan flags |
---|
| 117 | + * @priv_flags: private (in-kernel) bridge vlan flags |
---|
| 118 | + * @state: STP state (e.g. blocking, learning, forwarding) |
---|
113 | 119 | * @stats: per-cpu VLAN statistics |
---|
114 | 120 | * @br: if MASTER flag set, this points to a bridge struct |
---|
115 | 121 | * @port: if MASTER flag unset, this points to a port struct |
---|
.. | .. |
---|
129 | 135 | struct rhash_head tnode; |
---|
130 | 136 | u16 vid; |
---|
131 | 137 | u16 flags; |
---|
| 138 | + u16 priv_flags; |
---|
| 139 | + u8 state; |
---|
132 | 140 | struct br_vlan_stats __percpu *stats; |
---|
133 | 141 | union { |
---|
134 | 142 | struct net_bridge *br; |
---|
.. | .. |
---|
153 | 161 | * @vlan_list: sorted VLAN entry list |
---|
154 | 162 | * @num_vlans: number of total VLAN entries |
---|
155 | 163 | * @pvid: PVID VLAN id |
---|
| 164 | + * @pvid_state: PVID's STP state (e.g. forwarding, learning, blocking) |
---|
156 | 165 | * |
---|
157 | 166 | * IMPORTANT: Be careful when checking if there're VLAN entries using list |
---|
158 | 167 | * primitives because the bridge can have entries in its list which |
---|
.. | .. |
---|
166 | 175 | struct list_head vlan_list; |
---|
167 | 176 | u16 num_vlans; |
---|
168 | 177 | u16 pvid; |
---|
| 178 | + u8 pvid_state; |
---|
| 179 | +}; |
---|
| 180 | + |
---|
| 181 | +/* bridge fdb flags */ |
---|
| 182 | +enum { |
---|
| 183 | + BR_FDB_LOCAL, |
---|
| 184 | + BR_FDB_STATIC, |
---|
| 185 | + BR_FDB_STICKY, |
---|
| 186 | + BR_FDB_ADDED_BY_USER, |
---|
| 187 | + BR_FDB_ADDED_BY_EXT_LEARN, |
---|
| 188 | + BR_FDB_OFFLOADED, |
---|
| 189 | + BR_FDB_NOTIFY, |
---|
| 190 | + BR_FDB_NOTIFY_INACTIVE |
---|
169 | 191 | }; |
---|
170 | 192 | |
---|
171 | 193 | struct net_bridge_fdb_key { |
---|
.. | .. |
---|
179 | 201 | |
---|
180 | 202 | struct net_bridge_fdb_key key; |
---|
181 | 203 | struct hlist_node fdb_node; |
---|
182 | | - unsigned char is_local:1, |
---|
183 | | - is_static:1, |
---|
184 | | - added_by_user:1, |
---|
185 | | - added_by_external_learn:1, |
---|
186 | | - offloaded:1; |
---|
| 204 | + unsigned long flags; |
---|
187 | 205 | |
---|
188 | 206 | /* write-heavy members should not affect lookups */ |
---|
189 | 207 | unsigned long updated ____cacheline_aligned_in_smp; |
---|
.. | .. |
---|
194 | 212 | |
---|
195 | 213 | #define MDB_PG_FLAGS_PERMANENT BIT(0) |
---|
196 | 214 | #define MDB_PG_FLAGS_OFFLOAD BIT(1) |
---|
| 215 | +#define MDB_PG_FLAGS_FAST_LEAVE BIT(2) |
---|
| 216 | +#define MDB_PG_FLAGS_STAR_EXCL BIT(3) |
---|
| 217 | +#define MDB_PG_FLAGS_BLOCKED BIT(4) |
---|
| 218 | + |
---|
| 219 | +#define PG_SRC_ENT_LIMIT 32 |
---|
| 220 | + |
---|
| 221 | +#define BR_SGRP_F_DELETE BIT(0) |
---|
| 222 | +#define BR_SGRP_F_SEND BIT(1) |
---|
| 223 | +#define BR_SGRP_F_INSTALLED BIT(2) |
---|
| 224 | + |
---|
| 225 | +struct net_bridge_mcast_gc { |
---|
| 226 | + struct hlist_node gc_node; |
---|
| 227 | + void (*destroy)(struct net_bridge_mcast_gc *gc); |
---|
| 228 | +}; |
---|
| 229 | + |
---|
| 230 | +struct net_bridge_group_src { |
---|
| 231 | + struct hlist_node node; |
---|
| 232 | + |
---|
| 233 | + struct br_ip addr; |
---|
| 234 | + struct net_bridge_port_group *pg; |
---|
| 235 | + u8 flags; |
---|
| 236 | + u8 src_query_rexmit_cnt; |
---|
| 237 | + struct timer_list timer; |
---|
| 238 | + |
---|
| 239 | + struct net_bridge *br; |
---|
| 240 | + struct net_bridge_mcast_gc mcast_gc; |
---|
| 241 | + struct rcu_head rcu; |
---|
| 242 | +}; |
---|
| 243 | + |
---|
| 244 | +struct net_bridge_port_group_sg_key { |
---|
| 245 | + struct net_bridge_port *port; |
---|
| 246 | + struct br_ip addr; |
---|
| 247 | +}; |
---|
197 | 248 | |
---|
198 | 249 | struct net_bridge_port_group { |
---|
199 | | - struct net_bridge_port *port; |
---|
200 | 250 | struct net_bridge_port_group __rcu *next; |
---|
201 | | - struct hlist_node mglist; |
---|
202 | | - struct rcu_head rcu; |
---|
203 | | - struct timer_list timer; |
---|
204 | | - struct br_ip addr; |
---|
| 251 | + struct net_bridge_port_group_sg_key key; |
---|
205 | 252 | unsigned char eth_addr[ETH_ALEN] __aligned(2); |
---|
206 | 253 | unsigned char flags; |
---|
| 254 | + unsigned char filter_mode; |
---|
| 255 | + unsigned char grp_query_rexmit_cnt; |
---|
| 256 | + unsigned char rt_protocol; |
---|
| 257 | + |
---|
| 258 | + struct hlist_head src_list; |
---|
| 259 | + unsigned int src_ents; |
---|
| 260 | + struct timer_list timer; |
---|
| 261 | + struct timer_list rexmit_timer; |
---|
| 262 | + struct hlist_node mglist; |
---|
| 263 | + |
---|
| 264 | + struct rhash_head rhnode; |
---|
| 265 | + struct net_bridge_mcast_gc mcast_gc; |
---|
| 266 | + struct rcu_head rcu; |
---|
207 | 267 | }; |
---|
208 | 268 | |
---|
209 | | -struct net_bridge_mdb_entry |
---|
210 | | -{ |
---|
211 | | - struct hlist_node hlist[2]; |
---|
| 269 | +struct net_bridge_mdb_entry { |
---|
| 270 | + struct rhash_head rhnode; |
---|
212 | 271 | struct net_bridge *br; |
---|
213 | 272 | struct net_bridge_port_group __rcu *ports; |
---|
214 | | - struct rcu_head rcu; |
---|
215 | | - struct timer_list timer; |
---|
216 | 273 | struct br_ip addr; |
---|
217 | 274 | bool host_joined; |
---|
218 | | -}; |
---|
219 | 275 | |
---|
220 | | -struct net_bridge_mdb_htable |
---|
221 | | -{ |
---|
222 | | - struct hlist_head *mhash; |
---|
| 276 | + struct timer_list timer; |
---|
| 277 | + struct hlist_node mdb_node; |
---|
| 278 | + |
---|
| 279 | + struct net_bridge_mcast_gc mcast_gc; |
---|
223 | 280 | struct rcu_head rcu; |
---|
224 | | - struct net_bridge_mdb_htable *old; |
---|
225 | | - u32 size; |
---|
226 | | - u32 max; |
---|
227 | | - u32 secret; |
---|
228 | | - u32 ver; |
---|
229 | 281 | }; |
---|
230 | 282 | |
---|
231 | 283 | struct net_bridge_port { |
---|
.. | .. |
---|
283 | 335 | #endif |
---|
284 | 336 | u16 group_fwd_mask; |
---|
285 | 337 | u16 backup_redirected_cnt; |
---|
| 338 | + |
---|
| 339 | + struct bridge_stp_xstats stp_xstats; |
---|
286 | 340 | }; |
---|
287 | 341 | |
---|
288 | 342 | #define kobj_to_brport(obj) container_of(obj, struct net_bridge_port, kobj) |
---|
289 | 343 | |
---|
290 | 344 | #define br_auto_port(p) ((p)->flags & BR_AUTO_MASK) |
---|
291 | 345 | #define br_promisc_port(p) ((p)->flags & BR_PROMISC) |
---|
292 | | - |
---|
293 | | -#define br_port_exists(dev) (dev->priv_flags & IFF_BRIDGE_PORT) |
---|
294 | 346 | |
---|
295 | 347 | static inline struct net_bridge_port *br_port_get_rcu(const struct net_device *dev) |
---|
296 | 348 | { |
---|
.. | .. |
---|
299 | 351 | |
---|
300 | 352 | static inline struct net_bridge_port *br_port_get_rtnl(const struct net_device *dev) |
---|
301 | 353 | { |
---|
302 | | - return br_port_exists(dev) ? |
---|
| 354 | + return netif_is_bridge_port(dev) ? |
---|
303 | 355 | rtnl_dereference(dev->rx_handler_data) : NULL; |
---|
304 | 356 | } |
---|
305 | 357 | |
---|
306 | 358 | static inline struct net_bridge_port *br_port_get_rtnl_rcu(const struct net_device *dev) |
---|
307 | 359 | { |
---|
308 | | - return br_port_exists(dev) ? |
---|
| 360 | + return netif_is_bridge_port(dev) ? |
---|
309 | 361 | rcu_dereference_rtnl(dev->rx_handler_data) : NULL; |
---|
310 | 362 | } |
---|
| 363 | + |
---|
| 364 | +enum net_bridge_opts { |
---|
| 365 | + BROPT_VLAN_ENABLED, |
---|
| 366 | + BROPT_VLAN_STATS_ENABLED, |
---|
| 367 | + BROPT_NF_CALL_IPTABLES, |
---|
| 368 | + BROPT_NF_CALL_IP6TABLES, |
---|
| 369 | + BROPT_NF_CALL_ARPTABLES, |
---|
| 370 | + BROPT_GROUP_ADDR_SET, |
---|
| 371 | + BROPT_MULTICAST_ENABLED, |
---|
| 372 | + BROPT_MULTICAST_QUERIER, |
---|
| 373 | + BROPT_MULTICAST_QUERY_USE_IFADDR, |
---|
| 374 | + BROPT_MULTICAST_STATS_ENABLED, |
---|
| 375 | + BROPT_HAS_IPV6_ADDR, |
---|
| 376 | + BROPT_NEIGH_SUPPRESS_ENABLED, |
---|
| 377 | + BROPT_MTU_SET_BY_USER, |
---|
| 378 | + BROPT_VLAN_STATS_PER_PORT, |
---|
| 379 | + BROPT_NO_LL_LEARN, |
---|
| 380 | + BROPT_VLAN_BRIDGE_BINDING, |
---|
| 381 | +}; |
---|
311 | 382 | |
---|
312 | 383 | struct net_bridge { |
---|
313 | 384 | spinlock_t lock; |
---|
.. | .. |
---|
315 | 386 | struct list_head port_list; |
---|
316 | 387 | struct net_device *dev; |
---|
317 | 388 | struct pcpu_sw_netstats __percpu *stats; |
---|
| 389 | + unsigned long options; |
---|
318 | 390 | /* These fields are accessed on each packet */ |
---|
319 | 391 | #ifdef CONFIG_BRIDGE_VLAN_FILTERING |
---|
320 | | - u8 vlan_enabled; |
---|
321 | | - u8 vlan_stats_enabled; |
---|
322 | 392 | __be16 vlan_proto; |
---|
323 | 393 | u16 default_pvid; |
---|
324 | 394 | struct net_bridge_vlan_group __rcu *vlgrp; |
---|
.. | .. |
---|
330 | 400 | struct rtable fake_rtable; |
---|
331 | 401 | struct rt6_info fake_rt6_info; |
---|
332 | 402 | }; |
---|
333 | | - bool nf_call_iptables; |
---|
334 | | - bool nf_call_ip6tables; |
---|
335 | | - bool nf_call_arptables; |
---|
336 | 403 | #endif |
---|
337 | 404 | u16 group_fwd_mask; |
---|
338 | 405 | u16 group_fwd_mask_required; |
---|
.. | .. |
---|
340 | 407 | /* STP */ |
---|
341 | 408 | bridge_id designated_root; |
---|
342 | 409 | bridge_id bridge_id; |
---|
343 | | - u32 root_path_cost; |
---|
344 | 410 | unsigned char topology_change; |
---|
345 | 411 | unsigned char topology_change_detected; |
---|
346 | 412 | u16 root_port; |
---|
.. | .. |
---|
352 | 418 | unsigned long bridge_hello_time; |
---|
353 | 419 | unsigned long bridge_forward_delay; |
---|
354 | 420 | unsigned long bridge_ageing_time; |
---|
| 421 | + u32 root_path_cost; |
---|
355 | 422 | |
---|
356 | 423 | u8 group_addr[ETH_ALEN]; |
---|
357 | | - bool group_addr_set; |
---|
358 | 424 | |
---|
359 | 425 | enum { |
---|
360 | 426 | BR_NO_STP, /* no spanning tree */ |
---|
.. | .. |
---|
363 | 429 | } stp_enabled; |
---|
364 | 430 | |
---|
365 | 431 | #ifdef CONFIG_BRIDGE_IGMP_SNOOPING |
---|
366 | | - unsigned char multicast_router; |
---|
367 | 432 | |
---|
368 | | - u8 multicast_disabled:1; |
---|
369 | | - u8 multicast_querier:1; |
---|
370 | | - u8 multicast_query_use_ifaddr:1; |
---|
371 | | - u8 has_ipv6_addr:1; |
---|
372 | | - u8 multicast_stats_enabled:1; |
---|
373 | | - |
---|
374 | | - u32 hash_elasticity; |
---|
375 | 433 | u32 hash_max; |
---|
376 | 434 | |
---|
377 | 435 | u32 multicast_last_member_count; |
---|
378 | 436 | u32 multicast_startup_query_count; |
---|
379 | 437 | |
---|
380 | 438 | u8 multicast_igmp_version; |
---|
381 | | - |
---|
| 439 | + u8 multicast_router; |
---|
| 440 | +#if IS_ENABLED(CONFIG_IPV6) |
---|
| 441 | + u8 multicast_mld_version; |
---|
| 442 | +#endif |
---|
| 443 | + spinlock_t multicast_lock; |
---|
382 | 444 | unsigned long multicast_last_member_interval; |
---|
383 | 445 | unsigned long multicast_membership_interval; |
---|
384 | 446 | unsigned long multicast_querier_interval; |
---|
.. | .. |
---|
386 | 448 | unsigned long multicast_query_response_interval; |
---|
387 | 449 | unsigned long multicast_startup_query_interval; |
---|
388 | 450 | |
---|
389 | | - spinlock_t multicast_lock; |
---|
390 | | - struct net_bridge_mdb_htable __rcu *mdb; |
---|
| 451 | + struct rhashtable mdb_hash_tbl; |
---|
| 452 | + struct rhashtable sg_port_tbl; |
---|
| 453 | + |
---|
| 454 | + struct hlist_head mcast_gc_list; |
---|
| 455 | + struct hlist_head mdb_list; |
---|
391 | 456 | struct hlist_head router_list; |
---|
392 | 457 | |
---|
393 | 458 | struct timer_list multicast_router_timer; |
---|
.. | .. |
---|
399 | 464 | struct bridge_mcast_other_query ip6_other_query; |
---|
400 | 465 | struct bridge_mcast_own_query ip6_own_query; |
---|
401 | 466 | struct bridge_mcast_querier ip6_querier; |
---|
402 | | - u8 multicast_mld_version; |
---|
403 | 467 | #endif /* IS_ENABLED(CONFIG_IPV6) */ |
---|
| 468 | + struct work_struct mcast_gc_work; |
---|
404 | 469 | #endif |
---|
405 | 470 | |
---|
406 | 471 | struct timer_list hello_timer; |
---|
.. | .. |
---|
413 | 478 | #ifdef CONFIG_NET_SWITCHDEV |
---|
414 | 479 | int offload_fwd_mark; |
---|
415 | 480 | #endif |
---|
416 | | - bool neigh_suppress_enabled; |
---|
417 | | - bool mtu_set_by_user; |
---|
418 | 481 | struct hlist_head fdb_list; |
---|
| 482 | + |
---|
| 483 | +#if IS_ENABLED(CONFIG_BRIDGE_MRP) |
---|
| 484 | + struct list_head mrp_list; |
---|
| 485 | +#endif |
---|
419 | 486 | }; |
---|
420 | 487 | |
---|
421 | 488 | struct br_input_skb_cb { |
---|
422 | 489 | struct net_device *brdev; |
---|
423 | 490 | |
---|
| 491 | + u16 frag_max_size; |
---|
424 | 492 | #ifdef CONFIG_BRIDGE_IGMP_SNOOPING |
---|
425 | | - int igmp; |
---|
426 | | - int mrouters_only; |
---|
| 493 | + u8 igmp; |
---|
| 494 | + u8 mrouters_only:1; |
---|
427 | 495 | #endif |
---|
428 | | - |
---|
429 | | - bool proxyarp_replied; |
---|
430 | | - bool src_port_isolated; |
---|
431 | | - |
---|
| 496 | + u8 proxyarp_replied:1; |
---|
| 497 | + u8 src_port_isolated:1; |
---|
432 | 498 | #ifdef CONFIG_BRIDGE_VLAN_FILTERING |
---|
433 | | - bool vlan_filtered; |
---|
| 499 | + u8 vlan_filtered:1; |
---|
| 500 | +#endif |
---|
| 501 | +#ifdef CONFIG_NETFILTER_FAMILY_BRIDGE |
---|
| 502 | + u8 br_netfilter_broute:1; |
---|
434 | 503 | #endif |
---|
435 | 504 | |
---|
436 | 505 | #ifdef CONFIG_NET_SWITCHDEV |
---|
.. | .. |
---|
492 | 561 | return true; |
---|
493 | 562 | } |
---|
494 | 563 | |
---|
| 564 | +static inline bool nbp_state_should_learn(const struct net_bridge_port *p) |
---|
| 565 | +{ |
---|
| 566 | + return p->state == BR_STATE_LEARNING || p->state == BR_STATE_FORWARDING; |
---|
| 567 | +} |
---|
| 568 | + |
---|
| 569 | +static inline bool br_vlan_valid_id(u16 vid, struct netlink_ext_ack *extack) |
---|
| 570 | +{ |
---|
| 571 | + bool ret = vid > 0 && vid < VLAN_VID_MASK; |
---|
| 572 | + |
---|
| 573 | + if (!ret) |
---|
| 574 | + NL_SET_ERR_MSG_MOD(extack, "Vlan id is invalid"); |
---|
| 575 | + |
---|
| 576 | + return ret; |
---|
| 577 | +} |
---|
| 578 | + |
---|
| 579 | +static inline bool br_vlan_valid_range(const struct bridge_vlan_info *cur, |
---|
| 580 | + const struct bridge_vlan_info *last, |
---|
| 581 | + struct netlink_ext_ack *extack) |
---|
| 582 | +{ |
---|
| 583 | + /* pvid flag is not allowed in ranges */ |
---|
| 584 | + if (cur->flags & BRIDGE_VLAN_INFO_PVID) { |
---|
| 585 | + NL_SET_ERR_MSG_MOD(extack, "Pvid isn't allowed in a range"); |
---|
| 586 | + return false; |
---|
| 587 | + } |
---|
| 588 | + |
---|
| 589 | + /* when cur is the range end, check if: |
---|
| 590 | + * - it has range start flag |
---|
| 591 | + * - range ids are invalid (end is equal to or before start) |
---|
| 592 | + */ |
---|
| 593 | + if (last) { |
---|
| 594 | + if (cur->flags & BRIDGE_VLAN_INFO_RANGE_BEGIN) { |
---|
| 595 | + NL_SET_ERR_MSG_MOD(extack, "Found a new vlan range start while processing one"); |
---|
| 596 | + return false; |
---|
| 597 | + } else if (!(cur->flags & BRIDGE_VLAN_INFO_RANGE_END)) { |
---|
| 598 | + NL_SET_ERR_MSG_MOD(extack, "Vlan range end flag is missing"); |
---|
| 599 | + return false; |
---|
| 600 | + } else if (cur->vid <= last->vid) { |
---|
| 601 | + NL_SET_ERR_MSG_MOD(extack, "End vlan id is less than or equal to start vlan id"); |
---|
| 602 | + return false; |
---|
| 603 | + } |
---|
| 604 | + } |
---|
| 605 | + |
---|
| 606 | + /* check for required range flags */ |
---|
| 607 | + if (!(cur->flags & (BRIDGE_VLAN_INFO_RANGE_BEGIN | |
---|
| 608 | + BRIDGE_VLAN_INFO_RANGE_END))) { |
---|
| 609 | + NL_SET_ERR_MSG_MOD(extack, "Both vlan range flags are missing"); |
---|
| 610 | + return false; |
---|
| 611 | + } |
---|
| 612 | + |
---|
| 613 | + return true; |
---|
| 614 | +} |
---|
| 615 | + |
---|
| 616 | +static inline int br_afspec_cmd_to_rtm(int cmd) |
---|
| 617 | +{ |
---|
| 618 | + switch (cmd) { |
---|
| 619 | + case RTM_SETLINK: |
---|
| 620 | + return RTM_NEWVLAN; |
---|
| 621 | + case RTM_DELLINK: |
---|
| 622 | + return RTM_DELVLAN; |
---|
| 623 | + } |
---|
| 624 | + |
---|
| 625 | + return 0; |
---|
| 626 | +} |
---|
| 627 | + |
---|
| 628 | +static inline int br_opt_get(const struct net_bridge *br, |
---|
| 629 | + enum net_bridge_opts opt) |
---|
| 630 | +{ |
---|
| 631 | + return test_bit(opt, &br->options); |
---|
| 632 | +} |
---|
| 633 | + |
---|
| 634 | +int br_boolopt_toggle(struct net_bridge *br, enum br_boolopt_id opt, bool on, |
---|
| 635 | + struct netlink_ext_ack *extack); |
---|
| 636 | +int br_boolopt_get(const struct net_bridge *br, enum br_boolopt_id opt); |
---|
| 637 | +int br_boolopt_multi_toggle(struct net_bridge *br, |
---|
| 638 | + struct br_boolopt_multi *bm, |
---|
| 639 | + struct netlink_ext_ack *extack); |
---|
| 640 | +void br_boolopt_multi_get(const struct net_bridge *br, |
---|
| 641 | + struct br_boolopt_multi *bm); |
---|
| 642 | +void br_opt_toggle(struct net_bridge *br, enum net_bridge_opts opt, bool on); |
---|
| 643 | + |
---|
495 | 644 | /* br_device.c */ |
---|
496 | 645 | void br_dev_setup(struct net_device *dev); |
---|
497 | 646 | void br_dev_delete(struct net_device *dev, struct list_head *list); |
---|
.. | .. |
---|
500 | 649 | static inline void br_netpoll_send_skb(const struct net_bridge_port *p, |
---|
501 | 650 | struct sk_buff *skb) |
---|
502 | 651 | { |
---|
503 | | - struct netpoll *np = p->np; |
---|
504 | | - |
---|
505 | | - if (np) |
---|
506 | | - netpoll_send_skb(np, skb); |
---|
| 652 | + netpoll_send_skb(p->np, skb); |
---|
507 | 653 | } |
---|
508 | 654 | |
---|
509 | 655 | int br_netpoll_enable(struct net_bridge_port *p); |
---|
.. | .. |
---|
547 | 693 | int br_fdb_insert(struct net_bridge *br, struct net_bridge_port *source, |
---|
548 | 694 | const unsigned char *addr, u16 vid); |
---|
549 | 695 | void br_fdb_update(struct net_bridge *br, struct net_bridge_port *source, |
---|
550 | | - const unsigned char *addr, u16 vid, bool added_by_user); |
---|
| 696 | + const unsigned char *addr, u16 vid, unsigned long flags); |
---|
551 | 697 | |
---|
552 | 698 | int br_fdb_delete(struct ndmsg *ndm, struct nlattr *tb[], |
---|
553 | 699 | struct net_device *dev, const unsigned char *addr, u16 vid); |
---|
554 | 700 | int br_fdb_add(struct ndmsg *nlh, struct nlattr *tb[], struct net_device *dev, |
---|
555 | | - const unsigned char *addr, u16 vid, u16 nlh_flags); |
---|
| 701 | + const unsigned char *addr, u16 vid, u16 nlh_flags, |
---|
| 702 | + struct netlink_ext_ack *extack); |
---|
556 | 703 | int br_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb, |
---|
557 | 704 | struct net_device *dev, struct net_device *fdev, int *idx); |
---|
| 705 | +int br_fdb_get(struct sk_buff *skb, struct nlattr *tb[], struct net_device *dev, |
---|
| 706 | + const unsigned char *addr, u16 vid, u32 portid, u32 seq, |
---|
| 707 | + struct netlink_ext_ack *extack); |
---|
558 | 708 | int br_fdb_sync_static(struct net_bridge *br, struct net_bridge_port *p); |
---|
559 | 709 | void br_fdb_unsync_static(struct net_bridge *br, struct net_bridge_port *p); |
---|
560 | 710 | int br_fdb_external_learn_add(struct net_bridge *br, struct net_bridge_port *p, |
---|
.. | .. |
---|
564 | 714 | const unsigned char *addr, u16 vid, |
---|
565 | 715 | bool swdev_notify); |
---|
566 | 716 | void br_fdb_offloaded_set(struct net_bridge *br, struct net_bridge_port *p, |
---|
567 | | - const unsigned char *addr, u16 vid); |
---|
| 717 | + const unsigned char *addr, u16 vid, bool offloaded); |
---|
568 | 718 | |
---|
569 | 719 | /* br_forward.c */ |
---|
570 | 720 | enum br_pkt_type { |
---|
.. | .. |
---|
603 | 753 | |
---|
604 | 754 | /* br_input.c */ |
---|
605 | 755 | int br_handle_frame_finish(struct net *net, struct sock *sk, struct sk_buff *skb); |
---|
606 | | -rx_handler_result_t br_handle_frame(struct sk_buff **pskb); |
---|
| 756 | +rx_handler_func_t *br_get_rx_handler(const struct net_device *dev); |
---|
607 | 757 | |
---|
608 | 758 | static inline bool br_rx_handler_check_rcu(const struct net_device *dev) |
---|
609 | 759 | { |
---|
610 | | - return rcu_dereference(dev->rx_handler) == br_handle_frame; |
---|
| 760 | + return rcu_dereference(dev->rx_handler) == br_get_rx_handler(dev); |
---|
611 | 761 | } |
---|
612 | 762 | |
---|
613 | 763 | static inline bool br_rx_handler_check_rtnl(const struct net_device *dev) |
---|
614 | 764 | { |
---|
615 | | - return rcu_dereference_rtnl(dev->rx_handler) == br_handle_frame; |
---|
| 765 | + return rcu_dereference_rtnl(dev->rx_handler) == br_get_rx_handler(dev); |
---|
616 | 766 | } |
---|
617 | 767 | |
---|
618 | 768 | static inline struct net_bridge_port *br_port_get_check_rcu(const struct net_device *dev) |
---|
.. | .. |
---|
633 | 783 | |
---|
634 | 784 | /* br_multicast.c */ |
---|
635 | 785 | #ifdef CONFIG_BRIDGE_IGMP_SNOOPING |
---|
636 | | -extern unsigned int br_mdb_rehash_seq; |
---|
637 | 786 | int br_multicast_rcv(struct net_bridge *br, struct net_bridge_port *port, |
---|
638 | 787 | struct sk_buff *skb, u16 vid); |
---|
639 | 788 | struct net_bridge_mdb_entry *br_mdb_get(struct net_bridge *br, |
---|
.. | .. |
---|
643 | 792 | void br_multicast_enable_port(struct net_bridge_port *port); |
---|
644 | 793 | void br_multicast_disable_port(struct net_bridge_port *port); |
---|
645 | 794 | void br_multicast_init(struct net_bridge *br); |
---|
| 795 | +void br_multicast_join_snoopers(struct net_bridge *br); |
---|
| 796 | +void br_multicast_leave_snoopers(struct net_bridge *br); |
---|
646 | 797 | void br_multicast_open(struct net_bridge *br); |
---|
647 | 798 | void br_multicast_stop(struct net_bridge *br); |
---|
648 | 799 | void br_multicast_dev_del(struct net_bridge *br); |
---|
.. | .. |
---|
658 | 809 | int br_multicast_set_mld_version(struct net_bridge *br, unsigned long val); |
---|
659 | 810 | #endif |
---|
660 | 811 | struct net_bridge_mdb_entry * |
---|
661 | | -br_mdb_ip_get(struct net_bridge_mdb_htable *mdb, struct br_ip *dst); |
---|
| 812 | +br_mdb_ip_get(struct net_bridge *br, struct br_ip *dst); |
---|
662 | 813 | struct net_bridge_mdb_entry * |
---|
663 | | -br_multicast_new_group(struct net_bridge *br, struct net_bridge_port *port, |
---|
664 | | - struct br_ip *group); |
---|
665 | | -void br_multicast_free_pg(struct rcu_head *head); |
---|
| 814 | +br_multicast_new_group(struct net_bridge *br, struct br_ip *group); |
---|
666 | 815 | struct net_bridge_port_group * |
---|
667 | 816 | br_multicast_new_port_group(struct net_bridge_port *port, struct br_ip *group, |
---|
668 | 817 | struct net_bridge_port_group __rcu *next, |
---|
669 | | - unsigned char flags, const unsigned char *src); |
---|
670 | | -void br_mdb_init(void); |
---|
671 | | -void br_mdb_uninit(void); |
---|
672 | | -void br_mdb_notify(struct net_device *dev, struct net_bridge_port *port, |
---|
673 | | - struct br_ip *group, int type, u8 flags); |
---|
| 818 | + unsigned char flags, const unsigned char *src, |
---|
| 819 | + u8 filter_mode, u8 rt_protocol); |
---|
| 820 | +int br_mdb_hash_init(struct net_bridge *br); |
---|
| 821 | +void br_mdb_hash_fini(struct net_bridge *br); |
---|
| 822 | +void br_mdb_notify(struct net_device *dev, struct net_bridge_mdb_entry *mp, |
---|
| 823 | + struct net_bridge_port_group *pg, int type); |
---|
674 | 824 | void br_rtr_notify(struct net_device *dev, struct net_bridge_port *port, |
---|
675 | 825 | int type); |
---|
| 826 | +void br_multicast_del_pg(struct net_bridge_mdb_entry *mp, |
---|
| 827 | + struct net_bridge_port_group *pg, |
---|
| 828 | + struct net_bridge_port_group __rcu **pp); |
---|
676 | 829 | void br_multicast_count(struct net_bridge *br, const struct net_bridge_port *p, |
---|
677 | 830 | const struct sk_buff *skb, u8 type, u8 dir); |
---|
678 | 831 | int br_multicast_init_stats(struct net_bridge *br); |
---|
.. | .. |
---|
680 | 833 | void br_multicast_get_stats(const struct net_bridge *br, |
---|
681 | 834 | const struct net_bridge_port *p, |
---|
682 | 835 | struct br_mcast_stats *dest); |
---|
| 836 | +void br_mdb_init(void); |
---|
| 837 | +void br_mdb_uninit(void); |
---|
| 838 | +void br_multicast_host_join(struct net_bridge_mdb_entry *mp, bool notify); |
---|
| 839 | +void br_multicast_host_leave(struct net_bridge_mdb_entry *mp, bool notify); |
---|
| 840 | +void br_multicast_star_g_handle_mode(struct net_bridge_port_group *pg, |
---|
| 841 | + u8 filter_mode); |
---|
| 842 | +void br_multicast_sg_add_exclude_ports(struct net_bridge_mdb_entry *star_mp, |
---|
| 843 | + struct net_bridge_port_group *sg); |
---|
683 | 844 | |
---|
684 | 845 | #define mlock_dereference(X, br) \ |
---|
685 | 846 | rcu_dereference_protected(X, lockdep_is_held(&br->multicast_lock)) |
---|
.. | .. |
---|
698 | 859 | { |
---|
699 | 860 | bool own_querier_enabled; |
---|
700 | 861 | |
---|
701 | | - if (br->multicast_querier) { |
---|
702 | | - if (is_ipv6 && !br->has_ipv6_addr) |
---|
| 862 | + if (br_opt_get(br, BROPT_MULTICAST_QUERIER)) { |
---|
| 863 | + if (is_ipv6 && !br_opt_get(br, BROPT_HAS_IPV6_ADDR)) |
---|
703 | 864 | own_querier_enabled = false; |
---|
704 | 865 | else |
---|
705 | 866 | own_querier_enabled = true; |
---|
.. | .. |
---|
728 | 889 | } |
---|
729 | 890 | } |
---|
730 | 891 | |
---|
| 892 | +static inline bool br_multicast_is_star_g(const struct br_ip *ip) |
---|
| 893 | +{ |
---|
| 894 | + switch (ip->proto) { |
---|
| 895 | + case htons(ETH_P_IP): |
---|
| 896 | + return ipv4_is_zeronet(ip->src.ip4); |
---|
| 897 | +#if IS_ENABLED(CONFIG_IPV6) |
---|
| 898 | + case htons(ETH_P_IPV6): |
---|
| 899 | + return ipv6_addr_any(&ip->src.ip6); |
---|
| 900 | +#endif |
---|
| 901 | + default: |
---|
| 902 | + return false; |
---|
| 903 | + } |
---|
| 904 | +} |
---|
| 905 | + |
---|
| 906 | +static inline bool br_multicast_should_handle_mode(const struct net_bridge *br, |
---|
| 907 | + __be16 proto) |
---|
| 908 | +{ |
---|
| 909 | + switch (proto) { |
---|
| 910 | + case htons(ETH_P_IP): |
---|
| 911 | + return !!(br->multicast_igmp_version == 3); |
---|
| 912 | +#if IS_ENABLED(CONFIG_IPV6) |
---|
| 913 | + case htons(ETH_P_IPV6): |
---|
| 914 | + return !!(br->multicast_mld_version == 2); |
---|
| 915 | +#endif |
---|
| 916 | + default: |
---|
| 917 | + return false; |
---|
| 918 | + } |
---|
| 919 | +} |
---|
| 920 | + |
---|
731 | 921 | static inline int br_multicast_igmp_type(const struct sk_buff *skb) |
---|
732 | 922 | { |
---|
733 | 923 | return BR_INPUT_SKB_CB(skb)->igmp; |
---|
| 924 | +} |
---|
| 925 | + |
---|
| 926 | +static inline unsigned long br_multicast_lmqt(const struct net_bridge *br) |
---|
| 927 | +{ |
---|
| 928 | + return br->multicast_last_member_interval * |
---|
| 929 | + br->multicast_last_member_count; |
---|
| 930 | +} |
---|
| 931 | + |
---|
| 932 | +static inline unsigned long br_multicast_gmi(const struct net_bridge *br) |
---|
| 933 | +{ |
---|
| 934 | + return br->multicast_membership_interval; |
---|
734 | 935 | } |
---|
735 | 936 | #else |
---|
736 | 937 | static inline int br_multicast_rcv(struct net_bridge *br, |
---|
.. | .. |
---|
765 | 966 | } |
---|
766 | 967 | |
---|
767 | 968 | static inline void br_multicast_init(struct net_bridge *br) |
---|
| 969 | +{ |
---|
| 970 | +} |
---|
| 971 | + |
---|
| 972 | +static inline void br_multicast_join_snoopers(struct net_bridge *br) |
---|
| 973 | +{ |
---|
| 974 | +} |
---|
| 975 | + |
---|
| 976 | +static inline void br_multicast_leave_snoopers(struct net_bridge *br) |
---|
768 | 977 | { |
---|
769 | 978 | } |
---|
770 | 979 | |
---|
.. | .. |
---|
805 | 1014 | { |
---|
806 | 1015 | } |
---|
807 | 1016 | |
---|
| 1017 | +static inline int br_mdb_hash_init(struct net_bridge *br) |
---|
| 1018 | +{ |
---|
| 1019 | + return 0; |
---|
| 1020 | +} |
---|
| 1021 | + |
---|
| 1022 | +static inline void br_mdb_hash_fini(struct net_bridge *br) |
---|
| 1023 | +{ |
---|
| 1024 | +} |
---|
| 1025 | + |
---|
808 | 1026 | static inline void br_multicast_count(struct net_bridge *br, |
---|
809 | 1027 | const struct net_bridge_port *p, |
---|
810 | 1028 | const struct sk_buff *skb, |
---|
.. | .. |
---|
831 | 1049 | #ifdef CONFIG_BRIDGE_VLAN_FILTERING |
---|
832 | 1050 | bool br_allowed_ingress(const struct net_bridge *br, |
---|
833 | 1051 | struct net_bridge_vlan_group *vg, struct sk_buff *skb, |
---|
834 | | - u16 *vid); |
---|
| 1052 | + u16 *vid, u8 *state); |
---|
835 | 1053 | bool br_allowed_egress(struct net_bridge_vlan_group *vg, |
---|
836 | 1054 | const struct sk_buff *skb); |
---|
837 | 1055 | bool br_should_learn(struct net_bridge_port *p, struct sk_buff *skb, u16 *vid); |
---|
.. | .. |
---|
840 | 1058 | struct net_bridge_vlan_group *vg, |
---|
841 | 1059 | struct sk_buff *skb); |
---|
842 | 1060 | int br_vlan_add(struct net_bridge *br, u16 vid, u16 flags, |
---|
843 | | - bool *changed); |
---|
| 1061 | + bool *changed, struct netlink_ext_ack *extack); |
---|
844 | 1062 | int br_vlan_delete(struct net_bridge *br, u16 vid); |
---|
845 | 1063 | void br_vlan_flush(struct net_bridge *br); |
---|
846 | 1064 | struct net_bridge_vlan *br_vlan_find(struct net_bridge_vlan_group *vg, u16 vid); |
---|
.. | .. |
---|
850 | 1068 | int __br_vlan_set_proto(struct net_bridge *br, __be16 proto); |
---|
851 | 1069 | int br_vlan_set_proto(struct net_bridge *br, unsigned long val); |
---|
852 | 1070 | int br_vlan_set_stats(struct net_bridge *br, unsigned long val); |
---|
| 1071 | +int br_vlan_set_stats_per_port(struct net_bridge *br, unsigned long val); |
---|
853 | 1072 | int br_vlan_init(struct net_bridge *br); |
---|
854 | 1073 | int br_vlan_set_default_pvid(struct net_bridge *br, unsigned long val); |
---|
855 | | -int __br_vlan_set_default_pvid(struct net_bridge *br, u16 pvid); |
---|
| 1074 | +int __br_vlan_set_default_pvid(struct net_bridge *br, u16 pvid, |
---|
| 1075 | + struct netlink_ext_ack *extack); |
---|
856 | 1076 | int nbp_vlan_add(struct net_bridge_port *port, u16 vid, u16 flags, |
---|
857 | | - bool *changed); |
---|
| 1077 | + bool *changed, struct netlink_ext_ack *extack); |
---|
858 | 1078 | int nbp_vlan_delete(struct net_bridge_port *port, u16 vid); |
---|
859 | 1079 | void nbp_vlan_flush(struct net_bridge_port *port); |
---|
860 | | -int nbp_vlan_init(struct net_bridge_port *port); |
---|
| 1080 | +int nbp_vlan_init(struct net_bridge_port *port, struct netlink_ext_ack *extack); |
---|
861 | 1081 | int nbp_get_num_vlan_infos(struct net_bridge_port *p, u32 filter_mask); |
---|
862 | 1082 | void br_vlan_get_stats(const struct net_bridge_vlan *v, |
---|
863 | 1083 | struct br_vlan_stats *stats); |
---|
| 1084 | +void br_vlan_port_event(struct net_bridge_port *p, unsigned long event); |
---|
| 1085 | +int br_vlan_bridge_event(struct net_device *dev, unsigned long event, |
---|
| 1086 | + void *ptr); |
---|
| 1087 | +void br_vlan_rtnl_init(void); |
---|
| 1088 | +void br_vlan_rtnl_uninit(void); |
---|
| 1089 | +void br_vlan_notify(const struct net_bridge *br, |
---|
| 1090 | + const struct net_bridge_port *p, |
---|
| 1091 | + u16 vid, u16 vid_range, |
---|
| 1092 | + int cmd); |
---|
| 1093 | +bool br_vlan_can_enter_range(const struct net_bridge_vlan *v_curr, |
---|
| 1094 | + const struct net_bridge_vlan *range_end); |
---|
864 | 1095 | |
---|
865 | 1096 | static inline struct net_bridge_vlan_group *br_vlan_group( |
---|
866 | 1097 | const struct net_bridge *br) |
---|
.. | .. |
---|
894 | 1125 | int err = 0; |
---|
895 | 1126 | |
---|
896 | 1127 | if (skb_vlan_tag_present(skb)) { |
---|
897 | | - *vid = skb_vlan_tag_get(skb) & VLAN_VID_MASK; |
---|
| 1128 | + *vid = skb_vlan_tag_get_id(skb); |
---|
898 | 1129 | } else { |
---|
899 | 1130 | *vid = 0; |
---|
900 | 1131 | err = -EINVAL; |
---|
.. | .. |
---|
912 | 1143 | return vg->pvid; |
---|
913 | 1144 | } |
---|
914 | 1145 | |
---|
| 1146 | +static inline u16 br_vlan_flags(const struct net_bridge_vlan *v, u16 pvid) |
---|
| 1147 | +{ |
---|
| 1148 | + return v->vid == pvid ? v->flags | BRIDGE_VLAN_INFO_PVID : v->flags; |
---|
| 1149 | +} |
---|
915 | 1150 | #else |
---|
916 | 1151 | static inline bool br_allowed_ingress(const struct net_bridge *br, |
---|
917 | 1152 | struct net_bridge_vlan_group *vg, |
---|
918 | 1153 | struct sk_buff *skb, |
---|
919 | | - u16 *vid) |
---|
| 1154 | + u16 *vid, u8 *state) |
---|
920 | 1155 | { |
---|
921 | 1156 | return true; |
---|
922 | 1157 | } |
---|
.. | .. |
---|
942 | 1177 | } |
---|
943 | 1178 | |
---|
944 | 1179 | static inline int br_vlan_add(struct net_bridge *br, u16 vid, u16 flags, |
---|
945 | | - bool *changed) |
---|
| 1180 | + bool *changed, struct netlink_ext_ack *extack) |
---|
946 | 1181 | { |
---|
947 | 1182 | *changed = false; |
---|
948 | 1183 | return -EOPNOTSUPP; |
---|
.. | .. |
---|
967 | 1202 | } |
---|
968 | 1203 | |
---|
969 | 1204 | static inline int nbp_vlan_add(struct net_bridge_port *port, u16 vid, u16 flags, |
---|
970 | | - bool *changed) |
---|
| 1205 | + bool *changed, struct netlink_ext_ack *extack) |
---|
971 | 1206 | { |
---|
972 | 1207 | *changed = false; |
---|
973 | 1208 | return -EOPNOTSUPP; |
---|
.. | .. |
---|
988 | 1223 | return NULL; |
---|
989 | 1224 | } |
---|
990 | 1225 | |
---|
991 | | -static inline int nbp_vlan_init(struct net_bridge_port *port) |
---|
| 1226 | +static inline int nbp_vlan_init(struct net_bridge_port *port, |
---|
| 1227 | + struct netlink_ext_ack *extack) |
---|
992 | 1228 | { |
---|
993 | 1229 | return 0; |
---|
994 | 1230 | } |
---|
.. | .. |
---|
1043 | 1279 | struct br_vlan_stats *stats) |
---|
1044 | 1280 | { |
---|
1045 | 1281 | } |
---|
| 1282 | + |
---|
| 1283 | +static inline void br_vlan_port_event(struct net_bridge_port *p, |
---|
| 1284 | + unsigned long event) |
---|
| 1285 | +{ |
---|
| 1286 | +} |
---|
| 1287 | + |
---|
| 1288 | +static inline int br_vlan_bridge_event(struct net_device *dev, |
---|
| 1289 | + unsigned long event, void *ptr) |
---|
| 1290 | +{ |
---|
| 1291 | + return 0; |
---|
| 1292 | +} |
---|
| 1293 | + |
---|
| 1294 | +static inline void br_vlan_rtnl_init(void) |
---|
| 1295 | +{ |
---|
| 1296 | +} |
---|
| 1297 | + |
---|
| 1298 | +static inline void br_vlan_rtnl_uninit(void) |
---|
| 1299 | +{ |
---|
| 1300 | +} |
---|
| 1301 | + |
---|
| 1302 | +static inline void br_vlan_notify(const struct net_bridge *br, |
---|
| 1303 | + const struct net_bridge_port *p, |
---|
| 1304 | + u16 vid, u16 vid_range, |
---|
| 1305 | + int cmd) |
---|
| 1306 | +{ |
---|
| 1307 | +} |
---|
| 1308 | + |
---|
| 1309 | +static inline bool br_vlan_can_enter_range(const struct net_bridge_vlan *v_curr, |
---|
| 1310 | + const struct net_bridge_vlan *range_end) |
---|
| 1311 | +{ |
---|
| 1312 | + return true; |
---|
| 1313 | +} |
---|
| 1314 | +#endif |
---|
| 1315 | + |
---|
| 1316 | +/* br_vlan_options.c */ |
---|
| 1317 | +#ifdef CONFIG_BRIDGE_VLAN_FILTERING |
---|
| 1318 | +bool br_vlan_opts_eq_range(const struct net_bridge_vlan *v_curr, |
---|
| 1319 | + const struct net_bridge_vlan *range_end); |
---|
| 1320 | +bool br_vlan_opts_fill(struct sk_buff *skb, const struct net_bridge_vlan *v); |
---|
| 1321 | +size_t br_vlan_opts_nl_size(void); |
---|
| 1322 | +int br_vlan_process_options(const struct net_bridge *br, |
---|
| 1323 | + const struct net_bridge_port *p, |
---|
| 1324 | + struct net_bridge_vlan *range_start, |
---|
| 1325 | + struct net_bridge_vlan *range_end, |
---|
| 1326 | + struct nlattr **tb, |
---|
| 1327 | + struct netlink_ext_ack *extack); |
---|
| 1328 | + |
---|
| 1329 | +/* vlan state manipulation helpers using *_ONCE to annotate lock-free access */ |
---|
| 1330 | +static inline u8 br_vlan_get_state(const struct net_bridge_vlan *v) |
---|
| 1331 | +{ |
---|
| 1332 | + return READ_ONCE(v->state); |
---|
| 1333 | +} |
---|
| 1334 | + |
---|
| 1335 | +static inline void br_vlan_set_state(struct net_bridge_vlan *v, u8 state) |
---|
| 1336 | +{ |
---|
| 1337 | + WRITE_ONCE(v->state, state); |
---|
| 1338 | +} |
---|
| 1339 | + |
---|
| 1340 | +static inline u8 br_vlan_get_pvid_state(const struct net_bridge_vlan_group *vg) |
---|
| 1341 | +{ |
---|
| 1342 | + return READ_ONCE(vg->pvid_state); |
---|
| 1343 | +} |
---|
| 1344 | + |
---|
| 1345 | +static inline void br_vlan_set_pvid_state(struct net_bridge_vlan_group *vg, |
---|
| 1346 | + u8 state) |
---|
| 1347 | +{ |
---|
| 1348 | + WRITE_ONCE(vg->pvid_state, state); |
---|
| 1349 | +} |
---|
| 1350 | + |
---|
| 1351 | +/* learn_allow is true at ingress and false at egress */ |
---|
| 1352 | +static inline bool br_vlan_state_allowed(u8 state, bool learn_allow) |
---|
| 1353 | +{ |
---|
| 1354 | + switch (state) { |
---|
| 1355 | + case BR_STATE_LEARNING: |
---|
| 1356 | + return learn_allow; |
---|
| 1357 | + case BR_STATE_FORWARDING: |
---|
| 1358 | + return true; |
---|
| 1359 | + default: |
---|
| 1360 | + return false; |
---|
| 1361 | + } |
---|
| 1362 | +} |
---|
1046 | 1363 | #endif |
---|
1047 | 1364 | |
---|
1048 | 1365 | struct nf_br_ops { |
---|
.. | .. |
---|
1078 | 1395 | /* br_stp_if.c */ |
---|
1079 | 1396 | void br_stp_enable_bridge(struct net_bridge *br); |
---|
1080 | 1397 | void br_stp_disable_bridge(struct net_bridge *br); |
---|
1081 | | -void br_stp_set_enabled(struct net_bridge *br, unsigned long val); |
---|
| 1398 | +int br_stp_set_enabled(struct net_bridge *br, unsigned long val, |
---|
| 1399 | + struct netlink_ext_ack *extack); |
---|
1082 | 1400 | void br_stp_enable_port(struct net_bridge_port *p); |
---|
1083 | 1401 | void br_stp_disable_port(struct net_bridge_port *p); |
---|
1084 | 1402 | bool br_stp_recalculate_bridge_id(struct net_bridge *br); |
---|
.. | .. |
---|
1103 | 1421 | extern int (*br_fdb_test_addr_hook)(struct net_device *dev, unsigned char *addr); |
---|
1104 | 1422 | #endif |
---|
1105 | 1423 | |
---|
| 1424 | +/* br_mrp.c */ |
---|
| 1425 | +#if IS_ENABLED(CONFIG_BRIDGE_MRP) |
---|
| 1426 | +int br_mrp_parse(struct net_bridge *br, struct net_bridge_port *p, |
---|
| 1427 | + struct nlattr *attr, int cmd, struct netlink_ext_ack *extack); |
---|
| 1428 | +int br_mrp_process(struct net_bridge_port *p, struct sk_buff *skb); |
---|
| 1429 | +bool br_mrp_enabled(struct net_bridge *br); |
---|
| 1430 | +void br_mrp_port_del(struct net_bridge *br, struct net_bridge_port *p); |
---|
| 1431 | +int br_mrp_fill_info(struct sk_buff *skb, struct net_bridge *br); |
---|
| 1432 | +#else |
---|
| 1433 | +static inline int br_mrp_parse(struct net_bridge *br, struct net_bridge_port *p, |
---|
| 1434 | + struct nlattr *attr, int cmd, |
---|
| 1435 | + struct netlink_ext_ack *extack) |
---|
| 1436 | +{ |
---|
| 1437 | + return -EOPNOTSUPP; |
---|
| 1438 | +} |
---|
| 1439 | + |
---|
| 1440 | +static inline int br_mrp_process(struct net_bridge_port *p, struct sk_buff *skb) |
---|
| 1441 | +{ |
---|
| 1442 | + return 0; |
---|
| 1443 | +} |
---|
| 1444 | + |
---|
| 1445 | +static inline bool br_mrp_enabled(struct net_bridge *br) |
---|
| 1446 | +{ |
---|
| 1447 | + return false; |
---|
| 1448 | +} |
---|
| 1449 | + |
---|
| 1450 | +static inline void br_mrp_port_del(struct net_bridge *br, |
---|
| 1451 | + struct net_bridge_port *p) |
---|
| 1452 | +{ |
---|
| 1453 | +} |
---|
| 1454 | + |
---|
| 1455 | +static inline int br_mrp_fill_info(struct sk_buff *skb, struct net_bridge *br) |
---|
| 1456 | +{ |
---|
| 1457 | + return 0; |
---|
| 1458 | +} |
---|
| 1459 | + |
---|
| 1460 | +#endif |
---|
| 1461 | + |
---|
1106 | 1462 | /* br_netlink.c */ |
---|
1107 | 1463 | extern struct rtnl_link_ops br_link_ops; |
---|
1108 | 1464 | int br_netlink_init(void); |
---|
1109 | 1465 | void br_netlink_fini(void); |
---|
1110 | 1466 | void br_ifinfo_notify(int event, const struct net_bridge *br, |
---|
1111 | 1467 | const struct net_bridge_port *port); |
---|
1112 | | -int br_setlink(struct net_device *dev, struct nlmsghdr *nlmsg, u16 flags); |
---|
| 1468 | +int br_setlink(struct net_device *dev, struct nlmsghdr *nlmsg, u16 flags, |
---|
| 1469 | + struct netlink_ext_ack *extack); |
---|
1113 | 1470 | int br_dellink(struct net_device *dev, struct nlmsghdr *nlmsg, u16 flags); |
---|
1114 | 1471 | int br_getlink(struct sk_buff *skb, u32 pid, u32 seq, struct net_device *dev, |
---|
1115 | 1472 | u32 filter_mask, int nlflags); |
---|
| 1473 | +int br_process_vlan_info(struct net_bridge *br, |
---|
| 1474 | + struct net_bridge_port *p, int cmd, |
---|
| 1475 | + struct bridge_vlan_info *vinfo_curr, |
---|
| 1476 | + struct bridge_vlan_info **vinfo_last, |
---|
| 1477 | + bool *changed, |
---|
| 1478 | + struct netlink_ext_ack *extack); |
---|
1116 | 1479 | |
---|
1117 | 1480 | #ifdef CONFIG_SYSFS |
---|
1118 | 1481 | /* br_sysfs_if.c */ |
---|
.. | .. |
---|
1144 | 1507 | unsigned long mask); |
---|
1145 | 1508 | void br_switchdev_fdb_notify(const struct net_bridge_fdb_entry *fdb, |
---|
1146 | 1509 | int type); |
---|
1147 | | -int br_switchdev_port_vlan_add(struct net_device *dev, u16 vid, u16 flags); |
---|
| 1510 | +int br_switchdev_port_vlan_add(struct net_device *dev, u16 vid, u16 flags, |
---|
| 1511 | + struct netlink_ext_ack *extack); |
---|
1148 | 1512 | int br_switchdev_port_vlan_del(struct net_device *dev, u16 vid); |
---|
1149 | 1513 | |
---|
1150 | 1514 | static inline void br_switchdev_frame_unmark(struct sk_buff *skb) |
---|
.. | .. |
---|
1176 | 1540 | } |
---|
1177 | 1541 | |
---|
1178 | 1542 | static inline int br_switchdev_port_vlan_add(struct net_device *dev, |
---|
1179 | | - u16 vid, u16 flags) |
---|
| 1543 | + u16 vid, u16 flags, |
---|
| 1544 | + struct netlink_ext_ack *extack) |
---|
1180 | 1545 | { |
---|
1181 | 1546 | return -EOPNOTSUPP; |
---|
1182 | 1547 | } |
---|