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