1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Bridge Multiple Spanning Tree Support 4 * 5 * Authors: 6 * Tobias Waldekranz <tobias@waldekranz.com> 7 */ 8 9 #include <linux/kernel.h> 10 #include <net/switchdev.h> 11 12 #include "br_private.h" 13 14 DEFINE_STATIC_KEY_FALSE(br_mst_used); 15 16 bool br_mst_enabled(const struct net_device *dev) 17 { 18 if (!netif_is_bridge_master(dev)) 19 return false; 20 21 return br_opt_get(netdev_priv(dev), BROPT_MST_ENABLED); 22 } 23 EXPORT_SYMBOL_GPL(br_mst_enabled); 24 25 void br_mst_uninit(struct net_bridge *br) 26 { 27 if (br_opt_get(br, BROPT_MST_ENABLED)) 28 static_branch_dec(&br_mst_used); 29 } 30 31 int br_mst_get_info(const struct net_device *dev, u16 msti, unsigned long *vids) 32 { 33 const struct net_bridge_vlan_group *vg; 34 const struct net_bridge_vlan *v; 35 const struct net_bridge *br; 36 37 ASSERT_RTNL(); 38 39 if (!netif_is_bridge_master(dev)) 40 return -EINVAL; 41 42 br = netdev_priv(dev); 43 if (!br_opt_get(br, BROPT_MST_ENABLED)) 44 return -EINVAL; 45 46 vg = br_vlan_group(br); 47 48 list_for_each_entry(v, &vg->vlan_list, vlist) { 49 if (v->msti == msti) 50 __set_bit(v->vid, vids); 51 } 52 53 return 0; 54 } 55 EXPORT_SYMBOL_GPL(br_mst_get_info); 56 57 int br_mst_get_state(const struct net_device *dev, u16 msti, u8 *state) 58 { 59 const struct net_bridge_port *p = NULL; 60 const struct net_bridge_vlan_group *vg; 61 const struct net_bridge_vlan *v; 62 63 ASSERT_RTNL(); 64 65 p = br_port_get_check_rtnl(dev); 66 if (!p || !br_opt_get(p->br, BROPT_MST_ENABLED)) 67 return -EINVAL; 68 69 vg = nbp_vlan_group(p); 70 71 list_for_each_entry(v, &vg->vlan_list, vlist) { 72 if (v->brvlan->msti == msti) { 73 *state = v->state; 74 return 0; 75 } 76 } 77 78 return -ENOENT; 79 } 80 EXPORT_SYMBOL_GPL(br_mst_get_state); 81 82 static void br_mst_vlan_set_state(struct net_bridge_vlan_group *vg, 83 struct net_bridge_vlan *v, 84 u8 state) 85 { 86 if (br_vlan_get_state(v) == state) 87 return; 88 89 if (v->vid == vg->pvid) 90 br_vlan_set_pvid_state(vg, state); 91 92 br_vlan_set_state(v, state); 93 } 94 95 int br_mst_set_state(struct net_bridge_port *p, u16 msti, u8 state, 96 struct netlink_ext_ack *extack) 97 { 98 struct switchdev_attr attr = { 99 .id = SWITCHDEV_ATTR_ID_PORT_MST_STATE, 100 .orig_dev = p->dev, 101 .u.mst_state = { 102 .msti = msti, 103 .state = state, 104 }, 105 }; 106 struct net_bridge_vlan_group *vg; 107 struct net_bridge_vlan *v; 108 int err = 0; 109 110 /* MSTI 0 (CST) state changes are notified via the regular 111 * SWITCHDEV_ATTR_ID_PORT_STP_STATE. All other MSTIs are handled via 112 * netlink with RTNL held 113 */ 114 if (msti) { 115 ASSERT_RTNL(); 116 117 err = switchdev_port_attr_set(p->dev, &attr, extack); 118 if (err && err != -EOPNOTSUPP) 119 goto out; 120 err = 0; 121 } 122 123 rcu_read_lock(); 124 vg = nbp_vlan_group_rcu(p); 125 if (!vg) 126 goto out_rcu_unlock; 127 128 list_for_each_entry_rcu(v, &vg->vlan_list, vlist) { 129 if (v->brvlan->msti != msti) 130 continue; 131 132 br_mst_vlan_set_state(vg, v, state); 133 } 134 135 out_rcu_unlock: 136 rcu_read_unlock(); 137 out: 138 return err; 139 } 140 141 static void br_mst_vlan_sync_state(struct net_bridge_vlan *pv, u16 msti) 142 { 143 struct net_bridge_vlan_group *vg = nbp_vlan_group(pv->port); 144 struct net_bridge_vlan *v; 145 146 list_for_each_entry(v, &vg->vlan_list, vlist) { 147 /* If this port already has a defined state in this 148 * MSTI (through some other VLAN membership), inherit 149 * it. 150 */ 151 if (v != pv && v->brvlan->msti == msti) { 152 br_mst_vlan_set_state(vg, pv, v->state); 153 return; 154 } 155 } 156 157 /* Otherwise, start out in a new MSTI with all ports disabled. */ 158 return br_mst_vlan_set_state(vg, pv, BR_STATE_DISABLED); 159 } 160 161 int br_mst_vlan_set_msti(struct net_bridge_vlan *mv, u16 msti) 162 { 163 struct switchdev_attr attr = { 164 .id = SWITCHDEV_ATTR_ID_VLAN_MSTI, 165 .orig_dev = mv->br->dev, 166 .u.vlan_msti = { 167 .vid = mv->vid, 168 .msti = msti, 169 }, 170 }; 171 struct net_bridge_vlan_group *vg; 172 struct net_bridge_vlan *pv; 173 struct net_bridge_port *p; 174 int err; 175 176 if (mv->msti == msti) 177 return 0; 178 179 err = switchdev_port_attr_set(mv->br->dev, &attr, NULL); 180 if (err && err != -EOPNOTSUPP) 181 return err; 182 183 mv->msti = msti; 184 185 list_for_each_entry(p, &mv->br->port_list, list) { 186 vg = nbp_vlan_group(p); 187 188 pv = br_vlan_find(vg, mv->vid); 189 if (pv) 190 br_mst_vlan_sync_state(pv, msti); 191 } 192 193 return 0; 194 } 195 196 void br_mst_vlan_init_state(struct net_bridge_vlan *v) 197 { 198 /* VLANs always start out in MSTI 0 (CST) */ 199 v->msti = 0; 200 201 if (br_vlan_is_master(v)) 202 v->state = BR_STATE_FORWARDING; 203 else 204 v->state = v->port->state; 205 } 206 207 int br_mst_set_enabled(struct net_bridge *br, bool on, 208 struct netlink_ext_ack *extack) 209 { 210 struct switchdev_attr attr = { 211 .id = SWITCHDEV_ATTR_ID_BRIDGE_MST, 212 .orig_dev = br->dev, 213 .u.mst = on, 214 }; 215 struct net_bridge_vlan_group *vg; 216 struct net_bridge_port *p; 217 int err; 218 219 list_for_each_entry(p, &br->port_list, list) { 220 vg = nbp_vlan_group(p); 221 222 if (!vg->num_vlans) 223 continue; 224 225 NL_SET_ERR_MSG(extack, 226 "MST mode can't be changed while VLANs exist"); 227 return -EBUSY; 228 } 229 230 if (br_opt_get(br, BROPT_MST_ENABLED) == on) 231 return 0; 232 233 err = switchdev_port_attr_set(br->dev, &attr, extack); 234 if (err && err != -EOPNOTSUPP) 235 return err; 236 237 if (on) 238 static_branch_inc(&br_mst_used); 239 else 240 static_branch_dec(&br_mst_used); 241 242 br_opt_toggle(br, BROPT_MST_ENABLED, on); 243 return 0; 244 } 245 246 size_t br_mst_info_size(const struct net_bridge_vlan_group *vg) 247 { 248 DECLARE_BITMAP(seen, VLAN_N_VID) = { 0 }; 249 const struct net_bridge_vlan *v; 250 size_t sz; 251 252 /* IFLA_BRIDGE_MST */ 253 sz = nla_total_size(0); 254 255 list_for_each_entry_rcu(v, &vg->vlan_list, vlist) { 256 if (test_bit(v->brvlan->msti, seen)) 257 continue; 258 259 /* IFLA_BRIDGE_MST_ENTRY */ 260 sz += nla_total_size(0) + 261 /* IFLA_BRIDGE_MST_ENTRY_MSTI */ 262 nla_total_size(sizeof(u16)) + 263 /* IFLA_BRIDGE_MST_ENTRY_STATE */ 264 nla_total_size(sizeof(u8)); 265 266 __set_bit(v->brvlan->msti, seen); 267 } 268 269 return sz; 270 } 271 272 int br_mst_fill_info(struct sk_buff *skb, 273 const struct net_bridge_vlan_group *vg) 274 { 275 DECLARE_BITMAP(seen, VLAN_N_VID) = { 0 }; 276 const struct net_bridge_vlan *v; 277 struct nlattr *nest; 278 int err = 0; 279 280 list_for_each_entry(v, &vg->vlan_list, vlist) { 281 if (test_bit(v->brvlan->msti, seen)) 282 continue; 283 284 nest = nla_nest_start_noflag(skb, IFLA_BRIDGE_MST_ENTRY); 285 if (!nest || 286 nla_put_u16(skb, IFLA_BRIDGE_MST_ENTRY_MSTI, v->brvlan->msti) || 287 nla_put_u8(skb, IFLA_BRIDGE_MST_ENTRY_STATE, v->state)) { 288 err = -EMSGSIZE; 289 break; 290 } 291 nla_nest_end(skb, nest); 292 293 __set_bit(v->brvlan->msti, seen); 294 } 295 296 return err; 297 } 298 299 static const struct nla_policy br_mst_nl_policy[IFLA_BRIDGE_MST_ENTRY_MAX + 1] = { 300 [IFLA_BRIDGE_MST_ENTRY_MSTI] = NLA_POLICY_RANGE(NLA_U16, 301 1, /* 0 reserved for CST */ 302 VLAN_N_VID - 1), 303 [IFLA_BRIDGE_MST_ENTRY_STATE] = NLA_POLICY_RANGE(NLA_U8, 304 BR_STATE_DISABLED, 305 BR_STATE_BLOCKING), 306 }; 307 308 static int br_mst_process_one(struct net_bridge_port *p, 309 const struct nlattr *attr, 310 struct netlink_ext_ack *extack) 311 { 312 struct nlattr *tb[IFLA_BRIDGE_MST_ENTRY_MAX + 1]; 313 u16 msti; 314 u8 state; 315 int err; 316 317 err = nla_parse_nested(tb, IFLA_BRIDGE_MST_ENTRY_MAX, attr, 318 br_mst_nl_policy, extack); 319 if (err) 320 return err; 321 322 if (!tb[IFLA_BRIDGE_MST_ENTRY_MSTI]) { 323 NL_SET_ERR_MSG_MOD(extack, "MSTI not specified"); 324 return -EINVAL; 325 } 326 327 if (!tb[IFLA_BRIDGE_MST_ENTRY_STATE]) { 328 NL_SET_ERR_MSG_MOD(extack, "State not specified"); 329 return -EINVAL; 330 } 331 332 msti = nla_get_u16(tb[IFLA_BRIDGE_MST_ENTRY_MSTI]); 333 state = nla_get_u8(tb[IFLA_BRIDGE_MST_ENTRY_STATE]); 334 335 return br_mst_set_state(p, msti, state, extack); 336 } 337 338 int br_mst_process(struct net_bridge_port *p, const struct nlattr *mst_attr, 339 struct netlink_ext_ack *extack) 340 { 341 struct nlattr *attr; 342 int err, msts = 0; 343 int rem; 344 345 if (!br_opt_get(p->br, BROPT_MST_ENABLED)) { 346 NL_SET_ERR_MSG_MOD(extack, "Can't modify MST state when MST is disabled"); 347 return -EBUSY; 348 } 349 350 nla_for_each_nested(attr, mst_attr, rem) { 351 switch (nla_type(attr)) { 352 case IFLA_BRIDGE_MST_ENTRY: 353 err = br_mst_process_one(p, attr, extack); 354 break; 355 default: 356 continue; 357 } 358 359 msts++; 360 if (err) 361 break; 362 } 363 364 if (!msts) { 365 NL_SET_ERR_MSG_MOD(extack, "Found no MST entries to process"); 366 err = -EINVAL; 367 } 368 369 return err; 370 } 371