Legacy iptables doesn't accept -4 or -6 if they don't match the symlink's native family. The only exception to that is iptables-restore which simply ignores the lines introduced by non-matching options, which is useful to create combined dump files for feeding into both iptables-restore and ip6tables-restore. Signed-off-by: Phil Sutter <phil@xxxxxx> --- .../shell/testcases/iptables/0006-46-args_0 | 88 +++++++++++++++++++ iptables/xtables.c | 21 ++--- 2 files changed, 96 insertions(+), 13 deletions(-) create mode 100755 iptables/tests/shell/testcases/iptables/0006-46-args_0 diff --git a/iptables/tests/shell/testcases/iptables/0006-46-args_0 b/iptables/tests/shell/testcases/iptables/0006-46-args_0 new file mode 100755 index 0000000000000..17a0a01829df5 --- /dev/null +++ b/iptables/tests/shell/testcases/iptables/0006-46-args_0 @@ -0,0 +1,88 @@ +#!/bin/bash + +RC=0 + +$XT_MULTI iptables -6 -A FORWARD -j ACCEPT +rc=$? +if [[ $rc -ne 2 ]]; then + echo "'iptables -6' returned $rc instead of 2" + RC=1 +fi + +$XT_MULTI ip6tables -4 -A FORWARD -j ACCEPT +rc=$? +if [[ $rc -ne 2 ]]; then + echo "'ip6tables -4' returned $rc instead of 2" + RC=1 +fi + +RULESET='*filter +-4 -A FORWARD -d 10.0.0.1 -j ACCEPT +-6 -A FORWARD -d fec0:10::1 -j ACCEPT +COMMIT +' +EXPECT4='-P FORWARD ACCEPT +-A FORWARD -d 10.0.0.1/32 -j ACCEPT' +EXPECT6='-P FORWARD ACCEPT +-A FORWARD -d fec0:10::1/128 -j ACCEPT' +EXPECT_EMPTY='-P FORWARD ACCEPT' + +echo "$RULESET" | $XT_MULTI iptables-restore || { + echo "iptables-restore failed!" + RC=1 +} +diff -u -Z <(echo -e "$EXPECT4") <($XT_MULTI iptables -S FORWARD) || { + echo "unexpected iptables ruleset" + RC=1 +} +diff -u -Z <(echo -e "$EXPECT_EMPTY") <($XT_MULTI ip6tables -S FORWARD) || { + echo "unexpected non-empty ip6tables ruleset" + RC=1 +} + +$XT_MULTI iptables -F FORWARD + +echo "$RULESET" | $XT_MULTI ip6tables-restore || { + echo "ip6tables-restore failed!" + RC=1 +} +diff -u -Z <(echo -e "$EXPECT6") <($XT_MULTI ip6tables -S FORWARD) || { + echo "unexpected ip6tables ruleset" + RC=1 +} +diff -u -Z <(echo -e "$EXPECT_EMPTY") <($XT_MULTI iptables -S FORWARD) || { + echo "unexpected non-empty iptables ruleset" + RC=1 +} + +$XT_MULTI ip6tables -F FORWARD + +$XT_MULTI iptables -4 -A FORWARD -d 10.0.0.1 -j ACCEPT || { + echo "iptables failed!" + RC=1 +} +diff -u -Z <(echo -e "$EXPECT4") <($XT_MULTI iptables -S FORWARD) || { + echo "unexpected iptables ruleset" + RC=1 +} +diff -u -Z <(echo -e "$EXPECT_EMPTY") <($XT_MULTI ip6tables -S FORWARD) || { + echo "unexpected non-empty ip6tables ruleset" + RC=1 +} + +$XT_MULTI iptables -F FORWARD + +$XT_MULTI ip6tables -6 -A FORWARD -d fec0:10::1 -j ACCEPT || { + echo "ip6tables failed!" + RC=1 +} +diff -u -Z <(echo -e "$EXPECT6") <($XT_MULTI ip6tables -S FORWARD) || { + echo "unexpected ip6tables ruleset" + RC=1 +} +diff -u -Z <(echo -e "$EXPECT_EMPTY") <($XT_MULTI iptables -S FORWARD) || { + echo "unexpected non-empty iptables ruleset" + RC=1 +} + +exit $RC diff --git a/iptables/xtables.c b/iptables/xtables.c index 8f9dc628d0029..3d75a1ddacae2 100644 --- a/iptables/xtables.c +++ b/iptables/xtables.c @@ -917,27 +917,22 @@ void do_parse(struct nft_handle *h, int argc, char *argv[], break; case '4': + if (args->family == AF_INET) + break; + if (p->restore && args->family == AF_INET6) return; - if (args->family != AF_INET) - exit_tryhelp(2); - - h->ops = nft_family_ops_lookup(args->family); - break; + exit_tryhelp(2); case '6': + if (args->family == AF_INET6) + break; + if (p->restore && args->family == AF_INET) return; - args->family = AF_INET6; - xtables_set_nfproto(AF_INET6); - - h->ops = nft_family_ops_lookup(args->family); - if (h->ops == NULL) - xtables_error(PARAMETER_PROBLEM, - "Unknown family"); - break; + exit_tryhelp(2); case 1: /* non option */ if (optarg[0] == '!' && optarg[1] == '\0') { -- 2.25.1