]> git.ipfire.org Git - thirdparty/iptables.git/commitdiff
nft: split parsing from netlink commands
authorPablo Neira Ayuso <pablo@netfilter.org>
Mon, 6 Jan 2020 12:20:13 +0000 (13:20 +0100)
committerPhil Sutter <phil@nwl.cc>
Mon, 11 May 2020 12:28:28 +0000 (14:28 +0200)
This patch updates the parser to generate a list of command objects.
This list of commands is then transformed to a list of netlink jobs.
This new command object stores the rule using the nftnl representation
via nft_rule_new().

To reduce the number of updates in this patch, the nft_*_rule_find()
functions have been updated to restore the native representation to
skip the update of the rule comparison code.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Phil Sutter <phil@nwl.cc>
15 files changed:
iptables/Makefile.am
iptables/nft-arp.c
iptables/nft-bridge.c
iptables/nft-cmd.c [new file with mode: 0644]
iptables/nft-cmd.h [new file with mode: 0644]
iptables/nft-shared.c
iptables/nft-shared.h
iptables/nft.c
iptables/nft.h
iptables/tests/shell/testcases/ip6tables/0004-return-codes_0
iptables/tests/shell/testcases/iptables/0004-return-codes_0
iptables/xtables-arp.c
iptables/xtables-eb.c
iptables/xtables-restore.c
iptables/xtables.c

index 71b1b1d48d4b6c5ea3902deee2f0eb82fb13a9f2..dc66b3cc09c088ba6ac05f1ddc4652ce4fc135d6 100644 (file)
@@ -38,7 +38,7 @@ xtables_nft_multi_SOURCES += xtables-save.c xtables-restore.c \
                                nft-shared.c nft-ipv4.c nft-ipv6.c nft-arp.c \
                                xtables-monitor.c nft-cache.c \
                                xtables-arp-standalone.c xtables-arp.c \
-                               nft-bridge.c \
+                               nft-bridge.c nft-cmd.c \
                                xtables-eb-standalone.c xtables-eb.c \
                                xtables-eb-translate.c \
                                xtables-translate.c
