1488570ebSJim Harris /* SPDX-License-Identifier: BSD-3-Clause 2a6dbe372Spaul luse * Copyright (C) 2018 Intel Corporation. 34c30f7fcSYanbo Zhou * All rights reserved. 497aa2c86SAlexey Marchuk * Copyright (c) 2021, 2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 54c30f7fcSYanbo Zhou */ 64c30f7fcSYanbo Zhou 74c30f7fcSYanbo Zhou #include "spdk/stdinc.h" 8ab04d59cSjiaqizho #include "spdk/nvmf_spec.h" 9ae431e31SKonrad Sztyber #include "spdk_internal/cunit.h" 10a36785dfSDennis Maisenbacher #include "spdk/bdev_zone.h" 1149bff95fSBen Walker 124c30f7fcSYanbo Zhou #include "common/lib/test_env.c" 1349bff95fSBen Walker #include "common/lib/test_sock.c" 1449bff95fSBen Walker 154c30f7fcSYanbo Zhou #include "nvmf/ctrlr.c" 164c30f7fcSYanbo Zhou #include "nvmf/tcp.c" 17572a0c8aSKrzysztof Karas #include "spdk/sock.h" 18572a0c8aSKrzysztof Karas #include "spdk/hexlify.h" 194c30f7fcSYanbo Zhou 204c30f7fcSYanbo Zhou #define UT_IPV4_ADDR "192.168.0.1" 214c30f7fcSYanbo Zhou #define UT_PORT "4420" 224c30f7fcSYanbo Zhou #define UT_NVMF_ADRFAM_INVALID 0xf 234c30f7fcSYanbo Zhou #define UT_MAX_QUEUE_DEPTH 128 244c30f7fcSYanbo Zhou #define UT_MAX_QPAIRS_PER_CTRLR 128 254c30f7fcSYanbo Zhou #define UT_IN_CAPSULE_DATA_SIZE 1024 264c30f7fcSYanbo Zhou #define UT_MAX_IO_SIZE 4096 274c30f7fcSYanbo Zhou #define UT_IO_UNIT_SIZE 1024 284c30f7fcSYanbo Zhou #define UT_MAX_AQ_DEPTH 64 294c30f7fcSYanbo Zhou #define UT_SQ_HEAD_MAX 128 303c88819bSZiye Yang #define UT_NUM_SHARED_BUFFERS 128 314c30f7fcSYanbo Zhou 32f0956d33SZiye Yang static void *g_accel_p = (void *)0xdeadbeaf; 33f0956d33SZiye Yang 342172c432STomasz Zawadzki SPDK_LOG_REGISTER_COMPONENT(nvmf) 354c30f7fcSYanbo Zhou 364c30f7fcSYanbo Zhou DEFINE_STUB(spdk_nvmf_qpair_get_listen_trid, 374c30f7fcSYanbo Zhou int, 384c30f7fcSYanbo Zhou (struct spdk_nvmf_qpair *qpair, struct spdk_nvme_transport_id *trid), 394c30f7fcSYanbo Zhou 0); 40608b54a2SKonrad Sztyber DEFINE_STUB(spdk_nvmf_qpair_disconnect, int, (struct spdk_nvmf_qpair *qpair), 0); 414c30f7fcSYanbo Zhou 429cb21ad6SSeth Howell DEFINE_STUB(nvmf_subsystem_add_ctrlr, 434c30f7fcSYanbo Zhou int, 444c30f7fcSYanbo Zhou (struct spdk_nvmf_subsystem *subsystem, struct spdk_nvmf_ctrlr *ctrlr), 454c30f7fcSYanbo Zhou 0); 464c30f7fcSYanbo Zhou 479cb21ad6SSeth Howell DEFINE_STUB(nvmf_subsystem_get_ctrlr, 484c30f7fcSYanbo Zhou struct spdk_nvmf_ctrlr *, 494c30f7fcSYanbo Zhou (struct spdk_nvmf_subsystem *subsystem, uint16_t cntlid), 504c30f7fcSYanbo Zhou NULL); 514c30f7fcSYanbo Zhou 524c30f7fcSYanbo Zhou DEFINE_STUB(spdk_nvmf_tgt_find_subsystem, 534c30f7fcSYanbo Zhou struct spdk_nvmf_subsystem *, 544c30f7fcSYanbo Zhou (struct spdk_nvmf_tgt *tgt, const char *subnqn), 554c30f7fcSYanbo Zhou NULL); 564c30f7fcSYanbo Zhou 574c30f7fcSYanbo Zhou DEFINE_STUB(spdk_nvmf_subsystem_listener_allowed, 584c30f7fcSYanbo Zhou bool, 596913a864SJacek Kalwas (struct spdk_nvmf_subsystem *subsystem, const struct spdk_nvme_transport_id *trid), 604c30f7fcSYanbo Zhou true); 614c30f7fcSYanbo Zhou 627bcff376SShuhei Matsumoto DEFINE_STUB(nvmf_subsystem_find_listener, 637bcff376SShuhei Matsumoto struct spdk_nvmf_subsystem_listener *, 647bcff376SShuhei Matsumoto (struct spdk_nvmf_subsystem *subsystem, 657bcff376SShuhei Matsumoto const struct spdk_nvme_transport_id *trid), 667bcff376SShuhei Matsumoto (void *)0x1); 677bcff376SShuhei Matsumoto 68c6ab15a6SJim Harris DEFINE_STUB(spdk_sock_get_numa_id, int32_t, (struct spdk_sock *sock), 0); 69c6ab15a6SJim Harris 70d37555b4SJonas Pfefferle DEFINE_STUB(spdk_nvmf_ns_find_host, 71d37555b4SJonas Pfefferle struct spdk_nvmf_host *, 72d37555b4SJonas Pfefferle (struct spdk_nvmf_ns *ns, const char *hostnqn), 73d37555b4SJonas Pfefferle NULL); 74d37555b4SJonas Pfefferle 759cb21ad6SSeth Howell DEFINE_STUB_V(nvmf_get_discovery_log_page, 763fe30060SChangpeng Liu (struct spdk_nvmf_tgt *tgt, const char *hostnqn, struct iovec *iov, 773d8904c6SAlexey Marchuk uint32_t iovcnt, uint64_t offset, uint32_t length, struct spdk_nvme_transport_id *cmd_src_trid)); 784c30f7fcSYanbo Zhou 799cb21ad6SSeth Howell DEFINE_STUB_V(nvmf_subsystem_remove_ctrlr, 804c30f7fcSYanbo Zhou (struct spdk_nvmf_subsystem *subsystem, struct spdk_nvmf_ctrlr *ctrlr)); 814c30f7fcSYanbo Zhou 824c30f7fcSYanbo Zhou DEFINE_STUB(spdk_nvmf_subsystem_get_first_ns, 834c30f7fcSYanbo Zhou struct spdk_nvmf_ns *, 844c30f7fcSYanbo Zhou (struct spdk_nvmf_subsystem *subsystem), 854c30f7fcSYanbo Zhou NULL); 864c30f7fcSYanbo Zhou 874c30f7fcSYanbo Zhou DEFINE_STUB(spdk_nvmf_subsystem_get_next_ns, 884c30f7fcSYanbo Zhou struct spdk_nvmf_ns *, 894c30f7fcSYanbo Zhou (struct spdk_nvmf_subsystem *subsystem, struct spdk_nvmf_ns *prev_ns), 904c30f7fcSYanbo Zhou NULL); 91415a0d2bSKonrad Sztyber DEFINE_STUB(nvmf_subsystem_zone_append_supported, bool, 92415a0d2bSKonrad Sztyber (struct spdk_nvmf_subsystem *subsystem), false); 934c30f7fcSYanbo Zhou DEFINE_STUB(spdk_nvmf_subsystem_host_allowed, 944c30f7fcSYanbo Zhou bool, 954c30f7fcSYanbo Zhou (struct spdk_nvmf_subsystem *subsystem, const char *hostnqn), 964c30f7fcSYanbo Zhou true); 974c30f7fcSYanbo Zhou 989cb21ad6SSeth Howell DEFINE_STUB(nvmf_ctrlr_dsm_supported, 994c30f7fcSYanbo Zhou bool, 1004c30f7fcSYanbo Zhou (struct spdk_nvmf_ctrlr *ctrlr), 1014c30f7fcSYanbo Zhou false); 1024c30f7fcSYanbo Zhou 1039cb21ad6SSeth Howell DEFINE_STUB(nvmf_ctrlr_write_zeroes_supported, 1044c30f7fcSYanbo Zhou bool, 1054c30f7fcSYanbo Zhou (struct spdk_nvmf_ctrlr *ctrlr), 1064c30f7fcSYanbo Zhou false); 1074c30f7fcSYanbo Zhou 1088305e49bSEvgeniy Kochetov DEFINE_STUB(nvmf_ctrlr_copy_supported, 1098305e49bSEvgeniy Kochetov bool, 1108305e49bSEvgeniy Kochetov (struct spdk_nvmf_ctrlr *ctrlr), 1118305e49bSEvgeniy Kochetov false); 1128305e49bSEvgeniy Kochetov 1139cb21ad6SSeth Howell DEFINE_STUB(nvmf_bdev_ctrlr_read_cmd, 1141b6b6cc4SBen Walker int, 1151b6b6cc4SBen Walker (struct spdk_bdev *bdev, struct spdk_bdev_desc *desc, struct spdk_io_channel *ch, 1161b6b6cc4SBen Walker struct spdk_nvmf_request *req), 1171b6b6cc4SBen Walker 0); 1181b6b6cc4SBen Walker 1199cb21ad6SSeth Howell DEFINE_STUB(nvmf_bdev_ctrlr_write_cmd, 1201b6b6cc4SBen Walker int, 1211b6b6cc4SBen Walker (struct spdk_bdev *bdev, struct spdk_bdev_desc *desc, struct spdk_io_channel *ch, 1221b6b6cc4SBen Walker struct spdk_nvmf_request *req), 1231b6b6cc4SBen Walker 0); 1241b6b6cc4SBen Walker 1259cb21ad6SSeth Howell DEFINE_STUB(nvmf_bdev_ctrlr_compare_cmd, 126941d9e7aSMaciej Szwed int, 127941d9e7aSMaciej Szwed (struct spdk_bdev *bdev, struct spdk_bdev_desc *desc, struct spdk_io_channel *ch, 128941d9e7aSMaciej Szwed struct spdk_nvmf_request *req), 129941d9e7aSMaciej Szwed 0); 130941d9e7aSMaciej Szwed 1319cb21ad6SSeth Howell DEFINE_STUB(nvmf_bdev_ctrlr_compare_and_write_cmd, 13271beb568SMaciej Szwed int, 13371beb568SMaciej Szwed (struct spdk_bdev *bdev, struct spdk_bdev_desc *desc, struct spdk_io_channel *ch, 13471beb568SMaciej Szwed struct spdk_nvmf_request *cmp_req, struct spdk_nvmf_request *write_req), 13571beb568SMaciej Szwed 0); 13671beb568SMaciej Szwed 1379cb21ad6SSeth Howell DEFINE_STUB(nvmf_bdev_ctrlr_write_zeroes_cmd, 1381b6b6cc4SBen Walker int, 1391b6b6cc4SBen Walker (struct spdk_bdev *bdev, struct spdk_bdev_desc *desc, struct spdk_io_channel *ch, 1401b6b6cc4SBen Walker struct spdk_nvmf_request *req), 1411b6b6cc4SBen Walker 0); 1421b6b6cc4SBen Walker 1439cb21ad6SSeth Howell DEFINE_STUB(nvmf_bdev_ctrlr_flush_cmd, 1441b6b6cc4SBen Walker int, 1451b6b6cc4SBen Walker (struct spdk_bdev *bdev, struct spdk_bdev_desc *desc, struct spdk_io_channel *ch, 1461b6b6cc4SBen Walker struct spdk_nvmf_request *req), 1471b6b6cc4SBen Walker 0); 1481b6b6cc4SBen Walker 1499cb21ad6SSeth Howell DEFINE_STUB(nvmf_bdev_ctrlr_dsm_cmd, 1501b6b6cc4SBen Walker int, 1511b6b6cc4SBen Walker (struct spdk_bdev *bdev, struct spdk_bdev_desc *desc, struct spdk_io_channel *ch, 1521b6b6cc4SBen Walker struct spdk_nvmf_request *req), 1531b6b6cc4SBen Walker 0); 1541b6b6cc4SBen Walker 1558305e49bSEvgeniy Kochetov DEFINE_STUB(nvmf_bdev_ctrlr_copy_cmd, 1568305e49bSEvgeniy Kochetov int, 1578305e49bSEvgeniy Kochetov (struct spdk_bdev *bdev, struct spdk_bdev_desc *desc, struct spdk_io_channel *ch, 1588305e49bSEvgeniy Kochetov struct spdk_nvmf_request *req), 1598305e49bSEvgeniy Kochetov 0); 1608305e49bSEvgeniy Kochetov 1619cb21ad6SSeth Howell DEFINE_STUB(nvmf_bdev_ctrlr_nvme_passthru_io, 1621b6b6cc4SBen Walker int, 1631b6b6cc4SBen Walker (struct spdk_bdev *bdev, struct spdk_bdev_desc *desc, struct spdk_io_channel *ch, 1641b6b6cc4SBen Walker struct spdk_nvmf_request *req), 1651b6b6cc4SBen Walker 0); 1661b6b6cc4SBen Walker 16762649a7dSMichael Haeuptle DEFINE_STUB(spdk_nvmf_bdev_ctrlr_abort_cmd, 168b8a87e6aSShuhei Matsumoto int, 169b8a87e6aSShuhei Matsumoto (struct spdk_bdev *bdev, struct spdk_bdev_desc *desc, struct spdk_io_channel *ch, 170b8a87e6aSShuhei Matsumoto struct spdk_nvmf_request *req, struct spdk_nvmf_request *req_to_abort), 171b8a87e6aSShuhei Matsumoto 0); 172b8a87e6aSShuhei Matsumoto 1739cb21ad6SSeth Howell DEFINE_STUB(nvmf_bdev_ctrlr_get_dif_ctx, 1742c9b0af2SShuhei Matsumoto bool, 175*b09de013SShuhei Matsumoto (struct spdk_bdev_desc *desc, struct spdk_nvme_cmd *cmd, struct spdk_dif_ctx *dif_ctx), 1762c9b0af2SShuhei Matsumoto false); 1772c9b0af2SShuhei Matsumoto 1785e4d957eSShuhei Matsumoto DEFINE_STUB_V(nvmf_bdev_ctrlr_identify_iocs_nvm, 1795e4d957eSShuhei Matsumoto (struct spdk_nvmf_ns *ns, struct spdk_nvme_nvm_ns_data *nsdata_nvm)); 1805e4d957eSShuhei Matsumoto 18161d85773SSeth Howell DEFINE_STUB(nvmf_transport_req_complete, 182a4d666fdSBen Walker int, 183a4d666fdSBen Walker (struct spdk_nvmf_request *req), 184a4d666fdSBen Walker 0); 185a4d666fdSBen Walker 1865818b42fSmatthewb DEFINE_STUB(nvmf_bdev_zcopy_enabled, 1875818b42fSmatthewb bool, 1885818b42fSmatthewb (struct spdk_bdev *bdev), 1895818b42fSmatthewb false); 1905818b42fSmatthewb 1910e09df57SKonrad Sztyber DEFINE_STUB(nvmf_bdev_ctrlr_zcopy_start, 1925818b42fSmatthewb int, 1935818b42fSmatthewb (struct spdk_bdev *bdev, struct spdk_bdev_desc *desc, struct spdk_io_channel *ch, 1945818b42fSmatthewb struct spdk_nvmf_request *req), 1955818b42fSmatthewb 0); 1965818b42fSmatthewb 1977a374fbcSKonrad Sztyber DEFINE_STUB_V(nvmf_bdev_ctrlr_zcopy_end, (struct spdk_nvmf_request *req, bool commit)); 1985818b42fSmatthewb 19999680358SShuhei Matsumoto DEFINE_STUB_V(spdk_nvmf_request_free_buffers, 20099680358SShuhei Matsumoto (struct spdk_nvmf_request *req, struct spdk_nvmf_transport_poll_group *group, 20179945ef0SShuhei Matsumoto struct spdk_nvmf_transport *transport)); 20299680358SShuhei Matsumoto 203960460f0SZiye Yang DEFINE_STUB(spdk_sock_get_optimal_sock_group, 204960460f0SZiye Yang int, 2056301f891STomasz Zawadzki (struct spdk_sock *sock, struct spdk_sock_group **group, struct spdk_sock_group *hint), 206960460f0SZiye Yang 0); 207960460f0SZiye Yang 208960460f0SZiye Yang DEFINE_STUB(spdk_sock_group_get_ctx, 209960460f0SZiye Yang void *, 210960460f0SZiye Yang (struct spdk_sock_group *group), 211960460f0SZiye Yang NULL); 212960460f0SZiye Yang 2139cb21ad6SSeth Howell DEFINE_STUB_V(nvmf_ns_reservation_request, (void *ctx)); 214bc1d0b91SChangpeng Liu 2157ed0904bSSeth Howell DEFINE_STUB_V(spdk_nvme_trid_populate_transport, (struct spdk_nvme_transport_id *trid, 2167ed0904bSSeth Howell enum spdk_nvme_transport_type trtype)); 217f038354eSSeth Howell DEFINE_STUB_V(spdk_nvmf_transport_register, (const struct spdk_nvmf_transport_ops *ops)); 2187ed0904bSSeth Howell 2195584232cSBen Walker DEFINE_STUB_V(spdk_nvmf_tgt_new_qpair, (struct spdk_nvmf_tgt *tgt, struct spdk_nvmf_qpair *qpair)); 2205584232cSBen Walker 221604b4503SShuhei Matsumoto DEFINE_STUB_V(nvmf_transport_qpair_abort_request, 222604b4503SShuhei Matsumoto (struct spdk_nvmf_qpair *qpair, struct spdk_nvmf_request *req)); 223604b4503SShuhei Matsumoto 224db221b40SKonrad Sztyber DEFINE_STUB_V(nvmf_qpair_set_state, (struct spdk_nvmf_qpair *q, enum spdk_nvmf_qpair_state s)); 225db221b40SKonrad Sztyber 226afefd815SJacek Kalwas DEFINE_STUB_V(spdk_nvme_print_command, (uint16_t qid, struct spdk_nvme_cmd *cmd)); 22781717da1SJacek Kalwas DEFINE_STUB_V(spdk_nvme_print_completion, (uint16_t qid, struct spdk_nvme_cpl *cpl)); 228afefd815SJacek Kalwas 2293b461269SNick Connolly DEFINE_STUB(nvmf_transport_req_free, 2303b461269SNick Connolly int, 2313b461269SNick Connolly (struct spdk_nvmf_request *req), 2323b461269SNick Connolly 0); 2333b461269SNick Connolly 234712e8cb7SBen Walker DEFINE_STUB(accel_channel_create, int, (void *io_device, void *ctx_buf), 0); 235712e8cb7SBen Walker DEFINE_STUB_V(accel_channel_destroy, (void *io_device, void *ctx_buf)); 236f63c0899SChangpeng Liu DEFINE_STUB(spdk_bdev_reset, int, (struct spdk_bdev_desc *desc, struct spdk_io_channel *ch, 237f63c0899SChangpeng Liu spdk_bdev_io_completion_cb cb, void *cb_arg), 0); 238f63c0899SChangpeng Liu DEFINE_STUB_V(spdk_bdev_free_io, (struct spdk_bdev_io *bdev_io)); 239f0956d33SZiye Yang 240a36785dfSDennis Maisenbacher DEFINE_STUB(spdk_bdev_get_max_active_zones, uint32_t, 241a36785dfSDennis Maisenbacher (const struct spdk_bdev *bdev), 0); 242a36785dfSDennis Maisenbacher DEFINE_STUB(spdk_bdev_get_max_open_zones, uint32_t, 243a36785dfSDennis Maisenbacher (const struct spdk_bdev *bdev), 0); 244a36785dfSDennis Maisenbacher DEFINE_STUB(spdk_bdev_is_zoned, bool, (const struct spdk_bdev *bdev), false); 245a36785dfSDennis Maisenbacher DEFINE_STUB(spdk_bdev_get_zone_size, uint64_t, (const struct spdk_bdev *bdev), 0); 246a36785dfSDennis Maisenbacher 2477bbeb80aSAnkit Kumar DEFINE_STUB(spdk_nvme_ns_get_format_index, uint32_t, 2487bbeb80aSAnkit Kumar (const struct spdk_nvme_ns_data *nsdata), 0); 2497bbeb80aSAnkit Kumar 250eaf70c87SKrzysztof Karas DEFINE_STUB(spdk_sock_get_impl_name, const char *, (struct spdk_sock *sock), ""); 251aabfea70SKrzysztof Karas 25281fc34dfSKrzysztof Goreczny DEFINE_STUB(spdk_sock_group_register_interrupt, int, (struct spdk_sock_group *group, 25381fc34dfSKrzysztof Goreczny uint32_t events, spdk_interrupt_fn fn, void *arg, const char *name), 0); 25481fc34dfSKrzysztof Goreczny DEFINE_STUB_V(spdk_sock_group_unregister_interrupt, (struct spdk_sock_group *group)); 25581fc34dfSKrzysztof Goreczny 2567efdf905SSlawomir Ptak DEFINE_STUB(spdk_nvmf_subsystem_is_discovery, bool, (struct spdk_nvmf_subsystem *subsystem), false); 257ea1a6608SJim Harris DEFINE_STUB(spdk_nvmf_subsystem_get_nqn, const char *, 258ea1a6608SJim Harris (const struct spdk_nvmf_subsystem *subsystem), NULL); 259ee164e62SKonrad Sztyber DEFINE_STUB_V(spdk_keyring_put_key, (struct spdk_key *k)); 2607efdf905SSlawomir Ptak 26109e8e884SArtur Paszkiewicz DEFINE_STUB(nvmf_ns_is_ptpl_capable, bool, (const struct spdk_nvmf_ns *ns), false); 2620a6bb8caSKonrad Sztyber DEFINE_STUB(nvmf_subsystem_host_auth_required, bool, (struct spdk_nvmf_subsystem *s, const char *n), 2630a6bb8caSKonrad Sztyber false); 2640a6bb8caSKonrad Sztyber DEFINE_STUB(nvmf_qpair_auth_init, int, (struct spdk_nvmf_qpair *q), 0); 2650a6bb8caSKonrad Sztyber DEFINE_STUB(nvmf_auth_request_exec, int, (struct spdk_nvmf_request *r), 2660a6bb8caSKonrad Sztyber SPDK_NVMF_REQUEST_EXEC_STATUS_ASYNCHRONOUS); 267c7d22538SKrzysztof Goreczny DEFINE_STUB(nvmf_request_get_buffers_abort, bool, (struct spdk_nvmf_request *r), false); 26805632afdSAtul Malakar DEFINE_STUB(spdk_bdev_io_type_supported, bool, 26905632afdSAtul Malakar (struct spdk_bdev *bdev, enum spdk_bdev_io_type io_type), false); 270f0956d33SZiye Yang struct spdk_io_channel * 27134c48f1bSBen Walker spdk_accel_get_io_channel(void) 272f0956d33SZiye Yang { 273f0956d33SZiye Yang return spdk_get_io_channel(g_accel_p); 274f0956d33SZiye Yang } 275d478edd4SZiye Yang 27690c56d96SZiye Yang DEFINE_STUB(spdk_accel_submit_crc32cv, 277d478edd4SZiye Yang int, 27890c56d96SZiye Yang (struct spdk_io_channel *ch, uint32_t *dst, struct iovec *iovs, 27990c56d96SZiye Yang uint32_t iovcnt, uint32_t seed, spdk_accel_completion_cb cb_fn, void *cb_arg), 280d478edd4SZiye Yang 0); 281d478edd4SZiye Yang 2823b461269SNick Connolly DEFINE_STUB(spdk_nvmf_bdev_ctrlr_nvme_passthru_admin, 2833b461269SNick Connolly int, 2843b461269SNick Connolly (struct spdk_bdev *bdev, struct spdk_bdev_desc *desc, 2853b461269SNick Connolly struct spdk_io_channel *ch, struct spdk_nvmf_request *req, 2863b461269SNick Connolly spdk_nvmf_nvme_passthru_cmd_cb cb_fn), 2873b461269SNick Connolly 0) 2883b461269SNick Connolly 28911cc2256SKonrad Sztyber struct spdk_key { 29011cc2256SKonrad Sztyber const char *name; 29111cc2256SKonrad Sztyber char data[4096]; 29211cc2256SKonrad Sztyber int len; 29311cc2256SKonrad Sztyber } g_ut_psk = { 29411cc2256SKonrad Sztyber .name = "ut-key", 29511cc2256SKonrad Sztyber }; 29611cc2256SKonrad Sztyber 29711cc2256SKonrad Sztyber struct spdk_key * 29811cc2256SKonrad Sztyber spdk_keyring_get_key(const char *name) 29911cc2256SKonrad Sztyber { 30011cc2256SKonrad Sztyber if (strcmp(name, g_ut_psk.name) == 0) { 30111cc2256SKonrad Sztyber return &g_ut_psk; 30211cc2256SKonrad Sztyber } 30311cc2256SKonrad Sztyber 30411cc2256SKonrad Sztyber return NULL; 30511cc2256SKonrad Sztyber } 30611cc2256SKonrad Sztyber 30711cc2256SKonrad Sztyber int 30811cc2256SKonrad Sztyber spdk_key_get_key(struct spdk_key *key, void *buf, int len) 30911cc2256SKonrad Sztyber { 31011cc2256SKonrad Sztyber len = spdk_min(key->len, len); 31111cc2256SKonrad Sztyber 31211cc2256SKonrad Sztyber memcpy(buf, key->data, len); 31311cc2256SKonrad Sztyber 31411cc2256SKonrad Sztyber return len; 31511cc2256SKonrad Sztyber } 31611cc2256SKonrad Sztyber 31711cc2256SKonrad Sztyber const char * 31811cc2256SKonrad Sztyber spdk_key_get_name(struct spdk_key *k) 31911cc2256SKonrad Sztyber { 32011cc2256SKonrad Sztyber return k->name; 32111cc2256SKonrad Sztyber } 32211cc2256SKonrad Sztyber 3234c30f7fcSYanbo Zhou struct spdk_bdev { 3244c30f7fcSYanbo Zhou int ut_mock; 3254c30f7fcSYanbo Zhou uint64_t blockcnt; 3264c30f7fcSYanbo Zhou }; 3274c30f7fcSYanbo Zhou 3284c30f7fcSYanbo Zhou int 3294c30f7fcSYanbo Zhou spdk_nvme_transport_id_compare(const struct spdk_nvme_transport_id *trid1, 3304c30f7fcSYanbo Zhou const struct spdk_nvme_transport_id *trid2) 3314c30f7fcSYanbo Zhou { 3324c30f7fcSYanbo Zhou return 0; 3334c30f7fcSYanbo Zhou } 3344c30f7fcSYanbo Zhou 3357ed0904bSSeth Howell const char * 3367ed0904bSSeth Howell spdk_nvme_transport_id_trtype_str(enum spdk_nvme_transport_type trtype) 3377ed0904bSSeth Howell { 3387ed0904bSSeth Howell switch (trtype) { 3397ed0904bSSeth Howell case SPDK_NVME_TRANSPORT_PCIE: 3407ed0904bSSeth Howell return "PCIe"; 3417ed0904bSSeth Howell case SPDK_NVME_TRANSPORT_RDMA: 3427ed0904bSSeth Howell return "RDMA"; 3437ed0904bSSeth Howell case SPDK_NVME_TRANSPORT_FC: 3447ed0904bSSeth Howell return "FC"; 3457ed0904bSSeth Howell default: 3467ed0904bSSeth Howell return NULL; 3477ed0904bSSeth Howell } 3487ed0904bSSeth Howell } 3497ed0904bSSeth Howell 3507ed0904bSSeth Howell int 3517ed0904bSSeth Howell spdk_nvme_transport_id_populate_trstring(struct spdk_nvme_transport_id *trid, const char *trstring) 3527ed0904bSSeth Howell { 3537ed0904bSSeth Howell int len, i; 3547ed0904bSSeth Howell 3557ed0904bSSeth Howell if (trstring == NULL) { 3567ed0904bSSeth Howell return -EINVAL; 3577ed0904bSSeth Howell } 3587ed0904bSSeth Howell 3597ed0904bSSeth Howell len = strnlen(trstring, SPDK_NVMF_TRSTRING_MAX_LEN); 3607ed0904bSSeth Howell if (len == SPDK_NVMF_TRSTRING_MAX_LEN) { 3617ed0904bSSeth Howell return -EINVAL; 3627ed0904bSSeth Howell } 3637ed0904bSSeth Howell 3647ed0904bSSeth Howell /* cast official trstring to uppercase version of input. */ 3657ed0904bSSeth Howell for (i = 0; i < len; i++) { 3667ed0904bSSeth Howell trid->trstring[i] = toupper(trstring[i]); 3677ed0904bSSeth Howell } 3687ed0904bSSeth Howell return 0; 3697ed0904bSSeth Howell } 3707ed0904bSSeth Howell 3714c30f7fcSYanbo Zhou int 372ab04d59cSjiaqizho spdk_nvmf_request_get_buffers(struct spdk_nvmf_request *req, 373ab04d59cSjiaqizho struct spdk_nvmf_transport_poll_group *group, 374ab04d59cSjiaqizho struct spdk_nvmf_transport *transport, 375ab04d59cSjiaqizho uint32_t length) 376ab04d59cSjiaqizho { 377ab04d59cSjiaqizho /* length more than 1 io unit length will fail. */ 378ab04d59cSjiaqizho if (length >= transport->opts.io_unit_size) { 379ab04d59cSjiaqizho return -EINVAL; 380ab04d59cSjiaqizho } 381ab04d59cSjiaqizho 382ab04d59cSjiaqizho req->iovcnt = 1; 383ab04d59cSjiaqizho req->iov[0].iov_base = (void *)0xDEADBEEF; 384ab04d59cSjiaqizho 385ab04d59cSjiaqizho return 0; 386ab04d59cSjiaqizho } 387ab04d59cSjiaqizho 388ab04d59cSjiaqizho 3894c30f7fcSYanbo Zhou void 3909cb21ad6SSeth Howell nvmf_bdev_ctrlr_identify_ns(struct spdk_nvmf_ns *ns, struct spdk_nvme_ns_data *nsdata, 3911c7f92f0SShuhei Matsumoto bool dif_insert_or_strip) 3924c30f7fcSYanbo Zhou { 3934c30f7fcSYanbo Zhou uint64_t num_blocks; 3944c30f7fcSYanbo Zhou 3954c30f7fcSYanbo Zhou SPDK_CU_ASSERT_FATAL(ns->bdev != NULL); 3964c30f7fcSYanbo Zhou num_blocks = ns->bdev->blockcnt; 3974c30f7fcSYanbo Zhou nsdata->nsze = num_blocks; 3984c30f7fcSYanbo Zhou nsdata->ncap = num_blocks; 3994c30f7fcSYanbo Zhou nsdata->nuse = num_blocks; 4004c30f7fcSYanbo Zhou nsdata->nlbaf = 0; 4014c30f7fcSYanbo Zhou nsdata->flbas.format = 0; 4027bbeb80aSAnkit Kumar nsdata->flbas.msb_format = 0; 4034c30f7fcSYanbo Zhou nsdata->lbaf[0].lbads = spdk_u32log2(512); 4044c30f7fcSYanbo Zhou } 4054c30f7fcSYanbo Zhou 4064c30f7fcSYanbo Zhou const char * 4074c30f7fcSYanbo Zhou spdk_nvmf_subsystem_get_sn(const struct spdk_nvmf_subsystem *subsystem) 4084c30f7fcSYanbo Zhou { 4094c30f7fcSYanbo Zhou return subsystem->sn; 4104c30f7fcSYanbo Zhou } 4114c30f7fcSYanbo Zhou 41214032a98SGregory Shapiro const char * 41314032a98SGregory Shapiro spdk_nvmf_subsystem_get_mn(const struct spdk_nvmf_subsystem *subsystem) 41414032a98SGregory Shapiro { 41514032a98SGregory Shapiro return subsystem->mn; 41614032a98SGregory Shapiro } 41714032a98SGregory Shapiro 4184c30f7fcSYanbo Zhou static void 4194c30f7fcSYanbo Zhou test_nvmf_tcp_create(void) 4204c30f7fcSYanbo Zhou { 4214c30f7fcSYanbo Zhou struct spdk_thread *thread; 4224c30f7fcSYanbo Zhou struct spdk_nvmf_transport *transport; 4234c30f7fcSYanbo Zhou struct spdk_nvmf_tcp_transport *ttransport; 4244c30f7fcSYanbo Zhou struct spdk_nvmf_transport_opts opts; 4250e983c56SKrzysztof Goreczny struct spdk_sock_group grp = {}; 4264c30f7fcSYanbo Zhou 4275d0b5e2cSBen Walker thread = spdk_thread_create(NULL, NULL); 4284c30f7fcSYanbo Zhou SPDK_CU_ASSERT_FATAL(thread != NULL); 429605e530aSBen Walker spdk_set_thread(thread); 4304c30f7fcSYanbo Zhou 4310e983c56SKrzysztof Goreczny MOCK_SET(spdk_sock_group_create, &grp); 4320e983c56SKrzysztof Goreczny 4334c30f7fcSYanbo Zhou /* case 1 */ 4344c30f7fcSYanbo Zhou memset(&opts, 0, sizeof(opts)); 4354c30f7fcSYanbo Zhou opts.max_queue_depth = UT_MAX_QUEUE_DEPTH; 4364c30f7fcSYanbo Zhou opts.max_qpairs_per_ctrlr = UT_MAX_QPAIRS_PER_CTRLR; 4374c30f7fcSYanbo Zhou opts.in_capsule_data_size = UT_IN_CAPSULE_DATA_SIZE; 4384c30f7fcSYanbo Zhou opts.max_io_size = UT_MAX_IO_SIZE; 4394c30f7fcSYanbo Zhou opts.io_unit_size = UT_IO_UNIT_SIZE; 4404c30f7fcSYanbo Zhou opts.max_aq_depth = UT_MAX_AQ_DEPTH; 4413c88819bSZiye Yang opts.num_shared_buffers = UT_NUM_SHARED_BUFFERS; 4424c30f7fcSYanbo Zhou /* expect success */ 4434de405abSSeth Howell transport = nvmf_tcp_create(&opts); 4444c30f7fcSYanbo Zhou CU_ASSERT_PTR_NOT_NULL(transport); 4454c30f7fcSYanbo Zhou ttransport = SPDK_CONTAINEROF(transport, struct spdk_nvmf_tcp_transport, transport); 4464c30f7fcSYanbo Zhou SPDK_CU_ASSERT_FATAL(ttransport != NULL); 44704d09f92SZiye Yang transport->opts = opts; 44804d09f92SZiye Yang CU_ASSERT(transport->opts.max_queue_depth == UT_MAX_QUEUE_DEPTH); 44904d09f92SZiye Yang CU_ASSERT(transport->opts.max_io_size == UT_MAX_IO_SIZE); 45004d09f92SZiye Yang CU_ASSERT(transport->opts.in_capsule_data_size == UT_IN_CAPSULE_DATA_SIZE); 45104d09f92SZiye Yang CU_ASSERT(transport->opts.io_unit_size == UT_IO_UNIT_SIZE); 4524c30f7fcSYanbo Zhou /* destroy transport */ 45343022da3SJacek Kalwas CU_ASSERT(nvmf_tcp_destroy(transport, NULL, NULL) == 0); 4544c30f7fcSYanbo Zhou 4554c30f7fcSYanbo Zhou /* case 2 */ 4564c30f7fcSYanbo Zhou memset(&opts, 0, sizeof(opts)); 4574c30f7fcSYanbo Zhou opts.max_queue_depth = UT_MAX_QUEUE_DEPTH; 4584c30f7fcSYanbo Zhou opts.max_qpairs_per_ctrlr = UT_MAX_QPAIRS_PER_CTRLR; 4594c30f7fcSYanbo Zhou opts.in_capsule_data_size = UT_IN_CAPSULE_DATA_SIZE; 4604c30f7fcSYanbo Zhou opts.max_io_size = UT_MAX_IO_SIZE; 4614c30f7fcSYanbo Zhou opts.io_unit_size = UT_MAX_IO_SIZE + 1; 4624c30f7fcSYanbo Zhou opts.max_aq_depth = UT_MAX_AQ_DEPTH; 4633c88819bSZiye Yang opts.num_shared_buffers = UT_NUM_SHARED_BUFFERS; 4644c30f7fcSYanbo Zhou /* expect success */ 4654de405abSSeth Howell transport = nvmf_tcp_create(&opts); 46604d09f92SZiye Yang CU_ASSERT_PTR_NOT_NULL(transport); 4674c30f7fcSYanbo Zhou ttransport = SPDK_CONTAINEROF(transport, struct spdk_nvmf_tcp_transport, transport); 4684c30f7fcSYanbo Zhou SPDK_CU_ASSERT_FATAL(ttransport != NULL); 46904d09f92SZiye Yang transport->opts = opts; 47004d09f92SZiye Yang CU_ASSERT(transport->opts.max_queue_depth == UT_MAX_QUEUE_DEPTH); 47104d09f92SZiye Yang CU_ASSERT(transport->opts.max_io_size == UT_MAX_IO_SIZE); 47204d09f92SZiye Yang CU_ASSERT(transport->opts.in_capsule_data_size == UT_IN_CAPSULE_DATA_SIZE); 47304d09f92SZiye Yang CU_ASSERT(transport->opts.io_unit_size == UT_MAX_IO_SIZE); 4744c30f7fcSYanbo Zhou /* destroy transport */ 47543022da3SJacek Kalwas CU_ASSERT(nvmf_tcp_destroy(transport, NULL, NULL) == 0); 4764c30f7fcSYanbo Zhou 4774c30f7fcSYanbo Zhou /* case 3 */ 4784c30f7fcSYanbo Zhou memset(&opts, 0, sizeof(opts)); 4794c30f7fcSYanbo Zhou opts.max_queue_depth = UT_MAX_QUEUE_DEPTH; 4804c30f7fcSYanbo Zhou opts.max_qpairs_per_ctrlr = UT_MAX_QPAIRS_PER_CTRLR; 4814c30f7fcSYanbo Zhou opts.in_capsule_data_size = UT_IN_CAPSULE_DATA_SIZE; 4824c30f7fcSYanbo Zhou opts.max_io_size = UT_MAX_IO_SIZE; 4834c30f7fcSYanbo Zhou opts.io_unit_size = 16; 4844c30f7fcSYanbo Zhou opts.max_aq_depth = UT_MAX_AQ_DEPTH; 485c9c7c281SJosh Soref /* expect fails */ 4864de405abSSeth Howell transport = nvmf_tcp_create(&opts); 4874c30f7fcSYanbo Zhou CU_ASSERT_PTR_NULL(transport); 4884c30f7fcSYanbo Zhou 4890e983c56SKrzysztof Goreczny MOCK_CLEAR_P(spdk_sock_group_create); 4900e983c56SKrzysztof Goreczny 4919cba82b9SBen Walker spdk_thread_exit(thread); 492e7ead00bSShuhei Matsumoto while (!spdk_thread_is_exited(thread)) { 493e7ead00bSShuhei Matsumoto spdk_thread_poll(thread, 0, 0); 494e7ead00bSShuhei Matsumoto } 495e036215fSBen Walker spdk_thread_destroy(thread); 4964c30f7fcSYanbo Zhou } 4974c30f7fcSYanbo Zhou 4984c30f7fcSYanbo Zhou static void 4994c30f7fcSYanbo Zhou test_nvmf_tcp_destroy(void) 5004c30f7fcSYanbo Zhou { 5014c30f7fcSYanbo Zhou struct spdk_thread *thread; 5024c30f7fcSYanbo Zhou struct spdk_nvmf_transport *transport; 5034c30f7fcSYanbo Zhou struct spdk_nvmf_transport_opts opts; 5040e983c56SKrzysztof Goreczny struct spdk_sock_group grp = {}; 5054c30f7fcSYanbo Zhou 5065d0b5e2cSBen Walker thread = spdk_thread_create(NULL, NULL); 5074c30f7fcSYanbo Zhou SPDK_CU_ASSERT_FATAL(thread != NULL); 508605e530aSBen Walker spdk_set_thread(thread); 5094c30f7fcSYanbo Zhou 5104c30f7fcSYanbo Zhou /* case 1 */ 5114c30f7fcSYanbo Zhou memset(&opts, 0, sizeof(opts)); 5124c30f7fcSYanbo Zhou opts.max_queue_depth = UT_MAX_QUEUE_DEPTH; 5134c30f7fcSYanbo Zhou opts.max_qpairs_per_ctrlr = UT_MAX_QPAIRS_PER_CTRLR; 5144c30f7fcSYanbo Zhou opts.in_capsule_data_size = UT_IN_CAPSULE_DATA_SIZE; 5154c30f7fcSYanbo Zhou opts.max_io_size = UT_MAX_IO_SIZE; 5164c30f7fcSYanbo Zhou opts.io_unit_size = UT_IO_UNIT_SIZE; 5174c30f7fcSYanbo Zhou opts.max_aq_depth = UT_MAX_AQ_DEPTH; 5183c88819bSZiye Yang opts.num_shared_buffers = UT_NUM_SHARED_BUFFERS; 5190e983c56SKrzysztof Goreczny MOCK_SET(spdk_sock_group_create, &grp); 5204de405abSSeth Howell transport = nvmf_tcp_create(&opts); 5210e983c56SKrzysztof Goreczny MOCK_CLEAR_P(spdk_sock_group_create); 5224c30f7fcSYanbo Zhou CU_ASSERT_PTR_NOT_NULL(transport); 52304d09f92SZiye Yang transport->opts = opts; 5244c30f7fcSYanbo Zhou /* destroy transport */ 5250d98a949SNaresh Gottumukkala CU_ASSERT(nvmf_tcp_destroy(transport, NULL, NULL) == 0); 5264c30f7fcSYanbo Zhou 5279cba82b9SBen Walker spdk_thread_exit(thread); 528e7ead00bSShuhei Matsumoto while (!spdk_thread_is_exited(thread)) { 529e7ead00bSShuhei Matsumoto spdk_thread_poll(thread, 0, 0); 530e7ead00bSShuhei Matsumoto } 531e036215fSBen Walker spdk_thread_destroy(thread); 5324c30f7fcSYanbo Zhou } 5334c30f7fcSYanbo Zhou 5344c30f7fcSYanbo Zhou static void 535f0956d33SZiye Yang init_accel(void) 536f0956d33SZiye Yang { 537712e8cb7SBen Walker spdk_io_device_register(g_accel_p, accel_channel_create, accel_channel_destroy, 538f0956d33SZiye Yang sizeof(int), "accel_p"); 539f0956d33SZiye Yang } 540f0956d33SZiye Yang 541f0956d33SZiye Yang static void 542f0956d33SZiye Yang fini_accel(void) 543f0956d33SZiye Yang { 544f0956d33SZiye Yang spdk_io_device_unregister(g_accel_p, NULL); 545f0956d33SZiye Yang } 546f0956d33SZiye Yang 547f0956d33SZiye Yang static void 5484c30f7fcSYanbo Zhou test_nvmf_tcp_poll_group_create(void) 5494c30f7fcSYanbo Zhou { 5503c88819bSZiye Yang struct spdk_nvmf_transport *transport; 5514c30f7fcSYanbo Zhou struct spdk_nvmf_transport_poll_group *group; 55285fa4324SAlexey Marchuk struct spdk_nvmf_tcp_poll_group *tgroup; 55394cd652bSZiye Yang struct spdk_thread *thread; 5543c88819bSZiye Yang struct spdk_nvmf_transport_opts opts; 55549bff95fSBen Walker struct spdk_sock_group grp = {}; 55694cd652bSZiye Yang 5575d0b5e2cSBen Walker thread = spdk_thread_create(NULL, NULL); 55894cd652bSZiye Yang SPDK_CU_ASSERT_FATAL(thread != NULL); 55994cd652bSZiye Yang spdk_set_thread(thread); 5604c30f7fcSYanbo Zhou 561f0956d33SZiye Yang init_accel(); 562f0956d33SZiye Yang 5633c88819bSZiye Yang memset(&opts, 0, sizeof(opts)); 5643c88819bSZiye Yang opts.max_queue_depth = UT_MAX_QUEUE_DEPTH; 5653c88819bSZiye Yang opts.max_qpairs_per_ctrlr = UT_MAX_QPAIRS_PER_CTRLR; 5663c88819bSZiye Yang opts.in_capsule_data_size = UT_IN_CAPSULE_DATA_SIZE; 5673c88819bSZiye Yang opts.max_io_size = UT_MAX_IO_SIZE; 5683c88819bSZiye Yang opts.io_unit_size = UT_IO_UNIT_SIZE; 5693c88819bSZiye Yang opts.max_aq_depth = UT_MAX_AQ_DEPTH; 5703c88819bSZiye Yang opts.num_shared_buffers = UT_NUM_SHARED_BUFFERS; 5710e983c56SKrzysztof Goreczny MOCK_SET(spdk_sock_group_create, &grp); 5724de405abSSeth Howell transport = nvmf_tcp_create(&opts); 5730e983c56SKrzysztof Goreczny MOCK_CLEAR_P(spdk_sock_group_create); 5743c88819bSZiye Yang CU_ASSERT_PTR_NOT_NULL(transport); 5753c88819bSZiye Yang transport->opts = opts; 57649bff95fSBen Walker MOCK_SET(spdk_sock_group_create, &grp); 5775e373163SJohn Levon group = nvmf_tcp_poll_group_create(transport, NULL); 57849bff95fSBen Walker MOCK_CLEAR_P(spdk_sock_group_create); 5793c88819bSZiye Yang SPDK_CU_ASSERT_FATAL(group); 58085fa4324SAlexey Marchuk if (opts.in_capsule_data_size < SPDK_NVME_TCP_IN_CAPSULE_DATA_MAX_SIZE) { 58185fa4324SAlexey Marchuk tgroup = SPDK_CONTAINEROF(group, struct spdk_nvmf_tcp_poll_group, group); 58285fa4324SAlexey Marchuk SPDK_CU_ASSERT_FATAL(tgroup->control_msg_list); 58385fa4324SAlexey Marchuk } 5843c88819bSZiye Yang group->transport = transport; 5854de405abSSeth Howell nvmf_tcp_poll_group_destroy(group); 5860d98a949SNaresh Gottumukkala nvmf_tcp_destroy(transport, NULL, NULL); 58794cd652bSZiye Yang 588f0956d33SZiye Yang fini_accel(); 5899cba82b9SBen Walker spdk_thread_exit(thread); 590e7ead00bSShuhei Matsumoto while (!spdk_thread_is_exited(thread)) { 591e7ead00bSShuhei Matsumoto spdk_thread_poll(thread, 0, 0); 592e7ead00bSShuhei Matsumoto } 593e036215fSBen Walker spdk_thread_destroy(thread); 5944c30f7fcSYanbo Zhou } 5954c30f7fcSYanbo Zhou 59616b85196SShuhei Matsumoto static void 59716b85196SShuhei Matsumoto test_nvmf_tcp_send_c2h_data(void) 59816b85196SShuhei Matsumoto { 59916b85196SShuhei Matsumoto struct spdk_thread *thread; 60016b85196SShuhei Matsumoto struct spdk_nvmf_tcp_transport ttransport = {}; 60116b85196SShuhei Matsumoto struct spdk_nvmf_tcp_qpair tqpair = {}; 60216b85196SShuhei Matsumoto struct spdk_nvmf_tcp_req tcp_req = {}; 60316b85196SShuhei Matsumoto struct nvme_tcp_pdu pdu = {}; 60416b85196SShuhei Matsumoto struct spdk_nvme_tcp_c2h_data_hdr *c2h_data; 60516b85196SShuhei Matsumoto 606b1144ce3SEd rodriguez ttransport.tcp_opts.c2h_success = true; 60716b85196SShuhei Matsumoto thread = spdk_thread_create(NULL, NULL); 60816b85196SShuhei Matsumoto SPDK_CU_ASSERT_FATAL(thread != NULL); 60916b85196SShuhei Matsumoto spdk_set_thread(thread); 61016b85196SShuhei Matsumoto 611a2adca79SBen Walker tcp_req.pdu = &pdu; 612a2adca79SBen Walker tcp_req.req.length = 300; 613988af676SZiye Yang tcp_req.req.qpair = &tqpair.qpair; 614a2adca79SBen Walker 61516b85196SShuhei Matsumoto tqpair.qpair.transport = &ttransport.transport; 61616b85196SShuhei Matsumoto 61716b85196SShuhei Matsumoto /* Set qpair state to make unrelated operations NOP */ 618b95aae63SKonrad Sztyber tqpair.state = NVMF_TCP_QPAIR_STATE_RUNNING; 61916b85196SShuhei Matsumoto tqpair.recv_state = NVME_TCP_PDU_RECV_STATE_ERROR; 62016b85196SShuhei Matsumoto 62116b85196SShuhei Matsumoto tcp_req.req.cmd = (union nvmf_h2c_msg *)&tcp_req.cmd; 62216b85196SShuhei Matsumoto 62316b85196SShuhei Matsumoto tcp_req.req.iov[0].iov_base = (void *)0xDEADBEEF; 624a2adca79SBen Walker tcp_req.req.iov[0].iov_len = 101; 62516b85196SShuhei Matsumoto tcp_req.req.iov[1].iov_base = (void *)0xFEEDBEEF; 626a2adca79SBen Walker tcp_req.req.iov[1].iov_len = 100; 62716b85196SShuhei Matsumoto tcp_req.req.iov[2].iov_base = (void *)0xC0FFEE; 628a2adca79SBen Walker tcp_req.req.iov[2].iov_len = 99; 62916b85196SShuhei Matsumoto tcp_req.req.iovcnt = 3; 630a2adca79SBen Walker tcp_req.req.length = 300; 63116b85196SShuhei Matsumoto 6324de405abSSeth Howell nvmf_tcp_send_c2h_data(&tqpair, &tcp_req); 63316b85196SShuhei Matsumoto 634ea65bf61SBen Walker c2h_data = &pdu.hdr.c2h_data; 635a2adca79SBen Walker CU_ASSERT(c2h_data->datao == 0); 63675a12cbfSSlawomir Ptak CU_ASSERT(c2h_data->datal == 300); 637a2adca79SBen Walker CU_ASSERT(c2h_data->common.plen == sizeof(*c2h_data) + 300); 63816b85196SShuhei Matsumoto CU_ASSERT(c2h_data->common.flags & SPDK_NVME_TCP_C2H_DATA_FLAGS_LAST_PDU); 639b1144ce3SEd rodriguez CU_ASSERT(c2h_data->common.flags & SPDK_NVME_TCP_C2H_DATA_FLAGS_SUCCESS); 64016b85196SShuhei Matsumoto 641a2adca79SBen Walker CU_ASSERT(pdu.data_iovcnt == 3); 642a2adca79SBen Walker CU_ASSERT((uint64_t)pdu.data_iov[0].iov_base == 0xDEADBEEF); 643a2adca79SBen Walker CU_ASSERT(pdu.data_iov[0].iov_len == 101); 644a2adca79SBen Walker CU_ASSERT((uint64_t)pdu.data_iov[1].iov_base == 0xFEEDBEEF); 645a2adca79SBen Walker CU_ASSERT(pdu.data_iov[1].iov_len == 100); 646a2adca79SBen Walker CU_ASSERT((uint64_t)pdu.data_iov[2].iov_base == 0xC0FFEE); 647a2adca79SBen Walker CU_ASSERT(pdu.data_iov[2].iov_len == 99); 64816b85196SShuhei Matsumoto 649b1144ce3SEd rodriguez tcp_req.pdu_in_use = false; 650b1144ce3SEd rodriguez tcp_req.rsp.cdw0 = 1; 651b1144ce3SEd rodriguez nvmf_tcp_send_c2h_data(&tqpair, &tcp_req); 652b1144ce3SEd rodriguez 653b1144ce3SEd rodriguez CU_ASSERT(c2h_data->common.flags & SPDK_NVME_TCP_C2H_DATA_FLAGS_LAST_PDU); 654b1144ce3SEd rodriguez CU_ASSERT((c2h_data->common.flags & SPDK_NVME_TCP_C2H_DATA_FLAGS_SUCCESS) == 0); 655b1144ce3SEd rodriguez 656b1144ce3SEd rodriguez ttransport.tcp_opts.c2h_success = false; 657b1144ce3SEd rodriguez tcp_req.pdu_in_use = false; 658b1144ce3SEd rodriguez tcp_req.rsp.cdw0 = 0; 659b1144ce3SEd rodriguez nvmf_tcp_send_c2h_data(&tqpair, &tcp_req); 660b1144ce3SEd rodriguez 661b1144ce3SEd rodriguez CU_ASSERT(c2h_data->common.flags & SPDK_NVME_TCP_C2H_DATA_FLAGS_LAST_PDU); 662b1144ce3SEd rodriguez CU_ASSERT((c2h_data->common.flags & SPDK_NVME_TCP_C2H_DATA_FLAGS_SUCCESS) == 0); 663b1144ce3SEd rodriguez 664b1144ce3SEd rodriguez tcp_req.pdu_in_use = false; 665b1144ce3SEd rodriguez tcp_req.rsp.cdw0 = 1; 666b1144ce3SEd rodriguez nvmf_tcp_send_c2h_data(&tqpair, &tcp_req); 667b1144ce3SEd rodriguez 668b1144ce3SEd rodriguez CU_ASSERT(c2h_data->common.flags & SPDK_NVME_TCP_C2H_DATA_FLAGS_LAST_PDU); 669b1144ce3SEd rodriguez CU_ASSERT((c2h_data->common.flags & SPDK_NVME_TCP_C2H_DATA_FLAGS_SUCCESS) == 0); 670b1144ce3SEd rodriguez 67116b85196SShuhei Matsumoto spdk_thread_exit(thread); 672e7ead00bSShuhei Matsumoto while (!spdk_thread_is_exited(thread)) { 673e7ead00bSShuhei Matsumoto spdk_thread_poll(thread, 0, 0); 674e7ead00bSShuhei Matsumoto } 67516b85196SShuhei Matsumoto spdk_thread_destroy(thread); 67616b85196SShuhei Matsumoto } 67716b85196SShuhei Matsumoto 678399529aaSBen Walker #define NVMF_TCP_PDU_MAX_H2C_DATA_SIZE (128 * 1024) 679399529aaSBen Walker 68016b85196SShuhei Matsumoto static void 68116b85196SShuhei Matsumoto test_nvmf_tcp_h2c_data_hdr_handle(void) 68216b85196SShuhei Matsumoto { 68316b85196SShuhei Matsumoto struct spdk_nvmf_tcp_transport ttransport = {}; 68416b85196SShuhei Matsumoto struct spdk_nvmf_tcp_qpair tqpair = {}; 68516b85196SShuhei Matsumoto struct nvme_tcp_pdu pdu = {}; 68616b85196SShuhei Matsumoto struct spdk_nvmf_tcp_req tcp_req = {}; 68716b85196SShuhei Matsumoto struct spdk_nvme_tcp_h2c_data_hdr *h2c_data; 68816b85196SShuhei Matsumoto 68916b85196SShuhei Matsumoto /* Set qpair state to make unrelated operations NOP */ 690b95aae63SKonrad Sztyber tqpair.state = NVMF_TCP_QPAIR_STATE_RUNNING; 69116b85196SShuhei Matsumoto tqpair.recv_state = NVME_TCP_PDU_RECV_STATE_ERROR; 692427cbb46SMengjinWu tqpair.resource_count = 1; 693427cbb46SMengjinWu tqpair.reqs = &tcp_req; 69416b85196SShuhei Matsumoto 69516b85196SShuhei Matsumoto tcp_req.req.iov[0].iov_base = (void *)0xDEADBEEF; 696a2adca79SBen Walker tcp_req.req.iov[0].iov_len = 101; 69716b85196SShuhei Matsumoto tcp_req.req.iov[1].iov_base = (void *)0xFEEDBEEF; 698a2adca79SBen Walker tcp_req.req.iov[1].iov_len = 99; 69916b85196SShuhei Matsumoto tcp_req.req.iovcnt = 2; 700a2adca79SBen Walker tcp_req.req.length = 200; 70160af3c00SRui Chang tcp_req.state = TCP_REQUEST_STATE_TRANSFERRING_HOST_TO_CONTROLLER; 70216b85196SShuhei Matsumoto 70316b85196SShuhei Matsumoto tcp_req.req.cmd = (union nvmf_h2c_msg *)&tcp_req.cmd; 70416b85196SShuhei Matsumoto tcp_req.req.cmd->nvme_cmd.cid = 1; 705427cbb46SMengjinWu tcp_req.ttag = 1; 70616b85196SShuhei Matsumoto 707ea65bf61SBen Walker h2c_data = &pdu.hdr.h2c_data; 70816b85196SShuhei Matsumoto h2c_data->cccid = 1; 709427cbb46SMengjinWu h2c_data->ttag = 1; 710a2adca79SBen Walker h2c_data->datao = 0; 711a2adca79SBen Walker h2c_data->datal = 200; 71216b85196SShuhei Matsumoto 7134de405abSSeth Howell nvmf_tcp_h2c_data_hdr_handle(&ttransport, &tqpair, &pdu); 71416b85196SShuhei Matsumoto 71516b85196SShuhei Matsumoto CU_ASSERT(pdu.data_iovcnt == 2); 716a2adca79SBen Walker CU_ASSERT((uint64_t)pdu.data_iov[0].iov_base == 0xDEADBEEF); 717a2adca79SBen Walker CU_ASSERT(pdu.data_iov[0].iov_len == 101); 71816b85196SShuhei Matsumoto CU_ASSERT((uint64_t)pdu.data_iov[1].iov_base == 0xFEEDBEEF); 719a2adca79SBen Walker CU_ASSERT(pdu.data_iov[1].iov_len == 99); 72016b85196SShuhei Matsumoto } 72116b85196SShuhei Matsumoto 722ab04d59cSjiaqizho 723ab04d59cSjiaqizho static void 724c9c7c281SJosh Soref test_nvmf_tcp_in_capsule_data_handle(void) 725ab04d59cSjiaqizho { 726ab04d59cSjiaqizho struct spdk_nvmf_tcp_transport ttransport = {}; 72718ede8d3SKrzysztof Goreczny struct spdk_nvmf_transport_ops ops = {}; 728ab04d59cSjiaqizho struct spdk_nvmf_tcp_qpair tqpair = {}; 729f8ac678eSZiye Yang struct nvme_tcp_pdu *pdu, pdu_in_progress = {}; 730ab04d59cSjiaqizho union nvmf_c2h_msg rsp0 = {}; 731ab04d59cSjiaqizho union nvmf_c2h_msg rsp = {}; 732ab04d59cSjiaqizho 733ab04d59cSjiaqizho struct spdk_nvmf_tcp_req tcp_req2 = {}; 734ab04d59cSjiaqizho struct spdk_nvmf_tcp_req tcp_req1 = {}; 735ab04d59cSjiaqizho 736ab04d59cSjiaqizho struct spdk_nvme_tcp_cmd *capsule_data; 737ab04d59cSjiaqizho struct spdk_nvmf_capsule_cmd *nvmf_capsule_data; 738ab04d59cSjiaqizho struct spdk_nvme_sgl_descriptor *sgl; 739ab04d59cSjiaqizho 740ab04d59cSjiaqizho struct spdk_nvmf_transport_poll_group *group; 741ab04d59cSjiaqizho struct spdk_nvmf_tcp_poll_group tcp_group = {}; 742ab04d59cSjiaqizho struct spdk_sock_group grp = {}; 743ab04d59cSjiaqizho 744f8ac678eSZiye Yang tqpair.pdu_in_progress = &pdu_in_progress; 745ab04d59cSjiaqizho ttransport.transport.opts.max_io_size = UT_MAX_IO_SIZE; 746ab04d59cSjiaqizho ttransport.transport.opts.io_unit_size = UT_IO_UNIT_SIZE; 74718ede8d3SKrzysztof Goreczny ttransport.transport.ops = &ops; 748c7d22538SKrzysztof Goreczny ops.req_get_buffers_done = nvmf_tcp_req_get_buffers_done; 749ab04d59cSjiaqizho 750ab04d59cSjiaqizho tcp_group.sock_group = &grp; 751ab04d59cSjiaqizho TAILQ_INIT(&tcp_group.qpairs); 752ab04d59cSjiaqizho group = &tcp_group.group; 753ab04d59cSjiaqizho group->transport = &ttransport.transport; 754ab04d59cSjiaqizho tqpair.group = &tcp_group; 755ab04d59cSjiaqizho 75660af3c00SRui Chang TAILQ_INIT(&tqpair.tcp_req_free_queue); 75760af3c00SRui Chang TAILQ_INIT(&tqpair.tcp_req_working_queue); 758a2adca79SBen Walker 75960af3c00SRui Chang TAILQ_INSERT_TAIL(&tqpair.tcp_req_free_queue, &tcp_req2, state_link); 760ab04d59cSjiaqizho tqpair.state_cntr[TCP_REQUEST_STATE_FREE]++; 761ab04d59cSjiaqizho tqpair.qpair.transport = &ttransport.transport; 762b95aae63SKonrad Sztyber tqpair.state = NVMF_TCP_QPAIR_STATE_RUNNING; 763ab04d59cSjiaqizho tqpair.recv_state = NVME_TCP_PDU_RECV_STATE_AWAIT_PDU_PSH; 764781d42adSKonrad Sztyber tqpair.qpair.state = SPDK_NVMF_QPAIR_ENABLED; 765ab04d59cSjiaqizho 766ab04d59cSjiaqizho /* init a null tcp_req into tqpair TCP_REQUEST_STATE_FREE queue */ 767ab04d59cSjiaqizho tcp_req2.req.qpair = &tqpair.qpair; 768ab04d59cSjiaqizho tcp_req2.req.cmd = (union nvmf_h2c_msg *)&tcp_req2.cmd; 769ab04d59cSjiaqizho tcp_req2.req.rsp = &rsp; 770ab04d59cSjiaqizho 771ab04d59cSjiaqizho /* init tcp_req1 */ 772ab04d59cSjiaqizho tcp_req1.req.qpair = &tqpair.qpair; 773ab04d59cSjiaqizho tcp_req1.req.cmd = (union nvmf_h2c_msg *)&tcp_req1.cmd; 774ab04d59cSjiaqizho tcp_req1.req.rsp = &rsp0; 775ab04d59cSjiaqizho tcp_req1.state = TCP_REQUEST_STATE_NEW; 776c7d22538SKrzysztof Goreczny tcp_req1.req.data_from_pool = false; 777ab04d59cSjiaqizho 77860af3c00SRui Chang TAILQ_INSERT_TAIL(&tqpair.tcp_req_working_queue, &tcp_req1, state_link); 779ab04d59cSjiaqizho tqpair.state_cntr[TCP_REQUEST_STATE_NEW]++; 780ab04d59cSjiaqizho 781ab04d59cSjiaqizho /* init pdu, make pdu need sgl buff */ 782f8ac678eSZiye Yang pdu = tqpair.pdu_in_progress; 783ea65bf61SBen Walker capsule_data = &pdu->hdr.capsule_cmd; 784ea65bf61SBen Walker nvmf_capsule_data = (struct spdk_nvmf_capsule_cmd *)&pdu->hdr.capsule_cmd.ccsqe; 785ab04d59cSjiaqizho sgl = &capsule_data->ccsqe.dptr.sgl1; 786ab04d59cSjiaqizho 787ab04d59cSjiaqizho capsule_data->common.pdu_type = SPDK_NVME_TCP_PDU_TYPE_CAPSULE_CMD; 788ab04d59cSjiaqizho capsule_data->common.hlen = sizeof(*capsule_data); 789ab04d59cSjiaqizho capsule_data->common.plen = 1096; 790ab04d59cSjiaqizho capsule_data->ccsqe.opc = SPDK_NVME_OPC_FABRIC; 791ab04d59cSjiaqizho 792ab04d59cSjiaqizho sgl->unkeyed.subtype = SPDK_NVME_SGL_SUBTYPE_TRANSPORT; 793ab04d59cSjiaqizho sgl->generic.type = SPDK_NVME_SGL_TYPE_TRANSPORT_DATA_BLOCK; 794ab04d59cSjiaqizho sgl->unkeyed.length = UT_IO_UNIT_SIZE; 795ab04d59cSjiaqizho 796ab04d59cSjiaqizho nvmf_capsule_data->fctype = SPDK_NVMF_FABRIC_COMMAND_CONNECT; 797ab04d59cSjiaqizho 798c7d22538SKrzysztof Goreczny /* pretend that tcp_req1 is waiting in the iobuf waiting queue */ 7994de405abSSeth Howell nvmf_tcp_req_process(&ttransport, &tcp_req1); 800c7d22538SKrzysztof Goreczny CU_ASSERT(tcp_req1.req.data_from_pool == false); 801ab04d59cSjiaqizho 802ab04d59cSjiaqizho sgl->unkeyed.length = UT_IO_UNIT_SIZE - 1; 803ab04d59cSjiaqizho 804c7d22538SKrzysztof Goreczny /* process tqpair capsule req. */ 805f8ac678eSZiye Yang nvmf_tcp_capsule_cmd_hdr_handle(&ttransport, &tqpair, tqpair.pdu_in_progress); 806ab04d59cSjiaqizho CU_ASSERT(tqpair.recv_state == NVME_TCP_PDU_RECV_STATE_AWAIT_PDU_PAYLOAD); 807f8ac678eSZiye Yang CU_ASSERT(tqpair.pdu_in_progress->req == (void *)&tcp_req2); 808c7d22538SKrzysztof Goreczny 809c7d22538SKrzysztof Goreczny /* pretend that buffer for tcp_req1 becomes available */ 810c7d22538SKrzysztof Goreczny spdk_nvmf_request_get_buffers(&tcp_req1.req, group, &ttransport.transport, UT_IO_UNIT_SIZE - 1); 811c7d22538SKrzysztof Goreczny /* trigger callback as nvmf_request_iobuf_get_cb would */ 812c7d22538SKrzysztof Goreczny ttransport.transport.ops->req_get_buffers_done(&tcp_req1.req); 813c7d22538SKrzysztof Goreczny CU_ASSERT(tcp_req1.state == TCP_REQUEST_STATE_TRANSFERRING_HOST_TO_CONTROLLER); 814ab04d59cSjiaqizho } 815ab04d59cSjiaqizho 8160d1c7bf8SMao Jiang static void 8170d1c7bf8SMao Jiang test_nvmf_tcp_qpair_init_mem_resource(void) 8180d1c7bf8SMao Jiang { 8190d1c7bf8SMao Jiang int rc; 8200d1c7bf8SMao Jiang struct spdk_nvmf_tcp_qpair *tqpair = NULL; 8210d1c7bf8SMao Jiang struct spdk_nvmf_transport transport = {}; 8223056c8acSKonrad Sztyber struct spdk_thread *thread; 8233056c8acSKonrad Sztyber 8243056c8acSKonrad Sztyber thread = spdk_thread_create(NULL, NULL); 8253056c8acSKonrad Sztyber SPDK_CU_ASSERT_FATAL(thread != NULL); 8263056c8acSKonrad Sztyber spdk_set_thread(thread); 8270d1c7bf8SMao Jiang 8280d1c7bf8SMao Jiang tqpair = calloc(1, sizeof(*tqpair)); 8290d1c7bf8SMao Jiang tqpair->qpair.transport = &transport; 8300d1c7bf8SMao Jiang 8310d1c7bf8SMao Jiang nvmf_tcp_opts_init(&transport.opts); 8325eb3239cSMengjinWu CU_ASSERT(transport.opts.max_queue_depth == SPDK_NVMF_TCP_DEFAULT_MAX_IO_QUEUE_DEPTH); 8330d1c7bf8SMao Jiang CU_ASSERT(transport.opts.max_qpairs_per_ctrlr == SPDK_NVMF_TCP_DEFAULT_MAX_QPAIRS_PER_CTRLR); 8340d1c7bf8SMao Jiang CU_ASSERT(transport.opts.in_capsule_data_size == SPDK_NVMF_TCP_DEFAULT_IN_CAPSULE_DATA_SIZE); 8350d1c7bf8SMao Jiang CU_ASSERT(transport.opts.max_io_size == SPDK_NVMF_TCP_DEFAULT_MAX_IO_SIZE); 8360d1c7bf8SMao Jiang CU_ASSERT(transport.opts.io_unit_size == SPDK_NVMF_TCP_DEFAULT_IO_UNIT_SIZE); 8375eb3239cSMengjinWu CU_ASSERT(transport.opts.max_aq_depth == SPDK_NVMF_TCP_DEFAULT_MAX_ADMIN_QUEUE_DEPTH); 8380d1c7bf8SMao Jiang CU_ASSERT(transport.opts.num_shared_buffers == SPDK_NVMF_TCP_DEFAULT_NUM_SHARED_BUFFERS); 8390d1c7bf8SMao Jiang CU_ASSERT(transport.opts.buf_cache_size == SPDK_NVMF_TCP_DEFAULT_BUFFER_CACHE_SIZE); 8400d1c7bf8SMao Jiang CU_ASSERT(transport.opts.dif_insert_or_strip == SPDK_NVMF_TCP_DEFAULT_DIF_INSERT_OR_STRIP); 8410d1c7bf8SMao Jiang CU_ASSERT(transport.opts.abort_timeout_sec == SPDK_NVMF_TCP_DEFAULT_ABORT_TIMEOUT_SEC); 8420d1c7bf8SMao Jiang CU_ASSERT(transport.opts.transport_specific == NULL); 8430d1c7bf8SMao Jiang 8440d1c7bf8SMao Jiang rc = nvmf_tcp_qpair_init(&tqpair->qpair); 8450d1c7bf8SMao Jiang CU_ASSERT(rc == 0); 8460d1c7bf8SMao Jiang CU_ASSERT(tqpair->host_hdgst_enable == true); 8470d1c7bf8SMao Jiang CU_ASSERT(tqpair->host_ddgst_enable == true); 8480d1c7bf8SMao Jiang 8490d1c7bf8SMao Jiang rc = nvmf_tcp_qpair_init_mem_resource(tqpair); 8500d1c7bf8SMao Jiang CU_ASSERT(rc == 0); 8515eb3239cSMengjinWu CU_ASSERT(tqpair->resource_count == SPDK_NVMF_TCP_DEFAULT_MAX_IO_QUEUE_DEPTH); 8520d1c7bf8SMao Jiang CU_ASSERT(tqpair->reqs != NULL); 8530d1c7bf8SMao Jiang CU_ASSERT(tqpair->bufs != NULL); 8540d1c7bf8SMao Jiang CU_ASSERT(tqpair->pdus != NULL); 8550d1c7bf8SMao Jiang /* Just to check the first and last entry */ 8560d1c7bf8SMao Jiang CU_ASSERT(tqpair->reqs[0].ttag == 1); 8570d1c7bf8SMao Jiang CU_ASSERT(tqpair->reqs[0].req.qpair == &tqpair->qpair); 8580d1c7bf8SMao Jiang CU_ASSERT(tqpair->reqs[0].pdu == &tqpair->pdus[0]); 8590d1c7bf8SMao Jiang CU_ASSERT(tqpair->reqs[0].pdu->qpair == &tqpair->qpair); 8600d1c7bf8SMao Jiang CU_ASSERT(tqpair->reqs[0].buf == (void *)((uintptr_t)tqpair->bufs)); 8610d1c7bf8SMao Jiang CU_ASSERT(tqpair->reqs[0].req.rsp == (void *)&tqpair->reqs[0].rsp); 8620d1c7bf8SMao Jiang CU_ASSERT(tqpair->reqs[0].req.cmd == (void *)&tqpair->reqs[0].cmd); 8630d1c7bf8SMao Jiang CU_ASSERT(tqpair->reqs[0].state == TCP_REQUEST_STATE_FREE); 8640d1c7bf8SMao Jiang CU_ASSERT(tqpair->reqs[127].ttag == 128); 8650d1c7bf8SMao Jiang CU_ASSERT(tqpair->reqs[127].req.qpair == &tqpair->qpair); 8660d1c7bf8SMao Jiang CU_ASSERT(tqpair->reqs[127].pdu == &tqpair->pdus[127]); 8670d1c7bf8SMao Jiang CU_ASSERT(tqpair->reqs[127].pdu->qpair == &tqpair->qpair); 8680d1c7bf8SMao Jiang CU_ASSERT(tqpair->reqs[127].buf == (void *)((uintptr_t)tqpair->bufs) + 127 * 4096); 8690d1c7bf8SMao Jiang CU_ASSERT(tqpair->reqs[127].req.rsp == (void *)&tqpair->reqs[127].rsp); 8700d1c7bf8SMao Jiang CU_ASSERT(tqpair->reqs[127].req.cmd == (void *)&tqpair->reqs[127].cmd); 8710d1c7bf8SMao Jiang CU_ASSERT(tqpair->reqs[127].state == TCP_REQUEST_STATE_FREE); 8725eb3239cSMengjinWu CU_ASSERT(tqpair->state_cntr[TCP_REQUEST_STATE_FREE] == SPDK_NVMF_TCP_DEFAULT_MAX_IO_QUEUE_DEPTH); 8735eb3239cSMengjinWu CU_ASSERT(tqpair->mgmt_pdu == &tqpair->pdus[2 * SPDK_NVMF_TCP_DEFAULT_MAX_IO_QUEUE_DEPTH]); 8740d1c7bf8SMao Jiang CU_ASSERT(tqpair->mgmt_pdu->qpair == tqpair); 8755eb3239cSMengjinWu CU_ASSERT(tqpair->pdu_in_progress == 8765eb3239cSMengjinWu &tqpair->pdus[2 * SPDK_NVMF_TCP_DEFAULT_MAX_IO_QUEUE_DEPTH - 1]); 8770d1c7bf8SMao Jiang CU_ASSERT(tqpair->recv_buf_size == (4096 + sizeof(struct spdk_nvme_tcp_cmd) + 2 * 8780d1c7bf8SMao Jiang SPDK_NVME_TCP_DIGEST_LEN) * SPDK_NVMF_TCP_RECV_BUF_SIZE_FACTOR); 8790d1c7bf8SMao Jiang 8800d1c7bf8SMao Jiang /* Free all of tqpair resource */ 8810d1c7bf8SMao Jiang nvmf_tcp_qpair_destroy(tqpair); 8823056c8acSKonrad Sztyber 8833056c8acSKonrad Sztyber spdk_thread_exit(thread); 8843056c8acSKonrad Sztyber while (!spdk_thread_is_exited(thread)) { 8853056c8acSKonrad Sztyber spdk_thread_poll(thread, 0, 0); 8863056c8acSKonrad Sztyber } 8873056c8acSKonrad Sztyber spdk_thread_destroy(thread); 8880d1c7bf8SMao Jiang } 8890d1c7bf8SMao Jiang 890be4e9db7SChengqiangMeng static void 891be4e9db7SChengqiangMeng test_nvmf_tcp_send_c2h_term_req(void) 892be4e9db7SChengqiangMeng { 893be4e9db7SChengqiangMeng struct spdk_nvmf_tcp_qpair tqpair = {}; 894be4e9db7SChengqiangMeng struct nvme_tcp_pdu pdu = {}, mgmt_pdu = {}, pdu_in_progress = {}; 895be4e9db7SChengqiangMeng enum spdk_nvme_tcp_term_req_fes fes = SPDK_NVME_TCP_TERM_REQ_FES_INVALID_HEADER_FIELD; 896be4e9db7SChengqiangMeng uint32_t error_offset = 1; 897be4e9db7SChengqiangMeng 898be4e9db7SChengqiangMeng mgmt_pdu.qpair = &tqpair; 899be4e9db7SChengqiangMeng tqpair.mgmt_pdu = &mgmt_pdu; 900be4e9db7SChengqiangMeng tqpair.pdu_in_progress = &pdu_in_progress; 90178df9be4SBen Walker tqpair.tcp_pdu_working_count = 1; 902be4e9db7SChengqiangMeng 903be4e9db7SChengqiangMeng /* case1: hlen < SPDK_NVME_TCP_TERM_REQ_ERROR_DATA_MAX_SIZE, Expect: copy_len == hlen */ 904be4e9db7SChengqiangMeng pdu.hdr.common.hlen = 64; 905be4e9db7SChengqiangMeng nvmf_tcp_send_c2h_term_req(&tqpair, &pdu, fes, error_offset); 90678df9be4SBen Walker CU_ASSERT(tqpair.recv_state == NVME_TCP_PDU_RECV_STATE_QUIESCING); 907be4e9db7SChengqiangMeng CU_ASSERT(tqpair.mgmt_pdu->hdr.term_req.common.hlen == sizeof(struct spdk_nvme_tcp_term_req_hdr)); 908be4e9db7SChengqiangMeng CU_ASSERT(tqpair.mgmt_pdu->hdr.term_req.common.plen == tqpair.mgmt_pdu->hdr.term_req.common.hlen + 909be4e9db7SChengqiangMeng pdu.hdr.common.hlen); 910be4e9db7SChengqiangMeng CU_ASSERT(tqpair.mgmt_pdu->hdr.term_req.common.pdu_type == SPDK_NVME_TCP_PDU_TYPE_C2H_TERM_REQ); 911b5aeff1dSMengjinWu CU_ASSERT(tqpair.mgmt_pdu->hdr.term_req.fes == SPDK_NVME_TCP_TERM_REQ_FES_INVALID_HEADER_FIELD); 912be4e9db7SChengqiangMeng 913be4e9db7SChengqiangMeng /* case2: hlen > SPDK_NVME_TCP_TERM_REQ_ERROR_DATA_MAX_SIZE, Expect: copy_len == SPDK_NVME_TCP_TERM_REQ_ERROR_DATA_MAX_SIZE */ 914be4e9db7SChengqiangMeng pdu.hdr.common.hlen = 255; 915be4e9db7SChengqiangMeng nvmf_tcp_send_c2h_term_req(&tqpair, &pdu, fes, error_offset); 91678df9be4SBen Walker CU_ASSERT(tqpair.recv_state == NVME_TCP_PDU_RECV_STATE_QUIESCING); 917be4e9db7SChengqiangMeng CU_ASSERT(tqpair.mgmt_pdu->hdr.term_req.common.hlen == sizeof(struct spdk_nvme_tcp_term_req_hdr)); 918be4e9db7SChengqiangMeng CU_ASSERT(tqpair.mgmt_pdu->hdr.term_req.common.plen == (unsigned) 919be4e9db7SChengqiangMeng tqpair.mgmt_pdu->hdr.term_req.common.hlen + SPDK_NVME_TCP_TERM_REQ_ERROR_DATA_MAX_SIZE); 920be4e9db7SChengqiangMeng CU_ASSERT(tqpair.mgmt_pdu->hdr.term_req.common.pdu_type == SPDK_NVME_TCP_PDU_TYPE_C2H_TERM_REQ); 921b5aeff1dSMengjinWu CU_ASSERT(tqpair.mgmt_pdu->hdr.term_req.fes == SPDK_NVME_TCP_TERM_REQ_FES_INVALID_HEADER_FIELD); 922be4e9db7SChengqiangMeng } 923be4e9db7SChengqiangMeng 924476a77f9SMao Jiang static void 925476a77f9SMao Jiang test_nvmf_tcp_send_capsule_resp_pdu(void) 926476a77f9SMao Jiang { 927476a77f9SMao Jiang struct spdk_nvmf_tcp_req tcp_req = {}; 928476a77f9SMao Jiang struct spdk_nvmf_tcp_qpair tqpair = {}; 929476a77f9SMao Jiang struct nvme_tcp_pdu pdu = {}; 930476a77f9SMao Jiang 931476a77f9SMao Jiang tcp_req.pdu_in_use = false; 932476a77f9SMao Jiang tcp_req.req.qpair = &tqpair.qpair; 933476a77f9SMao Jiang tcp_req.pdu = &pdu; 934476a77f9SMao Jiang tcp_req.req.rsp = (union nvmf_c2h_msg *)&tcp_req.rsp; 935476a77f9SMao Jiang tcp_req.req.cmd = (union nvmf_h2c_msg *)&tcp_req.cmd; 936476a77f9SMao Jiang tqpair.host_hdgst_enable = true; 937476a77f9SMao Jiang 938476a77f9SMao Jiang nvmf_tcp_send_capsule_resp_pdu(&tcp_req, &tqpair); 939476a77f9SMao Jiang CU_ASSERT(pdu.hdr.capsule_resp.common.pdu_type == SPDK_NVME_TCP_PDU_TYPE_CAPSULE_RESP); 940476a77f9SMao Jiang CU_ASSERT(pdu.hdr.capsule_resp.common.plen == sizeof(struct spdk_nvme_tcp_rsp) + 941476a77f9SMao Jiang SPDK_NVME_TCP_DIGEST_LEN); 942476a77f9SMao Jiang CU_ASSERT(pdu.hdr.capsule_resp.common.hlen == sizeof(struct spdk_nvme_tcp_rsp)); 943476a77f9SMao Jiang CU_ASSERT(!memcmp(&pdu.hdr.capsule_resp.rccqe, &tcp_req.req.rsp->nvme_cpl, 944476a77f9SMao Jiang sizeof(struct spdk_nvme_cpl))); 945476a77f9SMao Jiang CU_ASSERT(pdu.hdr.capsule_resp.common.flags & SPDK_NVME_TCP_CH_FLAGS_HDGSTF); 946476a77f9SMao Jiang CU_ASSERT(pdu.cb_fn == nvmf_tcp_request_free); 947476a77f9SMao Jiang CU_ASSERT(pdu.cb_arg == &tcp_req); 948476a77f9SMao Jiang CU_ASSERT(pdu.iov[0].iov_base == &pdu.hdr.raw); 949476a77f9SMao Jiang CU_ASSERT(pdu.iov[0].iov_len == sizeof(struct spdk_nvme_tcp_rsp) + SPDK_NVME_TCP_DIGEST_LEN); 950476a77f9SMao Jiang 951476a77f9SMao Jiang /* hdgst disable */ 952476a77f9SMao Jiang tqpair.host_hdgst_enable = false; 953476a77f9SMao Jiang tcp_req.pdu_in_use = false; 954476a77f9SMao Jiang memset(&pdu, 0, sizeof(pdu)); 955476a77f9SMao Jiang 956476a77f9SMao Jiang nvmf_tcp_send_capsule_resp_pdu(&tcp_req, &tqpair); 957476a77f9SMao Jiang CU_ASSERT(pdu.hdr.capsule_resp.common.pdu_type == SPDK_NVME_TCP_PDU_TYPE_CAPSULE_RESP); 958476a77f9SMao Jiang CU_ASSERT(pdu.hdr.capsule_resp.common.plen == sizeof(struct spdk_nvme_tcp_rsp)); 959476a77f9SMao Jiang CU_ASSERT(pdu.hdr.capsule_resp.common.hlen == sizeof(struct spdk_nvme_tcp_rsp)); 960476a77f9SMao Jiang CU_ASSERT(!memcmp(&pdu.hdr.capsule_resp.rccqe, &tcp_req.req.rsp->nvme_cpl, 961476a77f9SMao Jiang sizeof(struct spdk_nvme_cpl))); 962476a77f9SMao Jiang CU_ASSERT(!(pdu.hdr.capsule_resp.common.flags & SPDK_NVME_TCP_CH_FLAGS_HDGSTF)); 963476a77f9SMao Jiang CU_ASSERT(pdu.cb_fn == nvmf_tcp_request_free); 964476a77f9SMao Jiang CU_ASSERT(pdu.cb_arg == &tcp_req); 965476a77f9SMao Jiang CU_ASSERT(pdu.iov[0].iov_base == &pdu.hdr.raw); 966476a77f9SMao Jiang CU_ASSERT(pdu.iov[0].iov_len == sizeof(struct spdk_nvme_tcp_rsp)); 967476a77f9SMao Jiang } 968476a77f9SMao Jiang 969a2838de9SChengqiangMeng static void 970a2838de9SChengqiangMeng test_nvmf_tcp_icreq_handle(void) 971a2838de9SChengqiangMeng { 972a2838de9SChengqiangMeng struct spdk_nvmf_tcp_transport ttransport = {}; 973a2838de9SChengqiangMeng struct spdk_nvmf_tcp_qpair tqpair = {}; 974a2838de9SChengqiangMeng struct nvme_tcp_pdu pdu = {}; 975a2838de9SChengqiangMeng struct nvme_tcp_pdu mgmt_pdu = {}; 976a2838de9SChengqiangMeng struct nvme_tcp_pdu pdu_in_progress = {}; 977a2838de9SChengqiangMeng struct spdk_nvme_tcp_ic_resp *ic_resp; 978a2838de9SChengqiangMeng 979a2838de9SChengqiangMeng mgmt_pdu.qpair = &tqpair; 980a2838de9SChengqiangMeng tqpair.mgmt_pdu = &mgmt_pdu; 981a2838de9SChengqiangMeng tqpair.pdu_in_progress = &pdu_in_progress; 98278df9be4SBen Walker tqpair.tcp_pdu_working_count = 1; 983a2838de9SChengqiangMeng 984a2838de9SChengqiangMeng /* case 1: Expected ICReq PFV 0 and got are different. */ 985a2838de9SChengqiangMeng pdu.hdr.ic_req.pfv = 1; 986a2838de9SChengqiangMeng 987a2838de9SChengqiangMeng nvmf_tcp_icreq_handle(&ttransport, &tqpair, &pdu); 988a2838de9SChengqiangMeng 98978df9be4SBen Walker CU_ASSERT(tqpair.recv_state == NVME_TCP_PDU_RECV_STATE_QUIESCING); 990a2838de9SChengqiangMeng 9911d723028SMengjinWu /* case 2: Expected ICReq HPDA in range 0-31 and got are different. */ 9921d723028SMengjinWu pdu.hdr.ic_req.hpda = SPDK_NVME_TCP_HPDA_MAX + 1; 9931d723028SMengjinWu 9941d723028SMengjinWu nvmf_tcp_icreq_handle(&ttransport, &tqpair, &pdu); 9951d723028SMengjinWu 99678df9be4SBen Walker CU_ASSERT(tqpair.recv_state == NVME_TCP_PDU_RECV_STATE_QUIESCING); 9971d723028SMengjinWu 9981d723028SMengjinWu /* case 3: Expect: PASS. */ 999a2838de9SChengqiangMeng ttransport.transport.opts.max_io_size = 32; 1000a2838de9SChengqiangMeng pdu.hdr.ic_req.pfv = 0; 1001a2838de9SChengqiangMeng tqpair.host_hdgst_enable = false; 1002a2838de9SChengqiangMeng tqpair.host_ddgst_enable = false; 1003a2838de9SChengqiangMeng tqpair.recv_buf_size = 64; 1004a2838de9SChengqiangMeng pdu.hdr.ic_req.hpda = 16; 1005a2838de9SChengqiangMeng 1006a2838de9SChengqiangMeng nvmf_tcp_icreq_handle(&ttransport, &tqpair, &pdu); 1007a2838de9SChengqiangMeng 1008a2838de9SChengqiangMeng ic_resp = &tqpair.mgmt_pdu->hdr.ic_resp; 1009a2838de9SChengqiangMeng CU_ASSERT(tqpair.recv_buf_size == MIN_SOCK_PIPE_SIZE); 1010a2838de9SChengqiangMeng CU_ASSERT(tqpair.cpda == pdu.hdr.ic_req.hpda); 1011a2838de9SChengqiangMeng CU_ASSERT(ic_resp->common.pdu_type == SPDK_NVME_TCP_PDU_TYPE_IC_RESP); 1012a2838de9SChengqiangMeng CU_ASSERT(ic_resp->common.hlen == sizeof(struct spdk_nvme_tcp_ic_resp)); 1013a2838de9SChengqiangMeng CU_ASSERT(ic_resp->common.plen == sizeof(struct spdk_nvme_tcp_ic_resp)); 1014a2838de9SChengqiangMeng CU_ASSERT(ic_resp->pfv == 0); 1015a2838de9SChengqiangMeng CU_ASSERT(ic_resp->cpda == tqpair.cpda); 1016a2838de9SChengqiangMeng CU_ASSERT(ic_resp->maxh2cdata == ttransport.transport.opts.max_io_size); 1017a2838de9SChengqiangMeng CU_ASSERT(ic_resp->dgst.bits.hdgst_enable == 0); 1018a2838de9SChengqiangMeng CU_ASSERT(ic_resp->dgst.bits.ddgst_enable == 0); 1019a2838de9SChengqiangMeng CU_ASSERT(tqpair.recv_state == NVME_TCP_PDU_RECV_STATE_AWAIT_PDU_READY); 1020a2838de9SChengqiangMeng } 1021a2838de9SChengqiangMeng 1022f7b9f80bSmatthewb static void 1023f7b9f80bSmatthewb test_nvmf_tcp_check_xfer_type(void) 1024f7b9f80bSmatthewb { 1025f7b9f80bSmatthewb const uint16_t cid = 0xAA; 1026f7b9f80bSmatthewb struct spdk_nvmf_tcp_transport ttransport = {}; 1027f7b9f80bSmatthewb struct spdk_nvmf_tcp_qpair tqpair = {}; 1028f7b9f80bSmatthewb struct nvme_tcp_pdu pdu_in_progress = {}; 1029f7b9f80bSmatthewb union nvmf_c2h_msg rsp0 = {}; 1030f7b9f80bSmatthewb 1031f7b9f80bSmatthewb struct spdk_nvmf_tcp_req tcp_req = {}; 1032f7b9f80bSmatthewb struct nvme_tcp_pdu rsp_pdu = {}; 1033f7b9f80bSmatthewb 1034f7b9f80bSmatthewb struct spdk_nvme_tcp_cmd *capsule_data; 1035f7b9f80bSmatthewb struct spdk_nvme_sgl_descriptor *sgl; 1036f7b9f80bSmatthewb 1037f7b9f80bSmatthewb struct spdk_nvmf_transport_poll_group *group; 1038f7b9f80bSmatthewb struct spdk_nvmf_tcp_poll_group tcp_group = {}; 1039f7b9f80bSmatthewb struct spdk_sock_group grp = {}; 1040f7b9f80bSmatthewb 1041f7b9f80bSmatthewb tqpair.pdu_in_progress = &pdu_in_progress; 1042f7b9f80bSmatthewb ttransport.transport.opts.max_io_size = UT_MAX_IO_SIZE; 1043f7b9f80bSmatthewb ttransport.transport.opts.io_unit_size = UT_IO_UNIT_SIZE; 1044f7b9f80bSmatthewb 1045f7b9f80bSmatthewb tcp_group.sock_group = &grp; 1046f7b9f80bSmatthewb TAILQ_INIT(&tcp_group.qpairs); 1047f7b9f80bSmatthewb group = &tcp_group.group; 1048f7b9f80bSmatthewb group->transport = &ttransport.transport; 1049f7b9f80bSmatthewb tqpair.group = &tcp_group; 1050f7b9f80bSmatthewb 1051f7b9f80bSmatthewb TAILQ_INIT(&tqpair.tcp_req_free_queue); 1052f7b9f80bSmatthewb TAILQ_INIT(&tqpair.tcp_req_working_queue); 1053f7b9f80bSmatthewb 1054f7b9f80bSmatthewb tqpair.qpair.transport = &ttransport.transport; 1055b95aae63SKonrad Sztyber tqpair.state = NVMF_TCP_QPAIR_STATE_RUNNING; 1056f7b9f80bSmatthewb tqpair.recv_state = NVME_TCP_PDU_RECV_STATE_AWAIT_PDU_PSH; 1057781d42adSKonrad Sztyber tqpair.qpair.state = SPDK_NVMF_QPAIR_ENABLED; 1058f7b9f80bSmatthewb 1059f7b9f80bSmatthewb /* init tcp_req */ 1060f7b9f80bSmatthewb tcp_req.req.qpair = &tqpair.qpair; 1061f7b9f80bSmatthewb tcp_req.pdu = &rsp_pdu; 1062f7b9f80bSmatthewb tcp_req.req.cmd = (union nvmf_h2c_msg *)&tcp_req.cmd; 1063f7b9f80bSmatthewb tcp_req.req.rsp = &rsp0; 1064f7b9f80bSmatthewb tcp_req.state = TCP_REQUEST_STATE_NEW; 1065f7b9f80bSmatthewb 1066f7b9f80bSmatthewb TAILQ_INSERT_TAIL(&tqpair.tcp_req_working_queue, &tcp_req, state_link); 1067f7b9f80bSmatthewb tqpair.state_cntr[TCP_REQUEST_STATE_NEW]++; 1068f7b9f80bSmatthewb 1069f7b9f80bSmatthewb /* init pdu, make pdu need sgl buff */ 1070f7b9f80bSmatthewb capsule_data = &tqpair.pdu_in_progress->hdr.capsule_cmd; 1071f7b9f80bSmatthewb sgl = &capsule_data->ccsqe.dptr.sgl1; 1072f7b9f80bSmatthewb 1073f7b9f80bSmatthewb capsule_data->common.pdu_type = SPDK_NVME_TCP_PDU_TYPE_CAPSULE_CMD; 1074f7b9f80bSmatthewb capsule_data->common.hlen = sizeof(*capsule_data); 1075f7b9f80bSmatthewb capsule_data->common.plen = 1096; 1076f7b9f80bSmatthewb capsule_data->ccsqe.opc = 0x10 | SPDK_NVME_DATA_BIDIRECTIONAL; 1077f7b9f80bSmatthewb /* Need to set to a non zero valid to check it gets copied to the response */ 1078f7b9f80bSmatthewb capsule_data->ccsqe.cid = cid; 1079f7b9f80bSmatthewb 1080f7b9f80bSmatthewb /* Set up SGL to ensure nvmf_tcp_req_parse_sgl returns an error */ 1081f7b9f80bSmatthewb sgl->unkeyed.subtype = SPDK_NVME_SGL_SUBTYPE_TRANSPORT; 1082f7b9f80bSmatthewb sgl->generic.type = SPDK_NVME_SGL_TYPE_TRANSPORT_DATA_BLOCK; 1083f7b9f80bSmatthewb sgl->unkeyed.length = UT_IO_UNIT_SIZE; 1084f7b9f80bSmatthewb 1085f7b9f80bSmatthewb /* Process a command and ensure that it fails and the request is set up to return an error */ 1086f7b9f80bSmatthewb nvmf_tcp_req_process(&ttransport, &tcp_req); 1087f7b9f80bSmatthewb CU_ASSERT(tcp_req.state == TCP_REQUEST_STATE_TRANSFERRING_CONTROLLER_TO_HOST); 1088f7b9f80bSmatthewb CU_ASSERT(tqpair.recv_state == NVME_TCP_PDU_RECV_STATE_AWAIT_PDU_READY); 1089f7b9f80bSmatthewb CU_ASSERT(tcp_req.req.rsp->nvme_cpl.cid == cid); 1090f7b9f80bSmatthewb CU_ASSERT(tcp_req.req.rsp->nvme_cpl.status.sct == SPDK_NVME_SCT_GENERIC); 1091f7b9f80bSmatthewb CU_ASSERT(tcp_req.req.rsp->nvme_cpl.status.sc == SPDK_NVME_SC_INVALID_OPCODE); 1092f7b9f80bSmatthewb } 1093f7b9f80bSmatthewb 1094f7b9f80bSmatthewb static void 1095f7b9f80bSmatthewb test_nvmf_tcp_invalid_sgl(void) 1096f7b9f80bSmatthewb { 1097f7b9f80bSmatthewb const uint16_t cid = 0xAABB; 1098f7b9f80bSmatthewb struct spdk_nvmf_tcp_transport ttransport = {}; 1099f7b9f80bSmatthewb struct spdk_nvmf_tcp_qpair tqpair = {}; 1100f7b9f80bSmatthewb struct nvme_tcp_pdu pdu_in_progress = {}; 1101f7b9f80bSmatthewb union nvmf_c2h_msg rsp0 = {}; 1102f7b9f80bSmatthewb 1103f7b9f80bSmatthewb struct spdk_nvmf_tcp_req tcp_req = {}; 1104f7b9f80bSmatthewb struct nvme_tcp_pdu rsp_pdu = {}; 11058ed53eeeSMengjinWu struct nvme_tcp_pdu mgmt_pdu = {}; 1106f7b9f80bSmatthewb 1107f7b9f80bSmatthewb struct spdk_nvme_tcp_cmd *capsule_data; 1108f7b9f80bSmatthewb struct spdk_nvme_sgl_descriptor *sgl; 1109f7b9f80bSmatthewb 1110f7b9f80bSmatthewb struct spdk_nvmf_transport_poll_group *group; 1111f7b9f80bSmatthewb struct spdk_nvmf_tcp_poll_group tcp_group = {}; 1112f7b9f80bSmatthewb struct spdk_sock_group grp = {}; 1113f7b9f80bSmatthewb 1114f7b9f80bSmatthewb tqpair.pdu_in_progress = &pdu_in_progress; 1115f7b9f80bSmatthewb ttransport.transport.opts.max_io_size = UT_MAX_IO_SIZE; 1116f7b9f80bSmatthewb ttransport.transport.opts.io_unit_size = UT_IO_UNIT_SIZE; 1117f7b9f80bSmatthewb 1118f7b9f80bSmatthewb tcp_group.sock_group = &grp; 1119f7b9f80bSmatthewb TAILQ_INIT(&tcp_group.qpairs); 1120f7b9f80bSmatthewb group = &tcp_group.group; 1121f7b9f80bSmatthewb group->transport = &ttransport.transport; 1122f7b9f80bSmatthewb tqpair.group = &tcp_group; 1123f7b9f80bSmatthewb 1124f7b9f80bSmatthewb TAILQ_INIT(&tqpair.tcp_req_free_queue); 1125f7b9f80bSmatthewb TAILQ_INIT(&tqpair.tcp_req_working_queue); 1126f7b9f80bSmatthewb 1127f7b9f80bSmatthewb tqpair.qpair.transport = &ttransport.transport; 1128b95aae63SKonrad Sztyber tqpair.state = NVMF_TCP_QPAIR_STATE_RUNNING; 1129f7b9f80bSmatthewb tqpair.recv_state = NVME_TCP_PDU_RECV_STATE_AWAIT_PDU_PSH; 1130781d42adSKonrad Sztyber tqpair.qpair.state = SPDK_NVMF_QPAIR_ENABLED; 1131f7b9f80bSmatthewb 1132f7b9f80bSmatthewb /* init tcp_req */ 1133f7b9f80bSmatthewb tcp_req.req.qpair = &tqpair.qpair; 1134f7b9f80bSmatthewb tcp_req.pdu = &rsp_pdu; 11358ed53eeeSMengjinWu tcp_req.pdu->qpair = &tqpair; 11368ed53eeeSMengjinWu tqpair.mgmt_pdu = &mgmt_pdu; 11378ed53eeeSMengjinWu tqpair.mgmt_pdu->qpair = &tqpair; 1138f7b9f80bSmatthewb tcp_req.req.cmd = (union nvmf_h2c_msg *)&tcp_req.cmd; 1139f7b9f80bSmatthewb tcp_req.req.rsp = &rsp0; 1140f7b9f80bSmatthewb tcp_req.state = TCP_REQUEST_STATE_NEW; 1141f7b9f80bSmatthewb 1142f7b9f80bSmatthewb TAILQ_INSERT_TAIL(&tqpair.tcp_req_working_queue, &tcp_req, state_link); 1143f7b9f80bSmatthewb tqpair.state_cntr[TCP_REQUEST_STATE_NEW]++; 1144f7b9f80bSmatthewb 1145f7b9f80bSmatthewb /* init pdu, make pdu need sgl buff */ 1146f7b9f80bSmatthewb capsule_data = &tqpair.pdu_in_progress->hdr.capsule_cmd; 1147f7b9f80bSmatthewb sgl = &capsule_data->ccsqe.dptr.sgl1; 1148f7b9f80bSmatthewb 1149f7b9f80bSmatthewb capsule_data->common.pdu_type = SPDK_NVME_TCP_PDU_TYPE_CAPSULE_CMD; 1150f7b9f80bSmatthewb capsule_data->common.hlen = sizeof(*capsule_data); 1151f7b9f80bSmatthewb capsule_data->common.plen = 1096; 1152f7b9f80bSmatthewb capsule_data->ccsqe.opc = SPDK_NVME_OPC_WRITE; 1153f7b9f80bSmatthewb /* Need to set to a non zero valid to check it gets copied to the response */ 1154f7b9f80bSmatthewb capsule_data->ccsqe.cid = cid; 1155f7b9f80bSmatthewb 1156f7b9f80bSmatthewb /* Set up SGL to ensure nvmf_tcp_req_parse_sgl returns an error */ 1157f7b9f80bSmatthewb sgl->unkeyed.subtype = SPDK_NVME_SGL_SUBTYPE_TRANSPORT; 1158f7b9f80bSmatthewb sgl->generic.type = SPDK_NVME_SGL_TYPE_TRANSPORT_DATA_BLOCK; 1159f7b9f80bSmatthewb sgl->unkeyed.length = UT_MAX_IO_SIZE + 1; 1160f7b9f80bSmatthewb 1161f7b9f80bSmatthewb /* Process a command and ensure that it fails and the request is set up to return an error */ 1162f7b9f80bSmatthewb nvmf_tcp_req_process(&ttransport, &tcp_req); 11638ed53eeeSMengjinWu CU_ASSERT(tcp_req.state == TCP_REQUEST_STATE_NEED_BUFFER); 116478df9be4SBen Walker CU_ASSERT(tqpair.recv_state == NVME_TCP_PDU_RECV_STATE_QUIESCING); 11658ed53eeeSMengjinWu CU_ASSERT(tqpair.mgmt_pdu->hdr.term_req.common.pdu_type == SPDK_NVME_TCP_PDU_TYPE_C2H_TERM_REQ); 1166f7b9f80bSmatthewb } 1167f7b9f80bSmatthewb 1168fbed5966Sxiaoxiangxzhang static void 1169fbed5966Sxiaoxiangxzhang test_nvmf_tcp_pdu_ch_handle(void) 1170fbed5966Sxiaoxiangxzhang { 1171fbed5966Sxiaoxiangxzhang struct spdk_nvmf_tcp_qpair tqpair = {}; 1172fbed5966Sxiaoxiangxzhang struct nvme_tcp_pdu mgmt_pdu = {}, pdu_in_progress = {}; 1173fbed5966Sxiaoxiangxzhang 1174fbed5966Sxiaoxiangxzhang mgmt_pdu.qpair = &tqpair; 1175fbed5966Sxiaoxiangxzhang tqpair.mgmt_pdu = &mgmt_pdu; 1176fbed5966Sxiaoxiangxzhang tqpair.pdu_in_progress = &pdu_in_progress; 1177fbed5966Sxiaoxiangxzhang tqpair.recv_state = NVME_TCP_PDU_RECV_STATE_AWAIT_PDU_CH; 1178fbed5966Sxiaoxiangxzhang tqpair.cpda = 0; 1179fbed5966Sxiaoxiangxzhang 1180fbed5966Sxiaoxiangxzhang /* Test case: Already received ICreq PDU. Expect: fail */ 1181fbed5966Sxiaoxiangxzhang tqpair.pdu_in_progress->hdr.common.pdu_type = SPDK_NVME_TCP_PDU_TYPE_IC_REQ; 1182b95aae63SKonrad Sztyber tqpair.state = NVMF_TCP_QPAIR_STATE_INITIALIZING; 1183fbed5966Sxiaoxiangxzhang nvmf_tcp_pdu_ch_handle(&tqpair); 118478df9be4SBen Walker CU_ASSERT(tqpair.recv_state == NVME_TCP_PDU_RECV_STATE_QUIESCING); 1185fbed5966Sxiaoxiangxzhang CU_ASSERT(tqpair.mgmt_pdu->hdr.term_req.common.pdu_type == SPDK_NVME_TCP_PDU_TYPE_C2H_TERM_REQ); 1186fbed5966Sxiaoxiangxzhang CU_ASSERT(tqpair.mgmt_pdu->hdr.term_req.common.hlen == sizeof(struct spdk_nvme_tcp_term_req_hdr)); 1187fbed5966Sxiaoxiangxzhang CU_ASSERT(tqpair.mgmt_pdu->hdr.term_req.common.plen == tqpair.mgmt_pdu->hdr.term_req.common.hlen); 1188fbed5966Sxiaoxiangxzhang 1189fbed5966Sxiaoxiangxzhang /* Test case: Expected PDU header length and received are different. Expect: fail */ 1190fbed5966Sxiaoxiangxzhang tqpair.recv_state = NVME_TCP_PDU_RECV_STATE_AWAIT_PDU_CH; 1191fbed5966Sxiaoxiangxzhang tqpair.pdu_in_progress->hdr.common.pdu_type = SPDK_NVME_TCP_PDU_TYPE_IC_REQ; 1192b95aae63SKonrad Sztyber tqpair.state = NVMF_TCP_QPAIR_STATE_INVALID; 1193fbed5966Sxiaoxiangxzhang tqpair.pdu_in_progress->hdr.common.plen = sizeof(struct spdk_nvme_tcp_ic_req); 1194fbed5966Sxiaoxiangxzhang tqpair.pdu_in_progress->hdr.common.hlen = 0; 1195fbed5966Sxiaoxiangxzhang nvmf_tcp_pdu_ch_handle(&tqpair); 119678df9be4SBen Walker CU_ASSERT(tqpair.recv_state == NVME_TCP_PDU_RECV_STATE_QUIESCING); 1197fbed5966Sxiaoxiangxzhang CU_ASSERT(tqpair.mgmt_pdu->hdr.term_req.common.pdu_type == SPDK_NVME_TCP_PDU_TYPE_C2H_TERM_REQ); 1198fbed5966Sxiaoxiangxzhang CU_ASSERT(tqpair.mgmt_pdu->hdr.term_req.common.hlen == sizeof(struct spdk_nvme_tcp_term_req_hdr)); 1199fbed5966Sxiaoxiangxzhang CU_ASSERT(tqpair.mgmt_pdu->hdr.term_req.common.plen == tqpair.mgmt_pdu->hdr.term_req.common.hlen); 1200fbed5966Sxiaoxiangxzhang CU_ASSERT(tqpair.mgmt_pdu->hdr.term_req.fei[0] == 2); 1201fbed5966Sxiaoxiangxzhang 120234edd9f1SKamil Godzwon /* Test case: The TCP/IP tqpair connection is not negotiated. Expect: fail */ 1203fbed5966Sxiaoxiangxzhang tqpair.recv_state = NVME_TCP_PDU_RECV_STATE_AWAIT_PDU_CH; 1204fbed5966Sxiaoxiangxzhang tqpair.pdu_in_progress->hdr.common.pdu_type = SPDK_NVME_TCP_PDU_TYPE_IC_RESP; 1205b95aae63SKonrad Sztyber tqpair.state = NVMF_TCP_QPAIR_STATE_INVALID; 1206fbed5966Sxiaoxiangxzhang tqpair.pdu_in_progress->hdr.common.plen = sizeof(struct spdk_nvme_tcp_ic_req); 1207fbed5966Sxiaoxiangxzhang tqpair.pdu_in_progress->hdr.common.hlen = 0; 1208fbed5966Sxiaoxiangxzhang nvmf_tcp_pdu_ch_handle(&tqpair); 120978df9be4SBen Walker CU_ASSERT(tqpair.recv_state == NVME_TCP_PDU_RECV_STATE_QUIESCING); 1210fbed5966Sxiaoxiangxzhang CU_ASSERT(tqpair.mgmt_pdu->hdr.term_req.common.pdu_type == SPDK_NVME_TCP_PDU_TYPE_C2H_TERM_REQ); 1211fbed5966Sxiaoxiangxzhang CU_ASSERT(tqpair.mgmt_pdu->hdr.term_req.common.hlen == sizeof(struct spdk_nvme_tcp_term_req_hdr)); 1212fbed5966Sxiaoxiangxzhang CU_ASSERT(tqpair.mgmt_pdu->hdr.term_req.common.plen == tqpair.mgmt_pdu->hdr.term_req.common.hlen); 1213fbed5966Sxiaoxiangxzhang 1214fbed5966Sxiaoxiangxzhang /* Test case: Unexpected PDU type. Expect: fail */ 1215fbed5966Sxiaoxiangxzhang tqpair.recv_state = NVME_TCP_PDU_RECV_STATE_AWAIT_PDU_CH; 1216fbed5966Sxiaoxiangxzhang tqpair.pdu_in_progress->hdr.common.pdu_type = SPDK_NVME_TCP_PDU_TYPE_CAPSULE_RESP; 1217b95aae63SKonrad Sztyber tqpair.state = NVMF_TCP_QPAIR_STATE_RUNNING; 1218fbed5966Sxiaoxiangxzhang tqpair.pdu_in_progress->hdr.common.plen = 0; 1219fbed5966Sxiaoxiangxzhang tqpair.pdu_in_progress->hdr.common.hlen = sizeof(struct spdk_nvme_tcp_ic_req); 1220fbed5966Sxiaoxiangxzhang nvmf_tcp_pdu_ch_handle(&tqpair); 122178df9be4SBen Walker CU_ASSERT(tqpair.recv_state == NVME_TCP_PDU_RECV_STATE_QUIESCING); 1222fbed5966Sxiaoxiangxzhang CU_ASSERT(tqpair.mgmt_pdu->hdr.term_req.common.pdu_type == SPDK_NVME_TCP_PDU_TYPE_C2H_TERM_REQ); 1223fbed5966Sxiaoxiangxzhang CU_ASSERT(tqpair.mgmt_pdu->hdr.term_req.common.hlen == sizeof(struct spdk_nvme_tcp_term_req_hdr)); 1224fbed5966Sxiaoxiangxzhang CU_ASSERT(tqpair.mgmt_pdu->hdr.term_req.common.plen == tqpair.mgmt_pdu->hdr.term_req.common.hlen + 1225fbed5966Sxiaoxiangxzhang (unsigned)SPDK_NVME_TCP_TERM_REQ_ERROR_DATA_MAX_SIZE); 1226fbed5966Sxiaoxiangxzhang 1227fbed5966Sxiaoxiangxzhang /* Test case: PDU type is SPDK_NVME_TCP_PDU_TYPE_IC_REQ, let plen error. Expect: fail */ 1228fbed5966Sxiaoxiangxzhang tqpair.recv_state = NVME_TCP_PDU_RECV_STATE_AWAIT_PDU_CH; 1229fbed5966Sxiaoxiangxzhang tqpair.pdu_in_progress->hdr.common.pdu_type = SPDK_NVME_TCP_PDU_TYPE_IC_REQ; 1230b95aae63SKonrad Sztyber tqpair.state = NVMF_TCP_QPAIR_STATE_INVALID; 1231fbed5966Sxiaoxiangxzhang tqpair.pdu_in_progress->hdr.common.plen = 0; 1232fbed5966Sxiaoxiangxzhang tqpair.pdu_in_progress->hdr.common.hlen = sizeof(struct spdk_nvme_tcp_ic_req); 1233fbed5966Sxiaoxiangxzhang nvmf_tcp_pdu_ch_handle(&tqpair); 123478df9be4SBen Walker CU_ASSERT(tqpair.recv_state == NVME_TCP_PDU_RECV_STATE_QUIESCING); 1235fbed5966Sxiaoxiangxzhang CU_ASSERT(tqpair.mgmt_pdu->hdr.term_req.common.pdu_type == SPDK_NVME_TCP_PDU_TYPE_C2H_TERM_REQ); 1236fbed5966Sxiaoxiangxzhang CU_ASSERT(tqpair.mgmt_pdu->hdr.term_req.common.hlen == sizeof(struct spdk_nvme_tcp_term_req_hdr)); 1237fbed5966Sxiaoxiangxzhang CU_ASSERT(tqpair.mgmt_pdu->hdr.term_req.common.plen == tqpair.mgmt_pdu->hdr.term_req.common.hlen + 1238fbed5966Sxiaoxiangxzhang (unsigned)SPDK_NVME_TCP_TERM_REQ_ERROR_DATA_MAX_SIZE); 1239fbed5966Sxiaoxiangxzhang CU_ASSERT(tqpair.mgmt_pdu->hdr.term_req.fei[0] == 4); 1240fbed5966Sxiaoxiangxzhang 1241fbed5966Sxiaoxiangxzhang /* Test case: PDU type is SPDK_NVME_TCP_PDU_TYPE_CAPSULE_CMD, let plen error. Expect: fail */ 1242fbed5966Sxiaoxiangxzhang tqpair.recv_state = NVME_TCP_PDU_RECV_STATE_AWAIT_PDU_CH; 1243fbed5966Sxiaoxiangxzhang tqpair.pdu_in_progress->hdr.common.pdu_type = SPDK_NVME_TCP_PDU_TYPE_CAPSULE_CMD; 1244b95aae63SKonrad Sztyber tqpair.state = NVMF_TCP_QPAIR_STATE_RUNNING; 1245fbed5966Sxiaoxiangxzhang tqpair.pdu_in_progress->hdr.common.flags = SPDK_NVME_TCP_CH_FLAGS_HDGSTF; 1246fbed5966Sxiaoxiangxzhang tqpair.pdu_in_progress->hdr.common.plen = 0; 1247fbed5966Sxiaoxiangxzhang tqpair.pdu_in_progress->hdr.common.hlen = sizeof(struct spdk_nvme_tcp_cmd); 1248fbed5966Sxiaoxiangxzhang nvmf_tcp_pdu_ch_handle(&tqpair); 124978df9be4SBen Walker CU_ASSERT(tqpair.recv_state == NVME_TCP_PDU_RECV_STATE_QUIESCING); 1250fbed5966Sxiaoxiangxzhang CU_ASSERT(tqpair.mgmt_pdu->hdr.term_req.common.pdu_type == SPDK_NVME_TCP_PDU_TYPE_C2H_TERM_REQ); 1251fbed5966Sxiaoxiangxzhang CU_ASSERT(tqpair.mgmt_pdu->hdr.term_req.common.hlen == sizeof(struct spdk_nvme_tcp_term_req_hdr)); 1252fbed5966Sxiaoxiangxzhang CU_ASSERT(tqpair.mgmt_pdu->hdr.term_req.common.plen == sizeof(struct spdk_nvme_tcp_cmd) + sizeof( 1253fbed5966Sxiaoxiangxzhang struct spdk_nvme_tcp_term_req_hdr)); 1254fbed5966Sxiaoxiangxzhang CU_ASSERT(tqpair.mgmt_pdu->hdr.term_req.fei[0] == 4); 1255fbed5966Sxiaoxiangxzhang 1256fbed5966Sxiaoxiangxzhang /* Test case: PDU type is SPDK_NVME_TCP_PDU_TYPE_H2C_DATA, let plen error. Expect: fail */ 1257fbed5966Sxiaoxiangxzhang tqpair.recv_state = NVME_TCP_PDU_RECV_STATE_AWAIT_PDU_CH; 1258fbed5966Sxiaoxiangxzhang tqpair.pdu_in_progress->hdr.common.pdu_type = SPDK_NVME_TCP_PDU_TYPE_H2C_DATA; 1259b95aae63SKonrad Sztyber tqpair.state = NVMF_TCP_QPAIR_STATE_RUNNING; 1260fbed5966Sxiaoxiangxzhang tqpair.pdu_in_progress->hdr.common.plen = 0; 1261fbed5966Sxiaoxiangxzhang tqpair.pdu_in_progress->hdr.common.pdo = 64; 1262fbed5966Sxiaoxiangxzhang tqpair.pdu_in_progress->hdr.common.hlen = sizeof(struct spdk_nvme_tcp_h2c_data_hdr); 1263fbed5966Sxiaoxiangxzhang nvmf_tcp_pdu_ch_handle(&tqpair); 126478df9be4SBen Walker CU_ASSERT(tqpair.recv_state == NVME_TCP_PDU_RECV_STATE_QUIESCING); 1265fbed5966Sxiaoxiangxzhang CU_ASSERT(tqpair.mgmt_pdu->hdr.term_req.common.pdu_type == SPDK_NVME_TCP_PDU_TYPE_C2H_TERM_REQ); 1266fbed5966Sxiaoxiangxzhang CU_ASSERT(tqpair.mgmt_pdu->hdr.term_req.common.hlen == sizeof(struct spdk_nvme_tcp_term_req_hdr)); 1267fbed5966Sxiaoxiangxzhang CU_ASSERT(tqpair.mgmt_pdu->hdr.term_req.common.plen == tqpair.mgmt_pdu->hdr.term_req.common.hlen + 1268fbed5966Sxiaoxiangxzhang (unsigned)sizeof(struct spdk_nvme_tcp_term_req_hdr)); 1269fbed5966Sxiaoxiangxzhang CU_ASSERT(tqpair.mgmt_pdu->hdr.term_req.fei[0] == 4); 1270fbed5966Sxiaoxiangxzhang 1271fbed5966Sxiaoxiangxzhang /* Test case: PDU type is SPDK_NVME_TCP_PDU_TYPE_H2C_TERM_REQ, let plen error. Expect: fail */ 1272fbed5966Sxiaoxiangxzhang tqpair.recv_state = NVME_TCP_PDU_RECV_STATE_AWAIT_PDU_CH; 1273fbed5966Sxiaoxiangxzhang tqpair.pdu_in_progress->hdr.common.pdu_type = SPDK_NVME_TCP_PDU_TYPE_H2C_TERM_REQ; 1274b95aae63SKonrad Sztyber tqpair.state = NVMF_TCP_QPAIR_STATE_RUNNING; 1275fbed5966Sxiaoxiangxzhang tqpair.pdu_in_progress->hdr.common.plen = 0; 1276fbed5966Sxiaoxiangxzhang tqpair.pdu_in_progress->hdr.common.hlen = sizeof(struct spdk_nvme_tcp_term_req_hdr); 1277fbed5966Sxiaoxiangxzhang nvmf_tcp_pdu_ch_handle(&tqpair); 127878df9be4SBen Walker CU_ASSERT(tqpair.recv_state == NVME_TCP_PDU_RECV_STATE_QUIESCING); 1279fbed5966Sxiaoxiangxzhang CU_ASSERT(tqpair.mgmt_pdu->hdr.term_req.common.pdu_type == SPDK_NVME_TCP_PDU_TYPE_C2H_TERM_REQ); 1280fbed5966Sxiaoxiangxzhang CU_ASSERT(tqpair.mgmt_pdu->hdr.term_req.common.hlen == sizeof(struct spdk_nvme_tcp_term_req_hdr)); 1281fbed5966Sxiaoxiangxzhang CU_ASSERT(tqpair.mgmt_pdu->hdr.term_req.common.plen == tqpair.mgmt_pdu->hdr.term_req.common.hlen + 1282fbed5966Sxiaoxiangxzhang (unsigned)sizeof(struct spdk_nvme_tcp_term_req_hdr)); 1283fbed5966Sxiaoxiangxzhang CU_ASSERT(tqpair.mgmt_pdu->hdr.term_req.fei[0] == 4); 1284fbed5966Sxiaoxiangxzhang 1285fbed5966Sxiaoxiangxzhang /* Test case: PDU type is SPDK_NVME_TCP_PDU_TYPE_CAPSULE_CMD, let pdo error. Expect: fail */ 1286fbed5966Sxiaoxiangxzhang tqpair.recv_state = NVME_TCP_PDU_RECV_STATE_AWAIT_PDU_CH; 1287fbed5966Sxiaoxiangxzhang tqpair.pdu_in_progress->hdr.common.pdu_type = SPDK_NVME_TCP_PDU_TYPE_CAPSULE_CMD; 1288b95aae63SKonrad Sztyber tqpair.state = NVMF_TCP_QPAIR_STATE_RUNNING; 1289fbed5966Sxiaoxiangxzhang tqpair.cpda = 1; 1290fbed5966Sxiaoxiangxzhang tqpair.pdu_in_progress->hdr.common.flags = SPDK_NVME_TCP_CH_FLAGS_HDGSTF; 1291fbed5966Sxiaoxiangxzhang tqpair.pdu_in_progress->hdr.common.plen = 0; 1292fbed5966Sxiaoxiangxzhang tqpair.pdu_in_progress->hdr.common.pdo = 63; 1293fbed5966Sxiaoxiangxzhang tqpair.pdu_in_progress->hdr.common.hlen = sizeof(struct spdk_nvme_tcp_cmd); 1294fbed5966Sxiaoxiangxzhang nvmf_tcp_pdu_ch_handle(&tqpair); 129578df9be4SBen Walker CU_ASSERT(tqpair.recv_state == NVME_TCP_PDU_RECV_STATE_QUIESCING); 1296fbed5966Sxiaoxiangxzhang CU_ASSERT(tqpair.mgmt_pdu->hdr.term_req.common.pdu_type == SPDK_NVME_TCP_PDU_TYPE_C2H_TERM_REQ); 1297fbed5966Sxiaoxiangxzhang CU_ASSERT(tqpair.mgmt_pdu->hdr.term_req.common.hlen == sizeof(struct spdk_nvme_tcp_term_req_hdr)); 1298fbed5966Sxiaoxiangxzhang CU_ASSERT(tqpair.mgmt_pdu->hdr.term_req.common.plen == sizeof(struct spdk_nvme_tcp_cmd) + sizeof( 1299fbed5966Sxiaoxiangxzhang struct spdk_nvme_tcp_term_req_hdr)); 1300fbed5966Sxiaoxiangxzhang CU_ASSERT(tqpair.mgmt_pdu->hdr.term_req.fei[0] == 3); 1301fbed5966Sxiaoxiangxzhang 1302fbed5966Sxiaoxiangxzhang /* Test case: PDU type is SPDK_NVME_TCP_PDU_TYPE_H2C_DATA, let pdo error. Expect: fail */ 1303fbed5966Sxiaoxiangxzhang tqpair.recv_state = NVME_TCP_PDU_RECV_STATE_AWAIT_PDU_CH; 1304fbed5966Sxiaoxiangxzhang tqpair.pdu_in_progress->hdr.common.pdu_type = SPDK_NVME_TCP_PDU_TYPE_H2C_DATA; 1305b95aae63SKonrad Sztyber tqpair.state = NVMF_TCP_QPAIR_STATE_RUNNING; 1306fbed5966Sxiaoxiangxzhang tqpair.cpda = 1; 1307fbed5966Sxiaoxiangxzhang tqpair.pdu_in_progress->hdr.common.plen = 0; 1308fbed5966Sxiaoxiangxzhang tqpair.pdu_in_progress->hdr.common.pdo = 63; 1309fbed5966Sxiaoxiangxzhang tqpair.pdu_in_progress->hdr.common.hlen = sizeof(struct spdk_nvme_tcp_h2c_data_hdr); 1310fbed5966Sxiaoxiangxzhang nvmf_tcp_pdu_ch_handle(&tqpair); 131178df9be4SBen Walker CU_ASSERT(tqpair.recv_state == NVME_TCP_PDU_RECV_STATE_QUIESCING); 1312fbed5966Sxiaoxiangxzhang CU_ASSERT(tqpair.mgmt_pdu->hdr.term_req.common.pdu_type == SPDK_NVME_TCP_PDU_TYPE_C2H_TERM_REQ); 1313fbed5966Sxiaoxiangxzhang CU_ASSERT(tqpair.mgmt_pdu->hdr.term_req.common.hlen == sizeof(struct spdk_nvme_tcp_term_req_hdr)); 1314fbed5966Sxiaoxiangxzhang CU_ASSERT(tqpair.mgmt_pdu->hdr.term_req.common.plen == tqpair.mgmt_pdu->hdr.term_req.common.hlen + 1315fbed5966Sxiaoxiangxzhang (unsigned)sizeof(struct spdk_nvme_tcp_term_req_hdr)); 1316fbed5966Sxiaoxiangxzhang CU_ASSERT(tqpair.mgmt_pdu->hdr.term_req.fei[0] == 3); 1317fbed5966Sxiaoxiangxzhang 13183f912cf0SMichal Berger /* Test case: All parameters is conformed to the function. Expect: PASS */ 1319fbed5966Sxiaoxiangxzhang tqpair.recv_state = NVME_TCP_PDU_RECV_STATE_AWAIT_PDU_CH; 1320fbed5966Sxiaoxiangxzhang tqpair.pdu_in_progress->hdr.common.pdu_type = SPDK_NVME_TCP_PDU_TYPE_IC_REQ; 1321b95aae63SKonrad Sztyber tqpair.state = NVMF_TCP_QPAIR_STATE_INVALID; 1322fbed5966Sxiaoxiangxzhang tqpair.pdu_in_progress->hdr.common.plen = sizeof(struct spdk_nvme_tcp_ic_req); 1323fbed5966Sxiaoxiangxzhang tqpair.pdu_in_progress->hdr.common.hlen = sizeof(struct spdk_nvme_tcp_ic_req); 1324fbed5966Sxiaoxiangxzhang nvmf_tcp_pdu_ch_handle(&tqpair); 1325fbed5966Sxiaoxiangxzhang CU_ASSERT(tqpair.recv_state == NVME_TCP_PDU_RECV_STATE_AWAIT_PDU_PSH); 1326fbed5966Sxiaoxiangxzhang CU_ASSERT(tqpair.pdu_in_progress->psh_len == tqpair.pdu_in_progress->hdr.common.hlen - sizeof( 1327fbed5966Sxiaoxiangxzhang struct spdk_nvme_tcp_common_pdu_hdr)); 1328fbed5966Sxiaoxiangxzhang } 1329fbed5966Sxiaoxiangxzhang 1330663243cbSKrzysztof Karas static void 1331663243cbSKrzysztof Karas test_nvmf_tcp_tls_add_remove_credentials(void) 1332663243cbSKrzysztof Karas { 1333663243cbSKrzysztof Karas struct spdk_thread *thread; 1334663243cbSKrzysztof Karas struct spdk_nvmf_transport *transport; 1335663243cbSKrzysztof Karas struct spdk_nvmf_tcp_transport *ttransport; 1336663243cbSKrzysztof Karas struct spdk_nvmf_transport_opts opts; 1337663243cbSKrzysztof Karas struct spdk_nvmf_subsystem subsystem; 1338663243cbSKrzysztof Karas struct tcp_psk_entry *entry; 13390e983c56SKrzysztof Goreczny struct spdk_sock_group grp = {}; 1340663243cbSKrzysztof Karas const char subnqn[] = {"nqn.2016-06.io.spdk:cnode1"}; 1341663243cbSKrzysztof Karas const char hostnqn[] = {"nqn.2016-06.io.spdk:host1"}; 134203b6183aSKrzysztof Karas const char *psk = "NVMeTLSkey-1:01:VRLbtnN9AQb2WXW3c9+wEf/DRLz0QuLdbYvEhwtdWwNf9LrZ:"; 1343663243cbSKrzysztof Karas bool found = false; 1344663243cbSKrzysztof Karas 1345663243cbSKrzysztof Karas thread = spdk_thread_create(NULL, NULL); 1346663243cbSKrzysztof Karas SPDK_CU_ASSERT_FATAL(thread != NULL); 1347663243cbSKrzysztof Karas spdk_set_thread(thread); 1348663243cbSKrzysztof Karas 1349663243cbSKrzysztof Karas memset(&opts, 0, sizeof(opts)); 1350663243cbSKrzysztof Karas opts.max_queue_depth = UT_MAX_QUEUE_DEPTH; 1351663243cbSKrzysztof Karas opts.max_qpairs_per_ctrlr = UT_MAX_QPAIRS_PER_CTRLR; 1352663243cbSKrzysztof Karas opts.in_capsule_data_size = UT_IN_CAPSULE_DATA_SIZE; 1353663243cbSKrzysztof Karas opts.max_io_size = UT_MAX_IO_SIZE; 1354663243cbSKrzysztof Karas opts.io_unit_size = UT_IO_UNIT_SIZE; 1355663243cbSKrzysztof Karas opts.max_aq_depth = UT_MAX_AQ_DEPTH; 1356663243cbSKrzysztof Karas opts.num_shared_buffers = UT_NUM_SHARED_BUFFERS; 13570e983c56SKrzysztof Goreczny MOCK_SET(spdk_sock_group_create, &grp); 1358663243cbSKrzysztof Karas transport = nvmf_tcp_create(&opts); 13590e983c56SKrzysztof Goreczny MOCK_CLEAR_P(spdk_sock_group_create); 1360663243cbSKrzysztof Karas 1361663243cbSKrzysztof Karas memset(&subsystem, 0, sizeof(subsystem)); 1362663243cbSKrzysztof Karas snprintf(subsystem.subnqn, sizeof(subsystem.subnqn), "%s", subnqn); 136311cc2256SKonrad Sztyber snprintf(g_ut_psk.data, sizeof(g_ut_psk.data), "%s", psk); 136411cc2256SKonrad Sztyber g_ut_psk.len = strlen(psk) + 1; 136503b6183aSKrzysztof Karas 136603b6183aSKrzysztof Karas struct spdk_json_val psk_json[] = { 136703b6183aSKrzysztof Karas {"", 2, SPDK_JSON_VAL_OBJECT_BEGIN}, 136803b6183aSKrzysztof Karas {"psk", 3, SPDK_JSON_VAL_NAME}, 136911cc2256SKonrad Sztyber {(void *)g_ut_psk.name, strlen(g_ut_psk.name), SPDK_JSON_VAL_STRING}, 137003b6183aSKrzysztof Karas {"", 0, SPDK_JSON_VAL_OBJECT_END}, 137103b6183aSKrzysztof Karas }; 137203b6183aSKrzysztof Karas 1373663243cbSKrzysztof Karas nvmf_tcp_subsystem_add_host(transport, &subsystem, hostnqn, psk_json); 1374663243cbSKrzysztof Karas 1375663243cbSKrzysztof Karas ttransport = SPDK_CONTAINEROF(transport, struct spdk_nvmf_tcp_transport, transport); 1376663243cbSKrzysztof Karas TAILQ_FOREACH(entry, &ttransport->psks, link) { 1377663243cbSKrzysztof Karas if ((strcmp(subnqn, entry->subnqn) == 0) && 1378663243cbSKrzysztof Karas (strcmp(hostnqn, entry->hostnqn) == 0)) { 1379663243cbSKrzysztof Karas found = true; 1380663243cbSKrzysztof Karas } 1381663243cbSKrzysztof Karas } 1382663243cbSKrzysztof Karas 1383663243cbSKrzysztof Karas CU_ASSERT(found == true); 1384663243cbSKrzysztof Karas found = false; 1385663243cbSKrzysztof Karas 1386663243cbSKrzysztof Karas nvmf_tcp_subsystem_remove_host(transport, &subsystem, hostnqn); 1387663243cbSKrzysztof Karas 1388663243cbSKrzysztof Karas ttransport = SPDK_CONTAINEROF(transport, struct spdk_nvmf_tcp_transport, transport); 1389663243cbSKrzysztof Karas TAILQ_FOREACH(entry, &ttransport->psks, link) { 1390663243cbSKrzysztof Karas if ((strcmp(subnqn, entry->subnqn) == 0) && 1391663243cbSKrzysztof Karas (strcmp(hostnqn, entry->hostnqn) == 0)) { 1392663243cbSKrzysztof Karas found = true; 1393663243cbSKrzysztof Karas } 1394663243cbSKrzysztof Karas } 1395663243cbSKrzysztof Karas 1396663243cbSKrzysztof Karas CU_ASSERT(found == false); 1397663243cbSKrzysztof Karas 1398663243cbSKrzysztof Karas CU_ASSERT(nvmf_tcp_destroy(transport, NULL, NULL) == 0); 1399663243cbSKrzysztof Karas 1400663243cbSKrzysztof Karas spdk_thread_exit(thread); 1401663243cbSKrzysztof Karas while (!spdk_thread_is_exited(thread)) { 1402663243cbSKrzysztof Karas spdk_thread_poll(thread, 0, 0); 1403663243cbSKrzysztof Karas } 1404663243cbSKrzysztof Karas spdk_thread_destroy(thread); 1405663243cbSKrzysztof Karas } 1406663243cbSKrzysztof Karas 14073e98fd06SKrzysztof Karas static void 14083e98fd06SKrzysztof Karas test_nvmf_tcp_tls_generate_psk_id(void) 14093e98fd06SKrzysztof Karas { 14103e98fd06SKrzysztof Karas const char psk_id_reference[] = {"NVMe0R01 nqn.2016-06.io.spdk:host1 nqn.2016-06.io.spdk:cnode1"}; 14113e98fd06SKrzysztof Karas const char subnqn[] = {"nqn.2016-06.io.spdk:cnode1"}; 14123e98fd06SKrzysztof Karas const char hostnqn[] = {"nqn.2016-06.io.spdk:host1"}; 14133e98fd06SKrzysztof Karas char psk_id[NVMF_PSK_IDENTITY_LEN] = {}; 14143e98fd06SKrzysztof Karas char too_small_psk_id[5] = {}; 14153e98fd06SKrzysztof Karas 14163e98fd06SKrzysztof Karas /* Check if we can generate expected PSK id. */ 14173e98fd06SKrzysztof Karas CU_ASSERT(nvme_tcp_generate_psk_identity(psk_id, NVMF_PSK_IDENTITY_LEN, hostnqn, 1418169ee6c3SKrzysztof Karas subnqn, NVME_TCP_CIPHER_AES_128_GCM_SHA256) == 0); 14193e98fd06SKrzysztof Karas CU_ASSERT(strcmp(psk_id, psk_id_reference) == 0); 14203e98fd06SKrzysztof Karas 14213e98fd06SKrzysztof Karas /* Test with a buffer that is too small to fit PSK id. */ 14223e98fd06SKrzysztof Karas CU_ASSERT(nvme_tcp_generate_psk_identity(too_small_psk_id, sizeof(too_small_psk_id), hostnqn, 1423169ee6c3SKrzysztof Karas subnqn, NVME_TCP_CIPHER_AES_128_GCM_SHA256) != 0); 1424572a0c8aSKrzysztof Karas 1425572a0c8aSKrzysztof Karas /* Test with unknown cipher suite. */ 1426572a0c8aSKrzysztof Karas CU_ASSERT(nvme_tcp_generate_psk_identity(psk_id, NVMF_PSK_IDENTITY_LEN, hostnqn, 1427572a0c8aSKrzysztof Karas subnqn, UINT8_MAX) != 0); 14283e98fd06SKrzysztof Karas } 14293e98fd06SKrzysztof Karas 14307a50a6bcSKrzysztof Karas static void 14317a50a6bcSKrzysztof Karas test_nvmf_tcp_tls_generate_retained_psk(void) 14327a50a6bcSKrzysztof Karas { 14337a50a6bcSKrzysztof Karas const char hostnqn[] = {"nqn.2016-06.io.spdk:host1"}; 14347a50a6bcSKrzysztof Karas const char psk_reference1[] = {"1234567890ABCDEF"}; 14357a50a6bcSKrzysztof Karas const char psk_reference2[] = {"FEDCBA0987654321"}; 1436572a0c8aSKrzysztof Karas uint8_t unhexlified_str1[SPDK_TLS_PSK_MAX_LEN] = {}; 1437572a0c8aSKrzysztof Karas uint8_t unhexlified_str2[SPDK_TLS_PSK_MAX_LEN] = {}; 1438572a0c8aSKrzysztof Karas char *unhexlified1; 1439572a0c8aSKrzysztof Karas char *unhexlified2; 14407a50a6bcSKrzysztof Karas uint8_t psk_retained1[SPDK_TLS_PSK_MAX_LEN] = {}; 14417a50a6bcSKrzysztof Karas uint8_t psk_retained2[SPDK_TLS_PSK_MAX_LEN] = {}; 14427a50a6bcSKrzysztof Karas uint8_t too_small_psk_retained[5] = {}; 1443572a0c8aSKrzysztof Karas int psk_retained_len1, psk_retained_len2; 14447a50a6bcSKrzysztof Karas int retained_size; 14457a50a6bcSKrzysztof Karas 1446572a0c8aSKrzysztof Karas unhexlified1 = spdk_unhexlify(psk_reference1); 1447572a0c8aSKrzysztof Karas SPDK_CU_ASSERT_FATAL(unhexlified1 != NULL); 1448572a0c8aSKrzysztof Karas unhexlified2 = spdk_unhexlify(psk_reference2); 1449572a0c8aSKrzysztof Karas SPDK_CU_ASSERT_FATAL(unhexlified2 != NULL); 1450572a0c8aSKrzysztof Karas 1451572a0c8aSKrzysztof Karas memcpy(unhexlified_str1, unhexlified1, strlen(psk_reference1) / 2); 1452572a0c8aSKrzysztof Karas memcpy(unhexlified_str2, unhexlified2, strlen(psk_reference2) / 2); 1453572a0c8aSKrzysztof Karas free(unhexlified1); 1454572a0c8aSKrzysztof Karas free(unhexlified2); 1455572a0c8aSKrzysztof Karas 1456572a0c8aSKrzysztof Karas /* Make sure that retained PSKs are different with different input PSKs and the same hash. */ 1457572a0c8aSKrzysztof Karas retained_size = nvme_tcp_derive_retained_psk(unhexlified_str1, strlen(psk_reference1) / 2, hostnqn, 1458572a0c8aSKrzysztof Karas psk_retained1, SPDK_TLS_PSK_MAX_LEN, NVME_TCP_HASH_ALGORITHM_SHA256); 145968577d33SKrzysztof Karas CU_ASSERT(retained_size > 0); 1460572a0c8aSKrzysztof Karas 1461572a0c8aSKrzysztof Karas CU_ASSERT(nvme_tcp_derive_retained_psk(unhexlified_str2, strlen(psk_reference2) / 2, hostnqn, 1462572a0c8aSKrzysztof Karas psk_retained2, 1463572a0c8aSKrzysztof Karas SPDK_TLS_PSK_MAX_LEN, NVME_TCP_HASH_ALGORITHM_SHA256) > 0); 14647a50a6bcSKrzysztof Karas CU_ASSERT(memcmp(psk_retained1, psk_retained2, retained_size) != 0); 14657a50a6bcSKrzysztof Karas 1466572a0c8aSKrzysztof Karas /* Make sure that retained PSKs are different with different hash and the same input PSKs. */ 1467572a0c8aSKrzysztof Karas psk_retained_len1 = nvme_tcp_derive_retained_psk(unhexlified_str1, strlen(psk_reference1) / 2, 1468572a0c8aSKrzysztof Karas hostnqn, psk_retained1, SPDK_TLS_PSK_MAX_LEN, NVME_TCP_HASH_ALGORITHM_SHA256); 1469572a0c8aSKrzysztof Karas CU_ASSERT(psk_retained_len1 > 0); 1470572a0c8aSKrzysztof Karas psk_retained_len2 = nvme_tcp_derive_retained_psk(unhexlified_str1, strlen(psk_reference1) / 2, 1471572a0c8aSKrzysztof Karas hostnqn, psk_retained2, SPDK_TLS_PSK_MAX_LEN, NVME_TCP_HASH_ALGORITHM_SHA384); 1472572a0c8aSKrzysztof Karas CU_ASSERT(psk_retained_len2 > 0); 1473572a0c8aSKrzysztof Karas CU_ASSERT(psk_retained_len1 < psk_retained_len2); 1474572a0c8aSKrzysztof Karas 1475572a0c8aSKrzysztof Karas /* Make sure that passing unknown value as hash errors out the function. */ 1476572a0c8aSKrzysztof Karas CU_ASSERT(nvme_tcp_derive_retained_psk(unhexlified_str1, strlen(psk_reference1) / 2, hostnqn, 1477572a0c8aSKrzysztof Karas psk_retained1, SPDK_TLS_PSK_MAX_LEN, -1) < 0); 1478572a0c8aSKrzysztof Karas 14797a50a6bcSKrzysztof Karas /* Make sure that passing buffer insufficient in size errors out the function. */ 1480572a0c8aSKrzysztof Karas CU_ASSERT(nvme_tcp_derive_retained_psk(unhexlified_str1, strlen(psk_reference1) / 2, hostnqn, 1481572a0c8aSKrzysztof Karas too_small_psk_retained, sizeof(too_small_psk_retained), NVME_TCP_HASH_ALGORITHM_SHA256) < 0); 14827a50a6bcSKrzysztof Karas } 14837a50a6bcSKrzysztof Karas 1484e036416bSKrzysztof Karas static void 1485e036416bSKrzysztof Karas test_nvmf_tcp_tls_generate_tls_psk(void) 1486e036416bSKrzysztof Karas { 1487e036416bSKrzysztof Karas const char psk_id_reference[] = {"NVMe0R01 nqn.2016-06.io.spdk:host1 nqn.2016-06.io.spdk:cnode1"}; 1488e036416bSKrzysztof Karas const char hostnqn[] = {"nqn.2016-06.io.spdk:host1"}; 1489e036416bSKrzysztof Karas const char psk_reference[] = {"1234567890ABCDEF"}; 1490572a0c8aSKrzysztof Karas char *unhexlified; 1491572a0c8aSKrzysztof Karas uint8_t unhexlified_str[SPDK_TLS_PSK_MAX_LEN] = {}; 1492e036416bSKrzysztof Karas uint8_t psk_retained[SPDK_TLS_PSK_MAX_LEN] = {}; 1493572a0c8aSKrzysztof Karas uint8_t psk_key1[SPDK_TLS_PSK_MAX_LEN] = {}, psk_key2[SPDK_TLS_PSK_MAX_LEN] = {}; 1494e036416bSKrzysztof Karas uint8_t too_small_psk_tls[5] = {}; 1495572a0c8aSKrzysztof Karas int retained_size, tls_size; 1496e036416bSKrzysztof Karas 1497572a0c8aSKrzysztof Karas unhexlified = spdk_unhexlify(psk_reference); 1498572a0c8aSKrzysztof Karas CU_ASSERT(unhexlified != NULL); 1499572a0c8aSKrzysztof Karas 1500572a0c8aSKrzysztof Karas memcpy(unhexlified_str, unhexlified, strlen(psk_reference) / 2); 1501572a0c8aSKrzysztof Karas free(unhexlified); 1502572a0c8aSKrzysztof Karas 1503572a0c8aSKrzysztof Karas retained_size = nvme_tcp_derive_retained_psk(unhexlified_str, strlen(psk_reference) / 2, hostnqn, 1504572a0c8aSKrzysztof Karas psk_retained, SPDK_TLS_PSK_MAX_LEN, NVME_TCP_HASH_ALGORITHM_SHA256); 1505e036416bSKrzysztof Karas CU_ASSERT(retained_size > 0); 1506e036416bSKrzysztof Karas 1507572a0c8aSKrzysztof Karas /* Make sure that different cipher suites produce different TLS PSKs. */ 1508572a0c8aSKrzysztof Karas tls_size = nvme_tcp_derive_tls_psk(psk_retained, retained_size, psk_id_reference, psk_key1, 1509572a0c8aSKrzysztof Karas SPDK_TLS_PSK_MAX_LEN, NVME_TCP_CIPHER_AES_128_GCM_SHA256); 1510572a0c8aSKrzysztof Karas CU_ASSERT(tls_size > 0); 1511572a0c8aSKrzysztof Karas CU_ASSERT(nvme_tcp_derive_tls_psk(psk_retained, retained_size, psk_id_reference, psk_key2, 1512572a0c8aSKrzysztof Karas SPDK_TLS_PSK_MAX_LEN, NVME_TCP_CIPHER_AES_256_GCM_SHA384) > 0); 1513572a0c8aSKrzysztof Karas CU_ASSERT(memcmp(psk_key1, psk_key2, tls_size) != 0); 1514572a0c8aSKrzysztof Karas 1515572a0c8aSKrzysztof Karas /* Make sure that passing unknown value as hash errors out the function. */ 1516572a0c8aSKrzysztof Karas CU_ASSERT(nvme_tcp_derive_tls_psk(psk_retained, retained_size, psk_id_reference, 1517572a0c8aSKrzysztof Karas psk_key1, SPDK_TLS_PSK_MAX_LEN, UINT8_MAX) < 0); 1518572a0c8aSKrzysztof Karas 1519e036416bSKrzysztof Karas /* Make sure that passing buffer insufficient in size errors out the function. */ 1520e036416bSKrzysztof Karas CU_ASSERT(nvme_tcp_derive_tls_psk(psk_retained, retained_size, psk_id_reference, 1521169ee6c3SKrzysztof Karas too_small_psk_tls, sizeof(too_small_psk_tls), 1522169ee6c3SKrzysztof Karas NVME_TCP_CIPHER_AES_128_GCM_SHA256) < 0); 1523e036416bSKrzysztof Karas } 1524e036416bSKrzysztof Karas 15258dd1cd21SBen Walker int 15268dd1cd21SBen Walker main(int argc, char **argv) 15274c30f7fcSYanbo Zhou { 15284c30f7fcSYanbo Zhou CU_pSuite suite = NULL; 15294c30f7fcSYanbo Zhou unsigned int num_failures; 15304c30f7fcSYanbo Zhou 153178b696bcSVitaliy Mysak CU_initialize_registry(); 15324c30f7fcSYanbo Zhou 15334c30f7fcSYanbo Zhou suite = CU_add_suite("nvmf", NULL, NULL); 15344c30f7fcSYanbo Zhou 1535dcf0ca15SVitaliy Mysak CU_ADD_TEST(suite, test_nvmf_tcp_create); 1536dcf0ca15SVitaliy Mysak CU_ADD_TEST(suite, test_nvmf_tcp_destroy); 1537dcf0ca15SVitaliy Mysak CU_ADD_TEST(suite, test_nvmf_tcp_poll_group_create); 1538dcf0ca15SVitaliy Mysak CU_ADD_TEST(suite, test_nvmf_tcp_send_c2h_data); 1539dcf0ca15SVitaliy Mysak CU_ADD_TEST(suite, test_nvmf_tcp_h2c_data_hdr_handle); 1540c9c7c281SJosh Soref CU_ADD_TEST(suite, test_nvmf_tcp_in_capsule_data_handle); 15410d1c7bf8SMao Jiang CU_ADD_TEST(suite, test_nvmf_tcp_qpair_init_mem_resource); 1542be4e9db7SChengqiangMeng CU_ADD_TEST(suite, test_nvmf_tcp_send_c2h_term_req); 1543476a77f9SMao Jiang CU_ADD_TEST(suite, test_nvmf_tcp_send_capsule_resp_pdu); 1544a2838de9SChengqiangMeng CU_ADD_TEST(suite, test_nvmf_tcp_icreq_handle); 1545f7b9f80bSmatthewb CU_ADD_TEST(suite, test_nvmf_tcp_check_xfer_type); 1546f7b9f80bSmatthewb CU_ADD_TEST(suite, test_nvmf_tcp_invalid_sgl); 1547fbed5966Sxiaoxiangxzhang CU_ADD_TEST(suite, test_nvmf_tcp_pdu_ch_handle); 1548663243cbSKrzysztof Karas CU_ADD_TEST(suite, test_nvmf_tcp_tls_add_remove_credentials); 15493e98fd06SKrzysztof Karas CU_ADD_TEST(suite, test_nvmf_tcp_tls_generate_psk_id); 15507a50a6bcSKrzysztof Karas CU_ADD_TEST(suite, test_nvmf_tcp_tls_generate_retained_psk); 1551e036416bSKrzysztof Karas CU_ADD_TEST(suite, test_nvmf_tcp_tls_generate_tls_psk); 15524c30f7fcSYanbo Zhou 1553ea941caeSKonrad Sztyber num_failures = spdk_ut_run_tests(argc, argv, NULL); 15544c30f7fcSYanbo Zhou CU_cleanup_registry(); 15554c30f7fcSYanbo Zhou return num_failures; 15564c30f7fcSYanbo Zhou } 1557