diff options
author | David Ahern <dsahern@gmail.com> | 2019-06-08 23:53:23 +0200 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2019-06-10 19:44:56 +0200 |
commit | 2ab75bfb17e2cf3159033e91ebf2eb11efc1f0d3 (patch) | |
tree | 0e51f9cffab9f1f2ecd11614000d8b761b254806 /net/ipv6/ip6_fib.c | |
parent | nexthops: Add ipv6 helper to walk all fib6_nh in a nexthop struct (diff) | |
download | linux-2ab75bfb17e2cf3159033e91ebf2eb11efc1f0d3.tar.xz linux-2ab75bfb17e2cf3159033e91ebf2eb11efc1f0d3.zip |
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/ipv6/ip6_fib.c')
-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, |