test_vxlan_nolocalbypass.sh 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. #!/bin/bash
  2. # SPDX-License-Identifier: GPL-2.0
  3. # This test is for checking the [no]localbypass VXLAN device option. The test
  4. # configures two VXLAN devices in the same network namespace and a tc filter on
  5. # the loopback device that drops encapsulated packets. The test sends packets
  6. # from the first VXLAN device and verifies that by default these packets are
  7. # received by the second VXLAN device. The test then enables the nolocalbypass
  8. # option and verifies that packets are no longer received by the second VXLAN
  9. # device.
  10. source lib.sh
  11. ret=0
  12. TESTS="
  13. nolocalbypass
  14. "
  15. VERBOSE=0
  16. PAUSE_ON_FAIL=no
  17. PAUSE=no
  18. ################################################################################
  19. # Utilities
  20. log_test()
  21. {
  22. local rc=$1
  23. local expected=$2
  24. local msg="$3"
  25. if [ ${rc} -eq ${expected} ]; then
  26. printf "TEST: %-60s [ OK ]\n" "${msg}"
  27. nsuccess=$((nsuccess+1))
  28. else
  29. ret=1
  30. nfail=$((nfail+1))
  31. printf "TEST: %-60s [FAIL]\n" "${msg}"
  32. if [ "$VERBOSE" = "1" ]; then
  33. echo " rc=$rc, expected $expected"
  34. fi
  35. if [ "${PAUSE_ON_FAIL}" = "yes" ]; then
  36. echo
  37. echo "hit enter to continue, 'q' to quit"
  38. read a
  39. [ "$a" = "q" ] && exit 1
  40. fi
  41. fi
  42. if [ "${PAUSE}" = "yes" ]; then
  43. echo
  44. echo "hit enter to continue, 'q' to quit"
  45. read a
  46. [ "$a" = "q" ] && exit 1
  47. fi
  48. [ "$VERBOSE" = "1" ] && echo
  49. }
  50. run_cmd()
  51. {
  52. local cmd="$1"
  53. local out
  54. local stderr="2>/dev/null"
  55. if [ "$VERBOSE" = "1" ]; then
  56. printf "COMMAND: $cmd\n"
  57. stderr=
  58. fi
  59. out=$(eval $cmd $stderr)
  60. rc=$?
  61. if [ "$VERBOSE" = "1" -a -n "$out" ]; then
  62. echo " $out"
  63. fi
  64. return $rc
  65. }
  66. tc_check_packets()
  67. {
  68. local ns=$1; shift
  69. local id=$1; shift
  70. local handle=$1; shift
  71. local count=$1; shift
  72. local pkts
  73. sleep 0.1
  74. pkts=$(tc -n $ns -j -s filter show $id \
  75. | jq ".[] | select(.options.handle == $handle) | \
  76. .options.actions[0].stats.packets")
  77. [[ $pkts == $count ]]
  78. }
  79. ################################################################################
  80. # Setup
  81. setup()
  82. {
  83. setup_ns ns1
  84. ip -n $ns1 address add 192.0.2.1/32 dev lo
  85. ip -n $ns1 address add 198.51.100.1/32 dev lo
  86. ip -n $ns1 link add name vx0 up type vxlan id 100 local 198.51.100.1 \
  87. dstport 4789 nolearning
  88. ip -n $ns1 link add name vx1 up type vxlan id 100 dstport 4790
  89. }
  90. cleanup()
  91. {
  92. cleanup_ns $ns1
  93. }
  94. ################################################################################
  95. # Tests
  96. nolocalbypass()
  97. {
  98. local smac=00:01:02:03:04:05
  99. local dmac=00:0a:0b:0c:0d:0e
  100. run_cmd "bridge -n $ns1 fdb add $dmac dev vx0 self static dst 192.0.2.1 port 4790"
  101. run_cmd "tc -n $ns1 qdisc add dev vx1 clsact"
  102. run_cmd "tc -n $ns1 filter add dev vx1 ingress pref 1 handle 101 proto all flower src_mac $smac dst_mac $dmac action pass"
  103. run_cmd "tc -n $ns1 qdisc add dev lo clsact"
  104. run_cmd "tc -n $ns1 filter add dev lo ingress pref 1 handle 101 proto ip flower ip_proto udp dst_port 4790 action drop"
  105. run_cmd "ip -n $ns1 -d -j link show dev vx0 | jq -e '.[][\"linkinfo\"][\"info_data\"][\"localbypass\"] == true'"
  106. log_test $? 0 "localbypass enabled"
  107. run_cmd "ip netns exec $ns1 mausezahn vx0 -a $smac -b $dmac -c 1 -p 100 -q"
  108. tc_check_packets "$ns1" "dev vx1 ingress" 101 1
  109. log_test $? 0 "Packet received by local VXLAN device - localbypass"
  110. run_cmd "ip -n $ns1 link set dev vx0 type vxlan nolocalbypass"
  111. run_cmd "ip -n $ns1 -d -j link show dev vx0 | jq -e '.[][\"linkinfo\"][\"info_data\"][\"localbypass\"] == false'"
  112. log_test $? 0 "localbypass disabled"
  113. run_cmd "ip netns exec $ns1 mausezahn vx0 -a $smac -b $dmac -c 1 -p 100 -q"
  114. tc_check_packets "$ns1" "dev vx1 ingress" 101 1
  115. log_test $? 0 "Packet not received by local VXLAN device - nolocalbypass"
  116. run_cmd "ip -n $ns1 link set dev vx0 type vxlan localbypass"
  117. run_cmd "ip -n $ns1 -d -j link show dev vx0 | jq -e '.[][\"linkinfo\"][\"info_data\"][\"localbypass\"] == true'"
  118. log_test $? 0 "localbypass enabled"
  119. run_cmd "ip netns exec $ns1 mausezahn vx0 -a $smac -b $dmac -c 1 -p 100 -q"
  120. tc_check_packets "$ns1" "dev vx1 ingress" 101 2
  121. log_test $? 0 "Packet received by local VXLAN device - localbypass"
  122. }
  123. ################################################################################
  124. # Usage
  125. usage()
  126. {
  127. cat <<EOF
  128. usage: ${0##*/} OPTS
  129. -t <test> Test(s) to run (default: all)
  130. (options: $TESTS)
  131. -p Pause on fail
  132. -P Pause after each test before cleanup
  133. -v Verbose mode (show commands and output)
  134. EOF
  135. }
  136. ################################################################################
  137. # Main
  138. trap cleanup EXIT
  139. while getopts ":t:pPvh" opt; do
  140. case $opt in
  141. t) TESTS=$OPTARG ;;
  142. p) PAUSE_ON_FAIL=yes;;
  143. P) PAUSE=yes;;
  144. v) VERBOSE=$(($VERBOSE + 1));;
  145. h) usage; exit 0;;
  146. *) usage; exit 1;;
  147. esac
  148. done
  149. # Make sure we don't pause twice.
  150. [ "${PAUSE}" = "yes" ] && PAUSE_ON_FAIL=no
  151. if [ "$(id -u)" -ne 0 ];then
  152. echo "SKIP: Need root privileges"
  153. exit $ksft_skip;
  154. fi
  155. if [ ! -x "$(command -v ip)" ]; then
  156. echo "SKIP: Could not run test without ip tool"
  157. exit $ksft_skip
  158. fi
  159. if [ ! -x "$(command -v bridge)" ]; then
  160. echo "SKIP: Could not run test without bridge tool"
  161. exit $ksft_skip
  162. fi
  163. if [ ! -x "$(command -v mausezahn)" ]; then
  164. echo "SKIP: Could not run test without mausezahn tool"
  165. exit $ksft_skip
  166. fi
  167. if [ ! -x "$(command -v jq)" ]; then
  168. echo "SKIP: Could not run test without jq tool"
  169. exit $ksft_skip
  170. fi
  171. ip link help vxlan 2>&1 | grep -q "localbypass"
  172. if [ $? -ne 0 ]; then
  173. echo "SKIP: iproute2 ip too old, missing VXLAN nolocalbypass support"
  174. exit $ksft_skip
  175. fi
  176. cleanup
  177. for t in $TESTS
  178. do
  179. setup; $t; cleanup;
  180. done
  181. if [ "$TESTS" != "none" ]; then
  182. printf "\nTests passed: %3d\n" ${nsuccess}
  183. printf "Tests failed: %3d\n" ${nfail}
  184. fi
  185. exit $ret