ACK: [PATCH] geneve: add transport ports in route lookup for geneve

Colin Ian King colin.king at canonical.com
Tue Mar 9 11:18:18 UTC 2021


On 08/03/2021 19:50, Tim Gardner wrote:
> From: Mark Gray <mark.d.gray at redhat.com>
> 
> CVE-2020-25645
> 
> [ 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 at gmail.com>
> Signed-off-by: Mark Gray <mark.d.gray at redhat.com>
> Reviewed-by: Greg Rose <gvrose8192 at gmail.com>
> Signed-off-by: David S. Miller <davem at davemloft.net>
> Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
> (cherry picked from commit e76c0f41d7b1951ef4161e079c832c2e904fd29f linux-5.8.y)
> Signed-off-by: Tim Gardner <tim.gardner at canonical.com>
> ---
> 
> v1 - clean cherrypick from a stable release. The upstream commit 34beb21594519ce64a55a498c2fe7d567bc1ca20
> requires backporting.
> 
>  drivers/net/geneve.c | 37 +++++++++++++++++++++++++++----------
>  1 file changed, 27 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/net/geneve.c b/drivers/net/geneve.c
> index 6b461be1820b..474d01ee1d4a 100644
> --- a/drivers/net/geneve.c
> +++ b/drivers/net/geneve.c
> @@ -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;
> @@ -1033,13 +1042,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);
> +		sport = udp_flow_src_port(geneve->net, skb,
> +					  1, USHRT_MAX, true);
>  
> -		rt = geneve_get_v4_rt(skb, dev, gs4, &fl4, info);
> +		rt = geneve_get_v4_rt(skb, dev, gs4, &fl4, info,
> +				      geneve->info.key.tp_dst, sport);
>  		if (IS_ERR(rt))
>  			return PTR_ERR(rt);
>  
> @@ -1049,9 +1063,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);
> +		sport = udp_flow_src_port(geneve->net, skb,
> +					  1, USHRT_MAX, true);
>  
> -		dst = geneve_get_v6_dst(skb, dev, gs6, &fl6, info);
> +		dst = geneve_get_v6_dst(skb, dev, gs6, &fl6, info,
> +					geneve->info.key.tp_dst, sport);
>  		if (IS_ERR(dst))
>  			return PTR_ERR(dst);
>  
> @@ -1062,8 +1080,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;
>  }
> 

Acked-by: Colin Ian King <colin.king at canonical.com>



More information about the kernel-team mailing list