index d4a86610ec2171a0663968d79ff8dd81bc43d1ad..e9a2d9de21560631738be5237df32bbab3df2e65 100644 (file)
@@ -634,14 +634,15 @@ static bool nft_arp_is_same(const void *data_a,
 }
 
 static bool nft_arp_rule_find(struct nft_handle *h, struct nftnl_rule *r,
-                             void *data)
+                             struct nftnl_rule *rule)
 {
-       const struct iptables_command_state *cs = data;
+       struct iptables_command_state _cs = {}, *cs = &_cs;
        struct iptables_command_state this = {};
        bool ret = false;
 
        /* Delete by matching rule case */
        nft_rule_to_iptables_command_state(h, r, &this);
+       nft_rule_to_iptables_command_state(h, rule, cs);
 
        if (!nft_arp_is_same(&cs->arp, &this.arp))
                goto out;
@@ -655,6 +656,7 @@ static bool nft_arp_rule_find(struct nft_handle *h, struct nftnl_rule *r,
        ret = true;
 out:
        h->ops->clear_cs(&this);
+       h->ops->clear_cs(cs);
        return ret;
 }
 
index 3f85cbbf5e4cf9d5010097d6ad151d3dd49a42ff..0d60c724afff07601ac0c116f879b773a91bcf6e 100644 (file)
@@ -748,13 +748,14 @@ static bool nft_bridge_is_same(const void *data_a, const void *data_b)
 }
 
 static bool nft_bridge_rule_find(struct nft_handle *h, struct nftnl_rule *r,
-                                void *data)
+                                struct nftnl_rule *rule)
 {
-       struct iptables_command_state *cs = data;
+       struct iptables_command_state _cs = {}, *cs = &_cs;
        struct iptables_command_state this = {};
        bool ret = false;
 
        nft_rule_to_ebtables_command_state(h, r, &this);
+       nft_rule_to_ebtables_command_state(h, rule, cs);
 
        DEBUGP("comparing with... ");
 
@@ -779,6 +780,7 @@ static bool nft_bridge_rule_find(struct nft_handle *h, struct nftnl_rule *r,
        ret = true;
 out:
        h->ops->clear_cs(&this);
+       h->ops->clear_cs(cs);
        return ret;
 }
 
diff --git a/iptables/nft-cmd.c b/iptables/nft-cmd.c
new file mode 100644 (file)
index 0000000..96887c0
--- /dev/null
@@ -0,0 +1,327 @@
+/*
+ * (C) 2012 by Pablo Neira Ayuso <pablo@netfilter.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This code has been sponsored by Sophos Astaro <http://www.sophos.com>
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include "nft.h"
+#include "nft-cmd.h"
+
+struct nft_cmd *nft_cmd_new(struct nft_handle *h, int command,
+                           const char *table, const char *chain,
+                           struct iptables_command_state *state,
+                           int rulenum, bool verbose)
+{
+       struct nftnl_rule *rule;
+       struct nft_cmd *cmd;
+
+       cmd = calloc(1, sizeof(struct nft_cmd));
+       if (!cmd)
+               return NULL;
+
+       cmd->command = command;
+       cmd->table = strdup(table);
+       if (chain)
+               cmd->chain = strdup(chain);
+       cmd->rulenum = rulenum;
+       cmd->verbose = verbose;
+
+       if (state) {
+               rule = nft_rule_new(h, chain, table, state);
+               if (!rule)
+                       return NULL;
+
+               cmd->obj.rule = rule;
+
+               if (!state->target && strlen(state->jumpto) > 0)
+                       cmd->jumpto = strdup(state->jumpto);
+       }
+
+       list_add_tail(&cmd->head, &h->cmd_list);
+
+       return cmd;
+}
+
+void nft_cmd_free(struct nft_cmd *cmd)
+{
+       free((void *)cmd->table);
+       free((void *)cmd->chain);
+       free((void *)cmd->policy);
+       free((void *)cmd->rename);
+       free((void *)cmd->jumpto);
+
+       switch (cmd->command) {
+       case NFT_COMPAT_RULE_CHECK:
+       case NFT_COMPAT_RULE_DELETE:
+               if (cmd->obj.rule)
+                       nftnl_rule_free(cmd->obj.rule);
+               break;
+       default:
+               break;
+       }
+
+       list_del(&cmd->head);
+       free(cmd);
+}
+
+int nft_cmd_rule_append(struct nft_handle *h, const char *chain,
+                       const char *table, struct iptables_command_state *state,
+                       void *ref, bool verbose)
+{
+       struct nft_cmd *cmd;
+
+       cmd = nft_cmd_new(h, NFT_COMPAT_RULE_APPEND, table, chain, state, -1,
+                         verbose);
+       if (!cmd)
+               return 0;
+
+       return 1;
+}
+
+int nft_cmd_rule_insert(struct nft_handle *h, const char *chain,
+                       const char *table, struct iptables_command_state *state,
+                       int rulenum, bool verbose)
+{
+       struct nft_cmd *cmd;
+
+       cmd = nft_cmd_new(h, NFT_COMPAT_RULE_INSERT, table, chain, state,
+                         rulenum, verbose);
+       if (!cmd)
+               return 0;
+
+       return 1;
+}
+
+int nft_cmd_rule_delete(struct nft_handle *h, const char *chain,
+                       const char *table, struct iptables_command_state *state,
+                       bool verbose)
+{
+       struct nft_cmd *cmd;
+
+       cmd = nft_cmd_new(h, NFT_COMPAT_RULE_DELETE, table, chain, state,
+                         -1, verbose);
+       if (!cmd)
+               return 0;
+
+       return 1;
+}
+
+int nft_cmd_rule_delete_num(struct nft_handle *h, const char *chain,
+                           const char *table, int rulenum, bool verbose)
+{
+       struct nft_cmd *cmd;
+
+       cmd = nft_cmd_new(h, NFT_COMPAT_RULE_DELETE, table, chain, NULL,
+                         rulenum, verbose);
+       if (!cmd)
+               return 0;
+
+       return 1;
+}
+
+int nft_cmd_rule_flush(struct nft_handle *h, const char *chain,
+                      const char *table, bool verbose)
+{
+       struct nft_cmd *cmd;
+
+       cmd = nft_cmd_new(h, NFT_COMPAT_RULE_FLUSH, table, chain, NULL, -1,
+                         verbose);
+       if (!cmd)
+               return 0;
+
+       return 1;
+}
+
+int nft_cmd_chain_zero_counters(struct nft_handle *h, const char *chain,
+                               const char *table, bool verbose)
+{
+       struct nft_cmd *cmd;
+
+       cmd = nft_cmd_new(h, NFT_COMPAT_CHAIN_ZERO, table, chain, NULL, -1,
+                         verbose);
+       if (!cmd)
+               return 0;
+
+       return 1;
+}
+
+int nft_cmd_chain_user_add(struct nft_handle *h, const char *chain,
+                          const char *table)
+{
+       struct nft_cmd *cmd;
+
+       cmd = nft_cmd_new(h, NFT_COMPAT_CHAIN_USER_ADD, table, chain, NULL, -1,
+                         false);
+       if (!cmd)
+               return 0;
+
+       return 1;
+}
+
+int nft_cmd_chain_user_del(struct nft_handle *h, const char *chain,
+                          const char *table, bool verbose)
+{
+       struct nft_cmd *cmd;
+
+       cmd = nft_cmd_new(h, NFT_COMPAT_CHAIN_USER_DEL, table, chain, NULL, -1,
+                         verbose);
+       if (!cmd)
+               return 0;
+
+       return 1;
+}
+
+int nft_cmd_chain_user_rename(struct nft_handle *h,const char *chain,
+                             const char *table, const char *newname)
+{
+       struct nft_cmd *cmd;
+
+       cmd = nft_cmd_new(h, NFT_COMPAT_CHAIN_RENAME, table, chain, NULL, -1,
+                         false);
+       if (!cmd)
+               return 0;
+
+       cmd->rename = strdup(newname);
+
+       return 1;
+}
+
+int nft_cmd_rule_list(struct nft_handle *h, const char *chain,
+                     const char *table, int rulenum, unsigned int format)
+{
+       struct nft_cmd *cmd;
+
+       cmd = nft_cmd_new(h, NFT_COMPAT_RULE_LIST, table, chain, NULL, rulenum,
+                         false);
+       if (!cmd)
+               return 0;
+
+       cmd->format = format;
+
+       return 1;
+}
+
+int nft_cmd_rule_replace(struct nft_handle *h, const char *chain,
+                        const char *table, void *data, int rulenum,
+                        bool verbose)
+{
+       struct nft_cmd *cmd;
+
+       cmd = nft_cmd_new(h, NFT_COMPAT_RULE_REPLACE, table, chain, data,
+                         rulenum, verbose);
+       if (!cmd)
+               return 0;
+
+       return 1;
+}
+
+int nft_cmd_rule_check(struct nft_handle *h, const char *chain,
+                      const char *table, void *data, bool verbose)
+{
+       struct nft_cmd *cmd;
+
+       cmd = nft_cmd_new(h, NFT_COMPAT_RULE_CHECK, table, chain, data, -1,
+                         verbose);
+       if (!cmd)
+               return 0;
+
+       return 1;
+}
+
+int nft_cmd_chain_set(struct nft_handle *h, const char *table,
+                     const char *chain, const char *policy,
+                     const struct xt_counters *counters)
+{
+       struct nft_cmd *cmd;
+
+       cmd = nft_cmd_new(h, NFT_COMPAT_CHAIN_UPDATE, table, chain, NULL, -1,
+                         false);
+       if (!cmd)
+               return 0;
+
+       cmd->policy = strdup(policy);
+       if (counters)
+               cmd->counters = *counters;
+
+       return 1;
+}
+
+int nft_cmd_table_flush(struct nft_handle *h, const char *table)
+{
+       struct nft_cmd *cmd;
+
+       cmd = nft_cmd_new(h, NFT_COMPAT_TABLE_FLUSH, table, NULL, NULL, -1,
+                         false);
+       if (!cmd)
+               return 0;
+
+       return 1;
+}
+
+int nft_cmd_chain_restore(struct nft_handle *h, const char *chain,
+                         const char *table)
+{
+       struct nft_cmd *cmd;
+
+       cmd = nft_cmd_new(h, NFT_COMPAT_CHAIN_RESTORE, table, chain, NULL, -1,
+                         false);
+       if (!cmd)
+               return 0;
+
+       return 1;
+}
+
+int nft_cmd_rule_zero_counters(struct nft_handle *h, const char *chain,
+                              const char *table, int rulenum)
+{
+       struct nft_cmd *cmd;
+
+       cmd = nft_cmd_new(h, NFT_COMPAT_RULE_ZERO, table, chain, NULL, rulenum,
+                         false);
+       if (!cmd)
+               return 0;
+
+       return 1;
+}
+
+int nft_cmd_rule_list_save(struct nft_handle *h, const char *chain,
+                          const char *table, int rulenum, int counters)
+{
+       struct nft_cmd *cmd;
+
+       cmd = nft_cmd_new(h, NFT_COMPAT_RULE_SAVE, table, chain, NULL, rulenum,
+                         false);
+       if (!cmd)
+               return 0;
+
+       cmd->counters_save = counters;
+
+       return 1;
+}
+
+int ebt_cmd_user_chain_policy(struct nft_handle *h, const char *table,
+                              const char *chain, const char *policy)
+{
+       struct nft_cmd *cmd;
+
+       cmd = nft_cmd_new(h, NFT_COMPAT_BRIDGE_USER_CHAIN_UPDATE, table, chain,
+                         NULL, -1, false);
+       if (!cmd)
+               return 0;
+
+       cmd->policy = strdup(policy);
+
+       return 1;
+}
+
+void nft_cmd_table_new(struct nft_handle *h, const char *table)
+{
+       nft_cmd_new(h, NFT_COMPAT_TABLE_NEW, table, NULL, NULL, -1, false);
+}
diff --git a/iptables/nft-cmd.h b/iptables/nft-cmd.h
new file mode 100644 (file)
index 0000000..33ee766
--- /dev/null
@@ -0,0 +1,78 @@
+#ifndef _NFT_CMD_H_
+#define _NFT_CMD_H_
+
+#include <libiptc/linux_list.h>
+#include <stdbool.h>
+#include "nft.h"
+
+struct nftnl_rule;
+
+struct nft_cmd {
+       struct list_head                head;
+       int                             command;
+       const char                      *table;
+       const char                      *chain;
+       const char                      *jumpto;
+       int                             rulenum;
+       bool                            verbose;
+       unsigned int                    format;
+       struct {
+               struct nftnl_rule       *rule;
+       } obj;
+       const char                      *policy;
+       struct xt_counters              counters;
+       const char                      *rename;
+       int                             counters_save;
+};
+
+struct nft_cmd *nft_cmd_new(struct nft_handle *h, int command,
+                           const char *table, const char *chain,
+                           struct iptables_command_state *state,
+                           int rulenum, bool verbose);
+void nft_cmd_free(struct nft_cmd *cmd);
+
+int nft_cmd_rule_append(struct nft_handle *h, const char *chain,
+                       const char *table, struct iptables_command_state *state,
+                        void *ref, bool verbose);
+int nft_cmd_rule_insert(struct nft_handle *h, const char *chain,
+                       const char *table, struct iptables_command_state *state,
+                       int rulenum, bool verbose);
+int nft_cmd_rule_delete(struct nft_handle *h, const char *chain,
+                        const char *table, struct iptables_command_state *state,
+                       bool verbose);
+int nft_cmd_rule_delete_num(struct nft_handle *h, const char *chain,
+                           const char *table, int rulenum, bool verbose);
+int nft_cmd_rule_flush(struct nft_handle *h, const char *chain,
+                      const char *table, bool verbose);
+int nft_cmd_zero_counters(struct nft_handle *h, const char *chain,
+                         const char *table, bool verbose);
+int nft_cmd_chain_user_add(struct nft_handle *h, const char *chain,
+                          const char *table);
+int nft_cmd_chain_user_del(struct nft_handle *h, const char *chain,
+                          const char *table, bool verbose);
+int nft_cmd_chain_zero_counters(struct nft_handle *h, const char *chain,
+                               const char *table, bool verbose);
+int nft_cmd_rule_list(struct nft_handle *h, const char *chain,
+                     const char *table, int rulenum, unsigned int format);
+int nft_cmd_rule_check(struct nft_handle *h, const char *chain,
+                       const char *table, void *data, bool verbose);
+int nft_cmd_chain_set(struct nft_handle *h, const char *table,
+                     const char *chain, const char *policy,
+                     const struct xt_counters *counters);
+int nft_cmd_chain_user_rename(struct nft_handle *h,const char *chain,
+                             const char *table, const char *newname);
+int nft_cmd_rule_replace(struct nft_handle *h, const char *chain,
+                        const char *table, void *data, int rulenum,
+                        bool verbose);
+int nft_cmd_table_flush(struct nft_handle *h, const char *table);
+int nft_cmd_chain_restore(struct nft_handle *h, const char *chain,
+                         const char *table);
+int nft_cmd_rule_zero_counters(struct nft_handle *h, const char *chain,
+                              const char *table, int rulenum);
+int nft_cmd_rule_list_save(struct nft_handle *h, const char *chain,
+                          const char *table, int rulenum, int counters);
+int ebt_cmd_user_chain_policy(struct nft_handle *h, const char *table,
+                             const char *chain, const char *policy);
+void nft_cmd_table_new(struct nft_handle *h, const char *table);
+
+#endif /* _NFT_CMD_H_ */
index 5192e36358b7cb3ed60e6032217ce5e4df550e37..bfc7bc2203239f6f25640254ceb0dfb93322740d 100644 (file)
@@ -989,12 +989,14 @@ void nft_ipv46_parse_target(struct xtables_target *t, void *data)
        cs->target = t;
 }
 
