diff --git a/Makefile.am b/Makefile.am
index e26801deeb..516e9acbf2 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -847,6 +847,7 @@ libnm_lib_h_pub_real = \
libnm/nm-device-vxlan.h \
libnm/nm-device-wifi.h \
libnm/nm-device-wimax.h \
+ libnm/nm-device-wireguard.h \
libnm/nm-device-wpan.h \
libnm/nm-device.h \
libnm/nm-dhcp-config.h \
@@ -905,6 +906,7 @@ libnm_lib_c_real = \
libnm/nm-device-vxlan.c \
libnm/nm-device-wifi.c \
libnm/nm-device-wimax.c \
+ libnm/nm-device-wireguard.c \
libnm/nm-device-wpan.c \
libnm/nm-device.c \
libnm/nm-dhcp-config.c \
diff --git a/docs/libnm/libnm-docs.xml b/docs/libnm/libnm-docs.xml
index bdb3c2daec..cba1661045 100644
--- a/docs/libnm/libnm-docs.xml
+++ b/docs/libnm/libnm-docs.xml
@@ -265,6 +265,7 @@ print ("NetworkManager version " + client.get_version())]]>
+
diff --git a/libnm/NetworkManager.h b/libnm/NetworkManager.h
index 9cecef3acb..070a02a9af 100644
--- a/libnm/NetworkManager.h
+++ b/libnm/NetworkManager.h
@@ -53,6 +53,7 @@
#include "nm-device-vxlan.h"
#include "nm-device-wifi.h"
#include "nm-device-wimax.h"
+#include "nm-device-wireguard.h"
#include "nm-device-wpan.h"
#include "nm-device.h"
#include "nm-dhcp-config.h"
diff --git a/libnm/libnm.ver b/libnm/libnm.ver
index 23d551e69e..ef9701754a 100644
--- a/libnm/libnm.ver
+++ b/libnm/libnm.ver
@@ -1386,6 +1386,10 @@ global:
nm_connection_get_setting_sriov;
nm_connection_get_setting_wpan;
nm_device_6lowpan_get_type;
+ nm_device_wireguard_get_fwmark;
+ nm_device_wireguard_get_listen_port;
+ nm_device_wireguard_get_public_key;
+ nm_device_wireguard_get_type;
nm_device_wpan_get_type;
nm_setting_6lowpan_get_type;
nm_setting_sriov_add_vf;
diff --git a/libnm/meson.build b/libnm/meson.build
index 27089004c7..62e3e9d755 100644
--- a/libnm/meson.build
+++ b/libnm/meson.build
@@ -57,6 +57,7 @@ libnm_headers = files(
'nm-device-vxlan.h',
'nm-device-wifi.h',
'nm-device-wimax.h',
+ 'nm-device-wireguard.h',
'nm-device-wpan.h',
'nm-dhcp-config.h',
'nm-ip-config.h',
@@ -120,6 +121,7 @@ libnm_sources = files(
'nm-device-vxlan.c',
'nm-device-wifi.c',
'nm-device-wimax.c',
+ 'nm-device-wireguard.c',
'nm-device-wpan.c',
'nm-dhcp-config.c',
'nm-dhcp4-config.c',
diff --git a/libnm/nm-client.c b/libnm/nm-client.c
index cdf8bf13f9..96db30c756 100644
--- a/libnm/nm-client.c
+++ b/libnm/nm-client.c
@@ -75,6 +75,7 @@
#include "nm-device-vxlan.h"
#include "nm-device-wifi.h"
#include "nm-device-wimax.h"
+#include "nm-device-wireguard.h"
#include "nm-device-wpan.h"
#include "nm-dhcp4-config.h"
#include "nm-dhcp6-config.h"
@@ -2575,6 +2576,8 @@ obj_nm_for_gdbus_object (NMClient *self, GDBusObject *object, GDBusObjectManager
type = NM_TYPE_DEVICE_WIFI;
else if (strcmp (ifname, NM_DBUS_INTERFACE_DEVICE_WIMAX) == 0)
type = NM_TYPE_DEVICE_WIMAX;
+ else if (strcmp (ifname, NM_DBUS_INTERFACE_DEVICE_WIREGUARD) == 0)
+ type = NM_TYPE_DEVICE_WIREGUARD;
else if (strcmp (ifname, NM_DBUS_INTERFACE_DHCP4_CONFIG) == 0)
type = NM_TYPE_DHCP4_CONFIG;
else if (strcmp (ifname, NM_DBUS_INTERFACE_DHCP6_CONFIG) == 0)
diff --git a/libnm/nm-device-wireguard.c b/libnm/nm-device-wireguard.c
new file mode 100644
index 0000000000..aaad71a440
--- /dev/null
+++ b/libnm/nm-device-wireguard.c
@@ -0,0 +1,209 @@
+/*
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ *
+ * Copyright 2018 Javier Arteaga
+ */
+
+#include "nm-default.h"
+
+#include "nm-device-wireguard.h"
+#include "nm-object-private.h"
+
+typedef struct {
+ GBytes *public_key;
+ guint listen_port;
+ guint fwmark;
+} NMDeviceWireGuardPrivate;
+
+/**
+ * NMDeviceWireGuard:
+ */
+struct _NMDeviceWireGuard {
+ NMDevice parent;
+};
+
+struct _NMDeviceWireGuardClass {
+ NMDeviceClass parent;
+};
+
+G_DEFINE_TYPE (NMDeviceWireGuard, nm_device_wireguard, NM_TYPE_DEVICE)
+
+#define NM_DEVICE_WIREGUARD_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE_WIREGUARD, NMDeviceWireGuardPrivate))
+
+NM_GOBJECT_PROPERTIES_DEFINE_BASE (
+ PROP_PUBLIC_KEY,
+ PROP_LISTEN_PORT,
+ PROP_FWMARK,
+);
+
+/**
+ * nm_device_wireguard_get_public_key:
+ * @device: a #NMDeviceWireGuard
+ *
+ * Gets the public key for this interface
+ *
+ * Returns: (transfer none): the #GBytes containing the 32-byte public key
+ *
+ * Since: 1.14
+ **/
+GBytes *
+nm_device_wireguard_get_public_key (NMDeviceWireGuard *device)
+{
+ g_return_val_if_fail (NM_IS_DEVICE_WIREGUARD (device), NULL);
+
+ return NM_DEVICE_WIREGUARD_GET_PRIVATE (device)->public_key;
+}
+
+/**
+ * nm_device_wireguard_get_listen_port:
+ * @device: a #NMDeviceWireGuard
+ *
+ * Gets the local UDP port this interface listens on
+ *
+ * Returns: UDP listen port
+ *
+ * Since: 1.14
+ **/
+guint16
+nm_device_wireguard_get_listen_port (NMDeviceWireGuard *device)
+{
+ g_return_val_if_fail (NM_IS_DEVICE_WIREGUARD (device), 0);
+
+ return NM_DEVICE_WIREGUARD_GET_PRIVATE (device)->listen_port;
+}
+
+/**
+ * nm_device_wireguard_get_fwmark:
+ * @device: a #NMDeviceWireGuard
+ *
+ * Gets the fwmark (firewall mark) for this interface.
+ * It can be used to set routing policy for outgoing encrypted packets.
+ * See: ip-rule(8)
+ *
+ * Returns: 0 if fwmark not in use, 32-bit fwmark value otherwise
+ *
+ * Since: 1.14
+ **/
+guint32
+nm_device_wireguard_get_fwmark (NMDeviceWireGuard *device)
+{
+ g_return_val_if_fail (NM_IS_DEVICE_WIREGUARD (device), 0);
+
+ return NM_DEVICE_WIREGUARD_GET_PRIVATE (device)->fwmark;
+}
+
+/***********************************************************/
+
+static void
+get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ NMDeviceWireGuard *device = NM_DEVICE_WIREGUARD (object);
+
+ switch (prop_id) {
+ case PROP_PUBLIC_KEY:
+ g_value_set_boxed (value, nm_device_wireguard_get_public_key (device));
+ break;
+ case PROP_LISTEN_PORT:
+ g_value_set_uint (value, nm_device_wireguard_get_listen_port (device));
+ break;
+ case PROP_FWMARK:
+ g_value_set_uint (value, nm_device_wireguard_get_fwmark (device));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+nm_device_wireguard_init (NMDeviceWireGuard *device)
+{
+}
+
+static void
+init_dbus (NMObject *object)
+{
+ NMDeviceWireGuardPrivate *priv = NM_DEVICE_WIREGUARD_GET_PRIVATE (object);
+ const NMPropertiesInfo property_info[] = {
+ { NM_DEVICE_WIREGUARD_PUBLIC_KEY, &priv->public_key },
+ { NM_DEVICE_WIREGUARD_LISTEN_PORT, &priv->listen_port },
+ { NM_DEVICE_WIREGUARD_FWMARK, &priv->fwmark },
+ { NULL }
+ };
+
+ NM_OBJECT_CLASS (nm_device_wireguard_parent_class)->init_dbus (object);
+
+ _nm_object_register_properties (object,
+ NM_DBUS_INTERFACE_DEVICE_WIREGUARD,
+ property_info);
+}
+
+static void
+nm_device_wireguard_class_init (NMDeviceWireGuardClass *wireguard_class)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (wireguard_class);
+ NMObjectClass *nm_object_class = NM_OBJECT_CLASS (wireguard_class);
+
+ g_type_class_add_private (wireguard_class, sizeof (NMDeviceWireGuardPrivate));
+
+ object_class->get_property = get_property;
+
+ nm_object_class->init_dbus = init_dbus;
+
+ /**
+ * NMDeviceWireGuard:public-key:
+ *
+ * 32-byte public key, derived from the current private key.
+ *
+ * Since: 1.14
+ **/
+ obj_properties[PROP_PUBLIC_KEY] =
+ g_param_spec_boxed (NM_DEVICE_WIREGUARD_PUBLIC_KEY, "", "",
+ G_TYPE_BYTES,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+
+ /**
+ * NMDeviceWireGuard:listen-port:
+ *
+ * Local UDP listen port.
+ * Set to 0 to allow a random port to be chosen (default).
+ *
+ * Since: 1.14
+ **/
+ obj_properties[PROP_LISTEN_PORT] =
+ g_param_spec_uint (NM_DEVICE_WIREGUARD_LISTEN_PORT, "", "",
+ 0, G_MAXUINT16, 0,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+
+ /**
+ * NMDeviceWireGuard:fwmark:
+ *
+ * Optional firewall mark - see ip-rule(8).
+ * Used when setting routing policy for outgoing encrypted packets.
+ * Set to 0 to disable the mark (default).
+ *
+ * Since: 1.14
+ **/
+ obj_properties[PROP_FWMARK] =
+ g_param_spec_uint (NM_DEVICE_WIREGUARD_FWMARK, "", "",
+ 0, G_MAXUINT32, 0,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+
+ g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties);
+}
diff --git a/libnm/nm-device-wireguard.h b/libnm/nm-device-wireguard.h
new file mode 100644
index 0000000000..37e97a0aa2
--- /dev/null
+++ b/libnm/nm-device-wireguard.h
@@ -0,0 +1,56 @@
+/*
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ *
+ * Copyright 2018 Javier Arteaga
+ */
+
+#ifndef __NM_DEVICE_WIREGUARD_H__
+#define __NM_DEVICE_WIREGUARD_H__
+
+#if !defined (__NETWORKMANAGER_H_INSIDE__) && !defined(NETWORKMANAGER_COMPILATION)
+#error "Only can be included directly."
+#endif
+
+#include "nm-device.h"
+
+G_BEGIN_DECLS
+
+#define NM_TYPE_DEVICE_WIREGUARD (nm_device_wireguard_get_type ())
+#define NM_DEVICE_WIREGUARD(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE_WIREGUARD, NMDeviceWireGuard))
+#define NM_DEVICE_WIREGUARD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DEVICE_WIREGUARD, NMDeviceWireGuardClass))
+#define NM_IS_DEVICE_WIREGUARD(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DEVICE_WIREGUARD))
+#define NM_IS_DEVICE_WIREGUARD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE_WIREGUARD))
+#define NM_DEVICE_WIREGUARD_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_WIREGUARD, NMDeviceWireGuardClass))
+
+typedef struct _NMDeviceWireGuardClass NMDeviceWireGuardClass;
+
+#define NM_DEVICE_WIREGUARD_PUBLIC_KEY "public-key"
+#define NM_DEVICE_WIREGUARD_LISTEN_PORT "listen-port"
+#define NM_DEVICE_WIREGUARD_FWMARK "fwmark"
+
+NM_AVAILABLE_IN_1_14
+GType nm_device_wireguard_get_type (void);
+
+NM_AVAILABLE_IN_1_14
+GBytes* nm_device_wireguard_get_public_key (NMDeviceWireGuard *device);
+NM_AVAILABLE_IN_1_14
+guint16 nm_device_wireguard_get_listen_port (NMDeviceWireGuard *device);
+NM_AVAILABLE_IN_1_14
+guint32 nm_device_wireguard_get_fwmark (NMDeviceWireGuard *device);
+
+G_END_DECLS
+
+#endif /* __NM_DEVICE_WIREGUARD_H__ */
diff --git a/libnm/nm-types.h b/libnm/nm-types.h
index d759b890ae..bb77e642df 100644
--- a/libnm/nm-types.h
+++ b/libnm/nm-types.h
@@ -55,6 +55,7 @@ typedef struct _NMDeviceVlan NMDeviceVlan;
typedef struct _NMDeviceVxlan NMDeviceVxlan;
typedef struct _NMDeviceWifi NMDeviceWifi;
typedef struct _NMDeviceWimax NMDeviceWimax;
+typedef struct _NMDeviceWireGuard NMDeviceWireGuard;
typedef struct _NMDeviceWpan NMDeviceWpan;
typedef struct _NMDhcpConfig NMDhcpConfig;
typedef struct _NMIPConfig NMIPConfig;