Message ID | 20240705004440.186345-1-stephen@networkplumber.org (mailing list archive) |
---|---|
State | Accepted |
Commit | 0ea0699ea01df81750becf742083933a23a95d94 |
Headers | show |
Series | [iproute] route: filter by interface on multipath routes | expand |
Context | Check | Description |
---|---|---|
netdev/tree_selection | success | Not a local patch |
Hello: This patch was applied to iproute2/iproute2.git (main) by Stephen Hemminger <stephen@networkplumber.org>: On Thu, 4 Jul 2024 17:44:19 -0700 you wrote: > The ip route command would silently hide multipath routes when filter > by interface. The problem was it was not looking for interface when > filter multipath routes. > > Example: > ip link add name dummy1 up type dummy > ip link add name dummy2 up type dummy > ip address add 192.0.2.1/28 dev dummy1 > ip address add 192.0.2.17/28 dev dummy2 > ip route add 198.51.100.0/24 \ > nexthop via 192.0.2.2 dev dummy1 \ > nexthop via 192.0.2.18 dev dummy2 > > [...] Here is the summary with links: - [iproute] route: filter by interface on multipath routes https://git.kernel.org/pub/scm/network/iproute2/iproute2.git/commit/?id=0ea0699ea01d You are awesome, thank you!
diff --git a/ip/iproute.c b/ip/iproute.c index b5304611..44666240 100644 --- a/ip/iproute.c +++ b/ip/iproute.c @@ -154,6 +154,24 @@ static int flush_update(void) return 0; } +static bool filter_multipath(const struct rtattr *rta) +{ + const struct rtnexthop *nh = RTA_DATA(rta); + int len = RTA_PAYLOAD(rta); + + while (len >= sizeof(*nh)) { + if (nh->rtnh_len > len) + break; + + if (!((nh->rtnh_ifindex ^ filter.oif) & filter.oifmask)) + return true; + + len -= NLMSG_ALIGN(nh->rtnh_len); + nh = RTNH_NEXT(nh); + } + return false; +} + static int filter_nlmsg(struct nlmsghdr *n, struct rtattr **tb, int host_len) { struct rtmsg *r = NLMSG_DATA(n); @@ -310,12 +328,15 @@ static int filter_nlmsg(struct nlmsghdr *n, struct rtattr **tb, int host_len) return 0; } if (filter.oifmask) { - int oif = 0; + if (tb[RTA_OIF]) { + int oif = rta_getattr_u32(tb[RTA_OIF]); - if (tb[RTA_OIF]) - oif = rta_getattr_u32(tb[RTA_OIF]); - if ((oif^filter.oif)&filter.oifmask) - return 0; + if ((oif ^ filter.oif) & filter.oifmask) + return 0; + } else if (tb[RTA_MULTIPATH]) { + if (!filter_multipath(tb[RTA_MULTIPATH])) + return 0; + } } if (filter.markmask) { int mark = 0;
The ip route command would silently hide multipath routes when filter by interface. The problem was it was not looking for interface when filter multipath routes. Example: ip link add name dummy1 up type dummy ip link add name dummy2 up type dummy ip address add 192.0.2.1/28 dev dummy1 ip address add 192.0.2.17/28 dev dummy2 ip route add 198.51.100.0/24 \ nexthop via 192.0.2.2 dev dummy1 \ nexthop via 192.0.2.18 dev dummy2 Before: ip route show dev dummy1 192.0.2.0/28 proto kernel scope link src 192.0.2.1 After: ip route show dev dummy1 192.0.2.0/28 proto kernel scope link src 192.0.2.1 198.51.100.0/24 nexthop via 192.0.2.2 dev dummy1 weight 1 nexthop via 192.0.2.18 dev dummy2 weight 1 Reported-by: "Muggeridge, Matt" <matt.muggeridge2@hpe.com> Signed-off-by: Stephen Hemminger <stephen@networkplumber.org> --- ip/iproute.c | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-)