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