diff --git a/clients/cli/connections.c b/clients/cli/connections.c index ca249a9976..9ab926a021 100644 --- a/clients/cli/connections.c +++ b/clients/cli/connections.c @@ -2820,6 +2820,7 @@ static const NameItem nmc_bridge_slave_settings [] = { static const NameItem nmc_tun_settings [] = { { NM_SETTING_CONNECTION_SETTING_NAME, NULL, NULL, TRUE }, { NM_SETTING_TUN_SETTING_NAME, NULL, NULL, TRUE }, + { NM_SETTING_WIRED_SETTING_NAME, "ethernet", NULL, FALSE }, { NM_SETTING_IP4_CONFIG_SETTING_NAME, NULL, NULL, FALSE }, { NM_SETTING_IP6_CONFIG_SETTING_NAME, NULL, NULL, FALSE }, { NULL, NULL, NULL, FALSE } @@ -2845,6 +2846,7 @@ static const NameItem nmc_macvlan_settings [] = { static const NameItem nmc_vxlan_settings [] = { { NM_SETTING_CONNECTION_SETTING_NAME, NULL, NULL, TRUE }, { NM_SETTING_VXLAN_SETTING_NAME, NULL, NULL, TRUE }, + { NM_SETTING_WIRED_SETTING_NAME, "ethernet", NULL, FALSE }, { NM_SETTING_IP4_CONFIG_SETTING_NAME, NULL, NULL, FALSE }, { NM_SETTING_IP6_CONFIG_SETTING_NAME, NULL, NULL, FALSE }, { NULL, NULL, NULL, FALSE } diff --git a/clients/cli/settings.c b/clients/cli/settings.c index c899d8fb33..9f95dfe268 100644 --- a/clients/cli/settings.c +++ b/clients/cli/settings.c @@ -732,6 +732,7 @@ NmcOutputField nmc_fields_setting_ip_tunnel[] = { SETTING_FIELD (NM_SETTING_IP_TUNNEL_OUTPUT_KEY), /* 9 */ SETTING_FIELD (NM_SETTING_IP_TUNNEL_ENCAPSULATION_LIMIT), /* 10 */ SETTING_FIELD (NM_SETTING_IP_TUNNEL_FLOW_LABEL), /* 11 */ + SETTING_FIELD (NM_SETTING_IP_TUNNEL_MTU), /* 12 */ {NULL, NULL, 0, NULL, FALSE, FALSE, 0} }; #define NMC_FIELDS_SETTING_IP_TUNNEL_ALL "name"","\ @@ -745,7 +746,8 @@ NmcOutputField nmc_fields_setting_ip_tunnel[] = { NM_SETTING_IP_TUNNEL_INPUT_KEY","\ NM_SETTING_IP_TUNNEL_OUTPUT_KEY","\ NM_SETTING_IP_TUNNEL_ENCAPSULATION_LIMIT","\ - NM_SETTING_IP_TUNNEL_FLOW_LABEL + NM_SETTING_IP_TUNNEL_FLOW_LABEL","\ + NM_SETTING_IP_TUNNEL_MTU #define NMC_FIELDS_SETTING_IP_TUNNEL_COMMON NMC_FIELDS_SETTING_IP_TUNNEL_ALL /* Available fields for NM_SETTING_MACVLAN_SETTING_NAME */ @@ -1407,6 +1409,7 @@ DEFINE_GETTER (nmc_property_ip_tunnel_get_input_key, NM_SETTING_IP_TUNNEL_INPUT_ DEFINE_GETTER (nmc_property_ip_tunnel_get_output_key, NM_SETTING_IP_TUNNEL_OUTPUT_KEY); DEFINE_GETTER (nmc_property_ip_tunnel_get_encapsulation_limit, NM_SETTING_IP_TUNNEL_ENCAPSULATION_LIMIT); DEFINE_GETTER (nmc_property_ip_tunnel_get_flow_label, NM_SETTING_IP_TUNNEL_FLOW_LABEL); +DEFINE_GETTER (nmc_property_ip_tunnel_get_mtu, NM_SETTING_IP_TUNNEL_MTU); static const char ** nmc_property_ip_tunnel_allowed_mode (NMSetting *setting, const char *prop) @@ -7385,6 +7388,13 @@ nmc_properties_init (void) NULL, NULL, NULL); + nmc_add_prop_funcs (GLUE (IP_TUNNEL, MTU), + nmc_property_ip_tunnel_get_mtu, + nmc_property_set_uint, + NULL, + NULL, + NULL, + NULL); /* Add editable properties for NM_SETTING_MACVLAN_SETTING_NAME */ nmc_add_prop_funcs (GLUE (MACVLAN, PARENT), @@ -8738,6 +8748,7 @@ setting_ip_tunnel_details (NMSetting *setting, NmCli *nmc, const char *one_prop set_val_str (arr, 9, nmc_property_ip_tunnel_get_output_key (setting, NMC_PROPERTY_GET_PRETTY)); set_val_str (arr, 10, nmc_property_ip_tunnel_get_encapsulation_limit (setting, NMC_PROPERTY_GET_PRETTY)); set_val_str (arr, 11, nmc_property_ip_tunnel_get_flow_label (setting, NMC_PROPERTY_GET_PRETTY)); + set_val_str (arr, 12, nmc_property_ip_tunnel_get_mtu (setting, NMC_PROPERTY_GET_PRETTY)); g_ptr_array_add (nmc->output_data, arr); print_data (nmc); /* Print all data */ diff --git a/libnm-core/nm-setting-ip-tunnel.c b/libnm-core/nm-setting-ip-tunnel.c index 672a49c599..cd63aa119b 100644 --- a/libnm-core/nm-setting-ip-tunnel.c +++ b/libnm-core/nm-setting-ip-tunnel.c @@ -49,6 +49,7 @@ typedef struct { char *output_key; guint encapsulation_limit; guint flow_label; + guint mtu; } NMSettingIPTunnelPrivate; enum { @@ -64,6 +65,7 @@ enum { PROP_OUTPUT_KEY, PROP_ENCAPSULATION_LIMIT, PROP_FLOW_LABEL, + PROP_MTU, LAST_PROP }; @@ -266,6 +268,24 @@ nm_setting_ip_tunnel_get_flow_label (NMSettingIPTunnel *setting) return NM_SETTING_IP_TUNNEL_GET_PRIVATE (setting)->flow_label; } +/** + * nm_setting_ip_tunnel_get_mtu: + * @setting: the #NMSettingIPTunnel + * + * Returns the #NMSettingIPTunnel:mtu property of the setting. + * + * Returns: the MTU + * + * Since: 1.2 + **/ +guint +nm_setting_ip_tunnel_get_mtu (NMSettingIPTunnel *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_IP_TUNNEL (setting), 0); + + return NM_SETTING_IP_TUNNEL_GET_PRIVATE (setting)->mtu; +} + /*********************************************************************/ static gboolean @@ -460,6 +480,9 @@ set_property (GObject *object, guint prop_id, case PROP_FLOW_LABEL: priv->flow_label = g_value_get_uint (value); break; + case PROP_MTU: + priv->mtu = g_value_get_uint (value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -507,6 +530,9 @@ get_property (GObject *object, guint prop_id, case PROP_FLOW_LABEL: g_value_set_uint (value, priv->flow_label); break; + case PROP_MTU: + g_value_set_uint (value, priv->mtu); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -721,4 +747,21 @@ nm_setting_ip_tunnel_class_init (NMSettingIPTunnelClass *setting_class) G_PARAM_CONSTRUCT | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS)); + + /** + * NMSettingIPTunel:mtu: + * + * If non-zero, only transmit packets of the specified size or smaller, + * breaking larger packets up into multiple fragments. + * + * Since: 1.2 + **/ + g_object_class_install_property + (object_class, PROP_MTU, + g_param_spec_uint (NM_SETTING_IP_TUNNEL_MTU, "", "", + 0, G_MAXUINT, 0, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + NM_SETTING_PARAM_FUZZY_IGNORE | + G_PARAM_STATIC_STRINGS)); } diff --git a/libnm-core/nm-setting-ip-tunnel.h b/libnm-core/nm-setting-ip-tunnel.h index a07bd50db0..09814f350c 100644 --- a/libnm-core/nm-setting-ip-tunnel.h +++ b/libnm-core/nm-setting-ip-tunnel.h @@ -49,6 +49,7 @@ G_BEGIN_DECLS #define NM_SETTING_IP_TUNNEL_OUTPUT_KEY "output-key" #define NM_SETTING_IP_TUNNEL_ENCAPSULATION_LIMIT "encapsulation-limit" #define NM_SETTING_IP_TUNNEL_FLOW_LABEL "flow-label" +#define NM_SETTING_IP_TUNNEL_MTU "mtu" struct _NMSettingIPTunnel { NMSetting parent; @@ -89,6 +90,8 @@ NM_AVAILABLE_IN_1_2 guint nm_setting_ip_tunnel_get_encapsulation_limit (NMSettingIPTunnel *setting); NM_AVAILABLE_IN_1_2 guint nm_setting_ip_tunnel_get_flow_label (NMSettingIPTunnel *setting); +NM_AVAILABLE_IN_1_2 +guint nm_setting_ip_tunnel_get_mtu (NMSettingIPTunnel *setting); G_END_DECLS diff --git a/libnm/libnm.ver b/libnm/libnm.ver index 8eca4962c5..4636e9acec 100644 --- a/libnm/libnm.ver +++ b/libnm/libnm.ver @@ -949,6 +949,7 @@ global: nm_setting_ip_tunnel_get_input_key; nm_setting_ip_tunnel_get_local; nm_setting_ip_tunnel_get_mode; + nm_setting_ip_tunnel_get_mtu; nm_setting_ip_tunnel_get_output_key; nm_setting_ip_tunnel_get_parent; nm_setting_ip_tunnel_get_path_mtu_discovery; diff --git a/src/devices/nm-device-ip-tunnel.c b/src/devices/nm-device-ip-tunnel.c index bcb6dbf247..2fa6bee19d 100644 --- a/src/devices/nm-device-ip-tunnel.c +++ b/src/devices/nm-device-ip-tunnel.c @@ -35,6 +35,7 @@ #include "nm-core-internal.h" #include "nm-connection-provider.h" #include "nm-activation-request.h" +#include "nm-ip4-config.h" #include "nmdbus-device-ip-tunnel.h" @@ -777,6 +778,24 @@ setup_start (NMDevice *device, const NMPlatformLink *plink) update_properties (device); } +static void +ip4_config_pre_commit (NMDevice *device, NMIP4Config *config) +{ + NMConnection *connection; + NMSettingIPTunnel *s_ip_tunnel; + guint32 mtu; + + connection = nm_device_get_applied_connection (device); + g_assert (connection); + s_ip_tunnel = nm_connection_get_setting_ip_tunnel (connection); + g_assert (s_ip_tunnel); + + /* MTU override */ + mtu = nm_setting_ip_tunnel_get_mtu (s_ip_tunnel); + if (mtu) + nm_ip4_config_set_mtu (config, mtu, NM_IP_CONFIG_SOURCE_USER); +} + static void unrealize (NMDevice *device, gboolean remove_resources) { @@ -865,6 +884,7 @@ nm_device_ip_tunnel_class_init (NMDeviceIPTunnelClass *klass) device_class->update_connection = update_connection; device_class->check_connection_compatible = check_connection_compatible; device_class->create_and_realize = create_and_realize; + device_class->ip4_config_pre_commit = ip4_config_pre_commit; device_class->realize = realize; device_class->setup_start = setup_start; device_class->unrealize = unrealize; diff --git a/src/devices/nm-device-tun.c b/src/devices/nm-device-tun.c index 3501ddb466..e1ec520363 100644 --- a/src/devices/nm-device-tun.c +++ b/src/devices/nm-device-tun.c @@ -25,8 +25,10 @@ #include #include "nm-default.h" +#include "nm-activation-request.h" #include "nm-device-tun.h" #include "nm-device-private.h" +#include "nm-ip4-config.h" #include "nm-platform.h" #include "nm-device-factory.h" #include "nm-setting-tun.h" @@ -285,6 +287,62 @@ check_connection_compatible (NMDevice *device, NMConnection *connection) return TRUE; } +static NMActStageReturn +act_stage1_prepare (NMDevice *device, NMDeviceStateReason *reason) +{ + NMDeviceTun *self = NM_DEVICE_TUN (device); + NMDeviceTunPrivate *priv = NM_DEVICE_TUN_GET_PRIVATE (self); + NMActRequest *req; + NMConnection *connection; + NMSettingWired *s_wired; + const char *cloned_mac; + NMActStageReturn ret; + + g_return_val_if_fail (reason != NULL, NM_ACT_STAGE_RETURN_FAILURE); + + ret = NM_DEVICE_CLASS (nm_device_tun_parent_class)->act_stage1_prepare (device, reason); + if (ret != NM_ACT_STAGE_RETURN_SUCCESS) + return ret; + + /* Nothing to do for TUN devices */ + if (g_strcmp0 (priv->mode, "tap")) + return NM_ACT_STAGE_RETURN_SUCCESS; + + req = nm_device_get_act_request (device); + g_return_val_if_fail (req != NULL, NM_ACT_STAGE_RETURN_FAILURE); + + connection = nm_act_request_get_applied_connection (req); + g_return_val_if_fail (connection != NULL, NM_ACT_STAGE_RETURN_FAILURE); + + s_wired = nm_connection_get_setting_wired (connection); + if (s_wired) { + /* Set device MAC address if the connection wants to change it */ + cloned_mac = nm_setting_wired_get_cloned_mac_address (s_wired); + if (cloned_mac) + nm_device_set_hw_addr (device, cloned_mac, "set", LOGD_DEVICE); + } + + return NM_ACT_STAGE_RETURN_SUCCESS; +} + +static void +ip4_config_pre_commit (NMDevice *device, NMIP4Config *config) +{ + NMConnection *connection; + NMSettingWired *s_wired; + guint32 mtu; + + connection = nm_device_get_applied_connection (device); + g_assert (connection); + + s_wired = nm_connection_get_setting_wired (connection); + if (s_wired) { + mtu = nm_setting_wired_get_mtu (s_wired); + if (mtu) + nm_ip4_config_set_mtu (config, mtu, NM_IP_CONFIG_SOURCE_USER); + } +} + static void unrealize (NMDevice *device, gboolean remove_resources) { @@ -392,6 +450,8 @@ nm_device_tun_class_init (NMDeviceTunClass *klass) device_class->setup_start = setup_start; device_class->unrealize = unrealize; device_class->update_connection = update_connection; + device_class->act_stage1_prepare = act_stage1_prepare; + device_class->ip4_config_pre_commit = ip4_config_pre_commit; /* properties */ g_object_class_install_property diff --git a/src/devices/nm-device-vxlan.c b/src/devices/nm-device-vxlan.c index 514554c4c4..a2dfa7d91a 100644 --- a/src/devices/nm-device-vxlan.c +++ b/src/devices/nm-device-vxlan.c @@ -30,8 +30,10 @@ #include "nm-utils.h" #include "nm-device-factory.h" #include "nm-setting-vxlan.h" +#include "nm-setting-wired.h" #include "nm-connection-provider.h" #include "nm-activation-request.h" +#include "nm-ip4-config.h" #include "nmdbus-device-vxlan.h" @@ -515,6 +517,56 @@ update_connection (NMDevice *device, NMConnection *connection) } } +static NMActStageReturn +act_stage1_prepare (NMDevice *device, NMDeviceStateReason *reason) +{ + NMActRequest *req; + NMConnection *connection; + NMSettingWired *s_wired; + const char *cloned_mac; + NMActStageReturn ret; + + g_return_val_if_fail (reason != NULL, NM_ACT_STAGE_RETURN_FAILURE); + + ret = NM_DEVICE_CLASS (nm_device_vxlan_parent_class)->act_stage1_prepare (device, reason); + if (ret != NM_ACT_STAGE_RETURN_SUCCESS) + return ret; + + req = nm_device_get_act_request (device); + g_return_val_if_fail (req != NULL, NM_ACT_STAGE_RETURN_FAILURE); + + connection = nm_act_request_get_applied_connection (req); + g_return_val_if_fail (connection != NULL, NM_ACT_STAGE_RETURN_FAILURE); + + s_wired = nm_connection_get_setting_wired (connection); + if (s_wired) { + /* Set device MAC address if the connection wants to change it */ + cloned_mac = nm_setting_wired_get_cloned_mac_address (s_wired); + if (cloned_mac) + nm_device_set_hw_addr (device, cloned_mac, "set", LOGD_DEVICE); + } + + return NM_ACT_STAGE_RETURN_SUCCESS; +} + +static void +ip4_config_pre_commit (NMDevice *device, NMIP4Config *config) +{ + NMConnection *connection; + NMSettingWired *s_wired; + guint32 mtu; + + connection = nm_device_get_applied_connection (device); + g_assert (connection); + + s_wired = nm_connection_get_setting_wired (connection); + if (s_wired) { + mtu = nm_setting_wired_get_mtu (s_wired); + if (mtu) + nm_ip4_config_set_mtu (config, mtu, NM_IP_CONFIG_SOURCE_USER); + } +} + /**************************************************************/ static void @@ -622,6 +674,8 @@ nm_device_vxlan_class_init (NMDeviceVxlanClass *klass) device_class->check_connection_compatible = check_connection_compatible; device_class->complete_connection = complete_connection; device_class->update_connection = update_connection; + device_class->act_stage1_prepare = act_stage1_prepare; + device_class->ip4_config_pre_commit = ip4_config_pre_commit; /* properties */ g_object_class_install_property