On Tue, 18 Jun 2019 08:48:23 -0600 David Ahern <dsah...@gmail.com> wrote:
> > +++ b/net/ipv4/fib_trie.c > > @@ -2000,28 +2000,92 @@ void fib_free_table(struct fib_table *tb) > > call_rcu(&tb->rcu, __trie_free_rcu); > > } > > > > +static int fib_dump_fnhe_from_leaf(struct fib_alias *fa, struct sk_buff > > *skb, > > + struct netlink_callback *cb, > > + int *fa_index, int fa_start) > > +{ > > + struct net *net = sock_net(cb->skb->sk); > > + struct fib_info *fi = fa->fa_info; > > + struct fnhe_hash_bucket *bucket; > > + struct fib_nh_common *nhc; > > + int i, genid; > > + > > + if (!fi || fi->fib_flags & RTNH_F_DEAD) > > + return 0; > > + > > + nhc = fib_info_nhc(fi, 0); > > This should be a loop over fi->fib_nhs for net: > for (i = 0; i < fi->fib_nhs; i++) { > nhc = fib_info_nhc(fi, 0); > ... > > and a loop over fib_info_num_path(fi) for net-next: > for (i = 0; i < fib_info_num_path(fi); i++) { > nhc = fib_info_nhc(fi, 0); > ... Right, I started this from net-next and only later "adapted" to net clearly in the wrong way. Thanks for providing both expressions. Fixed in v6. > > > + if (nhc->nhc_flags & RTNH_F_DEAD) > > + return 0; > > And then the loop over the exception bucket could be a helper in route.c > in which case you don't need to export rt_fill_info and nhc_exceptions > code does not spread to fib_trie.c Cleaner I guess, changed in v6. > > + > > + bucket = rcu_dereference(nhc->nhc_exceptions); > > + if (!bucket) > > + return 0; > > + > > + genid = fnhe_genid(net); > > + > > + for (i = 0; i < FNHE_HASH_SIZE; i++) { > > + struct fib_nh_exception *fnhe; > > + > > + for (fnhe = rcu_dereference(bucket[i].chain); fnhe; > > + fnhe = rcu_dereference(fnhe->fnhe_next)) { > > + struct flowi4 fl4 = {}; > > rather than pass an empty flow struct, update rt_fill_info to handle a > NULL fl4; it's only a few checks. Added patch and changed in v6. -- Stefano