2 # SPDX-License-Identifier: GPL-2.0
4 # Uncomment to see generated bytecode
13 IPVETH0="192.168.254.1"
14 IPVETH1="192.168.254.2"
15 IPVETH1b="192.168.254.3"
17 IPVETH2="192.168.111.1"
18 IPVETH3="192.168.111.2"
20 IP_LOCAL="192.168.99.1"
22 TRACE_ROOT=/sys/kernel/debug/tracing
27 if [ ! -z "$2" ]; then
28 MAC=$(ip netns exec $2 ip link show $1 | grep ether | awk '{print $2}')
30 MAC=$(ip link show $1 | grep ether | awk '{print $2}')
33 echo "0x${MAC:10:2}${MAC:8:2}${MAC:6:2}${MAC:4:2}${MAC:2:2}${MAC:0:2}"
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
50 function setup_one_veth {
52 ip link add $2 type veth peer name $3
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
60 ip netns exec $1 ip addr add $6/32 dev $3
66 cat ${TRACE_ROOT}/trace | grep -v '^#'
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
75 function install_test {
77 cp /dev/null ${TRACE_ROOT}/trace
79 OPTS="encap bpf headroom 14 $1 obj test_lwt_bpf.o section $2 $VERBOSE"
81 if [ "$1" == "in" ]; then
82 ip route add table local local ${IP_LOCAL}/32 $OPTS dev lo
84 ip route add ${IPVETH1}/32 $OPTS dev $VETH0
88 function remove_prog {
89 if [ "$1" == "in" ]; then
90 ip route del table local local ${IP_LOCAL}/32 dev lo
92 ip route del ${IPVETH1}/32 dev $VETH0
96 function filter_trace {
97 # Add newline to allow starting EXPECT= variables on newline
99 echo "${NL}$*" | sed -e 's/^.*: : //g'
102 function expect_fail {
111 function match_trace {
116 GOT="$(filter_trace "$TRACE")"
118 [ "$GOT" != "$EXPECT" ] && {
119 expect_fail "$EXPECT" "$GOT"
126 function test_start {
128 echo "----------------------------------------------------------------"
129 echo "Starting test: $*"
130 echo "----------------------------------------------------------------"
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"
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
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"
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
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"
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
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"
202 match_trace "$(get_trace)" "
203 src: 1fea8c0 dst: 2fea8c0
204 src: 1fea8c0 dst: 2fea8c0
205 src: 1fea8c0 dst: 2fea8c0" || exit 1
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"
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
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"
233 match_trace "$(get_trace)" "
239 cb3: 0 cb4: 0" || exit 1
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"
249 # We will both request & reply packets as the packets will
250 # be from $IP_LOCAL => $IP_LOCAL
251 match_trace "$(get_trace)" "
263 cb3: 0 cb4: 0" || exit 1
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"
273 match_trace "$(get_trace)" "
276 dropping with: 2" || exit 1
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"
286 match_trace "$(get_trace)" "
289 dropping with: 2" || exit 1
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"
299 match_trace "$(get_trace)" "
300 redirected to $DST_IFINDEX
301 redirected to $DST_IFINDEX
302 redirected to $DST_IFINDEX" || exit 1
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"
312 match_trace "$(get_trace)" "
313 redirected to $DST_IFINDEX
314 redirected to $DST_IFINDEX
315 redirected to $DST_IFINDEX" || exit 1
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"
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
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"
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
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"
351 match_trace "$(get_trace)" ""|| exit 1
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"
361 match_trace "$(get_trace)" ""|| exit 1
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
371 DST_MAC=$(lookup_mac $VETH1 $NS1)
372 SRC_MAC=$(lookup_mac $VETH0)
373 DST_IFINDEX=$(cat /sys/class/net/$VETH0/ifindex)
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
392 test_push_ll_and_redirect
393 test_no_l2_and_redirect
396 test_netperf_redirect
399 echo 0 > ${TRACE_ROOT}/tracing_on