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