|
@@ -4019,14 +4019,21 @@ static int mlxsw_sp_lag_index_get(struct mlxsw_sp *mlxsw_sp,
|
|
|
static bool
|
|
|
mlxsw_sp_master_lag_check(struct mlxsw_sp *mlxsw_sp,
|
|
|
struct net_device *lag_dev,
|
|
|
- struct netdev_lag_upper_info *lag_upper_info)
|
|
|
+ struct netdev_lag_upper_info *lag_upper_info,
|
|
|
+ struct netlink_ext_ack *extack)
|
|
|
{
|
|
|
u16 lag_id;
|
|
|
|
|
|
- if (mlxsw_sp_lag_index_get(mlxsw_sp, lag_dev, &lag_id) != 0)
|
|
|
+ if (mlxsw_sp_lag_index_get(mlxsw_sp, lag_dev, &lag_id) != 0) {
|
|
|
+ NL_SET_ERR_MSG(extack,
|
|
|
+ "spectrum: Exceeded number of supported LAG devices");
|
|
|
return false;
|
|
|
- if (lag_upper_info->tx_type != NETDEV_LAG_TX_TYPE_HASH)
|
|
|
+ }
|
|
|
+ if (lag_upper_info->tx_type != NETDEV_LAG_TX_TYPE_HASH) {
|
|
|
+ NL_SET_ERR_MSG(extack,
|
|
|
+ "spectrum: LAG device using unsupported Tx type");
|
|
|
return false;
|
|
|
+ }
|
|
|
return true;
|
|
|
}
|
|
|
|
|
@@ -4231,6 +4238,7 @@ static int mlxsw_sp_netdevice_port_upper_event(struct net_device *lower_dev,
|
|
|
{
|
|
|
struct netdev_notifier_changeupper_info *info;
|
|
|
struct mlxsw_sp_port *mlxsw_sp_port;
|
|
|
+ struct netlink_ext_ack *extack;
|
|
|
struct net_device *upper_dev;
|
|
|
struct mlxsw_sp *mlxsw_sp;
|
|
|
int err = 0;
|
|
@@ -4238,6 +4246,7 @@ static int mlxsw_sp_netdevice_port_upper_event(struct net_device *lower_dev,
|
|
|
mlxsw_sp_port = netdev_priv(dev);
|
|
|
mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
|
|
|
info = ptr;
|
|
|
+ extack = netdev_notifier_info_to_extack(&info->info);
|
|
|
|
|
|
switch (event) {
|
|
|
case NETDEV_PRECHANGEUPPER:
|
|
@@ -4245,25 +4254,43 @@ static int mlxsw_sp_netdevice_port_upper_event(struct net_device *lower_dev,
|
|
|
if (!is_vlan_dev(upper_dev) &&
|
|
|
!netif_is_lag_master(upper_dev) &&
|
|
|
!netif_is_bridge_master(upper_dev) &&
|
|
|
- !netif_is_ovs_master(upper_dev))
|
|
|
+ !netif_is_ovs_master(upper_dev)) {
|
|
|
+ NL_SET_ERR_MSG(extack,
|
|
|
+ "spectrum: Unknown upper device type");
|
|
|
return -EINVAL;
|
|
|
+ }
|
|
|
if (!info->linking)
|
|
|
break;
|
|
|
- if (netdev_has_any_upper_dev(upper_dev))
|
|
|
+ if (netdev_has_any_upper_dev(upper_dev)) {
|
|
|
+ NL_SET_ERR_MSG(extack,
|
|
|
+ "spectrum: Enslaving a port to a device that already has an upper device is not supported");
|
|
|
return -EINVAL;
|
|
|
+ }
|
|
|
if (netif_is_lag_master(upper_dev) &&
|
|
|
!mlxsw_sp_master_lag_check(mlxsw_sp, upper_dev,
|
|
|
- info->upper_info))
|
|
|
+ info->upper_info, extack))
|
|
|
return -EINVAL;
|
|
|
- if (netif_is_lag_master(upper_dev) && vlan_uses_dev(dev))
|
|
|
+ if (netif_is_lag_master(upper_dev) && vlan_uses_dev(dev)) {
|
|
|
+ NL_SET_ERR_MSG(extack,
|
|
|
+ "spectrum: Master device is a LAG master and this device has a VLAN");
|
|
|
return -EINVAL;
|
|
|
+ }
|
|
|
if (netif_is_lag_port(dev) && is_vlan_dev(upper_dev) &&
|
|
|
- !netif_is_lag_master(vlan_dev_real_dev(upper_dev)))
|
|
|
+ !netif_is_lag_master(vlan_dev_real_dev(upper_dev))) {
|
|
|
+ NL_SET_ERR_MSG(extack,
|
|
|
+ "spectrum: Can not put a VLAN on a LAG port");
|
|
|
return -EINVAL;
|
|
|
- if (netif_is_ovs_master(upper_dev) && vlan_uses_dev(dev))
|
|
|
+ }
|
|
|
+ if (netif_is_ovs_master(upper_dev) && vlan_uses_dev(dev)) {
|
|
|
+ NL_SET_ERR_MSG(extack,
|
|
|
+ "spectrum: Master device is an OVS master and this device has a VLAN");
|
|
|
return -EINVAL;
|
|
|
- if (netif_is_ovs_port(dev) && is_vlan_dev(upper_dev))
|
|
|
+ }
|
|
|
+ if (netif_is_ovs_port(dev) && is_vlan_dev(upper_dev)) {
|
|
|
+ NL_SET_ERR_MSG(extack,
|
|
|
+ "spectrum: Can not put a VLAN on an OVS port");
|
|
|
return -EINVAL;
|
|
|
+ }
|
|
|
break;
|
|
|
case NETDEV_CHANGEUPPER:
|
|
|
upper_dev = info->upper_dev;
|