Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 58189ca7 authored by David Ahern's avatar David Ahern Committed by David S. Miller
Browse files

net: Fix vti use case with oif in dst lookups



Steffen reported that the recent change to add oif to dst lookups breaks
the VTI use case. The problem is that with the oif set in the flow struct
the comparison to the nh_oif is triggered. Fix by splitting the
FLOWI_FLAG_VRFSRC into 2 flags -- one that triggers the vrf device cache
bypass (FLOWI_FLAG_VRFSRC) and another telling the lookup to not compare
nh oif (FLOWI_FLAG_SKIP_NH_OIF).

Fixes: 42a7b32b ("xfrm: Add oif to dst lookups")

Signed-off-by: default avatarDavid Ahern <dsa@cumulusnetworks.com>
Acked-by: default avatarSteffen Klassert <steffen.klassert@secunet.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent d828755e
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -193,7 +193,8 @@ static netdev_tx_t vrf_process_v4_outbound(struct sk_buff *skb,
		.flowi4_oif = vrf_dev->ifindex,
		.flowi4_iif = LOOPBACK_IFINDEX,
		.flowi4_tos = RT_TOS(ip4h->tos),
		.flowi4_flags = FLOWI_FLAG_ANYSRC | FLOWI_FLAG_VRFSRC,
		.flowi4_flags = FLOWI_FLAG_ANYSRC | FLOWI_FLAG_VRFSRC |
				FLOWI_FLAG_SKIP_NH_OIF,
		.daddr = ip4h->daddr,
	};

+1 −0
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@ struct flowi_common {
#define FLOWI_FLAG_ANYSRC		0x01
#define FLOWI_FLAG_KNOWN_NH		0x02
#define FLOWI_FLAG_VRFSRC		0x04
#define FLOWI_FLAG_SKIP_NH_OIF		0x08
	__u32	flowic_secid;
	struct flowi_tunnel flowic_tun_key;
};
+1 −1
Original line number Diff line number Diff line
@@ -255,7 +255,7 @@ static inline void ip_route_connect_init(struct flowi4 *fl4, __be32 dst, __be32
		flow_flags |= FLOWI_FLAG_ANYSRC;

	if (netif_index_is_vrf(sock_net(sk), oif))
		flow_flags |= FLOWI_FLAG_VRFSRC;
		flow_flags |= FLOWI_FLAG_VRFSRC | FLOWI_FLAG_SKIP_NH_OIF;

	flowi4_init_output(fl4, oif, sk->sk_mark, tos, RT_SCOPE_UNIVERSE,
			   protocol, flow_flags, dst, src, dport, sport);
+1 −1
Original line number Diff line number Diff line
@@ -1426,7 +1426,7 @@ int fib_table_lookup(struct fib_table *tb, const struct flowi4 *flp,
			    nh->nh_flags & RTNH_F_LINKDOWN &&
			    !(fib_flags & FIB_LOOKUP_IGNORE_LINKSTATE))
				continue;
			if (!(flp->flowi4_flags & FLOWI_FLAG_VRFSRC)) {
			if (!(flp->flowi4_flags & FLOWI_FLAG_SKIP_NH_OIF)) {
				if (flp->flowi4_oif &&
				    flp->flowi4_oif != nh->nh_oif)
					continue;
+2 −1
Original line number Diff line number Diff line
@@ -1024,7 +1024,8 @@ int udp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
		if (netif_index_is_vrf(net, ipc.oif)) {
			flowi4_init_output(fl4, ipc.oif, sk->sk_mark, tos,
					   RT_SCOPE_UNIVERSE, sk->sk_protocol,
					   (flow_flags | FLOWI_FLAG_VRFSRC),
					   (flow_flags | FLOWI_FLAG_VRFSRC |
					    FLOWI_FLAG_SKIP_NH_OIF),
					   faddr, saddr, dport,
					   inet->inet_sport);

Loading