summaryrefslogtreecommitdiff
path: root/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
diff options
context:
space:
mode:
authorIdo Schimmel <idosch@mellanox.com>2017-03-16 09:08:18 +0100
committerDavid S. Miller <davem@davemloft.net>2017-03-16 10:18:35 -0700
commit7179eb5acd59d64cb8bef2d8788af8e9647f6986 (patch)
tree5b4008bafc6a9147442ab4f96c91d7e4e3964023 /drivers/net/ethernet/mellanox/mlxsw/spectrum.c
parent9db032bb1e8eed0721884c01a6c87f55f3d400fa (diff)
downloadlwn-7179eb5acd59d64cb8bef2d8788af8e9647f6986.tar.gz
lwn-7179eb5acd59d64cb8bef2d8788af8e9647f6986.zip
mlxsw: spectrum_router: Add support for VRFs
Allow port netdevs, LAG and VLAN devices stacked on top of these to be enslaved to a VRF master device. Upon enslavement, create a router interface (RIF) for the enslaved netdev and associate it with a virtual router (VR) based on the VRF's table ID. If a RIF already exists for the netdev (f.e., due to the existence of an IP address), then it's deleted and a new one is created with the appropriate VR binding. Signed-off-by: Ido Schimmel <idosch@mellanox.com> Signed-off-by: Jiri Pirko <jiri@mellanox.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/mellanox/mlxsw/spectrum.c')
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/spectrum.c19
1 files changed, 16 insertions, 3 deletions
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
index 475499b6c989..659df3225a24 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
@@ -3951,7 +3951,8 @@ static int mlxsw_sp_netdevice_port_upper_event(struct net_device *dev,
upper_dev = info->upper_dev;
if (!is_vlan_dev(upper_dev) &&
!netif_is_lag_master(upper_dev) &&
- !netif_is_bridge_master(upper_dev))
+ !netif_is_bridge_master(upper_dev) &&
+ !netif_is_l3_master(upper_dev))
return -EINVAL;
if (!info->linking)
break;
@@ -3991,6 +3992,11 @@ static int mlxsw_sp_netdevice_port_upper_event(struct net_device *dev,
else
mlxsw_sp_port_lag_leave(mlxsw_sp_port,
upper_dev);
+ } else if (netif_is_l3_master(upper_dev)) {
+ if (info->linking)
+ err = mlxsw_sp_port_vrf_join(mlxsw_sp_port);
+ else
+ mlxsw_sp_port_vrf_leave(mlxsw_sp_port);
} else {
err = -EINVAL;
WARN_ON(1);
@@ -4353,14 +4359,16 @@ static int mlxsw_sp_netdevice_vport_event(struct net_device *dev,
switch (event) {
case NETDEV_PRECHANGEUPPER:
upper_dev = info->upper_dev;
- if (!netif_is_bridge_master(upper_dev))
+ if (!netif_is_bridge_master(upper_dev) &&
+ !netif_is_l3_master(upper_dev))
return -EINVAL;
if (!info->linking)
break;
/* We can't have multiple VLAN interfaces configured on
* the same port and being members in the same bridge.
*/
- if (!mlxsw_sp_port_master_bridge_check(mlxsw_sp_port,
+ if (netif_is_bridge_master(upper_dev) &&
+ !mlxsw_sp_port_master_bridge_check(mlxsw_sp_port,
upper_dev))
return -EINVAL;
break;
@@ -4372,6 +4380,11 @@ static int mlxsw_sp_netdevice_vport_event(struct net_device *dev,
upper_dev);
else
mlxsw_sp_vport_bridge_leave(mlxsw_sp_vport);
+ } else if (netif_is_l3_master(upper_dev)) {
+ if (info->linking)
+ err = mlxsw_sp_vport_vrf_join(mlxsw_sp_vport);
+ else
+ mlxsw_sp_vport_vrf_leave(mlxsw_sp_vport);
} else {
err = -EINVAL;
WARN_ON(1);