Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

net: ipv6: Add RT6_LOOKUP_F_IFACE flag if oif is set

Wolfgang reported that IPv6 stack is ignoring oif in output route lookups:

With ipv6, ip -6 route get always returns the specific route.

$ ip -6 r
2001:db8:e2::1 dev enp2s0 proto kernel metric 256
2001:db8:e2::/64 dev enp2s0 metric 1024
2001:db8:e3::1 dev enp3s0 proto kernel metric 256
2001:db8:e3::/64 dev enp3s0 metric 1024
fe80::/64 dev enp3s0 proto kernel metric 256
default via 2001:db8:e3::255 dev enp3s0 metric 1024

$ ip -6 r get 2001:db8:e2::100
2001:db8:e2::100 from :: dev enp2s0 src 2001:db8:e3::1 metric 0
cache

$ ip -6 r get 2001:db8:e2::100 oif enp3s0
2001:db8:e2::100 from :: dev enp2s0 src 2001:db8:e3::1 metric 0
cache

The stack does consider the oif but a mismatch in rt6_device_match is not
considered fatal because RT6_LOOKUP_F_IFACE is not set in the flags.

Cc: Wolfgang Nothdurft <netdev@linux-dude.de>
Signed-off-by: David Ahern <dsa@cumulusnetworks.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

David Ahern and committed by
David S. Miller
741a11d9 75c261b5

+2 -1
+2 -1
net/ipv6/route.c
··· 1193 1193 1194 1194 fl6->flowi6_iif = LOOPBACK_IFINDEX; 1195 1195 1196 - if ((sk && sk->sk_bound_dev_if) || rt6_need_strict(&fl6->daddr)) 1196 + if ((sk && sk->sk_bound_dev_if) || rt6_need_strict(&fl6->daddr) || 1197 + fl6->flowi6_oif) 1197 1198 flags |= RT6_LOOKUP_F_IFACE; 1198 1199 1199 1200 if (!ipv6_addr_any(&fl6->saddr))