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)

Reply via email to