nf_unregister_hooks(nft_base_chain(chain)->ops, hook_nops);
 }
 
+/* Internal table flags */
+#define NFT_TABLE_INACTIVE     (1 << 15)
+
+static int nft_trans_table_add(struct nft_ctx *ctx, int msg_type)
+{
+       struct nft_trans *trans;
+
+       trans = nft_trans_alloc(ctx, msg_type, sizeof(struct nft_trans_table));
+       if (trans == NULL)
+               return -ENOMEM;
+
+       if (msg_type == NFT_MSG_NEWTABLE)
+               ctx->table->flags |= NFT_TABLE_INACTIVE;
+
+       list_add_tail(&trans->list, &ctx->net->nft.commit_list);
+       return 0;
+}
+
+static int nft_deltable(struct nft_ctx *ctx)
+{
+       int err;
+
+       err = nft_trans_table_add(ctx, NFT_MSG_DELTABLE);
+       if (err < 0)
+               return err;
+
+       list_del_rcu(&ctx->table->list);
+       return err;
+}
+
+static int nft_trans_chain_add(struct nft_ctx *ctx, int msg_type)
+{
+       struct nft_trans *trans;
+
+       trans = nft_trans_alloc(ctx, msg_type, sizeof(struct nft_trans_chain));
+       if (trans == NULL)
+               return -ENOMEM;
+
+       if (msg_type == NFT_MSG_NEWCHAIN)
+               ctx->chain->flags |= NFT_CHAIN_INACTIVE;
+
+       list_add_tail(&trans->list, &ctx->net->nft.commit_list);
+       return 0;
+}
+
+static int nft_delchain(struct nft_ctx *ctx)
+{
+       int err;
+
+       err = nft_trans_chain_add(ctx, NFT_MSG_DELCHAIN);
+       if (err < 0)
+               return err;
+
+       ctx->table->use--;
+       list_del_rcu(&ctx->chain->list);
+
+       return err;
+}
+
+static inline bool
+nft_rule_is_active(struct net *net, const struct nft_rule *rule)
+{
+       return (rule->genmask & (1 << net->nft.gencursor)) == 0;
+}
+
+static inline int gencursor_next(struct net *net)
+{
+       return net->nft.gencursor+1 == 1 ? 1 : 0;
+}
+
+static inline int
+nft_rule_is_active_next(struct net *net, const struct nft_rule *rule)
+{
+       return (rule->genmask & (1 << gencursor_next(net))) == 0;
+}
+
+static inline void
+nft_rule_activate_next(struct net *net, struct nft_rule *rule)
+{
+       /* Now inactive, will be active in the future */
+       rule->genmask = (1 << net->nft.gencursor);
+}
+
+static inline void
+nft_rule_deactivate_next(struct net *net, struct nft_rule *rule)
+{
+       rule->genmask = (1 << gencursor_next(net));
+}
+
+static inline void nft_rule_clear(struct net *net, struct nft_rule *rule)
+{
+       rule->genmask = 0;
+}
+
+static int
+nf_tables_delrule_deactivate(struct nft_ctx *ctx, struct nft_rule *rule)
+{
+       /* You cannot delete the same rule twice */
+       if (nft_rule_is_active_next(ctx->net, rule)) {
+               nft_rule_deactivate_next(ctx->net, rule);
+               ctx->chain->use--;
+               return 0;
+       }
+       return -ENOENT;
+}
+
+static struct nft_trans *nft_trans_rule_add(struct nft_ctx *ctx, int msg_type,
+                                           struct nft_rule *rule)
+{
+       struct nft_trans *trans;
+
+       trans = nft_trans_alloc(ctx, msg_type, sizeof(struct nft_trans_rule));
+       if (trans == NULL)
+               return NULL;
+
+       nft_trans_rule(trans) = rule;
+       list_add_tail(&trans->list, &ctx->net->nft.commit_list);
+
+       return trans;
+}
+
+static int nft_delrule(struct nft_ctx *ctx, struct nft_rule *rule)
+{
+       struct nft_trans *trans;
+       int err;
+
+       trans = nft_trans_rule_add(ctx, NFT_MSG_DELRULE, rule);
+       if (trans == NULL)
+               return -ENOMEM;
+
+       err = nf_tables_delrule_deactivate(ctx, rule);
+       if (err < 0) {
+               nft_trans_destroy(trans);
+               return err;
+       }
+
+       return 0;
+}
+
+static int nft_delrule_by_chain(struct nft_ctx *ctx)
+{
+       struct nft_rule *rule;
+       int err;
+
+       list_for_each_entry(rule, &ctx->chain->rules, list) {
+               err = nft_delrule(ctx, rule);
+               if (err < 0)
+                       return err;
+       }
+       return 0;
+}
+
+/* Internal set flag */
+#define NFT_SET_INACTIVE       (1 << 15)
+
+static int nft_trans_set_add(struct nft_ctx *ctx, int msg_type,
+                            struct nft_set *set)
+{
+       struct nft_trans *trans;
+
+       trans = nft_trans_alloc(ctx, msg_type, sizeof(struct nft_trans_set));
+       if (trans == NULL)
+               return -ENOMEM;
+
+       if (msg_type == NFT_MSG_NEWSET && ctx->nla[NFTA_SET_ID] != NULL) {
+               nft_trans_set_id(trans) =
+                       ntohl(nla_get_be32(ctx->nla[NFTA_SET_ID]));
+               set->flags |= NFT_SET_INACTIVE;
+       }
+       nft_trans_set(trans) = set;
+       list_add_tail(&trans->list, &ctx->net->nft.commit_list);
+
+       return 0;
+}
+
+static int nft_delset(struct nft_ctx *ctx, struct nft_set *set)
+{
+       int err;
+
+       err = nft_trans_set_add(ctx, NFT_MSG_DELSET, set);
+       if (err < 0)
+               return err;
+
+       list_del_rcu(&set->list);
+       ctx->table->use--;
+
+       return err;
+}
+
 /*
  * Tables
  */
        return skb->len;
 }
 
