From ef113733c288eccadc105579b8e8c1bfdcc09ad1 Mon Sep 17 00:00:00 2001 From: Beniamino Galvani Date: Wed, 25 Oct 2023 11:44:41 +0200 Subject: [PATCH] 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: Beniamino Galvani Reviewed-by: Przemek Kitszel Reviewed-by: David Ahern Link: https://lore.kernel.org/r/20231025094441.417464-1-b.galvani@gmail.com Signed-off-by: Paolo Abeni --- drivers/net/bareudp.c | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/drivers/net/bareudp.c b/drivers/net/bareudp.c index 9c11a0d0273b..31377bb1cc97 100644 --- a/drivers/net/bareudp.c +++ b/drivers/net/bareudp.c @@ -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; }