xref: /linux/tools/testing/selftests/net/amt.sh (revision a1ff5a7d78a036d6c2178ee5acd6ba4946243800)
1*32266073STaehee Yoo#!/bin/bash
2c08e8baeSTaehee Yoo# SPDX-License-Identifier: GPL-2.0
3c08e8baeSTaehee Yoo
4c08e8baeSTaehee Yoo# Author: Taehee Yoo <ap420073@gmail.com>
5c08e8baeSTaehee Yoo#
6c08e8baeSTaehee Yoo# This script evaluates the AMT driver.
7c08e8baeSTaehee Yoo# There are four network-namespaces, LISTENER, SOURCE, GATEWAY, RELAY.
8c08e8baeSTaehee Yoo# The role of LISTENER is to listen multicast traffic.
9c08e8baeSTaehee Yoo# In order to do that, it send IGMP group join message.
10c08e8baeSTaehee Yoo# The role of SOURCE is to send multicast traffic to listener.
11c08e8baeSTaehee Yoo# The role of GATEWAY is to work Gateway role of AMT interface.
12c08e8baeSTaehee Yoo# The role of RELAY is to work Relay role of AMT interface.
13c08e8baeSTaehee Yoo#
14c08e8baeSTaehee Yoo#
15c08e8baeSTaehee Yoo#       +------------------------+
16c08e8baeSTaehee Yoo#       |    LISTENER netns      |
17c08e8baeSTaehee Yoo#       |                        |
18c08e8baeSTaehee Yoo#       |  +------------------+  |
19c08e8baeSTaehee Yoo#       |  |       l_gw       |  |
20c08e8baeSTaehee Yoo#       |  |  192.168.0.2/24  |  |
21c08e8baeSTaehee Yoo#       |  |  2001:db8::2/64  |  |
22c08e8baeSTaehee Yoo#       |  +------------------+  |
23c08e8baeSTaehee Yoo#       |            .           |
24c08e8baeSTaehee Yoo#       +------------------------+
25c08e8baeSTaehee Yoo#                    .
26c08e8baeSTaehee Yoo#                    .
27c08e8baeSTaehee Yoo#       +-----------------------------------------------------+
28c08e8baeSTaehee Yoo#       |            .         GATEWAY netns                  |
29c08e8baeSTaehee Yoo#       |            .                                        |
30c08e8baeSTaehee Yoo#       |+---------------------------------------------------+|
31c08e8baeSTaehee Yoo#       ||           .          br0                          ||
32c08e8baeSTaehee Yoo#       || +------------------+       +------------------+   ||
33c08e8baeSTaehee Yoo#       || |       gw_l       |       |       amtg       |   ||
34c08e8baeSTaehee Yoo#       || |  192.168.0.1/24  |       +--------+---------+   ||
35c08e8baeSTaehee Yoo#       || |  2001:db8::1/64  |                |             ||
36c08e8baeSTaehee Yoo#       || +------------------+                |             ||
37c08e8baeSTaehee Yoo#       |+-------------------------------------|-------------+|
38c08e8baeSTaehee Yoo#       |                                      |              |
39c08e8baeSTaehee Yoo#       |                             +--------+---------+    |
40c08e8baeSTaehee Yoo#       |                             |     gw_relay     |    |
41c08e8baeSTaehee Yoo#       |                             |    10.0.0.1/24   |    |
42c08e8baeSTaehee Yoo#       |                             +------------------+    |
43c08e8baeSTaehee Yoo#       |                                      .              |
44c08e8baeSTaehee Yoo#       +-----------------------------------------------------+
45c08e8baeSTaehee Yoo#                                              .
46c08e8baeSTaehee Yoo#                                              .
47c08e8baeSTaehee Yoo#       +-----------------------------------------------------+
48c08e8baeSTaehee Yoo#       |                       RELAY netns    .              |
49c08e8baeSTaehee Yoo#       |                             +------------------+    |
50c08e8baeSTaehee Yoo#       |                             |     relay_gw     |    |
51c08e8baeSTaehee Yoo#       |                             |    10.0.0.2/24   |    |
52c08e8baeSTaehee Yoo#       |                             +--------+---------+    |
53c08e8baeSTaehee Yoo#       |                                      |              |
54c08e8baeSTaehee Yoo#       |                                      |              |
55c08e8baeSTaehee Yoo#       |  +------------------+       +--------+---------+    |
56c08e8baeSTaehee Yoo#       |  |     relay_src    |       |       amtr       |    |
57c08e8baeSTaehee Yoo#       |  |   172.17.0.1/24  |       +------------------+    |
58c08e8baeSTaehee Yoo#       |  | 2001:db8:3::1/64 |                               |
59c08e8baeSTaehee Yoo#       |  +------------------+                               |
60c08e8baeSTaehee Yoo#       |            .                                        |
61c08e8baeSTaehee Yoo#       |            .                                        |
62c08e8baeSTaehee Yoo#       +-----------------------------------------------------+
63c08e8baeSTaehee Yoo#                    .
64c08e8baeSTaehee Yoo#                    .
65c08e8baeSTaehee Yoo#       +------------------------+
66c08e8baeSTaehee Yoo#       |            .           |
67c08e8baeSTaehee Yoo#       |  +------------------+  |
68c08e8baeSTaehee Yoo#       |  |     src_relay    |  |
69c08e8baeSTaehee Yoo#       |  |   172.17.0.2/24  |  |
70c08e8baeSTaehee Yoo#       |  | 2001:db8:3::2/64 |  |
71c08e8baeSTaehee Yoo#       |  +------------------+  |
72c08e8baeSTaehee Yoo#       |      SOURCE netns      |
73c08e8baeSTaehee Yoo#       +------------------------+
74c08e8baeSTaehee Yoo#==============================================================================
75c08e8baeSTaehee Yoo
76c08e8baeSTaehee Yooreadonly LISTENER=$(mktemp -u listener-XXXXXXXX)
77c08e8baeSTaehee Yooreadonly GATEWAY=$(mktemp -u gateway-XXXXXXXX)
78c08e8baeSTaehee Yooreadonly RELAY=$(mktemp -u relay-XXXXXXXX)
79c08e8baeSTaehee Yooreadonly SOURCE=$(mktemp -u source-XXXXXXXX)
80cc563e74STaehee Yooreadonly SMCROUTEDIR="$(mktemp -d)"
81c08e8baeSTaehee YooERR=4
82c08e8baeSTaehee Yooerr=0
83c08e8baeSTaehee Yoo
84c08e8baeSTaehee Yooexit_cleanup()
85c08e8baeSTaehee Yoo{
86c08e8baeSTaehee Yoo	for ns in "$@"; do
87c08e8baeSTaehee Yoo		ip netns delete "${ns}" 2>/dev/null || true
88c08e8baeSTaehee Yoo	done
89cc563e74STaehee Yoo	if [ -f "$SMCROUTEDIR/amt.pid" ]; then
90cc563e74STaehee Yoo		smcpid=$(< $SMCROUTEDIR/amt.pid)
91cc563e74STaehee Yoo		kill $smcpid
92cc563e74STaehee Yoo	fi
93cc563e74STaehee Yoo	rm -rf $SMCROUTEDIR
94c08e8baeSTaehee Yoo
95c08e8baeSTaehee Yoo	exit $ERR
96c08e8baeSTaehee Yoo}
97c08e8baeSTaehee Yoo
98c08e8baeSTaehee Yoocreate_namespaces()
99c08e8baeSTaehee Yoo{
100c08e8baeSTaehee Yoo	ip netns add "${LISTENER}" || exit_cleanup
101c08e8baeSTaehee Yoo	ip netns add "${GATEWAY}" || exit_cleanup "${LISTENER}"
102c08e8baeSTaehee Yoo	ip netns add "${RELAY}" || exit_cleanup "${LISTENER}" "${GATEWAY}"
103c08e8baeSTaehee Yoo	ip netns add "${SOURCE}" || exit_cleanup "${LISTENER}" "${GATEWAY}" \
104c08e8baeSTaehee Yoo		"${RELAY}"
105c08e8baeSTaehee Yoo}
106c08e8baeSTaehee Yoo
107c08e8baeSTaehee Yoo# The trap function handler
108c08e8baeSTaehee Yoo#
109c08e8baeSTaehee Yooexit_cleanup_all()
110c08e8baeSTaehee Yoo{
111c08e8baeSTaehee Yoo	exit_cleanup "${LISTENER}" "${GATEWAY}" "${RELAY}" "${SOURCE}"
112c08e8baeSTaehee Yoo}
113c08e8baeSTaehee Yoo
114c08e8baeSTaehee Yoosetup_interface()
115c08e8baeSTaehee Yoo{
116c08e8baeSTaehee Yoo	for ns in "${LISTENER}" "${GATEWAY}" "${RELAY}" "${SOURCE}"; do
117c08e8baeSTaehee Yoo		ip -netns "${ns}" link set dev lo up
118c08e8baeSTaehee Yoo	done;
119c08e8baeSTaehee Yoo
120c08e8baeSTaehee Yoo	ip link add l_gw type veth peer name gw_l
121c08e8baeSTaehee Yoo	ip link add gw_relay type veth peer name relay_gw
122c08e8baeSTaehee Yoo	ip link add relay_src type veth peer name src_relay
123c08e8baeSTaehee Yoo
124c08e8baeSTaehee Yoo	ip link set l_gw netns "${LISTENER}" up
125c08e8baeSTaehee Yoo	ip link set gw_l netns "${GATEWAY}" up
126c08e8baeSTaehee Yoo	ip link set gw_relay netns "${GATEWAY}" up
127c08e8baeSTaehee Yoo	ip link set relay_gw netns "${RELAY}" up
128c08e8baeSTaehee Yoo	ip link set relay_src netns "${RELAY}" up
129c08e8baeSTaehee Yoo	ip link set src_relay netns "${SOURCE}" up mtu 1400
130c08e8baeSTaehee Yoo
131c08e8baeSTaehee Yoo	ip netns exec "${LISTENER}" ip a a 192.168.0.2/24 dev l_gw
132c08e8baeSTaehee Yoo	ip netns exec "${LISTENER}" ip r a default via 192.168.0.1 dev l_gw
133c08e8baeSTaehee Yoo	ip netns exec "${LISTENER}" ip a a 2001:db8::2/64 dev l_gw
134c08e8baeSTaehee Yoo	ip netns exec "${LISTENER}" ip r a default via 2001:db8::1 dev l_gw
135c08e8baeSTaehee Yoo	ip netns exec "${LISTENER}" ip a a 239.0.0.1/32 dev l_gw autojoin
136c08e8baeSTaehee Yoo	ip netns exec "${LISTENER}" ip a a ff0e::5:6/128 dev l_gw autojoin
137c08e8baeSTaehee Yoo
138c08e8baeSTaehee Yoo	ip netns exec "${GATEWAY}" ip a a 192.168.0.1/24 dev gw_l
139c08e8baeSTaehee Yoo	ip netns exec "${GATEWAY}" ip a a 2001:db8::1/64 dev gw_l
140c08e8baeSTaehee Yoo	ip netns exec "${GATEWAY}" ip a a 10.0.0.1/24 dev gw_relay
141c08e8baeSTaehee Yoo	ip netns exec "${GATEWAY}" ip link add br0 type bridge
142c08e8baeSTaehee Yoo	ip netns exec "${GATEWAY}" ip link set br0 up
143c08e8baeSTaehee Yoo	ip netns exec "${GATEWAY}" ip link set gw_l master br0
144c08e8baeSTaehee Yoo	ip netns exec "${GATEWAY}" ip link set gw_l up
145c08e8baeSTaehee Yoo	ip netns exec "${GATEWAY}" ip link add amtg master br0 type amt \
146c08e8baeSTaehee Yoo		mode gateway local 10.0.0.1 discovery 10.0.0.2 dev gw_relay \
147c08e8baeSTaehee Yoo		gateway_port 2268 relay_port 2268
148c08e8baeSTaehee Yoo	ip netns exec "${RELAY}" ip a a 10.0.0.2/24 dev relay_gw
149c08e8baeSTaehee Yoo	ip netns exec "${RELAY}" ip link add amtr type amt mode relay \
150c08e8baeSTaehee Yoo		local 10.0.0.2 dev relay_gw relay_port 2268 max_tunnels 4
151c08e8baeSTaehee Yoo	ip netns exec "${RELAY}" ip a a 172.17.0.1/24 dev relay_src
152c08e8baeSTaehee Yoo	ip netns exec "${RELAY}" ip a a 2001:db8:3::1/64 dev relay_src
153c08e8baeSTaehee Yoo	ip netns exec "${SOURCE}" ip a a 172.17.0.2/24 dev src_relay
154c08e8baeSTaehee Yoo	ip netns exec "${SOURCE}" ip a a 2001:db8:3::2/64 dev src_relay
155c08e8baeSTaehee Yoo	ip netns exec "${SOURCE}" ip r a default via 172.17.0.1 dev src_relay
156c08e8baeSTaehee Yoo	ip netns exec "${SOURCE}" ip r a default via 2001:db8:3::1 dev src_relay
157c08e8baeSTaehee Yoo	ip netns exec "${RELAY}" ip link set amtr up
158c08e8baeSTaehee Yoo	ip netns exec "${GATEWAY}" ip link set amtg up
159c08e8baeSTaehee Yoo}
160c08e8baeSTaehee Yoo
161c08e8baeSTaehee Yoosetup_sysctl()
162c08e8baeSTaehee Yoo{
163c08e8baeSTaehee Yoo	ip netns exec "${RELAY}" sysctl net.ipv4.ip_forward=1 -w -q
164c08e8baeSTaehee Yoo}
165c08e8baeSTaehee Yoo
166c08e8baeSTaehee Yoosetup_iptables()
167c08e8baeSTaehee Yoo{
168c08e8baeSTaehee Yoo	ip netns exec "${RELAY}" iptables -t mangle -I PREROUTING \
169c08e8baeSTaehee Yoo		-d 239.0.0.1 -j TTL --ttl-set 2
170c08e8baeSTaehee Yoo	ip netns exec "${RELAY}" ip6tables -t mangle -I PREROUTING \
171c08e8baeSTaehee Yoo		-j HL --hl-set 2
172c08e8baeSTaehee Yoo}
173c08e8baeSTaehee Yoo
174c08e8baeSTaehee Yoosetup_mcast_routing()
175c08e8baeSTaehee Yoo{
176cc563e74STaehee Yoo	ip netns exec "${RELAY}" smcrouted -P $SMCROUTEDIR/amt.pid
177c08e8baeSTaehee Yoo	ip netns exec "${RELAY}" smcroutectl a relay_src \
178c08e8baeSTaehee Yoo		172.17.0.2 239.0.0.1 amtr
179c08e8baeSTaehee Yoo	ip netns exec "${RELAY}" smcroutectl a relay_src \
180c08e8baeSTaehee Yoo		2001:db8:3::2 ff0e::5:6 amtr
181c08e8baeSTaehee Yoo}
182c08e8baeSTaehee Yoo
183c08e8baeSTaehee Yootest_remote_ip()
184c08e8baeSTaehee Yoo{
185c08e8baeSTaehee Yoo	REMOTE=$(ip netns exec "${GATEWAY}" \
186c08e8baeSTaehee Yoo		ip -d -j link show amtg | jq .[0].linkinfo.info_data.remote)
187c08e8baeSTaehee Yoo	if [ $REMOTE == "\"10.0.0.2\"" ]; then
188c08e8baeSTaehee Yoo		printf "TEST: %-60s  [ OK ]\n" "amt discovery"
189c08e8baeSTaehee Yoo	else
190c08e8baeSTaehee Yoo		printf "TEST: %-60s  [FAIL]\n" "amt discovery"
191c08e8baeSTaehee Yoo		ERR=1
192c08e8baeSTaehee Yoo	fi
193c08e8baeSTaehee Yoo}
194c08e8baeSTaehee Yoo
195c08e8baeSTaehee Yoosend_mcast_torture4()
196c08e8baeSTaehee Yoo{
197c08e8baeSTaehee Yoo	ip netns exec "${SOURCE}" bash -c \
198c08e8baeSTaehee Yoo		'cat /dev/urandom | head -c 1G | nc -w 1 -u 239.0.0.1 4001'
199c08e8baeSTaehee Yoo}
200c08e8baeSTaehee Yoo
201c08e8baeSTaehee Yoo
202c08e8baeSTaehee Yoosend_mcast_torture6()
203c08e8baeSTaehee Yoo{
204c08e8baeSTaehee Yoo	ip netns exec "${SOURCE}" bash -c \
205c08e8baeSTaehee Yoo		'cat /dev/urandom | head -c 1G | nc -w 1 -u ff0e::5:6 6001'
206c08e8baeSTaehee Yoo}
207c08e8baeSTaehee Yoo
208c08e8baeSTaehee Yoocheck_features()
209c08e8baeSTaehee Yoo{
210c08e8baeSTaehee Yoo        ip link help 2>&1 | grep -q amt
211c08e8baeSTaehee Yoo        if [ $? -ne 0 ]; then
212c08e8baeSTaehee Yoo                echo "Missing amt support in iproute2" >&2
213c08e8baeSTaehee Yoo                exit_cleanup
214c08e8baeSTaehee Yoo        fi
215c08e8baeSTaehee Yoo}
216c08e8baeSTaehee Yoo
217c08e8baeSTaehee Yootest_ipv4_forward()
218c08e8baeSTaehee Yoo{
2194c639b6aSJakub Kicinski	RESULT4=$(ip netns exec "${LISTENER}" timeout 15 socat - UDP4-LISTEN:4000,readbytes=128 || true)
2204c639b6aSJakub Kicinski	if echo "$RESULT4" | grep -q "172.17.0.2"; then
221c08e8baeSTaehee Yoo		printf "TEST: %-60s  [ OK ]\n" "IPv4 amt multicast forwarding"
222c08e8baeSTaehee Yoo		exit 0
223c08e8baeSTaehee Yoo	else
224c08e8baeSTaehee Yoo		printf "TEST: %-60s  [FAIL]\n" "IPv4 amt multicast forwarding"
225c08e8baeSTaehee Yoo		exit 1
226c08e8baeSTaehee Yoo	fi
227c08e8baeSTaehee Yoo}
228c08e8baeSTaehee Yoo
229c08e8baeSTaehee Yootest_ipv6_forward()
230c08e8baeSTaehee Yoo{
2314c639b6aSJakub Kicinski	RESULT6=$(ip netns exec "${LISTENER}" timeout 15 socat - UDP6-LISTEN:6000,readbytes=128 || true)
2324c639b6aSJakub Kicinski	if echo "$RESULT6" | grep -q "2001:db8:3::2"; then
233c08e8baeSTaehee Yoo		printf "TEST: %-60s  [ OK ]\n" "IPv6 amt multicast forwarding"
234c08e8baeSTaehee Yoo		exit 0
235c08e8baeSTaehee Yoo	else
236c08e8baeSTaehee Yoo		printf "TEST: %-60s  [FAIL]\n" "IPv6 amt multicast forwarding"
237c08e8baeSTaehee Yoo		exit 1
238c08e8baeSTaehee Yoo	fi
239c08e8baeSTaehee Yoo}
240c08e8baeSTaehee Yoo
241c08e8baeSTaehee Yoosend_mcast4()
242c08e8baeSTaehee Yoo{
243c08e8baeSTaehee Yoo	sleep 2
244c08e8baeSTaehee Yoo	ip netns exec "${SOURCE}" bash -c \
2454c639b6aSJakub Kicinski		'printf "%s %128s" 172.17.0.2 | nc -w 1 -u 239.0.0.1 4000' &
246c08e8baeSTaehee Yoo}
247c08e8baeSTaehee Yoo
248c08e8baeSTaehee Yoosend_mcast6()
249c08e8baeSTaehee Yoo{
250c08e8baeSTaehee Yoo	sleep 2
251c08e8baeSTaehee Yoo	ip netns exec "${SOURCE}" bash -c \
2524c639b6aSJakub Kicinski		'printf "%s %128s" 2001:db8:3::2 | nc -w 1 -u ff0e::5:6 6000' &
253c08e8baeSTaehee Yoo}
254c08e8baeSTaehee Yoo
255c08e8baeSTaehee Yoocheck_features
256c08e8baeSTaehee Yoo
257c08e8baeSTaehee Yoocreate_namespaces
258c08e8baeSTaehee Yoo
259c08e8baeSTaehee Yooset -e
260c08e8baeSTaehee Yootrap exit_cleanup_all EXIT
261c08e8baeSTaehee Yoo
262c08e8baeSTaehee Yoosetup_interface
263c08e8baeSTaehee Yoosetup_sysctl
264c08e8baeSTaehee Yoosetup_iptables
265c08e8baeSTaehee Yoosetup_mcast_routing
266c08e8baeSTaehee Yootest_remote_ip
267c08e8baeSTaehee Yootest_ipv4_forward &
268c08e8baeSTaehee Yoopid=$!
269c08e8baeSTaehee Yoosend_mcast4
270c08e8baeSTaehee Yoowait $pid || err=$?
271c08e8baeSTaehee Yooif [ $err -eq 1 ]; then
272c08e8baeSTaehee Yoo	ERR=1
273c08e8baeSTaehee Yoofi
274c08e8baeSTaehee Yootest_ipv6_forward &
275c08e8baeSTaehee Yoopid=$!
276c08e8baeSTaehee Yoosend_mcast6
277c08e8baeSTaehee Yoowait $pid || err=$?
278c08e8baeSTaehee Yooif [ $err -eq 1 ]; then
279c08e8baeSTaehee Yoo	ERR=1
280c08e8baeSTaehee Yoofi
281c08e8baeSTaehee Yoosend_mcast_torture4
282c08e8baeSTaehee Yooprintf "TEST: %-60s  [ OK ]\n" "IPv4 amt traffic forwarding torture"
283c08e8baeSTaehee Yoosend_mcast_torture6
284c08e8baeSTaehee Yooprintf "TEST: %-60s  [ OK ]\n" "IPv6 amt traffic forwarding torture"
285c08e8baeSTaehee Yoosleep 5
286c08e8baeSTaehee Yooif [ "${ERR}" -eq 1 ]; then
287c08e8baeSTaehee Yoo        echo "Some tests failed." >&2
288c08e8baeSTaehee Yooelse
289c08e8baeSTaehee Yoo        ERR=0
290c08e8baeSTaehee Yoofi
291