0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <linux/kernel.h>
0010 #include <net/switchdev.h>
0011
0012 #include "br_private.h"
0013
0014 DEFINE_STATIC_KEY_FALSE(br_mst_used);
0015
0016 bool br_mst_enabled(const struct net_device *dev)
0017 {
0018 if (!netif_is_bridge_master(dev))
0019 return false;
0020
0021 return br_opt_get(netdev_priv(dev), BROPT_MST_ENABLED);
0022 }
0023 EXPORT_SYMBOL_GPL(br_mst_enabled);
0024
0025 int br_mst_get_info(const struct net_device *dev, u16 msti, unsigned long *vids)
0026 {
0027 const struct net_bridge_vlan_group *vg;
0028 const struct net_bridge_vlan *v;
0029 const struct net_bridge *br;
0030
0031 ASSERT_RTNL();
0032
0033 if (!netif_is_bridge_master(dev))
0034 return -EINVAL;
0035
0036 br = netdev_priv(dev);
0037 if (!br_opt_get(br, BROPT_MST_ENABLED))
0038 return -EINVAL;
0039
0040 vg = br_vlan_group(br);
0041
0042 list_for_each_entry(v, &vg->vlan_list, vlist) {
0043 if (v->msti == msti)
0044 __set_bit(v->vid, vids);
0045 }
0046
0047 return 0;
0048 }
0049 EXPORT_SYMBOL_GPL(br_mst_get_info);
0050
0051 int br_mst_get_state(const struct net_device *dev, u16 msti, u8 *state)
0052 {
0053 const struct net_bridge_port *p = NULL;
0054 const struct net_bridge_vlan_group *vg;
0055 const struct net_bridge_vlan *v;
0056
0057 ASSERT_RTNL();
0058
0059 p = br_port_get_check_rtnl(dev);
0060 if (!p || !br_opt_get(p->br, BROPT_MST_ENABLED))
0061 return -EINVAL;
0062
0063 vg = nbp_vlan_group(p);
0064
0065 list_for_each_entry(v, &vg->vlan_list, vlist) {
0066 if (v->brvlan->msti == msti) {
0067 *state = v->state;
0068 return 0;
0069 }
0070 }
0071
0072 return -ENOENT;
0073 }
0074 EXPORT_SYMBOL_GPL(br_mst_get_state);
0075
0076 static void br_mst_vlan_set_state(struct net_bridge_port *p, struct net_bridge_vlan *v,
0077 u8 state)
0078 {
0079 struct net_bridge_vlan_group *vg = nbp_vlan_group(p);
0080
0081 if (v->state == state)
0082 return;
0083
0084 br_vlan_set_state(v, state);
0085
0086 if (v->vid == vg->pvid)
0087 br_vlan_set_pvid_state(vg, state);
0088 }
0089
0090 int br_mst_set_state(struct net_bridge_port *p, u16 msti, u8 state,
0091 struct netlink_ext_ack *extack)
0092 {
0093 struct switchdev_attr attr = {
0094 .id = SWITCHDEV_ATTR_ID_PORT_MST_STATE,
0095 .orig_dev = p->dev,
0096 .u.mst_state = {
0097 .msti = msti,
0098 .state = state,
0099 },
0100 };
0101 struct net_bridge_vlan_group *vg;
0102 struct net_bridge_vlan *v;
0103 int err;
0104
0105 vg = nbp_vlan_group(p);
0106 if (!vg)
0107 return 0;
0108
0109
0110
0111
0112 if (msti) {
0113 err = switchdev_port_attr_set(p->dev, &attr, extack);
0114 if (err && err != -EOPNOTSUPP)
0115 return err;
0116 }
0117
0118 list_for_each_entry(v, &vg->vlan_list, vlist) {
0119 if (v->brvlan->msti != msti)
0120 continue;
0121
0122 br_mst_vlan_set_state(p, v, state);
0123 }
0124
0125 return 0;
0126 }
0127
0128 static void br_mst_vlan_sync_state(struct net_bridge_vlan *pv, u16 msti)
0129 {
0130 struct net_bridge_vlan_group *vg = nbp_vlan_group(pv->port);
0131 struct net_bridge_vlan *v;
0132
0133 list_for_each_entry(v, &vg->vlan_list, vlist) {
0134
0135
0136
0137
0138 if (v != pv && v->brvlan->msti == msti) {
0139 br_mst_vlan_set_state(pv->port, pv, v->state);
0140 return;
0141 }
0142 }
0143
0144
0145 return br_mst_vlan_set_state(pv->port, pv, BR_STATE_DISABLED);
0146 }
0147
0148 int br_mst_vlan_set_msti(struct net_bridge_vlan *mv, u16 msti)
0149 {
0150 struct switchdev_attr attr = {
0151 .id = SWITCHDEV_ATTR_ID_VLAN_MSTI,
0152 .orig_dev = mv->br->dev,
0153 .u.vlan_msti = {
0154 .vid = mv->vid,
0155 .msti = msti,
0156 },
0157 };
0158 struct net_bridge_vlan_group *vg;
0159 struct net_bridge_vlan *pv;
0160 struct net_bridge_port *p;
0161 int err;
0162
0163 if (mv->msti == msti)
0164 return 0;
0165
0166 err = switchdev_port_attr_set(mv->br->dev, &attr, NULL);
0167 if (err && err != -EOPNOTSUPP)
0168 return err;
0169
0170 mv->msti = msti;
0171
0172 list_for_each_entry(p, &mv->br->port_list, list) {
0173 vg = nbp_vlan_group(p);
0174
0175 pv = br_vlan_find(vg, mv->vid);
0176 if (pv)
0177 br_mst_vlan_sync_state(pv, msti);
0178 }
0179
0180 return 0;
0181 }
0182
0183 void br_mst_vlan_init_state(struct net_bridge_vlan *v)
0184 {
0185
0186 v->msti = 0;
0187
0188 if (br_vlan_is_master(v))
0189 v->state = BR_STATE_FORWARDING;
0190 else
0191 v->state = v->port->state;
0192 }
0193
0194 int br_mst_set_enabled(struct net_bridge *br, bool on,
0195 struct netlink_ext_ack *extack)
0196 {
0197 struct switchdev_attr attr = {
0198 .id = SWITCHDEV_ATTR_ID_BRIDGE_MST,
0199 .orig_dev = br->dev,
0200 .u.mst = on,
0201 };
0202 struct net_bridge_vlan_group *vg;
0203 struct net_bridge_port *p;
0204 int err;
0205
0206 list_for_each_entry(p, &br->port_list, list) {
0207 vg = nbp_vlan_group(p);
0208
0209 if (!vg->num_vlans)
0210 continue;
0211
0212 NL_SET_ERR_MSG(extack,
0213 "MST mode can't be changed while VLANs exist");
0214 return -EBUSY;
0215 }
0216
0217 if (br_opt_get(br, BROPT_MST_ENABLED) == on)
0218 return 0;
0219
0220 err = switchdev_port_attr_set(br->dev, &attr, extack);
0221 if (err && err != -EOPNOTSUPP)
0222 return err;
0223
0224 if (on)
0225 static_branch_enable(&br_mst_used);
0226 else
0227 static_branch_disable(&br_mst_used);
0228
0229 br_opt_toggle(br, BROPT_MST_ENABLED, on);
0230 return 0;
0231 }
0232
0233 size_t br_mst_info_size(const struct net_bridge_vlan_group *vg)
0234 {
0235 DECLARE_BITMAP(seen, VLAN_N_VID) = { 0 };
0236 const struct net_bridge_vlan *v;
0237 size_t sz;
0238
0239
0240 sz = nla_total_size(0);
0241
0242 list_for_each_entry_rcu(v, &vg->vlan_list, vlist) {
0243 if (test_bit(v->brvlan->msti, seen))
0244 continue;
0245
0246
0247 sz += nla_total_size(0) +
0248
0249 nla_total_size(sizeof(u16)) +
0250
0251 nla_total_size(sizeof(u8));
0252
0253 __set_bit(v->brvlan->msti, seen);
0254 }
0255
0256 return sz;
0257 }
0258
0259 int br_mst_fill_info(struct sk_buff *skb,
0260 const struct net_bridge_vlan_group *vg)
0261 {
0262 DECLARE_BITMAP(seen, VLAN_N_VID) = { 0 };
0263 const struct net_bridge_vlan *v;
0264 struct nlattr *nest;
0265 int err = 0;
0266
0267 list_for_each_entry(v, &vg->vlan_list, vlist) {
0268 if (test_bit(v->brvlan->msti, seen))
0269 continue;
0270
0271 nest = nla_nest_start_noflag(skb, IFLA_BRIDGE_MST_ENTRY);
0272 if (!nest ||
0273 nla_put_u16(skb, IFLA_BRIDGE_MST_ENTRY_MSTI, v->brvlan->msti) ||
0274 nla_put_u8(skb, IFLA_BRIDGE_MST_ENTRY_STATE, v->state)) {
0275 err = -EMSGSIZE;
0276 break;
0277 }
0278 nla_nest_end(skb, nest);
0279
0280 __set_bit(v->brvlan->msti, seen);
0281 }
0282
0283 return err;
0284 }
0285
0286 static const struct nla_policy br_mst_nl_policy[IFLA_BRIDGE_MST_ENTRY_MAX + 1] = {
0287 [IFLA_BRIDGE_MST_ENTRY_MSTI] = NLA_POLICY_RANGE(NLA_U16,
0288 1,
0289 VLAN_N_VID - 1),
0290 [IFLA_BRIDGE_MST_ENTRY_STATE] = NLA_POLICY_RANGE(NLA_U8,
0291 BR_STATE_DISABLED,
0292 BR_STATE_BLOCKING),
0293 };
0294
0295 static int br_mst_process_one(struct net_bridge_port *p,
0296 const struct nlattr *attr,
0297 struct netlink_ext_ack *extack)
0298 {
0299 struct nlattr *tb[IFLA_BRIDGE_MST_ENTRY_MAX + 1];
0300 u16 msti;
0301 u8 state;
0302 int err;
0303
0304 err = nla_parse_nested(tb, IFLA_BRIDGE_MST_ENTRY_MAX, attr,
0305 br_mst_nl_policy, extack);
0306 if (err)
0307 return err;
0308
0309 if (!tb[IFLA_BRIDGE_MST_ENTRY_MSTI]) {
0310 NL_SET_ERR_MSG_MOD(extack, "MSTI not specified");
0311 return -EINVAL;
0312 }
0313
0314 if (!tb[IFLA_BRIDGE_MST_ENTRY_STATE]) {
0315 NL_SET_ERR_MSG_MOD(extack, "State not specified");
0316 return -EINVAL;
0317 }
0318
0319 msti = nla_get_u16(tb[IFLA_BRIDGE_MST_ENTRY_MSTI]);
0320 state = nla_get_u8(tb[IFLA_BRIDGE_MST_ENTRY_STATE]);
0321
0322 return br_mst_set_state(p, msti, state, extack);
0323 }
0324
0325 int br_mst_process(struct net_bridge_port *p, const struct nlattr *mst_attr,
0326 struct netlink_ext_ack *extack)
0327 {
0328 struct nlattr *attr;
0329 int err, msts = 0;
0330 int rem;
0331
0332 if (!br_opt_get(p->br, BROPT_MST_ENABLED)) {
0333 NL_SET_ERR_MSG_MOD(extack, "Can't modify MST state when MST is disabled");
0334 return -EBUSY;
0335 }
0336
0337 nla_for_each_nested(attr, mst_attr, rem) {
0338 switch (nla_type(attr)) {
0339 case IFLA_BRIDGE_MST_ENTRY:
0340 err = br_mst_process_one(p, attr, extack);
0341 break;
0342 default:
0343 continue;
0344 }
0345
0346 msts++;
0347 if (err)
0348 break;
0349 }
0350
0351 if (!msts) {
0352 NL_SET_ERR_MSG_MOD(extack, "Found no MST entries to process");
0353 err = -EINVAL;
0354 }
0355
0356 return err;
0357 }