291 lines · bash
1#!/bin/bash2# SPDX-License-Identifier: GPL-2.03 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)80readonly SMCROUTEDIR="$(mktemp -d)"81ERR=482err=083 84exit_cleanup()85{86 for ns in "$@"; do87 ip netns delete "${ns}" 2>/dev/null || true88 done89 if [ -f "$SMCROUTEDIR/amt.pid" ]; then90 smcpid=$(< $SMCROUTEDIR/amt.pid)91 kill $smcpid92 fi93 rm -rf $SMCROUTEDIR94 95 exit $ERR96}97 98create_namespaces()99{100 ip netns add "${LISTENER}" || exit_cleanup101 ip netns add "${GATEWAY}" || exit_cleanup "${LISTENER}"102 ip netns add "${RELAY}" || exit_cleanup "${LISTENER}" "${GATEWAY}"103 ip netns add "${SOURCE}" || exit_cleanup "${LISTENER}" "${GATEWAY}" \104 "${RELAY}"105}106 107# The trap function handler108#109exit_cleanup_all()110{111 exit_cleanup "${LISTENER}" "${GATEWAY}" "${RELAY}" "${SOURCE}"112}113 114setup_interface()115{116 for ns in "${LISTENER}" "${GATEWAY}" "${RELAY}" "${SOURCE}"; do117 ip -netns "${ns}" link set dev lo up118 done;119 120 ip link add l_gw type veth peer name gw_l121 ip link add gw_relay type veth peer name relay_gw122 ip link add relay_src type veth peer name src_relay123 124 ip link set l_gw netns "${LISTENER}" up125 ip link set gw_l netns "${GATEWAY}" up126 ip link set gw_relay netns "${GATEWAY}" up127 ip link set relay_gw netns "${RELAY}" up128 ip link set relay_src netns "${RELAY}" up129 ip link set src_relay netns "${SOURCE}" up mtu 1400130 131 ip netns exec "${LISTENER}" ip a a 192.168.0.2/24 dev l_gw132 ip netns exec "${LISTENER}" ip r a default via 192.168.0.1 dev l_gw133 ip netns exec "${LISTENER}" ip a a 2001:db8::2/64 dev l_gw134 ip netns exec "${LISTENER}" ip r a default via 2001:db8::1 dev l_gw135 ip netns exec "${LISTENER}" ip a a 239.0.0.1/32 dev l_gw autojoin136 ip netns exec "${LISTENER}" ip a a ff0e::5:6/128 dev l_gw autojoin137 138 ip netns exec "${GATEWAY}" ip a a 192.168.0.1/24 dev gw_l139 ip netns exec "${GATEWAY}" ip a a 2001:db8::1/64 dev gw_l140 ip netns exec "${GATEWAY}" ip a a 10.0.0.1/24 dev gw_relay141 ip netns exec "${GATEWAY}" ip link add br0 type bridge142 ip netns exec "${GATEWAY}" ip link set br0 up143 ip netns exec "${GATEWAY}" ip link set gw_l master br0144 ip netns exec "${GATEWAY}" ip link set gw_l up145 ip netns exec "${GATEWAY}" ip link add amtg master br0 type amt \146 mode gateway local 10.0.0.1 discovery 10.0.0.2 dev gw_relay \147 gateway_port 2268 relay_port 2268148 ip netns exec "${RELAY}" ip a a 10.0.0.2/24 dev relay_gw149 ip netns exec "${RELAY}" ip link add amtr type amt mode relay \150 local 10.0.0.2 dev relay_gw relay_port 2268 max_tunnels 4151 ip netns exec "${RELAY}" ip a a 172.17.0.1/24 dev relay_src152 ip netns exec "${RELAY}" ip a a 2001:db8:3::1/64 dev relay_src153 ip netns exec "${SOURCE}" ip a a 172.17.0.2/24 dev src_relay154 ip netns exec "${SOURCE}" ip a a 2001:db8:3::2/64 dev src_relay155 ip netns exec "${SOURCE}" ip r a default via 172.17.0.1 dev src_relay156 ip netns exec "${SOURCE}" ip r a default via 2001:db8:3::1 dev src_relay157 ip netns exec "${RELAY}" ip link set amtr up158 ip netns exec "${GATEWAY}" ip link set amtg up159}160 161setup_sysctl()162{163 ip netns exec "${RELAY}" sysctl net.ipv4.ip_forward=1 -w -q164}165 166setup_iptables()167{168 ip netns exec "${RELAY}" iptables -t mangle -I PREROUTING \169 -d 239.0.0.1 -j TTL --ttl-set 2170 ip netns exec "${RELAY}" ip6tables -t mangle -I PREROUTING \171 -j HL --hl-set 2172}173 174setup_mcast_routing()175{176 ip netns exec "${RELAY}" smcrouted -P $SMCROUTEDIR/amt.pid177 ip netns exec "${RELAY}" smcroutectl a relay_src \178 172.17.0.2 239.0.0.1 amtr179 ip netns exec "${RELAY}" smcroutectl a relay_src \180 2001:db8:3::2 ff0e::5:6 amtr181}182 183test_remote_ip()184{185 REMOTE=$(ip netns exec "${GATEWAY}" \186 ip -d -j link show amtg | jq .[0].linkinfo.info_data.remote)187 if [ $REMOTE == "\"10.0.0.2\"" ]; then188 printf "TEST: %-60s [ OK ]\n" "amt discovery"189 else190 printf "TEST: %-60s [FAIL]\n" "amt discovery"191 ERR=1192 fi193}194 195send_mcast_torture4()196{197 ip netns exec "${SOURCE}" bash -c \198 'cat /dev/urandom | head -c 1G | nc -w 1 -u 239.0.0.1 4001'199}200 201 202send_mcast_torture6()203{204 ip netns exec "${SOURCE}" bash -c \205 'cat /dev/urandom | head -c 1G | nc -w 1 -u ff0e::5:6 6001'206}207 208check_features()209{210 ip link help 2>&1 | grep -q amt211 if [ $? -ne 0 ]; then212 echo "Missing amt support in iproute2" >&2213 exit_cleanup214 fi215}216 217test_ipv4_forward()218{219 RESULT4=$(ip netns exec "${LISTENER}" timeout 15 socat - UDP4-LISTEN:4000,readbytes=128 || true)220 if echo "$RESULT4" | grep -q "172.17.0.2"; then221 printf "TEST: %-60s [ OK ]\n" "IPv4 amt multicast forwarding"222 exit 0223 else224 printf "TEST: %-60s [FAIL]\n" "IPv4 amt multicast forwarding"225 exit 1226 fi227}228 229test_ipv6_forward()230{231 RESULT6=$(ip netns exec "${LISTENER}" timeout 15 socat - UDP6-LISTEN:6000,readbytes=128 || true)232 if echo "$RESULT6" | grep -q "2001:db8:3::2"; then233 printf "TEST: %-60s [ OK ]\n" "IPv6 amt multicast forwarding"234 exit 0235 else236 printf "TEST: %-60s [FAIL]\n" "IPv6 amt multicast forwarding"237 exit 1238 fi239}240 241send_mcast4()242{243 sleep 2244 ip netns exec "${SOURCE}" bash -c \245 'printf "%s %128s" 172.17.0.2 | nc -w 1 -u 239.0.0.1 4000' &246}247 248send_mcast6()249{250 sleep 2251 ip netns exec "${SOURCE}" bash -c \252 'printf "%s %128s" 2001:db8:3::2 | nc -w 1 -u ff0e::5:6 6000' &253}254 255check_features256 257create_namespaces258 259set -e260trap exit_cleanup_all EXIT261 262setup_interface263setup_sysctl264setup_iptables265setup_mcast_routing266test_remote_ip267test_ipv4_forward &268pid=$!269send_mcast4270wait $pid || err=$?271if [ $err -eq 1 ]; then272 ERR=1273fi274test_ipv6_forward &275pid=$!276send_mcast6277wait $pid || err=$?278if [ $err -eq 1 ]; then279 ERR=1280fi281send_mcast_torture4282printf "TEST: %-60s [ OK ]\n" "IPv4 amt traffic forwarding torture"283send_mcast_torture6284printf "TEST: %-60s [ OK ]\n" "IPv6 amt traffic forwarding torture"285sleep 5286if [ "${ERR}" -eq 1 ]; then287 echo "Some tests failed." >&2288else289 ERR=0290fi291