1 #!/bin/bash 2 # SPDX-License-Identifier: GPL-2.0 3 # Author: Jesper Dangaard Brouer <hawk@kernel.org> 4 5 # Kselftest framework requirement - SKIP code is 4. 6 readonly KSFT_SKIP=4 7 readonly NS1="ns1-$(mktemp -u XXXXXX)" 8 readonly NS2="ns2-$(mktemp -u XXXXXX)" 9 10 # Allow wrapper scripts to name test 11 if [ -z "$TESTNAME" ]; then 12 TESTNAME=xdp_vlan 13 fi 14 15 # Default XDP mode 16 XDP_MODE=xdpgeneric 17 18 usage() { 19 echo "Testing XDP + TC eBPF VLAN manipulations: $TESTNAME" 20 echo "" 21 echo "Usage: $0 [-vfh]" 22 echo " -v | --verbose : Verbose" 23 echo " --flush : Flush before starting (e.g. after --interactive)" 24 echo " --interactive : Keep netns setup running after test-run" 25 echo " --mode=XXX : Choose XDP mode (xdp | xdpgeneric | xdpdrv)" 26 echo "" 27 } 28 29 valid_xdp_mode() 30 { 31 local mode=$1 32 33 case "$mode" in 34 xdpgeneric | xdpdrv | xdp) 35 return 0 36 ;; 37 *) 38 return 1 39 esac 40 } 41 42 cleanup() 43 { 44 local status=$? 45 46 if [ "$status" = "0" ]; then 47 echo "selftests: $TESTNAME [PASS]"; 48 else 49 echo "selftests: $TESTNAME [FAILED]"; 50 fi 51 52 if [ -n "$INTERACTIVE" ]; then 53 echo "Namespace setup still active explore with:" 54 echo " ip netns exec ${NS1} bash" 55 echo " ip netns exec ${NS2} bash" 56 exit $status 57 fi 58 59 set +e 60 ip link del veth1 2> /dev/null 61 ip netns del ${NS1} 2> /dev/null 62 ip netns del ${NS2} 2> /dev/null 63 } 64 65 # Using external program "getopt" to get --long-options 66 OPTIONS=$(getopt -o hvfi: \ 67 --long verbose,flush,help,interactive,debug,mode: -- "$@") 68 if (( $? != 0 )); then 69 usage 70 echo "selftests: $TESTNAME [FAILED] Error calling getopt, unknown option?" 71 exit 2 72 fi 73 eval set -- "$OPTIONS" 74 75 ## --- Parse command line arguments / parameters --- 76 while true; do 77 case "$1" in 78 -v | --verbose) 79 export VERBOSE=yes 80 shift 81 ;; 82 -i | --interactive | --debug ) 83 INTERACTIVE=yes 84 shift 85 ;; 86 -f | --flush ) 87 cleanup 88 shift 89 ;; 90 --mode ) 91 shift 92 XDP_MODE=$1 93 shift 94 ;; 95 -- ) 96 shift 97 break 98 ;; 99 -h | --help ) 100 usage; 101 echo "selftests: $TESTNAME [SKIP] usage help info requested" 102 exit $KSFT_SKIP 103 ;; 104 * ) 105 shift 106 break 107 ;; 108 esac 109 done 110 111 if [ "$EUID" -ne 0 ]; then 112 echo "selftests: $TESTNAME [FAILED] need root privileges" 113 exit 1 114 fi 115 116 valid_xdp_mode $XDP_MODE 117 if [ $? -ne 0 ]; then 118 echo "selftests: $TESTNAME [FAILED] unknown XDP mode ($XDP_MODE)" 119 exit 1 120 fi 121 122 ip link set dev lo xdpgeneric off 2>/dev/null > /dev/null 123 if [ $? -ne 0 ]; then 124 echo "selftests: $TESTNAME [SKIP] need ip xdp support" 125 exit $KSFT_SKIP 126 fi 127 128 # Interactive mode likely require us to cleanup netns 129 if [ -n "$INTERACTIVE" ]; then 130 ip link del veth1 2> /dev/null 131 ip netns del ${NS1} 2> /dev/null 132 ip netns del ${NS2} 2> /dev/null 133 fi 134 135 # Exit on failure 136 set -e 137 138 # Some shell-tools dependencies 139 which ip > /dev/null 140 which tc > /dev/null 141 which ethtool > /dev/null 142 143 # Make rest of shell verbose, showing comments as doc/info 144 if [ -n "$VERBOSE" ]; then 145 set -v 146 fi 147 148 # Create two namespaces 149 ip netns add ${NS1} 150 ip netns add ${NS2} 151 152 # Run cleanup if failing or on kill 153 trap cleanup 0 2 3 6 9 154 155 # Create veth pair 156 ip link add veth1 type veth peer name veth2 157 158 # Move veth1 and veth2 into the respective namespaces 159 ip link set veth1 netns ${NS1} 160 ip link set veth2 netns ${NS2} 161 162 # NOTICE: XDP require VLAN header inside packet payload 163 # - Thus, disable VLAN offloading driver features 164 # - For veth REMEMBER TX side VLAN-offload 165 # 166 # Disable rx-vlan-offload (mostly needed on ns1) 167 ip netns exec ${NS1} ethtool -K veth1 rxvlan off 168 ip netns exec ${NS2} ethtool -K veth2 rxvlan off 169 # 170 # Disable tx-vlan-offload (mostly needed on ns2) 171 ip netns exec ${NS2} ethtool -K veth2 txvlan off 172 ip netns exec ${NS1} ethtool -K veth1 txvlan off 173 174 export IPADDR1=100.64.41.1 175 export IPADDR2=100.64.41.2 176 177 # In ns1/veth1 add IP-addr on plain net_device 178 ip netns exec ${NS1} ip addr add ${IPADDR1}/24 dev veth1 179 ip netns exec ${NS1} ip link set veth1 up 180 181 # In ns2/veth2 create VLAN device 182 export VLAN=4011 183 export DEVNS2=veth2 184 ip netns exec ${NS2} ip link add link $DEVNS2 name $DEVNS2.$VLAN type vlan id $VLAN 185 ip netns exec ${NS2} ip addr add ${IPADDR2}/24 dev $DEVNS2.$VLAN 186 ip netns exec ${NS2} ip link set $DEVNS2 up 187 ip netns exec ${NS2} ip link set $DEVNS2.$VLAN up 188 189 # Bringup lo in netns (to avoids confusing people using --interactive) 190 ip netns exec ${NS1} ip link set lo up 191 ip netns exec ${NS2} ip link set lo up 192 193 # At this point, the hosts cannot reach each-other, 194 # because ns2 are using VLAN tags on the packets. 195 196 ip netns exec ${NS2} sh -c 'ping -W 1 -c 1 100.64.41.1 || echo "Success: First ping must fail"' 197 198 199 # Now we can use the test_xdp_vlan.c program to pop/push these VLAN tags 200 # ---------------------------------------------------------------------- 201 # In ns1: ingress use XDP to remove VLAN tags 202 export DEVNS1=veth1 203 export BPF_FILE=test_xdp_vlan.bpf.o 204 205 # First test: Remove VLAN by setting VLAN ID 0, using "xdp_vlan_change" 206 export XDP_PROG=xdp_vlan_change 207 ip netns exec ${NS1} ip link set $DEVNS1 $XDP_MODE object $BPF_FILE section $XDP_PROG 208 209 # In ns1: egress use TC to add back VLAN tag 4011 210 # (del cmd) 211 # tc qdisc del dev $DEVNS1 clsact 2> /dev/null 212 # 213 ip netns exec ${NS1} tc qdisc add dev $DEVNS1 clsact 214 ip netns exec ${NS1} tc filter add dev $DEVNS1 egress \ 215 prio 1 handle 1 bpf da obj $BPF_FILE sec tc_vlan_push 216 217 # Now the namespaces can reach each-other, test with ping: 218 ip netns exec ${NS2} ping -i 0.2 -W 2 -c 2 $IPADDR1 219 ip netns exec ${NS1} ping -i 0.2 -W 2 -c 2 $IPADDR2 220 221 # Second test: Replace xdp prog, that fully remove vlan header 222 # 223 # Catch kernel bug for generic-XDP, that does didn't allow us to 224 # remove a VLAN header, because skb->protocol still contain VLAN 225 # ETH_P_8021Q indication, and this cause overwriting of our changes. 226 # 227 export XDP_PROG=xdp_vlan_remove_outer2 228 ip netns exec ${NS1} ip link set $DEVNS1 $XDP_MODE off 229 ip netns exec ${NS1} ip link set $DEVNS1 $XDP_MODE object $BPF_FILE section $XDP_PROG 230 231 # Now the namespaces should still be able reach each-other, test with ping: 232 ip netns exec ${NS2} ping -i 0.2 -W 2 -c 2 $IPADDR1 233 ip netns exec ${NS1} ping -i 0.2 -W 2 -c 2 $IPADDR2
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.