406 lines · bash
1#!/bin/bash2# SPDX-License-Identifier: GPL-2.03 4# Uncomment to see generated bytecode5#VERBOSE=verbose6 7NS1=lwt_ns18NS2=lwt_ns29VETH0=tst_lwt1a10VETH1=tst_lwt1b11VETH2=tst_lwt2a12VETH3=tst_lwt2b13IPVETH0="192.168.254.1"14IPVETH1="192.168.254.2"15IPVETH1b="192.168.254.3"16 17IPVETH2="192.168.111.1"18IPVETH3="192.168.111.2"19 20IP_LOCAL="192.168.99.1"21 22PROG_SRC="test_lwt_bpf.c"23BPF_PROG="test_lwt_bpf.o"24TRACE_ROOT=/sys/kernel/tracing25CONTEXT_INFO=$(cat ${TRACE_ROOT}/trace_options | grep context)26 27function lookup_mac()28{29 set +x30 if [ ! -z "$2" ]; then31 MAC=$(ip netns exec $2 ip link show $1 | grep ether | awk '{print $2}')32 else33 MAC=$(ip link show $1 | grep ether | awk '{print $2}')34 fi35 MAC="${MAC//:/}"36 echo "0x${MAC:10:2}${MAC:8:2}${MAC:6:2}${MAC:4:2}${MAC:2:2}${MAC:0:2}"37 set -x38}39 40function cleanup {41 set +ex42 rm $BPF_PROG 2> /dev/null43 ip link del $VETH0 2> /dev/null44 ip link del $VETH1 2> /dev/null45 ip link del $VETH2 2> /dev/null46 ip link del $VETH3 2> /dev/null47 ip netns exec $NS1 killall netserver48 ip netns delete $NS1 2> /dev/null49 ip netns delete $NS2 2> /dev/null50 set -ex51}52 53function setup_one_veth {54 ip netns add $155 ip link add $2 type veth peer name $356 ip link set dev $2 up57 ip addr add $4/24 dev $258 ip link set $3 netns $159 ip netns exec $1 ip link set dev $3 up60 ip netns exec $1 ip addr add $5/24 dev $361 62 if [ "$6" ]; then63 ip netns exec $1 ip addr add $6/32 dev $364 fi65}66 67function get_trace {68 set +x69 cat ${TRACE_ROOT}/trace | grep -v '^#'70 set -x71}72 73function cleanup_routes {74 ip route del ${IPVETH1}/32 dev $VETH0 2> /dev/null || true75 ip route del table local local ${IP_LOCAL}/32 dev lo 2> /dev/null || true76}77 78function install_test {79 cleanup_routes80 cp /dev/null ${TRACE_ROOT}/trace81 82 OPTS="encap bpf headroom 14 $1 obj $BPF_PROG section $2 $VERBOSE"83 84 if [ "$1" == "in" ]; then85 ip route add table local local ${IP_LOCAL}/32 $OPTS dev lo86 else87 ip route add ${IPVETH1}/32 $OPTS dev $VETH088 fi89}90 91function remove_prog {92 if [ "$1" == "in" ]; then93 ip route del table local local ${IP_LOCAL}/32 dev lo94 else95 ip route del ${IPVETH1}/32 dev $VETH096 fi97}98 99function filter_trace {100 # Add newline to allow starting EXPECT= variables on newline101 NL=$'\n'102 echo "${NL}$*" | sed -e 's/bpf_trace_printk: //g'103}104 105function expect_fail {106 set +x107 echo "FAIL:"108 echo "Expected: $1"109 echo "Got: $2"110 set -x111 exit 1112}113 114function match_trace {115 set +x116 RET=0117 TRACE=$1118 EXPECT=$2119 GOT="$(filter_trace "$TRACE")"120 121 [ "$GOT" != "$EXPECT" ] && {122 expect_fail "$EXPECT" "$GOT"123 RET=1124 }125 set -x126 return $RET127}128 129function test_start {130 set +x131 echo "----------------------------------------------------------------"132 echo "Starting test: $*"133 echo "----------------------------------------------------------------"134 set -x135}136 137function failure {138 get_trace139 echo "FAIL: $*"140 exit 1141}142 143function test_ctx_xmit {144 test_start "test_ctx on lwt xmit"145 install_test xmit test_ctx146 ping -c 3 $IPVETH1 || {147 failure "test_ctx xmit: packets are dropped"148 }149 match_trace "$(get_trace)" "150len 84 hash 0 protocol 8151cb 1234 ingress_ifindex 0 ifindex $DST_IFINDEX152len 84 hash 0 protocol 8153cb 1234 ingress_ifindex 0 ifindex $DST_IFINDEX154len 84 hash 0 protocol 8155cb 1234 ingress_ifindex 0 ifindex $DST_IFINDEX" || exit 1156 remove_prog xmit157}158 159function test_ctx_out {160 test_start "test_ctx on lwt out"161 install_test out test_ctx162 ping -c 3 $IPVETH1 || {163 failure "test_ctx out: packets are dropped"164 }165 match_trace "$(get_trace)" "166len 84 hash 0 protocol 8167cb 1234 ingress_ifindex 0 ifindex 0168len 84 hash 0 protocol 8169cb 1234 ingress_ifindex 0 ifindex 0170len 84 hash 0 protocol 8171cb 1234 ingress_ifindex 0 ifindex 0" || exit 1172 remove_prog out173}174 175function test_ctx_in {176 test_start "test_ctx on lwt in"177 install_test in test_ctx178 ping -c 3 $IP_LOCAL || {179 failure "test_ctx out: packets are dropped"180 }181 # We will both request & reply packets as the packets will182 # be from $IP_LOCAL => $IP_LOCAL183 match_trace "$(get_trace)" "184len 84 hash 0 protocol 8185cb 1234 ingress_ifindex 1 ifindex 1186len 84 hash 0 protocol 8187cb 1234 ingress_ifindex 1 ifindex 1188len 84 hash 0 protocol 8189cb 1234 ingress_ifindex 1 ifindex 1190len 84 hash 0 protocol 8191cb 1234 ingress_ifindex 1 ifindex 1192len 84 hash 0 protocol 8193cb 1234 ingress_ifindex 1 ifindex 1194len 84 hash 0 protocol 8195cb 1234 ingress_ifindex 1 ifindex 1" || exit 1196 remove_prog in197}198 199function test_data {200 test_start "test_data on lwt $1"201 install_test $1 test_data202 ping -c 3 $IPVETH1 || {203 failure "test_data ${1}: packets are dropped"204 }205 match_trace "$(get_trace)" "206src: 1fea8c0 dst: 2fea8c0207src: 1fea8c0 dst: 2fea8c0208src: 1fea8c0 dst: 2fea8c0" || exit 1209 remove_prog $1210}211 212function test_data_in {213 test_start "test_data on lwt in"214 install_test in test_data215 ping -c 3 $IP_LOCAL || {216 failure "test_data in: packets are dropped"217 }218 # We will both request & reply packets as the packets will219 # be from $IP_LOCAL => $IP_LOCAL220 match_trace "$(get_trace)" "221src: 163a8c0 dst: 163a8c0222src: 163a8c0 dst: 163a8c0223src: 163a8c0 dst: 163a8c0224src: 163a8c0 dst: 163a8c0225src: 163a8c0 dst: 163a8c0226src: 163a8c0 dst: 163a8c0" || exit 1227 remove_prog in228}229 230function test_cb {231 test_start "test_cb on lwt $1"232 install_test $1 test_cb233 ping -c 3 $IPVETH1 || {234 failure "test_cb ${1}: packets are dropped"235 }236 match_trace "$(get_trace)" "237cb0: 0 cb1: 0 cb2: 0238cb3: 0 cb4: 0239cb0: 0 cb1: 0 cb2: 0240cb3: 0 cb4: 0241cb0: 0 cb1: 0 cb2: 0242cb3: 0 cb4: 0" || exit 1243 remove_prog $1244}245 246function test_cb_in {247 test_start "test_cb on lwt in"248 install_test in test_cb249 ping -c 3 $IP_LOCAL || {250 failure "test_cb in: packets are dropped"251 }252 # We will both request & reply packets as the packets will253 # be from $IP_LOCAL => $IP_LOCAL254 match_trace "$(get_trace)" "255cb0: 0 cb1: 0 cb2: 0256cb3: 0 cb4: 0257cb0: 0 cb1: 0 cb2: 0258cb3: 0 cb4: 0259cb0: 0 cb1: 0 cb2: 0260cb3: 0 cb4: 0261cb0: 0 cb1: 0 cb2: 0262cb3: 0 cb4: 0263cb0: 0 cb1: 0 cb2: 0264cb3: 0 cb4: 0265cb0: 0 cb1: 0 cb2: 0266cb3: 0 cb4: 0" || exit 1267 remove_prog in268}269 270function test_drop_all {271 test_start "test_drop_all on lwt $1"272 install_test $1 drop_all273 ping -c 3 $IPVETH1 && {274 failure "test_drop_all ${1}: Unexpected success of ping"275 }276 match_trace "$(get_trace)" "277dropping with: 2278dropping with: 2279dropping with: 2" || exit 1280 remove_prog $1281}282 283function test_drop_all_in {284 test_start "test_drop_all on lwt in"285 install_test in drop_all286 ping -c 3 $IP_LOCAL && {287 failure "test_drop_all in: Unexpected success of ping"288 }289 match_trace "$(get_trace)" "290dropping with: 2291dropping with: 2292dropping with: 2" || exit 1293 remove_prog in294}295 296function test_push_ll_and_redirect {297 test_start "test_push_ll_and_redirect on lwt xmit"298 install_test xmit push_ll_and_redirect299 ping -c 3 $IPVETH1 || {300 failure "Redirected packets appear to be dropped"301 }302 match_trace "$(get_trace)" "303redirected to $DST_IFINDEX304redirected to $DST_IFINDEX305redirected to $DST_IFINDEX" || exit 1306 remove_prog xmit307}308 309function test_no_l2_and_redirect {310 test_start "test_no_l2_and_redirect on lwt xmit"311 install_test xmit fill_garbage_and_redirect312 ping -c 3 $IPVETH1 && {313 failure "Unexpected success despite lack of L2 header"314 }315 match_trace "$(get_trace)" "316redirected to $DST_IFINDEX317redirected to $DST_IFINDEX318redirected to $DST_IFINDEX" || exit 1319 remove_prog xmit320}321 322function test_rewrite {323 test_start "test_rewrite on lwt xmit"324 install_test xmit test_rewrite325 ping -c 3 $IPVETH1 || {326 failure "Rewritten packets appear to be dropped"327 }328 match_trace "$(get_trace)" "329out: rewriting from 2fea8c0 to 3fea8c0330out: rewriting from 2fea8c0 to 3fea8c0331out: rewriting from 2fea8c0 to 3fea8c0" || exit 1332 remove_prog out333}334 335function test_fill_garbage {336 test_start "test_fill_garbage on lwt xmit"337 install_test xmit fill_garbage338 ping -c 3 $IPVETH1 && {339 failure "test_drop_all ${1}: Unexpected success of ping"340 }341 match_trace "$(get_trace)" "342Set initial 96 bytes of header to FF343Set initial 96 bytes of header to FF344Set initial 96 bytes of header to FF" || exit 1345 remove_prog xmit346}347 348function test_netperf_nop {349 test_start "test_netperf_nop on lwt xmit"350 install_test xmit nop351 netperf -H $IPVETH1 -t TCP_STREAM || {352 failure "packets appear to be dropped"353 }354 match_trace "$(get_trace)" ""|| exit 1355 remove_prog xmit356}357 358function test_netperf_redirect {359 test_start "test_netperf_redirect on lwt xmit"360 install_test xmit push_ll_and_redirect_silent361 netperf -H $IPVETH1 -t TCP_STREAM || {362 failure "Rewritten packets appear to be dropped"363 }364 match_trace "$(get_trace)" ""|| exit 1365 remove_prog xmit366}367 368cleanup369setup_one_veth $NS1 $VETH0 $VETH1 $IPVETH0 $IPVETH1 $IPVETH1b370setup_one_veth $NS2 $VETH2 $VETH3 $IPVETH2 $IPVETH3371ip netns exec $NS1 netserver372echo 1 > ${TRACE_ROOT}/tracing_on373echo nocontext-info > ${TRACE_ROOT}/trace_options374 375DST_MAC=$(lookup_mac $VETH1 $NS1)376SRC_MAC=$(lookup_mac $VETH0)377DST_IFINDEX=$(cat /sys/class/net/$VETH0/ifindex)378 379CLANG_OPTS="-O2 --target=bpf -I ../include/"380CLANG_OPTS+=" -DSRC_MAC=$SRC_MAC -DDST_MAC=$DST_MAC -DDST_IFINDEX=$DST_IFINDEX"381clang $CLANG_OPTS -c $PROG_SRC -o $BPF_PROG382 383test_ctx_xmit384test_ctx_out385test_ctx_in386test_data "xmit"387test_data "out"388test_data_in389test_cb "xmit"390test_cb "out"391test_cb_in392test_drop_all "xmit"393test_drop_all "out"394test_drop_all_in395test_rewrite396test_push_ll_and_redirect397test_no_l2_and_redirect398test_fill_garbage399test_netperf_nop400test_netperf_redirect401 402cleanup403echo 0 > ${TRACE_ROOT}/tracing_on404echo $CONTEXT_INFO > ${TRACE_ROOT}/trace_options405exit 0406