]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/commitdiff
geneve: fix TOS inheriting for ipv4
authorMatthias May <matthias.may@westermo.com>
Fri, 5 Aug 2022 19:00:06 +0000 (21:00 +0200)
committerStefan Bader <stefan.bader@canonical.com>
Mon, 17 Oct 2022 09:57:21 +0000 (11:57 +0200)
BugLink: https://bugs.launchpad.net/bugs/1990564
commit b4ab94d6adaa5cf842b68bd28f4b50bc774496bd upstream.

The current code retrieves the TOS field after the lookup
on the ipv4 routing table. The routing process currently
only allows routing based on the original 3 TOS bits, and
not on the full 6 DSCP bits.
As a result the retrieved TOS is cut to the 3 bits.
However for inheriting purposes the full 6 bits should be used.

Extract the full 6 bits before the route lookup and use
that instead of the cut off 3 TOS bits.

Fixes: e305ac6cf5a1 ("geneve: Add support to collect tunnel metadata.")
Signed-off-by: Matthias May <matthias.may@westermo.com>
Acked-by: Guillaume Nault <gnault@redhat.com>
Link: https://lore.kernel.org/r/20220805190006.8078-1-matthias.may@westermo.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Kamal Mostafa <kamal@canonical.com>
Signed-off-by: Stefan Bader <stefan.bader@canonical.com>
drivers/net/geneve.c

index cb326a0167097fa3de860ec95757e1f44372be8b..605332f36d9dfa5bad0789f74ea802919307fdb4 100644 (file)
@@ -774,7 +774,8 @@ static struct rtable *geneve_get_v4_rt(struct sk_buff *skb,
                                       struct geneve_sock *gs4,
                                       struct flowi4 *fl4,
                                       const struct ip_tunnel_info *info,
-                                      __be16 dport, __be16 sport)
+                                      __be16 dport, __be16 sport,
+                                      __u8 *full_tos)
 {
        bool use_cache = ip_tunnel_dst_cache_usable(skb, info);
        struct geneve_dev *geneve = netdev_priv(dev);
@@ -799,6 +800,8 @@ static struct rtable *geneve_get_v4_rt(struct sk_buff *skb,
                use_cache = false;
        }
        fl4->flowi4_tos = RT_TOS(tos);
+       if (full_tos)
+               *full_tos = tos;
 
        dst_cache = (struct dst_cache *)&info->dst_cache;
        if (use_cache) {
@@ -886,6 +889,7 @@ static int geneve_xmit_skb(struct sk_buff *skb, struct net_device *dev,
        const struct ip_tunnel_key *key = &info->key;
        struct rtable *rt;
        struct flowi4 fl4;
+       __u8 full_tos;
        __u8 tos, ttl;
        __be16 df = 0;
        __be16 sport;
@@ -896,7 +900,7 @@ static int geneve_xmit_skb(struct sk_buff *skb, struct net_device *dev,
 
        sport = udp_flow_src_port(geneve->net, skb, 1, USHRT_MAX, true);
        rt = geneve_get_v4_rt(skb, dev, gs4, &fl4, info,
-                             geneve->cfg.info.key.tp_dst, sport);
+                             geneve->cfg.info.key.tp_dst, sport, &full_tos);
        if (IS_ERR(rt))
                return PTR_ERR(rt);
 
@@ -940,7 +944,7 @@ static int geneve_xmit_skb(struct sk_buff *skb, struct net_device *dev,
 
                df = key->tun_flags & TUNNEL_DONT_FRAGMENT ? htons(IP_DF) : 0;
        } else {
-               tos = ip_tunnel_ecn_encap(fl4.flowi4_tos, ip_hdr(skb), skb);
+               tos = ip_tunnel_ecn_encap(full_tos, ip_hdr(skb), skb);
                if (geneve->cfg.ttl_inherit)
                        ttl = ip_tunnel_get_ttl(ip_hdr(skb), skb);
                else
@@ -1122,7 +1126,7 @@ static int geneve_fill_metadata_dst(struct net_device *dev, struct sk_buff *skb)
                                          1, USHRT_MAX, true);
 
                rt = geneve_get_v4_rt(skb, dev, gs4, &fl4, info,
-                                     geneve->cfg.info.key.tp_dst, sport);
+                                     geneve->cfg.info.key.tp_dst, sport, NULL);
                if (IS_ERR(rt))
                        return PTR_ERR(rt);