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