This fixes a bunch of issues found when actually testing my code: * Although add_param_to_argv() takes care of the trailing newline character, it has to be removed for lines defining tables and chains. * Table flushing must be done in a separate transaction, otherwise the cache still contains old entries and automatic insertion of built-in chains does not happen. * Call nft_table_new() for each table definition to trigger creation of built-in chains. Otherwise the relevant batch jobs are later inserted after those created by chain definitions, effectively undoing any policy changes. * Fix off-by-one when assigning to variable pointing at chain name in chain definition. * Skip chain policy setting for non-built-in chains. * Make sure free_argv() is called after each call to do_commandeb(). * Call nft_fini() before returning to caller. Signed-off-by: Phil Sutter <phil@xxxxxx> --- iptables/xtables-restore.c | 39 ++++++++++++++++++++++++++------------ 1 file changed, 27 insertions(+), 12 deletions(-) diff --git a/iptables/xtables-restore.c b/iptables/xtables-restore.c index 5c0ae98e8821a..ead61842bc360 100644 --- a/iptables/xtables-restore.c +++ b/iptables/xtables-restore.c @@ -645,30 +645,38 @@ int xtables_eb_restore_main(int argc, char *argv[]) if (buffer[0] == '#' || buffer[0] == '\n') continue; if (buffer[0] == '*') { + *strchr(buffer, '\n') = '\0'; table = ebt_parse_table_name(buffer + 1); - if (flush) + if (flush) { nft_table_flush(&h, table); + nft_commit(&h); + } + nft_table_new(&h, table); continue; } else if (!table) { xtables_error(PARAMETER_PROBLEM, "no table specified"); } if (buffer[0] == ':') { - char *ch, *chain = buffer; + char *ch, *chain = buffer + 1; const char *policy; if (!(ch = strchr(buffer, ' '))) xtables_error(PARAMETER_PROBLEM, "no policy specified"); *ch = '\0'; + *strchr(ch + 1, '\n') = '\0'; policy = ebt_parse_policy_name(ch + 1); /* No need to check chain name for consistency, since * we're supposed to be reading an automatically generated * file. */ - if (ebt_get_current_chain(chain) < 0) + if (ebt_get_current_chain(chain) < 0) { nft_chain_user_add(&h, chain, table); - ret = nft_chain_set(&h, table, chain, policy, NULL); - if (ret < 0) - xtables_error(PARAMETER_PROBLEM, "Wrong policy"); + } else { + ret = nft_chain_set(&h, table, chain, policy, NULL); + if (!ret) + xtables_error(PARAMETER_PROBLEM, + "Wrong policy '%s' of chain %s in table %s", policy, chain, table); + } continue; } @@ -685,13 +693,20 @@ int xtables_eb_restore_main(int argc, char *argv[]) DEBUGP("argv[%u]: %s\n", i, newargv[i]); optind = 0; /* Setting optind = 1 causes serious annoyances */ - if (!do_commandeb(&h, newargc, newargv, &newargv[2])) - return 1; + ret = do_commandeb(&h, newargc, newargv, &newargv[2]); + + free_argv(); + + if (!ret) + break; } - if (!nft_commit(&h)) { + if (ret) + ret = nft_commit(&h); + + nft_fini(&h); + + if (!ret) fprintf(stderr, "%s\n", nft_strerror(errno)); - return 1; - } - return 0; + return !ret; } -- 2.18.0 -- To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html