Skip to content

Commit 613d09b

Browse files
David Aherndavem330
authored andcommitted
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: Shrijeet Mukherjee <shm@cumulusnetworks.com> Signed-off-by: David Ahern <dsa@cumulusnetworks.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent cd2fbe1 commit 613d09b

File tree

5 files changed

+18
-2
lines changed

5 files changed

+18
-2
lines changed

include/net/flow.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ struct flowi_common {
3333
__u8 flowic_flags;
3434
#define FLOWI_FLAG_ANYSRC 0x01
3535
#define FLOWI_FLAG_KNOWN_NH 0x02
36+
#define FLOWI_FLAG_VRFSRC 0x04
3637
__u32 flowic_secid;
3738
struct flowi_tunnel flowic_tun_key;
3839
};

include/net/route.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,9 @@ static inline void ip_route_connect_init(struct flowi4 *fl4, __be32 dst, __be32
251251
if (inet_sk(sk)->transparent)
252252
flow_flags |= FLOWI_FLAG_ANYSRC;
253253

254+
if (netif_index_is_vrf(sock_net(sk), oif))
255+
flow_flags |= FLOWI_FLAG_VRFSRC;
256+
254257
flowi4_init_output(fl4, oif, sk->sk_mark, tos, RT_SCOPE_UNIVERSE,
255258
protocol, flow_flags, dst, src, dport, sport);
256259
}

net/ipv4/fib_trie.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1423,8 +1423,11 @@ int fib_table_lookup(struct fib_table *tb, const struct flowi4 *flp,
14231423
nh->nh_flags & RTNH_F_LINKDOWN &&
14241424
!(fib_flags & FIB_LOOKUP_IGNORE_LINKSTATE))
14251425
continue;
1426-
if (flp->flowi4_oif && flp->flowi4_oif != nh->nh_oif)
1427-
continue;
1426+
if (!(flp->flowi4_flags & FLOWI_FLAG_VRFSRC)) {
1427+
if (flp->flowi4_oif &&
1428+
flp->flowi4_oif != nh->nh_oif)
1429+
continue;
1430+
}
14281431

14291432
if (!(fib_flags & FIB_LOOKUP_NOREF))
14301433
atomic_inc(&fi->fib_clntref);

net/ipv4/icmp.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@
9696
#include <net/xfrm.h>
9797
#include <net/inet_common.h>
9898
#include <net/ip_fib.h>
99+
#include <net/vrf.h>
99100

100101
/*
101102
* Build xmit assembly blocks
@@ -425,6 +426,7 @@ static void icmp_reply(struct icmp_bxm *icmp_param, struct sk_buff *skb)
425426
fl4.flowi4_mark = mark;
426427
fl4.flowi4_tos = RT_TOS(ip_hdr(skb)->tos);
427428
fl4.flowi4_proto = IPPROTO_ICMP;
429+
fl4.flowi4_oif = vrf_master_ifindex_rcu(skb->dev) ? : skb->dev->ifindex;
428430
security_skb_classify_flow(skb, flowi4_to_flowi(&fl4));
429431
rt = ip_route_output_key(net, &fl4);
430432
if (IS_ERR(rt))
@@ -458,6 +460,8 @@ static struct rtable *icmp_route_lookup(struct net *net,
458460
fl4->flowi4_proto = IPPROTO_ICMP;
459461
fl4->fl4_icmp_type = type;
460462
fl4->fl4_icmp_code = code;
463+
fl4->flowi4_oif = vrf_master_ifindex_rcu(skb_in->dev) ? : skb_in->dev->ifindex;
464+
461465
security_skb_classify_flow(skb_in, flowi4_to_flowi(fl4));
462466
rt = __ip_route_output_key(net, fl4);
463467
if (IS_ERR(rt))

net/ipv4/route.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2131,6 +2131,11 @@ struct rtable *__ip_route_output_key(struct net *net, struct flowi4 *fl4)
21312131
fl4->saddr = inet_select_addr(dev_out, 0,
21322132
RT_SCOPE_HOST);
21332133
}
2134+
if (netif_is_vrf(dev_out) &&
2135+
!(fl4->flowi4_flags & FLOWI_FLAG_VRFSRC)) {
2136+
rth = vrf_dev_get_rth(dev_out);
2137+
goto out;
2138+
}
21342139
}
21352140

21362141
if (!fl4->daddr) {

0 commit comments

Comments
 (0)