From cc99d0047d7b39c5af1c7540d3682e8484527a3b Mon Sep 17 00:00:00 2001 From: Martin Schwenke Date: Sun, 29 Sep 2024 11:57:58 +1000 Subject: [PATCH] ctdb-common: Add functions for local IP address checking 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 Reviewed-by: John Mulligan Reviewed-by: Anoop C S --- ctdb/common/system_socket.c | 76 +++++++++++++++++++++++++++++++++++++ ctdb/common/system_socket.h | 8 ++++ ctdb/wscript | 10 ++++- 3 files changed, 93 insertions(+), 1 deletion(-) diff --git a/ctdb/common/system_socket.c b/ctdb/common/system_socket.c index 273b9c3400e..cf4f4fe5d72 100644 --- a/ctdb/common/system_socket.c +++ b/ctdb/common/system_socket.c @@ -56,10 +56,13 @@ #define ETHERTYPE_IP6 0x86dd #endif +#include + #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 */ diff --git a/ctdb/common/system_socket.h b/ctdb/common/system_socket.h index 065c53cb2a8..2674f2b8e85 100644 --- a/ctdb/common/system_socket.h +++ b/ctdb/common/system_socket.h @@ -20,8 +20,16 @@ #ifndef __CTDB_SYSTEM_SOCKET_H__ #define __CTDB_SYSTEM_SOCKET_H__ +#include + #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); diff --git a/ctdb/wscript b/ctdb/wscript index e89f6548af3..13cbfb267a5 100644 --- a/ctdb/wscript +++ b/ctdb/wscript @@ -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', -- 2.47.3