[prev in list] [next in list] [prev in thread] [next in thread] 

List:       netfilter-devel
Subject:    [iptables PATCH] xtables: Align return codes with legacy iptables
From:       Phil Sutter <phil () nwl ! cc>
Date:       2018-08-31 10:29:57
Message-ID: 20180831102957.16554-1-phil () nwl ! cc
[Download RAW message or body]

Make sure return codes match legacy ones at least for a few selected
commands typically used to check ruleset state.

Signed-off-by: Phil Sutter <phil@nwl.cc>
---
 iptables/nft.c                                | 15 ++++++++
 iptables/nft.h                                |  1 +
 .../testcases/ip6tables/0004-return-codes_0   | 38 +++++++++++++++++++
 .../testcases/iptables/0004-return-codes_0    | 38 +++++++++++++++++++
 iptables/xtables.c                            | 20 +++++++---
 5 files changed, 107 insertions(+), 5 deletions(-)
 create mode 100755 iptables/tests/shell/testcases/ip6tables/0004-return-codes_0
 create mode 100755 iptables/tests/shell/testcases/iptables/0004-return-codes_0

diff --git a/iptables/nft.c b/iptables/nft.c
index b2165069c6d89..7123060b34ef5 100644
--- a/iptables/nft.c
+++ b/iptables/nft.c
@@ -1725,6 +1725,21 @@ nft_chain_find(struct nft_handle *h, const char *table, const \
char *chain)  return nft_chain_list_find(list, table, chain);
 }
 
