Commit 89d40d65 authored by Thomas Haller's avatar Thomas Haller

wireguard: add "mtu" setting for WireGuard profiles

This adds new API for 1.16.0 and is an ABI break since 1.16-rc1.

(cherry picked from commit d5e93ae6)
parent 80683101
......@@ -7536,6 +7536,9 @@ static const NMMetaPropertyInfo *const property_infos_WIREGUARD[] = {
.base = 16,
),
),
PROPERTY_INFO_WITH_DESC (NM_SETTING_WIREGUARD_MTU,
.property_type = &_pt_gobject_mtu,
),
NULL
};
......
......@@ -364,6 +364,7 @@
#define DESCRIBE_DOC_NM_SETTING_WIMAX_NETWORK_NAME N_("Network Service Provider (NSP) name of the WiMAX network this connection should use. Deprecated: 1")
#define DESCRIBE_DOC_NM_SETTING_WIREGUARD_FWMARK N_("The use of fwmark is optional and is by default off. Setting it to 0 disables it. Otherwise it is a 32-bit fwmark for outgoing packets.")
#define DESCRIBE_DOC_NM_SETTING_WIREGUARD_LISTEN_PORT N_("The listen-port. If listen-port is not specified, the port will be chosen randomly when the interface comes up.")
#define DESCRIBE_DOC_NM_SETTING_WIREGUARD_MTU N_("If non-zero, only transmit packets of the specified size or smaller, breaking larger packets up into multiple fragments. If zero a default MTU is used. Note that contrary to wg-quick's MTU setting, this does not take into account the current routes at the time of activation.")
#define DESCRIBE_DOC_NM_SETTING_WIREGUARD_PRIVATE_KEY N_("The 256 bit private-key in base64 encoding.")
#define DESCRIBE_DOC_NM_SETTING_WIREGUARD_PRIVATE_KEY_FLAGS N_("Flags indicating how to handle the \"private-key\" property.")
#define DESCRIBE_DOC_NM_SETTING_WPAN_CHANNEL N_("IEEE 802.15.4 channel. A positive integer or -1, meaning \"do not set, use whatever the device is already set to\".")
......
......@@ -850,10 +850,11 @@ typedef struct {
/*****************************************************************************/
NM_GOBJECT_PROPERTIES_DEFINE_BASE (
PROP_FWMARK,
PROP_LISTEN_PORT,
PROP_MTU,
PROP_PRIVATE_KEY,
PROP_PRIVATE_KEY_FLAGS,
PROP_LISTEN_PORT,
PROP_FWMARK,
);
typedef struct {
......@@ -862,6 +863,7 @@ typedef struct {
GHashTable *peers_hash;
NMSettingSecretFlags private_key_flags;
guint32 fwmark;
guint32 mtu;
guint16 listen_port;
bool private_key_valid:1;
} NMSettingWireGuardPrivate;
......@@ -978,6 +980,22 @@ nm_setting_wireguard_get_listen_port (NMSettingWireGuard *self)
return NM_SETTING_WIREGUARD_GET_PRIVATE (self)->listen_port;
}
/**
* nm_setting_wireguard_get_mtu:
* @self: the #NMSettingWireGuard instance
*
* Returns: the MTU of the setting.
*
* Since: 1.16
*/
guint32
nm_setting_wireguard_get_mtu (NMSettingWireGuard *self)
{
g_return_val_if_fail (NM_IS_SETTING_WIREGUARD (self), 0);
return NM_SETTING_WIREGUARD_GET_PRIVATE (self)->mtu;
}
/*****************************************************************************/
static void
......@@ -2160,18 +2178,21 @@ get_property (GObject *object, guint prop_id,
NMSettingWireGuardPrivate *priv = NM_SETTING_WIREGUARD_GET_PRIVATE (setting);
switch (prop_id) {
case PROP_FWMARK:
g_value_set_uint (value, priv->fwmark);
break;
case PROP_LISTEN_PORT:
g_value_set_uint (value, priv->listen_port);
break;
case PROP_MTU:
g_value_set_uint (value, priv->mtu);
break;
case PROP_PRIVATE_KEY:
g_value_set_string (value, priv->private_key);
break;
case PROP_PRIVATE_KEY_FLAGS:
g_value_set_flags (value, priv->private_key_flags);
break;
case PROP_LISTEN_PORT:
g_value_set_uint (value, priv->listen_port);
break;
case PROP_FWMARK:
g_value_set_uint (value, priv->fwmark);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
......@@ -2186,6 +2207,15 @@ set_property (GObject *object, guint prop_id,
const char *str;
switch (prop_id) {
case PROP_FWMARK:
priv->fwmark = g_value_get_uint (value);
break;
case PROP_LISTEN_PORT:
priv->listen_port = g_value_get_uint (value);
break;
case PROP_MTU:
priv->mtu = g_value_get_uint (value);
break;
case PROP_PRIVATE_KEY:
nm_clear_pointer (&priv->private_key, nm_free_secret);
str = g_value_get_string (value);
......@@ -2203,12 +2233,6 @@ set_property (GObject *object, guint prop_id,
case PROP_PRIVATE_KEY_FLAGS:
priv->private_key_flags = g_value_get_flags (value);
break;
case PROP_LISTEN_PORT:
priv->listen_port = g_value_get_uint (value);
break;
case PROP_FWMARK:
priv->fwmark = g_value_get_uint (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
......@@ -2338,6 +2362,25 @@ nm_setting_wireguard_class_init (NMSettingWireGuardClass *klass)
| NM_SETTING_PARAM_INFERRABLE
| G_PARAM_STATIC_STRINGS);
/**
* NMSettingWireGuard:mtu:
*
* If non-zero, only transmit packets of the specified size or smaller,
* breaking larger packets up into multiple fragments.
*
* If zero a default MTU is used. Note that contrary to wg-quick's MTU
* setting, this does not take into account the current routes at the
* time of activation.
*
* Since: 1.16
**/
obj_properties[PROP_MTU] =
g_param_spec_uint (NM_SETTING_WIREGUARD_MTU, "", "",
0, G_MAXUINT32, 0,
G_PARAM_READWRITE
| NM_SETTING_PARAM_INFERRABLE
| G_PARAM_STATIC_STRINGS);
/* ---dbus---
* property: peers
* format: array of 'a{sv}'
......
......@@ -126,19 +126,21 @@ int nm_wireguard_peer_cmp (const NMWireGuardPeer *a,
#define NM_SETTING_WIREGUARD_SETTING_NAME "wireguard"
#define NM_SETTING_WIREGUARD_FWMARK "fwmark"
#define NM_SETTING_WIREGUARD_LISTEN_PORT "listen-port"
#define NM_SETTING_WIREGUARD_PRIVATE_KEY "private-key"
#define NM_SETTING_WIREGUARD_PRIVATE_KEY_FLAGS "private-key-flags"
#define NM_SETTING_WIREGUARD_LISTEN_PORT "listen-port"
#define NM_SETTING_WIREGUARD_FWMARK "fwmark"
#define NM_SETTING_WIREGUARD_PEERS "peers"
#define NM_WIREGUARD_PEER_ATTR_PUBLIC_KEY "public-key"
#define NM_SETTING_WIREGUARD_MTU "mtu"
#define NM_WIREGUARD_PEER_ATTR_ALLOWED_IPS "allowed-ips"
#define NM_WIREGUARD_PEER_ATTR_ENDPOINT "endpoint"
#define NM_WIREGUARD_PEER_ATTR_PERSISTENT_KEEPALIVE "persistent-keepalive"
#define NM_WIREGUARD_PEER_ATTR_PRESHARED_KEY "preshared-key"
#define NM_WIREGUARD_PEER_ATTR_PRESHARED_KEY_FLAGS "preshared-key-flags"
#define NM_WIREGUARD_PEER_ATTR_ALLOWED_IPS "allowed-ips"
#define NM_WIREGUARD_PEER_ATTR_PERSISTENT_KEEPALIVE "persistent-keepalive"
#define NM_WIREGUARD_PEER_ATTR_PUBLIC_KEY "public-key"
/*****************************************************************************/
......@@ -194,6 +196,9 @@ gboolean nm_setting_wireguard_remove_peer (NMSettingWireGuard *self,
NM_AVAILABLE_IN_1_16
guint nm_setting_wireguard_clear_peers (NMSettingWireGuard *self);
NM_AVAILABLE_IN_1_16
guint32 nm_setting_wireguard_get_mtu (NMSettingWireGuard *self);
/*****************************************************************************/
G_END_DECLS
......
......@@ -1466,6 +1466,7 @@ global:
nm_setting_wireguard_clear_peers;
nm_setting_wireguard_get_fwmark;
nm_setting_wireguard_get_listen_port;
nm_setting_wireguard_get_mtu;
nm_setting_wireguard_get_peer;
nm_setting_wireguard_get_peer_by_public_key;
nm_setting_wireguard_get_peers_len;
......
......@@ -827,6 +827,9 @@ ipv6.ip6-privacy=0
<varlistentry>
<term><varname>wifi.wake-on-wlan</varname></term>
</varlistentry>
<varlistentry>
<term><varname>wireguard.mtu</varname></term>
</varlistentry>
</variablelist>
<!-- The following comment is used by check-config-options.sh, don't remove it. -->
<!-- end connection defaults -->
......
......@@ -1247,6 +1247,34 @@ act_stage2_config (NMDevice *device,
return NM_ACT_STAGE_RETURN_FAILURE;
}
static guint32
get_configured_mtu (NMDevice *device, NMDeviceMtuSource *out_source)
{
/* When "MTU" for `wg-quick up` is unset, it calls `ip route get` for
* each configured endpoint, to determine the suitable MTU how to reach
* each endpoint.
* For `wg-quick` this works very well, because whenever the script runs it
* determines the best setting at that point in time. It's simply not concerned
* with what happens later (and it's not around anyway).
*
* NetworkManager sticks around, so the right MTU would need to be re-determined
* whenever anything relevant changes. Which basically means, to re-evaluate whenever
* something related to addresses or routing changes (which happens all the time).
*
* The correct MTU indeed depends on the MTU setting of other interfaces (or routes).
* But it's still odd, that activating/deactivating a seemingly unrelated interface
* would trigger an MTU change. It's odd to explain/document and odd to implemented
* -- despite this being the reality.
*
* For now, only support configuring an explicit MTU, or leave the setting untouched.
* The same limitiation also applies to other "ip-tunnel" types, where we could use
* similar smarts for autodetecting the MTU.
*/
return nm_device_get_configured_mtu_from_connection (device,
NM_TYPE_SETTING_WIREGUARD,
out_source);
}
static void
device_state_changed (NMDevice *device,
NMDeviceState new_state,
......@@ -1275,8 +1303,17 @@ can_reapply_change (NMDevice *device,
GError **error)
{
if (nm_streq (setting_name, NM_SETTING_WIREGUARD_SETTING_NAME)) {
/* we allow reapplying all WireGuard settings. */
return TRUE;
/* Most, but not all WireGuard settings can be reapplied. Whitelist.
*
* MTU cannot be reapplied. */
return nm_device_hash_check_invalid_keys (diffs,
NM_SETTING_WIREGUARD_SETTING_NAME,
error,
NM_SETTING_WIREGUARD_FWMARK,
NM_SETTING_WIREGUARD_LISTEN_PORT,
NM_SETTING_WIREGUARD_PEERS,
NM_SETTING_WIREGUARD_PRIVATE_KEY,
NM_SETTING_WIREGUARD_PRIVATE_KEY_FLAGS);
}
return NM_DEVICE_CLASS (nm_device_wireguard_parent_class)->can_reapply_change (device,
......@@ -1451,6 +1488,7 @@ nm_device_wireguard_class_init (NMDeviceWireGuardClass *klass)
device_class->update_connection = update_connection;
device_class->can_reapply_change = can_reapply_change;
device_class->reapply_connection = reapply_connection;
device_class->get_configured_mtu = get_configured_mtu;
obj_properties[PROP_PUBLIC_KEY] =
g_param_spec_variant (NM_DEVICE_WIREGUARD_PUBLIC_KEY,
......
......@@ -8871,6 +8871,10 @@ nm_device_get_configured_mtu_from_connection (NMDevice *self,
if (setting)
mtu = nm_setting_ip_tunnel_get_mtu (NM_SETTING_IP_TUNNEL (setting));
global_property_name = NM_CON_DEFAULT ("ip-tunnel.mtu");
} else if (setting_type == NM_TYPE_SETTING_WIREGUARD) {
if (setting)
mtu = nm_setting_wireguard_get_mtu (NM_SETTING_WIREGUARD (setting));
global_property_name = NM_CON_DEFAULT ("wireguard.mtu");
} else
g_return_val_if_reached (0);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment