Merge branch 'mlxsw-cleanups'

Petr Machata says:

====================
mlxsw: Cleanups in router code

This patchset moves some router-related code from spectrum.c to
spectrum_router.c where it should be. It also simplifies handlers of
netevent notifications.

- Patch #1 caches router pointer in a dedicated variable. This obviates the
  need to access the same as mlxsw_sp->router, making lines shorter, and
  permitting a future patch to add code that fits within 80 character
  limit.

- Patch #2 moves IP / IPv6 validation notifier blocks from spectrum.c
  to spectrum_router, where the handlers are anyway.

- In patch #3, pass router pointer to scheduler of deferred work directly,
  instead of having it deduce it on its own.

- This makes the router pointer available in the handler function
  mlxsw_sp_router_netevent_event(), so in patch #4, use it directly,
  instead of finding it through mlxsw_sp_port.

- In patch #5, extend mlxsw_sp_router_schedule_work() so that the
  NETEVENT_NEIGH_UPDATE handler can use it directly instead of inlining
  equivalent code.

- In patches #6 and #7, add helpers for two common operations involving
  a backing netdev of a RIF. This makes it unnecessary for the function
  mlxsw_sp_rif_dev() to be visible outside of the router module, so in
  patch #8, hide it.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
David S. Miller 2023-06-12 09:49:30 +01:00
commit 55d7c91406
6 changed files with 89 additions and 81 deletions

View File

