xref: /spdk/test/unit/lib/nvmf/ctrlr_discovery.c/ctrlr_discovery_ut.c (revision 0fd542bcf43352bf25e48e6f131fe30f26f7c1b8)
1 /*   SPDX-License-Identifier: BSD-3-Clause
2  *   Copyright (C) 2017 Intel Corporation.
3  *   All rights reserved.
4  *   Copyright (c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
5  */
6 
7 #include "spdk/stdinc.h"
8 
9 #include "spdk_internal/cunit.h"
10 #include "spdk_internal/mock.h"
11 
12 #include "common/lib/test_env.c"
13 #include "spdk/bdev_module.h"
14 #include "nvmf/ctrlr_discovery.c"
15 #include "nvmf/subsystem.c"
16 
17 SPDK_LOG_REGISTER_COMPONENT(nvmf)
18 
19 DEFINE_STUB_V(spdk_bdev_module_release_bdev,
20 	      (struct spdk_bdev *bdev));
21 
22 DEFINE_STUB(spdk_bdev_get_block_size, uint32_t,
23 	    (const struct spdk_bdev *bdev), 512);
24 
25 DEFINE_STUB(spdk_nvmf_transport_stop_listen,
26 	    int,
27 	    (struct spdk_nvmf_transport *transport,
28 	     const struct spdk_nvme_transport_id *trid), 0);
29 
30 DEFINE_STUB(spdk_nvmf_transport_get_first,
31 	    struct spdk_nvmf_transport *,
32 	    (struct spdk_nvmf_tgt *tgt), NULL);
33 
34 DEFINE_STUB(spdk_nvmf_transport_get_next,
35 	    struct spdk_nvmf_transport *,
36 	    (struct spdk_nvmf_transport *transport), NULL);
37 
38 DEFINE_STUB_V(spdk_bdev_close, (struct spdk_bdev_desc *desc));
39 
40 DEFINE_STUB_V(nvmf_ctrlr_async_event_discovery_log_change_notice, (void *ctx));
41 DEFINE_STUB(spdk_nvmf_qpair_disconnect, int, (struct spdk_nvmf_qpair *qpair), 0);
42 
43 DEFINE_STUB(spdk_bdev_open_ext, int,
44 	    (const char *bdev_name, bool write,	spdk_bdev_event_cb_t event_cb,
45 	     void *event_ctx, struct spdk_bdev_desc **desc), 0);
46 
47 DEFINE_STUB(spdk_bdev_desc_get_bdev, struct spdk_bdev *,
48 	    (struct spdk_bdev_desc *desc), NULL);
49 
50 DEFINE_STUB(spdk_bdev_get_md_size, uint32_t,
51 	    (const struct spdk_bdev *bdev), 0);
52 
53 DEFINE_STUB(spdk_bdev_is_md_interleaved, bool,
54 	    (const struct spdk_bdev *bdev), false);
55 
56 DEFINE_STUB(spdk_bdev_module_claim_bdev, int,
57 	    (struct spdk_bdev *bdev, struct spdk_bdev_desc *desc,
58 	     struct spdk_bdev_module *module), 0);
59 
60 DEFINE_STUB(spdk_bdev_io_type_supported, bool,
61 	    (struct spdk_bdev *bdev, enum spdk_bdev_io_type io_type), false);
62 
63 DEFINE_STUB_V(nvmf_ctrlr_reservation_notice_log,
64 	      (struct spdk_nvmf_ctrlr *ctrlr, struct spdk_nvmf_ns *ns,
65 	       enum spdk_nvme_reservation_notification_log_page_type type));
66 
67 DEFINE_STUB(spdk_nvmf_request_complete, int,
68 	    (struct spdk_nvmf_request *req), -1);
69 
70 DEFINE_STUB(nvmf_ctrlr_async_event_ana_change_notice, int,
71 	    (struct spdk_nvmf_ctrlr *ctrlr), 0);
72 
73 DEFINE_STUB(nvmf_ctrlr_async_event_ns_notice, int,
74 	    (struct spdk_nvmf_ctrlr *ctrlr), 0);
75 
76 DEFINE_STUB(spdk_nvme_transport_id_trtype_str, const char *,
77 	    (enum spdk_nvme_transport_type trtype), NULL);
78 
79 DEFINE_STUB(spdk_bdev_is_zoned, bool, (const struct spdk_bdev *bdev), false);
80 
81 DEFINE_STUB(spdk_bdev_get_max_zone_append_size, uint32_t,
82 	    (const struct spdk_bdev *bdev), 0);
83 DEFINE_STUB(spdk_key_dup, struct spdk_key *, (struct spdk_key *k), NULL);
84 DEFINE_STUB(spdk_key_get_name, const char *, (struct spdk_key *k), NULL);
85 DEFINE_STUB_V(spdk_keyring_put_key, (struct spdk_key *k));
86 DEFINE_STUB(nvmf_auth_is_supported, bool, (void), false);
87 
88 DEFINE_STUB(spdk_bdev_get_nvme_ctratt, union spdk_bdev_nvme_ctratt,
89 	    (struct spdk_bdev *bdev), {});
90 
91 const char *
92 spdk_bdev_get_name(const struct spdk_bdev *bdev)
93 {
94 	return "test";
95 }
96 
97 const struct spdk_uuid *
98 spdk_bdev_get_uuid(const struct spdk_bdev *bdev)
99 {
100 	return &bdev->uuid;
101 }
102 
103 int
104 spdk_nvme_transport_id_compare(const struct spdk_nvme_transport_id *trid1,
105 			       const struct spdk_nvme_transport_id *trid2)
106 {
107 	return !(trid1->trtype == trid2->trtype && strcasecmp(trid1->traddr, trid2->traddr) == 0 &&
108 		 strcasecmp(trid1->trsvcid, trid2->trsvcid) == 0);
109 }
110 
111 int
112 spdk_nvmf_transport_listen(struct spdk_nvmf_transport *transport,
113 			   const struct spdk_nvme_transport_id *trid, struct spdk_nvmf_listen_opts *opts)
114 {
115 	return 0;
116 }
117 
118 static struct spdk_nvmf_listener g_listener = {};
119 
120 struct spdk_nvmf_listener *
121 nvmf_transport_find_listener(struct spdk_nvmf_transport *transport,
122 			     const struct spdk_nvme_transport_id *trid)
123 {
124 	struct spdk_nvmf_listener *listener;
125 
126 	if (TAILQ_EMPTY(&transport->listeners)) {
127 		return &g_listener;
128 	}
129 
130 	TAILQ_FOREACH(listener, &transport->listeners, link) {
131 		if (spdk_nvme_transport_id_compare(&listener->trid, trid) == 0) {
132 			return listener;
133 		}
134 	}
135 
136 	return NULL;
137 }
138 
139 void
140 nvmf_transport_listener_discover(struct spdk_nvmf_transport *transport,
141 				 struct spdk_nvme_transport_id *trid,
142 				 struct spdk_nvmf_discovery_log_page_entry *entry)
143 {
144 	transport->ops->listener_discover(transport, trid, entry);
145 }
146 
147 static void
148 test_dummy_listener_discover(struct spdk_nvmf_transport *transport,
149 			     struct spdk_nvme_transport_id *trid, struct spdk_nvmf_discovery_log_page_entry *entry)
150 {
151 	entry->trtype = 42;
152 }
153 
154 struct spdk_nvmf_transport_ops g_transport_ops = { .listener_discover = test_dummy_listener_discover };
155 
156 static struct spdk_nvmf_transport g_transport = {
157 	.ops = &g_transport_ops
158 };
159 
160 int
161 spdk_nvmf_transport_create_async(const char *transport_name,
162 				 struct spdk_nvmf_transport_opts *tprt_opts,
163 				 spdk_nvmf_transport_create_done_cb cb_fn, void *cb_arg)
164 {
165 	if (strcasecmp(transport_name, spdk_nvme_transport_id_trtype_str(SPDK_NVME_TRANSPORT_RDMA))) {
166 		cb_fn(cb_arg, &g_transport);
167 		return 0;
168 	}
169 
170 	return -1;
171 }
172 
173 struct spdk_nvmf_subsystem *
174 spdk_nvmf_tgt_find_subsystem(struct spdk_nvmf_tgt *tgt, const char *subnqn)
175 {
176 	return NULL;
177 }
178 
179 DEFINE_RETURN_MOCK(spdk_nvmf_tgt_get_transport, struct spdk_nvmf_transport *);
180 struct spdk_nvmf_transport *
181 spdk_nvmf_tgt_get_transport(struct spdk_nvmf_tgt *tgt, const char *transport_name)
182 {
183 	HANDLE_RETURN_MOCK(spdk_nvmf_tgt_get_transport);
184 	return &g_transport;
185 }
186 
187 int
188 spdk_nvme_transport_id_parse_trtype(enum spdk_nvme_transport_type *trtype, const char *str)
189 {
190 	if (trtype == NULL || str == NULL) {
191 		return -EINVAL;
192 	}
193 
194 	if (strcasecmp(str, "PCIe") == 0) {
195 		*trtype = SPDK_NVME_TRANSPORT_PCIE;
196 	} else if (strcasecmp(str, "RDMA") == 0) {
197 		*trtype = SPDK_NVME_TRANSPORT_RDMA;
198 	} else {
199 		return -ENOENT;
200 	}
201 	return 0;
202 }
203 
204 void
205 nvmf_ctrlr_ns_changed(struct spdk_nvmf_ctrlr *ctrlr, uint32_t nsid)
206 {
207 }
208 
209 void
210 nvmf_ctrlr_destruct(struct spdk_nvmf_ctrlr *ctrlr)
211 {
212 }
213 
214 int
215 nvmf_poll_group_update_subsystem(struct spdk_nvmf_poll_group *group,
216 				 struct spdk_nvmf_subsystem *subsystem)
217 {
218 	return 0;
219 }
220 
221 int
222 nvmf_poll_group_add_subsystem(struct spdk_nvmf_poll_group *group,
223 			      struct spdk_nvmf_subsystem *subsystem,
224 			      spdk_nvmf_poll_group_mod_done cb_fn, void *cb_arg)
225 {
226 	return 0;
227 }
228 
229 void
230 nvmf_poll_group_remove_subsystem(struct spdk_nvmf_poll_group *group,
231 				 struct spdk_nvmf_subsystem *subsystem,
232 				 spdk_nvmf_poll_group_mod_done cb_fn, void *cb_arg)
233 {
234 }
235 
236 void
237 nvmf_poll_group_pause_subsystem(struct spdk_nvmf_poll_group *group,
238 				struct spdk_nvmf_subsystem *subsystem,
239 				uint32_t nsid,
240 				spdk_nvmf_poll_group_mod_done cb_fn, void *cb_arg)
241 {
242 }
243 
244 void
245 nvmf_poll_group_resume_subsystem(struct spdk_nvmf_poll_group *group,
246 				 struct spdk_nvmf_subsystem *subsystem,
247 				 spdk_nvmf_poll_group_mod_done cb_fn, void *cb_arg)
248 {
249 }
250 
251 static void
252 _subsystem_add_listen_done(void *cb_arg, int status)
253 {
254 	SPDK_CU_ASSERT_FATAL(status == 0);
255 }
256 
257 static void
258 test_gen_trid(struct spdk_nvme_transport_id *trid, enum spdk_nvme_transport_type trtype,
259 	      enum spdk_nvmf_adrfam adrfam, const char *tradd, const char *trsvcid)
260 {
261 	snprintf(trid->traddr, sizeof(trid->traddr), "%s", tradd);
262 	snprintf(trid->trsvcid, sizeof(trid->trsvcid), "%s", trsvcid);
263 	trid->adrfam = adrfam;
264 	trid->trtype = trtype;
265 	switch (trtype) {
266 	case SPDK_NVME_TRANSPORT_RDMA:
267 		snprintf(trid->trstring, SPDK_NVMF_TRSTRING_MAX_LEN, "%s", SPDK_NVME_TRANSPORT_NAME_RDMA);
268 		break;
269 	case SPDK_NVME_TRANSPORT_TCP:
270 		snprintf(trid->trstring, SPDK_NVMF_TRSTRING_MAX_LEN, "%s", SPDK_NVME_TRANSPORT_NAME_TCP);
271 		break;
272 	default:
273 		SPDK_CU_ASSERT_FATAL(0 && "not supported by test");
274 	}
275 }
276 
277 static void
278 test_discovery_log(void)
279 {
280 	struct spdk_nvmf_tgt tgt = {};
281 	struct spdk_nvmf_subsystem *subsystem;
282 	uint8_t buffer[8192];
283 	struct iovec iov;
284 	struct spdk_nvmf_discovery_log_page *disc_log;
285 	struct spdk_nvmf_discovery_log_page_entry *entry;
286 	struct spdk_nvme_transport_id trid = {};
287 	const char *hostnqn = "nqn.2016-06.io.spdk:host1";
288 	int rc;
289 
290 	iov.iov_base = buffer;
291 	iov.iov_len = 8192;
292 
293 	tgt.max_subsystems = 1024;
294 	tgt.subsystem_ids = spdk_bit_array_create(tgt.max_subsystems);
295 	RB_INIT(&tgt.subsystems);
296 
297 	/* Add one subsystem and verify that the discovery log contains it */
298 	subsystem = spdk_nvmf_subsystem_create(&tgt, "nqn.2016-06.io.spdk:subsystem1",
299 					       SPDK_NVMF_SUBTYPE_NVME, 0);
300 	SPDK_CU_ASSERT_FATAL(subsystem != NULL);
301 
302 	rc = spdk_nvmf_subsystem_add_host(subsystem, hostnqn, NULL);
303 	CU_ASSERT(rc == 0);
304 
305 	/* Get only genctr (first field in the header) */
306 	memset(buffer, 0xCC, sizeof(buffer));
307 	disc_log = (struct spdk_nvmf_discovery_log_page *)buffer;
308 	nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0, sizeof(disc_log->genctr),
309 				    &trid);
310 	/* No listeners yet on new subsystem, so genctr should still be 0. */
311 	CU_ASSERT(disc_log->genctr == 0);
312 
313 	test_gen_trid(&trid, SPDK_NVME_TRANSPORT_RDMA, SPDK_NVMF_ADRFAM_IPV4, "1234", "5678");
314 	spdk_nvmf_subsystem_add_listener(subsystem, &trid, _subsystem_add_listen_done, NULL);
315 	subsystem->state = SPDK_NVMF_SUBSYSTEM_ACTIVE;
316 
317 	/* Get only genctr (first field in the header) */
318 	memset(buffer, 0xCC, sizeof(buffer));
319 	disc_log = (struct spdk_nvmf_discovery_log_page *)buffer;
320 	nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0, sizeof(disc_log->genctr),
321 				    &trid);
322 	CU_ASSERT(disc_log->genctr == 1); /* one added subsystem and listener */
323 
324 	/* Get only the header, no entries */
325 	memset(buffer, 0xCC, sizeof(buffer));
326 	disc_log = (struct spdk_nvmf_discovery_log_page *)buffer;
327 	nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0, sizeof(*disc_log),
328 				    &trid);
329 	CU_ASSERT(disc_log->genctr == 1);
330 	CU_ASSERT(disc_log->numrec == 1);
331 
332 	/* Offset 0, exact size match */
333 	memset(buffer, 0xCC, sizeof(buffer));
334 	disc_log = (struct spdk_nvmf_discovery_log_page *)buffer;
335 	nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0,
336 				    sizeof(*disc_log) + sizeof(disc_log->entries[0]), &trid);
337 	CU_ASSERT(disc_log->genctr != 0);
338 	CU_ASSERT(disc_log->numrec == 1);
339 	CU_ASSERT(disc_log->entries[0].trtype == 42);
340 
341 	/* Offset 0, oversize buffer */
342 	memset(buffer, 0xCC, sizeof(buffer));
343 	disc_log = (struct spdk_nvmf_discovery_log_page *)buffer;
344 	nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0, sizeof(buffer), &trid);
345 	CU_ASSERT(disc_log->genctr != 0);
346 	CU_ASSERT(disc_log->numrec == 1);
347 	CU_ASSERT(disc_log->entries[0].trtype == 42);
348 	CU_ASSERT(spdk_mem_all_zero(buffer + sizeof(*disc_log) + sizeof(disc_log->entries[0]),
349 				    sizeof(buffer) - (sizeof(*disc_log) + sizeof(disc_log->entries[0]))));
350 
351 	/* Get just the first entry, no header */
352 	memset(buffer, 0xCC, sizeof(buffer));
353 	entry = (struct spdk_nvmf_discovery_log_page_entry *)buffer;
354 	nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1,
355 				    offsetof(struct spdk_nvmf_discovery_log_page, entries[0]), sizeof(*entry), &trid);
356 	CU_ASSERT(entry->trtype == 42);
357 
358 	/* remove the host and verify that the discovery log contains nothing */
359 	rc = spdk_nvmf_subsystem_remove_host(subsystem, hostnqn);
360 	CU_ASSERT(rc == 0);
361 
362 	/* Get only the header, no entries */
363 	memset(buffer, 0xCC, sizeof(buffer));
364 	disc_log = (struct spdk_nvmf_discovery_log_page *)buffer;
365 	nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0, sizeof(*disc_log),
366 				    &trid);
367 	CU_ASSERT(disc_log->genctr != 0);
368 	CU_ASSERT(disc_log->numrec == 0);
369 
370 	/* destroy the subsystem and verify that the discovery log contains nothing */
371 	subsystem->state = SPDK_NVMF_SUBSYSTEM_INACTIVE;
372 	rc = spdk_nvmf_subsystem_destroy(subsystem, NULL, NULL);
373 	CU_ASSERT(rc == 0);
374 
375 	/* Get only the header, no entries */
376 	memset(buffer, 0xCC, sizeof(buffer));
377 	disc_log = (struct spdk_nvmf_discovery_log_page *)buffer;
378 	nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0, sizeof(*disc_log),
379 				    &trid);
380 	CU_ASSERT(disc_log->genctr != 0);
381 	CU_ASSERT(disc_log->numrec == 0);
382 
383 	spdk_bit_array_free(&tgt.subsystem_ids);
384 }
385 
386 static void
387 test_rdma_discover(struct spdk_nvmf_transport *transport, struct spdk_nvme_transport_id *trid,
388 		   struct spdk_nvmf_discovery_log_page_entry *entry)
389 {
390 	entry->trtype = SPDK_NVMF_TRTYPE_RDMA;
391 	entry->adrfam = trid->adrfam;
392 	memcpy(entry->traddr, trid->traddr, sizeof(entry->traddr));
393 	memcpy(entry->trsvcid, trid->trsvcid, sizeof(entry->trsvcid));
394 }
395 
396 static void
397 test_tcp_discover(struct spdk_nvmf_transport *transport, struct spdk_nvme_transport_id *trid,
398 		  struct spdk_nvmf_discovery_log_page_entry *entry)
399 {
400 	entry->trtype = SPDK_NVMF_TRTYPE_TCP;
401 	entry->adrfam = trid->adrfam;
402 	memcpy(entry->traddr, trid->traddr, sizeof(entry->traddr));
403 	memcpy(entry->trsvcid, trid->trsvcid, sizeof(entry->trsvcid));
404 }
405 
406 static void
407 test_discovery_log_with_filters(void)
408 {
409 	struct spdk_nvmf_tgt tgt = {};
410 	struct spdk_nvmf_transport_ops rdma_tr_ops = { .listener_discover = test_rdma_discover }, tcp_tr_ops
411 		= { .listener_discover = test_tcp_discover };
412 	struct spdk_nvmf_transport rdma_tr = {.ops = &rdma_tr_ops }, tcp_tr = { .ops = &tcp_tr_ops };
413 	struct spdk_nvmf_subsystem *subsystem;
414 	const char *hostnqn = "nqn.2016-06.io.spdk:host1";
415 	uint8_t buffer[8192];
416 	struct iovec iov;
417 	struct spdk_nvmf_discovery_log_page *disc_log;
418 	struct spdk_nvmf_listener rdma_listener_1 = {}, rdma_listener_2 = {}, rdma_listener_3 = {},
419 	tcp_listener_1 = {}, tcp_listener_2 = {}, tcp_listener_3 = {};
420 	struct spdk_nvme_transport_id rdma_trid_1 = {}, rdma_trid_2 = {}, rdma_trid_3 = {}, rdma_trid_4 = {},
421 	tcp_trid_1 = {}, tcp_trid_2 = {}, tcp_trid_3 = {}, tcp_trid_4 = {};
422 	struct spdk_nvmf_referral ref1 = {}, ref2 = {};
423 
424 	iov.iov_base = buffer;
425 	iov.iov_len = 8192;
426 
427 	tgt.max_subsystems = 4;
428 	tgt.subsystem_ids = spdk_bit_array_create(tgt.max_subsystems);
429 	RB_INIT(&tgt.subsystems);
430 
431 	subsystem = spdk_nvmf_subsystem_create(&tgt, "nqn.2016-06.io.spdk:subsystem1",
432 					       SPDK_NVMF_SUBTYPE_NVME, 0);
433 	subsystem->flags.allow_any_host = true;
434 	SPDK_CU_ASSERT_FATAL(subsystem != NULL);
435 
436 	TAILQ_INIT(&tgt.referrals);
437 
438 	test_gen_trid(&rdma_trid_1, SPDK_NVME_TRANSPORT_RDMA, SPDK_NVMF_ADRFAM_IPV4, "10.10.10.10", "4420");
439 	test_gen_trid(&rdma_trid_2, SPDK_NVME_TRANSPORT_RDMA, SPDK_NVMF_ADRFAM_IPV4, "11.11.11.11", "4420");
440 	test_gen_trid(&rdma_trid_3, SPDK_NVME_TRANSPORT_RDMA, SPDK_NVMF_ADRFAM_IPV4, "10.10.10.10", "4421");
441 	test_gen_trid(&rdma_trid_4, SPDK_NVME_TRANSPORT_RDMA, SPDK_NVMF_ADRFAM_IPV4, "10.10.10.10", "4430");
442 	test_gen_trid(&tcp_trid_1, SPDK_NVME_TRANSPORT_TCP, SPDK_NVMF_ADRFAM_IPV4, "11.11.11.11", "4421");
443 	test_gen_trid(&tcp_trid_2, SPDK_NVME_TRANSPORT_TCP, SPDK_NVMF_ADRFAM_IPV4, "10.10.10.10", "4422");
444 	test_gen_trid(&tcp_trid_3, SPDK_NVME_TRANSPORT_TCP, SPDK_NVMF_ADRFAM_IPV4, "11.11.11.11", "4422");
445 	test_gen_trid(&tcp_trid_4, SPDK_NVME_TRANSPORT_TCP, SPDK_NVMF_ADRFAM_IPV4, "11.11.11.11", "4430");
446 
447 	rdma_listener_1.trid = rdma_trid_1;
448 	rdma_listener_2.trid = rdma_trid_2;
449 	rdma_listener_3.trid = rdma_trid_3;
450 	TAILQ_INIT(&rdma_tr.listeners);
451 	TAILQ_INSERT_TAIL(&rdma_tr.listeners, &rdma_listener_1, link);
452 	TAILQ_INSERT_TAIL(&rdma_tr.listeners, &rdma_listener_2, link);
453 	TAILQ_INSERT_TAIL(&rdma_tr.listeners, &rdma_listener_3, link);
454 
455 	tcp_listener_1.trid = tcp_trid_1;
456 	tcp_listener_2.trid = tcp_trid_2;
457 	tcp_listener_3.trid = tcp_trid_3;
458 	TAILQ_INIT(&tcp_tr.listeners);
459 	TAILQ_INSERT_TAIL(&tcp_tr.listeners, &tcp_listener_1, link);
460 	TAILQ_INSERT_TAIL(&tcp_tr.listeners, &tcp_listener_2, link);
461 	TAILQ_INSERT_TAIL(&tcp_tr.listeners, &tcp_listener_3, link);
462 
463 	MOCK_SET(spdk_nvmf_tgt_get_transport, &rdma_tr);
464 	spdk_nvmf_subsystem_add_listener(subsystem, &rdma_trid_1, _subsystem_add_listen_done, NULL);
465 	spdk_nvmf_subsystem_add_listener(subsystem, &rdma_trid_2, _subsystem_add_listen_done, NULL);
466 	spdk_nvmf_subsystem_add_listener(subsystem, &rdma_trid_3, _subsystem_add_listen_done, NULL);
467 	MOCK_SET(spdk_nvmf_tgt_get_transport, &tcp_tr);
468 	spdk_nvmf_subsystem_add_listener(subsystem, &tcp_trid_1, _subsystem_add_listen_done, NULL);
469 	spdk_nvmf_subsystem_add_listener(subsystem, &tcp_trid_2, _subsystem_add_listen_done, NULL);
470 	spdk_nvmf_subsystem_add_listener(subsystem, &tcp_trid_3, _subsystem_add_listen_done, NULL);
471 	MOCK_CLEAR(spdk_nvmf_tgt_get_transport);
472 
473 	subsystem->state = SPDK_NVMF_SUBSYSTEM_ACTIVE;
474 
475 	ref1.trid = rdma_trid_4;
476 
477 	ref1.entry.trtype = rdma_trid_4.trtype;
478 	ref1.entry.adrfam = rdma_trid_4.adrfam;
479 	ref1.entry.subtype = SPDK_NVMF_SUBTYPE_DISCOVERY;
480 	ref1.entry.treq.secure_channel = SPDK_NVMF_TREQ_SECURE_CHANNEL_NOT_REQUIRED;
481 	ref1.entry.cntlid = 0xffff;
482 	memcpy(ref1.entry.trsvcid, rdma_trid_4.trsvcid, sizeof(ref1.entry.trsvcid));
483 	memcpy(ref1.entry.traddr, rdma_trid_4.traddr, sizeof(ref1.entry.traddr));
484 	snprintf(ref1.entry.subnqn, sizeof(ref1.entry.subnqn), "%s", SPDK_NVMF_DISCOVERY_NQN);
485 
486 	ref2.trid = tcp_trid_4;
487 
488 	ref2.entry.trtype = tcp_trid_4.trtype;
489 	ref2.entry.adrfam = tcp_trid_4.adrfam;
490 	ref2.entry.subtype = SPDK_NVMF_SUBTYPE_DISCOVERY;
491 	ref2.entry.treq.secure_channel = SPDK_NVMF_TREQ_SECURE_CHANNEL_NOT_REQUIRED;
492 	ref2.entry.cntlid = 0xffff;
493 	memcpy(ref2.entry.trsvcid, tcp_trid_4.trsvcid, sizeof(ref2.entry.trsvcid));
494 	memcpy(ref2.entry.traddr, tcp_trid_4.traddr, sizeof(ref2.entry.traddr));
495 	snprintf(ref2.entry.subnqn, sizeof(ref2.entry.subnqn), "%s", SPDK_NVMF_DISCOVERY_NQN);
496 
497 	TAILQ_INSERT_HEAD(&tgt.referrals, &ref1, link);
498 	TAILQ_INSERT_HEAD(&tgt.referrals, &ref2, link);
499 
500 	nvmf_update_discovery_log(&tgt, NULL);
501 
502 	disc_log = (struct spdk_nvmf_discovery_log_page *)buffer;
503 	memset(buffer, 0, sizeof(buffer));
504 
505 	/* Test case 1 - check that all trids are reported */
506 	tgt.discovery_filter = SPDK_NVMF_TGT_DISCOVERY_MATCH_ANY;
507 	nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0, 8192, &rdma_trid_1);
508 	CU_ASSERT(disc_log->numrec == 8);
509 
510 	/* Test case 2 - check that only entries of the same transport type are returned */
511 	tgt.discovery_filter = SPDK_NVMF_TGT_DISCOVERY_MATCH_TRANSPORT_TYPE;
512 	nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0, 8192, &rdma_trid_1);
513 	CU_ASSERT(disc_log->numrec == 5);
514 	CU_ASSERT(disc_log->entries[0].trtype == rdma_trid_1.trtype);
515 	CU_ASSERT(disc_log->entries[1].trtype == rdma_trid_1.trtype);
516 	CU_ASSERT(disc_log->entries[2].trtype == rdma_trid_1.trtype);
517 	CU_ASSERT(disc_log->entries[3].trtype == tcp_trid_4.trtype);
518 	CU_ASSERT(disc_log->entries[4].trtype == rdma_trid_4.trtype);
519 
520 	nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0, 8192, &tcp_trid_1);
521 	CU_ASSERT(disc_log->numrec == 5);
522 	CU_ASSERT(disc_log->entries[0].trtype == tcp_trid_1.trtype);
523 	CU_ASSERT(disc_log->entries[1].trtype == tcp_trid_1.trtype);
524 	CU_ASSERT(disc_log->entries[2].trtype == tcp_trid_1.trtype);
525 	CU_ASSERT(disc_log->entries[3].trtype == tcp_trid_1.trtype);
526 	CU_ASSERT(disc_log->entries[4].trtype == rdma_trid_4.trtype);
527 
528 	/* Test case 3 - check that only entries of the same transport address are returned */
529 	tgt.discovery_filter = SPDK_NVMF_TGT_DISCOVERY_MATCH_TRANSPORT_ADDRESS;
530 	nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0, 8192, &rdma_trid_1);
531 	CU_ASSERT(disc_log->numrec == 5);
532 	/* 1 tcp and 3 rdma  */
533 	CU_ASSERT(strcasecmp(disc_log->entries[0].traddr, rdma_trid_1.traddr) == 0);
534 	CU_ASSERT(strcasecmp(disc_log->entries[1].traddr, rdma_trid_1.traddr) == 0);
535 	CU_ASSERT(strcasecmp(disc_log->entries[2].traddr, rdma_trid_1.traddr) == 0);
536 	CU_ASSERT(strcasecmp(disc_log->entries[3].traddr, tcp_trid_4.traddr) == 0);
537 	CU_ASSERT(strcasecmp(disc_log->entries[4].traddr, rdma_trid_4.traddr) == 0);
538 
539 	nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0, 8192, &tcp_trid_1);
540 	CU_ASSERT(disc_log->numrec == 5);
541 	/* 1 rdma and 3 tcp */
542 	CU_ASSERT((disc_log->entries[0].trtype ^ disc_log->entries[1].trtype ^ disc_log->entries[2].trtype)
543 		  != 0);
544 	CU_ASSERT(strcasecmp(disc_log->entries[0].traddr, tcp_trid_1.traddr) == 0);
545 	CU_ASSERT(strcasecmp(disc_log->entries[1].traddr, tcp_trid_1.traddr) == 0);
546 	CU_ASSERT(strcasecmp(disc_log->entries[2].traddr, tcp_trid_1.traddr) == 0);
547 	CU_ASSERT(strcasecmp(disc_log->entries[3].traddr, tcp_trid_1.traddr) == 0);
548 	CU_ASSERT(strcasecmp(disc_log->entries[4].traddr, rdma_trid_4.traddr) == 0);
549 
550 	/* Test case 4 - check that only entries of the same transport address and type returned */
551 	tgt.discovery_filter = SPDK_NVMF_TGT_DISCOVERY_MATCH_TRANSPORT_TYPE |
552 			       SPDK_NVMF_TGT_DISCOVERY_MATCH_TRANSPORT_ADDRESS;
553 	nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0, 8192, &rdma_trid_1);
554 	CU_ASSERT(disc_log->numrec == 4);
555 	CU_ASSERT(strcasecmp(disc_log->entries[0].traddr, rdma_trid_1.traddr) == 0);
556 	CU_ASSERT(strcasecmp(disc_log->entries[1].traddr, rdma_trid_1.traddr) == 0);
557 	CU_ASSERT(strcasecmp(disc_log->entries[2].traddr, tcp_trid_4.traddr) == 0);
558 	CU_ASSERT(strcasecmp(disc_log->entries[3].traddr, rdma_trid_4.traddr) == 0);
559 	CU_ASSERT(disc_log->entries[0].trtype == rdma_trid_1.trtype);
560 	CU_ASSERT(disc_log->entries[1].trtype == rdma_trid_1.trtype);
561 	CU_ASSERT(disc_log->entries[2].trtype == tcp_trid_4.trtype);
562 	CU_ASSERT(disc_log->entries[3].trtype == rdma_trid_4.trtype);
563 
564 	nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0, 8192, &rdma_trid_2);
565 	CU_ASSERT(disc_log->numrec == 3);
566 	CU_ASSERT(strcasecmp(disc_log->entries[0].traddr, rdma_trid_2.traddr) == 0);
567 	CU_ASSERT(strcasecmp(disc_log->entries[1].traddr, tcp_trid_4.traddr) == 0);
568 	CU_ASSERT(strcasecmp(disc_log->entries[2].traddr, rdma_trid_4.traddr) == 0);
569 	CU_ASSERT(disc_log->entries[0].trtype == rdma_trid_2.trtype);
570 	CU_ASSERT(disc_log->entries[1].trtype == tcp_trid_4.trtype);
571 	CU_ASSERT(disc_log->entries[2].trtype == rdma_trid_4.trtype);
572 
573 	nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0, 8192, &tcp_trid_1);
574 	CU_ASSERT(disc_log->numrec == 4);
575 	CU_ASSERT(strcasecmp(disc_log->entries[0].traddr, tcp_trid_1.traddr) == 0);
576 	CU_ASSERT(strcasecmp(disc_log->entries[1].traddr, tcp_trid_1.traddr) == 0);
577 	CU_ASSERT(strcasecmp(disc_log->entries[2].traddr, tcp_trid_4.traddr) == 0);
578 	CU_ASSERT(strcasecmp(disc_log->entries[3].traddr, rdma_trid_4.traddr) == 0);
579 	CU_ASSERT(disc_log->entries[0].trtype == tcp_trid_1.trtype);
580 	CU_ASSERT(disc_log->entries[1].trtype == tcp_trid_1.trtype);
581 	CU_ASSERT(disc_log->entries[2].trtype == tcp_trid_4.trtype);
582 	CU_ASSERT(disc_log->entries[3].trtype == rdma_trid_4.trtype);
583 
584 	nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0, 8192, &rdma_trid_2);
585 	CU_ASSERT(disc_log->numrec == 3);
586 	CU_ASSERT(strcasecmp(disc_log->entries[0].traddr, rdma_trid_2.traddr) == 0);
587 	CU_ASSERT(strcasecmp(disc_log->entries[1].traddr, tcp_trid_4.traddr) == 0);
588 	CU_ASSERT(strcasecmp(disc_log->entries[2].traddr, rdma_trid_4.traddr) == 0);
589 	CU_ASSERT(disc_log->entries[0].trtype == rdma_trid_2.trtype);
590 	CU_ASSERT(disc_log->entries[1].trtype == tcp_trid_4.trtype);
591 	CU_ASSERT(disc_log->entries[2].trtype == rdma_trid_4.trtype);
592 
593 	/* Test case 5 - check that only entries of the same transport address and type returned */
594 	tgt.discovery_filter = SPDK_NVMF_TGT_DISCOVERY_MATCH_TRANSPORT_TYPE |
595 			       SPDK_NVMF_TGT_DISCOVERY_MATCH_TRANSPORT_SVCID;
596 	nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0, 8192, &rdma_trid_1);
597 	CU_ASSERT(disc_log->numrec == 4);
598 	CU_ASSERT(strcasecmp(disc_log->entries[0].trsvcid, rdma_trid_1.trsvcid) == 0);
599 	CU_ASSERT(strcasecmp(disc_log->entries[1].trsvcid, rdma_trid_2.trsvcid) == 0);
600 	CU_ASSERT(strcasecmp(disc_log->entries[2].trsvcid, tcp_trid_4.trsvcid) == 0);
601 	CU_ASSERT(strcasecmp(disc_log->entries[3].trsvcid, rdma_trid_4.trsvcid) == 0);
602 	CU_ASSERT(disc_log->entries[0].trtype == rdma_trid_1.trtype);
603 	CU_ASSERT(disc_log->entries[1].trtype == rdma_trid_2.trtype);
604 	CU_ASSERT(disc_log->entries[2].trtype == tcp_trid_4.trtype);
605 	CU_ASSERT(disc_log->entries[3].trtype == rdma_trid_4.trtype);
606 
607 	nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0, 8192, &rdma_trid_3);
608 	CU_ASSERT(disc_log->numrec == 3);
609 	CU_ASSERT(strcasecmp(disc_log->entries[0].trsvcid, rdma_trid_3.trsvcid) == 0);
610 	CU_ASSERT(strcasecmp(disc_log->entries[1].trsvcid, tcp_trid_4.trsvcid) == 0);
611 	CU_ASSERT(strcasecmp(disc_log->entries[2].trsvcid, rdma_trid_4.trsvcid) == 0);
612 	CU_ASSERT(disc_log->entries[0].trtype == rdma_trid_3.trtype);
613 	CU_ASSERT(disc_log->entries[1].trtype == tcp_trid_4.trtype);
614 	CU_ASSERT(disc_log->entries[2].trtype == rdma_trid_4.trtype);
615 
616 	nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0, 8192, &tcp_trid_1);
617 	CU_ASSERT(disc_log->numrec == 3);
618 	CU_ASSERT(strcasecmp(disc_log->entries[0].trsvcid, tcp_trid_1.trsvcid) == 0);
619 	CU_ASSERT(strcasecmp(disc_log->entries[1].trsvcid, tcp_trid_4.trsvcid) == 0);
620 	CU_ASSERT(strcasecmp(disc_log->entries[2].trsvcid, rdma_trid_4.trsvcid) == 0);
621 	CU_ASSERT(disc_log->entries[0].trtype == tcp_trid_1.trtype);
622 	CU_ASSERT(disc_log->entries[1].trtype == tcp_trid_4.trtype);
623 	CU_ASSERT(disc_log->entries[2].trtype == rdma_trid_4.trtype);
624 
625 	nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0, 8192, &tcp_trid_2);
626 	CU_ASSERT(disc_log->numrec == 4);
627 	CU_ASSERT(strcasecmp(disc_log->entries[0].trsvcid, tcp_trid_2.trsvcid) == 0);
628 	CU_ASSERT(strcasecmp(disc_log->entries[1].trsvcid, tcp_trid_2.trsvcid) == 0);
629 	CU_ASSERT(strcasecmp(disc_log->entries[2].trsvcid, tcp_trid_4.trsvcid) == 0);
630 	CU_ASSERT(strcasecmp(disc_log->entries[3].trsvcid, rdma_trid_4.trsvcid) == 0);
631 	CU_ASSERT(disc_log->entries[0].trtype == tcp_trid_2.trtype);
632 	CU_ASSERT(disc_log->entries[1].trtype == tcp_trid_2.trtype);
633 	CU_ASSERT(disc_log->entries[2].trtype == tcp_trid_4.trtype);
634 	CU_ASSERT(disc_log->entries[3].trtype == rdma_trid_4.trtype);
635 
636 	/* Test case 6 - check that only entries of the same transport address and type returned.
637 	 * That also implies trtype since RDMA and TCP listeners can't occupy the same socket */
638 	tgt.discovery_filter = SPDK_NVMF_TGT_DISCOVERY_MATCH_TRANSPORT_ADDRESS |
639 			       SPDK_NVMF_TGT_DISCOVERY_MATCH_TRANSPORT_SVCID;
640 	nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0, 8192, &rdma_trid_1);
641 	CU_ASSERT(disc_log->numrec == 3);
642 	CU_ASSERT(strcasecmp(disc_log->entries[0].traddr, rdma_trid_1.traddr) == 0);
643 	CU_ASSERT(strcasecmp(disc_log->entries[1].traddr, tcp_trid_4.traddr) == 0);
644 	CU_ASSERT(strcasecmp(disc_log->entries[2].traddr, rdma_trid_4.traddr) == 0);
645 	CU_ASSERT(strcasecmp(disc_log->entries[0].trsvcid, rdma_trid_1.trsvcid) == 0);
646 	CU_ASSERT(strcasecmp(disc_log->entries[1].trsvcid, tcp_trid_4.trsvcid) == 0);
647 	CU_ASSERT(strcasecmp(disc_log->entries[2].trsvcid, rdma_trid_4.trsvcid) == 0);
648 	CU_ASSERT(disc_log->entries[0].trtype == rdma_trid_1.trtype);
649 	CU_ASSERT(disc_log->entries[1].trtype == tcp_trid_4.trtype);
650 	CU_ASSERT(disc_log->entries[2].trtype == rdma_trid_4.trtype);
651 
652 	nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0, 8192, &rdma_trid_2);
653 	CU_ASSERT(disc_log->numrec == 3);
654 	CU_ASSERT(strcasecmp(disc_log->entries[0].traddr, rdma_trid_2.traddr) == 0);
655 	CU_ASSERT(strcasecmp(disc_log->entries[1].traddr, tcp_trid_4.traddr) == 0);
656 	CU_ASSERT(strcasecmp(disc_log->entries[2].traddr, rdma_trid_4.traddr) == 0);
657 	CU_ASSERT(strcasecmp(disc_log->entries[0].trsvcid, rdma_trid_2.trsvcid) == 0);
658 	CU_ASSERT(strcasecmp(disc_log->entries[1].trsvcid, tcp_trid_4.trsvcid) == 0);
659 	CU_ASSERT(strcasecmp(disc_log->entries[2].trsvcid, rdma_trid_4.trsvcid) == 0);
660 	CU_ASSERT(disc_log->entries[0].trtype == rdma_trid_2.trtype);
661 	CU_ASSERT(disc_log->entries[1].trtype == tcp_trid_4.trtype);
662 	CU_ASSERT(disc_log->entries[2].trtype == rdma_trid_4.trtype);
663 
664 	nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0, 8192, &rdma_trid_3);
665 	CU_ASSERT(disc_log->numrec == 3);
666 	CU_ASSERT(strcasecmp(disc_log->entries[0].traddr, rdma_trid_3.traddr) == 0);
667 	CU_ASSERT(strcasecmp(disc_log->entries[1].traddr, tcp_trid_4.traddr) == 0);
668 	CU_ASSERT(strcasecmp(disc_log->entries[2].traddr, rdma_trid_4.traddr) == 0);
669 	CU_ASSERT(strcasecmp(disc_log->entries[0].trsvcid, rdma_trid_3.trsvcid) == 0);
670 	CU_ASSERT(strcasecmp(disc_log->entries[1].trsvcid, tcp_trid_4.trsvcid) == 0);
671 	CU_ASSERT(strcasecmp(disc_log->entries[2].trsvcid, rdma_trid_4.trsvcid) == 0);
672 	CU_ASSERT(disc_log->entries[0].trtype == rdma_trid_3.trtype);
673 	CU_ASSERT(disc_log->entries[1].trtype == tcp_trid_4.trtype);
674 	CU_ASSERT(disc_log->entries[2].trtype == rdma_trid_4.trtype);
675 
676 	nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0, 8192, &tcp_trid_1);
677 	CU_ASSERT(disc_log->numrec == 3);
678 	CU_ASSERT(strcasecmp(disc_log->entries[0].traddr, tcp_trid_1.traddr) == 0);
679 	CU_ASSERT(strcasecmp(disc_log->entries[1].traddr, tcp_trid_4.traddr) == 0);
680 	CU_ASSERT(strcasecmp(disc_log->entries[2].traddr, rdma_trid_4.traddr) == 0);
681 	CU_ASSERT(strcasecmp(disc_log->entries[0].trsvcid, tcp_trid_1.trsvcid) == 0);
682 	CU_ASSERT(strcasecmp(disc_log->entries[1].trsvcid, tcp_trid_4.trsvcid) == 0);
683 	CU_ASSERT(strcasecmp(disc_log->entries[2].trsvcid, rdma_trid_4.trsvcid) == 0);
684 	CU_ASSERT(disc_log->entries[0].trtype == tcp_trid_1.trtype);
685 	CU_ASSERT(disc_log->entries[1].trtype == tcp_trid_4.trtype);
686 	CU_ASSERT(disc_log->entries[2].trtype == rdma_trid_4.trtype);
687 
688 	nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0, 8192, &tcp_trid_2);
689 	CU_ASSERT(disc_log->numrec == 3);
690 	CU_ASSERT(strcasecmp(disc_log->entries[0].traddr, tcp_trid_2.traddr) == 0);
691 	CU_ASSERT(strcasecmp(disc_log->entries[1].traddr, tcp_trid_4.traddr) == 0);
692 	CU_ASSERT(strcasecmp(disc_log->entries[2].traddr, rdma_trid_4.traddr) == 0);
693 	CU_ASSERT(strcasecmp(disc_log->entries[0].trsvcid, tcp_trid_2.trsvcid) == 0);
694 	CU_ASSERT(strcasecmp(disc_log->entries[1].trsvcid, tcp_trid_4.trsvcid) == 0);
695 	CU_ASSERT(strcasecmp(disc_log->entries[2].trsvcid, rdma_trid_4.trsvcid) == 0);
696 	CU_ASSERT(disc_log->entries[0].trtype == tcp_trid_2.trtype);
697 	CU_ASSERT(disc_log->entries[1].trtype == tcp_trid_4.trtype);
698 	CU_ASSERT(disc_log->entries[2].trtype == rdma_trid_4.trtype);
699 
700 	nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0, 8192, &tcp_trid_3);
701 	CU_ASSERT(disc_log->numrec == 3);
702 	CU_ASSERT(strcasecmp(disc_log->entries[0].traddr, tcp_trid_3.traddr) == 0);
703 	CU_ASSERT(strcasecmp(disc_log->entries[1].traddr, tcp_trid_4.traddr) == 0);
704 	CU_ASSERT(strcasecmp(disc_log->entries[2].traddr, rdma_trid_4.traddr) == 0);
705 	CU_ASSERT(strcasecmp(disc_log->entries[0].trsvcid, tcp_trid_3.trsvcid) == 0);
706 	CU_ASSERT(strcasecmp(disc_log->entries[1].trsvcid, tcp_trid_4.trsvcid) == 0);
707 	CU_ASSERT(strcasecmp(disc_log->entries[2].trsvcid, rdma_trid_4.trsvcid) == 0);
708 	CU_ASSERT(disc_log->entries[0].trtype == tcp_trid_3.trtype);
709 	CU_ASSERT(disc_log->entries[1].trtype == tcp_trid_4.trtype);
710 	CU_ASSERT(disc_log->entries[2].trtype == rdma_trid_4.trtype);
711 
712 	/* Test case 7 - check that only entries of the same transport address, svcid and type returned */
713 	tgt.discovery_filter = SPDK_NVMF_TGT_DISCOVERY_MATCH_TRANSPORT_TYPE |
714 			       SPDK_NVMF_TGT_DISCOVERY_MATCH_TRANSPORT_ADDRESS |
715 			       SPDK_NVMF_TGT_DISCOVERY_MATCH_TRANSPORT_SVCID;
716 	nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0, 8192, &rdma_trid_1);
717 	CU_ASSERT(disc_log->numrec == 3);
718 	CU_ASSERT(strcasecmp(disc_log->entries[0].traddr, rdma_trid_1.traddr) == 0);
719 	CU_ASSERT(strcasecmp(disc_log->entries[1].traddr, tcp_trid_4.traddr) == 0);
720 	CU_ASSERT(strcasecmp(disc_log->entries[2].traddr, rdma_trid_4.traddr) == 0);
721 	CU_ASSERT(strcasecmp(disc_log->entries[0].trsvcid, rdma_trid_1.trsvcid) == 0);
722 	CU_ASSERT(strcasecmp(disc_log->entries[1].trsvcid, tcp_trid_4.trsvcid) == 0);
723 	CU_ASSERT(strcasecmp(disc_log->entries[2].trsvcid, rdma_trid_4.trsvcid) == 0);
724 	CU_ASSERT(disc_log->entries[0].trtype == rdma_trid_1.trtype);
725 	CU_ASSERT(disc_log->entries[1].trtype == tcp_trid_4.trtype);
726 	CU_ASSERT(disc_log->entries[2].trtype == rdma_trid_4.trtype);
727 
728 	nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0, 8192, &rdma_trid_2);
729 	CU_ASSERT(disc_log->numrec == 3);
730 	CU_ASSERT(strcasecmp(disc_log->entries[0].traddr, rdma_trid_2.traddr) == 0);
731 	CU_ASSERT(strcasecmp(disc_log->entries[1].traddr, tcp_trid_4.traddr) == 0);
732 	CU_ASSERT(strcasecmp(disc_log->entries[2].traddr, rdma_trid_4.traddr) == 0);
733 	CU_ASSERT(strcasecmp(disc_log->entries[0].trsvcid, rdma_trid_2.trsvcid) == 0);
734 	CU_ASSERT(strcasecmp(disc_log->entries[1].trsvcid, tcp_trid_4.trsvcid) == 0);
735 	CU_ASSERT(strcasecmp(disc_log->entries[2].trsvcid, rdma_trid_4.trsvcid) == 0);
736 	CU_ASSERT(disc_log->entries[0].trtype == rdma_trid_2.trtype);
737 	CU_ASSERT(disc_log->entries[1].trtype == tcp_trid_4.trtype);
738 	CU_ASSERT(disc_log->entries[2].trtype == rdma_trid_4.trtype);
739 
740 	nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0, 8192, &rdma_trid_3);
741 	CU_ASSERT(disc_log->numrec == 3);
742 	CU_ASSERT(strcasecmp(disc_log->entries[0].traddr, rdma_trid_3.traddr) == 0);
743 	CU_ASSERT(strcasecmp(disc_log->entries[1].traddr, tcp_trid_4.traddr) == 0);
744 	CU_ASSERT(strcasecmp(disc_log->entries[2].traddr, rdma_trid_4.traddr) == 0);
745 	CU_ASSERT(strcasecmp(disc_log->entries[0].trsvcid, rdma_trid_3.trsvcid) == 0);
746 	CU_ASSERT(strcasecmp(disc_log->entries[1].trsvcid, tcp_trid_4.trsvcid) == 0);
747 	CU_ASSERT(strcasecmp(disc_log->entries[2].trsvcid, rdma_trid_4.trsvcid) == 0);
748 	CU_ASSERT(disc_log->entries[0].trtype == rdma_trid_3.trtype);
749 	CU_ASSERT(disc_log->entries[1].trtype == tcp_trid_4.trtype);
750 	CU_ASSERT(disc_log->entries[2].trtype == rdma_trid_4.trtype);
751 
752 	nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0, 8192, &tcp_trid_1);
753 	CU_ASSERT(disc_log->numrec == 3);
754 	CU_ASSERT(strcasecmp(disc_log->entries[0].traddr, tcp_trid_1.traddr) == 0);
755 	CU_ASSERT(strcasecmp(disc_log->entries[1].traddr, tcp_trid_4.traddr) == 0);
756 	CU_ASSERT(strcasecmp(disc_log->entries[2].traddr, rdma_trid_4.traddr) == 0);
757 	CU_ASSERT(strcasecmp(disc_log->entries[0].trsvcid, tcp_trid_1.trsvcid) == 0);
758 	CU_ASSERT(strcasecmp(disc_log->entries[1].trsvcid, tcp_trid_4.trsvcid) == 0);
759 	CU_ASSERT(strcasecmp(disc_log->entries[2].trsvcid, rdma_trid_4.trsvcid) == 0);
760 	CU_ASSERT(disc_log->entries[0].trtype == tcp_trid_1.trtype);
761 	CU_ASSERT(disc_log->entries[1].trtype == tcp_trid_4.trtype);
762 	CU_ASSERT(disc_log->entries[2].trtype == rdma_trid_4.trtype);
763 
764 	nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0, 8192, &tcp_trid_2);
765 	CU_ASSERT(disc_log->numrec == 3);
766 	CU_ASSERT(strcasecmp(disc_log->entries[0].traddr, tcp_trid_2.traddr) == 0);
767 	CU_ASSERT(strcasecmp(disc_log->entries[1].traddr, tcp_trid_4.traddr) == 0);
768 	CU_ASSERT(strcasecmp(disc_log->entries[2].traddr, rdma_trid_4.traddr) == 0);
769 	CU_ASSERT(strcasecmp(disc_log->entries[0].trsvcid, tcp_trid_2.trsvcid) == 0);
770 	CU_ASSERT(strcasecmp(disc_log->entries[1].trsvcid, tcp_trid_4.trsvcid) == 0);
771 	CU_ASSERT(strcasecmp(disc_log->entries[2].trsvcid, rdma_trid_4.trsvcid) == 0);
772 	CU_ASSERT(disc_log->entries[0].trtype == tcp_trid_2.trtype);
773 	CU_ASSERT(disc_log->entries[1].trtype == tcp_trid_4.trtype);
774 	CU_ASSERT(disc_log->entries[2].trtype == rdma_trid_4.trtype);
775 
776 	nvmf_get_discovery_log_page(&tgt, hostnqn, &iov, 1, 0, 8192, &tcp_trid_3);
777 	CU_ASSERT(disc_log->numrec == 3);
778 	CU_ASSERT(strcasecmp(disc_log->entries[0].traddr, tcp_trid_3.traddr) == 0);
779 	CU_ASSERT(strcasecmp(disc_log->entries[1].traddr, tcp_trid_4.traddr) == 0);
780 	CU_ASSERT(strcasecmp(disc_log->entries[2].traddr, rdma_trid_4.traddr) == 0);
781 	CU_ASSERT(strcasecmp(disc_log->entries[0].trsvcid, tcp_trid_3.trsvcid) == 0);
782 	CU_ASSERT(strcasecmp(disc_log->entries[1].trsvcid, tcp_trid_4.trsvcid) == 0);
783 	CU_ASSERT(strcasecmp(disc_log->entries[2].trsvcid, rdma_trid_4.trsvcid) == 0);
784 	CU_ASSERT(disc_log->entries[0].trtype == tcp_trid_3.trtype);
785 	CU_ASSERT(disc_log->entries[1].trtype == tcp_trid_4.trtype);
786 	CU_ASSERT(disc_log->entries[2].trtype == rdma_trid_4.trtype);
787 
788 	subsystem->state = SPDK_NVMF_SUBSYSTEM_INACTIVE;
789 	spdk_nvmf_subsystem_destroy(subsystem, NULL, NULL);
790 	spdk_bit_array_free(&tgt.subsystem_ids);
791 }
792 
793 int
794 main(int argc, char **argv)
795 {
796 	CU_pSuite	suite = NULL;
797 	unsigned int	num_failures;
798 
799 	CU_initialize_registry();
800 
801 	suite = CU_add_suite("nvmf", NULL, NULL);
802 
803 	CU_ADD_TEST(suite, test_discovery_log);
804 	CU_ADD_TEST(suite, test_discovery_log_with_filters);
805 
806 	num_failures = spdk_ut_run_tests(argc, argv, NULL);
807 	CU_cleanup_registry();
808 	return num_failures;
809 }
810