-/* Internal table flags */
-#define NFT_TABLE_INACTIVE     (1 << 15)
-
 static int nf_tables_gettable(struct sock *nlsk, struct sk_buff *skb,
                              const struct nlmsghdr *nlh,
                              const struct nlattr * const nla[])
        return ret;
 }
 
-static int nft_trans_table_add(struct nft_ctx *ctx, int msg_type)
-{
-       struct nft_trans *trans;
-
-       trans = nft_trans_alloc(ctx, msg_type, sizeof(struct nft_trans_table));
-       if (trans == NULL)
-               return -ENOMEM;
-
-       if (msg_type == NFT_MSG_NEWTABLE)
-               ctx->table->flags |= NFT_TABLE_INACTIVE;
-
-       list_add_tail(&trans->list, &ctx->net->nft.commit_list);
-       return 0;
-}
-
 static int nf_tables_newtable(struct sock *nlsk, struct sk_buff *skb,
                              const struct nlmsghdr *nlh,
                              const struct nlattr * const nla[])
        struct nft_af_info *afi;
        struct nft_table *table;
        struct net *net = sock_net(skb->sk);
-       int family = nfmsg->nfgen_family, err;
+       int family = nfmsg->nfgen_family;
        struct nft_ctx ctx;
 
        afi = nf_tables_afinfo_lookup(net, family, false);
                return -EBUSY;
 
        nft_ctx_init(&ctx, skb, nlh, afi, table, NULL, nla);
-       err = nft_trans_table_add(&ctx, NFT_MSG_DELTABLE);
-       if (err < 0)
-               return err;
 
-       list_del_rcu(&table->list);
-       return 0;
+       return nft_deltable(&ctx);
 }
 
 static void nf_tables_table_destroy(struct nft_ctx *ctx)
                rcu_assign_pointer(chain->stats, newstats);
 }
 
-static int nft_trans_chain_add(struct nft_ctx *ctx, int msg_type)
-{
-       struct nft_trans *trans;
-
-       trans = nft_trans_alloc(ctx, msg_type, sizeof(struct nft_trans_chain));
-       if (trans == NULL)
-               return -ENOMEM;
-
-       if (msg_type == NFT_MSG_NEWCHAIN)
-               ctx->chain->flags |= NFT_CHAIN_INACTIVE;
-
-       list_add_tail(&trans->list, &ctx->net->nft.commit_list);
-       return 0;
-}
-
 static void nf_tables_chain_destroy(struct nft_chain *chain)
 {
        BUG_ON(chain->use > 0);
        struct net *net = sock_net(skb->sk);
        int family = nfmsg->nfgen_family;
        struct nft_ctx ctx;
-       int err;
 
        afi = nf_tables_afinfo_lookup(net, family, false);
        if (IS_ERR(afi))
                return -EBUSY;
 
        nft_ctx_init(&ctx, skb, nlh, afi, table, chain, nla);
-       err = nft_trans_chain_add(&ctx, NFT_MSG_DELCHAIN);
-       if (err < 0)
-               return err;
 
-       table->use--;
-       list_del_rcu(&chain->list);
-       return 0;
+       return nft_delchain(&ctx);
 }
 
 /*
        return err;
 }
 
-static inline bool
-nft_rule_is_active(struct net *net, const struct nft_rule *rule)
-{
-       return (rule->genmask & (1 << net->nft.gencursor)) == 0;
-}
-
-static inline int gencursor_next(struct net *net)
-{
-       return net->nft.gencursor+1 == 1 ? 1 : 0;
-}
-
-static inline int
-nft_rule_is_active_next(struct net *net, const struct nft_rule *rule)
-{
-       return (rule->genmask & (1 << gencursor_next(net))) == 0;
-}
-
-static inline void
-nft_rule_activate_next(struct net *net, struct nft_rule *rule)
-{
-       /* Now inactive, will be active in the future */
-       rule->genmask = (1 << net->nft.gencursor);
-}
-
-static inline void
-nft_rule_disactivate_next(struct net *net, struct nft_rule *rule)
-{
-       rule->genmask = (1 << gencursor_next(net));
-}
-
-static inline void nft_rule_clear(struct net *net, struct nft_rule *rule)
-{
-       rule->genmask = 0;
-}
-
 static int nf_tables_dump_rules(struct sk_buff *skb,
                                struct netlink_callback *cb)
 {
        kfree(rule);
 }
 
