]> git.ipfire.org Git - thirdparty/nftables.git/commitdiff
main: enforce options before commands
authorPablo Neira Ayuso <pablo@netfilter.org>
Fri, 13 Dec 2019 10:32:46 +0000 (11:32 +0100)
committerPablo Neira Ayuso <pablo@netfilter.org>
Wed, 18 Dec 2019 09:06:05 +0000 (10:06 +0100)
This patch turns on POSIXLY_CORRECT on the getopt parser to enforce
options before commands. Users get a hint in such a case:

 # nft list ruleset -a
 Error: syntax error, options must be specified before commands
 nft list ruleset -a
    ^             ~~

This patch recovers 9fc71bc6b602 ("main: Fix for misleading error with
negative chain priority").

Tests have been updated.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
src/main.c
tests/shell/testcases/cache/0001_cache_handling_0
tests/shell/testcases/chains/0016delete_handle_0
tests/shell/testcases/chains/0039negative_priority_0 [new file with mode: 0755]
tests/shell/testcases/flowtable/0010delete_handle_0
tests/shell/testcases/maps/0008interval_map_delete_0
tests/shell/testcases/optionals/comments_0
tests/shell/testcases/optionals/comments_handles_0
tests/shell/testcases/optionals/delete_object_handles_0
tests/shell/testcases/optionals/handles_0
tests/shell/testcases/sets/0028delete_handle_0

index fde8b15c587037859c2df0f21a311b569310181c..74199f93fa668a871edb73a2c7de17cf0459ffa6 100644 (file)
@@ -46,7 +46,7 @@ enum opt_vals {
        OPT_TERSE               = 't',
        OPT_INVALID             = '?',
 };
-#define OPTSTRING      "hvcf:iI:jvnsNaeSupypTt"
+#define OPTSTRING      "+hvcf:iI:jvnsNaeSupypTt"
 
 static const struct option options[] = {
        {
@@ -202,6 +202,47 @@ static const struct {
        },
 };
 
+static void nft_options_error(int argc, char * const argv[], int pos)
+{
+       int i;
+
+       fprintf(stderr, "Error: syntax error, options must be specified before commands\n");
+       for (i = 0; i < argc; i++)
+               fprintf(stderr, "%s ", argv[i]);
+       printf("\n%4c%*s\n", '^', pos - 2, "~~");
+}
+
+static bool nft_options_check(int argc, char * const argv[])
+{
+       bool skip = false, nonoption = false;
+       int pos = 0, i;
+
+       for (i = 1; i < argc; i++) {
+               pos += strlen(argv[i - 1]) + 1;
+               if (argv[i][0] == '{') {
+                       break;
+               } else if (skip) {
+                       skip = false;
+                       continue;
+               } else if (argv[i][0] == '-') {
+                       if (nonoption) {
+                               nft_options_error(argc, argv, pos);
+                               return false;
+                       } else if (argv[i][1] == 'I' ||
+                                  argv[i][1] == 'f' ||
+                                  !strcmp(argv[i], "--includepath") ||
+                                  !strcmp(argv[i], "--file")) {
+                               skip = true;
+                               continue;
+                       }
+               } else if (argv[i][0] != '-') {
+                       nonoption = true;
+               }
+       }
+
+       return true;
+}
+
 int main(int argc, char * const *argv)
 {
        char *buf = NULL, *filename = NULL;
@@ -211,6 +252,9 @@ int main(int argc, char * const *argv)
        unsigned int len;
        int i, val, rc;
 
+       if (!nft_options_check(argc, argv))
+               exit(EXIT_FAILURE);
+
        nft = nft_ctx_new(NFT_CTX_DEFAULT);
 
        while (1) {
index 431aada59234798593d7a544abdddb1ef12df2f3..0a6844045b15a53ad3f024e16b01760dd8e3cea8 100755 (executable)
@@ -20,7 +20,7 @@ TMP=$(mktemp)
 echo "$RULESET" >> "$TMP"
 $NFT "flush ruleset;include \"$TMP\""
 rm -f "$TMP"
-rule_handle=$($NFT list ruleset -a | awk '/saddr/{print $NF}')
+rule_handle=$($NFT -a list ruleset | awk '/saddr/{print $NF}')
 $NFT delete rule inet test test handle $rule_handle
 $NFT delete set inet test test
 $NFT -f - <<< "$RULESET"
index 4633d771c619ef1a36cdcc0e01f5d2bb742a16f1..8fd1ad864672c3599f20d3396a7439b267f01a12 100755 (executable)
@@ -10,8 +10,8 @@ $NFT add chain ip6 test-ip6 x
 $NFT add chain ip6 test-ip6 y
 $NFT add chain ip6 test-ip6 z
 
-chain_y_handle=$($NFT list ruleset -a | awk -v n=1 '/chain y/ && !--n {print $NF; exit}');
-chain_z_handle=$($NFT list ruleset -a | awk -v n=2 '/chain z/ && !--n {print $NF; exit}');
+chain_y_handle=$($NFT -a list ruleset | awk -v n=1 '/chain y/ && !--n {print $NF; exit}');
+chain_z_handle=$($NFT -a list ruleset | awk -v n=2 '/chain z/ && !--n {print $NF; exit}');
 
 $NFT delete chain test-ip handle $chain_y_handle
 $NFT delete chain ip6 test-ip6 handle $chain_z_handle
diff --git a/tests/shell/testcases/chains/0039negative_priority_0 b/tests/shell/testcases/chains/0039negative_priority_0
new file mode 100755 (executable)
index 0000000..ba17b8c
--- /dev/null
@@ -0,0 +1,8 @@
+#!/bin/bash
+
+# Test parsing of negative priority values
+
+set -e
+
+$NFT add table t
+$NFT add chain t c { type filter hook input priority -30\; }
index 303967ddb44a9dac6f46e36ea199e0fce21f6d59..985d4a3ad6ce2beb2fd7998ca2dbfaedc6702c18 100755 (executable)
@@ -7,7 +7,7 @@ set -e
 $NFT add table inet t
 $NFT add flowtable inet t f { hook ingress priority filter\; devices = { lo }\; }
 
-FH=$($NFT list ruleset -a | awk '/flowtable f/ { print $NF }')
+FH=$($NFT -a list ruleset | awk '/flowtable f/ { print $NF }')
 
 $NFT delete flowtable inet t handle $FH
 
index a43fd28019f7b4faac556196ff86ca2fae2f83ce..7da6eb38ddf73f59d66f3a40b4b3a15fe6bde735 100755 (executable)
@@ -24,7 +24,7 @@ $NFT delete element filter m { 127.0.0.3 }
 $NFT add element filter m { 127.0.0.3 : 0x3 }
 $NFT add element filter m { 127.0.0.2 : 0x2 }
 
-GET=$($NFT list ruleset -s)
+GET=$($NFT -s list ruleset)
 if [ "$EXPECTED" != "$GET" ] ; then
        DIFF="$(which diff)"
        [ -x $DIFF ] && $DIFF -u <(echo "$EXPECTED") <(echo "$GET")
index 29b85062463548b236629dd2e954badf593c9769..ab859365a57023c452ad017fe872e55ccf772009 100755 (executable)
@@ -5,4 +5,4 @@
 $NFT add table test
 $NFT add chain test test
 $NFT add rule test test tcp dport 22 counter accept comment test_comment
-$NFT list table test -a | grep 'accept comment \"test_comment\"' >/dev/null
+$NFT -a list table test | grep 'accept comment \"test_comment\"' >/dev/null
index 30539bf0d760d263eeac3fe4027e42462bcbc9c8..a01df1df50f410b91e5c8a8a69de1042a76a21f5 100755 (executable)
@@ -6,5 +6,5 @@ $NFT add table test
 $NFT add chain test test
 $NFT add rule test test tcp dport 22 counter accept comment test_comment
 set -e
-$NFT list table test -a | grep 'accept comment \"test_comment\" # handle '[[:digit:]]$ >/dev/null
+$NFT -a list table test | grep 'accept comment \"test_comment\" # handle '[[:digit:]]$ >/dev/null
 $NFT list table test | grep 'accept comment \"test_comment\"' | grep -v '# handle '[[:digit:]]$ >/dev/null
index d5d96547ee14499f6268961f69bde0489b4e28ac..a2ae4228d6fa41bc17cdf4ca4017d1852e0a69c1 100755 (executable)
@@ -10,8 +10,8 @@ $NFT add quota ip6 test-ip6 http-quota over 25 mbytes
 $NFT add counter ip6 test-ip6 http-traffic
 $NFT add quota ip6 test-ip6 ssh-quota 10 mbytes
 
-counter_handle=$($NFT list ruleset -a | awk '/https-traffic/{print $NF}')
-quota_handle=$($NFT list ruleset -a | awk '/ssh-quota/{print $NF}')
+counter_handle=$($NFT -a list ruleset | awk '/https-traffic/{print $NF}')
+quota_handle=$($NFT -a list ruleset | awk '/ssh-quota/{print $NF}')
 $NFT delete counter test-ip handle $counter_handle
 $NFT delete quota ip6 test-ip6 handle $quota_handle
 
index 7c6a437cf12b5224437ef6d8cdaf615ccb27eb0f..80f3c5b226e6fac160501b93e094f77c9f78d2ee 100755 (executable)
@@ -5,4 +5,4 @@
 $NFT add table test
 $NFT add chain test test
 $NFT add rule test test tcp dport 22 counter accept
-$NFT list table test -a | grep 'accept # handle '[[:digit:]]$ >/dev/null
+$NFT -a list table test | grep 'accept # handle '[[:digit:]]$ >/dev/null
index 4e8b3228f6052af9d2b22c4e4edf758db918f3a8..5ad17c223db27c7323c0cca5a491fd7ea372cbd4 100755 (executable)
@@ -7,7 +7,7 @@ $NFT add set test-ip y { type inet_service \; timeout 3h45s \;}
 $NFT add set test-ip z { type ipv4_addr\; flags constant , interval\;}
 $NFT add set test-ip c {type ipv4_addr \; flags timeout \; elements={192.168.1.1 timeout 10s, 192.168.1.2 timeout 30s} \;}
 
-set_handle=$($NFT list ruleset -a | awk '/set c/{print $NF}')
+set_handle=$($NFT -a list ruleset | awk '/set c/{print $NF}')
 $NFT delete set test-ip handle $set_handle
 
 EXPECTED="table ip test-ip {