Follow on patch adds support for active-backup nexthops. Control planes needs to always analyze all legs of the nexthops, but datapath only wants to consider the primary.
Signed-off-by: David Ahern <dsah...@kernel.org> --- include/net/nexthop.h | 2 +- net/ipv4/nexthop.c | 6 +++--- net/ipv6/ip6_fib.c | 4 ++-- net/ipv6/route.c | 37 ++++++++++++++++++++----------------- 4 files changed, 26 insertions(+), 23 deletions(-) diff --git a/include/net/nexthop.h b/include/net/nexthop.h index 271d2cb92954..8cedadb902b6 100644 --- a/include/net/nexthop.h +++ b/include/net/nexthop.h @@ -346,7 +346,7 @@ static inline void nexthop_path_fib6_result(struct fib6_result *res, int hash) } } -int nexthop_for_each_fib6_nh(struct nexthop *nh, +int nexthop_for_each_fib6_nh(struct nexthop *nh, bool primary_only, int (*cb)(struct fib6_nh *nh, void *arg), void *arg); diff --git a/net/ipv4/nexthop.c b/net/ipv4/nexthop.c index 0020ea2ecc9f..8984e1e4058b 100644 --- a/net/ipv4/nexthop.c +++ b/net/ipv4/nexthop.c @@ -684,7 +684,7 @@ static int nexthop_fib6_nh_cb(struct nexthop *nh, return cb(&nhi->fib6_nh, arg); } -static int nexthop_fib6_nhg_cb(struct nh_group *nhg, +static int nexthop_fib6_nhg_cb(struct nh_group *nhg, bool primary_only, int (*cb)(struct fib6_nh *nh, void *arg), void *arg) { @@ -703,7 +703,7 @@ static int nexthop_fib6_nhg_cb(struct nh_group *nhg, return 0; } -int nexthop_for_each_fib6_nh(struct nexthop *nh, +int nexthop_for_each_fib6_nh(struct nexthop *nh, bool primary_only, int (*cb)(struct fib6_nh *nh, void *arg), void *arg) { @@ -713,7 +713,7 @@ int nexthop_for_each_fib6_nh(struct nexthop *nh, struct nh_group *nhg; nhg = rcu_dereference_rtnl(nh->nh_grp); - err = nexthop_fib6_nhg_cb(nhg, cb, arg); + err = nexthop_fib6_nhg_cb(nhg, primary_only, cb, arg); } else { err = nexthop_fib6_nh_cb(nh, cb, arg); } diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c index 49ee89bbcba0..7e593f9d519d 100644 --- a/net/ipv6/ip6_fib.c +++ b/net/ipv6/ip6_fib.c @@ -1009,8 +1009,8 @@ static void fib6_drop_pcpu_from(struct fib6_info *f6i, .table = table }; - nexthop_for_each_fib6_nh(f6i->nh, fib6_nh_drop_pcpu_from, - &arg); + nexthop_for_each_fib6_nh(f6i->nh, false, + fib6_nh_drop_pcpu_from, &arg); } else { struct fib6_nh *fib6_nh; diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 82cbb46a2a4f..e2bd3dc7194d 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -526,7 +526,7 @@ static struct fib6_nh *rt6_nh_dev_match(struct net *net, struct nexthop *nh, if (nexthop_is_blackhole(nh)) return NULL; - if (nexthop_for_each_fib6_nh(nh, __rt6_nh_dev_match, &arg)) + if (nexthop_for_each_fib6_nh(nh, true, __rt6_nh_dev_match, &arg)) return arg.nh; return NULL; @@ -827,7 +827,8 @@ static void __find_rr_leaf(struct fib6_info *f6i_start, res->nh = nexthop_fib6_nh(f6i->nh); return; } - if (nexthop_for_each_fib6_nh(f6i->nh, rt6_nh_find_match, + if (nexthop_for_each_fib6_nh(f6i->nh, true, + rt6_nh_find_match, &arg)) { matched = true; nh = arg.nh; @@ -1774,8 +1775,8 @@ static int rt6_nh_flush_exceptions(struct fib6_nh *nh, void *arg) void rt6_flush_exceptions(struct fib6_info *f6i) { if (f6i->nh) - nexthop_for_each_fib6_nh(f6i->nh, rt6_nh_flush_exceptions, - f6i); + nexthop_for_each_fib6_nh(f6i->nh, false, + rt6_nh_flush_exceptions, f6i); else fib6_nh_flush_exceptions(f6i->fib6_nh, f6i); } @@ -1897,7 +1898,7 @@ static int rt6_remove_exception_rt(struct rt6_info *rt) int rc; /* rc = 1 means an entry was found */ - rc = nexthop_for_each_fib6_nh(from->nh, + rc = nexthop_for_each_fib6_nh(from->nh, false, rt6_nh_remove_exception_rt, &arg); return rc ? 0 : -ENOENT; @@ -1973,7 +1974,8 @@ static void rt6_update_exception_stamp_rt(struct rt6_info *rt) .gw = &rt->rt6i_gateway, }; - nexthop_for_each_fib6_nh(from->nh, fib6_nh_find_match, &arg); + nexthop_for_each_fib6_nh(from->nh, false, fib6_nh_find_match, + &arg); if (!arg.match) goto unlock; @@ -2166,8 +2168,8 @@ void rt6_age_exceptions(struct fib6_info *f6i, .now = now }; - nexthop_for_each_fib6_nh(f6i->nh, rt6_nh_age_exceptions, - &arg); + nexthop_for_each_fib6_nh(f6i->nh, false, + rt6_nh_age_exceptions, &arg); } else { fib6_nh_age_exceptions(f6i->fib6_nh, gc_args, now); } @@ -2768,7 +2770,7 @@ static void __ip6_rt_update_pmtu(struct dst_entry *dst, const struct sock *sk, .gw = &rt6->rt6i_gateway, }; - nexthop_for_each_fib6_nh(res.f6i->nh, + nexthop_for_each_fib6_nh(res.f6i->nh, true, fib6_nh_find_match, &arg); /* fib6_info uses a nexthop that does not have fib6_nh @@ -2959,7 +2961,7 @@ static struct rt6_info *__ip6_route_redirect(struct net *net, if (nexthop_is_blackhole(rt->nh)) continue; /* on match, res->nh is filled in and potentially ret */ - if (nexthop_for_each_fib6_nh(rt->nh, + if (nexthop_for_each_fib6_nh(rt->nh, true, fib6_nh_redirect_match, &arg)) goto out; @@ -3906,7 +3908,8 @@ static int ip6_del_cached_rt_nh(struct fib6_config *cfg, struct fib6_info *f6i) .f6i = f6i }; - return nexthop_for_each_fib6_nh(f6i->nh, fib6_nh_del_cached_rt, &arg); + return nexthop_for_each_fib6_nh(f6i->nh, false, + fib6_nh_del_cached_rt, &arg); } static int ip6_route_del(struct fib6_config *cfg, @@ -4096,7 +4099,7 @@ static void rt6_do_redirect(struct dst_entry *dst, struct sock *sk, struct sk_bu .gw = &rt->rt6i_gateway, }; - nexthop_for_each_fib6_nh(res.f6i->nh, + nexthop_for_each_fib6_nh(res.f6i->nh, true, fib6_nh_find_match, &arg); /* fib6_info uses a nexthop that does not have fib6_nh @@ -4835,8 +4838,8 @@ static int rt6_mtu_change_route(struct fib6_info *f6i, void *p_arg) arg->f6i = f6i; if (f6i->nh) { /* fib6_nh_mtu_change only returns 0, so this is safe */ - return nexthop_for_each_fib6_nh(f6i->nh, fib6_nh_mtu_change, - arg); + return nexthop_for_each_fib6_nh(f6i->nh, false, + fib6_nh_mtu_change, arg); } return fib6_nh_mtu_change(f6i->fib6_nh, arg); @@ -5381,7 +5384,7 @@ static size_t rt6_nlmsg_size(struct fib6_info *f6i) if (f6i->nh) { nexthop_len = nla_total_size(4); /* RTA_NH_ID */ - nexthop_for_each_fib6_nh(f6i->nh, rt6_nh_nlmsg_size, + nexthop_for_each_fib6_nh(f6i->nh, false, rt6_nh_nlmsg_size, &nexthop_len); } else { struct fib6_nh *nh = f6i->fib6_nh; @@ -5636,7 +5639,7 @@ static bool fib6_info_uses_dev(const struct fib6_info *f6i, if (f6i->nh) { struct net_device *_dev = (struct net_device *)dev; - return !!nexthop_for_each_fib6_nh(f6i->nh, + return !!nexthop_for_each_fib6_nh(f6i->nh, true, fib6_info_nh_uses_dev, _dev); } @@ -5769,7 +5772,7 @@ int rt6_dump_route(struct fib6_info *rt, void *p_arg, unsigned int skip) rcu_read_lock(); if (rt->nh) { - err = nexthop_for_each_fib6_nh(rt->nh, + err = nexthop_for_each_fib6_nh(rt->nh, false, rt6_nh_dump_exceptions, &w); } else { -- 2.21.1 (Apple Git-122.3)