action |= BIT(NF_NAT_MANIP_DST);
 
        err = nf_ct_nat(skb, ct, ctinfo, &action, range, commit);
+       if (err != NF_ACCEPT)
+               return err & NF_VERDICT_MASK;
 
        if (action & BIT(NF_NAT_MANIP_SRC))
                tc_skb_cb(skb)->post_ct_snat = 1;
                state.pf = family;
                err = nf_conntrack_in(skb, &state);
                if (err != NF_ACCEPT)
-                       goto out_push;
+                       goto nf_error;
        }
 
 do_nat:
 
        err = tcf_ct_act_nat(skb, ct, ctinfo, p->ct_action, &p->range, commit);
        if (err != NF_ACCEPT)
-               goto drop;
+               goto nf_error;
 
        if (!nf_ct_is_confirmed(ct) && commit && p->helper && !nfct_help(ct)) {
                err = __nf_ct_try_assign_helper(ct, p->tmpl, GFP_ATOMIC);
        }
 
        if (nf_ct_is_confirmed(ct) ? ((!cached && !skip_add) || add_helper) : commit) {
-               if (nf_ct_helper(skb, ct, ctinfo, family) != NF_ACCEPT)
-                       goto drop;
+               err = nf_ct_helper(skb, ct, ctinfo, family);
+               if (err != NF_ACCEPT)
+                       goto nf_error;
        }
 
        if (commit) {
                /* This will take care of sending queued events
                 * even if the connection is already confirmed.
                 */
-               if (nf_conntrack_confirm(skb) != NF_ACCEPT)
-                       goto drop;
+               err = nf_conntrack_confirm(skb);
+               if (err != NF_ACCEPT)
+                       goto nf_error;
        }
 
        if (!skip_add)
 drop:
        tcf_action_inc_drop_qstats(&c->common);
        return TC_ACT_SHOT;
+
+nf_error:
+       /* some verdicts store extra data in upper bits, such
+        * as errno or queue number.
+        */
+       switch (err & NF_VERDICT_MASK) {
+       case NF_DROP:
+               goto drop;
+       case NF_STOLEN:
+               tcf_action_inc_drop_qstats(&c->common);
+               return TC_ACT_CONSUMED;
+       default:
+               DEBUG_NET_WARN_ON_ONCE(1);
+               goto drop;
+       }
 }
 
 static const struct nla_policy ct_policy[TCA_CT_MAX + 1] = {