geneve: add transport ports in route lookup for geneve
[ Upstream commit 34beb21594519ce64a55a498c2fe7d567bc1ca20 ] This patch adds transport ports information for route lookup so that IPsec can select Geneve tunnel traffic to do encryption. This is needed for OVS/OVN IPsec with encrypted Geneve tunnels. This can be tested by configuring a host-host VPN using an IKE daemon and specifying port numbers. For example, for an Openswan-type configuration, the following parameters should be configured on both hosts and IPsec set up as-per normal: $ cat /etc/ipsec.conf conn in ... left=$IP1 right=$IP2 ... leftprotoport=udp/6081 rightprotoport=udp ... conn out ... left=$IP1 right=$IP2 ... leftprotoport=udp rightprotoport=udp/6081 ... The tunnel can then be setup using "ip" on both hosts (but changing the relevant IP addresses): $ ip link add tun type geneve id 1000 remote $IP2 $ ip addr add 192.168.0.1/24 dev tun $ ip link set tun up This can then be tested by pinging from $IP1: $ ping 192.168.0.2 Without this patch the traffic is unencrypted on the wire. Fixes: 2d07dc79fe04 ("geneve: add initial netdev driver for GENEVE tunnels") Signed-off-by: Qiuyu Xiao <qiuyu.xiao.qyx@gmail.com> Signed-off-by: Mark Gray <mark.d.gray@redhat.com> Reviewed-by: Greg Rose <gvrose8192@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
79cd5858ac
commit
745c24fd1d
@ -773,7 +773,8 @@ static struct rtable *geneve_get_v4_rt(struct sk_buff *skb,
|
||||
struct net_device *dev,
|
||||
struct geneve_sock *gs4,
|
||||
struct flowi4 *fl4,
|
||||
const struct ip_tunnel_info *info)
|
||||
const struct ip_tunnel_info *info,
|
||||
__be16 dport, __be16 sport)
|
||||
{
|
||||
bool use_cache = ip_tunnel_dst_cache_usable(skb, info);
|
||||
struct geneve_dev *geneve = netdev_priv(dev);
|
||||
@ -789,6 +790,8 @@ static struct rtable *geneve_get_v4_rt(struct sk_buff *skb,
|
||||
fl4->flowi4_proto = IPPROTO_UDP;
|
||||
fl4->daddr = info->key.u.ipv4.dst;
|
||||
fl4->saddr = info->key.u.ipv4.src;
|
||||
fl4->fl4_dport = dport;
|
||||
fl4->fl4_sport = sport;
|
||||
|
||||
tos = info->key.tos;
|
||||
if ((tos == 1) && !geneve->collect_md) {
|
||||
@ -823,7 +826,8 @@ static struct dst_entry *geneve_get_v6_dst(struct sk_buff *skb,
|
||||
struct net_device *dev,
|
||||
struct geneve_sock *gs6,
|
||||
struct flowi6 *fl6,
|
||||
const struct ip_tunnel_info *info)
|
||||
const struct ip_tunnel_info *info,
|
||||
__be16 dport, __be16 sport)
|
||||
{
|
||||
bool use_cache = ip_tunnel_dst_cache_usable(skb, info);
|
||||
struct geneve_dev *geneve = netdev_priv(dev);
|
||||
@ -839,6 +843,9 @@ static struct dst_entry *geneve_get_v6_dst(struct sk_buff *skb,
|
||||
fl6->flowi6_proto = IPPROTO_UDP;
|
||||
fl6->daddr = info->key.u.ipv6.dst;
|
||||
fl6->saddr = info->key.u.ipv6.src;
|
||||
fl6->fl6_dport = dport;
|
||||
fl6->fl6_sport = sport;
|
||||
|
||||
prio = info->key.tos;
|
||||
if ((prio == 1) && !geneve->collect_md) {
|
||||
prio = ip_tunnel_get_dsfield(ip_hdr(skb), skb);
|
||||
@ -885,14 +892,15 @@ static int geneve_xmit_skb(struct sk_buff *skb, struct net_device *dev,
|
||||
__be16 sport;
|
||||
int err;
|
||||
|
||||
rt = geneve_get_v4_rt(skb, dev, gs4, &fl4, info);
|
||||
sport = udp_flow_src_port(geneve->net, skb, 1, USHRT_MAX, true);
|
||||
rt = geneve_get_v4_rt(skb, dev, gs4, &fl4, info,
|
||||
geneve->info.key.tp_dst, sport);
|
||||
if (IS_ERR(rt))
|
||||
return PTR_ERR(rt);
|
||||
|
||||
skb_tunnel_check_pmtu(skb, &rt->dst,
|
||||
GENEVE_IPV4_HLEN + info->options_len);
|
||||
|
||||
sport = udp_flow_src_port(geneve->net, skb, 1, USHRT_MAX, true);
|
||||
if (geneve->collect_md) {
|
||||
tos = ip_tunnel_ecn_encap(key->tos, ip_hdr(skb), skb);
|
||||
ttl = key->ttl;
|
||||
@ -947,13 +955,14 @@ static int geneve6_xmit_skb(struct sk_buff *skb, struct net_device *dev,
|
||||
__be16 sport;
|
||||
int err;
|
||||
|
||||
dst = geneve_get_v6_dst(skb, dev, gs6, &fl6, info);
|
||||
sport = udp_flow_src_port(geneve->net, skb, 1, USHRT_MAX, true);
|
||||
dst = geneve_get_v6_dst(skb, dev, gs6, &fl6, info,
|
||||
geneve->info.key.tp_dst, sport);
|
||||
if (IS_ERR(dst))
|
||||
return PTR_ERR(dst);
|
||||
|
||||
skb_tunnel_check_pmtu(skb, dst, GENEVE_IPV6_HLEN + info->options_len);
|
||||
|
||||
sport = udp_flow_src_port(geneve->net, skb, 1, USHRT_MAX, true);
|
||||
if (geneve->collect_md) {
|
||||
prio = ip_tunnel_ecn_encap(key->tos, ip_hdr(skb), skb);
|
||||
ttl = key->ttl;
|
||||
@ -1034,13 +1043,18 @@ static int geneve_fill_metadata_dst(struct net_device *dev, struct sk_buff *skb)
|
||||
{
|
||||
struct ip_tunnel_info *info = skb_tunnel_info(skb);
|
||||
struct geneve_dev *geneve = netdev_priv(dev);
|
||||
__be16 sport;
|
||||
|
||||
if (ip_tunnel_info_af(info) == AF_INET) {
|
||||
struct rtable *rt;
|
||||
struct flowi4 fl4;
|
||||
struct geneve_sock *gs4 = rcu_dereference(geneve->sock4);
|
||||
|
||||
rt = geneve_get_v4_rt(skb, dev, gs4, &fl4, info);
|
||||
struct geneve_sock *gs4 = rcu_dereference(geneve->sock4);
|
||||
sport = udp_flow_src_port(geneve->net, skb,
|
||||
1, USHRT_MAX, true);
|
||||
|
||||
rt = geneve_get_v4_rt(skb, dev, gs4, &fl4, info,
|
||||
geneve->info.key.tp_dst, sport);
|
||||
if (IS_ERR(rt))
|
||||
return PTR_ERR(rt);
|
||||
|
||||
@ -1050,9 +1064,13 @@ static int geneve_fill_metadata_dst(struct net_device *dev, struct sk_buff *skb)
|
||||
} else if (ip_tunnel_info_af(info) == AF_INET6) {
|
||||
struct dst_entry *dst;
|
||||
struct flowi6 fl6;
|
||||
struct geneve_sock *gs6 = rcu_dereference(geneve->sock6);
|
||||
|
||||
dst = geneve_get_v6_dst(skb, dev, gs6, &fl6, info);
|
||||
struct geneve_sock *gs6 = rcu_dereference(geneve->sock6);
|
||||
sport = udp_flow_src_port(geneve->net, skb,
|
||||
1, USHRT_MAX, true);
|
||||
|
||||
dst = geneve_get_v6_dst(skb, dev, gs6, &fl6, info,
|
||||
geneve->info.key.tp_dst, sport);
|
||||
if (IS_ERR(dst))
|
||||
return PTR_ERR(dst);
|
||||
|
||||
@ -1063,8 +1081,7 @@ static int geneve_fill_metadata_dst(struct net_device *dev, struct sk_buff *skb)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
info->key.tp_src = udp_flow_src_port(geneve->net, skb,
|
||||
1, USHRT_MAX, true);
|
||||
info->key.tp_src = sport;
|
||||
info->key.tp_dst = geneve->info.key.tp_dst;
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user