Hi, When I setup the firewall rules, I would like to be able to "rollback" to the previous valid state. I'm using this pseudo-code: iptables-save > previous_rules iptables-restore < new_rules on error: iptables-restore < previous_rules First problem is that iptables-save doesn't load the needed kernel modules to get the table list. Second problem is that iptables-save (with no argument) exit with code 0 (success) even if /proc/net/ip_tables_names is empty. In my pseudo-code: if previous_rule is empty, "iptables-restore < previous_rules" doesn't restore the previous status (iptables-restore does nothing with empty input). I have to check iptables-save exit code *and* that previous_rules is not empty. If the kernel module ip_tables is loaded, /proc/net/ip_table_names exists but is empty. The module iptable_filter is needed to fill /proc/net/ip_table_names. Same problems with ip6tables-save with /proc/net/ip6_tables_names, and modules ip6_tables and ip6table_filter. Attached patch change iptables-save and ip6tables-save behaviour: if there is no table, print the message: iptables-save v1.4.1: /proc/net/ip_tables_names is empty and the exit code is 1 (error). The message may be changed for a better message :-) Victor
Index: iptables-save.c =================================================================== --- iptables-save.c (révision 7568) +++ iptables-save.c (copie de travail) @@ -35,6 +35,7 @@ static int for_each_table(int (*func)(const char *tablename)) { int ret = 1; + unsigned int count = 0; FILE *procfile = NULL; char tablename[IPT_TABLE_MAXNAMELEN+1]; @@ -51,8 +52,13 @@ tablename); tablename[strlen(tablename) - 1] = '\0'; ret &= func(tablename); + count += 1; } + if (!count) + exit_error(OTHER_PROBLEM, + "/proc/net/ip_tables_names is empty\n", + tablename); return ret; } Index: ip6tables-save.c =================================================================== --- ip6tables-save.c (révision 7568) +++ ip6tables-save.c (copie de travail) @@ -37,6 +37,7 @@ static int for_each_table(int (*func)(const char *tablename)) { int ret = 1; + unsigned int count = 0; FILE *procfile = NULL; char tablename[IP6T_TABLE_MAXNAMELEN+1]; @@ -53,8 +54,13 @@ tablename); tablename[strlen(tablename) - 1] = '\0'; ret &= func(tablename); + count += 1; } + if (!count) + exit_error(OTHER_PROBLEM, + "/proc/net/ip6_tables_names is empty\n", + tablename); return ret; }