From: Martin Schwenke Date: Tue, 5 Jul 2022 02:31:57 +0000 (+1000) Subject: ctdb-common: Use POSIX if_nameindex() to check interface existence X-Git-Tag: tevent-0.13.0~44 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=00f1d6d94764ba1312500c72fd08e7df3fae064b;p=thirdparty%2Fsamba.git ctdb-common: Use POSIX if_nameindex() to check interface existence This works as an unprivileged user, so avoids unnecessary errors when running in test mode (and not as root): 2022-02-18T12:21:12.436491+11:00 node.0 ctdbd[6958]: ctdb_sys_check_iface_exists: Failed to open raw socket 2022-02-18T12:21:12.436534+11:00 node.0 ctdbd[6958]: ctdb_sys_check_iface_exists: Failed to open raw socket 2022-02-18T12:21:12.436557+11:00 node.0 ctdbd[6958]: ctdb_sys_check_iface_exists: Failed to open raw socket 2022-02-18T12:21:12.436577+11:00 node.0 ctdbd[6958]: ctdb_sys_check_iface_exists: Failed to open raw socket The corresponding porting test would now become pointless because it would just confirm that "fake" does not exist. Attempt to make it useful by using a less likely name than "fake" and attempting to detect the loopback interface. Signed-off-by: Martin Schwenke Reviewed-by: Amitay Isaacs --- diff --git a/ctdb/common/system.c b/ctdb/common/system.c index 650b62bab16..08dc68284fd 100644 --- a/ctdb/common/system.c +++ b/ctdb/common/system.c @@ -148,32 +148,36 @@ void ctdb_wait_for_process_to_exit(pid_t pid) } } -#ifdef HAVE_AF_PACKET +#ifdef HAVE_IF_NAMEINDEX bool ctdb_sys_check_iface_exists(const char *iface) { - int s; - struct ifreq ifr; + struct if_nameindex *ifnis, *ifni; + bool found = false; - s = socket(AF_PACKET, SOCK_RAW, 0); - if (s == -1){ - /* We don't know if the interface exists, so assume yes */ - DBG_ERR("Failed to open raw socket\n"); - return true; + ifnis = if_nameindex(); + if (ifnis == NULL) { + DBG_ERR("Failed to retrieve inteface list\n"); + return false; } - strlcpy(ifr.ifr_name, iface, sizeof(ifr.ifr_name)); - if (ioctl(s, SIOCGIFINDEX, &ifr) < 0 && errno == ENODEV) { - DBG_ERR("Interface '%s' not found\n", iface); - close(s); - return false; + for (ifni = ifnis; + ifni->if_index != 0 || ifni->if_name != NULL; + ifni++) { + int cmp = strcmp(iface, ifni->if_name); + if (cmp == 0) { + found = true; + goto done; + } } - close(s); - return true; +done: + if_freenameindex(ifnis); + + return found; } -#else /* HAVE_AF_PACKET */ +#else /* HAVE_IF_NAMEINDEX */ bool ctdb_sys_check_iface_exists(const char *iface) { @@ -181,7 +185,7 @@ bool ctdb_sys_check_iface_exists(const char *iface) return true; } -#endif /* HAVE_AF_PACKET */ +#endif /* HAVE_IF_NAMEINDEX */ #ifdef HAVE_PEERCRED diff --git a/ctdb/tests/UNIT/cunit/porting_tests_001.sh b/ctdb/tests/UNIT/cunit/porting_tests_001.sh index 52291b20cc6..bdb7fc531d4 100755 --- a/ctdb/tests/UNIT/cunit/porting_tests_001.sh +++ b/ctdb/tests/UNIT/cunit/porting_tests_001.sh @@ -11,16 +11,5 @@ remove_socket () test_cleanup remove_socket -os=$(uname) -if [ "$os" = "Linux" ] ; then - uid=$(id -u) - if [ "$uid" -eq 0 ] ; then - ok "ctdb_sys_check_iface_exists: Interface 'fake' not found" - else - ok "ctdb_sys_check_iface_exists: Failed to open raw socket" - fi -else - ok_null -fi - -unit_test porting_tests --socket=${socket} +ok_null +unit_test porting_tests --socket="$socket" diff --git a/ctdb/tests/src/porting_tests.c b/ctdb/tests/src/porting_tests.c index 8902c34dfc2..00618d2c4a7 100644 --- a/ctdb/tests/src/porting_tests.c +++ b/ctdb/tests/src/porting_tests.c @@ -171,15 +171,17 @@ static int fork_helper(void) */ static int test_ctdb_sys_check_iface_exists(void) { - const char *fakename = "fake"; - bool test; + bool test1, test2; + + test1 = ctdb_sys_check_iface_exists("unlikely123xyz"); + assert(!test1); + + /* Linux and others */ + test1 = ctdb_sys_check_iface_exists("lo"); + /* FreeBSD */ + test2 = ctdb_sys_check_iface_exists("lo0"); + assert(test1 || test2); - test = ctdb_sys_check_iface_exists(fakename); - if (geteuid() == 0) { - assert(test == false); - } else { - assert(test == true); - } return 0; }