Loading...
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.
6readonly KSFT_SKIP=4
7readonly NS1="ns1-$(mktemp -u XXXXXX)"
8readonly NS2="ns2-$(mktemp -u XXXXXX)"
9
10# Allow wrapper scripts to name test
11if [ -z "$TESTNAME" ]; then
12 TESTNAME=xdp_vlan
13fi
14
15# Default XDP mode
16XDP_MODE=xdpgeneric
17
18usage() {
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
29valid_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
42cleanup()
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
66OPTIONS=$(getopt -o hvfi: \
67 --long verbose,flush,help,interactive,debug,mode: -- "$@")
68if (( $? != 0 )); then
69 usage
70 echo "selftests: $TESTNAME [FAILED] Error calling getopt, unknown option?"
71 exit 2
72fi
73eval set -- "$OPTIONS"
74
75## --- Parse command line arguments / parameters ---
76while 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
109done
110
111if [ "$EUID" -ne 0 ]; then
112 echo "selftests: $TESTNAME [FAILED] need root privileges"
113 exit 1
114fi
115
116valid_xdp_mode $XDP_MODE
117if [ $? -ne 0 ]; then
118 echo "selftests: $TESTNAME [FAILED] unknown XDP mode ($XDP_MODE)"
119 exit 1
120fi
121
122ip link set dev lo xdpgeneric off 2>/dev/null > /dev/null
123if [ $? -ne 0 ]; then
124 echo "selftests: $TESTNAME [SKIP] need ip xdp support"
125 exit $KSFT_SKIP
126fi
127
128# Interactive mode likely require us to cleanup netns
129if [ -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
133fi
134
135# Exit on failure
136set -e
137
138# Some shell-tools dependencies
139which ip > /dev/null
140which tc > /dev/null
141which ethtool > /dev/null
142
143# Make rest of shell verbose, showing comments as doc/info
144if [ -n "$VERBOSE" ]; then
145 set -v
146fi
147
148# Create two namespaces
149ip netns add ${NS1}
150ip netns add ${NS2}
151
152# Run cleanup if failing or on kill
153trap cleanup 0 2 3 6 9
154
155# Create veth pair
156ip link add veth1 type veth peer name veth2
157
158# Move veth1 and veth2 into the respective namespaces
159ip link set veth1 netns ${NS1}
160ip 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)
167ip netns exec ${NS1} ethtool -K veth1 rxvlan off
168ip netns exec ${NS2} ethtool -K veth2 rxvlan off
169#
170# Disable tx-vlan-offload (mostly needed on ns2)
171ip netns exec ${NS2} ethtool -K veth2 txvlan off
172ip netns exec ${NS1} ethtool -K veth1 txvlan off
173
174export IPADDR1=100.64.41.1
175export IPADDR2=100.64.41.2
176
177# In ns1/veth1 add IP-addr on plain net_device
178ip netns exec ${NS1} ip addr add ${IPADDR1}/24 dev veth1
179ip netns exec ${NS1} ip link set veth1 up
180
181# In ns2/veth2 create VLAN device
182export VLAN=4011
183export DEVNS2=veth2
184ip netns exec ${NS2} ip link add link $DEVNS2 name $DEVNS2.$VLAN type vlan id $VLAN
185ip netns exec ${NS2} ip addr add ${IPADDR2}/24 dev $DEVNS2.$VLAN
186ip netns exec ${NS2} ip link set $DEVNS2 up
187ip netns exec ${NS2} ip link set $DEVNS2.$VLAN up
188
189# Bringup lo in netns (to avoids confusing people using --interactive)
190ip netns exec ${NS1} ip link set lo up
191ip 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
196ip 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
202export DEVNS1=veth1
203export BPF_FILE=test_xdp_vlan.bpf.o
204
205# First test: Remove VLAN by setting VLAN ID 0, using "xdp_vlan_change"
206export XDP_PROG=xdp_vlan_change
207ip 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#
213ip netns exec ${NS1} tc qdisc add dev $DEVNS1 clsact
214ip 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:
218ip netns exec ${NS2} ping -i 0.2 -W 2 -c 2 $IPADDR1
219ip 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#
227export XDP_PROG=xdp_vlan_remove_outer2
228ip netns exec ${NS1} ip link set $DEVNS1 $XDP_MODE off
229ip 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:
232ip netns exec ${NS2} ping -i 0.2 -W 2 -c 2 $IPADDR1
233ip netns exec ${NS1} ping -i 0.2 -W 2 -c 2 $IPADDR2
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.
6readonly KSFT_SKIP=4
7readonly NS1="ns1-$(mktemp -u XXXXXX)"
8readonly NS2="ns2-$(mktemp -u XXXXXX)"
9
10# Allow wrapper scripts to name test
11if [ -z "$TESTNAME" ]; then
12 TESTNAME=xdp_vlan
13fi
14
15# Default XDP mode
16XDP_MODE=xdpgeneric
17
18usage() {
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
29valid_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
42cleanup()
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
66OPTIONS=$(getopt -o hvfi: \
67 --long verbose,flush,help,interactive,debug,mode: -- "$@")
68if (( $? != 0 )); then
69 usage
70 echo "selftests: $TESTNAME [FAILED] Error calling getopt, unknown option?"
71 exit 2
72fi
73eval set -- "$OPTIONS"
74
75## --- Parse command line arguments / parameters ---
76while 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
109done
110
111if [ "$EUID" -ne 0 ]; then
112 echo "selftests: $TESTNAME [FAILED] need root privileges"
113 exit 1
114fi
115
116valid_xdp_mode $XDP_MODE
117if [ $? -ne 0 ]; then
118 echo "selftests: $TESTNAME [FAILED] unknown XDP mode ($XDP_MODE)"
119 exit 1
120fi
121
122ip link set dev lo xdpgeneric off 2>/dev/null > /dev/null
123if [ $? -ne 0 ]; then
124 echo "selftests: $TESTNAME [SKIP] need ip xdp support"
125 exit $KSFT_SKIP
126fi
127
128# Interactive mode likely require us to cleanup netns
129if [ -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
133fi
134
135# Exit on failure
136set -e
137
138# Some shell-tools dependencies
139which ip > /dev/null
140which tc > /dev/null
141which ethtool > /dev/null
142
143# Make rest of shell verbose, showing comments as doc/info
144if [ -n "$VERBOSE" ]; then
145 set -v
146fi
147
148# Create two namespaces
149ip netns add ${NS1}
150ip netns add ${NS2}
151
152# Run cleanup if failing or on kill
153trap cleanup 0 2 3 6 9
154
155# Create veth pair
156ip link add veth1 type veth peer name veth2
157
158# Move veth1 and veth2 into the respective namespaces
159ip link set veth1 netns ${NS1}
160ip 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)
167ip netns exec ${NS1} ethtool -K veth1 rxvlan off
168ip netns exec ${NS2} ethtool -K veth2 rxvlan off
169#
170# Disable tx-vlan-offload (mostly needed on ns2)
171ip netns exec ${NS2} ethtool -K veth2 txvlan off
172ip netns exec ${NS1} ethtool -K veth1 txvlan off
173
174export IPADDR1=100.64.41.1
175export IPADDR2=100.64.41.2
176
177# In ns1/veth1 add IP-addr on plain net_device
178ip netns exec ${NS1} ip addr add ${IPADDR1}/24 dev veth1
179ip netns exec ${NS1} ip link set veth1 up
180
181# In ns2/veth2 create VLAN device
182export VLAN=4011
183export DEVNS2=veth2
184ip netns exec ${NS2} ip link add link $DEVNS2 name $DEVNS2.$VLAN type vlan id $VLAN
185ip netns exec ${NS2} ip addr add ${IPADDR2}/24 dev $DEVNS2.$VLAN
186ip netns exec ${NS2} ip link set $DEVNS2 up
187ip netns exec ${NS2} ip link set $DEVNS2.$VLAN up
188
189# Bringup lo in netns (to avoids confusing people using --interactive)
190ip netns exec ${NS1} ip link set lo up
191ip 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
196ip 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
202export DEVNS1=veth1
203export BPF_FILE=test_xdp_vlan.bpf.o
204
205# First test: Remove VLAN by setting VLAN ID 0, using "xdp_vlan_change"
206export XDP_PROG=xdp_vlan_change
207ip 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#
213ip netns exec ${NS1} tc qdisc add dev $DEVNS1 clsact
214ip 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:
218ip netns exec ${NS2} ping -i 0.2 -W 2 -c 2 $IPADDR1
219ip 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#
227export XDP_PROG=xdp_vlan_remove_outer2
228ip netns exec ${NS1} ip link set $DEVNS1 $XDP_MODE off
229ip 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:
232ip netns exec ${NS2} ping -i 0.2 -W 2 -c 2 $IPADDR1
233ip netns exec ${NS1} ping -i 0.2 -W 2 -c 2 $IPADDR2