~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/tools/testing/selftests/bpf/test_tc_tunnel.sh

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 #!/bin/bash
  2 # SPDX-License-Identifier: GPL-2.0
  3 #
  4 # In-place tunneling
  5 
  6 BPF_FILE="test_tc_tunnel.bpf.o"
  7 # must match the port that the bpf program filters on
  8 readonly port=8000
  9 
 10 readonly ns_prefix="ns-$$-"
 11 readonly ns1="${ns_prefix}1"
 12 readonly ns2="${ns_prefix}2"
 13 
 14 readonly ns1_v4=192.168.1.1
 15 readonly ns2_v4=192.168.1.2
 16 readonly ns1_v6=fd::1
 17 readonly ns2_v6=fd::2
 18 
 19 # Must match port used by bpf program
 20 readonly udpport=5555
 21 # MPLSoverUDP
 22 readonly mplsudpport=6635
 23 readonly mplsproto=137
 24 
 25 readonly infile="$(mktemp)"
 26 readonly outfile="$(mktemp)"
 27 
 28 setup() {
 29         ip netns add "${ns1}"
 30         ip netns add "${ns2}"
 31 
 32         ip link add dev veth1 mtu 1500 netns "${ns1}" type veth \
 33               peer name veth2 mtu 1500 netns "${ns2}"
 34 
 35         ip netns exec "${ns1}" ethtool -K veth1 tso off
 36 
 37         ip -netns "${ns1}" link set veth1 up
 38         ip -netns "${ns2}" link set veth2 up
 39 
 40         ip -netns "${ns1}" -4 addr add "${ns1_v4}/24" dev veth1
 41         ip -netns "${ns2}" -4 addr add "${ns2_v4}/24" dev veth2
 42         ip -netns "${ns1}" -6 addr add "${ns1_v6}/64" dev veth1 nodad
 43         ip -netns "${ns2}" -6 addr add "${ns2_v6}/64" dev veth2 nodad
 44 
 45         # clamp route to reserve room for tunnel headers
 46         ip -netns "${ns1}" -4 route flush table main
 47         ip -netns "${ns1}" -6 route flush table main
 48         ip -netns "${ns1}" -4 route add "${ns2_v4}" mtu 1450 dev veth1
 49         ip -netns "${ns1}" -6 route add "${ns2_v6}" mtu 1430 dev veth1
 50 
 51         sleep 1
 52 
 53         dd if=/dev/urandom of="${infile}" bs="${datalen}" count=1 status=none
 54 }
 55 
 56 cleanup() {
 57         ip netns del "${ns2}"
 58         ip netns del "${ns1}"
 59 
 60         if [[ -f "${outfile}" ]]; then
 61                 rm "${outfile}"
 62         fi
 63         if [[ -f "${infile}" ]]; then
 64                 rm "${infile}"
 65         fi
 66 
 67         if [[ -n $server_pid ]]; then
 68                 kill $server_pid 2> /dev/null
 69         fi
 70 }
 71 
 72 server_listen() {
 73         ip netns exec "${ns2}" nc "${netcat_opt}" -l "${port}" > "${outfile}" &
 74         server_pid=$!
 75 }
 76 
 77 client_connect() {
 78         ip netns exec "${ns1}" timeout 2 nc "${netcat_opt}" -w 1 "${addr2}" "${port}" < "${infile}"
 79         echo $?
 80 }
 81 
 82 verify_data() {
 83         wait "${server_pid}"
 84         server_pid=
 85         # sha1sum returns two fields [sha1] [filepath]
 86         # convert to bash array and access first elem
 87         insum=($(sha1sum ${infile}))
 88         outsum=($(sha1sum ${outfile}))
 89         if [[ "${insum[0]}" != "${outsum[0]}" ]]; then
 90                 echo "data mismatch"
 91                 exit 1
 92         fi
 93 }
 94 
 95 wait_for_port() {
 96         for i in $(seq 20); do
 97                 if ip netns exec "${ns2}" ss ${2:--4}OHntl | grep -q "$1"; then
 98                         return 0
 99                 fi
100                 sleep 0.1
101         done
102         return 1
103 }
104 
105 set -e
106 
107 # no arguments: automated test, run all
108 if [[ "$#" -eq "0" ]]; then
109         echo "ipip"
110         $0 ipv4 ipip none 100
111 
112         echo "ipip6"
113         $0 ipv4 ipip6 none 100
114 
115         echo "ip6ip6"
116         $0 ipv6 ip6tnl none 100
117 
118         echo "sit"
119         $0 ipv6 sit none 100
120 
121         echo "ip4 vxlan"
122         $0 ipv4 vxlan eth 2000
123 
124         echo "ip6 vxlan"
125         $0 ipv6 ip6vxlan eth 2000
126 
127         for mac in none mpls eth ; do
128                 echo "ip gre $mac"
129                 $0 ipv4 gre $mac 100
130 
131                 echo "ip6 gre $mac"
132                 $0 ipv6 ip6gre $mac 100
133 
134                 echo "ip gre $mac gso"
135                 $0 ipv4 gre $mac 2000
136 
137                 echo "ip6 gre $mac gso"
138                 $0 ipv6 ip6gre $mac 2000
139 
140                 echo "ip udp $mac"
141                 $0 ipv4 udp $mac 100
142 
143                 echo "ip6 udp $mac"
144                 $0 ipv6 ip6udp $mac 100
145 
146                 echo "ip udp $mac gso"
147                 $0 ipv4 udp $mac 2000
148 
149                 echo "ip6 udp $mac gso"
150                 $0 ipv6 ip6udp $mac 2000
151         done
152 
153         echo "OK. All tests passed"
154         exit 0
155 fi
156 
157 if [[ "$#" -ne "4" ]]; then
158         echo "Usage: $0"
159         echo "   or: $0 <ipv4|ipv6> <tuntype> <none|mpls|eth> <data_len>"
160         exit 1
161 fi
162 
163 case "$1" in
164 "ipv4")
165         readonly addr1="${ns1_v4}"
166         readonly addr2="${ns2_v4}"
167         readonly ipproto=4
168         readonly netcat_opt=-${ipproto}
169         readonly foumod=fou
170         readonly foutype=ipip
171         readonly fouproto=4
172         readonly fouproto_mpls=${mplsproto}
173         readonly gretaptype=gretap
174         ;;
175 "ipv6")
176         readonly addr1="${ns1_v6}"
177         readonly addr2="${ns2_v6}"
178         readonly ipproto=6
179         readonly netcat_opt=-${ipproto}
180         readonly foumod=fou6
181         readonly foutype=ip6tnl
182         readonly fouproto="41 -6"
183         readonly fouproto_mpls="${mplsproto} -6"
184         readonly gretaptype=ip6gretap
185         ;;
186 *)
187         echo "unknown arg: $1"
188         exit 1
189         ;;
190 esac
191 
192 readonly tuntype=$2
193 readonly mac=$3
194 readonly datalen=$4
195 
196 echo "encap ${addr1} to ${addr2}, type ${tuntype}, mac ${mac} len ${datalen}"
197 
198 trap cleanup EXIT
199 
200 setup
201 
202 # basic communication works
203 echo "test basic connectivity"
204 server_listen
205 wait_for_port ${port} ${netcat_opt}
206 client_connect
207 verify_data
208 
209 # clientside, insert bpf program to encap all TCP to port ${port}
210 # client can no longer connect
211 ip netns exec "${ns1}" tc qdisc add dev veth1 clsact
212 ip netns exec "${ns1}" tc filter add dev veth1 egress \
213         bpf direct-action object-file ${BPF_FILE} \
214         section "encap_${tuntype}_${mac}"
215 echo "test bpf encap without decap (expect failure)"
216 server_listen
217 wait_for_port ${port} ${netcat_opt}
218 ! client_connect
219 
220 if [[ "$tuntype" =~ "udp" ]]; then
221         # Set up fou tunnel.
222         ttype="${foutype}"
223         targs="encap fou encap-sport auto encap-dport $udpport"
224         # fou may be a module; allow this to fail.
225         modprobe "${foumod}" ||true
226         if [[ "$mac" == "mpls" ]]; then
227                 dport=${mplsudpport}
228                 dproto=${fouproto_mpls}
229                 tmode="mode any ttl 255"
230         else
231                 dport=${udpport}
232                 dproto=${fouproto}
233         fi
234         ip netns exec "${ns2}" ip fou add port $dport ipproto ${dproto}
235         targs="encap fou encap-sport auto encap-dport $dport"
236 elif [[ "$tuntype" =~ "gre" && "$mac" == "eth" ]]; then
237         ttype=$gretaptype
238 elif [[ "$tuntype" =~ "vxlan" && "$mac" == "eth" ]]; then
239         ttype="vxlan"
240         targs="id 1 dstport 8472 udp6zerocsumrx"
241 elif [[ "$tuntype" == "ipip6" ]]; then
242         ttype="ip6tnl"
243         targs=""
244 else
245         ttype=$tuntype
246         targs=""
247 fi
248 
249 # tunnel address family differs from inner for SIT
250 if [[ "${tuntype}" == "sit" ]]; then
251         link_addr1="${ns1_v4}"
252         link_addr2="${ns2_v4}"
253 elif [[ "${tuntype}" == "ipip6" ]]; then
254         link_addr1="${ns1_v6}"
255         link_addr2="${ns2_v6}"
256 else
257         link_addr1="${addr1}"
258         link_addr2="${addr2}"
259 fi
260 
261 # serverside, insert decap module
262 # server is still running
263 # client can connect again
264 ip netns exec "${ns2}" ip link add name testtun0 type "${ttype}" \
265         ${tmode} remote "${link_addr1}" local "${link_addr2}" $targs
266 
267 expect_tun_fail=0
268 
269 if [[ "$tuntype" == "ip6udp" && "$mac" == "mpls" ]]; then
270         # No support for MPLS IPv6 fou tunnel; expect failure.
271         expect_tun_fail=1
272 elif [[ "$tuntype" =~ "udp" && "$mac" == "eth" ]]; then
273         # No support for TEB fou tunnel; expect failure.
274         expect_tun_fail=1
275 elif [[ "$tuntype" =~ (gre|vxlan) && "$mac" == "eth" ]]; then
276         # Share ethernet address between tunnel/veth2 so L2 decap works.
277         ethaddr=$(ip netns exec "${ns2}" ip link show veth2 | \
278                   awk '/ether/ { print $2 }')
279         ip netns exec "${ns2}" ip link set testtun0 address $ethaddr
280 elif [[ "$mac" == "mpls" ]]; then
281         modprobe mpls_iptunnel ||true
282         modprobe mpls_gso ||true
283         ip netns exec "${ns2}" sysctl -qw net.mpls.platform_labels=65536
284         ip netns exec "${ns2}" ip -f mpls route add 1000 dev lo
285         ip netns exec "${ns2}" ip link set lo up
286         ip netns exec "${ns2}" sysctl -qw net.mpls.conf.testtun0.input=1
287         ip netns exec "${ns2}" sysctl -qw net.ipv4.conf.lo.rp_filter=0
288 fi
289 
290 # Because packets are decapped by the tunnel they arrive on testtun0 from
291 # the IP stack perspective.  Ensure reverse path filtering is disabled
292 # otherwise we drop the TCP SYN as arriving on testtun0 instead of the
293 # expected veth2 (veth2 is where 192.168.1.2 is configured).
294 ip netns exec "${ns2}" sysctl -qw net.ipv4.conf.all.rp_filter=0
295 # rp needs to be disabled for both all and testtun0 as the rp value is
296 # selected as the max of the "all" and device-specific values.
297 ip netns exec "${ns2}" sysctl -qw net.ipv4.conf.testtun0.rp_filter=0
298 ip netns exec "${ns2}" ip link set dev testtun0 up
299 if [[ "$expect_tun_fail" == 1 ]]; then
300         # This tunnel mode is not supported, so we expect failure.
301         echo "test bpf encap with tunnel device decap (expect failure)"
302         ! client_connect
303 else
304         echo "test bpf encap with tunnel device decap"
305         client_connect
306         verify_data
307         server_listen
308 fi
309 
310 # serverside, use BPF for decap
311 ip netns exec "${ns2}" ip link del dev testtun0
312 ip netns exec "${ns2}" tc qdisc add dev veth2 clsact
313 ip netns exec "${ns2}" tc filter add dev veth2 ingress \
314         bpf direct-action object-file ${BPF_FILE} section decap
315 echo "test bpf encap with bpf decap"
316 client_connect
317 verify_data
318 
319 echo OK

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php