Skip to content

Commit

Permalink
net: Use VRF device index for lookups on TX
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
David Ahern authored and davem330 committed Aug 14, 2015
1 parent cd2fbe1 commit 613d09b
Show file tree
Hide file tree
Showing 5 changed files with 18 additions and 2 deletions.
1 change: 1 addition & 0 deletions include/net/flow.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
};
Expand Down
3 changes: 3 additions & 0 deletions include/net/route.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down
7 changes: 5 additions & 2 deletions net/ipv4/fib_trie.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
continue;
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);
Expand Down
4 changes: 4 additions & 0 deletions net/ipv4/icmp.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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))
Expand Down Expand Up @@ -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))
Expand Down
5 changes: 5 additions & 0 deletions net/ipv4/route.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down

0 comments on commit 613d09b

Please sign in to comment.