mirror of https://gitee.com/openkylin/linux.git
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>
This commit is contained in:
parent
cd2fbe1b6b
commit
613d09b30f
|
@ -33,6 +33,7 @@ struct flowi_common {
|
||||||
__u8 flowic_flags;
|
__u8 flowic_flags;
|
||||||
#define FLOWI_FLAG_ANYSRC 0x01
|
#define FLOWI_FLAG_ANYSRC 0x01
|
||||||
#define FLOWI_FLAG_KNOWN_NH 0x02
|
#define FLOWI_FLAG_KNOWN_NH 0x02
|
||||||
|
#define FLOWI_FLAG_VRFSRC 0x04
|
||||||
__u32 flowic_secid;
|
__u32 flowic_secid;
|
||||||
struct flowi_tunnel flowic_tun_key;
|
struct flowi_tunnel flowic_tun_key;
|
||||||
};
|
};
|
||||||
|
|
|
@ -251,6 +251,9 @@ static inline void ip_route_connect_init(struct flowi4 *fl4, __be32 dst, __be32
|
||||||
if (inet_sk(sk)->transparent)
|
if (inet_sk(sk)->transparent)
|
||||||
flow_flags |= FLOWI_FLAG_ANYSRC;
|
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,
|
flowi4_init_output(fl4, oif, sk->sk_mark, tos, RT_SCOPE_UNIVERSE,
|
||||||
protocol, flow_flags, dst, src, dport, sport);
|
protocol, flow_flags, dst, src, dport, sport);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1423,8 +1423,11 @@ int fib_table_lookup(struct fib_table *tb, const struct flowi4 *flp,
|
||||||
nh->nh_flags & RTNH_F_LINKDOWN &&
|
nh->nh_flags & RTNH_F_LINKDOWN &&
|
||||||
!(fib_flags & FIB_LOOKUP_IGNORE_LINKSTATE))
|
!(fib_flags & FIB_LOOKUP_IGNORE_LINKSTATE))
|
||||||
continue;
|
continue;
|
||||||
if (flp->flowi4_oif && flp->flowi4_oif != nh->nh_oif)
|
if (!(flp->flowi4_flags & FLOWI_FLAG_VRFSRC)) {
|
||||||
continue;
|
if (flp->flowi4_oif &&
|
||||||
|
flp->flowi4_oif != nh->nh_oif)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (!(fib_flags & FIB_LOOKUP_NOREF))
|
if (!(fib_flags & FIB_LOOKUP_NOREF))
|
||||||
atomic_inc(&fi->fib_clntref);
|
atomic_inc(&fi->fib_clntref);
|
||||||
|
|
|
@ -96,6 +96,7 @@
|
||||||
#include <net/xfrm.h>
|
#include <net/xfrm.h>
|
||||||
#include <net/inet_common.h>
|
#include <net/inet_common.h>
|
||||||
#include <net/ip_fib.h>
|
#include <net/ip_fib.h>
|
||||||
|
#include <net/vrf.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Build xmit assembly blocks
|
* 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_mark = mark;
|
||||||
fl4.flowi4_tos = RT_TOS(ip_hdr(skb)->tos);
|
fl4.flowi4_tos = RT_TOS(ip_hdr(skb)->tos);
|
||||||
fl4.flowi4_proto = IPPROTO_ICMP;
|
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));
|
security_skb_classify_flow(skb, flowi4_to_flowi(&fl4));
|
||||||
rt = ip_route_output_key(net, &fl4);
|
rt = ip_route_output_key(net, &fl4);
|
||||||
if (IS_ERR(rt))
|
if (IS_ERR(rt))
|
||||||
|
@ -458,6 +460,8 @@ static struct rtable *icmp_route_lookup(struct net *net,
|
||||||
fl4->flowi4_proto = IPPROTO_ICMP;
|
fl4->flowi4_proto = IPPROTO_ICMP;
|
||||||
fl4->fl4_icmp_type = type;
|
fl4->fl4_icmp_type = type;
|
||||||
fl4->fl4_icmp_code = code;
|
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));
|
security_skb_classify_flow(skb_in, flowi4_to_flowi(fl4));
|
||||||
rt = __ip_route_output_key(net, fl4);
|
rt = __ip_route_output_key(net, fl4);
|
||||||
if (IS_ERR(rt))
|
if (IS_ERR(rt))
|
||||||
|
|
|
@ -2131,6 +2131,11 @@ struct rtable *__ip_route_output_key(struct net *net, struct flowi4 *fl4)
|
||||||
fl4->saddr = inet_select_addr(dev_out, 0,
|
fl4->saddr = inet_select_addr(dev_out, 0,
|
||||||
RT_SCOPE_HOST);
|
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) {
|
if (!fl4->daddr) {
|
||||||
|
|
Loading…
Reference in New Issue