rcu_read_unlock();
 }
 
+/* Compute flowlabel for outer IPv6 header */
+static __be32 seg6_make_flowlabel(struct net *net, struct sk_buff *skb,
+                                 struct ipv6hdr *inner_hdr)
+{
+       int do_flowlabel = net->ipv6.sysctl.seg6_flowlabel;
+       __be32 flowlabel = 0;
+       u32 hash;
+
+       if (do_flowlabel > 0) {
+               hash = skb_get_hash(skb);
+               rol32(hash, 16);
+               flowlabel = (__force __be32)hash & IPV6_FLOWLABEL_MASK;
+       } else if (!do_flowlabel && skb->protocol == htons(ETH_P_IPV6)) {
+               flowlabel = ip6_flowlabel(inner_hdr);
+       }
+       return flowlabel;
+}
+
 /* encapsulate an IPv6 packet within an outer IPv6 header with a given SRH */
 int seg6_do_srh_encap(struct sk_buff *skb, struct ipv6_sr_hdr *osrh, int proto)
 {
        struct ipv6hdr *hdr, *inner_hdr;
        struct ipv6_sr_hdr *isrh;
        int hdrlen, tot_len, err;
+       __be32 flowlabel;
 
        hdrlen = (osrh->hdrlen + 1) << 3;
        tot_len = hdrlen + sizeof(*hdr);
         * decapsulation will overwrite inner hlim with outer hlim
         */
 
+       flowlabel = seg6_make_flowlabel(net, skb, inner_hdr);
        if (skb->protocol == htons(ETH_P_IPV6)) {
                ip6_flow_hdr(hdr, ip6_tclass(ip6_flowinfo(inner_hdr)),
-                            ip6_flowlabel(inner_hdr));
+                            flowlabel);
                hdr->hop_limit = inner_hdr->hop_limit;
        } else {
-               ip6_flow_hdr(hdr, 0, 0);
+               ip6_flow_hdr(hdr, 0, flowlabel);
                hdr->hop_limit = ip6_dst_hoplimit(skb_dst(skb));
        }
 
 
                .extra1         = &zero,
                .extra2         = &one,
        },
+       {
+               .procname       = "seg6_flowlabel",
+               .data           = &init_net.ipv6.sysctl.seg6_flowlabel,
+               .maxlen         = sizeof(int),
+               .mode           = 0644,
+               .proc_handler   = proc_dointvec
+       },
        { }
 };
 
        ipv6_table[12].data = &net->ipv6.sysctl.max_dst_opts_len;
        ipv6_table[13].data = &net->ipv6.sysctl.max_hbh_opts_len;
        ipv6_table[14].data = &net->ipv6.sysctl.multipath_hash_policy,
+       ipv6_table[15].data = &net->ipv6.sysctl.seg6_flowlabel;
 
        ipv6_route_table = ipv6_route_sysctl_init(net);
        if (!ipv6_route_table)