[RFC PATCH 2/2] platform: add support for WireGuard links



Add support for a new wireguard link type to the platform code. For now
this only covers querying existing links via Generic Netlink and parsing
them into platform objects.
---
 src/nm-types.h                   |   5 +
 src/platform/nm-linux-platform.c | 250 +++++++++++++++++++++++++++++++++++++++
 src/platform/nm-platform.c       |  97 +++++++++++++++
 src/platform/nm-platform.h       |  44 +++++++
 src/platform/nmp-object.c        |  25 ++++
 src/platform/nmp-object.h        |  21 ++++
 6 files changed, 442 insertions(+)

diff --git a/src/nm-types.h b/src/nm-types.h
index 239202cf4..d44cd0047 100644
--- a/src/nm-types.h
+++ b/src/nm-types.h
@@ -162,6 +162,7 @@ typedef enum {
        NM_LINK_TYPE_VETH,
        NM_LINK_TYPE_VLAN,
        NM_LINK_TYPE_VXLAN,
+       NM_LINK_TYPE_WIREGUARD,
 
        /* Software types with slaves */
        NM_LINK_TYPE_BRIDGE = 0x10000 | 0x20000,
@@ -193,6 +194,10 @@ typedef enum {
        NMP_OBJECT_TYPE_LNK_SIT,
        NMP_OBJECT_TYPE_LNK_VLAN,
        NMP_OBJECT_TYPE_LNK_VXLAN,
+       NMP_OBJECT_TYPE_LNK_WIREGUARD,
+
+       NMP_OBJECT_TYPE_WIREGUARD_PEER,
+       NMP_OBJECT_TYPE_WIREGUARD_ALLOWEDIP,
 
        __NMP_OBJECT_TYPE_LAST,
        NMP_OBJECT_TYPE_MAX = __NMP_OBJECT_TYPE_LAST - 1,
diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c
index f29ee03e6..eb73858bd 100644
--- a/src/platform/nm-linux-platform.c
+++ b/src/platform/nm-linux-platform.c
@@ -161,6 +161,40 @@ G_STATIC_ASSERT (RTA_MAX == (__RTA_MAX - 1));
 
 /*****************************************************************************/
 
+#define WG_CMD_GET_DEVICE 0
+#define WG_CMD_SET_DEVICE 1
+
+#define IFLA_WG_DEVICE_UNSPEC           0
+#define IFLA_WG_DEVICE_IFINDEX          1
+#define IFLA_WG_DEVICE_IFNAME           2
+#define IFLA_WG_DEVICE_PRIVATE_KEY      3
+#define IFLA_WG_DEVICE_PUBLIC_KEY       4
+#define IFLA_WG_DEVICE_FLAGS            5
+#define IFLA_WG_DEVICE_LISTEN_PORT      6
+#define IFLA_WG_DEVICE_FWMARK           7
+#define IFLA_WG_DEVICE_PEERS            8
+#define __IFLA_WG_DEVICE_MAX            9
+
+#define IFLA_WG_PEER_UNSPEC                        0
+#define IFLA_WG_PEER_PUBLIC_KEY                    1
+#define IFLA_WG_PEER_PRESHARED_KEY                 2
+#define IFLA_WG_PEER_FLAGS                         3
+#define IFLA_WG_PEER_ENDPOINT                      4
+#define IFLA_WG_PEER_PERSISTENT_KEEPALIVE_INTERVAL 5
+#define IFLA_WG_PEER_LAST_HANDSHAKE_TIME           6
+#define IFLA_WG_PEER_RX_BYTES                      7
+#define IFLA_WG_PEER_TX_BYTES                      8
+#define IFLA_WG_PEER_ALLOWEDIPS                    9
+#define __IFLA_WG_PEER_MAX                         10
+
+#define IFLA_WG_ALLOWEDIP_UNSPEC        0
+#define IFLA_WG_ALLOWEDIP_FAMILY        1
+#define IFLA_WG_ALLOWEDIP_IPADDR        2
+#define IFLA_WG_ALLOWEDIP_CIDR_MASK     3
+#define __IFLA_WG_ALLOWEDIP_MAX         4
+
+/*****************************************************************************/
+
 #define _NMLOG_PREFIX_NAME                "platform-linux"
 #define _NMLOG_DOMAIN                     LOGD_PLATFORM
 #define _NMLOG2_DOMAIN                    LOGD_PLATFORM
@@ -543,6 +577,7 @@ static const LinkDesc linktypes[] = {
        { NM_LINK_TYPE_VETH,          "veth",        "veth",        NULL },
        { NM_LINK_TYPE_VLAN,          "vlan",        "vlan",        "vlan" },
        { NM_LINK_TYPE_VXLAN,         "vxlan",       "vxlan",       "vxlan" },
+       { NM_LINK_TYPE_WIREGUARD,     "wireguard",   "wireguard",   "wireguard" },
 
        { NM_LINK_TYPE_BRIDGE,        "bridge",      "bridge",      "bridge" },
        { NM_LINK_TYPE_BOND,          "bond",        "bond",        "bond" },
@@ -1377,6 +1412,218 @@ _parse_lnk_sit (const char *kind, struct nlattr *info_data)
 
 /*****************************************************************************/
 
+static int
+_wireguard_parse_allowedip (struct nlattr *allowedip_attr, CList *list_head)
+{
+       static const struct nla_policy allowedip_policy[__IFLA_WG_ALLOWEDIP_MAX] = {
+               [IFLA_WG_ALLOWEDIP_FAMILY]    = { .type = NLA_U16 },
+               [IFLA_WG_ALLOWEDIP_IPADDR]    = { .minlen = sizeof (struct in_addr) },
+               [IFLA_WG_ALLOWEDIP_CIDR_MASK] = { .type = NLA_U8 },
+       };
+       struct nlattr *tba[__IFLA_WG_ALLOWEDIP_MAX];
+       NMPObject *obj;
+       NMPlatformWireguardAllowedIP *allowedip;
+       int addr_len;
+       int ret;
+
+       ret = nla_parse_nested (tba, __IFLA_WG_ALLOWEDIP_MAX, allowedip_attr, allowedip_policy);
+       if (ret)
+               goto errout;
+
+       obj = nmp_object_new (NMP_OBJECT_TYPE_WIREGUARD_ALLOWEDIP, NULL);
+       allowedip = &obj->wireguard_allowedip;
+
+       allowedip->family = tba[IFLA_WG_ALLOWEDIP_FAMILY] ? nla_get_u16 (tba[IFLA_WG_ALLOWEDIP_FAMILY]) : 0;
+
+       addr_len = (allowedip->family == AF_INET)
+                  ? sizeof (in_addr_t)
+                  : sizeof (struct in6_addr);
+
+       ret = -NLE_ATTRSIZE;
+       _check_addr_or_errout (tba, IFLA_WG_ALLOWEDIP_IPADDR, addr_len);
+       if (tba[IFLA_WG_ALLOWEDIP_IPADDR])
+               memcpy (&allowedip->ip, nla_data (tba[IFLA_WG_ALLOWEDIP_IPADDR]), addr_len);
+
+       allowedip->cidr = tba[IFLA_WG_ALLOWEDIP_CIDR_MASK] ? nla_get_u8 (tba[IFLA_WG_ALLOWEDIP_CIDR_MASK]) : 
0;
+
+       c_list_link_tail (list_head, &allowedip->allowedips_lst);
+
+       ret = 0;
+errout:
+       return ret;
+}
+
+static int
+_wireguard_parse_peer (struct nlattr *peer_attr, CList *list_head)
+{
+       static const struct nla_policy peer_policy[__IFLA_WG_PEER_MAX] = {
+               [IFLA_WG_PEER_PUBLIC_KEY]                    = { .minlen = NM_WG_PUBLIC_KEY_LEN },
+               [IFLA_WG_PEER_PRESHARED_KEY]                 = { .minlen = NM_WG_SYMMETRIC_KEY_LEN },
+               [IFLA_WG_PEER_FLAGS]                         = { .type = NLA_U32 },
+               [IFLA_WG_PEER_ENDPOINT]                      = { .minlen = sizeof (struct sockaddr) },
+               [IFLA_WG_PEER_PERSISTENT_KEEPALIVE_INTERVAL] = { .type = NLA_U16 },
+               [IFLA_WG_PEER_LAST_HANDSHAKE_TIME]           = { .minlen = sizeof (struct timespec) },
+               [IFLA_WG_PEER_RX_BYTES]                      = { .type = NLA_U64 },
+               [IFLA_WG_PEER_TX_BYTES]                      = { .type = NLA_U64 },
+               [IFLA_WG_PEER_ALLOWEDIPS]                    = { .type = NLA_NESTED },
+       };
+       struct nlattr *tbp[__IFLA_WG_PEER_MAX];
+       NMPObject *obj;
+       NMPlatformWireguardPeer *peer;
+       int ret;
+
+       ret = nla_parse_nested (tbp, __IFLA_WG_PEER_MAX, peer_attr, peer_policy);
+       if (ret)
+               goto errout;
+
+       obj = nmp_object_new (NMP_OBJECT_TYPE_WIREGUARD_PEER, NULL);
+       peer = &obj->wireguard_peer;
+
+       if (tbp[IFLA_WG_PEER_PUBLIC_KEY])
+               memcpy (&peer->public_key, nla_data (tbp[IFLA_WG_PEER_PUBLIC_KEY]), sizeof 
(peer->public_key));
+
+       if (tbp[IFLA_WG_PEER_PRESHARED_KEY])
+               memcpy (&peer->preshared_key, nla_data (tbp[IFLA_WG_PEER_PRESHARED_KEY]), sizeof 
(peer->preshared_key));
+
+       if (tbp[IFLA_WG_PEER_ENDPOINT])
+               memcpy (&peer->endpoint, nla_data (tbp[IFLA_WG_PEER_ENDPOINT]), sizeof (peer->endpoint));
+
+       peer->persistent_keepalive_interval = tbp[IFLA_WG_PEER_PERSISTENT_KEEPALIVE_INTERVAL] ? nla_get_u64 
(tbp[IFLA_WG_PEER_PERSISTENT_KEEPALIVE_INTERVAL]) : 0;
+
+       if (tbp[IFLA_WG_PEER_LAST_HANDSHAKE_TIME])
+               memcpy (&peer->last_handshake_time, nla_data (tbp[IFLA_WG_PEER_LAST_HANDSHAKE_TIME]), sizeof 
(peer->last_handshake_time));
+
+       peer->rx_bytes = tbp[IFLA_WG_PEER_RX_BYTES] ? nla_get_u64 (tbp[IFLA_WG_PEER_RX_BYTES]) : 0;
+       peer->tx_bytes = tbp[IFLA_WG_PEER_TX_BYTES] ? nla_get_u64 (tbp[IFLA_WG_PEER_TX_BYTES]) : 0;
+
+       c_list_init (&peer->allowedips_lst_head);
+       if (tbp[IFLA_WG_PEER_ALLOWEDIPS]) {
+               struct nlattr *allowedip_attr;
+               int remaining_allowedips;
+               nla_for_each_nested (allowedip_attr, tbp[IFLA_WG_PEER_ALLOWEDIPS], remaining_allowedips) {
+                       ret = _wireguard_parse_allowedip (allowedip_attr, &peer->allowedips_lst_head);
+                       if (ret)
+                               goto errout;
+               }
+       }
+
+       c_list_link_tail (list_head, &peer->peers_lst);
+
+       ret = 0;
+errout:
+       return ret;
+}
+
+static int
+_wireguard_parse_getdevice (struct nl_msg *msg, void *arg)
+{
+       static const struct nla_policy device_policy[__IFLA_WG_DEVICE_MAX] = {
+               [IFLA_WG_DEVICE_IFINDEX]     = { .type = NLA_U32 },
+               [IFLA_WG_DEVICE_IFNAME]      = { .type = NLA_NUL_STRING, .maxlen = IFNAMSIZ - 1 },
+               [IFLA_WG_DEVICE_PRIVATE_KEY] = { .minlen = NM_WG_PUBLIC_KEY_LEN },
+               [IFLA_WG_DEVICE_PUBLIC_KEY]  = { .minlen = NM_WG_PUBLIC_KEY_LEN },
+               [IFLA_WG_DEVICE_FLAGS]       = { .type = NLA_U32 },
+               [IFLA_WG_DEVICE_LISTEN_PORT] = { .type = NLA_U16 },
+               [IFLA_WG_DEVICE_FWMARK]      = { .type = NLA_U32 },
+               [IFLA_WG_DEVICE_PEERS]       = { .type = NLA_NESTED },
+       };
+       struct nlattr *tbd[__IFLA_WG_DEVICE_MAX];
+       NMPObject *obj = * (NMPObject **) arg;
+       NMPlatformLnkWireguard *props;
+       struct nlmsghdr *nlh = nlmsg_hdr (msg);
+       int ret;
+
+       ret = genlmsg_parse (nlh, 0, tbd, __IFLA_WG_DEVICE_MAX - 1, device_policy);
+       if (ret)
+               goto errout;
+
+       props = &obj->lnk_wireguard;
+
+       props->listen_port = tbd[IFLA_WG_DEVICE_LISTEN_PORT] ? nla_get_u16 (tbd[IFLA_WG_DEVICE_LISTEN_PORT]) 
: 0;
+       props->fwmark = tbd[IFLA_WG_DEVICE_FWMARK] ? nla_get_u32 (tbd[IFLA_WG_DEVICE_FWMARK]) : 0;
+
+       if (tbd[IFLA_WG_DEVICE_PRIVATE_KEY])
+               nla_memcpy (props->private_key, tbd[IFLA_WG_DEVICE_PRIVATE_KEY], sizeof (props->private_key));
+       else
+               memset (props->private_key, 0, sizeof (props->private_key));
+
+       if (tbd[IFLA_WG_DEVICE_PUBLIC_KEY])
+               nla_memcpy (props->public_key, tbd[IFLA_WG_DEVICE_PUBLIC_KEY], sizeof (props->public_key));
+       else
+               memset (props->public_key, 0, sizeof (props->public_key));
+
+       c_list_init (&props->peers_lst_head);
+       if (tbd[IFLA_WG_DEVICE_PEERS]) {
+               struct nlattr *peer_attr;
+               int remaining_peers;
+               nla_for_each_nested (peer_attr, tbd[IFLA_WG_DEVICE_PEERS], remaining_peers) {
+                       ret = _wireguard_parse_peer (peer_attr, &props->peers_lst_head);
+                       if (ret)
+                               goto errout;
+               }
+       }
+
+       return NL_STOP;
+errout:
+       return NL_SKIP;
+}
+
+static NMPObject *
+_parse_lnk_wireguard (const char *kind, const char *ifname)
+{
+       nm_auto_nmpobj NMPObject *obj = NULL;
+       NMPObject *obj_result = NULL;
+       struct nl_sock *sock;
+       nm_auto_nlmsg struct nl_msg *msg = NULL;
+       struct nl_cb cb = {
+               .valid_cb = _wireguard_parse_getdevice,
+       };
+       static int family_id;
+
+       if (!nm_streq0 (kind, "wireguard"))
+               goto err;
+
+       sock = nl_socket_alloc ();
+       if (!sock)
+               goto err;
+
+       if (nl_connect (sock, NETLINK_GENERIC))
+               goto err_socket;
+
+       if (!family_id)
+               family_id = genl_ctrl_resolve (sock, "wireguard");
+       if (family_id <= 0)
+               goto err_socket;
+
+       msg = nlmsg_alloc ();
+
+       if (!genlmsg_put (msg, NL_AUTO_PORT, NL_AUTO_SEQ, family_id,
+                         0, NLM_F_DUMP, WG_CMD_GET_DEVICE, 1))
+               goto err_socket;
+
+       if (nla_put_string (msg, IFLA_WG_DEVICE_IFNAME, ifname) < 0)
+               goto err_socket;
+
+       if (nl_send_auto (sock, msg) < 0)
+               goto err_socket;
+
+       obj = nmp_object_new (NMP_OBJECT_TYPE_LNK_WIREGUARD, NULL);
+       cb.valid_arg = &obj;
+
+       if (nl_recvmsgs (sock, &cb) < 0)
+               goto err_socket;
+
+       obj_result = obj;
+       obj = NULL;
+
+err_socket:
+       nl_socket_free (sock);
+err:
+       return obj_result;
+}
+
+/*****************************************************************************/
+
 static gboolean
 _vlan_qos_mapping_from_nla (struct nlattr *nlattr,
                             const NMVlanQosMapping **out_map,
@@ -1814,6 +2061,9 @@ _new_from_nl_link (NMPlatform *platform, const NMPCache *cache, struct nlmsghdr
        case NM_LINK_TYPE_VXLAN:
                lnk_data = _parse_lnk_vxlan (nl_info_kind, nl_info_data);
                break;
+       case NM_LINK_TYPE_WIREGUARD:
+               lnk_data = _parse_lnk_wireguard (nl_info_kind, obj->link.name);
+               break;
        default:
                lnk_data_complete_from_cache = FALSE;
                break;
diff --git a/src/platform/nm-platform.c b/src/platform/nm-platform.c
index 7e2f27ced..2d631c7ca 100644
--- a/src/platform/nm-platform.c
+++ b/src/platform/nm-platform.c
@@ -27,6 +27,8 @@
 #include <unistd.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
+#include <sys/socket.h>
+#include <netdb.h>
 #include <string.h>
 #include <linux/ip.h>
 #include <linux/if_tun.h>
@@ -1906,6 +1908,12 @@ nm_platform_link_get_lnk_vxlan (NMPlatform *self, int ifindex, const NMPlatformL
        return _link_get_lnk (self, ifindex, NM_LINK_TYPE_VXLAN, out_link);
 }
 
+const NMPlatformLnkWireguard *
+nm_platform_link_get_lnk_wireguard (NMPlatform *self, int ifindex, const NMPlatformLink **out_link)
+{
+       return _link_get_lnk (self, ifindex, NM_LINK_TYPE_WIREGUARD, out_link);
+}
+
 /*****************************************************************************/
 
 /**
@@ -4994,6 +5002,95 @@ nm_platform_lnk_sit_to_string (const NMPlatformLnkSit *lnk, char *buf, gsize len
        return buf;
 }
 
+const char *
+nm_platform_lnk_wireguard_to_string (const NMPlatformLnkWireguard *lnk, char *buf, gsize len)
+{
+       gchar *public_b64;
+       if (!nm_utils_to_string_buffer_init_null (lnk, &buf, &len))
+               return buf;
+
+       public_b64 = g_base64_encode (lnk->public_key, sizeof (lnk->public_key));
+
+       g_snprintf (buf, len,
+                   "wireguard "
+                   "public_key %s "
+                   "private_key (hidden) "
+                   "listen_port %u "
+                   "fwmark 0x%x",
+                   public_b64,
+                   lnk->listen_port,
+                   lnk->fwmark);
+
+       g_free (public_b64);
+
+       return buf;
+}
+
+const char *
+nm_platform_wireguard_peer_to_string (const NMPlatformWireguardPeer *peer, char *buf, gsize len)
+{
+       gchar *public_b64;
+       char s_endpoint[NI_MAXHOST + NI_MAXSERV + sizeof("endpoint []:") + 1];
+
+       if (!nm_utils_to_string_buffer_init_null (peer, &buf, &len))
+               return buf;
+
+       if (peer->endpoint.addr.sa_family == AF_INET || peer->endpoint.addr.sa_family == AF_INET6) {
+               char host[NI_MAXHOST];
+               char service[NI_MAXSERV];
+               socklen_t addr_len = 0;
+
+               if (peer->endpoint.addr.sa_family == AF_INET)
+                       addr_len = sizeof (struct sockaddr_in);
+               else if (peer->endpoint.addr.sa_family == AF_INET6)
+                       addr_len = sizeof (struct sockaddr_in6);
+               if (!getnameinfo (&peer->endpoint.addr, addr_len, host, sizeof(host), service, 
sizeof(service), NI_DGRAM | NI_NUMERICSERV | NI_NUMERICHOST)) {
+                       if (peer->endpoint.addr.sa_family == AF_INET6 && strchr (host, ':'))
+                               g_snprintf(s_endpoint, sizeof (s_endpoint), "endpoint [%s]:%s ", host, 
service);
+                       else
+                               g_snprintf(s_endpoint, sizeof (s_endpoint), "endpoint %s:%s ", host, service);
+               }
+       } else {
+               s_endpoint[0] = '\0';
+       }
+
+       public_b64 = g_base64_encode (peer->public_key, sizeof (peer->public_key));
+
+       g_snprintf (buf, len,
+                   "wgpeer "
+                   "public_key %s "
+                   "preshared_key (hidden) "
+                   "%s" /* endpoint */
+                   "rx %"G_GUINT64_FORMAT" "
+                   "tx %"G_GUINT64_FORMAT"",
+                   public_b64,
+                   s_endpoint,
+                   peer->rx_bytes,
+                   peer->tx_bytes);
+
+       g_free (public_b64);
+
+       return buf;
+}
+
+const char *
+nm_platform_wireguard_allowedip_to_string (const NMPlatformWireguardAllowedIP *allowedip, char *buf, gsize 
len)
+{
+       char s_address[INET_ADDRSTRLEN];
+
+       if (!nm_utils_to_string_buffer_init_null (allowedip, &buf, &len))
+               return buf;
+
+       inet_ntop (allowedip->family, &allowedip->ip, s_address, sizeof(s_address));
+
+       g_snprintf (buf, len,
+                   "wgallowedip %s/%u",
+                   s_address,
+                   allowedip->cidr);
+
+       return buf;
+}
+
 const char *
 nm_platform_lnk_vlan_to_string (const NMPlatformLnkVlan *lnk, char *buf, gsize len)
 {
diff --git a/src/platform/nm-platform.h b/src/platform/nm-platform.h
index 53b2975bf..a8cf7bfd4 100644
--- a/src/platform/nm-platform.h
+++ b/src/platform/nm-platform.h
@@ -30,6 +30,7 @@
 #include "nm-dbus-interface.h"
 #include "nm-core-types-internal.h"
 
+#include "nm-utils/c-list.h"
 #include "nm-core-utils.h"
 #include "nm-setting-vlan.h"
 #include "nm-setting-wired.h"
@@ -80,6 +81,9 @@ typedef gboolean (*NMPObjectPredicateFunc) (const NMPObject *obj,
 /* Redefine this in host's endianness */
 #define NM_GRE_KEY      0x2000
 
+#define NM_WG_PUBLIC_KEY_LEN    32
+#define NM_WG_SYMMETRIC_KEY_LEN 32
+
 typedef enum {
        /* use our own platform enum for the nlmsg-flags. Otherwise, we'd have
         * to include <linux/netlink.h> */
@@ -682,6 +686,42 @@ typedef struct {
        bool l3miss:1;
 } NMPlatformLnkVxlan;
 
+typedef struct {
+       guint16 family;
+       union {
+               struct in_addr ip4;
+               struct in6_addr ip6;
+       } ip;
+       guint8 cidr;
+
+       CList allowedips_lst;
+} NMPlatformWireguardAllowedIP;
+
+typedef struct {
+       guint8 public_key[NM_WG_PUBLIC_KEY_LEN];
+       guint8 preshared_key[NM_WG_SYMMETRIC_KEY_LEN];
+       union {
+               struct sockaddr addr;
+               struct sockaddr_in addr4;
+               struct sockaddr_in6 addr6;
+       } endpoint;
+       struct timespec last_handshake_time;
+       guint64 rx_bytes, tx_bytes;
+       guint16 persistent_keepalive_interval;
+
+       CList peers_lst;
+       CList allowedips_lst_head;
+} NMPlatformWireguardPeer;
+
+typedef struct {
+       guint8 private_key[NM_WG_PUBLIC_KEY_LEN];
+       guint8 public_key[NM_WG_PUBLIC_KEY_LEN];
+       guint16 listen_port;
+       guint32 fwmark;
+
+       CList peers_lst_head;
+} NMPlatformLnkWireguard;
+
 typedef struct {
        gint64 owner;
        gint64 group;
@@ -1161,6 +1201,7 @@ const NMPlatformLnkMacvtap *nm_platform_link_get_lnk_macvtap (NMPlatform *self,
 const NMPlatformLnkSit *nm_platform_link_get_lnk_sit (NMPlatform *self, int ifindex, const NMPlatformLink 
**out_link);
 const NMPlatformLnkVlan *nm_platform_link_get_lnk_vlan (NMPlatform *self, int ifindex, const NMPlatformLink 
**out_link);
 const NMPlatformLnkVxlan *nm_platform_link_get_lnk_vxlan (NMPlatform *self, int ifindex, const 
NMPlatformLink **out_link);
+const NMPlatformLnkWireguard *nm_platform_link_get_lnk_wireguard (NMPlatform *self, int ifindex, const 
NMPlatformLink **out_link);
 
 NMPlatformError nm_platform_link_vlan_add (NMPlatform *self,
                                            const char *name,
@@ -1339,6 +1380,9 @@ const char *nm_platform_lnk_macvlan_to_string (const NMPlatformLnkMacvlan *lnk,
 const char *nm_platform_lnk_sit_to_string (const NMPlatformLnkSit *lnk, char *buf, gsize len);
 const char *nm_platform_lnk_vlan_to_string (const NMPlatformLnkVlan *lnk, char *buf, gsize len);
 const char *nm_platform_lnk_vxlan_to_string (const NMPlatformLnkVxlan *lnk, char *buf, gsize len);
+const char *nm_platform_lnk_wireguard_to_string (const NMPlatformLnkWireguard *lnk, char *buf, gsize len);
+const char *nm_platform_wireguard_peer_to_string (const NMPlatformWireguardPeer *peer, char *buf, gsize len);
+const char *nm_platform_wireguard_allowedip_to_string (const NMPlatformWireguardAllowedIP *peer, char *buf, 
gsize len);
 const char *nm_platform_ip4_address_to_string (const NMPlatformIP4Address *address, char *buf, gsize len);
 const char *nm_platform_ip6_address_to_string (const NMPlatformIP6Address *address, char *buf, gsize len);
 const char *nm_platform_ip4_route_to_string (const NMPlatformIP4Route *route, char *buf, gsize len);
diff --git a/src/platform/nmp-object.c b/src/platform/nmp-object.c
index 4df64e608..06883c57b 100644
--- a/src/platform/nmp-object.c
+++ b/src/platform/nmp-object.c
@@ -2807,5 +2807,30 @@ const NMPClass _nmp_classes[NMP_OBJECT_TYPE_MAX] = {
                .cmd_plobj_hash_update              = (void (*) (const NMPlatformObject *obj, NMHashState 
*h)) nm_platform_lnk_vxlan_hash_update,
                .cmd_plobj_cmp                      = (int (*) (const NMPlatformObject *obj1, const 
NMPlatformObject *obj2)) nm_platform_lnk_vxlan_cmp,
        },
+       [NMP_OBJECT_TYPE_LNK_WIREGUARD - 1] = {
+               .parent                             = DEDUP_MULTI_OBJ_CLASS_INIT(),
+               .obj_type                           = NMP_OBJECT_TYPE_LNK_WIREGUARD,
+               .sizeof_data                        = sizeof (NMPObjectLnkWireguard),
+               .sizeof_public                      = sizeof (NMPlatformLnkWireguard),
+               .obj_type_name                      = "wireguard",
+               .lnk_link_type                      = NM_LINK_TYPE_WIREGUARD,
+               .cmd_plobj_to_string                = (const char *(*) (const NMPlatformObject *obj, char 
*buf, gsize len)) nm_platform_lnk_wireguard_to_string,
+       },
+       [NMP_OBJECT_TYPE_WIREGUARD_PEER - 1] = {
+               .parent                             = DEDUP_MULTI_OBJ_CLASS_INIT(),
+               .obj_type                           = NMP_OBJECT_TYPE_WIREGUARD_PEER,
+               .sizeof_data                        = sizeof (NMPObjectWireguardPeer),
+               .sizeof_public                      = sizeof (NMPlatformWireguardPeer),
+               .obj_type_name                      = "wireguard-peer",
+               .cmd_plobj_to_string                = (const char *(*) (const NMPlatformObject *obj, char 
*buf, gsize len)) nm_platform_wireguard_peer_to_string,
+       },
+       [NMP_OBJECT_TYPE_WIREGUARD_ALLOWEDIP - 1] = {
+               .parent                             = DEDUP_MULTI_OBJ_CLASS_INIT(),
+               .obj_type                           = NMP_OBJECT_TYPE_WIREGUARD_ALLOWEDIP,
+               .sizeof_data                        = sizeof (NMPObjectWireguardAllowedIP),
+               .sizeof_public                      = sizeof (NMPlatformWireguardAllowedIP),
+               .obj_type_name                      = "wireguard-allowedip",
+               .cmd_plobj_to_string                = (const char *(*) (const NMPlatformObject *obj, char 
*buf, gsize len)) nm_platform_wireguard_allowedip_to_string,
+       },
 };
 
diff --git a/src/platform/nmp-object.h b/src/platform/nmp-object.h
index 8c36e2e3d..afa504f9c 100644
--- a/src/platform/nmp-object.h
+++ b/src/platform/nmp-object.h
@@ -209,6 +209,18 @@ typedef struct {
        NMPlatformLnkVxlan _public;
 } NMPObjectLnkVxlan;
 
+typedef struct {
+       NMPlatformLnkWireguard _public;
+} NMPObjectLnkWireguard;
+
+typedef struct {
+       NMPlatformWireguardPeer _public;
+} NMPObjectWireguardPeer;
+
+typedef struct {
+       NMPlatformWireguardAllowedIP _public;
+} NMPObjectWireguardAllowedIP;
+
 typedef struct {
        NMPlatformIP4Address _public;
 } NMPObjectIP4Address;
@@ -271,6 +283,15 @@ struct _NMPObject {
                NMPlatformLnkVxlan      lnk_vxlan;
                NMPObjectLnkVxlan       _lnk_vxlan;
 
+               NMPlatformLnkWireguard  lnk_wireguard;
+               NMPObjectLnkWireguard   _lnk_wireguard;
+
+               NMPlatformWireguardPeer wireguard_peer;
+               NMPObjectWireguardPeer  _wireguard_peer;
+
+               NMPlatformWireguardAllowedIP wireguard_allowedip;
+               NMPObjectWireguardAllowedIP  _wireguard_allowedip;
+
                NMPlatformIPAddress     ip_address;
                NMPlatformIPXAddress    ipx_address;
                NMPlatformIP4Address    ip4_address;
-- 
2.16.2



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]