flow_dissector: Fix fragment handling for header length computation
[cascardo/linux.git] / net / core / flow_dissector.c
index 1f88f82..8bd745f 100644 (file)
@@ -448,13 +448,12 @@ ip_proto_again:
                key_control->flags |= FLOW_DIS_IS_FRAGMENT;
 
                nhoff += sizeof(_fh);
+               ip_proto = fh->nexthdr;
 
                if (!(fh->frag_off & htons(IP6_OFFSET))) {
                        key_control->flags |= FLOW_DIS_FIRST_FRAG;
-                       if (flags & FLOW_DISSECTOR_F_PARSE_1ST_FRAG) {
-                               ip_proto = fh->nexthdr;
+                       if (flags & FLOW_DISSECTOR_F_PARSE_1ST_FRAG)
                                goto ip_proto_again;
-                       }
                }
                goto out_good;
        }
@@ -741,6 +740,11 @@ u32 __skb_get_poff(const struct sk_buff *skb, void *data,
 {
        u32 poff = keys->control.thoff;
 
+       /* skip L4 headers for fragments after the first */
+       if ((keys->control.flags & FLOW_DIS_IS_FRAGMENT) &&
+           !(keys->control.flags & FLOW_DIS_FIRST_FRAG))
+               return poff;
+
        switch (keys->basic.ip_proto) {
        case IPPROTO_TCP: {
                /* access doff as u8 to avoid unaligned access */