Skip to content

Commit 2b94e58

Browse files
jpirkodavem330
authored andcommitted
mlxsw: spectrum: Allow ports to work under OVS master
>From now on, a port can become a slave of OVS master. All vlans are enabled, STP state is set to "forwarding". It is up to the OVS userspace daemon to setup the flows either in kernel or in HW using TC flower offload. Signed-off-by: Jiri Pirko <[email protected]> Reviewed-by: Ido Schimmel <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 5be6614 commit 2b94e58

File tree

2 files changed

+64
-2
lines changed

2 files changed

+64
-2
lines changed

drivers/net/ethernet/mellanox/mlxsw/spectrum.c

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4036,6 +4036,56 @@ static void mlxsw_sp_port_vlan_unlink(struct mlxsw_sp_port *mlxsw_sp_port,
40364036
mlxsw_sp_vport->dev = mlxsw_sp_port->dev;
40374037
}
40384038

4039+
static int mlxsw_sp_port_stp_set(struct mlxsw_sp_port *mlxsw_sp_port,
4040+
bool enable)
4041+
{
4042+
struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
4043+
enum mlxsw_reg_spms_state spms_state;
4044+
char *spms_pl;
4045+
u16 vid;
4046+
int err;
4047+
4048+
spms_state = enable ? MLXSW_REG_SPMS_STATE_FORWARDING :
4049+
MLXSW_REG_SPMS_STATE_DISCARDING;
4050+
4051+
spms_pl = kmalloc(MLXSW_REG_SPMS_LEN, GFP_KERNEL);
4052+
if (!spms_pl)
4053+
return -ENOMEM;
4054+
mlxsw_reg_spms_pack(spms_pl, mlxsw_sp_port->local_port);
4055+
4056+
for (vid = 0; vid < VLAN_N_VID; vid++)
4057+
mlxsw_reg_spms_vid_pack(spms_pl, vid, spms_state);
4058+
4059+
err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(spms), spms_pl);
4060+
kfree(spms_pl);
4061+
return err;
4062+
}
4063+
4064+
static int mlxsw_sp_port_ovs_join(struct mlxsw_sp_port *mlxsw_sp_port)
4065+
{
4066+
int err;
4067+
4068+
err = mlxsw_sp_port_stp_set(mlxsw_sp_port, true);
4069+
if (err)
4070+
return err;
4071+
err = mlxsw_sp_port_vlan_set(mlxsw_sp_port, 2, VLAN_N_VID - 1,
4072+
true, false);
4073+
if (err)
4074+
goto err_port_vlan_set;
4075+
return 0;
4076+
4077+
err_port_vlan_set:
4078+
mlxsw_sp_port_stp_set(mlxsw_sp_port, false);
4079+
return err;
4080+
}
4081+
4082+
static void mlxsw_sp_port_ovs_leave(struct mlxsw_sp_port *mlxsw_sp_port)
4083+
{
4084+
mlxsw_sp_port_vlan_set(mlxsw_sp_port, 2, VLAN_N_VID - 1,
4085+
false, false);
4086+
mlxsw_sp_port_stp_set(mlxsw_sp_port, false);
4087+
}
4088+
40394089
static int mlxsw_sp_netdevice_port_upper_event(struct net_device *dev,
40404090
unsigned long event, void *ptr)
40414091
{
@@ -4055,7 +4105,8 @@ static int mlxsw_sp_netdevice_port_upper_event(struct net_device *dev,
40554105
if (!is_vlan_dev(upper_dev) &&
40564106
!netif_is_lag_master(upper_dev) &&
40574107
!netif_is_bridge_master(upper_dev) &&
4058-
!netif_is_l3_master(upper_dev))
4108+
!netif_is_l3_master(upper_dev) &&
4109+
!netif_is_ovs_master(upper_dev))
40594110
return -EINVAL;
40604111
if (!info->linking)
40614112
break;
@@ -4072,6 +4123,10 @@ static int mlxsw_sp_netdevice_port_upper_event(struct net_device *dev,
40724123
if (netif_is_lag_port(dev) && is_vlan_dev(upper_dev) &&
40734124
!netif_is_lag_master(vlan_dev_real_dev(upper_dev)))
40744125
return -EINVAL;
4126+
if (netif_is_ovs_master(upper_dev) && vlan_uses_dev(dev))
4127+
return -EINVAL;
4128+
if (netif_is_ovs_port(dev) && is_vlan_dev(upper_dev))
4129+
return -EINVAL;
40754130
break;
40764131
case NETDEV_CHANGEUPPER:
40774132
upper_dev = info->upper_dev;
@@ -4100,6 +4155,11 @@ static int mlxsw_sp_netdevice_port_upper_event(struct net_device *dev,
41004155
err = mlxsw_sp_port_vrf_join(mlxsw_sp_port);
41014156
else
41024157
mlxsw_sp_port_vrf_leave(mlxsw_sp_port);
4158+
} else if (netif_is_ovs_master(upper_dev)) {
4159+
if (info->linking)
4160+
err = mlxsw_sp_port_ovs_join(mlxsw_sp_port);
4161+
else
4162+
mlxsw_sp_port_ovs_leave(mlxsw_sp_port);
41034163
} else {
41044164
err = -EINVAL;
41054165
WARN_ON(1);

drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3098,7 +3098,9 @@ static int mlxsw_sp_inetaddr_vport_event(struct net_device *l3_dev,
30983098
static int mlxsw_sp_inetaddr_port_event(struct net_device *port_dev,
30993099
unsigned long event)
31003100
{
3101-
if (netif_is_bridge_port(port_dev) || netif_is_lag_port(port_dev))
3101+
if (netif_is_bridge_port(port_dev) ||
3102+
netif_is_lag_port(port_dev) ||
3103+
netif_is_ovs_port(port_dev))
31023104
return 0;
31033105

31043106
return mlxsw_sp_inetaddr_vport_event(port_dev, port_dev, event, 1);

0 commit comments

Comments
 (0)