#if IS_ENABLED(CONFIG_IPV6)
 static struct dst_entry *vxlan6_get_route(struct vxlan_dev *vxlan,
-                                         struct sk_buff *skb, int oif,
+                                         struct sk_buff *skb, int oif, u8 tos,
                                          const struct in6_addr *daddr,
                                          struct in6_addr *saddr,
                                          struct dst_cache *dst_cache,
        struct flowi6 fl6;
        int err;
 
+       if (tos && !info)
+               use_cache = false;
        if (use_cache) {
                ndst = dst_cache_get_ip6(dst_cache, saddr);
                if (ndst)
 
        memset(&fl6, 0, sizeof(fl6));
        fl6.flowi6_oif = oif;
+       fl6.flowi6_tos = RT_TOS(tos);
        fl6.daddr = *daddr;
        fl6.saddr = vxlan->cfg.saddr.sin6.sin6_addr;
        fl6.flowi6_mark = skb->mark;
                sk = vxlan->vn6_sock->sock->sk;
 
                ndst = vxlan6_get_route(vxlan, skb,
-                                       rdst ? rdst->remote_ifindex : 0,
+                                       rdst ? rdst->remote_ifindex : 0, tos,
                                        &dst->sin6.sin6_addr, &saddr,
                                        dst_cache, info);
                if (IS_ERR(ndst)) {
                if (!info)
                        udp_sum = !(flags & VXLAN_F_UDP_ZERO_CSUM6_TX);
 
+               tos = ip_tunnel_ecn_encap(tos, old_iph, skb);
                ttl = ttl ? : ip6_dst_hoplimit(ndst);
                skb_scrub_packet(skb, xnet);
                err = vxlan_build_skb(skb, ndst, sizeof(struct ipv6hdr),
                        return;
                }
                udp_tunnel6_xmit_skb(ndst, sk, skb, dev,
-                                    &saddr, &dst->sin6.sin6_addr,
-                                    0, ttl, src_port, dst_port, !udp_sum);
+                                    &saddr, &dst->sin6.sin6_addr, tos, ttl,
+                                    src_port, dst_port, !udp_sum);
 #endif
        }
 
 
                if (!vxlan->vn6_sock)
                        return -EINVAL;
-               ndst = vxlan6_get_route(vxlan, skb, 0,
+               ndst = vxlan6_get_route(vxlan, skb, 0, info->key.tos,
                                        &info->key.u.ipv6.dst,
                                        &info->key.u.ipv6.src, NULL, info);
                if (IS_ERR(ndst))