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