vrf-xfrm-tests.sh 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431
  1. #!/bin/bash
  2. # SPDX-License-Identifier: GPL-2.0
  3. #
  4. # Various combinations of VRF with xfrms and qdisc.
  5. source lib.sh
  6. PAUSE_ON_FAIL=no
  7. VERBOSE=0
  8. ret=0
  9. HOST1_4=192.168.1.1
  10. HOST2_4=192.168.1.2
  11. HOST1_6=2001:db8:1::1
  12. HOST2_6=2001:db8:1::2
  13. XFRM1_4=10.0.1.1
  14. XFRM2_4=10.0.1.2
  15. XFRM1_6=fc00:1000::1
  16. XFRM2_6=fc00:1000::2
  17. IF_ID=123
  18. VRF=red
  19. TABLE=300
  20. AUTH_1=0xd94fcfea65fddf21dc6e0d24a0253508
  21. AUTH_2=0xdc6e0d24a0253508d94fcfea65fddf21
  22. ENC_1=0xfc46c20f8048be9725930ff3fb07ac2a91f0347dffeacf62
  23. ENC_2=0x3fb07ac2a91f0347dffeacf62fc46c20f8048be9725930ff
  24. SPI_1=0x02122b77
  25. SPI_2=0x2b770212
  26. which ping6 > /dev/null 2>&1 && ping6=$(which ping6) || ping6=$(which ping)
  27. ################################################################################
  28. #
  29. log_test()
  30. {
  31. local rc=$1
  32. local expected=$2
  33. local msg="$3"
  34. if [ ${rc} -eq ${expected} ]; then
  35. printf "TEST: %-60s [ OK ]\n" "${msg}"
  36. nsuccess=$((nsuccess+1))
  37. else
  38. ret=1
  39. nfail=$((nfail+1))
  40. printf "TEST: %-60s [FAIL]\n" "${msg}"
  41. if [ "${PAUSE_ON_FAIL}" = "yes" ]; then
  42. echo
  43. echo "hit enter to continue, 'q' to quit"
  44. read a
  45. [ "$a" = "q" ] && exit 1
  46. fi
  47. fi
  48. }
  49. run_cmd_host1()
  50. {
  51. local cmd="$*"
  52. local out
  53. local rc
  54. if [ "$VERBOSE" = "1" ]; then
  55. printf " COMMAND: $cmd\n"
  56. fi
  57. out=$(eval ip netns exec $host1 $cmd 2>&1)
  58. rc=$?
  59. if [ "$VERBOSE" = "1" ]; then
  60. if [ -n "$out" ]; then
  61. echo
  62. echo " $out"
  63. fi
  64. echo
  65. fi
  66. return $rc
  67. }
  68. ################################################################################
  69. # create namespaces for hosts and sws
  70. create_vrf()
  71. {
  72. local ns=$1
  73. local vrf=$2
  74. local table=$3
  75. if [ -n "${ns}" ]; then
  76. ns="-netns ${ns}"
  77. fi
  78. ip ${ns} link add ${vrf} type vrf table ${table}
  79. ip ${ns} link set ${vrf} up
  80. ip ${ns} route add vrf ${vrf} unreachable default metric 8192
  81. ip ${ns} -6 route add vrf ${vrf} unreachable default metric 8192
  82. ip ${ns} addr add 127.0.0.1/8 dev ${vrf}
  83. ip ${ns} -6 addr add ::1 dev ${vrf} nodad
  84. ip ${ns} ru del pref 0
  85. ip ${ns} ru add pref 32765 from all lookup local
  86. ip ${ns} -6 ru del pref 0
  87. ip ${ns} -6 ru add pref 32765 from all lookup local
  88. }
  89. create_ns()
  90. {
  91. local ns=$1
  92. local addr=$2
  93. local addr6=$3
  94. [ -z "${addr}" ] && addr="-"
  95. [ -z "${addr6}" ] && addr6="-"
  96. if [ "${addr}" != "-" ]; then
  97. ip -netns ${ns} addr add dev lo ${addr}
  98. fi
  99. if [ "${addr6}" != "-" ]; then
  100. ip -netns ${ns} -6 addr add dev lo ${addr6}
  101. fi
  102. ip -netns ${ns} ro add unreachable default metric 8192
  103. ip -netns ${ns} -6 ro add unreachable default metric 8192
  104. ip netns exec ${ns} sysctl -qw net.ipv4.ip_forward=1
  105. ip netns exec ${ns} sysctl -qw net.ipv6.conf.all.keep_addr_on_down=1
  106. ip netns exec ${ns} sysctl -qw net.ipv6.conf.all.forwarding=1
  107. ip netns exec ${ns} sysctl -qw net.ipv6.conf.default.forwarding=1
  108. ip netns exec ${ns} sysctl -qw net.ipv6.conf.default.accept_dad=0
  109. }
  110. # create veth pair to connect namespaces and apply addresses.
  111. connect_ns()
  112. {
  113. local ns1=$1
  114. local ns1_dev=$2
  115. local ns1_addr=$3
  116. local ns1_addr6=$4
  117. local ns2=$5
  118. local ns2_dev=$6
  119. local ns2_addr=$7
  120. local ns2_addr6=$8
  121. local ns1arg
  122. local ns2arg
  123. if [ -n "${ns1}" ]; then
  124. ns1arg="-netns ${ns1}"
  125. fi
  126. if [ -n "${ns2}" ]; then
  127. ns2arg="-netns ${ns2}"
  128. fi
  129. ip ${ns1arg} li add ${ns1_dev} type veth peer name tmp
  130. ip ${ns1arg} li set ${ns1_dev} up
  131. ip ${ns1arg} li set tmp netns ${ns2} name ${ns2_dev}
  132. ip ${ns2arg} li set ${ns2_dev} up
  133. if [ "${ns1_addr}" != "-" ]; then
  134. ip ${ns1arg} addr add dev ${ns1_dev} ${ns1_addr}
  135. ip ${ns2arg} addr add dev ${ns2_dev} ${ns2_addr}
  136. fi
  137. if [ "${ns1_addr6}" != "-" ]; then
  138. ip ${ns1arg} addr add dev ${ns1_dev} ${ns1_addr6} nodad
  139. ip ${ns2arg} addr add dev ${ns2_dev} ${ns2_addr6} nodad
  140. fi
  141. }
  142. ################################################################################
  143. cleanup()
  144. {
  145. cleanup_ns $host1 $host2
  146. }
  147. setup()
  148. {
  149. setup_ns host1 host2
  150. create_ns "$host1"
  151. create_ns "$host2"
  152. connect_ns "$host1" eth0 ${HOST1_4}/24 ${HOST1_6}/64 \
  153. "$host2" eth0 ${HOST2_4}/24 ${HOST2_6}/64
  154. create_vrf "$host1" ${VRF} ${TABLE}
  155. ip -netns $host1 link set dev eth0 master ${VRF}
  156. }
  157. cleanup_xfrm()
  158. {
  159. for ns in $host1 $host2
  160. do
  161. for x in state policy
  162. do
  163. ip -netns ${ns} xfrm ${x} flush
  164. ip -6 -netns ${ns} xfrm ${x} flush
  165. done
  166. done
  167. }
  168. setup_xfrm()
  169. {
  170. local h1_4=$1
  171. local h2_4=$2
  172. local h1_6=$3
  173. local h2_6=$4
  174. local devarg="$5"
  175. #
  176. # policy
  177. #
  178. # host1 - IPv4 out
  179. ip -netns $host1 xfrm policy add \
  180. src ${h1_4} dst ${h2_4} ${devarg} dir out \
  181. tmpl src ${HOST1_4} dst ${HOST2_4} proto esp mode tunnel
  182. # host2 - IPv4 in
  183. ip -netns $host2 xfrm policy add \
  184. src ${h1_4} dst ${h2_4} dir in \
  185. tmpl src ${HOST1_4} dst ${HOST2_4} proto esp mode tunnel
  186. # host1 - IPv4 in
  187. ip -netns $host1 xfrm policy add \
  188. src ${h2_4} dst ${h1_4} ${devarg} dir in \
  189. tmpl src ${HOST2_4} dst ${HOST1_4} proto esp mode tunnel
  190. # host2 - IPv4 out
  191. ip -netns $host2 xfrm policy add \
  192. src ${h2_4} dst ${h1_4} dir out \
  193. tmpl src ${HOST2_4} dst ${HOST1_4} proto esp mode tunnel
  194. # host1 - IPv6 out
  195. ip -6 -netns $host1 xfrm policy add \
  196. src ${h1_6} dst ${h2_6} ${devarg} dir out \
  197. tmpl src ${HOST1_6} dst ${HOST2_6} proto esp mode tunnel
  198. # host2 - IPv6 in
  199. ip -6 -netns $host2 xfrm policy add \
  200. src ${h1_6} dst ${h2_6} dir in \
  201. tmpl src ${HOST1_6} dst ${HOST2_6} proto esp mode tunnel
  202. # host1 - IPv6 in
  203. ip -6 -netns $host1 xfrm policy add \
  204. src ${h2_6} dst ${h1_6} ${devarg} dir in \
  205. tmpl src ${HOST2_6} dst ${HOST1_6} proto esp mode tunnel
  206. # host2 - IPv6 out
  207. ip -6 -netns $host2 xfrm policy add \
  208. src ${h2_6} dst ${h1_6} dir out \
  209. tmpl src ${HOST2_6} dst ${HOST1_6} proto esp mode tunnel
  210. #
  211. # state
  212. #
  213. ip -netns $host1 xfrm state add src ${HOST1_4} dst ${HOST2_4} \
  214. proto esp spi ${SPI_1} reqid 0 mode tunnel \
  215. replay-window 4 replay-oseq 0x4 \
  216. auth-trunc 'hmac(sha1)' ${AUTH_1} 96 \
  217. enc 'cbc(aes)' ${ENC_1} \
  218. sel src ${h1_4} dst ${h2_4} ${devarg}
  219. ip -netns $host2 xfrm state add src ${HOST1_4} dst ${HOST2_4} \
  220. proto esp spi ${SPI_1} reqid 0 mode tunnel \
  221. replay-window 4 replay-oseq 0x4 \
  222. auth-trunc 'hmac(sha1)' ${AUTH_1} 96 \
  223. enc 'cbc(aes)' ${ENC_1} \
  224. sel src ${h1_4} dst ${h2_4}
  225. ip -netns $host1 xfrm state add src ${HOST2_4} dst ${HOST1_4} \
  226. proto esp spi ${SPI_2} reqid 0 mode tunnel \
  227. replay-window 4 replay-oseq 0x4 \
  228. auth-trunc 'hmac(sha1)' ${AUTH_2} 96 \
  229. enc 'cbc(aes)' ${ENC_2} \
  230. sel src ${h2_4} dst ${h1_4} ${devarg}
  231. ip -netns $host2 xfrm state add src ${HOST2_4} dst ${HOST1_4} \
  232. proto esp spi ${SPI_2} reqid 0 mode tunnel \
  233. replay-window 4 replay-oseq 0x4 \
  234. auth-trunc 'hmac(sha1)' ${AUTH_2} 96 \
  235. enc 'cbc(aes)' ${ENC_2} \
  236. sel src ${h2_4} dst ${h1_4}
  237. ip -6 -netns $host1 xfrm state add src ${HOST1_6} dst ${HOST2_6} \
  238. proto esp spi ${SPI_1} reqid 0 mode tunnel \
  239. replay-window 4 replay-oseq 0x4 \
  240. auth-trunc 'hmac(sha1)' ${AUTH_1} 96 \
  241. enc 'cbc(aes)' ${ENC_1} \
  242. sel src ${h1_6} dst ${h2_6} ${devarg}
  243. ip -6 -netns $host2 xfrm state add src ${HOST1_6} dst ${HOST2_6} \
  244. proto esp spi ${SPI_1} reqid 0 mode tunnel \
  245. replay-window 4 replay-oseq 0x4 \
  246. auth-trunc 'hmac(sha1)' ${AUTH_1} 96 \
  247. enc 'cbc(aes)' ${ENC_1} \
  248. sel src ${h1_6} dst ${h2_6}
  249. ip -6 -netns $host1 xfrm state add src ${HOST2_6} dst ${HOST1_6} \
  250. proto esp spi ${SPI_2} reqid 0 mode tunnel \
  251. replay-window 4 replay-oseq 0x4 \
  252. auth-trunc 'hmac(sha1)' ${AUTH_2} 96 \
  253. enc 'cbc(aes)' ${ENC_2} \
  254. sel src ${h2_6} dst ${h1_6} ${devarg}
  255. ip -6 -netns $host2 xfrm state add src ${HOST2_6} dst ${HOST1_6} \
  256. proto esp spi ${SPI_2} reqid 0 mode tunnel \
  257. replay-window 4 replay-oseq 0x4 \
  258. auth-trunc 'hmac(sha1)' ${AUTH_2} 96 \
  259. enc 'cbc(aes)' ${ENC_2} \
  260. sel src ${h2_6} dst ${h1_6}
  261. }
  262. cleanup_xfrm_dev()
  263. {
  264. ip -netns $host1 li del xfrm0
  265. ip -netns $host2 addr del ${XFRM2_4}/24 dev eth0
  266. ip -netns $host2 addr del ${XFRM2_6}/64 dev eth0
  267. }
  268. setup_xfrm_dev()
  269. {
  270. local vrfarg="vrf ${VRF}"
  271. ip -netns $host1 li add type xfrm dev eth0 if_id ${IF_ID}
  272. ip -netns $host1 li set xfrm0 ${vrfarg} up
  273. ip -netns $host1 addr add ${XFRM1_4}/24 dev xfrm0
  274. ip -netns $host1 addr add ${XFRM1_6}/64 dev xfrm0
  275. ip -netns $host2 addr add ${XFRM2_4}/24 dev eth0
  276. ip -netns $host2 addr add ${XFRM2_6}/64 dev eth0
  277. setup_xfrm ${XFRM1_4} ${XFRM2_4} ${XFRM1_6} ${XFRM2_6} "if_id ${IF_ID}"
  278. }
  279. run_tests()
  280. {
  281. cleanup_xfrm
  282. # no IPsec
  283. run_cmd_host1 ip vrf exec ${VRF} ping -c1 -w1 ${HOST2_4}
  284. log_test $? 0 "IPv4 no xfrm policy"
  285. run_cmd_host1 ip vrf exec ${VRF} ${ping6} -c1 -w1 ${HOST2_6}
  286. log_test $? 0 "IPv6 no xfrm policy"
  287. # xfrm without VRF in sel
  288. setup_xfrm ${HOST1_4} ${HOST2_4} ${HOST1_6} ${HOST2_6}
  289. run_cmd_host1 ip vrf exec ${VRF} ping -c1 -w1 ${HOST2_4}
  290. log_test $? 0 "IPv4 xfrm policy based on address"
  291. run_cmd_host1 ip vrf exec ${VRF} ${ping6} -c1 -w1 ${HOST2_6}
  292. log_test $? 0 "IPv6 xfrm policy based on address"
  293. cleanup_xfrm
  294. # xfrm with VRF in sel
  295. # Known failure: ipv4 resets the flow oif after the lookup. Fix is
  296. # not straightforward.
  297. # setup_xfrm ${HOST1_4} ${HOST2_4} ${HOST1_6} ${HOST2_6} "dev ${VRF}"
  298. # run_cmd_host1 ip vrf exec ${VRF} ping -c1 -w1 ${HOST2_4}
  299. # log_test $? 0 "IPv4 xfrm policy with VRF in selector"
  300. run_cmd_host1 ip vrf exec ${VRF} ${ping6} -c1 -w1 ${HOST2_6}
  301. log_test $? 0 "IPv6 xfrm policy with VRF in selector"
  302. cleanup_xfrm
  303. # xfrm with enslaved device in sel
  304. # Known failures: combined with the above, __xfrm{4,6}_selector_match
  305. # needs to consider both l3mdev and enslaved device index.
  306. # setup_xfrm ${HOST1_4} ${HOST2_4} ${HOST1_6} ${HOST2_6} "dev eth0"
  307. # run_cmd_host1 ip vrf exec ${VRF} ping -c1 -w1 ${HOST2_4}
  308. # log_test $? 0 "IPv4 xfrm policy with enslaved device in selector"
  309. # run_cmd_host1 ip vrf exec ${VRF} ${ping6} -c1 -w1 ${HOST2_6}
  310. # log_test $? 0 "IPv6 xfrm policy with enslaved device in selector"
  311. # cleanup_xfrm
  312. # xfrm device
  313. setup_xfrm_dev
  314. run_cmd_host1 ip vrf exec ${VRF} ping -c1 -w1 ${XFRM2_4}
  315. log_test $? 0 "IPv4 xfrm policy with xfrm device"
  316. run_cmd_host1 ip vrf exec ${VRF} ${ping6} -c1 -w1 ${XFRM2_6}
  317. log_test $? 0 "IPv6 xfrm policy with xfrm device"
  318. cleanup_xfrm_dev
  319. }
  320. ################################################################################
  321. # usage
  322. usage()
  323. {
  324. cat <<EOF
  325. usage: ${0##*/} OPTS
  326. -p Pause on fail
  327. -v verbose mode (show commands and output)
  328. done
  329. EOF
  330. }
  331. ################################################################################
  332. # main
  333. while getopts :pv o
  334. do
  335. case $o in
  336. p) PAUSE_ON_FAIL=yes;;
  337. v) VERBOSE=$(($VERBOSE + 1));;
  338. h) usage; exit 0;;
  339. *) usage; exit 1;;
  340. esac
  341. done
  342. cleanup 2>/dev/null
  343. setup
  344. echo
  345. echo "No qdisc on VRF device"
  346. run_tests
  347. run_cmd_host1 tc qdisc add dev ${VRF} root netem delay 100ms
  348. echo
  349. echo "netem qdisc on VRF device"
  350. run_tests
  351. printf "\nTests passed: %3d\n" ${nsuccess}
  352. printf "Tests failed: %3d\n" ${nfail}
  353. exit $ret