Currently, output route lookups behave differently between IPv4 and IPv6 when performed via the bpf_fib_lookup() helper with the BPF_FIB_LOOKUP_OUTPUT flag. IPv4 honors the oif and resolves the most specific route whose nexthop device matches the oif. If no such route exists, an error is returned. On the other hand, IPv6 simply resolves the most specific route, even if its nexthop device does not match the specified oif. Fix this by setting the RT6_LOOKUP_F_IFACE flag when performing an output route lookup, so that a device mismatch will be considered a fatal error. Reviewed-by: Petr Machata Signed-off-by: Ido Schimmel --- net/core/filter.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/core/filter.c b/net/core/filter.c index 0d5d5a17acb2..e92552b139b1 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -6255,6 +6255,7 @@ static int bpf_ipv6_fib_lookup(struct net *net, struct bpf_fib_lookup *params, if (flags & BPF_FIB_LOOKUP_OUTPUT) { fl6.flowi6_iif = 1; oif = fl6.flowi6_oif = params->ifindex; + strict = RT6_LOOKUP_F_IFACE; } else { oif = fl6.flowi6_iif = params->ifindex; fl6.flowi6_oif = 0; -- 2.53.0