PageRenderTime 45ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 1ms

/tools/testing/selftests/net/traceroute.sh

https://gitlab.com/deepcypher/linux
Shell | 322 lines | 191 code | 60 blank | 71 comment | 25 complexity | 615f8b640ca11bb82fc20b8b761c38ba MD5 | raw file
  1. #!/bin/bash
  2. # SPDX-License-Identifier: GPL-2.0
  3. #
  4. # Run traceroute/traceroute6 tests
  5. #
  6. VERBOSE=0
  7. PAUSE_ON_FAIL=no
  8. ################################################################################
  9. #
  10. log_test()
  11. {
  12. local rc=$1
  13. local expected=$2
  14. local msg="$3"
  15. if [ ${rc} -eq ${expected} ]; then
  16. printf "TEST: %-60s [ OK ]\n" "${msg}"
  17. nsuccess=$((nsuccess+1))
  18. else
  19. ret=1
  20. nfail=$((nfail+1))
  21. printf "TEST: %-60s [FAIL]\n" "${msg}"
  22. if [ "${PAUSE_ON_FAIL}" = "yes" ]; then
  23. echo
  24. echo "hit enter to continue, 'q' to quit"
  25. read a
  26. [ "$a" = "q" ] && exit 1
  27. fi
  28. fi
  29. }
  30. run_cmd()
  31. {
  32. local ns
  33. local cmd
  34. local out
  35. local rc
  36. ns="$1"
  37. shift
  38. cmd="$*"
  39. if [ "$VERBOSE" = "1" ]; then
  40. printf " COMMAND: $cmd\n"
  41. fi
  42. out=$(eval ip netns exec ${ns} ${cmd} 2>&1)
  43. rc=$?
  44. if [ "$VERBOSE" = "1" -a -n "$out" ]; then
  45. echo " $out"
  46. fi
  47. [ "$VERBOSE" = "1" ] && echo
  48. return $rc
  49. }
  50. ################################################################################
  51. # create namespaces and interconnects
  52. create_ns()
  53. {
  54. local ns=$1
  55. local addr=$2
  56. local addr6=$3
  57. [ -z "${addr}" ] && addr="-"
  58. [ -z "${addr6}" ] && addr6="-"
  59. ip netns add ${ns}
  60. ip netns exec ${ns} ip link set lo up
  61. if [ "${addr}" != "-" ]; then
  62. ip netns exec ${ns} ip addr add dev lo ${addr}
  63. fi
  64. if [ "${addr6}" != "-" ]; then
  65. ip netns exec ${ns} ip -6 addr add dev lo ${addr6}
  66. fi
  67. ip netns exec ${ns} ip ro add unreachable default metric 8192
  68. ip netns exec ${ns} ip -6 ro add unreachable default metric 8192
  69. ip netns exec ${ns} sysctl -qw net.ipv4.ip_forward=1
  70. ip netns exec ${ns} sysctl -qw net.ipv6.conf.all.keep_addr_on_down=1
  71. ip netns exec ${ns} sysctl -qw net.ipv6.conf.all.forwarding=1
  72. ip netns exec ${ns} sysctl -qw net.ipv6.conf.default.forwarding=1
  73. ip netns exec ${ns} sysctl -qw net.ipv6.conf.default.accept_dad=0
  74. }
  75. # create veth pair to connect namespaces and apply addresses.
  76. connect_ns()
  77. {
  78. local ns1=$1
  79. local ns1_dev=$2
  80. local ns1_addr=$3
  81. local ns1_addr6=$4
  82. local ns2=$5
  83. local ns2_dev=$6
  84. local ns2_addr=$7
  85. local ns2_addr6=$8
  86. ip netns exec ${ns1} ip li add ${ns1_dev} type veth peer name tmp
  87. ip netns exec ${ns1} ip li set ${ns1_dev} up
  88. ip netns exec ${ns1} ip li set tmp netns ${ns2} name ${ns2_dev}
  89. ip netns exec ${ns2} ip li set ${ns2_dev} up
  90. if [ "${ns1_addr}" != "-" ]; then
  91. ip netns exec ${ns1} ip addr add dev ${ns1_dev} ${ns1_addr}
  92. fi
  93. if [ "${ns2_addr}" != "-" ]; then
  94. ip netns exec ${ns2} ip addr add dev ${ns2_dev} ${ns2_addr}
  95. fi
  96. if [ "${ns1_addr6}" != "-" ]; then
  97. ip netns exec ${ns1} ip addr add dev ${ns1_dev} ${ns1_addr6}
  98. fi
  99. if [ "${ns2_addr6}" != "-" ]; then
  100. ip netns exec ${ns2} ip addr add dev ${ns2_dev} ${ns2_addr6}
  101. fi
  102. }
  103. ################################################################################
  104. # traceroute6 test
  105. #
  106. # Verify that in this scenario
  107. #
  108. # ------------------------ N2
  109. # | |
  110. # ------ ------ N3 ----
  111. # | R1 | | R2 |------|H2|
  112. # ------ ------ ----
  113. # | |
  114. # ------------------------ N1
  115. # |
  116. # ----
  117. # |H1|
  118. # ----
  119. #
  120. # where H1's default route goes through R1 and R1's default route goes
  121. # through R2 over N2, traceroute6 from H1 to H2 reports R2's address
  122. # on N2 and not N1.
  123. #
  124. # Addresses are assigned as follows:
  125. #
  126. # N1: 2000:101::/64
  127. # N2: 2000:102::/64
  128. # N3: 2000:103::/64
  129. #
  130. # R1's host part of address: 1
  131. # R2's host part of address: 2
  132. # H1's host part of address: 3
  133. # H2's host part of address: 4
  134. #
  135. # For example:
  136. # the IPv6 address of R1's interface on N2 is 2000:102::1/64
  137. cleanup_traceroute6()
  138. {
  139. local ns
  140. for ns in host-1 host-2 router-1 router-2
  141. do
  142. ip netns del ${ns} 2>/dev/null
  143. done
  144. }
  145. setup_traceroute6()
  146. {
  147. brdev=br0
  148. # start clean
  149. cleanup_traceroute6
  150. set -e
  151. create_ns host-1
  152. create_ns host-2
  153. create_ns router-1
  154. create_ns router-2
  155. # Setup N3
  156. connect_ns router-2 eth3 - 2000:103::2/64 host-2 eth3 - 2000:103::4/64
  157. ip netns exec host-2 ip route add default via 2000:103::2
  158. # Setup N2
  159. connect_ns router-1 eth2 - 2000:102::1/64 router-2 eth2 - 2000:102::2/64
  160. ip netns exec router-1 ip route add default via 2000:102::2
  161. # Setup N1. host-1 and router-2 connect to a bridge in router-1.
  162. ip netns exec router-1 ip link add name ${brdev} type bridge
  163. ip netns exec router-1 ip link set ${brdev} up
  164. ip netns exec router-1 ip addr add 2000:101::1/64 dev ${brdev}
  165. connect_ns host-1 eth0 - 2000:101::3/64 router-1 eth0 - -
  166. ip netns exec router-1 ip link set dev eth0 master ${brdev}
  167. ip netns exec host-1 ip route add default via 2000:101::1
  168. connect_ns router-2 eth1 - 2000:101::2/64 router-1 eth1 - -
  169. ip netns exec router-1 ip link set dev eth1 master ${brdev}
  170. # Prime the network
  171. ip netns exec host-1 ping6 -c5 2000:103::4 >/dev/null 2>&1
  172. set +e
  173. }
  174. run_traceroute6()
  175. {
  176. if [ ! -x "$(command -v traceroute6)" ]; then
  177. echo "SKIP: Could not run IPV6 test without traceroute6"
  178. return
  179. fi
  180. setup_traceroute6
  181. # traceroute6 host-2 from host-1 (expects 2000:102::2)
  182. run_cmd host-1 "traceroute6 2000:103::4 | grep -q 2000:102::2"
  183. log_test $? 0 "IPV6 traceroute"
  184. cleanup_traceroute6
  185. }
  186. ################################################################################
  187. # traceroute test
  188. #
  189. # Verify that traceroute from H1 to H2 shows 1.0.1.1 in this scenario
  190. #
  191. # 1.0.3.1/24
  192. # ---- 1.0.1.3/24 1.0.1.1/24 ---- 1.0.2.1/24 1.0.2.4/24 ----
  193. # |H1|--------------------------|R1|--------------------------|H2|
  194. # ---- N1 ---- N2 ----
  195. #
  196. # where net.ipv4.icmp_errors_use_inbound_ifaddr is set on R1 and
  197. # 1.0.3.1/24 and 1.0.1.1/24 are respectively R1's primary and secondary
  198. # address on N1.
  199. #
  200. cleanup_traceroute()
  201. {
  202. local ns
  203. for ns in host-1 host-2 router
  204. do
  205. ip netns del ${ns} 2>/dev/null
  206. done
  207. }
  208. setup_traceroute()
  209. {
  210. # start clean
  211. cleanup_traceroute
  212. set -e
  213. create_ns host-1
  214. create_ns host-2
  215. create_ns router
  216. connect_ns host-1 eth0 1.0.1.3/24 - \
  217. router eth1 1.0.3.1/24 -
  218. ip netns exec host-1 ip route add default via 1.0.1.1
  219. ip netns exec router ip addr add 1.0.1.1/24 dev eth1
  220. ip netns exec router sysctl -qw \
  221. net.ipv4.icmp_errors_use_inbound_ifaddr=1
  222. connect_ns host-2 eth0 1.0.2.4/24 - \
  223. router eth2 1.0.2.1/24 -
  224. ip netns exec host-2 ip route add default via 1.0.2.1
  225. # Prime the network
  226. ip netns exec host-1 ping -c5 1.0.2.4 >/dev/null 2>&1
  227. set +e
  228. }
  229. run_traceroute()
  230. {
  231. if [ ! -x "$(command -v traceroute)" ]; then
  232. echo "SKIP: Could not run IPV4 test without traceroute"
  233. return
  234. fi
  235. setup_traceroute
  236. # traceroute host-2 from host-1 (expects 1.0.1.1). Takes a while.
  237. run_cmd host-1 "traceroute 1.0.2.4 | grep -q 1.0.1.1"
  238. log_test $? 0 "IPV4 traceroute"
  239. cleanup_traceroute
  240. }
  241. ################################################################################
  242. # Run tests
  243. run_tests()
  244. {
  245. run_traceroute6
  246. run_traceroute
  247. }
  248. ################################################################################
  249. # main
  250. declare -i nfail=0
  251. declare -i nsuccess=0
  252. while getopts :pv o
  253. do
  254. case $o in
  255. p) PAUSE_ON_FAIL=yes;;
  256. v) VERBOSE=$(($VERBOSE + 1));;
  257. *) exit 1;;
  258. esac
  259. done
  260. run_tests
  261. printf "\nTests passed: %3d\n" ${nsuccess}
  262. printf "Tests failed: %3d\n" ${nfail}