Commit 0c5f1cd5 authored by Petr Machata's avatar Petr Machata Committed by David S. Miller

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: default avatarPetr Machata <petrm@mellanox.com>
Reviewed-by: default avatarIdo Schimmel <idosch@mellanox.com>
Signed-off-by: default avatarJiri Pirko <jiri@mellanox.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 65a6121b
...@@ -1355,9 +1355,12 @@ static void mlxsw_sp_netdevice_ipip_ol_down_event(struct mlxsw_sp *mlxsw_sp, ...@@ -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); 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 static int
mlxsw_sp_ipip_entry_ol_lb_update(struct mlxsw_sp *mlxsw_sp, mlxsw_sp_ipip_entry_ol_lb_update(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_ipip_entry *ipip_entry, struct mlxsw_sp_ipip_entry *ipip_entry,
bool keep_encap,
struct netlink_ext_ack *extack) struct netlink_ext_ack *extack)
{ {
struct mlxsw_sp_rif_ipip_lb *old_lb_rif = ipip_entry->ol_lb; 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, ...@@ -1370,13 +1373,32 @@ mlxsw_sp_ipip_entry_ol_lb_update(struct mlxsw_sp *mlxsw_sp,
if (IS_ERR(new_lb_rif)) if (IS_ERR(new_lb_rif))
return PTR_ERR(new_lb_rif); return PTR_ERR(new_lb_rif);
ipip_entry->ol_lb = 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); mlxsw_sp_rif_destroy(&old_lb_rif->common);
return 0; 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, int __mlxsw_sp_ipip_entry_update_tunnel(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_ipip_entry *ipip_entry, struct mlxsw_sp_ipip_entry *ipip_entry,
bool recreate_loopback,
bool keep_encap,
bool update_nexthops,
struct netlink_ext_ack *extack) struct netlink_ext_ack *extack)
{ {
int err; int err;
...@@ -1390,9 +1412,15 @@ int __mlxsw_sp_ipip_entry_update_tunnel(struct mlxsw_sp *mlxsw_sp, ...@@ -1390,9 +1412,15 @@ int __mlxsw_sp_ipip_entry_update_tunnel(struct mlxsw_sp *mlxsw_sp,
if (ipip_entry->decap_fib_entry) if (ipip_entry->decap_fib_entry)
mlxsw_sp_ipip_entry_demote_decap(mlxsw_sp, ipip_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 (recreate_loopback) {
if (err) err = mlxsw_sp_ipip_entry_ol_lb_update(mlxsw_sp, ipip_entry,
return err; 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) if (ipip_entry->ol_dev->flags & IFF_UP)
mlxsw_sp_ipip_entry_ol_up_event(mlxsw_sp, ipip_entry); 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, ...@@ -1410,7 +1438,7 @@ static int mlxsw_sp_netdevice_ipip_ol_vrf_event(struct mlxsw_sp *mlxsw_sp,
if (!ipip_entry) if (!ipip_entry)
return 0; return 0;
return __mlxsw_sp_ipip_entry_update_tunnel(mlxsw_sp, ipip_entry, 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, 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, ...@@ -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); 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, static void mlxsw_sp_nexthop_rif_gone_sync(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_rif *rif) struct mlxsw_sp_rif *rif)
{ {
......
...@@ -63,6 +63,7 @@ enum mlxsw_sp_rif_counter_dir { ...@@ -63,6 +63,7 @@ enum mlxsw_sp_rif_counter_dir {
struct mlxsw_sp_neigh_entry; struct mlxsw_sp_neigh_entry;
struct mlxsw_sp_nexthop; struct mlxsw_sp_nexthop;
struct mlxsw_sp_ipip_entry;
struct mlxsw_sp_rif *mlxsw_sp_rif_by_index(const struct mlxsw_sp *mlxsw_sp, struct mlxsw_sp_rif *mlxsw_sp_rif_by_index(const struct mlxsw_sp *mlxsw_sp,
u16 rif_index); u16 rif_index);
...@@ -103,6 +104,12 @@ mlxsw_sp_neigh_entry_counter_update(struct mlxsw_sp *mlxsw_sp, ...@@ -103,6 +104,12 @@ mlxsw_sp_neigh_entry_counter_update(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_neigh_entry *neigh_entry, struct mlxsw_sp_neigh_entry *neigh_entry,
bool adding); bool adding);
bool mlxsw_sp_neigh_ipv6_ignore(struct mlxsw_sp_neigh_entry *neigh_entry); bool mlxsw_sp_neigh_ipv6_ignore(struct mlxsw_sp_neigh_entry *neigh_entry);
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);
struct mlxsw_sp_nexthop *mlxsw_sp_nexthop_next(struct mlxsw_sp_router *router, struct mlxsw_sp_nexthop *mlxsw_sp_nexthop_next(struct mlxsw_sp_router *router,
struct mlxsw_sp_nexthop *nh); struct mlxsw_sp_nexthop *nh);
bool mlxsw_sp_nexthop_offload(struct mlxsw_sp_nexthop *nh); bool mlxsw_sp_nexthop_offload(struct mlxsw_sp_nexthop *nh);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment