struct flow_dissector_key_basic *key_basic;
        struct flow_dissector_key_addrs *key_addrs;
        struct flow_dissector_key_ports *key_ports;
+       struct flow_dissector_key_tags *key_tags;
 
        key_control = skb_flow_dissector_target(flow_dissector,
                                                FLOW_DISSECTOR_KEY_CONTROL,
                key_ports->src = flow_keys->sport;
                key_ports->dst = flow_keys->dport;
        }
+
+       if (dissector_uses_key(flow_dissector,
+                              FLOW_DISSECTOR_KEY_FLOW_LABEL)) {
+               key_tags = skb_flow_dissector_target(flow_dissector,
+                                                    FLOW_DISSECTOR_KEY_FLOW_LABEL,
+                                                    target_container);
+               key_tags->flow_label = ntohl(flow_keys->flow_label);
+       }
 }
 
 bool bpf_flow_dissect(struct bpf_prog *prog, struct bpf_flow_dissector *ctx,
 
              "is_encap=%u/%u "                                         \
              "ip_proto=0x%x/0x%x "                                     \
              "n_proto=0x%x/0x%x "                                      \
+             "flow_label=0x%x/0x%x "                                   \
              "sport=%u/%u "                                            \
              "dport=%u/%u\n",                                          \
              got.nhoff, expected.nhoff,                                \
              got.is_encap, expected.is_encap,                          \
              got.ip_proto, expected.ip_proto,                          \
              got.n_proto, expected.n_proto,                            \
+             got.flow_label, expected.flow_label,                      \
              got.sport, expected.sport,                                \
              got.dport, expected.dport)
 
                        .is_first_frag = true,
                },
        },
+       {
+               .name = "ipv6-flow-label",
+               .pkt.ipv6 = {
+                       .eth.h_proto = __bpf_constant_htons(ETH_P_IPV6),
+                       .iph.nexthdr = IPPROTO_TCP,
+                       .iph.payload_len = __bpf_constant_htons(MAGIC_BYTES),
+                       .iph.flow_lbl = { 0xb, 0xee, 0xef },
+                       .tcp.doff = 5,
+                       .tcp.source = 80,
+                       .tcp.dest = 8080,
+               },
+               .keys = {
+                       .nhoff = ETH_HLEN,
+                       .thoff = ETH_HLEN + sizeof(struct ipv6hdr),
+                       .addr_proto = ETH_P_IPV6,
+                       .ip_proto = IPPROTO_TCP,
+                       .n_proto = __bpf_constant_htons(ETH_P_IPV6),
+                       .sport = 80,
+                       .dport = 8080,
+                       .flow_label = __bpf_constant_htonl(0xbeeef),
+               },
+       },
+       {
+               .name = "ipv6-no-flow-label",
+               .pkt.ipv6 = {
+                       .eth.h_proto = __bpf_constant_htons(ETH_P_IPV6),
+                       .iph.nexthdr = IPPROTO_TCP,
+                       .iph.payload_len = __bpf_constant_htons(MAGIC_BYTES),
+                       .iph.flow_lbl = { 0xb, 0xee, 0xef },
+                       .tcp.doff = 5,
+                       .tcp.source = 80,
+                       .tcp.dest = 8080,
+               },
+               .keys = {
+                       .flags = BPF_FLOW_DISSECTOR_F_STOP_AT_FLOW_LABEL,
+                       .nhoff = ETH_HLEN,
+                       .thoff = ETH_HLEN + sizeof(struct ipv6hdr),
+                       .addr_proto = ETH_P_IPV6,
+                       .ip_proto = IPPROTO_TCP,
+                       .n_proto = __bpf_constant_htons(ETH_P_IPV6),
+                       .flow_label = __bpf_constant_htonl(0xbeeef),
+               },
+               .flags = BPF_FLOW_DISSECTOR_F_STOP_AT_FLOW_LABEL,
+       },
 };
 
 static int create_tap(const char *ifname)
 
        return ret;
 }
 
+#define IPV6_FLOWLABEL_MASK            __bpf_constant_htonl(0x000FFFFF)
+static inline __be32 ip6_flowlabel(const struct ipv6hdr *hdr)
+{
+       return *(__be32 *)hdr & IPV6_FLOWLABEL_MASK;
+}
+
 static __always_inline void *bpf_flow_dissect_get_header(struct __sk_buff *skb,
                                                         __u16 hdr_size,
                                                         void *buffer)
 
        keys->thoff += sizeof(struct ipv6hdr);
        keys->ip_proto = ip6h->nexthdr;
+       keys->flow_label = ip6_flowlabel(ip6h);
+
+       if (keys->flags & BPF_FLOW_DISSECTOR_F_STOP_AT_FLOW_LABEL)
+               return export_flow_keys(keys, BPF_OK);
 
        return parse_ipv6_proto(skb, ip6h->nexthdr);
 }