aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2016-12-23 12:31:20 -0500
committerDavid S. Miller <davem@davemloft.net>2016-12-23 12:31:20 -0500
commitd3a51d6cbc8a31bf924be1fe116e461138b1cddc (patch)
treef82056ea3aae09a9a74e3960b5ced4dcfd901527
parenta98f91758995cb59611e61318dddd8a6956b52c3 (diff)
parent58312125da5806308bd69e075fedae30f8cf7794 (diff)
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: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c13
-rw-r--r--net/core/neighbour.c1
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