1d2329247SHangbin Liu#!/bin/bash 2d2329247SHangbin Liu# SPDX-License-Identifier: GPL-2.0 3d2329247SHangbin Liu# 4d2329247SHangbin Liu# Test topology: 58955c1a3SHangbin Liu# - - - - - - - - - - - - - - - - - - - 68955c1a3SHangbin Liu# | veth1 veth2 veth3 | ns0 7d2329247SHangbin Liu# - -| - - - - - - | - - - - - - | - - 8d2329247SHangbin Liu# --------- --------- --------- 98955c1a3SHangbin Liu# | veth0 | | veth0 | | veth0 | 10d2329247SHangbin Liu# --------- --------- --------- 11d2329247SHangbin Liu# ns1 ns2 ns3 12d2329247SHangbin Liu# 13d2329247SHangbin Liu# Test modules: 14d2329247SHangbin Liu# XDP modes: generic, native, native + egress_prog 15d2329247SHangbin Liu# 16d2329247SHangbin Liu# Test cases: 17d2329247SHangbin Liu# ARP: Testing BPF_F_BROADCAST, the ingress interface also should receive 18d2329247SHangbin Liu# the redirects. 19d2329247SHangbin Liu# ns1 -> gw: ns1, ns2, ns3, should receive the arp request 20d2329247SHangbin Liu# IPv4: Testing BPF_F_BROADCAST | BPF_F_EXCLUDE_INGRESS, the ingress 21d2329247SHangbin Liu# interface should not receive the redirects. 22d2329247SHangbin Liu# ns1 -> gw: ns1 should not receive, ns2, ns3 should receive redirects. 23d2329247SHangbin Liu# IPv6: Testing none flag, all the pkts should be redirected back 24d2329247SHangbin Liu# ping test: ns1 -> ns2 (block), echo requests will be redirect back 25d2329247SHangbin Liu# egress_prog: 26d2329247SHangbin Liu# all src mac should be egress interface's mac 27d2329247SHangbin Liu 28d2329247SHangbin Liu# netns numbers 29d2329247SHangbin LiuNUM=3 30d2329247SHangbin LiuIFACES="" 31d2329247SHangbin LiuDRV_MODE="xdpgeneric xdpdrv xdpegress" 32d2329247SHangbin LiuPASS=0 33d2329247SHangbin LiuFAIL=0 348b4ac13aSHangbin LiuLOG_DIR=$(mktemp -d) 35cec74489SHangbin Liudeclare -a NS 36cec74489SHangbin LiuNS[0]="ns0-$(mktemp -u XXXXXX)" 37cec74489SHangbin LiuNS[1]="ns1-$(mktemp -u XXXXXX)" 38cec74489SHangbin LiuNS[2]="ns2-$(mktemp -u XXXXXX)" 39cec74489SHangbin LiuNS[3]="ns3-$(mktemp -u XXXXXX)" 40d2329247SHangbin Liu 41d2329247SHangbin Liutest_pass() 42d2329247SHangbin Liu{ 43d2329247SHangbin Liu echo "Pass: $@" 44d2329247SHangbin Liu PASS=$((PASS + 1)) 45d2329247SHangbin Liu} 46d2329247SHangbin Liu 47d2329247SHangbin Liutest_fail() 48d2329247SHangbin Liu{ 49d2329247SHangbin Liu echo "fail: $@" 50d2329247SHangbin Liu FAIL=$((FAIL + 1)) 51d2329247SHangbin Liu} 52d2329247SHangbin Liu 53d2329247SHangbin Liuclean_up() 54d2329247SHangbin Liu{ 55cec74489SHangbin Liu for i in $(seq 0 $NUM); do 56cec74489SHangbin Liu ip netns del ${NS[$i]} 2> /dev/null 57d2329247SHangbin Liu done 58d2329247SHangbin Liu} 59d2329247SHangbin Liu 60d2329247SHangbin Liu# Kselftest framework requirement - SKIP code is 4. 61d2329247SHangbin Liucheck_env() 62d2329247SHangbin Liu{ 63d2329247SHangbin Liu ip link set dev lo xdpgeneric off &>/dev/null 64d2329247SHangbin Liu if [ $? -ne 0 ];then 65d2329247SHangbin Liu echo "selftests: [SKIP] Could not run test without the ip xdpgeneric support" 66d2329247SHangbin Liu exit 4 67d2329247SHangbin Liu fi 68d2329247SHangbin Liu 69d2329247SHangbin Liu which tcpdump &>/dev/null 70d2329247SHangbin Liu if [ $? -ne 0 ];then 71d2329247SHangbin Liu echo "selftests: [SKIP] Could not run test without tcpdump" 72d2329247SHangbin Liu exit 4 73d2329247SHangbin Liu fi 74d2329247SHangbin Liu} 75d2329247SHangbin Liu 76d2329247SHangbin Liusetup_ns() 77d2329247SHangbin Liu{ 78d2329247SHangbin Liu local mode=$1 79d2329247SHangbin Liu IFACES="" 80d2329247SHangbin Liu 81d2329247SHangbin Liu if [ "$mode" = "xdpegress" ]; then 82d2329247SHangbin Liu mode="xdpdrv" 83d2329247SHangbin Liu fi 84d2329247SHangbin Liu 85cec74489SHangbin Liu ip netns add ${NS[0]} 86d2329247SHangbin Liu for i in $(seq $NUM); do 87cec74489SHangbin Liu ip netns add ${NS[$i]} 88cec74489SHangbin Liu ip -n ${NS[$i]} link add veth0 type veth peer name veth$i netns ${NS[0]} 89cec74489SHangbin Liu ip -n ${NS[$i]} link set veth0 up 90cec74489SHangbin Liu ip -n ${NS[0]} link set veth$i up 91d2329247SHangbin Liu 92cec74489SHangbin Liu ip -n ${NS[$i]} addr add 192.0.2.$i/24 dev veth0 93cec74489SHangbin Liu ip -n ${NS[$i]} addr add 2001:db8::$i/64 dev veth0 94d2329247SHangbin Liu # Add a neigh entry for IPv4 ping test 95cec74489SHangbin Liu ip -n ${NS[$i]} neigh add 192.0.2.253 lladdr 00:00:00:00:00:01 dev veth0 96cec74489SHangbin Liu ip -n ${NS[$i]} link set veth0 $mode obj \ 97*afef88e6SDaniel Müller xdp_dummy.bpf.o sec xdp &> /dev/null || \ 98d2329247SHangbin Liu { test_fail "Unable to load dummy xdp" && exit 1; } 99d2329247SHangbin Liu IFACES="$IFACES veth$i" 100cec74489SHangbin Liu veth_mac[$i]=$(ip -n ${NS[0]} link show veth$i | awk '/link\/ether/ {print $2}') 101d2329247SHangbin Liu done 102d2329247SHangbin Liu} 103d2329247SHangbin Liu 104d2329247SHangbin Liudo_egress_tests() 105d2329247SHangbin Liu{ 106d2329247SHangbin Liu local mode=$1 107d2329247SHangbin Liu 108d2329247SHangbin Liu # mac test 109cec74489SHangbin Liu ip netns exec ${NS[2]} tcpdump -e -i veth0 -nn -l -e &> ${LOG_DIR}/mac_ns1-2_${mode}.log & 110cec74489SHangbin Liu ip netns exec ${NS[3]} tcpdump -e -i veth0 -nn -l -e &> ${LOG_DIR}/mac_ns1-3_${mode}.log & 111d2329247SHangbin Liu sleep 0.5 112cec74489SHangbin Liu ip netns exec ${NS[1]} ping 192.0.2.254 -i 0.1 -c 4 &> /dev/null 113d2329247SHangbin Liu sleep 0.5 114648c3677SHangbin Liu pkill tcpdump 115d2329247SHangbin Liu 116d2329247SHangbin Liu # mac check 1178b4ac13aSHangbin Liu grep -q "${veth_mac[2]} > ff:ff:ff:ff:ff:ff" ${LOG_DIR}/mac_ns1-2_${mode}.log && \ 118d2329247SHangbin Liu test_pass "$mode mac ns1-2" || test_fail "$mode mac ns1-2" 1198b4ac13aSHangbin Liu grep -q "${veth_mac[3]} > ff:ff:ff:ff:ff:ff" ${LOG_DIR}/mac_ns1-3_${mode}.log && \ 120d2329247SHangbin Liu test_pass "$mode mac ns1-3" || test_fail "$mode mac ns1-3" 121d2329247SHangbin Liu} 122d2329247SHangbin Liu 123d2329247SHangbin Liudo_ping_tests() 124d2329247SHangbin Liu{ 125d2329247SHangbin Liu local mode=$1 126d2329247SHangbin Liu 127d2329247SHangbin Liu # ping6 test: echo request should be redirect back to itself, not others 128cec74489SHangbin Liu ip netns exec ${NS[1]} ip neigh add 2001:db8::2 dev veth0 lladdr 00:00:00:00:00:02 129d2329247SHangbin Liu 130cec74489SHangbin Liu ip netns exec ${NS[1]} tcpdump -i veth0 -nn -l -e &> ${LOG_DIR}/ns1-1_${mode}.log & 131cec74489SHangbin Liu ip netns exec ${NS[2]} tcpdump -i veth0 -nn -l -e &> ${LOG_DIR}/ns1-2_${mode}.log & 132cec74489SHangbin Liu ip netns exec ${NS[3]} tcpdump -i veth0 -nn -l -e &> ${LOG_DIR}/ns1-3_${mode}.log & 133d2329247SHangbin Liu sleep 0.5 134d2329247SHangbin Liu # ARP test 135cec74489SHangbin Liu ip netns exec ${NS[1]} arping -q -c 2 -I veth0 192.0.2.254 136d2329247SHangbin Liu # IPv4 test 137cec74489SHangbin Liu ip netns exec ${NS[1]} ping 192.0.2.253 -i 0.1 -c 4 &> /dev/null 138d2329247SHangbin Liu # IPv6 test 139cec74489SHangbin Liu ip netns exec ${NS[1]} ping6 2001:db8::2 -i 0.1 -c 2 &> /dev/null 140d2329247SHangbin Liu sleep 0.5 141648c3677SHangbin Liu pkill tcpdump 142d2329247SHangbin Liu 143d2329247SHangbin Liu # All netns should receive the redirect arp requests 144f53ea9dbSHangbin Liu [ $(grep -cF "who-has 192.0.2.254" ${LOG_DIR}/ns1-1_${mode}.log) -eq 4 ] && \ 145d2329247SHangbin Liu test_pass "$mode arp(F_BROADCAST) ns1-1" || \ 146d2329247SHangbin Liu test_fail "$mode arp(F_BROADCAST) ns1-1" 147f53ea9dbSHangbin Liu [ $(grep -cF "who-has 192.0.2.254" ${LOG_DIR}/ns1-2_${mode}.log) -eq 2 ] && \ 148d2329247SHangbin Liu test_pass "$mode arp(F_BROADCAST) ns1-2" || \ 149d2329247SHangbin Liu test_fail "$mode arp(F_BROADCAST) ns1-2" 150f53ea9dbSHangbin Liu [ $(grep -cF "who-has 192.0.2.254" ${LOG_DIR}/ns1-3_${mode}.log) -eq 2 ] && \ 151d2329247SHangbin Liu test_pass "$mode arp(F_BROADCAST) ns1-3" || \ 152d2329247SHangbin Liu test_fail "$mode arp(F_BROADCAST) ns1-3" 153d2329247SHangbin Liu 154d2329247SHangbin Liu # ns1 should not receive the redirect echo request, others should 1558b4ac13aSHangbin Liu [ $(grep -c "ICMP echo request" ${LOG_DIR}/ns1-1_${mode}.log) -eq 4 ] && \ 156d2329247SHangbin Liu test_pass "$mode IPv4 (F_BROADCAST|F_EXCLUDE_INGRESS) ns1-1" || \ 157d2329247SHangbin Liu test_fail "$mode IPv4 (F_BROADCAST|F_EXCLUDE_INGRESS) ns1-1" 1588b4ac13aSHangbin Liu [ $(grep -c "ICMP echo request" ${LOG_DIR}/ns1-2_${mode}.log) -eq 4 ] && \ 159d2329247SHangbin Liu test_pass "$mode IPv4 (F_BROADCAST|F_EXCLUDE_INGRESS) ns1-2" || \ 160d2329247SHangbin Liu test_fail "$mode IPv4 (F_BROADCAST|F_EXCLUDE_INGRESS) ns1-2" 1618b4ac13aSHangbin Liu [ $(grep -c "ICMP echo request" ${LOG_DIR}/ns1-3_${mode}.log) -eq 4 ] && \ 162d2329247SHangbin Liu test_pass "$mode IPv4 (F_BROADCAST|F_EXCLUDE_INGRESS) ns1-3" || \ 163d2329247SHangbin Liu test_fail "$mode IPv4 (F_BROADCAST|F_EXCLUDE_INGRESS) ns1-3" 164d2329247SHangbin Liu 165d2329247SHangbin Liu # ns1 should receive the echo request, ns2 should not 1668b4ac13aSHangbin Liu [ $(grep -c "ICMP6, echo request" ${LOG_DIR}/ns1-1_${mode}.log) -eq 4 ] && \ 167d2329247SHangbin Liu test_pass "$mode IPv6 (no flags) ns1-1" || \ 168d2329247SHangbin Liu test_fail "$mode IPv6 (no flags) ns1-1" 1698b4ac13aSHangbin Liu [ $(grep -c "ICMP6, echo request" ${LOG_DIR}/ns1-2_${mode}.log) -eq 0 ] && \ 170d2329247SHangbin Liu test_pass "$mode IPv6 (no flags) ns1-2" || \ 171d2329247SHangbin Liu test_fail "$mode IPv6 (no flags) ns1-2" 172d2329247SHangbin Liu} 173d2329247SHangbin Liu 174d2329247SHangbin Liudo_tests() 175d2329247SHangbin Liu{ 176d2329247SHangbin Liu local mode=$1 177d2329247SHangbin Liu local drv_p 178d2329247SHangbin Liu 179d2329247SHangbin Liu case ${mode} in 180d2329247SHangbin Liu xdpdrv) drv_p="-N";; 181d2329247SHangbin Liu xdpegress) drv_p="-X";; 182d2329247SHangbin Liu xdpgeneric) drv_p="-S";; 183d2329247SHangbin Liu esac 184d2329247SHangbin Liu 185cec74489SHangbin Liu ip netns exec ${NS[0]} ./xdp_redirect_multi $drv_p $IFACES &> ${LOG_DIR}/xdp_redirect_${mode}.log & 186d2329247SHangbin Liu xdp_pid=$! 187d2329247SHangbin Liu sleep 1 1888955c1a3SHangbin Liu if ! ps -p $xdp_pid > /dev/null; then 1898955c1a3SHangbin Liu test_fail "$mode xdp_redirect_multi start failed" 1908955c1a3SHangbin Liu return 1 1918955c1a3SHangbin Liu fi 192d2329247SHangbin Liu 193d2329247SHangbin Liu if [ "$mode" = "xdpegress" ]; then 194d2329247SHangbin Liu do_egress_tests $mode 195d2329247SHangbin Liu else 196d2329247SHangbin Liu do_ping_tests $mode 197d2329247SHangbin Liu fi 198d2329247SHangbin Liu 199d2329247SHangbin Liu kill $xdp_pid 200d2329247SHangbin Liu} 201d2329247SHangbin Liu 202d2329247SHangbin Liucheck_env 203d2329247SHangbin Liu 204cec74489SHangbin Liutrap clean_up EXIT 205cec74489SHangbin Liu 206d2329247SHangbin Liufor mode in ${DRV_MODE}; do 207d2329247SHangbin Liu setup_ns $mode 208d2329247SHangbin Liu do_tests $mode 209d2329247SHangbin Liu clean_up 210d2329247SHangbin Liudone 2118b4ac13aSHangbin Liurm -rf ${LOG_DIR} 212d2329247SHangbin Liu 213d2329247SHangbin Liuecho "Summary: PASS $PASS, FAIL $FAIL" 214d2329247SHangbin Liu[ $FAIL -eq 0 ] && exit 0 || exit 1 215