Commit 6bbc9ca6 authored by Petr Machata's avatar Petr Machata Committed by David S. Miller

mlxsw: spectrum_router: Allow address handlers to run on bridge ports

Currently the IP address event handlers bail out when the event is related
to a netdevice that is a bridge port or a member of a LAG. In order to
create a RIF when a bridged or LAG'd port is unenslaved, these event
handlers will be replayed. However, at the point in time when the
NETDEV_CHANGEUPPER event is delivered, informing of the loss of
enslavement, the port is still formally enslaved.

In order for the operation to have any effect, these handlers need an extra
parameter to indicate that the check for bridge or LAG membership should
not be done. In this patch, add an argument "nomaster" to several event
handlers.
Signed-off-by: default avatarPetr Machata <petrm@nvidia.com>
Reviewed-by: default avatarDanielle Ratson <danieller@nvidia.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent d7eb1f17
...@@ -8884,10 +8884,11 @@ static int mlxsw_sp_inetaddr_port_vlan_event(struct net_device *l3_dev, ...@@ -8884,10 +8884,11 @@ static int mlxsw_sp_inetaddr_port_vlan_event(struct net_device *l3_dev,
} }
static int mlxsw_sp_inetaddr_port_event(struct net_device *port_dev, static int mlxsw_sp_inetaddr_port_event(struct net_device *port_dev,
unsigned long event, unsigned long event, bool nomaster,
struct netlink_ext_ack *extack) struct netlink_ext_ack *extack)
{ {
if (netif_is_any_bridge_port(port_dev) || netif_is_lag_port(port_dev)) if (!nomaster && (netif_is_any_bridge_port(port_dev) ||
netif_is_lag_port(port_dev)))
return 0; return 0;
return mlxsw_sp_inetaddr_port_vlan_event(port_dev, port_dev, event, return mlxsw_sp_inetaddr_port_vlan_event(port_dev, port_dev, event,
...@@ -8918,10 +8919,10 @@ static int __mlxsw_sp_inetaddr_lag_event(struct net_device *l3_dev, ...@@ -8918,10 +8919,10 @@ static int __mlxsw_sp_inetaddr_lag_event(struct net_device *l3_dev,
} }
static int mlxsw_sp_inetaddr_lag_event(struct net_device *lag_dev, static int mlxsw_sp_inetaddr_lag_event(struct net_device *lag_dev,
unsigned long event, unsigned long event, bool nomaster,
struct netlink_ext_ack *extack) struct netlink_ext_ack *extack)
{ {
if (netif_is_bridge_port(lag_dev)) if (!nomaster && netif_is_bridge_port(lag_dev))
return 0; return 0;
return __mlxsw_sp_inetaddr_lag_event(lag_dev, lag_dev, event, return __mlxsw_sp_inetaddr_lag_event(lag_dev, lag_dev, event,
...@@ -8980,7 +8981,7 @@ static int mlxsw_sp_inetaddr_bridge_event(struct mlxsw_sp *mlxsw_sp, ...@@ -8980,7 +8981,7 @@ static int mlxsw_sp_inetaddr_bridge_event(struct mlxsw_sp *mlxsw_sp,
static int mlxsw_sp_inetaddr_vlan_event(struct mlxsw_sp *mlxsw_sp, static int mlxsw_sp_inetaddr_vlan_event(struct mlxsw_sp *mlxsw_sp,
struct net_device *vlan_dev, struct net_device *vlan_dev,
unsigned long event, unsigned long event, bool nomaster,
struct netlink_ext_ack *extack) struct netlink_ext_ack *extack)
{ {
struct net_device *real_dev = vlan_dev_real_dev(vlan_dev); struct net_device *real_dev = vlan_dev_real_dev(vlan_dev);
...@@ -8988,7 +8989,7 @@ static int mlxsw_sp_inetaddr_vlan_event(struct mlxsw_sp *mlxsw_sp, ...@@ -8988,7 +8989,7 @@ static int mlxsw_sp_inetaddr_vlan_event(struct mlxsw_sp *mlxsw_sp,
u16 lower_pvid; u16 lower_pvid;
int err; int err;
if (netif_is_bridge_port(vlan_dev)) if (!nomaster && netif_is_bridge_port(vlan_dev))
return 0; return 0;
if (mlxsw_sp_port_dev_check(real_dev)) { if (mlxsw_sp_port_dev_check(real_dev)) {
...@@ -9132,19 +9133,21 @@ static int mlxsw_sp_inetaddr_macvlan_event(struct mlxsw_sp *mlxsw_sp, ...@@ -9132,19 +9133,21 @@ static int mlxsw_sp_inetaddr_macvlan_event(struct mlxsw_sp *mlxsw_sp,
static int __mlxsw_sp_inetaddr_event(struct mlxsw_sp *mlxsw_sp, static int __mlxsw_sp_inetaddr_event(struct mlxsw_sp *mlxsw_sp,
struct net_device *dev, struct net_device *dev,
unsigned long event, unsigned long event, bool nomaster,
struct netlink_ext_ack *extack) struct netlink_ext_ack *extack)
{ {
if (mlxsw_sp_port_dev_check(dev)) if (mlxsw_sp_port_dev_check(dev))
return mlxsw_sp_inetaddr_port_event(dev, event, extack); return mlxsw_sp_inetaddr_port_event(dev, event, nomaster,
extack);
else if (netif_is_lag_master(dev)) else if (netif_is_lag_master(dev))
return mlxsw_sp_inetaddr_lag_event(dev, event, extack); return mlxsw_sp_inetaddr_lag_event(dev, event, nomaster,
extack);
else if (netif_is_bridge_master(dev)) else if (netif_is_bridge_master(dev))
return mlxsw_sp_inetaddr_bridge_event(mlxsw_sp, dev, -1, event, return mlxsw_sp_inetaddr_bridge_event(mlxsw_sp, dev, -1, event,
extack); extack);
else if (is_vlan_dev(dev)) else if (is_vlan_dev(dev))
return mlxsw_sp_inetaddr_vlan_event(mlxsw_sp, dev, event, return mlxsw_sp_inetaddr_vlan_event(mlxsw_sp, dev, event,
extack); nomaster, extack);
else if (netif_is_macvlan(dev)) else if (netif_is_macvlan(dev))
return mlxsw_sp_inetaddr_macvlan_event(mlxsw_sp, dev, event, return mlxsw_sp_inetaddr_macvlan_event(mlxsw_sp, dev, event,
extack); extack);
...@@ -9171,7 +9174,8 @@ static int mlxsw_sp_inetaddr_event(struct notifier_block *nb, ...@@ -9171,7 +9174,8 @@ static int mlxsw_sp_inetaddr_event(struct notifier_block *nb,
if (!mlxsw_sp_rif_should_config(rif, dev, event)) if (!mlxsw_sp_rif_should_config(rif, dev, event))
goto out; goto out;
err = __mlxsw_sp_inetaddr_event(router->mlxsw_sp, dev, event, NULL); err = __mlxsw_sp_inetaddr_event(router->mlxsw_sp, dev, event, false,
NULL);
out: out:
mutex_unlock(&router->lock); mutex_unlock(&router->lock);
return notifier_from_errno(err); return notifier_from_errno(err);
...@@ -9195,7 +9199,8 @@ static int mlxsw_sp_inetaddr_valid_event(struct notifier_block *unused, ...@@ -9195,7 +9199,8 @@ static int mlxsw_sp_inetaddr_valid_event(struct notifier_block *unused,
if (!mlxsw_sp_rif_should_config(rif, dev, event)) if (!mlxsw_sp_rif_should_config(rif, dev, event))
goto out; goto out;
err = __mlxsw_sp_inetaddr_event(mlxsw_sp, dev, event, ivi->extack); err = __mlxsw_sp_inetaddr_event(mlxsw_sp, dev, event, false,
ivi->extack);
out: out:
mutex_unlock(&mlxsw_sp->router->lock); mutex_unlock(&mlxsw_sp->router->lock);
return notifier_from_errno(err); return notifier_from_errno(err);
...@@ -9224,7 +9229,7 @@ static void mlxsw_sp_inet6addr_event_work(struct work_struct *work) ...@@ -9224,7 +9229,7 @@ static void mlxsw_sp_inet6addr_event_work(struct work_struct *work)
if (!mlxsw_sp_rif_should_config(rif, dev, event)) if (!mlxsw_sp_rif_should_config(rif, dev, event))
goto out; goto out;
__mlxsw_sp_inetaddr_event(mlxsw_sp, dev, event, NULL); __mlxsw_sp_inetaddr_event(mlxsw_sp, dev, event, false, NULL);
out: out:
mutex_unlock(&mlxsw_sp->router->lock); mutex_unlock(&mlxsw_sp->router->lock);
rtnl_unlock(); rtnl_unlock();
...@@ -9278,7 +9283,8 @@ static int mlxsw_sp_inet6addr_valid_event(struct notifier_block *unused, ...@@ -9278,7 +9283,8 @@ static int mlxsw_sp_inet6addr_valid_event(struct notifier_block *unused,
if (!mlxsw_sp_rif_should_config(rif, dev, event)) if (!mlxsw_sp_rif_should_config(rif, dev, event))
goto out; goto out;
err = __mlxsw_sp_inetaddr_event(mlxsw_sp, dev, event, i6vi->extack); err = __mlxsw_sp_inetaddr_event(mlxsw_sp, dev, event, false,
i6vi->extack);
out: out:
mutex_unlock(&mlxsw_sp->router->lock); mutex_unlock(&mlxsw_sp->router->lock);
return notifier_from_errno(err); return notifier_from_errno(err);
...@@ -9598,10 +9604,11 @@ static int mlxsw_sp_port_vrf_join(struct mlxsw_sp *mlxsw_sp, ...@@ -9598,10 +9604,11 @@ static int mlxsw_sp_port_vrf_join(struct mlxsw_sp *mlxsw_sp,
*/ */
rif = mlxsw_sp_rif_find_by_dev(mlxsw_sp, l3_dev); rif = mlxsw_sp_rif_find_by_dev(mlxsw_sp, l3_dev);
if (rif) if (rif)
__mlxsw_sp_inetaddr_event(mlxsw_sp, l3_dev, NETDEV_DOWN, __mlxsw_sp_inetaddr_event(mlxsw_sp, l3_dev, NETDEV_DOWN, false,
extack); extack);
return __mlxsw_sp_inetaddr_event(mlxsw_sp, l3_dev, NETDEV_UP, extack); return __mlxsw_sp_inetaddr_event(mlxsw_sp, l3_dev, NETDEV_UP, false,
extack);
} }
static void mlxsw_sp_port_vrf_leave(struct mlxsw_sp *mlxsw_sp, static void mlxsw_sp_port_vrf_leave(struct mlxsw_sp *mlxsw_sp,
...@@ -9612,7 +9619,7 @@ static void mlxsw_sp_port_vrf_leave(struct mlxsw_sp *mlxsw_sp, ...@@ -9612,7 +9619,7 @@ static void mlxsw_sp_port_vrf_leave(struct mlxsw_sp *mlxsw_sp,
rif = mlxsw_sp_rif_find_by_dev(mlxsw_sp, l3_dev); rif = mlxsw_sp_rif_find_by_dev(mlxsw_sp, l3_dev);
if (!rif) if (!rif)
return; return;
__mlxsw_sp_inetaddr_event(mlxsw_sp, l3_dev, NETDEV_DOWN, NULL); __mlxsw_sp_inetaddr_event(mlxsw_sp, l3_dev, NETDEV_DOWN, false, NULL);
} }
static bool mlxsw_sp_is_vrf_event(unsigned long event, void *ptr) static bool mlxsw_sp_is_vrf_event(unsigned long event, void *ptr)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment