xref: /openbmc/linux/tools/testing/selftests/net/bareudp.sh (revision 1ccd58331f6f2af73758e572f8aa0215b0cacc0e)
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
237*1ccd5833SGuillaume Nault
238*1ccd5833SGuillaume Nault	# The intermediate namespaces don't have routes for the reverse path,
239*1ccd5833SGuillaume Nault	# as it will be handled by tc. So we need to ensure that rp_filter is
240*1ccd5833SGuillaume Nault	# not going to block the traffic.
241*1ccd5833SGuillaume Nault	ip netns exec "${NS1}" sysctl -qw net.ipv4.conf.default.rp_filter=0
242*1ccd5833SGuillaume Nault	ip netns exec "${NS2}" sysctl -qw net.ipv4.conf.default.rp_filter=0
243bbbc7aa4SGuillaume Nault}
244bbbc7aa4SGuillaume Nault
245bbbc7aa4SGuillaume Naultsetup_overlay_ipv6()
246bbbc7aa4SGuillaume Nault{
247bbbc7aa4SGuillaume Nault	# Add the overlay IP addresses and route them through the veth devices
248bbbc7aa4SGuillaume Nault	ip -netns "${NS0}" address add 2001:db8::100/128 dev lo
249bbbc7aa4SGuillaume Nault	ip -netns "${NS3}" address add 2001:db8::103/128 dev lo
250bbbc7aa4SGuillaume Nault	ip -netns "${NS0}" route add 2001:db8::103/128 src 2001:db8::100 via 2001:db8::11
251bbbc7aa4SGuillaume Nault	ip -netns "${NS3}" route add 2001:db8::100/128 src 2001:db8::103 via 2001:db8::32
252bbbc7aa4SGuillaume Nault
253bbbc7aa4SGuillaume Nault	# Route the overlay addresses in the intermediate namespaces
254bbbc7aa4SGuillaume Nault	# (used after bareudp decapsulation)
255bbbc7aa4SGuillaume Nault	ip netns exec "${NS1}" sysctl -qw net.ipv6.conf.all.forwarding=1
256bbbc7aa4SGuillaume Nault	ip netns exec "${NS2}" sysctl -qw net.ipv6.conf.all.forwarding=1
257bbbc7aa4SGuillaume Nault	ip -netns "${NS1}" route add 2001:db8::100/128 via 2001:db8::10
258bbbc7aa4SGuillaume Nault	ip -netns "${NS2}" route add 2001:db8::103/128 via 2001:db8::33
259bbbc7aa4SGuillaume Nault}
260bbbc7aa4SGuillaume Nault
261bbbc7aa4SGuillaume Naultsetup_overlay_mpls()
262bbbc7aa4SGuillaume Nault{
263bbbc7aa4SGuillaume Nault	# Add specific overlay IP addresses, routed over MPLS
264bbbc7aa4SGuillaume Nault	ip -netns "${NS0}" address add 2001:db8::200/128 dev lo
265bbbc7aa4SGuillaume Nault	ip -netns "${NS3}" address add 2001:db8::203/128 dev lo
266bbbc7aa4SGuillaume Nault	ip -netns "${NS0}" route add 2001:db8::203/128 src 2001:db8::200 encap mpls 203 via 2001:db8::11
267bbbc7aa4SGuillaume Nault	ip -netns "${NS3}" route add 2001:db8::200/128 src 2001:db8::203 encap mpls 200 via 2001:db8::32
268bbbc7aa4SGuillaume Nault
269bbbc7aa4SGuillaume Nault	# Route the MPLS packets in the intermediate namespaces
270bbbc7aa4SGuillaume Nault	# (used after bareudp decapsulation)
271bbbc7aa4SGuillaume Nault	ip netns exec "${NS1}" sysctl -qw net.mpls.platform_labels=256
272bbbc7aa4SGuillaume Nault	ip netns exec "${NS2}" sysctl -qw net.mpls.platform_labels=256
273bbbc7aa4SGuillaume Nault	ip -netns "${NS1}" -family mpls route add 200 via inet6 2001:db8::10
274bbbc7aa4SGuillaume Nault	ip -netns "${NS2}" -family mpls route add 203 via inet6 2001:db8::33
275bbbc7aa4SGuillaume Nault}
276bbbc7aa4SGuillaume Nault
277bbbc7aa4SGuillaume Nault# Run "ping" from NS0 and print the result
278bbbc7aa4SGuillaume Nault#
279bbbc7aa4SGuillaume Nault# Parameters:
280bbbc7aa4SGuillaume Nault#
281bbbc7aa4SGuillaume Nault#   * $1: the variant of ping to use (normally either "ping" or "ping6"),
282bbbc7aa4SGuillaume Nault#   * $2: the IP address to ping,
283bbbc7aa4SGuillaume Nault#   * $3: a human readable description of the purpose of the test.
284bbbc7aa4SGuillaume Nault#
285bbbc7aa4SGuillaume Nault# If the test fails and PAUSE_ON_FAIL is active, the user is given the
286bbbc7aa4SGuillaume Nault# possibility to continue with the next test or to quit immediately.
287bbbc7aa4SGuillaume Nault#
288bbbc7aa4SGuillaume Naultping_test_one()
289bbbc7aa4SGuillaume Nault{
290bbbc7aa4SGuillaume Nault	local PING="$1"; readonly PING
291bbbc7aa4SGuillaume Nault	local IP="$2"; readonly IP
292bbbc7aa4SGuillaume Nault	local MSG="$3"; readonly MSG
293bbbc7aa4SGuillaume Nault	local RET
294bbbc7aa4SGuillaume Nault
295bbbc7aa4SGuillaume Nault	printf "TEST: %-60s  " "${MSG}"
296bbbc7aa4SGuillaume Nault
297bbbc7aa4SGuillaume Nault	set +e
298bbbc7aa4SGuillaume Nault	ip netns exec "${NS0}" "${PING}" -w 5 -c 1 "${IP}" > /dev/null 2>&1
299bbbc7aa4SGuillaume Nault	RET=$?
300bbbc7aa4SGuillaume Nault	set -e
301bbbc7aa4SGuillaume Nault
302bbbc7aa4SGuillaume Nault	if [ "${RET}" -eq 0 ]; then
303bbbc7aa4SGuillaume Nault		printf "[ OK ]\n"
304bbbc7aa4SGuillaume Nault	else
305bbbc7aa4SGuillaume Nault		ERR=1
306bbbc7aa4SGuillaume Nault		printf "[FAIL]\n"
307bbbc7aa4SGuillaume Nault		if [ "${PAUSE_ON_FAIL}" = "yes" ]; then
308bbbc7aa4SGuillaume Nault			printf "\nHit enter to continue, 'q' to quit\n"
309bbbc7aa4SGuillaume Nault			read a
310bbbc7aa4SGuillaume Nault			if [ "$a" = "q" ]; then
311bbbc7aa4SGuillaume Nault				exit 1
312bbbc7aa4SGuillaume Nault			fi
313bbbc7aa4SGuillaume Nault		fi
314bbbc7aa4SGuillaume Nault	fi
315bbbc7aa4SGuillaume Nault}
316bbbc7aa4SGuillaume Nault
317bbbc7aa4SGuillaume Nault# Run reachability tests
318bbbc7aa4SGuillaume Nault#
319bbbc7aa4SGuillaume Nault# Parameters:
320bbbc7aa4SGuillaume Nault#
321bbbc7aa4SGuillaume Nault#   * $1: human readable string describing the underlay protocol.
322bbbc7aa4SGuillaume Nault#
323bbbc7aa4SGuillaume Nault# $IPV4, $IPV6, $MPLS_UC and $MULTIPROTO are inherited from the calling
324bbbc7aa4SGuillaume Nault# function.
325bbbc7aa4SGuillaume Nault#
326bbbc7aa4SGuillaume Naultping_test()
327bbbc7aa4SGuillaume Nault{
328bbbc7aa4SGuillaume Nault	local UNDERLAY="$1"; readonly UNDERLAY
329bbbc7aa4SGuillaume Nault	local MODE
330bbbc7aa4SGuillaume Nault	local MSG
331bbbc7aa4SGuillaume Nault
332bbbc7aa4SGuillaume Nault	if [ "${MULTIPROTO}" = "multiproto" ]; then
333bbbc7aa4SGuillaume Nault		MODE=" (multiproto mode)"
334bbbc7aa4SGuillaume Nault	else
335bbbc7aa4SGuillaume Nault		MODE=""
336bbbc7aa4SGuillaume Nault	fi
337bbbc7aa4SGuillaume Nault
338bbbc7aa4SGuillaume Nault	if [ $IPV4 ]; then
339bbbc7aa4SGuillaume Nault		ping_test_one "ping" "192.0.2.103" "IPv4 packets over ${UNDERLAY}${MODE}"
340bbbc7aa4SGuillaume Nault	fi
341bbbc7aa4SGuillaume Nault	if [ $IPV6 ]; then
342bbbc7aa4SGuillaume Nault		ping_test_one "${PING6}" "2001:db8::103" "IPv6 packets over ${UNDERLAY}${MODE}"
343bbbc7aa4SGuillaume Nault	fi
344bbbc7aa4SGuillaume Nault	if [ $MPLS_UC ]; then
345bbbc7aa4SGuillaume Nault		ping_test_one "${PING6}" "2001:db8::203" "Unicast MPLS packets over ${UNDERLAY}${MODE}"
346bbbc7aa4SGuillaume Nault	fi
347bbbc7aa4SGuillaume Nault}
348bbbc7aa4SGuillaume Nault
349bbbc7aa4SGuillaume Nault# Set up a bareudp overlay and run reachability tests over IPv4 and IPv6
350bbbc7aa4SGuillaume Nault#
351bbbc7aa4SGuillaume Nault# Parameters:
352bbbc7aa4SGuillaume Nault#
353bbbc7aa4SGuillaume Nault#   * $1: the packet type (protocol) to be handled by bareudp,
354bbbc7aa4SGuillaume Nault#   * $2: a flag to activate or deactivate bareudp's "multiproto" mode.
355bbbc7aa4SGuillaume Nault#
356bbbc7aa4SGuillaume Naulttest_overlay()
357bbbc7aa4SGuillaume Nault{
358bbbc7aa4SGuillaume Nault	local ETHERTYPE="$1"; readonly ETHERTYPE
359bbbc7aa4SGuillaume Nault	local MULTIPROTO="$2"; readonly MULTIPROTO
360bbbc7aa4SGuillaume Nault	local IPV4
361bbbc7aa4SGuillaume Nault	local IPV6
362bbbc7aa4SGuillaume Nault	local MPLS_UC
363bbbc7aa4SGuillaume Nault
364bbbc7aa4SGuillaume Nault	case "${ETHERTYPE}" in
365bbbc7aa4SGuillaume Nault		"ipv4")
366bbbc7aa4SGuillaume Nault			IPV4="ipv4"
367bbbc7aa4SGuillaume Nault			if [ "${MULTIPROTO}" = "multiproto" ]; then
368bbbc7aa4SGuillaume Nault				IPV6="ipv6"
369bbbc7aa4SGuillaume Nault			else
370bbbc7aa4SGuillaume Nault				IPV6=""
371bbbc7aa4SGuillaume Nault			fi
372bbbc7aa4SGuillaume Nault			MPLS_UC=""
373bbbc7aa4SGuillaume Nault			;;
374bbbc7aa4SGuillaume Nault		"ipv6")
375bbbc7aa4SGuillaume Nault			IPV6="ipv6"
376bbbc7aa4SGuillaume Nault			IPV4=""
377bbbc7aa4SGuillaume Nault			MPLS_UC=""
378bbbc7aa4SGuillaume Nault			;;
379bbbc7aa4SGuillaume Nault		"mpls_uc")
380bbbc7aa4SGuillaume Nault			MPLS_UC="mpls_uc"
381bbbc7aa4SGuillaume Nault			IPV4=""
382bbbc7aa4SGuillaume Nault			IPV6=""
383bbbc7aa4SGuillaume Nault			;;
384bbbc7aa4SGuillaume Nault		*)
385bbbc7aa4SGuillaume Nault			exit 1
386bbbc7aa4SGuillaume Nault			;;
387bbbc7aa4SGuillaume Nault	esac
388bbbc7aa4SGuillaume Nault	readonly IPV4
389bbbc7aa4SGuillaume Nault	readonly IPV6
390bbbc7aa4SGuillaume Nault	readonly MPLS_UC
391bbbc7aa4SGuillaume Nault
392bbbc7aa4SGuillaume Nault	# Create the bareudp devices in the intermediate namespaces
393bbbc7aa4SGuillaume Nault	ip -netns "${NS1}" link add name bareudp_ns1 up type bareudp dstport 6635 ethertype "${ETHERTYPE}" "${MULTIPROTO}"
394bbbc7aa4SGuillaume Nault	ip -netns "${NS2}" link add name bareudp_ns2 up type bareudp dstport 6635 ethertype "${ETHERTYPE}" "${MULTIPROTO}"
395bbbc7aa4SGuillaume Nault
396bbbc7aa4SGuillaume Nault	# IPv4 over UDPv4
397bbbc7aa4SGuillaume Nault	if [ $IPV4 ]; then
398bbbc7aa4SGuillaume Nault		# Encapsulation instructions for bareudp over IPv4
399bbbc7aa4SGuillaume Nault		tc -netns "${NS1}" filter add dev veth10 ingress protocol ipv4         \
400bbbc7aa4SGuillaume Nault			flower dst_ip 192.0.2.103/32                                   \
401bbbc7aa4SGuillaume Nault			action tunnel_key set src_ip 192.0.2.21 dst_ip 192.0.2.22 id 0 \
402bbbc7aa4SGuillaume Nault			action mirred egress redirect dev bareudp_ns1
403bbbc7aa4SGuillaume Nault		tc -netns "${NS2}" filter add dev veth23 ingress protocol ipv4         \
404bbbc7aa4SGuillaume Nault			flower dst_ip 192.0.2.100/32                                   \
405bbbc7aa4SGuillaume Nault			action tunnel_key set src_ip 192.0.2.22 dst_ip 192.0.2.21 id 0 \
406bbbc7aa4SGuillaume Nault			action mirred egress redirect dev bareudp_ns2
407bbbc7aa4SGuillaume Nault	fi
408bbbc7aa4SGuillaume Nault
409bbbc7aa4SGuillaume Nault	# IPv6 over UDPv4
410bbbc7aa4SGuillaume Nault	if [ $IPV6 ]; then
411bbbc7aa4SGuillaume Nault		# Encapsulation instructions for bareudp over IPv4
412bbbc7aa4SGuillaume Nault		tc -netns "${NS1}" filter add dev veth10 ingress protocol ipv6         \
413bbbc7aa4SGuillaume Nault			flower dst_ip 2001:db8::103/128                                \
414bbbc7aa4SGuillaume Nault			action tunnel_key set src_ip 192.0.2.21 dst_ip 192.0.2.22 id 0 \
415bbbc7aa4SGuillaume Nault			action mirred egress redirect dev bareudp_ns1
416bbbc7aa4SGuillaume Nault		tc -netns "${NS2}" filter add dev veth23 ingress protocol ipv6         \
417bbbc7aa4SGuillaume Nault			flower dst_ip 2001:db8::100/128                                \
418bbbc7aa4SGuillaume Nault			action tunnel_key set src_ip 192.0.2.22 dst_ip 192.0.2.21 id 0 \
419bbbc7aa4SGuillaume Nault			action mirred egress redirect dev bareudp_ns2
420bbbc7aa4SGuillaume Nault	fi
421bbbc7aa4SGuillaume Nault
422bbbc7aa4SGuillaume Nault	# MPLS (unicast) over UDPv4
423bbbc7aa4SGuillaume Nault	if [ $MPLS_UC ]; then
424bbbc7aa4SGuillaume Nault		ip netns exec "${NS1}" sysctl -qw net.mpls.conf.bareudp_ns1.input=1
425bbbc7aa4SGuillaume Nault		ip netns exec "${NS2}" sysctl -qw net.mpls.conf.bareudp_ns2.input=1
426bbbc7aa4SGuillaume Nault
427bbbc7aa4SGuillaume Nault		# Encapsulation instructions for bareudp over IPv4
428bbbc7aa4SGuillaume Nault		tc -netns "${NS1}" filter add dev veth10 ingress protocol mpls_uc      \
429bbbc7aa4SGuillaume Nault			flower mpls_label 203                                          \
430bbbc7aa4SGuillaume Nault			action tunnel_key set src_ip 192.0.2.21 dst_ip 192.0.2.22 id 0 \
431bbbc7aa4SGuillaume Nault			action mirred egress redirect dev bareudp_ns1
432bbbc7aa4SGuillaume Nault		tc -netns "${NS2}" filter add dev veth23 ingress protocol mpls_uc      \
433bbbc7aa4SGuillaume Nault			flower mpls_label 200                                          \
434bbbc7aa4SGuillaume Nault			action tunnel_key set src_ip 192.0.2.22 dst_ip 192.0.2.21 id 0 \
435bbbc7aa4SGuillaume Nault			action mirred egress redirect dev bareudp_ns2
436bbbc7aa4SGuillaume Nault	fi
437bbbc7aa4SGuillaume Nault
438bbbc7aa4SGuillaume Nault	# Test IPv4 underlay
439bbbc7aa4SGuillaume Nault	ping_test "UDPv4"
440bbbc7aa4SGuillaume Nault
441bbbc7aa4SGuillaume Nault	# Cleanup bareudp encapsulation instructions, as they were specific to
442bbbc7aa4SGuillaume Nault	# the IPv4 underlay, before setting up and testing the IPv6 underlay
443bbbc7aa4SGuillaume Nault	tc -netns "${NS1}" filter delete dev veth10 ingress
444bbbc7aa4SGuillaume Nault	tc -netns "${NS2}" filter delete dev veth23 ingress
445bbbc7aa4SGuillaume Nault
446bbbc7aa4SGuillaume Nault	# IPv4 over UDPv6
447bbbc7aa4SGuillaume Nault	if [ $IPV4 ]; then
448bbbc7aa4SGuillaume Nault		# New encapsulation instructions for bareudp over IPv6
449bbbc7aa4SGuillaume Nault		tc -netns "${NS1}" filter add dev veth10 ingress protocol ipv4             \
450bbbc7aa4SGuillaume Nault			flower dst_ip 192.0.2.103/32                                       \
451bbbc7aa4SGuillaume Nault			action tunnel_key set src_ip 2001:db8::21 dst_ip 2001:db8::22 id 0 \
452bbbc7aa4SGuillaume Nault			action mirred egress redirect dev bareudp_ns1
453bbbc7aa4SGuillaume Nault		tc -netns "${NS2}" filter add dev veth23 ingress protocol ipv4             \
454bbbc7aa4SGuillaume Nault			flower dst_ip 192.0.2.100/32                                       \
455bbbc7aa4SGuillaume Nault			action tunnel_key set src_ip 2001:db8::22 dst_ip 2001:db8::21 id 0 \
456bbbc7aa4SGuillaume Nault			action mirred egress redirect dev bareudp_ns2
457bbbc7aa4SGuillaume Nault	fi
458bbbc7aa4SGuillaume Nault
459bbbc7aa4SGuillaume Nault	# IPv6 over UDPv6
460bbbc7aa4SGuillaume Nault	if [ $IPV6 ]; then
461bbbc7aa4SGuillaume Nault		# New encapsulation instructions for bareudp over IPv6
462bbbc7aa4SGuillaume Nault		tc -netns "${NS1}" filter add dev veth10 ingress protocol ipv6             \
463bbbc7aa4SGuillaume Nault			flower dst_ip 2001:db8::103/128                                    \
464bbbc7aa4SGuillaume Nault			action tunnel_key set src_ip 2001:db8::21 dst_ip 2001:db8::22 id 0 \
465bbbc7aa4SGuillaume Nault			action mirred egress redirect dev bareudp_ns1
466bbbc7aa4SGuillaume Nault		tc -netns "${NS2}" filter add dev veth23 ingress protocol ipv6             \
467bbbc7aa4SGuillaume Nault			flower dst_ip 2001:db8::100/128                                    \
468bbbc7aa4SGuillaume Nault			action tunnel_key set src_ip 2001:db8::22 dst_ip 2001:db8::21 id 0 \
469bbbc7aa4SGuillaume Nault			action mirred egress redirect dev bareudp_ns2
470bbbc7aa4SGuillaume Nault	fi
471bbbc7aa4SGuillaume Nault
472bbbc7aa4SGuillaume Nault	# MPLS (unicast) over UDPv6
473bbbc7aa4SGuillaume Nault	if [ $MPLS_UC ]; then
474bbbc7aa4SGuillaume Nault		# New encapsulation instructions for bareudp over IPv6
475bbbc7aa4SGuillaume Nault		tc -netns "${NS1}" filter add dev veth10 ingress protocol mpls_uc          \
476bbbc7aa4SGuillaume Nault			flower mpls_label 203                                              \
477bbbc7aa4SGuillaume Nault			action tunnel_key set src_ip 2001:db8::21 dst_ip 2001:db8::22 id 0 \
478bbbc7aa4SGuillaume Nault			action mirred egress redirect dev bareudp_ns1
479bbbc7aa4SGuillaume Nault		tc -netns "${NS2}" filter add dev veth23 ingress protocol mpls_uc          \
480bbbc7aa4SGuillaume Nault			flower mpls_label 200                                              \
481bbbc7aa4SGuillaume Nault			action tunnel_key set src_ip 2001:db8::22 dst_ip 2001:db8::21 id 0 \
482bbbc7aa4SGuillaume Nault			action mirred egress redirect dev bareudp_ns2
483bbbc7aa4SGuillaume Nault	fi
484bbbc7aa4SGuillaume Nault
485bbbc7aa4SGuillaume Nault	# Test IPv6 underlay
486bbbc7aa4SGuillaume Nault	ping_test "UDPv6"
487bbbc7aa4SGuillaume Nault
488bbbc7aa4SGuillaume Nault	tc -netns "${NS1}" filter delete dev veth10 ingress
489bbbc7aa4SGuillaume Nault	tc -netns "${NS2}" filter delete dev veth23 ingress
490bbbc7aa4SGuillaume Nault	ip -netns "${NS1}" link delete bareudp_ns1
491bbbc7aa4SGuillaume Nault	ip -netns "${NS2}" link delete bareudp_ns2
492bbbc7aa4SGuillaume Nault}
493bbbc7aa4SGuillaume Nault
494bbbc7aa4SGuillaume Naultcheck_features()
495bbbc7aa4SGuillaume Nault{
496bbbc7aa4SGuillaume Nault	ip link help 2>&1 | grep -q bareudp
497bbbc7aa4SGuillaume Nault	if [ $? -ne 0 ]; then
498bbbc7aa4SGuillaume Nault		echo "Missing bareudp support in iproute2" >&2
499bbbc7aa4SGuillaume Nault		exit_cleanup
500bbbc7aa4SGuillaume Nault	fi
501bbbc7aa4SGuillaume Nault
502bbbc7aa4SGuillaume Nault	# Use ping6 on systems where ping doesn't handle IPv6
503bbbc7aa4SGuillaume Nault	ping -w 1 -c 1 ::1 > /dev/null 2>&1 || PING6="ping6"
504bbbc7aa4SGuillaume Nault}
505bbbc7aa4SGuillaume Nault
506bbbc7aa4SGuillaume Naultusage()
507bbbc7aa4SGuillaume Nault{
508bbbc7aa4SGuillaume Nault	echo "Usage: $0 [-p]"
509bbbc7aa4SGuillaume Nault	exit 1
510bbbc7aa4SGuillaume Nault}
511bbbc7aa4SGuillaume Nault
512bbbc7aa4SGuillaume Naultwhile getopts :p o
513bbbc7aa4SGuillaume Naultdo
514bbbc7aa4SGuillaume Nault	case $o in
515bbbc7aa4SGuillaume Nault		p) PAUSE_ON_FAIL="yes";;
516bbbc7aa4SGuillaume Nault		*) usage;;
517bbbc7aa4SGuillaume Nault	esac
518bbbc7aa4SGuillaume Naultdone
519bbbc7aa4SGuillaume Nault
520bbbc7aa4SGuillaume Naultcheck_features
521bbbc7aa4SGuillaume Nault
522bbbc7aa4SGuillaume Nault# Create namespaces before setting up the exit trap.
523bbbc7aa4SGuillaume Nault# Otherwise, exit_cleanup_all() could delete namespaces that were not created
524bbbc7aa4SGuillaume Nault# by this script.
525bbbc7aa4SGuillaume Naultcreate_namespaces
526bbbc7aa4SGuillaume Nault
527bbbc7aa4SGuillaume Naultset -e
528bbbc7aa4SGuillaume Naulttrap exit_cleanup_all EXIT
529bbbc7aa4SGuillaume Nault
530bbbc7aa4SGuillaume Naultsetup_underlay
531bbbc7aa4SGuillaume Naultsetup_overlay_ipv4
532bbbc7aa4SGuillaume Naultsetup_overlay_ipv6
533bbbc7aa4SGuillaume Naultsetup_overlay_mpls
534bbbc7aa4SGuillaume Nault
535bbbc7aa4SGuillaume Naulttest_overlay ipv4 nomultiproto
536bbbc7aa4SGuillaume Naulttest_overlay ipv6 nomultiproto
537bbbc7aa4SGuillaume Naulttest_overlay ipv4 multiproto
538bbbc7aa4SGuillaume Naulttest_overlay mpls_uc nomultiproto
539bbbc7aa4SGuillaume Nault
540bbbc7aa4SGuillaume Naultif [ "${ERR}" -eq 1 ]; then
541bbbc7aa4SGuillaume Nault	echo "Some tests failed." >&2
542bbbc7aa4SGuillaume Naultelse
543bbbc7aa4SGuillaume Nault	ERR=0
544bbbc7aa4SGuillaume Naultfi
545