diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c index 45016ea50..2979ee5d3 100644 --- a/src/platform/nm-linux-platform.c +++ b/src/platform/nm-linux-platform.c @@ -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]); diff --git a/src/platform/nm-platform.c b/src/platform/nm-platform.c index f64015c70..c750caf56 100644 --- a/src/platform/nm-platform.c +++ b/src/platform/nm-platform.c @@ -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'; diff --git a/src/platform/nmp-object.c b/src/platform/nmp-object.c index c0711c792..03ddaaa7b 100644 --- a/src/platform/nmp-object.c +++ b/src/platform/nmp-object.c @@ -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], diff --git a/src/platform/nmp-object.h b/src/platform/nmp-object.h index 66c0eebef..efba5f1b8 100644 --- a/src/platform/nmp-object.h +++ b/src/platform/nmp-object.h @@ -21,6 +21,8 @@ #ifndef __NMP_OBJECT_H__ #define __NMP_OBJECT_H__ +#include + #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; /*****************************************************************************/