From 2ab75bfb17e2cf3159033e91ebf2eb11efc1f0d3 Mon Sep 17 00:00:00 2001 From: David Ahern Date: Sat, 8 Jun 2019 14:53:23 -0700 Subject: [PATCH] ipv6: Handle all fib6_nh in a nexthop in fib6_drop_pcpu_from Use nexthop_for_each_fib6_nh to walk all fib6_nh in a nexthop when dropping 'from' reference in pcpu routes. Signed-off-by: David Ahern Signed-off-by: David S. Miller --- net/ipv6/ip6_fib.c | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c index 17dcc916eb63..1cce2082279c 100644 --- a/net/ipv6/ip6_fib.c +++ b/net/ipv6/ip6_fib.c @@ -906,19 +906,42 @@ static void __fib6_drop_pcpu_from(struct fib6_nh *fib6_nh, } } +struct fib6_nh_pcpu_arg { + struct fib6_info *from; + const struct fib6_table *table; +}; + +static int fib6_nh_drop_pcpu_from(struct fib6_nh *nh, void *_arg) +{ + struct fib6_nh_pcpu_arg *arg = _arg; + + __fib6_drop_pcpu_from(nh, arg->from, arg->table); + return 0; +} + static void fib6_drop_pcpu_from(struct fib6_info *f6i, const struct fib6_table *table) { - struct fib6_nh *fib6_nh; - /* Make sure rt6_make_pcpu_route() wont add other percpu routes * while we are cleaning them here. */ f6i->fib6_destroying = 1; mb(); /* paired with the cmpxchg() in rt6_make_pcpu_route() */ - fib6_nh = f6i->fib6_nh; - __fib6_drop_pcpu_from(fib6_nh, f6i, table); + if (f6i->nh) { + struct fib6_nh_pcpu_arg arg = { + .from = f6i, + .table = table + }; + + nexthop_for_each_fib6_nh(f6i->nh, fib6_nh_drop_pcpu_from, + &arg); + } else { + struct fib6_nh *fib6_nh; + + fib6_nh = f6i->fib6_nh; + __fib6_drop_pcpu_from(fib6_nh, f6i, table); + } } static void fib6_purge_rt(struct fib6_info *rt, struct fib6_node *fn, -- 2.30.2