summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/spectrum.c4
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c23
2 files changed, 26 insertions, 1 deletions
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
index b343665219146..f5b2d965d476d 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
@@ -4760,6 +4760,10 @@ static int mlxsw_sp_netdevice_port_upper_event(struct net_device *lower_dev,
NL_SET_ERR_MSG_MOD(extack, "VLAN uppers are only supported with 802.1q VLAN protocol");
return -EOPNOTSUPP;
}
+ if (is_vlan_dev(upper_dev) && mlxsw_sp_port->security) {
+ NL_SET_ERR_MSG_MOD(extack, "VLAN uppers are not supported on a locked port");
+ return -EOPNOTSUPP;
+ }
break;
case NETDEV_CHANGEUPPER:
upper_dev = info->upper_dev;
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
index db149af7c888b..accea95cae5db 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
@@ -782,14 +782,26 @@ err_port_bridge_vlan_learning_set:
static int
mlxsw_sp_port_attr_br_pre_flags_set(struct mlxsw_sp_port *mlxsw_sp_port,
+ const struct net_device *orig_dev,
struct switchdev_brport_flags flags,
struct netlink_ext_ack *extack)
{
- if (flags.mask & ~(BR_LEARNING | BR_FLOOD | BR_MCAST_FLOOD)) {
+ if (flags.mask & ~(BR_LEARNING | BR_FLOOD | BR_MCAST_FLOOD |
+ BR_PORT_LOCKED | BR_PORT_MAB)) {
NL_SET_ERR_MSG_MOD(extack, "Unsupported bridge port flag");
return -EINVAL;
}
+ if ((flags.mask & BR_PORT_LOCKED) && is_vlan_dev(orig_dev)) {
+ NL_SET_ERR_MSG_MOD(extack, "Locked flag cannot be set on a VLAN upper");
+ return -EINVAL;
+ }
+
+ if ((flags.mask & BR_PORT_LOCKED) && vlan_uses_dev(orig_dev)) {
+ NL_SET_ERR_MSG_MOD(extack, "Locked flag cannot be set on a bridge port that has VLAN uppers");
+ return -EINVAL;
+ }
+
return 0;
}
@@ -822,6 +834,13 @@ static int mlxsw_sp_port_attr_br_flags_set(struct mlxsw_sp_port *mlxsw_sp_port,
return err;
}
+ if (flags.mask & BR_PORT_LOCKED) {
+ err = mlxsw_sp_port_security_set(mlxsw_sp_port,
+ flags.val & BR_PORT_LOCKED);
+ if (err)
+ return err;
+ }
+
if (bridge_port->bridge_device->multicast_enabled)
goto out;
@@ -1189,6 +1208,7 @@ static int mlxsw_sp_port_attr_set(struct net_device *dev, const void *ctx,
break;
case SWITCHDEV_ATTR_ID_PORT_PRE_BRIDGE_FLAGS:
err = mlxsw_sp_port_attr_br_pre_flags_set(mlxsw_sp_port,
+ attr->orig_dev,
attr->u.brport_flags,
extack);
break;
@@ -2787,6 +2807,7 @@ void mlxsw_sp_port_bridge_leave(struct mlxsw_sp_port *mlxsw_sp_port,
bridge_device->ops->port_leave(bridge_device, bridge_port,
mlxsw_sp_port);
+ mlxsw_sp_port_security_set(mlxsw_sp_port, false);
mlxsw_sp_bridge_port_put(mlxsw_sp->bridge, bridge_port);
}