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