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