amt.sh 8.9 KB

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