1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-22 13:34:15 +03:00

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 <mschwenke@ddn.com>
Reviewed-by: John Mulligan <jmulligan@redhat.com>
Reviewed-by: Anoop C S <anoopcs@samba.org>
This commit is contained in:
Martin Schwenke 2024-09-29 11:57:58 +10:00 committed by Anoop C S
parent aab763d659
commit cc99d0047d
3 changed files with 93 additions and 1 deletions

View File

@ -56,10 +56,13 @@
#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
*/

View File

@ -20,8 +20,16 @@
#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);

View 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',