+bool nft_chain_exists(struct nft_handle *h,
+		      const char *table, const char *chain)
+{
+	struct builtin_table *t = nft_table_builtin_find(h, table);
+
+	/* xtables does not support custom tables */
+	if (!t)
+		return false;
+
+	if (nft_chain_builtin_find(t, chain))
+		return true;
+
+	return !!nft_chain_find(h, table, chain);
+}
+
 int nft_chain_user_rename(struct nft_handle *h,const char *chain,
 			  const char *table, const char *newname)
 {
diff --git a/iptables/nft.h b/iptables/nft.h
index eb14e908ab924..7419ec21a63a8 100644
--- a/iptables/nft.h
+++ b/iptables/nft.h
@@ -86,6 +86,7 @@ int nft_chain_user_flush(struct nft_handle *h, struct \
nftnl_chain_list *list,  int nft_chain_user_rename(struct nft_handle *h, const char \
*chain, const char *table, const char *newname);  int nft_chain_zero_counters(struct \
nft_handle *h, const char *chain, const char *table, bool verbose);  struct \
builtin_chain *nft_chain_builtin_find(struct builtin_table *t, const char *chain); \
+bool nft_chain_exists(struct nft_handle *h, const char *table, const char *chain);  
 /*
  * Operations with rule-set.
diff --git a/iptables/tests/shell/testcases/ip6tables/0004-return-codes_0 \
b/iptables/tests/shell/testcases/ip6tables/0004-return-codes_0 new file mode 100755
index 0000000000000..f023b7915498e
--- /dev/null
+++ b/iptables/tests/shell/testcases/ip6tables/0004-return-codes_0
@@ -0,0 +1,38 @@
+#!/bin/sh
+
+# make sure error return codes are as expected useful cases
+# (e.g. commands to check ruleset state)
+
+global_rc=0
+
+cmd() { # (rc, cmd, [args ...])
+	rc_exp=$1; shift
+
+	$XT_MULTI "$@"
+	rc=$?
+
+	[ $rc -eq $rc_exp ] || {
+		echo "---> expected $rc_exp, got $rc for command '$@'"
+		global_rc=1
+	}
+}
+
+# test chain creation
+cmd 0 ip6tables -N foo
+cmd 1 ip6tables -N foo
+# iptables-nft allows this - bug or feature?
+#cmd 2 ip6tables -N "invalid name"
+
+# test rule adding
+cmd 0 ip6tables -A INPUT -j ACCEPT
+cmd 1 ip6tables -A noexist -j ACCEPT
+
+# test rule checking
+cmd 0 ip6tables -C INPUT -j ACCEPT
+cmd 1 ip6tables -C FORWARD -j ACCEPT
+cmd 1 ip6tables -C nonexist -j ACCEPT
+cmd 2 ip6tables -C INPUT -j foobar
+cmd 2 ip6tables -C INPUT -m foobar -j ACCEPT
+cmd 3 ip6tables -t foobar -C INPUT -j ACCEPT
+
+exit $global_rc
diff --git a/iptables/tests/shell/testcases/iptables/0004-return-codes_0 \
b/iptables/tests/shell/testcases/iptables/0004-return-codes_0 new file mode 100755
index 0000000000000..34dffeee4604a
--- /dev/null
+++ b/iptables/tests/shell/testcases/iptables/0004-return-codes_0
@@ -0,0 +1,38 @@
+#!/bin/sh
+
+# make sure error return codes are as expected useful cases
+# (e.g. commands to check ruleset state)
+
+global_rc=0
+
+cmd() { # (rc, cmd, [args ...])
+	rc_exp=$1; shift
+
+	$XT_MULTI "$@"
+	rc=$?
+
+	[ $rc -eq $rc_exp ] || {
+		echo "---> expected $rc_exp, got $rc for command '$@'"
+		global_rc=1
+	}
+}
+
+# test chain creation
+cmd 0 iptables -N foo
+cmd 1 iptables -N foo
+# iptables-nft allows this - bug or feature?
+#cmd 2 iptables -N "invalid name"
+
+# test rule adding
+cmd 0 iptables -A INPUT -j ACCEPT
+cmd 1 iptables -A noexist -j ACCEPT
+
+# test rule checking
+cmd 0 iptables -C INPUT -j ACCEPT
+cmd 1 iptables -C FORWARD -j ACCEPT
+cmd 1 iptables -C nonexist -j ACCEPT
+cmd 2 iptables -C INPUT -j foobar
+cmd 2 iptables -C INPUT -m foobar -j ACCEPT
+cmd 3 iptables -t foobar -C INPUT -j ACCEPT
+
+exit $global_rc
diff --git a/iptables/xtables.c b/iptables/xtables.c
index 72f6596251da0..313b985bbaa85 100644
--- a/iptables/xtables.c
+++ b/iptables/xtables.c
@@ -976,6 +976,10 @@ void do_parse(struct nft_handle *h, int argc, char *argv[],
 			if (cs->invert)
 				xtables_error(PARAMETER_PROBLEM,
 					   "unexpected ! flag before --table");
+			if (!nft_table_builtin_find(h, optarg))
+				xtables_error(VERSION_PROBLEM,
+					      "table '%s' does not exist",
+					      optarg);
 			p->table = optarg;
 			break;
 
@@ -1156,12 +1160,18 @@ void do_parse(struct nft_handle *h, int argc, char *argv[],
 					   p->chain);
 		}
 
-		/*
-		 * Contrary to what iptables does, we assume that any jumpto
-		 * is a custom chain jumps (if no target is found). Later on,
-		 * nf_table will spot the error if the chain does not exists.
-		 */
+		if (p->chain && !nft_chain_exists(h, p->table, p->chain))
+			xtables_error(OTHER_PROBLEM,
+				      "Chain '%s' does not exist", cs->jumpto);
+
+		if (!cs->target && strlen(cs->jumpto) > 0 &&
+		    !nft_chain_exists(h, p->table, cs->jumpto))
+			xtables_error(PARAMETER_PROBLEM,
+				      "Chain '%s' does not exist", cs->jumpto);
 	}
+	if (p->command == CMD_NEW_CHAIN &&
+	    nft_chain_exists(h, p->table, p->chain))
+		xtables_error(OTHER_PROBLEM, "Chain already exists");
 }
 
 int do_commandx(struct nft_handle *h, int argc, char *argv[], char **table,
-- 
2.18.0


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic