|
@@ -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;
|
|
}
|
|
}
|
|
@@ -1394,6 +1396,7 @@ static void mlxsw_sp_nexthop_fini(struct mlxsw_sp *mlxsw_sp,
|
|
{
|
|
{
|
|
struct mlxsw_sp_neigh_entry *neigh_entry = nh->neigh_entry;
|
|
struct mlxsw_sp_neigh_entry *neigh_entry = nh->neigh_entry;
|
|
|
|
|
|
|
|
+ __mlxsw_sp_nexthop_neigh_update(nh, true);
|
|
list_del(&nh->neigh_list_node);
|
|
list_del(&nh->neigh_list_node);
|
|
|
|
|
|
/* If that is the last nexthop connected to that neigh, remove from
|
|
/* 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,
|
|
nh = &nh_grp->nexthops[i];
|
|
nh = &nh_grp->nexthops[i];
|
|
mlxsw_sp_nexthop_fini(mlxsw_sp, nh);
|
|
mlxsw_sp_nexthop_fini(mlxsw_sp, nh);
|
|
}
|
|
}
|
|
|
|
+ mlxsw_sp_nexthop_group_refresh(mlxsw_sp, nh_grp);
|
|
|
|
+ WARN_ON_ONCE(nh_grp->adj_index_valid);
|
|
kfree(nh_grp);
|
|
kfree(nh_grp);
|
|
}
|
|
}
|
|
|
|
|