Merge tag 'selinux-pr-20180130' of git://git.kernel.org/pub/scm/linux/kernel/git...
[sfrench/cifs-2.6.git] / samples / bpf / test_lwt_bpf.sh
1 #!/bin/bash
2 # SPDX-License-Identifier: GPL-2.0
3
4 # Uncomment to see generated bytecode
5 #VERBOSE=verbose
6
7 NS1=lwt_ns1
8 NS2=lwt_ns2
9 VETH0=tst_lwt1a
10 VETH1=tst_lwt1b
11 VETH2=tst_lwt2a
12 VETH3=tst_lwt2b
13 IPVETH0="192.168.254.1"
14 IPVETH1="192.168.254.2"
15 IPVETH1b="192.168.254.3"
16
17 IPVETH2="192.168.111.1"
18 IPVETH3="192.168.111.2"
19
20 IP_LOCAL="192.168.99.1"
21
22 TRACE_ROOT=/sys/kernel/debug/tracing
23
24 function lookup_mac()
25 {
26         set +x
27         if [ ! -z "$2" ]; then
28                 MAC=$(ip netns exec $2 ip link show $1 | grep ether | awk '{print $2}')
29         else
30                 MAC=$(ip link show $1 | grep ether | awk '{print $2}')
31         fi
32         MAC="${MAC//:/}"
33         echo "0x${MAC:10:2}${MAC:8:2}${MAC:6:2}${MAC:4:2}${MAC:2:2}${MAC:0:2}"
34         set -x
35 }
36
37 function cleanup {
38         set +ex
39         rm test_lwt_bpf.o 2> /dev/null
40         ip link del $VETH0 2> /dev/null
41         ip link del $VETH1 2> /dev/null
42         ip link del $VETH2 2> /dev/null
43         ip link del $VETH3 2> /dev/null
44         ip netns exec $NS1 killall netserver
45         ip netns delete $NS1 2> /dev/null
46         ip netns delete $NS2 2> /dev/null
47         set -ex
48 }
49
50 function setup_one_veth {
51         ip netns add $1
52         ip link add $2 type veth peer name $3
53         ip link set dev $2 up
54         ip addr add $4/24 dev $2
55         ip link set $3 netns $1
56         ip netns exec $1 ip link set dev $3 up
57         ip netns exec $1 ip addr add $5/24 dev $3
58
59         if [ "$6" ]; then
60                 ip netns exec $1 ip addr add $6/32 dev $3
61         fi
62 }
63
64 function get_trace {
65         set +x
66         cat ${TRACE_ROOT}/trace | grep -v '^#'
67         set -x
68 }
69
70 function cleanup_routes {
71         ip route del ${IPVETH1}/32 dev $VETH0 2> /dev/null || true
72         ip route del table local local ${IP_LOCAL}/32 dev lo 2> /dev/null || true
73 }
74
75 function install_test {
76         cleanup_routes
77         cp /dev/null ${TRACE_ROOT}/trace
78
79         OPTS="encap bpf headroom 14 $1 obj test_lwt_bpf.o section $2 $VERBOSE"
80
81         if [ "$1" == "in" ];  then
82                 ip route add table local local ${IP_LOCAL}/32 $OPTS dev lo
83         else
84                 ip route add ${IPVETH1}/32 $OPTS dev $VETH0
85         fi
86 }
87
88 function remove_prog {
89         if [ "$1" == "in" ];  then
90                 ip route del table local local ${IP_LOCAL}/32 dev lo
91         else
92                 ip route del ${IPVETH1}/32 dev $VETH0
93         fi
94 }
95
96 function filter_trace {
97         # Add newline to allow starting EXPECT= variables on newline
98         NL=$'\n'
99         echo "${NL}$*" | sed -e 's/^.*: : //g'
100 }
101
102 function expect_fail {
103         set +x
104         echo "FAIL:"
105         echo "Expected: $1"
106         echo "Got: $2"
107         set -x
108         exit 1
109 }
110
111 function match_trace {
112         set +x
113         RET=0
114         TRACE=$1
115         EXPECT=$2
116         GOT="$(filter_trace "$TRACE")"
117
118         [ "$GOT" != "$EXPECT" ] && {
119                 expect_fail "$EXPECT" "$GOT"
120                 RET=1
121         }
122         set -x
123         return $RET
124 }
125
126 function test_start {
127         set +x
128         echo "----------------------------------------------------------------"
129         echo "Starting test: $*"
130         echo "----------------------------------------------------------------"
131         set -x
132 }
133
134 function failure {
135         get_trace
136         echo "FAIL: $*"
137         exit 1
138 }
139
140 function test_ctx_xmit {
141         test_start "test_ctx on lwt xmit"
142         install_test xmit test_ctx
143         ping -c 3 $IPVETH1 || {
144                 failure "test_ctx xmit: packets are dropped"
145         }
146         match_trace "$(get_trace)" "
147 len 84 hash 0 protocol 8
148 cb 1234 ingress_ifindex 0 ifindex $DST_IFINDEX
149 len 84 hash 0 protocol 8
150 cb 1234 ingress_ifindex 0 ifindex $DST_IFINDEX
151 len 84 hash 0 protocol 8
152 cb 1234 ingress_ifindex 0 ifindex $DST_IFINDEX" || exit 1
153         remove_prog xmit
154 }
155
156 function test_ctx_out {
157         test_start "test_ctx on lwt out"
158         install_test out test_ctx
159         ping -c 3 $IPVETH1 || {
160                 failure "test_ctx out: packets are dropped"
161         }
162         match_trace "$(get_trace)" "
163 len 84 hash 0 protocol 0
164 cb 1234 ingress_ifindex 0 ifindex 0
165 len 84 hash 0 protocol 0
166 cb 1234 ingress_ifindex 0 ifindex 0
167 len 84 hash 0 protocol 0
168 cb 1234 ingress_ifindex 0 ifindex 0" || exit 1
169         remove_prog out
170 }
171
172 function test_ctx_in {
173         test_start "test_ctx on lwt in"
174         install_test in test_ctx
175         ping -c 3 $IP_LOCAL || {
176                 failure "test_ctx out: packets are dropped"
177         }
178         # We will both request & reply packets as the packets will
179         # be from $IP_LOCAL => $IP_LOCAL
180         match_trace "$(get_trace)" "
181 len 84 hash 0 protocol 8
182 cb 1234 ingress_ifindex 1 ifindex 1
183 len 84 hash 0 protocol 8
184 cb 1234 ingress_ifindex 1 ifindex 1
185 len 84 hash 0 protocol 8
186 cb 1234 ingress_ifindex 1 ifindex 1
187 len 84 hash 0 protocol 8
188 cb 1234 ingress_ifindex 1 ifindex 1
189 len 84 hash 0 protocol 8
190 cb 1234 ingress_ifindex 1 ifindex 1
191 len 84 hash 0 protocol 8
192 cb 1234 ingress_ifindex 1 ifindex 1" || exit 1
193         remove_prog in
194 }
195
196 function test_data {
197         test_start "test_data on lwt $1"
198         install_test $1 test_data
199         ping -c 3 $IPVETH1 || {
200                 failure "test_data ${1}: packets are dropped"
201         }
202         match_trace "$(get_trace)" "
203 src: 1fea8c0 dst: 2fea8c0
204 src: 1fea8c0 dst: 2fea8c0
205 src: 1fea8c0 dst: 2fea8c0" || exit 1
206         remove_prog $1
207 }
208
209 function test_data_in {
210         test_start "test_data on lwt in"
211         install_test in test_data
212         ping -c 3 $IP_LOCAL || {
213                 failure "test_data in: packets are dropped"
214         }
215         # We will both request & reply packets as the packets will
216         # be from $IP_LOCAL => $IP_LOCAL
217         match_trace "$(get_trace)" "
218 src: 163a8c0 dst: 163a8c0
219 src: 163a8c0 dst: 163a8c0
220 src: 163a8c0 dst: 163a8c0
221 src: 163a8c0 dst: 163a8c0
222 src: 163a8c0 dst: 163a8c0
223 src: 163a8c0 dst: 163a8c0" || exit 1
224         remove_prog in
225 }
226
227 function test_cb {
228         test_start "test_cb on lwt $1"
229         install_test $1 test_cb
230         ping -c 3 $IPVETH1 || {
231                 failure "test_cb ${1}: packets are dropped"
232         }
233         match_trace "$(get_trace)" "
234 cb0: 0 cb1: 0 cb2: 0
235 cb3: 0 cb4: 0
236 cb0: 0 cb1: 0 cb2: 0
237 cb3: 0 cb4: 0
238 cb0: 0 cb1: 0 cb2: 0
239 cb3: 0 cb4: 0" || exit 1
240         remove_prog $1
241 }
242
243 function test_cb_in {
244         test_start "test_cb on lwt in"
245         install_test in test_cb
246         ping -c 3 $IP_LOCAL || {
247                 failure "test_cb in: packets are dropped"
248         }
249         # We will both request & reply packets as the packets will
250         # be from $IP_LOCAL => $IP_LOCAL
251         match_trace "$(get_trace)" "
252 cb0: 0 cb1: 0 cb2: 0
253 cb3: 0 cb4: 0
254 cb0: 0 cb1: 0 cb2: 0
255 cb3: 0 cb4: 0
256 cb0: 0 cb1: 0 cb2: 0
257 cb3: 0 cb4: 0
258 cb0: 0 cb1: 0 cb2: 0
259 cb3: 0 cb4: 0
260 cb0: 0 cb1: 0 cb2: 0
261 cb3: 0 cb4: 0
262 cb0: 0 cb1: 0 cb2: 0
263 cb3: 0 cb4: 0" || exit 1
264         remove_prog in
265 }
266
267 function test_drop_all {
268         test_start "test_drop_all on lwt $1"
269         install_test $1 drop_all
270         ping -c 3 $IPVETH1 && {
271                 failure "test_drop_all ${1}: Unexpected success of ping"
272         }
273         match_trace "$(get_trace)" "
274 dropping with: 2
275 dropping with: 2
276 dropping with: 2" || exit 1
277         remove_prog $1
278 }
279
280 function test_drop_all_in {
281         test_start "test_drop_all on lwt in"
282         install_test in drop_all
283         ping -c 3 $IP_LOCAL && {
284                 failure "test_drop_all in: Unexpected success of ping"
285         }
286         match_trace "$(get_trace)" "
287 dropping with: 2
288 dropping with: 2
289 dropping with: 2" || exit 1
290         remove_prog in
291 }
292
293 function test_push_ll_and_redirect {
294         test_start "test_push_ll_and_redirect on lwt xmit"
295         install_test xmit push_ll_and_redirect
296         ping -c 3 $IPVETH1 || {
297                 failure "Redirected packets appear to be dropped"
298         }
299         match_trace "$(get_trace)" "
300 redirected to $DST_IFINDEX
301 redirected to $DST_IFINDEX
302 redirected to $DST_IFINDEX" || exit 1
303         remove_prog xmit
304 }
305
306 function test_no_l2_and_redirect {
307         test_start "test_no_l2_and_redirect on lwt xmit"
308         install_test xmit fill_garbage_and_redirect
309         ping -c 3 $IPVETH1 && {
310                 failure "Unexpected success despite lack of L2 header"
311         }
312         match_trace "$(get_trace)" "
313 redirected to $DST_IFINDEX
314 redirected to $DST_IFINDEX
315 redirected to $DST_IFINDEX" || exit 1
316         remove_prog xmit
317 }
318
319 function test_rewrite {
320         test_start "test_rewrite on lwt xmit"
321         install_test xmit test_rewrite
322         ping -c 3 $IPVETH1 || {
323                 failure "Rewritten packets appear to be dropped"
324         }
325         match_trace "$(get_trace)" "
326 out: rewriting from 2fea8c0 to 3fea8c0
327 out: rewriting from 2fea8c0 to 3fea8c0
328 out: rewriting from 2fea8c0 to 3fea8c0" || exit 1
329         remove_prog out
330 }
331
332 function test_fill_garbage {
333         test_start "test_fill_garbage on lwt xmit"
334         install_test xmit fill_garbage
335         ping -c 3 $IPVETH1 && {
336                 failure "test_drop_all ${1}: Unexpected success of ping"
337         }
338         match_trace "$(get_trace)" "
339 Set initial 96 bytes of header to FF
340 Set initial 96 bytes of header to FF
341 Set initial 96 bytes of header to FF" || exit 1
342         remove_prog xmit
343 }
344
345 function test_netperf_nop {
346         test_start "test_netperf_nop on lwt xmit"
347         install_test xmit nop
348         netperf -H $IPVETH1 -t TCP_STREAM || {
349                 failure "packets appear to be dropped"
350         }
351         match_trace "$(get_trace)" ""|| exit 1
352         remove_prog xmit
353 }
354
355 function test_netperf_redirect {
356         test_start "test_netperf_redirect on lwt xmit"
357         install_test xmit push_ll_and_redirect_silent
358         netperf -H $IPVETH1 -t TCP_STREAM || {
359                 failure "Rewritten packets appear to be dropped"
360         }
361         match_trace "$(get_trace)" ""|| exit 1
362         remove_prog xmit
363 }
364
365 cleanup
366 setup_one_veth $NS1 $VETH0 $VETH1 $IPVETH0 $IPVETH1 $IPVETH1b
367 setup_one_veth $NS2 $VETH2 $VETH3 $IPVETH2 $IPVETH3
368 ip netns exec $NS1 netserver
369 echo 1 > ${TRACE_ROOT}/tracing_on
370
371 DST_MAC=$(lookup_mac $VETH1 $NS1)
372 SRC_MAC=$(lookup_mac $VETH0)
373 DST_IFINDEX=$(cat /sys/class/net/$VETH0/ifindex)
374
375 CLANG_OPTS="-O2 -target bpf -I ../include/"
376 CLANG_OPTS+=" -DSRC_MAC=$SRC_MAC -DDST_MAC=$DST_MAC -DDST_IFINDEX=$DST_IFINDEX"
377 clang $CLANG_OPTS -c test_lwt_bpf.c -o test_lwt_bpf.o
378
379 test_ctx_xmit
380 test_ctx_out
381 test_ctx_in
382 test_data "xmit"
383 test_data "out"
384 test_data_in
385 test_cb "xmit"
386 test_cb "out"
387 test_cb_in
388 test_drop_all "xmit"
389 test_drop_all "out"
390 test_drop_all_in
391 test_rewrite
392 test_push_ll_and_redirect
393 test_no_l2_and_redirect
394 test_fill_garbage
395 test_netperf_nop
396 test_netperf_redirect
397
398 cleanup
399 echo 0 > ${TRACE_ROOT}/tracing_on
400 exit 0