Commit 42cdb338 authored by Arkadi Sharshevsky's avatar Arkadi Sharshevsky Committed by David S. Miller

mlxsw: spectrum_router: Correctly dump neighbour activity

The device's neighbour table is periodically dumped in order to update
the kernel about active neighbours. A single dump session may span
multiple queries, until the response carries less records than requested
or when a record (can contain up to four neighbour entries) is not full.
Current code stops the session when the number of returned records is
zero, which can result in infinite loop in case of high packet rate.

Fix this by stopping the session according to the above logic.

Fixes: c723c735 ("mlxsw: spectrum_router: Periodically update the kernel's neigh table")
Signed-off-by: default avatarArkadi Sharshevsky <arkadis@mellanox.com>
Signed-off-by: default avatarIdo Schimmel <idosch@mellanox.com>
Signed-off-by: default avatarJiri Pirko <jiri@mellanox.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 2d644d4c
...@@ -800,6 +800,26 @@ static void mlxsw_sp_router_neigh_rec_process(struct mlxsw_sp *mlxsw_sp, ...@@ -800,6 +800,26 @@ static void mlxsw_sp_router_neigh_rec_process(struct mlxsw_sp *mlxsw_sp,
} }
} }
static bool mlxsw_sp_router_rauhtd_is_full(char *rauhtd_pl)
{
u8 num_rec, last_rec_index, num_entries;
num_rec = mlxsw_reg_rauhtd_num_rec_get(rauhtd_pl);
last_rec_index = num_rec - 1;
if (num_rec < MLXSW_REG_RAUHTD_REC_MAX_NUM)
return false;
if (mlxsw_reg_rauhtd_rec_type_get(rauhtd_pl, last_rec_index) ==
MLXSW_REG_RAUHTD_TYPE_IPV6)
return true;
num_entries = mlxsw_reg_rauhtd_ipv4_rec_num_entries_get(rauhtd_pl,
last_rec_index);
if (++num_entries == MLXSW_REG_RAUHTD_IPV4_ENT_PER_REC)
return true;
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; char *rauhtd_pl;
...@@ -826,7 +846,7 @@ static int mlxsw_sp_router_neighs_update_rauhtd(struct mlxsw_sp *mlxsw_sp) ...@@ -826,7 +846,7 @@ static int mlxsw_sp_router_neighs_update_rauhtd(struct mlxsw_sp *mlxsw_sp)
for (i = 0; i < num_rec; i++) for (i = 0; i < num_rec; i++)
mlxsw_sp_router_neigh_rec_process(mlxsw_sp, rauhtd_pl, mlxsw_sp_router_neigh_rec_process(mlxsw_sp, rauhtd_pl,
i); i);
} while (num_rec); } while (mlxsw_sp_router_rauhtd_is_full(rauhtd_pl));
rtnl_unlock(); rtnl_unlock();
kfree(rauhtd_pl); kfree(rauhtd_pl);
......
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