diff options
-rw-r--r-- | drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c | 57 |
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 | ||
1469 | static int | 1469 | static int |
1470 | mlxsw_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 | |||
1478 | static int | ||
1479 | mlxsw_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 | |||
1491 | static int | ||
1470 | mlxsw_sp_netdevice_ipip_ol_change_event(struct mlxsw_sp *mlxsw_sp, | 1492 | mlxsw_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 | ||
3330 | static 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 | |||
3300 | static int mlxsw_sp_nexthop_ipip_init(struct mlxsw_sp *mlxsw_sp, | 3337 | static 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 | } |