~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/tools/testing/selftests/netfilter/nft_queue.sh

Version: ~ [ linux-6.1-rc5 ] ~ [ linux-6.0.8 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.78 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.154 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.224 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.265 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.299 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.333 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.302 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 #!/bin/bash
  2 #
  3 # This tests nf_queue:
  4 # 1. can process packets from all hooks
  5 # 2. support running nfqueue from more than one base chain
  6 #
  7 # Kselftest framework requirement - SKIP code is 4.
  8 ksft_skip=4
  9 ret=0
 10 
 11 sfx=$(mktemp -u "XXXXXXXX")
 12 ns1="ns1-$sfx"
 13 ns2="ns2-$sfx"
 14 nsrouter="nsrouter-$sfx"
 15 
 16 cleanup()
 17 {
 18         ip netns del ${ns1}
 19         ip netns del ${ns2}
 20         ip netns del ${nsrouter}
 21         rm -f "$TMPFILE0"
 22         rm -f "$TMPFILE1"
 23 }
 24 
 25 nft --version > /dev/null 2>&1
 26 if [ $? -ne 0 ];then
 27         echo "SKIP: Could not run test without nft tool"
 28         exit $ksft_skip
 29 fi
 30 
 31 ip -Version > /dev/null 2>&1
 32 if [ $? -ne 0 ];then
 33         echo "SKIP: Could not run test without ip tool"
 34         exit $ksft_skip
 35 fi
 36 
 37 ip netns add ${nsrouter}
 38 if [ $? -ne 0 ];then
 39         echo "SKIP: Could not create net namespace"
 40         exit $ksft_skip
 41 fi
 42 
 43 TMPFILE0=$(mktemp)
 44 TMPFILE1=$(mktemp)
 45 trap cleanup EXIT
 46 
 47 ip netns add ${ns1}
 48 ip netns add ${ns2}
 49 
 50 ip link add veth0 netns ${nsrouter} type veth peer name eth0 netns ${ns1} > /dev/null 2>&1
 51 if [ $? -ne 0 ];then
 52     echo "SKIP: No virtual ethernet pair device support in kernel"
 53     exit $ksft_skip
 54 fi
 55 ip link add veth1 netns ${nsrouter} type veth peer name eth0 netns ${ns2}
 56 
 57 ip -net ${nsrouter} link set lo up
 58 ip -net ${nsrouter} link set veth0 up
 59 ip -net ${nsrouter} addr add 10.0.1.1/24 dev veth0
 60 ip -net ${nsrouter} addr add dead:1::1/64 dev veth0
 61 
 62 ip -net ${nsrouter} link set veth1 up
 63 ip -net ${nsrouter} addr add 10.0.2.1/24 dev veth1
 64 ip -net ${nsrouter} addr add dead:2::1/64 dev veth1
 65 
 66 ip -net ${ns1} link set lo up
 67 ip -net ${ns1} link set eth0 up
 68 
 69 ip -net ${ns2} link set lo up
 70 ip -net ${ns2} link set eth0 up
 71 
 72 ip -net ${ns1} addr add 10.0.1.99/24 dev eth0
 73 ip -net ${ns1} addr add dead:1::99/64 dev eth0
 74 ip -net ${ns1} route add default via 10.0.1.1
 75 ip -net ${ns1} route add default via dead:1::1
 76 
 77 ip -net ${ns2} addr add 10.0.2.99/24 dev eth0
 78 ip -net ${ns2} addr add dead:2::99/64 dev eth0
 79 ip -net ${ns2} route add default via 10.0.2.1
 80 ip -net ${ns2} route add default via dead:2::1
 81 
 82 load_ruleset() {
 83         local name=$1
 84         local prio=$2
 85 
 86 ip netns exec ${nsrouter} nft -f - <<EOF
 87 table inet $name {
 88         chain nfq {
 89                 ip protocol icmp queue bypass
 90                 icmpv6 type { "echo-request", "echo-reply" } queue num 1 bypass
 91         }
 92         chain pre {
 93                 type filter hook prerouting priority $prio; policy accept;
 94                 jump nfq
 95         }
 96         chain input {
 97                 type filter hook input priority $prio; policy accept;
 98                 jump nfq
 99         }
100         chain forward {
101                 type filter hook forward priority $prio; policy accept;
102                 tcp dport 12345 queue num 2
103                 jump nfq
104         }
105         chain output {
106                 type filter hook output priority $prio; policy accept;
107                 tcp dport 12345 queue num 3
108                 jump nfq
109         }
110         chain post {
111                 type filter hook postrouting priority $prio; policy accept;
112                 jump nfq
113         }
114 }
115 EOF
116 }
117 
118 load_counter_ruleset() {
119         local prio=$1
120 
121 ip netns exec ${nsrouter} nft -f - <<EOF
122 table inet countrules {
123         chain pre {
124                 type filter hook prerouting priority $prio; policy accept;
125                 counter
126         }
127         chain input {
128                 type filter hook input priority $prio; policy accept;
129                 counter
130         }
131         chain forward {
132                 type filter hook forward priority $prio; policy accept;
133                 counter
134         }
135         chain output {
136                 type filter hook output priority $prio; policy accept;
137                 counter
138         }
139         chain post {
140                 type filter hook postrouting priority $prio; policy accept;
141                 counter
142         }
143 }
144 EOF
145 }
146 
147 test_ping() {
148   ip netns exec ${ns1} ping -c 1 -q 10.0.2.99 > /dev/null
149   if [ $? -ne 0 ];then
150         return 1
151   fi
152 
153   ip netns exec ${ns1} ping -c 1 -q dead:2::99 > /dev/null
154   if [ $? -ne 0 ];then
155         return 1
156   fi
157 
158   return 0
159 }
160 
161 test_ping_router() {
162   ip netns exec ${ns1} ping -c 1 -q 10.0.2.1 > /dev/null
163   if [ $? -ne 0 ];then
164         return 1
165   fi
166 
167   ip netns exec ${ns1} ping -c 1 -q dead:2::1 > /dev/null
168   if [ $? -ne 0 ];then
169         return 1
170   fi
171 
172   return 0
173 }
174 
175 test_queue_blackhole() {
176         local proto=$1
177 
178 ip netns exec ${nsrouter} nft -f - <<EOF
179 table $proto blackh {
180         chain forward {
181         type filter hook forward priority 0; policy accept;
182                 queue num 600
183         }
184 }
185 EOF
186         if [ $proto = "ip" ] ;then
187                 ip netns exec ${ns1} ping -c 1 -q 10.0.2.99 > /dev/null
188                 lret=$?
189         elif [ $proto = "ip6" ]; then
190                 ip netns exec ${ns1} ping -c 1 -q dead:2::99 > /dev/null
191                 lret=$?
192         else
193                 lret=111
194         fi
195 
196         # queue without bypass keyword should drop traffic if no listener exists.
197         if [ $lret -eq 0 ];then
198                 echo "FAIL: $proto expected failure, got $lret" 1>&2
199                 exit 1
200         fi
201 
202         ip netns exec ${nsrouter} nft delete table $proto blackh
203         if [ $? -ne 0 ] ;then
204                 echo "FAIL: $proto: Could not delete blackh table"
205                 exit 1
206         fi
207 
208         echo "PASS: $proto: statement with no listener results in packet drop"
209 }
210 
211 test_queue()
212 {
213         local expected=$1
214         local last=""
215 
216         # spawn nf-queue listeners
217         ip netns exec ${nsrouter} ./nf-queue -c -q 0 -t 3 > "$TMPFILE0" &
218         ip netns exec ${nsrouter} ./nf-queue -c -q 1 -t 3 > "$TMPFILE1" &
219         sleep 1
220         test_ping
221         ret=$?
222         if [ $ret -ne 0 ];then
223                 echo "FAIL: netns routing/connectivity with active listener on queue $queue: $ret" 1>&2
224                 exit $ret
225         fi
226 
227         test_ping_router
228         ret=$?
229         if [ $ret -ne 0 ];then
230                 echo "FAIL: netns router unreachable listener on queue $queue: $ret" 1>&2
231                 exit $ret
232         fi
233 
234         wait
235         ret=$?
236 
237         for file in $TMPFILE0 $TMPFILE1; do
238                 last=$(tail -n1 "$file")
239                 if [ x"$last" != x"$expected packets total" ]; then
240                         echo "FAIL: Expected $expected packets total, but got $last" 1>&2
241                         cat "$file" 1>&2
242 
243                         ip netns exec ${nsrouter} nft list ruleset
244                         exit 1
245                 fi
246         done
247 
248         echo "PASS: Expected and received $last"
249 }
250 
251 test_tcp_forward()
252 {
253         ip netns exec ${nsrouter} ./nf-queue -q 2 -t 10 &
254         local nfqpid=$!
255 
256         tmpfile=$(mktemp) || exit 1
257         dd conv=sparse status=none if=/dev/zero bs=1M count=100 of=$tmpfile
258         ip netns exec ${ns2} nc -w 5 -l -p 12345 <"$tmpfile" >/dev/null &
259         local rpid=$!
260 
261         sleep 1
262         ip netns exec ${ns1} nc -w 5 10.0.2.99 12345 <"$tmpfile" >/dev/null &
263 
264         rm -f "$tmpfile"
265 
266         wait $rpid
267         wait $lpid
268         [ $? -eq 0 ] && echo "PASS: tcp and nfqueue in forward chain"
269 }
270 
271 test_tcp_localhost()
272 {
273         tc -net "${nsrouter}" qdisc add dev lo root netem loss random 1%
274 
275         tmpfile=$(mktemp) || exit 1
276 
277         dd conv=sparse status=none if=/dev/zero bs=1M count=900 of=$tmpfile
278         ip netns exec ${nsrouter} nc -w 5 -l -p 12345 <"$tmpfile" >/dev/null &
279         local rpid=$!
280 
281         ip netns exec ${nsrouter} ./nf-queue -q 3 -t 30 &
282         local nfqpid=$!
283 
284         sleep 1
285         ip netns exec ${nsrouter} nc -w 5 127.0.0.1 12345 <"$tmpfile" > /dev/null
286         rm -f "$tmpfile"
287 
288         wait $rpid
289         [ $? -eq 0 ] && echo "PASS: tcp via loopback"
290 }
291 
292 ip netns exec ${nsrouter} sysctl net.ipv6.conf.all.forwarding=1 > /dev/null
293 ip netns exec ${nsrouter} sysctl net.ipv4.conf.veth0.forwarding=1 > /dev/null
294 ip netns exec ${nsrouter} sysctl net.ipv4.conf.veth1.forwarding=1 > /dev/null
295 
296 load_ruleset "filter" 0
297 
298 sleep 3
299 
300 test_ping
301 ret=$?
302 if [ $ret -eq 0 ];then
303         # queue bypass works (rules were skipped, no listener)
304         echo "PASS: ${ns1} can reach ${ns2}"
305 else
306         echo "FAIL: ${ns1} cannot reach ${ns2}: $ret" 1>&2
307         exit $ret
308 fi
309 
310 test_queue_blackhole ip
311 test_queue_blackhole ip6
312 
313 # dummy ruleset to add base chains between the
314 # queueing rules.  We don't want the second reinject
315 # to re-execute the old hooks.
316 load_counter_ruleset 10
317 
318 # we are hooking all: prerouting/input/forward/output/postrouting.
319 # we ping ${ns2} from ${ns1} via ${nsrouter} using ipv4 and ipv6, so:
320 # 1x icmp prerouting,forward,postrouting -> 3 queue events (6 incl. reply).
321 # 1x icmp prerouting,input,output postrouting -> 4 queue events incl. reply.
322 # so we expect that userspace program receives 10 packets.
323 test_queue 10
324 
325 # same.  We queue to a second program as well.
326 load_ruleset "filter2" 20
327 test_queue 20
328 
329 test_tcp_forward
330 test_tcp_localhost
331 
332 exit $ret

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp