aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c57
1 files changed, 55 insertions, 2 deletions
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
index c1928561c412..e9187841d82a 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
@@ -1467,6 +1467,28 @@ mlxsw_sp_netdevice_ipip_ul_vrf_event(struct mlxsw_sp *mlxsw_sp,
1467} 1467}
1468 1468
1469static int 1469static int
1470mlxsw_sp_netdevice_ipip_ul_up_event(struct mlxsw_sp *mlxsw_sp,
1471 struct mlxsw_sp_ipip_entry *ipip_entry,
1472 struct net_device *ul_dev)
1473{
1474 return __mlxsw_sp_ipip_entry_update_tunnel(mlxsw_sp, ipip_entry,
1475 false, false, true, NULL);
1476}
1477
1478static int
1479mlxsw_sp_netdevice_ipip_ul_down_event(struct mlxsw_sp *mlxsw_sp,
1480 struct mlxsw_sp_ipip_entry *ipip_entry,
1481 struct net_device *ul_dev)
1482{
1483 /* A down underlay device causes encapsulated packets to not be
1484 * forwarded, but decap still works. So refresh next hops without
1485 * touching anything else.
1486 */
1487 return __mlxsw_sp_ipip_entry_update_tunnel(mlxsw_sp, ipip_entry,
1488 false, false, true, NULL);
1489}
1490
1491static int
1470mlxsw_sp_netdevice_ipip_ol_change_event(struct mlxsw_sp *mlxsw_sp, 1492mlxsw_sp_netdevice_ipip_ol_change_event(struct mlxsw_sp *mlxsw_sp,
1471 struct net_device *ol_dev, 1493 struct net_device *ol_dev,
1472 struct netlink_ext_ack *extack) 1494 struct netlink_ext_ack *extack)
@@ -1604,6 +1626,14 @@ __mlxsw_sp_netdevice_ipip_ul_event(struct mlxsw_sp *mlxsw_sp,
1604 ul_dev, 1626 ul_dev,
1605 extack); 1627 extack);
1606 break; 1628 break;
1629
1630 case NETDEV_UP:
1631 return mlxsw_sp_netdevice_ipip_ul_up_event(mlxsw_sp, ipip_entry,
1632 ul_dev);
1633 case NETDEV_DOWN:
1634 return mlxsw_sp_netdevice_ipip_ul_down_event(mlxsw_sp,
1635 ipip_entry,
1636 ul_dev);
1607 } 1637 }
1608 return 0; 1638 return 0;
1609} 1639}
@@ -3297,10 +3327,19 @@ static void mlxsw_sp_nexthop_neigh_fini(struct mlxsw_sp *mlxsw_sp,
3297 neigh_release(n); 3327 neigh_release(n);
3298} 3328}
3299 3329
3330static bool mlxsw_sp_ipip_netdev_ul_up(struct net_device *ol_dev)
3331{
3332 struct net_device *ul_dev = __mlxsw_sp_ipip_netdev_ul_dev_get(ol_dev);
3333
3334 return ul_dev ? (ul_dev->flags & IFF_UP) : true;
3335}
3336
3300static int mlxsw_sp_nexthop_ipip_init(struct mlxsw_sp *mlxsw_sp, 3337static int mlxsw_sp_nexthop_ipip_init(struct mlxsw_sp *mlxsw_sp,
3301 struct mlxsw_sp_nexthop *nh, 3338 struct mlxsw_sp_nexthop *nh,
3302 struct net_device *ol_dev) 3339 struct net_device *ol_dev)
3303{ 3340{
3341 bool removing;
3342
3304 if (!nh->nh_grp->gateway || nh->ipip_entry) 3343 if (!nh->nh_grp->gateway || nh->ipip_entry)
3305 return 0; 3344 return 0;
3306 3345
@@ -3308,7 +3347,8 @@ static int mlxsw_sp_nexthop_ipip_init(struct mlxsw_sp *mlxsw_sp,
3308 if (!nh->ipip_entry) 3347 if (!nh->ipip_entry)
3309 return -ENOENT; 3348 return -ENOENT;
3310 3349
3311 __mlxsw_sp_nexthop_neigh_update(nh, false); 3350 removing = !mlxsw_sp_ipip_netdev_ul_up(ol_dev);
3351 __mlxsw_sp_nexthop_neigh_update(nh, removing);
3312 return 0; 3352 return 0;
3313} 3353}
3314 3354
@@ -3476,9 +3516,22 @@ static void mlxsw_sp_nexthop_rif_update(struct mlxsw_sp *mlxsw_sp,
3476 struct mlxsw_sp_rif *rif) 3516 struct mlxsw_sp_rif *rif)
3477{ 3517{
3478 struct mlxsw_sp_nexthop *nh; 3518 struct mlxsw_sp_nexthop *nh;
3519 bool removing;
3479 3520
3480 list_for_each_entry(nh, &rif->nexthop_list, rif_list_node) { 3521 list_for_each_entry(nh, &rif->nexthop_list, rif_list_node) {
3481 __mlxsw_sp_nexthop_neigh_update(nh, false); 3522 switch (nh->type) {
3523 case MLXSW_SP_NEXTHOP_TYPE_ETH:
3524 removing = false;
3525 break;
3526 case MLXSW_SP_NEXTHOP_TYPE_IPIP:
3527 removing = !mlxsw_sp_ipip_netdev_ul_up(rif->dev);
3528 break;
3529 default:
3530 WARN_ON(1);
3531 continue;
3532 }
3533
3534 __mlxsw_sp_nexthop_neigh_update(nh, removing);
3482 mlxsw_sp_nexthop_group_refresh(mlxsw_sp, nh->nh_grp); 3535 mlxsw_sp_nexthop_group_refresh(mlxsw_sp, nh->nh_grp);
3483 } 3536 }
3484} 3537}