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: a6bf9e933d
("mlxsw: spectrum_router: Offload neighbours based on NUD state change")
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:
Родитель
53f800e3ba
Коммит
93a87e5e79
|
@ -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)
|
||||||
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,
|
||||||
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,
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
Загрузка…
Ссылка в новой задаче