From 0c5f1cd5ba8c03567c67910816a7a0fb9fee5746 Mon Sep 17 00:00:00 2001 From: Petr Machata Date: Fri, 3 Nov 2017 10:03:38 +0100 Subject: mlxsw: spectrum_router: Generalize __mlxsw_sp_ipip_entry_update_tunnel() The work that needs to be done to update HW configuration in response to changes is similar to what __mlxsw_sp_ipip_entry_update_tunnel() already does, but with a number of twists: each change requires a different subset of things to happen. Extend the function to support all these uses, and allow finely-grained configuration of what should happen at each call through a suite of function arguments. Publish the updated function to allow use from the spectrum_ipip module. Signed-off-by: Petr Machata Reviewed-by: Ido Schimmel Signed-off-by: Jiri Pirko Signed-off-by: David S. Miller --- .../net/ethernet/mellanox/mlxsw/spectrum_router.c | 47 ++++++++++++++++++++-- 1 file changed, 43 insertions(+), 4 deletions(-) (limited to 'drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c') diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c index e2795b889068..1376a9738b3c 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c @@ -1355,9 +1355,12 @@ static void mlxsw_sp_netdevice_ipip_ol_down_event(struct mlxsw_sp *mlxsw_sp, mlxsw_sp_ipip_entry_ol_down_event(mlxsw_sp, ipip_entry); } +static void mlxsw_sp_nexthop_rif_update(struct mlxsw_sp *mlxsw_sp, + struct mlxsw_sp_rif *rif); static int mlxsw_sp_ipip_entry_ol_lb_update(struct mlxsw_sp *mlxsw_sp, struct mlxsw_sp_ipip_entry *ipip_entry, + bool keep_encap, struct netlink_ext_ack *extack) { struct mlxsw_sp_rif_ipip_lb *old_lb_rif = ipip_entry->ol_lb; @@ -1370,13 +1373,32 @@ mlxsw_sp_ipip_entry_ol_lb_update(struct mlxsw_sp *mlxsw_sp, if (IS_ERR(new_lb_rif)) return PTR_ERR(new_lb_rif); ipip_entry->ol_lb = new_lb_rif; + + if (keep_encap) { + list_splice_init(&old_lb_rif->common.nexthop_list, + &new_lb_rif->common.nexthop_list); + mlxsw_sp_nexthop_rif_update(mlxsw_sp, &new_lb_rif->common); + } + mlxsw_sp_rif_destroy(&old_lb_rif->common); return 0; } +/** + * Update the offload related to an IPIP entry. This always updates decap, and + * in addition to that it also: + * @recreate_loopback: recreates the associated loopback RIF + * @keep_encap: updates next hops that use the tunnel netdevice. This is only + * relevant when recreate_loopback is true. + * @update_nexthops: updates next hops, keeping the current loopback RIF. This + * is only relevant when recreate_loopback is false. + */ int __mlxsw_sp_ipip_entry_update_tunnel(struct mlxsw_sp *mlxsw_sp, struct mlxsw_sp_ipip_entry *ipip_entry, + bool recreate_loopback, + bool keep_encap, + bool update_nexthops, struct netlink_ext_ack *extack) { int err; @@ -1390,9 +1412,15 @@ int __mlxsw_sp_ipip_entry_update_tunnel(struct mlxsw_sp *mlxsw_sp, if (ipip_entry->decap_fib_entry) mlxsw_sp_ipip_entry_demote_decap(mlxsw_sp, ipip_entry); - err = mlxsw_sp_ipip_entry_ol_lb_update(mlxsw_sp, ipip_entry, extack); - if (err) - return err; + if (recreate_loopback) { + err = mlxsw_sp_ipip_entry_ol_lb_update(mlxsw_sp, ipip_entry, + keep_encap, extack); + if (err) + return err; + } else if (update_nexthops) { + mlxsw_sp_nexthop_rif_update(mlxsw_sp, + &ipip_entry->ol_lb->common); + } if (ipip_entry->ol_dev->flags & IFF_UP) mlxsw_sp_ipip_entry_ol_up_event(mlxsw_sp, ipip_entry); @@ -1410,7 +1438,7 @@ static int mlxsw_sp_netdevice_ipip_ol_vrf_event(struct mlxsw_sp *mlxsw_sp, if (!ipip_entry) return 0; return __mlxsw_sp_ipip_entry_update_tunnel(mlxsw_sp, ipip_entry, - extack); + true, false, false, extack); } int mlxsw_sp_netdevice_ipip_ol_event(struct mlxsw_sp *mlxsw_sp, @@ -3285,6 +3313,17 @@ static void mlxsw_sp_nexthop4_event(struct mlxsw_sp *mlxsw_sp, mlxsw_sp_nexthop_group_refresh(mlxsw_sp, nh->nh_grp); } +static void mlxsw_sp_nexthop_rif_update(struct mlxsw_sp *mlxsw_sp, + struct mlxsw_sp_rif *rif) +{ + struct mlxsw_sp_nexthop *nh; + + list_for_each_entry(nh, &rif->nexthop_list, rif_list_node) { + __mlxsw_sp_nexthop_neigh_update(nh, false); + mlxsw_sp_nexthop_group_refresh(mlxsw_sp, nh->nh_grp); + } +} + static void mlxsw_sp_nexthop_rif_gone_sync(struct mlxsw_sp *mlxsw_sp, struct mlxsw_sp_rif *rif) { -- cgit v1.2.3-55-g7522