Merge branch 'mlxsw-router-fixes'
authorDavid S. Miller <davem@davemloft.net>
Fri, 23 Dec 2016 17:31:20 +0000 (12:31 -0500)
committerDavid S. Miller <davem@davemloft.net>
Fri, 23 Dec 2016 17:31:20 +0000 (12:31 -0500)
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: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
net/core/neighbour.c

index 53126bf68ea937e7b2c6951787c25450ec0ebdb5..01d0efa9c5c7419b6e2fa99ed6b99562811bcbd5 100644 (file)
@@ -942,7 +942,7 @@ static void mlxsw_sp_router_neigh_update_hw(struct work_struct *work)
        char rauht_pl[MLXSW_REG_RAUHT_LEN];
        struct net_device *dev;
        bool entry_connected;
-       u8 nud_state;
+       u8 nud_state, dead;
        bool updating;
        bool removing;
        bool adding;
@@ -953,10 +953,11 @@ static void mlxsw_sp_router_neigh_update_hw(struct work_struct *work)
        dip = ntohl(*((__be32 *) n->primary_key));
        memcpy(neigh_entry->ha, n->ha, sizeof(neigh_entry->ha));
        nud_state = n->nud_state;
+       dead = n->dead;
        dev = n->dev;
        read_unlock_bh(&n->lock);
 
-       entry_connected = nud_state & NUD_VALID;
+       entry_connected = nud_state & NUD_VALID && !dead;
        adding = (!neigh_entry->offloaded) && entry_connected;
        updating = 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 net_device *dev = fib_nh->nh_dev;
        struct neighbour *n;
-       u8 nud_state;
+       u8 nud_state, dead;
 
        /* Take a reference of neigh here ensuring that neigh would
         * 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);
        read_lock_bh(&n->lock);
        nud_state = n->nud_state;
+       dead = n->dead;
        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;
 }
@@ -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;
 
+       __mlxsw_sp_nexthop_neigh_update(nh, true);
        list_del(&nh->neigh_list_node);
 
        /* 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];
                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);
 }
 
index 782dd866366554e53dda3e6c69c807ec90bd0e08..7bb12e07ffef4273e156893cc150ea5c9d79e8bd 100644 (file)
@@ -100,6 +100,7 @@ static void neigh_cleanup_and_release(struct neighbour *neigh)
                neigh->parms->neigh_cleanup(neigh);
 
        __neigh_notify(neigh, RTM_DELNEIGH, 0);
+       call_netevent_notifiers(NETEVENT_NEIGH_UPDATE, neigh);
        neigh_release(neigh);
 }