diff --git a/libknet/tests/api_knet_handle_pmtud_set.c b/libknet/tests/api_knet_handle_pmtud_set.c index ef9d3577..ccb7f3f8 100644 --- a/libknet/tests/api_knet_handle_pmtud_set.c +++ b/libknet/tests/api_knet_handle_pmtud_set.c @@ -1,120 +1,120 @@ /* * Copyright (C) 2016-2025 Red Hat, Inc. All rights reserved. * * Authors: Fabio M. Di Nitto * * This software licensed under GPL-2.0+ */ #include "config.h" #include #include #include #include #include #include "libknet.h" #include "internals.h" #include "test-common.h" static int private_data; static void sock_notify(void *pvt_data, int datafd, int8_t channel, uint8_t tx_rx, int error, int errorno) { return; } static void test(void) { knet_handle_t knet_h1, knet_h[2]; int res; int logfds[2]; unsigned int iface_mtu = 0, data_mtu; int datafd = 0; int8_t channel = 0; struct sockaddr_storage lo; printf("Test knet_handle_pmtud_set incorrect knet_h\n"); if ((!knet_handle_pmtud_set(NULL, iface_mtu)) || (errno != EINVAL)) { printf("knet_handle_pmtud_set accepted invalid knet_h or returned incorrect error: %s\n", strerror(errno)); exit(FAIL); } setup_logpipes(logfds); knet_h1 = knet_handle_start(logfds, KNET_LOG_DEBUG, knet_h); flush_logs(logfds[0], stdout); iface_mtu = KNET_PMTUD_SIZE_V4 + 1; printf("Test knet_handle_pmtud_set with wrong iface_mtu\n"); FAIL_ON_SUCCESS(knet_handle_pmtud_set(knet_h1, iface_mtu), EINVAL); FAIL_ON_ERR(knet_handle_enable_sock_notify(knet_h1, &private_data, sock_notify)); datafd = 0; channel = -1; FAIL_ON_ERR(knet_handle_add_datafd(knet_h1, &datafd, &channel, 0)); FAIL_ON_ERR(knet_host_add(knet_h1, 1)); FAIL_ON_ERR(_knet_link_set_config(knet_h1, 1, 0, KNET_TRANSPORT_UDP, 0, AF_INET, 0, &lo)); FAIL_ON_ERR(knet_link_set_pong_count(knet_h1, 1, 0, 1)); FAIL_ON_ERR(knet_link_set_enable(knet_h1, 1, 0, 1)); FAIL_ON_ERR(wait_for_host(knet_h1, 1, 4, logfds[0], stdout)); FAIL_ON_ERR(knet_handle_pmtud_get(knet_h1, &data_mtu)); /* * 28 = IP (20) + UDP (8) */ iface_mtu = data_mtu + 28 + KNET_HEADER_ALL_SIZE - 64; printf("Test knet_handle_pmtud_set with iface_mtu %u\n", iface_mtu); FAIL_ON_ERR(knet_handle_pmtud_set(knet_h1, iface_mtu)); /* * wait for PMTUd to pick up the change */ - test_sleep(knet_h1, 1); + test_sleep(knet_h1, 10); flush_logs(logfds[0], stdout); if (knet_h1->data_mtu != data_mtu - 64) { printf("knet_handle_pmtud_set failed to set the value\n"); CLEAN_EXIT(FAIL); } printf("Test knet_handle_pmtud_set with iface_mtu 0\n"); FAIL_ON_ERR(knet_handle_pmtud_set(knet_h1, 0)); /* * wait for PMTUd to pick up the change */ - test_sleep(knet_h1, 1); + test_sleep(knet_h1, 15); flush_logs(logfds[0], stdout); if (knet_h1->data_mtu != data_mtu) { printf("knet_handle_pmtud_set failed to redetect MTU: detected mtu: %u data_mtu: %u \n", knet_h1->data_mtu, data_mtu); CLEAN_EXIT(FAIL); } CLEAN_EXIT(CONTINUE); } int main(int argc, char *argv[]) { test(); return PASS; } diff --git a/libknet/tests/fun_onwire_upgrade.c b/libknet/tests/fun_onwire_upgrade.c index 119558cf..d37a934b 100644 --- a/libknet/tests/fun_onwire_upgrade.c +++ b/libknet/tests/fun_onwire_upgrade.c @@ -1,297 +1,299 @@ /* * Copyright (C) 2020-2025 Red Hat, Inc. All rights reserved. * * Authors: Fabio M. Di Nitto * * This software licensed under GPL-2.0+ */ #include "config.h" #include #include #include #include #include #include #include #include "libknet.h" #include "compress.h" #include "internals.h" #include "netutils.h" #include "test-common.h" #undef TESTNODES #define TESTNODES 3 static int upgrade_onwire_max_ver(knet_handle_t knet_h, int nodes, uint8_t min, uint8_t max, int seconds, int logfd, FILE *std) { if (knet_handle_disconnect_links(knet_h) < 0) { return -1; } if (wait_for_nodes_state(knet_h, TESTNODES, 0, seconds, logfd, std) < 0) { printf("Failed waiting for nodes 0\n"); return -1; } knet_h->onwire_min_ver = min; knet_h->onwire_max_ver = max; if (knet_handle_reconnect_links(knet_h) < 0) { return -1; } if (nodes) { if (wait_for_nodes_state(knet_h, nodes, 1, seconds, logfd, std) < 0) { printf("Failed waiting for nodes 1\n"); return -1; } } return 0; } static void onwire_ver_callback_fn(void *private_data, uint8_t onwire_min_ver, uint8_t onwire_max_ver, uint8_t onwire_ver) { knet_handle_t knet_h = (knet_handle_t)private_data; printf("Received callback from %p: min: %u max: %u current: %u\n", knet_h, onwire_min_ver, onwire_max_ver, onwire_ver); } static void test(void) { knet_handle_t knet_h[TESTNODES + 1]; int logfds[2]; int i,j; int res; int seconds = 10; if (is_memcheck() || is_helgrind()) { printf("Test suite is running under valgrind, adjusting wait_for_host timeout\n"); seconds = seconds * 16; } setup_logpipes(logfds); knet_handle_start_nodes(knet_h, TESTNODES, logfds, KNET_LOG_DEBUG); flush_logs(logfds[0], stdout); for (i = 1; i <= TESTNODES; i++) { knet_h[i]->onwire_ver_remap = 1; FAIL_ON_ERR(knet_handle_enable_onwire_ver_notify(knet_h[i], (void *)&knet_h[i], onwire_ver_callback_fn)); } flush_logs(logfds[0], stdout); knet_handle_join_nodes(knet_h, TESTNODES, 1, AF_INET, KNET_TRANSPORT_UDP); flush_logs(logfds[0], stdout); printf("Test normal onwire upgrade from %u to %u\n", knet_h[1]->onwire_ver, knet_h[1]->onwire_ver + 1); for (i = 1; i <= TESTNODES; i++) { FAIL_ON_ERR(upgrade_onwire_max_ver(knet_h[i], TESTNODES, knet_h[1]->onwire_ver, knet_h[1]->onwire_ver + 1, seconds, logfds[0], stdout)); flush_logs(logfds[0], stdout); } flush_logs(logfds[0], stdout); sleep(seconds); flush_logs(logfds[0], stdout); for (i = 1; i <= TESTNODES; i++) { printf("node %u, onwire: %u min: %u max: %u\n", i, knet_h[i]->onwire_ver, knet_h[i]->onwire_min_ver, knet_h[i]->onwire_max_ver); } flush_logs(logfds[0], stdout); sleep(seconds); flush_logs(logfds[0], stdout); printf("Test onwire upgrade from %u to %u (all but one node)\n", knet_h[1]->onwire_ver, knet_h[1]->onwire_ver + 1); for (i = 1; i < TESTNODES; i++) { FAIL_ON_ERR(upgrade_onwire_max_ver(knet_h[i], TESTNODES, knet_h[i]->onwire_ver, knet_h[i]->onwire_ver + 1, seconds, logfds[0], stdout)); flush_logs(logfds[0], stdout); } flush_logs(logfds[0], stdout); sleep(seconds); flush_logs(logfds[0], stdout); for (i = 1; i <= TESTNODES; i++) { printf("node %u, onwire: %u min: %u max: %u\n", i, knet_h[i]->onwire_ver, knet_h[i]->onwire_min_ver, knet_h[i]->onwire_max_ver); } + flush_logs(logfds[0], stdout); + sleep(seconds); flush_logs(logfds[0], stdout); sleep(seconds); flush_logs(logfds[0], stdout); printf("Test onwire upgrade from %u to %u (all but one node - phase 2, node should be kicked out and remaining nodes should upgrade)\n", knet_h[1]->onwire_max_ver, knet_h[1]->onwire_max_ver + 1); for (i = 1; i < TESTNODES; i++) { FAIL_ON_ERR(upgrade_onwire_max_ver(knet_h[i], TESTNODES - 1, knet_h[i]->onwire_max_ver, knet_h[i]->onwire_max_ver + 1, seconds, logfds[0], stdout)); flush_logs(logfds[0], stdout); } flush_logs(logfds[0], stdout); sleep(seconds); flush_logs(logfds[0], stdout); for (i = 1; i <= TESTNODES; i++) { printf("node %u, onwire: %u min: %u max: %u\n", i, knet_h[i]->onwire_ver, knet_h[i]->onwire_min_ver, knet_h[i]->onwire_max_ver); for (j = 1; j <= TESTNODES; j++) { if (j == i) { continue; } if (i == TESTNODES) { /* * highset node has been kicked out and should not * be able to reach any other node */ if (knet_h[i]->host_index[j]->status.reachable != 0) { clean_exit(knet_h, TESTNODES, logfds, FAIL); } } else { /* * all other nodes should detect the highest node unreachable * and all the remaining nodes reachable */ if (j == TESTNODES) { if (knet_h[i]->host_index[j]->status.reachable != 0) { clean_exit(knet_h, TESTNODES, logfds, FAIL); } } else { if (knet_h[i]->host_index[j]->status.reachable != 1) { clean_exit(knet_h, TESTNODES, logfds, FAIL); } } } } } flush_logs(logfds[0], stdout); sleep(seconds); flush_logs(logfds[0], stdout); /* * CHANGE THIS TEST if we decide to support downgrades */ printf("Testing node rejoining one version lower (cluster should reject the node)\n"); FAIL_ON_ERR(upgrade_onwire_max_ver(knet_h[TESTNODES], 0, knet_h[1]->onwire_min_ver - 1, knet_h[1]->onwire_max_ver - 1, seconds, logfds[0], stdout)); /* * need more time here for membership to settle */ flush_logs(logfds[0], stdout); sleep(seconds); flush_logs(logfds[0], stdout); sleep(seconds); flush_logs(logfds[0], stdout); for (i = 1; i <= TESTNODES; i++) { printf("node %u, onwire: %u min: %u max: %u\n", i, knet_h[i]->onwire_ver, knet_h[i]->onwire_min_ver, knet_h[i]->onwire_max_ver); for (j = 1; j <= TESTNODES; j++) { if (j == i) { continue; } if (i == TESTNODES) { /* * highset node has been kicked out and should not * be able to reach any other node */ if (knet_h[i]->host_index[j]->status.reachable != 0) { clean_exit(knet_h, TESTNODES, logfds, FAIL); } } else { /* * all other nodes should detect the highest node unreachable * and all the remaining nodes reachable */ if (j == TESTNODES) { if (knet_h[i]->host_index[j]->status.reachable != 0) { clean_exit(knet_h, TESTNODES, logfds, FAIL); } } else { if (knet_h[i]->host_index[j]->status.reachable != 1) { clean_exit(knet_h, TESTNODES, logfds, FAIL); } } } } } printf("Testing node rejoining with proper version (cluster should reform)\n"); FAIL_ON_ERR(upgrade_onwire_max_ver(knet_h[TESTNODES], TESTNODES, knet_h[1]->onwire_min_ver, knet_h[1]->onwire_max_ver, seconds, logfds[0], stdout)); /* * need more time here for membership to settle */ flush_logs(logfds[0], stdout); sleep(seconds); flush_logs(logfds[0], stdout); sleep(seconds); flush_logs(logfds[0], stdout); for (i = 1; i <= TESTNODES; i++) { printf("node %u, onwire: %u min: %u max: %u\n", i, knet_h[i]->onwire_ver, knet_h[i]->onwire_min_ver, knet_h[i]->onwire_max_ver); for (j = 1; j <= TESTNODES; j++) { if (j == i) { continue; } if ((knet_h[i]->host_index[j]->status.reachable != 1) || (knet_h[i]->onwire_ver != knet_h[1]->onwire_max_ver)) { clean_exit(knet_h, TESTNODES, logfds, FAIL); } } } printf("Testing node force onwire version\n"); for (i = 1; i <= TESTNODES; i++) { if (knet_handle_set_onwire_ver(knet_h[i], knet_h[i]->onwire_min_ver) < 0) { clean_exit(knet_h, TESTNODES, logfds, FAIL); } } /* * need more time here for membership to settle */ flush_logs(logfds[0], stdout); sleep(seconds); flush_logs(logfds[0], stdout); sleep(seconds); flush_logs(logfds[0], stdout); for (i = 1; i <= TESTNODES; i++) { printf("node %u, onwire: %u min: %u max: %u\n", i, knet_h[i]->onwire_ver, knet_h[i]->onwire_min_ver, knet_h[i]->onwire_max_ver); for (j = 1; j <= TESTNODES; j++) { if (j == i) { continue; } if ((knet_h[i]->host_index[j]->status.reachable != 1) || (knet_h[i]->onwire_ver != knet_h[1]->onwire_min_ver)) { clean_exit(knet_h, TESTNODES, logfds, FAIL); } } } flush_logs(logfds[0], stdout); close_logpipes(logfds); knet_handle_stop_everything(knet_h, TESTNODES); } int main(int argc, char *argv[]) { test(); return PASS; } diff --git a/libnozzle/tests/test-common.c b/libnozzle/tests/test-common.c index 0a3233ec..ad06350a 100644 --- a/libnozzle/tests/test-common.c +++ b/libnozzle/tests/test-common.c @@ -1,220 +1,220 @@ /* * Copyright (C) 2018-2025 Red Hat, Inc. All rights reserved. * * Author: Fabio M. Di Nitto * * This software licensed under GPL-2.0+ */ #include "config.h" #include #include #include #include #include #include #include #include #include #include #ifdef KNET_BSD #include #include #endif #ifdef KNET_SOLARIS #include #endif #include "test-common.h" void need_root(void) { if (geteuid() != 0) { printf("This test requires root privileges\n"); exit(SKIP); } } void need_tun(void) { int fd; #ifdef KNET_LINUX const char *tundev = "/dev/net/tun"; #endif #ifdef KNET_BSD const char *tundev = "/dev/tap"; struct ifreq ifr; #endif #ifdef KNET_SOLARIS const char *tundev = "/dev/tun"; #endif #if defined(KNET_BSD) || defined(KNET_SOLARIS) int ioctlfd = socket(AF_LOCAL, SOCK_DGRAM, 0); if (ioctlfd < 0) { printf("Unable to init ioctlfd (errno=%d)\n", errno); exit(FAIL); } #endif fd = open(tundev, O_RDWR); if (fd < 0) { printf("Failed to open %s (errno=%d); this test requires TUN support\n", tundev, errno); #if defined(KNET_BSD) || defined(KNET_SOLARIS) close(ioctlfd); #endif exit(SKIP); } #ifdef KNET_BSD memset(&ifr, 0, sizeof(struct ifreq)); ioctl(fd, TAPGIFNAME, &ifr); #endif close(fd); #ifdef KNET_BSD ioctl(ioctlfd, SIOCIFDESTROY, &ifr); ioctl(ioctlfd, SIOCGIFFLAGS, &ifr); close(ioctlfd); #endif } int test_iface(char *name, size_t size, const char *updownpath) { nozzle_t nozzle; nozzle=nozzle_open(name, size, updownpath); if (!nozzle) { printf("Unable to open nozzle (errno=%d).\n", errno); return -1; } printf("Created interface: %s\n", name); if (is_if_in_system(name) > 0) { printf("Found interface %s on the system\n", name); } else { printf("Unable to find interface %s on the system\n", name); } if (!nozzle_get_handle_by_name(name)) { printf("Unable to find interface %s in nozzle db\n", name); } else { printf("Found interface %s in nozzle db\n", name); } nozzle_close(nozzle); if (is_if_in_system(name) == 0) printf("Successfully removed interface %s from the system\n", name); return 0; } int is_if_in_system(char *name) { #ifdef KNET_SOLARIS dlpi_handle_t dlpi_handle; int err = dlpi_open(name, &dlpi_handle, 0); if (err != DLPI_SUCCESS) { return 0; } dlpi_close(dlpi_handle); return 1; #else struct ifaddrs *ifap = NULL; struct ifaddrs *ifa; int found = 0; if (getifaddrs(&ifap) < 0) { printf("Unable to get interface list.\n"); return -1; } ifa = ifap; while (ifa) { if (!strncmp(name, ifa->ifa_name, IFNAMSIZ)) { found = 1; break; } ifa=ifa->ifa_next; } freeifaddrs(ifap); return found; #endif } int get_random_byte(void) { pid_t mypid; uint8_t *pid; uint8_t randombyte = 0; uint8_t i; if (sizeof(pid_t) < 4) { printf("pid_t is smaller than 4 bytes?\n"); exit(77); } mypid = getpid(); pid = (uint8_t *)&mypid; for (i = 0; i < sizeof(pid_t); i++) { if (pid[i] == 0) { pid[i] = 128; } } randombyte = pid[1]; return randombyte; } void make_local_ips(char *testipv4_1, char *testipv4_2, char *testipv6_1, char *testipv6_2) { pid_t mypid; uint8_t *pid; uint8_t i; memset(testipv4_1, 0, IPBUFSIZE); memset(testipv4_2, 0, IPBUFSIZE); memset(testipv6_1, 0, IPBUFSIZE); memset(testipv6_2, 0, IPBUFSIZE); mypid = getpid(); pid = (uint8_t *)&mypid; for (i = 0; i < sizeof(pid_t); i++) { if ((pid[i] == 0) || (pid[i] == 255)) { pid[i] = 128; } } snprintf(testipv4_1, IPBUFSIZE - 1, "127.%u.%u.%u", pid[1], pid[2], pid[0]); snprintf(testipv4_2, IPBUFSIZE - 1, "127.%u.%d.%u", pid[1], pid[2]+1, pid[0]); snprintf(testipv6_1, IPBUFSIZE - 1, "fe%02x:%x%x::1", - pid[1], + pid[1] & 0x7f, pid[2], pid[0]); snprintf(testipv6_2, IPBUFSIZE - 1, "fe%02x:%x%x:1::1", - pid[1], + pid[1] & 0x7f, pid[2], pid[0]); }