diff options
| author | Ido Schimmel <idosch@mellanox.com> | 2016-12-23 03:32:49 -0500 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2016-12-23 12:31:19 -0500 |
| commit | 93a87e5e794fb71a51f97fbde6c0010680b62d70 (patch) | |
| tree | 51a161755aad0f93b29bafccb55f682b79efc1be | |
| parent | 53f800e3baf980827c197a9332f63effe80d4809 (diff) | |
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: a6bf9e933daf ("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>
| -rw-r--r-- | drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c | 10 |
1 files changed, 6 insertions, 4 deletions
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c index 53126bf68ea9..a0f9742f62df 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c | |||
| @@ -942,7 +942,7 @@ static void mlxsw_sp_router_neigh_update_hw(struct work_struct *work) | |||
| 942 | char rauht_pl[MLXSW_REG_RAUHT_LEN]; | 942 | char rauht_pl[MLXSW_REG_RAUHT_LEN]; |
| 943 | struct net_device *dev; | 943 | struct net_device *dev; |
| 944 | bool entry_connected; | 944 | bool entry_connected; |
| 945 | u8 nud_state; | 945 | u8 nud_state, dead; |
| 946 | bool updating; | 946 | bool updating; |
| 947 | bool removing; | 947 | bool removing; |
| 948 | bool adding; | 948 | bool adding; |
| @@ -953,10 +953,11 @@ static void mlxsw_sp_router_neigh_update_hw(struct work_struct *work) | |||
| 953 | dip = ntohl(*((__be32 *) n->primary_key)); | 953 | dip = ntohl(*((__be32 *) n->primary_key)); |
| 954 | memcpy(neigh_entry->ha, n->ha, sizeof(neigh_entry->ha)); | 954 | memcpy(neigh_entry->ha, n->ha, sizeof(neigh_entry->ha)); |
| 955 | nud_state = n->nud_state; | 955 | nud_state = n->nud_state; |
| 956 | dead = n->dead; | ||
| 956 | dev = n->dev; | 957 | dev = n->dev; |
| 957 | read_unlock_bh(&n->lock); | 958 | read_unlock_bh(&n->lock); |
| 958 | 959 | ||
| 959 | entry_connected = nud_state & NUD_VALID; | 960 | entry_connected = nud_state & NUD_VALID && !dead; |
| 960 | adding = (!neigh_entry->offloaded) && entry_connected; | 961 | adding = (!neigh_entry->offloaded) && entry_connected; |
| 961 | updating = neigh_entry->offloaded && entry_connected; | 962 | updating = neigh_entry->offloaded && entry_connected; |
| 962 | removing = neigh_entry->offloaded && !entry_connected; | 963 | removing = neigh_entry->offloaded && !entry_connected; |
| @@ -1351,7 +1352,7 @@ static int mlxsw_sp_nexthop_init(struct mlxsw_sp *mlxsw_sp, | |||
| 1351 | struct mlxsw_sp_neigh_entry *neigh_entry; | 1352 | struct mlxsw_sp_neigh_entry *neigh_entry; |
| 1352 | struct net_device *dev = fib_nh->nh_dev; | 1353 | struct net_device *dev = fib_nh->nh_dev; |
| 1353 | struct neighbour *n; | 1354 | struct neighbour *n; |
| 1354 | u8 nud_state; | 1355 | u8 nud_state, dead; |
| 1355 | 1356 | ||
| 1356 | /* Take a reference of neigh here ensuring that neigh would | 1357 | /* Take a reference of neigh here ensuring that neigh would |
| 1357 | * not be detructed before the nexthop entry is finished. | 1358 | * 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 | list_add_tail(&nh->neigh_list_node, &neigh_entry->nexthop_list); | 1384 | list_add_tail(&nh->neigh_list_node, &neigh_entry->nexthop_list); |
| 1384 | read_lock_bh(&n->lock); | 1385 | read_lock_bh(&n->lock); |
| 1385 | nud_state = n->nud_state; | 1386 | nud_state = n->nud_state; |
| 1387 | dead = n->dead; | ||
| 1386 | read_unlock_bh(&n->lock); | 1388 | read_unlock_bh(&n->lock); |
| 1387 | __mlxsw_sp_nexthop_neigh_update(nh, !(nud_state & NUD_VALID)); | 1389 | __mlxsw_sp_nexthop_neigh_update(nh, !(nud_state & NUD_VALID && !dead)); |
| 1388 | 1390 | ||
| 1389 | return 0; | 1391 | return 0; |
| 1390 | } | 1392 | } |
