summaryrefslogtreecommitdiff
path: root/src/platform/nmp-object.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/platform/nmp-object.c')
-rw-r--r--src/platform/nmp-object.c301
1 files changed, 158 insertions, 143 deletions
diff --git a/src/platform/nmp-object.c b/src/platform/nmp-object.c
index b0f899ce6e..058f0aee6c 100644
--- a/src/platform/nmp-object.c
+++ b/src/platform/nmp-object.c
@@ -27,6 +27,7 @@
#include <libudev.h>
#include "nm-utils.h"
+#include "nm-utils/nm-secret-utils.h"
#include "nm-core-utils.h"
#include "nm-platform-utils.h"
@@ -347,117 +348,92 @@ _vlan_xgress_qos_mappings_cpy (guint *dst_n_map,
/*****************************************************************************/
static void
-_wireguard_peers_hash_update (gsize n_peers,
- const NMWireGuardPeer *peers,
- NMHashState *h)
-{
- gsize i, j;
-
- nm_hash_update_val (h, n_peers);
- for (i = 0; i < n_peers; i++) {
- const NMWireGuardPeer *p = &peers[i];
-
- nm_hash_update (h, p->public_key, sizeof (p->public_key));
- nm_hash_update (h, p->preshared_key, sizeof (p->preshared_key));
- nm_hash_update_vals (h,
- p->persistent_keepalive_interval,
- p->allowedips_len,
- p->rx_bytes,
- p->tx_bytes,
- p->last_handshake_time.tv_sec,
- p->last_handshake_time.tv_nsec,
- p->endpoint.addr.sa_family);
-
- if (p->endpoint.addr.sa_family == AF_INET)
- nm_hash_update_val (h, p->endpoint.addr4);
- else if (p->endpoint.addr.sa_family == AF_INET6)
- nm_hash_update_val (h, p->endpoint.addr6);
- else if (p->endpoint.addr.sa_family != AF_UNSPEC)
- g_assert_not_reached ();
-
- for (j = 0; j < p->allowedips_len; j++) {
- const NMWireGuardAllowedIP *ip = &p->allowedips[j];
-
- nm_hash_update_vals (h, ip->family, ip->mask);
-
- if (ip->family == AF_INET)
- nm_hash_update_val (h, ip->ip.addr4);
- else if (ip->family == AF_INET6)
- nm_hash_update_val (h, ip->ip.addr6);
- else if (ip->family != AF_UNSPEC)
- g_assert_not_reached ();
- }
- }
+_wireguard_allowed_ip_hash_update (const NMPWireGuardAllowedIP *ip,
+ NMHashState *h)
+{
+ nm_hash_update_vals (h, ip->family,
+ ip->mask);
+
+ if (ip->family == AF_INET)
+ nm_hash_update_val (h, ip->addr.addr4);
+ else if (ip->family == AF_INET6)
+ nm_hash_update_val (h, ip->addr.addr6);
}
static int
-_wireguard_peers_cmp (gsize n_peers,
- const NMWireGuardPeer *p1,
- const NMWireGuardPeer *p2)
-{
- gsize i, j;
-
- for (i = 0; i < n_peers; i++) {
- const NMWireGuardPeer *a = &p1[i];
- const NMWireGuardPeer *b = &p2[i];
-
- NM_CMP_FIELD (a, b, last_handshake_time.tv_sec);
- NM_CMP_FIELD (a, b, last_handshake_time.tv_nsec);
- NM_CMP_FIELD (a, b, rx_bytes);
- NM_CMP_FIELD (a, b, tx_bytes);
- NM_CMP_FIELD (a, b, allowedips_len);
- NM_CMP_FIELD (a, b, persistent_keepalive_interval);
- NM_CMP_FIELD (a, b, endpoint.addr.sa_family);
- NM_CMP_FIELD_MEMCMP (a, b, public_key);
- NM_CMP_FIELD_MEMCMP (a, b, preshared_key);
-
- if (a->endpoint.addr.sa_family == AF_INET)
- NM_CMP_FIELD_MEMCMP (a, b, endpoint.addr4);
- else if (a->endpoint.addr.sa_family == AF_INET6)
- NM_CMP_FIELD_MEMCMP (a, b, endpoint.addr6);
- else if (a->endpoint.addr.sa_family != AF_UNSPEC)
- g_assert_not_reached ();
-
- for (j = 0; j < a->allowedips_len; j++) {
- const NMWireGuardAllowedIP *aip = &a->allowedips[j];
- const NMWireGuardAllowedIP *bip = &b->allowedips[j];
-
- NM_CMP_FIELD (aip, bip, family);
- NM_CMP_FIELD (aip, bip, mask);
-
- if (aip->family == AF_INET)
- NM_CMP_FIELD_MEMCMP (&aip->ip, &bip->ip, addr4);
- else if (aip->family == AF_INET6)
- NM_CMP_FIELD_MEMCMP (&aip->ip, &bip->ip, addr6);
- else if (aip->family != AF_UNSPEC)
- g_assert_not_reached ();
- }
- }
+_wireguard_allowed_ip_cmp (const NMPWireGuardAllowedIP *a,
+ const NMPWireGuardAllowedIP *b)
+{
+ NM_CMP_SELF (a, b);
+
+ NM_CMP_FIELD (a, b, family);
+ NM_CMP_FIELD (a, b, mask);
+
+ if (a->family == AF_INET)
+ NM_CMP_FIELD (a, b, addr.addr4);
+ else if (a->family == AF_INET6)
+ NM_CMP_FIELD_IN6ADDR (a, b, addr.addr6);
return 0;
}
static void
-_wireguard_peers_cpy (gsize *dst_n_peers,
- NMWireGuardPeer **dst_peers,
- gsize src_n_peers,
- const NMWireGuardPeer *src_peers)
-{
- if (src_n_peers == 0) {
- g_clear_pointer (dst_peers, g_free);
- *dst_n_peers = 0;
- } else if ( src_n_peers != *dst_n_peers
- || _wireguard_peers_cmp (src_n_peers, *dst_peers, src_peers) != 0) {
- gsize i;
- g_clear_pointer (dst_peers, g_free);
- *dst_n_peers = src_n_peers;
- if (src_n_peers > 0)
- *dst_peers = nm_memdup (src_peers, sizeof (*src_peers) * src_n_peers);
- for (i = 0; i < src_n_peers; i++) {
- dst_peers[i]->allowedips = nm_memdup (src_peers[i].allowedips, sizeof (src_peers[i].allowedips) * src_peers[i].allowedips_len);
- dst_peers[i]->allowedips_len = src_peers[i].allowedips_len;
- }
+_wireguard_peer_hash_update (const NMPWireGuardPeer *peer,
+ NMHashState *h)
+{
+ guint i;
+
+ nm_hash_update (h, peer->public_key, sizeof (peer->public_key));
+ nm_hash_update (h, peer->preshared_key, sizeof (peer->preshared_key));
+ nm_hash_update_vals (h,
+ peer->persistent_keepalive_interval,
+ peer->allowed_ips_len,
+ peer->rx_bytes,
+ peer->tx_bytes,
+ peer->last_handshake_time.tv_sec,
+ peer->last_handshake_time.tv_nsec,
+ peer->endpoint_port,
+ peer->endpoint_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);
+
+ for (i = 0; i < peer->allowed_ips_len; i++)
+ _wireguard_allowed_ip_hash_update (&peer->allowed_ips[i], h);
+}
+
+static int
+_wireguard_peer_cmp (const NMPWireGuardPeer *a,
+ const NMPWireGuardPeer *b)
+{
+ guint i;
+
+ NM_CMP_SELF (a, b);
+
+ NM_CMP_FIELD (a, b, last_handshake_time.tv_sec);
+ NM_CMP_FIELD (a, b, last_handshake_time.tv_nsec);
+ NM_CMP_FIELD (a, b, rx_bytes);
+ 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_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);
+
+ for (i = 0; i < a->allowed_ips_len; i++) {
+ NM_CMP_RETURN (_wireguard_allowed_ip_cmp (&a->allowed_ips[i],
+ &b->allowed_ips[i]));
}
+
+ return 0;
}
/*****************************************************************************/
@@ -587,12 +563,25 @@ _vt_cmd_obj_dispose_lnk_vlan (NMPObject *obj)
}
static void
-_vt_cmd_obj_dispose_lnk_wireguard (NMPObject *obj)
+_wireguard_clear (NMPObjectLnkWireGuard *lnk)
{
- if (obj->_lnk_wireguard.peers_len)
- g_free (obj->_lnk_wireguard.peers[0].allowedips);
+ guint i;
+
+ nm_explicit_bzero (lnk->_public.private_key,
+ sizeof (lnk->_public.private_key));
+ for (i = 0; i < lnk->peers_len; i++) {
+ NMPWireGuardPeer *peer = (NMPWireGuardPeer *) &lnk->peers[i];
+
+ nm_explicit_bzero (peer->preshared_key, sizeof (peer->preshared_key));
+ }
+ g_free ((gpointer) lnk->peers);
+ g_free ((gpointer) lnk->_allowed_ips_buf);
+}
- g_free (obj->_lnk_wireguard.peers);
+static void
+_vt_cmd_obj_dispose_lnk_wireguard (NMPObject *obj)
+{
+ _wireguard_clear (&obj->_lnk_wireguard);
}
static NMPObject *
@@ -859,7 +848,7 @@ _vt_cmd_obj_to_string_lnk_wireguard (const NMPObject *obj, NMPObjectToStringMode
const NMPClass *klass;
char buf2[sizeof (_nm_utils_to_string_buffer)];
char *b;
- gsize i, l;
+ guint i;
klass = NMP_OBJECT_GET_CLASS (obj);
@@ -871,23 +860,26 @@ _vt_cmd_obj_to_string_lnk_wireguard (const NMPObject *obj, NMPObjectToStringMode
b = buf;
nm_utils_strbuf_append (&b, &buf_size,
- "[%s,%p,%u,%calive,%cvisible; %s "
- "peers (%" G_GSIZE_FORMAT ") {",
+ "[%s,%p,%u,%calive,%cvisible; %s"
+ "%s",
klass->obj_type_name, obj, obj->parent._ref_count,
nmp_object_is_alive (obj) ? '+' : '-',
nmp_object_is_visible (obj) ? '+' : '-',
nmp_object_to_string (obj, NMP_OBJECT_TO_STRING_PUBLIC, buf2, sizeof (buf2)),
- obj->_lnk_wireguard.peers_len);
+ obj->_lnk_wireguard.peers_len > 0
+ ? " peers {"
+ : "");
for (i = 0; i < obj->_lnk_wireguard.peers_len; i++) {
- const NMWireGuardPeer *peer = &obj->_lnk_wireguard.peers[i];
+ const NMPWireGuardPeer *peer = &obj->_lnk_wireguard.peers[i];
+
+ nm_utils_strbuf_append_str (&b, &buf_size, " { ");
nm_platform_wireguard_peer_to_string (peer, b, buf_size);
- l = strlen (b);
- b += l;
- buf_size -= l;
+ nm_utils_strbuf_seek_end (&b, &buf_size);
+ nm_utils_strbuf_append_str (&b, &buf_size, " }");
}
-
- nm_utils_strbuf_append_str (&b, &buf_size, " }");
+ if (obj->_lnk_wireguard.peers_len)
+ nm_utils_strbuf_append_str (&b, &buf_size, " }");
return buf;
case NMP_OBJECT_TO_STRING_PUBLIC:
@@ -947,6 +939,7 @@ _vt_cmd_obj_hash_update_link (const NMPObject *obj, NMHashState *h)
nm_platform_link_hash_update (&obj->link, h);
nm_hash_update_vals (h,
obj->_link.netlink.is_in_netlink,
+ obj->_link.wireguard_family_id,
obj->_link.udev.device);
if (obj->_link.netlink.lnk)
nmp_object_hash_update (obj->_link.netlink.lnk, h);
@@ -969,10 +962,15 @@ _vt_cmd_obj_hash_update_lnk_vlan (const NMPObject *obj, NMHashState *h)
static void
_vt_cmd_obj_hash_update_lnk_wireguard (const NMPObject *obj, NMHashState *h)
{
+ guint i;
+
nm_assert (NMP_OBJECT_GET_TYPE (obj) == NMP_OBJECT_TYPE_LNK_WIREGUARD);
nm_platform_lnk_wireguard_hash_update (&obj->lnk_wireguard, h);
- _wireguard_peers_hash_update (obj->_lnk_wireguard.peers_len, obj->_lnk_wireguard.peers, h);
+
+ nm_hash_update_val (h, obj->_lnk_wireguard.peers_len);
+ for (i = 0; i < obj->_lnk_wireguard.peers_len; i++)
+ _wireguard_peer_hash_update (&obj->_lnk_wireguard.peers[i], h);
}
int
@@ -980,12 +978,7 @@ nmp_object_cmp (const NMPObject *obj1, const NMPObject *obj2)
{
const NMPClass *klass1, *klass2;
- if (obj1 == obj2)
- return 0;
- if (!obj1)
- return -1;
- if (!obj2)
- return 1;
+ NM_CMP_SELF (obj1, obj2);
g_return_val_if_fail (NMP_OBJECT_IS_VALID (obj1), -1);
g_return_val_if_fail (NMP_OBJECT_IS_VALID (obj2), 1);
@@ -1006,16 +999,11 @@ nmp_object_cmp (const NMPObject *obj1, const NMPObject *obj2)
static int
_vt_cmd_obj_cmp_link (const NMPObject *obj1, const NMPObject *obj2)
{
- int i;
+ NM_CMP_RETURN (nm_platform_link_cmp (&obj1->link, &obj2->link));
+ NM_CMP_DIRECT (obj1->_link.netlink.is_in_netlink, obj2->_link.netlink.is_in_netlink);
+ NM_CMP_RETURN (nmp_object_cmp (obj1->_link.netlink.lnk, obj2->_link.netlink.lnk));
+ NM_CMP_DIRECT (obj1->_link.wireguard_family_id, obj2->_link.wireguard_family_id);
- i = nm_platform_link_cmp (&obj1->link, &obj2->link);
- if (i)
- return i;
- if (obj1->_link.netlink.is_in_netlink != obj2->_link.netlink.is_in_netlink)
- return obj1->_link.netlink.is_in_netlink ? -1 : 1;
- i = nmp_object_cmp (obj1->_link.netlink.lnk, obj2->_link.netlink.lnk);
- if (i)
- return i;
if (obj1->_link.udev.device != obj2->_link.udev.device) {
if (!obj1->_link.udev.device)
return -1;
@@ -1028,6 +1016,7 @@ _vt_cmd_obj_cmp_link (const NMPObject *obj1, const NMPObject *obj2)
* Have this check as very last. */
return (obj1->_link.udev.device < obj2->_link.udev.device) ? -1 : 1;
}
+
return 0;
}
@@ -1056,16 +1045,16 @@ _vt_cmd_obj_cmp_lnk_vlan (const NMPObject *obj1, const NMPObject *obj2)
static int
_vt_cmd_obj_cmp_lnk_wireguard (const NMPObject *obj1, const NMPObject *obj2)
{
- int c;
+ guint i;
- c = nm_platform_lnk_wireguard_cmp (&obj1->lnk_wireguard, &obj2->lnk_wireguard);
- if (c)
- return c;
+ NM_CMP_RETURN (nm_platform_lnk_wireguard_cmp (&obj1->lnk_wireguard, &obj2->lnk_wireguard));
+
+ NM_CMP_FIELD (obj1, obj2, _lnk_wireguard.peers_len);
- if (obj1->_lnk_wireguard.peers_len != obj2->_lnk_wireguard.peers_len)
- return obj1->_lnk_wireguard.peers_len < obj2->_lnk_wireguard.peers_len ? -1 : 1;
+ for (i = 0; i < obj1->_lnk_wireguard.peers_len; i++)
+ NM_CMP_RETURN (_wireguard_peer_cmp (&obj1->_lnk_wireguard.peers[i], &obj2->_lnk_wireguard.peers[i]));
- return _wireguard_peers_cmp(obj1->_lnk_wireguard.peers_len, obj1->_lnk_wireguard.peers, obj2->_lnk_wireguard.peers);
+ return 0;
}
/* @src is a const object, which is not entirely correct for link types, where
@@ -1137,9 +1126,36 @@ _vt_cmd_obj_copy_lnk_vlan (NMPObject *dst, const NMPObject *src)
static void
_vt_cmd_obj_copy_lnk_wireguard (NMPObject *dst, const NMPObject *src)
{
- dst->lnk_wireguard = src->lnk_wireguard;
- _wireguard_peers_cpy (&dst->_lnk_wireguard.peers_len, &dst->_lnk_wireguard.peers,
- src->_lnk_wireguard.peers_len, src->_lnk_wireguard.peers);
+ guint i;
+
+ nm_assert (dst != src);
+
+ _wireguard_clear (&dst->_lnk_wireguard);
+
+ dst->_lnk_wireguard = src->_lnk_wireguard;
+
+ dst->_lnk_wireguard.peers = nm_memdup (dst->_lnk_wireguard.peers,
+ sizeof (NMPWireGuardPeer) * dst->_lnk_wireguard.peers_len);
+ dst->_lnk_wireguard._allowed_ips_buf = nm_memdup (dst->_lnk_wireguard._allowed_ips_buf,
+ sizeof (NMPWireGuardAllowedIP) * dst->_lnk_wireguard._allowed_ips_buf_len);
+
+ /* all the peers' pointers point into the buffer. They need to be readjusted. */
+ for (i = 0; i < dst->_lnk_wireguard.peers_len; i++) {
+ NMPWireGuardPeer *peer = (NMPWireGuardPeer *) &dst->_lnk_wireguard.peers[i];
+
+ if (peer->allowed_ips_len == 0) {
+ nm_assert (!peer->allowed_ips);
+ continue;
+ }
+ nm_assert (dst->_lnk_wireguard._allowed_ips_buf_len > 0);
+ nm_assert (src->_lnk_wireguard._allowed_ips_buf);
+ nm_assert (peer->allowed_ips >= src->_lnk_wireguard._allowed_ips_buf);
+ nm_assert (&peer->allowed_ips[peer->allowed_ips_len] <= &src->_lnk_wireguard._allowed_ips_buf[src->_lnk_wireguard._allowed_ips_buf_len]);
+
+ peer->allowed_ips = &dst->_lnk_wireguard._allowed_ips_buf[peer->allowed_ips - src->_lnk_wireguard._allowed_ips_buf];
+ }
+
+ nm_assert (nmp_object_equal (src, dst));
}
#define _vt_cmd_plobj_id_copy(type, plat_type, cmd) \
@@ -3084,4 +3100,3 @@ const NMPClass _nmp_classes[NMP_OBJECT_TYPE_MAX] = {
.cmd_plobj_cmp = (int (*) (const NMPlatformObject *obj1, const NMPlatformObject *obj2)) nm_platform_lnk_vlan_cmp,
},
};
-