diff options
-rw-r--r-- | drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c | 13 | ||||
-rw-r--r-- | net/core/neighbour.c | 1 |
2 files changed, 10 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..01d0efa9c5c7 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 | } |
@@ -1394,6 +1396,7 @@ static void mlxsw_sp_nexthop_fini(struct mlxsw_sp *mlxsw_sp, | |||
1394 | { | 1396 | { |
1395 | struct mlxsw_sp_neigh_entry *neigh_entry = nh->neigh_entry; | 1397 | struct mlxsw_sp_neigh_entry *neigh_entry = nh->neigh_entry; |
1396 | 1398 | ||
1399 | __mlxsw_sp_nexthop_neigh_update(nh, true); | ||
1397 | list_del(&nh->neigh_list_node); | 1400 | list_del(&nh->neigh_list_node); |
1398 | 1401 | ||
1399 | /* If that is the last nexthop connected to that neigh, remove from | 1402 | /* If that is the last nexthop connected to that neigh, remove from |
@@ -1452,6 +1455,8 @@ mlxsw_sp_nexthop_group_destroy(struct mlxsw_sp *mlxsw_sp, | |||
1452 | nh = &nh_grp->nexthops[i]; | 1455 | nh = &nh_grp->nexthops[i]; |
1453 | mlxsw_sp_nexthop_fini(mlxsw_sp, nh); | 1456 | mlxsw_sp_nexthop_fini(mlxsw_sp, nh); |
1454 | } | 1457 | } |
1458 | mlxsw_sp_nexthop_group_refresh(mlxsw_sp, nh_grp); | ||
1459 | WARN_ON_ONCE(nh_grp->adj_index_valid); | ||
1455 | kfree(nh_grp); | 1460 | kfree(nh_grp); |
1456 | } | 1461 | } |
1457 | 1462 | ||
diff --git a/net/core/neighbour.c b/net/core/neighbour.c index 782dd8663665..7bb12e07ffef 100644 --- a/net/core/neighbour.c +++ b/net/core/neighbour.c | |||
@@ -100,6 +100,7 @@ static void neigh_cleanup_and_release(struct neighbour *neigh) | |||
100 | neigh->parms->neigh_cleanup(neigh); | 100 | neigh->parms->neigh_cleanup(neigh); |
101 | 101 | ||
102 | __neigh_notify(neigh, RTM_DELNEIGH, 0); | 102 | __neigh_notify(neigh, RTM_DELNEIGH, 0); |
103 | call_netevent_notifiers(NETEVENT_NEIGH_UPDATE, neigh); | ||
103 | neigh_release(neigh); | 104 | neigh_release(neigh); |
104 | } | 105 | } |
105 | 106 | ||