@ -5139,14 +5139,6 @@ static int mlxsw_sp_netdevice_event(struct notifier_block *nb,
return notifier_from_errno(err); 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_inet6addr_valid_nb __read_mostly = {
.notifier_call = mlxsw_sp_inet6addr_valid_event,
};
static const struct pci_device_id mlxsw_sp1_pci_id_table[] = { static const struct pci_device_id mlxsw_sp1_pci_id_table[] = {
{PCI_VDEVICE(MELLANOX, PCI_DEVICE_ID_MELLANOX_SPECTRUM), 0}, {PCI_VDEVICE(MELLANOX, PCI_DEVICE_ID_MELLANOX_SPECTRUM), 0},
{0, }, {0, },
@ -5191,12 +5183,9 @@ static int __init mlxsw_sp_module_init(void)
{ {
int err; int err;
register_inetaddr_validator_notifier(&mlxsw_sp_inetaddr_valid_nb);
register_inet6addr_validator_notifier(&mlxsw_sp_inet6addr_valid_nb);
err = mlxsw_core_driver_register(&mlxsw_sp1_driver); err = mlxsw_core_driver_register(&mlxsw_sp1_driver);
if (err) if (err)
goto err_sp1_core_driver_register; return err;
err = mlxsw_core_driver_register(&mlxsw_sp2_driver); err = mlxsw_core_driver_register(&mlxsw_sp2_driver);
if (err) if (err)
@ -5242,9 +5231,6 @@ err_sp3_core_driver_register:
mlxsw_core_driver_unregister(&mlxsw_sp2_driver); mlxsw_core_driver_unregister(&mlxsw_sp2_driver);
err_sp2_core_driver_register: err_sp2_core_driver_register:
mlxsw_core_driver_unregister(&mlxsw_sp1_driver); mlxsw_core_driver_unregister(&mlxsw_sp1_driver);
err_sp1_core_driver_register:
unregister_inet6addr_validator_notifier(&mlxsw_sp_inet6addr_valid_nb);
unregister_inetaddr_validator_notifier(&mlxsw_sp_inetaddr_valid_nb);
return err; return err;
} }
@ -5258,8 +5244,6 @@ static void __exit mlxsw_sp_module_exit(void)
mlxsw_core_driver_unregister(&mlxsw_sp3_driver); mlxsw_core_driver_unregister(&mlxsw_sp3_driver);
mlxsw_core_driver_unregister(&mlxsw_sp2_driver); mlxsw_core_driver_unregister(&mlxsw_sp2_driver);
mlxsw_core_driver_unregister(&mlxsw_sp1_driver); mlxsw_core_driver_unregister(&mlxsw_sp1_driver);
unregister_inet6addr_validator_notifier(&mlxsw_sp_inet6addr_valid_nb);
unregister_inetaddr_validator_notifier(&mlxsw_sp_inetaddr_valid_nb);
} }
module_init(mlxsw_sp_module_init); module_init(mlxsw_sp_module_init);

View File

@ -755,10 +755,6 @@ int mlxsw_sp_router_init(struct mlxsw_sp *mlxsw_sp,
void mlxsw_sp_router_fini(struct mlxsw_sp *mlxsw_sp); void mlxsw_sp_router_fini(struct mlxsw_sp *mlxsw_sp);
void mlxsw_sp_rif_macvlan_del(struct mlxsw_sp *mlxsw_sp, void mlxsw_sp_rif_macvlan_del(struct mlxsw_sp *mlxsw_sp,
const struct net_device *macvlan_dev); const struct net_device *macvlan_dev);
int mlxsw_sp_inetaddr_valid_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 int
mlxsw_sp_port_vlan_router_join(struct mlxsw_sp_port_vlan *mlxsw_sp_port_vlan, mlxsw_sp_port_vlan_router_join(struct mlxsw_sp_port_vlan *mlxsw_sp_port_vlan,
struct net_device *l3_dev, struct net_device *l3_dev,

View File

@ -221,7 +221,7 @@ start_again:
for (; i < rif_count; i++) { for (; i < rif_count; i++) {
struct mlxsw_sp_rif *rif = mlxsw_sp_rif_by_index(mlxsw_sp, i); struct mlxsw_sp_rif *rif = mlxsw_sp_rif_by_index(mlxsw_sp, i);
if (!rif || !mlxsw_sp_rif_dev(rif)) if (!rif || !mlxsw_sp_rif_has_dev(rif))
continue; continue;
err = mlxsw_sp_erif_entry_get(mlxsw_sp, &entry, rif, err = mlxsw_sp_erif_entry_get(mlxsw_sp, &entry, rif,
counters_enabled); counters_enabled);

View File

@ -704,12 +704,12 @@ void mlxsw_sp_mr_vif_del(struct mlxsw_sp_mr_table *mr_table, vifi_t vif_index)
static struct mlxsw_sp_mr_vif * static struct mlxsw_sp_mr_vif *
mlxsw_sp_mr_dev_vif_lookup(struct mlxsw_sp_mr_table *mr_table, mlxsw_sp_mr_dev_vif_lookup(struct mlxsw_sp_mr_table *mr_table,
const struct net_device *dev) const struct mlxsw_sp_rif *rif)
{ {
vifi_t vif_index; vifi_t vif_index;
for (vif_index = 0; vif_index < MAXVIFS; vif_index++) for (vif_index = 0; vif_index < MAXVIFS; vif_index++)
if (mr_table->vifs[vif_index].dev == dev) if (mlxsw_sp_rif_dev_is(rif, mr_table->vifs[vif_index].dev))
return &mr_table->vifs[vif_index]; return &mr_table->vifs[vif_index];
return NULL; return NULL;
} }
@ -717,13 +717,12 @@ mlxsw_sp_mr_dev_vif_lookup(struct mlxsw_sp_mr_table *mr_table,
int mlxsw_sp_mr_rif_add(struct mlxsw_sp_mr_table *mr_table, int mlxsw_sp_mr_rif_add(struct mlxsw_sp_mr_table *mr_table,
const struct mlxsw_sp_rif *rif) const struct mlxsw_sp_rif *rif)
{ {
const struct net_device *rif_dev = mlxsw_sp_rif_dev(rif);
struct mlxsw_sp_mr_vif *mr_vif; struct mlxsw_sp_mr_vif *mr_vif;
if (!rif_dev) if (!mlxsw_sp_rif_has_dev(rif))
return 0; return 0;
mr_vif = mlxsw_sp_mr_dev_vif_lookup(mr_table, rif_dev); mr_vif = mlxsw_sp_mr_dev_vif_lookup(mr_table, rif);
if (!mr_vif) if (!mr_vif)
return 0; return 0;
return mlxsw_sp_mr_vif_resolve(mr_table, mr_vif->dev, mr_vif, return mlxsw_sp_mr_vif_resolve(mr_table, mr_vif->dev, mr_vif,
@ -733,13 +732,12 @@ int mlxsw_sp_mr_rif_add(struct mlxsw_sp_mr_table *mr_table,
void mlxsw_sp_mr_rif_del(struct mlxsw_sp_mr_table *mr_table, void mlxsw_sp_mr_rif_del(struct mlxsw_sp_mr_table *mr_table,
const struct mlxsw_sp_rif *rif) const struct mlxsw_sp_rif *rif)
{ {
const struct net_device *rif_dev = mlxsw_sp_rif_dev(rif);
struct mlxsw_sp_mr_vif *mr_vif; struct mlxsw_sp_mr_vif *mr_vif;
if (!rif_dev) if (!mlxsw_sp_rif_has_dev(rif))
return; return;
mr_vif = mlxsw_sp_mr_dev_vif_lookup(mr_table, rif_dev); mr_vif = mlxsw_sp_mr_dev_vif_lookup(mr_table, rif);
if (!mr_vif) if (!mr_vif)
return; return;
mlxsw_sp_mr_vif_unresolve(mr_table, mr_vif->dev, mr_vif); mlxsw_sp_mr_vif_unresolve(mr_table, mr_vif->dev, mr_vif);
@ -748,17 +746,16 @@ void mlxsw_sp_mr_rif_del(struct mlxsw_sp_mr_table *mr_table,
void mlxsw_sp_mr_rif_mtu_update(struct mlxsw_sp_mr_table *mr_table, void mlxsw_sp_mr_rif_mtu_update(struct mlxsw_sp_mr_table *mr_table,
const struct mlxsw_sp_rif *rif, int mtu) const struct mlxsw_sp_rif *rif, int mtu)
{ {
const struct net_device *rif_dev = mlxsw_sp_rif_dev(rif);
struct mlxsw_sp *mlxsw_sp = mr_table->mlxsw_sp; struct mlxsw_sp *mlxsw_sp = mr_table->mlxsw_sp;
struct mlxsw_sp_mr_route_vif_entry *rve; struct mlxsw_sp_mr_route_vif_entry *rve;
struct mlxsw_sp_mr *mr = mlxsw_sp->mr; struct mlxsw_sp_mr *mr = mlxsw_sp->mr;
struct mlxsw_sp_mr_vif *mr_vif; struct mlxsw_sp_mr_vif *mr_vif;
if (!rif_dev) if (!mlxsw_sp_rif_has_dev(rif))
return; return;
/* Search for a VIF that use that RIF */ /* Search for a VIF that use that RIF */
mr_vif = mlxsw_sp_mr_dev_vif_lookup(mr_table, rif_dev); mr_vif = mlxsw_sp_mr_dev_vif_lookup(mr_table, rif);
if (!mr_vif) if (!mr_vif)
return; return;

View File

@ -2748,13 +2748,12 @@ static void mlxsw_sp_router_update_priority_work(struct work_struct *work)
} }
static int mlxsw_sp_router_schedule_work(struct net *net, static int mlxsw_sp_router_schedule_work(struct net *net,
struct notifier_block *nb, struct mlxsw_sp_router *router,
struct neighbour *n,
void (*cb)(struct work_struct *)) void (*cb)(struct work_struct *))
{ {
struct mlxsw_sp_netevent_work *net_work; struct mlxsw_sp_netevent_work *net_work;
struct mlxsw_sp_router *router;
router = container_of(nb, struct mlxsw_sp_router, netevent_nb);
if (!net_eq(net, mlxsw_sp_net(router->mlxsw_sp))) if (!net_eq(net, mlxsw_sp_net(router->mlxsw_sp)))
return NOTIFY_DONE; return NOTIFY_DONE;
@ -2764,19 +2763,31 @@ static int mlxsw_sp_router_schedule_work(struct net *net,
INIT_WORK(&net_work->work, cb); INIT_WORK(&net_work->work, cb);
net_work->mlxsw_sp = router->mlxsw_sp; net_work->mlxsw_sp = router->mlxsw_sp;
net_work->n = n;
mlxsw_core_schedule_work(&net_work->work); mlxsw_core_schedule_work(&net_work->work);
return NOTIFY_DONE; return NOTIFY_DONE;
} }
static bool mlxsw_sp_dev_lower_is_port(struct net_device *dev)
{
struct mlxsw_sp_port *mlxsw_sp_port;
rcu_read_lock();
mlxsw_sp_port = mlxsw_sp_port_dev_lower_find_rcu(dev);
rcu_read_unlock();
return !!mlxsw_sp_port;
}
static int mlxsw_sp_router_netevent_event(struct notifier_block *nb, static int mlxsw_sp_router_netevent_event(struct notifier_block *nb,
unsigned long event, void *ptr) unsigned long event, void *ptr)
{ {
struct mlxsw_sp_netevent_work *net_work; struct mlxsw_sp_router *router;
struct mlxsw_sp_port *mlxsw_sp_port;
struct mlxsw_sp *mlxsw_sp;
unsigned long interval; unsigned long interval;
struct neigh_parms *p; struct neigh_parms *p;
struct neighbour *n; struct neighbour *n;
struct net *net;
router = container_of(nb, struct mlxsw_sp_router, netevent_nb);
switch (event) { switch (event) {
case NETEVENT_DELAY_PROBE_TIME_UPDATE: case NETEVENT_DELAY_PROBE_TIME_UPDATE:
@ -2790,51 +2801,37 @@ static int mlxsw_sp_router_netevent_event(struct notifier_block *nb,
/* We are in atomic context and can't take RTNL mutex, /* We are in atomic context and can't take RTNL mutex,
* so use RCU variant to walk the device chain. * so use RCU variant to walk the device chain.
*/ */
mlxsw_sp_port = mlxsw_sp_port_lower_dev_hold(p->dev); if (!mlxsw_sp_dev_lower_is_port(p->dev))
if (!mlxsw_sp_port)
return NOTIFY_DONE; return NOTIFY_DONE;
mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
interval = jiffies_to_msecs(NEIGH_VAR(p, DELAY_PROBE_TIME)); interval = jiffies_to_msecs(NEIGH_VAR(p, DELAY_PROBE_TIME));
mlxsw_sp->router->neighs_update.interval = interval; router->neighs_update.interval = interval;
mlxsw_sp_port_dev_put(mlxsw_sp_port);
break; break;
case NETEVENT_NEIGH_UPDATE: case NETEVENT_NEIGH_UPDATE:
n = ptr; n = ptr;
net = neigh_parms_net(n->parms);
if (n->tbl->family != AF_INET && n->tbl->family != AF_INET6) if (n->tbl->family != AF_INET && n->tbl->family != AF_INET6)
return NOTIFY_DONE; return NOTIFY_DONE;
mlxsw_sp_port = mlxsw_sp_port_lower_dev_hold(n->dev); if (!mlxsw_sp_dev_lower_is_port(n->dev))
if (!mlxsw_sp_port)
return NOTIFY_DONE; return NOTIFY_DONE;
net_work = kzalloc(sizeof(*net_work), GFP_ATOMIC);
if (!net_work) {
mlxsw_sp_port_dev_put(mlxsw_sp_port);
return NOTIFY_BAD;
}
INIT_WORK(&net_work->work, mlxsw_sp_router_neigh_event_work);
net_work->mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
net_work->n = n;
/* Take a reference to ensure the neighbour won't be /* Take a reference to ensure the neighbour won't be
* destructed until we drop the reference in delayed * destructed until we drop the reference in delayed
* work. * work.
*/ */
neigh_clone(n); neigh_clone(n);
mlxsw_core_schedule_work(&net_work->work); return mlxsw_sp_router_schedule_work(net, router, n,
mlxsw_sp_port_dev_put(mlxsw_sp_port); mlxsw_sp_router_neigh_event_work);
break;
case NETEVENT_IPV4_MPATH_HASH_UPDATE: case NETEVENT_IPV4_MPATH_HASH_UPDATE:
case NETEVENT_IPV6_MPATH_HASH_UPDATE: case NETEVENT_IPV6_MPATH_HASH_UPDATE:
return mlxsw_sp_router_schedule_work(ptr, nb, return mlxsw_sp_router_schedule_work(ptr, router, NULL,
mlxsw_sp_router_mp_hash_event_work); mlxsw_sp_router_mp_hash_event_work);
case NETEVENT_IPV4_FWD_UPDATE_PRIORITY_UPDATE: case NETEVENT_IPV4_FWD_UPDATE_PRIORITY_UPDATE:
return mlxsw_sp_router_schedule_work(ptr, nb, return mlxsw_sp_router_schedule_work(ptr, router, NULL,
mlxsw_sp_router_update_priority_work); mlxsw_sp_router_update_priority_work);
} }
@ -7708,7 +7705,7 @@ mlxsw_sp_rif_find_by_dev(const struct mlxsw_sp *mlxsw_sp,
for (i = 0; i < max_rifs; i++) for (i = 0; i < max_rifs; i++)
if (mlxsw_sp->router->rifs[i] && if (mlxsw_sp->router->rifs[i] &&
mlxsw_sp->router->rifs[i]->dev == dev) mlxsw_sp_rif_dev_is(mlxsw_sp->router->rifs[i], dev))
return mlxsw_sp->router->rifs[i]; return mlxsw_sp->router->rifs[i];
return NULL; return NULL;
@ -8078,11 +8075,22 @@ int mlxsw_sp_rif_dev_ifindex(const struct mlxsw_sp_rif *rif)
return rif->dev->ifindex; return rif->dev->ifindex;
} }
const struct net_device *mlxsw_sp_rif_dev(const struct mlxsw_sp_rif *rif) static const struct net_device *mlxsw_sp_rif_dev(const struct mlxsw_sp_rif *rif)
{ {
return rif->dev; return rif->dev;
} }
bool mlxsw_sp_rif_has_dev(const struct mlxsw_sp_rif *rif)
{
return !!mlxsw_sp_rif_dev(rif);
}
bool mlxsw_sp_rif_dev_is(const struct mlxsw_sp_rif *rif,
const struct net_device *dev)
{
return mlxsw_sp_rif_dev(rif) == dev;
}
static void mlxsw_sp_rif_push_l3_stats(struct mlxsw_sp_rif *rif) static void mlxsw_sp_rif_push_l3_stats(struct mlxsw_sp_rif *rif)
{ {
struct rtnl_hw_stats64 stats = {}; struct rtnl_hw_stats64 stats = {};
@ -8879,8 +8887,8 @@ out:
return notifier_from_errno(err); return notifier_from_errno(err);
} }
int mlxsw_sp_inetaddr_valid_event(struct notifier_block *unused, static int mlxsw_sp_inetaddr_valid_event(struct notifier_block *unused,
unsigned long event, void *ptr) unsigned long event, void *ptr)
{ {
struct in_validator_info *ivi = (struct in_validator_info *) ptr; struct in_validator_info *ivi = (struct in_validator_info *) ptr;
struct net_device *dev = ivi->ivi_dev->dev; struct net_device *dev = ivi->ivi_dev->dev;
@ -8962,8 +8970,8 @@ static int mlxsw_sp_inet6addr_event(struct notifier_block *nb,
return NOTIFY_DONE; return NOTIFY_DONE;
} }
int mlxsw_sp_inet6addr_valid_event(struct notifier_block *unused, static int mlxsw_sp_inet6addr_valid_event(struct notifier_block *unused,
unsigned long event, void *ptr) unsigned long event, void *ptr)
{ {
struct in6_validator_info *i6vi = (struct in6_validator_info *) ptr; struct in6_validator_info *i6vi = (struct in6_validator_info *) ptr;
struct net_device *dev = i6vi->i6vi_dev->dev; struct net_device *dev = i6vi->i6vi_dev->dev;
@ -10510,6 +10518,7 @@ int mlxsw_sp_router_init(struct mlxsw_sp *mlxsw_sp,
struct netlink_ext_ack *extack) struct netlink_ext_ack *extack)
{ {
struct mlxsw_sp_router *router; struct mlxsw_sp_router *router;
struct notifier_block *nb;
int err; int err;
router = kzalloc(sizeof(*mlxsw_sp->router), GFP_KERNEL); router = kzalloc(sizeof(*mlxsw_sp->router), GFP_KERNEL);
@ -10588,6 +10597,17 @@ int mlxsw_sp_router_init(struct mlxsw_sp *mlxsw_sp,
if (err) if (err)
goto err_register_inet6addr_notifier; goto err_register_inet6addr_notifier;
router->inetaddr_valid_nb.notifier_call = mlxsw_sp_inetaddr_valid_event;
err = register_inetaddr_validator_notifier(&router->inetaddr_valid_nb);
if (err)
goto err_register_inetaddr_valid_notifier;
nb = &router->inet6addr_valid_nb;
nb->notifier_call = mlxsw_sp_inet6addr_valid_event;
err = register_inet6addr_validator_notifier(nb);
if (err)
goto err_register_inet6addr_valid_notifier;
mlxsw_sp->router->netevent_nb.notifier_call = mlxsw_sp->router->netevent_nb.notifier_call =
mlxsw_sp_router_netevent_event; mlxsw_sp_router_netevent_event;
err = register_netevent_notifier(&mlxsw_sp->router->netevent_nb); err = register_netevent_notifier(&mlxsw_sp->router->netevent_nb);
@ -10627,6 +10647,10 @@ err_register_fib_notifier:
err_register_nexthop_notifier: err_register_nexthop_notifier:
unregister_netevent_notifier(&mlxsw_sp->router->netevent_nb); unregister_netevent_notifier(&mlxsw_sp->router->netevent_nb);
err_register_netevent_notifier: err_register_netevent_notifier:
unregister_inet6addr_validator_notifier(&router->inet6addr_valid_nb);
err_register_inet6addr_valid_notifier:
unregister_inetaddr_validator_notifier(&router->inetaddr_valid_nb);
err_register_inetaddr_valid_notifier:
unregister_inet6addr_notifier(&router->inet6addr_nb); unregister_inet6addr_notifier(&router->inet6addr_nb);
err_register_inet6addr_notifier: err_register_inet6addr_notifier:
unregister_inetaddr_notifier(&router->inetaddr_nb); unregister_inetaddr_notifier(&router->inetaddr_nb);
@ -10664,15 +10688,18 @@ err_router_ops_init:
void mlxsw_sp_router_fini(struct mlxsw_sp *mlxsw_sp) void mlxsw_sp_router_fini(struct mlxsw_sp *mlxsw_sp)
{ {
struct mlxsw_sp_router *router = mlxsw_sp->router;
unregister_netdevice_notifier_net(mlxsw_sp_net(mlxsw_sp), unregister_netdevice_notifier_net(mlxsw_sp_net(mlxsw_sp),
&mlxsw_sp->router->netdevice_nb); &router->netdevice_nb);
unregister_fib_notifier(mlxsw_sp_net(mlxsw_sp), unregister_fib_notifier(mlxsw_sp_net(mlxsw_sp), &router->fib_nb);
&mlxsw_sp->router->fib_nb);
unregister_nexthop_notifier(mlxsw_sp_net(mlxsw_sp), unregister_nexthop_notifier(mlxsw_sp_net(mlxsw_sp),
&mlxsw_sp->router->nexthop_nb); &router->nexthop_nb);
unregister_netevent_notifier(&mlxsw_sp->router->netevent_nb); unregister_netevent_notifier(&router->netevent_nb);
unregister_inet6addr_notifier(&mlxsw_sp->router->inet6addr_nb); unregister_inet6addr_validator_notifier(&router->inet6addr_valid_nb);
unregister_inetaddr_notifier(&mlxsw_sp->router->inetaddr_nb); unregister_inetaddr_validator_notifier(&router->inetaddr_valid_nb);
unregister_inet6addr_notifier(&router->inet6addr_nb);
unregister_inetaddr_notifier(&router->inetaddr_nb);
mlxsw_core_flush_owq(); mlxsw_core_flush_owq();
mlxsw_sp_mp_hash_fini(mlxsw_sp); mlxsw_sp_mp_hash_fini(mlxsw_sp);
mlxsw_sp_neigh_fini(mlxsw_sp); mlxsw_sp_neigh_fini(mlxsw_sp);
@ -10680,12 +10707,12 @@ void mlxsw_sp_router_fini(struct mlxsw_sp *mlxsw_sp)
mlxsw_sp_vrs_fini(mlxsw_sp); mlxsw_sp_vrs_fini(mlxsw_sp);
mlxsw_sp_mr_fini(mlxsw_sp); mlxsw_sp_mr_fini(mlxsw_sp);
mlxsw_sp_lpm_fini(mlxsw_sp); mlxsw_sp_lpm_fini(mlxsw_sp);
rhashtable_destroy(&mlxsw_sp->router->nexthop_group_ht); rhashtable_destroy(&router->nexthop_group_ht);
rhashtable_destroy(&mlxsw_sp->router->nexthop_ht); rhashtable_destroy(&router->nexthop_ht);
mlxsw_sp_ipips_fini(mlxsw_sp); mlxsw_sp_ipips_fini(mlxsw_sp);
mlxsw_sp_rifs_fini(mlxsw_sp); mlxsw_sp_rifs_fini(mlxsw_sp);
__mlxsw_sp_router_fini(mlxsw_sp); __mlxsw_sp_router_fini(mlxsw_sp);
cancel_delayed_work_sync(&mlxsw_sp->router->nh_grp_activity_dw); cancel_delayed_work_sync(&router->nh_grp_activity_dw);
mutex_destroy(&mlxsw_sp->router->lock); mutex_destroy(&router->lock);
kfree(mlxsw_sp->router); kfree(router);
} }

View File

@ -52,6 +52,8 @@ struct mlxsw_sp_router {
struct notifier_block inetaddr_nb; struct notifier_block inetaddr_nb;
struct notifier_block inet6addr_nb; struct notifier_block inet6addr_nb;
struct notifier_block netdevice_nb; struct notifier_block netdevice_nb;
struct notifier_block inetaddr_valid_nb;
struct notifier_block inet6addr_valid_nb;
const struct mlxsw_sp_rif_ops **rif_ops_arr; const struct mlxsw_sp_rif_ops **rif_ops_arr;
const struct mlxsw_sp_ipip_ops **ipip_ops_arr; const struct mlxsw_sp_ipip_ops **ipip_ops_arr;
struct mlxsw_sp_router_nve_decap nve_decap_config; struct mlxsw_sp_router_nve_decap nve_decap_config;
@ -91,7 +93,9 @@ u16 mlxsw_sp_ipip_lb_ul_vr_id(const struct mlxsw_sp_rif_ipip_lb *rif);
u16 mlxsw_sp_ipip_lb_ul_rif_id(const struct mlxsw_sp_rif_ipip_lb *lb_rif); u16 mlxsw_sp_ipip_lb_ul_rif_id(const struct mlxsw_sp_rif_ipip_lb *lb_rif);
u32 mlxsw_sp_ipip_dev_ul_tb_id(const struct net_device *ol_dev); u32 mlxsw_sp_ipip_dev_ul_tb_id(const struct net_device *ol_dev);
int mlxsw_sp_rif_dev_ifindex(const struct mlxsw_sp_rif *rif); int mlxsw_sp_rif_dev_ifindex(const struct mlxsw_sp_rif *rif);
const struct net_device *mlxsw_sp_rif_dev(const struct mlxsw_sp_rif *rif); bool mlxsw_sp_rif_has_dev(const struct mlxsw_sp_rif *rif);
bool mlxsw_sp_rif_dev_is(const struct mlxsw_sp_rif *rif,
const struct net_device *dev);
int mlxsw_sp_rif_counter_value_get(struct mlxsw_sp *mlxsw_sp, int mlxsw_sp_rif_counter_value_get(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_rif *rif, struct mlxsw_sp_rif *rif,
enum mlxsw_sp_rif_counter_dir dir, enum mlxsw_sp_rif_counter_dir dir,