1 #!/bin/bash 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 76 readonly LISTENER=$(mktemp -u listener-XXXXXXXX) 77 readonly GATEWAY=$(mktemp -u gateway-XXXXXXXX) 78 readonly RELAY=$(mktemp -u relay-XXXXXXXX) 79 readonly SOURCE=$(mktemp -u source-XXXXXXXX) 80 readonly SMCROUTEDIR="$(mktemp -d)" 81 ERR=4 82 err=0 83 84 exit_cleanup() 85 { 86 for ns in "$@"; do 87 ip netns delete "${ns}" 2>/dev/null || true 88 done 89 if [ -f "$SMCROUTEDIR/amt.pid" ]; then 90 smcpid=$(< $SMCROUTEDIR/amt.pid) 91 kill $smcpid 92 fi 93 rm -rf $SMCROUTEDIR 94 95 exit $ERR 96 } 97 98 create_namespaces() 99 { 100 ip netns add "${LISTENER}" || exit_cleanup 101 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 handler 108 # 109 exit_cleanup_all() 110 { 111 exit_cleanup "${LISTENER}" "${GATEWAY}" "${RELAY}" "${SOURCE}" 112 } 113 114 setup_interface() 115 { 116 for ns in "${LISTENER}" "${GATEWAY}" "${RELAY}" "${SOURCE}"; do 117 ip -netns "${ns}" link set dev lo up 118 done; 119 120 ip link add l_gw type veth peer name gw_l 121 ip link add gw_relay type veth peer name relay_gw 122 ip link add relay_src type veth peer name src_relay 123 124 ip link set l_gw netns "${LISTENER}" up 125 ip link set gw_l netns "${GATEWAY}" up 126 ip link set gw_relay netns "${GATEWAY}" up 127 ip link set relay_gw netns "${RELAY}" up 128 ip link set relay_src netns "${RELAY}" up 129 ip link set src_relay netns "${SOURCE}" up mtu 1400 130 131 ip netns exec "${LISTENER}" ip a a 192.168.0.2/24 dev l_gw 132 ip netns exec "${LISTENER}" ip r a default via 192.168.0.1 dev l_gw 133 ip netns exec "${LISTENER}" ip a a 2001:db8::2/64 dev l_gw 134 ip netns exec "${LISTENER}" ip r a default via 2001:db8::1 dev l_gw 135 ip netns exec "${LISTENER}" ip a a 239.0.0.1/32 dev l_gw autojoin 136 ip netns exec "${LISTENER}" ip a a ff0e::5:6/128 dev l_gw autojoin 137 138 ip netns exec "${GATEWAY}" ip a a 192.168.0.1/24 dev gw_l 139 ip netns exec "${GATEWAY}" ip a a 2001:db8::1/64 dev gw_l 140 ip netns exec "${GATEWAY}" ip a a 10.0.0.1/24 dev gw_relay 141 ip netns exec "${GATEWAY}" ip link add br0 type bridge 142 ip netns exec "${GATEWAY}" ip link set br0 up 143 ip netns exec "${GATEWAY}" ip link set gw_l master br0 144 ip netns exec "${GATEWAY}" ip link set gw_l up 145 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 2268 148 ip netns exec "${RELAY}" ip a a 10.0.0.2/24 dev relay_gw 149 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 4 151 ip netns exec "${RELAY}" ip a a 172.17.0.1/24 dev relay_src 152 ip netns exec "${RELAY}" ip a a 2001:db8:3::1/64 dev relay_src 153 ip netns exec "${SOURCE}" ip a a 172.17.0.2/24 dev src_relay 154 ip netns exec "${SOURCE}" ip a a 2001:db8:3::2/64 dev src_relay 155 ip netns exec "${SOURCE}" ip r a default via 172.17.0.1 dev src_relay 156 ip netns exec "${SOURCE}" ip r a default via 2001:db8:3::1 dev src_relay 157 ip netns exec "${RELAY}" ip link set amtr up 158 ip netns exec "${GATEWAY}" ip link set amtg up 159 } 160 161 setup_sysctl() 162 { 163 ip netns exec "${RELAY}" sysctl net.ipv4.ip_forward=1 -w -q 164 } 165 166 setup_iptables() 167 { 168 ip netns exec "${RELAY}" iptables -t mangle -I PREROUTING \ 169 -d 239.0.0.1 -j TTL --ttl-set 2 170 ip netns exec "${RELAY}" ip6tables -t mangle -I PREROUTING \ 171 -j HL --hl-set 2 172 } 173 174 setup_mcast_routing() 175 { 176 ip netns exec "${RELAY}" smcrouted -P $SMCROUTEDIR/amt.pid 177 ip netns exec "${RELAY}" smcroutectl a relay_src \ 178 172.17.0.2 239.0.0.1 amtr 179 ip netns exec "${RELAY}" smcroutectl a relay_src \ 180 2001:db8:3::2 ff0e::5:6 amtr 181 } 182 183 test_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\"" ]; then 188 printf "TEST: %-60s [ OK ]\n" "amt discovery" 189 else 190 printf "TEST: %-60s [FAIL]\n" "amt discovery" 191 ERR=1 192 fi 193 } 194 195 send_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 202 send_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 208 check_features() 209 { 210 ip link help 2>&1 | grep -q amt 211 if [ $? -ne 0 ]; then 212 echo "Missing amt support in iproute2" >&2 213 exit_cleanup 214 fi 215 } 216 217 test_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"; then 221 printf "TEST: %-60s [ OK ]\n" "IPv4 amt multicast forwarding" 222 exit 0 223 else 224 printf "TEST: %-60s [FAIL]\n" "IPv4 amt multicast forwarding" 225 exit 1 226 fi 227 } 228 229 test_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"; then 233 printf "TEST: %-60s [ OK ]\n" "IPv6 amt multicast forwarding" 234 exit 0 235 else 236 printf "TEST: %-60s [FAIL]\n" "IPv6 amt multicast forwarding" 237 exit 1 238 fi 239 } 240 241 send_mcast4() 242 { 243 sleep 2 244 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 248 send_mcast6() 249 { 250 sleep 2 251 ip netns exec "${SOURCE}" bash -c \ 252 'printf "%s %128s" 2001:db8:3::2 | nc -w 1 -u ff0e::5:6 6000' & 253 } 254 255 check_features 256 257 create_namespaces 258 259 set -e 260 trap exit_cleanup_all EXIT 261 262 setup_interface 263 setup_sysctl 264 setup_iptables 265 setup_mcast_routing 266 test_remote_ip 267 test_ipv4_forward & 268 pid=$! 269 send_mcast4 270 wait $pid || err=$? 271 if [ $err -eq 1 ]; then 272 ERR=1 273 fi 274 test_ipv6_forward & 275 pid=$! 276 send_mcast6 277 wait $pid || err=$? 278 if [ $err -eq 1 ]; then 279 ERR=1 280 fi 281 send_mcast_torture4 282 printf "TEST: %-60s [ OK ]\n" "IPv4 amt traffic forwarding torture" 283 send_mcast_torture6 284 printf "TEST: %-60s [ OK ]\n" "IPv6 amt traffic forwarding torture" 285 sleep 5 286 if [ "${ERR}" -eq 1 ]; then 287 echo "Some tests failed." >&2 288 else 289 ERR=0 290 fi
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.