diff options
author | David Ahern <dsa@cumulusnetworks.com> | 2017-02-02 21:37:09 +0100 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2017-02-05 01:58:14 +0100 |
commit | beb1afac518dec5a15dc92ba8f0ca016dcf457b4 (patch) | |
tree | fd862968261f8dec35eed33991fa394232cc58db /net/ipv6/ip6_fib.c | |
parent | net: ipv6: Allow shorthand delete of all nexthops in multipath route (diff) | |
download | linux-beb1afac518dec5a15dc92ba8f0ca016dcf457b4.tar.xz linux-beb1afac518dec5a15dc92ba8f0ca016dcf457b4.zip |
net: ipv6: Add support to dump multipath routes via RTA_MULTIPATH attribute
IPv6 returns multipath routes as a series of individual routes making
their display and handling by userspace different and more complicated
than IPv4, putting the burden on the user to see that a route is part of
a multipath route and internally creating a multipath route if desired
(e.g., libnl does this as of commit 29b71371e764). This patch addresses
this difference, allowing multipath routes to be returned using the
RTA_MULTIPATH attribute.
The end result is that IPv6 multipath routes can be treated and displayed
in a format similar to IPv4:
$ ip -6 ro ls vrf red
2001:db8:1::/120 dev eth1 proto kernel metric 256 pref medium
2001:db8:2::/120 dev eth2 proto kernel metric 256 pref medium
2001:db8:200::/120 metric 1024
nexthop via 2001:db8:1::2 dev eth1 weight 1
nexthop via 2001:db8:2::2 dev eth2 weight 1
Signed-off-by: David Ahern <dsa@cumulusnetworks.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 | 10 |
1 files changed, 10 insertions, 0 deletions
diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c index febde6c112bf..1bf5e22fb95d 100644 --- a/net/ipv6/ip6_fib.c +++ b/net/ipv6/ip6_fib.c @@ -318,6 +318,16 @@ static int fib6_dump_node(struct fib6_walker *w) w->leaf = rt; return 1; } + + /* Multipath routes are dumped in one route with the + * RTA_MULTIPATH attribute. Jump 'rt' to point to the + * last sibling of this route (no need to dump the + * sibling routes again) + */ + if (rt->rt6i_nsiblings) + rt = list_last_entry(&rt->rt6i_siblings, + struct rt6_info, + rt6i_siblings); } w->leaf = NULL; return 0; |