Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

mlxsw: spectrum_switchdev: Ban PVID change if bridge has a RIF

When traffic passes through a router port, it needs to be assigned a FID
for ASIC to forward correctly. For bridges, this FID used to be the one
corresponding to VLAN 1. In a previous patch, this was changed to
instead use the PVID at the time that the RIF is created. This patch
guards PVID changes after the RIF was introduced.

Signed-off-by: Petr Machata <petrm@mellanox.com>
Signed-off-by: Ido Schimmel <idosch@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Petr Machata and committed by
David S. Miller
567ad1a2 a28b1ebe

+45 -2
+45 -2
drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
··· 1135 1135 return err; 1136 1136 } 1137 1137 1138 + static int 1139 + mlxsw_sp_br_ban_rif_pvid_change(struct mlxsw_sp *mlxsw_sp, 1140 + const struct net_device *br_dev, 1141 + const struct switchdev_obj_port_vlan *vlan) 1142 + { 1143 + struct mlxsw_sp_rif *rif; 1144 + struct mlxsw_sp_fid *fid; 1145 + u16 pvid; 1146 + u16 vid; 1147 + 1148 + rif = mlxsw_sp_rif_find_by_dev(mlxsw_sp, br_dev); 1149 + if (!rif) 1150 + return 0; 1151 + fid = mlxsw_sp_rif_fid(rif); 1152 + pvid = mlxsw_sp_fid_8021q_vid(fid); 1153 + 1154 + for (vid = vlan->vid_begin; vid <= vlan->vid_end; ++vid) { 1155 + if (vlan->flags & BRIDGE_VLAN_INFO_PVID) { 1156 + if (vid != pvid) { 1157 + netdev_err(br_dev, "Can't change PVID, it's used by router interface\n"); 1158 + return -EBUSY; 1159 + } 1160 + } else { 1161 + if (vid == pvid) { 1162 + netdev_err(br_dev, "Can't remove PVID, it's used by router interface\n"); 1163 + return -EBUSY; 1164 + } 1165 + } 1166 + } 1167 + 1168 + return 0; 1169 + } 1170 + 1138 1171 static int mlxsw_sp_port_vlans_add(struct mlxsw_sp_port *mlxsw_sp_port, 1139 1172 const struct switchdev_obj_port_vlan *vlan, 1140 1173 struct switchdev_trans *trans) ··· 1179 1146 struct mlxsw_sp_bridge_port *bridge_port; 1180 1147 u16 vid; 1181 1148 1182 - if (netif_is_bridge_master(orig_dev)) 1183 - return -EOPNOTSUPP; 1149 + if (netif_is_bridge_master(orig_dev)) { 1150 + int err = 0; 1151 + 1152 + if ((vlan->flags & BRIDGE_VLAN_INFO_BRENTRY) && 1153 + br_vlan_enabled(orig_dev) && 1154 + switchdev_trans_ph_prepare(trans)) 1155 + err = mlxsw_sp_br_ban_rif_pvid_change(mlxsw_sp, 1156 + orig_dev, vlan); 1157 + if (!err) 1158 + err = -EOPNOTSUPP; 1159 + return err; 1160 + } 1184 1161 1185 1162 if (switchdev_trans_ph_prepare(trans)) 1186 1163 return 0;