shared_network_unittest.cc 66 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722
  1. // Copyright (C) 2017 Internet Systems Consortium, Inc. ("ISC")
  2. //
  3. // This Source Code Form is subject to the terms of the Mozilla Public
  4. // License, v. 2.0. If a copy of the MPL was not distributed with this
  5. // file, You can obtain one at http://mozilla.org/MPL/2.0/.
  6. #include <config.h>
  7. #include <asiolink/io_address.h>
  8. #include <dhcp/option.h>
  9. #include <dhcp/option_int.h>
  10. #include <dhcp/option6_client_fqdn.h>
  11. #include <dhcp/tests/iface_mgr_test_config.h>
  12. #include <dhcpsrv/lease_mgr_factory.h>
  13. #include <dhcp6/tests/dhcp6_client.h>
  14. #include <dhcp6/tests/dhcp6_test_utils.h>
  15. #include <stats/stats_mgr.h>
  16. #include <boost/pointer_cast.hpp>
  17. #include <vector>
  18. using namespace isc;
  19. using namespace isc::asiolink;
  20. using namespace isc::dhcp;
  21. using namespace isc::dhcp::test;
  22. using namespace isc::stats;
  23. namespace {
  24. /// @brief Array of server configurations used throughout the tests.
  25. const char* NETWORKS_CONFIG[] = {
  26. // Configuration #0.
  27. "{"
  28. " \"interfaces-config\": {"
  29. " \"interfaces\": [ \"*\" ]"
  30. " },"
  31. " \"preferred-lifetime\": 3000,"
  32. " \"rebind-timer\": 2000, "
  33. " \"renew-timer\": 1000, "
  34. " \"shared-networks\": ["
  35. " {"
  36. " \"name\": \"frog\","
  37. " \"interface\": \"eth1\","
  38. " \"subnet6\": ["
  39. " {"
  40. " \"subnet\": \"2001:db8:1::/64\","
  41. " \"id\": 10,"
  42. " \"pools\": ["
  43. " {"
  44. " \"pool\": \"2001:db8:1::20 - 2001:db8:1::20\""
  45. " }"
  46. " ],"
  47. " \"pd-pools\": ["
  48. " {"
  49. " \"prefix\": \"4000::\","
  50. " \"prefix-len\": 96,"
  51. " \"delegated-len\": 96"
  52. " }"
  53. " ]"
  54. " },"
  55. " {"
  56. " \"subnet\": \"2001:db8:2::/64\","
  57. " \"id\": 100,"
  58. " \"pools\": ["
  59. " {"
  60. " \"pool\": \"2001:db8:2::20 - 2001:db8:2::20\""
  61. " }"
  62. " ],"
  63. " \"pd-pools\": ["
  64. " {"
  65. " \"prefix\": \"5000::\","
  66. " \"prefix-len\": 96,"
  67. " \"delegated-len\": 96"
  68. " }"
  69. " ]"
  70. " }"
  71. " ]"
  72. " }"
  73. " ],"
  74. " \"subnet6\": ["
  75. " {"
  76. " \"subnet\": \"3000::/96\","
  77. " \"id\": 1000,"
  78. " \"interface\": \"eth0\","
  79. " \"pools\": ["
  80. " {"
  81. " \"pool\": \"3000::1 - 3000::1\""
  82. " }"
  83. " ]"
  84. " }"
  85. " ]"
  86. "}",
  87. // Configuration #1.
  88. "{"
  89. " \"interfaces-config\": {"
  90. " \"interfaces\": [ \"*\" ]"
  91. " },"
  92. " \"preferred-lifetime\": 3000,"
  93. " \"rebind-timer\": 2000, "
  94. " \"renew-timer\": 1000, "
  95. " \"shared-networks\": ["
  96. " {"
  97. " \"name\": \"frog\","
  98. " \"relay\": {"
  99. " \"ip-address\": \"3001::1\""
  100. " },"
  101. " \"subnet6\": ["
  102. " {"
  103. " \"subnet\": \"2001:db8:1::/64\","
  104. " \"id\": 10,"
  105. " \"pools\": ["
  106. " {"
  107. " \"pool\": \"2001:db8:1::20 - 2001:db8:1::20\""
  108. " }"
  109. " ]"
  110. " }"
  111. " ]"
  112. " }"
  113. " ],"
  114. " \"subnet6\": ["
  115. " {"
  116. " \"subnet\": \"2001:db8:2::/64\","
  117. " \"id\": 1000,"
  118. " \"relay\": {"
  119. " \"ip-address\": \"3001::2\""
  120. " },"
  121. " \"pools\": ["
  122. " {"
  123. " \"pool\": \"2001:db8:2::20 - 2001:db8:2::20\""
  124. " }"
  125. " ]"
  126. " }"
  127. " ]"
  128. "}",
  129. // Configuration #2.
  130. "{"
  131. " \"interfaces-config\": {"
  132. " \"interfaces\": [ \"*\" ]"
  133. " },"
  134. " \"preferred-lifetime\": 3000,"
  135. " \"rebind-timer\": 2000, "
  136. " \"renew-timer\": 1000, "
  137. " \"client-classes\": ["
  138. " {"
  139. " \"name\": \"a-devices\","
  140. " \"test\": \"option[1234].hex == 0x0001\""
  141. " },"
  142. " {"
  143. " \"name\": \"b-devices\","
  144. " \"test\": \"option[1234].hex == 0x0002\""
  145. " }"
  146. " ],"
  147. " \"shared-networks\": ["
  148. " {"
  149. " \"name\": \"frog\","
  150. " \"interface\": \"eth1\","
  151. " \"subnet6\": ["
  152. " {"
  153. " \"subnet\": \"2001:db8:1::/64\","
  154. " \"id\": 10,"
  155. " \"pools\": ["
  156. " {"
  157. " \"pool\": \"2001:db8:1::20 - 2001:db8:1::20\""
  158. " }"
  159. " ],"
  160. " \"client-class\": \"a-devices\""
  161. " },"
  162. " {"
  163. " \"subnet\": \"2001:db8:2::/64\","
  164. " \"id\": 100,"
  165. " \"pools\": ["
  166. " {"
  167. " \"pool\": \"2001:db8:2::20 - 2001:db8:2::20\""
  168. " }"
  169. " ]"
  170. " }"
  171. " ]"
  172. " }"
  173. " ]"
  174. "}",
  175. // Configuration #3.
  176. "{"
  177. " \"interfaces-config\": {"
  178. " \"interfaces\": [ \"*\" ]"
  179. " },"
  180. " \"preferred-lifetime\": 3000,"
  181. " \"rebind-timer\": 2000, "
  182. " \"renew-timer\": 1000, "
  183. " \"client-classes\": ["
  184. " {"
  185. " \"name\": \"a-devices\","
  186. " \"test\": \"option[1234].hex == 0x0001\""
  187. " },"
  188. " {"
  189. " \"name\": \"b-devices\","
  190. " \"test\": \"option[1234].hex == 0x0002\""
  191. " }"
  192. " ],"
  193. " \"shared-networks\": ["
  194. " {"
  195. " \"name\": \"frog\","
  196. " \"interface\": \"eth1\","
  197. " \"subnet6\": ["
  198. " {"
  199. " \"subnet\": \"2001:db8:1::/64\","
  200. " \"id\": 10,"
  201. " \"pools\": ["
  202. " {"
  203. " \"pool\": \"2001:db8:1::20 - 2001:db8:1::20\""
  204. " }"
  205. " ],"
  206. " \"client-class\": \"a-devices\""
  207. " },"
  208. " {"
  209. " \"subnet\": \"2001:db8:2::/64\","
  210. " \"id\": 100,"
  211. " \"pools\": ["
  212. " {"
  213. " \"pool\": \"2001:db8:2::20 - 2001:db8:2::20\""
  214. " }"
  215. " ],"
  216. " \"client-class\": \"b-devices\""
  217. " }"
  218. " ]"
  219. " }"
  220. " ]"
  221. "}",
  222. // Configuration #4.
  223. "{"
  224. " \"interfaces-config\": {"
  225. " \"interfaces\": [ \"*\" ]"
  226. " },"
  227. " \"preferred-lifetime\": 3000,"
  228. " \"rebind-timer\": 2000, "
  229. " \"renew-timer\": 1000, "
  230. " \"shared-networks\": ["
  231. " {"
  232. " \"name\": \"frog\","
  233. " \"interface\": \"eth1\","
  234. " \"subnet6\": ["
  235. " {"
  236. " \"subnet\": \"2001:db8:1::/64\","
  237. " \"id\": 10,"
  238. " \"pools\": ["
  239. " {"
  240. " \"pool\": \"2001:db8:1::1 - 2001:db8:1::64\""
  241. " }"
  242. " ],"
  243. " \"pd-pools\": ["
  244. " {"
  245. " \"prefix\": \"4000::\","
  246. " \"prefix-len\": 96,"
  247. " \"delegated-len\": 96"
  248. " }"
  249. " ],"
  250. " \"reservations\": ["
  251. " {"
  252. " \"duid\": \"00:03:00:01:aa:bb:cc:dd:ee:ff\","
  253. " \"ip-addresses\": [ \"2001:db8:1::28\" ]"
  254. " }"
  255. " ]"
  256. " },"
  257. " {"
  258. " \"subnet\": \"2001:db8:2::/64\","
  259. " \"id\": 100,"
  260. " \"pools\": ["
  261. " {"
  262. " \"pool\": \"2001:db8:2::1 - 2001:db8:2::64\""
  263. " }"
  264. " ],"
  265. " \"pd-pools\": ["
  266. " {"
  267. " \"prefix\": \"5000::\","
  268. " \"prefix-len\": 96,"
  269. " \"delegated-len\": 96"
  270. " }"
  271. " ],"
  272. " \"reservations\": ["
  273. " {"
  274. " \"duid\": \"00:03:00:01:11:22:33:44:55:66\","
  275. " \"ip-addresses\": [ \"2001:db8:2::28\" ],"
  276. " \"prefixes\": [ \"1234::/64\" ]"
  277. " }"
  278. " ]"
  279. " }"
  280. " ]"
  281. " }"
  282. " ]"
  283. "}",
  284. // Configuration #5.
  285. "{"
  286. " \"interfaces-config\": {"
  287. " \"interfaces\": [ \"*\" ]"
  288. " },"
  289. " \"preferred-lifetime\": 3000,"
  290. " \"rebind-timer\": 2000, "
  291. " \"renew-timer\": 1000, "
  292. " \"shared-networks\": ["
  293. " {"
  294. " \"name\": \"frog\","
  295. " \"interface\": \"eth1\","
  296. " \"subnet6\": ["
  297. " {"
  298. " \"subnet\": \"2001:db8:1::/64\","
  299. " \"id\": 10,"
  300. " \"pools\": ["
  301. " {"
  302. " \"pool\": \"2001:db8:1::1 - 2001:db8:1::64\""
  303. " }"
  304. " ],"
  305. " \"reservations\": ["
  306. " {"
  307. " \"duid\": \"00:03:00:01:11:22:33:44:55:66\","
  308. " \"ip-addresses\": [ \"2001:db8:1::28\" ]"
  309. " }"
  310. " ]"
  311. " },"
  312. " {"
  313. " \"subnet\": \"2001:db8:2::/64\","
  314. " \"id\": 100,"
  315. " \"pools\": ["
  316. " {"
  317. " \"pool\": \"2001:db8:2::1 - 2001:db8:2::64\""
  318. " }"
  319. " ],"
  320. " \"reservations\": ["
  321. " {"
  322. " \"duid\": \"00:03:00:01:aa:bb:cc:dd:ee:ff\","
  323. " \"ip-addresses\": [ \"2001:db8:2::28\" ]"
  324. " }"
  325. " ]"
  326. " }"
  327. " ]"
  328. " }"
  329. " ]"
  330. "}",
  331. // Configuration #6.
  332. "{"
  333. " \"interfaces-config\": {"
  334. " \"interfaces\": [ \"*\" ]"
  335. " },"
  336. " \"preferred-lifetime\": 3000,"
  337. " \"rebind-timer\": 2000, "
  338. " \"renew-timer\": 1000, "
  339. " \"client-classes\": ["
  340. " {"
  341. " \"name\": \"a-devices\","
  342. " \"test\": \"option[1234].hex == 0x0001\""
  343. " }"
  344. " ],"
  345. " \"shared-networks\": ["
  346. " {"
  347. " \"name\": \"frog\","
  348. " \"interface\": \"eth1\","
  349. " \"subnet6\": ["
  350. " {"
  351. " \"subnet\": \"2001:db8:1::/64\","
  352. " \"id\": 10,"
  353. " \"pools\": ["
  354. " {"
  355. " \"pool\": \"2001:db8:1::1 - 2001:db8:1::64\""
  356. " }"
  357. " ],"
  358. " \"client-class\": \"a-devices\","
  359. " \"reservations\": ["
  360. " {"
  361. " \"duid\": \"00:03:00:01:aa:bb:cc:dd:ee:ff\","
  362. " \"ip-addresses\": [ \"2001:db8:1::28\" ]"
  363. " }"
  364. " ]"
  365. " },"
  366. " {"
  367. " \"subnet\": \"2001:db8:2::/64\","
  368. " \"id\": 100,"
  369. " \"pools\": ["
  370. " {"
  371. " \"pool\": \"2001:db8:2::16 - 2001:db8:2::16\""
  372. " }"
  373. " ]"
  374. " }"
  375. " ]"
  376. " }"
  377. " ]"
  378. "}",
  379. // Configuration #7.
  380. "{"
  381. " \"interfaces-config\": {"
  382. " \"interfaces\": [ \"*\" ]"
  383. " },"
  384. " \"preferred-lifetime\": 3000,"
  385. " \"rebind-timer\": 2000, "
  386. " \"renew-timer\": 1000, "
  387. " \"option-data\": ["
  388. " {"
  389. " \"name\": \"nis-servers\","
  390. " \"data\": \"3000::20\""
  391. " }"
  392. " ],"
  393. " \"shared-networks\": ["
  394. " {"
  395. " \"name\": \"frog\","
  396. " \"interface\": \"eth1\","
  397. " \"option-data\": ["
  398. " {"
  399. " \"name\": \"dns-servers\","
  400. " \"data\": \"3001::21\""
  401. " },"
  402. " {"
  403. " \"name\": \"nisp-servers\","
  404. " \"data\": \"3002::34\""
  405. " }"
  406. " ],"
  407. " \"subnet6\": ["
  408. " {"
  409. " \"subnet\": \"2001:db8:1::/64\","
  410. " \"id\": 10,"
  411. " \"option-data\": ["
  412. " {"
  413. " \"name\": \"sntp-servers\","
  414. " \"data\": \"4004::22\""
  415. " },"
  416. " {"
  417. " \"name\": \"nisp-servers\","
  418. " \"data\": \"3003::33\""
  419. " }"
  420. " ],"
  421. " \"pools\": ["
  422. " {"
  423. " \"pool\": \"2001:db8:1::20 - 2001:db8:1::20\""
  424. " }"
  425. " ]"
  426. " },"
  427. " {"
  428. " \"subnet\": \"2001:db8:2::/64\","
  429. " \"id\": 100,"
  430. " \"pools\": ["
  431. " {"
  432. " \"pool\": \"2001:db8:2::20 - 2001:db8:2::20\""
  433. " }"
  434. " ]"
  435. " }"
  436. " ]"
  437. " }"
  438. " ],"
  439. " \"subnet6\": ["
  440. " \{"
  441. " \"subnet\": \"3000::/96\","
  442. " \"id\": 1000,"
  443. " \"interface\": \"eth0\","
  444. " \"option-data\": ["
  445. " {"
  446. " \"name\": \"nisp-servers\","
  447. " \"data\": \"4000::5\""
  448. " }"
  449. " ],"
  450. " \"pools\": ["
  451. " {"
  452. " \"pool\": \"3000::1 - 3000::1\""
  453. " }"
  454. " ]"
  455. " }"
  456. " ]"
  457. "}",
  458. // Configuration #8.
  459. "{"
  460. " \"interfaces-config\": {"
  461. " \"interfaces\": [ \"*\" ]"
  462. " },"
  463. " \"preferred-lifetime\": 3000,"
  464. " \"rebind-timer\": 2000, "
  465. " \"renew-timer\": 1000, "
  466. " \"shared-networks\": ["
  467. " {"
  468. " \"name\": \"frog\","
  469. " \"interface\": \"eth1\","
  470. " \"subnet6\": ["
  471. " {"
  472. " \"subnet\": \"2001:db8:1::/64\","
  473. " \"id\": 10,"
  474. " \"pools\": ["
  475. " {"
  476. " \"pool\": \"2001:db8:1::20 - 2001:db8:1::20\""
  477. " }"
  478. " ]"
  479. " },"
  480. " {"
  481. " \"subnet\": \"2001:db8:2::/64\","
  482. " \"id\": 100,"
  483. " \"pools\": ["
  484. " {"
  485. " \"pool\": \"2001:db8:2::20 - 2001:db8:2::20\""
  486. " }"
  487. " ]"
  488. " }"
  489. " ]"
  490. " },"
  491. " {"
  492. " \"name\": \"dog\","
  493. " \"interface\": \"eth0\","
  494. " \"subnet6\": ["
  495. " {"
  496. " \"subnet\": \"2001:db8:3::/64\","
  497. " \"id\": 1000,"
  498. " \"pools\": ["
  499. " {"
  500. " \"pool\": \"2001:db8:3::20 - 2001:db8:3::20\""
  501. " }"
  502. " ]"
  503. " },"
  504. " {"
  505. " \"subnet\": \"2001:db8:4::/64\","
  506. " \"id\": 10000,"
  507. " \"pools\": ["
  508. " {"
  509. " \"pool\": \"2001:db8:4::20 - 2001:db8:4::20\""
  510. " }"
  511. " ]"
  512. " }"
  513. " ]"
  514. " }"
  515. " ]"
  516. "}",
  517. // Configuration #9.
  518. "{"
  519. " \"interfaces-config\": {"
  520. " \"interfaces\": [ \"*\" ]"
  521. " },"
  522. " \"preferred-lifetime\": 3000,"
  523. " \"rebind-timer\": 2000, "
  524. " \"renew-timer\": 1000, "
  525. " \"shared-networks\": ["
  526. " {"
  527. " \"name\": \"frog\","
  528. " \"relay\": {"
  529. " \"ip-address\": \"3000::1\""
  530. " },"
  531. " \"subnet6\": ["
  532. " {"
  533. " \"subnet\": \"2001:db8:1::/64\","
  534. " \"id\": 10,"
  535. " \"pools\": ["
  536. " {"
  537. " \"pool\": \"2001:db8:1::20 - 2001:db8:1::20\""
  538. " }"
  539. " ]"
  540. " },"
  541. " {"
  542. " \"subnet\": \"2001:db8:2::/64\","
  543. " \"id\": 100,"
  544. " \"pools\": ["
  545. " {"
  546. " \"pool\": \"2001:db8:2::20 - 2001:db8:2::20\""
  547. " }"
  548. " ]"
  549. " }"
  550. " ]"
  551. " },"
  552. " {"
  553. " \"name\": \"dog\","
  554. " \"relay\": {"
  555. " \"ip-address\": \"3000::2\""
  556. " },"
  557. " \"subnet6\": ["
  558. " {"
  559. " \"subnet\": \"2001:db8:3::/64\","
  560. " \"id\": 1000,"
  561. " \"pools\": ["
  562. " {"
  563. " \"pool\": \"2001:db8:3::20 - 2001:db8:3::20\""
  564. " }"
  565. " ]"
  566. " },"
  567. " {"
  568. " \"subnet\": \"2001:db8:4::/64\","
  569. " \"id\": 10000,"
  570. " \"pools\": ["
  571. " {"
  572. " \"pool\": \"2001:db8:4::20 - 2001:db8:4::20\""
  573. " }"
  574. " ]"
  575. " }"
  576. " ]"
  577. " }"
  578. " ]"
  579. "}",
  580. // Configuration #10.
  581. "{"
  582. " \"interfaces-config\": {"
  583. " \"interfaces\": [ \"*\" ]"
  584. " },"
  585. " \"preferred-lifetime\": 3000,"
  586. " \"rebind-timer\": 2000, "
  587. " \"renew-timer\": 1000, "
  588. " \"client-classes\": ["
  589. " {"
  590. " \"name\": \"class-with-dns-servers\","
  591. " \"option-data\": ["
  592. " {"
  593. " \"name\": \"dns-servers\","
  594. " \"data\": \"2001:db8:1::50\""
  595. " }"
  596. " ]"
  597. " }"
  598. " ],"
  599. " \"shared-networks\": ["
  600. " {"
  601. " \"name\": \"frog\","
  602. " \"interface\": \"eth1\","
  603. " \"subnet6\": ["
  604. " {"
  605. " \"subnet\": \"2001:db8:1::/64\","
  606. " \"id\": 10,"
  607. " \"pools\": ["
  608. " {"
  609. " \"pool\": \"2001:db8:1::20 - 2001:db8:1::20\""
  610. " }"
  611. " ]"
  612. " },"
  613. " {"
  614. " \"subnet\": \"2001:db8:2::/64\","
  615. " \"id\": 100,"
  616. " \"pools\": ["
  617. " {"
  618. " \"pool\": \"2001:db8:2::20 - 2001:db8:2::30\""
  619. " }"
  620. " ],"
  621. " \"reservations\": ["
  622. " {"
  623. " \"duid\": \"00:03:00:01:11:22:33:44:55:66\","
  624. " \"ip-addresses\": [ \"2001:db8:2::20\" ],"
  625. " \"hostname\": \"test.example.org\","
  626. " \"client-classes\": [ \"class-with-dns-servers\" ]"
  627. " }"
  628. " ]"
  629. " }"
  630. " ]"
  631. " }"
  632. " ]"
  633. "}",
  634. // Configuration #11.
  635. "{"
  636. " \"interfaces-config\": {"
  637. " \"interfaces\": [ \"*\" ]"
  638. " },"
  639. " \"preferred-lifetime\": 3000,"
  640. " \"rebind-timer\": 2000, "
  641. " \"renew-timer\": 1000, "
  642. " \"client-classes\": ["
  643. " {"
  644. " \"name\": \"a-devices\","
  645. " \"test\": \"option[1234].hex == 0x0001\""
  646. " },"
  647. " {"
  648. " \"name\": \"b-devices\","
  649. " \"test\": \"option[1234].hex == 0x0002\""
  650. " }"
  651. " ],"
  652. " \"shared-networks\": ["
  653. " {"
  654. " \"name\": \"frog\","
  655. " \"interface\": \"eth1\","
  656. " \"client-class\": \"a-devices\","
  657. " \"subnet6\": ["
  658. " {"
  659. " \"subnet\": \"2001:db8:1::/64\","
  660. " \"id\": 10,"
  661. " \"pools\": ["
  662. " {"
  663. " \"pool\": \"2001:db8:1::20 - 2001:db8:1::20\""
  664. " }"
  665. " ]"
  666. " }"
  667. " ]"
  668. " },"
  669. " {"
  670. " \"name\": \"dog\","
  671. " \"interface\": \"eth1\","
  672. " \"client-class\": \"b-devices\","
  673. " \"subnet6\": ["
  674. " {"
  675. " \"subnet\": \"2001:db8:2::/64\","
  676. " \"id\": 1000,"
  677. " \"pools\": ["
  678. " {"
  679. " \"pool\": \"2001:db8:2::20 - 2001:db8:2::20\""
  680. " }"
  681. " ]"
  682. " }"
  683. " ]"
  684. " }"
  685. " ]"
  686. "}",
  687. // Configuration #12.
  688. "{"
  689. " \"interfaces-config\": {"
  690. " \"interfaces\": [ \"*\" ]"
  691. " },"
  692. " \"preferred-lifetime\": 3000,"
  693. " \"rebind-timer\": 2000, "
  694. " \"renew-timer\": 1000, "
  695. " \"client-classes\": ["
  696. " {"
  697. " \"name\": \"b-devices\","
  698. " \"test\": \"option[1234].hex == 0x0002\""
  699. " }"
  700. " ],"
  701. " \"shared-networks\": ["
  702. " {"
  703. " \"name\": \"frog\","
  704. " \"interface\": \"eth1\","
  705. " \"subnet6\": ["
  706. " {"
  707. " \"subnet\": \"2001:db8:1::/64\","
  708. " \"id\": 10,"
  709. " \"pools\": ["
  710. " {"
  711. " \"pool\": \"2001:db8:1::20 - 2001:db8:1::20\""
  712. " }"
  713. " ]"
  714. " },"
  715. " {"
  716. " \"subnet\": \"2001:db8:2::/64\","
  717. " \"id\": 100,"
  718. " \"pools\": ["
  719. " {"
  720. " \"pool\": \"2001:db8:2::20 - 2001:db8:2::20\""
  721. " }"
  722. " ],"
  723. " \"client-class\": \"b-devices\""
  724. " }"
  725. " ]"
  726. " }"
  727. " ]"
  728. "}",
  729. // Configuration #13.
  730. "{"
  731. " \"interfaces-config\": {"
  732. " \"interfaces\": [ \"*\" ]"
  733. " },"
  734. " \"preferred-lifetime\": 3000,"
  735. " \"rebind-timer\": 2000, "
  736. " \"renew-timer\": 1000, "
  737. " \"shared-networks\": ["
  738. " {"
  739. " \"name\": \"frog\","
  740. " \"subnet6\": ["
  741. " {"
  742. " \"subnet\": \"2001:db8:1::/64\","
  743. " \"id\": 10,"
  744. " \"relay\": {"
  745. " \"ip-address\": \"3001::1\""
  746. " },"
  747. " \"pools\": ["
  748. " {"
  749. " \"pool\": \"2001:db8:1::20 - 2001:db8:1::20\""
  750. " }"
  751. " ]"
  752. " },"
  753. " {"
  754. " \"subnet\": \"2001:db8:2::/64\","
  755. " \"id\": 100,"
  756. " \"relay\": {"
  757. " \"ip-address\": \"3001::1\""
  758. " },"
  759. " \"pools\": ["
  760. " {"
  761. " \"pool\": \"2001:db8:2::20 - 2001:db8:2::20\""
  762. " }"
  763. " ]"
  764. " }"
  765. " ]"
  766. " }"
  767. " ],"
  768. " \"subnet6\": ["
  769. " {"
  770. " \"subnet\": \"2001:db8:3::/64\","
  771. " \"id\": 1000,"
  772. " \"relay\": {"
  773. " \"ip-address\": \"3001::2\""
  774. " },"
  775. " \"pools\": ["
  776. " {"
  777. " \"pool\": \"2001:db8:3::20 - 2001:db8:3::20\""
  778. " }"
  779. " ]"
  780. " }"
  781. " ]"
  782. "}",
  783. // Configuration #14.
  784. "{"
  785. " \"interfaces-config\": {"
  786. " \"interfaces\": [ \"*\" ]"
  787. " },"
  788. " \"preferred-lifetime\": 3000,"
  789. " \"rebind-timer\": 2000, "
  790. " \"renew-timer\": 1000, "
  791. " \"shared-networks\": ["
  792. " {"
  793. " \"name\": \"frog\","
  794. " \"interface-id\": \"vlan10\","
  795. " \"subnet6\": ["
  796. " {"
  797. " \"subnet\": \"2001:db8:1::/64\","
  798. " \"id\": 10,"
  799. " \"pools\": ["
  800. " {"
  801. " \"pool\": \"2001:db8:1::20 - 2001:db8:1::20\""
  802. " }"
  803. " ]"
  804. " }"
  805. " ]"
  806. " }"
  807. " ],"
  808. " \"subnet6\": ["
  809. " {"
  810. " \"subnet\": \"2001:db8:2::/64\","
  811. " \"id\": 1000,"
  812. " \"interface-id\": \"vlan1000\","
  813. " \"pools\": ["
  814. " {"
  815. " \"pool\": \"2001:db8:2::20 - 2001:db8:2::20\""
  816. " }"
  817. " ]"
  818. " }"
  819. " ]"
  820. "}",
  821. // Configuration #15.
  822. "{"
  823. " \"interfaces-config\": {"
  824. " \"interfaces\": [ \"*\" ]"
  825. " },"
  826. " \"preferred-lifetime\": 3000,"
  827. " \"rebind-timer\": 2000, "
  828. " \"renew-timer\": 1000, "
  829. " \"shared-networks\": ["
  830. " {"
  831. " \"name\": \"frog\","
  832. " \"subnet6\": ["
  833. " {"
  834. " \"subnet\": \"2001:db8:1::/64\","
  835. " \"id\": 10,"
  836. " \"interface-id\": \"vlan10\","
  837. " \"pools\": ["
  838. " {"
  839. " \"pool\": \"2001:db8:1::20 - 2001:db8:1::20\""
  840. " }"
  841. " ]"
  842. " },"
  843. " {"
  844. " \"subnet\": \"2001:db8:2::/64\","
  845. " \"id\": 10,"
  846. " \"interface-id\": \"vlan10\","
  847. " \"pools\": ["
  848. " {"
  849. " \"pool\": \"2001:db8:2::20 - 2001:db8:2::20\""
  850. " }"
  851. " ]"
  852. " }"
  853. " ]"
  854. " }"
  855. " ],"
  856. " \"subnet6\": ["
  857. " {"
  858. " \"subnet\": \"2001:db8:2::/64\","
  859. " \"id\": 1000,"
  860. " \"interface-id\": \"vlan1000\","
  861. " \"pools\": ["
  862. " {"
  863. " \"pool\": \"2001:db8:2::20 - 2001:db8:2::20\""
  864. " }"
  865. " ]"
  866. " }"
  867. " ]"
  868. "}"
  869. };
  870. /// @Brief Test fixture class for DHCPv6 server using shared networks.
  871. class Dhcpv6SharedNetworkTest : public Dhcpv6SrvTest {
  872. public:
  873. /// @brief Indicates how test functions should check presence of a lease on
  874. /// the server.
  875. enum class LeaseOnServer{
  876. MUST_EXIST,
  877. MUST_NOT_EXIST,
  878. };
  879. /// @brief Constructor.
  880. Dhcpv6SharedNetworkTest()
  881. : Dhcpv6SrvTest(),
  882. iface_mgr_test_config_(true) {
  883. IfaceMgr::instance().openSockets6();
  884. StatsMgr::instance().removeAll();
  885. }
  886. /// @brief Conducts 4 packets exchanges for a client
  887. ///
  888. /// @param client this client will conduct the exchange
  889. /// @param exp_addr expected IPv6 address to be assigned
  890. /// @param iaid the iaid to be used by a client
  891. /// @param hint hint to be sent (if empty, no hint will be sent)
  892. void
  893. doSARR(Dhcp6Client& client, std::string exp_addr, uint32_t iaid,
  894. std::string hint = "") {
  895. if (hint.empty()) {
  896. ASSERT_NO_THROW(client.requestAddress(iaid, IOAddress("::")));
  897. } else {
  898. ASSERT_NO_THROW(client.requestAddress(iaid, IOAddress(hint)));
  899. }
  900. ASSERT_NO_THROW(client.doSARR());
  901. ASSERT_TRUE(hasLeaseForAddress(client, IOAddress(exp_addr)));
  902. }
  903. /// @brief Check if client has a lease for the specified address.
  904. ///
  905. /// Apart from checking whether the client has got the lease it also
  906. /// checks whether this lease is stored in the lease database.
  907. ///
  908. /// @param client Reference to the client.
  909. /// @param address Leased address.
  910. /// @param lease_on_server Specify whether the lease should be also present or
  911. /// absent in the lease database.
  912. ///
  913. /// @return true if the lease for the client has been found both in the
  914. /// database and in the server's response.
  915. bool hasLeaseForAddress(Dhcp6Client& client, const IOAddress& address,
  916. const LeaseOnServer& lease_on_server = LeaseOnServer::MUST_EXIST) {
  917. Lease6Ptr lease = LeaseMgrFactory::instance().getLease6(Lease::TYPE_NA, address);
  918. return ((((lease_on_server == LeaseOnServer::MUST_EXIST) && lease) ||
  919. ((lease_on_server == LeaseOnServer::MUST_NOT_EXIST) && !lease)) &&
  920. client.hasLeaseForAddress(address));
  921. }
  922. /// @brief Check if client has a lease for the specified prefix.
  923. ///
  924. /// Apart from checking whether the client has got the lease it also
  925. /// checks whether this lease is stored in the lease database.
  926. ///
  927. /// @param client Reference to the client.
  928. /// @param prefix Leased prefix.
  929. /// @param prefix_len Leased prefix length.
  930. /// @param lease_on_server Specify whether the lease should be also present or
  931. /// absent in the lease database.
  932. ///
  933. /// @return true if the lease for the client has been found both in the
  934. /// database and in the server's response.
  935. bool hasLeaseForPrefix(Dhcp6Client& client, const IOAddress& prefix,
  936. const uint8_t prefix_len, const IAID& iaid,
  937. const LeaseOnServer& lease_on_server = LeaseOnServer::MUST_EXIST) {
  938. Lease6Ptr lease = LeaseMgrFactory::instance().getLease6(Lease::TYPE_PD, prefix);
  939. return ((((lease_on_server == LeaseOnServer::MUST_EXIST) && lease &&
  940. (lease->prefixlen_ = prefix_len) && (lease->iaid_ == iaid)) ||
  941. ((lease_on_server == LeaseOnServer::MUST_NOT_EXIST) && !lease)) &&
  942. client.hasLeaseForPrefix(prefix, prefix_len, iaid));
  943. }
  944. /// @brief Check if client has a lease belonging to address range.
  945. ///
  946. /// Apart from checking whether the client has got the lease it also
  947. /// checks whether this lease is stored in the lease database.
  948. ///
  949. /// @param client Reference to the client.
  950. /// @param first Lower bound of the address range.
  951. /// @param last Upper bound of the address range.
  952. /// @param lease_on_server Specify whether the lease should be also present or
  953. /// absent in the lease database.
  954. bool hasLeaseForAddressRange(Dhcp6Client& client, const IOAddress& first, const IOAddress& last,
  955. const LeaseOnServer& lease_on_server = LeaseOnServer::MUST_EXIST) {
  956. std::vector<Lease6> leases = client.getLeasesByAddressRange(first, last);
  957. for (auto lease_it = leases.cbegin(); lease_it != leases.cend(); ++lease_it) {
  958. // Take into account only valid leases.
  959. if (lease_it->valid_lft_ == 0) {
  960. continue;
  961. }
  962. Lease6Ptr lease = LeaseMgrFactory::instance().getLease6(Lease::TYPE_NA, lease_it->addr_);
  963. if ((lease && (lease_on_server == LeaseOnServer::MUST_NOT_EXIST)) ||
  964. (!lease && (lease_on_server == LeaseOnServer::MUST_EXIST))) {
  965. return (false);
  966. }
  967. }
  968. return (!leases.empty());
  969. }
  970. /// @brief Check if client has a lease belonging to a prefix pool.
  971. ///
  972. /// Apart from checking whether the client has got the lease it also
  973. /// checks whether this lease is stored in the lease database.
  974. ///
  975. /// @param client Reference to the client.
  976. /// @param prefix Pool prefix.
  977. /// @param prefix_len Prefix length.
  978. /// @param delegated_len Delegated prefix length.
  979. /// @param lease_on_server Specify whether the lease should be also present or
  980. /// absent in the lease database.
  981. ///
  982. /// @return true if client has a lease belonging to specified pool,
  983. /// false otherwise.
  984. bool hasLeaseForPrefixPool(Dhcp6Client& client, const asiolink::IOAddress& prefix,
  985. const uint8_t prefix_len, const uint8_t delegated_len,
  986. const LeaseOnServer& lease_on_server = LeaseOnServer::MUST_EXIST) {
  987. std::vector<Lease6> leases = client.getLeasesByPrefixPool(prefix, prefix_len, delegated_len);
  988. for (auto lease_it = leases.cbegin(); lease_it != leases.cend(); ++lease_it) {
  989. // Take into account only valid leases.
  990. if (lease_it->valid_lft_ == 0) {
  991. continue;
  992. }
  993. Lease6Ptr lease = LeaseMgrFactory::instance().getLease6(Lease::TYPE_PD, lease_it->addr_);
  994. if ((lease && (lease->prefixlen_ == lease->prefixlen_) &&
  995. (lease_on_server == LeaseOnServer::MUST_NOT_EXIST)) ||
  996. (!lease && (lease_on_server == LeaseOnServer::MUST_EXIST))) {
  997. return (false);
  998. }
  999. }
  1000. return (!leases.empty());
  1001. }
  1002. /// @brief Destructor.
  1003. virtual ~Dhcpv6SharedNetworkTest() {
  1004. StatsMgr::instance().removeAll();
  1005. }
  1006. /// @brief Interface Manager's fake configuration control.
  1007. IfaceMgrTestConfig iface_mgr_test_config_;
  1008. };
  1009. // Running out of addresses within a subnet in a shared network.
  1010. TEST_F(Dhcpv6SharedNetworkTest, addressPoolInSharedNetworkShortage) {
  1011. // Create client #1.
  1012. Dhcp6Client client1;
  1013. client1.setInterface("eth1");
  1014. // Configure the server with one shared network including two subnets and
  1015. // one subnet outside of the shared network.
  1016. ASSERT_NO_FATAL_FAILURE(configure(NETWORKS_CONFIG[0], *client1.getServer()));
  1017. // Client #1 requests an address in first subnet within a shared network.
  1018. ASSERT_NO_THROW(client1.requestAddress(0xabca0, IOAddress("2001:db8:1::20")));
  1019. ASSERT_NO_THROW(client1.doSARR());
  1020. ASSERT_TRUE(hasLeaseForAddress(client1, IOAddress("2001:db8:1::20")));
  1021. // Client #2 The second client will request a lease and should be assigned
  1022. // an address from the second subnet.
  1023. Dhcp6Client client2(client1.getServer());
  1024. client2.setInterface("eth1");
  1025. ASSERT_NO_THROW(client2.requestAddress(0xabca0));
  1026. ASSERT_NO_THROW(client2.doSARR());
  1027. ASSERT_TRUE(hasLeaseForAddress(client2, IOAddress("2001:db8:2::20")));
  1028. // Cient #3. It sends Solicit which should result in NoAddrsAvail status
  1029. // code because all addresses available for this link have been assigned.
  1030. Dhcp6Client client3(client1.getServer());
  1031. client3.setInterface("eth1");
  1032. ASSERT_NO_THROW(client3.requestAddress(0xabca0));
  1033. ASSERT_NO_THROW(client3.doSolicit(true));
  1034. EXPECT_EQ(0, client3.getLeaseNum());
  1035. // Client #3 should be assigned an address if subnet 3 is selected for it.
  1036. client3.setInterface("eth0");
  1037. ASSERT_NO_THROW(client3.doSolicit(true));
  1038. EXPECT_EQ(1, client3.getLeaseNum());
  1039. // Client #1 should be able to renew its lease.
  1040. ASSERT_NO_THROW(client1.doRenew());
  1041. EXPECT_EQ(1, client1.getLeaseNum());
  1042. EXPECT_TRUE(hasLeaseForAddress(client1, IOAddress("2001:db8:1::20")));
  1043. // Client #2 should be able to renew its lease too.
  1044. ASSERT_NO_THROW(client2.doRenew());
  1045. EXPECT_EQ(1, client2.getLeaseNum());
  1046. EXPECT_TRUE(hasLeaseForAddress(client2, IOAddress("2001:db8:2::20")));
  1047. }
  1048. // Shared network is selected based on relay link address.
  1049. TEST_F(Dhcpv6SharedNetworkTest, sharedNetworkSelectedByRelay) {
  1050. // Create client #1. This is a relayed client which is using relay address
  1051. // matching configured shared network.
  1052. Dhcp6Client client1;
  1053. client1.useRelay(true, IOAddress("3001::1"));
  1054. // Configure the server with one shared network and one subnet outside of the
  1055. // shared network.
  1056. ASSERT_NO_FATAL_FAILURE(configure(NETWORKS_CONFIG[1], *client1.getServer()));
  1057. // Client #1 should be assigned an address from shared network.
  1058. ASSERT_NO_THROW(client1.requestAddress(0xabca0));
  1059. ASSERT_NO_THROW(client1.doSARR());
  1060. ASSERT_TRUE(hasLeaseForAddress(client1, IOAddress("2001:db8:1::20")));
  1061. // Create client #2. This is a relayed client which is using relay
  1062. // address matching subnet outside of the shared network.
  1063. Dhcp6Client client2(client1.getServer());
  1064. client2.useRelay(true, IOAddress("3001::2"));
  1065. ASSERT_NO_THROW(client2.requestAddress(0xabca0));
  1066. ASSERT_NO_THROW(client2.doSARR());
  1067. ASSERT_TRUE(hasLeaseForAddress(client2, IOAddress("2001:db8:2::20")));
  1068. }
  1069. // Providing a hint for any address belonging to a shared network.
  1070. TEST_F(Dhcpv6SharedNetworkTest, hintWithinSharedNetwork) {
  1071. // Create client #1.
  1072. Dhcp6Client client;
  1073. client.setInterface("eth1");
  1074. // Configure the server with one shared network including two subnets and
  1075. // one subnet outside of the shared network.
  1076. ASSERT_NO_FATAL_FAILURE(configure(NETWORKS_CONFIG[0], *client.getServer()));
  1077. // Provide a hint to an existing address within first subnet. This address
  1078. // should be offered out of this subnet.
  1079. ASSERT_NO_THROW(client.requestAddress(0xabca, IOAddress("2001:db8:1::20")));
  1080. ASSERT_NO_THROW(client.doSolicit(true));
  1081. ASSERT_TRUE(hasLeaseForAddress(client, IOAddress("2001:db8:1::20"),
  1082. LeaseOnServer::MUST_NOT_EXIST));
  1083. // Similarly, we should be offerred an address from another subnet within
  1084. // the same shared network when we ask for it.
  1085. client.clearRequestedIAs();
  1086. ASSERT_NO_THROW(client.requestAddress(0xabca, IOAddress("2001:db8:2::20")));
  1087. ASSERT_NO_THROW(client.doSolicit(true));
  1088. ASSERT_TRUE(hasLeaseForAddress(client, IOAddress("2001:db8:2::20"),
  1089. LeaseOnServer::MUST_NOT_EXIST));
  1090. // Asking for an address that is not in address pool should result in getting
  1091. // an address from one of the subnets, but generally hard to tell from which one.
  1092. client.clearRequestedIAs();
  1093. ASSERT_NO_THROW(client.requestAddress(0xabca, IOAddress("3002::123")));
  1094. ASSERT_NO_THROW(client.doSolicit(true));
  1095. std::vector<Lease6> leases = client.getLeasesByType(Lease::TYPE_NA);
  1096. ASSERT_EQ(1, leases.size());
  1097. if (!hasLeaseForAddress(client, IOAddress("2001:db8:1::20"),
  1098. LeaseOnServer::MUST_NOT_EXIST) &&
  1099. !hasLeaseForAddress(client, IOAddress("2001:db8:2::20"),
  1100. LeaseOnServer::MUST_NOT_EXIST)) {
  1101. ADD_FAILURE() << "Unexpected address advertised by the server " << leases.at(0).addr_;
  1102. }
  1103. }
  1104. // Shared network is selected based on the client class specified.
  1105. TEST_F(Dhcpv6SharedNetworkTest, subnetInSharedNetworkSelectedByClass) {
  1106. // Create client #1.
  1107. Dhcp6Client client1;
  1108. client1.setInterface("eth1");
  1109. // Configure the server with one shared network including two subnets and
  1110. // one subnet outside of the shared network.
  1111. ASSERT_NO_FATAL_FAILURE(configure(NETWORKS_CONFIG[2], *client1.getServer()));
  1112. // Client #1 requests an address in the restricted subnet but can't be assigned
  1113. // this address because the client doesn't belong to a certain class.
  1114. ASSERT_NO_THROW(client1.requestAddress(0xabca, IOAddress("2001:db8:1::20")));
  1115. ASSERT_NO_THROW(client1.doSARR());
  1116. ASSERT_TRUE(hasLeaseForAddress(client1, IOAddress("2001:db8:2::20")));
  1117. // Release the lease that the client has got, because we'll need this address
  1118. // further in the test.
  1119. client1.doRelease();
  1120. // Add option 1234 which would cause the client to be classified as "a-devices".
  1121. OptionPtr option1234(new OptionUint16(Option::V6, 1234, 0x0001));
  1122. client1.addExtraOption(option1234);
  1123. // This time, the allocation of the address provided as hint should be successful.
  1124. ASSERT_NO_THROW(client1.doSARR());
  1125. ASSERT_TRUE(hasLeaseForAddress(client1, IOAddress("2001:db8:1::20")));
  1126. // Client 2 should be assigned an address from the unrestricted subnet.
  1127. Dhcp6Client client2(client1.getServer());
  1128. client2.setInterface("eth1");
  1129. ASSERT_NO_THROW(client2.requestAddress(0xabca0));
  1130. ASSERT_NO_THROW(client2.doSARR());
  1131. ASSERT_TRUE(hasLeaseForAddress(client2, IOAddress("2001:db8:2::20")));
  1132. // Now, let's reconfigure the server to also apply restrictions on the
  1133. // subnet to which client2 now belongs.
  1134. ASSERT_NO_FATAL_FAILURE(configure(NETWORKS_CONFIG[3], *client1.getServer()));
  1135. ASSERT_NO_THROW(client2.doRenew());
  1136. EXPECT_EQ(0, client2.getLeaseNum());
  1137. // If we add option 1234 with a value matching this class, the lease should
  1138. // get renewed.
  1139. OptionPtr option1234_bis(new OptionUint16(Option::V6, 1234, 0x0002));
  1140. client2.addExtraOption(option1234_bis);
  1141. ASSERT_NO_THROW(client2.doRenew());
  1142. EXPECT_EQ(1, client2.getLeaseNum());
  1143. }
  1144. // IPv6 address reservation exists in one of the subnets within shared network.
  1145. TEST_F(Dhcpv6SharedNetworkTest, reservationInSharedNetwork) {
  1146. // Create client #1. Explicitly set client's DUID to the one that has a
  1147. // reservation in the second subnet within shared network.
  1148. Dhcp6Client client1;
  1149. client1.setInterface("eth1");
  1150. client1.setDUID("00:03:00:01:11:22:33:44:55:66");
  1151. // Create server configuration with a shared network including two subnets. There
  1152. // is an IP address reservation in each subnet for two respective clients.
  1153. ASSERT_NO_FATAL_FAILURE(configure(NETWORKS_CONFIG[4], *client1.getServer()));
  1154. // Client #1 should get his reserved address from the second subnet.
  1155. ASSERT_NO_THROW(client1.requestAddress(0xabca, IOAddress("2001:db8:1::20")));
  1156. ASSERT_NO_THROW(client1.doSARR());
  1157. ASSERT_TRUE(hasLeaseForAddress(client1, IOAddress("2001:db8:2::28")));
  1158. // Create client #2.
  1159. Dhcp6Client client2;
  1160. client2.setInterface("eth1");
  1161. client2.setDUID("00:03:00:01:aa:bb:cc:dd:ee:ff");
  1162. // Client #2 should get its reserved address from the first subnet.
  1163. ASSERT_NO_THROW(client2.requestAddress(0xabca, IOAddress("2001:db8:1::30")));
  1164. ASSERT_NO_THROW(client2.doSARR());
  1165. ASSERT_TRUE(hasLeaseForAddress(client2, IOAddress("2001:db8:1::28")));
  1166. // Reconfigure the server. Now, the first client get's second client's
  1167. // reservation and vice versa.
  1168. ASSERT_NO_FATAL_FAILURE(configure(NETWORKS_CONFIG[5], *client1.getServer()));
  1169. // The first client is trying to renew the lease but should get a different lease
  1170. // because its lease is now reserved for some other client. The client won't be
  1171. // assigned a lease for which it has a reservation because another client holds
  1172. // this lease.
  1173. ASSERT_NO_THROW(client1.doRenew());
  1174. ASSERT_TRUE(client1.hasLeaseWithZeroLifetimeForAddress(IOAddress("2001:db8:2::28")));
  1175. ASSERT_FALSE(hasLeaseForAddress(client1, IOAddress("2001:db8:1::28")));
  1176. // The client should be allocated a lease from one of the dynamic pools.
  1177. if (!hasLeaseForAddressRange(client1, IOAddress("2001:db8:2::1"), IOAddress("2001:db8:2::64")) &&
  1178. !hasLeaseForAddressRange(client1, IOAddress("2001:db8:1::1"), IOAddress("2001:db8:1::64"))) {
  1179. ADD_FAILURE() << "unexpected lease allocated for renewing client";
  1180. }
  1181. // Client #2 is now renewing its lease and should get its newly reserved address.
  1182. ASSERT_NO_THROW(client2.doRenew());
  1183. ASSERT_TRUE(client2.hasLeaseWithZeroLifetimeForAddress(IOAddress("2001:db8:1::28")));
  1184. ASSERT_TRUE(hasLeaseForAddress(client2, IOAddress("2001:db8:2::28")));
  1185. // Same for client #1.
  1186. ASSERT_NO_THROW(client1.doRenew());
  1187. ASSERT_TRUE(hasLeaseForAddress(client1, IOAddress("2001:db8:1::28")));
  1188. }
  1189. // Reserved address can't be assigned as long as access to a subnet is
  1190. // restricted by classification.
  1191. TEST_F(Dhcpv6SharedNetworkTest, reservationAccessRestrictedByClass) {
  1192. // Create client #1. Explicitly set client's DUID to the one that has a
  1193. // reservation in the firstsubnet within shared network.
  1194. Dhcp6Client client;
  1195. client.setInterface("eth1");
  1196. client.setDUID("00:03:00:01:aa:bb:cc:dd:ee:ff");
  1197. // Create server configuration with a shared network including two subnets. Access to
  1198. // one of the subnets is restricted by client classification.
  1199. ASSERT_NO_FATAL_FAILURE(configure(NETWORKS_CONFIG[6], *client.getServer()));
  1200. // Assigned address should be allocated from the second subnet, because the
  1201. // client doesn't belong to the "a-devices" class.
  1202. ASSERT_NO_THROW(client.requestAddress(0xabca));
  1203. ASSERT_NO_THROW(client.doSARR());
  1204. ASSERT_TRUE(hasLeaseForAddress(client, IOAddress("2001:db8:2::16")));
  1205. // Add option 1234 which would cause the client to be classified as "a-devices".
  1206. OptionPtr option1234(new OptionUint16(Option::V6, 1234, 0x0001));
  1207. client.addExtraOption(option1234);
  1208. // The client should now be assigned the reserved address from the first subnet.
  1209. ASSERT_NO_THROW(client.doRenew());
  1210. ASSERT_TRUE(client.hasLeaseWithZeroLifetimeForAddress(IOAddress("2001:db8:2::16")));
  1211. ASSERT_TRUE(hasLeaseForAddress(client, IOAddress("2001:db8:1::28")));
  1212. }
  1213. // Subnet in which the client is renewing an address is restricted by classification.
  1214. TEST_F(Dhcpv6SharedNetworkTest, renewalRestrictedByClass) {
  1215. // Create client.
  1216. Dhcp6Client client;
  1217. client.setInterface("eth1");
  1218. // Create server configuration with a shared network including two subnets. Access to
  1219. // the second subnet is restricted by client classification.
  1220. ASSERT_NO_FATAL_FAILURE(configure(NETWORKS_CONFIG[12], *client.getServer()));
  1221. // Add option 1234 to cause the client to belong to the class.
  1222. OptionPtr option1234(new OptionUint16(Option::V6, 1234, 0x0002));
  1223. client.addExtraOption(option1234);
  1224. // Client requests an address from the second subnet which should be successful.
  1225. ASSERT_NO_THROW(client.requestAddress(0xabca, IOAddress("2001:db8:2::20")));
  1226. ASSERT_NO_THROW(client.doSARR());
  1227. ASSERT_TRUE(hasLeaseForAddress(client, IOAddress("2001:db8:2::20")));
  1228. // Now remove the client from this class.
  1229. client.clearExtraOptions();
  1230. // The client should not be able to renew the existing lease because it is now
  1231. // prohibited by the classification. Instead, the client should get a lease from the
  1232. // unrestricted subnet.
  1233. ASSERT_NO_THROW(client.doRenew());
  1234. ASSERT_TRUE(client.hasLeaseWithZeroLifetimeForAddress(IOAddress("2001:db8:2::20")));
  1235. ASSERT_TRUE(hasLeaseForAddress(client, IOAddress("2001:db8:1::20")));
  1236. }
  1237. // Some options are specified on the shared subnet level, some on the
  1238. // subnets level.
  1239. TEST_F(Dhcpv6SharedNetworkTest, optionsDerivation) {
  1240. // Client #1.
  1241. Dhcp6Client client1;
  1242. client1.setInterface("eth1");
  1243. ASSERT_NO_FATAL_FAILURE(configure(NETWORKS_CONFIG[7], *client1.getServer()));
  1244. // Client #1 belongs to shared network. By providing a hint "2001:db8:1::20 we force
  1245. // the server to select first subnet within the shared network for this client.
  1246. ASSERT_NO_THROW(client1.requestAddress(0xabca, IOAddress("2001:db8:1::20")));
  1247. // Request all configured options.
  1248. ASSERT_NO_THROW(client1.requestOption(D6O_NIS_SERVERS));
  1249. ASSERT_NO_THROW(client1.requestOption(D6O_NISP_SERVERS));
  1250. ASSERT_NO_THROW(client1.requestOption(D6O_NAME_SERVERS));
  1251. ASSERT_NO_THROW(client1.requestOption(D6O_SNTP_SERVERS));
  1252. // Perform 4-way exchange and make sure we have been assigned address from the
  1253. // subnet we wanted.
  1254. ASSERT_NO_THROW(client1.doSARR());
  1255. ASSERT_TRUE(hasLeaseForAddress(client1, IOAddress("2001:db8:1::20")));
  1256. // This option is specified on the global level.
  1257. ASSERT_TRUE(client1.hasOptionWithAddress(D6O_NIS_SERVERS, "3000::20"));
  1258. // Subnet specific value should override a value specified on the shared network level.
  1259. ASSERT_TRUE(client1.hasOptionWithAddress(D6O_NISP_SERVERS, "3003::33"));
  1260. // Shared network level value should be derived to the subnet.
  1261. ASSERT_TRUE(client1.hasOptionWithAddress(D6O_NAME_SERVERS, "3001::21"));
  1262. // This option is only specified in the subnet level.
  1263. ASSERT_TRUE(client1.hasOptionWithAddress(D6O_SNTP_SERVERS, "4004::22"));
  1264. // Client #2.
  1265. Dhcp6Client client2(client1.getServer());
  1266. client2.setInterface("eth1");
  1267. // Request an address from the second subnet within the shared network.
  1268. ASSERT_NO_THROW(client2.requestAddress(0xabca, IOAddress("2001:db8:2::20")));
  1269. // Request all configured options.
  1270. ASSERT_NO_THROW(client2.requestOption(D6O_NIS_SERVERS));
  1271. ASSERT_NO_THROW(client2.requestOption(D6O_NISP_SERVERS));
  1272. ASSERT_NO_THROW(client2.requestOption(D6O_NAME_SERVERS));
  1273. ASSERT_NO_THROW(client2.requestOption(D6O_SNTP_SERVERS));
  1274. // Perform 4-way exchange and make sure we have been assigned address from the
  1275. // subnet we wanted.
  1276. ASSERT_NO_THROW(client2.doSARR());
  1277. ASSERT_TRUE(hasLeaseForAddress(client2, IOAddress("2001:db8:2::20")));
  1278. // This option is specified on the global level.
  1279. ASSERT_TRUE(client2.hasOptionWithAddress(D6O_NIS_SERVERS, "3000::20"));
  1280. // Shared network level value should be derived to the subnet.
  1281. ASSERT_TRUE(client2.hasOptionWithAddress(D6O_NAME_SERVERS, "3001::21"));
  1282. ASSERT_TRUE(client2.hasOptionWithAddress(D6O_NISP_SERVERS, "3002::34"));
  1283. // Client #3.
  1284. Dhcp6Client client3(client1.getServer());
  1285. client3.setInterface("eth0");
  1286. // Request an address from the subnet outside of the shared network.
  1287. ASSERT_NO_THROW(client3.requestAddress(0xabca, IOAddress("3000::1")));
  1288. // Request all configured options.
  1289. ASSERT_NO_THROW(client3.requestOption(D6O_NIS_SERVERS));
  1290. ASSERT_NO_THROW(client3.requestOption(D6O_NISP_SERVERS));
  1291. ASSERT_NO_THROW(client3.requestOption(D6O_NAME_SERVERS));
  1292. ASSERT_NO_THROW(client3.requestOption(D6O_SNTP_SERVERS));
  1293. // Perform 4-way exchange and make sure we have been assigned address from the
  1294. // subnet we wanted.
  1295. ASSERT_NO_THROW(client3.doSARR());
  1296. ASSERT_TRUE(hasLeaseForAddress(client3, IOAddress("3000::1")));
  1297. // This option is specified on the global level.
  1298. ASSERT_TRUE(client3.hasOptionWithAddress(D6O_NIS_SERVERS, "3000::20"));
  1299. // Subnet specific value should be assigned.
  1300. ASSERT_TRUE(client3.hasOptionWithAddress(D6O_NISP_SERVERS, "4000::5"));
  1301. }
  1302. // Different shared network is selected for different local interface.
  1303. TEST_F(Dhcpv6SharedNetworkTest, sharedNetworkSelectionByInterface) {
  1304. // Create client #1. The server receives requests from this client
  1305. // via interface eth1 and should assign shared network "frog" for
  1306. // this client.
  1307. Dhcp6Client client1;
  1308. client1.setInterface("eth1");
  1309. client1.requestAddress(0xabca);
  1310. // Create server configuration with two shared networks selected
  1311. // by the local interface: eth1 and eth0.
  1312. ASSERT_NO_FATAL_FAILURE(configure(NETWORKS_CONFIG[8], *client1.getServer()));
  1313. // Client #1 should be assigned an address from one of the two subnets
  1314. // belonging to the first shared network.
  1315. ASSERT_NO_THROW(client1.doSARR());
  1316. if (!hasLeaseForAddress(client1, IOAddress("2001:db8:1::20")) &&
  1317. !hasLeaseForAddress(client1, IOAddress("2001:db8:2::20"))) {
  1318. ADD_FAILURE() << "unexpected shared network selected for the client";
  1319. }
  1320. // Client #2.
  1321. Dhcp6Client client2;
  1322. client2.setInterface("eth0");
  1323. client2.requestAddress(0xabca);
  1324. // Client #2 should be assigned an address from one of the two subnets
  1325. // belonging to the second shared network.
  1326. ASSERT_NO_THROW(client2.doSARR());
  1327. if (!hasLeaseForAddress(client2, IOAddress("2001:db8:3::20")) &&
  1328. !hasLeaseForAddress(client2, IOAddress("2001:db8:4::20"))) {
  1329. ADD_FAILURE() << "unexpected shared network selected for the client";
  1330. }
  1331. }
  1332. // Different shared network is selected for different relay address.
  1333. TEST_F(Dhcpv6SharedNetworkTest, sharedNetworkSelectionByRelay) {
  1334. // Create relayed client #1.
  1335. Dhcp6Client client1;
  1336. client1.useRelay(true, IOAddress("3000::1"));
  1337. client1.requestAddress(0xabcd);
  1338. // Create server configuration with two shared networks selected
  1339. // by the relay address.
  1340. ASSERT_NO_FATAL_FAILURE(configure(NETWORKS_CONFIG[9], *client1.getServer()));
  1341. // Client #1 should be assigned an address from one of the two subnets
  1342. // belonging to the first shared network.
  1343. ASSERT_NO_THROW(client1.doSARR());
  1344. if (!hasLeaseForAddress(client1, IOAddress("2001:db8:1::20")) &&
  1345. !hasLeaseForAddress(client1, IOAddress("2001:db8:2::20"))) {
  1346. ADD_FAILURE() << "unexpected shared network selected for the client";
  1347. }
  1348. // Create relayed client #2.
  1349. Dhcp6Client client2;
  1350. client2.useRelay(true, IOAddress("3000::2"));
  1351. client2.requestAddress(0xabca);
  1352. // Client #2 should be assigned an address from one of the two subnets
  1353. // belonging to the second shared network.
  1354. ASSERT_NO_THROW(client2.doSARR());
  1355. if (!hasLeaseForAddress(client2, IOAddress("2001:db8:3::20")) &&
  1356. !hasLeaseForAddress(client2, IOAddress("2001:db8:4::20"))) {
  1357. ADD_FAILURE() << "unexpected shared network selected for the client";
  1358. }
  1359. }
  1360. // Host reservations include hostname and client class.
  1361. TEST_F(Dhcpv6SharedNetworkTest, variousFieldsInReservation) {
  1362. // Create client #1.
  1363. Dhcp6Client client;
  1364. client.setInterface("eth1");
  1365. client.setDUID("00:03:00:01:11:22:33:44:55:66");
  1366. ASSERT_NO_THROW(client.requestAddress(0xabcd));
  1367. ASSERT_NO_THROW(client.requestOption(D6O_NAME_SERVERS));
  1368. ASSERT_NO_THROW(client.useFQDN(Option6ClientFqdn::FLAG_S,
  1369. "bird.example.org",
  1370. Option6ClientFqdn::FULL));
  1371. ASSERT_NO_FATAL_FAILURE(configure(NETWORKS_CONFIG[10], *client.getServer()));
  1372. // Perform 4-way exchange.
  1373. ASSERT_NO_THROW(client.doSARR());
  1374. // The client should get an FQDN from the reservation, rather than
  1375. // the FQDN it has sent to the server. If there is a logic error,
  1376. // the server would use the first subnet from the shared network to
  1377. // assign the FQDN. This subnet has no reservation so it would
  1378. // return the same FQDN that the client has sent. We expect
  1379. // that the FQDN being sent is the one that is included in the
  1380. // reservations.
  1381. ASSERT_TRUE(client.getContext().response_);
  1382. OptionPtr opt_fqdn = client.getContext().response_->getOption(D6O_CLIENT_FQDN);
  1383. ASSERT_TRUE(opt_fqdn);
  1384. Option6ClientFqdnPtr fqdn = boost::dynamic_pointer_cast<Option6ClientFqdn>(opt_fqdn);
  1385. ASSERT_TRUE(fqdn);
  1386. ASSERT_EQ("test.example.org.", fqdn->getDomainName());
  1387. // Make sure that the correct hostname has been stored in the database.
  1388. Lease6Ptr lease = LeaseMgrFactory::instance().getLease6(Lease::TYPE_NA,
  1389. IOAddress("2001:db8:2::20"));
  1390. ASSERT_TRUE(lease);
  1391. EXPECT_EQ("test.example.org.", lease->hostname_);
  1392. // The DNS servers option should be derived from the client class based on the
  1393. // static class reservations.
  1394. ASSERT_TRUE(client.hasOptionWithAddress(D6O_NAME_SERVERS, "2001:db8:1::50"));
  1395. }
  1396. // Shared network is selected based on the client class specified.
  1397. TEST_F(Dhcpv6SharedNetworkTest, sharedNetworkSelectedByClass) {
  1398. // Create client #1.
  1399. Dhcp6Client client1;
  1400. client1.setInterface("eth1");
  1401. client1.requestAddress(0xabcd);
  1402. // Add option 1234 which would cause the client1 to be classified as "b-devices".
  1403. OptionPtr option1234(new OptionUint16(Option::V6, 1234, 0x0002));
  1404. client1.addExtraOption(option1234);
  1405. // Configure the server with two shared networks which can be accessed
  1406. // by clients belonging to "a-devices" and "b-devices" classes
  1407. // respectively.
  1408. ASSERT_NO_FATAL_FAILURE(configure(NETWORKS_CONFIG[11], *client1.getServer()));
  1409. // The client 1 should be offerred an address from the second subnet.
  1410. ASSERT_NO_THROW(client1.doSolicit(true));
  1411. ASSERT_TRUE(hasLeaseForAddress(client1, IOAddress("2001:db8:2::20"),
  1412. LeaseOnServer::MUST_NOT_EXIST));
  1413. // Create another client which will belong to a different class.
  1414. Dhcp6Client client2;
  1415. client2.setInterface("eth1");
  1416. client2.requestAddress(0xabcd);
  1417. /// Add option 1234 which will cause the client 2 to be classified as "a-devices".
  1418. option1234.reset(new OptionUint16(Option::V6, 1234, 0x0001));
  1419. client2.addExtraOption(option1234);
  1420. // Client 2 should be offerred an address from the first subnet.
  1421. ASSERT_NO_THROW(client2.doSolicit(true));
  1422. ASSERT_TRUE(hasLeaseForAddress(client2, IOAddress("2001:db8:1::20"),
  1423. LeaseOnServer::MUST_NOT_EXIST));
  1424. }
  1425. // Client requests two addresses and two prefixes and obtains them from two
  1426. // different subnets.
  1427. TEST_F(Dhcpv6SharedNetworkTest, assignmentsFromDifferentSubnets) {
  1428. // Create client.
  1429. Dhcp6Client client;
  1430. client.setInterface("eth1");
  1431. client.requestAddress(0xabcd);
  1432. client.requestAddress(0x1234);
  1433. client.requestPrefix(0x1111);
  1434. client.requestPrefix(0x2222);
  1435. // Configure the server with a shared network including two subnets. Each
  1436. // subnet has an address and prefix pool with a single available address
  1437. // and prefix respectively.
  1438. ASSERT_NO_FATAL_FAILURE(configure(NETWORKS_CONFIG[0], *client.getServer()));
  1439. // 4-way exchange.
  1440. ASSERT_NO_THROW(client.doSARR());
  1441. // The two addresses should come from different subnets.
  1442. ASSERT_TRUE(hasLeaseForAddress(client, IOAddress("2001:db8:1::20")));
  1443. ASSERT_TRUE(hasLeaseForAddress(client, IOAddress("2001:db8:2::20")));
  1444. // Same for prefixes.
  1445. ASSERT_TRUE(hasLeaseForPrefixPool(client, IOAddress("4000::"), 96, 96));
  1446. ASSERT_TRUE(hasLeaseForPrefixPool(client, IOAddress("5000::"), 96, 96));
  1447. // Try to renew.
  1448. ASSERT_NO_THROW(client.doRenew());
  1449. ASSERT_TRUE(hasLeaseForAddress(client, IOAddress("2001:db8:1::20")));
  1450. ASSERT_TRUE(hasLeaseForAddress(client, IOAddress("2001:db8:2::20")));
  1451. ASSERT_TRUE(hasLeaseForPrefixPool(client, IOAddress("4000::"), 96, 96));
  1452. ASSERT_TRUE(hasLeaseForPrefixPool(client, IOAddress("5000::"), 96, 96));
  1453. }
  1454. // Client requests 2 addresses and 2 prefixes. There is one address and one prefix
  1455. // reserved for the client.
  1456. TEST_F(Dhcpv6SharedNetworkTest, reservedAddressAndPrefix) {
  1457. // Create client.
  1458. Dhcp6Client client;
  1459. client.setInterface("eth1");
  1460. client.setDUID("00:03:00:01:11:22:33:44:55:66");
  1461. // Client will request two addresses and two prefixes.
  1462. client.requestAddress(0xabcd);
  1463. client.requestAddress(0x1234);
  1464. client.requestPrefix(0x1111);
  1465. client.requestPrefix(0x2222);
  1466. // The server configuration contains a shared network with two subnets. Each
  1467. // subnet has an address and prefix pool. One of the subnets includes a reservation
  1468. // for an address and prefix.
  1469. ASSERT_NO_FATAL_FAILURE(configure(NETWORKS_CONFIG[4], *client.getServer()));
  1470. // 4-way exchange.
  1471. ASSERT_NO_THROW(client.doSARR());
  1472. ASSERT_EQ(4, client.getLeaseNum());
  1473. // The client should have got one reserved address and one reserved prefix.
  1474. ASSERT_TRUE(hasLeaseForAddress(client, IOAddress("2001:db8:2::28")));
  1475. ASSERT_TRUE(hasLeaseForPrefix(client, IOAddress("1234::"), 64, IAID(0x1111)));
  1476. // The client should have got dynamically allocated address too and it must be
  1477. // different than the reserved address.
  1478. std::vector<Lease6> leases_1234 = client.getLeasesByIAID(0x1234);
  1479. ASSERT_EQ(1, leases_1234.size());
  1480. ASSERT_NE("2001:db8:2::28", leases_1234[0].addr_.toText());
  1481. // Same for prefix.
  1482. std::vector<Lease6> leases_2222 = client.getLeasesByIAID(0x2222);
  1483. ASSERT_EQ(1, leases_2222.size());
  1484. ASSERT_NE("1234::", leases_2222[0].addr_.toText());
  1485. // Try to renew and check this again.
  1486. ASSERT_NO_THROW(client.doRenew());
  1487. ASSERT_EQ(4, client.getLeaseNum());
  1488. ASSERT_TRUE(hasLeaseForAddress(client, IOAddress("2001:db8:2::28")));
  1489. ASSERT_TRUE(hasLeaseForPrefix(client, IOAddress("1234::"), 64, IAID(0x1111)));
  1490. leases_1234 = client.getLeasesByIAID(0x1234);
  1491. ASSERT_EQ(1, leases_1234.size());
  1492. ASSERT_NE("2001:db8:2::28", leases_1234[0].addr_.toText());
  1493. leases_2222 = client.getLeasesByIAID(0x2222);
  1494. ASSERT_EQ(1, leases_2222.size());
  1495. ASSERT_NE("1234::", leases_2222[0].addr_.toText());
  1496. }
  1497. // Relay address is specified for each subnet within shared network.
  1498. TEST_F(Dhcpv6SharedNetworkTest, relaySpecifiedForEachSubnet) {
  1499. // Create client.
  1500. Dhcp6Client client;
  1501. client.useRelay(true, IOAddress("3001::1"));
  1502. // Client will request two addresses.
  1503. client.requestAddress(0xabcd);
  1504. client.requestAddress(0x1234);
  1505. // Configure the server with three subnets. Two of them belong to a shared network.
  1506. // Each subnet is configured with relay info, i.e. IP address of the relay agent
  1507. // for which the shared network is used.
  1508. ASSERT_NO_FATAL_FAILURE(configure(NETWORKS_CONFIG[13], *client.getServer()));
  1509. // 4-way exchange.
  1510. ASSERT_NO_THROW(client.doSARR());
  1511. ASSERT_EQ(2, client.getLeaseNum());
  1512. // The client should have got two leases, one from each subnet within the
  1513. // shared network.
  1514. ASSERT_TRUE(hasLeaseForAddress(client, IOAddress("2001:db8:1::20")));
  1515. ASSERT_TRUE(hasLeaseForAddress(client, IOAddress("2001:db8:2::20")));
  1516. }
  1517. // Shared network is selected based on interface id.
  1518. TEST_F(Dhcpv6SharedNetworkTest, sharedNetworkSelectedByInterfaceId) {
  1519. // Create client #1. This is a relayed client for which interface id
  1520. // has been spefified and this interface id is matching the one specified
  1521. // for the shared network.
  1522. Dhcp6Client client1;
  1523. client1.useRelay(true, IOAddress("3001::1"));
  1524. client1.useInterfaceId("vlan10");
  1525. // Configure the server with one shared network and one subnet outside of the
  1526. // shared network.
  1527. ASSERT_NO_FATAL_FAILURE(configure(NETWORKS_CONFIG[14], *client1.getServer()));
  1528. // Client #1 should be assigned an address from shared network.
  1529. ASSERT_NO_THROW(client1.requestAddress(0xabca0));
  1530. ASSERT_NO_THROW(client1.doSARR());
  1531. ASSERT_TRUE(hasLeaseForAddress(client1, IOAddress("2001:db8:1::20")));
  1532. // Create client #2. This is a relayed client which is using interface id
  1533. // matching a subnet outside of the shared network.
  1534. Dhcp6Client client2(client1.getServer());
  1535. client2.useRelay(true, IOAddress("3001::2"));
  1536. client2.useInterfaceId("vlan1000");
  1537. ASSERT_NO_THROW(client2.requestAddress(0xabca0));
  1538. ASSERT_NO_THROW(client2.doSARR());
  1539. ASSERT_TRUE(hasLeaseForAddress(client2, IOAddress("2001:db8:2::20")));
  1540. }
  1541. // Shared network is selected based on interface id specified for a subnet
  1542. // belonging to a shared network.
  1543. TEST_F(Dhcpv6SharedNetworkTest, sharedNetworkSelectedByInterfaceIdInSubnet) {
  1544. // Create client #1. This is a relayed client for which interface id
  1545. // has been spefified and this interface id is matching the one specified
  1546. // for the shared network.
  1547. Dhcp6Client client1;
  1548. client1.useRelay(true, IOAddress("3001::1"));
  1549. client1.useInterfaceId("vlan10");
  1550. // Configure the server with one shared network and one subnet outside of the
  1551. // shared network.
  1552. ASSERT_NO_FATAL_FAILURE(configure(NETWORKS_CONFIG[15], *client1.getServer()));
  1553. // Client #1 should be assigned an address from shared network.
  1554. ASSERT_NO_THROW(client1.requestAddress(0xabca0));
  1555. ASSERT_NO_THROW(client1.doSARR());
  1556. ASSERT_TRUE(hasLeaseForAddress(client1, IOAddress("2001:db8:1::20")));
  1557. // Create client #2. This is a relayed client which is using interface id
  1558. // matching a subnet outside of the shared network.
  1559. Dhcp6Client client2(client1.getServer());
  1560. client2.useRelay(true, IOAddress("3001::2"));
  1561. client2.useInterfaceId("vlan1000");
  1562. ASSERT_NO_THROW(client2.requestAddress(0xabca0));
  1563. ASSERT_NO_THROW(client2.doSARR());
  1564. ASSERT_TRUE(hasLeaseForAddress(client2, IOAddress("2001:db8:2::20")));
  1565. }
  1566. } // end of anonymous namespace