Commit ef113733 authored by Beniamino Galvani's avatar Beniamino Galvani Committed by Paolo Abeni
Browse files

bareudp: use ports to lookup route



The source and destination ports should be taken into account when
determining the route destination; they can affect the result, for
example in case there are routing rules defined.

Signed-off-by: default avatarBeniamino Galvani <b.galvani@gmail.com>
Reviewed-by: default avatarPrzemek Kitszel <przemyslaw.kitszel@intel.com>
Reviewed-by: default avatarDavid Ahern <dsahern@kernel.org>
Link: https://lore.kernel.org/r/20231025094441.417464-1-b.galvani@gmail.com


Signed-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
parent 39673361
Loading
Loading
Loading
Loading
+16 −13
Original line number Diff line number Diff line
@@ -306,8 +306,11 @@ static int bareudp_xmit_skb(struct sk_buff *skb, struct net_device *dev,
	if (!sock)
		return -ESHUTDOWN;

	sport = udp_flow_src_port(bareudp->net, skb,
				  bareudp->sport_min, USHRT_MAX,
				  true);
	rt = udp_tunnel_dst_lookup(skb, dev, bareudp->net, 0, &saddr, &info->key,
				   0, 0, key->tos,
				   sport, bareudp->port, key->tos,
				   use_cache ?
				   (struct dst_cache *)&info->dst_cache : NULL);

@@ -317,9 +320,6 @@ static int bareudp_xmit_skb(struct sk_buff *skb, struct net_device *dev,
	skb_tunnel_check_pmtu(skb, &rt->dst,
			      BAREUDP_IPV4_HLEN + info->options_len, false);

	sport = udp_flow_src_port(bareudp->net, skb,
				  bareudp->sport_min, USHRT_MAX,
				  true);
	tos = ip_tunnel_ecn_encap(key->tos, ip_hdr(skb), skb);
	ttl = key->ttl;
	df = key->tun_flags & TUNNEL_DONT_FRAGMENT ? htons(IP_DF) : 0;
@@ -371,8 +371,11 @@ static int bareudp6_xmit_skb(struct sk_buff *skb, struct net_device *dev,
	if (!sock)
		return -ESHUTDOWN;

	sport = udp_flow_src_port(bareudp->net, skb,
				  bareudp->sport_min, USHRT_MAX,
				  true);
	dst = udp_tunnel6_dst_lookup(skb, dev, bareudp->net, sock, 0, &saddr,
				     key, 0, 0, key->tos,
				     key, sport, bareudp->port, key->tos,
				     use_cache ?
				     (struct dst_cache *) &info->dst_cache : NULL);
	if (IS_ERR(dst))
@@ -381,9 +384,6 @@ static int bareudp6_xmit_skb(struct sk_buff *skb, struct net_device *dev,
	skb_tunnel_check_pmtu(skb, dst, BAREUDP_IPV6_HLEN + info->options_len,
			      false);

	sport = udp_flow_src_port(bareudp->net, skb,
				  bareudp->sport_min, USHRT_MAX,
				  true);
	prio = ip_tunnel_ecn_encap(key->tos, ip_hdr(skb), skb);
	ttl = key->ttl;

@@ -480,15 +480,20 @@ static int bareudp_fill_metadata_dst(struct net_device *dev,
	struct ip_tunnel_info *info = skb_tunnel_info(skb);
	struct bareudp_dev *bareudp = netdev_priv(dev);
	bool use_cache;
	__be16 sport;

	use_cache = ip_tunnel_dst_cache_usable(skb, info);
	sport = udp_flow_src_port(bareudp->net, skb,
				  bareudp->sport_min, USHRT_MAX,
				  true);

	if (!ipv6_mod_enabled() || ip_tunnel_info_af(info) == AF_INET) {
		struct rtable *rt;
		__be32 saddr;

		rt = udp_tunnel_dst_lookup(skb, dev, bareudp->net, 0, &saddr,
					   &info->key, 0, 0, info->key.tos,
					   &info->key, sport, bareudp->port,
					   info->key.tos,
					   use_cache ? &info->dst_cache : NULL);
		if (IS_ERR(rt))
			return PTR_ERR(rt);
@@ -502,7 +507,7 @@ static int bareudp_fill_metadata_dst(struct net_device *dev,

		dst = udp_tunnel6_dst_lookup(skb, dev, bareudp->net, sock,
					     0, &saddr, &info->key,
					     0, 0, info->key.tos,
					     sport, bareudp->port, info->key.tos,
					     use_cache ? &info->dst_cache : NULL);
		if (IS_ERR(dst))
			return PTR_ERR(dst);
@@ -513,9 +518,7 @@ static int bareudp_fill_metadata_dst(struct net_device *dev,
		return -EINVAL;
	}

	info->key.tp_src = udp_flow_src_port(bareudp->net, skb,
					     bareudp->sport_min,
			USHRT_MAX, true);
	info->key.tp_src = sport;
	info->key.tp_dst = bareudp->port;
	return 0;
}