vrf-xfrm-tests.sh 11 KB

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