hc
2024-10-09 05e59e5fb0064c97a1c10921ecd549f2d4a58565
kernel/net/bridge/br_stp.c
....@@ -1,14 +1,10 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * Spanning tree protocol; generic parts
34 * Linux ethernet bridge
45 *
56 * Authors:
67 * Lennert Buytenhek <buytenh@gnu.org>
7
- *
8
- * This program is free software; you can redistribute it and/or
9
- * modify it under the terms of the GNU General Public License
10
- * as published by the Free Software Foundation; either version
11
- * 2 of the License, or (at your option) any later version.
128 */
139 #include <linux/kernel.h>
1410 #include <linux/rculist.h>
....@@ -40,6 +36,12 @@
4036 };
4137 int err;
4238
39
+ /* Don't change the state of the ports if they are driven by a different
40
+ * protocol.
41
+ */
42
+ if (p->flags & BR_MRP_AWARE)
43
+ return;
44
+
4345 p->state = state;
4446 err = switchdev_port_attr_set(p->dev, &attr);
4547 if (err && err != -EOPNOTSUPP)
....@@ -49,6 +51,17 @@
4951 br_info(p->br, "port %u(%s) entered %s state\n",
5052 (unsigned int) p->port_no, p->dev->name,
5153 br_port_state_names[p->state]);
54
+
55
+ if (p->br->stp_enabled == BR_KERNEL_STP) {
56
+ switch (p->state) {
57
+ case BR_STATE_BLOCKING:
58
+ p->stp_xstats.transition_blk++;
59
+ break;
60
+ case BR_STATE_FORWARDING:
61
+ p->stp_xstats.transition_fwd++;
62
+ break;
63
+ }
64
+ }
5265 }
5366
5467 /* called under bridge lock */
....@@ -56,7 +69,8 @@
5669 {
5770 struct net_bridge_port *p;
5871
59
- list_for_each_entry_rcu(p, &br->port_list, list) {
72
+ list_for_each_entry_rcu(p, &br->port_list, list,
73
+ lockdep_is_held(&br->lock)) {
6074 if (p->port_no == port_no)
6175 return p;
6276 }
....@@ -488,6 +502,8 @@
488502 struct net_bridge *br;
489503 int was_root;
490504
505
+ p->stp_xstats.rx_bpdu++;
506
+
491507 br = p->br;
492508 was_root = br_is_root_bridge(br);
493509
....@@ -521,6 +537,8 @@
521537 /* called under bridge lock */
522538 void br_received_tcn_bpdu(struct net_bridge_port *p)
523539 {
540
+ p->stp_xstats.rx_tcn++;
541
+
524542 if (br_is_designated_port(p)) {
525543 br_info(p->br, "port %u(%s) received tcn bpdu\n",
526544 (unsigned int) p->port_no, p->dev->name);