bridge_mdb.sh 45 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371
  1. #!/bin/bash
  2. # SPDX-License-Identifier: GPL-2.0
  3. # +-----------------------+ +------------------------+
  4. # | H1 (vrf) | | H2 (vrf) |
  5. # | + $h1.10 | | + $h2.10 |
  6. # | | 192.0.2.1/28 | | | 192.0.2.2/28 |
  7. # | | 2001:db8:1::1/64 | | | 2001:db8:1::2/64 |
  8. # | | | | | |
  9. # | | + $h1.20 | | | + $h2.20 |
  10. # | \ | 198.51.100.1/24 | | \ | 198.51.100.2/24 |
  11. # | \ | 2001:db8:2::1/64 | | \ | 2001:db8:2::2/64 |
  12. # | \| | | \| |
  13. # | + $h1 | | + $h2 |
  14. # +----|------------------+ +----|-------------------+
  15. # | |
  16. # +----|--------------------------------------------------|-------------------+
  17. # | SW | | |
  18. # | +--|--------------------------------------------------|-----------------+ |
  19. # | | + $swp1 BR0 (802.1q) + $swp2 | |
  20. # | | vid 10 vid 10 | |
  21. # | | vid 20 vid 20 | |
  22. # | | | |
  23. # | +-----------------------------------------------------------------------+ |
  24. # +---------------------------------------------------------------------------+
  25. ALL_TESTS="
  26. cfg_test
  27. fwd_test
  28. ctrl_test
  29. "
  30. NUM_NETIFS=4
  31. source lib.sh
  32. source tc_common.sh
  33. h1_create()
  34. {
  35. simple_if_init $h1
  36. vlan_create $h1 10 v$h1 192.0.2.1/28 2001:db8:1::1/64
  37. vlan_create $h1 20 v$h1 198.51.100.1/24 2001:db8:2::1/64
  38. }
  39. h1_destroy()
  40. {
  41. vlan_destroy $h1 20
  42. vlan_destroy $h1 10
  43. simple_if_fini $h1
  44. }
  45. h2_create()
  46. {
  47. simple_if_init $h2
  48. vlan_create $h2 10 v$h2 192.0.2.2/28
  49. vlan_create $h2 20 v$h2 198.51.100.2/24
  50. }
  51. h2_destroy()
  52. {
  53. vlan_destroy $h2 20
  54. vlan_destroy $h2 10
  55. simple_if_fini $h2
  56. }
  57. switch_create()
  58. {
  59. ip link add name br0 type bridge vlan_filtering 1 vlan_default_pvid 0 \
  60. mcast_snooping 1 mcast_igmp_version 3 mcast_mld_version 2
  61. bridge vlan add vid 10 dev br0 self
  62. bridge vlan add vid 20 dev br0 self
  63. ip link set dev br0 up
  64. ip link set dev $swp1 master br0
  65. ip link set dev $swp1 up
  66. bridge vlan add vid 10 dev $swp1
  67. bridge vlan add vid 20 dev $swp1
  68. ip link set dev $swp2 master br0
  69. ip link set dev $swp2 up
  70. bridge vlan add vid 10 dev $swp2
  71. bridge vlan add vid 20 dev $swp2
  72. tc qdisc add dev br0 clsact
  73. tc qdisc add dev $h2 clsact
  74. }
  75. switch_destroy()
  76. {
  77. tc qdisc del dev $h2 clsact
  78. tc qdisc del dev br0 clsact
  79. bridge vlan del vid 20 dev $swp2
  80. bridge vlan del vid 10 dev $swp2
  81. ip link set dev $swp2 down
  82. ip link set dev $swp2 nomaster
  83. bridge vlan del vid 20 dev $swp1
  84. bridge vlan del vid 10 dev $swp1
  85. ip link set dev $swp1 down
  86. ip link set dev $swp1 nomaster
  87. ip link set dev br0 down
  88. bridge vlan del vid 20 dev br0 self
  89. bridge vlan del vid 10 dev br0 self
  90. ip link del dev br0
  91. }
  92. setup_prepare()
  93. {
  94. h1=${NETIFS[p1]}
  95. swp1=${NETIFS[p2]}
  96. swp2=${NETIFS[p3]}
  97. h2=${NETIFS[p4]}
  98. vrf_prepare
  99. forwarding_enable
  100. h1_create
  101. h2_create
  102. switch_create
  103. }
  104. cleanup()
  105. {
  106. pre_cleanup
  107. switch_destroy
  108. h2_destroy
  109. h1_destroy
  110. forwarding_restore
  111. vrf_cleanup
  112. }
  113. cfg_test_host_common()
  114. {
  115. local name=$1; shift
  116. local grp=$1; shift
  117. local src=$1; shift
  118. local state=$1; shift
  119. local invalid_state=$1; shift
  120. RET=0
  121. # Check basic add, replace and delete behavior.
  122. bridge mdb add dev br0 port br0 grp $grp $state vid 10
  123. bridge mdb get dev br0 grp $grp vid 10 &> /dev/null
  124. check_err $? "Failed to add $name host entry"
  125. bridge mdb replace dev br0 port br0 grp $grp $state vid 10 &> /dev/null
  126. check_err $? "Failed to replace $name host entry"
  127. bridge mdb del dev br0 port br0 grp $grp $state vid 10
  128. bridge mdb get dev br0 grp $grp vid 10 &> /dev/null
  129. check_fail $? "Failed to delete $name host entry"
  130. # Check error cases.
  131. bridge mdb add dev br0 port br0 grp $grp $invalid_state vid 10 \
  132. &> /dev/null
  133. check_fail $? "Managed to add $name host entry with a $invalid_state state"
  134. bridge mdb add dev br0 port br0 grp $grp src $src $state vid 10 \
  135. &> /dev/null
  136. check_fail $? "Managed to add $name host entry with a source"
  137. bridge mdb add dev br0 port br0 grp $grp $state vid 10 \
  138. filter_mode exclude &> /dev/null
  139. check_fail $? "Managed to add $name host entry with a filter mode"
  140. bridge mdb add dev br0 port br0 grp $grp $state vid 10 \
  141. source_list $src &> /dev/null
  142. check_fail $? "Managed to add $name host entry with a source list"
  143. bridge mdb add dev br0 port br0 grp $grp $state vid 10 \
  144. proto 123 &> /dev/null
  145. check_fail $? "Managed to add $name host entry with a protocol"
  146. log_test "Common host entries configuration tests ($name)"
  147. }
  148. # Check configuration of host entries from all types.
  149. cfg_test_host()
  150. {
  151. echo
  152. log_info "# Host entries configuration tests"
  153. cfg_test_host_common "IPv4" "239.1.1.1" "192.0.2.1" "temp" "permanent"
  154. cfg_test_host_common "IPv6" "ff0e::1" "2001:db8:1::1" "temp" "permanent"
  155. cfg_test_host_common "L2" "01:02:03:04:05:06" "00:00:00:00:00:01" \
  156. "permanent" "temp"
  157. }
  158. cfg_test_port_common()
  159. {
  160. local name=$1;shift
  161. local grp_key=$1; shift
  162. RET=0
  163. # Check basic add, replace and delete behavior.
  164. bridge mdb add dev br0 port $swp1 $grp_key permanent vid 10
  165. bridge mdb get dev br0 $grp_key vid 10 &> /dev/null
  166. check_err $? "Failed to add $name entry"
  167. bridge mdb replace dev br0 port $swp1 $grp_key permanent vid 10 \
  168. &> /dev/null
  169. check_err $? "Failed to replace $name entry"
  170. bridge mdb del dev br0 port $swp1 $grp_key permanent vid 10
  171. bridge mdb get dev br0 $grp_key vid 10 &> /dev/null
  172. check_fail $? "Failed to delete $name entry"
  173. # Check default protocol and replacement.
  174. bridge mdb add dev br0 port $swp1 $grp_key permanent vid 10
  175. bridge -d mdb get dev br0 $grp_key vid 10 | grep -q "static"
  176. check_err $? "$name entry not added with default \"static\" protocol"
  177. bridge mdb replace dev br0 port $swp1 $grp_key permanent vid 10 \
  178. proto 123
  179. bridge -d mdb get dev br0 $grp_key vid 10 | grep -q "123"
  180. check_err $? "Failed to replace protocol of $name entry"
  181. bridge mdb del dev br0 port $swp1 $grp_key permanent vid 10
  182. # Check behavior when VLAN is not specified.
  183. bridge mdb add dev br0 port $swp1 $grp_key permanent
  184. bridge mdb get dev br0 $grp_key vid 10 &> /dev/null
  185. check_err $? "$name entry with VLAN 10 not added when VLAN was not specified"
  186. bridge mdb get dev br0 $grp_key vid 20 &> /dev/null
  187. check_err $? "$name entry with VLAN 20 not added when VLAN was not specified"
  188. bridge mdb del dev br0 port $swp1 $grp_key permanent
  189. bridge mdb get dev br0 $grp_key vid 10 &> /dev/null
  190. check_fail $? "$name entry with VLAN 10 not deleted when VLAN was not specified"
  191. bridge mdb get dev br0 $grp_key vid 20 &> /dev/null
  192. check_fail $? "$name entry with VLAN 20 not deleted when VLAN was not specified"
  193. # Check behavior when bridge port is down.
  194. ip link set dev $swp1 down
  195. bridge mdb add dev br0 port $swp1 $grp_key permanent vid 10
  196. check_err $? "Failed to add $name permanent entry when bridge port is down"
  197. bridge mdb del dev br0 port $swp1 $grp_key permanent vid 10
  198. bridge mdb add dev br0 port $swp1 $grp_key temp vid 10 &> /dev/null
  199. check_fail $? "Managed to add $name temporary entry when bridge port is down"
  200. ip link set dev $swp1 up
  201. setup_wait_dev $swp1
  202. # Check error cases.
  203. ip link set dev br0 down
  204. bridge mdb add dev br0 port $swp1 $grp_key permanent vid 10 \
  205. &> /dev/null
  206. check_fail $? "Managed to add $name entry when bridge is down"
  207. ip link set dev br0 up
  208. ip link set dev br0 type bridge mcast_snooping 0
  209. bridge mdb add dev br0 port $swp1 $grp_key permanent vid \
  210. 10 &> /dev/null
  211. check_fail $? "Managed to add $name entry when multicast snooping is disabled"
  212. ip link set dev br0 type bridge mcast_snooping 1
  213. bridge mdb add dev br0 port $swp1 $grp_key permanent vid 5000 \
  214. &> /dev/null
  215. check_fail $? "Managed to add $name entry with an invalid VLAN"
  216. log_test "Common port group entries configuration tests ($name)"
  217. }
  218. src_list_create()
  219. {
  220. local src_prefix=$1; shift
  221. local num_srcs=$1; shift
  222. local src_list
  223. local i
  224. for i in $(seq 1 $num_srcs); do
  225. src_list=${src_list},${src_prefix}${i}
  226. done
  227. echo $src_list | cut -c 2-
  228. }
  229. __cfg_test_port_ip_star_g()
  230. {
  231. local name=$1; shift
  232. local grp=$1; shift
  233. local invalid_grp=$1; shift
  234. local src_prefix=$1; shift
  235. local src1=${src_prefix}1
  236. local src2=${src_prefix}2
  237. local src3=${src_prefix}3
  238. local max_srcs=31
  239. local num_srcs
  240. RET=0
  241. bridge mdb add dev br0 port $swp1 grp $grp vid 10
  242. bridge -d mdb get dev br0 grp $grp vid 10 | grep -q "exclude"
  243. check_err $? "Default filter mode is not \"exclude\""
  244. bridge mdb del dev br0 port $swp1 grp $grp vid 10
  245. # Check basic add and delete behavior.
  246. bridge mdb add dev br0 port $swp1 grp $grp vid 10 filter_mode exclude \
  247. source_list $src1
  248. bridge -d mdb get dev br0 grp $grp vid 10 &> /dev/null
  249. check_err $? "(*, G) entry not created"
  250. bridge -d mdb get dev br0 grp $grp src $src1 vid 10 &> /dev/null
  251. check_err $? "(S, G) entry not created"
  252. bridge mdb del dev br0 port $swp1 grp $grp vid 10
  253. bridge -d mdb get dev br0 grp $grp vid 10 &> /dev/null
  254. check_fail $? "(*, G) entry not deleted"
  255. bridge -d mdb get dev br0 grp $grp src $src1 vid 10 &> /dev/null
  256. check_fail $? "(S, G) entry not deleted"
  257. ## State (permanent / temp) tests.
  258. # Check that group and source timer are not set for permanent entries.
  259. bridge mdb add dev br0 port $swp1 grp $grp permanent vid 10 \
  260. filter_mode exclude source_list $src1
  261. bridge -d mdb get dev br0 grp $grp vid 10 | grep -q "permanent"
  262. check_err $? "(*, G) entry not added as \"permanent\" when should"
  263. bridge -d mdb get dev br0 grp $grp src $src1 vid 10 | \
  264. grep -q "permanent"
  265. check_err $? "(S, G) entry not added as \"permanent\" when should"
  266. bridge -d -s mdb get dev br0 grp $grp vid 10 | grep -q " 0.00"
  267. check_err $? "(*, G) \"permanent\" entry has a pending group timer"
  268. bridge -d -s mdb get dev br0 grp $grp vid 10 | grep -q "/0.00"
  269. check_err $? "\"permanent\" source entry has a pending source timer"
  270. bridge mdb del dev br0 port $swp1 grp $grp vid 10
  271. # Check that group timer is set for temporary (*, G) EXCLUDE, but not
  272. # the source timer.
  273. bridge mdb add dev br0 port $swp1 grp $grp temp vid 10 \
  274. filter_mode exclude source_list $src1
  275. bridge -d mdb get dev br0 grp $grp vid 10 | grep -q "temp"
  276. check_err $? "(*, G) EXCLUDE entry not added as \"temp\" when should"
  277. bridge -d mdb get dev br0 grp $grp src $src1 vid 10 | grep -q "temp"
  278. check_err $? "(S, G) \"blocked\" entry not added as \"temp\" when should"
  279. bridge -d -s mdb get dev br0 grp $grp vid 10 | grep -q " 0.00"
  280. check_fail $? "(*, G) EXCLUDE entry does not have a pending group timer"
  281. bridge -d -s mdb get dev br0 grp $grp vid 10 | grep -q "/0.00"
  282. check_err $? "\"blocked\" source entry has a pending source timer"
  283. bridge mdb del dev br0 port $swp1 grp $grp vid 10
  284. # Check that group timer is not set for temporary (*, G) INCLUDE, but
  285. # that the source timer is set.
  286. bridge mdb add dev br0 port $swp1 grp $grp temp vid 10 \
  287. filter_mode include source_list $src1
  288. bridge -d mdb get dev br0 grp $grp vid 10 | grep -q "temp"
  289. check_err $? "(*, G) INCLUDE entry not added as \"temp\" when should"
  290. bridge -d mdb get dev br0 grp $grp src $src1 vid 10 | grep -q "temp"
  291. check_err $? "(S, G) entry not added as \"temp\" when should"
  292. bridge -d -s mdb get dev br0 grp $grp vid 10 | grep -q " 0.00"
  293. check_err $? "(*, G) INCLUDE entry has a pending group timer"
  294. bridge -d -s mdb get dev br0 grp $grp vid 10 | grep -q "/0.00"
  295. check_fail $? "Source entry does not have a pending source timer"
  296. bridge mdb del dev br0 port $swp1 grp $grp vid 10
  297. # Check that group timer is never set for (S, G) entries.
  298. bridge mdb add dev br0 port $swp1 grp $grp temp vid 10 \
  299. filter_mode include source_list $src1
  300. bridge -d -s mdb get dev br0 grp $grp src $src1 vid 10 | grep -q " 0.00"
  301. check_err $? "(S, G) entry has a pending group timer"
  302. bridge mdb del dev br0 port $swp1 grp $grp vid 10
  303. ## Filter mode (include / exclude) tests.
  304. # Check that (*, G) INCLUDE entries are added with correct filter mode
  305. # and that (S, G) entries are not marked as "blocked".
  306. bridge mdb add dev br0 port $swp1 grp $grp vid 10 \
  307. filter_mode include source_list $src1
  308. bridge -d mdb get dev br0 grp $grp vid 10 | grep -q "include"
  309. check_err $? "(*, G) INCLUDE not added with \"include\" filter mode"
  310. bridge -d mdb get dev br0 grp $grp src $src1 vid 10 | grep -q "blocked"
  311. check_fail $? "(S, G) entry marked as \"blocked\" when should not"
  312. bridge mdb del dev br0 port $swp1 grp $grp vid 10
  313. # Check that (*, G) EXCLUDE entries are added with correct filter mode
  314. # and that (S, G) entries are marked as "blocked".
  315. bridge mdb add dev br0 port $swp1 grp $grp vid 10 \
  316. filter_mode exclude source_list $src1
  317. bridge -d mdb get dev br0 grp $grp vid 10 | grep -q "exclude"
  318. check_err $? "(*, G) EXCLUDE not added with \"exclude\" filter mode"
  319. bridge -d mdb get dev br0 grp $grp src $src1 vid 10 | grep -q "blocked"
  320. check_err $? "(S, G) entry not marked as \"blocked\" when should"
  321. bridge mdb del dev br0 port $swp1 grp $grp vid 10
  322. ## Protocol tests.
  323. # Check that (*, G) and (S, G) entries are added with the specified
  324. # protocol.
  325. bridge mdb add dev br0 port $swp1 grp $grp vid 10 \
  326. filter_mode exclude source_list $src1 proto zebra
  327. bridge -d mdb get dev br0 grp $grp vid 10 | grep -q "zebra"
  328. check_err $? "(*, G) entry not added with \"zebra\" protocol"
  329. bridge -d mdb get dev br0 grp $grp src $src1 vid 10 | grep -q "zebra"
  330. check_err $? "(S, G) entry not marked added with \"zebra\" protocol"
  331. bridge mdb del dev br0 port $swp1 grp $grp vid 10
  332. ## Replace tests.
  333. # Check that state can be modified.
  334. bridge mdb add dev br0 port $swp1 grp $grp temp vid 10 \
  335. filter_mode exclude source_list $src1
  336. bridge mdb replace dev br0 port $swp1 grp $grp permanent vid 10 \
  337. filter_mode exclude source_list $src1
  338. bridge -d mdb get dev br0 grp $grp vid 10 | grep -q "permanent"
  339. check_err $? "(*, G) entry not marked as \"permanent\" after replace"
  340. bridge -d mdb get dev br0 grp $grp src $src1 vid 10 | grep -q "permanent"
  341. check_err $? "(S, G) entry not marked as \"permanent\" after replace"
  342. bridge mdb replace dev br0 port $swp1 grp $grp temp vid 10 \
  343. filter_mode exclude source_list $src1
  344. bridge -d mdb get dev br0 grp $grp vid 10 | grep -q "temp"
  345. check_err $? "(*, G) entry not marked as \"temp\" after replace"
  346. bridge -d mdb get dev br0 grp $grp src $src1 vid 10 | grep -q "temp"
  347. check_err $? "(S, G) entry not marked as \"temp\" after replace"
  348. bridge mdb del dev br0 port $swp1 grp $grp vid 10
  349. # Check that filter mode can be modified.
  350. bridge mdb add dev br0 port $swp1 grp $grp temp vid 10 \
  351. filter_mode exclude source_list $src1
  352. bridge mdb replace dev br0 port $swp1 grp $grp temp vid 10 \
  353. filter_mode include source_list $src1
  354. bridge -d mdb get dev br0 grp $grp vid 10 | grep -q "include"
  355. check_err $? "(*, G) not marked with \"include\" filter mode after replace"
  356. bridge -d mdb get dev br0 grp $grp src $src1 vid 10 | grep -q "blocked"
  357. check_fail $? "(S, G) marked as \"blocked\" after replace"
  358. bridge mdb replace dev br0 port $swp1 grp $grp temp vid 10 \
  359. filter_mode exclude source_list $src1
  360. bridge -d mdb get dev br0 grp $grp vid 10 | grep -q "exclude"
  361. check_err $? "(*, G) not marked with \"exclude\" filter mode after replace"
  362. bridge -d mdb get dev br0 grp $grp src $src1 vid 10 | grep -q "blocked"
  363. check_err $? "(S, G) not marked as \"blocked\" after replace"
  364. bridge mdb del dev br0 port $swp1 grp $grp vid 10
  365. # Check that sources can be added to and removed from the source list.
  366. bridge mdb add dev br0 port $swp1 grp $grp temp vid 10 \
  367. filter_mode exclude source_list $src1
  368. bridge mdb replace dev br0 port $swp1 grp $grp temp vid 10 \
  369. filter_mode exclude source_list $src1,$src2,$src3
  370. bridge -d mdb get dev br0 grp $grp src $src1 vid 10 &> /dev/null
  371. check_err $? "(S, G) entry for source $src1 not created after replace"
  372. bridge -d mdb get dev br0 grp $grp src $src2 vid 10 &> /dev/null
  373. check_err $? "(S, G) entry for source $src2 not created after replace"
  374. bridge -d mdb get dev br0 grp $grp src $src3 vid 10 &> /dev/null
  375. check_err $? "(S, G) entry for source $src3 not created after replace"
  376. bridge mdb replace dev br0 port $swp1 grp $grp temp vid 10 \
  377. filter_mode exclude source_list $src1,$src3
  378. bridge -d mdb get dev br0 grp $grp src $src1 vid 10 &> /dev/null
  379. check_err $? "(S, G) entry for source $src1 not created after second replace"
  380. bridge -d mdb get dev br0 grp $grp src $src2 vid 10 &> /dev/null
  381. check_fail $? "(S, G) entry for source $src2 created after second replace"
  382. bridge -d mdb get dev br0 grp $grp src $src3 vid 10 &> /dev/null
  383. check_err $? "(S, G) entry for source $src3 not created after second replace"
  384. bridge mdb del dev br0 port $swp1 grp $grp vid 10
  385. # Check that protocol can be modified.
  386. bridge mdb add dev br0 port $swp1 grp $grp temp vid 10 \
  387. filter_mode exclude source_list $src1 proto zebra
  388. bridge mdb replace dev br0 port $swp1 grp $grp temp vid 10 \
  389. filter_mode exclude source_list $src1 proto bgp
  390. bridge -d mdb get dev br0 grp $grp vid 10 | grep -q "bgp"
  391. check_err $? "(*, G) protocol not changed to \"bgp\" after replace"
  392. bridge -d mdb get dev br0 grp $grp src $src1 vid 10 | grep -q "bgp"
  393. check_err $? "(S, G) protocol not changed to \"bgp\" after replace"
  394. bridge mdb del dev br0 port $swp1 grp $grp vid 10
  395. ## Star exclude tests.
  396. # Check star exclude functionality. When adding a new EXCLUDE (*, G),
  397. # it needs to be also added to all (S, G) entries for proper
  398. # replication.
  399. bridge mdb add dev br0 port $swp2 grp $grp vid 10 \
  400. filter_mode include source_list $src1
  401. bridge mdb add dev br0 port $swp1 grp $grp vid 10
  402. bridge -d mdb get dev br0 grp $grp src $src1 vid 10 | grep "$swp1" | \
  403. grep -q "added_by_star_ex"
  404. check_err $? "\"added_by_star_ex\" entry not created after adding (*, G) entry"
  405. bridge mdb del dev br0 port $swp1 grp $grp vid 10
  406. bridge mdb del dev br0 port $swp2 grp $grp src $src1 vid 10
  407. ## Error cases tests.
  408. bridge mdb add dev br0 port $swp1 grp $invalid_grp vid 10 &> /dev/null
  409. check_fail $? "Managed to add an entry with an invalid group"
  410. bridge mdb add dev br0 port $swp1 grp $grp vid 10 filter_mode include \
  411. &> /dev/null
  412. check_fail $? "Managed to add an INCLUDE entry with an empty source list"
  413. bridge mdb add dev br0 port $swp1 grp $grp vid 10 filter_mode include \
  414. source_list $grp &> /dev/null
  415. check_fail $? "Managed to add an entry with an invalid source in source list"
  416. bridge mdb add dev br0 port $swp1 grp $grp vid 10 \
  417. source_list $src &> /dev/null
  418. check_fail $? "Managed to add an entry with a source list and no filter mode"
  419. bridge mdb add dev br0 port $swp1 grp $grp vid 10 filter_mode include \
  420. source_list $src1
  421. bridge mdb add dev br0 port $swp1 grp $grp vid 10 filter_mode exclude \
  422. source_list $src1 &> /dev/null
  423. check_fail $? "Managed to replace an entry without using replace"
  424. bridge mdb del dev br0 port $swp1 grp $grp vid 10
  425. bridge mdb add dev br0 port $swp1 grp $grp src $src2 vid 10
  426. bridge mdb add dev br0 port $swp1 grp $grp vid 10 filter_mode include \
  427. source_list $src1,$src2,$src3 &> /dev/null
  428. check_fail $? "Managed to add a source that already has a forwarding entry"
  429. bridge mdb del dev br0 port $swp1 grp $grp src $src2 vid 10
  430. # Check maximum number of sources.
  431. bridge mdb add dev br0 port $swp1 grp $grp vid 10 filter_mode exclude \
  432. source_list $(src_list_create $src_prefix $max_srcs)
  433. num_srcs=$(bridge -d mdb show dev br0 vid 10 | grep "$grp" | \
  434. grep "src" | wc -l)
  435. [[ $num_srcs -eq $max_srcs ]]
  436. check_err $? "Failed to configure maximum number of sources ($max_srcs)"
  437. bridge mdb del dev br0 port $swp1 grp $grp vid 10
  438. bridge mdb add dev br0 port $swp1 grp $grp vid 10 filter_mode exclude \
  439. source_list $(src_list_create $src_prefix $((max_srcs + 1))) \
  440. &> /dev/null
  441. check_fail $? "Managed to exceed maximum number of sources ($max_srcs)"
  442. log_test "$name (*, G) port group entries configuration tests"
  443. }
  444. cfg_test_port_ip_star_g()
  445. {
  446. echo
  447. log_info "# Port group entries configuration tests - (*, G)"
  448. cfg_test_port_common "IPv4 (*, G)" "grp 239.1.1.1"
  449. cfg_test_port_common "IPv6 (*, G)" "grp ff0e::1"
  450. __cfg_test_port_ip_star_g "IPv4" "239.1.1.1" "224.0.0.1" "192.0.2."
  451. __cfg_test_port_ip_star_g "IPv6" "ff0e::1" "ff02::1" "2001:db8:1::"
  452. }
  453. __cfg_test_port_ip_sg()
  454. {
  455. local name=$1; shift
  456. local grp=$1; shift
  457. local src=$1; shift
  458. local grp_key="grp $grp src $src"
  459. RET=0
  460. bridge mdb add dev br0 port $swp1 $grp_key vid 10
  461. bridge -d mdb get dev br0 $grp_key vid 10 | grep -q "include"
  462. check_err $? "Default filter mode is not \"include\""
  463. bridge mdb del dev br0 port $swp1 $grp_key vid 10
  464. # Check that entries can be added as both permanent and temp and that
  465. # group timer is set correctly.
  466. bridge mdb add dev br0 port $swp1 $grp_key permanent vid 10
  467. bridge -d mdb get dev br0 $grp_key vid 10 | grep -q "permanent"
  468. check_err $? "Entry not added as \"permanent\" when should"
  469. bridge -d -s mdb get dev br0 $grp_key vid 10 | grep -q " 0.00"
  470. check_err $? "\"permanent\" entry has a pending group timer"
  471. bridge mdb del dev br0 port $swp1 $grp_key vid 10
  472. bridge mdb add dev br0 port $swp1 $grp_key temp vid 10
  473. bridge -d mdb get dev br0 $grp_key vid 10 | grep -q "temp"
  474. check_err $? "Entry not added as \"temp\" when should"
  475. bridge -d -s mdb get dev br0 $grp_key vid 10 | grep -q " 0.00"
  476. check_fail $? "\"temp\" entry has an unpending group timer"
  477. bridge mdb del dev br0 port $swp1 $grp_key vid 10
  478. # Check error cases.
  479. bridge mdb add dev br0 port $swp1 $grp_key vid 10 \
  480. filter_mode include &> /dev/null
  481. check_fail $? "Managed to add an entry with a filter mode"
  482. bridge mdb add dev br0 port $swp1 $grp_key vid 10 \
  483. filter_mode include source_list $src &> /dev/null
  484. check_fail $? "Managed to add an entry with a source list"
  485. bridge mdb add dev br0 port $swp1 grp $grp src $grp vid 10 &> /dev/null
  486. check_fail $? "Managed to add an entry with an invalid source"
  487. bridge mdb add dev br0 port $swp1 $grp_key vid 10 temp
  488. bridge mdb add dev br0 port $swp1 $grp_key vid 10 permanent &> /dev/null
  489. check_fail $? "Managed to replace an entry without using replace"
  490. bridge mdb del dev br0 port $swp1 $grp_key vid 10
  491. # Check that we can replace available attributes.
  492. bridge mdb add dev br0 port $swp1 $grp_key vid 10 proto 123
  493. bridge mdb replace dev br0 port $swp1 $grp_key vid 10 proto 111
  494. bridge -d mdb get dev br0 $grp_key vid 10 | grep -q "111"
  495. check_err $? "Failed to replace protocol"
  496. bridge mdb replace dev br0 port $swp1 $grp_key vid 10 permanent
  497. bridge -d mdb get dev br0 $grp_key vid 10 | grep -q "permanent"
  498. check_err $? "Entry not marked as \"permanent\" after replace"
  499. bridge -d -s mdb get dev br0 $grp_key vid 10 | grep -q " 0.00"
  500. check_err $? "Entry has a pending group timer after replace"
  501. bridge mdb replace dev br0 port $swp1 $grp_key vid 10 temp
  502. bridge -d mdb get dev br0 $grp_key vid 10 | grep -q "temp"
  503. check_err $? "Entry not marked as \"temp\" after replace"
  504. bridge -d -s mdb get dev br0 $grp_key vid 10 | grep -q " 0.00"
  505. check_fail $? "Entry has an unpending group timer after replace"
  506. bridge mdb del dev br0 port $swp1 $grp_key vid 10
  507. # Check star exclude functionality. When adding a (S, G), all matching
  508. # (*, G) ports need to be added to it.
  509. bridge mdb add dev br0 port $swp2 grp $grp vid 10
  510. bridge mdb add dev br0 port $swp1 $grp_key vid 10
  511. bridge mdb get dev br0 $grp_key vid 10 | grep $swp2 | \
  512. grep -q "added_by_star_ex"
  513. check_err $? "\"added_by_star_ex\" entry not created after adding (S, G) entry"
  514. bridge mdb del dev br0 port $swp1 $grp_key vid 10
  515. bridge mdb del dev br0 port $swp2 grp $grp vid 10
  516. log_test "$name (S, G) port group entries configuration tests"
  517. }
  518. cfg_test_port_ip_sg()
  519. {
  520. echo
  521. log_info "# Port group entries configuration tests - (S, G)"
  522. cfg_test_port_common "IPv4 (S, G)" "grp 239.1.1.1 src 192.0.2.1"
  523. cfg_test_port_common "IPv6 (S, G)" "grp ff0e::1 src 2001:db8:1::1"
  524. __cfg_test_port_ip_sg "IPv4" "239.1.1.1" "192.0.2.1"
  525. __cfg_test_port_ip_sg "IPv6" "ff0e::1" "2001:db8:1::1"
  526. }
  527. cfg_test_port_ip()
  528. {
  529. cfg_test_port_ip_star_g
  530. cfg_test_port_ip_sg
  531. }
  532. __cfg_test_port_l2()
  533. {
  534. local grp="01:02:03:04:05:06"
  535. RET=0
  536. bridge meb add dev br0 port $swp grp 00:01:02:03:04:05 \
  537. permanent vid 10 &> /dev/null
  538. check_fail $? "Managed to add an entry with unicast MAC"
  539. bridge mdb add dev br0 port $swp grp $grp src 00:01:02:03:04:05 \
  540. permanent vid 10 &> /dev/null
  541. check_fail $? "Managed to add an entry with a source"
  542. bridge mdb add dev br0 port $swp1 grp $grp permanent vid 10 \
  543. filter_mode include &> /dev/null
  544. check_fail $? "Managed to add an entry with a filter mode"
  545. bridge mdb add dev br0 port $swp1 grp $grp permanent vid 10 \
  546. source_list 00:01:02:03:04:05 &> /dev/null
  547. check_fail $? "Managed to add an entry with a source list"
  548. log_test "L2 (*, G) port group entries configuration tests"
  549. }
  550. cfg_test_port_l2()
  551. {
  552. echo
  553. log_info "# Port group entries configuration tests - L2"
  554. cfg_test_port_common "L2 (*, G)" "grp 01:02:03:04:05:06"
  555. __cfg_test_port_l2
  556. }
  557. # Check configuration of regular (port) entries of all types.
  558. cfg_test_port()
  559. {
  560. cfg_test_port_ip
  561. cfg_test_port_l2
  562. }
  563. ipv4_grps_get()
  564. {
  565. local max_grps=$1; shift
  566. local i
  567. for i in $(seq 0 $((max_grps - 1))); do
  568. echo "239.1.1.$i"
  569. done
  570. }
  571. ipv6_grps_get()
  572. {
  573. local max_grps=$1; shift
  574. local i
  575. for i in $(seq 0 $((max_grps - 1))); do
  576. echo "ff0e::$(printf %x $i)"
  577. done
  578. }
  579. l2_grps_get()
  580. {
  581. local max_grps=$1; shift
  582. local i
  583. for i in $(seq 0 $((max_grps - 1))); do
  584. echo "01:00:00:00:00:$(printf %02x $i)"
  585. done
  586. }
  587. cfg_test_dump_common()
  588. {
  589. local name=$1; shift
  590. local fn=$1; shift
  591. local max_bridges=2
  592. local max_grps=256
  593. local max_ports=32
  594. local num_entries
  595. local batch_file
  596. local grp
  597. local i j
  598. RET=0
  599. # Create net devices.
  600. for i in $(seq 1 $max_bridges); do
  601. ip link add name br-test${i} up type bridge vlan_filtering 1 \
  602. mcast_snooping 1
  603. for j in $(seq 1 $max_ports); do
  604. ip link add name br-test${i}-du${j} up \
  605. master br-test${i} type dummy
  606. done
  607. done
  608. # Create batch file with MDB entries.
  609. batch_file=$(mktemp)
  610. for i in $(seq 1 $max_bridges); do
  611. for j in $(seq 1 $max_ports); do
  612. for grp in $($fn $max_grps); do
  613. echo "mdb add dev br-test${i} \
  614. port br-test${i}-du${j} grp $grp \
  615. permanent vid 1" >> $batch_file
  616. done
  617. done
  618. done
  619. # Program the batch file and check for expected number of entries.
  620. bridge -b $batch_file
  621. for i in $(seq 1 $max_bridges); do
  622. num_entries=$(bridge mdb show dev br-test${i} | \
  623. grep "permanent" | wc -l)
  624. [[ $num_entries -eq $((max_grps * max_ports)) ]]
  625. check_err $? "Wrong number of entries in br-test${i}"
  626. done
  627. # Cleanup.
  628. rm $batch_file
  629. for i in $(seq 1 $max_bridges); do
  630. ip link del dev br-test${i}
  631. for j in $(seq $max_ports); do
  632. ip link del dev br-test${i}-du${j}
  633. done
  634. done
  635. log_test "$name large scale dump tests"
  636. }
  637. # Check large scale dump.
  638. cfg_test_dump()
  639. {
  640. echo
  641. log_info "# Large scale dump tests"
  642. cfg_test_dump_common "IPv4" ipv4_grps_get
  643. cfg_test_dump_common "IPv6" ipv6_grps_get
  644. cfg_test_dump_common "L2" l2_grps_get
  645. }
  646. # Check flush functionality with different parameters.
  647. cfg_test_flush()
  648. {
  649. local num_entries
  650. # Add entries with different attributes and check that they are all
  651. # flushed when the flush command is given with no parameters.
  652. # Different port.
  653. bridge mdb add dev br0 port $swp1 grp 239.1.1.1 vid 10
  654. bridge mdb add dev br0 port $swp2 grp 239.1.1.2 vid 10
  655. # Different VLAN ID.
  656. bridge mdb add dev br0 port $swp1 grp 239.1.1.3 vid 10
  657. bridge mdb add dev br0 port $swp1 grp 239.1.1.4 vid 20
  658. # Different routing protocol.
  659. bridge mdb add dev br0 port $swp1 grp 239.1.1.5 vid 10 proto bgp
  660. bridge mdb add dev br0 port $swp1 grp 239.1.1.6 vid 10 proto zebra
  661. # Different state.
  662. bridge mdb add dev br0 port $swp1 grp 239.1.1.7 vid 10 permanent
  663. bridge mdb add dev br0 port $swp1 grp 239.1.1.8 vid 10 temp
  664. bridge mdb flush dev br0
  665. num_entries=$(bridge mdb show dev br0 | wc -l)
  666. [[ $num_entries -eq 0 ]]
  667. check_err $? 0 "Not all entries flushed after flush all"
  668. # Check that when flushing by port only entries programmed with the
  669. # specified port are flushed and the rest are not.
  670. bridge mdb add dev br0 port $swp1 grp 239.1.1.1 vid 10
  671. bridge mdb add dev br0 port $swp2 grp 239.1.1.1 vid 10
  672. bridge mdb add dev br0 port br0 grp 239.1.1.1 vid 10
  673. bridge mdb flush dev br0 port $swp1
  674. bridge mdb get dev br0 grp 239.1.1.1 vid 10 | grep -q "port $swp1"
  675. check_fail $? "Entry not flushed by specified port"
  676. bridge mdb get dev br0 grp 239.1.1.1 vid 10 | grep -q "port $swp2"
  677. check_err $? "Entry flushed by wrong port"
  678. bridge mdb get dev br0 grp 239.1.1.1 vid 10 | grep -q "port br0"
  679. check_err $? "Host entry flushed by wrong port"
  680. bridge mdb flush dev br0 port br0
  681. bridge mdb get dev br0 grp 239.1.1.1 vid 10 | grep -q "port br0"
  682. check_fail $? "Host entry not flushed by specified port"
  683. bridge mdb flush dev br0
  684. # Check that when flushing by VLAN ID only entries programmed with the
  685. # specified VLAN ID are flushed and the rest are not.
  686. bridge mdb add dev br0 port $swp1 grp 239.1.1.1 vid 10
  687. bridge mdb add dev br0 port $swp2 grp 239.1.1.1 vid 10
  688. bridge mdb add dev br0 port $swp1 grp 239.1.1.1 vid 20
  689. bridge mdb add dev br0 port $swp2 grp 239.1.1.1 vid 20
  690. bridge mdb flush dev br0 vid 10
  691. bridge mdb get dev br0 grp 239.1.1.1 vid 10 &> /dev/null
  692. check_fail $? "Entry not flushed by specified VLAN ID"
  693. bridge mdb get dev br0 grp 239.1.1.1 vid 20 &> /dev/null
  694. check_err $? "Entry flushed by wrong VLAN ID"
  695. bridge mdb flush dev br0
  696. # Check that all permanent entries are flushed when "permanent" is
  697. # specified and that temporary entries are not.
  698. bridge mdb add dev br0 port $swp1 grp 239.1.1.1 permanent vid 10
  699. bridge mdb add dev br0 port $swp2 grp 239.1.1.1 temp vid 10
  700. bridge mdb flush dev br0 permanent
  701. bridge mdb get dev br0 grp 239.1.1.1 vid 10 | grep -q "port $swp1"
  702. check_fail $? "Entry not flushed by \"permanent\" state"
  703. bridge mdb get dev br0 grp 239.1.1.1 vid 10 | grep -q "port $swp2"
  704. check_err $? "Entry flushed by wrong state (\"permanent\")"
  705. bridge mdb flush dev br0
  706. # Check that all temporary entries are flushed when "nopermanent" is
  707. # specified and that permanent entries are not.
  708. bridge mdb add dev br0 port $swp1 grp 239.1.1.1 permanent vid 10
  709. bridge mdb add dev br0 port $swp2 grp 239.1.1.1 temp vid 10
  710. bridge mdb flush dev br0 nopermanent
  711. bridge mdb get dev br0 grp 239.1.1.1 vid 10 | grep -q "port $swp1"
  712. check_err $? "Entry flushed by wrong state (\"nopermanent\")"
  713. bridge mdb get dev br0 grp 239.1.1.1 vid 10 | grep -q "port $swp2"
  714. check_fail $? "Entry not flushed by \"nopermanent\" state"
  715. bridge mdb flush dev br0
  716. # Check that L2 host entries are not flushed when "nopermanent" is
  717. # specified, but flushed when "permanent" is specified.
  718. bridge mdb add dev br0 port br0 grp 01:02:03:04:05:06 permanent vid 10
  719. bridge mdb flush dev br0 nopermanent
  720. bridge mdb get dev br0 grp 01:02:03:04:05:06 vid 10 &> /dev/null
  721. check_err $? "L2 host entry flushed by wrong state (\"nopermanent\")"
  722. bridge mdb flush dev br0 permanent
  723. bridge mdb get dev br0 grp 01:02:03:04:05:06 vid 10 &> /dev/null
  724. check_fail $? "L2 host entry not flushed by \"permanent\" state"
  725. bridge mdb flush dev br0
  726. # Check that IPv4 host entries are not flushed when "permanent" is
  727. # specified, but flushed when "nopermanent" is specified.
  728. bridge mdb add dev br0 port br0 grp 239.1.1.1 temp vid 10
  729. bridge mdb flush dev br0 permanent
  730. bridge mdb get dev br0 grp 239.1.1.1 vid 10 &> /dev/null
  731. check_err $? "IPv4 host entry flushed by wrong state (\"permanent\")"
  732. bridge mdb flush dev br0 nopermanent
  733. bridge mdb get dev br0 grp 239.1.1.1 vid 10 &> /dev/null
  734. check_fail $? "IPv4 host entry not flushed by \"nopermanent\" state"
  735. bridge mdb flush dev br0
  736. # Check that IPv6 host entries are not flushed when "permanent" is
  737. # specified, but flushed when "nopermanent" is specified.
  738. bridge mdb add dev br0 port br0 grp ff0e::1 temp vid 10
  739. bridge mdb flush dev br0 permanent
  740. bridge mdb get dev br0 grp ff0e::1 vid 10 &> /dev/null
  741. check_err $? "IPv6 host entry flushed by wrong state (\"permanent\")"
  742. bridge mdb flush dev br0 nopermanent
  743. bridge mdb get dev br0 grp ff0e::1 vid 10 &> /dev/null
  744. check_fail $? "IPv6 host entry not flushed by \"nopermanent\" state"
  745. bridge mdb flush dev br0
  746. # Check that when flushing by routing protocol only entries programmed
  747. # with the specified routing protocol are flushed and the rest are not.
  748. bridge mdb add dev br0 port $swp1 grp 239.1.1.1 vid 10 proto bgp
  749. bridge mdb add dev br0 port $swp2 grp 239.1.1.1 vid 10 proto zebra
  750. bridge mdb add dev br0 port br0 grp 239.1.1.1 vid 10
  751. bridge mdb flush dev br0 proto bgp
  752. bridge mdb get dev br0 grp 239.1.1.1 vid 10 | grep -q "port $swp1"
  753. check_fail $? "Entry not flushed by specified routing protocol"
  754. bridge mdb get dev br0 grp 239.1.1.1 vid 10 | grep -q "port $swp2"
  755. check_err $? "Entry flushed by wrong routing protocol"
  756. bridge mdb get dev br0 grp 239.1.1.1 vid 10 | grep -q "port br0"
  757. check_err $? "Host entry flushed by wrong routing protocol"
  758. bridge mdb flush dev br0
  759. # Test that an error is returned when trying to flush using unsupported
  760. # parameters.
  761. bridge mdb flush dev br0 src_vni 10 &> /dev/null
  762. check_fail $? "Managed to flush by source VNI"
  763. bridge mdb flush dev br0 dst 198.51.100.1 &> /dev/null
  764. check_fail $? "Managed to flush by destination IP"
  765. bridge mdb flush dev br0 dst_port 4789 &> /dev/null
  766. check_fail $? "Managed to flush by UDP destination port"
  767. bridge mdb flush dev br0 vni 10 &> /dev/null
  768. check_fail $? "Managed to flush by destination VNI"
  769. log_test "Flush tests"
  770. }
  771. cfg_test()
  772. {
  773. cfg_test_host
  774. cfg_test_port
  775. cfg_test_dump
  776. cfg_test_flush
  777. }
  778. __fwd_test_host_ip()
  779. {
  780. local grp=$1; shift
  781. local dmac=$1; shift
  782. local src=$1; shift
  783. local mode=$1; shift
  784. local name
  785. local eth_type
  786. RET=0
  787. if [[ $mode == "-4" ]]; then
  788. name="IPv4"
  789. eth_type="ipv4"
  790. else
  791. name="IPv6"
  792. eth_type="ipv6"
  793. fi
  794. tc filter add dev br0 ingress protocol 802.1q pref 1 handle 1 flower \
  795. vlan_ethtype $eth_type vlan_id 10 dst_ip $grp src_ip $src \
  796. action drop
  797. # Packet should only be flooded to multicast router ports when there is
  798. # no matching MDB entry. The bridge is not configured as a multicast
  799. # router port.
  800. $MZ $mode $h1.10 -a own -b $dmac -c 1 -p 128 -A $src -B $grp -t udp -q
  801. tc_check_packets "dev br0 ingress" 1 0
  802. check_err $? "Packet locally received after flood"
  803. # Install a regular port group entry and expect the packet to not be
  804. # locally received.
  805. bridge mdb add dev br0 port $swp2 grp $grp temp vid 10
  806. $MZ $mode $h1.10 -a own -b $dmac -c 1 -p 128 -A $src -B $grp -t udp -q
  807. tc_check_packets "dev br0 ingress" 1 0
  808. check_err $? "Packet locally received after installing a regular entry"
  809. # Add a host entry and expect the packet to be locally received.
  810. bridge mdb add dev br0 port br0 grp $grp temp vid 10
  811. $MZ $mode $h1.10 -a own -b $dmac -c 1 -p 128 -A $src -B $grp -t udp -q
  812. tc_check_packets "dev br0 ingress" 1 1
  813. check_err $? "Packet not locally received after adding a host entry"
  814. # Remove the host entry and expect the packet to not be locally
  815. # received.
  816. bridge mdb del dev br0 port br0 grp $grp vid 10
  817. $MZ $mode $h1.10 -a own -b $dmac -c 1 -p 128 -A $src -B $grp -t udp -q
  818. tc_check_packets "dev br0 ingress" 1 1
  819. check_err $? "Packet locally received after removing a host entry"
  820. bridge mdb del dev br0 port $swp2 grp $grp vid 10
  821. tc filter del dev br0 ingress protocol 802.1q pref 1 handle 1 flower
  822. log_test "$name host entries forwarding tests"
  823. }
  824. fwd_test_host_ip()
  825. {
  826. __fwd_test_host_ip "239.1.1.1" "01:00:5e:01:01:01" "192.0.2.1" "-4"
  827. __fwd_test_host_ip "ff0e::1" "33:33:00:00:00:01" "2001:db8:1::1" "-6"
  828. }
  829. fwd_test_host_l2()
  830. {
  831. local dmac=01:02:03:04:05:06
  832. RET=0
  833. tc filter add dev br0 ingress protocol all pref 1 handle 1 flower \
  834. dst_mac $dmac action drop
  835. # Packet should be flooded and locally received when there is no
  836. # matching MDB entry.
  837. $MZ $h1.10 -c 1 -p 128 -a own -b $dmac -q
  838. tc_check_packets "dev br0 ingress" 1 1
  839. check_err $? "Packet not locally received after flood"
  840. # Install a regular port group entry and expect the packet to not be
  841. # locally received.
  842. bridge mdb add dev br0 port $swp2 grp $dmac permanent vid 10
  843. $MZ $h1.10 -c 1 -p 128 -a own -b $dmac -q
  844. tc_check_packets "dev br0 ingress" 1 1
  845. check_err $? "Packet locally received after installing a regular entry"
  846. # Add a host entry and expect the packet to be locally received.
  847. bridge mdb add dev br0 port br0 grp $dmac permanent vid 10
  848. $MZ $h1.10 -c 1 -p 128 -a own -b $dmac -q
  849. tc_check_packets "dev br0 ingress" 1 2
  850. check_err $? "Packet not locally received after adding a host entry"
  851. # Remove the host entry and expect the packet to not be locally
  852. # received.
  853. bridge mdb del dev br0 port br0 grp $dmac permanent vid 10
  854. $MZ $h1.10 -c 1 -p 128 -a own -b $dmac -q
  855. tc_check_packets "dev br0 ingress" 1 2
  856. check_err $? "Packet locally received after removing a host entry"
  857. bridge mdb del dev br0 port $swp2 grp $dmac permanent vid 10
  858. tc filter del dev br0 ingress protocol all pref 1 handle 1 flower
  859. log_test "L2 host entries forwarding tests"
  860. }
  861. fwd_test_host()
  862. {
  863. # Disable multicast router on the bridge to ensure that packets are
  864. # only locally received when a matching host entry is present.
  865. ip link set dev br0 type bridge mcast_router 0
  866. fwd_test_host_ip
  867. fwd_test_host_l2
  868. ip link set dev br0 type bridge mcast_router 1
  869. }
  870. __fwd_test_port_ip()
  871. {
  872. local grp=$1; shift
  873. local dmac=$1; shift
  874. local valid_src=$1; shift
  875. local invalid_src=$1; shift
  876. local mode=$1; shift
  877. local filter_mode=$1; shift
  878. local name
  879. local eth_type
  880. local src_list
  881. RET=0
  882. if [[ $mode == "-4" ]]; then
  883. name="IPv4"
  884. eth_type="ipv4"
  885. else
  886. name="IPv6"
  887. eth_type="ipv6"
  888. fi
  889. # The valid source is the one we expect to get packets from after
  890. # adding the entry.
  891. if [[ $filter_mode == "include" ]]; then
  892. src_list=$valid_src
  893. else
  894. src_list=$invalid_src
  895. fi
  896. tc filter add dev $h2 ingress protocol 802.1q pref 1 handle 1 flower \
  897. vlan_ethtype $eth_type vlan_id 10 dst_ip $grp \
  898. src_ip $valid_src action drop
  899. tc filter add dev $h2 ingress protocol 802.1q pref 1 handle 2 flower \
  900. vlan_ethtype $eth_type vlan_id 10 dst_ip $grp \
  901. src_ip $invalid_src action drop
  902. $MZ $mode $h1.10 -a own -b $dmac -c 1 -p 128 -A $valid_src -B $grp -t udp -q
  903. tc_check_packets "dev $h2 ingress" 1 0
  904. check_err $? "Packet from valid source received on H2 before adding entry"
  905. $MZ $mode $h1.10 -a own -b $dmac -c 1 -p 128 -A $invalid_src -B $grp -t udp -q
  906. tc_check_packets "dev $h2 ingress" 2 0
  907. check_err $? "Packet from invalid source received on H2 before adding entry"
  908. bridge mdb add dev br0 port $swp2 grp $grp vid 10 \
  909. filter_mode $filter_mode source_list $src_list
  910. $MZ $mode $h1.10 -a own -b $dmac -c 1 -p 128 -A $valid_src -B $grp -t udp -q
  911. tc_check_packets "dev $h2 ingress" 1 1
  912. check_err $? "Packet from valid source not received on H2 after adding entry"
  913. $MZ $mode $h1.10 -a own -b $dmac -c 1 -p 128 -A $invalid_src -B $grp -t udp -q
  914. tc_check_packets "dev $h2 ingress" 2 0
  915. check_err $? "Packet from invalid source received on H2 after adding entry"
  916. bridge mdb replace dev br0 port $swp2 grp $grp vid 10 \
  917. filter_mode exclude
  918. $MZ $mode $h1.10 -a own -b $dmac -c 1 -p 128 -A $valid_src -B $grp -t udp -q
  919. tc_check_packets "dev $h2 ingress" 1 2
  920. check_err $? "Packet from valid source not received on H2 after allowing all sources"
  921. $MZ $mode $h1.10 -a own -b $dmac -c 1 -p 128 -A $invalid_src -B $grp -t udp -q
  922. tc_check_packets "dev $h2 ingress" 2 1
  923. check_err $? "Packet from invalid source not received on H2 after allowing all sources"
  924. bridge mdb del dev br0 port $swp2 grp $grp vid 10
  925. $MZ $mode $h1.10 -a own -b $dmac -c 1 -p 128 -A $valid_src -B $grp -t udp -q
  926. tc_check_packets "dev $h2 ingress" 1 2
  927. check_err $? "Packet from valid source received on H2 after deleting entry"
  928. $MZ $mode $h1.10 -a own -b $dmac -c 1 -p 128 -A $invalid_src -B $grp -t udp -q
  929. tc_check_packets "dev $h2 ingress" 2 1
  930. check_err $? "Packet from invalid source received on H2 after deleting entry"
  931. tc filter del dev $h2 ingress protocol 802.1q pref 1 handle 2 flower
  932. tc filter del dev $h2 ingress protocol 802.1q pref 1 handle 1 flower
  933. log_test "$name port group \"$filter_mode\" entries forwarding tests"
  934. }
  935. fwd_test_port_ip()
  936. {
  937. __fwd_test_port_ip "239.1.1.1" "01:00:5e:01:01:01" "192.0.2.1" "192.0.2.2" "-4" "exclude"
  938. __fwd_test_port_ip "ff0e::1" "33:33:00:00:00:01" "2001:db8:1::1" "2001:db8:1::2" "-6" \
  939. "exclude"
  940. __fwd_test_port_ip "239.1.1.1" "01:00:5e:01:01:01" "192.0.2.1" "192.0.2.2" "-4" "include"
  941. __fwd_test_port_ip "ff0e::1" "33:33:00:00:00:01" "2001:db8:1::1" "2001:db8:1::2" "-6" \
  942. "include"
  943. }
  944. fwd_test_port_l2()
  945. {
  946. local dmac=01:02:03:04:05:06
  947. RET=0
  948. tc filter add dev $h2 ingress protocol all pref 1 handle 1 flower \
  949. dst_mac $dmac action drop
  950. $MZ $h1.10 -c 1 -p 128 -a own -b $dmac -q
  951. tc_check_packets "dev $h2 ingress" 1 0
  952. check_err $? "Packet received on H2 before adding entry"
  953. bridge mdb add dev br0 port $swp2 grp $dmac permanent vid 10
  954. $MZ $h1.10 -c 1 -p 128 -a own -b $dmac -q
  955. tc_check_packets "dev $h2 ingress" 1 1
  956. check_err $? "Packet not received on H2 after adding entry"
  957. bridge mdb del dev br0 port $swp2 grp $dmac permanent vid 10
  958. $MZ $h1.10 -c 1 -p 128 -a own -b $dmac -q
  959. tc_check_packets "dev $h2 ingress" 1 1
  960. check_err $? "Packet received on H2 after deleting entry"
  961. tc filter del dev $h2 ingress protocol all pref 1 handle 1 flower
  962. log_test "L2 port entries forwarding tests"
  963. }
  964. fwd_test_port()
  965. {
  966. # Disable multicast flooding to ensure that packets are only forwarded
  967. # out of a port when a matching port group entry is present.
  968. bridge link set dev $swp2 mcast_flood off
  969. fwd_test_port_ip
  970. fwd_test_port_l2
  971. bridge link set dev $swp2 mcast_flood on
  972. }
  973. fwd_test()
  974. {
  975. echo
  976. log_info "# Forwarding tests"
  977. # Set the Max Response Delay to 100 centiseconds (1 second) so that the
  978. # bridge will start forwarding according to its MDB soon after a
  979. # multicast querier is enabled.
  980. ip link set dev br0 type bridge mcast_query_response_interval 100
  981. # Forwarding according to MDB entries only takes place when the bridge
  982. # detects that there is a valid querier in the network. Set the bridge
  983. # as the querier and assign it a valid IPv6 link-local address to be
  984. # used as the source address for MLD queries.
  985. ip -6 address add fe80::1/64 nodad dev br0
  986. ip link set dev br0 type bridge mcast_querier 1
  987. sleep 10
  988. fwd_test_host
  989. fwd_test_port
  990. ip link set dev br0 type bridge mcast_querier 0
  991. ip -6 address del fe80::1/64 dev br0
  992. ip link set dev br0 type bridge mcast_query_response_interval 1000
  993. }
  994. ctrl_igmpv3_is_in_test()
  995. {
  996. RET=0
  997. # Add a permanent entry and check that it is not affected by the
  998. # received IGMP packet.
  999. bridge mdb add dev br0 port $swp1 grp 239.1.1.1 permanent vid 10 \
  1000. filter_mode include source_list 192.0.2.1
  1001. # IS_IN ( 192.0.2.2 )
  1002. $MZ $h1.10 -c 1 -a own -b 01:00:5e:01:01:01 -A 192.0.2.1 -B 239.1.1.1 \
  1003. -t ip proto=2,p=$(igmpv3_is_in_get 239.1.1.1 192.0.2.2) -q
  1004. bridge mdb get dev br0 grp 239.1.1.1 src 192.0.2.2 vid 10 &> /dev/null
  1005. check_fail $? "Permanent entry affected by IGMP packet"
  1006. # Replace the permanent entry with a temporary one and check that after
  1007. # processing the IGMP packet, a new source is added to the list along
  1008. # with a new forwarding entry.
  1009. bridge mdb replace dev br0 port $swp1 grp 239.1.1.1 temp vid 10 \
  1010. filter_mode include source_list 192.0.2.1
  1011. # IS_IN ( 192.0.2.2 )
  1012. $MZ $h1.10 -a own -b 01:00:5e:01:01:01 -c 1 -A 192.0.2.1 -B 239.1.1.1 \
  1013. -t ip proto=2,p=$(igmpv3_is_in_get 239.1.1.1 192.0.2.2) -q
  1014. bridge -d mdb get dev br0 grp 239.1.1.1 vid 10 | grep -q 192.0.2.2
  1015. check_err $? "Source not add to source list"
  1016. bridge mdb get dev br0 grp 239.1.1.1 src 192.0.2.2 vid 10 &> /dev/null
  1017. check_err $? "(S, G) entry not created for new source"
  1018. bridge mdb del dev br0 port $swp1 grp 239.1.1.1 vid 10
  1019. log_test "IGMPv3 MODE_IS_INCLUDE tests"
  1020. }
  1021. ctrl_mldv2_is_in_test()
  1022. {
  1023. RET=0
  1024. # Add a permanent entry and check that it is not affected by the
  1025. # received MLD packet.
  1026. bridge mdb add dev br0 port $swp1 grp ff0e::1 permanent vid 10 \
  1027. filter_mode include source_list 2001:db8:1::1
  1028. # IS_IN ( 2001:db8:1::2 )
  1029. local p=$(mldv2_is_in_get fe80::1 ff0e::1 2001:db8:1::2)
  1030. $MZ -6 $h1.10 -a own -b 33:33:00:00:00:01 -c 1 -A fe80::1 -B ff0e::1 \
  1031. -t ip hop=1,next=0,p="$p" -q
  1032. bridge mdb get dev br0 grp ff0e::1 src 2001:db8:1::2 vid 10 &> /dev/null
  1033. check_fail $? "Permanent entry affected by MLD packet"
  1034. # Replace the permanent entry with a temporary one and check that after
  1035. # processing the MLD packet, a new source is added to the list along
  1036. # with a new forwarding entry.
  1037. bridge mdb replace dev br0 port $swp1 grp ff0e::1 temp vid 10 \
  1038. filter_mode include source_list 2001:db8:1::1
  1039. # IS_IN ( 2001:db8:1::2 )
  1040. $MZ -6 $h1.10 -a own -b 33:33:00:00:00:01 -c 1 -A fe80::1 -B ff0e::1 \
  1041. -t ip hop=1,next=0,p="$p" -q
  1042. bridge -d mdb get dev br0 grp ff0e::1 vid 10 | grep -q 2001:db8:1::2
  1043. check_err $? "Source not add to source list"
  1044. bridge mdb get dev br0 grp ff0e::1 src 2001:db8:1::2 vid 10 &> /dev/null
  1045. check_err $? "(S, G) entry not created for new source"
  1046. bridge mdb del dev br0 port $swp1 grp ff0e::1 vid 10
  1047. log_test "MLDv2 MODE_IS_INCLUDE tests"
  1048. }
  1049. ctrl_test()
  1050. {
  1051. echo
  1052. log_info "# Control packets tests"
  1053. ctrl_igmpv3_is_in_test
  1054. ctrl_mldv2_is_in_test
  1055. }
  1056. if ! bridge mdb help 2>&1 | grep -q "flush"; then
  1057. echo "SKIP: iproute2 too old, missing bridge mdb flush support"
  1058. exit $ksft_skip
  1059. fi
  1060. trap cleanup EXIT
  1061. setup_prepare
  1062. setup_wait
  1063. tests_run
  1064. exit $EXIT_STATUS