openvswitch.sh 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869
  1. #!/bin/bash
  2. # SPDX-License-Identifier: GPL-2.0
  3. #
  4. # OVS kernel module self tests
  5. trap ovs_exit_sig EXIT TERM INT ERR
  6. # Kselftest framework requirement - SKIP code is 4.
  7. ksft_skip=4
  8. PAUSE_ON_FAIL=no
  9. VERBOSE=0
  10. TRACING=0
  11. WAIT_TIMEOUT=5
  12. if test "X$KSFT_MACHINE_SLOW" == "Xyes"; then
  13. WAIT_TIMEOUT=10
  14. fi
  15. tests="
  16. arp_ping eth-arp: Basic arp ping between two NS
  17. ct_connect_v4 ip4-ct-xon: Basic ipv4 tcp connection using ct
  18. connect_v4 ip4-xon: Basic ipv4 ping between two NS
  19. nat_connect_v4 ip4-nat-xon: Basic ipv4 tcp connection via NAT
  20. nat_related_v4 ip4-nat-related: ICMP related matches work with SNAT
  21. netlink_checks ovsnl: validate netlink attrs and settings
  22. upcall_interfaces ovs: test the upcall interfaces
  23. drop_reason drop: test drop reasons are emitted
  24. psample psample: Sampling packets with psample"
  25. info() {
  26. [ "${ovs_dir}" != "" ] &&
  27. echo "`date +"[%m-%d %H:%M:%S]"` $*" >> ${ovs_dir}/debug.log
  28. [ $VERBOSE = 0 ] || echo $*
  29. }
  30. ovs_wait() {
  31. info "waiting $WAIT_TIMEOUT s for: $@"
  32. if "$@" ; then
  33. info "wait succeeded immediately"
  34. return 0
  35. fi
  36. # A quick re-check helps speed up small races in fast systems.
  37. # However, fractional sleeps might not necessarily work.
  38. local start=0
  39. sleep 0.1 || { sleep 1; start=1; }
  40. for (( i=start; i<WAIT_TIMEOUT; i++ )); do
  41. if "$@" ; then
  42. info "wait succeeded after $i seconds"
  43. return 0
  44. fi
  45. sleep 1
  46. done
  47. info "wait failed after $i seconds"
  48. return 1
  49. }
  50. ovs_base=`pwd`
  51. sbxs=
  52. sbx_add () {
  53. info "adding sandbox '$1'"
  54. sbxs="$sbxs $1"
  55. NO_BIN=0
  56. # Create sandbox.
  57. local d="$ovs_base"/$1
  58. if [ -e $d ]; then
  59. info "removing $d"
  60. rm -rf "$d"
  61. fi
  62. mkdir "$d" || return 1
  63. ovs_setenv $1
  64. }
  65. ovs_exit_sig() {
  66. [ -e ${ovs_dir}/cleanup ] && . "$ovs_dir/cleanup"
  67. }
  68. on_exit() {
  69. echo "$1" > ${ovs_dir}/cleanup.tmp
  70. cat ${ovs_dir}/cleanup >> ${ovs_dir}/cleanup.tmp
  71. mv ${ovs_dir}/cleanup.tmp ${ovs_dir}/cleanup
  72. }
  73. ovs_setenv() {
  74. sandbox=$1
  75. ovs_dir=$ovs_base${1:+/$1}; export ovs_dir
  76. test -e ${ovs_dir}/cleanup || : > ${ovs_dir}/cleanup
  77. }
  78. ovs_sbx() {
  79. if test "X$2" != X; then
  80. (ovs_setenv $1; shift;
  81. info "run cmd: $@"; "$@" >> ${ovs_dir}/debug.log)
  82. else
  83. ovs_setenv $1
  84. fi
  85. }
  86. ovs_add_dp () {
  87. info "Adding DP/Bridge IF: sbx:$1 dp:$2 {$3, $4, $5}"
  88. sbxname="$1"
  89. shift
  90. ovs_sbx "$sbxname" python3 $ovs_base/ovs-dpctl.py add-dp $*
  91. on_exit "ovs_sbx $sbxname python3 $ovs_base/ovs-dpctl.py del-dp $1;"
  92. }
  93. ovs_add_if () {
  94. info "Adding IF to DP: br:$2 if:$3"
  95. if [ "$4" != "-u" ]; then
  96. ovs_sbx "$1" python3 $ovs_base/ovs-dpctl.py add-if "$2" "$3" \
  97. || return 1
  98. else
  99. python3 $ovs_base/ovs-dpctl.py add-if \
  100. -u "$2" "$3" >$ovs_dir/$3.out 2>$ovs_dir/$3.err &
  101. pid=$!
  102. on_exit "ovs_sbx $1 kill -TERM $pid 2>/dev/null"
  103. fi
  104. }
  105. ovs_del_if () {
  106. info "Deleting IF from DP: br:$2 if:$3"
  107. ovs_sbx "$1" python3 $ovs_base/ovs-dpctl.py del-if "$2" "$3" || return 1
  108. }
  109. ovs_netns_spawn_daemon() {
  110. sbx=$1
  111. shift
  112. netns=$1
  113. shift
  114. if [ "$netns" == "_default" ]; then
  115. $* >> $ovs_dir/stdout 2>> $ovs_dir/stderr &
  116. else
  117. ip netns exec $netns $* >> $ovs_dir/stdout 2>> $ovs_dir/stderr &
  118. fi
  119. pid=$!
  120. ovs_sbx "$sbx" on_exit "kill -TERM $pid 2>/dev/null"
  121. }
  122. ovs_spawn_daemon() {
  123. sbx=$1
  124. shift
  125. ovs_netns_spawn_daemon $sbx "_default" $*
  126. }
  127. ovs_add_netns_and_veths () {
  128. info "Adding netns attached: sbx:$1 dp:$2 {$3, $4, $5}"
  129. ovs_sbx "$1" ip netns add "$3" || return 1
  130. on_exit "ovs_sbx $1 ip netns del $3"
  131. ovs_sbx "$1" ip link add "$4" type veth peer name "$5" || return 1
  132. on_exit "ovs_sbx $1 ip link del $4 >/dev/null 2>&1"
  133. ovs_sbx "$1" ip link set "$4" up || return 1
  134. ovs_sbx "$1" ip link set "$5" netns "$3" || return 1
  135. ovs_sbx "$1" ip netns exec "$3" ip link set "$5" up || return 1
  136. if [ "$6" != "" ]; then
  137. ovs_sbx "$1" ip netns exec "$3" ip addr add "$6" dev "$5" \
  138. || return 1
  139. fi
  140. if [ "$7" != "-u" ]; then
  141. ovs_add_if "$1" "$2" "$4" || return 1
  142. else
  143. ovs_add_if "$1" "$2" "$4" -u || return 1
  144. fi
  145. if [ $TRACING -eq 1 ]; then
  146. ovs_netns_spawn_daemon "$1" "$3" tcpdump -l -i any -s 6553
  147. ovs_wait grep -q "listening on any" ${ovs_dir}/stderr
  148. fi
  149. return 0
  150. }
  151. ovs_add_flow () {
  152. info "Adding flow to DP: sbx:$1 br:$2 flow:$3 act:$4"
  153. ovs_sbx "$1" python3 $ovs_base/ovs-dpctl.py add-flow "$2" "$3" "$4"
  154. if [ $? -ne 0 ]; then
  155. info "Flow [ $3 : $4 ] failed"
  156. return 1
  157. fi
  158. return 0
  159. }
  160. ovs_del_flows () {
  161. info "Deleting all flows from DP: sbx:$1 br:$2"
  162. ovs_sbx "$1" python3 $ovs_base/ovs-dpctl.py del-flows "$2"
  163. return 0
  164. }
  165. ovs_drop_record_and_run () {
  166. local sbx=$1
  167. shift
  168. perf record -a -q -e skb:kfree_skb -o ${ovs_dir}/perf.data $* \
  169. >> ${ovs_dir}/stdout 2>> ${ovs_dir}/stderr
  170. return $?
  171. }
  172. ovs_drop_reason_count()
  173. {
  174. local reason=$1
  175. local perf_output=`perf script -i ${ovs_dir}/perf.data -F trace:event,trace`
  176. local pattern="skb:kfree_skb:.*reason: $reason"
  177. return `echo "$perf_output" | grep "$pattern" | wc -l`
  178. }
  179. ovs_test_flow_fails () {
  180. ERR_MSG="Flow actions may not be safe on all matching packets"
  181. PRE_TEST=$(dmesg | grep -c "${ERR_MSG}")
  182. ovs_add_flow $@ &> /dev/null $@ && return 1
  183. POST_TEST=$(dmesg | grep -c "${ERR_MSG}")
  184. if [ "$PRE_TEST" == "$POST_TEST" ]; then
  185. return 1
  186. fi
  187. return 0
  188. }
  189. usage() {
  190. echo
  191. echo "$0 [OPTIONS] [TEST]..."
  192. echo "If no TEST argument is given, all tests will be run."
  193. echo
  194. echo "Options"
  195. echo " -t: capture traffic via tcpdump"
  196. echo " -v: verbose"
  197. echo " -p: pause on failure"
  198. echo
  199. echo "Available tests${tests}"
  200. exit 1
  201. }
  202. # psample test
  203. # - use psample to observe packets
  204. test_psample() {
  205. sbx_add "test_psample" || return $?
  206. # Add a datapath with per-vport dispatching.
  207. ovs_add_dp "test_psample" psample -V 2:1 || return 1
  208. info "create namespaces"
  209. ovs_add_netns_and_veths "test_psample" "psample" \
  210. client c0 c1 172.31.110.10/24 -u || return 1
  211. ovs_add_netns_and_veths "test_psample" "psample" \
  212. server s0 s1 172.31.110.20/24 -u || return 1
  213. # Check if psample actions can be configured.
  214. ovs_add_flow "test_psample" psample \
  215. 'in_port(1),eth(),eth_type(0x0806),arp()' 'psample(group=1)' &> /dev/null
  216. if [ $? == 1 ]; then
  217. info "no support for psample - skipping"
  218. ovs_exit_sig
  219. return $ksft_skip
  220. fi
  221. ovs_del_flows "test_psample" psample
  222. # Test action verification.
  223. OLDIFS=$IFS
  224. IFS='*'
  225. min_key='in_port(1),eth(),eth_type(0x0800),ipv4()'
  226. for testcase in \
  227. "cookie to large"*"psample(group=1,cookie=1615141312111009080706050403020100)" \
  228. "no group with cookie"*"psample(cookie=abcd)" \
  229. "no group"*"psample()";
  230. do
  231. set -- $testcase;
  232. ovs_test_flow_fails "test_psample" psample $min_key $2
  233. if [ $? == 1 ]; then
  234. info "failed - $1"
  235. return 1
  236. fi
  237. done
  238. IFS=$OLDIFS
  239. ovs_del_flows "test_psample" psample
  240. # Allow ARP
  241. ovs_add_flow "test_psample" psample \
  242. 'in_port(1),eth(),eth_type(0x0806),arp()' '2' || return 1
  243. ovs_add_flow "test_psample" psample \
  244. 'in_port(2),eth(),eth_type(0x0806),arp()' '1' || return 1
  245. # Sample first 14 bytes of all traffic.
  246. ovs_add_flow "test_psample" psample \
  247. "in_port(1),eth(),eth_type(0x0800),ipv4()" \
  248. "trunc(14),psample(group=1,cookie=c0ffee),2"
  249. # Sample all traffic. In this case, use a sample() action with both
  250. # psample and an upcall emulating simultaneous local sampling and
  251. # sFlow / IPFIX.
  252. nlpid=$(grep -E "listening on upcall packet handler" \
  253. $ovs_dir/s0.out | cut -d ":" -f 2 | tr -d ' ')
  254. ovs_add_flow "test_psample" psample \
  255. "in_port(2),eth(),eth_type(0x0800),ipv4()" \
  256. "sample(sample=100%,actions(psample(group=2,cookie=eeff0c),userspace(pid=${nlpid},userdata=eeff0c))),1"
  257. # Record psample data.
  258. ovs_spawn_daemon "test_psample" python3 $ovs_base/ovs-dpctl.py psample-events
  259. ovs_wait grep -q "listening for psample events" ${ovs_dir}/stdout
  260. # Send a single ping.
  261. ovs_sbx "test_psample" ip netns exec client ping -I c1 172.31.110.20 -c 1 || return 1
  262. # We should have received one userspace action upcall and 2 psample packets.
  263. ovs_wait grep -q "userspace action command" $ovs_dir/s0.out || return 1
  264. # client -> server samples should only contain the first 14 bytes of the packet.
  265. ovs_wait grep -qE "rate:4294967295,group:1,cookie:c0ffee data:[0-9a-f]{28}$" \
  266. $ovs_dir/stdout || return 1
  267. ovs_wait grep -q "rate:4294967295,group:2,cookie:eeff0c" $ovs_dir/stdout || return 1
  268. return 0
  269. }
  270. # drop_reason test
  271. # - drop packets and verify the right drop reason is reported
  272. test_drop_reason() {
  273. which perf >/dev/null 2>&1 || return $ksft_skip
  274. sbx_add "test_drop_reason" || return $?
  275. ovs_add_dp "test_drop_reason" dropreason || return 1
  276. info "create namespaces"
  277. for ns in client server; do
  278. ovs_add_netns_and_veths "test_drop_reason" "dropreason" "$ns" \
  279. "${ns:0:1}0" "${ns:0:1}1" || return 1
  280. done
  281. # Setup client namespace
  282. ip netns exec client ip addr add 172.31.110.10/24 dev c1
  283. ip netns exec client ip link set c1 up
  284. # Setup server namespace
  285. ip netns exec server ip addr add 172.31.110.20/24 dev s1
  286. ip netns exec server ip link set s1 up
  287. # Check if drop reasons can be sent
  288. ovs_add_flow "test_drop_reason" dropreason \
  289. 'in_port(1),eth(),eth_type(0x0806),arp()' 'drop(10)' 2>/dev/null
  290. if [ $? == 1 ]; then
  291. info "no support for drop reasons - skipping"
  292. ovs_exit_sig
  293. return $ksft_skip
  294. fi
  295. ovs_del_flows "test_drop_reason" dropreason
  296. # Allow ARP
  297. ovs_add_flow "test_drop_reason" dropreason \
  298. 'in_port(1),eth(),eth_type(0x0806),arp()' '2' || return 1
  299. ovs_add_flow "test_drop_reason" dropreason \
  300. 'in_port(2),eth(),eth_type(0x0806),arp()' '1' || return 1
  301. # Allow client ICMP traffic but drop return path
  302. ovs_add_flow "test_drop_reason" dropreason \
  303. "in_port(1),eth(),eth_type(0x0800),ipv4(src=172.31.110.10,proto=1),icmp()" '2'
  304. ovs_add_flow "test_drop_reason" dropreason \
  305. "in_port(2),eth(),eth_type(0x0800),ipv4(src=172.31.110.20,proto=1),icmp()" 'drop'
  306. ovs_drop_record_and_run "test_drop_reason" ip netns exec client ping -c 2 172.31.110.20
  307. ovs_drop_reason_count 0x30001 # OVS_DROP_FLOW_ACTION
  308. if [[ "$?" -ne "2" ]]; then
  309. info "Did not detect expected drops: $?"
  310. return 1
  311. fi
  312. # Drop UDP 6000 traffic with an explicit action and an error code.
  313. ovs_add_flow "test_drop_reason" dropreason \
  314. "in_port(1),eth(),eth_type(0x0800),ipv4(src=172.31.110.10,proto=17),udp(dst=6000)" \
  315. 'drop(42)'
  316. # Drop UDP 7000 traffic with an explicit action with no error code.
  317. ovs_add_flow "test_drop_reason" dropreason \
  318. "in_port(1),eth(),eth_type(0x0800),ipv4(src=172.31.110.10,proto=17),udp(dst=7000)" \
  319. 'drop(0)'
  320. ovs_drop_record_and_run \
  321. "test_drop_reason" ip netns exec client nc -i 1 -zuv 172.31.110.20 6000
  322. ovs_drop_reason_count 0x30004 # OVS_DROP_EXPLICIT_ACTION_ERROR
  323. if [[ "$?" -ne "1" ]]; then
  324. info "Did not detect expected explicit error drops: $?"
  325. return 1
  326. fi
  327. ovs_drop_record_and_run \
  328. "test_drop_reason" ip netns exec client nc -i 1 -zuv 172.31.110.20 7000
  329. ovs_drop_reason_count 0x30003 # OVS_DROP_EXPLICIT_ACTION
  330. if [[ "$?" -ne "1" ]]; then
  331. info "Did not detect expected explicit drops: $?"
  332. return 1
  333. fi
  334. return 0
  335. }
  336. # arp_ping test
  337. # - client has 1500 byte MTU
  338. # - server has 1500 byte MTU
  339. # - send ARP ping between two ns
  340. test_arp_ping () {
  341. which arping >/dev/null 2>&1 || return $ksft_skip
  342. sbx_add "test_arp_ping" || return $?
  343. ovs_add_dp "test_arp_ping" arpping || return 1
  344. info "create namespaces"
  345. for ns in client server; do
  346. ovs_add_netns_and_veths "test_arp_ping" "arpping" "$ns" \
  347. "${ns:0:1}0" "${ns:0:1}1" || return 1
  348. done
  349. # Setup client namespace
  350. ip netns exec client ip addr add 172.31.110.10/24 dev c1
  351. ip netns exec client ip link set c1 up
  352. HW_CLIENT=`ip netns exec client ip link show dev c1 | grep -E 'link/ether [0-9a-f:]+' | awk '{print $2;}'`
  353. info "Client hwaddr: $HW_CLIENT"
  354. # Setup server namespace
  355. ip netns exec server ip addr add 172.31.110.20/24 dev s1
  356. ip netns exec server ip link set s1 up
  357. HW_SERVER=`ip netns exec server ip link show dev s1 | grep -E 'link/ether [0-9a-f:]+' | awk '{print $2;}'`
  358. info "Server hwaddr: $HW_SERVER"
  359. ovs_add_flow "test_arp_ping" arpping \
  360. "in_port(1),eth(),eth_type(0x0806),arp(sip=172.31.110.10,tip=172.31.110.20,sha=$HW_CLIENT,tha=ff:ff:ff:ff:ff:ff)" '2' || return 1
  361. ovs_add_flow "test_arp_ping" arpping \
  362. "in_port(2),eth(),eth_type(0x0806),arp()" '1' || return 1
  363. ovs_sbx "test_arp_ping" ip netns exec client arping -I c1 172.31.110.20 -c 1 || return 1
  364. return 0
  365. }
  366. # ct_connect_v4 test
  367. # - client has 1500 byte MTU
  368. # - server has 1500 byte MTU
  369. # - use ICMP to ping in each direction
  370. # - only allow CT state stuff to pass through new in c -> s
  371. test_ct_connect_v4 () {
  372. which nc >/dev/null 2>/dev/null || return $ksft_skip
  373. sbx_add "test_ct_connect_v4" || return $?
  374. ovs_add_dp "test_ct_connect_v4" ct4 || return 1
  375. info "create namespaces"
  376. for ns in client server; do
  377. ovs_add_netns_and_veths "test_ct_connect_v4" "ct4" "$ns" \
  378. "${ns:0:1}0" "${ns:0:1}1" || return 1
  379. done
  380. ip netns exec client ip addr add 172.31.110.10/24 dev c1
  381. ip netns exec client ip link set c1 up
  382. ip netns exec server ip addr add 172.31.110.20/24 dev s1
  383. ip netns exec server ip link set s1 up
  384. # Add forwarding for ARP and ip packets - completely wildcarded
  385. ovs_add_flow "test_ct_connect_v4" ct4 \
  386. 'in_port(1),eth(),eth_type(0x0806),arp()' '2' || return 1
  387. ovs_add_flow "test_ct_connect_v4" ct4 \
  388. 'in_port(2),eth(),eth_type(0x0806),arp()' '1' || return 1
  389. ovs_add_flow "test_ct_connect_v4" ct4 \
  390. 'ct_state(-trk),eth(),eth_type(0x0800),ipv4()' \
  391. 'ct(commit),recirc(0x1)' || return 1
  392. ovs_add_flow "test_ct_connect_v4" ct4 \
  393. 'recirc_id(0x1),ct_state(+trk+new),in_port(1),eth(),eth_type(0x0800),ipv4(src=172.31.110.10)' \
  394. '2' || return 1
  395. ovs_add_flow "test_ct_connect_v4" ct4 \
  396. 'recirc_id(0x1),ct_state(+trk+est),in_port(1),eth(),eth_type(0x0800),ipv4(src=172.31.110.10)' \
  397. '2' || return 1
  398. ovs_add_flow "test_ct_connect_v4" ct4 \
  399. 'recirc_id(0x1),ct_state(+trk+est),in_port(2),eth(),eth_type(0x0800),ipv4(dst=172.31.110.10)' \
  400. '1' || return 1
  401. ovs_add_flow "test_ct_connect_v4" ct4 \
  402. 'recirc_id(0x1),ct_state(+trk+inv),eth(),eth_type(0x0800),ipv4()' 'drop' || \
  403. return 1
  404. # do a ping
  405. ovs_sbx "test_ct_connect_v4" ip netns exec client ping 172.31.110.20 -c 3 || return 1
  406. # create an echo server in 'server'
  407. echo "server" | \
  408. ovs_netns_spawn_daemon "test_ct_connect_v4" "server" \
  409. nc -lvnp 4443
  410. ovs_sbx "test_ct_connect_v4" ip netns exec client nc -i 1 -zv 172.31.110.20 4443 || return 1
  411. # Now test in the other direction (should fail)
  412. echo "client" | \
  413. ovs_netns_spawn_daemon "test_ct_connect_v4" "client" \
  414. nc -lvnp 4443
  415. ovs_sbx "test_ct_connect_v4" ip netns exec client nc -i 1 -zv 172.31.110.10 4443
  416. if [ $? == 0 ]; then
  417. info "ct connect to client was successful"
  418. return 1
  419. fi
  420. info "done..."
  421. return 0
  422. }
  423. # connect_v4 test
  424. # - client has 1500 byte MTU
  425. # - server has 1500 byte MTU
  426. # - use ICMP to ping in each direction
  427. test_connect_v4 () {
  428. sbx_add "test_connect_v4" || return $?
  429. ovs_add_dp "test_connect_v4" cv4 || return 1
  430. info "create namespaces"
  431. for ns in client server; do
  432. ovs_add_netns_and_veths "test_connect_v4" "cv4" "$ns" \
  433. "${ns:0:1}0" "${ns:0:1}1" || return 1
  434. done
  435. ip netns exec client ip addr add 172.31.110.10/24 dev c1
  436. ip netns exec client ip link set c1 up
  437. ip netns exec server ip addr add 172.31.110.20/24 dev s1
  438. ip netns exec server ip link set s1 up
  439. # Add forwarding for ARP and ip packets - completely wildcarded
  440. ovs_add_flow "test_connect_v4" cv4 \
  441. 'in_port(1),eth(),eth_type(0x0806),arp()' '2' || return 1
  442. ovs_add_flow "test_connect_v4" cv4 \
  443. 'in_port(2),eth(),eth_type(0x0806),arp()' '1' || return 1
  444. ovs_add_flow "test_connect_v4" cv4 \
  445. 'in_port(1),eth(),eth_type(0x0800),ipv4(src=172.31.110.10)' '2' || return 1
  446. ovs_add_flow "test_connect_v4" cv4 \
  447. 'in_port(2),eth(),eth_type(0x0800),ipv4(src=172.31.110.20)' '1' || return 1
  448. # do a ping
  449. ovs_sbx "test_connect_v4" ip netns exec client ping 172.31.110.20 -c 3 || return 1
  450. info "done..."
  451. return 0
  452. }
  453. # nat_connect_v4 test
  454. # - client has 1500 byte MTU
  455. # - server has 1500 byte MTU
  456. # - use ICMP to ping in each direction
  457. # - only allow CT state stuff to pass through new in c -> s
  458. test_nat_connect_v4 () {
  459. which nc >/dev/null 2>/dev/null || return $ksft_skip
  460. sbx_add "test_nat_connect_v4" || return $?
  461. ovs_add_dp "test_nat_connect_v4" nat4 || return 1
  462. info "create namespaces"
  463. for ns in client server; do
  464. ovs_add_netns_and_veths "test_nat_connect_v4" "nat4" "$ns" \
  465. "${ns:0:1}0" "${ns:0:1}1" || return 1
  466. done
  467. ip netns exec client ip addr add 172.31.110.10/24 dev c1
  468. ip netns exec client ip link set c1 up
  469. ip netns exec server ip addr add 172.31.110.20/24 dev s1
  470. ip netns exec server ip link set s1 up
  471. ip netns exec client ip route add default via 172.31.110.20
  472. ovs_add_flow "test_nat_connect_v4" nat4 \
  473. 'in_port(1),eth(),eth_type(0x0806),arp()' '2' || return 1
  474. ovs_add_flow "test_nat_connect_v4" nat4 \
  475. 'in_port(2),eth(),eth_type(0x0806),arp()' '1' || return 1
  476. ovs_add_flow "test_nat_connect_v4" nat4 \
  477. "ct_state(-trk),in_port(1),eth(),eth_type(0x0800),ipv4(dst=192.168.0.20)" \
  478. "ct(commit,nat(dst=172.31.110.20)),recirc(0x1)"
  479. ovs_add_flow "test_nat_connect_v4" nat4 \
  480. "ct_state(-trk),in_port(2),eth(),eth_type(0x0800),ipv4()" \
  481. "ct(commit,nat),recirc(0x2)"
  482. ovs_add_flow "test_nat_connect_v4" nat4 \
  483. "recirc_id(0x1),ct_state(+trk-inv),in_port(1),eth(),eth_type(0x0800),ipv4()" "2"
  484. ovs_add_flow "test_nat_connect_v4" nat4 \
  485. "recirc_id(0x2),ct_state(+trk-inv),in_port(2),eth(),eth_type(0x0800),ipv4()" "1"
  486. # do a ping
  487. ovs_sbx "test_nat_connect_v4" ip netns exec client ping 192.168.0.20 -c 3 || return 1
  488. # create an echo server in 'server'
  489. echo "server" | \
  490. ovs_netns_spawn_daemon "test_nat_connect_v4" "server" \
  491. nc -lvnp 4443
  492. ovs_sbx "test_nat_connect_v4" ip netns exec client nc -i 1 -zv 192.168.0.20 4443 || return 1
  493. # Now test in the other direction (should fail)
  494. echo "client" | \
  495. ovs_netns_spawn_daemon "test_nat_connect_v4" "client" \
  496. nc -lvnp 4443
  497. ovs_sbx "test_nat_connect_v4" ip netns exec client nc -i 1 -zv 172.31.110.10 4443
  498. if [ $? == 0 ]; then
  499. info "connect to client was successful"
  500. return 1
  501. fi
  502. info "done..."
  503. return 0
  504. }
  505. # nat_related_v4 test
  506. # - client->server ip packets go via SNAT
  507. # - client solicits ICMP destination unreachable packet from server
  508. # - undo NAT for ICMP reply and test dst ip has been updated
  509. test_nat_related_v4 () {
  510. which nc >/dev/null 2>/dev/null || return $ksft_skip
  511. sbx_add "test_nat_related_v4" || return $?
  512. ovs_add_dp "test_nat_related_v4" natrelated4 || return 1
  513. info "create namespaces"
  514. for ns in client server; do
  515. ovs_add_netns_and_veths "test_nat_related_v4" "natrelated4" "$ns" \
  516. "${ns:0:1}0" "${ns:0:1}1" || return 1
  517. done
  518. ip netns exec client ip addr add 172.31.110.10/24 dev c1
  519. ip netns exec client ip link set c1 up
  520. ip netns exec server ip addr add 172.31.110.20/24 dev s1
  521. ip netns exec server ip link set s1 up
  522. ip netns exec server ip route add 192.168.0.20/32 via 172.31.110.10
  523. # Allow ARP
  524. ovs_add_flow "test_nat_related_v4" natrelated4 \
  525. "in_port(1),eth(),eth_type(0x0806),arp()" "2" || return 1
  526. ovs_add_flow "test_nat_related_v4" natrelated4 \
  527. "in_port(2),eth(),eth_type(0x0806),arp()" "1" || return 1
  528. # Allow IP traffic from client->server, rewrite source IP with SNAT to 192.168.0.20
  529. ovs_add_flow "test_nat_related_v4" natrelated4 \
  530. "ct_state(-trk),in_port(1),eth(),eth_type(0x0800),ipv4(dst=172.31.110.20)" \
  531. "ct(commit,nat(src=192.168.0.20)),recirc(0x1)" || return 1
  532. ovs_add_flow "test_nat_related_v4" natrelated4 \
  533. "recirc_id(0x1),ct_state(+trk-inv),in_port(1),eth(),eth_type(0x0800),ipv4()" \
  534. "2" || return 1
  535. # Allow related ICMP responses back from server and undo NAT to restore original IP
  536. # Drop any ICMP related packets where dst ip hasn't been restored back to original IP
  537. ovs_add_flow "test_nat_related_v4" natrelated4 \
  538. "ct_state(-trk),in_port(2),eth(),eth_type(0x0800),ipv4()" \
  539. "ct(commit,nat),recirc(0x2)" || return 1
  540. ovs_add_flow "test_nat_related_v4" natrelated4 \
  541. "recirc_id(0x2),ct_state(+rel+trk),in_port(2),eth(),eth_type(0x0800),ipv4(src=172.31.110.20,dst=172.31.110.10,proto=1),icmp()" \
  542. "1" || return 1
  543. ovs_add_flow "test_nat_related_v4" natrelated4 \
  544. "recirc_id(0x2),ct_state(+rel+trk),in_port(2),eth(),eth_type(0x0800),ipv4(dst=192.168.0.20,proto=1),icmp()" \
  545. "drop" || return 1
  546. # Solicit destination unreachable response from server
  547. ovs_sbx "test_nat_related_v4" ip netns exec client \
  548. bash -c "echo a | nc -u -w 1 172.31.110.20 10000"
  549. # Check to make sure no packets matched the drop rule with incorrect dst ip
  550. python3 "$ovs_base/ovs-dpctl.py" dump-flows natrelated4 \
  551. | grep "drop" | grep "packets:0" >/dev/null || return 1
  552. info "done..."
  553. return 0
  554. }
  555. # netlink_validation
  556. # - Create a dp
  557. # - check no warning with "old version" simulation
  558. test_netlink_checks () {
  559. sbx_add "test_netlink_checks" || return 1
  560. info "setting up new DP"
  561. ovs_add_dp "test_netlink_checks" nv0 || return 1
  562. # now try again
  563. PRE_TEST=$(dmesg | grep -E "RIP: [0-9a-fA-Fx]+:ovs_dp_cmd_new\+")
  564. ovs_add_dp "test_netlink_checks" nv0 -V 0 || return 1
  565. POST_TEST=$(dmesg | grep -E "RIP: [0-9a-fA-Fx]+:ovs_dp_cmd_new\+")
  566. if [ "$PRE_TEST" != "$POST_TEST" ]; then
  567. info "failed - gen warning"
  568. return 1
  569. fi
  570. ovs_add_netns_and_veths "test_netlink_checks" nv0 left left0 l0 || \
  571. return 1
  572. ovs_add_netns_and_veths "test_netlink_checks" nv0 right right0 r0 || \
  573. return 1
  574. [ $(python3 $ovs_base/ovs-dpctl.py show nv0 | grep port | \
  575. wc -l) == 3 ] || \
  576. return 1
  577. ovs_del_if "test_netlink_checks" nv0 right0 || return 1
  578. [ $(python3 $ovs_base/ovs-dpctl.py show nv0 | grep port | \
  579. wc -l) == 2 ] || \
  580. return 1
  581. info "Checking clone depth"
  582. ERR_MSG="Flow actions may not be safe on all matching packets"
  583. PRE_TEST=$(dmesg | grep -c "${ERR_MSG}")
  584. ovs_add_flow "test_netlink_checks" nv0 \
  585. 'in_port(1),eth(),eth_type(0x800),ipv4()' \
  586. 'clone(clone(clone(clone(clone(clone(clone(clone(clone(clone(clone(clone(clone(clone(clone(clone(clone(drop)))))))))))))))))' \
  587. >/dev/null 2>&1 && return 1
  588. POST_TEST=$(dmesg | grep -c "${ERR_MSG}")
  589. if [ "$PRE_TEST" == "$POST_TEST" ]; then
  590. info "failed - clone depth too large"
  591. return 1
  592. fi
  593. PRE_TEST=$(dmesg | grep -c "${ERR_MSG}")
  594. ovs_add_flow "test_netlink_checks" nv0 \
  595. 'in_port(1),eth(),eth_type(0x0806),arp()' 'drop(0),2' \
  596. &> /dev/null && return 1
  597. POST_TEST=$(dmesg | grep -c "${ERR_MSG}")
  598. if [ "$PRE_TEST" == "$POST_TEST" ]; then
  599. info "failed - error not generated"
  600. return 1
  601. fi
  602. return 0
  603. }
  604. test_upcall_interfaces() {
  605. sbx_add "test_upcall_interfaces" || return 1
  606. info "setting up new DP"
  607. ovs_add_dp "test_upcall_interfaces" ui0 -V 2:1 || return 1
  608. ovs_add_netns_and_veths "test_upcall_interfaces" ui0 upc left0 l0 \
  609. 172.31.110.1/24 -u || return 1
  610. ovs_wait grep -q "listening on upcall packet handler" ${ovs_dir}/left0.out
  611. info "sending arping"
  612. ip netns exec upc arping -I l0 172.31.110.20 -c 1 \
  613. >$ovs_dir/arping.stdout 2>$ovs_dir/arping.stderr
  614. grep -E "MISS upcall\[0/yes\]: .*arp\(sip=172.31.110.1,tip=172.31.110.20,op=1,sha=" $ovs_dir/left0.out >/dev/null 2>&1 || return 1
  615. return 0
  616. }
  617. run_test() {
  618. (
  619. tname="$1"
  620. tdesc="$2"
  621. if python3 ovs-dpctl.py -h 2>&1 | \
  622. grep -E "Need to (install|upgrade) the python" >/dev/null 2>&1; then
  623. stdbuf -o0 printf "TEST: %-60s [PYLIB]\n" "${tdesc}"
  624. return $ksft_skip
  625. fi
  626. python3 ovs-dpctl.py show >/dev/null 2>&1 || \
  627. echo "[DPCTL] show exception."
  628. if ! lsmod | grep openvswitch >/dev/null 2>&1; then
  629. stdbuf -o0 printf "TEST: %-60s [NOMOD]\n" "${tdesc}"
  630. return $ksft_skip
  631. fi
  632. printf "TEST: %-60s [START]\n" "${tname}"
  633. unset IFS
  634. eval test_${tname}
  635. ret=$?
  636. if [ $ret -eq 0 ]; then
  637. printf "TEST: %-60s [ OK ]\n" "${tdesc}"
  638. ovs_exit_sig
  639. rm -rf "$ovs_dir"
  640. elif [ $ret -eq 1 ]; then
  641. printf "TEST: %-60s [FAIL]\n" "${tdesc}"
  642. if [ "${PAUSE_ON_FAIL}" = "yes" ]; then
  643. echo
  644. echo "Pausing. Logs in $ovs_dir/. Hit enter to continue"
  645. read a
  646. fi
  647. ovs_exit_sig
  648. [ "${PAUSE_ON_FAIL}" = "yes" ] || rm -rf "$ovs_dir"
  649. exit 1
  650. elif [ $ret -eq $ksft_skip ]; then
  651. printf "TEST: %-60s [SKIP]\n" "${tdesc}"
  652. elif [ $ret -eq 2 ]; then
  653. rm -rf test_${tname}
  654. run_test "$1" "$2"
  655. fi
  656. return $ret
  657. )
  658. ret=$?
  659. case $ret in
  660. 0)
  661. [ $all_skipped = true ] && [ $exitcode=$ksft_skip ] && exitcode=0
  662. all_skipped=false
  663. ;;
  664. $ksft_skip)
  665. [ $all_skipped = true ] && exitcode=$ksft_skip
  666. ;;
  667. *)
  668. all_skipped=false
  669. exitcode=1
  670. ;;
  671. esac
  672. return $ret
  673. }
  674. exitcode=0
  675. desc=0
  676. all_skipped=true
  677. while getopts :pvt o
  678. do
  679. case $o in
  680. p) PAUSE_ON_FAIL=yes;;
  681. v) VERBOSE=1;;
  682. t) if which tcpdump > /dev/null 2>&1; then
  683. TRACING=1
  684. else
  685. echo "=== tcpdump not available, tracing disabled"
  686. fi
  687. ;;
  688. *) usage;;
  689. esac
  690. done
  691. shift $(($OPTIND-1))
  692. IFS="
  693. "
  694. for arg do
  695. # Check first that all requested tests are available before running any
  696. command -v > /dev/null "test_${arg}" || { echo "=== Test ${arg} not found"; usage; }
  697. done
  698. name=""
  699. desc=""
  700. for t in ${tests}; do
  701. [ "${name}" = "" ] && name="${t}" && continue
  702. [ "${desc}" = "" ] && desc="${t}"
  703. run_this=1
  704. for arg do
  705. [ "${arg}" != "${arg#--*}" ] && continue
  706. [ "${arg}" = "${name}" ] && run_this=1 && break
  707. run_this=0
  708. done
  709. if [ $run_this -eq 1 ]; then
  710. run_test "${name}" "${desc}"
  711. fi
  712. name=""
  713. desc=""
  714. done
  715. exit ${exitcode}