From 0e79512939c3cc5e4b01bd7ec883b90db167c5fc Mon Sep 17 00:00:00 2001 From: Martin Belanger Date: Tue, 12 Sep 2023 15:55:55 -0400 Subject: [PATCH] tree: Add 2 new public functions to lookup existing controllers There is duplicate code between libnvme and nvme-cli. When trying to instantiate a controller, both libnvme and nvme-cli scan the sysfs looking for an existing controller that can be reused. This patch adds nvme_ctrl_find() and nvme_ctrl_config_match(). These functions can be used by nvme-cli to lookup existing controllers. This will allow removing the duplicate code in nvme-cli (separate commit to follow on the nvme-cli GitHub repo). Signed-off-by: Martin Belanger --- src/libnvme.map | 2 + src/nvme/fabrics.c | 2 + src/nvme/private.h | 2 +- src/nvme/tree.c | 262 +++++++++++++++------- src/nvme/tree.h | 45 ++++ test/tree.c | 532 ++++++++++++++++++++++++++++----------------- 6 files changed, 571 insertions(+), 274 deletions(-) diff --git a/src/libnvme.map b/src/libnvme.map index a6870458..af3cea18 100644 --- a/src/libnvme.map +++ b/src/libnvme.map @@ -1,6 +1,8 @@ # SPDX-License-Identifier: LGPL-2.1-or-later LIBNVME_1_6 { global: + nvme_ctrl_config_match; + nvme_ctrl_find; nvme_ctrl_get_src_addr; nvme_ctrl_release_fd; nvme_host_release_fds; diff --git a/src/nvme/fabrics.c b/src/nvme/fabrics.c index 224a5c89..21fb2920 100644 --- a/src/nvme/fabrics.c +++ b/src/nvme/fabrics.c @@ -834,6 +834,7 @@ static const char *lookup_context(nvme_root_t r, nvme_ctrl_t c) NULL, NULL, nvme_ctrl_get_trsvcid(c), + NULL, NULL)) return nvme_subsystem_get_application(s); } @@ -863,6 +864,7 @@ int nvmf_add_ctrl(nvme_host_t h, nvme_ctrl_t c, nvme_ctrl_get_host_traddr(c), nvme_ctrl_get_host_iface(c), nvme_ctrl_get_trsvcid(c), + NULL, NULL); if (fc) { const char *key; diff --git a/src/nvme/private.h b/src/nvme/private.h index edb6c4e2..ba05befb 100644 --- a/src/nvme/private.h +++ b/src/nvme/private.h @@ -180,7 +180,7 @@ int json_dump_tree(nvme_root_t r); nvme_ctrl_t __nvme_lookup_ctrl(nvme_subsystem_t s, const char *transport, const char *traddr, const char *host_traddr, const char *host_iface, const char *trsvcid, - nvme_ctrl_t p); + nvme_ctrl_t p, const char *subsysnqn); #if (LOG_FUNCNAME == 1) #define __nvme_log_func __func__ diff --git a/src/nvme/tree.c b/src/nvme/tree.c index 989fb056..36781191 100644 --- a/src/nvme/tree.c +++ b/src/nvme/tree.c @@ -44,6 +44,8 @@ * @host_traddr: Host transport address (source address) * @host_iface: Host interface for connection (tcp only) * @iface_list: Interface list (tcp only) + * @addreq: Address comparison function (for traddr, host-traddr) + * @well_known_nqn: Set to "true" when @subsysnqn is the well-known NQN */ struct candidate_args { const char *transport; @@ -53,7 +55,10 @@ struct candidate_args { const char *host_traddr; const char *host_iface; struct ifaddrs *iface_list; + bool (*addreq)(const char *, const char *); + bool well_known_nqn; }; +typedef bool (*ctrl_match_t)(struct nvme_ctrl *c, struct candidate_args *candidate); const char *nvme_slots_sysfs_dir = "/sys/bus/pci/slots"; @@ -1257,7 +1262,7 @@ struct nvme_ctrl *nvme_create_ctrl(nvme_root_t r, static bool _tcp_ctrl_match_host_traddr_no_src_addr(struct nvme_ctrl *c, struct candidate_args *candidate) { if (c->cfg.host_traddr) - return nvme_ipaddrs_eq(candidate->host_traddr, c->cfg.host_traddr); + return candidate->addreq(candidate->host_traddr, c->cfg.host_traddr); /* If c->cfg.host_traddr is NULL, then the controller (c) * uses the interface's primary address as the source @@ -1405,7 +1410,7 @@ static bool _tcp_opt_params_match(struct nvme_ctrl *c, struct candidate_args *ca /* Check host_traddr only if candidate is interested */ if (candidate->host_traddr && - !nvme_ipaddrs_eq(candidate->host_traddr, src_addr)) + !candidate->addreq(candidate->host_traddr, src_addr)) return false; /* Check host_iface only if candidate is interested */ @@ -1418,19 +1423,12 @@ static bool _tcp_opt_params_match(struct nvme_ctrl *c, struct candidate_args *ca } /** - * _tcp_lookup_ctrl() - Look for an existing controller that can be reused - * @s: Subsystem object under which to do the search - * @transport: Transport type ("tcp") - * @traddr: Destination IP address - * @host_iface: Interface for the connection (optional) - * @host_traddr: Source IP address (optional) - * @trsvcid: Destination TCP port - * @p: Starting point is the linked-list (NULL to start at the beginning) + * _tcp_match_ctrl() - Check if controller matches candidate (TCP only) + * @c: An existing controller instance + * @candidate: Candidate ctrl we're trying to match with @c. * * We want to determine if an existing controller can be re-used - * for the candidate controller we're trying to instantiate. The - * candidate is identified by @transport, @traddr, @trsvcid, - * @host_traddr, and @host_iface. + * for the candidate controller we're trying to instantiate. * * For TCP, we do not have a match if the candidate's transport, traddr, * trsvcid are not identical to those of the the existing controller. @@ -1440,92 +1438,204 @@ static bool _tcp_opt_params_match(struct nvme_ctrl *c, struct candidate_args *ca * not specify them (both NULL), we can ignore them. Otherwise, we must * employ advanced investigation techniques to determine if there's a match. * - * Return: Pointer to the matching controller or NULL. + * Return: true if a match is found, false otherwise. */ -static nvme_ctrl_t _tcp_lookup_ctrl(nvme_subsystem_t s, const char *transport, - const char *traddr, const char *host_traddr, - const char *host_iface, const char *trsvcid, - nvme_ctrl_t p) +static bool _tcp_match_ctrl(struct nvme_ctrl *c, struct candidate_args *candidate) { - struct candidate_args candidate = {0}; - struct nvme_ctrl *c, *matching_c = NULL; + if (!streq0(c->transport, candidate->transport)) + return false; - candidate.traddr = traddr; - candidate.trsvcid = trsvcid; - candidate.transport = transport; - candidate.host_iface = host_iface; - candidate.host_traddr = host_traddr; + if (!streq0(c->trsvcid, candidate->trsvcid)) + return false; - /* For TCP we may need to access the interface map. Let's retrieve - * and cache the map and use it for the duration of the loop below. - */ - if (getifaddrs(&candidate.iface_list) == -1) - candidate.iface_list = NULL; + if (!candidate->addreq(c->traddr, candidate->traddr)) + return false; - c = p ? nvme_subsystem_next_ctrl(s, p) : nvme_subsystem_first_ctrl(s); - for (; c != NULL; c = nvme_subsystem_next_ctrl(s, c)) { - if (!streq0(c->transport, candidate.transport)) - continue; + if (candidate->well_known_nqn && !nvme_ctrl_is_discovery_ctrl(c)) + return false; - if (!streq0(c->trsvcid, candidate.trsvcid)) - continue; + if (candidate->subsysnqn && !streq0(c->subsysnqn, candidate->subsysnqn)) + return false; - if (!nvme_ipaddrs_eq(c->traddr, candidate.traddr)) - continue; + /* Check host_traddr / host_iface only if candidate is interested */ + if ((candidate->host_iface || candidate->host_traddr) && + !_tcp_opt_params_match(c, candidate)) + return false; - /* Check host_traddr / host_iface only if candidate is interested */ - if ((candidate.host_iface || candidate.host_traddr) && - !_tcp_opt_params_match(c, &candidate)) - continue; + return true; +} - matching_c = c; - break; +/** + * _match_ctrl() - Check if controller matches candidate (non TCP transport) + * @c: An existing controller instance + * @candidate: Candidate ctrl we're trying to match with @c. + * + * We want to determine if an existing controller can be re-used + * for the candidate controller we're trying to instantiate. This function + * is used for all transports except TCP. + * + * Return: true if a match is found, false otherwise. + */ +static bool _match_ctrl(struct nvme_ctrl *c, struct candidate_args *candidate) +{ + if (!streq0(c->transport, candidate->transport)) + return false; + + if (candidate->traddr && c->traddr && + !candidate->addreq(c->traddr, candidate->traddr)) + return false; + + if (candidate->host_traddr && c->cfg.host_traddr && + !candidate->addreq(c->cfg.host_traddr, candidate->host_traddr)) + return false; + + if (candidate->host_iface && c->cfg.host_iface && + !streq0(c->cfg.host_iface, candidate->host_iface)) + return false; + + if (candidate->trsvcid && c->trsvcid && + !streq0(c->trsvcid, candidate->trsvcid)) + return false; + + if (candidate->well_known_nqn && !nvme_ctrl_is_discovery_ctrl(c)) + return false; + + if (candidate->subsysnqn && !streq0(c->subsysnqn, candidate->subsysnqn)) + return false; + + return true; +} +/** + * _candidate_init() - Init candidate and get the matching function + * + * @candidate: Candidate struct to initialize + * @transport: Transport name + * @traddr: Transport address + * @trsvcid: Transport service identifier + * @subsysnqn: Subsystem NQN + * @host_traddr: Host transport address + * @host_iface: Host interface name + * @host_iface: Host interface name + * + * The function _candidate_free() must be called to release resources once + * the candidate object is not longer required. + * + * Return: The matching function to use when comparing an existing + * controller to the candidate controller. + */ +static ctrl_match_t _candidate_init(struct candidate_args *candidate, + const char *transport, + const char *traddr, + const char *trsvcid, + const char *subsysnqn, + const char *host_traddr, + const char *host_iface) +{ + memset(candidate, 0, sizeof(*candidate)); + + candidate->traddr = traddr; + candidate->trsvcid = trsvcid; + candidate->transport = transport; + candidate->subsysnqn = subsysnqn; + candidate->host_iface = host_iface; + candidate->host_traddr = host_traddr; + + if (streq0(subsysnqn, NVME_DISC_SUBSYS_NAME)) { + /* Since TP8013, the NQN of discovery controllers can be the + * well-known NQN (i.e. nqn.2014-08.org.nvmexpress.discovery) or + * a unique NQN. A DC created using the well-known NQN may later + * display a unique NQN when looked up in the sysfs. Therefore, + * ignore (i.e. set to NULL) the well-known NQN when looking for + * a match. + */ + candidate->subsysnqn = NULL; + candidate->well_known_nqn = true; } - freeifaddrs(candidate.iface_list); /* This is NULL-safe */ + if (streq0(transport, "tcp")) { + /* For TCP we may need to access the interface map. + * Let's retrieve and cache the map. + */ + if (getifaddrs(&candidate->iface_list) == -1) + candidate->iface_list = NULL; - return matching_c; + candidate->addreq = nvme_ipaddrs_eq; + return _tcp_match_ctrl; + } + + if (streq0(transport, "rdma")) { + candidate->addreq = nvme_ipaddrs_eq; + return _match_ctrl; + } + + /* All other transport types */ + candidate->addreq = streqcase0; + return _match_ctrl; +} + +/** + * _candidate_free() - Release resources allocated by _candidate_init() + * + * @candidate: data to free. + */ +static void _candidate_free(struct candidate_args *candidate) +{ + freeifaddrs(candidate->iface_list); /* This is NULL-safe */ } nvme_ctrl_t __nvme_lookup_ctrl(nvme_subsystem_t s, const char *transport, const char *traddr, const char *host_traddr, const char *host_iface, const char *trsvcid, - nvme_ctrl_t p) - + nvme_ctrl_t p, const char *subsysnqn) { - struct nvme_ctrl *c; - bool (*addreq)(const char *, const char *); - - /* TCP requires special handling */ - if (streq0(transport, "tcp")) - return _tcp_lookup_ctrl(s, transport, traddr, - host_traddr, host_iface, trsvcid, p); + struct nvme_ctrl *c, *matching_c = NULL; + struct candidate_args candidate; + ctrl_match_t ctrl_match; - if (streq0(transport, "rdma")) - addreq = nvme_ipaddrs_eq; /* IP address compare for RDMA */ - else - addreq = streqcase0; /* Case-insensitive for everything else */ + /* Init candidate and get the matching function to use */ + ctrl_match = _candidate_init(&candidate, transport, traddr, trsvcid, + subsysnqn, host_traddr, host_iface); c = p ? nvme_subsystem_next_ctrl(s, p) : nvme_subsystem_first_ctrl(s); for (; c != NULL; c = nvme_subsystem_next_ctrl(s, c)) { - if (!streq0(c->transport, transport)) - continue; - if (traddr && c->traddr && - !addreq(c->traddr, traddr)) - continue; - if (host_traddr && c->cfg.host_traddr && - !addreq(c->cfg.host_traddr, host_traddr)) - continue; - if (host_iface && c->cfg.host_iface && - !streq0(c->cfg.host_iface, host_iface)) - continue; - if (trsvcid && c->trsvcid && - !streq0(c->trsvcid, trsvcid)) - continue; - return c; + if (ctrl_match(c, &candidate)) { + matching_c = c; + break; + } } - return NULL; + _candidate_free(&candidate); + + return matching_c; +} + +bool nvme_ctrl_config_match(struct nvme_ctrl *c, const char *transport, + const char *traddr, const char *trsvcid, + const char *subsysnqn, const char *host_traddr, + const char *host_iface) +{ + bool match; + ctrl_match_t ctrl_match; + struct candidate_args candidate; + + /* Init candidate and get the matching function to use */ + ctrl_match = _candidate_init(&candidate, transport, traddr, trsvcid, + subsysnqn, host_traddr, host_iface); + + match = ctrl_match(c, &candidate); + + _candidate_free(&candidate); + + return match; +} + +nvme_ctrl_t nvme_ctrl_find(nvme_subsystem_t s, const char *transport, + const char *traddr, const char *trsvcid, + const char *subsysnqn, const char *host_traddr, + const char *host_iface) +{ + return __nvme_lookup_ctrl(s, transport, traddr, host_traddr, host_iface, + trsvcid, NULL/*p*/, subsysnqn); } nvme_ctrl_t nvme_lookup_ctrl(nvme_subsystem_t s, const char *transport, @@ -1540,7 +1650,7 @@ nvme_ctrl_t nvme_lookup_ctrl(nvme_subsystem_t s, const char *transport, return NULL; c = __nvme_lookup_ctrl(s, transport, traddr, host_traddr, - host_iface, trsvcid, p); + host_iface, trsvcid, p, NULL); if (c) return c; diff --git a/src/nvme/tree.h b/src/nvme/tree.h index 8b9a483c..24ff9d82 100644 --- a/src/nvme/tree.h +++ b/src/nvme/tree.h @@ -307,6 +307,51 @@ nvme_ctrl_t nvme_lookup_ctrl(nvme_subsystem_t s, const char *transport, const char *host_iface, const char *trsvcid, nvme_ctrl_t p); +/** + * nvme_ctrl_find() - Locate an existing controller + * @s: &nvme_subsystem_t object + * @transport: Transport name + * @traddr: Transport address + * @trsvcid: Transport service identifier + * @subsysnqn: Subsystem NQN + * @host_traddr: Host transport address + * @host_iface: Host interface name + * + * Lookup a controller in @s based on @transport, @traddr, @trsvcid, + * @subsysnqn, @host_traddr, and @host_iface. @transport must be specified, + * other fields may be required depending on the transport. Parameters set + * to NULL will be ignored. + * + * Unlike nvme_lookup_ctrl(), this function does not create a new object if + * an existing controller cannot be found. + * + * Return: Controller instance on success, NULL otherwise. + */ +nvme_ctrl_t nvme_ctrl_find(nvme_subsystem_t s, const char *transport, + const char *traddr, const char *trsvcid, + const char *subsysnqn, const char *host_traddr, + const char *host_iface); + +/** + * nvme_ctrl_config_match() - Check if ctrl @c matches config params + * @c: An existing controller instance + * @transport: Transport name + * @traddr: Transport address + * @trsvcid: Transport service identifier + * @subsysnqn: Subsystem NQN + * @host_traddr: Host transport address + * @host_iface: Host interface name + * + * Check that controller @c matches parameters: @transport, @traddr, + * @trsvcid, @subsysnqn, @host_traddr, and @host_iface. Parameters set + * to NULL will be ignored. + * + * Return: true if there's a match, false otherwise. + */ +bool nvme_ctrl_config_match(struct nvme_ctrl *c, const char *transport, + const char *traddr, const char *trsvcid, + const char *subsysnqn, const char *host_traddr, + const char *host_iface); /** * nvme_create_ctrl() - Allocate an unconnected NVMe controller diff --git a/test/tree.c b/test/tree.c index 068ae865..c9370f97 100644 --- a/test/tree.c +++ b/test/tree.c @@ -419,6 +419,7 @@ struct ctrl_args { const char *host_traddr; const char *host_iface; const char *address; + const char *subsysnqn; }; static void set_ctrl_args(struct ctrl_args *args, @@ -427,7 +428,8 @@ static void set_ctrl_args(struct ctrl_args *args, const char *trsvcid, const char *host_traddr, const char *host_iface, - const char *address) + const char *address, + const char *subsysnqn) { args->transport = transport; args->traddr = traddr; @@ -435,6 +437,7 @@ static void set_ctrl_args(struct ctrl_args *args, args->host_traddr = host_traddr; args->host_iface = host_iface; args->address = address; + args->subsysnqn = subsysnqn; } static bool ctrl_match(const char *tag, @@ -448,17 +451,16 @@ static bool ctrl_match(const char *tag, 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_DEBUG); + r = nvme_create_root(stdout, LOG_INFO); assert(r); - nvme_init_logging(r, LOG_INFO, false, false); - h = nvme_default_host(r); assert(h); - s = nvme_lookup_subsystem(h, DEFAULT_SUBSYSNAME, DEFAULT_SUBSYSNQN); + 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, @@ -470,30 +472,52 @@ static bool ctrl_match(const char *tag, 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) failed to match (%s, %s, %s, %s, %s, %s)\n", + 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->host_traddr, candidate->host_iface, - reference->transport, reference->traddr, reference->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) should not match (%s, %s, %s, %s, %s, %s)\n", + 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->host_traddr, candidate->host_iface, - reference->transport, reference->traddr, reference->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 */ @@ -520,73 +544,73 @@ static bool test_ctrl_match_fc(void) /*******************************************************************/ /* 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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; @@ -607,73 +631,73 @@ static bool test_ctrl_match_rdma(void) /*******************************************************************/ /* Reference ID 1 */ - set_ctrl_args(&reference, "rdma", "192.168.2.1", "4420", "192.168.1.20", NULL, NULL); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + set_ctrl_args(&candidate, "rdma", "192.168.2.1", "8009", NULL, "", NULL, NULL); pass &= ctrl_match("RDMA", 3, 5, &reference, &candidate, false); return pass; @@ -682,8 +706,9 @@ static bool test_ctrl_match_rdma(void) /** * test_ctrl_match_tcp - Test that we can look up TCP controllers * - * @note: The mocked getifaddrs() returns 4 interface entries as follows. - * Therefore the tests must use IP addresses that match there. + * @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 @@ -706,330 +731,442 @@ static bool test_ctrl_match_tcp() /*******************************************************************/ /* IPv4: Reference ID 1 */ - set_ctrl_args(&reference, "tcp", "123.123.123.123", "8009", NULL, NULL, NULL); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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"); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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"); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + set_ctrl_args(&reference, "tcp", "aaaa::bbbb", "8009", NULL, NULL, NULL, NULL); - set_ctrl_args(&candidate, "tcp", "aaaa::bbbb", "8009", 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + set_ctrl_args(&reference, "tcp", "aaaa::bbbb", "8009", NULL, "eth0", NULL, NULL); - set_ctrl_args(&candidate, "tcp", "aaaa::bbbb", "8009", NULL, 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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"); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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"); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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; @@ -1039,6 +1176,7 @@ int main(int argc, char *argv[]) pass &= test_ctrl_match_fc(); pass &= test_ctrl_match_rdma(); pass &= test_ctrl_match_tcp(); + pass &= test_ctrl_config_match(); fflush(stdout);