1c08e8baeSTaehee Yoo#!/bin/sh 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) 80c08e8baeSTaehee YooERR=4 81c08e8baeSTaehee Yooerr=0 82c08e8baeSTaehee Yoo 83c08e8baeSTaehee Yooexit_cleanup() 84c08e8baeSTaehee Yoo{ 85c08e8baeSTaehee Yoo for ns in "$@"; do 86c08e8baeSTaehee Yoo ip netns delete "${ns}" 2>/dev/null || true 87c08e8baeSTaehee Yoo done 88c08e8baeSTaehee Yoo 89c08e8baeSTaehee Yoo exit $ERR 90c08e8baeSTaehee Yoo} 91c08e8baeSTaehee Yoo 92c08e8baeSTaehee Yoocreate_namespaces() 93c08e8baeSTaehee Yoo{ 94c08e8baeSTaehee Yoo ip netns add "${LISTENER}" || exit_cleanup 95c08e8baeSTaehee Yoo ip netns add "${GATEWAY}" || exit_cleanup "${LISTENER}" 96c08e8baeSTaehee Yoo ip netns add "${RELAY}" || exit_cleanup "${LISTENER}" "${GATEWAY}" 97c08e8baeSTaehee Yoo ip netns add "${SOURCE}" || exit_cleanup "${LISTENER}" "${GATEWAY}" \ 98c08e8baeSTaehee Yoo "${RELAY}" 99c08e8baeSTaehee Yoo} 100c08e8baeSTaehee Yoo 101c08e8baeSTaehee Yoo# The trap function handler 102c08e8baeSTaehee Yoo# 103c08e8baeSTaehee Yooexit_cleanup_all() 104c08e8baeSTaehee Yoo{ 105c08e8baeSTaehee Yoo exit_cleanup "${LISTENER}" "${GATEWAY}" "${RELAY}" "${SOURCE}" 106c08e8baeSTaehee Yoo} 107c08e8baeSTaehee Yoo 108c08e8baeSTaehee Yoosetup_interface() 109c08e8baeSTaehee Yoo{ 110c08e8baeSTaehee Yoo for ns in "${LISTENER}" "${GATEWAY}" "${RELAY}" "${SOURCE}"; do 111c08e8baeSTaehee Yoo ip -netns "${ns}" link set dev lo up 112c08e8baeSTaehee Yoo done; 113c08e8baeSTaehee Yoo 114c08e8baeSTaehee Yoo ip link add l_gw type veth peer name gw_l 115c08e8baeSTaehee Yoo ip link add gw_relay type veth peer name relay_gw 116c08e8baeSTaehee Yoo ip link add relay_src type veth peer name src_relay 117c08e8baeSTaehee Yoo 118c08e8baeSTaehee Yoo ip link set l_gw netns "${LISTENER}" up 119c08e8baeSTaehee Yoo ip link set gw_l netns "${GATEWAY}" up 120c08e8baeSTaehee Yoo ip link set gw_relay netns "${GATEWAY}" up 121c08e8baeSTaehee Yoo ip link set relay_gw netns "${RELAY}" up 122c08e8baeSTaehee Yoo ip link set relay_src netns "${RELAY}" up 123c08e8baeSTaehee Yoo ip link set src_relay netns "${SOURCE}" up mtu 1400 124c08e8baeSTaehee Yoo 125c08e8baeSTaehee Yoo ip netns exec "${LISTENER}" ip a a 192.168.0.2/24 dev l_gw 126c08e8baeSTaehee Yoo ip netns exec "${LISTENER}" ip r a default via 192.168.0.1 dev l_gw 127c08e8baeSTaehee Yoo ip netns exec "${LISTENER}" ip a a 2001:db8::2/64 dev l_gw 128c08e8baeSTaehee Yoo ip netns exec "${LISTENER}" ip r a default via 2001:db8::1 dev l_gw 129c08e8baeSTaehee Yoo ip netns exec "${LISTENER}" ip a a 239.0.0.1/32 dev l_gw autojoin 130c08e8baeSTaehee Yoo ip netns exec "${LISTENER}" ip a a ff0e::5:6/128 dev l_gw autojoin 131c08e8baeSTaehee Yoo 132c08e8baeSTaehee Yoo ip netns exec "${GATEWAY}" ip a a 192.168.0.1/24 dev gw_l 133c08e8baeSTaehee Yoo ip netns exec "${GATEWAY}" ip a a 2001:db8::1/64 dev gw_l 134c08e8baeSTaehee Yoo ip netns exec "${GATEWAY}" ip a a 10.0.0.1/24 dev gw_relay 135c08e8baeSTaehee Yoo ip netns exec "${GATEWAY}" ip link add br0 type bridge 136c08e8baeSTaehee Yoo ip netns exec "${GATEWAY}" ip link set br0 up 137c08e8baeSTaehee Yoo ip netns exec "${GATEWAY}" ip link set gw_l master br0 138c08e8baeSTaehee Yoo ip netns exec "${GATEWAY}" ip link set gw_l up 139c08e8baeSTaehee Yoo ip netns exec "${GATEWAY}" ip link add amtg master br0 type amt \ 140c08e8baeSTaehee Yoo mode gateway local 10.0.0.1 discovery 10.0.0.2 dev gw_relay \ 141c08e8baeSTaehee Yoo gateway_port 2268 relay_port 2268 142c08e8baeSTaehee Yoo ip netns exec "${RELAY}" ip a a 10.0.0.2/24 dev relay_gw 143c08e8baeSTaehee Yoo ip netns exec "${RELAY}" ip link add amtr type amt mode relay \ 144c08e8baeSTaehee Yoo local 10.0.0.2 dev relay_gw relay_port 2268 max_tunnels 4 145c08e8baeSTaehee Yoo ip netns exec "${RELAY}" ip a a 172.17.0.1/24 dev relay_src 146c08e8baeSTaehee Yoo ip netns exec "${RELAY}" ip a a 2001:db8:3::1/64 dev relay_src 147c08e8baeSTaehee Yoo ip netns exec "${SOURCE}" ip a a 172.17.0.2/24 dev src_relay 148c08e8baeSTaehee Yoo ip netns exec "${SOURCE}" ip a a 2001:db8:3::2/64 dev src_relay 149c08e8baeSTaehee Yoo ip netns exec "${SOURCE}" ip r a default via 172.17.0.1 dev src_relay 150c08e8baeSTaehee Yoo ip netns exec "${SOURCE}" ip r a default via 2001:db8:3::1 dev src_relay 151c08e8baeSTaehee Yoo ip netns exec "${RELAY}" ip link set amtr up 152c08e8baeSTaehee Yoo ip netns exec "${GATEWAY}" ip link set amtg up 153c08e8baeSTaehee Yoo} 154c08e8baeSTaehee Yoo 155c08e8baeSTaehee Yoosetup_sysctl() 156c08e8baeSTaehee Yoo{ 157c08e8baeSTaehee Yoo ip netns exec "${RELAY}" sysctl net.ipv4.ip_forward=1 -w -q 158c08e8baeSTaehee Yoo} 159c08e8baeSTaehee Yoo 160c08e8baeSTaehee Yoosetup_iptables() 161c08e8baeSTaehee Yoo{ 162c08e8baeSTaehee Yoo ip netns exec "${RELAY}" iptables -t mangle -I PREROUTING \ 163c08e8baeSTaehee Yoo -d 239.0.0.1 -j TTL --ttl-set 2 164c08e8baeSTaehee Yoo ip netns exec "${RELAY}" ip6tables -t mangle -I PREROUTING \ 165c08e8baeSTaehee Yoo -j HL --hl-set 2 166c08e8baeSTaehee Yoo} 167c08e8baeSTaehee Yoo 168c08e8baeSTaehee Yoosetup_mcast_routing() 169c08e8baeSTaehee Yoo{ 170c08e8baeSTaehee Yoo ip netns exec "${RELAY}" smcrouted 171c08e8baeSTaehee Yoo ip netns exec "${RELAY}" smcroutectl a relay_src \ 172c08e8baeSTaehee Yoo 172.17.0.2 239.0.0.1 amtr 173c08e8baeSTaehee Yoo ip netns exec "${RELAY}" smcroutectl a relay_src \ 174c08e8baeSTaehee Yoo 2001:db8:3::2 ff0e::5:6 amtr 175c08e8baeSTaehee Yoo} 176c08e8baeSTaehee Yoo 177c08e8baeSTaehee Yootest_remote_ip() 178c08e8baeSTaehee Yoo{ 179c08e8baeSTaehee Yoo REMOTE=$(ip netns exec "${GATEWAY}" \ 180c08e8baeSTaehee Yoo ip -d -j link show amtg | jq .[0].linkinfo.info_data.remote) 181c08e8baeSTaehee Yoo if [ $REMOTE == "\"10.0.0.2\"" ]; then 182c08e8baeSTaehee Yoo printf "TEST: %-60s [ OK ]\n" "amt discovery" 183c08e8baeSTaehee Yoo else 184c08e8baeSTaehee Yoo printf "TEST: %-60s [FAIL]\n" "amt discovery" 185c08e8baeSTaehee Yoo ERR=1 186c08e8baeSTaehee Yoo fi 187c08e8baeSTaehee Yoo} 188c08e8baeSTaehee Yoo 189c08e8baeSTaehee Yoosend_mcast_torture4() 190c08e8baeSTaehee Yoo{ 191c08e8baeSTaehee Yoo ip netns exec "${SOURCE}" bash -c \ 192c08e8baeSTaehee Yoo 'cat /dev/urandom | head -c 1G | nc -w 1 -u 239.0.0.1 4001' 193c08e8baeSTaehee Yoo} 194c08e8baeSTaehee Yoo 195c08e8baeSTaehee Yoo 196c08e8baeSTaehee Yoosend_mcast_torture6() 197c08e8baeSTaehee Yoo{ 198c08e8baeSTaehee Yoo ip netns exec "${SOURCE}" bash -c \ 199c08e8baeSTaehee Yoo 'cat /dev/urandom | head -c 1G | nc -w 1 -u ff0e::5:6 6001' 200c08e8baeSTaehee Yoo} 201c08e8baeSTaehee Yoo 202c08e8baeSTaehee Yoocheck_features() 203c08e8baeSTaehee Yoo{ 204c08e8baeSTaehee Yoo ip link help 2>&1 | grep -q amt 205c08e8baeSTaehee Yoo if [ $? -ne 0 ]; then 206c08e8baeSTaehee Yoo echo "Missing amt support in iproute2" >&2 207c08e8baeSTaehee Yoo exit_cleanup 208c08e8baeSTaehee Yoo fi 209c08e8baeSTaehee Yoo} 210c08e8baeSTaehee Yoo 211c08e8baeSTaehee Yootest_ipv4_forward() 212c08e8baeSTaehee Yoo{ 213*1ebaa96fSJakub Kicinski RESULT4=$(ip netns exec "${LISTENER}" timeout 15 socat - UDP4-LISTEN:4000,readbytes=128 || true) 214*1ebaa96fSJakub Kicinski if echo "$RESULT4" | grep -q "172.17.0.2"; then 215c08e8baeSTaehee Yoo printf "TEST: %-60s [ OK ]\n" "IPv4 amt multicast forwarding" 216c08e8baeSTaehee Yoo exit 0 217c08e8baeSTaehee Yoo else 218c08e8baeSTaehee Yoo printf "TEST: %-60s [FAIL]\n" "IPv4 amt multicast forwarding" 219c08e8baeSTaehee Yoo exit 1 220c08e8baeSTaehee Yoo fi 221c08e8baeSTaehee Yoo} 222c08e8baeSTaehee Yoo 223c08e8baeSTaehee Yootest_ipv6_forward() 224c08e8baeSTaehee Yoo{ 225*1ebaa96fSJakub Kicinski RESULT6=$(ip netns exec "${LISTENER}" timeout 15 socat - UDP6-LISTEN:6000,readbytes=128 || true) 226*1ebaa96fSJakub Kicinski if echo "$RESULT6" | grep -q "2001:db8:3::2"; then 227c08e8baeSTaehee Yoo printf "TEST: %-60s [ OK ]\n" "IPv6 amt multicast forwarding" 228c08e8baeSTaehee Yoo exit 0 229c08e8baeSTaehee Yoo else 230c08e8baeSTaehee Yoo printf "TEST: %-60s [FAIL]\n" "IPv6 amt multicast forwarding" 231c08e8baeSTaehee Yoo exit 1 232c08e8baeSTaehee Yoo fi 233c08e8baeSTaehee Yoo} 234c08e8baeSTaehee Yoo 235c08e8baeSTaehee Yoosend_mcast4() 236c08e8baeSTaehee Yoo{ 237c08e8baeSTaehee Yoo sleep 2 238c08e8baeSTaehee Yoo ip netns exec "${SOURCE}" bash -c \ 239*1ebaa96fSJakub Kicinski 'printf "%s %128s" 172.17.0.2 | nc -w 1 -u 239.0.0.1 4000' & 240c08e8baeSTaehee Yoo} 241c08e8baeSTaehee Yoo 242c08e8baeSTaehee Yoosend_mcast6() 243c08e8baeSTaehee Yoo{ 244c08e8baeSTaehee Yoo sleep 2 245c08e8baeSTaehee Yoo ip netns exec "${SOURCE}" bash -c \ 246*1ebaa96fSJakub Kicinski 'printf "%s %128s" 2001:db8:3::2 | nc -w 1 -u ff0e::5:6 6000' & 247c08e8baeSTaehee Yoo} 248c08e8baeSTaehee Yoo 249c08e8baeSTaehee Yoocheck_features 250c08e8baeSTaehee Yoo 251c08e8baeSTaehee Yoocreate_namespaces 252c08e8baeSTaehee Yoo 253c08e8baeSTaehee Yooset -e 254c08e8baeSTaehee Yootrap exit_cleanup_all EXIT 255c08e8baeSTaehee Yoo 256c08e8baeSTaehee Yoosetup_interface 257c08e8baeSTaehee Yoosetup_sysctl 258c08e8baeSTaehee Yoosetup_iptables 259c08e8baeSTaehee Yoosetup_mcast_routing 260c08e8baeSTaehee Yootest_remote_ip 261c08e8baeSTaehee Yootest_ipv4_forward & 262c08e8baeSTaehee Yoopid=$! 263c08e8baeSTaehee Yoosend_mcast4 264c08e8baeSTaehee Yoowait $pid || err=$? 265c08e8baeSTaehee Yooif [ $err -eq 1 ]; then 266c08e8baeSTaehee Yoo ERR=1 267c08e8baeSTaehee Yoofi 268c08e8baeSTaehee Yootest_ipv6_forward & 269c08e8baeSTaehee Yoopid=$! 270c08e8baeSTaehee Yoosend_mcast6 271c08e8baeSTaehee Yoowait $pid || err=$? 272c08e8baeSTaehee Yooif [ $err -eq 1 ]; then 273c08e8baeSTaehee Yoo ERR=1 274c08e8baeSTaehee Yoofi 275c08e8baeSTaehee Yoosend_mcast_torture4 276c08e8baeSTaehee Yooprintf "TEST: %-60s [ OK ]\n" "IPv4 amt traffic forwarding torture" 277c08e8baeSTaehee Yoosend_mcast_torture6 278c08e8baeSTaehee Yooprintf "TEST: %-60s [ OK ]\n" "IPv6 amt traffic forwarding torture" 279c08e8baeSTaehee Yoosleep 5 280c08e8baeSTaehee Yooif [ "${ERR}" -eq 1 ]; then 281c08e8baeSTaehee Yoo echo "Some tests failed." >&2 282c08e8baeSTaehee Yooelse 283c08e8baeSTaehee Yoo ERR=0 284c08e8baeSTaehee Yoofi 285