Commit d3a51d6c authored by David S. Miller's avatar David S. Miller

Merge branch 'mlxsw-router-fixes'

Jiri Pirko says:

====================
mlxsw: Router fixes

Ido says:

First two patches ensure we remove from the device's table neighbours
that are considered to be dead by the neighbour core.

The last patch removes nexthop groups from the device when they are no
longer valid.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents a98f9175 58312125
...@@ -942,7 +942,7 @@ static void mlxsw_sp_router_neigh_update_hw(struct work_struct *work) ...@@ -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) ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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);
} }
......
...@@ -100,6 +100,7 @@ static void neigh_cleanup_and_release(struct neighbour *neigh) ...@@ -100,6 +100,7 @@ static void neigh_cleanup_and_release(struct neighbour *neigh)
neigh->parms->neigh_cleanup(neigh); neigh->parms->neigh_cleanup(neigh);
__neigh_notify(neigh, RTM_DELNEIGH, 0); __neigh_notify(neigh, RTM_DELNEIGH, 0);
call_netevent_notifiers(NETEVENT_NEIGH_UPDATE, neigh);
neigh_release(neigh); neigh_release(neigh);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment