aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIdo Schimmel <idosch@mellanox.com>2016-12-23 03:32:49 -0500
committerDavid S. Miller <davem@davemloft.net>2016-12-23 12:31:19 -0500
commit93a87e5e794fb71a51f97fbde6c0010680b62d70 (patch)
tree51a161755aad0f93b29bafccb55f682b79efc1be
parent53f800e3baf980827c197a9332f63effe80d4809 (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.c10
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}