diff options
author | Beniamino Galvani <b.galvani@gmail.com> | 2023-10-25 12:44:41 +0300 |
---|---|---|
committer | Paolo Abeni <pabeni@redhat.com> | 2023-10-26 16:21:09 +0300 |
commit | ef113733c288eccadc105579b8e8c1bfdcc09ad1 (patch) | |
tree | d7215c903bf009dea10b47b01a77d07363018a2d | |
parent | 39673361266bcb76a9782ee9e27dad1be5dcadcc (diff) | |
download | linux-ef113733c288eccadc105579b8e8c1bfdcc09ad1.tar.xz |
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 <b.galvani@gmail.com>
Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
Reviewed-by: David Ahern <dsahern@kernel.org>
Link: https://lore.kernel.org/r/20231025094441.417464-1-b.galvani@gmail.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
-rw-r--r-- | drivers/net/bareudp.c | 29 |
1 files 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; } |