mlxsw: spectrum: router: Add support for address validator notifier
Add support for inetaddr_validator and inet6addr_validator. The notifiers provide a means for validating ipv4 and ipv6 addresses before the addresses are installed and on failure the error is propagated back to the user. Signed-off-by: David Ahern <dsahern@gmail.com> Reviewed-by: Ido Schimmel <idosch@mellanox.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
de95e04791
commit
89d5dd2efd
@ -4521,9 +4521,16 @@ static int mlxsw_sp_netdevice_event(struct notifier_block *nb,
|
||||
return notifier_from_errno(err);
|
||||
}
|
||||
|
||||
static struct notifier_block mlxsw_sp_inetaddr_valid_nb __read_mostly = {
|
||||
.notifier_call = mlxsw_sp_inetaddr_valid_event,
|
||||
};
|
||||
|
||||
static struct notifier_block mlxsw_sp_inetaddr_nb __read_mostly = {
|
||||
.notifier_call = mlxsw_sp_inetaddr_event,
|
||||
.priority = 10, /* Must be called before FIB notifier block */
|
||||
};
|
||||
|
||||
static struct notifier_block mlxsw_sp_inet6addr_valid_nb __read_mostly = {
|
||||
.notifier_call = mlxsw_sp_inet6addr_valid_event,
|
||||
};
|
||||
|
||||
static struct notifier_block mlxsw_sp_inet6addr_nb __read_mostly = {
|
||||
@ -4548,7 +4555,9 @@ static int __init mlxsw_sp_module_init(void)
|
||||
{
|
||||
int err;
|
||||
|
||||
register_inetaddr_validator_notifier(&mlxsw_sp_inetaddr_valid_nb);
|
||||
register_inetaddr_notifier(&mlxsw_sp_inetaddr_nb);
|
||||
register_inet6addr_validator_notifier(&mlxsw_sp_inet6addr_valid_nb);
|
||||
register_inet6addr_notifier(&mlxsw_sp_inet6addr_nb);
|
||||
register_netevent_notifier(&mlxsw_sp_router_netevent_nb);
|
||||
|
||||
@ -4567,7 +4576,9 @@ static int __init mlxsw_sp_module_init(void)
|
||||
err_core_driver_register:
|
||||
unregister_netevent_notifier(&mlxsw_sp_router_netevent_nb);
|
||||
unregister_inet6addr_notifier(&mlxsw_sp_inet6addr_nb);
|
||||
unregister_inet6addr_validator_notifier(&mlxsw_sp_inet6addr_valid_nb);
|
||||
unregister_inetaddr_notifier(&mlxsw_sp_inetaddr_nb);
|
||||
unregister_inetaddr_validator_notifier(&mlxsw_sp_inetaddr_valid_nb);
|
||||
return err;
|
||||
}
|
||||
|
||||
@ -4577,7 +4588,9 @@ static void __exit mlxsw_sp_module_exit(void)
|
||||
mlxsw_core_driver_unregister(&mlxsw_sp_driver);
|
||||
unregister_netevent_notifier(&mlxsw_sp_router_netevent_nb);
|
||||
unregister_inet6addr_notifier(&mlxsw_sp_inet6addr_nb);
|
||||
unregister_inet6addr_validator_notifier(&mlxsw_sp_inet6addr_valid_nb);
|
||||
unregister_inetaddr_notifier(&mlxsw_sp_inetaddr_nb);
|
||||
unregister_inetaddr_validator_notifier(&mlxsw_sp_inetaddr_valid_nb);
|
||||
}
|
||||
|
||||
module_init(mlxsw_sp_module_init);
|
||||
|
@ -391,8 +391,12 @@ int mlxsw_sp_router_netevent_event(struct notifier_block *unused,
|
||||
int mlxsw_sp_netdevice_router_port_event(struct net_device *dev);
|
||||
int mlxsw_sp_inetaddr_event(struct notifier_block *unused,
|
||||
unsigned long event, void *ptr);
|
||||
int mlxsw_sp_inetaddr_valid_event(struct notifier_block *unused,
|
||||
unsigned long event, void *ptr);
|
||||
int mlxsw_sp_inet6addr_event(struct notifier_block *unused,
|
||||
unsigned long event, void *ptr);
|
||||
int mlxsw_sp_inet6addr_valid_event(struct notifier_block *unused,
|
||||
unsigned long event, void *ptr);
|
||||
int mlxsw_sp_netdevice_vrf_event(struct net_device *l3_dev, unsigned long event,
|
||||
struct netdev_notifier_changeupper_info *info);
|
||||
bool mlxsw_sp_netdev_is_ipip(const struct mlxsw_sp *mlxsw_sp,
|
||||
|
@ -5781,6 +5781,32 @@ int mlxsw_sp_inetaddr_event(struct notifier_block *unused,
|
||||
struct mlxsw_sp_rif *rif;
|
||||
int err = 0;
|
||||
|
||||
/* NETDEV_UP event is handled by mlxsw_sp_inetaddr_valid_event */
|
||||
if (event == NETDEV_UP)
|
||||
goto out;
|
||||
|
||||
mlxsw_sp = mlxsw_sp_lower_get(dev);
|
||||
if (!mlxsw_sp)
|
||||
goto out;
|
||||
|
||||
rif = mlxsw_sp_rif_find_by_dev(mlxsw_sp, dev);
|
||||
if (!mlxsw_sp_rif_should_config(rif, dev, event))
|
||||
goto out;
|
||||
|
||||
err = __mlxsw_sp_inetaddr_event(dev, event);
|
||||
out:
|
||||
return notifier_from_errno(err);
|
||||
}
|
||||
|
||||
int mlxsw_sp_inetaddr_valid_event(struct notifier_block *unused,
|
||||
unsigned long event, void *ptr)
|
||||
{
|
||||
struct in_validator_info *ivi = (struct in_validator_info *) ptr;
|
||||
struct net_device *dev = ivi->ivi_dev->dev;
|
||||
struct mlxsw_sp *mlxsw_sp;
|
||||
struct mlxsw_sp_rif *rif;
|
||||
int err = 0;
|
||||
|
||||
mlxsw_sp = mlxsw_sp_lower_get(dev);
|
||||
if (!mlxsw_sp)
|
||||
goto out;
|
||||
@ -5833,6 +5859,10 @@ int mlxsw_sp_inet6addr_event(struct notifier_block *unused,
|
||||
struct mlxsw_sp_inet6addr_event_work *inet6addr_work;
|
||||
struct net_device *dev = if6->idev->dev;
|
||||
|
||||
/* NETDEV_UP event is handled by mlxsw_sp_inet6addr_valid_event */
|
||||
if (event == NETDEV_UP)
|
||||
return NOTIFY_DONE;
|
||||
|
||||
if (!mlxsw_sp_port_dev_lower_find_rcu(dev))
|
||||
return NOTIFY_DONE;
|
||||
|
||||
@ -5849,6 +5879,28 @@ int mlxsw_sp_inet6addr_event(struct notifier_block *unused,
|
||||
return NOTIFY_DONE;
|
||||
}
|
||||
|
||||
int mlxsw_sp_inet6addr_valid_event(struct notifier_block *unused,
|
||||
unsigned long event, void *ptr)
|
||||
{
|
||||
struct in6_validator_info *i6vi = (struct in6_validator_info *) ptr;
|
||||
struct net_device *dev = i6vi->i6vi_dev->dev;
|
||||
struct mlxsw_sp *mlxsw_sp;
|
||||
struct mlxsw_sp_rif *rif;
|
||||
int err = 0;
|
||||
|
||||
mlxsw_sp = mlxsw_sp_lower_get(dev);
|
||||
if (!mlxsw_sp)
|
||||
goto out;
|
||||
|
||||
rif = mlxsw_sp_rif_find_by_dev(mlxsw_sp, dev);
|
||||
if (!mlxsw_sp_rif_should_config(rif, dev, event))
|
||||
goto out;
|
||||
|
||||
err = __mlxsw_sp_inetaddr_event(dev, event);
|
||||
out:
|
||||
return notifier_from_errno(err);
|
||||
}
|
||||
|
||||
static int mlxsw_sp_rif_edit(struct mlxsw_sp *mlxsw_sp, u16 rif_index,
|
||||
const char *mac, int mtu)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user