test_bridge_neigh_suppress.sh 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972
  1. #!/bin/bash
  2. # SPDX-License-Identifier: GPL-2.0
  3. #
  4. # This test is for checking bridge neighbor suppression functionality. The
  5. # topology consists of two bridges (VTEPs) connected using VXLAN. A single
  6. # host is connected to each bridge over multiple VLANs. The test checks that
  7. # ARP/NS messages from the first host are suppressed on the VXLAN port when
  8. # should.
  9. #
  10. # +-----------------------+ +------------------------+
  11. # | h1 | | h2 |
  12. # | | | |
  13. # | + eth0.10 | | + eth0.10 |
  14. # | | 192.0.2.1/28 | | | 192.0.2.2/28 |
  15. # | | 2001:db8:1::1/64 | | | 2001:db8:1::2/64 |
  16. # | | | | | |
  17. # | | + eth0.20 | | | + eth0.20 |
  18. # | \ | 192.0.2.17/28 | | \ | 192.0.2.18/28 |
  19. # | \ | 2001:db8:2::1/64 | | \ | 2001:db8:2::2/64 |
  20. # | \| | | \| |
  21. # | + eth0 | | + eth0 |
  22. # +----|------------------+ +----|-------------------+
  23. # | |
  24. # | |
  25. # +----|-------------------------------+ +----|-------------------------------+
  26. # | + swp1 + vx0 | | + swp1 + vx0 |
  27. # | | | | | | | |
  28. # | | br0 | | | | | |
  29. # | +------------+-----------+ | | +------------+-----------+ |
  30. # | | | | | |
  31. # | | | | | |
  32. # | +---+---+ | | +---+---+ |
  33. # | | | | | | | |
  34. # | | | | | | | |
  35. # | + + | | + + |
  36. # | br0.10 br0.20 | | br0.10 br0.20 |
  37. # | | | |
  38. # | 192.0.2.33 | | 192.0.2.34 |
  39. # | + lo | | + lo |
  40. # | | | |
  41. # | | | |
  42. # | 192.0.2.49/28 | | 192.0.2.50/28 |
  43. # | veth0 +-------+ veth0 |
  44. # | | | |
  45. # | sw1 | | sw2 |
  46. # +------------------------------------+ +------------------------------------+
  47. source lib.sh
  48. ret=0
  49. # All tests in this script. Can be overridden with -t option.
  50. TESTS="
  51. neigh_suppress_arp
  52. neigh_suppress_uc_arp
  53. neigh_suppress_ns
  54. neigh_suppress_uc_ns
  55. neigh_vlan_suppress_arp
  56. neigh_vlan_suppress_ns
  57. "
  58. VERBOSE=0
  59. PAUSE_ON_FAIL=no
  60. PAUSE=no
  61. ################################################################################
  62. # Utilities
  63. log_test()
  64. {
  65. local rc=$1
  66. local expected=$2
  67. local msg="$3"
  68. if [ ${rc} -eq ${expected} ]; then
  69. printf "TEST: %-60s [ OK ]\n" "${msg}"
  70. nsuccess=$((nsuccess+1))
  71. else
  72. ret=1
  73. nfail=$((nfail+1))
  74. printf "TEST: %-60s [FAIL]\n" "${msg}"
  75. if [ "$VERBOSE" = "1" ]; then
  76. echo " rc=$rc, expected $expected"
  77. fi
  78. if [ "${PAUSE_ON_FAIL}" = "yes" ]; then
  79. echo
  80. echo "hit enter to continue, 'q' to quit"
  81. read a
  82. [ "$a" = "q" ] && exit 1
  83. fi
  84. fi
  85. if [ "${PAUSE}" = "yes" ]; then
  86. echo
  87. echo "hit enter to continue, 'q' to quit"
  88. read a
  89. [ "$a" = "q" ] && exit 1
  90. fi
  91. [ "$VERBOSE" = "1" ] && echo
  92. }
  93. run_cmd()
  94. {
  95. local cmd="$1"
  96. local out
  97. local stderr="2>/dev/null"
  98. if [ "$VERBOSE" = "1" ]; then
  99. printf "COMMAND: $cmd\n"
  100. stderr=
  101. fi
  102. out=$(eval $cmd $stderr)
  103. rc=$?
  104. if [ "$VERBOSE" = "1" -a -n "$out" ]; then
  105. echo " $out"
  106. fi
  107. return $rc
  108. }
  109. tc_check_packets()
  110. {
  111. local ns=$1; shift
  112. local id=$1; shift
  113. local handle=$1; shift
  114. local count=$1; shift
  115. local pkts
  116. sleep 0.1
  117. pkts=$(tc -n $ns -j -s filter show $id \
  118. | jq ".[] | select(.options.handle == $handle) | \
  119. .options.actions[0].stats.packets")
  120. [[ $pkts == $count ]]
  121. }
  122. ################################################################################
  123. # Setup
  124. setup_topo_ns()
  125. {
  126. local ns=$1; shift
  127. ip netns exec $ns sysctl -qw net.ipv6.conf.all.keep_addr_on_down=1
  128. ip netns exec $ns sysctl -qw net.ipv6.conf.default.ignore_routes_with_linkdown=1
  129. ip netns exec $ns sysctl -qw net.ipv6.conf.all.accept_dad=0
  130. ip netns exec $ns sysctl -qw net.ipv6.conf.default.accept_dad=0
  131. }
  132. setup_topo()
  133. {
  134. local ns
  135. setup_ns h1 h2 sw1 sw2
  136. for ns in $h1 $h2 $sw1 $sw2; do
  137. setup_topo_ns $ns
  138. done
  139. ip -n $h1 link add name eth0 type veth peer name swp1 netns $sw1
  140. ip -n $sw1 link add name veth0 type veth peer name veth0 netns $sw2
  141. ip -n $h2 link add name eth0 type veth peer name swp1 netns $sw2
  142. }
  143. setup_host_common()
  144. {
  145. local ns=$1; shift
  146. local v4addr1=$1; shift
  147. local v4addr2=$1; shift
  148. local v6addr1=$1; shift
  149. local v6addr2=$1; shift
  150. ip -n $ns link set dev eth0 up
  151. ip -n $ns link add link eth0 name eth0.10 up type vlan id 10
  152. ip -n $ns link add link eth0 name eth0.20 up type vlan id 20
  153. ip -n $ns address add $v4addr1 dev eth0.10
  154. ip -n $ns address add $v4addr2 dev eth0.20
  155. ip -n $ns address add $v6addr1 dev eth0.10
  156. ip -n $ns address add $v6addr2 dev eth0.20
  157. }
  158. setup_h1()
  159. {
  160. local ns=$h1
  161. local v4addr1=192.0.2.1/28
  162. local v4addr2=192.0.2.17/28
  163. local v6addr1=2001:db8:1::1/64
  164. local v6addr2=2001:db8:2::1/64
  165. setup_host_common $ns $v4addr1 $v4addr2 $v6addr1 $v6addr2
  166. }
  167. setup_h2()
  168. {
  169. local ns=$h2
  170. local v4addr1=192.0.2.2/28
  171. local v4addr2=192.0.2.18/28
  172. local v6addr1=2001:db8:1::2/64
  173. local v6addr2=2001:db8:2::2/64
  174. setup_host_common $ns $v4addr1 $v4addr2 $v6addr1 $v6addr2
  175. }
  176. setup_sw_common()
  177. {
  178. local ns=$1; shift
  179. local local_addr=$1; shift
  180. local remote_addr=$1; shift
  181. local veth_addr=$1; shift
  182. local gw_addr=$1; shift
  183. ip -n $ns address add $local_addr/32 dev lo
  184. ip -n $ns link set dev veth0 up
  185. ip -n $ns address add $veth_addr/28 dev veth0
  186. ip -n $ns route add default via $gw_addr
  187. ip -n $ns link add name br0 up type bridge vlan_filtering 1 \
  188. vlan_default_pvid 0 mcast_snooping 0
  189. ip -n $ns link add link br0 name br0.10 up type vlan id 10
  190. bridge -n $ns vlan add vid 10 dev br0 self
  191. ip -n $ns link add link br0 name br0.20 up type vlan id 20
  192. bridge -n $ns vlan add vid 20 dev br0 self
  193. ip -n $ns link set dev swp1 up master br0
  194. bridge -n $ns vlan add vid 10 dev swp1
  195. bridge -n $ns vlan add vid 20 dev swp1
  196. ip -n $ns link add name vx0 up master br0 type vxlan \
  197. local $local_addr dstport 4789 nolearning external
  198. bridge -n $ns fdb add 00:00:00:00:00:00 dev vx0 self static \
  199. dst $remote_addr src_vni 10010
  200. bridge -n $ns fdb add 00:00:00:00:00:00 dev vx0 self static \
  201. dst $remote_addr src_vni 10020
  202. bridge -n $ns link set dev vx0 vlan_tunnel on learning off
  203. bridge -n $ns vlan add vid 10 dev vx0
  204. bridge -n $ns vlan add vid 10 dev vx0 tunnel_info id 10010
  205. bridge -n $ns vlan add vid 20 dev vx0
  206. bridge -n $ns vlan add vid 20 dev vx0 tunnel_info id 10020
  207. }
  208. setup_sw1()
  209. {
  210. local ns=$sw1
  211. local local_addr=192.0.2.33
  212. local remote_addr=192.0.2.34
  213. local veth_addr=192.0.2.49
  214. local gw_addr=192.0.2.50
  215. setup_sw_common $ns $local_addr $remote_addr $veth_addr $gw_addr
  216. }
  217. setup_sw2()
  218. {
  219. local ns=$sw2
  220. local local_addr=192.0.2.34
  221. local remote_addr=192.0.2.33
  222. local veth_addr=192.0.2.50
  223. local gw_addr=192.0.2.49
  224. setup_sw_common $ns $local_addr $remote_addr $veth_addr $gw_addr
  225. }
  226. setup()
  227. {
  228. set -e
  229. setup_topo
  230. setup_h1
  231. setup_h2
  232. setup_sw1
  233. setup_sw2
  234. sleep 5
  235. set +e
  236. }
  237. cleanup()
  238. {
  239. cleanup_ns $h1 $h2 $sw1 $sw2
  240. }
  241. ################################################################################
  242. # Tests
  243. neigh_suppress_arp_common()
  244. {
  245. local vid=$1; shift
  246. local sip=$1; shift
  247. local tip=$1; shift
  248. local h2_mac
  249. echo
  250. echo "Per-port ARP suppression - VLAN $vid"
  251. echo "----------------------------------"
  252. run_cmd "tc -n $sw1 qdisc replace dev vx0 clsact"
  253. run_cmd "tc -n $sw1 filter replace dev vx0 egress pref 1 handle 101 proto 0x0806 flower indev swp1 arp_tip $tip arp_sip $sip arp_op request action pass"
  254. # Initial state - check that ARP requests are not suppressed and that
  255. # ARP replies are received.
  256. run_cmd "ip netns exec $h1 arping -q -b -c 1 -w 5 -s $sip -I eth0.$vid $tip"
  257. log_test $? 0 "arping"
  258. tc_check_packets $sw1 "dev vx0 egress" 101 1
  259. log_test $? 0 "ARP suppression"
  260. # Enable neighbor suppression and check that nothing changes compared
  261. # to the initial state.
  262. run_cmd "bridge -n $sw1 link set dev vx0 neigh_suppress on"
  263. run_cmd "bridge -n $sw1 -d link show dev vx0 | grep \"neigh_suppress on\""
  264. log_test $? 0 "\"neigh_suppress\" is on"
  265. run_cmd "ip netns exec $h1 arping -q -b -c 1 -w 5 -s $sip -I eth0.$vid $tip"
  266. log_test $? 0 "arping"
  267. tc_check_packets $sw1 "dev vx0 egress" 101 2
  268. log_test $? 0 "ARP suppression"
  269. # Install an FDB entry for the remote host and check that nothing
  270. # changes compared to the initial state.
  271. h2_mac=$(ip -n $h2 -j -p link show eth0.$vid | jq -r '.[]["address"]')
  272. run_cmd "bridge -n $sw1 fdb replace $h2_mac dev vx0 master static vlan $vid"
  273. log_test $? 0 "FDB entry installation"
  274. run_cmd "ip netns exec $h1 arping -q -b -c 1 -w 5 -s $sip -I eth0.$vid $tip"
  275. log_test $? 0 "arping"
  276. tc_check_packets $sw1 "dev vx0 egress" 101 3
  277. log_test $? 0 "ARP suppression"
  278. # Install a neighbor on the matching SVI interface and check that ARP
  279. # requests are suppressed.
  280. run_cmd "ip -n $sw1 neigh replace $tip lladdr $h2_mac nud permanent dev br0.$vid"
  281. log_test $? 0 "Neighbor entry installation"
  282. run_cmd "ip netns exec $h1 arping -q -b -c 1 -w 5 -s $sip -I eth0.$vid $tip"
  283. log_test $? 0 "arping"
  284. tc_check_packets $sw1 "dev vx0 egress" 101 3
  285. log_test $? 0 "ARP suppression"
  286. # Take the second host down and check that ARP requests are suppressed
  287. # and that ARP replies are received.
  288. run_cmd "ip -n $h2 link set dev eth0.$vid down"
  289. log_test $? 0 "H2 down"
  290. run_cmd "ip netns exec $h1 arping -q -b -c 1 -w 5 -s $sip -I eth0.$vid $tip"
  291. log_test $? 0 "arping"
  292. tc_check_packets $sw1 "dev vx0 egress" 101 3
  293. log_test $? 0 "ARP suppression"
  294. run_cmd "ip -n $h2 link set dev eth0.$vid up"
  295. log_test $? 0 "H2 up"
  296. # Disable neighbor suppression and check that ARP requests are no
  297. # longer suppressed.
  298. run_cmd "bridge -n $sw1 link set dev vx0 neigh_suppress off"
  299. run_cmd "bridge -n $sw1 -d link show dev vx0 | grep \"neigh_suppress off\""
  300. log_test $? 0 "\"neigh_suppress\" is off"
  301. run_cmd "ip netns exec $h1 arping -q -b -c 1 -w 5 -s $sip -I eth0.$vid $tip"
  302. log_test $? 0 "arping"
  303. tc_check_packets $sw1 "dev vx0 egress" 101 4
  304. log_test $? 0 "ARP suppression"
  305. # Take the second host down and check that ARP requests are not
  306. # suppressed and that ARP replies are not received.
  307. run_cmd "ip -n $h2 link set dev eth0.$vid down"
  308. log_test $? 0 "H2 down"
  309. run_cmd "ip netns exec $h1 arping -q -b -c 1 -w 5 -s $sip -I eth0.$vid $tip"
  310. log_test $? 1 "arping"
  311. tc_check_packets $sw1 "dev vx0 egress" 101 5
  312. log_test $? 0 "ARP suppression"
  313. }
  314. neigh_suppress_arp()
  315. {
  316. local vid=10
  317. local sip=192.0.2.1
  318. local tip=192.0.2.2
  319. neigh_suppress_arp_common $vid $sip $tip
  320. vid=20
  321. sip=192.0.2.17
  322. tip=192.0.2.18
  323. neigh_suppress_arp_common $vid $sip $tip
  324. }
  325. neigh_suppress_uc_arp_common()
  326. {
  327. local vid=$1; shift
  328. local sip=$1; shift
  329. local tip=$1; shift
  330. local tmac
  331. echo
  332. echo "Unicast ARP, per-port ARP suppression - VLAN $vid"
  333. echo "-----------------------------------------------"
  334. run_cmd "bridge -n $sw1 link set dev vx0 neigh_suppress on"
  335. run_cmd "bridge -n $sw1 -d link show dev vx0 | grep \"neigh_suppress on\""
  336. log_test $? 0 "\"neigh_suppress\" is on"
  337. tmac=$(ip -n $h2 -j -p link show eth0.$vid | jq -r '.[]["address"]')
  338. run_cmd "bridge -n $sw1 fdb replace $tmac dev vx0 master static vlan $vid"
  339. run_cmd "ip -n $sw1 neigh replace $tip lladdr $tmac nud permanent dev br0.$vid"
  340. run_cmd "tc -n $h1 qdisc replace dev eth0.$vid clsact"
  341. run_cmd "tc -n $h1 filter replace dev eth0.$vid ingress pref 1 handle 101 proto arp flower arp_sip $tip arp_op reply action pass"
  342. run_cmd "tc -n $h2 qdisc replace dev eth0.$vid clsact"
  343. run_cmd "tc -n $h2 filter replace dev eth0.$vid egress pref 1 handle 101 proto arp flower arp_tip $sip arp_op reply action pass"
  344. run_cmd "ip netns exec $h1 mausezahn eth0.$vid -c 1 -a own -b $tmac -t arp 'request sip=$sip, tip=$tip, tmac=$tmac' -q"
  345. tc_check_packets $h1 "dev eth0.$vid ingress" 101 1
  346. log_test $? 0 "Unicast ARP, suppression on, h1 filter"
  347. tc_check_packets $h2 "dev eth0.$vid egress" 101 1
  348. log_test $? 0 "Unicast ARP, suppression on, h2 filter"
  349. }
  350. neigh_suppress_uc_arp()
  351. {
  352. local vid=10
  353. local sip=192.0.2.1
  354. local tip=192.0.2.2
  355. neigh_suppress_uc_arp_common $vid $sip $tip
  356. vid=20
  357. sip=192.0.2.17
  358. tip=192.0.2.18
  359. neigh_suppress_uc_arp_common $vid $sip $tip
  360. }
  361. neigh_suppress_ns_common()
  362. {
  363. local vid=$1; shift
  364. local saddr=$1; shift
  365. local daddr=$1; shift
  366. local maddr=$1; shift
  367. local h2_mac
  368. echo
  369. echo "Per-port NS suppression - VLAN $vid"
  370. echo "---------------------------------"
  371. run_cmd "tc -n $sw1 qdisc replace dev vx0 clsact"
  372. run_cmd "tc -n $sw1 filter replace dev vx0 egress pref 1 handle 101 proto ipv6 flower indev swp1 ip_proto icmpv6 dst_ip $maddr src_ip $saddr type 135 code 0 action pass"
  373. # Initial state - check that NS messages are not suppressed and that ND
  374. # messages are received.
  375. run_cmd "ip netns exec $h1 ndisc6 -q -r 1 -s $saddr -w 5000 $daddr eth0.$vid"
  376. log_test $? 0 "ndisc6"
  377. tc_check_packets $sw1 "dev vx0 egress" 101 1
  378. log_test $? 0 "NS suppression"
  379. # Enable neighbor suppression and check that nothing changes compared
  380. # to the initial state.
  381. run_cmd "bridge -n $sw1 link set dev vx0 neigh_suppress on"
  382. run_cmd "bridge -n $sw1 -d link show dev vx0 | grep \"neigh_suppress on\""
  383. log_test $? 0 "\"neigh_suppress\" is on"
  384. run_cmd "ip netns exec $h1 ndisc6 -q -r 1 -s $saddr -w 5000 $daddr eth0.$vid"
  385. log_test $? 0 "ndisc6"
  386. tc_check_packets $sw1 "dev vx0 egress" 101 2
  387. log_test $? 0 "NS suppression"
  388. # Install an FDB entry for the remote host and check that nothing
  389. # changes compared to the initial state.
  390. h2_mac=$(ip -n $h2 -j -p link show eth0.$vid | jq -r '.[]["address"]')
  391. run_cmd "bridge -n $sw1 fdb replace $h2_mac dev vx0 master static vlan $vid"
  392. log_test $? 0 "FDB entry installation"
  393. run_cmd "ip netns exec $h1 ndisc6 -q -r 1 -s $saddr -w 5000 $daddr eth0.$vid"
  394. log_test $? 0 "ndisc6"
  395. tc_check_packets $sw1 "dev vx0 egress" 101 3
  396. log_test $? 0 "NS suppression"
  397. # Install a neighbor on the matching SVI interface and check that NS
  398. # messages are suppressed.
  399. run_cmd "ip -n $sw1 neigh replace $daddr lladdr $h2_mac nud permanent dev br0.$vid"
  400. log_test $? 0 "Neighbor entry installation"
  401. run_cmd "ip netns exec $h1 ndisc6 -q -r 1 -s $saddr -w 5000 $daddr eth0.$vid"
  402. log_test $? 0 "ndisc6"
  403. tc_check_packets $sw1 "dev vx0 egress" 101 3
  404. log_test $? 0 "NS suppression"
  405. # Take the second host down and check that NS messages are suppressed
  406. # and that ND messages are received.
  407. run_cmd "ip -n $h2 link set dev eth0.$vid down"
  408. log_test $? 0 "H2 down"
  409. run_cmd "ip netns exec $h1 ndisc6 -q -r 1 -s $saddr -w 5000 $daddr eth0.$vid"
  410. log_test $? 0 "ndisc6"
  411. tc_check_packets $sw1 "dev vx0 egress" 101 3
  412. log_test $? 0 "NS suppression"
  413. run_cmd "ip -n $h2 link set dev eth0.$vid up"
  414. log_test $? 0 "H2 up"
  415. # Disable neighbor suppression and check that NS messages are no longer
  416. # suppressed.
  417. run_cmd "bridge -n $sw1 link set dev vx0 neigh_suppress off"
  418. run_cmd "bridge -n $sw1 -d link show dev vx0 | grep \"neigh_suppress off\""
  419. log_test $? 0 "\"neigh_suppress\" is off"
  420. run_cmd "ip netns exec $h1 ndisc6 -q -r 1 -s $saddr -w 5000 $daddr eth0.$vid"
  421. log_test $? 0 "ndisc6"
  422. tc_check_packets $sw1 "dev vx0 egress" 101 4
  423. log_test $? 0 "NS suppression"
  424. # Take the second host down and check that NS messages are not
  425. # suppressed and that ND messages are not received.
  426. run_cmd "ip -n $h2 link set dev eth0.$vid down"
  427. log_test $? 0 "H2 down"
  428. run_cmd "ip netns exec $h1 ndisc6 -q -r 1 -s $saddr -w 5000 $daddr eth0.$vid"
  429. log_test $? 2 "ndisc6"
  430. tc_check_packets $sw1 "dev vx0 egress" 101 5
  431. log_test $? 0 "NS suppression"
  432. }
  433. neigh_suppress_ns()
  434. {
  435. local vid=10
  436. local saddr=2001:db8:1::1
  437. local daddr=2001:db8:1::2
  438. local maddr=ff02::1:ff00:2
  439. neigh_suppress_ns_common $vid $saddr $daddr $maddr
  440. vid=20
  441. saddr=2001:db8:2::1
  442. daddr=2001:db8:2::2
  443. maddr=ff02::1:ff00:2
  444. neigh_suppress_ns_common $vid $saddr $daddr $maddr
  445. }
  446. icmpv6_header_get()
  447. {
  448. local csum=$1; shift
  449. local tip=$1; shift
  450. local type
  451. local p
  452. # Type 135 (Neighbor Solicitation), hex format
  453. type="87"
  454. p=$(:
  455. )"$type:"$( : ICMPv6.type
  456. )"00:"$( : ICMPv6.code
  457. )"$csum:"$( : ICMPv6.checksum
  458. )"00:00:00:00:"$( : Reserved
  459. )"$tip:"$( : Target Address
  460. )
  461. echo $p
  462. }
  463. neigh_suppress_uc_ns_common()
  464. {
  465. local vid=$1; shift
  466. local sip=$1; shift
  467. local dip=$1; shift
  468. local full_dip=$1; shift
  469. local csum=$1; shift
  470. local tmac
  471. echo
  472. echo "Unicast NS, per-port NS suppression - VLAN $vid"
  473. echo "---------------------------------------------"
  474. run_cmd "bridge -n $sw1 link set dev vx0 neigh_suppress on"
  475. run_cmd "bridge -n $sw1 -d link show dev vx0 | grep \"neigh_suppress on\""
  476. log_test $? 0 "\"neigh_suppress\" is on"
  477. tmac=$(ip -n $h2 -j -p link show eth0.$vid | jq -r '.[]["address"]')
  478. run_cmd "bridge -n $sw1 fdb replace $tmac dev vx0 master static vlan $vid"
  479. run_cmd "ip -n $sw1 -6 neigh replace $dip lladdr $tmac nud permanent dev br0.$vid"
  480. run_cmd "tc -n $h1 qdisc replace dev eth0.$vid clsact"
  481. run_cmd "tc -n $h1 filter replace dev eth0.$vid ingress pref 1 handle 101 proto ipv6 flower ip_proto icmpv6 src_ip $dip type 136 code 0 action pass"
  482. run_cmd "tc -n $h2 qdisc replace dev eth0.$vid clsact"
  483. run_cmd "tc -n $h2 filter replace dev eth0.$vid egress pref 1 handle 101 proto ipv6 flower ip_proto icmpv6 dst_ip $sip type 136 code 0 action pass"
  484. run_cmd "ip netns exec $h1 mausezahn -6 eth0.$vid -c 1 -a own -b $tmac -A $sip -B $dip -t ip hop=255,next=58,payload=$(icmpv6_header_get $csum $full_dip) -q"
  485. tc_check_packets $h1 "dev eth0.$vid ingress" 101 1
  486. log_test $? 0 "Unicast NS, suppression on, h1 filter"
  487. tc_check_packets $h2 "dev eth0.$vid egress" 101 1
  488. log_test $? 0 "Unicast NS, suppression on, h2 filter"
  489. }
  490. neigh_suppress_uc_ns()
  491. {
  492. local vid=10
  493. local saddr=2001:db8:1::1
  494. local daddr=2001:db8:1::2
  495. local full_daddr=20:01:0d:b8:00:01:00:00:00:00:00:00:00:00:00:02
  496. local csum="ef:79"
  497. neigh_suppress_uc_ns_common $vid $saddr $daddr $full_daddr $csum
  498. vid=20
  499. saddr=2001:db8:2::1
  500. daddr=2001:db8:2::2
  501. full_daddr=20:01:0d:b8:00:02:00:00:00:00:00:00:00:00:00:02
  502. csum="ef:76"
  503. neigh_suppress_uc_ns_common $vid $saddr $daddr $full_daddr $csum
  504. }
  505. neigh_vlan_suppress_arp()
  506. {
  507. local vid1=10
  508. local vid2=20
  509. local sip1=192.0.2.1
  510. local sip2=192.0.2.17
  511. local tip1=192.0.2.2
  512. local tip2=192.0.2.18
  513. local h2_mac1
  514. local h2_mac2
  515. echo
  516. echo "Per-{Port, VLAN} ARP suppression"
  517. echo "--------------------------------"
  518. run_cmd "tc -n $sw1 qdisc replace dev vx0 clsact"
  519. run_cmd "tc -n $sw1 filter replace dev vx0 egress pref 1 handle 101 proto 0x0806 flower indev swp1 arp_tip $tip1 arp_sip $sip1 arp_op request action pass"
  520. run_cmd "tc -n $sw1 filter replace dev vx0 egress pref 1 handle 102 proto 0x0806 flower indev swp1 arp_tip $tip2 arp_sip $sip2 arp_op request action pass"
  521. h2_mac1=$(ip -n $h2 -j -p link show eth0.$vid1 | jq -r '.[]["address"]')
  522. h2_mac2=$(ip -n $h2 -j -p link show eth0.$vid2 | jq -r '.[]["address"]')
  523. run_cmd "bridge -n $sw1 fdb replace $h2_mac1 dev vx0 master static vlan $vid1"
  524. run_cmd "bridge -n $sw1 fdb replace $h2_mac2 dev vx0 master static vlan $vid2"
  525. run_cmd "ip -n $sw1 neigh replace $tip1 lladdr $h2_mac1 nud permanent dev br0.$vid1"
  526. run_cmd "ip -n $sw1 neigh replace $tip2 lladdr $h2_mac2 nud permanent dev br0.$vid2"
  527. # Enable per-{Port, VLAN} neighbor suppression and check that ARP
  528. # requests are not suppressed and that ARP replies are received.
  529. run_cmd "bridge -n $sw1 link set dev vx0 neigh_vlan_suppress on"
  530. run_cmd "bridge -n $sw1 -d link show dev vx0 | grep \"neigh_vlan_suppress on\""
  531. log_test $? 0 "\"neigh_vlan_suppress\" is on"
  532. run_cmd "ip netns exec $h1 arping -q -b -c 1 -w 5 -s $sip1 -I eth0.$vid1 $tip1"
  533. log_test $? 0 "arping (VLAN $vid1)"
  534. run_cmd "ip netns exec $h1 arping -q -b -c 1 -w 5 -s $sip2 -I eth0.$vid2 $tip2"
  535. log_test $? 0 "arping (VLAN $vid2)"
  536. tc_check_packets $sw1 "dev vx0 egress" 101 1
  537. log_test $? 0 "ARP suppression (VLAN $vid1)"
  538. tc_check_packets $sw1 "dev vx0 egress" 102 1
  539. log_test $? 0 "ARP suppression (VLAN $vid2)"
  540. # Enable neighbor suppression on VLAN 10 and check that only on this
  541. # VLAN ARP requests are suppressed.
  542. run_cmd "bridge -n $sw1 vlan set vid $vid1 dev vx0 neigh_suppress on"
  543. run_cmd "bridge -n $sw1 -d vlan show dev vx0 vid $vid1 | grep \"neigh_suppress on\""
  544. log_test $? 0 "\"neigh_suppress\" is on (VLAN $vid1)"
  545. run_cmd "bridge -n $sw1 -d vlan show dev vx0 vid $vid2 | grep \"neigh_suppress off\""
  546. log_test $? 0 "\"neigh_suppress\" is off (VLAN $vid2)"
  547. run_cmd "ip netns exec $h1 arping -q -b -c 1 -w 5 -s $sip1 -I eth0.$vid1 $tip1"
  548. log_test $? 0 "arping (VLAN $vid1)"
  549. run_cmd "ip netns exec $h1 arping -q -b -c 1 -w 5 -s $sip2 -I eth0.$vid2 $tip2"
  550. log_test $? 0 "arping (VLAN $vid2)"
  551. tc_check_packets $sw1 "dev vx0 egress" 101 1
  552. log_test $? 0 "ARP suppression (VLAN $vid1)"
  553. tc_check_packets $sw1 "dev vx0 egress" 102 2
  554. log_test $? 0 "ARP suppression (VLAN $vid2)"
  555. # Enable neighbor suppression on the port and check that it has no
  556. # effect compared to previous state.
  557. run_cmd "bridge -n $sw1 link set dev vx0 neigh_suppress on"
  558. run_cmd "bridge -n $sw1 -d link show dev vx0 | grep \"neigh_suppress on\""
  559. log_test $? 0 "\"neigh_suppress\" is on"
  560. run_cmd "ip netns exec $h1 arping -q -b -c 1 -w 5 -s $sip1 -I eth0.$vid1 $tip1"
  561. log_test $? 0 "arping (VLAN $vid1)"
  562. run_cmd "ip netns exec $h1 arping -q -b -c 1 -w 5 -s $sip2 -I eth0.$vid2 $tip2"
  563. log_test $? 0 "arping (VLAN $vid2)"
  564. tc_check_packets $sw1 "dev vx0 egress" 101 1
  565. log_test $? 0 "ARP suppression (VLAN $vid1)"
  566. tc_check_packets $sw1 "dev vx0 egress" 102 3
  567. log_test $? 0 "ARP suppression (VLAN $vid2)"
  568. # Disable neighbor suppression on the port and check that it has no
  569. # effect compared to previous state.
  570. run_cmd "bridge -n $sw1 link set dev vx0 neigh_suppress off"
  571. run_cmd "bridge -n $sw1 -d link show dev vx0 | grep \"neigh_suppress off\""
  572. log_test $? 0 "\"neigh_suppress\" is off"
  573. run_cmd "ip netns exec $h1 arping -q -b -c 1 -w 5 -s $sip1 -I eth0.$vid1 $tip1"
  574. log_test $? 0 "arping (VLAN $vid1)"
  575. run_cmd "ip netns exec $h1 arping -q -b -c 1 -w 5 -s $sip2 -I eth0.$vid2 $tip2"
  576. log_test $? 0 "arping (VLAN $vid2)"
  577. tc_check_packets $sw1 "dev vx0 egress" 101 1
  578. log_test $? 0 "ARP suppression (VLAN $vid1)"
  579. tc_check_packets $sw1 "dev vx0 egress" 102 4
  580. log_test $? 0 "ARP suppression (VLAN $vid2)"
  581. # Disable neighbor suppression on VLAN 10 and check that ARP requests
  582. # are no longer suppressed on this VLAN.
  583. run_cmd "bridge -n $sw1 vlan set vid $vid1 dev vx0 neigh_suppress off"
  584. run_cmd "bridge -n $sw1 -d vlan show dev vx0 vid $vid1 | grep \"neigh_suppress off\""
  585. log_test $? 0 "\"neigh_suppress\" is off (VLAN $vid1)"
  586. run_cmd "ip netns exec $h1 arping -q -b -c 1 -w 5 -s $sip1 -I eth0.$vid1 $tip1"
  587. log_test $? 0 "arping (VLAN $vid1)"
  588. run_cmd "ip netns exec $h1 arping -q -b -c 1 -w 5 -s $sip2 -I eth0.$vid2 $tip2"
  589. log_test $? 0 "arping (VLAN $vid2)"
  590. tc_check_packets $sw1 "dev vx0 egress" 101 2
  591. log_test $? 0 "ARP suppression (VLAN $vid1)"
  592. tc_check_packets $sw1 "dev vx0 egress" 102 5
  593. log_test $? 0 "ARP suppression (VLAN $vid2)"
  594. # Disable per-{Port, VLAN} neighbor suppression, enable neighbor
  595. # suppression on the port and check that on both VLANs ARP requests are
  596. # suppressed.
  597. run_cmd "bridge -n $sw1 link set dev vx0 neigh_vlan_suppress off"
  598. run_cmd "bridge -n $sw1 -d link show dev vx0 | grep \"neigh_vlan_suppress off\""
  599. log_test $? 0 "\"neigh_vlan_suppress\" is off"
  600. run_cmd "bridge -n $sw1 link set dev vx0 neigh_suppress on"
  601. run_cmd "bridge -n $sw1 -d link show dev vx0 | grep \"neigh_suppress on\""
  602. log_test $? 0 "\"neigh_suppress\" is on"
  603. run_cmd "ip netns exec $h1 arping -q -b -c 1 -w 5 -s $sip1 -I eth0.$vid1 $tip1"
  604. log_test $? 0 "arping (VLAN $vid1)"
  605. run_cmd "ip netns exec $h1 arping -q -b -c 1 -w 5 -s $sip2 -I eth0.$vid2 $tip2"
  606. log_test $? 0 "arping (VLAN $vid2)"
  607. tc_check_packets $sw1 "dev vx0 egress" 101 2
  608. log_test $? 0 "ARP suppression (VLAN $vid1)"
  609. tc_check_packets $sw1 "dev vx0 egress" 102 5
  610. log_test $? 0 "ARP suppression (VLAN $vid2)"
  611. }
  612. neigh_vlan_suppress_ns()
  613. {
  614. local vid1=10
  615. local vid2=20
  616. local saddr1=2001:db8:1::1
  617. local saddr2=2001:db8:2::1
  618. local daddr1=2001:db8:1::2
  619. local daddr2=2001:db8:2::2
  620. local maddr=ff02::1:ff00:2
  621. local h2_mac1
  622. local h2_mac2
  623. echo
  624. echo "Per-{Port, VLAN} NS suppression"
  625. echo "-------------------------------"
  626. run_cmd "tc -n $sw1 qdisc replace dev vx0 clsact"
  627. run_cmd "tc -n $sw1 filter replace dev vx0 egress pref 1 handle 101 proto ipv6 flower indev swp1 ip_proto icmpv6 dst_ip $maddr src_ip $saddr1 type 135 code 0 action pass"
  628. run_cmd "tc -n $sw1 filter replace dev vx0 egress pref 1 handle 102 proto ipv6 flower indev swp1 ip_proto icmpv6 dst_ip $maddr src_ip $saddr2 type 135 code 0 action pass"
  629. h2_mac1=$(ip -n $h2 -j -p link show eth0.$vid1 | jq -r '.[]["address"]')
  630. h2_mac2=$(ip -n $h2 -j -p link show eth0.$vid2 | jq -r '.[]["address"]')
  631. run_cmd "bridge -n $sw1 fdb replace $h2_mac1 dev vx0 master static vlan $vid1"
  632. run_cmd "bridge -n $sw1 fdb replace $h2_mac2 dev vx0 master static vlan $vid2"
  633. run_cmd "ip -n $sw1 neigh replace $daddr1 lladdr $h2_mac1 nud permanent dev br0.$vid1"
  634. run_cmd "ip -n $sw1 neigh replace $daddr2 lladdr $h2_mac2 nud permanent dev br0.$vid2"
  635. # Enable per-{Port, VLAN} neighbor suppression and check that NS
  636. # messages are not suppressed and that ND messages are received.
  637. run_cmd "bridge -n $sw1 link set dev vx0 neigh_vlan_suppress on"
  638. run_cmd "bridge -n $sw1 -d link show dev vx0 | grep \"neigh_vlan_suppress on\""
  639. log_test $? 0 "\"neigh_vlan_suppress\" is on"
  640. run_cmd "ip netns exec $h1 ndisc6 -q -r 1 -s $saddr1 -w 5000 $daddr1 eth0.$vid1"
  641. log_test $? 0 "ndisc6 (VLAN $vid1)"
  642. run_cmd "ip netns exec $h1 ndisc6 -q -r 1 -s $saddr2 -w 5000 $daddr2 eth0.$vid2"
  643. log_test $? 0 "ndisc6 (VLAN $vid2)"
  644. tc_check_packets $sw1 "dev vx0 egress" 101 1
  645. log_test $? 0 "NS suppression (VLAN $vid1)"
  646. tc_check_packets $sw1 "dev vx0 egress" 102 1
  647. log_test $? 0 "NS suppression (VLAN $vid2)"
  648. # Enable neighbor suppression on VLAN 10 and check that only on this
  649. # VLAN NS messages are suppressed.
  650. run_cmd "bridge -n $sw1 vlan set vid $vid1 dev vx0 neigh_suppress on"
  651. run_cmd "bridge -n $sw1 -d vlan show dev vx0 vid $vid1 | grep \"neigh_suppress on\""
  652. log_test $? 0 "\"neigh_suppress\" is on (VLAN $vid1)"
  653. run_cmd "bridge -n $sw1 -d vlan show dev vx0 vid $vid2 | grep \"neigh_suppress off\""
  654. log_test $? 0 "\"neigh_suppress\" is off (VLAN $vid2)"
  655. run_cmd "ip netns exec $h1 ndisc6 -q -r 1 -s $saddr1 -w 5000 $daddr1 eth0.$vid1"
  656. log_test $? 0 "ndisc6 (VLAN $vid1)"
  657. run_cmd "ip netns exec $h1 ndisc6 -q -r 1 -s $saddr2 -w 5000 $daddr2 eth0.$vid2"
  658. log_test $? 0 "ndisc6 (VLAN $vid2)"
  659. tc_check_packets $sw1 "dev vx0 egress" 101 1
  660. log_test $? 0 "NS suppression (VLAN $vid1)"
  661. tc_check_packets $sw1 "dev vx0 egress" 102 2
  662. log_test $? 0 "NS suppression (VLAN $vid2)"
  663. # Enable neighbor suppression on the port and check that it has no
  664. # effect compared to previous state.
  665. run_cmd "bridge -n $sw1 link set dev vx0 neigh_suppress on"
  666. run_cmd "bridge -n $sw1 -d link show dev vx0 | grep \"neigh_suppress on\""
  667. log_test $? 0 "\"neigh_suppress\" is on"
  668. run_cmd "ip netns exec $h1 ndisc6 -q -r 1 -s $saddr1 -w 5000 $daddr1 eth0.$vid1"
  669. log_test $? 0 "ndisc6 (VLAN $vid1)"
  670. run_cmd "ip netns exec $h1 ndisc6 -q -r 1 -s $saddr2 -w 5000 $daddr2 eth0.$vid2"
  671. log_test $? 0 "ndisc6 (VLAN $vid2)"
  672. tc_check_packets $sw1 "dev vx0 egress" 101 1
  673. log_test $? 0 "NS suppression (VLAN $vid1)"
  674. tc_check_packets $sw1 "dev vx0 egress" 102 3
  675. log_test $? 0 "NS suppression (VLAN $vid2)"
  676. # Disable neighbor suppression on the port and check that it has no
  677. # effect compared to previous state.
  678. run_cmd "bridge -n $sw1 link set dev vx0 neigh_suppress off"
  679. run_cmd "bridge -n $sw1 -d link show dev vx0 | grep \"neigh_suppress off\""
  680. log_test $? 0 "\"neigh_suppress\" is off"
  681. run_cmd "ip netns exec $h1 ndisc6 -q -r 1 -s $saddr1 -w 5000 $daddr1 eth0.$vid1"
  682. log_test $? 0 "ndisc6 (VLAN $vid1)"
  683. run_cmd "ip netns exec $h1 ndisc6 -q -r 1 -s $saddr2 -w 5000 $daddr2 eth0.$vid2"
  684. log_test $? 0 "ndisc6 (VLAN $vid2)"
  685. tc_check_packets $sw1 "dev vx0 egress" 101 1
  686. log_test $? 0 "NS suppression (VLAN $vid1)"
  687. tc_check_packets $sw1 "dev vx0 egress" 102 4
  688. log_test $? 0 "NS suppression (VLAN $vid2)"
  689. # Disable neighbor suppression on VLAN 10 and check that NS messages
  690. # are no longer suppressed on this VLAN.
  691. run_cmd "bridge -n $sw1 vlan set vid $vid1 dev vx0 neigh_suppress off"
  692. run_cmd "bridge -n $sw1 -d vlan show dev vx0 vid $vid1 | grep \"neigh_suppress off\""
  693. log_test $? 0 "\"neigh_suppress\" is off (VLAN $vid1)"
  694. run_cmd "ip netns exec $h1 ndisc6 -q -r 1 -s $saddr1 -w 5000 $daddr1 eth0.$vid1"
  695. log_test $? 0 "ndisc6 (VLAN $vid1)"
  696. run_cmd "ip netns exec $h1 ndisc6 -q -r 1 -s $saddr2 -w 5000 $daddr2 eth0.$vid2"
  697. log_test $? 0 "ndisc6 (VLAN $vid2)"
  698. tc_check_packets $sw1 "dev vx0 egress" 101 2
  699. log_test $? 0 "NS suppression (VLAN $vid1)"
  700. tc_check_packets $sw1 "dev vx0 egress" 102 5
  701. log_test $? 0 "NS suppression (VLAN $vid2)"
  702. # Disable per-{Port, VLAN} neighbor suppression, enable neighbor
  703. # suppression on the port and check that on both VLANs NS messages are
  704. # suppressed.
  705. run_cmd "bridge -n $sw1 link set dev vx0 neigh_vlan_suppress off"
  706. run_cmd "bridge -n $sw1 -d link show dev vx0 | grep \"neigh_vlan_suppress off\""
  707. log_test $? 0 "\"neigh_vlan_suppress\" is off"
  708. run_cmd "bridge -n $sw1 link set dev vx0 neigh_suppress on"
  709. run_cmd "bridge -n $sw1 -d link show dev vx0 | grep \"neigh_suppress on\""
  710. log_test $? 0 "\"neigh_suppress\" is on"
  711. run_cmd "ip netns exec $h1 ndisc6 -q -r 1 -s $saddr1 -w 5000 $daddr1 eth0.$vid1"
  712. log_test $? 0 "ndisc6 (VLAN $vid1)"
  713. run_cmd "ip netns exec $h1 ndisc6 -q -r 1 -s $saddr2 -w 5000 $daddr2 eth0.$vid2"
  714. log_test $? 0 "ndisc6 (VLAN $vid2)"
  715. tc_check_packets $sw1 "dev vx0 egress" 101 2
  716. log_test $? 0 "NS suppression (VLAN $vid1)"
  717. tc_check_packets $sw1 "dev vx0 egress" 102 5
  718. log_test $? 0 "NS suppression (VLAN $vid2)"
  719. }
  720. ################################################################################
  721. # Usage
  722. usage()
  723. {
  724. cat <<EOF
  725. usage: ${0##*/} OPTS
  726. -t <test> Test(s) to run (default: all)
  727. (options: $TESTS)
  728. -p Pause on fail
  729. -P Pause after each test before cleanup
  730. -v Verbose mode (show commands and output)
  731. EOF
  732. }
  733. ################################################################################
  734. # Main
  735. trap cleanup EXIT
  736. while getopts ":t:pPvh" opt; do
  737. case $opt in
  738. t) TESTS=$OPTARG;;
  739. p) PAUSE_ON_FAIL=yes;;
  740. P) PAUSE=yes;;
  741. v) VERBOSE=$(($VERBOSE + 1));;
  742. h) usage; exit 0;;
  743. *) usage; exit 1;;
  744. esac
  745. done
  746. # Make sure we don't pause twice.
  747. [ "${PAUSE}" = "yes" ] && PAUSE_ON_FAIL=no
  748. if [ "$(id -u)" -ne 0 ];then
  749. echo "SKIP: Need root privileges"
  750. exit $ksft_skip;
  751. fi
  752. if [ ! -x "$(command -v ip)" ]; then
  753. echo "SKIP: Could not run test without ip tool"
  754. exit $ksft_skip
  755. fi
  756. if [ ! -x "$(command -v bridge)" ]; then
  757. echo "SKIP: Could not run test without bridge tool"
  758. exit $ksft_skip
  759. fi
  760. if [ ! -x "$(command -v tc)" ]; then
  761. echo "SKIP: Could not run test without tc tool"
  762. exit $ksft_skip
  763. fi
  764. if [ ! -x "$(command -v arping)" ]; then
  765. echo "SKIP: Could not run test without arping tool"
  766. exit $ksft_skip
  767. fi
  768. if [ ! -x "$(command -v ndisc6)" ]; then
  769. echo "SKIP: Could not run test without ndisc6 tool"
  770. exit $ksft_skip
  771. fi
  772. if [ ! -x "$(command -v jq)" ]; then
  773. echo "SKIP: Could not run test without jq tool"
  774. exit $ksft_skip
  775. fi
  776. if [ ! -x "$(command -v mausezahn)" ]; then
  777. echo "SKIP: Could not run test without mausezahn tool"
  778. exit $ksft_skip
  779. fi
  780. bridge link help 2>&1 | grep -q "neigh_vlan_suppress"
  781. if [ $? -ne 0 ]; then
  782. echo "SKIP: iproute2 bridge too old, missing per-VLAN neighbor suppression support"
  783. exit $ksft_skip
  784. fi
  785. # Start clean.
  786. cleanup
  787. for t in $TESTS
  788. do
  789. setup; $t; cleanup;
  790. done
  791. if [ "$TESTS" != "none" ]; then
  792. printf "\nTests passed: %3d\n" ${nsuccess}
  793. printf "Tests failed: %3d\n" ${nfail}
  794. fi
  795. exit $ret