-bool nft_ipv46_rule_find(struct nft_handle *h, struct nftnl_rule *r, void *data)
+bool nft_ipv46_rule_find(struct nft_handle *h, struct nftnl_rule *r,
+                        struct nftnl_rule *rule)
 {
-       struct iptables_command_state *cs = data, this = {};
+       struct iptables_command_state _cs = {}, this = {}, *cs = &_cs;
        bool ret = false;
 
        nft_rule_to_iptables_command_state(h, r, &this);
+       nft_rule_to_iptables_command_state(h, rule, cs);
 
        DEBUGP("comparing with... ");
 #ifdef DEBUG_DEL
@@ -1022,6 +1024,7 @@ bool nft_ipv46_rule_find(struct nft_handle *h, struct nftnl_rule *r, void *data)
        ret = true;
 out:
        h->ops->clear_cs(&this);
+       h->ops->clear_cs(cs);
        return ret;
 }
 
index bee99a7dd0c9301d50211a57b08ffec4440001d0..89e9d0b9be33516071caf8981ca31ac8a2fae102 100644 (file)
@@ -110,7 +110,7 @@ struct nft_family_ops {
                           struct iptables_command_state *cs);
        void (*clear_cs)(struct iptables_command_state *cs);
        bool (*rule_find)(struct nft_handle *h, struct nftnl_rule *r,
-                         void *data);
+                         struct nftnl_rule *rule);
        int (*xlate)(const void *data, struct xt_xlate *xl);
 };
 
@@ -172,7 +172,7 @@ struct nft_family_ops *nft_family_ops_lookup(int family);
 
 void nft_ipv46_parse_target(struct xtables_target *t, void *data);
 bool nft_ipv46_rule_find(struct nft_handle *h, struct nftnl_rule *r,
-                        void *data);
+                        struct nftnl_rule *rule);
 
 bool compare_matches(struct xtables_rule_match *mt1, struct xtables_rule_match *mt2);
 bool compare_targets(struct xtables_target *tg1, struct xtables_target *tg2);
index 468c703a1d09fbca822c777cb0aa6c97af7f9245..bbbf7c6166ac6b5d6f011e9edbcecfb04e0778be 100644 (file)
@@ -256,24 +256,6 @@ static int mnl_batch_talk(struct nft_handle *h, int numcmds)
        return err;
 }
 
-enum obj_update_type {
-       NFT_COMPAT_TABLE_ADD,
-       NFT_COMPAT_TABLE_FLUSH,
-       NFT_COMPAT_CHAIN_ADD,
-       NFT_COMPAT_CHAIN_USER_ADD,
-       NFT_COMPAT_CHAIN_USER_DEL,
-       NFT_COMPAT_CHAIN_USER_FLUSH,
-       NFT_COMPAT_CHAIN_UPDATE,
-       NFT_COMPAT_CHAIN_RENAME,
-       NFT_COMPAT_CHAIN_ZERO,
-       NFT_COMPAT_RULE_APPEND,
-       NFT_COMPAT_RULE_INSERT,
-       NFT_COMPAT_RULE_REPLACE,
-       NFT_COMPAT_RULE_DELETE,
-       NFT_COMPAT_RULE_FLUSH,
-       NFT_COMPAT_SET_ADD,
-};
-
 enum obj_action {
        NFT_COMPAT_COMMIT,
        NFT_COMPAT_ABORT,
@@ -362,6 +344,15 @@ static int mnl_append_error(const struct nft_handle *h,
                snprintf(tcr, sizeof(tcr), "set %s",
                         nftnl_set_get_str(o->set, NFTNL_SET_NAME));
                break;
+       case NFT_COMPAT_RULE_LIST:
+       case NFT_COMPAT_RULE_CHECK:
+       case NFT_COMPAT_CHAIN_RESTORE:
+       case NFT_COMPAT_RULE_SAVE:
+       case NFT_COMPAT_RULE_ZERO:
+       case NFT_COMPAT_BRIDGE_USER_CHAIN_UPDATE:
+       case NFT_COMPAT_TABLE_NEW:
+               assert(0);
+               break;
        }
 
        return snprintf(buf, len, "%s: %s", errmsg, tcr);
@@ -813,12 +804,18 @@ int nft_init(struct nft_handle *h, int family, const struct builtin_table *t)
 
        INIT_LIST_HEAD(&h->obj_list);
        INIT_LIST_HEAD(&h->err_list);
+       INIT_LIST_HEAD(&h->cmd_list);
 
        return 0;
 }
 
 void nft_fini(struct nft_handle *h)
 {
+       struct nft_cmd *cmd, *next;
+
+       list_for_each_entry_safe(cmd, next, &h->cmd_list, head)
+               nft_cmd_free(cmd);
+
        flush_chain_cache(h, NULL);
        mnl_socket_close(h->nl);
 }
@@ -1327,7 +1324,7 @@ void add_compat(struct nftnl_rule *r, uint32_t proto, bool inv)
                              inv ? NFT_RULE_COMPAT_F_INV : 0);
 }
 
