Commit 93a87e5e authored by Ido Schimmel's avatar Ido Schimmel Committed by David S. Miller

mlxsw: spectrum_router: Don't reflect dead neighs

When a neighbour is considered to be dead, we should remove it from the
device's table regardless of its NUD state.

Without this patch, after setting a port to be administratively down we
get the following errors when we periodically try to update the kernel
about neighbours activity:

[  461.947268] mlxsw_spectrum 0000:03:00.0 sw1p3: Failed to find
matching neighbour for IP=192.168.100.2

Fixes: a6bf9e93 ("mlxsw: spectrum_router: Offload neighbours based on NUD state change")
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 53f800e3
...@@ -942,7 +942,7 @@ static void mlxsw_sp_router_neigh_update_hw(struct work_struct *work) ...@@ -942,7 +942,7 @@ static void mlxsw_sp_router_neigh_update_hw(struct work_struct *work)
char rauht_pl[MLXSW_REG_RAUHT_LEN]; char rauht_pl[MLXSW_REG_RAUHT_LEN];
struct net_device *dev; struct net_device *dev;
bool entry_connected; bool entry_connected;
u8 nud_state; u8 nud_state, dead;
bool updating; bool updating;
bool removing; bool removing;
bool adding; bool adding;
...@@ -953,10 +953,11 @@ static void mlxsw_sp_router_neigh_update_hw(struct work_struct *work) ...@@ -953,10 +953,11 @@ static void mlxsw_sp_router_neigh_update_hw(struct work_struct *work)
dip = ntohl(*((__be32 *) n->primary_key)); dip = ntohl(*((__be32 *) n->primary_key));
memcpy(neigh_entry->ha, n->ha, sizeof(neigh_entry->ha)); memcpy(neigh_entry->ha, n->ha, sizeof(neigh_entry->ha));
nud_state = n->nud_state; nud_state = n->nud_state;
dead = n->dead;
dev = n->dev; dev = n->dev;
read_unlock_bh(&n->lock); read_unlock_bh(&n->lock);
entry_connected = nud_state & NUD_VALID; entry_connected = nud_state & NUD_VALID && !dead;
adding = (!neigh_entry->offloaded) && entry_connected; adding = (!neigh_entry->offloaded) && entry_connected;
updating = neigh_entry->offloaded && entry_connected; updating = neigh_entry->offloaded && entry_connected;
removing = neigh_entry->offloaded && !entry_connected; removing = neigh_entry->offloaded && !entry_connected;
...@@ -1351,7 +1352,7 @@ static int mlxsw_sp_nexthop_init(struct mlxsw_sp *mlxsw_sp, ...@@ -1351,7 +1352,7 @@ static int mlxsw_sp_nexthop_init(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_neigh_entry *neigh_entry; struct mlxsw_sp_neigh_entry *neigh_entry;
struct net_device *dev = fib_nh->nh_dev; struct net_device *dev = fib_nh->nh_dev;
struct neighbour *n; struct neighbour *n;
u8 nud_state; u8 nud_state, dead;
/* Take a reference of neigh here ensuring that neigh would /* Take a reference of neigh here ensuring that neigh would
* not be detructed before the nexthop entry is finished. * not be detructed before the nexthop entry is finished.
...@@ -1383,8 +1384,9 @@ static int mlxsw_sp_nexthop_init(struct mlxsw_sp *mlxsw_sp, ...@@ -1383,8 +1384,9 @@ static int mlxsw_sp_nexthop_init(struct mlxsw_sp *mlxsw_sp,
list_add_tail(&nh->neigh_list_node, &neigh_entry->nexthop_list); list_add_tail(&nh->neigh_list_node, &neigh_entry->nexthop_list);
read_lock_bh(&n->lock); read_lock_bh(&n->lock);
nud_state = n->nud_state; nud_state = n->nud_state;
dead = n->dead;
read_unlock_bh(&n->lock); read_unlock_bh(&n->lock);
__mlxsw_sp_nexthop_neigh_update(nh, !(nud_state & NUD_VALID)); __mlxsw_sp_nexthop_neigh_update(nh, !(nud_state & NUD_VALID && !dead));
return 0; return 0;
} }
......
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