return 0;
 }
 
-static int tcf_ct_handle_fragments(struct net *net, struct sk_buff *skb,
-                                  u8 family, u16 zone, bool *defrag)
+static int handle_fragments(struct net *net, struct sk_buff *skb,
+                           u16 zone, u8 family, u16 *mru)
 {
-       enum ip_conntrack_info ctinfo;
-       struct nf_conn *ct;
-       int err = 0;
-       bool frag;
-       u16 mru;
-
-       /* Previously seen (loopback)? Ignore. */
-       ct = nf_ct_get(skb, &ctinfo);
-       if ((ct && !nf_ct_is_template(ct)) || ctinfo == IP_CT_UNTRACKED)
-               return 0;
-
-       if (family == NFPROTO_IPV4)
-               err = tcf_ct_ipv4_is_fragment(skb, &frag);
-       else
-               err = tcf_ct_ipv6_is_fragment(skb, &frag);
-       if (err || !frag)
-               return err;
-
-       skb_get(skb);
-       mru = tc_skb_cb(skb)->mru;
+       int err;
 
        if (family == NFPROTO_IPV4) {
                enum ip_defrag_users user = IP_DEFRAG_CONNTRACK_IN + zone;
                if (err && err != -EINPROGRESS)
                        return err;
 
-               if (!err) {
-                       *defrag = true;
-                       mru = IPCB(skb)->frag_max_size;
-               }
+               if (!err)
+                       *mru = IPCB(skb)->frag_max_size;
        } else { /* NFPROTO_IPV6 */
 #if IS_ENABLED(CONFIG_NF_DEFRAG_IPV6)
                enum ip6_defrag_users user = IP6_DEFRAG_CONNTRACK_IN + zone;
                if (err && err != -EINPROGRESS)
                        goto out_free;
 
-               if (!err) {
-                       *defrag = true;
-                       mru = IP6CB(skb)->frag_max_size;
-               }
+               if (!err)
+                       *mru = IP6CB(skb)->frag_max_size;
 #else
                err = -EOPNOTSUPP;
                goto out_free;
 #endif
        }
 
-       if (err != -EINPROGRESS)
-               tc_skb_cb(skb)->mru = mru;
        skb_clear_hash(skb);
        skb->ignore_df = 1;
        return err;
        return err;
 }
 
+static int tcf_ct_handle_fragments(struct net *net, struct sk_buff *skb,
+                                  u8 family, u16 zone, bool *defrag)
+{
+       enum ip_conntrack_info ctinfo;
+       struct nf_conn *ct;
+       int err = 0;
+       bool frag;
+       u16 mru;
+
+       /* Previously seen (loopback)? Ignore. */
+       ct = nf_ct_get(skb, &ctinfo);
+       if ((ct && !nf_ct_is_template(ct)) || ctinfo == IP_CT_UNTRACKED)
+               return 0;
+
+       if (family == NFPROTO_IPV4)
+               err = tcf_ct_ipv4_is_fragment(skb, &frag);
+       else
+               err = tcf_ct_ipv6_is_fragment(skb, &frag);
+       if (err || !frag)
+               return err;
+
+       skb_get(skb);
+       err = handle_fragments(net, skb, zone, family, &mru);
+       if (err)
+               return err;
+
+       *defrag = true;
+       tc_skb_cb(skb)->mru = mru;
+
+       return 0;
+}
+
 static void tcf_ct_params_free(struct tcf_ct_params *params)
 {
        if (params->helper) {