summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c4
-rw-r--r--drivers/net/netdevsim/fib.c2
-rw-r--r--include/net/ip6_fib.h5
-rw-r--r--net/ipv6/route.c8
4 files changed, 12 insertions, 7 deletions
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
index ac9a174372cc..a5f980b6940e 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
@@ -5008,7 +5008,7 @@ mlxsw_sp_fib6_entry_hw_flags_set(struct mlxsw_sp *mlxsw_sp,
common);
list_for_each_entry(mlxsw_sp_rt6, &fib6_entry->rt6_list, list)
fib6_info_hw_flags_set(mlxsw_sp_net(mlxsw_sp), mlxsw_sp_rt6->rt,
- should_offload, !should_offload);
+ should_offload, !should_offload, false);
}
#else
static void
@@ -5030,7 +5030,7 @@ mlxsw_sp_fib6_entry_hw_flags_clear(struct mlxsw_sp *mlxsw_sp,
common);
list_for_each_entry(mlxsw_sp_rt6, &fib6_entry->rt6_list, list)
fib6_info_hw_flags_set(mlxsw_sp_net(mlxsw_sp), mlxsw_sp_rt6->rt,
- false, false);
+ false, false, false);
}
#else
static void
diff --git a/drivers/net/netdevsim/fib.c b/drivers/net/netdevsim/fib.c
index ca19da169853..6b1ec3b4750c 100644
--- a/drivers/net/netdevsim/fib.c
+++ b/drivers/net/netdevsim/fib.c
@@ -595,7 +595,7 @@ static void nsim_fib6_rt_hw_flags_set(struct nsim_fib_data *data,
struct nsim_fib6_rt_nh *fib6_rt_nh;
list_for_each_entry(fib6_rt_nh, &fib6_rt->nh_list, list)
- fib6_info_hw_flags_set(net, fib6_rt_nh->rt, false, trap);
+ fib6_info_hw_flags_set(net, fib6_rt_nh->rt, false, trap, false);
}
#else
static void nsim_fib6_rt_hw_flags_set(struct nsim_fib_data *data,
diff --git a/include/net/ip6_fib.h b/include/net/ip6_fib.h
index 1e262b23c68b..15b7fbe6b15c 100644
--- a/include/net/ip6_fib.h
+++ b/include/net/ip6_fib.h
@@ -195,7 +195,8 @@ struct fib6_info {
fib6_destroying:1,
offload:1,
trap:1,
- unused:2;
+ offload_failed:1,
+ unused:1;
struct rcu_head rcu;
struct nexthop *nh;
@@ -539,7 +540,7 @@ static inline bool fib6_metric_locked(struct fib6_info *f6i, int metric)
return !!(f6i->fib6_metrics->metrics[RTAX_LOCK - 1] & (1 << metric));
}
void fib6_info_hw_flags_set(struct net *net, struct fib6_info *f6i,
- bool offload, bool trap);
+ bool offload, bool trap, bool offload_failed);
#if IS_BUILTIN(CONFIG_IPV6) && defined(CONFIG_BPF_SYSCALL)
struct bpf_iter__ipv6_route {
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 0d1784b0d65d..bc75b705f54b 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -5619,6 +5619,8 @@ static int rt6_fill_node(struct net *net, struct sk_buff *skb,
rtm->rtm_flags |= RTM_F_OFFLOAD;
if (rt->trap)
rtm->rtm_flags |= RTM_F_TRAP;
+ if (rt->offload_failed)
+ rtm->rtm_flags |= RTM_F_OFFLOAD_FAILED;
}
if (rtnl_put_cacheinfo(skb, dst, 0, expires, dst ? dst->error : 0) < 0)
@@ -6070,16 +6072,18 @@ errout:
}
void fib6_info_hw_flags_set(struct net *net, struct fib6_info *f6i,
- bool offload, bool trap)
+ bool offload, bool trap, bool offload_failed)
{
struct sk_buff *skb;
int err;
- if (f6i->offload == offload && f6i->trap == trap)
+ if (f6i->offload == offload && f6i->trap == trap &&
+ f6i->offload_failed == offload_failed)
return;
f6i->offload = offload;
f6i->trap = trap;
+ f6i->offload_failed = offload_failed;
if (!rcu_access_pointer(f6i->fib6_node))
/* The route was removed from the tree, do not send