vxlan_flooding.sh 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326
  1. #!/bin/bash
  2. # SPDX-License-Identifier: GPL-2.0
  3. #
  4. # Test VxLAN flooding. The device stores flood records in a singly linked list
  5. # where each record stores up to three IPv4 addresses of remote VTEPs. The test
  6. # verifies that packets are correctly flooded in various cases such as deletion
  7. # of a record in the middle of the list.
  8. #
  9. # +--------------------+
  10. # | H1 (vrf) |
  11. # | + $h1 |
  12. # | | 203.0.113.1/24|
  13. # +----|---------------+
  14. # |
  15. # +----|----------------------------------------------------------------------+
  16. # | SW | |
  17. # | +--|--------------------------------------------------------------------+ |
  18. # | | + $swp1 BR0 (802.1d) | |
  19. # | | | |
  20. # | | + vxlan0 (vxlan) | |
  21. # | | local 198.51.100.1 | |
  22. # | | remote 198.51.100.{2..13} | |
  23. # | | id 10 dstport 4789 | |
  24. # | +-----------------------------------------------------------------------+ |
  25. # | |
  26. # | 198.51.100.0/24 via 192.0.2.2 |
  27. # | |
  28. # | + $rp1 |
  29. # | | 192.0.2.1/24 |
  30. # +----|----------------------------------------------------------------------+
  31. # |
  32. # +----|--------------------------------------------------------+
  33. # | | R2 (vrf) |
  34. # | + $rp2 |
  35. # | 192.0.2.2/24 |
  36. # | |
  37. # +-------------------------------------------------------------+
  38. lib_dir=$(dirname $0)/../../../net/forwarding
  39. ALL_TESTS="flooding_test"
  40. NUM_NETIFS=4
  41. source $lib_dir/tc_common.sh
  42. source $lib_dir/lib.sh
  43. h1_create()
  44. {
  45. simple_if_init $h1 203.0.113.1/24
  46. }
  47. h1_destroy()
  48. {
  49. simple_if_fini $h1 203.0.113.1/24
  50. }
  51. switch_create()
  52. {
  53. # Make sure the bridge uses the MAC address of the local port and
  54. # not that of the VxLAN's device
  55. ip link add dev br0 type bridge mcast_snooping 0
  56. ip link set dev br0 address $(mac_get $swp1)
  57. ip link add name vxlan0 type vxlan id 10 nolearning noudpcsum \
  58. ttl 20 tos inherit local 198.51.100.1 dstport 4789
  59. ip address add 198.51.100.1/32 dev lo
  60. ip link set dev $swp1 master br0
  61. ip link set dev vxlan0 master br0
  62. ip link set dev br0 up
  63. ip link set dev $swp1 up
  64. ip link set dev vxlan0 up
  65. }
  66. switch_destroy()
  67. {
  68. ip link set dev vxlan0 down
  69. ip link set dev $swp1 down
  70. ip link set dev br0 down
  71. ip link set dev vxlan0 nomaster
  72. ip link set dev $swp1 nomaster
  73. ip address del 198.51.100.1/32 dev lo
  74. ip link del dev vxlan0
  75. ip link del dev br0
  76. }
  77. router1_create()
  78. {
  79. # This router is in the default VRF, where the VxLAN device is
  80. # performing the L3 lookup
  81. ip link set dev $rp1 up
  82. ip address add 192.0.2.1/24 dev $rp1
  83. ip route add 198.51.100.0/24 via 192.0.2.2
  84. }
  85. router1_destroy()
  86. {
  87. ip route del 198.51.100.0/24 via 192.0.2.2
  88. ip address del 192.0.2.1/24 dev $rp1
  89. ip link set dev $rp1 down
  90. }
  91. router2_create()
  92. {
  93. # This router is not in the default VRF, so use simple_if_init()
  94. simple_if_init $rp2 192.0.2.2/24
  95. }
  96. router2_destroy()
  97. {
  98. simple_if_fini $rp2 192.0.2.2/24
  99. }
  100. setup_prepare()
  101. {
  102. h1=${NETIFS[p1]}
  103. swp1=${NETIFS[p2]}
  104. rp1=${NETIFS[p3]}
  105. rp2=${NETIFS[p4]}
  106. vrf_prepare
  107. h1_create
  108. switch_create
  109. router1_create
  110. router2_create
  111. forwarding_enable
  112. }
  113. cleanup()
  114. {
  115. pre_cleanup
  116. forwarding_restore
  117. router2_destroy
  118. router1_destroy
  119. switch_destroy
  120. h1_destroy
  121. vrf_cleanup
  122. }
  123. flooding_remotes_add()
  124. {
  125. local num_remotes=$1
  126. local lsb
  127. local i
  128. for i in $(eval echo {1..$num_remotes}); do
  129. lsb=$((i + 1))
  130. bridge fdb append 00:00:00:00:00:00 dev vxlan0 self \
  131. dst 198.51.100.$lsb
  132. done
  133. }
  134. flooding_filters_add()
  135. {
  136. local num_remotes=$1
  137. local lsb
  138. local i
  139. # Prevent unwanted packets from entering the bridge and interfering
  140. # with the test.
  141. tc qdisc add dev br0 clsact
  142. tc filter add dev br0 egress protocol all pref 1 handle 1 \
  143. matchall skip_hw action drop
  144. tc qdisc add dev $h1 clsact
  145. tc filter add dev $h1 egress protocol all pref 1 handle 1 \
  146. flower skip_hw dst_mac de:ad:be:ef:13:37 action pass
  147. tc filter add dev $h1 egress protocol all pref 2 handle 2 \
  148. matchall skip_hw action drop
  149. tc qdisc add dev $rp2 clsact
  150. for i in $(eval echo {1..$num_remotes}); do
  151. lsb=$((i + 1))
  152. tc filter add dev $rp2 ingress protocol ip pref $i handle $i \
  153. flower ip_proto udp dst_ip 198.51.100.$lsb \
  154. dst_port 4789 skip_sw action drop
  155. done
  156. }
  157. flooding_filters_del()
  158. {
  159. local num_remotes=$1
  160. local i
  161. for i in $(eval echo {1..$num_remotes}); do
  162. tc filter del dev $rp2 ingress protocol ip pref $i \
  163. handle $i flower
  164. done
  165. tc qdisc del dev $rp2 clsact
  166. tc filter del dev $h1 egress protocol all pref 2 handle 2 matchall
  167. tc filter del dev $h1 egress protocol all pref 1 handle 1 flower
  168. tc qdisc del dev $h1 clsact
  169. tc filter del dev br0 egress protocol all pref 1 handle 1 matchall
  170. tc qdisc del dev br0 clsact
  171. }
  172. flooding_check_packets()
  173. {
  174. local packets=("$@")
  175. local num_remotes=${#packets[@]}
  176. local i
  177. for i in $(eval echo {1..$num_remotes}); do
  178. tc_check_packets "dev $rp2 ingress" $i ${packets[i - 1]}
  179. check_err $? "remote $i - did not get expected number of packets"
  180. done
  181. }
  182. flooding_test()
  183. {
  184. # Use 12 remote VTEPs that will be stored in 4 records. The array
  185. # 'packets' will store how many packets are expected to be received
  186. # by each remote VTEP at each stage of the test
  187. declare -a packets=(1 1 1 1 1 1 1 1 1 1 1 1)
  188. local num_remotes=12
  189. RET=0
  190. # Add FDB entries for remote VTEPs and corresponding tc filters on the
  191. # ingress of the nexthop router. These filters will count how many
  192. # packets were flooded to each remote VTEP
  193. flooding_remotes_add $num_remotes
  194. flooding_filters_add $num_remotes
  195. # Send one packet and make sure it is flooded to all the remote VTEPs
  196. $MZ $h1 -q -p 64 -b de:ad:be:ef:13:37 -t ip -c 1
  197. flooding_check_packets "${packets[@]}"
  198. log_test "flood after 1 packet"
  199. # Delete the third record which corresponds to VTEPs with LSB 8..10
  200. # and check that packet is flooded correctly when we remove a record
  201. # from the middle of the list
  202. RET=0
  203. packets=(2 2 2 2 2 2 1 1 1 2 2 2)
  204. bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 198.51.100.8
  205. bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 198.51.100.9
  206. bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 198.51.100.10
  207. $MZ $h1 -q -p 64 -b de:ad:be:ef:13:37 -t ip -c 1
  208. flooding_check_packets "${packets[@]}"
  209. log_test "flood after 2 packets"
  210. # Delete the first record and make sure the packet is flooded correctly
  211. RET=0
  212. packets=(2 2 2 3 3 3 1 1 1 3 3 3)
  213. bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 198.51.100.2
  214. bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 198.51.100.3
  215. bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 198.51.100.4
  216. $MZ $h1 -q -p 64 -b de:ad:be:ef:13:37 -t ip -c 1
  217. flooding_check_packets "${packets[@]}"
  218. log_test "flood after 3 packets"
  219. # Delete the last record and make sure the packet is flooded correctly
  220. RET=0
  221. packets=(2 2 2 4 4 4 1 1 1 3 3 3)
  222. bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 198.51.100.11
  223. bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 198.51.100.12
  224. bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 198.51.100.13
  225. $MZ $h1 -q -p 64 -b de:ad:be:ef:13:37 -t ip -c 1
  226. flooding_check_packets "${packets[@]}"
  227. log_test "flood after 4 packets"
  228. # Delete the last record, one entry at a time and make sure single
  229. # entries are correctly removed
  230. RET=0
  231. packets=(2 2 2 4 5 5 1 1 1 3 3 3)
  232. bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 198.51.100.5
  233. $MZ $h1 -q -p 64 -b de:ad:be:ef:13:37 -t ip -c 1
  234. flooding_check_packets "${packets[@]}"
  235. log_test "flood after 5 packets"
  236. RET=0
  237. packets=(2 2 2 4 5 6 1 1 1 3 3 3)
  238. bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 198.51.100.6
  239. $MZ $h1 -q -p 64 -b de:ad:be:ef:13:37 -t ip -c 1
  240. flooding_check_packets "${packets[@]}"
  241. log_test "flood after 6 packets"
  242. RET=0
  243. packets=(2 2 2 4 5 6 1 1 1 3 3 3)
  244. bridge fdb del 00:00:00:00:00:00 dev vxlan0 self dst 198.51.100.7
  245. $MZ $h1 -q -p 64 -b de:ad:be:ef:13:37 -t ip -c 1
  246. flooding_check_packets "${packets[@]}"
  247. log_test "flood after 7 packets"
  248. flooding_filters_del $num_remotes
  249. }
  250. trap cleanup EXIT
  251. setup_prepare
  252. setup_wait
  253. tests_run
  254. exit $EXIT_STATUS