-static struct nft_trans *nft_trans_rule_add(struct nft_ctx *ctx, int msg_type,
-                                           struct nft_rule *rule)
-{
-       struct nft_trans *trans;
-
-       trans = nft_trans_alloc(ctx, msg_type, sizeof(struct nft_trans_rule));
-       if (trans == NULL)
-               return NULL;
-
-       nft_trans_rule(trans) = rule;
-       list_add_tail(&trans->list, &ctx->net->nft.commit_list);
-
-       return trans;
-}
-
 #define NFT_RULE_MAXEXPRS      128
 
 static struct nft_expr_info *info;
                                err = -ENOMEM;
                                goto err2;
                        }
-                       nft_rule_disactivate_next(net, old_rule);
+                       nft_rule_deactivate_next(net, old_rule);
                        chain->use--;
                        list_add_tail_rcu(&rule->list, &old_rule->list);
                } else {
        return err;
 }
 
-static int
-nf_tables_delrule_deactivate(struct nft_ctx *ctx, struct nft_rule *rule)
-{
-       /* You cannot delete the same rule twice */
-       if (nft_rule_is_active_next(ctx->net, rule)) {
-               nft_rule_disactivate_next(ctx->net, rule);
-               ctx->chain->use--;
-               return 0;
-       }
-       return -ENOENT;
-}
-
-static int nft_delrule(struct nft_ctx *ctx, struct nft_rule *rule)
-{
-       struct nft_trans *trans;
-       int err;
-
-       trans = nft_trans_rule_add(ctx, NFT_MSG_DELRULE, rule);
-       if (trans == NULL)
-               return -ENOMEM;
-
-       err = nf_tables_delrule_deactivate(ctx, rule);
-       if (err < 0) {
-               nft_trans_destroy(trans);
-               return err;
-       }
-
-       return 0;
-}
-
-static int nft_delrule_by_chain(struct nft_ctx *ctx)
-{
-       struct nft_rule *rule;
-       int err;
-
-       list_for_each_entry(rule, &ctx->chain->rules, list) {
-               err = nft_delrule(ctx, rule);
-               if (err < 0)
-                       return err;
-       }
-       return 0;
-}
-
 static int nf_tables_delrule(struct sock *nlsk, struct sk_buff *skb,
                             const struct nlmsghdr *nlh,
                             const struct nlattr * const nla[])
        return 0;
 }
 
-#define NFT_SET_INACTIVE       (1 << 15)       /* Internal set flag */
-
 static int nf_tables_getset(struct sock *nlsk, struct sk_buff *skb,
                            const struct nlmsghdr *nlh,
                            const struct nlattr * const nla[])
        return 0;
 }
 
-static int nft_trans_set_add(struct nft_ctx *ctx, int msg_type,
-                            struct nft_set *set)
-{
-       struct nft_trans *trans;
-
-       trans = nft_trans_alloc(ctx, msg_type, sizeof(struct nft_trans_set));
-       if (trans == NULL)
-               return -ENOMEM;
-
-       if (msg_type == NFT_MSG_NEWSET && ctx->nla[NFTA_SET_ID] != NULL) {
-               nft_trans_set_id(trans) =
-                       ntohl(nla_get_be32(ctx->nla[NFTA_SET_ID]));
-               set->flags |= NFT_SET_INACTIVE;
-       }
-       nft_trans_set(trans) = set;
-       list_add_tail(&trans->list, &ctx->net->nft.commit_list);
-
-       return 0;
-}
-
 static int nf_tables_newset(struct sock *nlsk, struct sk_buff *skb,
                            const struct nlmsghdr *nlh,
                            const struct nlattr * const nla[])
        if (!list_empty(&set->bindings))
                return -EBUSY;
 
-       err = nft_trans_set_add(&ctx, NFT_MSG_DELSET, set);
-       if (err < 0)
-               return err;
-
-       list_del_rcu(&set->list);
-       ctx.table->use--;
-       return 0;
+       return nft_delset(&ctx, set);
 }
 
 static int nf_tables_bind_check_setelem(const struct nft_ctx *ctx,