mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-08-05 16:54:27 +00:00
mlxsw: spectrum_router: Periodically dump active IPv6 neighbours
In addition to IPv4, periodically dump IPv6 neighbours and update the kernel about them. Signed-off-by: Arkadi Sharshevsky <arkadis@mellanox.com> 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>
This commit is contained in:
parent
72e8ebe1b3
commit
60f040ca11
1 changed files with 69 additions and 10 deletions
|
@ -968,6 +968,36 @@ static void mlxsw_sp_router_neigh_ent_ipv4_process(struct mlxsw_sp *mlxsw_sp,
|
||||||
neigh_release(n);
|
neigh_release(n);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void mlxsw_sp_router_neigh_ent_ipv6_process(struct mlxsw_sp *mlxsw_sp,
|
||||||
|
char *rauhtd_pl,
|
||||||
|
int rec_index)
|
||||||
|
{
|
||||||
|
struct net_device *dev;
|
||||||
|
struct neighbour *n;
|
||||||
|
struct in6_addr dip;
|
||||||
|
u16 rif;
|
||||||
|
|
||||||
|
mlxsw_reg_rauhtd_ent_ipv6_unpack(rauhtd_pl, rec_index, &rif,
|
||||||
|
(char *) &dip);
|
||||||
|
|
||||||
|
if (!mlxsw_sp->router->rifs[rif]) {
|
||||||
|
dev_err_ratelimited(mlxsw_sp->bus_info->dev, "Incorrect RIF in neighbour entry\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
dev = mlxsw_sp->router->rifs[rif]->dev;
|
||||||
|
n = neigh_lookup(&nd_tbl, &dip, dev);
|
||||||
|
if (!n) {
|
||||||
|
netdev_err(dev, "Failed to find matching neighbour for IP=%pI6c\n",
|
||||||
|
&dip);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
netdev_dbg(dev, "Updating neighbour with IP=%pI6c\n", &dip);
|
||||||
|
neigh_event_send(n, NULL);
|
||||||
|
neigh_release(n);
|
||||||
|
}
|
||||||
|
|
||||||
static void mlxsw_sp_router_neigh_rec_ipv4_process(struct mlxsw_sp *mlxsw_sp,
|
static void mlxsw_sp_router_neigh_rec_ipv4_process(struct mlxsw_sp *mlxsw_sp,
|
||||||
char *rauhtd_pl,
|
char *rauhtd_pl,
|
||||||
int rec_index)
|
int rec_index)
|
||||||
|
@ -991,6 +1021,15 @@ static void mlxsw_sp_router_neigh_rec_ipv4_process(struct mlxsw_sp *mlxsw_sp,
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void mlxsw_sp_router_neigh_rec_ipv6_process(struct mlxsw_sp *mlxsw_sp,
|
||||||
|
char *rauhtd_pl,
|
||||||
|
int rec_index)
|
||||||
|
{
|
||||||
|
/* One record contains one entry. */
|
||||||
|
mlxsw_sp_router_neigh_ent_ipv6_process(mlxsw_sp, rauhtd_pl,
|
||||||
|
rec_index);
|
||||||
|
}
|
||||||
|
|
||||||
static void mlxsw_sp_router_neigh_rec_process(struct mlxsw_sp *mlxsw_sp,
|
static void mlxsw_sp_router_neigh_rec_process(struct mlxsw_sp *mlxsw_sp,
|
||||||
char *rauhtd_pl, int rec_index)
|
char *rauhtd_pl, int rec_index)
|
||||||
{
|
{
|
||||||
|
@ -1000,7 +1039,8 @@ static void mlxsw_sp_router_neigh_rec_process(struct mlxsw_sp *mlxsw_sp,
|
||||||
rec_index);
|
rec_index);
|
||||||
break;
|
break;
|
||||||
case MLXSW_REG_RAUHTD_TYPE_IPV6:
|
case MLXSW_REG_RAUHTD_TYPE_IPV6:
|
||||||
WARN_ON_ONCE(1);
|
mlxsw_sp_router_neigh_rec_ipv6_process(mlxsw_sp, rauhtd_pl,
|
||||||
|
rec_index);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1025,22 +1065,20 @@ static bool mlxsw_sp_router_rauhtd_is_full(char *rauhtd_pl)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int mlxsw_sp_router_neighs_update_rauhtd(struct mlxsw_sp *mlxsw_sp)
|
static int
|
||||||
|
__mlxsw_sp_router_neighs_update_rauhtd(struct mlxsw_sp *mlxsw_sp,
|
||||||
|
char *rauhtd_pl,
|
||||||
|
enum mlxsw_reg_rauhtd_type type)
|
||||||
{
|
{
|
||||||
char *rauhtd_pl;
|
int i, num_rec;
|
||||||
u8 num_rec;
|
int err;
|
||||||
int i, err;
|
|
||||||
|
|
||||||
rauhtd_pl = kmalloc(MLXSW_REG_RAUHTD_LEN, GFP_KERNEL);
|
|
||||||
if (!rauhtd_pl)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
/* Make sure the neighbour's netdev isn't removed in the
|
/* Make sure the neighbour's netdev isn't removed in the
|
||||||
* process.
|
* process.
|
||||||
*/
|
*/
|
||||||
rtnl_lock();
|
rtnl_lock();
|
||||||
do {
|
do {
|
||||||
mlxsw_reg_rauhtd_pack(rauhtd_pl, MLXSW_REG_RAUHTD_TYPE_IPV4);
|
mlxsw_reg_rauhtd_pack(rauhtd_pl, type);
|
||||||
err = mlxsw_reg_query(mlxsw_sp->core, MLXSW_REG(rauhtd),
|
err = mlxsw_reg_query(mlxsw_sp->core, MLXSW_REG(rauhtd),
|
||||||
rauhtd_pl);
|
rauhtd_pl);
|
||||||
if (err) {
|
if (err) {
|
||||||
|
@ -1054,6 +1092,27 @@ static int mlxsw_sp_router_neighs_update_rauhtd(struct mlxsw_sp *mlxsw_sp)
|
||||||
} while (mlxsw_sp_router_rauhtd_is_full(rauhtd_pl));
|
} while (mlxsw_sp_router_rauhtd_is_full(rauhtd_pl));
|
||||||
rtnl_unlock();
|
rtnl_unlock();
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mlxsw_sp_router_neighs_update_rauhtd(struct mlxsw_sp *mlxsw_sp)
|
||||||
|
{
|
||||||
|
enum mlxsw_reg_rauhtd_type type;
|
||||||
|
char *rauhtd_pl;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
rauhtd_pl = kmalloc(MLXSW_REG_RAUHTD_LEN, GFP_KERNEL);
|
||||||
|
if (!rauhtd_pl)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
type = MLXSW_REG_RAUHTD_TYPE_IPV4;
|
||||||
|
err = __mlxsw_sp_router_neighs_update_rauhtd(mlxsw_sp, rauhtd_pl, type);
|
||||||
|
if (err)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
type = MLXSW_REG_RAUHTD_TYPE_IPV6;
|
||||||
|
err = __mlxsw_sp_router_neighs_update_rauhtd(mlxsw_sp, rauhtd_pl, type);
|
||||||
|
out:
|
||||||
kfree(rauhtd_pl);
|
kfree(rauhtd_pl);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue