summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPhil Sutter <phil@nwl.cc>2019-10-18 19:02:29 +0200
committerPhil Sutter <phil@nwl.cc>2019-11-06 13:41:48 +0100
commit73a9a032404e2020e2b954781ce5fc8a57d5bb9f (patch)
tree07c4c4893cb8de7d47eeb931e6bb641019a685bf
parent3c0e4590ffbca3b0153eaff3338b331de2fe737c (diff)
xtables-restore: Introduce struct nft_xt_restore_state
This data structure holds parser state information. A follow-up patch will extract line parsing code into a separate function which will need a place to persistently store this info in between calls. While being at it, make 'in_table' variable boolean and drop some extra braces in conditionals checking its value. Signed-off-by: Phil Sutter <phil@nwl.cc> Acked-by: Pablo Neira Ayuso <pablo@netfilter.org>
-rw-r--r--iptables/xtables-restore.c66
1 files changed, 35 insertions, 31 deletions
diff --git a/iptables/xtables-restore.c b/iptables/xtables-restore.c
index 341579bd..a9cb4ea5 100644
--- a/iptables/xtables-restore.c
+++ b/iptables/xtables-restore.c
@@ -68,14 +68,18 @@ static const struct nft_xt_restore_cb restore_cb = {
.chain_restore = nft_chain_restore,
};
+struct nft_xt_restore_state {
+ const struct builtin_table *curtable;
+ struct argv_store av_store;
+ bool in_table;
+};
+
void xtables_restore_parse(struct nft_handle *h,
const struct nft_xt_restore_parse *p)
{
- const struct builtin_table *curtable = NULL;
const struct nft_xt_restore_cb *cb = p->cb;
- struct argv_store av_store = {};
+ struct nft_xt_restore_state state = {};
char buffer[10240];
- int in_table = 0;
line = 0;
@@ -97,7 +101,7 @@ void xtables_restore_parse(struct nft_handle *h,
if (verbose)
fputs(buffer, stdout);
continue;
- } else if ((strcmp(buffer, "COMMIT\n") == 0) && (in_table)) {
+ } else if ((strcmp(buffer, "COMMIT\n") == 0) && state.in_table) {
if (!p->testing) {
/* Commit per table, although we support
* global commit at once, stick by now to
@@ -111,9 +115,9 @@ void xtables_restore_parse(struct nft_handle *h,
if (cb->abort)
ret = cb->abort(h);
}
- in_table = 0;
+ state.in_table = false;
- } else if ((buffer[0] == '*') && (!in_table || !p->commit)) {
+ } else if ((buffer[0] == '*') && (!state.in_table || !p->commit)) {
/* New table */
char *table;
@@ -124,8 +128,8 @@ void xtables_restore_parse(struct nft_handle *h,
"%s: line %u table name invalid\n",
xt_params->program_name, line);
- curtable = nft_table_builtin_find(h, table);
- if (!curtable)
+ state.curtable = nft_table_builtin_find(h, table);
+ if (!state.curtable)
xtables_error(PARAMETER_PROBLEM,
"%s: line %u table name '%s' invalid\n",
xt_params->program_name, line, table);
@@ -141,12 +145,12 @@ void xtables_restore_parse(struct nft_handle *h,
}
ret = 1;
- in_table = 1;
+ state.in_table = true;
if (cb->table_new)
cb->table_new(h, table);
- } else if ((buffer[0] == ':') && (in_table)) {
+ } else if ((buffer[0] == ':') && state.in_table) {
/* New chain. */
char *policy, *chain = NULL;
struct xt_counters count = {};
@@ -171,7 +175,7 @@ void xtables_restore_parse(struct nft_handle *h,
"%s: line %u policy invalid\n",
xt_params->program_name, line);
- if (nft_chain_builtin_find(curtable, chain)) {
+ if (nft_chain_builtin_find(state.curtable, chain)) {
if (counters) {
char *ctrs;
ctrs = strtok(NULL, " \t\n");
@@ -183,7 +187,7 @@ void xtables_restore_parse(struct nft_handle *h,
}
if (cb->chain_set &&
- cb->chain_set(h, curtable->name,
+ cb->chain_set(h, state.curtable->name,
chain, policy, &count) < 0) {
xtables_error(OTHER_PROBLEM,
"Can't set policy `%s'"
@@ -193,14 +197,14 @@ void xtables_restore_parse(struct nft_handle *h,
}
DEBUGP("Setting policy of chain %s to %s\n",
chain, policy);
- } else if (cb->chain_restore(h, chain, curtable->name) < 0 &&
+ } else if (cb->chain_restore(h, chain, state.curtable->name) < 0 &&
errno != EEXIST) {
xtables_error(PARAMETER_PROBLEM,
"cannot create chain "
"'%s' (%s)\n", chain,
strerror(errno));
} else if (h->family == NFPROTO_BRIDGE &&
- !ebt_set_user_chain_policy(h, curtable->name,
+ !ebt_set_user_chain_policy(h, state.curtable->name,
chain, policy)) {
xtables_error(OTHER_PROBLEM,
"Can't set policy `%s'"
@@ -209,30 +213,30 @@ void xtables_restore_parse(struct nft_handle *h,
strerror(errno));
}
ret = 1;
- } else if (in_table) {
+ } else if (state.in_table) {
char *pcnt = NULL;
char *bcnt = NULL;
char *parsestart = buffer;
- add_argv(&av_store, xt_params->program_name, 0);
- add_argv(&av_store, "-t", 0);
- add_argv(&av_store, curtable->name, 0);
+ add_argv(&state.av_store, xt_params->program_name, 0);
+ add_argv(&state.av_store, "-t", 0);
+ add_argv(&state.av_store, state.curtable->name, 0);
tokenize_rule_counters(&parsestart, &pcnt, &bcnt, line);
if (counters && pcnt && bcnt) {
- add_argv(&av_store, "--set-counters", 0);
- add_argv(&av_store, pcnt, 0);
- add_argv(&av_store, bcnt, 0);
+ add_argv(&state.av_store, "--set-counters", 0);
+ add_argv(&state.av_store, pcnt, 0);
+ add_argv(&state.av_store, bcnt, 0);
}
- add_param_to_argv(&av_store, parsestart, line);
+ add_param_to_argv(&state.av_store, parsestart, line);
DEBUGP("calling do_command4(%u, argv, &%s, handle):\n",
- av_store.argc, curtable->name);
- debug_print_argv(&av_store);
+ state.av_store.argc, state.curtable->name);
+ debug_print_argv(&state.av_store);
- ret = cb->do_command(h, av_store.argc, av_store.argv,
- &av_store.argv[2], true);
+ ret = cb->do_command(h, state.av_store.argc, state.av_store.argv,
+ &state.av_store.argv[2], true);
if (ret < 0) {
if (cb->abort)
ret = cb->abort(h);
@@ -246,11 +250,11 @@ void xtables_restore_parse(struct nft_handle *h,
exit(1);
}
- free_argv(&av_store);
+ free_argv(&state.av_store);
fflush(stdout);
}
- if (p->tablename && curtable &&
- (strcmp(p->tablename, curtable->name) != 0))
+ if (p->tablename && state.curtable &&
+ (strcmp(p->tablename, state.curtable->name) != 0))
continue;
if (!ret) {
fprintf(stderr, "%s: line %u failed\n",
@@ -258,11 +262,11 @@ void xtables_restore_parse(struct nft_handle *h,
exit(1);
}
}
- if (in_table && p->commit) {
+ if (state.in_table && p->commit) {
fprintf(stderr, "%s: COMMIT expected at line %u\n",
xt_params->program_name, line + 1);
exit(1);
- } else if (in_table && cb->commit && !cb->commit(h)) {
+ } else if (state.in_table && cb->commit && !cb->commit(h)) {
xtables_error(OTHER_PROBLEM, "%s: final implicit COMMIT failed",
xt_params->program_name);
}