// SPDX-License-Identifier: LGPL-2.1-or-later /** * This file is part of libnvme. * Copyright (c) 2023 Daniel Wagner, SUSE LLC */ #include #include #include #include #include #include #include #include struct test_data { /* input data */ const char *subsysname; const char *subsysnqn; const char *transport; const char *traddr; const char *host_traddr; const char *host_iface; const char *trsvcid; /* track controller generated by input data */ nvme_subsystem_t s; nvme_ctrl_t c; int ctrl_id; }; #define DEFAULT_SUBSYSNAME "subsysname" #define DEFAULT_SUBSYSNQN "subsysnqn" #define SRC_ADDR4 "192.168.56.100" #define SRC_ADDR6 "1234:5678:abcd:EF01:1234:5678:abcd:EF01" struct test_data test_data[] = { { DEFAULT_SUBSYSNAME, DEFAULT_SUBSYSNQN, "tcp", "192.168.1.1", "192.168.1.20", NULL, "4420" }, { DEFAULT_SUBSYSNAME, DEFAULT_SUBSYSNQN, "tcp", "192.168.1.1", "192.168.1.20", NULL, "4421" }, { DEFAULT_SUBSYSNAME, DEFAULT_SUBSYSNQN, "tcp", "192.168.1.2", "192.168.1.20", "eth1", "4420" }, { DEFAULT_SUBSYSNAME, DEFAULT_SUBSYSNQN, "tcp", "192.168.1.2", "192.168.1.20", "eth1", "4421" }, { DEFAULT_SUBSYSNAME, DEFAULT_SUBSYSNQN, "rdma", "192.168.1.3", "192.168.1.20", NULL, NULL }, { DEFAULT_SUBSYSNAME, DEFAULT_SUBSYSNQN, "rdma", "192.168.1.4", "192.168.1.20", NULL, NULL }, { DEFAULT_SUBSYSNAME, DEFAULT_SUBSYSNQN, "fc", "nn-0x201700a09890f5bf:pn-0x201900a09890f5bf", "nn-0x200000109b579ef3:pn-0x100000109b579ef3" }, { DEFAULT_SUBSYSNAME, DEFAULT_SUBSYSNQN, "fc", "nn-0x201700a09890f5bf:pn-0x201900a09890f5bf", "nn-0x200000109b579ef6:pn-0x100000109b579ef6", }, }; static struct test_data *find_test_data(nvme_ctrl_t c) { for (int i = 0; i < ARRAY_SIZE(test_data); i++) { struct test_data *d = &test_data[i]; if (d->c == c) return d; } return NULL; } static void show_ctrl(nvme_ctrl_t c) { struct test_data *d = find_test_data(c); if (d) printf("ctrl%d ", d->ctrl_id); else printf(" "); printf("0x%p: %s %s %s %s %s ", c, nvme_ctrl_get_transport(c), nvme_ctrl_get_traddr(c), nvme_ctrl_get_host_traddr(c), nvme_ctrl_get_host_iface(c), nvme_ctrl_get_trsvcid(c)); } static bool match_ctrl(struct test_data *d, nvme_ctrl_t c) { bool pass = true; const char *trsvid, *host_traddr, *host_iface; if (d->c != c) pass = false; if (strcmp(d->transport, nvme_ctrl_get_transport(d->c))) pass = false; if (strcmp(d->traddr, nvme_ctrl_get_traddr(d->c))) pass = false; host_traddr = nvme_ctrl_get_host_traddr(c); if (d->host_traddr && (!host_traddr || strcmp(d->host_traddr, host_traddr))) pass = false; host_iface = nvme_ctrl_get_host_iface(c); if (d->host_iface && (!host_iface || strcmp(d->host_iface, host_iface))) pass = false; trsvid = nvme_ctrl_get_trsvcid(c); if (d->trsvcid && (!trsvid || strcmp(d->trsvcid, trsvid))) pass = false; printf("[%s]", pass? "PASS" : "FAILED"); return pass; } static nvme_root_t create_tree() { nvme_root_t r; nvme_host_t h; r = nvme_create_root(stdout, LOG_DEBUG); assert(r); h = nvme_default_host(r); assert(h); printf(" ctrls created:\n"); for (int i = 0; i < ARRAY_SIZE(test_data); i++) { struct test_data *d = &test_data[i]; d->s = nvme_lookup_subsystem(h, d->subsysname, d->subsysnqn); assert(d->s); d->c = nvme_lookup_ctrl(d->s, d->transport, d->traddr, d->host_traddr, d->host_iface, d->trsvcid, NULL); assert(d->c); d->ctrl_id = i; printf(" "); show_ctrl(d->c); match_ctrl(d, d->c); printf("\n"); } printf("\n"); return r; } static unsigned int count_entries(nvme_root_t r) { nvme_host_t h; nvme_subsystem_t s; nvme_ctrl_t c; unsigned int i = 0; nvme_for_each_host(r, h) nvme_for_each_subsystem(h, s) nvme_subsystem_for_each_ctrl(s, c) i++; return i; } static bool tcp_ctrl_lookup(nvme_subsystem_t s, struct test_data *d) { nvme_ctrl_t c; bool pass = true; c = nvme_lookup_ctrl(s, d->transport, d->traddr, NULL, NULL, d->trsvcid, NULL); printf("%10s %12s %10s -> ", d->trsvcid, "", ""); show_ctrl(c); pass &= match_ctrl(d, c); printf("\n"); if (d->host_traddr) { c = nvme_lookup_ctrl(s, d->transport, d->traddr, d->host_traddr, NULL, d->trsvcid, NULL); printf("%10s %12s %10s -> ", d->trsvcid, d->host_traddr, ""); show_ctrl(c); pass &= match_ctrl(d, c); printf("\n"); } if (d->host_iface) { c = nvme_lookup_ctrl(s, d->transport, d->traddr, NULL, d->host_iface, d->trsvcid, NULL); printf("%10s %12s %10s -> ", d->trsvcid, "", d->host_iface); show_ctrl(c); pass &= match_ctrl(d, c); printf("\n"); } if (d->host_iface && d->traddr) { c = nvme_lookup_ctrl(s, d->transport, d->traddr, d->host_traddr, d->host_iface, d->trsvcid, NULL); printf("%10s %12s %10s -> ", d->trsvcid, d->host_traddr, d->host_iface); show_ctrl(c); pass &= match_ctrl(d, c); printf("\n"); } return pass; } static bool default_ctrl_lookup(nvme_subsystem_t s, struct test_data *d) { nvme_ctrl_t c; bool pass = true; c = nvme_lookup_ctrl(s, d->transport, d->traddr, d->host_traddr, NULL, NULL, NULL); printf("%10s %12s %10s -> ", "", "", ""); show_ctrl(c); pass &= match_ctrl(d, c); printf("\n"); return pass; } static bool ctrl_lookups(nvme_root_t r) { nvme_host_t h; nvme_subsystem_t s; bool pass = true; h = nvme_first_host(r); s = nvme_lookup_subsystem(h, DEFAULT_SUBSYSNAME, DEFAULT_SUBSYSNQN); printf(" lookup controller:\n"); for (int i = 0; i < ARRAY_SIZE(test_data); i++) { struct test_data *d = &test_data[i]; printf("%10s %12s %10s ", "", "", ""); show_ctrl(d->c); printf("\n"); if (!strcmp("tcp", d->transport)) pass &= tcp_ctrl_lookup(s, d); else pass &= default_ctrl_lookup(s, d); printf("\n"); } return pass; } static bool test_lookup(void) { nvme_root_t r; bool pass; printf("test_lookup:\n"); r = create_tree(); pass = count_entries(r) == ARRAY_SIZE(test_data); pass &= ctrl_lookups(r); nvme_free_tree(r); return pass; } static bool test_src_addr() { bool pass = true; nvme_root_t r; nvme_host_t h; nvme_ctrl_t c; nvme_subsystem_t s; char *src_addr, buffer[100]; /* big enough for IPv6 max length */ printf("\n" "test_src_addr:\n"); r = nvme_create_root(stdout, LOG_DEBUG); assert(r); h = nvme_default_host(r); assert(h); s = nvme_lookup_subsystem(h, DEFAULT_SUBSYSNAME, DEFAULT_SUBSYSNQN); assert(s); c = nvme_lookup_ctrl(s, "tcp", "192.168.56.1", NULL, NULL, "8009", NULL); assert(c); c->address = NULL; printf(" - Test c->address = NULL : src_addr = NULL "); src_addr = nvme_ctrl_get_src_addr(c, buffer, sizeof(buffer)); if (src_addr != NULL) { printf("[FAIL]\n"); fprintf(stderr, "nvme_ctrl_get_src_addr() c->address=NULL should return src_addr=NULL\n"); pass = false; } else { printf("[PASS]\n"); } c->address = ""; printf(" - Test c->address = \"\" : src_addr = NULL "); src_addr = nvme_ctrl_get_src_addr(c, buffer, sizeof(buffer)); if (src_addr != NULL) { printf("[FAIL]\n"); fprintf(stderr, "nvme_ctrl_get_src_addr() c->address="" should return src_addr=NULL\n"); pass = false; } else { printf("[PASS]\n"); } c->address = "traddr=192.168.56.1,trsvcid=8009"; printf(" - Test c->address = \"%s\" : src_addr = NULL ", c->address); src_addr = nvme_ctrl_get_src_addr(c, buffer, sizeof(buffer)); if (src_addr != NULL) { printf("[FAIL]\n"); fprintf(stderr, "nvme_ctrl_get_src_addr() c->address=%s should return src_addr=NULL\n", c->address); pass = false; } else { printf("[PASS]\n"); } c->address = "traddr=192.168.56.1,trsvcid=8009,src_addr=" SRC_ADDR4; printf(" - Test c->address = \"%s\" : src_addr = \"" SRC_ADDR4 "\" ", c->address); src_addr = nvme_ctrl_get_src_addr(c, buffer, sizeof(buffer)); if (!src_addr || strcmp(src_addr, SRC_ADDR4)) { printf("[FAIL]\n"); fprintf(stderr, "nvme_ctrl_get_src_addr() c->address=%s should return src_addr=" SRC_ADDR4 "\n", c->address); pass = false; } else { printf("[PASS]\n"); } c->address = "traddr=192.168.56.1,src_addr=" SRC_ADDR4 ",trsvcid=8009"; printf(" - Test c->address = \"%s\" : src_addr = \"" SRC_ADDR4 "\" ", c->address); src_addr = nvme_ctrl_get_src_addr(c, buffer, sizeof(buffer)); if (!src_addr || strcmp(src_addr, SRC_ADDR4)) { printf("[FAIL]\n"); fprintf(stderr, "nvme_ctrl_get_src_addr() c->address=%s should return src_addr=" SRC_ADDR4 "\n", c->address); pass = false; } else { printf("[PASS]\n"); } c->address = "traddr=1234::abcd,trsvcid=8009,src_addr=" SRC_ADDR6; printf(" - Test c->address = \"%s\" : src_addr = \"" SRC_ADDR6 "\" ", c->address); src_addr = nvme_ctrl_get_src_addr(c, buffer, sizeof(buffer)); if (!src_addr || strcmp(src_addr, SRC_ADDR6)) { printf("[FAIL]\n"); fprintf(stderr, "nvme_ctrl_get_src_addr() c->address=%s should return src_addr=" SRC_ADDR6 "\n", c->address); pass = false; } else { printf("[PASS]\n"); } c->address = "traddr=1234::abcd,src_addr=" SRC_ADDR6 ",trsvcid=8009"; printf(" - Test c->address = \"%s\" : src_addr = \"" SRC_ADDR6 "\" ", c->address); src_addr = nvme_ctrl_get_src_addr(c, buffer, sizeof(buffer)); if (!src_addr || strcmp(src_addr, SRC_ADDR6)) { printf("[FAIL]\n"); fprintf(stderr, "nvme_ctrl_get_src_addr() c->address=%s should return src_addr=" SRC_ADDR6 "\n", c->address); pass = false; } else { printf("[PASS]\n"); } c->address = "traddr=1234::abcd,trsvcid=8009,src_addr=" SRC_ADDR6 "%scope"; printf(" - Test c->address = \"%s\" : src_addr = \"" SRC_ADDR6 "\" ", c->address); src_addr = nvme_ctrl_get_src_addr(c, buffer, sizeof(buffer)); if (!src_addr || strcmp(src_addr, SRC_ADDR6)) { printf("[FAIL]\n"); fprintf(stderr, "nvme_ctrl_get_src_addr() c->address=%s should return src_addr=" SRC_ADDR6 "\n", c->address); pass = false; } else { printf("[PASS]\n"); } c->address = "traddr=1234::abcd,src_addr=" SRC_ADDR6 "%scope,trsvcid=8009"; printf(" - Test c->address = \"%s\" : src_addr = \"" SRC_ADDR6 "\" ", c->address); src_addr = nvme_ctrl_get_src_addr(c, buffer, sizeof(buffer)); if (!src_addr || strcmp(src_addr, SRC_ADDR6)) { printf("[FAIL]\n"); fprintf(stderr, "nvme_ctrl_get_src_addr() c->address=%s should return src_addr=" SRC_ADDR6 "\n", c->address); pass = false; } else { printf("[PASS]\n"); } c->address = NULL; /* Needed to avoid freeing non-malloced memory (see above) */ nvme_free_tree(r); return pass; } struct ctrl_args { const char *transport; const char *traddr; const char *trsvcid; const char *host_traddr; const char *host_iface; const char *address; const char *subsysnqn; }; static void set_ctrl_args(struct ctrl_args *args, const char *transport, const char *traddr, const char *trsvcid, const char *host_traddr, const char *host_iface, const char *address, const char *subsysnqn) { args->transport = transport; args->traddr = traddr; args->trsvcid = trsvcid; args->host_traddr = host_traddr; args->host_iface = host_iface; args->address = address; args->subsysnqn = subsysnqn; } static bool ctrl_match(const char *tag, int reference_id, int candidate_id, struct ctrl_args *reference, struct ctrl_args *candidate, bool should_match) { nvme_root_t r; nvme_host_t h; nvme_ctrl_t reference_ctrl; /* Existing controller (from sysfs) */ nvme_ctrl_t candidate_ctrl; nvme_ctrl_t found_ctrl; nvme_subsystem_t s; r = nvme_create_root(stdout, LOG_INFO); assert(r); h = nvme_default_host(r); assert(h); s = nvme_lookup_subsystem(h, DEFAULT_SUBSYSNAME, reference->subsysnqn ? reference->subsysnqn : DEFAULT_SUBSYSNQN); assert(s); reference_ctrl = nvme_lookup_ctrl(s, reference->transport, reference->traddr, reference->host_traddr, reference->host_iface, reference->trsvcid, NULL); assert(reference_ctrl); reference_ctrl->name = "nvme1"; /* fake the device name */ if (reference->address) { reference_ctrl->address = (char *)reference->address; } /* nvme_ctrl_find() MUST BE RUN BEFORE nvme_lookup_ctrl() */ found_ctrl = nvme_ctrl_find(s, candidate->transport, candidate->traddr, candidate->trsvcid, candidate->subsysnqn, candidate->host_traddr, candidate->host_iface); candidate_ctrl = nvme_lookup_ctrl(s, candidate->transport, candidate->traddr, candidate->host_traddr, candidate->host_iface, candidate->trsvcid, NULL); if (should_match) { if (candidate_ctrl != reference_ctrl) { printf("%s-%d-%d: Candidate (%s, %s, %s, %s, %s, %s) failed to match (%s, %s, %s, %s, %s, %s, %s)\n", tag, reference_id, candidate_id, candidate->transport, candidate->traddr, candidate->trsvcid, candidate->subsysnqn, candidate->host_traddr, candidate->host_iface, reference->transport, reference->traddr, reference->trsvcid, reference->subsysnqn, reference->host_traddr, reference->host_iface, reference->address); return false; } if (!found_ctrl) { printf("%s-%d-%d: Candidate (%s, %s, %s, %s, %s, %s) failed to find controller\n", tag, reference_id, candidate_id, candidate->transport, candidate->traddr, candidate->trsvcid, candidate->subsysnqn, candidate->host_traddr, candidate->host_iface); return false; } } else { if (candidate_ctrl == reference_ctrl) { printf("%s-%d-%d: Candidate (%s, %s, %s, %s, %s, %s) should not match (%s, %s, %s, %s, %s, %s, %s)\n", tag, reference_id, candidate_id, candidate->transport, candidate->traddr, candidate->trsvcid, candidate->subsysnqn, candidate->host_traddr, candidate->host_iface, reference->transport, reference->traddr, reference->trsvcid, reference->subsysnqn, reference->host_traddr, reference->host_iface, reference->address); return false; } if (found_ctrl) { printf("%s-%d-%d: Candidate (%s, %s, %s, %s, %s, %s) should not have found controller. found_ctrl=%p reference=%p\n", tag, reference_id, candidate_id, candidate->transport, candidate->traddr, candidate->trsvcid, candidate->subsysnqn, candidate->host_traddr, candidate->host_iface, found_ctrl, reference_ctrl); return false; } } /* Set the faked data back to NULL before freeing the tree */ reference_ctrl->name = NULL; reference_ctrl->address = NULL; nvme_free_tree(r); return true; } /** * test_ctrl_match_fc - Test that we can look up FC controllers * * @return true when all tests have passed. false otherwise. */ static bool test_ctrl_match_fc(void) { bool pass = true; struct ctrl_args reference = {0}; struct ctrl_args candidate = {0}; printf("test_ctrl_match_fc:\n"); /*******************************************************************/ /* Reference ID 1 */ set_ctrl_args(&reference, "fc", "21:00:00:e0:8b:05:05:01", "4420", "21:00:00:e0:8b:05:05:20", NULL, NULL, NULL); set_ctrl_args(&candidate, "fc", "21:00:00:e0:8b:05:05:01", "4420", "21:00:00:e0:8b:05:05:20", NULL, NULL, NULL); pass &= ctrl_match("FC", 1, 0, &reference, &candidate, true); set_ctrl_args(&candidate, "fc", "21:00:00:e0:8b:05:05:01", "4420", NULL, NULL, NULL, NULL); pass &= ctrl_match("FC", 1, 1, &reference, &candidate, true); set_ctrl_args(&candidate, "fc", "21:00:00:e0:8b:05:05:01", "4420", NULL, "eth0", NULL, NULL); pass &= ctrl_match("FC", 1, 2, &reference, &candidate, true); set_ctrl_args(&candidate, "fc", "192.168.2.2", "4420", NULL, "eth0", NULL, NULL); pass &= ctrl_match("FC", 1, 3, &reference, &candidate, false); set_ctrl_args(&candidate, "fc", "21:00:00:e0:8b:05:05:01", "8009", NULL, NULL, NULL, NULL); pass &= ctrl_match("FC", 1, 4, &reference, &candidate, false); set_ctrl_args(&candidate, "fc", "21:00:00:e0:8b:05:05:01", "4420", "21:00:00:e0:8b:05:05:21", NULL, NULL, NULL); pass &= ctrl_match("FC", 1, 5, &reference, &candidate, false); set_ctrl_args(&candidate, "fc", "21:00:00:e0:8b:05:05:01", "8009", NULL, "", NULL, NULL); pass &= ctrl_match("FC", 1, 6, &reference, &candidate, false); /*******************************************************************/ /* Reference ID 2 */ set_ctrl_args(&reference, "fc", "21:00:00:e0:8b:05:05:01", "4420", NULL, NULL, NULL, NULL); set_ctrl_args(&candidate, "fc", "21:00:00:e0:8b:05:05:01", "4420", "21:00:00:e0:8b:05:05:20", NULL, NULL, NULL); pass &= ctrl_match("FC", 2, 0, &reference, &candidate, true); set_ctrl_args(&candidate, "fc", "21:00:00:e0:8b:05:05:01", "4420", NULL, NULL, NULL, NULL); pass &= ctrl_match("FC", 2, 1, &reference, &candidate, true); set_ctrl_args(&candidate, "fc", "21:00:00:e0:8b:05:05:01", "4420", NULL, "eth0", NULL, NULL); pass &= ctrl_match("FC", 2, 2, &reference, &candidate, true); set_ctrl_args(&candidate, "fc", "192.168.2.2", "4420", NULL, "eth0", NULL, NULL); pass &= ctrl_match("FC", 2, 3, &reference, &candidate, false); set_ctrl_args(&candidate, "fc", "21:00:00:e0:8b:05:05:01", "8009", NULL, NULL, NULL, NULL); pass &= ctrl_match("FC", 2, 4, &reference, &candidate, false); set_ctrl_args(&candidate, "fc", "21:00:00:e0:8b:05:05:01", "8009", NULL, "", NULL, NULL); pass &= ctrl_match("FC", 2, 5, &reference, &candidate, false); /*******************************************************************/ /* Reference ID 3 */ set_ctrl_args(&reference, "fc", "21:00:00:e0:8b:05:05:01", "4420", NULL, "eth0", NULL, NULL); set_ctrl_args(&candidate, "fc", "21:00:00:e0:8b:05:05:01", "4420", "21:00:00:e0:8b:05:05:20", NULL, NULL, NULL); pass &= ctrl_match("FC", 3, 0, &reference, &candidate, true); set_ctrl_args(&candidate, "fc", "21:00:00:e0:8b:05:05:01", "4420", NULL, NULL, NULL, NULL); pass &= ctrl_match("FC", 3, 1, &reference, &candidate, true); set_ctrl_args(&candidate, "fc", "21:00:00:e0:8b:05:05:01", "4420", NULL, "eth0", NULL, NULL); pass &= ctrl_match("FC", 3, 2, &reference, &candidate, true); set_ctrl_args(&candidate, "fc", "192.168.2.2", "4420", NULL, "eth0", NULL, NULL); pass &= ctrl_match("FC", 3, 3, &reference, &candidate, false); set_ctrl_args(&candidate, "fc", "21:00:00:e0:8b:05:05:01", "8009", NULL, NULL, NULL, NULL); pass &= ctrl_match("FC", 3, 4, &reference, &candidate, false); set_ctrl_args(&candidate, "fc", "21:00:00:e0:8b:05:05:01", "8009", NULL, "", NULL, NULL); pass &= ctrl_match("FC", 3, 5, &reference, &candidate, false); return pass; } /** * test_ctrl_match_rdma - Test that we can look up RDMA controllers * * @return true when all tests have passed. false otherwise. */ static bool test_ctrl_match_rdma(void) { bool pass = true; struct ctrl_args reference = {0}; struct ctrl_args candidate = {0}; printf("test_ctrl_match_rdma:\n"); /*******************************************************************/ /* Reference ID 1 */ set_ctrl_args(&reference, "rdma", "192.168.2.1", "4420", "192.168.1.20", NULL, NULL, NULL); set_ctrl_args(&candidate, "rdma", "192.168.2.1", "4420", "192.168.1.20", NULL, NULL, NULL); pass &= ctrl_match("RDMA", 1, 0, &reference, &candidate, true); set_ctrl_args(&candidate, "rdma", "192.168.2.1", "4420", NULL, NULL, NULL, NULL); pass &= ctrl_match("RDMA", 1, 1, &reference, &candidate, true); set_ctrl_args(&candidate, "rdma", "192.168.2.1", "4420", NULL, "eth0", NULL, NULL); pass &= ctrl_match("RDMA", 1, 2, &reference, &candidate, true); set_ctrl_args(&candidate, "rdma", "192.168.2.2", "4420", NULL, "eth0", NULL, NULL); pass &= ctrl_match("RDMA", 1, 3, &reference, &candidate, false); set_ctrl_args(&candidate, "rdma", "192.168.2.1", "8009", NULL, NULL, NULL, NULL); pass &= ctrl_match("RDMA", 1, 4, &reference, &candidate, false); set_ctrl_args(&candidate, "rdma", "192.168.2.1", "4420", "192.168.1.21", NULL, NULL, NULL); pass &= ctrl_match("RDMA", 1, 5, &reference, &candidate, false); set_ctrl_args(&candidate, "rdma", "192.168.2.1", "8009", NULL, "", NULL, NULL); pass &= ctrl_match("RDMA", 1, 6, &reference, &candidate, false); /*******************************************************************/ /* Reference ID 2 */ set_ctrl_args(&reference, "rdma", "192.168.2.1", "4420", NULL, NULL, NULL, NULL); set_ctrl_args(&candidate, "rdma", "192.168.2.1", "4420", "192.168.1.20", NULL, NULL, NULL); pass &= ctrl_match("RDMA", 2, 0, &reference, &candidate, true); set_ctrl_args(&candidate, "rdma", "192.168.2.1", "4420", NULL, NULL, NULL, NULL); pass &= ctrl_match("RDMA", 2, 1, &reference, &candidate, true); set_ctrl_args(&candidate, "rdma", "192.168.2.1", "4420", NULL, "eth0", NULL, NULL); pass &= ctrl_match("RDMA", 2, 2, &reference, &candidate, true); set_ctrl_args(&candidate, "rdma", "192.168.2.2", "4420", NULL, "eth0", NULL, NULL); pass &= ctrl_match("RDMA", 2, 3, &reference, &candidate, false); set_ctrl_args(&candidate, "rdma", "192.168.2.1", "8009", NULL, NULL, NULL, NULL); pass &= ctrl_match("RDMA", 2, 4, &reference, &candidate, false); set_ctrl_args(&candidate, "rdma", "192.168.2.1", "8009", NULL, "", NULL, NULL); pass &= ctrl_match("RDMA", 2, 5, &reference, &candidate, false); /*******************************************************************/ /* Reference ID 3 */ set_ctrl_args(&reference, "rdma", "192.168.2.1", "4420", NULL, "eth0", NULL, NULL); set_ctrl_args(&candidate, "rdma", "192.168.2.1", "4420", "192.168.1.20", NULL, NULL, NULL); pass &= ctrl_match("RDMA", 3, 0, &reference, &candidate, true); set_ctrl_args(&candidate, "rdma", "192.168.2.1", "4420", NULL, NULL, NULL, NULL); pass &= ctrl_match("RDMA", 3, 1, &reference, &candidate, true); set_ctrl_args(&candidate, "rdma", "192.168.2.1", "4420", NULL, "eth0", NULL, NULL); pass &= ctrl_match("RDMA", 3, 2, &reference, &candidate, true); set_ctrl_args(&candidate, "rdma", "192.168.2.2", "4420", NULL, "eth0", NULL, NULL); pass &= ctrl_match("RDMA", 3, 3, &reference, &candidate, false); set_ctrl_args(&candidate, "rdma", "192.168.2.1", "8009", NULL, NULL, NULL, NULL); pass &= ctrl_match("RDMA", 3, 4, &reference, &candidate, false); set_ctrl_args(&candidate, "rdma", "192.168.2.1", "8009", NULL, "", NULL, NULL); pass &= ctrl_match("RDMA", 3, 5, &reference, &candidate, false); return pass; } /** * test_ctrl_match_tcp - Test that we can look up TCP controllers * * @note: The mocked getifaddrs() returns 2 interface entries with the * following addresses. Therefore the tests must use IP addresses * that match these. * * eth0 * \_ 192.168.1.20 * \_ fe80::dead:beef * * lo * \_ 127.0.0.1 * \_ ::1 * * @return true when all tests have passed. false otherwise. */ static bool test_ctrl_match_tcp() { bool pass = true; struct ctrl_args reference = {0}; struct ctrl_args candidate = {0}; printf("\n" "test_ctrl_match_tcp:\n"); /*******************************************************************/ /* IPv4: Reference ID 1 */ set_ctrl_args(&reference, "tcp", "123.123.123.123", "8009", NULL, NULL, NULL, NULL); set_ctrl_args(&candidate, "tcp", "123.123.123.123", "8009", NULL, NULL, NULL, NULL); pass &= ctrl_match("IPv4", 1, 0, &reference, &candidate, true); set_ctrl_args(&candidate, "tcp", "123.123.123.123", "8009", "192.168.1.20", NULL, NULL, NULL); pass &= ctrl_match("IPv4", 1, 1, &reference, &candidate, true); set_ctrl_args(&candidate, "tcp", "123.123.123.123", "8009", NULL, "eth0", NULL, NULL); pass &= ctrl_match("IPv4", 1, 2, &reference, &candidate, true); set_ctrl_args(&candidate, "tcp", "123.123.123.123", "8009", "192.168.1.20", "eth0", NULL, NULL); pass &= ctrl_match("IPv4", 1, 3, &reference, &candidate, true); set_ctrl_args(&candidate, "tcp", "123.123.123.123", "8009", "192.168.1.21", NULL, NULL, NULL); pass &= ctrl_match("IPv4", 1, 4, &reference, &candidate, true); set_ctrl_args(&candidate, "tcp", "123.123.123.123", "8009", "192.168.1.21", "eth0", NULL, NULL); pass &= ctrl_match("IPv4", 1, 5, &reference, &candidate, true); set_ctrl_args(&candidate, "tcp", "123.123.123.123", "8009", NULL, "lo", NULL, NULL); pass &= ctrl_match("IPv4", 1, 6, &reference, &candidate, true); set_ctrl_args(&candidate, "tcp", "123.123.123.123", "8009", "192.168.1.20", "lo", NULL, NULL); pass &= ctrl_match("IPv4", 1, 7, &reference, &candidate, true); set_ctrl_args(&candidate, "tcp", "123.123.123.123", "8009", "192.168.1.21", "lo", NULL, NULL); pass &= ctrl_match("IPv4", 1, 8, &reference, &candidate, true); /*******************************************************************/ /* IPv4: Reference ID 2 */ set_ctrl_args(&reference, "tcp", "123.123.123.123", "8009", "192.168.1.20", NULL, NULL, NULL); set_ctrl_args(&candidate, "tcp", "123.123.123.123", "8009", NULL, NULL, NULL, NULL); pass &= ctrl_match("IPv4", 2, 0, &reference, &candidate, true); set_ctrl_args(&candidate, "tcp", "123.123.123.123", "8009", "192.168.1.20", NULL, NULL, NULL); pass &= ctrl_match("IPv4", 2, 1, &reference, &candidate, true); set_ctrl_args(&candidate, "tcp", "123.123.123.123", "8009", NULL, "eth0", NULL, NULL); pass &= ctrl_match("IPv4", 2, 2, &reference, &candidate, true); set_ctrl_args(&candidate, "tcp", "123.123.123.123", "8009", "192.168.1.20", "eth0", NULL, NULL); pass &= ctrl_match("IPv4", 2, 3, &reference, &candidate, true); set_ctrl_args(&candidate, "tcp", "123.123.123.123", "8009", "192.168.1.21", NULL, NULL, NULL); pass &= ctrl_match("IPv4", 2, 4, &reference, &candidate, false); set_ctrl_args(&candidate, "tcp", "123.123.123.123", "8009", "192.168.1.21", "eth0", NULL, NULL); pass &= ctrl_match("IPv4", 2, 5, &reference, &candidate, false); set_ctrl_args(&candidate, "tcp", "123.123.123.123", "8009", NULL, "lo", NULL, NULL); pass &= ctrl_match("IPv4", 2, 6, &reference, &candidate, false); set_ctrl_args(&candidate, "tcp", "123.123.123.123", "8009", "192.168.1.20", "lo", NULL, NULL); pass &= ctrl_match("IPv4", 2, 7, &reference, &candidate, false); set_ctrl_args(&candidate, "tcp", "123.123.123.123", "8009", "192.168.1.21", "lo", NULL, NULL); pass &= ctrl_match("IPv4", 2, 8, &reference, &candidate, false); /*******************************************************************/ /* IPv4: Reference ID 3 */ set_ctrl_args(&reference, "tcp", "123.123.123.123", "8009", NULL, "eth0", NULL, NULL); set_ctrl_args(&candidate, "tcp", "123.123.123.123", "8009", NULL, NULL, NULL, NULL); pass &= ctrl_match("IPv4", 3, 0, &reference, &candidate, true); set_ctrl_args(&candidate, "tcp", "123.123.123.123", "8009", "192.168.1.20", NULL, NULL, NULL); pass &= ctrl_match("IPv4", 3, 1, &reference, &candidate, true); set_ctrl_args(&candidate, "tcp", "123.123.123.123", "8009", NULL, "eth0", NULL, NULL); pass &= ctrl_match("IPv4", 3, 2, &reference, &candidate, true); set_ctrl_args(&candidate, "tcp", "123.123.123.123", "8009", "192.168.1.20", "eth0", NULL, NULL); pass &= ctrl_match("IPv4", 3, 3, &reference, &candidate, true); set_ctrl_args(&candidate, "tcp", "123.123.123.123", "8009", "192.168.1.21", NULL, NULL, NULL); pass &= ctrl_match("IPv4", 3, 4, &reference, &candidate, false); set_ctrl_args(&candidate, "tcp", "123.123.123.123", "8009", "192.168.1.21", "eth0", NULL, NULL); pass &= ctrl_match("IPv4", 3, 5, &reference, &candidate, false); set_ctrl_args(&candidate, "tcp", "123.123.123.123", "8009", NULL, "lo", NULL, NULL); pass &= ctrl_match("IPv4", 3, 6, &reference, &candidate, false); set_ctrl_args(&candidate, "tcp", "123.123.123.123", "8009", "192.168.1.20", "lo", NULL, NULL); pass &= ctrl_match("IPv4", 3, 7, &reference, &candidate, false); set_ctrl_args(&candidate, "tcp", "123.123.123.123", "8009", "192.168.1.21", "lo", NULL, NULL); pass &= ctrl_match("IPv4", 3, 8, &reference, &candidate, false); /*******************************************************************/ /* IPv4: Reference ID 4 */ set_ctrl_args(&reference, "tcp", "123.123.123.123", "8009", "192.168.1.20", "eth0", NULL, NULL); set_ctrl_args(&candidate, "tcp", "123.123.123.123", "8009", NULL, NULL, NULL, NULL); pass &= ctrl_match("IPv4", 4, 0, &reference, &candidate, true); set_ctrl_args(&candidate, "tcp", "123.123.123.123", "8009", "192.168.1.20", NULL, NULL, NULL); pass &= ctrl_match("IPv4", 4, 1, &reference, &candidate, true); set_ctrl_args(&candidate, "tcp", "123.123.123.123", "8009", NULL, "eth0", NULL, NULL); pass &= ctrl_match("IPv4", 4, 2, &reference, &candidate, true); set_ctrl_args(&candidate, "tcp", "123.123.123.123", "8009", "192.168.1.20", "eth0", NULL, NULL); pass &= ctrl_match("IPv4", 4, 3, &reference, &candidate, true); set_ctrl_args(&candidate, "tcp", "123.123.123.123", "8009", "192.168.1.21", NULL, NULL, NULL); pass &= ctrl_match("IPv4", 4, 4, &reference, &candidate, false); set_ctrl_args(&candidate, "tcp", "123.123.123.123", "8009", "192.168.1.21", "eth0", NULL, NULL); pass &= ctrl_match("IPv4", 4, 5, &reference, &candidate, false); set_ctrl_args(&candidate, "tcp", "123.123.123.123", "8009", NULL, "lo", NULL, NULL); pass &= ctrl_match("IPv4", 4, 6, &reference, &candidate, false); set_ctrl_args(&candidate, "tcp", "123.123.123.123", "8009", "192.168.1.20", "lo", NULL, NULL); pass &= ctrl_match("IPv4", 4, 7, &reference, &candidate, false); set_ctrl_args(&candidate, "tcp", "123.123.123.123", "8009", "192.168.1.21", "lo", NULL, NULL); pass &= ctrl_match("IPv4", 4, 8, &reference, &candidate, false); /*******************************************************************/ /* IPv4: Reference ID 5 */ set_ctrl_args(&reference, "tcp", "123.123.123.123", "8009", "192.168.1.21", NULL, NULL, NULL); set_ctrl_args(&candidate, "tcp", "123.123.123.123", "8009", NULL, NULL, NULL, NULL); pass &= ctrl_match("IPv4", 5, 0, &reference, &candidate, true); set_ctrl_args(&candidate, "tcp", "123.123.123.123", "8009", "192.168.1.20", NULL, NULL, NULL); pass &= ctrl_match("IPv4", 5, 1, &reference, &candidate, false); set_ctrl_args(&candidate, "tcp", "123.123.123.123", "8009", NULL, "eth0", NULL, NULL); pass &= ctrl_match("IPv4", 5, 2, &reference, &candidate, false); set_ctrl_args(&candidate, "tcp", "123.123.123.123", "8009", "192.168.1.20", "eth0", NULL, NULL); pass &= ctrl_match("IPv4", 5, 3, &reference, &candidate, false); set_ctrl_args(&candidate, "tcp", "123.123.123.123", "8009", "192.168.1.21", NULL, NULL, NULL); pass &= ctrl_match("IPv4", 5, 4, &reference, &candidate, true); set_ctrl_args(&candidate, "tcp", "123.123.123.123", "8009", "192.168.1.21", "eth0", NULL, NULL); pass &= ctrl_match("IPv4", 5, 5, &reference, &candidate, false); set_ctrl_args(&candidate, "tcp", "123.123.123.123", "8009", NULL, "lo", NULL, NULL); pass &= ctrl_match("IPv4", 5, 6, &reference, &candidate, false); set_ctrl_args(&candidate, "tcp", "123.123.123.123", "8009", "192.168.1.20", "lo", NULL, NULL); pass &= ctrl_match("IPv4", 5, 7, &reference, &candidate, false); set_ctrl_args(&candidate, "tcp", "123.123.123.123", "8009", "192.168.1.21", "lo", NULL, NULL); pass &= ctrl_match("IPv4", 5, 8, &reference, &candidate, false); /*******************************************************************/ /* IPv4: Reference ID 6 */ set_ctrl_args(&reference, "tcp", "123.123.123.123", "8009", NULL, NULL, "traddr=123.123.123.123,trsvcid=8009,src_addr=192.168.1.20", NULL); set_ctrl_args(&candidate, "tcp", "123.123.123.123", "8009", NULL, NULL, NULL, NULL); pass &= ctrl_match("IPv4", 6, 0, &reference, &candidate, true); set_ctrl_args(&candidate, "tcp", "123.123.123.123", "8009", "192.168.1.20", NULL, NULL, NULL); pass &= ctrl_match("IPv4", 6, 1, &reference, &candidate, true); set_ctrl_args(&candidate, "tcp", "123.123.123.123", "8009", NULL, "eth0", NULL, NULL); pass &= ctrl_match("IPv4", 6, 2, &reference, &candidate, true); set_ctrl_args(&candidate, "tcp", "123.123.123.123", "8009", "192.168.1.20", "eth0", NULL, NULL); pass &= ctrl_match("IPv4", 6, 3, &reference, &candidate, true); set_ctrl_args(&candidate, "tcp", "123.123.123.123", "8009", "192.168.1.21", NULL, NULL, NULL); pass &= ctrl_match("IPv4", 6, 4, &reference, &candidate, false); set_ctrl_args(&candidate, "tcp", "123.123.123.123", "8009", "192.168.1.21", "eth0", NULL, NULL); pass &= ctrl_match("IPv4", 6, 5, &reference, &candidate, false); set_ctrl_args(&candidate, "tcp", "123.123.123.123", "8009", NULL, "lo", NULL, NULL); pass &= ctrl_match("IPv4", 6, 6, &reference, &candidate, false); set_ctrl_args(&candidate, "tcp", "123.123.123.123", "8009", "192.168.1.20", "lo", NULL, NULL); pass &= ctrl_match("IPv4", 6, 7, &reference, &candidate, false); set_ctrl_args(&candidate, "tcp", "123.123.123.123", "8009", "192.168.1.21", "lo", NULL, NULL); pass &= ctrl_match("IPv4", 6, 8, &reference, &candidate, false); /*******************************************************************/ /* IPv4: Reference ID 7 */ set_ctrl_args(&reference, "tcp", "123.123.123.123", "8009", NULL, NULL, "traddr=123.123.123.123,trsvcid=8009,src_addr=127.0.0.1", NULL); set_ctrl_args(&candidate, "tcp", "123.123.123.123", "8009", NULL, NULL, NULL, NULL); pass &= ctrl_match("IPv4", 7, 0, &reference, &candidate, true); set_ctrl_args(&candidate, "tcp", "123.123.123.123", "8009", "192.168.1.20", NULL, NULL, NULL); pass &= ctrl_match("IPv4", 7, 1, &reference, &candidate, false); set_ctrl_args(&candidate, "tcp", "123.123.123.123", "8009", NULL, "eth0", NULL, NULL); pass &= ctrl_match("IPv4", 7, 2, &reference, &candidate, false); set_ctrl_args(&candidate, "tcp", "123.123.123.123", "8009", "192.168.1.20", "eth0", NULL, NULL); pass &= ctrl_match("IPv4", 7, 3, &reference, &candidate, false); set_ctrl_args(&candidate, "tcp", "123.123.123.123", "8009", "192.168.1.21", NULL, NULL, NULL); pass &= ctrl_match("IPv4", 7, 4, &reference, &candidate, false); set_ctrl_args(&candidate, "tcp", "123.123.123.123", "8009", "192.168.1.21", "eth0", NULL, NULL); pass &= ctrl_match("IPv4", 7, 5, &reference, &candidate, false); set_ctrl_args(&candidate, "tcp", "123.123.123.123", "8009", NULL, "lo", NULL, NULL); pass &= ctrl_match("IPv4", 7, 6, &reference, &candidate, true); set_ctrl_args(&candidate, "tcp", "123.123.123.123", "8009", "192.168.1.20", "lo", NULL, NULL); pass &= ctrl_match("IPv4", 7, 7, &reference, &candidate, false); set_ctrl_args(&candidate, "tcp", "123.123.123.123", "8009", "192.168.1.21", "lo", NULL, NULL); pass &= ctrl_match("IPv4", 7, 8, &reference, &candidate, false); /*******************************************************************/ /* IPv6: Reference ID 1 */ set_ctrl_args(&reference, "tcp", "aaaa::bbbb", "8009", NULL, NULL, NULL, NULL); set_ctrl_args(&candidate, "tcp", "aaaa::bbbb", "8009", NULL, NULL, NULL, NULL); pass &= ctrl_match("IPv6", 1, 0, &reference, &candidate, true); set_ctrl_args(&candidate, "tcp", "aaaa::bbbb", "8009", "fe80::dead:beef", NULL, NULL, NULL); pass &= ctrl_match("IPv6", 1, 1, &reference, &candidate, true); set_ctrl_args(&candidate, "tcp", "aaaa::bbbb", "8009", NULL, "eth0", NULL, NULL); pass &= ctrl_match("IPv6", 1, 2, &reference, &candidate, true); set_ctrl_args(&candidate, "tcp", "aaaa::bbbb", "8009", "fe80::dead:beef", "eth0", NULL, NULL); pass &= ctrl_match("IPv6", 1, 3, &reference, &candidate, true); set_ctrl_args(&candidate, "tcp", "aaaa::bbbb", "8009", "fe80::dead:cafe", NULL, NULL, NULL); pass &= ctrl_match("IPv6", 1, 4, &reference, &candidate, true); set_ctrl_args(&candidate, "tcp", "aaaa::bbbb", "8009", "fe80::dead:cafe", "eth0", NULL, NULL); pass &= ctrl_match("IPv6", 1, 5, &reference, &candidate, true); set_ctrl_args(&candidate, "tcp", "aaaa::bbbb", "8009", NULL, "lo", NULL, NULL); pass &= ctrl_match("IPv6", 1, 6, &reference, &candidate, true); set_ctrl_args(&candidate, "tcp", "aaaa::bbbb", "8009", "fe80::dead:beef", "lo", NULL, NULL); pass &= ctrl_match("IPv6", 1, 7, &reference, &candidate, true); set_ctrl_args(&candidate, "tcp", "aaaa::bbbb", "8009", "fe80::dead:cafe", "lo", NULL, NULL); pass &= ctrl_match("IPv6", 1, 8, &reference, &candidate, true); /*******************************************************************/ /* IPv6: Reference ID 2 */ set_ctrl_args(&reference, "tcp", "aaaa::bbbb", "8009", "fe80::dead:beef", NULL, NULL, NULL); set_ctrl_args(&candidate, "tcp", "aaaa::bbbb", "8009", NULL, NULL, NULL, NULL); pass &= ctrl_match("IPv6", 2, 0, &reference, &candidate, true); set_ctrl_args(&candidate, "tcp", "aaaa::bbbb", "8009", "fe80::dead:beef", NULL, NULL, NULL); pass &= ctrl_match("IPv6", 2, 1, &reference, &candidate, true); set_ctrl_args(&candidate, "tcp", "aaaa::bbbb", "8009", NULL, "eth0", NULL, NULL); pass &= ctrl_match("IPv6", 2, 2, &reference, &candidate, true); set_ctrl_args(&candidate, "tcp", "aaaa::bbbb", "8009", "fe80::dead:beef", "eth0", NULL, NULL); pass &= ctrl_match("IPv6", 2, 3, &reference, &candidate, true); set_ctrl_args(&candidate, "tcp", "aaaa::bbbb", "8009", "fe80::dead:cafe", NULL, NULL, NULL); pass &= ctrl_match("IPv6", 2, 4, &reference, &candidate, false); set_ctrl_args(&candidate, "tcp", "aaaa::bbbb", "8009", "fe80::dead:cafe", "eth0", NULL, NULL); pass &= ctrl_match("IPv6", 2, 5, &reference, &candidate, false); set_ctrl_args(&candidate, "tcp", "aaaa::bbbb", "8009", NULL, "lo", NULL, NULL); pass &= ctrl_match("IPv6", 2, 6, &reference, &candidate, false); set_ctrl_args(&candidate, "tcp", "aaaa::bbbb", "8009", "fe80::dead:beef", "lo", NULL, NULL); pass &= ctrl_match("IPv6", 2, 7, &reference, &candidate, false); set_ctrl_args(&candidate, "tcp", "aaaa::bbbb", "8009", "fe80::dead:cafe", "lo", NULL, NULL); pass &= ctrl_match("IPv6", 2, 8, &reference, &candidate, false); /*******************************************************************/ /* IPv6: Reference ID 3 */ set_ctrl_args(&reference, "tcp", "aaaa::bbbb", "8009", NULL, "eth0", NULL, NULL); set_ctrl_args(&candidate, "tcp", "aaaa::bbbb", "8009", NULL, NULL, NULL, NULL); pass &= ctrl_match("IPv6", 3, 0, &reference, &candidate, true); set_ctrl_args(&candidate, "tcp", "aaaa::bbbb", "8009", "fe80::dead:beef", NULL, NULL, NULL); pass &= ctrl_match("IPv6", 3, 1, &reference, &candidate, true); set_ctrl_args(&candidate, "tcp", "aaaa::bbbb", "8009", NULL, "eth0", NULL, NULL); pass &= ctrl_match("IPv6", 3, 2, &reference, &candidate, true); set_ctrl_args(&candidate, "tcp", "aaaa::bbbb", "8009", "fe80::dead:beef", "eth0", NULL, NULL); pass &= ctrl_match("IPv6", 3, 3, &reference, &candidate, true); set_ctrl_args(&candidate, "tcp", "aaaa::bbbb", "8009", "fe80::dead:cafe", NULL, NULL, NULL); pass &= ctrl_match("IPv6", 3, 4, &reference, &candidate, false); set_ctrl_args(&candidate, "tcp", "aaaa::bbbb", "8009", "fe80::dead:cafe", "eth0", NULL, NULL); pass &= ctrl_match("IPv6", 3, 5, &reference, &candidate, false); set_ctrl_args(&candidate, "tcp", "aaaa::bbbb", "8009", NULL, "lo", NULL, NULL); pass &= ctrl_match("IPv6", 3, 6, &reference, &candidate, false); set_ctrl_args(&candidate, "tcp", "aaaa::bbbb", "8009", "fe80::dead:beef", "lo", NULL, NULL); pass &= ctrl_match("IPv6", 3, 7, &reference, &candidate, false); set_ctrl_args(&candidate, "tcp", "aaaa::bbbb", "8009", "fe80::dead:cafe", "lo", NULL, NULL); pass &= ctrl_match("IPv6", 3, 8, &reference, &candidate, false); /*******************************************************************/ /* IPv6: Reference ID 4 */ set_ctrl_args(&reference, "tcp", "aaaa::bbbb", "8009", "fe80::dead:beef", "eth0", NULL, NULL); set_ctrl_args(&candidate, "tcp", "aaaa::bbbb", "8009", NULL, NULL, NULL, NULL); pass &= ctrl_match("IPv6", 4, 0, &reference, &candidate, true); set_ctrl_args(&candidate, "tcp", "aaaa::bbbb", "8009", "fe80::dead:beef", NULL, NULL, NULL); pass &= ctrl_match("IPv6", 4, 1, &reference, &candidate, true); set_ctrl_args(&candidate, "tcp", "aaaa::bbbb", "8009", NULL, "eth0", NULL, NULL); pass &= ctrl_match("IPv6", 4, 2, &reference, &candidate, true); set_ctrl_args(&candidate, "tcp", "aaaa::bbbb", "8009", "fe80::dead:beef", "eth0", NULL, NULL); pass &= ctrl_match("IPv6", 4, 3, &reference, &candidate, true); set_ctrl_args(&candidate, "tcp", "aaaa::bbbb", "8009", "fe80::dead:cafe", NULL, NULL, NULL); pass &= ctrl_match("IPv6", 4, 4, &reference, &candidate, false); set_ctrl_args(&candidate, "tcp", "aaaa::bbbb", "8009", "fe80::dead:cafe", "eth0", NULL, NULL); pass &= ctrl_match("IPv6", 4, 5, &reference, &candidate, false); set_ctrl_args(&candidate, "tcp", "aaaa::bbbb", "8009", NULL, "lo", NULL, NULL); pass &= ctrl_match("IPv6", 4, 6, &reference, &candidate, false); set_ctrl_args(&candidate, "tcp", "aaaa::bbbb", "8009", "fe80::dead:beef", "lo", NULL, NULL); pass &= ctrl_match("IPv6", 4, 7, &reference, &candidate, false); set_ctrl_args(&candidate, "tcp", "aaaa::bbbb", "8009", "fe80::dead:cafe", "lo", NULL, NULL); pass &= ctrl_match("IPv6", 4, 8, &reference, &candidate, false); /*******************************************************************/ /* IPv6: Reference ID 5 */ set_ctrl_args(&reference, "tcp", "aaaa::bbbb", "8009", "fe80::dead:cafe", NULL, NULL, NULL); set_ctrl_args(&candidate, "tcp", "aaaa::bbbb", "8009", NULL, NULL, NULL, NULL); pass &= ctrl_match("IPv6", 5, 0, &reference, &candidate, true); set_ctrl_args(&candidate, "tcp", "aaaa::bbbb", "8009", "fe80::dead:beef", NULL, NULL, NULL); pass &= ctrl_match("IPv6", 5, 1, &reference, &candidate, false); set_ctrl_args(&candidate, "tcp", "aaaa::bbbb", "8009", NULL, "eth0", NULL, NULL); pass &= ctrl_match("IPv6", 5, 2, &reference, &candidate, false); set_ctrl_args(&candidate, "tcp", "aaaa::bbbb", "8009", "fe80::dead:beef", "eth0", NULL, NULL); pass &= ctrl_match("IPv6", 5, 3, &reference, &candidate, false); set_ctrl_args(&candidate, "tcp", "aaaa::bbbb", "8009", "fe80::dead:cafe", NULL, NULL, NULL); pass &= ctrl_match("IPv6", 5, 4, &reference, &candidate, true); set_ctrl_args(&candidate, "tcp", "aaaa::bbbb", "8009", "fe80::dead:cafe", "eth0", NULL, NULL); pass &= ctrl_match("IPv6", 5, 5, &reference, &candidate, false); set_ctrl_args(&candidate, "tcp", "aaaa::bbbb", "8009", NULL, "lo", NULL, NULL); pass &= ctrl_match("IPv6", 5, 6, &reference, &candidate, false); set_ctrl_args(&candidate, "tcp", "aaaa::bbbb", "8009", "fe80::dead:beef", "lo", NULL, NULL); pass &= ctrl_match("IPv6", 5, 7, &reference, &candidate, false); set_ctrl_args(&candidate, "tcp", "aaaa::bbbb", "8009", "fe80::dead:cafe", "lo", NULL, NULL); pass &= ctrl_match("IPv6", 5, 8, &reference, &candidate, false); /*******************************************************************/ /* IPv6: Reference ID 6 */ set_ctrl_args(&reference, "tcp", "aaaa::bbbb", "8009", NULL, NULL, "traddr=aaaa::bbbb,trsvcid=8009,src_addr=fe80::dead:beef", NULL); set_ctrl_args(&candidate, "tcp", "aaaa::bbbb", "8009", NULL, NULL, NULL, NULL); pass &= ctrl_match("IPv6", 6, 0, &reference, &candidate, true); set_ctrl_args(&candidate, "tcp", "aaaa::bbbb", "8009", "fe80::dead:beef", NULL, NULL, NULL); pass &= ctrl_match("IPv6", 6, 1, &reference, &candidate, true); set_ctrl_args(&candidate, "tcp", "aaaa::bbbb", "8009", NULL, "eth0", NULL, NULL); pass &= ctrl_match("IPv6", 6, 2, &reference, &candidate, true); set_ctrl_args(&candidate, "tcp", "aaaa::bbbb", "8009", "fe80::dead:beef", "eth0", NULL, NULL); pass &= ctrl_match("IPv6", 6, 3, &reference, &candidate, true); set_ctrl_args(&candidate, "tcp", "aaaa::bbbb", "8009", "fe80::dead:cafe", NULL, NULL, NULL); pass &= ctrl_match("IPv6", 6, 4, &reference, &candidate, false); set_ctrl_args(&candidate, "tcp", "aaaa::bbbb", "8009", "fe80::dead:cafe", "eth0", NULL, NULL); pass &= ctrl_match("IPv6", 6, 5, &reference, &candidate, false); set_ctrl_args(&candidate, "tcp", "aaaa::bbbb", "8009", NULL, "lo", NULL, NULL); pass &= ctrl_match("IPv6", 6, 6, &reference, &candidate, false); set_ctrl_args(&candidate, "tcp", "aaaa::bbbb", "8009", "fe80::dead:beef", "lo", NULL, NULL); pass &= ctrl_match("IPv6", 6, 7, &reference, &candidate, false); set_ctrl_args(&candidate, "tcp", "aaaa::bbbb", "8009", "fe80::dead:cafe", "lo", NULL, NULL); pass &= ctrl_match("IPv6", 6, 8, &reference, &candidate, false); /*******************************************************************/ /* IPv6: Reference ID 7 */ set_ctrl_args(&reference, "tcp", "aaaa::bbbb", "8009", NULL, NULL, "traddr=aaaa::bbbb,trsvcid=8009,src_addr=::1", NULL); set_ctrl_args(&candidate, "tcp", "aaaa::bbbb", "8009", NULL, NULL, NULL, NULL); pass &= ctrl_match("IPv6", 7, 0, &reference, &candidate, true); set_ctrl_args(&candidate, "tcp", "aaaa::bbbb", "8009", "fe80::dead:beef", NULL, NULL, NULL); pass &= ctrl_match("IPv6", 7, 1, &reference, &candidate, false); set_ctrl_args(&candidate, "tcp", "aaaa::bbbb", "8009", NULL, "eth0", NULL, NULL); pass &= ctrl_match("IPv6", 7, 2, &reference, &candidate, false); set_ctrl_args(&candidate, "tcp", "aaaa::bbbb", "8009", "fe80::dead:beef", "eth0", NULL, NULL); pass &= ctrl_match("IPv6", 7, 3, &reference, &candidate, false); set_ctrl_args(&candidate, "tcp", "aaaa::bbbb", "8009", "fe80::dead:cafe", NULL, NULL, NULL); pass &= ctrl_match("IPv6", 7, 4, &reference, &candidate, false); set_ctrl_args(&candidate, "tcp", "aaaa::bbbb", "8009", "fe80::dead:cafe", "eth0", NULL, NULL); pass &= ctrl_match("IPv6", 7, 5, &reference, &candidate, false); set_ctrl_args(&candidate, "tcp", "aaaa::bbbb", "8009", NULL, "lo", NULL, NULL); pass &= ctrl_match("IPv6", 7, 6, &reference, &candidate, true); set_ctrl_args(&candidate, "tcp", "aaaa::bbbb", "8009", "fe80::dead:beef", "lo", NULL, NULL); pass &= ctrl_match("IPv6", 7, 7, &reference, &candidate, false); set_ctrl_args(&candidate, "tcp", "aaaa::bbbb", "8009", "fe80::dead:cafe", "lo", NULL, NULL); pass &= ctrl_match("IPv6", 7, 8, &reference, &candidate, false); return pass; } static bool ctrl_config_match(const char *tag, int reference_id, int candidate_id, struct ctrl_args *reference, struct ctrl_args *candidate, bool should_match) { bool match; nvme_root_t r; nvme_host_t h; nvme_ctrl_t reference_ctrl; /* Existing controller (from sysfs) */ nvme_subsystem_t s; r = nvme_create_root(stdout, LOG_INFO); assert(r); h = nvme_default_host(r); assert(h); s = nvme_lookup_subsystem(h, DEFAULT_SUBSYSNAME, reference->subsysnqn ? reference->subsysnqn : DEFAULT_SUBSYSNQN); assert(s); reference_ctrl = nvme_lookup_ctrl(s, reference->transport, reference->traddr, reference->host_traddr, reference->host_iface, reference->trsvcid, NULL); assert(reference_ctrl); reference_ctrl->name = "nvme1"; /* fake the device name */ if (reference->address) { reference_ctrl->address = (char *)reference->address; } match = nvme_ctrl_config_match(reference_ctrl, candidate->transport, candidate->traddr, candidate->trsvcid, candidate->subsysnqn, candidate->host_traddr, candidate->host_iface); if (should_match) { if (!match) { printf("%s-%d-%d: Failed to match config for Candidate (%s, %s, %s, %s, %s, %s)\n", tag, reference_id, candidate_id, candidate->transport, candidate->traddr, candidate->trsvcid, candidate->subsysnqn, candidate->host_traddr, candidate->host_iface); return false; } } else { if (match) { printf("%s-%d-%d: Config should not have matched for Candidate (%s, %s, %s, %s, %s, %s)\n", tag, reference_id, candidate_id, candidate->transport, candidate->traddr, candidate->trsvcid, candidate->subsysnqn, candidate->host_traddr, candidate->host_iface); return false; } } /* Set the faked data back to NULL before freeing the tree */ reference_ctrl->name = NULL; reference_ctrl->address = NULL; nvme_free_tree(r); return true; } static bool test_ctrl_config_match() { bool pass = true; struct ctrl_args reference = {0}; struct ctrl_args candidate = {0}; printf("\n" "test_ctrl_config_match:\n"); set_ctrl_args(&reference, "tcp", "123.123.123.123", "8009", NULL, NULL, NULL, NULL); set_ctrl_args(&candidate, "tcp", "123.123.123.123", "8009", NULL, NULL, NULL, NULL); pass &= ctrl_config_match("IPv4", 1, 0, &reference, &candidate, true); set_ctrl_args(&candidate, "tcp", "123.123.123.123", "8009", "192.168.1.20", NULL, NULL, NULL); pass &= ctrl_config_match("IPv4", 1, 1, &reference, &candidate, true); set_ctrl_args(&candidate, "tcp", "123.123.123.123", "8009", NULL, "eth0", NULL, NULL); pass &= ctrl_config_match("IPv4", 1, 2, &reference, &candidate, true); set_ctrl_args(&candidate, "tcp", "123.123.123.123", "8009", "192.168.1.20", "eth0", NULL, NULL); pass &= ctrl_config_match("IPv4", 1, 3, &reference, &candidate, true); set_ctrl_args(&candidate, "tcp", "123.123.123.123", "8009", "192.168.1.21", NULL, NULL, NULL); pass &= ctrl_config_match("IPv4", 1, 4, &reference, &candidate, true); set_ctrl_args(&candidate, "tcp", "123.123.123.123", "8009", "192.168.1.21", "eth0", NULL, NULL); pass &= ctrl_config_match("IPv4", 1, 5, &reference, &candidate, true); set_ctrl_args(&candidate, "tcp", "123.123.123.123", "8009", NULL, "lo", NULL, NULL); pass &= ctrl_config_match("IPv4", 1, 6, &reference, &candidate, true); set_ctrl_args(&candidate, "tcp", "123.123.123.123", "8009", "192.168.1.20", "lo", NULL, NULL); pass &= ctrl_config_match("IPv4", 1, 7, &reference, &candidate, true); set_ctrl_args(&candidate, "tcp", "123.123.123.123", "8009", "192.168.1.21", "lo", NULL, NULL); pass &= ctrl_config_match("IPv4", 1, 8, &reference, &candidate, true); set_ctrl_args(&candidate, "tcp", "123.123.123.123", "8009", "192.168.1.21", "lo", NULL, "hello"); pass &= ctrl_config_match("IPv4", 1, 9, &reference, &candidate, false); set_ctrl_args(&candidate, "tcp", "123.123.123.123", "8009", "192.168.1.21", "lo", NULL, DEFAULT_SUBSYSNQN); pass &= ctrl_config_match("IPv4", 1, 9, &reference, &candidate, true); return pass; } /** * This test module uses a mocked ifaddrs library (mock-ifaddrs.c) * such that there are 2 fake interfaces (eth0 and lo) with the * following IP addresses: * * - eth0 * \_ IPv4: 192.168.1.20 * \_ IPv6: fe80::dead:beef * * - lo * \_ IPv4: 127.0.0.1 * \_ IPv6: ::1 */ int main(int argc, char *argv[]) { bool pass = true; pass &= test_lookup(); pass &= test_src_addr(); pass &= test_ctrl_match_fc(); pass &= test_ctrl_match_rdma(); pass &= test_ctrl_match_tcp(); pass &= test_ctrl_config_match(); fflush(stdout); exit(pass ? EXIT_SUCCESS : EXIT_FAILURE); }