123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284 |
- #!/bin/sh
- # SPDX-License-Identifier: GPL-2.0
- # Author: Taehee Yoo <[email protected]>
- #
- # This script evaluates the AMT driver.
- # There are four network-namespaces, LISTENER, SOURCE, GATEWAY, RELAY.
- # The role of LISTENER is to listen multicast traffic.
- # In order to do that, it send IGMP group join message.
- # The role of SOURCE is to send multicast traffic to listener.
- # The role of GATEWAY is to work Gateway role of AMT interface.
- # The role of RELAY is to work Relay role of AMT interface.
- #
- #
- # +------------------------+
- # | LISTENER netns |
- # | |
- # | +------------------+ |
- # | | l_gw | |
- # | | 192.168.0.2/24 | |
- # | | 2001:db8::2/64 | |
- # | +------------------+ |
- # | . |
- # +------------------------+
- # .
- # .
- # +-----------------------------------------------------+
- # | . GATEWAY netns |
- # | . |
- # |+---------------------------------------------------+|
- # || . br0 ||
- # || +------------------+ +------------------+ ||
- # || | gw_l | | amtg | ||
- # || | 192.168.0.1/24 | +--------+---------+ ||
- # || | 2001:db8::1/64 | | ||
- # || +------------------+ | ||
- # |+-------------------------------------|-------------+|
- # | | |
- # | +--------+---------+ |
- # | | gw_relay | |
- # | | 10.0.0.1/24 | |
- # | +------------------+ |
- # | . |
- # +-----------------------------------------------------+
- # .
- # .
- # +-----------------------------------------------------+
- # | RELAY netns . |
- # | +------------------+ |
- # | | relay_gw | |
- # | | 10.0.0.2/24 | |
- # | +--------+---------+ |
- # | | |
- # | | |
- # | +------------------+ +--------+---------+ |
- # | | relay_src | | amtr | |
- # | | 172.17.0.1/24 | +------------------+ |
- # | | 2001:db8:3::1/64 | |
- # | +------------------+ |
- # | . |
- # | . |
- # +-----------------------------------------------------+
- # .
- # .
- # +------------------------+
- # | . |
- # | +------------------+ |
- # | | src_relay | |
- # | | 172.17.0.2/24 | |
- # | | 2001:db8:3::2/64 | |
- # | +------------------+ |
- # | SOURCE netns |
- # +------------------------+
- #==============================================================================
- readonly LISTENER=$(mktemp -u listener-XXXXXXXX)
- readonly GATEWAY=$(mktemp -u gateway-XXXXXXXX)
- readonly RELAY=$(mktemp -u relay-XXXXXXXX)
- readonly SOURCE=$(mktemp -u source-XXXXXXXX)
- ERR=4
- err=0
- exit_cleanup()
- {
- for ns in "$@"; do
- ip netns delete "${ns}" 2>/dev/null || true
- done
- exit $ERR
- }
- create_namespaces()
- {
- ip netns add "${LISTENER}" || exit_cleanup
- ip netns add "${GATEWAY}" || exit_cleanup "${LISTENER}"
- ip netns add "${RELAY}" || exit_cleanup "${LISTENER}" "${GATEWAY}"
- ip netns add "${SOURCE}" || exit_cleanup "${LISTENER}" "${GATEWAY}" \
- "${RELAY}"
- }
- # The trap function handler
- #
- exit_cleanup_all()
- {
- exit_cleanup "${LISTENER}" "${GATEWAY}" "${RELAY}" "${SOURCE}"
- }
- setup_interface()
- {
- for ns in "${LISTENER}" "${GATEWAY}" "${RELAY}" "${SOURCE}"; do
- ip -netns "${ns}" link set dev lo up
- done;
- ip link add l_gw type veth peer name gw_l
- ip link add gw_relay type veth peer name relay_gw
- ip link add relay_src type veth peer name src_relay
- ip link set l_gw netns "${LISTENER}" up
- ip link set gw_l netns "${GATEWAY}" up
- ip link set gw_relay netns "${GATEWAY}" up
- ip link set relay_gw netns "${RELAY}" up
- ip link set relay_src netns "${RELAY}" up
- ip link set src_relay netns "${SOURCE}" up mtu 1400
- ip netns exec "${LISTENER}" ip a a 192.168.0.2/24 dev l_gw
- ip netns exec "${LISTENER}" ip r a default via 192.168.0.1 dev l_gw
- ip netns exec "${LISTENER}" ip a a 2001:db8::2/64 dev l_gw
- ip netns exec "${LISTENER}" ip r a default via 2001:db8::1 dev l_gw
- ip netns exec "${LISTENER}" ip a a 239.0.0.1/32 dev l_gw autojoin
- ip netns exec "${LISTENER}" ip a a ff0e::5:6/128 dev l_gw autojoin
- ip netns exec "${GATEWAY}" ip a a 192.168.0.1/24 dev gw_l
- ip netns exec "${GATEWAY}" ip a a 2001:db8::1/64 dev gw_l
- ip netns exec "${GATEWAY}" ip a a 10.0.0.1/24 dev gw_relay
- ip netns exec "${GATEWAY}" ip link add br0 type bridge
- ip netns exec "${GATEWAY}" ip link set br0 up
- ip netns exec "${GATEWAY}" ip link set gw_l master br0
- ip netns exec "${GATEWAY}" ip link set gw_l up
- ip netns exec "${GATEWAY}" ip link add amtg master br0 type amt \
- mode gateway local 10.0.0.1 discovery 10.0.0.2 dev gw_relay \
- gateway_port 2268 relay_port 2268
- ip netns exec "${RELAY}" ip a a 10.0.0.2/24 dev relay_gw
- ip netns exec "${RELAY}" ip link add amtr type amt mode relay \
- local 10.0.0.2 dev relay_gw relay_port 2268 max_tunnels 4
- ip netns exec "${RELAY}" ip a a 172.17.0.1/24 dev relay_src
- ip netns exec "${RELAY}" ip a a 2001:db8:3::1/64 dev relay_src
- ip netns exec "${SOURCE}" ip a a 172.17.0.2/24 dev src_relay
- ip netns exec "${SOURCE}" ip a a 2001:db8:3::2/64 dev src_relay
- ip netns exec "${SOURCE}" ip r a default via 172.17.0.1 dev src_relay
- ip netns exec "${SOURCE}" ip r a default via 2001:db8:3::1 dev src_relay
- ip netns exec "${RELAY}" ip link set amtr up
- ip netns exec "${GATEWAY}" ip link set amtg up
- }
- setup_sysctl()
- {
- ip netns exec "${RELAY}" sysctl net.ipv4.ip_forward=1 -w -q
- }
- setup_iptables()
- {
- ip netns exec "${RELAY}" iptables -t mangle -I PREROUTING \
- -d 239.0.0.1 -j TTL --ttl-set 2
- ip netns exec "${RELAY}" ip6tables -t mangle -I PREROUTING \
- -j HL --hl-set 2
- }
- setup_mcast_routing()
- {
- ip netns exec "${RELAY}" smcrouted
- ip netns exec "${RELAY}" smcroutectl a relay_src \
- 172.17.0.2 239.0.0.1 amtr
- ip netns exec "${RELAY}" smcroutectl a relay_src \
- 2001:db8:3::2 ff0e::5:6 amtr
- }
- test_remote_ip()
- {
- REMOTE=$(ip netns exec "${GATEWAY}" \
- ip -d -j link show amtg | jq .[0].linkinfo.info_data.remote)
- if [ $REMOTE == "\"10.0.0.2\"" ]; then
- printf "TEST: %-60s [ OK ]\n" "amt discovery"
- else
- printf "TEST: %-60s [FAIL]\n" "amt discovery"
- ERR=1
- fi
- }
- send_mcast_torture4()
- {
- ip netns exec "${SOURCE}" bash -c \
- 'cat /dev/urandom | head -c 1G | nc -w 1 -u 239.0.0.1 4001'
- }
- send_mcast_torture6()
- {
- ip netns exec "${SOURCE}" bash -c \
- 'cat /dev/urandom | head -c 1G | nc -w 1 -u ff0e::5:6 6001'
- }
- check_features()
- {
- ip link help 2>&1 | grep -q amt
- if [ $? -ne 0 ]; then
- echo "Missing amt support in iproute2" >&2
- exit_cleanup
- fi
- }
- test_ipv4_forward()
- {
- RESULT4=$(ip netns exec "${LISTENER}" nc -w 1 -l -u 239.0.0.1 4000)
- if [ "$RESULT4" == "172.17.0.2" ]; then
- printf "TEST: %-60s [ OK ]\n" "IPv4 amt multicast forwarding"
- exit 0
- else
- printf "TEST: %-60s [FAIL]\n" "IPv4 amt multicast forwarding"
- exit 1
- fi
- }
- test_ipv6_forward()
- {
- RESULT6=$(ip netns exec "${LISTENER}" nc -w 1 -l -u ff0e::5:6 6000)
- if [ "$RESULT6" == "2001:db8:3::2" ]; then
- printf "TEST: %-60s [ OK ]\n" "IPv6 amt multicast forwarding"
- exit 0
- else
- printf "TEST: %-60s [FAIL]\n" "IPv6 amt multicast forwarding"
- exit 1
- fi
- }
- send_mcast4()
- {
- sleep 2
- ip netns exec "${SOURCE}" bash -c \
- 'echo 172.17.0.2 | nc -w 1 -u 239.0.0.1 4000' &
- }
- send_mcast6()
- {
- sleep 2
- ip netns exec "${SOURCE}" bash -c \
- 'echo 2001:db8:3::2 | nc -w 1 -u ff0e::5:6 6000' &
- }
- check_features
- create_namespaces
- set -e
- trap exit_cleanup_all EXIT
- setup_interface
- setup_sysctl
- setup_iptables
- setup_mcast_routing
- test_remote_ip
- test_ipv4_forward &
- pid=$!
- send_mcast4
- wait $pid || err=$?
- if [ $err -eq 1 ]; then
- ERR=1
- fi
- test_ipv6_forward &
- pid=$!
- send_mcast6
- wait $pid || err=$?
- if [ $err -eq 1 ]; then
- ERR=1
- fi
- send_mcast_torture4
- printf "TEST: %-60s [ OK ]\n" "IPv4 amt traffic forwarding torture"
- send_mcast_torture6
- printf "TEST: %-60s [ OK ]\n" "IPv6 amt traffic forwarding torture"
- sleep 5
- if [ "${ERR}" -eq 1 ]; then
- echo "Some tests failed." >&2
- else
- ERR=0
- fi
|