]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
ctdb-common: Use POSIX if_nameindex() to check interface existence
authorMartin Schwenke <martin@meltin.net>
Tue, 5 Jul 2022 02:31:57 +0000 (12:31 +1000)
committerAmitay Isaacs <amitay@samba.org>
Fri, 22 Jul 2022 16:09:31 +0000 (16:09 +0000)
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 <martin@meltin.net>
Reviewed-by: Amitay Isaacs <amitay@gmail.com>
ctdb/common/system.c
ctdb/tests/UNIT/cunit/porting_tests_001.sh
ctdb/tests/src/porting_tests.c

index 650b62bab167ceec280a26fcb7cd2005dabdfadf..08dc68284fd840f4eca30365285c465336cd0a11 100644 (file)
@@ -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
 
index 52291b20cc6ee218205d5924862add524265b31d..bdb7fc531d49a192f032deb576eaf6e97a763c78 100755 (executable)
@@ -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"
index 8902c34dfc2a30469d9f4dda41a839057f292497..00618d2c4a7983c53130cb4b35ad20d6c92c5d3d 100644 (file)
@@ -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;
 }