summaryrefslogtreecommitdiff
path: root/tools/testing/selftests/netfilter/nft_audit.sh
blob: bb34329e02a7f99b0b60bef66f9f1a2441b04c16 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
#!/bin/bash
# SPDX-License-Identifier: GPL-2.0
#
# Check that audit logs generated for nft commands are as expected.

SKIP_RC=4
RC=0

nft --version >/dev/null 2>&1 || {
	echo "SKIP: missing nft tool"
	exit $SKIP_RC
}

logfile=$(mktemp)
rulefile=$(mktemp)
echo "logging into $logfile"
./audit_logread >"$logfile" &
logread_pid=$!
trap 'kill $logread_pid; rm -f $logfile $rulefile' EXIT
exec 3<"$logfile"

do_test() { # (cmd, log)
	echo -n "testing for cmd: $1 ... "
	cat <&3 >/dev/null
	$1 >/dev/null || exit 1
	sleep 0.1
	res=$(diff -a -u <(echo "$2") - <&3)
	[ $? -eq 0 ] && { echo "OK"; return; }
	echo "FAIL"
	grep -v '^\(---\|+++\|@@\)' <<< "$res"
	((RC--))
}

nft flush ruleset

# adding tables, chains and rules

for table in t1 t2; do
	do_test "nft add table $table" \
	"table=$table family=2 entries=1 op=nft_register_table"

	do_test "nft add chain $table c1" \
	"table=$table family=2 entries=1 op=nft_register_chain"

	do_test "nft add chain $table c2; add chain $table c3" \
	"table=$table family=2 entries=2 op=nft_register_chain"

	cmd="add rule $table c1 counter"

	do_test "nft $cmd" \
	"table=$table family=2 entries=1 op=nft_register_rule"

	do_test "nft $cmd; $cmd" \
	"table=$table family=2 entries=2 op=nft_register_rule"

	cmd=""
	sep=""
	for chain in c2 c3; do
		for i in {1..3}; do
			cmd+="$sep add rule $table $chain counter"
			sep=";"
		done
	done
	do_test "nft $cmd" \
	"table=$table family=2 entries=6 op=nft_register_rule"
done

for ((i = 0; i < 500; i++)); do
	echo "add rule t2 c3 counter accept comment \"rule $i\""
done >$rulefile
do_test "nft -f $rulefile" \
'table=t2 family=2 entries=500 op=nft_register_rule'

# adding sets and elements

settype='type inet_service; counter'
setelem='{ 22, 80, 443 }'
setblock="{ $settype; elements = $setelem; }"
do_test "nft add set t1 s $setblock" \
"table=t1 family=2 entries=4 op=nft_register_set"

do_test "nft add set t1 s2 $setblock; add set t1 s3 { $settype; }" \
"table=t1 family=2 entries=5 op=nft_register_set"

do_test "nft add element t1 s3 $setelem" \
"table=t1 family=2 entries=3 op=nft_register_setelem"

# adding counters

do_test 'nft add counter t1 c1' \
'table=t1 family=2 entries=1 op=nft_register_obj'

do_test 'nft add counter t2 c1; add counter t2 c2' \
'table=t2 family=2 entries=2 op=nft_register_obj'

# adding/updating quotas

do_test 'nft add quota t1 q1 { 10 bytes }' \
'table=t1 family=2 entries=1 op=nft_register_obj'

do_test 'nft add quota t2 q1 { 10 bytes }; add quota t2 q2 { 10 bytes }' \
'table=t2 family=2 entries=2 op=nft_register_obj'

# changing the quota value triggers obj update path
do_test 'nft add quota t1 q1 { 20 bytes }' \
'table=t1 family=2 entries=1 op=nft_register_obj'

# resetting rules

do_test 'nft reset rules t1 c2' \
'table=t1 family=2 entries=3 op=nft_reset_rule'

do_test 'nft reset rules table t1' \
'table=t1 family=2 entries=3 op=nft_reset_rule
table=t1 family=2 entries=3 op=nft_reset_rule
table=t1 family=2 entries=3 op=nft_reset_rule'

do_test 'nft reset rules t2 c3' \
'table=t2 family=2 entries=189 op=nft_reset_rule
table=t2 family=2 entries=188 op=nft_reset_rule
table=t2 family=2 entries=126 op=nft_reset_rule'

do_test 'nft reset rules t2' \
'table=t2 family=2 entries=3 op=nft_reset_rule
table=t2 family=2 entries=3 op=nft_reset_rule
table=t2 family=2 entries=186 op=nft_reset_rule
table=t2 family=2 entries=188 op=nft_reset_rule
table=t2 family=2 entries=129 op=nft_reset_rule'

do_test 'nft reset rules' \
'table=t1 family=2 entries=3 op=nft_reset_rule
table=t1 family=2 entries=3 op=nft_reset_rule
table=t1 family=2 entries=3 op=nft_reset_rule
table=t2 family=2 entries=3 op=nft_reset_rule
table=t2 family=2 entries=3 op=nft_reset_rule
table=t2 family=2 entries=180 op=nft_reset_rule
table=t2 family=2 entries=188 op=nft_reset_rule
table=t2 family=2 entries=135 op=nft_reset_rule'

# resetting sets and elements

elem=(22 ,80 ,443)
relem=""
for i in {1..3}; do
	relem+="${elem[((i - 1))]}"
	do_test "nft reset element t1 s { $relem }" \
	"table=t1 family=2 entries=$i op=nft_reset_setelem"
done

do_test 'nft reset set t1 s' \
'table=t1 family=2 entries=3 op=nft_reset_setelem'

# deleting rules

readarray -t handles < <(nft -a list chain t1 c1 | \
			 sed -n 's/.*counter.* handle \(.*\)$/\1/p')

do_test "nft delete rule t1 c1 handle ${handles[0]}" \
'table=t1 family=2 entries=1 op=nft_unregister_rule'

cmd='delete rule t1 c1 handle'
do_test "nft $cmd ${handles[1]}; $cmd ${handles[2]}" \
'table=t1 family=2 entries=2 op=nft_unregister_rule'

do_test 'nft flush chain t1 c2' \
'table=t1 family=2 entries=3 op=nft_unregister_rule'

do_test 'nft flush table t2' \
'table=t2 family=2 entries=509 op=nft_unregister_rule'

# deleting chains

do_test 'nft delete chain t2 c2' \
'table=t2 family=2 entries=1 op=nft_unregister_chain'

# deleting sets and elements

do_test 'nft delete element t1 s { 22 }' \
'table=t1 family=2 entries=1 op=nft_unregister_setelem'

do_test 'nft delete element t1 s { 80, 443 }' \
'table=t1 family=2 entries=2 op=nft_unregister_setelem'

do_test 'nft flush set t1 s2' \
'table=t1 family=2 entries=3 op=nft_unregister_setelem'

do_test 'nft delete set t1 s2' \
'table=t1 family=2 entries=1 op=nft_unregister_set'

do_test 'nft delete set t1 s3' \
'table=t1 family=2 entries=1 op=nft_unregister_set'

exit $RC