On 6/19/19 5:59 PM, Stefano Brivio wrote:
> diff --git a/include/net/route.h b/include/net/route.h
> index 065b47754f05..e7f65388a6d4 100644
> --- a/include/net/route.h
> +++ b/include/net/route.h
> @@ -44,6 +44,7 @@
>  #define RT_CONN_FLAGS_TOS(sk,tos)   (RT_TOS(tos) | sock_flag(sk, 
> SOCK_LOCALROUTE))
>  
>  struct fib_nh;
> +struct fib_alias;
>  struct fib_info;
>  struct uncached_list;
>  struct rtable {

we should not expose fib_alias to route.c.

> @@ -230,6 +231,9 @@ void fib_modify_prefix_metric(struct in_ifaddr *ifa, u32 
> new_metric);
>  void rt_add_uncached_list(struct rtable *rt);
>  void rt_del_uncached_list(struct rtable *rt);
>  
> +int fnhe_dump_buckets(struct fib_alias *fa, int nhsel, struct sk_buff *skb,
> +                   struct netlink_callback *cb, int *fa_index, int fa_start);
> +
>  static inline void ip_rt_put(struct rtable *rt)
>  {
>       /* dst_release() accepts a NULL parameter.
> diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c
> index 94e5d83db4db..03f51e5192e5 100644
> --- a/net/ipv4/fib_trie.c
> +++ b/net/ipv4/fib_trie.c
> @@ -2078,28 +2078,51 @@ 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 fib_info *fi = fa->fa_info;
> +     int nhsel;
> +
> +     if (!fi || fi->fib_flags & RTNH_F_DEAD)
> +             return 0;
> +
> +     for (nhsel = 0; nhsel < fib_info_num_path(fi); nhsel++) {
> +             int err;
> +
> +             err = fnhe_dump_buckets(fa, nhsel, skb, cb, fa_index, fa_start);
> +             if (err)
> +                     return err;
> +     }
> +
> +     return 0;
> +}

fib_info would be the better argument to pass in to the fnhe dump, and
I think the loop over where the bucket is should be in route.c as well.
So how about fib_info_dump_fnhe() as the helper exposed from route.c,
and it does the loop over nexthops and calls fnhe_dump_buckets.

As for the loop, you could fill an skb without finishing a bucket inside
of a nexthop so you need top track which nexthop is current as well.

Reply via email to