0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076 readonly LISTENER=$(mktemp -u listener-XXXXXXXX)
0077 readonly GATEWAY=$(mktemp -u gateway-XXXXXXXX)
0078 readonly RELAY=$(mktemp -u relay-XXXXXXXX)
0079 readonly SOURCE=$(mktemp -u source-XXXXXXXX)
0080 ERR=4
0081 err=0
0082
0083 exit_cleanup()
0084 {
0085 for ns in "$@"; do
0086 ip netns delete "${ns}" 2>/dev/null || true
0087 done
0088
0089 exit $ERR
0090 }
0091
0092 create_namespaces()
0093 {
0094 ip netns add "${LISTENER}" || exit_cleanup
0095 ip netns add "${GATEWAY}" || exit_cleanup "${LISTENER}"
0096 ip netns add "${RELAY}" || exit_cleanup "${LISTENER}" "${GATEWAY}"
0097 ip netns add "${SOURCE}" || exit_cleanup "${LISTENER}" "${GATEWAY}" \
0098 "${RELAY}"
0099 }
0100
0101
0102
0103 exit_cleanup_all()
0104 {
0105 exit_cleanup "${LISTENER}" "${GATEWAY}" "${RELAY}" "${SOURCE}"
0106 }
0107
0108 setup_interface()
0109 {
0110 for ns in "${LISTENER}" "${GATEWAY}" "${RELAY}" "${SOURCE}"; do
0111 ip -netns "${ns}" link set dev lo up
0112 done;
0113
0114 ip link add l_gw type veth peer name gw_l
0115 ip link add gw_relay type veth peer name relay_gw
0116 ip link add relay_src type veth peer name src_relay
0117
0118 ip link set l_gw netns "${LISTENER}" up
0119 ip link set gw_l netns "${GATEWAY}" up
0120 ip link set gw_relay netns "${GATEWAY}" up
0121 ip link set relay_gw netns "${RELAY}" up
0122 ip link set relay_src netns "${RELAY}" up
0123 ip link set src_relay netns "${SOURCE}" up mtu 1400
0124
0125 ip netns exec "${LISTENER}" ip a a 192.168.0.2/24 dev l_gw
0126 ip netns exec "${LISTENER}" ip r a default via 192.168.0.1 dev l_gw
0127 ip netns exec "${LISTENER}" ip a a 2001:db8::2/64 dev l_gw
0128 ip netns exec "${LISTENER}" ip r a default via 2001:db8::1 dev l_gw
0129 ip netns exec "${LISTENER}" ip a a 239.0.0.1/32 dev l_gw autojoin
0130 ip netns exec "${LISTENER}" ip a a ff0e::5:6/128 dev l_gw autojoin
0131
0132 ip netns exec "${GATEWAY}" ip a a 192.168.0.1/24 dev gw_l
0133 ip netns exec "${GATEWAY}" ip a a 2001:db8::1/64 dev gw_l
0134 ip netns exec "${GATEWAY}" ip a a 10.0.0.1/24 dev gw_relay
0135 ip netns exec "${GATEWAY}" ip link add br0 type bridge
0136 ip netns exec "${GATEWAY}" ip link set br0 up
0137 ip netns exec "${GATEWAY}" ip link set gw_l master br0
0138 ip netns exec "${GATEWAY}" ip link set gw_l up
0139 ip netns exec "${GATEWAY}" ip link add amtg master br0 type amt \
0140 mode gateway local 10.0.0.1 discovery 10.0.0.2 dev gw_relay \
0141 gateway_port 2268 relay_port 2268
0142 ip netns exec "${RELAY}" ip a a 10.0.0.2/24 dev relay_gw
0143 ip netns exec "${RELAY}" ip link add amtr type amt mode relay \
0144 local 10.0.0.2 dev relay_gw relay_port 2268 max_tunnels 4
0145 ip netns exec "${RELAY}" ip a a 172.17.0.1/24 dev relay_src
0146 ip netns exec "${RELAY}" ip a a 2001:db8:3::1/64 dev relay_src
0147 ip netns exec "${SOURCE}" ip a a 172.17.0.2/24 dev src_relay
0148 ip netns exec "${SOURCE}" ip a a 2001:db8:3::2/64 dev src_relay
0149 ip netns exec "${SOURCE}" ip r a default via 172.17.0.1 dev src_relay
0150 ip netns exec "${SOURCE}" ip r a default via 2001:db8:3::1 dev src_relay
0151 ip netns exec "${RELAY}" ip link set amtr up
0152 ip netns exec "${GATEWAY}" ip link set amtg up
0153 }
0154
0155 setup_sysctl()
0156 {
0157 ip netns exec "${RELAY}" sysctl net.ipv4.ip_forward=1 -w -q
0158 }
0159
0160 setup_iptables()
0161 {
0162 ip netns exec "${RELAY}" iptables -t mangle -I PREROUTING \
0163 -d 239.0.0.1 -j TTL --ttl-set 2
0164 ip netns exec "${RELAY}" ip6tables -t mangle -I PREROUTING \
0165 -j HL --hl-set 2
0166 }
0167
0168 setup_mcast_routing()
0169 {
0170 ip netns exec "${RELAY}" smcrouted
0171 ip netns exec "${RELAY}" smcroutectl a relay_src \
0172 172.17.0.2 239.0.0.1 amtr
0173 ip netns exec "${RELAY}" smcroutectl a relay_src \
0174 2001:db8:3::2 ff0e::5:6 amtr
0175 }
0176
0177 test_remote_ip()
0178 {
0179 REMOTE=$(ip netns exec "${GATEWAY}" \
0180 ip -d -j link show amtg | jq .[0].linkinfo.info_data.remote)
0181 if [ $REMOTE == "\"10.0.0.2\"" ]; then
0182 printf "TEST: %-60s [ OK ]\n" "amt discovery"
0183 else
0184 printf "TEST: %-60s [FAIL]\n" "amt discovery"
0185 ERR=1
0186 fi
0187 }
0188
0189 send_mcast_torture4()
0190 {
0191 ip netns exec "${SOURCE}" bash -c \
0192 'cat /dev/urandom | head -c 1G | nc -w 1 -u 239.0.0.1 4001'
0193 }
0194
0195
0196 send_mcast_torture6()
0197 {
0198 ip netns exec "${SOURCE}" bash -c \
0199 'cat /dev/urandom | head -c 1G | nc -w 1 -u ff0e::5:6 6001'
0200 }
0201
0202 check_features()
0203 {
0204 ip link help 2>&1 | grep -q amt
0205 if [ $? -ne 0 ]; then
0206 echo "Missing amt support in iproute2" >&2
0207 exit_cleanup
0208 fi
0209 }
0210
0211 test_ipv4_forward()
0212 {
0213 RESULT4=$(ip netns exec "${LISTENER}" nc -w 1 -l -u 239.0.0.1 4000)
0214 if [ "$RESULT4" == "172.17.0.2" ]; then
0215 printf "TEST: %-60s [ OK ]\n" "IPv4 amt multicast forwarding"
0216 exit 0
0217 else
0218 printf "TEST: %-60s [FAIL]\n" "IPv4 amt multicast forwarding"
0219 exit 1
0220 fi
0221 }
0222
0223 test_ipv6_forward()
0224 {
0225 RESULT6=$(ip netns exec "${LISTENER}" nc -w 1 -l -u ff0e::5:6 6000)
0226 if [ "$RESULT6" == "2001:db8:3::2" ]; then
0227 printf "TEST: %-60s [ OK ]\n" "IPv6 amt multicast forwarding"
0228 exit 0
0229 else
0230 printf "TEST: %-60s [FAIL]\n" "IPv6 amt multicast forwarding"
0231 exit 1
0232 fi
0233 }
0234
0235 send_mcast4()
0236 {
0237 sleep 2
0238 ip netns exec "${SOURCE}" bash -c \
0239 'echo 172.17.0.2 | nc -w 1 -u 239.0.0.1 4000' &
0240 }
0241
0242 send_mcast6()
0243 {
0244 sleep 2
0245 ip netns exec "${SOURCE}" bash -c \
0246 'echo 2001:db8:3::2 | nc -w 1 -u ff0e::5:6 6000' &
0247 }
0248
0249 check_features
0250
0251 create_namespaces
0252
0253 set -e
0254 trap exit_cleanup_all EXIT
0255
0256 setup_interface
0257 setup_sysctl
0258 setup_iptables
0259 setup_mcast_routing
0260 test_remote_ip
0261 test_ipv4_forward &
0262 pid=$!
0263 send_mcast4
0264 wait $pid || err=$?
0265 if [ $err -eq 1 ]; then
0266 ERR=1
0267 fi
0268 test_ipv6_forward &
0269 pid=$!
0270 send_mcast6
0271 wait $pid || err=$?
0272 if [ $err -eq 1 ]; then
0273 ERR=1
0274 fi
0275 send_mcast_torture4
0276 printf "TEST: %-60s [ OK ]\n" "IPv4 amt traffic forwarding torture"
0277 send_mcast_torture6
0278 printf "TEST: %-60s [ OK ]\n" "IPv6 amt traffic forwarding torture"
0279 sleep 5
0280 if [ "${ERR}" -eq 1 ]; then
0281 echo "Some tests failed." >&2
0282 else
0283 ERR=0
0284 fi