]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
ctdb-common: Add functions for local IP address checking
authorMartin Schwenke <mschwenke@ddn.com>
Sun, 29 Sep 2024 01:57:58 +0000 (11:57 +1000)
committerAnoop C S <anoopcs@samba.org>
Mon, 7 Oct 2024 15:58:38 +0000 (15:58 +0000)
This is a wrapper around getifaddrs(2), which is in libreplace, so
should always be available.

Some users want to set net.ipv4.ip_nonlocal_bind = 1.  So, CTDB needs
a way of testing if public IPs are present, without using bind(2).

Doing all of this unconditionally in ctdb_sys_have_ip() will be
inefficient in the recovery daemon's local IP verification if there
are a lot of IP addresses.  Split it this way so the interface
information can be retrieved once and used multiple times.

This doesn't appear to need IP canonicalisation for IPv4-mapped IPv6
addresses.

Signed-off-by: Martin Schwenke <mschwenke@ddn.com>
Reviewed-by: John Mulligan <jmulligan@redhat.com>
Reviewed-by: Anoop C S <anoopcs@samba.org>
ctdb/common/system_socket.c
ctdb/common/system_socket.h
ctdb/wscript

index 273b9c3400ee177fa70552c4c0d8807692cd3bef..cf4f4fe5d7263a63eb4ef7abf63717870dd36a61 100644 (file)
 #define ETHERTYPE_IP6 0x86dd
 #endif
 
+#include <talloc.h>
+
 #include "lib/util/debug.h"
 #include "lib/util/blocking.h"
 
 #include "protocol/protocol.h"
+#include "protocol/protocol_util.h"
 
 #include "common/logging.h"
 #include "common/system_socket.h"
@@ -84,6 +87,79 @@ static uint32_t uint16_checksum(uint8_t *data, size_t n)
        return sum;
 }
 
+struct ctdb_sys_local_ips_context {
+       struct ifaddrs *ifa;
+};
+
+static int ctdb_sys_local_ips_destructor(
+       struct ctdb_sys_local_ips_context *ips_ctx)
+{
+       freeifaddrs(ips_ctx->ifa);
+       ips_ctx->ifa = NULL;
+
+       return 0;
+}
+
+int ctdb_sys_local_ips_init(TALLOC_CTX *ctx,
+                           struct ctdb_sys_local_ips_context **ips_ctx)
+{
+       struct ctdb_sys_local_ips_context *t = NULL;
+       int ret = 0;
+
+       t = talloc(ctx, struct ctdb_sys_local_ips_context);
+       if (t == NULL) {
+               return ENOMEM;
+       }
+
+       ret = getifaddrs(&t->ifa);
+       if (ret != 0) {
+               ret = errno;
+               talloc_free(t);
+               return ret;
+       }
+
+       talloc_set_destructor(t, ctdb_sys_local_ips_destructor);
+       *ips_ctx = t;
+
+       return ret;
+}
+
+bool ctdb_sys_local_ip_check(const struct ctdb_sys_local_ips_context *ips_ctx,
+                            const ctdb_sock_addr *addr)
+{
+       struct ifaddrs *ifa = NULL;
+       int ret;
+
+       for (ifa = ips_ctx->ifa; ifa != NULL; ifa = ifa->ifa_next) {
+               ctdb_sock_addr sock_addr;
+               bool match;
+
+               if (ifa->ifa_addr == NULL)
+                       continue;
+
+               /* Ignore non-IPv4/IPv6 interfaces */
+               switch (ifa->ifa_addr->sa_family) {
+               case AF_INET:
+               case AF_INET6:
+                       break;
+               default:
+                       continue;
+               }
+
+               ret = ctdb_sock_addr_from_sockaddr(ifa->ifa_addr, &sock_addr);
+               if (ret != 0) {
+                       return false;
+               }
+
+               match = ctdb_sock_addr_same_ip(&sock_addr, addr);
+               if (match) {
+                       return true;
+               }
+       }
+
+       return false;
+}
+
 /*
  * See if the given IP is currently on an interface
  */
index 065c53cb2a8ca574c74816d8b97436d4f1d49c81..2674f2b8e85478acc4c835ee55a4c24986d5ffd6 100644 (file)
 #ifndef __CTDB_SYSTEM_SOCKET_H__
 #define __CTDB_SYSTEM_SOCKET_H__
 
+#include <talloc.h>
+
 #include "protocol/protocol.h"
 
+struct ctdb_sys_local_ips_context;
+
+int ctdb_sys_local_ips_init(TALLOC_CTX *ctx,
+                           struct ctdb_sys_local_ips_context **ips_ctx);
+bool ctdb_sys_local_ip_check(const struct ctdb_sys_local_ips_context *ips_ctx,
+                            const ctdb_sock_addr *addr);
 bool ctdb_sys_have_ip(ctdb_sock_addr *addr);
 
 int ctdb_sys_send_arp(const ctdb_sock_addr *addr, const char *iface);
index e89f6548af3514817e55963a536fc3c9c19b09f7..13cbfb267a55c58fbe075d622fe79ea2d6e7886b 100644 (file)
@@ -415,7 +415,15 @@ def build(bld):
     bld.SAMBA_SUBSYSTEM('ctdb-system',
                         source=bld.SUBDIR('common',
                                           'system_socket.c system.c'),
-                        deps='replace talloc tevent tdb pcap samba-util')
+                        deps='''ctdb-protocol
+                                ctdb-protocol-util
+                                pcap
+                                replace
+                                samba-util
+                                talloc
+                                tdb
+                                tevent
+                             ''')
 
     bld.SAMBA_SUBSYSTEM('ctdb-common',
                         source=bld.SUBDIR('common',