platform: track wireguard endpoint as sockaddr struct
We need to track the IPv6 endpoint as struct sockaddr_in6, so that we have access to the scope-id.
This commit is contained in:
@@ -475,6 +475,30 @@ static struct nl_sock *_genl_sock (NMLinuxPlatform *platform);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static int
|
||||
_sock_addr_set_unaligned (NMSockAddrUnion *dst,
|
||||
gconstpointer src,
|
||||
gsize src_len)
|
||||
{
|
||||
int f_expected;
|
||||
struct sockaddr sa;
|
||||
|
||||
if (src_len == sizeof (struct sockaddr_in))
|
||||
f_expected = AF_INET;
|
||||
else if (src_len == sizeof (struct sockaddr_in6))
|
||||
f_expected = AF_INET6;
|
||||
else
|
||||
return AF_UNSPEC;
|
||||
|
||||
memcpy (&sa.sa_family, &((struct sockaddr *) src)->sa_family, sizeof (sa.sa_family));
|
||||
if (sa.sa_family != f_expected)
|
||||
return AF_UNSPEC;
|
||||
memcpy (dst, src, src_len);
|
||||
return f_expected;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static int
|
||||
wait_for_nl_response_to_nmerr (WaitForNlResponseResult seq_result)
|
||||
{
|
||||
@@ -2009,28 +2033,9 @@ _wireguard_update_from_peers_nla (CList *peers,
|
||||
nla_len (tb[WGPEER_A_PRESHARED_KEY]));
|
||||
}
|
||||
if (tb[WGPEER_A_ENDPOINT]) {
|
||||
const struct sockaddr *addr = nla_data (tb[WGPEER_A_ENDPOINT]);
|
||||
unsigned short family;
|
||||
|
||||
G_STATIC_ASSERT (sizeof (addr->sa_family) == sizeof (family));
|
||||
memcpy (&family, &addr->sa_family, sizeof (addr->sa_family));
|
||||
|
||||
if ( family == AF_INET
|
||||
&& nla_len (tb[WGPEER_A_ENDPOINT]) == sizeof (struct sockaddr_in)) {
|
||||
const struct sockaddr_in *addr4 = (const struct sockaddr_in *) addr;
|
||||
|
||||
peer_c->data.endpoint_family = AF_INET;
|
||||
peer_c->data.endpoint_port = unaligned_read_be16 (&addr4->sin_port);
|
||||
peer_c->data.endpoint_addr.addr4 = unaligned_read_ne32 (&addr4->sin_addr.s_addr);
|
||||
memcpy (&peer_c->data.endpoint_addr.addr4, &addr4->sin_addr.s_addr, 4);
|
||||
} else if ( family == AF_INET6
|
||||
&& nla_len (tb[WGPEER_A_ENDPOINT]) == sizeof (struct sockaddr_in6)) {
|
||||
const struct sockaddr_in6 *addr6 = (const struct sockaddr_in6 *) addr;
|
||||
|
||||
peer_c->data.endpoint_family = AF_INET6;
|
||||
peer_c->data.endpoint_port = unaligned_read_be16 (&addr6->sin6_port);
|
||||
memcpy (&peer_c->data.endpoint_addr.addr6, &addr6->sin6_addr, 16);
|
||||
}
|
||||
_sock_addr_set_unaligned (&peer_c->data.endpoint,
|
||||
nla_data (tb[WGPEER_A_ENDPOINT]),
|
||||
nla_len (tb[WGPEER_A_ENDPOINT]));
|
||||
}
|
||||
if (tb[WGPEER_A_PERSISTENT_KEEPALIVE_INTERVAL])
|
||||
peer_c->data.persistent_keepalive_interval = nla_get_u64 (tb[WGPEER_A_PERSISTENT_KEEPALIVE_INTERVAL]);
|
||||
|
@@ -5550,20 +5550,26 @@ nm_platform_wireguard_peer_to_string (const NMPWireGuardPeer *peer, char *buf, g
|
||||
gs_free char *public_key_b64 = NULL;
|
||||
char s_endpoint[NM_UTILS_INET_ADDRSTRLEN + 100];
|
||||
char s_addr[NM_UTILS_INET_ADDRSTRLEN];
|
||||
char s_scope_id[40];
|
||||
guint i;
|
||||
|
||||
nm_utils_to_string_buffer_init (&buf, &len);
|
||||
|
||||
if (peer->endpoint_family == AF_INET) {
|
||||
if (peer->endpoint.sa.sa_family == AF_INET) {
|
||||
nm_sprintf_buf (s_endpoint,
|
||||
" endpoint %s:%u",
|
||||
nm_utils_inet4_ntop (peer->endpoint_addr.addr4, s_addr),
|
||||
(guint) peer->endpoint_port);
|
||||
} else if (peer->endpoint_family == AF_INET6) {
|
||||
nm_utils_inet4_ntop (peer->endpoint.in.sin_addr.s_addr, s_addr),
|
||||
(guint) htons (peer->endpoint.in.sin_port));
|
||||
} else if (peer->endpoint.sa.sa_family == AF_INET6) {
|
||||
if (peer->endpoint.in6.sin6_scope_id != 0)
|
||||
nm_sprintf_buf (s_scope_id, "@%u", peer->endpoint.in6.sin6_scope_id);
|
||||
else
|
||||
s_scope_id[0] = '\0';
|
||||
nm_sprintf_buf (s_endpoint,
|
||||
" endpoint [%s]:%u",
|
||||
nm_utils_inet6_ntop (&peer->endpoint_addr.addr6, s_addr),
|
||||
(guint) peer->endpoint_port);
|
||||
" endpoint [%s]%s:%u",
|
||||
nm_utils_inet6_ntop (&peer->endpoint.in6.sin6_addr, s_addr),
|
||||
s_scope_id,
|
||||
(guint) htons (peer->endpoint.in6.sin6_port));
|
||||
} else
|
||||
s_endpoint[0] = '\0';
|
||||
|
||||
|
@@ -393,13 +393,12 @@ _wireguard_peer_hash_update (const NMPWireGuardPeer *peer,
|
||||
peer->tx_bytes,
|
||||
peer->last_handshake_time.tv_sec,
|
||||
peer->last_handshake_time.tv_nsec,
|
||||
peer->endpoint_port,
|
||||
peer->endpoint_family);
|
||||
peer->endpoint.sa.sa_family);
|
||||
|
||||
if (peer->endpoint_family == AF_INET)
|
||||
nm_hash_update_val (h, peer->endpoint_addr.addr4);
|
||||
else if (peer->endpoint_family == AF_INET6)
|
||||
nm_hash_update_val (h, peer->endpoint_addr.addr6);
|
||||
if (peer->endpoint.sa.sa_family == AF_INET)
|
||||
nm_hash_update_val (h, peer->endpoint.in);
|
||||
else if (peer->endpoint.sa.sa_family == AF_INET6)
|
||||
nm_hash_update_val (h, peer->endpoint.in6);
|
||||
|
||||
for (i = 0; i < peer->allowed_ips_len; i++)
|
||||
_wireguard_allowed_ip_hash_update (&peer->allowed_ips[i], h);
|
||||
@@ -419,15 +418,14 @@ _wireguard_peer_cmp (const NMPWireGuardPeer *a,
|
||||
NM_CMP_FIELD (a, b, tx_bytes);
|
||||
NM_CMP_FIELD (a, b, allowed_ips_len);
|
||||
NM_CMP_FIELD (a, b, persistent_keepalive_interval);
|
||||
NM_CMP_FIELD (a, b, endpoint_port);
|
||||
NM_CMP_FIELD (a, b, endpoint_family);
|
||||
NM_CMP_FIELD (a, b, endpoint.sa.sa_family);
|
||||
NM_CMP_FIELD_MEMCMP (a, b, public_key);
|
||||
NM_CMP_FIELD_MEMCMP (a, b, preshared_key);
|
||||
|
||||
if (a->endpoint_family == AF_INET)
|
||||
NM_CMP_FIELD (a, b, endpoint_addr.addr4);
|
||||
else if (a->endpoint_family == AF_INET6)
|
||||
NM_CMP_FIELD_IN6ADDR (a, b, endpoint_addr.addr6);
|
||||
if (a->endpoint.sa.sa_family == AF_INET)
|
||||
NM_CMP_FIELD_MEMCMP (a, b, endpoint.in);
|
||||
else if (a->endpoint.sa.sa_family == AF_INET6)
|
||||
NM_CMP_FIELD_MEMCMP (a, b, endpoint.in6);
|
||||
|
||||
for (i = 0; i < a->allowed_ips_len; i++) {
|
||||
NM_CMP_RETURN (_wireguard_allowed_ip_cmp (&a->allowed_ips[i],
|
||||
|
@@ -21,6 +21,8 @@
|
||||
#ifndef __NMP_OBJECT_H__
|
||||
#define __NMP_OBJECT_H__
|
||||
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include "nm-utils/nm-obj.h"
|
||||
#include "nm-utils/nm-dedup-multi.h"
|
||||
#include "nm-platform.h"
|
||||
@@ -29,6 +31,12 @@ struct udev_device;
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
typedef union {
|
||||
struct sockaddr sa;
|
||||
struct sockaddr_in in;
|
||||
struct sockaddr_in6 in6;
|
||||
} NMSockAddrUnion;
|
||||
|
||||
typedef struct {
|
||||
NMIPAddr addr;
|
||||
guint8 family;
|
||||
@@ -36,7 +44,7 @@ typedef struct {
|
||||
} NMPWireGuardAllowedIP;
|
||||
|
||||
typedef struct _NMPWireGuardPeer {
|
||||
NMIPAddr endpoint_addr;
|
||||
NMSockAddrUnion endpoint;
|
||||
struct timespec last_handshake_time;
|
||||
guint64 rx_bytes;
|
||||
guint64 tx_bytes;
|
||||
@@ -49,10 +57,8 @@ typedef struct _NMPWireGuardPeer {
|
||||
guint _construct_idx_end;
|
||||
};
|
||||
guint16 persistent_keepalive_interval;
|
||||
guint16 endpoint_port;
|
||||
guint8 public_key[NMP_WIREGUARD_PUBLIC_KEY_LEN];
|
||||
guint8 preshared_key[NMP_WIREGUARD_SYMMETRIC_KEY_LEN];
|
||||
guint8 endpoint_family;
|
||||
} NMPWireGuardPeer;
|
||||
|
||||
/*****************************************************************************/
|
||||
|
Reference in New Issue
Block a user