return 0;
 }
 
-static void __cls_bpf_delete_prog(struct cls_bpf_prog *prog)
+static void cls_bpf_free_parms(struct cls_bpf_prog *prog)
 {
-       tcf_exts_destroy(&prog->exts);
-       tcf_exts_put_net(&prog->exts);
-
        if (cls_bpf_is_ebpf(prog))
                bpf_prog_put(prog->filter);
        else
 
        kfree(prog->bpf_name);
        kfree(prog->bpf_ops);
+}
+
+static void __cls_bpf_delete_prog(struct cls_bpf_prog *prog)
+{
+       tcf_exts_destroy(&prog->exts);
+       tcf_exts_put_net(&prog->exts);
+
+       cls_bpf_free_parms(prog);
        kfree(prog);
 }
 
                goto errout_idr;
 
        ret = cls_bpf_offload(tp, prog, oldprog);
-       if (ret) {
-               if (!oldprog)
-                       idr_remove_ext(&head->handle_idr, prog->handle);
-               __cls_bpf_delete_prog(prog);
-               return ret;
-       }
+       if (ret)
+               goto errout_parms;
 
        if (!tc_in_hw(prog->gen_flags))
                prog->gen_flags |= TCA_CLS_FLAGS_NOT_IN_HW;
        *arg = prog;
        return 0;
 
+errout_parms:
+       cls_bpf_free_parms(prog);
 errout_idr:
        if (!oldprog)
                idr_remove_ext(&head->handle_idr, prog->handle);