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:
Thomas Haller
2018-12-24 00:41:01 +01:00
parent 2e48f6419f
commit 0713a6996c
4 changed files with 59 additions and 44 deletions

View File

@@ -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]);

View File

@@ -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';

View File

@@ -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],

View File

@@ -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;
/*****************************************************************************/