diff --git a/SOURCES/iptables-1.4.21-configure_set_lock_file_path.patch b/SOURCES/iptables-1.4.21-configure_set_lock_file_path.patch new file mode 100644 index 0000000..4132f96 --- /dev/null +++ b/SOURCES/iptables-1.4.21-configure_set_lock_file_path.patch @@ -0,0 +1,97 @@ +Adapted version of + +commit b91af533f4da15854893ba5cc082e1df6bcf9a97 +Author: Lorenzo Colitti +Date: Tue Mar 14 17:55:50 2017 +0900 + + iptables: set the path of the lock file via a configure option. + + Currently the iptables lock is hardcoded as "/run/xtables.lock". + Allow users to change this path using the --with-xt-lock-name + option to ./configure option. This is useful on systems like + Android which do not have /run. + + Tested on Ubuntu, as follows: + + 1. By default, the lock is placed in /run/xtables.lock: + + $ make distclean-recursive && ./autogen.sh && + ./configure --disable-nftables --prefix /tmp/iptables && + make -j64 && + make install && + sudo strace -e open,flock /tmp/iptables/sbin/iptables -L foo + ... + open("/run/xtables.lock", O_RDONLY|O_CREAT, 0600) = 3 + flock(3, LOCK_EX|LOCK_NB) = 0 + iptables: No chain/target/match by that name. + + 2. Specifying the lock results in the expected location being + used: + + $ make distclean-recursive && ./autogen.sh && \ + ./configure --disable-nftables --prefix /tmp/iptables \ + --with-xt-lock-name=/tmp/iptables/run/xtables.lock && + make -j64 && + make install && + sudo strace -e open,flock /tmp/iptables/sbin/iptables -L foo + ... + open("/tmp/iptables/run/xtables.lock", O_RDONLY|O_CREAT, 0600) = 3 + flock(3, LOCK_EX|LOCK_NB) = 0 + iptables: No chain/target/match by that name. + + Signed-off-by: Lorenzo Colitti + Signed-off-by: Pablo Neira Ayuso + +diff -up iptables-1.4.21/configure.ac.configure_set_lock_file_path iptables-1.4.21/configure.ac +--- iptables-1.4.21/configure.ac.configure_set_lock_file_path 2013-11-22 12:18:13.000000000 +0100 ++++ iptables-1.4.21/configure.ac 2017-04-05 14:47:17.308782472 +0200 +@@ -60,6 +60,10 @@ AC_ARG_ENABLE([nfsynproxy], + AC_ARG_WITH([pkgconfigdir], AS_HELP_STRING([--with-pkgconfigdir=PATH], + [Path to the pkgconfig directory [[LIBDIR/pkgconfig]]]), + [pkgconfigdir="$withval"], [pkgconfigdir='${libdir}/pkgconfig']) ++AC_ARG_WITH([xt-lock-name], AS_HELP_STRING([--with-xt-lock-name=PATH], ++ [Path to the xtables lock [[/run/xtables.lock]]]), ++ [xt_lock_name="$withval"], ++ [xt_lock_name="/run/xtables.lock"]) + + libiptc_LDFLAGS2=""; + AX_CHECK_LINKER_FLAGS([-Wl,--no-as-needed], +@@ -118,7 +122,7 @@ AM_CONDITIONAL([HAVE_LIBNFNETLINK], [tes + regular_CFLAGS="-Wall -Waggregate-return -Wmissing-declarations \ + -Wmissing-prototypes -Wredundant-decls -Wshadow -Wstrict-prototypes \ + -Winline -pipe"; +-regular_CPPFLAGS="${largefile_cppflags} -D_REENTRANT \ ++regular_CPPFLAGS="${largefile_cppflags} -DXT_LOCK_NAME=\\\"\${xt_lock_name}\\\" -D_REENTRANT \ + -DXTABLES_LIBDIR=\\\"\${xtlibdir}\\\" -DXTABLES_INTERNAL"; + kinclude_CPPFLAGS=""; + if [[ -n "$kbuilddir" ]]; then +@@ -156,6 +160,7 @@ AC_SUBST([libxtables_vcurrent]) + AC_SUBST([libxtables_vage]) + libxtables_vmajor=$(($libxtables_vcurrent - $libxtables_vage)); + AC_SUBST([libxtables_vmajor]) ++AC_SUBST([xt_lock_name]) + + AC_CONFIG_FILES([Makefile extensions/GNUmakefile include/Makefile + iptables/Makefile iptables/xtables.pc +@@ -188,7 +193,8 @@ Build parameters: + Support plugins via dlopen (shared): ${enable_shared} + Installation prefix (--prefix): ${prefix} + Xtables extension directory: ${e_xtlibdir} +- Pkg-config directory: ${e_pkgconfigdir}" ++ Pkg-config directory: ${e_pkgconfigdir} ++ Xtables lock file: ${xt_lock_name}" + + if [[ -n "$ksourcedir" ]]; then + echo " Kernel source directory: ${ksourcedir}" +diff -up iptables-1.4.21/iptables/xshared.c.configure_set_lock_file_path iptables-1.4.21/iptables/xshared.c +--- iptables-1.4.21/iptables/xshared.c.configure_set_lock_file_path 2017-04-05 14:46:47.861540910 +0200 ++++ iptables-1.4.21/iptables/xshared.c 2017-04-05 14:46:47.863540927 +0200 +@@ -17,8 +17,6 @@ + #include + #include "xshared.h" + +-#define XT_LOCK_NAME "/run/xtables.lock" +- + /* + * Print out any special helps. A user might like to be able to add a --help + * to the commandline, and see expected results. So we call help for all diff --git a/SOURCES/iptables-1.4.21-move_XT_LOCK_NAME_to_config.h.patch b/SOURCES/iptables-1.4.21-move_XT_LOCK_NAME_to_config.h.patch new file mode 100644 index 0000000..07836ca --- /dev/null +++ b/SOURCES/iptables-1.4.21-move_XT_LOCK_NAME_to_config.h.patch @@ -0,0 +1,67 @@ +Adapted version of + +commit 836846f0d747e1be8e37d2d43b215a68b30ea1a9 +Author: Lorenzo Colitti +Date: Thu Mar 16 12:54:20 2017 +0900 + + iptables: move XT_LOCK_NAME from CFLAGS to config.h. + + This slightly simplifies configure.ac and results in more + correct dependencies. + + Tested by running ./configure with --with-xt-lock-name and + without, and using strace to verify that the right lock is used. + + $ make distclean-recursive && ./autogen.sh && + ./configure --disable-nftables --prefix /tmp/iptables && + make -j64 && + make install && + sudo strace -e open,flock /tmp/iptables/sbin/iptables -L foo + ... + open("/run/xtables.lock", O_RDONLY|O_CREAT, 0600) = 3 + flock(3, LOCK_EX|LOCK_NB) = 0 + + $ make distclean-recursive && ./autogen.sh && \ + ./configure --disable-nftables --prefix /tmp/iptables \ + --with-xt-lock-name=/tmp/iptables/run/xtables.lock && + make -j64 && + make install && + sudo strace -e open,flock /tmp/iptables/sbin/iptables -L foo + ... + open("/tmp/iptables/run/xtables.lock", O_RDONLY|O_CREAT, 0600) = 3 + flock(3, LOCK_EX|LOCK_NB) = 0 + + Signed-off-by: Lorenzo Colitti + Signed-off-by: Pablo Neira Ayuso + +diff -up iptables-1.4.21/configure.ac.move_XT_LOCK_NAME_to_config.h iptables-1.4.21/configure.ac +--- iptables-1.4.21/configure.ac.move_XT_LOCK_NAME_to_config.h 2017-04-05 14:48:11.855229929 +0200 ++++ iptables-1.4.21/configure.ac 2017-04-05 14:48:11.856229937 +0200 +@@ -122,7 +122,7 @@ AM_CONDITIONAL([HAVE_LIBNFNETLINK], [tes + regular_CFLAGS="-Wall -Waggregate-return -Wmissing-declarations \ + -Wmissing-prototypes -Wredundant-decls -Wshadow -Wstrict-prototypes \ + -Winline -pipe"; +-regular_CPPFLAGS="${largefile_cppflags} -DXT_LOCK_NAME=\\\"\${xt_lock_name}\\\" -D_REENTRANT \ ++regular_CPPFLAGS="${largefile_cppflags} -D_REENTRANT \ + -DXTABLES_LIBDIR=\\\"\${xtlibdir}\\\" -DXTABLES_INTERNAL"; + kinclude_CPPFLAGS=""; + if [[ -n "$kbuilddir" ]]; then +@@ -160,7 +160,9 @@ AC_SUBST([libxtables_vcurrent]) + AC_SUBST([libxtables_vage]) + libxtables_vmajor=$(($libxtables_vcurrent - $libxtables_vage)); + AC_SUBST([libxtables_vmajor]) +-AC_SUBST([xt_lock_name]) ++ ++AC_DEFINE_UNQUOTED([XT_LOCK_NAME], "${xt_lock_name}", ++ [Location of the iptables lock file]) + + AC_CONFIG_FILES([Makefile extensions/GNUmakefile include/Makefile + iptables/Makefile iptables/xtables.pc +diff -up iptables-1.4.21/iptables/xshared.c.move_XT_LOCK_NAME_to_config.h iptables-1.4.21/iptables/xshared.c +--- iptables-1.4.21/iptables/xshared.c.move_XT_LOCK_NAME_to_config.h 2017-04-05 14:48:11.855229929 +0200 ++++ iptables-1.4.21/iptables/xshared.c 2017-04-05 14:48:11.856229937 +0200 +@@ -1,3 +1,4 @@ ++#include + #include + #include + #include diff --git a/SOURCES/iptables-1.4.21-remove_duplicated_argument_parsing.patch b/SOURCES/iptables-1.4.21-remove_duplicated_argument_parsing.patch new file mode 100644 index 0000000..a0fe335 --- /dev/null +++ b/SOURCES/iptables-1.4.21-remove_duplicated_argument_parsing.patch @@ -0,0 +1,401 @@ +Adapted version of + +commit 6e2e169eb66b63d2991e1c7ada931e3cdb0ced32 +Author: Lorenzo Colitti +Date: Thu Mar 16 16:55:01 2017 +0900 + + iptables: remove duplicated argument parsing code + + 1. Factor out repeated code to a new xs_has_arg function. + 2. Add a new parse_wait_time option to parse the value of -w. + 3. Make parse_wait_interval take argc and argv so its callers + can be simpler. + + Signed-off-by: Lorenzo Colitti + Signed-off-by: Pablo Neira Ayuso + +diff -up iptables-1.4.21/iptables/ip6tables.c.remove_duplicated_argument_parsing iptables-1.4.21/iptables/ip6tables.c +--- iptables-1.4.21/iptables/ip6tables.c.remove_duplicated_argument_parsing 2017-04-05 14:51:44.033970476 +0200 ++++ iptables-1.4.21/iptables/ip6tables.c 2017-04-05 14:51:44.044970566 +0200 +@@ -1388,8 +1388,7 @@ int do_command6(int argc, char *argv[], + add_command(&command, CMD_DELETE, CMD_NONE, + cs.invert); + chain = optarg; +- if (optind < argc && argv[optind][0] != '-' +- && argv[optind][0] != '!') { ++ if (xs_has_arg(argc, argv)) { + rulenum = parse_rulenumber(argv[optind++]); + command = CMD_DELETE_NUM; + } +@@ -1399,8 +1398,7 @@ int do_command6(int argc, char *argv[], + add_command(&command, CMD_REPLACE, CMD_NONE, + cs.invert); + chain = optarg; +- if (optind < argc && argv[optind][0] != '-' +- && argv[optind][0] != '!') ++ if (xs_has_arg(argc, argv)) + rulenum = parse_rulenumber(argv[optind++]); + else + xtables_error(PARAMETER_PROBLEM, +@@ -1412,8 +1410,7 @@ int do_command6(int argc, char *argv[], + add_command(&command, CMD_INSERT, CMD_NONE, + cs.invert); + chain = optarg; +- if (optind < argc && argv[optind][0] != '-' +- && argv[optind][0] != '!') ++ if (xs_has_arg(argc, argv)) + rulenum = parse_rulenumber(argv[optind++]); + else rulenum = 1; + break; +@@ -1422,11 +1419,9 @@ int do_command6(int argc, char *argv[], + add_command(&command, CMD_LIST, + CMD_ZERO | CMD_ZERO_NUM, cs.invert); + if (optarg) chain = optarg; +- else if (optind < argc && argv[optind][0] != '-' +- && argv[optind][0] != '!') ++ else if (xs_has_arg(argc, argv)) + chain = argv[optind++]; +- if (optind < argc && argv[optind][0] != '-' +- && argv[optind][0] != '!') ++ if (xs_has_arg(argc, argv)) + rulenum = parse_rulenumber(argv[optind++]); + break; + +@@ -1434,11 +1429,9 @@ int do_command6(int argc, char *argv[], + add_command(&command, CMD_LIST_RULES, + CMD_ZERO | CMD_ZERO_NUM, cs.invert); + if (optarg) chain = optarg; +- else if (optind < argc && argv[optind][0] != '-' +- && argv[optind][0] != '!') ++ else if (xs_has_arg(argc, argv)) + chain = argv[optind++]; +- if (optind < argc && argv[optind][0] != '-' +- && argv[optind][0] != '!') ++ if (xs_has_arg(argc, argv)) + rulenum = parse_rulenumber(argv[optind++]); + break; + +@@ -1446,8 +1439,7 @@ int do_command6(int argc, char *argv[], + add_command(&command, CMD_FLUSH, CMD_NONE, + cs.invert); + if (optarg) chain = optarg; +- else if (optind < argc && argv[optind][0] != '-' +- && argv[optind][0] != '!') ++ else if (xs_has_arg(argc, argv)) + chain = argv[optind++]; + break; + +@@ -1455,11 +1447,9 @@ int do_command6(int argc, char *argv[], + add_command(&command, CMD_ZERO, CMD_LIST|CMD_LIST_RULES, + cs.invert); + if (optarg) chain = optarg; +- else if (optind < argc && argv[optind][0] != '-' +- && argv[optind][0] != '!') ++ else if (xs_has_arg(argc, argv)) + chain = argv[optind++]; +- if (optind < argc && argv[optind][0] != '-' +- && argv[optind][0] != '!') { ++ if (xs_has_arg(argc, argv)) { + rulenum = parse_rulenumber(argv[optind++]); + command = CMD_ZERO_NUM; + } +@@ -1476,8 +1466,7 @@ int do_command6(int argc, char *argv[], + add_command(&command, CMD_DELETE_CHAIN, CMD_NONE, + cs.invert); + if (optarg) chain = optarg; +- else if (optind < argc && argv[optind][0] != '-' +- && argv[optind][0] != '!') ++ else if (xs_has_arg(argc, argv)) + chain = argv[optind++]; + break; + +@@ -1485,8 +1474,7 @@ int do_command6(int argc, char *argv[], + add_command(&command, CMD_RENAME_CHAIN, CMD_NONE, + cs.invert); + chain = optarg; +- if (optind < argc && argv[optind][0] != '-' +- && argv[optind][0] != '!') ++ if (xs_has_arg(argc, argv)) + newname = argv[optind++]; + else + xtables_error(PARAMETER_PROBLEM, +@@ -1499,8 +1487,7 @@ int do_command6(int argc, char *argv[], + add_command(&command, CMD_SET_POLICY, CMD_NONE, + cs.invert); + chain = optarg; +- if (optind < argc && argv[optind][0] != '-' +- && argv[optind][0] != '!') ++ if (xs_has_arg(argc, argv)) + policy = argv[optind++]; + else + xtables_error(PARAMETER_PROBLEM, +@@ -1610,16 +1597,7 @@ int do_command6(int argc, char *argv[], + "You cannot use `-w' from " + "ip6tables-restore"); + } +- wait = -1; +- if (optarg) { +- if (sscanf(optarg, "%i", &wait) != 1) +- xtables_error(PARAMETER_PROBLEM, +- "wait seconds not numeric"); +- } else if (optind < argc && argv[optind][0] != '-' +- && argv[optind][0] != '!') +- if (sscanf(argv[optind++], "%i", &wait) != 1) +- xtables_error(PARAMETER_PROBLEM, +- "wait seconds not numeric"); ++ wait = parse_wait_time(argc, argv); + break; + + case 'W': +@@ -1628,14 +1606,7 @@ int do_command6(int argc, char *argv[], + "You cannot use `-W' from " + "ip6tables-restore"); + } +- if (optarg) +- parse_wait_interval(optarg, &wait_interval); +- else if (optind < argc && +- argv[optind][0] != '-' && +- argv[optind][0] != '!') +- parse_wait_interval(argv[optind++], +- &wait_interval); +- ++ parse_wait_interval(argc, argv, &wait_interval); + wait_interval_set = true; + break; + +@@ -1685,8 +1656,7 @@ int do_command6(int argc, char *argv[], + bcnt = strchr(pcnt + 1, ','); + if (bcnt) + bcnt++; +- if (!bcnt && optind < argc && argv[optind][0] != '-' +- && argv[optind][0] != '!') ++ if (!bcnt && xs_has_arg(argc, argv)) + bcnt = argv[optind++]; + if (!bcnt) + xtables_error(PARAMETER_PROBLEM, +diff -up iptables-1.4.21/iptables/iptables.c.remove_duplicated_argument_parsing iptables-1.4.21/iptables/iptables.c +--- iptables-1.4.21/iptables/iptables.c.remove_duplicated_argument_parsing 2017-04-05 14:51:44.034970484 +0200 ++++ iptables-1.4.21/iptables/iptables.c 2017-04-05 14:51:44.044970566 +0200 +@@ -1381,8 +1381,7 @@ int do_command4(int argc, char *argv[], + add_command(&command, CMD_DELETE, CMD_NONE, + cs.invert); + chain = optarg; +- if (optind < argc && argv[optind][0] != '-' +- && argv[optind][0] != '!') { ++ if (xs_has_arg(argc, argv)) { + rulenum = parse_rulenumber(argv[optind++]); + command = CMD_DELETE_NUM; + } +@@ -1392,8 +1391,7 @@ int do_command4(int argc, char *argv[], + add_command(&command, CMD_REPLACE, CMD_NONE, + cs.invert); + chain = optarg; +- if (optind < argc && argv[optind][0] != '-' +- && argv[optind][0] != '!') ++ if (xs_has_arg(argc, argv)) + rulenum = parse_rulenumber(argv[optind++]); + else + xtables_error(PARAMETER_PROBLEM, +@@ -1405,8 +1403,7 @@ int do_command4(int argc, char *argv[], + add_command(&command, CMD_INSERT, CMD_NONE, + cs.invert); + chain = optarg; +- if (optind < argc && argv[optind][0] != '-' +- && argv[optind][0] != '!') ++ if (xs_has_arg(argc, argv)) + rulenum = parse_rulenumber(argv[optind++]); + else rulenum = 1; + break; +@@ -1415,11 +1412,9 @@ int do_command4(int argc, char *argv[], + add_command(&command, CMD_LIST, + CMD_ZERO | CMD_ZERO_NUM, cs.invert); + if (optarg) chain = optarg; +- else if (optind < argc && argv[optind][0] != '-' +- && argv[optind][0] != '!') ++ else if (xs_has_arg(argc, argv)) + chain = argv[optind++]; +- if (optind < argc && argv[optind][0] != '-' +- && argv[optind][0] != '!') ++ if (xs_has_arg(argc, argv)) + rulenum = parse_rulenumber(argv[optind++]); + break; + +@@ -1427,11 +1422,9 @@ int do_command4(int argc, char *argv[], + add_command(&command, CMD_LIST_RULES, + CMD_ZERO|CMD_ZERO_NUM, cs.invert); + if (optarg) chain = optarg; +- else if (optind < argc && argv[optind][0] != '-' +- && argv[optind][0] != '!') ++ else if (xs_has_arg(argc, argv)) + chain = argv[optind++]; +- if (optind < argc && argv[optind][0] != '-' +- && argv[optind][0] != '!') ++ if (xs_has_arg(argc, argv)) + rulenum = parse_rulenumber(argv[optind++]); + break; + +@@ -1439,8 +1432,7 @@ int do_command4(int argc, char *argv[], + add_command(&command, CMD_FLUSH, CMD_NONE, + cs.invert); + if (optarg) chain = optarg; +- else if (optind < argc && argv[optind][0] != '-' +- && argv[optind][0] != '!') ++ else if (xs_has_arg(argc, argv)) + chain = argv[optind++]; + break; + +@@ -1448,11 +1440,9 @@ int do_command4(int argc, char *argv[], + add_command(&command, CMD_ZERO, CMD_LIST|CMD_LIST_RULES, + cs.invert); + if (optarg) chain = optarg; +- else if (optind < argc && argv[optind][0] != '-' +- && argv[optind][0] != '!') ++ else if (xs_has_arg(argc, argv)) + chain = argv[optind++]; +- if (optind < argc && argv[optind][0] != '-' +- && argv[optind][0] != '!') { ++ if (xs_has_arg(argc, argv)) { + rulenum = parse_rulenumber(argv[optind++]); + command = CMD_ZERO_NUM; + } +@@ -1469,8 +1459,7 @@ int do_command4(int argc, char *argv[], + add_command(&command, CMD_DELETE_CHAIN, CMD_NONE, + cs.invert); + if (optarg) chain = optarg; +- else if (optind < argc && argv[optind][0] != '-' +- && argv[optind][0] != '!') ++ else if (xs_has_arg(argc, argv)) + chain = argv[optind++]; + break; + +@@ -1478,8 +1467,7 @@ int do_command4(int argc, char *argv[], + add_command(&command, CMD_RENAME_CHAIN, CMD_NONE, + cs.invert); + chain = optarg; +- if (optind < argc && argv[optind][0] != '-' +- && argv[optind][0] != '!') ++ if (xs_has_arg(argc, argv)) + newname = argv[optind++]; + else + xtables_error(PARAMETER_PROBLEM, +@@ -1492,8 +1480,7 @@ int do_command4(int argc, char *argv[], + add_command(&command, CMD_SET_POLICY, CMD_NONE, + cs.invert); + chain = optarg; +- if (optind < argc && argv[optind][0] != '-' +- && argv[optind][0] != '!') ++ if (xs_has_arg(argc, argv)) + policy = argv[optind++]; + else + xtables_error(PARAMETER_PROBLEM, +@@ -1601,16 +1588,7 @@ int do_command4(int argc, char *argv[], + "You cannot use `-w' from " + "iptables-restore"); + } +- wait = -1; +- if (optarg) { +- if (sscanf(optarg, "%i", &wait) != 1) +- xtables_error(PARAMETER_PROBLEM, +- "wait seconds not numeric"); +- } else if (optind < argc && argv[optind][0] != '-' +- && argv[optind][0] != '!') +- if (sscanf(argv[optind++], "%i", &wait) != 1) +- xtables_error(PARAMETER_PROBLEM, +- "wait seconds not numeric"); ++ wait = parse_wait_time(argc, argv); + break; + + case 'W': +@@ -1619,14 +1597,7 @@ int do_command4(int argc, char *argv[], + "You cannot use `-W' from " + "iptables-restore"); + } +- if (optarg) +- parse_wait_interval(optarg, &wait_interval); +- else if (optind < argc && +- argv[optind][0] != '-' && +- argv[optind][0] != '!') +- parse_wait_interval(argv[optind++], +- &wait_interval); +- ++ parse_wait_interval(argc, argv, &wait_interval); + wait_interval_set = true; + break; + +@@ -1676,8 +1647,7 @@ int do_command4(int argc, char *argv[], + bcnt = strchr(pcnt + 1, ','); + if (bcnt) + bcnt++; +- if (!bcnt && optind < argc && argv[optind][0] != '-' +- && argv[optind][0] != '!') ++ if (!bcnt && xs_has_arg(argc, argv)) + bcnt = argv[optind++]; + if (!bcnt) + xtables_error(PARAMETER_PROBLEM, +diff -up iptables-1.4.21/iptables/xshared.c.remove_duplicated_argument_parsing iptables-1.4.21/iptables/xshared.c +--- iptables-1.4.21/iptables/xshared.c.remove_duplicated_argument_parsing 2017-04-05 14:51:44.042970550 +0200 ++++ iptables-1.4.21/iptables/xshared.c 2017-04-05 14:51:44.045970574 +0200 +@@ -285,12 +285,36 @@ bool xtables_lock(int wait, struct timev + } + } + +-void parse_wait_interval(const char *str, struct timeval *wait_interval) ++int parse_wait_time(int argc, char *argv[]) + { ++ int wait = -1; ++ ++ if (optarg) { ++ if (sscanf(optarg, "%i", &wait) != 1) ++ xtables_error(PARAMETER_PROBLEM, ++ "wait seconds not numeric"); ++ } else if (xs_has_arg(argc, argv)) ++ if (sscanf(argv[optind++], "%i", &wait) != 1) ++ xtables_error(PARAMETER_PROBLEM, ++ "wait seconds not numeric"); ++ ++ return wait; ++} ++ ++void parse_wait_interval(int argc, char *argv[], struct timeval *wait_interval) ++{ ++ const char *arg; + unsigned int usec; + int ret; + +- ret = sscanf(str, "%u", &usec); ++ if (optarg) ++ arg = optarg; ++ else if (xs_has_arg(argc, argv)) ++ arg = argv[optind++]; ++ else ++ return; ++ ++ ret = sscanf(arg, "%u", &usec); + if (ret == 1) { + if (usec > 999999) + xtables_error(PARAMETER_PROBLEM, +@@ -303,3 +327,10 @@ void parse_wait_interval(const char *str + } + xtables_error(PARAMETER_PROBLEM, "wait interval not numeric"); + } ++ ++inline bool xs_has_arg(int argc, char *argv[]) ++{ ++ return optind < argc && ++ argv[optind][0] != '-' && ++ argv[optind][0] != '!'; ++} +diff -up iptables-1.4.21/iptables/xshared.h.remove_duplicated_argument_parsing iptables-1.4.21/iptables/xshared.h +--- iptables-1.4.21/iptables/xshared.h.remove_duplicated_argument_parsing 2017-04-05 14:51:44.034970484 +0200 ++++ iptables-1.4.21/iptables/xshared.h 2017-04-05 14:51:44.045970574 +0200 +@@ -86,7 +86,9 @@ extern void xs_init_target(struct xtable + extern void xs_init_match(struct xtables_match *); + bool xtables_lock(int wait, struct timeval *wait_interval); + +-void parse_wait_interval(const char *str, struct timeval *wait_interval); ++int parse_wait_time(int argc, char *argv[]); ++void parse_wait_interval(int argc, char *argv[], struct timeval *wait_interval); ++bool xs_has_arg(int argc, char *argv[]); + + extern const struct xtables_afinfo *afinfo; + diff --git a/SOURCES/iptables-1.4.21-restore_support_acquiring_the_lock.patch b/SOURCES/iptables-1.4.21-restore_support_acquiring_the_lock.patch new file mode 100644 index 0000000..77e1aff --- /dev/null +++ b/SOURCES/iptables-1.4.21-restore_support_acquiring_the_lock.patch @@ -0,0 +1,414 @@ +Adapted version of + +commit 999eaa241212d3952ddff39a99d0d55a74e3639e +Author: Lorenzo Colitti +Date: Thu Mar 16 16:55:02 2017 +0900 + + iptables-restore: support acquiring the lock. + + Currently, ip[6]tables-restore does not perform any locking, so it + is not safe to use concurrently with ip[6]tables. + + This patch makes ip[6]tables-restore wait for the lock if -w + was specified. Arguments to -w and -W are supported in the same + was as they are in ip[6]tables. + + The lock is not acquired on startup. Instead, it is acquired when + a new table handle is created (on encountering '*') and released + when the table is committed (COMMIT). This makes it possible to + keep long-running iptables-restore processes in the background + (for example, reading commands from a pipe opened by a system + management daemon) and simultaneously run iptables commands. + + If -w is not specified, then the command proceeds without taking + the lock. + + Tested as follows: + + 1. Run iptables-restore -w, and check that iptables commands work + with or without -w. + 2. Type "*filter" into the iptables-restore input. Verify that + a) ip[6]tables commands without -w fail with "another app is + currently holding the xtables lock...". + b) ip[6]tables commands with "-w 2" fail after 2 seconds. + c) ip[6]tables commands with "-w" hang until "COMMIT" is + typed into the iptables-restore window. + 3. With the lock held by an ip6tables-restore process: + strace -e flock /tmp/iptables/sbin/iptables-restore -w 1 -W 100000 + shows 11 calls to flock and fails. + 4. Run an iptables-restore with -w and one without -w, and check: + a) Type "*filter" in the first and then the second, and the + second exits with an error. + b) Type "*filter" in the second and "*filter" "-S" "COMMIT" + into the first. The rules are listed only when the first + copy sees "COMMIT". + + Signed-off-by: Narayan Kamath + Signed-off-by: Lorenzo Colitti + Signed-off-by: Pablo Neira Ayuso + +diff -up iptables-1.4.21/iptables/ip6tables.c.restore_support_acquiring_the_lock iptables-1.4.21/iptables/ip6tables.c +--- iptables-1.4.21/iptables/ip6tables.c.restore_support_acquiring_the_lock 2017-04-05 14:55:52.561008864 +0200 ++++ iptables-1.4.21/iptables/ip6tables.c 2017-04-05 14:55:52.564008888 +0200 +@@ -1767,7 +1767,7 @@ int do_command6(int argc, char *argv[], + generic_opt_check(command, cs.options); + + /* Attempt to acquire the xtables lock */ +- if (!restore && !xtables_lock(wait, &wait_interval)) { ++ if (!restore && xtables_lock(wait, &wait_interval) == XT_LOCK_BUSY) { + fprintf(stderr, "Another app is currently holding the xtables lock. "); + if (wait == 0) + fprintf(stderr, "Perhaps you want to use the -w option?\n"); +diff -up iptables-1.4.21/iptables/ip6tables-restore.c.restore_support_acquiring_the_lock iptables-1.4.21/iptables/ip6tables-restore.c +--- iptables-1.4.21/iptables/ip6tables-restore.c.restore_support_acquiring_the_lock 2013-11-22 12:18:13.000000000 +0100 ++++ iptables-1.4.21/iptables/ip6tables-restore.c 2017-04-05 14:58:41.513393942 +0200 +@@ -15,6 +15,7 @@ + #include + #include + #include "ip6tables.h" ++#include "xshared.h" + #include "xtables.h" + #include "libiptc/libip6tc.h" + #include "ip6tables-multi.h" +@@ -25,18 +26,24 @@ + #define DEBUGP(x, args...) + #endif + +-static int binary = 0, counters = 0, verbose = 0, noflush = 0; ++static int binary = 0, counters = 0, verbose = 0, noflush = 0, wait = 0; ++ ++static struct timeval wait_interval = { ++ .tv_sec = 1, ++}; + + /* Keeping track of external matches and targets. */ + static const struct option options[] = { +- {.name = "binary", .has_arg = false, .val = 'b'}, +- {.name = "counters", .has_arg = false, .val = 'c'}, +- {.name = "verbose", .has_arg = false, .val = 'v'}, +- {.name = "test", .has_arg = false, .val = 't'}, +- {.name = "help", .has_arg = false, .val = 'h'}, +- {.name = "noflush", .has_arg = false, .val = 'n'}, +- {.name = "modprobe", .has_arg = true, .val = 'M'}, +- {.name = "table", .has_arg = true, .val = 'T'}, ++ {.name = "binary", .has_arg = 0, .val = 'b'}, ++ {.name = "counters", .has_arg = 0, .val = 'c'}, ++ {.name = "verbose", .has_arg = 0, .val = 'v'}, ++ {.name = "test", .has_arg = 0, .val = 't'}, ++ {.name = "help", .has_arg = 0, .val = 'h'}, ++ {.name = "noflush", .has_arg = 0, .val = 'n'}, ++ {.name = "modprobe", .has_arg = 1, .val = 'M'}, ++ {.name = "table", .has_arg = 1, .val = 'T'}, ++ {.name = "wait", .has_arg = 2, .val = 'w'}, ++ {.name = "wait-interval", .has_arg = 2, .val = 'W'}, + {NULL}, + }; + +@@ -44,14 +51,16 @@ static void print_usage(const char *name + + static void print_usage(const char *name, const char *version) + { +- fprintf(stderr, "Usage: %s [-b] [-c] [-v] [-t] [-h]\n" ++ fprintf(stderr, "Usage: %s [-b] [-c] [-v] [-t] [-h] [-w secs] [-W usecs]\n" + " [ --binary ]\n" + " [ --counters ]\n" + " [ --verbose ]\n" + " [ --test ]\n" + " [ --help ]\n" ++ " [ --wait=\n" ++ " [ --wait-interval=\n" + " [ --noflush ]\n" +- " [ --modprobe=]\n", name); ++ " [ --modprobe=]\n", name); + + exit(1); + } +@@ -182,7 +191,7 @@ int ip6tables_restore_main(int argc, cha + { + struct xtc_handle *handle = NULL; + char buffer[10240]; +- int c; ++ int c, lock; + char curtable[XT_TABLE_MAXNAMELEN + 1]; + FILE *in; + int in_table = 0, testing = 0; +@@ -190,6 +199,7 @@ int ip6tables_restore_main(int argc, cha + const struct xtc_ops *ops = &ip6tc_ops; + + line = 0; ++ lock = XT_LOCK_NOT_ACQUIRED; + + ip6tables_globals.program_name = "ip6tables-restore"; + c = xtables_init_all(&ip6tables_globals, NFPROTO_IPV6); +@@ -204,7 +214,7 @@ int ip6tables_restore_main(int argc, cha + init_extensions6(); + #endif + +- while ((c = getopt_long(argc, argv, "bcvthnM:T:", options, NULL)) != -1) { ++ while ((c = getopt_long(argc, argv, "bcvthnwWM:T:", options, NULL)) != -1) { + switch (c) { + case 'b': + binary = 1; +@@ -225,6 +235,12 @@ int ip6tables_restore_main(int argc, cha + case 'n': + noflush = 1; + break; ++ case 'w': ++ wait = parse_wait_time(argc, argv); ++ break; ++ case 'W': ++ parse_wait_interval(argc, argv, &wait_interval); ++ break; + case 'M': + xtables_modprobe_program = optarg; + break; +@@ -269,8 +285,23 @@ int ip6tables_restore_main(int argc, cha + DEBUGP("Not calling commit, testing\n"); + ret = 1; + } ++ ++ /* Done with the current table, release the lock. */ ++ if (lock >= 0) { ++ xtables_unlock(lock); ++ lock = XT_LOCK_NOT_ACQUIRED; ++ } ++ + in_table = 0; + } else if ((buffer[0] == '*') && (!in_table)) { ++ /* Acquire a lock before we create a new table handle */ ++ lock = xtables_lock(wait, &wait_interval); ++ if (lock == XT_LOCK_BUSY) { ++ fprintf(stderr, "Another app is currently holding the xtables lock. " ++ "Perhaps you want to use the -w option?\n"); ++ exit(RESOURCE_PROBLEM); ++ } ++ + /* New table */ + char *table; + +diff -up iptables-1.4.21/iptables/iptables.c.restore_support_acquiring_the_lock iptables-1.4.21/iptables/iptables.c +--- iptables-1.4.21/iptables/iptables.c.restore_support_acquiring_the_lock 2017-04-05 14:55:52.562008872 +0200 ++++ iptables-1.4.21/iptables/iptables.c 2017-04-05 14:55:52.564008888 +0200 +@@ -1754,7 +1754,7 @@ int do_command4(int argc, char *argv[], + generic_opt_check(command, cs.options); + + /* Attempt to acquire the xtables lock */ +- if (!restore && !xtables_lock(wait, &wait_interval)) { ++ if (!restore && xtables_lock(wait, &wait_interval) == XT_LOCK_BUSY) { + fprintf(stderr, "Another app is currently holding the xtables lock. "); + if (wait == 0) + fprintf(stderr, "Perhaps you want to use the -w option?\n"); +diff -up iptables-1.4.21/iptables/iptables-restore.c.restore_support_acquiring_the_lock iptables-1.4.21/iptables/iptables-restore.c +--- iptables-1.4.21/iptables/iptables-restore.c.restore_support_acquiring_the_lock 2013-11-22 12:18:13.000000000 +0100 ++++ iptables-1.4.21/iptables/iptables-restore.c 2017-04-05 15:00:17.389179935 +0200 +@@ -12,6 +12,7 @@ + #include + #include + #include "iptables.h" ++#include "xshared.h" + #include "xtables.h" + #include "libiptc/libiptc.h" + #include "iptables-multi.h" +@@ -22,18 +23,24 @@ + #define DEBUGP(x, args...) + #endif + +-static int binary = 0, counters = 0, verbose = 0, noflush = 0; ++static int binary = 0, counters = 0, verbose = 0, noflush = 0, wait = 0; ++ ++static struct timeval wait_interval = { ++ .tv_sec = 1, ++}; + + /* Keeping track of external matches and targets. */ + static const struct option options[] = { +- {.name = "binary", .has_arg = false, .val = 'b'}, +- {.name = "counters", .has_arg = false, .val = 'c'}, +- {.name = "verbose", .has_arg = false, .val = 'v'}, +- {.name = "test", .has_arg = false, .val = 't'}, +- {.name = "help", .has_arg = false, .val = 'h'}, +- {.name = "noflush", .has_arg = false, .val = 'n'}, +- {.name = "modprobe", .has_arg = true, .val = 'M'}, +- {.name = "table", .has_arg = true, .val = 'T'}, ++ {.name = "binary", .has_arg = 0, .val = 'b'}, ++ {.name = "counters", .has_arg = 0, .val = 'c'}, ++ {.name = "verbose", .has_arg = 0, .val = 'v'}, ++ {.name = "test", .has_arg = 0, .val = 't'}, ++ {.name = "help", .has_arg = 0, .val = 'h'}, ++ {.name = "noflush", .has_arg = 0, .val = 'n'}, ++ {.name = "modprobe", .has_arg = 1, .val = 'M'}, ++ {.name = "table", .has_arg = 1, .val = 'T'}, ++ {.name = "wait", .has_arg = 2, .val = 'w'}, ++ {.name = "wait-interval", .has_arg = 2, .val = 'W'}, + {NULL}, + }; + +@@ -43,15 +50,17 @@ static void print_usage(const char *name + + static void print_usage(const char *name, const char *version) + { +- fprintf(stderr, "Usage: %s [-b] [-c] [-v] [-t] [-h]\n" ++ fprintf(stderr, "Usage: %s [-b] [-c] [-v] [-t] [-h] [-W usecs]\n" + " [ --binary ]\n" + " [ --counters ]\n" + " [ --verbose ]\n" + " [ --test ]\n" + " [ --help ]\n" + " [ --noflush ]\n" ++ " [ --wait=\n" ++ " [ --wait-interval=\n" + " [ --table= ]\n" +- " [ --modprobe=]\n", name); ++ " [ --modprobe=]\n", name); + + exit(1); + } +@@ -182,7 +191,7 @@ iptables_restore_main(int argc, char *ar + { + struct xtc_handle *handle = NULL; + char buffer[10240]; +- int c; ++ int c, lock; + char curtable[XT_TABLE_MAXNAMELEN + 1]; + FILE *in; + int in_table = 0, testing = 0; +@@ -190,6 +199,7 @@ iptables_restore_main(int argc, char *ar + const struct xtc_ops *ops = &iptc_ops; + + line = 0; ++ lock = XT_LOCK_NOT_ACQUIRED; + + iptables_globals.program_name = "iptables-restore"; + c = xtables_init_all(&iptables_globals, NFPROTO_IPV4); +@@ -204,7 +214,7 @@ iptables_restore_main(int argc, char *ar + init_extensions4(); + #endif + +- while ((c = getopt_long(argc, argv, "bcvthnM:T:", options, NULL)) != -1) { ++ while ((c = getopt_long(argc, argv, "bcvthnwWM:T:", options, NULL)) != -1) { + switch (c) { + case 'b': + binary = 1; +@@ -225,6 +235,12 @@ iptables_restore_main(int argc, char *ar + case 'n': + noflush = 1; + break; ++ case 'w': ++ wait = parse_wait_time(argc, argv); ++ break; ++ case 'W': ++ parse_wait_interval(argc, argv, &wait_interval); ++ break; + case 'M': + xtables_modprobe_program = optarg; + break; +@@ -269,8 +285,23 @@ iptables_restore_main(int argc, char *ar + DEBUGP("Not calling commit, testing\n"); + ret = 1; + } ++ ++ /* Done with the current table, release the lock. */ ++ if (lock >= 0) { ++ xtables_unlock(lock); ++ lock = XT_LOCK_NOT_ACQUIRED; ++ } ++ + in_table = 0; + } else if ((buffer[0] == '*') && (!in_table)) { ++ /* Acquire a lock before we create a new table handle */ ++ lock = xtables_lock(wait, &wait_interval); ++ if (lock == XT_LOCK_BUSY) { ++ fprintf(stderr, "Another app is currently holding the xtables lock. " ++ "Perhaps you want to use the -w option?\n"); ++ exit(RESOURCE_PROBLEM); ++ } ++ + /* New table */ + char *table; + +diff -up iptables-1.4.21/iptables/xshared.c.restore_support_acquiring_the_lock iptables-1.4.21/iptables/xshared.c +--- iptables-1.4.21/iptables/xshared.c.restore_support_acquiring_the_lock 2017-04-05 14:55:52.562008872 +0200 ++++ iptables-1.4.21/iptables/xshared.c 2017-04-05 14:55:52.565008896 +0200 +@@ -246,7 +246,7 @@ void xs_init_match(struct xtables_match + match->init(match->m); + } + +-bool xtables_lock(int wait, struct timeval *wait_interval) ++int xtables_lock(int wait, struct timeval *wait_interval) + { + struct timeval time_left, wait_time; + int fd, i = 0; +@@ -256,22 +256,22 @@ bool xtables_lock(int wait, struct timev + + fd = open(XT_LOCK_NAME, O_CREAT, 0600); + if (fd < 0) +- return true; ++ return XT_LOCK_UNSUPPORTED; + + if (wait == -1) { + if (flock(fd, LOCK_EX) == 0) +- return true; ++ return fd; + + fprintf(stderr, "Can't lock %s: %s\n", XT_LOCK_NAME, + strerror(errno)); +- return false; ++ return XT_LOCK_BUSY; + } + + while (1) { + if (flock(fd, LOCK_EX | LOCK_NB) == 0) +- return true; ++ return fd; + else if (timercmp(&time_left, wait_interval, <)) +- return false; ++ return XT_LOCK_BUSY; + + if (++i % 10 == 0) { + fprintf(stderr, "Another app is currently holding the xtables lock; " +@@ -285,6 +285,12 @@ bool xtables_lock(int wait, struct timev + } + } + ++void xtables_unlock(int lock) ++{ ++ if (lock >= 0) ++ close(lock); ++} ++ + int parse_wait_time(int argc, char *argv[]) + { + int wait = -1; +diff -up iptables-1.4.21/iptables/xshared.h.restore_support_acquiring_the_lock iptables-1.4.21/iptables/xshared.h +--- iptables-1.4.21/iptables/xshared.h.restore_support_acquiring_the_lock 2017-04-05 14:55:52.562008872 +0200 ++++ iptables-1.4.21/iptables/xshared.h 2017-04-05 14:55:52.565008896 +0200 +@@ -84,7 +84,28 @@ extern struct xtables_match *load_proto( + extern int subcmd_main(int, char **, const struct subcommand *); + extern void xs_init_target(struct xtables_target *); + extern void xs_init_match(struct xtables_match *); +-bool xtables_lock(int wait, struct timeval *wait_interval); ++ ++/** ++ * Values for the iptables lock. ++ * ++ * A value >= 0 indicates the lock filedescriptor. Other values are: ++ * ++ * XT_LOCK_UNSUPPORTED : The system does not support locking, execution will ++ * proceed lockless. ++ * ++ * XT_LOCK_BUSY : The lock was held by another process. xtables_lock only ++ * returns this value when |wait| == false. If |wait| == true, xtables_lock ++ * will not return unless the lock has been acquired. ++ * ++ * XT_LOCK_NOT_ACQUIRED : We have not yet attempted to acquire the lock. ++ */ ++enum { ++ XT_LOCK_BUSY = -1, ++ XT_LOCK_UNSUPPORTED = -2, ++ XT_LOCK_NOT_ACQUIRED = -3, ++}; ++extern int xtables_lock(int wait, struct timeval *tv); ++extern void xtables_unlock(int lock); + + int parse_wait_time(int argc, char *argv[]); + void parse_wait_interval(int argc, char *argv[], struct timeval *wait_interval); diff --git a/SOURCES/iptables-1.4.21-restore_version.patch b/SOURCES/iptables-1.4.21-restore_version.patch new file mode 100644 index 0000000..bee5903 --- /dev/null +++ b/SOURCES/iptables-1.4.21-restore_version.patch @@ -0,0 +1,143 @@ +Adapted version of + +commit 9cd3adbed2fd8cdb6366293f3799573b811be89b +Author: Dan Williams +Date: Mon Apr 10 12:31:56 2017 -0500 + + iptables-restore/ip6tables-restore: add --version/-V argument + + Prints program version just like iptables/ip6tables. + + Signed-off-by: Dan Williams + Signed-off-by: Pablo Neira Ayuso + +diff -up iptables-1.4.21/iptables/ip6tables-restore.c.restore_version iptables-1.4.21/iptables/ip6tables-restore.c +--- iptables-1.4.21/iptables/ip6tables-restore.c.restore_version 2017-04-20 16:49:34.253130005 +0200 ++++ iptables-1.4.21/iptables/ip6tables-restore.c 2017-04-20 16:51:43.931089903 +0200 +@@ -37,6 +37,7 @@ static const struct option options[] = { + {.name = "binary", .has_arg = 0, .val = 'b'}, + {.name = "counters", .has_arg = 0, .val = 'c'}, + {.name = "verbose", .has_arg = 0, .val = 'v'}, ++ {.name = "version", .has_arg = 0, .val = 'V'}, + {.name = "test", .has_arg = 0, .val = 't'}, + {.name = "help", .has_arg = 0, .val = 'h'}, + {.name = "noflush", .has_arg = 0, .val = 'n'}, +@@ -49,12 +50,16 @@ static const struct option options[] = { + + static void print_usage(const char *name, const char *version) __attribute__((noreturn)); + ++#define prog_name ip6tables_globals.program_name ++#define prog_vers ip6tables_globals.program_version ++ + static void print_usage(const char *name, const char *version) + { +- fprintf(stderr, "Usage: %s [-b] [-c] [-v] [-t] [-h] [-w secs] [-W usecs]\n" ++ fprintf(stderr, "Usage: %s [-b] [-c] [-v] [-V] [-t] [-h] [-w secs] [-W usecs]\n" + " [ --binary ]\n" + " [ --counters ]\n" + " [ --verbose ]\n" ++ " [ --version]\n" + " [ --test ]\n" + " [ --help ]\n" + " [ --wait=\n" +@@ -79,8 +84,7 @@ static struct xtc_handle *create_handle( + + if (!handle) { + xtables_error(PARAMETER_PROBLEM, "%s: unable to initialize " +- "table '%s'\n", ip6tables_globals.program_name, +- tablename); ++ "table '%s'\n", prog_name, tablename); + exit(1); + } + return handle; +@@ -214,7 +218,7 @@ int ip6tables_restore_main(int argc, cha + init_extensions6(); + #endif + +- while ((c = getopt_long(argc, argv, "bcvthnwWM:T:", options, NULL)) != -1) { ++ while ((c = getopt_long(argc, argv, "bcvVthnwWM:T:", options, NULL)) != -1) { + switch (c) { + case 'b': + binary = 1; +@@ -225,6 +229,9 @@ int ip6tables_restore_main(int argc, cha + case 'v': + verbose = 1; + break; ++ case 'V': ++ printf("%s v%s\n", prog_name, prog_vers); ++ exit(0); + case 't': + testing = 1; + break; +diff -up iptables-1.4.21/iptables/iptables-restore.8.in.restore_version iptables-1.4.21/iptables/iptables-restore.8.in +--- iptables-1.4.21/iptables/iptables-restore.8.in.restore_version 2013-11-22 12:18:13.000000000 +0100 ++++ iptables-1.4.21/iptables/iptables-restore.8.in 2017-04-20 16:52:20.883299806 +0200 +@@ -23,9 +23,9 @@ iptables-restore \(em Restore IP Tables + .P + ip6tables-restore \(em Restore IPv6 Tables + .SH SYNOPSIS +-\fBiptables\-restore\fP [\fB\-chntv\fP] [\fB\-M\fP \fImodprobe\fP] ++\fBiptables\-restore\fP [\fB\-chntvV\fP] [\fB\-M\fP \fImodprobe\fP] + .P +-\fBip6tables\-restore\fP [\fB\-chntv\fP] [\fB\-M\fP \fImodprobe\fP] ++\fBip6tables\-restore\fP [\fB\-chntvV\fP] [\fB\-M\fP \fImodprobe\fP] + [\fB\-T\fP \fIname\fP] + .SH DESCRIPTION + .PP +@@ -51,6 +51,9 @@ Only parse and construct the ruleset, bu + \fB\-v\fP, \fB\-\-verbose\fP + Print additional debug info during ruleset processing. + .TP ++\fB\-V\fP, \fB\-\-version\fP ++Print the program version number. ++.TP + \fB\-M\fP, \fB\-\-modprobe\fP \fImodprobe_program\fP + Specify the path to the modprobe program. By default, iptables-restore will + inspect /proc/sys/kernel/modprobe to determine the executable's path. +diff -up iptables-1.4.21/iptables/iptables-restore.c.restore_version iptables-1.4.21/iptables/iptables-restore.c +--- iptables-1.4.21/iptables/iptables-restore.c.restore_version 2017-04-20 16:49:34.253130005 +0200 ++++ iptables-1.4.21/iptables/iptables-restore.c 2017-04-20 17:29:32.495390523 +0200 +@@ -34,6 +34,7 @@ static const struct option options[] = { + {.name = "binary", .has_arg = 0, .val = 'b'}, + {.name = "counters", .has_arg = 0, .val = 'c'}, + {.name = "verbose", .has_arg = 0, .val = 'v'}, ++ {.name = "version", .has_arg = 0, .val = 'V'}, + {.name = "test", .has_arg = 0, .val = 't'}, + {.name = "help", .has_arg = 0, .val = 'h'}, + {.name = "noflush", .has_arg = 0, .val = 'n'}, +@@ -47,13 +48,15 @@ static const struct option options[] = { + static void print_usage(const char *name, const char *version) __attribute__((noreturn)); + + #define prog_name iptables_globals.program_name ++#define prog_vers iptables_globals.program_version + + static void print_usage(const char *name, const char *version) + { +- fprintf(stderr, "Usage: %s [-b] [-c] [-v] [-t] [-h] [-W usecs]\n" ++ fprintf(stderr, "Usage: %s [-b] [-c] [-v] [-V] [-t] [-h] [-W usecs]\n" + " [ --binary ]\n" + " [ --counters ]\n" + " [ --verbose ]\n" ++ " [ --version]\n" + " [ --test ]\n" + " [ --help ]\n" + " [ --noflush ]\n" +@@ -214,7 +217,7 @@ iptables_restore_main(int argc, char *ar + init_extensions4(); + #endif + +- while ((c = getopt_long(argc, argv, "bcvthnwWM:T:", options, NULL)) != -1) { ++ while ((c = getopt_long(argc, argv, "bcvVthnwWM:T:", options, NULL)) != -1) { + switch (c) { + case 'b': + binary = 1; +@@ -225,6 +228,9 @@ iptables_restore_main(int argc, char *ar + case 'v': + verbose = 1; + break; ++ case 'V': ++ printf("%s v%s\n", prog_name, prog_vers); ++ exit(0); + case 't': + testing = 1; + break; diff --git a/SOURCES/iptables-1.4.21-restore_wait_man.patch b/SOURCES/iptables-1.4.21-restore_wait_man.patch new file mode 100644 index 0000000..4d3b3df --- /dev/null +++ b/SOURCES/iptables-1.4.21-restore_wait_man.patch @@ -0,0 +1,51 @@ +Adapted version of + +commit 65801d02a482befd2745c792d6596ec75d434934 +Author: Dan Williams +Date: Mon Apr 10 12:35:18 2017 -0500 + + iptables-restore.8: document -w/-W options + + Fixes: 999eaa241212 ("iptables-restore: support acquiring the lock.") + Signed-off-by: Dan Williams + Signed-off-by: Pablo Neira Ayuso + +diff -up iptables-1.4.21/iptables/iptables-restore.8.in.restore_wait_man iptables-1.4.21/iptables/iptables-restore.8.in +--- iptables-1.4.21/iptables/iptables-restore.8.in.restore_wait_man 2017-04-20 17:33:23.386401192 +0200 ++++ iptables-1.4.21/iptables/iptables-restore.8.in 2017-04-20 17:35:13.562713997 +0200 +@@ -23,9 +23,11 @@ iptables-restore \(em Restore IP Tables + .P + ip6tables-restore \(em Restore IPv6 Tables + .SH SYNOPSIS +-\fBiptables\-restore\fP [\fB\-chntvV\fP] [\fB\-M\fP \fImodprobe\fP] ++\fBiptables\-restore\fP [\fB\-chntvV\fP] [\fB\-w\fP \fIsecs\fP] +++[\fB\-W\fP \fIusecs\fP] [\fB\-M\fP \fImodprobe\fP] + .P +-\fBip6tables\-restore\fP [\fB\-chntvV\fP] [\fB\-M\fP \fImodprobe\fP] ++\fBip6tables\-restore\fP [\fB\-chntvV\fP] [\fB\-w\fP \fIsecs\fP] +++[\fB\-W\fP \fIusecs\fP] [\fB\-M\fP \fImodprobe\fP] + [\fB\-T\fP \fIname\fP] + .SH DESCRIPTION + .PP +@@ -54,6 +56,21 @@ Print additional debug info during rules + \fB\-V\fP, \fB\-\-version\fP + Print the program version number. + .TP ++\fB\-w\fP, \fB\-\-wait\fP [\fIseconds\fP] ++Wait for the xtables lock. ++To prevent multiple instances of the program from running concurrently, ++an attempt will be made to obtain an exclusive lock at launch. By default, ++the program will exit if the lock cannot be obtained. This option will ++make the program wait (indefinitely or for optional \fIseconds\fP) until ++the exclusive lock can be obtained. ++.TP ++\fB\-W\fP, \fB\-\-wait-interval\fP \fImicroseconds\fP ++Interval to wait per each iteration. ++When running latency sensitive applications, waiting for the xtables lock ++for extended durations may not be acceptable. This option will make each ++iteration take the amount of time specified. The default interval is ++1 second. This option only works with \fB\-w\fP. ++.TP + \fB\-M\fP, \fB\-\-modprobe\fP \fImodprobe_program\fP + Specify the path to the modprobe program. By default, iptables-restore will + inspect /proc/sys/kernel/modprobe to determine the executable's path. diff --git a/SOURCES/iptables-1.4.21-wait-interval.patch b/SOURCES/iptables-1.4.21-wait-interval.patch new file mode 100644 index 0000000..ac116d8 --- /dev/null +++ b/SOURCES/iptables-1.4.21-wait-interval.patch @@ -0,0 +1,330 @@ +Adapted version of + +commit e8f857a5a1514c3e7d0d8ea0f7d2d571f0e37bd1 +Author: Subash Abhinov Kasiviswanathan +Date: Thu Jun 23 18:44:06 2016 -0600 + + xtables: Add an interval option for xtables lock wait + + ip[6]tables currently waits for 1 second for the xtables lock to be + freed if the -w option is used. We have seen that the lock is held + much less than that resulting in unnecessary delay when trying to + acquire the lock. This problem is even severe in case of latency + sensitive applications. + + Introduce a new option 'W' to specify the wait interval in microseconds. + If this option is not specified, the command sleeps for 1 second by + default. + + v1->v2: Change behavior to take millisecond sleep as an argument to + -w as suggested by Pablo. Also maintain current behavior for -w to + sleep for 1 second as mentioned by Liping. + + v2->v3: Move the millisecond behavior to a new option as suggested + by Pablo. + + v3->v4: Use select instead of usleep. Sleep every iteration for + the time specified in the "-W" argument. Update man page. + + v4->v5: Fix compilation error when enabling nftables + + v5->v6: Simplify -W so it only takes the interval wait in microseconds. + Bail out if -W is specific but -w is not. + + Joint work with Pablo Neira. + + Signed-off-by: Subash Abhinov Kasiviswanathan + Signed-off-by: Pablo Neira Ayuso + +diff -up iptables-1.4.21/iptables/ip6tables.c.wait-interval iptables-1.4.21/iptables/ip6tables.c +--- iptables-1.4.21/iptables/ip6tables.c.wait-interval 2017-04-05 14:04:04.560346651 +0200 ++++ iptables-1.4.21/iptables/ip6tables.c 2017-04-05 14:04:04.562346670 +0200 +@@ -103,6 +103,7 @@ static struct option original_opts[] = { + {.name = "out-interface", .has_arg = 1, .val = 'o'}, + {.name = "verbose", .has_arg = 0, .val = 'v'}, + {.name = "wait", .has_arg = 2, .val = 'w'}, ++ {.name = "wait-interval", .has_arg = 2, .val = 'W'}, + {.name = "exact", .has_arg = 0, .val = 'x'}, + {.name = "version", .has_arg = 0, .val = 'V'}, + {.name = "help", .has_arg = 2, .val = 'h'}, +@@ -258,7 +259,10 @@ exit_printhelp(const struct xtables_rule + " network interface name ([+] for wildcard)\n" + " --table -t table table to manipulate (default: `filter')\n" + " --verbose -v verbose mode\n" +-" --wait -w [seconds] wait for the xtables lock\n" ++" --wait -w [seconds] maximum wait to acquire xtables lock before give up\n" ++" --wait-interval -W [usecs] wait time to try to acquire xtables lock\n" ++" interval to wait for xtables lock\n" ++" default is 1 second\n" + " --line-numbers print line numbers when listing\n" + " --exact -x expand numbers (display exact values)\n" + /*"[!] --fragment -f match second or further fragments only\n"*/ +@@ -1323,6 +1327,10 @@ int do_command6(int argc, char *argv[], + + int verbose = 0; + int wait = 0; ++ struct timeval wait_interval = { ++ .tv_sec = 1, ++ }; ++ bool wait_interval_set = false; + const char *chain = NULL; + const char *shostnetworkmask = NULL, *dhostnetworkmask = NULL; + const char *policy = NULL, *newname = NULL; +@@ -1358,7 +1366,7 @@ int do_command6(int argc, char *argv[], + + opts = xt_params->orig_opts; + while ((cs.c = getopt_long(argc, argv, +- "-:A:C:D:R:I:L::S::M:F::Z::N:X::E:P:Vh::o:p:s:d:j:i:bvw::nt:m:xc:g:46", ++ "-:A:C:D:R:I:L::S::M:F::Z::N:X::E:P:Vh::o:p:s:d:j:i:bvw::W::nt:m:xc:g:46", + opts, NULL)) != -1) { + switch (cs.c) { + /* +@@ -1614,6 +1622,23 @@ int do_command6(int argc, char *argv[], + "wait seconds not numeric"); + break; + ++ case 'W': ++ if (restore) { ++ xtables_error(PARAMETER_PROBLEM, ++ "You cannot use `-W' from " ++ "ip6tables-restore"); ++ } ++ if (optarg) ++ parse_wait_interval(optarg, &wait_interval); ++ else if (optind < argc && ++ argv[optind][0] != '-' && ++ argv[optind][0] != '!') ++ parse_wait_interval(argv[optind++], ++ &wait_interval); ++ ++ wait_interval_set = true; ++ break; ++ + case 'm': + command_match(&cs); + break; +@@ -1718,6 +1743,10 @@ int do_command6(int argc, char *argv[], + cs.invert = FALSE; + } + ++ if (!wait && wait_interval_set) ++ xtables_error(PARAMETER_PROBLEM, ++ "--wait-interval only makes sense with --wait\n"); ++ + if (strcmp(*table, "nat") == 0 && + ((policy != NULL && strcmp(policy, "DROP") == 0) || + (cs.jumpto != NULL && strcmp(cs.jumpto, "DROP") == 0))) +@@ -1768,7 +1797,7 @@ int do_command6(int argc, char *argv[], + generic_opt_check(command, cs.options); + + /* Attempt to acquire the xtables lock */ +- if (!restore && !xtables_lock(wait)) { ++ if (!restore && !xtables_lock(wait, &wait_interval)) { + fprintf(stderr, "Another app is currently holding the xtables lock. "); + if (wait == 0) + fprintf(stderr, "Perhaps you want to use the -w option?\n"); +diff -up iptables-1.4.21/iptables/iptables.8.in.wait-interval iptables-1.4.21/iptables/iptables.8.in +--- iptables-1.4.21/iptables/iptables.8.in.wait-interval 2017-04-05 14:04:04.555346605 +0200 ++++ iptables-1.4.21/iptables/iptables.8.in 2017-04-05 14:04:04.562346670 +0200 +@@ -369,6 +369,13 @@ the program will exit if the lock cannot + make the program wait (indefinitely or for optional \fIseconds\fP) until + the exclusive lock can be obtained. + .TP ++\fB\-W\fP, \fB\-\-wait-interval\fP \fImicroseconds\fP ++Interval to wait per each iteration. ++When running latency sensitive applications, waiting for the xtables lock ++for extended durations may not be acceptable. This option will make each ++iteration take the amount of time specified. The default interval is ++1 second. This option only works with \fB\-w\fP. ++.TP + \fB\-n\fP, \fB\-\-numeric\fP + Numeric output. + IP addresses and port numbers will be printed in numeric format. +diff -up iptables-1.4.21/iptables/iptables.c.wait-interval iptables-1.4.21/iptables/iptables.c +--- iptables-1.4.21/iptables/iptables.c.wait-interval 2017-04-05 14:04:04.555346605 +0200 ++++ iptables-1.4.21/iptables/iptables.c 2017-04-05 14:04:04.563346679 +0200 +@@ -100,6 +100,7 @@ static struct option original_opts[] = { + {.name = "out-interface", .has_arg = 1, .val = 'o'}, + {.name = "verbose", .has_arg = 0, .val = 'v'}, + {.name = "wait", .has_arg = 2, .val = 'w'}, ++ {.name = "wait-interval", .has_arg = 2, .val = 'W'}, + {.name = "exact", .has_arg = 0, .val = 'x'}, + {.name = "fragments", .has_arg = 0, .val = 'f'}, + {.name = "version", .has_arg = 0, .val = 'V'}, +@@ -252,7 +253,9 @@ exit_printhelp(const struct xtables_rule + " network interface name ([+] for wildcard)\n" + " --table -t table table to manipulate (default: `filter')\n" + " --verbose -v verbose mode\n" +-" --wait -w [seconds] wait for the xtables lock\n" ++" --wait -w [seconds] maximum wait to acquire xtables lock before give up\n" ++" --wait-interval -W [usecs] wait time to try to acquire xtables lock\n" ++" default is 1 second\n" + " --line-numbers print line numbers when listing\n" + " --exact -x expand numbers (display exact values)\n" + "[!] --fragment -f match second or further fragments only\n" +@@ -1316,7 +1319,10 @@ int do_command4(int argc, char *argv[], + unsigned int nsaddrs = 0, ndaddrs = 0; + struct in_addr *saddrs = NULL, *smasks = NULL; + struct in_addr *daddrs = NULL, *dmasks = NULL; +- ++ struct timeval wait_interval = { ++ .tv_sec = 1, ++ }; ++ bool wait_interval_set = false; + int verbose = 0; + int wait = 0; + const char *chain = NULL; +@@ -1353,7 +1359,7 @@ int do_command4(int argc, char *argv[], + opterr = 0; + opts = xt_params->orig_opts; + while ((cs.c = getopt_long(argc, argv, +- "-:A:C:D:R:I:L::S::M:F::Z::N:X::E:P:Vh::o:p:s:d:j:i:fbvw::nt:m:xc:g:46", ++ "-:A:C:D:R:I:L::S::M:F::Z::N:X::E:P:Vh::o:p:s:d:j:i:fbvw::W::nt:m:xc:g:46", + opts, NULL)) != -1) { + switch (cs.c) { + /* +@@ -1607,6 +1613,23 @@ int do_command4(int argc, char *argv[], + "wait seconds not numeric"); + break; + ++ case 'W': ++ if (restore) { ++ xtables_error(PARAMETER_PROBLEM, ++ "You cannot use `-W' from " ++ "iptables-restore"); ++ } ++ if (optarg) ++ parse_wait_interval(optarg, &wait_interval); ++ else if (optind < argc && ++ argv[optind][0] != '-' && ++ argv[optind][0] != '!') ++ parse_wait_interval(argv[optind++], ++ &wait_interval); ++ ++ wait_interval_set = true; ++ break; ++ + case 'm': + command_match(&cs); + break; +@@ -1707,6 +1730,10 @@ int do_command4(int argc, char *argv[], + cs.invert = FALSE; + } + ++ if (!wait && wait_interval_set) ++ xtables_error(PARAMETER_PROBLEM, ++ "--wait-interval only makes sense with --wait\n"); ++ + if (strcmp(*table, "nat") == 0 && + ((policy != NULL && strcmp(policy, "DROP") == 0) || + (cs.jumpto != NULL && strcmp(cs.jumpto, "DROP") == 0))) +@@ -1757,7 +1784,7 @@ int do_command4(int argc, char *argv[], + generic_opt_check(command, cs.options); + + /* Attempt to acquire the xtables lock */ +- if (!restore && !xtables_lock(wait)) { ++ if (!restore && !xtables_lock(wait, &wait_interval)) { + fprintf(stderr, "Another app is currently holding the xtables lock. "); + if (wait == 0) + fprintf(stderr, "Perhaps you want to use the -w option?\n"); +diff -up iptables-1.4.21/iptables/xshared.c.wait-interval iptables-1.4.21/iptables/xshared.c +--- iptables-1.4.21/iptables/xshared.c.wait-interval 2017-04-05 14:04:04.557346624 +0200 ++++ iptables-1.4.21/iptables/xshared.c 2017-04-05 14:04:04.563346679 +0200 +@@ -9,12 +9,15 @@ + #include + #include + #include ++#include + #include + #include + #include ++#include + #include "xshared.h" + + #define XT_LOCK_NAME "/run/xtables.lock" ++#define BASE_MICROSECONDS 100000 + + /* + * Print out any special helps. A user might like to be able to add a --help +@@ -244,9 +247,15 @@ void xs_init_match(struct xtables_match + match->init(match->m); + } + +-bool xtables_lock(int wait) ++bool xtables_lock(int wait, struct timeval *wait_interval) + { +- int fd, waited = 0, i = 0; ++ struct timeval time_left, wait_time, waited_time; ++ int fd, i = 0; ++ ++ time_left.tv_sec = wait; ++ time_left.tv_usec = 0; ++ waited_time.tv_sec = 0; ++ waited_time.tv_usec = 0; + + fd = open(XT_LOCK_NAME, O_CREAT, 0600); + if (fd < 0) +@@ -255,12 +264,43 @@ bool xtables_lock(int wait) + while (1) { + if (flock(fd, LOCK_EX | LOCK_NB) == 0) + return true; +- else if (wait >= 0 && waited >= wait) ++ if (++i % 10 == 0) { ++ if (wait != -1) ++ fprintf(stderr, "Another app is currently holding the xtables lock; " ++ "still %lds %ldus time ahead to have a chance to grab the lock...\n", ++ time_left.tv_sec, time_left.tv_usec); ++ else ++ fprintf(stderr, "Another app is currently holding the xtables lock; " ++ "waiting for it to exit...\n"); ++ } ++ ++ wait_time = *wait_interval; ++ select(0, NULL, NULL, NULL, &wait_time); ++ if (wait == -1) ++ continue; ++ ++ timeradd(&waited_time, wait_interval, &waited_time); ++ timersub(&time_left, wait_interval, &time_left); ++ if (!timerisset(&time_left)) + return false; +- if (++i % 2 == 0) +- fprintf(stderr, "Another app is currently holding the xtables lock; " +- "waiting (%ds) for it to exit...\n", waited); +- waited++; +- sleep(1); + } + } ++ ++void parse_wait_interval(const char *str, struct timeval *wait_interval) ++{ ++ unsigned int usec; ++ int ret; ++ ++ ret = sscanf(str, "%u", &usec); ++ if (ret == 1) { ++ if (usec > 999999) ++ xtables_error(PARAMETER_PROBLEM, ++ "too long usec wait %u > 999999 usec", ++ usec); ++ ++ wait_interval->tv_sec = 0; ++ wait_interval->tv_usec = usec; ++ return; ++ } ++ xtables_error(PARAMETER_PROBLEM, "wait interval not numeric"); ++} +diff -up iptables-1.4.21/iptables/xshared.h.wait-interval iptables-1.4.21/iptables/xshared.h +--- iptables-1.4.21/iptables/xshared.h.wait-interval 2017-04-05 14:04:04.555346605 +0200 ++++ iptables-1.4.21/iptables/xshared.h 2017-04-05 14:04:04.563346679 +0200 +@@ -84,7 +84,9 @@ extern struct xtables_match *load_proto( + extern int subcmd_main(int, char **, const struct subcommand *); + extern void xs_init_target(struct xtables_target *); + extern void xs_init_match(struct xtables_match *); +-extern bool xtables_lock(int wait); ++bool xtables_lock(int wait, struct timeval *wait_interval); ++ ++void parse_wait_interval(const char *str, struct timeval *wait_interval); + + extern const struct xtables_afinfo *afinfo; + diff --git a/SOURCES/iptables-do_not_lock_again_and_again.patch b/SOURCES/iptables-do_not_lock_again_and_again.patch new file mode 100644 index 0000000..6d4913d --- /dev/null +++ b/SOURCES/iptables-do_not_lock_again_and_again.patch @@ -0,0 +1,78 @@ +commit 24f8174646123c2833bc87967b366796231b04e0 +Author: Liping Zhang +Date: Sun Feb 5 21:57:34 2017 +0800 + + xshared: do not lock again and again if "-w" option is not specified + + After running the following commands, some confusing messages was printed + out: + # while : ; do + iptables -A INPUT & + iptables -D INPUT & + done + [...] + Another app is currently holding the xtables lock; still -9s 0us time + ahead to have a chance to grab the lock... + Another app is currently holding the xtables lock; still -29s 0us time + ahead to have a chance to grab the lock... + + If "-w" option is not specified, the "wait" will be zero, so we should + check whether the timer_left is less than wait_interval before we call + select to sleep. + + Also remove unused "BASE_MICROSECONDS" and "struct timeval waited_time" + introduced by commit e8f857a5a151 ("xtables: Add an interval option for + xtables lock wait"). + + Fixes: e8f857a5a151 ("xtables: Add an interval option for xtables lock wait") + Signed-off-by: Liping Zhang + Signed-off-by: Pablo Neira Ayuso + +diff --git a/iptables/xshared.c b/iptables/xshared.c +index cccb8ae..055acf2 100644 +--- a/iptables/xshared.c ++++ b/iptables/xshared.c +@@ -17,7 +17,6 @@ + #include "xshared.h" + + #define XT_LOCK_NAME "/run/xtables.lock" +-#define BASE_MICROSECONDS 100000 + + /* + * Print out any special helps. A user might like to be able to add a --help +@@ -249,13 +248,11 @@ void xs_init_match(struct xtables_match *match) + + bool xtables_lock(int wait, struct timeval *wait_interval) + { +- struct timeval time_left, wait_time, waited_time; ++ struct timeval time_left, wait_time; + int fd, i = 0; + + time_left.tv_sec = wait; + time_left.tv_usec = 0; +- waited_time.tv_sec = 0; +- waited_time.tv_usec = 0; + + fd = open(XT_LOCK_NAME, O_CREAT, 0600); + if (fd < 0) +@@ -264,6 +261,9 @@ bool xtables_lock(int wait, struct timeval *wait_interval) + while (1) { + if (flock(fd, LOCK_EX | LOCK_NB) == 0) + return true; ++ else if (wait >= 0 && timercmp(&time_left, wait_interval, <)) ++ return false; ++ + if (++i % 10 == 0) { + if (wait != -1) + fprintf(stderr, "Another app is currently holding the xtables lock; " +@@ -279,10 +279,7 @@ bool xtables_lock(int wait, struct timeval *wait_interval) + if (wait == -1) + continue; + +- timeradd(&waited_time, wait_interval, &waited_time); + timersub(&time_left, wait_interval, &time_left); +- if (!timerisset(&time_left)) +- return false; + } + } + diff --git a/SOURCES/iptables-do_not_set_changed_for_check_options.patch b/SOURCES/iptables-do_not_set_changed_for_check_options.patch new file mode 100644 index 0000000..f36e064 --- /dev/null +++ b/SOURCES/iptables-do_not_set_changed_for_check_options.patch @@ -0,0 +1,79 @@ +commit 9b8cb7564a53865bf0e239bbc3e057de70edf65d +Author: Dan Williams +Date: Sat Feb 25 22:02:03 2017 -0600 + + libiptc: don't set_changed() when checking rules with module jumps + + Checking a rule that includes a jump to a module-based target currently + sets the "changed" flag on the handle, which then causes TC_COMMIT() to + run through the whole SO_SET_REPLACE/SO_SET_ADD_COUNTERS path. This + seems wrong for simply checking rules, an operation which is documented + as "...does not alter the existing iptables configuration..." but yet + it clearly could do so. + + Fix that by ensuring that rule check operations for module targets + don't set the changed flag, and thus exit early from TC_COMMIT(). + + Signed-off-by: Dan Williams + Signed-off-by: Pablo Neira Ayuso + +diff --git a/libiptc/libiptc.c b/libiptc/libiptc.c +index 2c66d04..a6e7057 100644 +--- a/libiptc/libiptc.c ++++ b/libiptc/libiptc.c +@@ -1686,7 +1686,8 @@ iptcc_standard_map(struct rule_head *r, int verdict) + + static int + iptcc_map_target(struct xtc_handle *const handle, +- struct rule_head *r) ++ struct rule_head *r, ++ bool dry_run) + { + STRUCT_ENTRY *e = r->entry; + STRUCT_ENTRY_TARGET *t = GET_TARGET(e); +@@ -1731,7 +1732,8 @@ iptcc_map_target(struct xtc_handle *const handle, + 0, + FUNCTION_MAXNAMELEN - 1 - strlen(t->u.user.name)); + r->type = IPTCC_R_MODULE; +- set_changed(handle); ++ if (!dry_run) ++ set_changed(handle); + return 1; + } + +@@ -1781,7 +1783,7 @@ TC_INSERT_ENTRY(const IPT_CHAINLABEL chain, + memcpy(r->entry, e, e->next_offset); + r->counter_map.maptype = COUNTER_MAP_SET; + +- if (!iptcc_map_target(handle, r)) { ++ if (!iptcc_map_target(handle, r, false)) { + free(r); + return 0; + } +@@ -1831,7 +1833,7 @@ TC_REPLACE_ENTRY(const IPT_CHAINLABEL chain, + memcpy(r->entry, e, e->next_offset); + r->counter_map.maptype = COUNTER_MAP_SET; + +- if (!iptcc_map_target(handle, r)) { ++ if (!iptcc_map_target(handle, r, false)) { + free(r); + return 0; + } +@@ -1870,7 +1872,7 @@ TC_APPEND_ENTRY(const IPT_CHAINLABEL chain, + memcpy(r->entry, e, e->next_offset); + r->counter_map.maptype = COUNTER_MAP_SET; + +- if (!iptcc_map_target(handle, r)) { ++ if (!iptcc_map_target(handle, r, false)) { + DEBUGP("unable to map target of rule for chain `%s'\n", chain); + free(r); + return 0; +@@ -1976,7 +1978,7 @@ static int delete_entry(const IPT_CHAINLABEL chain, const STRUCT_ENTRY *origfw, + + memcpy(r->entry, origfw, origfw->next_offset); + r->counter_map.maptype = COUNTER_MAP_NOMAP; +- if (!iptcc_map_target(handle, r)) { ++ if (!iptcc_map_target(handle, r, dry_run)) { + DEBUGP("unable to map target of rule for chain `%s'\n", chain); + free(r); + return 0; diff --git a/SOURCES/iptables-use_the_blocking_file_lock_request.patch b/SOURCES/iptables-use_the_blocking_file_lock_request.patch new file mode 100644 index 0000000..1cddc36 --- /dev/null +++ b/SOURCES/iptables-use_the_blocking_file_lock_request.patch @@ -0,0 +1,91 @@ +commit 72bb3dbf0ecdf3ec96aee80e5d152c8be4394da1 +Author: Liping Zhang +Date: Mon Feb 6 19:47:47 2017 +0800 + + xshared: using the blocking file lock request when we wait indefinitely + + When using "-w" to avoid concurrent instances, we try to do flock() every + one second until it success. But one second maybe too long in some + situations, and it's hard to select a suitable interval time. So when + using "iptables -w" to wait indefinitely, it's better to block until + it become success. + + Now do some performance tests. First, flush all the iptables rules in + filter table, and run "iptables -w -S" endlessly: + # iptables -F + # iptables -X + # while : ; do + iptables -w -S >&- & + done + + Second, after adding and deleting the iptables rules 100 times, measure + the time cost: + # time for i in $(seq 100); do + iptables -w -A INPUT + iptables -w -D INPUT + done + + Before this patch: + real 1m15.962s + user 0m0.224s + sys 0m1.475s + + Apply this patch: + real 0m1.830s + user 0m0.168s + sys 0m1.130s + + Signed-off-by: Liping Zhang + Signed-off-by: Pablo Neira Ayuso + +diff --git a/iptables/xshared.c b/iptables/xshared.c +index 055acf2..f0a5ddd 100644 +--- a/iptables/xshared.c ++++ b/iptables/xshared.c +@@ -1,4 +1,5 @@ + #include ++#include + #include + #include + #include +@@ -258,27 +259,29 @@ bool xtables_lock(int wait, struct timeval *wait_interval) + if (fd < 0) + return true; + ++ if (wait == -1) { ++ if (flock(fd, LOCK_EX) == 0) ++ return true; ++ ++ fprintf(stderr, "Can't lock %s: %s\n", XT_LOCK_NAME, ++ strerror(errno)); ++ return false; ++ } ++ + while (1) { + if (flock(fd, LOCK_EX | LOCK_NB) == 0) + return true; +- else if (wait >= 0 && timercmp(&time_left, wait_interval, <)) ++ else if (timercmp(&time_left, wait_interval, <)) + return false; + + if (++i % 10 == 0) { +- if (wait != -1) +- fprintf(stderr, "Another app is currently holding the xtables lock; " +- "still %lds %ldus time ahead to have a chance to grab the lock...\n", +- time_left.tv_sec, time_left.tv_usec); +- else +- fprintf(stderr, "Another app is currently holding the xtables lock; " +- "waiting for it to exit...\n"); ++ fprintf(stderr, "Another app is currently holding the xtables lock; " ++ "still %lds %ldus time ahead to have a chance to grab the lock...\n", ++ time_left.tv_sec, time_left.tv_usec); + } + + wait_time = *wait_interval; + select(0, NULL, NULL, NULL, &wait_time); +- if (wait == -1) +- continue; +- + timersub(&time_left, wait_interval, &time_left); + } + } diff --git a/SPECS/iptables.spec b/SPECS/iptables.spec index 9e237dd..91c3aa2 100644 --- a/SPECS/iptables.spec +++ b/SPECS/iptables.spec @@ -7,7 +7,7 @@ Name: iptables Summary: Tools for managing Linux kernel packet filtering capabilities Version: 1.4.21 -Release: 17%{?dist} +Release: 18%{?dist} Source: http://www.netfilter.org/projects/iptables/files/%{name}-%{version}.tar.bz2 Source1: iptables.init Source2: iptables-config @@ -22,6 +22,18 @@ Patch3: iptables-1.4.21-wait_seconds.patch Patch4: iptables-1.4.21-flock_wait.patch Patch5: iptables-1.4.21-rhbz_1261238.patch Patch6: iptables-c513cc3-rhbz_1298879.patch +Patch7: iptables-1.4.21-wait-interval.patch +Patch8: iptables-do_not_lock_again_and_again.patch +Patch9: iptables-use_the_blocking_file_lock_request.patch +Patch10: iptables-1.4.21-configure_set_lock_file_path.patch +Patch11: iptables-1.4.21-move_XT_LOCK_NAME_to_config.h.patch +Patch12: iptables-1.4.21-remove_duplicated_argument_parsing.patch +Patch13: iptables-1.4.21-restore_support_acquiring_the_lock.patch +# One patch invalid: 1cf4ba6fbe85b3cbe9828a7947000290e1989986 +Patch14: iptables-do_not_set_changed_for_check_options.patch +Patch15: iptables-1.4.21-restore_version.patch +Patch16: iptables-1.4.21-restore_wait_man.patch + Group: System Environment/Base URL: http://www.netfilter.org/ License: GPLv2 @@ -32,6 +44,8 @@ BuildRequires: libnfnetlink-devel BuildRequires: libselinux-devel BuildRequires: kernel-headers BuildRequires: systemd +BuildRequires: automake +BuildRequires: autoconf %description The iptables utility controls the network packet filtering code in the @@ -90,6 +104,16 @@ Currently only provides nfnl_osf with the pf.os database. %patch4 -p1 -b .flock_wait %patch5 -p1 -b .rhbz_1261238 %patch6 -p1 -b .rhbz_1298879 +%patch7 -p1 -b .wait-interval +%patch8 -p1 -b .do_not_lock_again_and_again +%patch9 -p1 -b .use_the_blocking_file_lock_request +%patch10 -p1 -b .configure_set_lock_file_path +%patch11 -p1 -b .move_XT_LOCK_NAME_to_config.h +%patch12 -p1 -b .remove_duplicated_argument_parsing +%patch13 -p1 -b .restore_support_acquiring_the_lock +%patch14 -p1 -b .do_not_set_changed_for_check_options +%patch15 -p1 -b .restore_version +%patch16 -p1 -b .restore_wait_man %build CFLAGS="$RPM_OPT_FLAGS -fno-strict-aliasing " \ @@ -243,6 +267,12 @@ done %changelog +* Mon Apr 24 2017 Thomas Woerner 1.4.21-18 +- Add support for --wait options to restore commands (RHBZ#1438597) +- Do not set changed flag for rule check operations with module targets + (RHBZ#1438597) +- Add version option to restore commands (RHBZ#1438597) + * Fri Jul 1 2016 Thomas Woerner 1.4.21-17 - Fixed init script not to fail on missing restorecon (RHBZ#1246380) - Adapted man page snipplet for TRACE to use proper logging backend names