xref: /openbmc/linux/tools/testing/selftests/net/bareudp.sh (revision bbbc7aa45eefd4ef7ffbd5ee3bb49bd8b68a2213)
1*bbbc7aa4SGuillaume Nault#!/bin/sh
2*bbbc7aa4SGuillaume Nault# SPDX-License-Identifier: GPL-2.0
3*bbbc7aa4SGuillaume Nault
4*bbbc7aa4SGuillaume Nault# Test various bareudp tunnel configurations.
5*bbbc7aa4SGuillaume Nault#
6*bbbc7aa4SGuillaume Nault# The bareudp module allows to tunnel network protocols like IP or MPLS over
7*bbbc7aa4SGuillaume Nault# UDP, without adding any intermediate header. This scripts tests several
8*bbbc7aa4SGuillaume Nault# configurations of bareudp (using IPv4 or IPv6 as underlay and transporting
9*bbbc7aa4SGuillaume Nault# IPv4, IPv6 or MPLS packets on the overlay).
10*bbbc7aa4SGuillaume Nault#
11*bbbc7aa4SGuillaume Nault# Network topology:
12*bbbc7aa4SGuillaume Nault#
13*bbbc7aa4SGuillaume Nault#   * A chain of 4 network namespaces, connected with veth pairs. Each veth
14*bbbc7aa4SGuillaume Nault#     is assigned an IPv4 and an IPv6 address. A host-route allows a veth to
15*bbbc7aa4SGuillaume Nault#     join its peer.
16*bbbc7aa4SGuillaume Nault#
17*bbbc7aa4SGuillaume Nault#   * NS0 and NS3 are at the extremities of the chain. They have additional
18*bbbc7aa4SGuillaume Nault#     IPv4 and IPv6 addresses on their loopback device. Routes are added in NS0
19*bbbc7aa4SGuillaume Nault#     and NS3, so that they can communicate using these overlay IP addresses.
20*bbbc7aa4SGuillaume Nault#     For IPv4 and IPv6 reachability tests, the route simply sets the peer's
21*bbbc7aa4SGuillaume Nault#     veth address as gateway. For MPLS reachability tests, an MPLS header is
22*bbbc7aa4SGuillaume Nault#     also pushed before the IP header.
23*bbbc7aa4SGuillaume Nault#
24*bbbc7aa4SGuillaume Nault#   * NS1 and NS2 are the intermediate namespaces. They use a bareudp device to
25*bbbc7aa4SGuillaume Nault#     encapsulate the traffic into UDP.
26*bbbc7aa4SGuillaume Nault#
27*bbbc7aa4SGuillaume Nault# +-----------------------------------------------------------------------+
28*bbbc7aa4SGuillaume Nault# |                                  NS0                                  |
29*bbbc7aa4SGuillaume Nault# |                                                                       |
30*bbbc7aa4SGuillaume Nault# |   lo:                                                                 |
31*bbbc7aa4SGuillaume Nault# |      * IPv4 address: 192.0.2.100/32                                   |
32*bbbc7aa4SGuillaume Nault# |      * IPv6 address: 2001:db8::100/128                                |
33*bbbc7aa4SGuillaume Nault# |      * IPv6 address: 2001:db8::200/128                                |
34*bbbc7aa4SGuillaume Nault# |      * IPv4 route: 192.0.2.103/32 reachable via 192.0.2.11            |
35*bbbc7aa4SGuillaume Nault# |      * IPv6 route: 2001:db8::103/128 reachable via 2001:db8::11       |
36*bbbc7aa4SGuillaume Nault# |      * IPv6 route: 2001:db8::203/128 reachable via 2001:db8::11       |
37*bbbc7aa4SGuillaume Nault# |                    (encapsulated with MPLS label 203)                 |
38*bbbc7aa4SGuillaume Nault# |                                                                       |
39*bbbc7aa4SGuillaume Nault# |   veth01:                                                             |
40*bbbc7aa4SGuillaume Nault# |   ^  * IPv4 address: 192.0.2.10, peer 192.0.2.11/32                   |
41*bbbc7aa4SGuillaume Nault# |   |  * IPv6 address: 2001:db8::10, peer 2001:db8::11/128              |
42*bbbc7aa4SGuillaume Nault# |   |                                                                   |
43*bbbc7aa4SGuillaume Nault# +---+-------------------------------------------------------------------+
44*bbbc7aa4SGuillaume Nault#     |
45*bbbc7aa4SGuillaume Nault#     | Traffic type: IP or MPLS (depending on test)
46*bbbc7aa4SGuillaume Nault#     |
47*bbbc7aa4SGuillaume Nault# +---+-------------------------------------------------------------------+
48*bbbc7aa4SGuillaume Nault# |   |                              NS1                                  |
49*bbbc7aa4SGuillaume Nault# |   |                                                                   |
50*bbbc7aa4SGuillaume Nault# |   v                                                                   |
51*bbbc7aa4SGuillaume Nault# |   veth10:                                                             |
52*bbbc7aa4SGuillaume Nault# |      * IPv4 address: 192.0.2.11, peer 192.0.2.10/32                   |
53*bbbc7aa4SGuillaume Nault# |      * IPv6 address: 2001:db8::11, peer 2001:db8::10/128              |
54*bbbc7aa4SGuillaume Nault# |                                                                       |
55*bbbc7aa4SGuillaume Nault# |   bareudp_ns1:                                                        |
56*bbbc7aa4SGuillaume Nault# |      * Encapsulate IP or MPLS packets received on veth10 into UDP     |
57*bbbc7aa4SGuillaume Nault# |        and send the resulting packets through veth12.                 |
58*bbbc7aa4SGuillaume Nault# |      * Decapsulate bareudp packets (either IP or MPLS, over UDP)      |
59*bbbc7aa4SGuillaume Nault# |        received on veth12 and send the inner packets through veth10.  |
60*bbbc7aa4SGuillaume Nault# |                                                                       |
61*bbbc7aa4SGuillaume Nault# |   veth12:                                                             |
62*bbbc7aa4SGuillaume Nault# |   ^  * IPv4 address: 192.0.2.21, peer 192.0.2.22/32                   |
63*bbbc7aa4SGuillaume Nault# |   |  * IPv6 address: 2001:db8::21, peer 2001:db8::22/128              |
64*bbbc7aa4SGuillaume Nault# |   |                                                                   |
65*bbbc7aa4SGuillaume Nault# +---+-------------------------------------------------------------------+
66*bbbc7aa4SGuillaume Nault#     |
67*bbbc7aa4SGuillaume Nault#     | Traffic type: IP or MPLS (depending on test), over UDP
68*bbbc7aa4SGuillaume Nault#     |
69*bbbc7aa4SGuillaume Nault# +---+-------------------------------------------------------------------+
70*bbbc7aa4SGuillaume Nault# |   |                              NS2                                  |
71*bbbc7aa4SGuillaume Nault# |   |                                                                   |
72*bbbc7aa4SGuillaume Nault# |   v                                                                   |
73*bbbc7aa4SGuillaume Nault# |   veth21:                                                             |
74*bbbc7aa4SGuillaume Nault# |      * IPv4 address: 192.0.2.22, peer 192.0.2.21/32                   |
75*bbbc7aa4SGuillaume Nault# |      * IPv6 address: 2001:db8::22, peer 2001:db8::21/128              |
76*bbbc7aa4SGuillaume Nault# |                                                                       |
77*bbbc7aa4SGuillaume Nault# |   bareudp_ns2:                                                        |
78*bbbc7aa4SGuillaume Nault# |      * Decapsulate bareudp packets (either IP or MPLS, over UDP)      |
79*bbbc7aa4SGuillaume Nault# |        received on veth21 and send the inner packets through veth23.  |
80*bbbc7aa4SGuillaume Nault# |      * Encapsulate IP or MPLS packets received on veth23 into UDP     |
81*bbbc7aa4SGuillaume Nault# |        and send the resulting packets through veth21.                 |
82*bbbc7aa4SGuillaume Nault# |                                                                       |
83*bbbc7aa4SGuillaume Nault# |   veth23:                                                             |
84*bbbc7aa4SGuillaume Nault# |   ^  * IPv4 address: 192.0.2.32, peer 192.0.2.33/32                   |
85*bbbc7aa4SGuillaume Nault# |   |  * IPv6 address: 2001:db8::32, peer 2001:db8::33/128              |
86*bbbc7aa4SGuillaume Nault# |   |                                                                   |
87*bbbc7aa4SGuillaume Nault# +---+-------------------------------------------------------------------+
88*bbbc7aa4SGuillaume Nault#     |
89*bbbc7aa4SGuillaume Nault#     | Traffic type: IP or MPLS (depending on test)
90*bbbc7aa4SGuillaume Nault#     |
91*bbbc7aa4SGuillaume Nault# +---+-------------------------------------------------------------------+
92*bbbc7aa4SGuillaume Nault# |   |                              NS3                                  |
93*bbbc7aa4SGuillaume Nault# |   v                                                                   |
94*bbbc7aa4SGuillaume Nault# |   veth32:                                                             |
95*bbbc7aa4SGuillaume Nault# |      * IPv4 address: 192.0.2.33, peer 192.0.2.32/32                   |
96*bbbc7aa4SGuillaume Nault# |      * IPv6 address: 2001:db8::33, peer 2001:db8::32/128              |
97*bbbc7aa4SGuillaume Nault# |                                                                       |
98*bbbc7aa4SGuillaume Nault# |   lo:                                                                 |
99*bbbc7aa4SGuillaume Nault# |      * IPv4 address: 192.0.2.103/32                                   |
100*bbbc7aa4SGuillaume Nault# |      * IPv6 address: 2001:db8::103/128                                |
101*bbbc7aa4SGuillaume Nault# |      * IPv6 address: 2001:db8::203/128                                |
102*bbbc7aa4SGuillaume Nault# |      * IPv4 route: 192.0.2.100/32 reachable via 192.0.2.32            |
103*bbbc7aa4SGuillaume Nault# |      * IPv6 route: 2001:db8::100/128 reachable via 2001:db8::32       |
104*bbbc7aa4SGuillaume Nault# |      * IPv6 route: 2001:db8::200/128 reachable via 2001:db8::32       |
105*bbbc7aa4SGuillaume Nault# |                    (encapsulated with MPLS label 200)                 |
106*bbbc7aa4SGuillaume Nault# |                                                                       |
107*bbbc7aa4SGuillaume Nault# +-----------------------------------------------------------------------+
108*bbbc7aa4SGuillaume Nault
109*bbbc7aa4SGuillaume NaultERR=4 # Return 4 by default, which is the SKIP code for kselftest
110*bbbc7aa4SGuillaume NaultPING6="ping"
111*bbbc7aa4SGuillaume NaultPAUSE_ON_FAIL="no"
112*bbbc7aa4SGuillaume Nault
113*bbbc7aa4SGuillaume Naultreadonly NS0=$(mktemp -u ns0-XXXXXXXX)
114*bbbc7aa4SGuillaume Naultreadonly NS1=$(mktemp -u ns1-XXXXXXXX)
115*bbbc7aa4SGuillaume Naultreadonly NS2=$(mktemp -u ns2-XXXXXXXX)
116*bbbc7aa4SGuillaume Naultreadonly NS3=$(mktemp -u ns3-XXXXXXXX)
117*bbbc7aa4SGuillaume Nault
118*bbbc7aa4SGuillaume Nault# Exit the script after having removed the network namespaces it created
119*bbbc7aa4SGuillaume Nault#
120*bbbc7aa4SGuillaume Nault# Parameters:
121*bbbc7aa4SGuillaume Nault#
122*bbbc7aa4SGuillaume Nault#   * The list of network namespaces to delete before exiting.
123*bbbc7aa4SGuillaume Nault#
124*bbbc7aa4SGuillaume Naultexit_cleanup()
125*bbbc7aa4SGuillaume Nault{
126*bbbc7aa4SGuillaume Nault	for ns in "$@"; do
127*bbbc7aa4SGuillaume Nault		ip netns delete "${ns}" 2>/dev/null || true
128*bbbc7aa4SGuillaume Nault	done
129*bbbc7aa4SGuillaume Nault
130*bbbc7aa4SGuillaume Nault	if [ "${ERR}" -eq 4 ]; then
131*bbbc7aa4SGuillaume Nault		echo "Error: Setting up the testing environment failed." >&2
132*bbbc7aa4SGuillaume Nault	fi
133*bbbc7aa4SGuillaume Nault
134*bbbc7aa4SGuillaume Nault	exit "${ERR}"
135*bbbc7aa4SGuillaume Nault}
136*bbbc7aa4SGuillaume Nault
137*bbbc7aa4SGuillaume Nault# Create the four network namespaces used by the script (NS0, NS1, NS2 and NS3)
138*bbbc7aa4SGuillaume Nault#
139*bbbc7aa4SGuillaume Nault# New namespaces are cleaned up manually in case of error, to ensure that only
140*bbbc7aa4SGuillaume Nault# namespaces created by this script are deleted.
141*bbbc7aa4SGuillaume Naultcreate_namespaces()
142*bbbc7aa4SGuillaume Nault{
143*bbbc7aa4SGuillaume Nault	ip netns add "${NS0}" || exit_cleanup
144*bbbc7aa4SGuillaume Nault	ip netns add "${NS1}" || exit_cleanup "${NS0}"
145*bbbc7aa4SGuillaume Nault	ip netns add "${NS2}" || exit_cleanup "${NS0}" "${NS1}"
146*bbbc7aa4SGuillaume Nault	ip netns add "${NS3}" || exit_cleanup "${NS0}" "${NS1}" "${NS2}"
147*bbbc7aa4SGuillaume Nault}
148*bbbc7aa4SGuillaume Nault
149*bbbc7aa4SGuillaume Nault# The trap function handler
150*bbbc7aa4SGuillaume Nault#
151*bbbc7aa4SGuillaume Naultexit_cleanup_all()
152*bbbc7aa4SGuillaume Nault{
153*bbbc7aa4SGuillaume Nault	exit_cleanup "${NS0}" "${NS1}" "${NS2}" "${NS3}"
154*bbbc7aa4SGuillaume Nault}
155*bbbc7aa4SGuillaume Nault
156*bbbc7aa4SGuillaume Nault# Configure a network interface using a host route
157*bbbc7aa4SGuillaume Nault#
158*bbbc7aa4SGuillaume Nault# Parameters
159*bbbc7aa4SGuillaume Nault#
160*bbbc7aa4SGuillaume Nault#   * $1: the netns the network interface resides in,
161*bbbc7aa4SGuillaume Nault#   * $2: the network interface name,
162*bbbc7aa4SGuillaume Nault#   * $3: the local IPv4 address to assign to this interface,
163*bbbc7aa4SGuillaume Nault#   * $4: the IPv4 address of the remote network interface,
164*bbbc7aa4SGuillaume Nault#   * $5: the local IPv6 address to assign to this interface,
165*bbbc7aa4SGuillaume Nault#   * $6: the IPv6 address of the remote network interface.
166*bbbc7aa4SGuillaume Nault#
167*bbbc7aa4SGuillaume Naultiface_config()
168*bbbc7aa4SGuillaume Nault{
169*bbbc7aa4SGuillaume Nault	local NS="${1}"; readonly NS
170*bbbc7aa4SGuillaume Nault	local DEV="${2}"; readonly DEV
171*bbbc7aa4SGuillaume Nault	local LOCAL_IP4="${3}"; readonly LOCAL_IP4
172*bbbc7aa4SGuillaume Nault	local PEER_IP4="${4}"; readonly PEER_IP4
173*bbbc7aa4SGuillaume Nault	local LOCAL_IP6="${5}"; readonly LOCAL_IP6
174*bbbc7aa4SGuillaume Nault	local PEER_IP6="${6}"; readonly PEER_IP6
175*bbbc7aa4SGuillaume Nault
176*bbbc7aa4SGuillaume Nault	ip -netns "${NS}" link set dev "${DEV}" up
177*bbbc7aa4SGuillaume Nault	ip -netns "${NS}" address add dev "${DEV}" "${LOCAL_IP4}" peer "${PEER_IP4}"
178*bbbc7aa4SGuillaume Nault	ip -netns "${NS}" address add dev "${DEV}" "${LOCAL_IP6}" peer "${PEER_IP6}" nodad
179*bbbc7aa4SGuillaume Nault}
180*bbbc7aa4SGuillaume Nault
181*bbbc7aa4SGuillaume Nault# Create base networking topology:
182*bbbc7aa4SGuillaume Nault#
183*bbbc7aa4SGuillaume Nault#   * set up the loopback device in all network namespaces (NS0..NS3),
184*bbbc7aa4SGuillaume Nault#   * set up a veth pair to connect each netns in sequence (NS0 with NS1,
185*bbbc7aa4SGuillaume Nault#     NS1 with NS2, etc.),
186*bbbc7aa4SGuillaume Nault#   * add and IPv4 and an IPv6 address on each veth interface,
187*bbbc7aa4SGuillaume Nault#   * prepare the ingress qdiscs in the intermediate namespaces.
188*bbbc7aa4SGuillaume Nault#
189*bbbc7aa4SGuillaume Naultsetup_underlay()
190*bbbc7aa4SGuillaume Nault{
191*bbbc7aa4SGuillaume Nault	for ns in "${NS0}" "${NS1}" "${NS2}" "${NS3}"; do
192*bbbc7aa4SGuillaume Nault		ip -netns "${ns}" link set dev lo up
193*bbbc7aa4SGuillaume Nault	done;
194*bbbc7aa4SGuillaume Nault
195*bbbc7aa4SGuillaume Nault	ip link add name veth01 netns "${NS0}" type veth peer name veth10 netns "${NS1}"
196*bbbc7aa4SGuillaume Nault	ip link add name veth12 netns "${NS1}" type veth peer name veth21 netns "${NS2}"
197*bbbc7aa4SGuillaume Nault	ip link add name veth23 netns "${NS2}" type veth peer name veth32 netns "${NS3}"
198*bbbc7aa4SGuillaume Nault	iface_config "${NS0}" veth01 192.0.2.10 192.0.2.11/32 2001:db8::10 2001:db8::11/128
199*bbbc7aa4SGuillaume Nault	iface_config "${NS1}" veth10 192.0.2.11 192.0.2.10/32 2001:db8::11 2001:db8::10/128
200*bbbc7aa4SGuillaume Nault	iface_config "${NS1}" veth12 192.0.2.21 192.0.2.22/32 2001:db8::21 2001:db8::22/128
201*bbbc7aa4SGuillaume Nault	iface_config "${NS2}" veth21 192.0.2.22 192.0.2.21/32 2001:db8::22 2001:db8::21/128
202*bbbc7aa4SGuillaume Nault	iface_config "${NS2}" veth23 192.0.2.32 192.0.2.33/32 2001:db8::32 2001:db8::33/128
203*bbbc7aa4SGuillaume Nault	iface_config "${NS3}" veth32 192.0.2.33 192.0.2.32/32 2001:db8::33 2001:db8::32/128
204*bbbc7aa4SGuillaume Nault
205*bbbc7aa4SGuillaume Nault	tc -netns "${NS1}" qdisc add dev veth10 ingress
206*bbbc7aa4SGuillaume Nault	tc -netns "${NS2}" qdisc add dev veth23 ingress
207*bbbc7aa4SGuillaume Nault}
208*bbbc7aa4SGuillaume Nault
209*bbbc7aa4SGuillaume Nault# Set up the IPv4, IPv6 and MPLS overlays.
210*bbbc7aa4SGuillaume Nault#
211*bbbc7aa4SGuillaume Nault# Configuration is similar for all protocols:
212*bbbc7aa4SGuillaume Nault#
213*bbbc7aa4SGuillaume Nault#   * add an overlay IP address on the loopback interface of each edge
214*bbbc7aa4SGuillaume Nault#     namespace,
215*bbbc7aa4SGuillaume Nault#   * route these IP addresses via the intermediate namespaces (for the MPLS
216*bbbc7aa4SGuillaume Nault#     tests, this is also where MPLS encapsulation is done),
217*bbbc7aa4SGuillaume Nault#   * add routes for these IP addresses (or MPLS labels) in the intermediate
218*bbbc7aa4SGuillaume Nault#     namespaces.
219*bbbc7aa4SGuillaume Nault#
220*bbbc7aa4SGuillaume Nault# The bareudp encapsulation isn't configured in setup_overlay_*(). That will be
221*bbbc7aa4SGuillaume Nault# done just before running the reachability tests.
222*bbbc7aa4SGuillaume Nault
223*bbbc7aa4SGuillaume Naultsetup_overlay_ipv4()
224*bbbc7aa4SGuillaume Nault{
225*bbbc7aa4SGuillaume Nault	# Add the overlay IP addresses and route them through the veth devices
226*bbbc7aa4SGuillaume Nault	ip -netns "${NS0}" address add 192.0.2.100/32 dev lo
227*bbbc7aa4SGuillaume Nault	ip -netns "${NS3}" address add 192.0.2.103/32 dev lo
228*bbbc7aa4SGuillaume Nault	ip -netns "${NS0}" route add 192.0.2.103/32 src 192.0.2.100 via 192.0.2.11
229*bbbc7aa4SGuillaume Nault	ip -netns "${NS3}" route add 192.0.2.100/32 src 192.0.2.103 via 192.0.2.32
230*bbbc7aa4SGuillaume Nault
231*bbbc7aa4SGuillaume Nault	# Route the overlay addresses in the intermediate namespaces
232*bbbc7aa4SGuillaume Nault	# (used after bareudp decapsulation)
233*bbbc7aa4SGuillaume Nault	ip netns exec "${NS1}" sysctl -qw net.ipv4.ip_forward=1
234*bbbc7aa4SGuillaume Nault	ip netns exec "${NS2}" sysctl -qw net.ipv4.ip_forward=1
235*bbbc7aa4SGuillaume Nault	ip -netns "${NS1}" route add 192.0.2.100/32 via 192.0.2.10
236*bbbc7aa4SGuillaume Nault	ip -netns "${NS2}" route add 192.0.2.103/32 via 192.0.2.33
237*bbbc7aa4SGuillaume Nault}
238*bbbc7aa4SGuillaume Nault
239*bbbc7aa4SGuillaume Naultsetup_overlay_ipv6()
240*bbbc7aa4SGuillaume Nault{
241*bbbc7aa4SGuillaume Nault	# Add the overlay IP addresses and route them through the veth devices
242*bbbc7aa4SGuillaume Nault	ip -netns "${NS0}" address add 2001:db8::100/128 dev lo
243*bbbc7aa4SGuillaume Nault	ip -netns "${NS3}" address add 2001:db8::103/128 dev lo
244*bbbc7aa4SGuillaume Nault	ip -netns "${NS0}" route add 2001:db8::103/128 src 2001:db8::100 via 2001:db8::11
245*bbbc7aa4SGuillaume Nault	ip -netns "${NS3}" route add 2001:db8::100/128 src 2001:db8::103 via 2001:db8::32
246*bbbc7aa4SGuillaume Nault
247*bbbc7aa4SGuillaume Nault	# Route the overlay addresses in the intermediate namespaces
248*bbbc7aa4SGuillaume Nault	# (used after bareudp decapsulation)
249*bbbc7aa4SGuillaume Nault	ip netns exec "${NS1}" sysctl -qw net.ipv6.conf.all.forwarding=1
250*bbbc7aa4SGuillaume Nault	ip netns exec "${NS2}" sysctl -qw net.ipv6.conf.all.forwarding=1
251*bbbc7aa4SGuillaume Nault	ip -netns "${NS1}" route add 2001:db8::100/128 via 2001:db8::10
252*bbbc7aa4SGuillaume Nault	ip -netns "${NS2}" route add 2001:db8::103/128 via 2001:db8::33
253*bbbc7aa4SGuillaume Nault}
254*bbbc7aa4SGuillaume Nault
255*bbbc7aa4SGuillaume Naultsetup_overlay_mpls()
256*bbbc7aa4SGuillaume Nault{
257*bbbc7aa4SGuillaume Nault	# Add specific overlay IP addresses, routed over MPLS
258*bbbc7aa4SGuillaume Nault	ip -netns "${NS0}" address add 2001:db8::200/128 dev lo
259*bbbc7aa4SGuillaume Nault	ip -netns "${NS3}" address add 2001:db8::203/128 dev lo
260*bbbc7aa4SGuillaume Nault	ip -netns "${NS0}" route add 2001:db8::203/128 src 2001:db8::200 encap mpls 203 via 2001:db8::11
261*bbbc7aa4SGuillaume Nault	ip -netns "${NS3}" route add 2001:db8::200/128 src 2001:db8::203 encap mpls 200 via 2001:db8::32
262*bbbc7aa4SGuillaume Nault
263*bbbc7aa4SGuillaume Nault	# Route the MPLS packets in the intermediate namespaces
264*bbbc7aa4SGuillaume Nault	# (used after bareudp decapsulation)
265*bbbc7aa4SGuillaume Nault	ip netns exec "${NS1}" sysctl -qw net.mpls.platform_labels=256
266*bbbc7aa4SGuillaume Nault	ip netns exec "${NS2}" sysctl -qw net.mpls.platform_labels=256
267*bbbc7aa4SGuillaume Nault	ip -netns "${NS1}" -family mpls route add 200 via inet6 2001:db8::10
268*bbbc7aa4SGuillaume Nault	ip -netns "${NS2}" -family mpls route add 203 via inet6 2001:db8::33
269*bbbc7aa4SGuillaume Nault}
270*bbbc7aa4SGuillaume Nault
271*bbbc7aa4SGuillaume Nault# Run "ping" from NS0 and print the result
272*bbbc7aa4SGuillaume Nault#
273*bbbc7aa4SGuillaume Nault# Parameters:
274*bbbc7aa4SGuillaume Nault#
275*bbbc7aa4SGuillaume Nault#   * $1: the variant of ping to use (normally either "ping" or "ping6"),
276*bbbc7aa4SGuillaume Nault#   * $2: the IP address to ping,
277*bbbc7aa4SGuillaume Nault#   * $3: a human readable description of the purpose of the test.
278*bbbc7aa4SGuillaume Nault#
279*bbbc7aa4SGuillaume Nault# If the test fails and PAUSE_ON_FAIL is active, the user is given the
280*bbbc7aa4SGuillaume Nault# possibility to continue with the next test or to quit immediately.
281*bbbc7aa4SGuillaume Nault#
282*bbbc7aa4SGuillaume Naultping_test_one()
283*bbbc7aa4SGuillaume Nault{
284*bbbc7aa4SGuillaume Nault	local PING="$1"; readonly PING
285*bbbc7aa4SGuillaume Nault	local IP="$2"; readonly IP
286*bbbc7aa4SGuillaume Nault	local MSG="$3"; readonly MSG
287*bbbc7aa4SGuillaume Nault	local RET
288*bbbc7aa4SGuillaume Nault
289*bbbc7aa4SGuillaume Nault	printf "TEST: %-60s  " "${MSG}"
290*bbbc7aa4SGuillaume Nault
291*bbbc7aa4SGuillaume Nault	set +e
292*bbbc7aa4SGuillaume Nault	ip netns exec "${NS0}" "${PING}" -w 5 -c 1 "${IP}" > /dev/null 2>&1
293*bbbc7aa4SGuillaume Nault	RET=$?
294*bbbc7aa4SGuillaume Nault	set -e
295*bbbc7aa4SGuillaume Nault
296*bbbc7aa4SGuillaume Nault	if [ "${RET}" -eq 0 ]; then
297*bbbc7aa4SGuillaume Nault		printf "[ OK ]\n"
298*bbbc7aa4SGuillaume Nault	else
299*bbbc7aa4SGuillaume Nault		ERR=1
300*bbbc7aa4SGuillaume Nault		printf "[FAIL]\n"
301*bbbc7aa4SGuillaume Nault		if [ "${PAUSE_ON_FAIL}" = "yes" ]; then
302*bbbc7aa4SGuillaume Nault			printf "\nHit enter to continue, 'q' to quit\n"
303*bbbc7aa4SGuillaume Nault			read a
304*bbbc7aa4SGuillaume Nault			if [ "$a" = "q" ]; then
305*bbbc7aa4SGuillaume Nault				exit 1
306*bbbc7aa4SGuillaume Nault			fi
307*bbbc7aa4SGuillaume Nault		fi
308*bbbc7aa4SGuillaume Nault	fi
309*bbbc7aa4SGuillaume Nault}
310*bbbc7aa4SGuillaume Nault
311*bbbc7aa4SGuillaume Nault# Run reachability tests
312*bbbc7aa4SGuillaume Nault#
313*bbbc7aa4SGuillaume Nault# Parameters:
314*bbbc7aa4SGuillaume Nault#
315*bbbc7aa4SGuillaume Nault#   * $1: human readable string describing the underlay protocol.
316*bbbc7aa4SGuillaume Nault#
317*bbbc7aa4SGuillaume Nault# $IPV4, $IPV6, $MPLS_UC and $MULTIPROTO are inherited from the calling
318*bbbc7aa4SGuillaume Nault# function.
319*bbbc7aa4SGuillaume Nault#
320*bbbc7aa4SGuillaume Naultping_test()
321*bbbc7aa4SGuillaume Nault{
322*bbbc7aa4SGuillaume Nault	local UNDERLAY="$1"; readonly UNDERLAY
323*bbbc7aa4SGuillaume Nault	local MODE
324*bbbc7aa4SGuillaume Nault	local MSG
325*bbbc7aa4SGuillaume Nault
326*bbbc7aa4SGuillaume Nault	if [ "${MULTIPROTO}" = "multiproto" ]; then
327*bbbc7aa4SGuillaume Nault		MODE=" (multiproto mode)"
328*bbbc7aa4SGuillaume Nault	else
329*bbbc7aa4SGuillaume Nault		MODE=""
330*bbbc7aa4SGuillaume Nault	fi
331*bbbc7aa4SGuillaume Nault
332*bbbc7aa4SGuillaume Nault	if [ $IPV4 ]; then
333*bbbc7aa4SGuillaume Nault		ping_test_one "ping" "192.0.2.103" "IPv4 packets over ${UNDERLAY}${MODE}"
334*bbbc7aa4SGuillaume Nault	fi
335*bbbc7aa4SGuillaume Nault	if [ $IPV6 ]; then
336*bbbc7aa4SGuillaume Nault		ping_test_one "${PING6}" "2001:db8::103" "IPv6 packets over ${UNDERLAY}${MODE}"
337*bbbc7aa4SGuillaume Nault	fi
338*bbbc7aa4SGuillaume Nault	if [ $MPLS_UC ]; then
339*bbbc7aa4SGuillaume Nault		ping_test_one "${PING6}" "2001:db8::203" "Unicast MPLS packets over ${UNDERLAY}${MODE}"
340*bbbc7aa4SGuillaume Nault	fi
341*bbbc7aa4SGuillaume Nault}
342*bbbc7aa4SGuillaume Nault
343*bbbc7aa4SGuillaume Nault# Set up a bareudp overlay and run reachability tests over IPv4 and IPv6
344*bbbc7aa4SGuillaume Nault#
345*bbbc7aa4SGuillaume Nault# Parameters:
346*bbbc7aa4SGuillaume Nault#
347*bbbc7aa4SGuillaume Nault#   * $1: the packet type (protocol) to be handled by bareudp,
348*bbbc7aa4SGuillaume Nault#   * $2: a flag to activate or deactivate bareudp's "multiproto" mode.
349*bbbc7aa4SGuillaume Nault#
350*bbbc7aa4SGuillaume Naulttest_overlay()
351*bbbc7aa4SGuillaume Nault{
352*bbbc7aa4SGuillaume Nault	local ETHERTYPE="$1"; readonly ETHERTYPE
353*bbbc7aa4SGuillaume Nault	local MULTIPROTO="$2"; readonly MULTIPROTO
354*bbbc7aa4SGuillaume Nault	local IPV4
355*bbbc7aa4SGuillaume Nault	local IPV6
356*bbbc7aa4SGuillaume Nault	local MPLS_UC
357*bbbc7aa4SGuillaume Nault
358*bbbc7aa4SGuillaume Nault	case "${ETHERTYPE}" in
359*bbbc7aa4SGuillaume Nault		"ipv4")
360*bbbc7aa4SGuillaume Nault			IPV4="ipv4"
361*bbbc7aa4SGuillaume Nault			if [ "${MULTIPROTO}" = "multiproto" ]; then
362*bbbc7aa4SGuillaume Nault				IPV6="ipv6"
363*bbbc7aa4SGuillaume Nault			else
364*bbbc7aa4SGuillaume Nault				IPV6=""
365*bbbc7aa4SGuillaume Nault			fi
366*bbbc7aa4SGuillaume Nault			MPLS_UC=""
367*bbbc7aa4SGuillaume Nault			;;
368*bbbc7aa4SGuillaume Nault		"ipv6")
369*bbbc7aa4SGuillaume Nault			IPV6="ipv6"
370*bbbc7aa4SGuillaume Nault			IPV4=""
371*bbbc7aa4SGuillaume Nault			MPLS_UC=""
372*bbbc7aa4SGuillaume Nault			;;
373*bbbc7aa4SGuillaume Nault		"mpls_uc")
374*bbbc7aa4SGuillaume Nault			MPLS_UC="mpls_uc"
375*bbbc7aa4SGuillaume Nault			IPV4=""
376*bbbc7aa4SGuillaume Nault			IPV6=""
377*bbbc7aa4SGuillaume Nault			;;
378*bbbc7aa4SGuillaume Nault		*)
379*bbbc7aa4SGuillaume Nault			exit 1
380*bbbc7aa4SGuillaume Nault			;;
381*bbbc7aa4SGuillaume Nault	esac
382*bbbc7aa4SGuillaume Nault	readonly IPV4
383*bbbc7aa4SGuillaume Nault	readonly IPV6
384*bbbc7aa4SGuillaume Nault	readonly MPLS_UC
385*bbbc7aa4SGuillaume Nault
386*bbbc7aa4SGuillaume Nault	# Create the bareudp devices in the intermediate namespaces
387*bbbc7aa4SGuillaume Nault	ip -netns "${NS1}" link add name bareudp_ns1 up type bareudp dstport 6635 ethertype "${ETHERTYPE}" "${MULTIPROTO}"
388*bbbc7aa4SGuillaume Nault	ip -netns "${NS2}" link add name bareudp_ns2 up type bareudp dstport 6635 ethertype "${ETHERTYPE}" "${MULTIPROTO}"
389*bbbc7aa4SGuillaume Nault
390*bbbc7aa4SGuillaume Nault	# IPv4 over UDPv4
391*bbbc7aa4SGuillaume Nault	if [ $IPV4 ]; then
392*bbbc7aa4SGuillaume Nault		# Encapsulation instructions for bareudp over IPv4
393*bbbc7aa4SGuillaume Nault		tc -netns "${NS1}" filter add dev veth10 ingress protocol ipv4         \
394*bbbc7aa4SGuillaume Nault			flower dst_ip 192.0.2.103/32                                   \
395*bbbc7aa4SGuillaume Nault			action tunnel_key set src_ip 192.0.2.21 dst_ip 192.0.2.22 id 0 \
396*bbbc7aa4SGuillaume Nault			action mirred egress redirect dev bareudp_ns1
397*bbbc7aa4SGuillaume Nault		tc -netns "${NS2}" filter add dev veth23 ingress protocol ipv4         \
398*bbbc7aa4SGuillaume Nault			flower dst_ip 192.0.2.100/32                                   \
399*bbbc7aa4SGuillaume Nault			action tunnel_key set src_ip 192.0.2.22 dst_ip 192.0.2.21 id 0 \
400*bbbc7aa4SGuillaume Nault			action mirred egress redirect dev bareudp_ns2
401*bbbc7aa4SGuillaume Nault	fi
402*bbbc7aa4SGuillaume Nault
403*bbbc7aa4SGuillaume Nault	# IPv6 over UDPv4
404*bbbc7aa4SGuillaume Nault	if [ $IPV6 ]; then
405*bbbc7aa4SGuillaume Nault		# Encapsulation instructions for bareudp over IPv4
406*bbbc7aa4SGuillaume Nault		tc -netns "${NS1}" filter add dev veth10 ingress protocol ipv6         \
407*bbbc7aa4SGuillaume Nault			flower dst_ip 2001:db8::103/128                                \
408*bbbc7aa4SGuillaume Nault			action tunnel_key set src_ip 192.0.2.21 dst_ip 192.0.2.22 id 0 \
409*bbbc7aa4SGuillaume Nault			action mirred egress redirect dev bareudp_ns1
410*bbbc7aa4SGuillaume Nault		tc -netns "${NS2}" filter add dev veth23 ingress protocol ipv6         \
411*bbbc7aa4SGuillaume Nault			flower dst_ip 2001:db8::100/128                                \
412*bbbc7aa4SGuillaume Nault			action tunnel_key set src_ip 192.0.2.22 dst_ip 192.0.2.21 id 0 \
413*bbbc7aa4SGuillaume Nault			action mirred egress redirect dev bareudp_ns2
414*bbbc7aa4SGuillaume Nault	fi
415*bbbc7aa4SGuillaume Nault
416*bbbc7aa4SGuillaume Nault	# MPLS (unicast) over UDPv4
417*bbbc7aa4SGuillaume Nault	if [ $MPLS_UC ]; then
418*bbbc7aa4SGuillaume Nault		ip netns exec "${NS1}" sysctl -qw net.mpls.conf.bareudp_ns1.input=1
419*bbbc7aa4SGuillaume Nault		ip netns exec "${NS2}" sysctl -qw net.mpls.conf.bareudp_ns2.input=1
420*bbbc7aa4SGuillaume Nault
421*bbbc7aa4SGuillaume Nault		# Encapsulation instructions for bareudp over IPv4
422*bbbc7aa4SGuillaume Nault		tc -netns "${NS1}" filter add dev veth10 ingress protocol mpls_uc      \
423*bbbc7aa4SGuillaume Nault			flower mpls_label 203                                          \
424*bbbc7aa4SGuillaume Nault			action tunnel_key set src_ip 192.0.2.21 dst_ip 192.0.2.22 id 0 \
425*bbbc7aa4SGuillaume Nault			action mirred egress redirect dev bareudp_ns1
426*bbbc7aa4SGuillaume Nault		tc -netns "${NS2}" filter add dev veth23 ingress protocol mpls_uc      \
427*bbbc7aa4SGuillaume Nault			flower mpls_label 200                                          \
428*bbbc7aa4SGuillaume Nault			action tunnel_key set src_ip 192.0.2.22 dst_ip 192.0.2.21 id 0 \
429*bbbc7aa4SGuillaume Nault			action mirred egress redirect dev bareudp_ns2
430*bbbc7aa4SGuillaume Nault	fi
431*bbbc7aa4SGuillaume Nault
432*bbbc7aa4SGuillaume Nault	# Test IPv4 underlay
433*bbbc7aa4SGuillaume Nault	ping_test "UDPv4"
434*bbbc7aa4SGuillaume Nault
435*bbbc7aa4SGuillaume Nault	# Cleanup bareudp encapsulation instructions, as they were specific to
436*bbbc7aa4SGuillaume Nault	# the IPv4 underlay, before setting up and testing the IPv6 underlay
437*bbbc7aa4SGuillaume Nault	tc -netns "${NS1}" filter delete dev veth10 ingress
438*bbbc7aa4SGuillaume Nault	tc -netns "${NS2}" filter delete dev veth23 ingress
439*bbbc7aa4SGuillaume Nault
440*bbbc7aa4SGuillaume Nault	# IPv4 over UDPv6
441*bbbc7aa4SGuillaume Nault	if [ $IPV4 ]; then
442*bbbc7aa4SGuillaume Nault		# New encapsulation instructions for bareudp over IPv6
443*bbbc7aa4SGuillaume Nault		tc -netns "${NS1}" filter add dev veth10 ingress protocol ipv4             \
444*bbbc7aa4SGuillaume Nault			flower dst_ip 192.0.2.103/32                                       \
445*bbbc7aa4SGuillaume Nault			action tunnel_key set src_ip 2001:db8::21 dst_ip 2001:db8::22 id 0 \
446*bbbc7aa4SGuillaume Nault			action mirred egress redirect dev bareudp_ns1
447*bbbc7aa4SGuillaume Nault		tc -netns "${NS2}" filter add dev veth23 ingress protocol ipv4             \
448*bbbc7aa4SGuillaume Nault			flower dst_ip 192.0.2.100/32                                       \
449*bbbc7aa4SGuillaume Nault			action tunnel_key set src_ip 2001:db8::22 dst_ip 2001:db8::21 id 0 \
450*bbbc7aa4SGuillaume Nault			action mirred egress redirect dev bareudp_ns2
451*bbbc7aa4SGuillaume Nault	fi
452*bbbc7aa4SGuillaume Nault
453*bbbc7aa4SGuillaume Nault	# IPv6 over UDPv6
454*bbbc7aa4SGuillaume Nault	if [ $IPV6 ]; then
455*bbbc7aa4SGuillaume Nault		# New encapsulation instructions for bareudp over IPv6
456*bbbc7aa4SGuillaume Nault		tc -netns "${NS1}" filter add dev veth10 ingress protocol ipv6             \
457*bbbc7aa4SGuillaume Nault			flower dst_ip 2001:db8::103/128                                    \
458*bbbc7aa4SGuillaume Nault			action tunnel_key set src_ip 2001:db8::21 dst_ip 2001:db8::22 id 0 \
459*bbbc7aa4SGuillaume Nault			action mirred egress redirect dev bareudp_ns1
460*bbbc7aa4SGuillaume Nault		tc -netns "${NS2}" filter add dev veth23 ingress protocol ipv6             \
461*bbbc7aa4SGuillaume Nault			flower dst_ip 2001:db8::100/128                                    \
462*bbbc7aa4SGuillaume Nault			action tunnel_key set src_ip 2001:db8::22 dst_ip 2001:db8::21 id 0 \
463*bbbc7aa4SGuillaume Nault			action mirred egress redirect dev bareudp_ns2
464*bbbc7aa4SGuillaume Nault	fi
465*bbbc7aa4SGuillaume Nault
466*bbbc7aa4SGuillaume Nault	# MPLS (unicast) over UDPv6
467*bbbc7aa4SGuillaume Nault	if [ $MPLS_UC ]; then
468*bbbc7aa4SGuillaume Nault		# New encapsulation instructions for bareudp over IPv6
469*bbbc7aa4SGuillaume Nault		tc -netns "${NS1}" filter add dev veth10 ingress protocol mpls_uc          \
470*bbbc7aa4SGuillaume Nault			flower mpls_label 203                                              \
471*bbbc7aa4SGuillaume Nault			action tunnel_key set src_ip 2001:db8::21 dst_ip 2001:db8::22 id 0 \
472*bbbc7aa4SGuillaume Nault			action mirred egress redirect dev bareudp_ns1
473*bbbc7aa4SGuillaume Nault		tc -netns "${NS2}" filter add dev veth23 ingress protocol mpls_uc          \
474*bbbc7aa4SGuillaume Nault			flower mpls_label 200                                              \
475*bbbc7aa4SGuillaume Nault			action tunnel_key set src_ip 2001:db8::22 dst_ip 2001:db8::21 id 0 \
476*bbbc7aa4SGuillaume Nault			action mirred egress redirect dev bareudp_ns2
477*bbbc7aa4SGuillaume Nault	fi
478*bbbc7aa4SGuillaume Nault
479*bbbc7aa4SGuillaume Nault	# Test IPv6 underlay
480*bbbc7aa4SGuillaume Nault	ping_test "UDPv6"
481*bbbc7aa4SGuillaume Nault
482*bbbc7aa4SGuillaume Nault	tc -netns "${NS1}" filter delete dev veth10 ingress
483*bbbc7aa4SGuillaume Nault	tc -netns "${NS2}" filter delete dev veth23 ingress
484*bbbc7aa4SGuillaume Nault	ip -netns "${NS1}" link delete bareudp_ns1
485*bbbc7aa4SGuillaume Nault	ip -netns "${NS2}" link delete bareudp_ns2
486*bbbc7aa4SGuillaume Nault}
487*bbbc7aa4SGuillaume Nault
488*bbbc7aa4SGuillaume Naultcheck_features()
489*bbbc7aa4SGuillaume Nault{
490*bbbc7aa4SGuillaume Nault	ip link help 2>&1 | grep -q bareudp
491*bbbc7aa4SGuillaume Nault	if [ $? -ne 0 ]; then
492*bbbc7aa4SGuillaume Nault		echo "Missing bareudp support in iproute2" >&2
493*bbbc7aa4SGuillaume Nault		exit_cleanup
494*bbbc7aa4SGuillaume Nault	fi
495*bbbc7aa4SGuillaume Nault
496*bbbc7aa4SGuillaume Nault	# Use ping6 on systems where ping doesn't handle IPv6
497*bbbc7aa4SGuillaume Nault	ping -w 1 -c 1 ::1 > /dev/null 2>&1 || PING6="ping6"
498*bbbc7aa4SGuillaume Nault}
499*bbbc7aa4SGuillaume Nault
500*bbbc7aa4SGuillaume Naultusage()
501*bbbc7aa4SGuillaume Nault{
502*bbbc7aa4SGuillaume Nault	echo "Usage: $0 [-p]"
503*bbbc7aa4SGuillaume Nault	exit 1
504*bbbc7aa4SGuillaume Nault}
505*bbbc7aa4SGuillaume Nault
506*bbbc7aa4SGuillaume Naultwhile getopts :p o
507*bbbc7aa4SGuillaume Naultdo
508*bbbc7aa4SGuillaume Nault	case $o in
509*bbbc7aa4SGuillaume Nault		p) PAUSE_ON_FAIL="yes";;
510*bbbc7aa4SGuillaume Nault		*) usage;;
511*bbbc7aa4SGuillaume Nault	esac
512*bbbc7aa4SGuillaume Naultdone
513*bbbc7aa4SGuillaume Nault
514*bbbc7aa4SGuillaume Naultcheck_features
515*bbbc7aa4SGuillaume Nault
516*bbbc7aa4SGuillaume Nault# Create namespaces before setting up the exit trap.
517*bbbc7aa4SGuillaume Nault# Otherwise, exit_cleanup_all() could delete namespaces that were not created
518*bbbc7aa4SGuillaume Nault# by this script.
519*bbbc7aa4SGuillaume Naultcreate_namespaces
520*bbbc7aa4SGuillaume Nault
521*bbbc7aa4SGuillaume Naultset -e
522*bbbc7aa4SGuillaume Naulttrap exit_cleanup_all EXIT
523*bbbc7aa4SGuillaume Nault
524*bbbc7aa4SGuillaume Naultsetup_underlay
525*bbbc7aa4SGuillaume Naultsetup_overlay_ipv4
526*bbbc7aa4SGuillaume Naultsetup_overlay_ipv6
527*bbbc7aa4SGuillaume Naultsetup_overlay_mpls
528*bbbc7aa4SGuillaume Nault
529*bbbc7aa4SGuillaume Naulttest_overlay ipv4 nomultiproto
530*bbbc7aa4SGuillaume Naulttest_overlay ipv6 nomultiproto
531*bbbc7aa4SGuillaume Naulttest_overlay ipv4 multiproto
532*bbbc7aa4SGuillaume Naulttest_overlay mpls_uc nomultiproto
533*bbbc7aa4SGuillaume Nault
534*bbbc7aa4SGuillaume Naultif [ "${ERR}" -eq 1 ]; then
535*bbbc7aa4SGuillaume Nault	echo "Some tests failed." >&2
536*bbbc7aa4SGuillaume Naultelse
537*bbbc7aa4SGuillaume Nault	ERR=0
538*bbbc7aa4SGuillaume Naultfi
539