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

Commit 613d09b3 authored by David Ahern's avatar David Ahern Committed by David S. Miller
Browse files

net: Use VRF device index for lookups on TX



As with ingress use the index of VRF master device for route lookups on
egress. However, the oif should only be used to direct the lookups to a
specific table. Routes in the table are not based on the VRF device but
rather interfaces that are part of the VRF so do not consider the oif for
lookups within the table. The FLOWI_FLAG_VRFSRC is used to control this
latter part.

Signed-off-by: default avatarShrijeet Mukherjee <shm@cumulusnetworks.com>
Signed-off-by: default avatarDavid Ahern <dsa@cumulusnetworks.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent cd2fbe1b
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@ struct flowi_common {
	__u8	flowic_flags;
#define FLOWI_FLAG_ANYSRC		0x01
#define FLOWI_FLAG_KNOWN_NH		0x02
#define FLOWI_FLAG_VRFSRC		0x04
	__u32	flowic_secid;
	struct flowi_tunnel flowic_tun_key;
};
+3 −0
Original line number Diff line number Diff line
@@ -251,6 +251,9 @@ static inline void ip_route_connect_init(struct flowi4 *fl4, __be32 dst, __be32
	if (inet_sk(sk)->transparent)
		flow_flags |= FLOWI_FLAG_ANYSRC;

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

	flowi4_init_output(fl4, oif, sk->sk_mark, tos, RT_SCOPE_UNIVERSE,
			   protocol, flow_flags, dst, src, dport, sport);
}
+5 −2
Original line number Diff line number Diff line
@@ -1423,8 +1423,11 @@ 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_oif && flp->flowi4_oif != nh->nh_oif)
			if (!(flp->flowi4_flags & FLOWI_FLAG_VRFSRC)) {
				if (flp->flowi4_oif &&
				    flp->flowi4_oif != nh->nh_oif)
					continue;
			}

			if (!(fib_flags & FIB_LOOKUP_NOREF))
				atomic_inc(&fi->fib_clntref);
+4 −0
Original line number Diff line number Diff line
@@ -96,6 +96,7 @@
#include <net/xfrm.h>
#include <net/inet_common.h>
#include <net/ip_fib.h>
#include <net/vrf.h>

/*
 *	Build xmit assembly blocks
@@ -425,6 +426,7 @@ static void icmp_reply(struct icmp_bxm *icmp_param, struct sk_buff *skb)
	fl4.flowi4_mark = mark;
	fl4.flowi4_tos = RT_TOS(ip_hdr(skb)->tos);
	fl4.flowi4_proto = IPPROTO_ICMP;
	fl4.flowi4_oif = vrf_master_ifindex_rcu(skb->dev) ? : skb->dev->ifindex;
	security_skb_classify_flow(skb, flowi4_to_flowi(&fl4));
	rt = ip_route_output_key(net, &fl4);
	if (IS_ERR(rt))
@@ -458,6 +460,8 @@ static struct rtable *icmp_route_lookup(struct net *net,
	fl4->flowi4_proto = IPPROTO_ICMP;
	fl4->fl4_icmp_type = type;
	fl4->fl4_icmp_code = code;
	fl4->flowi4_oif = vrf_master_ifindex_rcu(skb_in->dev) ? : skb_in->dev->ifindex;

	security_skb_classify_flow(skb_in, flowi4_to_flowi(fl4));
	rt = __ip_route_output_key(net, fl4);
	if (IS_ERR(rt))
+5 −0
Original line number Diff line number Diff line
@@ -2131,6 +2131,11 @@ struct rtable *__ip_route_output_key(struct net *net, struct flowi4 *fl4)
				fl4->saddr = inet_select_addr(dev_out, 0,
							      RT_SCOPE_HOST);
		}
		if (netif_is_vrf(dev_out) &&
		    !(fl4->flowi4_flags & FLOWI_FLAG_VRFSRC)) {
			rth = vrf_dev_get_rth(dev_out);
			goto out;
		}
	}

	if (!fl4->daddr) {