diff options
Diffstat (limited to 'drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c')
-rw-r--r-- | drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c | 23 |
1 files changed, 22 insertions, 1 deletions
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c index db149af7c888..accea95cae5d 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); } |