geneve: fix populating tclass in geneve_get_v6_dst
authorDaniel Borkmann <daniel@iogearbox.net>
Fri, 18 Mar 2016 17:37:58 +0000 (18:37 +0100)
committerDavid S. Miller <davem@davemloft.net>
Sun, 20 Mar 2016 17:44:34 +0000 (13:44 -0400)
The struct flowi6's flowi6_tos is not used in IPv6 route lookup, the
traffic class information is handled in the flowi6's flowlabel member
instead. For example, for policy routing, fib6_rule_match() uses
ip6_tclass() that is applied on the flowlabel for matching on tclass,
which would currently not work as expected.

Fixes: 3a56f86f1be6 ("geneve: handle ipv6 priority like ipv4 tos")
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/geneve.c

index 192631a..bc16889 100644 (file)
@@ -843,8 +843,8 @@ static struct dst_entry *geneve_get_v6_dst(struct sk_buff *skb,
        if (info) {
                fl6->daddr = info->key.u.ipv6.dst;
                fl6->saddr = info->key.u.ipv6.src;
-               fl6->flowi6_tos = RT_TOS(info->key.tos);
-               fl6->flowlabel = info->key.label;
+               fl6->flowlabel = ip6_make_flowinfo(RT_TOS(info->key.tos),
+                                                  info->key.label);
                dst_cache = &info->dst_cache;
        } else {
                prio = geneve->tos;
@@ -855,8 +855,8 @@ static struct dst_entry *geneve_get_v6_dst(struct sk_buff *skb,
                        use_cache = false;
                }
 
-               fl6->flowi6_tos = RT_TOS(prio);
-               fl6->flowlabel = geneve->label;
+               fl6->flowlabel = ip6_make_flowinfo(RT_TOS(prio),
+                                                  geneve->label);
                fl6->daddr = geneve->remote.sin6.sin6_addr;
                dst_cache = &geneve->dst_cache;
        }
@@ -1049,7 +1049,8 @@ static netdev_tx_t geneve6_xmit_skb(struct sk_buff *skb, struct net_device *dev,
                if (unlikely(err))
                        goto err;
 
-               prio = ip_tunnel_ecn_encap(fl6.flowi6_tos, iip, skb);
+               prio = ip_tunnel_ecn_encap(ip6_tclass(fl6.flowlabel),
+                                          iip, skb);
                ttl = geneve->ttl;
                if (!ttl && ipv6_addr_is_multicast(&fl6.daddr))
                        ttl = 1;