1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-or-later
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun * Spanning tree protocol; interface code
4*4882a593Smuzhiyun * Linux ethernet bridge
5*4882a593Smuzhiyun *
6*4882a593Smuzhiyun * Authors:
7*4882a593Smuzhiyun * Lennert Buytenhek <buytenh@gnu.org>
8*4882a593Smuzhiyun */
9*4882a593Smuzhiyun
10*4882a593Smuzhiyun #include <linux/kernel.h>
11*4882a593Smuzhiyun #include <linux/kmod.h>
12*4882a593Smuzhiyun #include <linux/etherdevice.h>
13*4882a593Smuzhiyun #include <linux/rtnetlink.h>
14*4882a593Smuzhiyun #include <net/switchdev.h>
15*4882a593Smuzhiyun
16*4882a593Smuzhiyun #include "br_private.h"
17*4882a593Smuzhiyun #include "br_private_stp.h"
18*4882a593Smuzhiyun
19*4882a593Smuzhiyun
20*4882a593Smuzhiyun /* Port id is composed of priority and port number.
21*4882a593Smuzhiyun * NB: some bits of priority are dropped to
22*4882a593Smuzhiyun * make room for more ports.
23*4882a593Smuzhiyun */
br_make_port_id(__u8 priority,__u16 port_no)24*4882a593Smuzhiyun static inline port_id br_make_port_id(__u8 priority, __u16 port_no)
25*4882a593Smuzhiyun {
26*4882a593Smuzhiyun return ((u16)priority << BR_PORT_BITS)
27*4882a593Smuzhiyun | (port_no & ((1<<BR_PORT_BITS)-1));
28*4882a593Smuzhiyun }
29*4882a593Smuzhiyun
30*4882a593Smuzhiyun #define BR_MAX_PORT_PRIORITY ((u16)~0 >> BR_PORT_BITS)
31*4882a593Smuzhiyun
32*4882a593Smuzhiyun /* called under bridge lock */
br_init_port(struct net_bridge_port * p)33*4882a593Smuzhiyun void br_init_port(struct net_bridge_port *p)
34*4882a593Smuzhiyun {
35*4882a593Smuzhiyun int err;
36*4882a593Smuzhiyun
37*4882a593Smuzhiyun p->port_id = br_make_port_id(p->priority, p->port_no);
38*4882a593Smuzhiyun br_become_designated_port(p);
39*4882a593Smuzhiyun br_set_state(p, BR_STATE_BLOCKING);
40*4882a593Smuzhiyun p->topology_change_ack = 0;
41*4882a593Smuzhiyun p->config_pending = 0;
42*4882a593Smuzhiyun
43*4882a593Smuzhiyun err = __set_ageing_time(p->dev, p->br->ageing_time);
44*4882a593Smuzhiyun if (err)
45*4882a593Smuzhiyun netdev_err(p->dev, "failed to offload ageing time\n");
46*4882a593Smuzhiyun }
47*4882a593Smuzhiyun
48*4882a593Smuzhiyun /* NO locks held */
br_stp_enable_bridge(struct net_bridge * br)49*4882a593Smuzhiyun void br_stp_enable_bridge(struct net_bridge *br)
50*4882a593Smuzhiyun {
51*4882a593Smuzhiyun struct net_bridge_port *p;
52*4882a593Smuzhiyun
53*4882a593Smuzhiyun spin_lock_bh(&br->lock);
54*4882a593Smuzhiyun if (br->stp_enabled == BR_KERNEL_STP)
55*4882a593Smuzhiyun mod_timer(&br->hello_timer, jiffies + br->hello_time);
56*4882a593Smuzhiyun mod_delayed_work(system_long_wq, &br->gc_work, HZ / 10);
57*4882a593Smuzhiyun
58*4882a593Smuzhiyun br_config_bpdu_generation(br);
59*4882a593Smuzhiyun
60*4882a593Smuzhiyun list_for_each_entry(p, &br->port_list, list) {
61*4882a593Smuzhiyun if (netif_running(p->dev) && netif_oper_up(p->dev))
62*4882a593Smuzhiyun br_stp_enable_port(p);
63*4882a593Smuzhiyun
64*4882a593Smuzhiyun }
65*4882a593Smuzhiyun spin_unlock_bh(&br->lock);
66*4882a593Smuzhiyun }
67*4882a593Smuzhiyun
68*4882a593Smuzhiyun /* NO locks held */
br_stp_disable_bridge(struct net_bridge * br)69*4882a593Smuzhiyun void br_stp_disable_bridge(struct net_bridge *br)
70*4882a593Smuzhiyun {
71*4882a593Smuzhiyun struct net_bridge_port *p;
72*4882a593Smuzhiyun
73*4882a593Smuzhiyun spin_lock_bh(&br->lock);
74*4882a593Smuzhiyun list_for_each_entry(p, &br->port_list, list) {
75*4882a593Smuzhiyun if (p->state != BR_STATE_DISABLED)
76*4882a593Smuzhiyun br_stp_disable_port(p);
77*4882a593Smuzhiyun
78*4882a593Smuzhiyun }
79*4882a593Smuzhiyun
80*4882a593Smuzhiyun __br_set_topology_change(br, 0);
81*4882a593Smuzhiyun br->topology_change_detected = 0;
82*4882a593Smuzhiyun spin_unlock_bh(&br->lock);
83*4882a593Smuzhiyun
84*4882a593Smuzhiyun del_timer_sync(&br->hello_timer);
85*4882a593Smuzhiyun del_timer_sync(&br->topology_change_timer);
86*4882a593Smuzhiyun del_timer_sync(&br->tcn_timer);
87*4882a593Smuzhiyun cancel_delayed_work_sync(&br->gc_work);
88*4882a593Smuzhiyun }
89*4882a593Smuzhiyun
90*4882a593Smuzhiyun /* called under bridge lock */
br_stp_enable_port(struct net_bridge_port * p)91*4882a593Smuzhiyun void br_stp_enable_port(struct net_bridge_port *p)
92*4882a593Smuzhiyun {
93*4882a593Smuzhiyun br_init_port(p);
94*4882a593Smuzhiyun br_port_state_selection(p->br);
95*4882a593Smuzhiyun br_ifinfo_notify(RTM_NEWLINK, NULL, p);
96*4882a593Smuzhiyun }
97*4882a593Smuzhiyun
98*4882a593Smuzhiyun /* called under bridge lock */
br_stp_disable_port(struct net_bridge_port * p)99*4882a593Smuzhiyun void br_stp_disable_port(struct net_bridge_port *p)
100*4882a593Smuzhiyun {
101*4882a593Smuzhiyun struct net_bridge *br = p->br;
102*4882a593Smuzhiyun int wasroot;
103*4882a593Smuzhiyun
104*4882a593Smuzhiyun wasroot = br_is_root_bridge(br);
105*4882a593Smuzhiyun br_become_designated_port(p);
106*4882a593Smuzhiyun br_set_state(p, BR_STATE_DISABLED);
107*4882a593Smuzhiyun p->topology_change_ack = 0;
108*4882a593Smuzhiyun p->config_pending = 0;
109*4882a593Smuzhiyun
110*4882a593Smuzhiyun br_ifinfo_notify(RTM_NEWLINK, NULL, p);
111*4882a593Smuzhiyun
112*4882a593Smuzhiyun del_timer(&p->message_age_timer);
113*4882a593Smuzhiyun del_timer(&p->forward_delay_timer);
114*4882a593Smuzhiyun del_timer(&p->hold_timer);
115*4882a593Smuzhiyun
116*4882a593Smuzhiyun if (!rcu_access_pointer(p->backup_port))
117*4882a593Smuzhiyun br_fdb_delete_by_port(br, p, 0, 0);
118*4882a593Smuzhiyun br_multicast_disable_port(p);
119*4882a593Smuzhiyun
120*4882a593Smuzhiyun br_configuration_update(br);
121*4882a593Smuzhiyun
122*4882a593Smuzhiyun br_port_state_selection(br);
123*4882a593Smuzhiyun
124*4882a593Smuzhiyun if (br_is_root_bridge(br) && !wasroot)
125*4882a593Smuzhiyun br_become_root_bridge(br);
126*4882a593Smuzhiyun }
127*4882a593Smuzhiyun
br_stp_call_user(struct net_bridge * br,char * arg)128*4882a593Smuzhiyun static int br_stp_call_user(struct net_bridge *br, char *arg)
129*4882a593Smuzhiyun {
130*4882a593Smuzhiyun char *argv[] = { BR_STP_PROG, br->dev->name, arg, NULL };
131*4882a593Smuzhiyun char *envp[] = { NULL };
132*4882a593Smuzhiyun int rc;
133*4882a593Smuzhiyun
134*4882a593Smuzhiyun /* call userspace STP and report program errors */
135*4882a593Smuzhiyun rc = call_usermodehelper(BR_STP_PROG, argv, envp, UMH_WAIT_PROC);
136*4882a593Smuzhiyun if (rc > 0) {
137*4882a593Smuzhiyun if (rc & 0xff)
138*4882a593Smuzhiyun br_debug(br, BR_STP_PROG " received signal %d\n",
139*4882a593Smuzhiyun rc & 0x7f);
140*4882a593Smuzhiyun else
141*4882a593Smuzhiyun br_debug(br, BR_STP_PROG " exited with code %d\n",
142*4882a593Smuzhiyun (rc >> 8) & 0xff);
143*4882a593Smuzhiyun }
144*4882a593Smuzhiyun
145*4882a593Smuzhiyun return rc;
146*4882a593Smuzhiyun }
147*4882a593Smuzhiyun
br_stp_start(struct net_bridge * br)148*4882a593Smuzhiyun static void br_stp_start(struct net_bridge *br)
149*4882a593Smuzhiyun {
150*4882a593Smuzhiyun int err = -ENOENT;
151*4882a593Smuzhiyun
152*4882a593Smuzhiyun if (net_eq(dev_net(br->dev), &init_net))
153*4882a593Smuzhiyun err = br_stp_call_user(br, "start");
154*4882a593Smuzhiyun
155*4882a593Smuzhiyun if (err && err != -ENOENT)
156*4882a593Smuzhiyun br_err(br, "failed to start userspace STP (%d)\n", err);
157*4882a593Smuzhiyun
158*4882a593Smuzhiyun spin_lock_bh(&br->lock);
159*4882a593Smuzhiyun
160*4882a593Smuzhiyun if (br->bridge_forward_delay < BR_MIN_FORWARD_DELAY)
161*4882a593Smuzhiyun __br_set_forward_delay(br, BR_MIN_FORWARD_DELAY);
162*4882a593Smuzhiyun else if (br->bridge_forward_delay > BR_MAX_FORWARD_DELAY)
163*4882a593Smuzhiyun __br_set_forward_delay(br, BR_MAX_FORWARD_DELAY);
164*4882a593Smuzhiyun
165*4882a593Smuzhiyun if (!err) {
166*4882a593Smuzhiyun br->stp_enabled = BR_USER_STP;
167*4882a593Smuzhiyun br_debug(br, "userspace STP started\n");
168*4882a593Smuzhiyun } else {
169*4882a593Smuzhiyun br->stp_enabled = BR_KERNEL_STP;
170*4882a593Smuzhiyun br_debug(br, "using kernel STP\n");
171*4882a593Smuzhiyun
172*4882a593Smuzhiyun /* To start timers on any ports left in blocking */
173*4882a593Smuzhiyun if (br->dev->flags & IFF_UP)
174*4882a593Smuzhiyun mod_timer(&br->hello_timer, jiffies + br->hello_time);
175*4882a593Smuzhiyun br_port_state_selection(br);
176*4882a593Smuzhiyun }
177*4882a593Smuzhiyun
178*4882a593Smuzhiyun spin_unlock_bh(&br->lock);
179*4882a593Smuzhiyun }
180*4882a593Smuzhiyun
br_stp_stop(struct net_bridge * br)181*4882a593Smuzhiyun static void br_stp_stop(struct net_bridge *br)
182*4882a593Smuzhiyun {
183*4882a593Smuzhiyun int err;
184*4882a593Smuzhiyun
185*4882a593Smuzhiyun if (br->stp_enabled == BR_USER_STP) {
186*4882a593Smuzhiyun err = br_stp_call_user(br, "stop");
187*4882a593Smuzhiyun if (err)
188*4882a593Smuzhiyun br_err(br, "failed to stop userspace STP (%d)\n", err);
189*4882a593Smuzhiyun
190*4882a593Smuzhiyun /* To start timers on any ports left in blocking */
191*4882a593Smuzhiyun spin_lock_bh(&br->lock);
192*4882a593Smuzhiyun br_port_state_selection(br);
193*4882a593Smuzhiyun spin_unlock_bh(&br->lock);
194*4882a593Smuzhiyun }
195*4882a593Smuzhiyun
196*4882a593Smuzhiyun br->stp_enabled = BR_NO_STP;
197*4882a593Smuzhiyun }
198*4882a593Smuzhiyun
br_stp_set_enabled(struct net_bridge * br,unsigned long val,struct netlink_ext_ack * extack)199*4882a593Smuzhiyun int br_stp_set_enabled(struct net_bridge *br, unsigned long val,
200*4882a593Smuzhiyun struct netlink_ext_ack *extack)
201*4882a593Smuzhiyun {
202*4882a593Smuzhiyun ASSERT_RTNL();
203*4882a593Smuzhiyun
204*4882a593Smuzhiyun if (br_mrp_enabled(br)) {
205*4882a593Smuzhiyun NL_SET_ERR_MSG_MOD(extack,
206*4882a593Smuzhiyun "STP can't be enabled if MRP is already enabled");
207*4882a593Smuzhiyun return -EINVAL;
208*4882a593Smuzhiyun }
209*4882a593Smuzhiyun
210*4882a593Smuzhiyun if (val) {
211*4882a593Smuzhiyun if (br->stp_enabled == BR_NO_STP)
212*4882a593Smuzhiyun br_stp_start(br);
213*4882a593Smuzhiyun } else {
214*4882a593Smuzhiyun if (br->stp_enabled != BR_NO_STP)
215*4882a593Smuzhiyun br_stp_stop(br);
216*4882a593Smuzhiyun }
217*4882a593Smuzhiyun
218*4882a593Smuzhiyun return 0;
219*4882a593Smuzhiyun }
220*4882a593Smuzhiyun
221*4882a593Smuzhiyun /* called under bridge lock */
br_stp_change_bridge_id(struct net_bridge * br,const unsigned char * addr)222*4882a593Smuzhiyun void br_stp_change_bridge_id(struct net_bridge *br, const unsigned char *addr)
223*4882a593Smuzhiyun {
224*4882a593Smuzhiyun /* should be aligned on 2 bytes for ether_addr_equal() */
225*4882a593Smuzhiyun unsigned short oldaddr_aligned[ETH_ALEN >> 1];
226*4882a593Smuzhiyun unsigned char *oldaddr = (unsigned char *)oldaddr_aligned;
227*4882a593Smuzhiyun struct net_bridge_port *p;
228*4882a593Smuzhiyun int wasroot;
229*4882a593Smuzhiyun
230*4882a593Smuzhiyun wasroot = br_is_root_bridge(br);
231*4882a593Smuzhiyun
232*4882a593Smuzhiyun br_fdb_change_mac_address(br, addr);
233*4882a593Smuzhiyun
234*4882a593Smuzhiyun memcpy(oldaddr, br->bridge_id.addr, ETH_ALEN);
235*4882a593Smuzhiyun memcpy(br->bridge_id.addr, addr, ETH_ALEN);
236*4882a593Smuzhiyun memcpy(br->dev->dev_addr, addr, ETH_ALEN);
237*4882a593Smuzhiyun
238*4882a593Smuzhiyun list_for_each_entry(p, &br->port_list, list) {
239*4882a593Smuzhiyun if (ether_addr_equal(p->designated_bridge.addr, oldaddr))
240*4882a593Smuzhiyun memcpy(p->designated_bridge.addr, addr, ETH_ALEN);
241*4882a593Smuzhiyun
242*4882a593Smuzhiyun if (ether_addr_equal(p->designated_root.addr, oldaddr))
243*4882a593Smuzhiyun memcpy(p->designated_root.addr, addr, ETH_ALEN);
244*4882a593Smuzhiyun }
245*4882a593Smuzhiyun
246*4882a593Smuzhiyun br_configuration_update(br);
247*4882a593Smuzhiyun br_port_state_selection(br);
248*4882a593Smuzhiyun if (br_is_root_bridge(br) && !wasroot)
249*4882a593Smuzhiyun br_become_root_bridge(br);
250*4882a593Smuzhiyun }
251*4882a593Smuzhiyun
252*4882a593Smuzhiyun /* should be aligned on 2 bytes for ether_addr_equal() */
253*4882a593Smuzhiyun static const unsigned short br_mac_zero_aligned[ETH_ALEN >> 1];
254*4882a593Smuzhiyun
255*4882a593Smuzhiyun /* called under bridge lock */
br_stp_recalculate_bridge_id(struct net_bridge * br)256*4882a593Smuzhiyun bool br_stp_recalculate_bridge_id(struct net_bridge *br)
257*4882a593Smuzhiyun {
258*4882a593Smuzhiyun const unsigned char *br_mac_zero =
259*4882a593Smuzhiyun (const unsigned char *)br_mac_zero_aligned;
260*4882a593Smuzhiyun const unsigned char *addr = br_mac_zero;
261*4882a593Smuzhiyun struct net_bridge_port *p;
262*4882a593Smuzhiyun
263*4882a593Smuzhiyun /* user has chosen a value so keep it */
264*4882a593Smuzhiyun if (br->dev->addr_assign_type == NET_ADDR_SET)
265*4882a593Smuzhiyun return false;
266*4882a593Smuzhiyun
267*4882a593Smuzhiyun list_for_each_entry(p, &br->port_list, list) {
268*4882a593Smuzhiyun if (addr == br_mac_zero ||
269*4882a593Smuzhiyun memcmp(p->dev->dev_addr, addr, ETH_ALEN) < 0)
270*4882a593Smuzhiyun addr = p->dev->dev_addr;
271*4882a593Smuzhiyun
272*4882a593Smuzhiyun }
273*4882a593Smuzhiyun
274*4882a593Smuzhiyun if (ether_addr_equal(br->bridge_id.addr, addr))
275*4882a593Smuzhiyun return false; /* no change */
276*4882a593Smuzhiyun
277*4882a593Smuzhiyun br_stp_change_bridge_id(br, addr);
278*4882a593Smuzhiyun return true;
279*4882a593Smuzhiyun }
280*4882a593Smuzhiyun
281*4882a593Smuzhiyun /* Acquires and releases bridge lock */
br_stp_set_bridge_priority(struct net_bridge * br,u16 newprio)282*4882a593Smuzhiyun void br_stp_set_bridge_priority(struct net_bridge *br, u16 newprio)
283*4882a593Smuzhiyun {
284*4882a593Smuzhiyun struct net_bridge_port *p;
285*4882a593Smuzhiyun int wasroot;
286*4882a593Smuzhiyun
287*4882a593Smuzhiyun spin_lock_bh(&br->lock);
288*4882a593Smuzhiyun wasroot = br_is_root_bridge(br);
289*4882a593Smuzhiyun
290*4882a593Smuzhiyun list_for_each_entry(p, &br->port_list, list) {
291*4882a593Smuzhiyun if (p->state != BR_STATE_DISABLED &&
292*4882a593Smuzhiyun br_is_designated_port(p)) {
293*4882a593Smuzhiyun p->designated_bridge.prio[0] = (newprio >> 8) & 0xFF;
294*4882a593Smuzhiyun p->designated_bridge.prio[1] = newprio & 0xFF;
295*4882a593Smuzhiyun }
296*4882a593Smuzhiyun
297*4882a593Smuzhiyun }
298*4882a593Smuzhiyun
299*4882a593Smuzhiyun br->bridge_id.prio[0] = (newprio >> 8) & 0xFF;
300*4882a593Smuzhiyun br->bridge_id.prio[1] = newprio & 0xFF;
301*4882a593Smuzhiyun br_configuration_update(br);
302*4882a593Smuzhiyun br_port_state_selection(br);
303*4882a593Smuzhiyun if (br_is_root_bridge(br) && !wasroot)
304*4882a593Smuzhiyun br_become_root_bridge(br);
305*4882a593Smuzhiyun spin_unlock_bh(&br->lock);
306*4882a593Smuzhiyun }
307*4882a593Smuzhiyun
308*4882a593Smuzhiyun /* called under bridge lock */
br_stp_set_port_priority(struct net_bridge_port * p,unsigned long newprio)309*4882a593Smuzhiyun int br_stp_set_port_priority(struct net_bridge_port *p, unsigned long newprio)
310*4882a593Smuzhiyun {
311*4882a593Smuzhiyun port_id new_port_id;
312*4882a593Smuzhiyun
313*4882a593Smuzhiyun if (newprio > BR_MAX_PORT_PRIORITY)
314*4882a593Smuzhiyun return -ERANGE;
315*4882a593Smuzhiyun
316*4882a593Smuzhiyun new_port_id = br_make_port_id(newprio, p->port_no);
317*4882a593Smuzhiyun if (br_is_designated_port(p))
318*4882a593Smuzhiyun p->designated_port = new_port_id;
319*4882a593Smuzhiyun
320*4882a593Smuzhiyun p->port_id = new_port_id;
321*4882a593Smuzhiyun p->priority = newprio;
322*4882a593Smuzhiyun if (!memcmp(&p->br->bridge_id, &p->designated_bridge, 8) &&
323*4882a593Smuzhiyun p->port_id < p->designated_port) {
324*4882a593Smuzhiyun br_become_designated_port(p);
325*4882a593Smuzhiyun br_port_state_selection(p->br);
326*4882a593Smuzhiyun }
327*4882a593Smuzhiyun
328*4882a593Smuzhiyun return 0;
329*4882a593Smuzhiyun }
330*4882a593Smuzhiyun
331*4882a593Smuzhiyun /* called under bridge lock */
br_stp_set_path_cost(struct net_bridge_port * p,unsigned long path_cost)332*4882a593Smuzhiyun int br_stp_set_path_cost(struct net_bridge_port *p, unsigned long path_cost)
333*4882a593Smuzhiyun {
334*4882a593Smuzhiyun if (path_cost < BR_MIN_PATH_COST ||
335*4882a593Smuzhiyun path_cost > BR_MAX_PATH_COST)
336*4882a593Smuzhiyun return -ERANGE;
337*4882a593Smuzhiyun
338*4882a593Smuzhiyun p->flags |= BR_ADMIN_COST;
339*4882a593Smuzhiyun p->path_cost = path_cost;
340*4882a593Smuzhiyun br_configuration_update(p->br);
341*4882a593Smuzhiyun br_port_state_selection(p->br);
342*4882a593Smuzhiyun return 0;
343*4882a593Smuzhiyun }
344*4882a593Smuzhiyun
br_show_bridge_id(char * buf,const struct bridge_id * id)345*4882a593Smuzhiyun ssize_t br_show_bridge_id(char *buf, const struct bridge_id *id)
346*4882a593Smuzhiyun {
347*4882a593Smuzhiyun return sprintf(buf, "%.2x%.2x.%.2x%.2x%.2x%.2x%.2x%.2x\n",
348*4882a593Smuzhiyun id->prio[0], id->prio[1],
349*4882a593Smuzhiyun id->addr[0], id->addr[1], id->addr[2],
350*4882a593Smuzhiyun id->addr[3], id->addr[4], id->addr[5]);
351*4882a593Smuzhiyun }
352