diff options
author | David Ahern <dsahern@gmail.com> | 2019-06-08 14:53:23 -0700 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2019-06-10 10:44:56 -0700 |
commit | 2ab75bfb17e2cf3159033e91ebf2eb11efc1f0d3 (patch) | |
tree | 0e51f9cffab9f1f2ecd11614000d8b761b254806 /net | |
parent | f88c9aa12fd0cff9cbb74b490350e6f0fac68296 (diff) |
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 <dsahern@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r-- | net/ipv6/ip6_fib.c | 31 |
1 files 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, |