diff options
Diffstat (limited to 'tests')
-rwxr-xr-x | tests/conntrack/bulk-load-stress.sh | 163 | ||||
-rw-r--r-- | tests/conntrack/load-stress.sh | 62 | ||||
-rw-r--r-- | tests/conntrack/test-conntrack.c | 84 | ||||
-rw-r--r-- | tests/conntrack/testsuite/00create | 47 | ||||
-rw-r--r-- | tests/conntrack/testsuite/01delete | 21 | ||||
-rw-r--r-- | tests/conntrack/testsuite/02filter | 8 | ||||
-rw-r--r-- | tests/conntrack/testsuite/08stdin | 125 | ||||
-rw-r--r-- | tests/conntrack/testsuite/09dumpopt | 173 | ||||
-rw-r--r-- | tests/conntrack/testsuite/10add | 42 | ||||
-rwxr-xr-x | tests/conntrackd/conntrackd-tests.py | 263 | ||||
-rw-r--r-- | tests/conntrackd/env.yaml | 2 | ||||
-rwxr-xr-x | tests/conntrackd/netns/conntrackd-netns-test.sh | 66 | ||||
-rw-r--r-- | tests/conntrackd/netns/conntrackd-nsr1.conf | 37 | ||||
-rw-r--r-- | tests/conntrackd/netns/conntrackd-nsr2.conf | 37 | ||||
-rw-r--r-- | tests/conntrackd/netns/ruleset-nsr1.nft | 6 | ||||
-rw-r--r-- | tests/conntrackd/scenarios.yaml | 100 | ||||
-rwxr-xr-x | tests/conntrackd/scenarios/basic/network-setup.sh | 59 | ||||
-rw-r--r-- | tests/conntrackd/tests.yaml | 83 |
18 files changed, 1366 insertions, 12 deletions
diff --git a/tests/conntrack/bulk-load-stress.sh b/tests/conntrack/bulk-load-stress.sh new file mode 100755 index 0000000..9250528 --- /dev/null +++ b/tests/conntrack/bulk-load-stress.sh @@ -0,0 +1,163 @@ +#!/bin/bash + +DEFAULT_CT="../../src/conntrack" +DEFAULT_SPORT_COUNT=0xffff +DEFAULT_DPORT_COUNT=0x2 +DEFAULT_TMP_FILE="./ct_data.txt" +DEFAULT_CT_ZONE=123 +DEFAULT_GEN_ONLY=0 +DEFAULT_CLEANUP_INDIVIDUAL=0 + +CT=$DEFAULT_CT +SPORT_COUNT=$DEFAULT_SPORT_COUNT +DPORT_COUNT=$DEFAULT_DPORT_COUNT +TMP_FILE=$DEFAULT_TMP_FILE +CT_ZONE=$DEFAULT_CT_ZONE +GEN_ONLY=$DEFAULT_GEN_ONLY +CLEANUP_INDIVIDUAL=$DEFAULT_CLEANUP_INDIVIDUAL + +print_help() +{ + me=$(basename "$0") + + echo "Script for stress-testing bulk ct entries load (-R option)" + echo "" + echo "Usage: $me [options]" + echo "" + echo "Where options can be:" + echo "" + echo "-dpc <dst_port_count> - number of destination port values." + echo " Default is ${DEFAULT_DPORT_COUNT}." + echo "" + echo "-spc <src_port_count> - number of source port values." + echo " Default is ${DEFAULT_SPORT_COUNT}." + echo "" + echo "-ct <ct_tool_path> - path to the conntrack tool." + echo " Default is ${DEFAULT_CT}." + echo "" + echo "-z <ct_zone> - ct zone to be used." + echo " Default is ${DEFAULT_CT_ZONE}." + echo "" + echo "-f <tmp_file_name> - tmp file to be used to generate the ct data to." + echo " Default is ${DEFAULT_TMP_FILE}." + echo "" + echo "-g - Generate tmp file and exit." + echo "" + echo "-h - Print this help and exit." +} + +function ct_data_gen() +{ + for (( d = 1; d <= $DPORT_COUNT; d++ )) do + for (( s = 1; s <= $SPORT_COUNT; s++ )) do + echo "-I -w $CT_ZONE -s 1.1.1.1 -d 2.2.2.2 -p tcp --sport ${s} --dport ${d} --state LISTEN -u SEEN_REPLY -t 50" + done + done +} + +if [ $UID -ne 0 ] +then + echo "Run this test as root" + exit 1 +fi + +while [ $# -gt 0 ] +do + case "$1" in + -spc) + SPORT_COUNT=${2:-} + if [ -z "$SPORT_COUNT" ] + then + echo "Source port must be specified!" + print_help + exit 1 + fi + shift + ;; + -dpc) + DPORT_COUNT=${2:-} + if [ -z "$DPORT_COUNT" ] + then + echo "Destination port must be specified!" + print_help + exit 1 + fi + shift + ;; + -ct) + CT=${2:-} + if [ -z "$CT" ] + then + echo "conntrack path must be specified!" + print_help + exit 1 + fi + shift + ;; + -z) + CT_ZONE=${2:-} + if [ -z "$CT_ZONE" ] + then + echo "ct zone must be specified!" + print_help + exit 1 + fi + shift + ;; + -f) + TMP_FILE=${2:-} + if [ -z "$TMP_FILE" ] + then + echo "Tmp file must be specified!" + print_help + exit 1 + fi + shift + ;; + -g) + GEN_ONLY=1 + ;; + -ci) + CLEANUP_INDIVIDUAL=1 + ;; + -h) + print_help + exit 1 + ;; + *) + echo "Unknown paramerer \"$1\"" + print_help + exit 1 + ;; + esac + shift +done + +ct_data_gen > $TMP_FILE + +NUM_ENTRIES=$(cat ${TMP_FILE} | wc -l) + +echo "File ${TMP_FILE} is generated, number of entries: ${NUM_ENTRIES}." + +if [ "$GEN_ONLY" -eq "1" ]; then + exit 0 +fi + +echo "Loading ${NUM_ENTRIES} entries from ${TMP_FILE} .." +time -p ${CT} -R $TMP_FILE + +if [ "$CLEANUP_INDIVIDUAL" -eq "1" ]; then + sed -i -e "s/-I/-D/g" -e "s/-t 50//g" $TMP_FILE + + NUM_ENTRIES=$(cat ${TMP_FILE} | wc -l) + + echo "File ${TMP_FILE} is updated, number of entries: ${NUM_ENTRIES}." + + echo "Cleaning ${NUM_ENTRIES} entries from ${TMP_FILE} .." + time -p ${CT} -R $TMP_FILE +fi + + +echo "Cleaning up zone ${CT_ZONE}.." +time -p ${CT} -D -w $CT_ZONE > /dev/null +rm $TMP_FILE diff --git a/tests/conntrack/load-stress.sh b/tests/conntrack/load-stress.sh new file mode 100644 index 0000000..597c4c6 --- /dev/null +++ b/tests/conntrack/load-stress.sh @@ -0,0 +1,62 @@ +#!/bin/bash + +SPORT_COUNT=128 +DPORT_COUNT=128 + +function ct_data_gen() +{ + for (( d = 1; d <= $DPORT_COUNT; d++ )) do + for (( s = 1; s <= $SPORT_COUNT; s++ )) do + ip netns exec ct-ns-test conntrack -I -s 1.1.1.1 -d 2.2.2.2 -p tcp --sport ${s} --dport ${d} --state LISTEN -u SEEN_REPLY -t 300 &> /dev/null + if [ $? -ne 0 ] + then + echo "[FAILED] cannot insert conntrack entries" + exit 1 + fi + done + done +} + +ip netns add ct-ns-test + +if [ $UID -ne 0 ] +then + echo "Run this test as root" + exit 1 +fi + +echo "Creating conntrack entries, please wait..." +ct_data_gen +ip netns exec ct-ns-test conntrack -U -p tcp -m 1 +if [ $? -ne 0 ] +then + echo "[FAILED] cannot update conntrack entries" + exit 1 +fi + +COUNT=`ip netns exec ct-ns-test conntrack -L | wc -l` +if [ $COUNT -ne 16384 ] +then + echo "$COUNT entries, expecting 131072" + exit 1 +fi + +ip netns exec ct-ns-test conntrack -F +if [ $? -ne 0 ] +then + echo "[FAILED] faild to flush conntrack entries" + exit 1 +fi + +COUNT=`ip netns exec ct-ns-test conntrack -L | wc -l` +if [ $COUNT -ne 0 ] +then + echo "$COUNT entries, expecting 0" + exit 1 +fi + +ip netns del ct-ns-test + +echo "[OK] test successful" + +exit 0 diff --git a/tests/conntrack/test-conntrack.c b/tests/conntrack/test-conntrack.c index 76ab051..372e025 100644 --- a/tests/conntrack/test-conntrack.c +++ b/tests/conntrack/test-conntrack.c @@ -28,6 +28,23 @@ int main() struct dirent *dent; char file[1024]; int i,n; + char cmd_buf[1024 * 8]; + int i_cmd_buf = 0; + char cmd, cur_cmd = 0; + char *cmd_opt; + +#define cmd_strappend(_s) do { \ + char * pos = stpncpy(cmd_buf + i_cmd_buf, _s, sizeof(cmd_buf) - i_cmd_buf); \ + i_cmd_buf = pos - cmd_buf; \ + if (i_cmd_buf == sizeof(cmd_buf)) { \ + printf("buffer full!\n"); \ + exit(EXIT_FAILURE); \ + } \ +} while (0) + +#define cmd_reset() do { \ + i_cmd_buf = 0; \ +} while (0) n = scandir("testsuite", &dents, NULL, alphasort); @@ -48,9 +65,7 @@ int main() } while (fgets(buf, sizeof(buf), fp)) { - char tmp[1024] = CT_PROG, *res; - tmp[strlen(CT_PROG)] = ' '; - + char *res; line++; if (buf[0] == '#' || buf[0] == ' ') @@ -63,27 +78,72 @@ int main() exit(EXIT_FAILURE); } *res = '\0'; - res+=2; + res++; + for (; *res == ' ' || *res == '\t'; res++); + cmd = res[0]; + cmd_opt = &res[1]; + for (; *cmd_opt == ' ' || *cmd_opt == '\t'; cmd_opt++); + res = strchr(cmd_opt, '\n'); + if (res) + *res = '\0'; + + if (cur_cmd && cmd != cur_cmd) { + /* complete current multi-line command */ + switch (cur_cmd) { + case '\n': + cmd_strappend("\" | "); + break; + default: + printf("Internal Error: unexpected multiline command %c", + cur_cmd); + exit(EXIT_FAILURE); + break; + } + + cur_cmd = 0; + } + + switch (cmd) { + case '\n': + if (!cur_cmd) { + cmd_strappend("echo \""); + cur_cmd = cmd; + } else + cmd_strappend("\n"); + cmd_strappend(buf); + continue; + default: + cmd_strappend(CT_PROG); + cmd_strappend(" "); + cmd_strappend(buf); + if (cmd == '|') { + cmd_strappend(" | "); + if (cmd_opt[0]) { + cmd_strappend("sed \""); + cmd_strappend(cmd_opt); + cmd_strappend("\" | "); + } + continue; + } + cmd_reset(); + break; + } - strcpy(tmp + strlen(CT_PROG) + 1, buf); - printf("(%d) Executing: %s\n", line, tmp); + printf("(%d) Executing: %s\n", line, cmd_buf); fflush(stdout); - ret = system(tmp); + ret = system(cmd_buf); if (WIFEXITED(ret) && WEXITSTATUS(ret) == EXIT_SUCCESS) { - if (res[0] == 'O' && - res[1] == 'K') + if (cmd == 'O') ok++; else { bad++; printf("^----- BAD\n"); } } else { - if (res[0] == 'B' && - res[1] == 'A' && - res[2] == 'D') + if (cmd == 'B') ok++; else { bad++; diff --git a/tests/conntrack/testsuite/00create b/tests/conntrack/testsuite/00create index afe4342..af22f18 100644 --- a/tests/conntrack/testsuite/00create +++ b/tests/conntrack/testsuite/00create @@ -6,6 +6,8 @@ -I -s 1.1.1.1 -d 2.2.2.2 --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY -t 50 ; BAD #missing source port -I -s 1.1.1.1 -d 2.2.2.2 -p tcp --dport 20 --state LISTEN -u SEEN_REPLY -t 50 ; BAD +#missing destination port +-I -s 1.1.1.1 -d 2.2.2.2 -p tcp --sport 20 --state LISTEN -u SEEN_REPLY -t 50 ; BAD #missing timeout -I -s 1.1.1.1 -d 2.2.2.2 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY ; BAD # create a conntrack @@ -14,13 +16,58 @@ -I -s 1.1.1.1 -d 2.2.2.2 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY -t 50 ; BAD # delete -D -s 1.1.1.1 -d 2.2.2.2 -p tcp --sport 10 --dport 20 ; OK +# delete again +-D -s 1.1.1.1 -d 2.2.2.2 -p tcp --sport 10 --dport 20 ; BAD # create from reply -I -r 2.2.2.2 -q 1.1.1.1 -p tcp --reply-port-src 11 --reply-port-dst 21 --state LISTEN -u SEEN_REPLY -t 50 ; OK # delete reverse -D -r 2.2.2.2 -q 1.1.1.1 -p tcp --reply-port-src 11 --reply-port-dst 21 ; OK +# delete reverse again +-D -r 2.2.2.2 -q 1.1.1.1 -p tcp --reply-port-src 11 --reply-port-dst 21 ; BAD # create a v6 conntrack -I -s 2001:DB8::1.1.1.1 -d 2001:DB8::2.2.2.2 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY -t 50 ; OK # delete v6 conntrack -D -s 2001:DB8::1.1.1.1 -d 2001:DB8::2.2.2.2 -p tcp --sport 10 --dport 20 ; OK # mismatched address family -I -s 2001:DB8::1.1.1.1 -d 2.2.2.2 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY -t 50 ; BAD +# creae icmp ping request entry +-I -t 29 -u SEEN_REPLY -s 1.1.1.1 -d 2.2.2.2 -r 2.2.2.2 -q 1.1.1.1 -p icmp --icmp-type 8 --icmp-code 0 --icmp-id 1226 ; OK +# delete icmp ping request entry +-D -u SEEN_REPLY -s 1.1.1.1 -d 2.2.2.2 -r 2.2.2.2 -q 1.1.1.1 -p icmp --icmp-type 8 --icmp-code 0 --icmp-id 1226 ; OK +# Test protocols unknown by the conntrack tool +# IGMP +-I -t 10 -s 0.0.0.0 -d 224.0.0.22 -r 224.0.0.22 -q 0.0.0.0 -p 2 ; OK +# Create again - should fail +-I -t 10 -s 0.0.0.0 -d 224.0.0.22 -r 224.0.0.22 -q 0.0.0.0 -p 2 ; BAD +# repeat using protocol name instead of the value, should fail as well +-I -t 10 -s 0.0.0.0 -d 224.0.0.22 -r 224.0.0.22 -q 0.0.0.0 -p igmp ; BAD +# delete +-D -s 0.0.0.0 -d 224.0.0.22 -r 224.0.0.22 -q 0.0.0.0 -p 2 ; OK +# delete again should fail +-D -s 0.0.0.0 -d 224.0.0.22 -r 224.0.0.22 -q 0.0.0.0 -p 2 ; BAD +# create using protocol name instead of the value +-I -t 10 -s 0.0.0.0 -d 224.0.0.22 -r 224.0.0.22 -q 0.0.0.0 -p igmp ; OK +# update +-U -t 11 -s 0.0.0.0 -d 224.0.0.22 -r 224.0.0.22 -q 0.0.0.0 -p 2 ; OK +# delete +-D -s 0.0.0.0 -d 224.0.0.22 -r 224.0.0.22 -q 0.0.0.0 -p 2 ; OK +# delete again should fail +-D -s 0.0.0.0 -d 224.0.0.22 -r 224.0.0.22 -q 0.0.0.0 -p igmp ; BAD +# take some protocol that is not normally not in /etc/protocols +-I -t 10 -s 0.0.0.0 -d 224.0.0.22 -r 224.0.0.22 -q 0.0.0.0 -p 200 ; OK +# update +-U -t 11 -s 0.0.0.0 -d 224.0.0.22 -r 224.0.0.22 -q 0.0.0.0 -p 200 ; OK +# delete +-D -s 0.0.0.0 -d 224.0.0.22 -r 224.0.0.22 -q 0.0.0.0 -p 200 ; OK +# delete again +-D -s 0.0.0.0 -d 224.0.0.22 -r 224.0.0.22 -q 0.0.0.0 -p 200 ; BAD +# Invalid protocol values +# 256 should fail +-I -t 10 -s 1.1.1.1 -d 2.2.2.2 -r 2.2.2.2 -q 1.1.1.1 -p 256 ; BAD +# take some invalid protocol name +-I -t 10 -s 0.0.0.0 -d 224.0.0.22 -r 224.0.0.22 -q 0.0.0.0 -p foo ; BAD +# take some other invalid protocol values +-I -t 10 -s 0.0.0.0 -d 224.0.0.22 -r 224.0.0.22 -q 0.0.0.0 -p -10 ; BAD +-I -t 10 -s 0.0.0.0 -d 224.0.0.22 -r 224.0.0.22 -q 0.0.0.0 -p 2000 ; BAD +-I -t 10 -s 0.0.0.0 -d 224.0.0.22 -r 224.0.0.22 -q 0.0.0.0 -p 20foo ; BAD +-I -t 10 -s 0.0.0.0 -d 224.0.0.22 -r 224.0.0.22 -q 0.0.0.0 -p foo20 ; BAD diff --git a/tests/conntrack/testsuite/01delete b/tests/conntrack/testsuite/01delete index 194d999..64dbb10 100644 --- a/tests/conntrack/testsuite/01delete +++ b/tests/conntrack/testsuite/01delete @@ -2,8 +2,22 @@ -I -s 1.1.1.1 -d 2.2.2.2 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY -t 50 ; OK # delete bad source -D -s 2.2.2.2 -p tcp --sport 10 --dport 20 ; BAD +# delete bad destination +-D -d 1.1.1.1 -p tcp --sport 10 --dport 20 ; BAD +# delete bad source port +-I -s 1.1.1.1 -d 2.2.2.2 -p tcp --sport 20 --dport 20 ; BAD +# delete bad destination port +-I -s 1.1.1.1 -d 2.2.2.2 -p tcp --sport 10 --dport 10 ; BAD # delete by source -D -s 1.1.1.1 ; OK +# re-create dummy with mark +-I -s 1.1.1.1 -d 2.2.2.2 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY -t 50 -m 20 ; OK +# delete bad mark +-D -m 10 ; BAD +# delete by mark +-D -m 20 ; OK +# delete by mark (does not exist anymore) +-D -m 20 ; BAD # re-create dummy -I -s 1.1.1.1 -d 2.2.2.2 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY -t 50 ; OK # delete by netmask @@ -14,3 +28,10 @@ -I -s 1.1.1.1 -d 2.2.2.2 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY -t 50 ; OK # try same command again but with CIDR -D -s 1.1.1.0/24 -d 2.2.2.0/24 ; OK +# try same command again but with CIDR (no matching found) +-D -s 1.1.1.0/24 -d 2.2.2.0/24 ; BAD +# try to delete mismatching address family +-D -s ::1 -d 2.2.2.2 ; BAD +# try to delete IPv6 address without specifying IPv6 family +-I -s ::1 -d ::2 -p tcp --sport 20 --dport 10 --state LISTEN -u SEEN_REPLY -t 40 ; OK +-D -s ::1 ; OK diff --git a/tests/conntrack/testsuite/02filter b/tests/conntrack/testsuite/02filter index 91a75eb..d58637f 100644 --- a/tests/conntrack/testsuite/02filter +++ b/tests/conntrack/testsuite/02filter @@ -23,5 +23,13 @@ conntrack -L --mark 0/0xffffffff; OK conntrack -L -s 1.1.1.0 --mask-src 255.255.255.0 -d 2.0.0.0 --mask-dst 255.0.0.0 ; OK conntrack -L -s 1.1.1.4/24 -d 2.3.4.5/8 ; OK conntrack -L -s 1.1.2.0/24 -d 2.3.4.5/8 ; OK +# filter filter mismatching address family +conntrack -L -s 2.2.2.2 -d ::1 ; BAD +# filter by IPv6 address, it implicitly sets IPv6 family +conntrack -L -s ::1 ; OK +# filter by IPv6 address mask, it implicitly sets IPv6 family +conntrack -L -s abcd:abcd:abcd:: --mask-src ffff:ffff:ffff:: ; OK +# filter filter mismatching address family +conntrack -L --mask-src ffff:ffff:ffff:: --mask-dst 255.0.0.0 ; BAD # delete dummy conntrack -D -d 2.2.2.2 ; OK diff --git a/tests/conntrack/testsuite/08stdin b/tests/conntrack/testsuite/08stdin new file mode 100644 index 0000000..158c4c3 --- /dev/null +++ b/tests/conntrack/testsuite/08stdin @@ -0,0 +1,125 @@ +# create +# create a conntrack +-I -s 1.1.1.1 -d 2.2.2.2 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY -t 50 ; +# create from reply +-I -r 2.2.2.2 -q 1.1.1.1 -p tcp --reply-port-src 11 --reply-port-dst 21 --state LISTEN -u SEEN_REPLY -t 50 ; +# create a v6 conntrack +-I -s 2001:DB8::1.1.1.1 -d 2001:DB8::2.2.2.2 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY -t 50 ; +# creae icmp ping request entry +-I -t 29 -u SEEN_REPLY -s 1.1.1.1 -d 2.2.2.2 -r 2.2.2.2 -q 1.1.1.1 -p icmp --icmp-type 8 --icmp-code 0 --icmp-id 1226 ; +-R - ; OK +# create again +-I -s 1.1.1.1 -d 2.2.2.2 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY -t 50 ; BAD +-I -r 2.2.2.2 -q 1.1.1.1 -p tcp --reply-port-src 11 --reply-port-dst 21 --state LISTEN -u SEEN_REPLY -t 50 ; BAD +-I -s 2001:DB8::1.1.1.1 -d 2001:DB8::2.2.2.2 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY -t 50 ; BAD +-I -t 29 -u SEEN_REPLY -s 1.1.1.1 -d 2.2.2.2 -r 2.2.2.2 -q 1.1.1.1 -p icmp --icmp-type 8 --icmp-code 0 --icmp-id 1226 ; BAD +# make sure create again with stdio mode fails as well +-I -s 1.1.1.1 -d 2.2.2.2 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY -t 50 ; +-R - ; BAD +-I -r 2.2.2.2 -q 1.1.1.1 -p tcp --reply-port-src 11 --reply-port-dst 21 --state LISTEN -u SEEN_REPLY -t 50 ; +-R - ; BAD +# empty lines are ignored +; +-I -s 2001:DB8::1.1.1.1 -d 2001:DB8::2.2.2.2 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY -t 50 ; +-R - ; BAD +# spaces or tabs are ignored as well + ; + ; +-I -t 29 -u SEEN_REPLY -s 1.1.1.1 -d 2.2.2.2 -r 2.2.2.2 -q 1.1.1.1 -p icmp --icmp-type 8 --icmp-code 0 --icmp-id 1226 ; +-R - ; BAD +# delete +-D -s 1.1.1.1 -d 2.2.2.2 -p tcp --sport 10 --dport 20 ; +# empty lines should be just ignored +; +; +# delete reverse +-D -r 2.2.2.2 -q 1.1.1.1 -p tcp --reply-port-src 11 --reply-port-dst 21 ; +# empty lines with spaces or tabs should be ignored as well + ; + ; + ; + ; + ; + ; +# delete v6 conntrack +-D -s 2001:DB8::1.1.1.1 -d 2001:DB8::2.2.2.2 -p tcp --sport 10 --dport 20 ; +# delete icmp ping request entry +-D -u SEEN_REPLY -s 1.1.1.1 -d 2.2.2.2 -r 2.2.2.2 -q 1.1.1.1 -p icmp --icmp-type 8 --icmp-code 0 --icmp-id 1226 ; +; +; +-R - ; OK +# create again - should succeed now +-I -s 1.1.1.1 -d 2.2.2.2 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY -t 50 ; OK +-I -r 2.2.2.2 -q 1.1.1.1 -p tcp --reply-port-src 11 --reply-port-dst 21 --state LISTEN -u SEEN_REPLY -t 50 ; OK +-I -s 2001:DB8::1.1.1.1 -d 2001:DB8::2.2.2.2 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY -t 50 ; OK +-I -t 29 -u SEEN_REPLY -s 1.1.1.1 -d 2.2.2.2 -r 2.2.2.2 -q 1.1.1.1 -p icmp --icmp-type 8 --icmp-code 0 --icmp-id 1226 ; OK +# delete again (for cleanup) +-D -s 1.1.1.1 -d 2.2.2.2 -p tcp --sport 10 --dport 20 ; +-D -r 2.2.2.2 -q 1.1.1.1 -p tcp --reply-port-src 11 --reply-port-dst 21 ; +-D -s 2001:DB8::1.1.1.1 -d 2001:DB8::2.2.2.2 -p tcp --sport 10 --dport 20 ; +-D -u SEEN_REPLY -s 1.1.1.1 -d 2.2.2.2 -r 2.2.2.2 -q 1.1.1.1 -p icmp --icmp-type 8 --icmp-code 0 --icmp-id 1226 ; +; +-R - ; OK +# delete no entries - should return err +-D -w 123 ; BAD +# delete no entries via stdin - should succeed since we do not count entries in stdin mode atm +-D -w 123 ; +-R - ; OK +# delete no entries in parallel with adding entries via stdin - should succeed +# -D and -I should work in parallel +-D -w 123 ; +-I -w 123 -s 1.1.1.1 -d 2.2.2.2 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY -t 50 ; +-R - ; OK +# now deleting entries should return success +-D -w 123 ; +-R - ; OK +# delete no entries via stdin - should succeed since we do not count entries in stdin mode atm +-D -w 123 ; +-R - ; OK +# validate it via standard command line way +-D -w 123 ; BAD +# create with -A +# create a conntrack +-A -s 1.1.1.1 -d 2.2.2.2 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY -t 50 ; +# create from reply +-A -r 2.2.2.2 -q 1.1.1.1 -p tcp --reply-port-src 11 --reply-port-dst 21 --state LISTEN -u SEEN_REPLY -t 50 ; +# create a v6 conntrack +-A -s 2001:DB8::1.1.1.1 -d 2001:DB8::2.2.2.2 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY -t 50 ; +# creae icmp ping request entry +-A -t 29 -u SEEN_REPLY -s 1.1.1.1 -d 2.2.2.2 -r 2.2.2.2 -q 1.1.1.1 -p icmp --icmp-type 8 --icmp-code 0 --icmp-id 1226 ; +-R - ; OK +# create again +-I -s 1.1.1.1 -d 2.2.2.2 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY -t 50 ; BAD +-I -r 2.2.2.2 -q 1.1.1.1 -p tcp --reply-port-src 11 --reply-port-dst 21 --state LISTEN -u SEEN_REPLY -t 50 ; BAD +-I -s 2001:DB8::1.1.1.1 -d 2001:DB8::2.2.2.2 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY -t 50 ; BAD +-I -t 29 -u SEEN_REPLY -s 1.1.1.1 -d 2.2.2.2 -r 2.2.2.2 -q 1.1.1.1 -p icmp --icmp-type 8 --icmp-code 0 --icmp-id 1226 ; BAD +# repeat, it should succeed +-A -s 1.1.1.1 -d 2.2.2.2 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY -t 50 ; +# create from reply +-A -r 2.2.2.2 -q 1.1.1.1 -p tcp --reply-port-src 11 --reply-port-dst 21 --state LISTEN -u SEEN_REPLY -t 50 ; +# create a v6 conntrack +-A -s 2001:DB8::1.1.1.1 -d 2001:DB8::2.2.2.2 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY -t 50 ; +# creae icmp ping request entry +-A -t 29 -u SEEN_REPLY -s 1.1.1.1 -d 2.2.2.2 -r 2.2.2.2 -q 1.1.1.1 -p icmp --icmp-type 8 --icmp-code 0 --icmp-id 1226 ; +-R - ; OK +# delete +-D -s 1.1.1.1 -d 2.2.2.2 -p tcp --sport 10 --dport 20 ; +# empty lines should be just ignored +; +; +# delete reverse +-D -r 2.2.2.2 -q 1.1.1.1 -p tcp --reply-port-src 11 --reply-port-dst 21 ; +# empty lines with spaces or tabs should be ignored as well + ; + ; + ; + ; + ; + ; +# delete v6 conntrack +-D -s 2001:DB8::1.1.1.1 -d 2001:DB8::2.2.2.2 -p tcp --sport 10 --dport 20 ; +# delete icmp ping request entry +-D -u SEEN_REPLY -s 1.1.1.1 -d 2.2.2.2 -r 2.2.2.2 -q 1.1.1.1 -p icmp --icmp-type 8 --icmp-code 0 --icmp-id 1226 ; +; +; +-R - ; OK diff --git a/tests/conntrack/testsuite/09dumpopt b/tests/conntrack/testsuite/09dumpopt new file mode 100644 index 0000000..c1e0e6e --- /dev/null +++ b/tests/conntrack/testsuite/09dumpopt @@ -0,0 +1,173 @@ +# test opts output for -L +# create +# create a conntrack +-I -w 10 -s 1.1.1.1 -d 2.2.2.2 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY -t 50 ; +# create from reply +-I -w 10 -r 2.2.2.2 -q 1.1.1.1 -p tcp --reply-port-src 11 --reply-port-dst 21 --state LISTEN -u SEEN_REPLY -t 50 ; +# create a v6 conntrack +-I -w 10 -s 2001:DB8::1.1.1.1 -d 2001:DB8::2.2.2.2 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY -t 50 ; +# creae icmp ping request entry +-I -w 10 -t 29 -u SEEN_REPLY -s 1.1.1.1 -d 2.2.2.2 -r 2.2.2.2 -q 1.1.1.1 -p icmp --icmp-type 8 --icmp-code 0 --icmp-id 1226 ; +-R - ; OK +# copy ipv4 bits to zone 11 +-L -w 10 -o save -f ipv4 ; |s/-w 10/-w 11/g +-R - ; OK +# copy ipv6 bits to zone 11 +-L -w 10 -o save -f ipv6 ; |s/-w 10/-w 11/g +-R - ; OK +# create again in zone 11 +-I -w 11 -s 1.1.1.1 -d 2.2.2.2 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY -t 50 ; BAD +-I -w 11 -r 2.2.2.2 -q 1.1.1.1 -p tcp --reply-port-src 11 --reply-port-dst 21 --state LISTEN -u SEEN_REPLY -t 50 ; BAD +-I -w 11 -s 2001:DB8::1.1.1.1 -d 2001:DB8::2.2.2.2 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY -t 50 ; BAD +-I -w 11 -t 29 -u SEEN_REPLY -s 1.1.1.1 -d 2.2.2.2 -r 2.2.2.2 -q 1.1.1.1 -p icmp --icmp-type 8 --icmp-code 0 --icmp-id 1226 ; BAD +# delete new entries +-D -w 11 -s 1.1.1.1 -d 2.2.2.2 -p tcp --sport 10 --dport 20 ; OK +# delete reverse +-D -w 11 -r 2.2.2.2 -q 1.1.1.1 -p tcp --reply-port-src 11 --reply-port-dst 21 ; OK +# delete v6 conntrack +-D -w 11-s 2001:DB8::1.1.1.1 -d 2001:DB8::2.2.2.2 -p tcp --sport 10 --dport 20 ; OK +# delete icmp ping request entry +-D -w 11 -u SEEN_REPLY -s 1.1.1.1 -d 2.2.2.2 -r 2.2.2.2 -q 1.1.1.1 -p icmp --icmp-type 8 --icmp-code 0 --icmp-id 1226 ; OK +# delete old entries +-D -w 10 -s 1.1.1.1 -d 2.2.2.2 -p tcp --sport 10 --dport 20 ; OK +# delete reverse +-D -w 10 -r 2.2.2.2 -q 1.1.1.1 -p tcp --reply-port-src 11 --reply-port-dst 21 ; OK +# delete v6 conntrack +-D -w 10-s 2001:DB8::1.1.1.1 -d 2001:DB8::2.2.2.2 -p tcp --sport 10 --dport 20 ; OK +# delete icmp ping request entry +-D -w 10 -u SEEN_REPLY -s 1.1.1.1 -d 2.2.2.2 -r 2.2.2.2 -q 1.1.1.1 -p icmp --icmp-type 8 --icmp-code 0 --icmp-id 1226 ; OK +# +# now test opts output for -D +# create entries again +# create a conntrack +-I -w 10 -s 1.1.1.1 -d 2.2.2.2 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY -t 50 ; +# create from reply +-I -w 10 -r 2.2.2.2 -q 1.1.1.1 -p tcp --reply-port-src 11 --reply-port-dst 21 --state LISTEN -u SEEN_REPLY -t 50 ; +# create a v6 conntrack +-I -w 10 -s 2001:DB8::1.1.1.1 -d 2001:DB8::2.2.2.2 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY -t 50 ; +# creae icmp ping request entry +-I -w 10 -t 29 -u SEEN_REPLY -s 1.1.1.1 -d 2.2.2.2 -r 2.2.2.2 -q 1.1.1.1 -p icmp --icmp-type 8 --icmp-code 0 --icmp-id 1226 ; +-R - ; OK +# move ipv4 bits to zone 11 +-D -w 10 -o save -f ipv4 ; |s/-w 10/-w 11/g; s/-D /-I /g +-R - ; OK +# move ipv6 bits to zone 11 +-D -w 10 -o save -f ipv6 ; |s/-w 10/-w 11/g; s/-D /-I /g +-R - ; OK +# create again in zone 11 +-I -w 11 -s 1.1.1.1 -d 2.2.2.2 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY -t 50 ; BAD +-I -w 11 -r 2.2.2.2 -q 1.1.1.1 -p tcp --reply-port-src 11 --reply-port-dst 21 --state LISTEN -u SEEN_REPLY -t 50 ; BAD +-I -w 11 -s 2001:DB8::1.1.1.1 -d 2001:DB8::2.2.2.2 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY -t 50 ; BAD +-I -w 11 -t 29 -u SEEN_REPLY -s 1.1.1.1 -d 2.2.2.2 -r 2.2.2.2 -q 1.1.1.1 -p icmp --icmp-type 8 --icmp-code 0 --icmp-id 1226 ; BAD +# delete new entries +-D -w 11 -s 1.1.1.1 -d 2.2.2.2 -p tcp --sport 10 --dport 20 ; OK +# delete reverse +-D -w 11 -r 2.2.2.2 -q 1.1.1.1 -p tcp --reply-port-src 11 --reply-port-dst 21 ; OK +# delete v6 conntrack +-D -w 11-s 2001:DB8::1.1.1.1 -d 2001:DB8::2.2.2.2 -p tcp --sport 10 --dport 20 ; OK +# delete icmp ping request entry +-D -w 11 -u SEEN_REPLY -s 1.1.1.1 -d 2.2.2.2 -r 2.2.2.2 -q 1.1.1.1 -p icmp --icmp-type 8 --icmp-code 0 --icmp-id 1226 ; OK +# delete old entries +-D -w 10 -s 1.1.1.1 -d 2.2.2.2 -p tcp --sport 10 --dport 20 ; BAD +# delete reverse +-D -w 10 -r 2.2.2.2 -q 1.1.1.1 -p tcp --reply-port-src 11 --reply-port-dst 21 ; BAD +# delete v6 conntrack +-D -w 10-s 2001:DB8::1.1.1.1 -d 2001:DB8::2.2.2.2 -p tcp --sport 10 --dport 20 ; BAD +# delete icmp ping request entry +-D -w 10 -u SEEN_REPLY -s 1.1.1.1 -d 2.2.2.2 -r 2.2.2.2 -q 1.1.1.1 -p icmp --icmp-type 8 --icmp-code 0 --icmp-id 1226 ; BAD +# +# Additional tests to check that family attribute is treated properly +# for -L and -D commands +# namely: +# - if family (-f) is given - only entries of the given family are dumped/deleted +# - if no family is given - entries of both ipv4 and ipv6 families are dumped/deleted +# First create some ipv4 and ipv6 entries +-I -w 10 -s 1.1.1.1 -d 2.2.2.2 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY -t 50 ; OK +-I -w 10 -r 2.2.2.2 -q 1.1.1.1 -p tcp --reply-port-src 11 --reply-port-dst 21 --state LISTEN -u SEEN_REPLY -t 50 ; OK +-I -w 10 -s 2001:DB8::1.1.1.1 -d 2001:DB8::2.2.2.2 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY -t 50 ; OK +-I -w 10 -t 29 -u SEEN_REPLY -s 1.1.1.1 -d 2.2.2.2 -r 2.2.2.2 -q 1.1.1.1 -p icmp --icmp-type 8 --icmp-code 0 --icmp-id 1226 ; OK +# dump all entries to zone 11 +-L -w 10 -o save; |s/-w 10/-w 11/g +-R - ; OK +# ensure that both ipv4 and ipv6 entries get copied (delete for each of them should succeed) +-D -w 11 -s 1.1.1.1 -d 2.2.2.2 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY ; OK +-D -w 11 -r 2.2.2.2 -q 1.1.1.1 -p tcp --reply-port-src 11 --reply-port-dst 21 --state LISTEN -u SEEN_REPLY ; OK +-D -w 11 -s 2001:DB8::1.1.1.1 -d 2001:DB8::2.2.2.2 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY; OK +-D -w 11 -u SEEN_REPLY -s 1.1.1.1 -d 2.2.2.2 -r 2.2.2.2 -q 1.1.1.1 -p icmp --icmp-type 8 --icmp-code 0 --icmp-id 1226 ; OK +# dump only ipv4 entries to zone 11 +-L -w 10 -o save -f ipv4; |s/-w 10/-w 11/g +-R - ; OK +# ensure that only ipv4 entries get copied (delete only for ipv4 entries should succeed) +-D -w 11 -s 1.1.1.1 -d 2.2.2.2 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY; OK +-D -w 11 -r 2.2.2.2 -q 1.1.1.1 -p tcp --reply-port-src 11 --reply-port-dst 21 --state LISTEN -u SEEN_REPLY; OK +-D -w 11 -s 2001:DB8::1.1.1.1 -d 2001:DB8::2.2.2.2 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY; BAD +-D -w 11 -u SEEN_REPLY -s 1.1.1.1 -d 2.2.2.2 -r 2.2.2.2 -q 1.1.1.1 -p icmp --icmp-type 8 --icmp-code 0 --icmp-id 1226 ; OK +# dump only ipv6 entries to zone 11 +-L -w 10 -o save -f ipv6; |s/-w 10/-w 11/g +-R - ; OK +# ensure that only ipv6 entries get copied (delete only for ipv6 entries should succeed) +-D -w 11 -s 1.1.1.1 -d 2.2.2.2 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY; BAD +-D -w 11 -r 2.2.2.2 -q 1.1.1.1 -p tcp --reply-port-src 11 --reply-port-dst 21 --state LISTEN -u SEEN_REPLY; BAD +-D -w 11 -s 2001:DB8::1.1.1.1 -d 2001:DB8::2.2.2.2 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY; OK +-D -w 11 -u SEEN_REPLY -s 1.1.1.1 -d 2.2.2.2 -r 2.2.2.2 -q 1.1.1.1 -p icmp --icmp-type 8 --icmp-code 0 --icmp-id 1226 ; BAD +# now test deleting w/ and /o family specified +# for simplicity do it by re-creating entries in zone 11 +# by copying ezisting entries from zone 10 into it +# re-create entries in ct zone 11 +-L -w 10 -o save; |s/-w 10/-w 11/g +-R - ; OK +# delete all entries in zone 11 +-D -w 11 ; OK +# both ipv4 and ipv6 should be deleted +-D -w 11 -s 1.1.1.1 -d 2.2.2.2 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY; BAD +-D -w 11 -r 2.2.2.2 -q 1.1.1.1 -p tcp --reply-port-src 11 --reply-port-dst 21 --state LISTEN -u SEEN_REPLY; BAD +-D -w 11 -s 2001:DB8::1.1.1.1 -d 2001:DB8::2.2.2.2 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY; BAD +-D -w 11 -u SEEN_REPLY -s 1.1.1.1 -d 2.2.2.2 -r 2.2.2.2 -q 1.1.1.1 -p icmp --icmp-type 8 --icmp-code 0 --icmp-id 1226 ; BAD +# re-create entries in ct zone 11 +-L -w 10 -o save; |s/-w 10/-w 11/g +-R - ; OK +# delete only ipv4 entries in zone 11 +-D -w 11 -f ipv4 ; OK +# ipv6 should remain +-D -w 11 -s 1.1.1.1 -d 2.2.2.2 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY; BAD +-D -w 11 -r 2.2.2.2 -q 1.1.1.1 -p tcp --reply-port-src 11 --reply-port-dst 21 --state LISTEN -u SEEN_REPLY; BAD +-D -w 11 -s 2001:DB8::1.1.1.1 -d 2001:DB8::2.2.2.2 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY; OK +-D -w 11 -u SEEN_REPLY -s 1.1.1.1 -d 2.2.2.2 -r 2.2.2.2 -q 1.1.1.1 -p icmp --icmp-type 8 --icmp-code 0 --icmp-id 1226 ; BAD + # re-create entries in ct zone 11 +-L -w 10 -o save; |s/-w 10/-w 11/g +-R - ; OK +# delete only ipv6 entries in zone 11 +-D -w 11 -f ipv6 ; OK +# ipv4 should remain +-D -w 11 -s 1.1.1.1 -d 2.2.2.2 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY; OK +-D -w 11 -r 2.2.2.2 -q 1.1.1.1 -p tcp --reply-port-src 11 --reply-port-dst 21 --state LISTEN -u SEEN_REPLY; OK +-D -w 11 -s 2001:DB8::1.1.1.1 -d 2001:DB8::2.2.2.2 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY; BAD +-D -w 11 -u SEEN_REPLY -s 1.1.1.1 -d 2.2.2.2 -r 2.2.2.2 -q 1.1.1.1 -p icmp --icmp-type 8 --icmp-code 0 --icmp-id 1226 ; OK +# clean up after yourself +-D -w 10 ; OK +# Cover protocols unknown to the conntrack tool +# Create a conntrack entries +# IGMP +-I -w 10 -t 59 -s 0.0.0.0 -d 224.0.0.22 -r 224.0.0.22 -q 0.0.0.0 -p 2 ; +# Some fency protocol +-I -w 10 -t 59 -s 0.0.0.0 -d 224.0.0.22 -r 224.0.0.22 -q 0.0.0.0 -p 200 ; +# Some fency protocol with IPv6 +-I -w 10 -t 59 -s 2001:DB8::1.1.1.1 -d 2001:DB8::2.2.2.2 -p 200 ; +-R - ; OK +# copy to zone 11 +-L -w 10 -o save ; |s/-w 10/-w 11/g +-R - ; OK +# Delete stuff in zone 10, should succeed +# IGMP +-D -w 10 -s 0.0.0.0 -d 224.0.0.22 -r 224.0.0.22 -q 0.0.0.0 -p 2 ; OK +# Some fency protocol +-D -w 10 -s 0.0.0.0 -d 224.0.0.22 -r 224.0.0.22 -q 0.0.0.0 -p 200 ; OK +# Some fency protocol with IPv6 +-D -w 10 -s 2001:DB8::1.1.1.1 -d 2001:DB8::2.2.2.2 -p 200 ; OK +# Delete stuff in zone 11, should succeed +# IGMP +-D -w 11 -s 0.0.0.0 -d 224.0.0.22 -r 224.0.0.22 -q 0.0.0.0 -p 2 ; OK +# Some fency protocol +-D -w 11 -s 0.0.0.0 -d 224.0.0.22 -r 224.0.0.22 -q 0.0.0.0 -p 200 ; OK +# Some fency protocol with IPv6 +-D -w 11 -s 2001:DB8::1.1.1.1 -d 2001:DB8::2.2.2.2 -p 200 ; OK diff --git a/tests/conntrack/testsuite/10add b/tests/conntrack/testsuite/10add new file mode 100644 index 0000000..4f9f3b9 --- /dev/null +++ b/tests/conntrack/testsuite/10add @@ -0,0 +1,42 @@ +#missing destination +-A -s 1.1.1.1 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY -t 50 ; BAD +#missing source +-A -d 2.2.2.2 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY -t 50 ; BAD +#missing protocol +-A -s 1.1.1.1 -d 2.2.2.2 --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY -t 50 ; BAD +#missing source port +-A -s 1.1.1.1 -d 2.2.2.2 -p tcp --dport 20 --state LISTEN -u SEEN_REPLY -t 50 ; BAD +#missing destination port +-A -s 1.1.1.1 -d 2.2.2.2 -p tcp --sport 20 --state LISTEN -u SEEN_REPLY -t 50 ; BAD +#missing timeout +-A -s 1.1.1.1 -d 2.2.2.2 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY ; BAD +# create a conntrack +-A -s 1.1.1.1 -d 2.2.2.2 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY -t 50 ; OK +# create again +-A -s 1.1.1.1 -d 2.2.2.2 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY -t 50 ; OK +# delete +-D -s 1.1.1.1 -d 2.2.2.2 -p tcp --sport 10 --dport 20 ; OK +# delete again +-D -s 1.1.1.1 -d 2.2.2.2 -p tcp --sport 10 --dport 20 ; BAD +# create from reply +-A -r 2.2.2.2 -q 1.1.1.1 -p tcp --reply-port-src 11 --reply-port-dst 21 --state LISTEN -u SEEN_REPLY -t 50 ; OK +# create again from reply +-A -r 2.2.2.2 -q 1.1.1.1 -p tcp --reply-port-src 11 --reply-port-dst 21 --state LISTEN -u SEEN_REPLY -t 50 ; OK +# delete reverse +-D -r 2.2.2.2 -q 1.1.1.1 -p tcp --reply-port-src 11 --reply-port-dst 21 ; OK +# delete reverse again +-D -r 2.2.2.2 -q 1.1.1.1 -p tcp --reply-port-src 11 --reply-port-dst 21 ; BAD +# create a v6 conntrack +-A -s 2001:DB8::1.1.1.1 -d 2001:DB8::2.2.2.2 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY -t 50 ; OK +# create again a v6 conntrack +-A -s 2001:DB8::1.1.1.1 -d 2001:DB8::2.2.2.2 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY -t 50 ; OK +# delete v6 conntrack +-D -s 2001:DB8::1.1.1.1 -d 2001:DB8::2.2.2.2 -p tcp --sport 10 --dport 20 ; OK +# mismatched address family +-A -s 2001:DB8::1.1.1.1 -d 2.2.2.2 -p tcp --sport 10 --dport 20 --state LISTEN -u SEEN_REPLY -t 50 ; BAD +# creae icmp ping request entry +-A -t 29 -u SEEN_REPLY -s 1.1.1.1 -d 2.2.2.2 -r 2.2.2.2 -q 1.1.1.1 -p icmp --icmp-type 8 --icmp-code 0 --icmp-id 1226 ; OK +# creae again icmp ping request entry +-A -t 29 -u SEEN_REPLY -s 1.1.1.1 -d 2.2.2.2 -r 2.2.2.2 -q 1.1.1.1 -p icmp --icmp-type 8 --icmp-code 0 --icmp-id 1226 ; OK +# delete icmp ping request entry +-D -u SEEN_REPLY -s 1.1.1.1 -d 2.2.2.2 -r 2.2.2.2 -q 1.1.1.1 -p icmp --icmp-type 8 --icmp-code 0 --icmp-id 1226 ; OK diff --git a/tests/conntrackd/conntrackd-tests.py b/tests/conntrackd/conntrackd-tests.py new file mode 100755 index 0000000..f760351 --- /dev/null +++ b/tests/conntrackd/conntrackd-tests.py @@ -0,0 +1,263 @@ +#!/usr/bin/env python3 + +# (C) 2021 by Arturo Borrero Gonzalez <arturo@netfilter.org> + +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# + +# tests.yaml file format: +# - name: "test 1" +# scenario: scenario1 +# test: +# - test1 cmd1 +# - test1 cmd2 + +# scenarios.yaml file format: +# - name: scenario1 +# start: +# - cmd1 +# - cmd2 +# stop: +# - cmd1 +# - cmd2 + +# env.yaml file format: +# - VAR1: value1 +# - VAR2: value2 + +import os +import sys +import argparse +import subprocess +import yaml +import logging + + +def read_yaml_file(file): + try: + with open(file, "r") as stream: + try: + return yaml.safe_load(stream) + except yaml.YAMLError as e: + logging.error(e) + exit(2) + except FileNotFoundError as e: + logging.error(e) + exit(2) + + +def validate_dictionary(dictionary, keys): + if not isinstance(dictionary, dict): + logging.error("not a dictionary:\n{}".format(dictionary)) + return False + for key in keys: + if dictionary.get(key) is None: + logging.error("missing key {} in dictionary:\n{}".format(key, dictionary)) + return False + return True + + +def stage_validate_config(args): + scenarios_dict = read_yaml_file(args.scenarios_file) + for definition in scenarios_dict: + if not validate_dictionary(definition, ["name", "start", "stop"]): + logging.error("couldn't validate file {}".format(args.scenarios_file)) + return False + + logging.debug("{} seems valid".format(args.scenarios_file)) + ctx.scenarios_dict = scenarios_dict + + tests_dict = read_yaml_file(args.tests_file) + for definition in tests_dict: + if not validate_dictionary(definition, ["name", "scenario", "test"]): + logging.error("couldn't validate file {}".format(args.tests_file)) + return False + + logging.debug("{} seems valid".format(args.tests_file)) + ctx.tests_dict = tests_dict + + env_list = read_yaml_file(args.env_file) + if not isinstance(env_list, list): + logging.error("couldn't validate file {}".format(args.env_file)) + return False + + # set env to default values if not overridden when calling this very script + for entry in env_list: + for key in entry: + os.environ[key] = os.getenv(key, entry[key]) + + +def cmd_run(cmd): + logging.debug("running command: {}".format(cmd)) + r = subprocess.run(cmd, shell=True) + if r.returncode != 0: + logging.warning("failed command: {}".format(cmd)) + return r.returncode + + +def scenario_get(name): + for n in ctx.scenarios_dict: + if n["name"] == name: + return n + + logging.error("couldn't find a definition for scenario '{}'".format(name)) + exit(1) + + +def scenario_start(scenario): + for cmd in scenario["start"]: + if cmd_run(cmd) == 0: + continue + + logging.warning("--- failed scenario: {}".format(scenario["name"])) + ctx.counter_scenario_failed += 1 + ctx.skip_current_test = True + return + + +def scenario_stop(scenario): + for cmd in scenario["stop"]: + cmd_run(cmd) + + +def test_get(name): + for n in ctx.tests_dict: + if n["name"] == name: + return n + + logging.error("couldn't find a definition for test '{}'".format(name)) + exit(1) + + +def _test_run(test_definition): + if ctx.skip_current_test: + return + + for cmd in test_definition["test"]: + if cmd_run(cmd) == 0: + continue + + logging.warning("--- failed test: {}".format(test_definition["name"])) + ctx.counter_test_failed += 1 + return + + logging.info("--- passed test: {}".format(test_definition["name"])) + ctx.counter_test_ok += 1 + + +def test_run(test_definition): + scenario = scenario_get(test_definition["scenario"]) + + logging.info("--- running test: {}".format(test_definition["name"])) + + scenario_start(scenario) + _test_run(test_definition) + scenario_stop(scenario) + + +def stage_run_tests(args): + if args.start_scenario: + scenario_start(scenario_get(args.start_scenario)) + return + + if args.stop_scenario: + scenario_stop(scenario_get(args.stop_scenario)) + return + + if args.single: + test_run(test_get(args.single)) + return + + for test_definition in ctx.tests_dict: + ctx.skip_current_test = False + test_run(test_definition) + + +def stage_report(): + logging.info("---") + logging.info("--- finished") + total = ctx.counter_test_ok + ctx.counter_test_failed + ctx.counter_scenario_failed + logging.info("--- passed tests: {}".format(ctx.counter_test_ok)) + logging.info("--- failed tests: {}".format(ctx.counter_test_failed)) + logging.info("--- scenario failure: {}".format(ctx.counter_scenario_failed)) + logging.info("--- total tests: {}".format(total)) + + +def parse_args(): + description = "Utility to run tests for conntrack-tools" + parser = argparse.ArgumentParser(description=description) + parser.add_argument( + "--tests-file", + default="tests.yaml", + help="File with testcase definitions. Defaults to '%(default)s'", + ) + parser.add_argument( + "--scenarios-file", + default="scenarios.yaml", + help="File with configuration scenarios for tests. Defaults to '%(default)s'", + ) + parser.add_argument( + "--env-file", + default="env.yaml", + help="File with environment variables for scenarios/tests. Defaults to '%(default)s'", + ) + parser.add_argument( + "--single", + help="Execute a single testcase and exit. Use this for developing testcases", + ) + parser.add_argument( + "--start-scenario", + help="Execute scenario start commands and exit. Use this for developing testcases", + ) + parser.add_argument( + "--stop-scenario", + help="Execute scenario stop commands and exit. Use this for cleanup", + ) + parser.add_argument( + "--debug", + action="store_true", + help="debug mode", + ) + + return parser.parse_args() + + +class Context: + def __init__(self): + self.scenarios_dict = None + self.tests_dict = None + self.counter_test_failed = 0 + self.counter_test_ok = 0 + self.counter_scenario_failed = 0 + self.skip_current_test = False + + +# global data +ctx = Context() + + +def main(): + args = parse_args() + + logging_format = "[%(filename)s] %(levelname)s: %(message)s" + if args.debug: + logging_level = logging.DEBUG + else: + logging_level = logging.INFO + logging.basicConfig(format=logging_format, level=logging_level, stream=sys.stdout) + + if os.geteuid() != 0: + logging.error("root required") + exit(1) + + stage_validate_config(args) + stage_run_tests(args) + stage_report() + + +if __name__ == "__main__": + main() diff --git a/tests/conntrackd/env.yaml b/tests/conntrackd/env.yaml new file mode 100644 index 0000000..daf8ea1 --- /dev/null +++ b/tests/conntrackd/env.yaml @@ -0,0 +1,2 @@ +- CONNTRACKD: ../../src/conntrackd +- CONNTRACK: ../../src/conntrack diff --git a/tests/conntrackd/netns/conntrackd-netns-test.sh b/tests/conntrackd/netns/conntrackd-netns-test.sh new file mode 100755 index 0000000..6f16587 --- /dev/null +++ b/tests/conntrackd/netns/conntrackd-netns-test.sh @@ -0,0 +1,66 @@ +#!/bin/bash + +if [ $UID -ne 0 ] +then + echo "You must be root to run this test script" + exit 0 +fi + +start () { + ip netns add ns1 + ip netns add ns2 + ip netns add nsr1 + ip netns add nsr2 + + ip link add veth0 netns ns1 type veth peer name veth1 netns nsr1 + ip link add veth0 netns nsr1 type veth peer name veth0 netns ns2 + ip link add veth2 netns nsr1 type veth peer name veth0 netns nsr2 + + ip -net ns1 addr add 192.168.10.2/24 dev veth0 + ip -net ns1 link set up dev veth0 + ip -net ns1 ro add 10.0.1.0/24 via 192.168.10.1 dev veth0 + + ip -net nsr1 addr add 10.0.1.1/24 dev veth0 + ip -net nsr1 addr add 192.168.10.1/24 dev veth1 + ip -net nsr1 link set up dev veth0 + ip -net nsr1 link set up dev veth1 + ip -net nsr1 route add default via 192.168.10.2 + ip netns exec nsr1 sysctl net.ipv4.ip_forward=1 + + ip -net nsr1 addr add 192.168.100.2/24 dev veth2 + ip -net nsr1 link set up dev veth2 + ip -net nsr2 addr add 192.168.100.3/24 dev veth0 + ip -net nsr2 link set up dev veth0 + + ip -net ns2 addr add 10.0.1.2/24 dev veth0 + ip -net ns2 link set up dev veth0 + ip -net ns2 route add default via 10.0.1.1 + + echo 1 > /proc/sys/net/netfilter/nf_log_all_netns + + ip netns exec nsr1 nft -f ruleset-nsr1.nft + ip netns exec nsr1 conntrackd -C conntrackd-nsr1.conf -d + ip netns exec nsr2 conntrackd -C conntrackd-nsr2.conf -d +} + +stop () { + ip netns del ns1 + ip netns del ns2 + ip netns del nsr1 + ip netns del nsr2 + killall -15 conntrackd +} + +case $1 in +start) + start + ;; +stop) + stop + ;; +*) + echo "$0 [start|stop]" + ;; +esac + +exit 0 diff --git a/tests/conntrackd/netns/conntrackd-nsr1.conf b/tests/conntrackd/netns/conntrackd-nsr1.conf new file mode 100644 index 0000000..c79eff5 --- /dev/null +++ b/tests/conntrackd/netns/conntrackd-nsr1.conf @@ -0,0 +1,37 @@ +Sync { + Mode FTFW { + } + Multicast { + IPv4_address 225.0.0.50 + Group 3780 + IPv4_interface 192.168.100.2 + Interface veth2 + SndSocketBuffer 1249280 + RcvSocketBuffer 1249280 + Checksum on + } +} +General { + HashSize 32768 + HashLimit 131072 + LogFile on + LockFile /var/lock/conntrack-nsr1.lock + UNIX { + Path /var/run/conntrackd-nsr1.ctl + } + NetlinkBufferSize 2097152 + NetlinkBufferSizeMaxGrowth 8388608 + Filter From Userspace { + Protocol Accept { + TCP + SCTP + DCCP + } + Address Ignore { + IPv4_address 127.0.0.1 + IPv4_address 192.168.10.1 + IPv4_address 10.0.10.1 + IPv4_address 192.168.100.2 + } + } +} diff --git a/tests/conntrackd/netns/conntrackd-nsr2.conf b/tests/conntrackd/netns/conntrackd-nsr2.conf new file mode 100644 index 0000000..65fa0d6 --- /dev/null +++ b/tests/conntrackd/netns/conntrackd-nsr2.conf @@ -0,0 +1,37 @@ +Sync { + Mode FTFW { + } + Multicast { + IPv4_address 225.0.0.50 + Group 3780 + IPv4_interface 192.168.100.3 + Interface veth0 + SndSocketBuffer 1249280 + RcvSocketBuffer 1249280 + Checksum on + } +} +General { + HashSize 32768 + HashLimit 131072 + LogFile on + LockFile /var/lock/conntrack-nsr2.lock + UNIX { + Path /var/run/conntrackd-nsr2.ctl + } + NetlinkBufferSize 2097152 + NetlinkBufferSizeMaxGrowth 8388608 + Filter From Userspace { + Protocol Accept { + TCP + SCTP + DCCP + } + Address Ignore { + IPv4_address 127.0.0.1 + IPv4_address 192.168.10.1 + IPv4_address 10.0.10.1 + IPv4_address 192.168.100.2 + } + } +} diff --git a/tests/conntrackd/netns/ruleset-nsr1.nft b/tests/conntrackd/netns/ruleset-nsr1.nft new file mode 100644 index 0000000..bd6f1b4 --- /dev/null +++ b/tests/conntrackd/netns/ruleset-nsr1.nft @@ -0,0 +1,6 @@ +table ip filter { + chain postrouting { + type nat hook postrouting priority srcnat; policy accept; + oif veth0 masquerade + } +} diff --git a/tests/conntrackd/scenarios.yaml b/tests/conntrackd/scenarios.yaml new file mode 100644 index 0000000..65d6fa4 --- /dev/null +++ b/tests/conntrackd/scenarios.yaml @@ -0,0 +1,100 @@ +- name: empty + start: + - ":" + stop: + - ":" +- name: simple_stats + start: + - rm -f /var/lock/conntrack.lock + - | + cat << EOF > /tmp/conntrackd_test_simple_stats + General { + HashSize 8192 + LockFile /var/lock/conntrack.lock + UNIX { Path /var/run/conntrackd.ctl } + } + Stats { + LogFile on + } + EOF + - $CONNTRACKD -C /tmp/conntrackd_test_simple_stats -d + stop: + - $CONNTRACKD -C /tmp/conntrackd_test_simple_stats -k + - rm -f /var/lock/conntrack.lock + - rm -f /tmp/conntrackd_test_simple_stats + +- name: basic_2_peer_network_tcp_notrack + start: + - scenarios/basic/./network-setup.sh start + - | + cat << EOF > /tmp/ruleset.nft + table ip filter { + chain postrouting { + type nat hook postrouting priority srcnat; policy accept; + oif veth0 masquerade + } + } + EOF + - ip netns exec nsr1 nft -f /tmp/ruleset.nft + - | + cat << EOF > /tmp/nsr1.conf + Sync { + Mode NOTRACK { + DisableExternalCache on + DisableInternalCache on + } + TCP { + IPv4_address 192.168.100.2 + IPv4_Destination_Address 192.168.100.3 + Interface veth2 + Port 3780 + } + } + General { + LogFile on + LockFile /var/lock/conntrack-nsr1.lock + UNIX { Path /var/run/conntrackd-nsr1.ctl } + } + EOF + - | + cat << EOF > /tmp/nsr2.conf + Sync { + Mode NOTRACK { + DisableExternalCache on + DisableInternalCache on + } + TCP { + IPv4_address 192.168.100.3 + IPv4_Destination_Address 192.168.100.2 + Interface veth0 + Port 3780 + } + } + General { + LogFile on + LockFile /var/lock/conntrack-nsr2.lock + UNIX { Path /var/run/conntrackd-nsr2.ctl } + } + EOF + # finally run the daemons + - ip netns exec nsr1 $CONNTRACKD -C /tmp/nsr1.conf -d + - ip netns exec nsr2 $CONNTRACKD -C /tmp/nsr2.conf -d + # make sure they are alive and connected before considering the scenario started + - timeout 5 bash -c -- ' + while ! ip netns exec nsr1 $CONNTRACKD -C /tmp/nsr1.conf -s | grep -q "server=connected" + ; do sleep 0.5 ; done' + - timeout 5 bash -c -- ' + while ! ip netns exec nsr1 $CONNTRACKD -C /tmp/nsr1.conf -s | grep -q "client=connected" + ; do sleep 0.5 ; done' + - timeout 5 bash -c -- ' + while ! ip netns exec nsr2 $CONNTRACKD -C /tmp/nsr2.conf -s | grep -q "server=connected" + ; do sleep 0.5 ; done' + - timeout 5 bash -c -- ' + while ! ip netns exec nsr2 $CONNTRACKD -C /tmp/nsr2.conf -s | grep -q "client=connected" + ; do sleep 0.5 ; done' + stop: + - $CONNTRACKD -C /tmp/nsr1.conf -k 2>/dev/null + - $CONNTRACKD -C /tmp/nsr2.conf -k 2>/dev/null + - rm -f /tmp/ruleset.nft /tmp/nsr2.conf /tmp/nsr1.conf + - rm -f /var/lock/conntrack-nsr1.lock /var/lock/conntrack-nsr2.lock + - scenarios/basic/./network-setup.sh stop diff --git a/tests/conntrackd/scenarios/basic/network-setup.sh b/tests/conntrackd/scenarios/basic/network-setup.sh new file mode 100755 index 0000000..7f2f78a --- /dev/null +++ b/tests/conntrackd/scenarios/basic/network-setup.sh @@ -0,0 +1,59 @@ +#!/bin/bash + +if [ $UID -ne 0 ] +then + echo "You must be root to run this test script" + exit 0 +fi + +start () { + ip netns add ns1 + ip netns add ns2 + ip netns add nsr1 + ip netns add nsr2 + + ip link add veth0 netns ns1 type veth peer name veth1 netns nsr1 + ip link add veth0 netns nsr1 type veth peer name veth0 netns ns2 + ip link add veth2 netns nsr1 type veth peer name veth0 netns nsr2 + + ip -net ns1 addr add 192.168.10.2/24 dev veth0 + ip -net ns1 link set up dev veth0 + ip -net ns1 ro add 10.0.1.0/24 via 192.168.10.1 dev veth0 + + ip -net nsr1 addr add 10.0.1.1/24 dev veth0 + ip -net nsr1 addr add 192.168.10.1/24 dev veth1 + ip -net nsr1 link set up dev veth0 + ip -net nsr1 link set up dev veth1 + ip -net nsr1 route add default via 192.168.10.2 + ip netns exec nsr1 sysctl -q net.ipv4.ip_forward=1 + + ip -net nsr1 addr add 192.168.100.2/24 dev veth2 + ip -net nsr1 link set up dev veth2 + ip -net nsr2 addr add 192.168.100.3/24 dev veth0 + ip -net nsr2 link set up dev veth0 + + ip -net ns2 addr add 10.0.1.2/24 dev veth0 + ip -net ns2 link set up dev veth0 + ip -net ns2 route add default via 10.0.1.1 +} + +stop () { + ip netns del ns1 + ip netns del ns2 + ip netns del nsr1 + ip netns del nsr2 +} + +case $1 in +start) + start + ;; +stop) + stop + ;; +*) + echo "$0 [start|stop]" + ;; +esac + +exit 0 diff --git a/tests/conntrackd/tests.yaml b/tests/conntrackd/tests.yaml new file mode 100644 index 0000000..307f38f --- /dev/null +++ b/tests/conntrackd/tests.yaml @@ -0,0 +1,83 @@ +- name: stats_general + scenario: simple_stats + # check that we can obtain stats via unix socket: general + test: + - $CONNTRACKD -C /tmp/conntrackd_test_simple_stats -s | grep -q "cache stats" + +- name: stats_network + scenario: simple_stats + # check that we can obtain stats via unix socket: network (no output) + test: + - $CONNTRACKD -C /tmp/conntrackd_test_simple_stats -s network + +- name: stats_runtime + scenario: simple_stats + # check that we can obtain stats via unix socket: runtime + test: + - $CONNTRACKD -C /tmp/conntrackd_test_simple_stats -s runtime | grep -q uptime + +- name: stats_process + scenario: simple_stats + # check that we can obtain stats via unix socket: process (no output) + test: + - $CONNTRACKD -C /tmp/conntrackd_test_simple_stats -s process + +- name: stats_queue + scenario: simple_stats + # check that we can obtain stats via unix socket: queue (no output) + test: + - $CONNTRACKD -C /tmp/conntrackd_test_simple_stats -s queue + +- name: stats_ct + scenario: simple_stats + # check that we can obtain stats via unix socket: ct + test: + - $CONNTRACKD -C /tmp/conntrackd_test_simple_stats -s ct | grep -q traffic + +- name: stats_expect + scenario: simple_stats + # check that we can obtain stats via unix socket: expect (no output) + test: + - $CONNTRACKD -C /tmp/conntrackd_test_simple_stats -s expect + +- name: tcp_notrack_replicate_icmp + scenario: basic_2_peer_network_tcp_notrack + # check that we can replicate a ICMP conntrack entry in a 2 conntrackd TCP/NOTRACK setup + test: + # PING should inject an ICMP conntrack entry in nsr1 + - ip netns exec ns1 ping -c1 10.0.1.2 >/dev/null + # verify conntrack entry is then replicated to nsr2, wait up to 5 seconds + - timeout 5 bash -c -- ' + while ! ip netns exec nsr2 $CONNTRACK -L -p icmp 2>/dev/null | grep -q icmp + ; do sleep 0.5 ; done' + +- name: hash_defaults_segfault + scenario: empty + test: + - rm -f /var/lock/conntrack.lock + - | + cat << EOF > /tmp/conntrackd_notrack_hash_defaults + Sync { + Mode NOTRACK { } + Multicast { + IPv4_address 225.0.0.50 + Group 3780 + IPv4_interface 127.0.0.1 + Interface lo + SndSocketBuffer 1249280 + RcvSocketBuffer 1249280 + Checksum on + } + } + General { + LogFile on + Syslog on + LockFile /var/lock/conntrackd.lock + UNIX { Path /var/run/conntrackd.sock } + NetlinkBufferSize 2097152 + NetlinkBufferSizeMaxGrowth 8388608 + } + EOF + - $CONNTRACKD -C /tmp/conntrackd_notrack_hash_defaults -d + - $CONNTRACKD -C /tmp/conntrackd_notrack_hash_defaults -s | grep -q "cache" + - $CONNTRACKD -C /tmp/conntrackd_notrack_hash_defaults -k |