-static struct nftnl_rule *
+struct nftnl_rule *
 nft_rule_new(struct nft_handle *h, const char *chain, const char *table,
             void *data)
 {
@@ -1355,10 +1352,9 @@ nft_chain_find(struct nft_handle *h, const char *table, const char *chain);
 
 int
 nft_rule_append(struct nft_handle *h, const char *chain, const char *table,
-               void *data, struct nftnl_rule *ref, bool verbose)
+               struct nftnl_rule *r, struct nftnl_rule *ref, bool verbose)
 {
        struct nftnl_chain *c;
-       struct nftnl_rule *r;
        int type;
 
        nft_xt_builtin_init(h, table);
@@ -1373,10 +1369,6 @@ nft_rule_append(struct nft_handle *h, const char *chain, const char *table,
 
        nft_fn = nft_rule_append;
 
-       r = nft_rule_new(h, chain, table, data);
-       if (r == NULL)
-               return 0;
-
        if (ref) {
                nftnl_rule_set_u64(r, NFTNL_RULE_HANDLE,
                                   nftnl_rule_get_u64(ref, NFTNL_RULE_HANDLE));
@@ -1384,10 +1376,8 @@ nft_rule_append(struct nft_handle *h, const char *chain, const char *table,
        } else
                type = NFT_COMPAT_RULE_APPEND;
 
-       if (batch_rule_add(h, type, r) == NULL) {
-               nftnl_rule_free(r);
+       if (batch_rule_add(h, type, r) == NULL)
                return 0;
-       }
 
        if (verbose)
                h->ops->print_rule(h, r, 0, FMT_PRINT_RULE);
@@ -1747,7 +1737,7 @@ int nft_chain_restore(struct nft_handle *h, const char *chain, const char *table
        } else {
                c = nftnl_chain_alloc();
                if (!c)
-                       return -1;
+                       return 0;
 
                nftnl_chain_set_str(c, NFTNL_CHAIN_TABLE, table);
                nftnl_chain_set_str(c, NFTNL_CHAIN_NAME, chain);
@@ -1758,7 +1748,7 @@ int nft_chain_restore(struct nft_handle *h, const char *chain, const char *table
                nftnl_chain_set_u32(c, NFTNL_CHAIN_POLICY, NF_ACCEPT);
 
        if (!created)
-               return 0;
+               return 1;
 
        ret = batch_chain_add(h, NFT_COMPAT_CHAIN_USER_ADD, c);
 
@@ -1766,7 +1756,8 @@ int nft_chain_restore(struct nft_handle *h, const char *chain, const char *table
        if (list)
                nftnl_chain_list_add(c, list);
 
-       return ret;
+       /* the core expects 1 for success and 0 for error */
+       return ret == 0 ? 1 : 0;
 }
 
 /* From linux/netlink.h */
@@ -2073,7 +2064,8 @@ static int __nft_rule_del(struct nft_handle *h, struct nftnl_rule *r)
 }
 
 static struct nftnl_rule *
-nft_rule_find(struct nft_handle *h, struct nftnl_chain *c, void *data, int rulenum)
+nft_rule_find(struct nft_handle *h, struct nftnl_chain *c,
+             struct nftnl_rule *rule, int rulenum)
 {
        struct nftnl_rule *r;
        struct nftnl_rule_iter *iter;
@@ -2091,7 +2083,7 @@ nft_rule_find(struct nft_handle *h, struct nftnl_chain *c, void *data, int rulen
 
        r = nftnl_rule_iter_next(iter);
        while (r != NULL) {
-               found = h->ops->rule_find(h, r, data);
+               found = h->ops->rule_find(h, r, rule);
                if (found)
                        break;
                r = nftnl_rule_iter_next(iter);
@@ -2103,7 +2095,7 @@ nft_rule_find(struct nft_handle *h, struct nftnl_chain *c, void *data, int rulen
 }
 
 int nft_rule_check(struct nft_handle *h, const char *chain,
-                  const char *table, void *data, bool verbose)
+                  const char *table, struct nftnl_rule *rule, bool verbose)
 {
        struct nftnl_chain *c;
        struct nftnl_rule *r;
@@ -2114,7 +2106,7 @@ int nft_rule_check(struct nft_handle *h, const char *chain,
        if (!c)
                goto fail_enoent;
 
-       r = nft_rule_find(h, c, data, -1);
+       r = nft_rule_find(h, c, rule, -1);
        if (r == NULL)
                goto fail_enoent;
 
@@ -2128,7 +2120,7 @@ fail_enoent:
 }
 
 int nft_rule_delete(struct nft_handle *h, const char *chain,
-                   const char *table, void *data, bool verbose)
+                   const char *table, struct nftnl_rule *rule, bool verbose)
 {
        int ret = 0;
        struct nftnl_chain *c;
@@ -2142,7 +2134,7 @@ int nft_rule_delete(struct nft_handle *h, const char *chain,
                return 0;
        }
 
-       r = nft_rule_find(h, c, data, -1);
+       r = nft_rule_find(h, c, rule, -1);
        if (r != NULL) {
                ret =__nft_rule_del(h, r);
                if (ret < 0)
@@ -2157,16 +2149,11 @@ int nft_rule_delete(struct nft_handle *h, const char *chain,
 
 static struct nftnl_rule *
 nft_rule_add(struct nft_handle *h, const char *chain,
-            const char *table, struct iptables_command_state *cs,
+            const char *table, struct nftnl_rule *r,
             struct nftnl_rule *ref, bool verbose)
 {
-       struct nftnl_rule *r;
        uint64_t ref_id;
 
-       r = nft_rule_new(h, chain, table, cs);
-       if (r == NULL)
-               return NULL;
-
        if (ref) {
                ref_id = nftnl_rule_get_u64(ref, NFTNL_RULE_HANDLE);
                if (ref_id > 0) {
@@ -2183,10 +2170,8 @@ nft_rule_add(struct nft_handle *h, const char *chain,
                }
        }
 
-       if (!batch_rule_add(h, NFT_COMPAT_RULE_INSERT, r)) {
-               nftnl_rule_free(r);
+       if (!batch_rule_add(h, NFT_COMPAT_RULE_INSERT, r))
                return NULL;
-       }
 
        if (verbose)
                h->ops->print_rule(h, r, 0, FMT_PRINT_RULE);
@@ -2195,9 +2180,10 @@ nft_rule_add(struct nft_handle *h, const char *chain,
 }
 
 int nft_rule_insert(struct nft_handle *h, const char *chain,
-                   const char *table, void *data, int rulenum, bool verbose)
+                   const char *table, struct nftnl_rule *new_rule, int rulenum,
+                   bool verbose)
 {
-       struct nftnl_rule *r = NULL, *new_rule;
+       struct nftnl_rule *r = NULL;
        struct nftnl_chain *c;
 
        nft_xt_builtin_init(h, table);
@@ -2211,22 +2197,22 @@ int nft_rule_insert(struct nft_handle *h, const char *chain,
        }
 
        if (rulenum > 0) {
-               r = nft_rule_find(h, c, data, rulenum);
+               r = nft_rule_find(h, c, new_rule, rulenum);
                if (r == NULL) {
                        /* special case: iptables allows to insert into
                         * rule_count + 1 position.
                         */
-                       r = nft_rule_find(h, c, data, rulenum - 1);
+                       r = nft_rule_find(h, c, new_rule, rulenum - 1);
                        if (r != NULL)
-                               return nft_rule_append(h, chain, table, data,
-                                                      NULL, verbose);
+                               return nft_rule_append(h, chain, table,
+                                                      new_rule, NULL, verbose);
 
                        errno = E2BIG;
                        goto err;
                }
        }
 
-       new_rule = nft_rule_add(h, chain, table, data, r, verbose);
+       new_rule = nft_rule_add(h, chain, table, new_rule, r, verbose);
        if (!new_rule)
                goto err;
 
@@ -2268,7 +2254,8 @@ int nft_rule_delete_num(struct nft_handle *h, const char *chain,
 }
 
 int nft_rule_replace(struct nft_handle *h, const char *chain,
-                    const char *table, void *data, int rulenum, bool verbose)
+                    const char *table, struct nftnl_rule *rule,
+                    int rulenum, bool verbose)
 {
        int ret = 0;
        struct nftnl_chain *c;
@@ -2282,13 +2269,13 @@ int nft_rule_replace(struct nft_handle *h, const char *chain,
                return 0;
        }
 
-       r = nft_rule_find(h, c, data, rulenum);
+       r = nft_rule_find(h, c, rule, rulenum);
        if (r != NULL) {
                DEBUGP("replacing rule with handle=%llu\n",
                        (unsigned long long)
                        nftnl_rule_get_u64(r, NFTNL_RULE_HANDLE));
 
-               ret = nft_rule_append(h, chain, table, data, r, verbose);
+               ret = nft_rule_append(h, chain, table, rule, r, verbose);
        } else
                errno = E2BIG;
 
@@ -2521,8 +2508,8 @@ int nft_rule_zero_counters(struct nft_handle *h, const char *chain,
                           const char *table, int rulenum)
 {
        struct iptables_command_state cs = {};
+       struct nftnl_rule *r, *new_rule;
        struct nftnl_chain *c;
-       struct nftnl_rule *r;
        int ret = 0;
 
        nft_fn = nft_rule_delete;
@@ -2541,8 +2528,11 @@ int nft_rule_zero_counters(struct nft_handle *h, const char *chain,
        nft_rule_to_iptables_command_state(h, r, &cs);
 
        cs.counters.pcnt = cs.counters.bcnt = 0;
+       new_rule = nft_rule_new(h, chain, table, &cs);
+       if (!new_rule)
+               return 1;
 
-       ret =  nft_rule_append(h, chain, table, &cs, r, false);
+       ret = nft_rule_append(h, chain, table, new_rule, r, false);
 
 error:
        return ret;
@@ -2644,6 +2634,15 @@ static void batch_obj_del(struct nft_handle *h, struct obj_update *o)
        case NFT_COMPAT_SET_ADD:
                nftnl_set_free(o->set);
                break;
+       case NFT_COMPAT_RULE_LIST:
+       case NFT_COMPAT_RULE_CHECK:
+       case NFT_COMPAT_CHAIN_RESTORE:
+       case NFT_COMPAT_RULE_SAVE:
+       case NFT_COMPAT_RULE_ZERO:
+       case NFT_COMPAT_BRIDGE_USER_CHAIN_UPDATE:
+       case NFT_COMPAT_TABLE_NEW:
+               assert(0);
+               break;
        }
        h->obj_list_num--;
        list_del(&o->head);
@@ -2711,6 +2710,13 @@ static void nft_refresh_transaction(struct nft_handle *h)
                case NFT_COMPAT_RULE_DELETE:
                case NFT_COMPAT_RULE_FLUSH:
                case NFT_COMPAT_SET_ADD:
+               case NFT_COMPAT_RULE_LIST:
+               case NFT_COMPAT_RULE_CHECK:
+               case NFT_COMPAT_CHAIN_RESTORE:
+               case NFT_COMPAT_RULE_SAVE:
+               case NFT_COMPAT_RULE_ZERO:
+               case NFT_COMPAT_BRIDGE_USER_CHAIN_UPDATE:
+               case NFT_COMPAT_TABLE_NEW:
                        break;
                }
        }
@@ -2808,6 +2814,14 @@ retry:
                                                     NLM_F_CREATE, &n->seq, n->set);
                        seq = n->seq;
                        break;
+               case NFT_COMPAT_RULE_LIST:
+               case NFT_COMPAT_RULE_CHECK:
+               case NFT_COMPAT_CHAIN_RESTORE:
+               case NFT_COMPAT_RULE_SAVE:
+               case NFT_COMPAT_RULE_ZERO:
+               case NFT_COMPAT_BRIDGE_USER_CHAIN_UPDATE:
+               case NFT_COMPAT_TABLE_NEW:
+                       assert(0);
                }
 
                mnl_nft_batch_continue(h->batch);
@@ -2969,19 +2983,145 @@ static void nft_bridge_commit_prepare(struct nft_handle *h)
        }
 }
 
+static void assert_chain_exists(struct nft_handle *h,
+                               const char *table, const char *chain)
+{
+       if (chain && !nft_chain_exists(h, table, chain))
+               xtables_error(PARAMETER_PROBLEM,
+                             "Chain '%s' does not exist", chain);
+}
+
+static int nft_prepare(struct nft_handle *h)
+{
+       struct nft_cmd *cmd, *next;
+       int ret = 1;
+
+       list_for_each_entry_safe(cmd, next, &h->cmd_list, head) {
+               switch (cmd->command) {
+               case NFT_COMPAT_TABLE_FLUSH:
+                       ret = nft_table_flush(h, cmd->table);
+                       break;
+               case NFT_COMPAT_CHAIN_USER_ADD:
+                       ret = nft_chain_user_add(h, cmd->chain, cmd->table);
+                       break;
+               case NFT_COMPAT_CHAIN_USER_DEL:
+                       ret = nft_chain_user_del(h, cmd->chain, cmd->table,
+                                                cmd->verbose);
+                       break;
+               case NFT_COMPAT_CHAIN_RESTORE:
+                       ret = nft_chain_restore(h, cmd->chain, cmd->table);
+                       break;
+               case NFT_COMPAT_CHAIN_UPDATE:
+                       ret = nft_chain_set(h, cmd->table, cmd->chain,
+                                           cmd->policy, &cmd->counters);
+                       break;
+               case NFT_COMPAT_CHAIN_RENAME:
+                       ret = nft_chain_user_rename(h, cmd->chain, cmd->table,
+                                                   cmd->rename);
+                       break;
+               case NFT_COMPAT_CHAIN_ZERO:
+                       ret = nft_chain_zero_counters(h, cmd->chain, cmd->table,
+                                                     cmd->verbose);
+                       break;
+               case NFT_COMPAT_RULE_APPEND:
+                       assert_chain_exists(h, cmd->table, cmd->jumpto);
+                       ret = nft_rule_append(h, cmd->chain, cmd->table,
+                                             cmd->obj.rule, NULL, cmd->verbose);
+                       break;
+               case NFT_COMPAT_RULE_INSERT:
+                       assert_chain_exists(h, cmd->table, cmd->jumpto);
+                       ret = nft_rule_insert(h, cmd->chain, cmd->table,
+                                             cmd->obj.rule, cmd->rulenum,
+                                             cmd->verbose);
+                       break;
+               case NFT_COMPAT_RULE_REPLACE:
+                       assert_chain_exists(h, cmd->table, cmd->jumpto);
+                       ret = nft_rule_replace(h, cmd->chain, cmd->table,
+                                             cmd->obj.rule, cmd->rulenum,
+                                             cmd->verbose);
+                       break;
+               case NFT_COMPAT_RULE_DELETE:
+                       assert_chain_exists(h, cmd->table, cmd->jumpto);
+                       if (cmd->rulenum >= 0)
+                               ret = nft_rule_delete_num(h, cmd->chain,
+                                                         cmd->table,
+                                                         cmd->rulenum,
+                                                         cmd->verbose);
+                       else
+                               ret = nft_rule_delete(h, cmd->chain, cmd->table,
+                                                     cmd->obj.rule, cmd->verbose);
+                       break;
+               case NFT_COMPAT_RULE_FLUSH:
+                       ret = nft_rule_flush(h, cmd->chain, cmd->table,
+                                            cmd->verbose);
+                       break;
+               case NFT_COMPAT_RULE_LIST:
+                       ret = nft_rule_list(h, cmd->chain, cmd->table,
+                                           cmd->rulenum, cmd->format);
+                       break;
+               case NFT_COMPAT_RULE_CHECK:
+                       assert_chain_exists(h, cmd->table, cmd->jumpto);
+                       ret = nft_rule_check(h, cmd->chain, cmd->table,
+                                            cmd->obj.rule, cmd->rulenum);
+                       break;
+               case NFT_COMPAT_RULE_ZERO:
+                       ret = nft_rule_zero_counters(h, cmd->chain, cmd->table,
+                                                     cmd->rulenum);
+                       break;
+               case NFT_COMPAT_RULE_SAVE:
+                       ret = nft_rule_list_save(h, cmd->chain, cmd->table,
+                                                cmd->rulenum,
+                                                cmd->counters_save);
+                       break;
+               case NFT_COMPAT_BRIDGE_USER_CHAIN_UPDATE:
+                       ret = ebt_set_user_chain_policy(h, cmd->table,
+                                                       cmd->chain, cmd->policy);
+                       break;
+               case NFT_COMPAT_TABLE_NEW:
+                       nft_xt_builtin_init(h, cmd->table);
+                       ret = 1;
+                       break;
+               case NFT_COMPAT_TABLE_ADD:
+               case NFT_COMPAT_CHAIN_ADD:
+               case NFT_COMPAT_SET_ADD:
+                       assert(0);
+                       break;
+               }
+
+               nft_cmd_free(cmd);
+
+               if (ret == 0)
+                       return 0;
+       }
+
+       return 1;
+}
+
 int nft_commit(struct nft_handle *h)
 {
+       if (!nft_prepare(h))
+               return 0;
+
        return nft_action(h, NFT_COMPAT_COMMIT);
 }
 
 int nft_bridge_commit(struct nft_handle *h)
 {
+       if (!nft_prepare(h))
+               return 0;
+
        nft_bridge_commit_prepare(h);
-       return nft_commit(h);
+
+       return nft_action(h, NFT_COMPAT_COMMIT);
 }
 
 int nft_abort(struct nft_handle *h)
 {
+       struct nft_cmd *cmd, *next;
+
+       list_for_each_entry_safe(cmd, next, &h->cmd_list, head)
+               nft_cmd_free(cmd);
+
        return nft_action(h, NFT_COMPAT_ABORT);
 }
 
index ebb4044d1a453041b058e0c4ea34a52e539399a7..7ddc3a8bbb0426081faf4a51ed13ac4b67e6efd3 100644 (file)
@@ -3,6 +3,8 @@
 
 #include "xshared.h"
 #include "nft-shared.h"
+#include "nft-cache.h"
+#include "nft-cmd.h"
 #include <libiptc/linux_list.h>
 
 enum nft_table_type {
@@ -45,6 +47,31 @@ struct nft_cache {
        } table[NFT_TABLE_MAX];
 };
 
+enum obj_update_type {
+       NFT_COMPAT_TABLE_ADD,
+       NFT_COMPAT_TABLE_FLUSH,
+       NFT_COMPAT_CHAIN_ADD,
+       NFT_COMPAT_CHAIN_USER_ADD,
+       NFT_COMPAT_CHAIN_USER_DEL,
+       NFT_COMPAT_CHAIN_USER_FLUSH,
+       NFT_COMPAT_CHAIN_UPDATE,
+       NFT_COMPAT_CHAIN_RENAME,
+       NFT_COMPAT_CHAIN_ZERO,
+       NFT_COMPAT_RULE_APPEND,
+       NFT_COMPAT_RULE_INSERT,
+       NFT_COMPAT_RULE_REPLACE,
+       NFT_COMPAT_RULE_DELETE,
+       NFT_COMPAT_RULE_FLUSH,
+       NFT_COMPAT_SET_ADD,
+       NFT_COMPAT_RULE_LIST,
+       NFT_COMPAT_RULE_CHECK,
+       NFT_COMPAT_CHAIN_RESTORE,
+       NFT_COMPAT_RULE_SAVE,
+       NFT_COMPAT_RULE_ZERO,
+       NFT_COMPAT_BRIDGE_USER_CHAIN_UPDATE,
+       NFT_COMPAT_TABLE_NEW,
+};
+
 struct nft_handle {
        int                     family;
        struct mnl_socket       *nl;
@@ -67,6 +94,7 @@ struct nft_handle {
        bool                    restore;
        bool                    noflush;
        int8_t                  config_done;
+       struct list_head        cmd_list;
 
        /* meta data, for error reporting */
        struct {
@@ -121,12 +149,13 @@ void nft_bridge_chain_postprocess(struct nft_handle *h,
  */
 struct nftnl_rule;
 
-int nft_rule_append(struct nft_handle *h, const char *chain, const char *table, void *data, struct nftnl_rule *ref, bool verbose);
-int nft_rule_insert(struct nft_handle *h, const char *chain, const char *table, void *data, int rulenum, bool verbose);
-int nft_rule_check(struct nft_handle *h, const char *chain, const char *table, void *data, bool verbose);
-int nft_rule_delete(struct nft_handle *h, const char *chain, const char *table, void *data, bool verbose);
+struct nftnl_rule *nft_rule_new(struct nft_handle *h, const char *chain, const char *table, void *data);
+int nft_rule_append(struct nft_handle *h, const char *chain, const char *table, struct nftnl_rule *r, struct nftnl_rule *ref, bool verbose);
+int nft_rule_insert(struct nft_handle *h, const char *chain, const char *table, struct nftnl_rule *r, int rulenum, bool verbose);
+int nft_rule_check(struct nft_handle *h, const char *chain, const char *table, struct nftnl_rule *r, bool verbose);
+int nft_rule_delete(struct nft_handle *h, const char *chain, const char *table, struct nftnl_rule *r, bool verbose);
 int nft_rule_delete_num(struct nft_handle *h, const char *chain, const char *table, int rulenum, bool verbose);
-int nft_rule_replace(struct nft_handle *h, const char *chain, const char *table, void *data, int rulenum, bool verbose);
+int nft_rule_replace(struct nft_handle *h, const char *chain, const char *table, struct nftnl_rule *r, int rulenum, bool verbose);
 int nft_rule_list(struct nft_handle *h, const char *chain, const char *table, int rulenum, unsigned int format);
 int nft_rule_list_save(struct nft_handle *h, const char *chain, const char *table, int rulenum, int counters);
 int nft_rule_save(struct nft_handle *h, const char *table, unsigned int format);
index f023b7915498e3abf9e24fd3bddf7c52a4ac9f57..c583b0ebd97c3fa3078ea6012edc96a71eb3c343 100755 (executable)
@@ -26,6 +26,7 @@ cmd 1 ip6tables -N foo
 # test rule adding
 cmd 0 ip6tables -A INPUT -j ACCEPT
 cmd 1 ip6tables -A noexist -j ACCEPT
+cmd 2 ip6tables -I INPUT -j foobar
 
 # test rule checking
 cmd 0 ip6tables -C INPUT -j ACCEPT
index ce02e0bcb128ba23a500ecf91b3b1e637305a734..f730bede1f6125180c92a27da00ae1e9dce47b22 100755 (executable)
@@ -54,10 +54,16 @@ cmd 1 "$ENOENT" iptables -Z bar
 # test chain rename
 cmd 0 iptables -E foo bar
 cmd 1 "$EEXIST_F" iptables -E foo bar
+cmd 1 "$ENOENT" iptables -E foo bar2
+cmd 0 iptables -N foo2
+cmd 1 "$EEXIST_F" iptables -E foo2 bar
 
 # test rule adding
 cmd 0 iptables -A INPUT -j ACCEPT
 cmd 1 "$ENOENT" iptables -A noexist -j ACCEPT
+cmd 2 "" iptables -I INPUT -j foobar
+cmd 2 "" iptables -R INPUT 1 -j foobar
+cmd 2 "" iptables -D INPUT -j foobar
 
 # test rulenum commands
 cmd 1 "$E2BIG_I" iptables -I INPUT 23 -j ACCEPT
index c8196f08baa59de794406c0ae30fc02700a9a815..a0136059bb7109e6a012428d7a91320f270710ae 100644 (file)
@@ -400,7 +400,7 @@ list_entries(struct nft_handle *h, const char *chain, const char *table,
        if (linenumbers)
                format |= FMT_LINENUMBERS;
 
-       return nft_rule_list(h, chain, table, rulenum, format);
+       return nft_cmd_rule_list(h, chain, table, rulenum, format);
 }
 
 static int
@@ -427,10 +427,10 @@ append_entry(struct nft_handle *h,
                        cs->arp.arp.tgt.s_addr = daddrs[j].s_addr;
                        cs->arp.arp.tmsk.s_addr = dmasks[j].s_addr;
                        if (append) {
-                               ret = nft_rule_append(h, chain, table, cs, NULL,
+                               ret = nft_cmd_rule_append(h, chain, table, cs, NULL,
                                                      verbose);
                        } else {
-                               ret = nft_rule_insert(h, chain, table, cs,
+                               ret = nft_cmd_rule_insert(h, chain, table, cs,
                                                      rulenum, verbose);
                        }
                }
@@ -455,7 +455,7 @@ replace_entry(const char *chain,
        cs->arp.arp.smsk.s_addr = smask->s_addr;
        cs->arp.arp.tmsk.s_addr = dmask->s_addr;
 
-       return nft_rule_replace(h, chain, table, cs, rulenum, verbose);
+       return nft_cmd_rule_replace(h, chain, table, cs, rulenum, verbose);
 }
 
 static int
@@ -479,7 +479,7 @@ delete_entry(const char *chain,
                for (j = 0; j < ndaddrs; j++) {
                        cs->arp.arp.tgt.s_addr = daddrs[j].s_addr;
                        cs->arp.arp.tmsk.s_addr = dmasks[j].s_addr;
-                       ret = nft_rule_delete(h, chain, table, cs, verbose);
+                       ret = nft_cmd_rule_delete(h, chain, table, cs, verbose);
                }
        }
 
@@ -955,7 +955,7 @@ int do_commandarp(struct nft_handle *h, int argc, char *argv[], char **table,
                                   options&OPT_VERBOSE, h);
                break;
        case CMD_DELETE_NUM:
-               ret = nft_rule_delete_num(h, chain, *table, rulenum - 1, verbose);
+               ret = nft_cmd_rule_delete_num(h, chain, *table, rulenum - 1, verbose);
                break;
        case CMD_REPLACE:
                ret = replace_entry(chain, *table, &cs, rulenum - 1,
@@ -977,10 +977,10 @@ int do_commandarp(struct nft_handle *h, int argc, char *argv[], char **table,
                                   options&OPT_LINENUMBERS);
                break;
        case CMD_FLUSH:
-               ret = nft_rule_flush(h, chain, *table, options & OPT_VERBOSE);
+               ret = nft_cmd_rule_flush(h, chain, *table, options & OPT_VERBOSE);
                break;
        case CMD_ZERO:
-               ret = nft_chain_zero_counters(h, chain, *table,
+               ret = nft_cmd_chain_zero_counters(h, chain, *table,
                                              options & OPT_VERBOSE);
                break;
        case CMD_LIST|CMD_ZERO:
@@ -990,21 +990,21 @@ int do_commandarp(struct nft_handle *h, int argc, char *argv[], char **table,
                                   /*options&OPT_EXPANDED*/0,
                                   options&OPT_LINENUMBERS);
                if (ret)
-                       ret = nft_chain_zero_counters(h, chain, *table,
+                       ret = nft_cmd_chain_zero_counters(h, chain, *table,
                                                      options & OPT_VERBOSE);
                break;
        case CMD_NEW_CHAIN:
-               ret = nft_chain_user_add(h, chain, *table);
+               ret = nft_cmd_chain_user_add(h, chain, *table);
                break;
        case CMD_DELETE_CHAIN:
-               ret = nft_chain_user_del(h, chain, *table,
+               ret = nft_cmd_chain_user_del(h, chain, *table,
                                         options & OPT_VERBOSE);
                break;
        case CMD_RENAME_CHAIN:
-               ret = nft_chain_user_rename(h, chain, *table, newname);
+               ret = nft_cmd_chain_user_rename(h, chain, *table, newname);
                break;
        case CMD_SET_POLICY:
-               ret = nft_chain_set(h, *table, chain, policy, NULL);
+               ret = nft_cmd_chain_set(h, *table, chain, policy, NULL);
                if (ret < 0)
                        xtables_error(PARAMETER_PROBLEM, "Wrong policy `%s'\n",
                                      policy);
index c006bc95ac6816d6b480250efde0c2b5ebd842ae..07ed651370913ab5843ee7ba1e5bb5c1b58be57d 100644 (file)
@@ -150,9 +150,9 @@ append_entry(struct nft_handle *h,
        int ret = 1;
 
        if (append)
-               ret = nft_rule_append(h, chain, table, cs, NULL, verbose);
+               ret = nft_cmd_rule_append(h, chain, table, cs, NULL, verbose);
        else
-               ret = nft_rule_insert(h, chain, table, cs, rule_nr, verbose);
+               ret = nft_cmd_rule_insert(h, chain, table, cs, rule_nr, verbose);
 
        return ret;
 }
@@ -169,10 +169,10 @@ delete_entry(struct nft_handle *h,
        int ret = 1;
 
        if (rule_nr == -1)
-               ret = nft_rule_delete(h, chain, table, cs, verbose);
+               ret = nft_cmd_rule_delete(h, chain, table, cs, verbose);
        else {
                do {
-                       ret = nft_rule_delete_num(h, chain, table,
+                       ret = nft_cmd_rule_delete_num(h, chain, table,
                                                  rule_nr, verbose);
                        rule_nr++;
                } while (rule_nr < rule_nr_end);
@@ -427,7 +427,7 @@ static int list_rules(struct nft_handle *h, const char *chain, const char *table
        if (!counters)
                format |= FMT_NOCOUNTS;
 
-       return nft_rule_list(h, chain, table, rule_nr, format);
+       return nft_cmd_rule_list(h, chain, table, rule_nr, format);
 }
 
 static int parse_rule_range(const char *argv, int *rule_nr, int *rule_nr_end)
@@ -813,7 +813,7 @@ int do_commandeb(struct nft_handle *h, int argc, char *argv[], char **table,
                        flags |= OPT_COMMAND;
 
                        if (c == 'N') {
-                               ret = nft_chain_user_add(h, chain, *table);
+                               ret = nft_cmd_chain_user_add(h, chain, *table);
                                break;
                        } else if (c == 'X') {
                                /* X arg is optional, optarg is NULL */
@@ -821,7 +821,7 @@ int do_commandeb(struct nft_handle *h, int argc, char *argv[], char **table,
                                        chain = argv[optind];
                                        optind++;
                                }
-                               ret = nft_chain_user_del(h, chain, *table, 0);
+                               ret = nft_cmd_chain_user_del(h, chain, *table, 0);
                                break;
                        }
 
@@ -835,7 +835,7 @@ int do_commandeb(struct nft_handle *h, int argc, char *argv[], char **table,
                                else if (strchr(argv[optind], ' ') != NULL)
                                        xtables_error(PARAMETER_PROBLEM, "Use of ' ' not allowed in chain names");
 
-                               ret = nft_chain_user_rename(h, chain, *table,
+                               ret = nft_cmd_chain_user_rename(h, chain, *table,
                                                            argv[optind]);
                                if (ret != 0 && errno == ENOENT)
                                        xtables_error(PARAMETER_PROBLEM, "Chain '%s' doesn't exists", chain);
@@ -1137,7 +1137,7 @@ print_zero:
                /*case 7 :*/ /* atomic-init */
                /*case 10:*/ /* atomic-save */
                case 11: /* init-table */
-                       nft_table_flush(h, *table);
+                       nft_cmd_table_flush(h, *table);
                        return 1;
                /*
                        replace->command = c;
@@ -1225,13 +1225,13 @@ print_zero:
 
        if (command == 'P') {
                if (selected_chain >= NF_BR_NUMHOOKS) {
-                       ret = ebt_set_user_chain_policy(h, *table, chain, policy);
+                       ret = ebt_cmd_user_chain_policy(h, *table, chain, policy);
                } else {
                        if (strcmp(policy, "RETURN") == 0) {
                                xtables_error(PARAMETER_PROBLEM,
                                              "Policy RETURN only allowed for user defined chains");
                        }
-                       ret = nft_chain_set(h, *table, chain, policy, NULL);
+                       ret = nft_cmd_chain_set(h, *table, chain, policy, NULL);
                        if (ret < 0)
                                xtables_error(PARAMETER_PROBLEM, "Wrong policy");
                }
@@ -1244,9 +1244,9 @@ print_zero:
                                 flags&LIST_C);
        }
        if (flags & OPT_ZERO) {
-               ret = nft_chain_zero_counters(h, chain, *table, 0);
+               ret = nft_cmd_chain_zero_counters(h, chain, *table, 0);
        } else if (command == 'F') {
-               ret = nft_rule_flush(h, chain, *table, 0);
+               ret = nft_cmd_rule_flush(h, chain, *table, 0);
        } else if (command == 'A') {
                ret = append_entry(h, chain, *table, &cs, 0, 0, true);
        } else if (command == 'I') {
index 136bff8e067fdf588496b274d4c97d01a3bb2460..55547e3af9d2e2f40bba39520da6968ef7c51d20 100644 (file)
@@ -61,11 +61,11 @@ static void print_usage(const char *name, const char *version)
 static const struct nft_xt_restore_cb restore_cb = {
        .commit         = nft_commit,
        .abort          = nft_abort,
-       .table_new      = nft_table_new,
-       .table_flush    = nft_table_flush,
+       .table_new      = nft_cmd_table_new,
+       .table_flush    = nft_cmd_table_flush,
        .do_command     = do_commandx,
-       .chain_set      = nft_chain_set,
-       .chain_restore  = nft_chain_restore,
+       .chain_set      = nft_cmd_chain_set,
+       .chain_restore  = nft_cmd_chain_restore,
 };
 
 struct nft_xt_restore_state {
@@ -195,7 +195,7 @@ static void xtables_restore_parse_line(struct nft_handle *h,
                                      "cannot create chain '%s' (%s)\n",
                                      chain, strerror(errno));
                } else if (h->family == NFPROTO_BRIDGE &&
-                          !ebt_set_user_chain_policy(h, state->curtable->name,
+                          !ebt_cmd_user_chain_policy(h, state->curtable->name,
                                                      chain, policy)) {
                        xtables_error(OTHER_PROBLEM,
                                      "Can't set policy `%s' on `%s' line %u: %s\n",
@@ -492,11 +492,11 @@ int xtables_ip6_restore_main(int argc, char *argv[])
 
 static const struct nft_xt_restore_cb ebt_restore_cb = {
        .commit         = nft_bridge_commit,
-       .table_new      = nft_table_new,
-       .table_flush    = nft_table_flush,
+       .table_new      = nft_cmd_table_new,
+       .table_flush    = nft_cmd_table_flush,
        .do_command     = do_commandeb,
-       .chain_set      = nft_chain_set,
-       .chain_restore  = nft_chain_restore,
+       .chain_set      = nft_cmd_chain_set,
+       .chain_restore  = nft_cmd_chain_restore,
 };
 
 static const struct option ebt_restore_options[] = {
@@ -538,11 +538,11 @@ int xtables_eb_restore_main(int argc, char *argv[])
 
 static const struct nft_xt_restore_cb arp_restore_cb = {
        .commit         = nft_commit,
-       .table_new      = nft_table_new,
-       .table_flush    = nft_table_flush,
+       .table_new      = nft_cmd_table_new,
+       .table_flush    = nft_cmd_table_flush,
        .do_command     = do_commandarp,
-       .chain_set      = nft_chain_set,
-       .chain_restore  = nft_chain_restore,
+       .chain_set      = nft_cmd_chain_set,
+       .chain_restore  = nft_cmd_chain_restore,
 };
 
 int xtables_arp_restore_main(int argc, char *argv[])
index 8c2d21d42b7d2f12d0a03d277eab21a63cb4fdd6..c180af13975f81d9bd5d450a11c564598f5e2ad0 100644 (file)
@@ -361,11 +361,11 @@ add_entry(const char *chain,
                                cs->fw.ip.dmsk.s_addr = d.mask.v4[j].s_addr;
 
                                if (append) {
-                                       ret = nft_rule_append(h, chain, table,
+                                       ret = nft_cmd_rule_append(h, chain, table,
                                                              cs, NULL,
                                                              verbose);
                                } else {
-                                       ret = nft_rule_insert(h, chain, table,
+                                       ret = nft_cmd_rule_insert(h, chain, table,
                                                              cs, rulenum,
                                                              verbose);
                                }
@@ -381,11 +381,11 @@ add_entry(const char *chain,
                                memcpy(&cs->fw6.ipv6.dmsk,
                                       &d.mask.v6[j], sizeof(struct in6_addr));
                                if (append) {
-                                       ret = nft_rule_append(h, chain, table,
+                                       ret = nft_cmd_rule_append(h, chain, table,
                                                              cs, NULL,
                                                              verbose);
                                } else {
-                                       ret = nft_rule_insert(h, chain, table,
+                                       ret = nft_cmd_rule_insert(h, chain, table,
                                                              cs, rulenum,
                                                              verbose);
                                }
@@ -418,7 +418,7 @@ replace_entry(const char *chain, const char *table,
        } else
                return 1;
 
-       return nft_rule_replace(h, chain, table, cs, rulenum, verbose);
+       return nft_cmd_rule_replace(h, chain, table, cs, rulenum, verbose);
 }
 
 static int
@@ -440,7 +440,7 @@ delete_entry(const char *chain, const char *table,
                        for (j = 0; j < d.naddrs; j++) {
                                cs->fw.ip.dst.s_addr = d.addr.v4[j].s_addr;
                                cs->fw.ip.dmsk.s_addr = d.mask.v4[j].s_addr;
-                               ret = nft_rule_delete(h, chain,
+                               ret = nft_cmd_rule_delete(h, chain,
                                                      table, cs, verbose);
                        }
                } else if (family == AF_INET6) {
@@ -453,7 +453,7 @@ delete_entry(const char *chain, const char *table,
                                       &d.addr.v6[j], sizeof(struct in6_addr));
                                memcpy(&cs->fw6.ipv6.dmsk,
                                       &d.mask.v6[j], sizeof(struct in6_addr));
-                               ret = nft_rule_delete(h, chain,
+                               ret = nft_cmd_rule_delete(h, chain,
                                                      table, cs, verbose);
                        }
                }
@@ -480,7 +480,7 @@ check_entry(const char *chain, const char *table,
                        for (j = 0; j < d.naddrs; j++) {
                                cs->fw.ip.dst.s_addr = d.addr.v4[j].s_addr;
                                cs->fw.ip.dmsk.s_addr = d.mask.v4[j].s_addr;
-                               ret = nft_rule_check(h, chain,
+                               ret = nft_cmd_rule_check(h, chain,
                                                     table, cs, verbose);
                        }
                } else if (family == AF_INET6) {
@@ -493,7 +493,7 @@ check_entry(const char *chain, const char *table,
                                       &d.addr.v6[j], sizeof(struct in6_addr));
                                memcpy(&cs->fw6.ipv6.dmsk,
                                       &d.mask.v6[j], sizeof(struct in6_addr));
-                               ret = nft_rule_check(h, chain,
+                               ret = nft_cmd_rule_check(h, chain,
                                                     table, cs, verbose);
                        }
                }
@@ -524,7 +524,7 @@ list_entries(struct nft_handle *h, const char *chain, const char *table,
        if (linenumbers)
                format |= FMT_LINENUMBERS;
 
-       return nft_rule_list(h, chain, table, rulenum, format);
+       return nft_cmd_rule_list(h, chain, table, rulenum, format);
 }
 
 static int
@@ -534,7 +534,7 @@ list_rules(struct nft_handle *h, const char *chain, const char *table,
        if (counters)
            counters = -1;              /* iptables -c format */
 
-       return nft_rule_list_save(h, chain, table, rulenum, counters);
+       return nft_cmd_rule_list_save(h, chain, table, rulenum, counters);
 }
 
 void do_parse(struct nft_handle *h, int argc, char *argv[],
@@ -1022,11 +1022,6 @@ void do_parse(struct nft_handle *h, int argc, char *argv[],
                                           opt2char(OPT_VIANAMEIN),
                                           p->chain);
                }
-
-               if (!p->xlate && !cs->target && strlen(cs->jumpto) > 0 &&
-                   !nft_chain_exists(h, p->table, cs->jumpto))
-                       xtables_error(PARAMETER_PROBLEM,
-                                     "Chain '%s' does not exist", cs->jumpto);
        }
 }
 
@@ -1057,8 +1052,8 @@ int do_commandx(struct nft_handle *h, int argc, char *argv[], char **table,
                                   cs.options & OPT_VERBOSE, h);
                break;
        case CMD_DELETE_NUM:
-               ret = nft_rule_delete_num(h, p.chain, p.table,
-                                         p.rulenum - 1, p.verbose);
+               ret = nft_cmd_rule_delete_num(h, p.chain, p.table,
+                                             p.rulenum - 1, p.verbose);
                break;
        case CMD_CHECK:
                ret = check_entry(p.chain, p.table, &cs, h->family,
@@ -1076,15 +1071,15 @@ int do_commandx(struct nft_handle *h, int argc, char *argv[], char **table,
                                cs.options&OPT_VERBOSE, h, false);
                break;
        case CMD_FLUSH:
-               ret = nft_rule_flush(h, p.chain, p.table,
-                                    cs.options & OPT_VERBOSE);
+               ret = nft_cmd_rule_flush(h, p.chain, p.table,
+                                        cs.options & OPT_VERBOSE);
                break;
        case CMD_ZERO:
-               ret = nft_chain_zero_counters(h, p.chain, p.table,
-                                             cs.options & OPT_VERBOSE);
+               ret = nft_cmd_chain_zero_counters(h, p.chain, p.table,
+                                                 cs.options & OPT_VERBOSE);
                break;
        case CMD_ZERO_NUM:
-               ret = nft_rule_zero_counters(h, p.chain, p.table,
+               ret = nft_cmd_rule_zero_counters(h, p.chain, p.table,
                                             p.rulenum - 1);
                break;
        case CMD_LIST:
@@ -1096,11 +1091,11 @@ int do_commandx(struct nft_handle *h, int argc, char *argv[], char **table,
                                   cs.options & OPT_EXPANDED,
                                   cs.options & OPT_LINENUMBERS);
                if (ret && (p.command & CMD_ZERO)) {
-                       ret = nft_chain_zero_counters(h, p.chain, p.table,
+                       ret = nft_cmd_chain_zero_counters(h, p.chain, p.table,
                                                      cs.options & OPT_VERBOSE);
                }
                if (ret && (p.command & CMD_ZERO_NUM)) {
-                       ret = nft_rule_zero_counters(h, p.chain, p.table,
+                       ret = nft_cmd_rule_zero_counters(h, p.chain, p.table,
                                                     p.rulenum - 1);
                }
                nft_check_xt_legacy(h->family, false);
@@ -1111,27 +1106,27 @@ int do_commandx(struct nft_handle *h, int argc, char *argv[], char **table,
                ret = list_rules(h, p.chain, p.table, p.rulenum,
                                 cs.options & OPT_VERBOSE);
                if (ret && (p.command & CMD_ZERO)) {
-                       ret = nft_chain_zero_counters(h, p.chain, p.table,
+                       ret = nft_cmd_chain_zero_counters(h, p.chain, p.table,
                                                      cs.options & OPT_VERBOSE);
                }
                if (ret && (p.command & CMD_ZERO_NUM)) {
-                       ret = nft_rule_zero_counters(h, p.chain, p.table,
+                       ret = nft_cmd_rule_zero_counters(h, p.chain, p.table,
                                                     p.rulenum - 1);
                }
                nft_check_xt_legacy(h->family, false);
                break;
        case CMD_NEW_CHAIN:
-               ret = nft_chain_user_add(h, p.chain, p.table);
+               ret = nft_cmd_chain_user_add(h, p.chain, p.table);
                break;
        case CMD_DELETE_CHAIN:
-               ret = nft_chain_user_del(h, p.chain, p.table,
+               ret = nft_cmd_chain_user_del(h, p.chain, p.table,
                                         cs.options & OPT_VERBOSE);
                break;
        case CMD_RENAME_CHAIN:
-               ret = nft_chain_user_rename(h, p.chain, p.table, p.newname);
+               ret = nft_cmd_chain_user_rename(h, p.chain, p.table, p.newname);
                break;
        case CMD_SET_POLICY:
-               ret = nft_chain_set(h, p.table, p.chain, p.policy, NULL);
+               ret = nft_cmd_chain_set(h, p.table, p.chain, p.policy, NULL);
                break;
        case CMD_NONE:
        /* do_parse ignored the line (eg: -4 with ip6tables-restore) */