diff options
author | Beniamino Galvani <bgalvani@redhat.com> | 2019-10-10 15:16:57 +0200 |
---|---|---|
committer | Beniamino Galvani <bgalvani@redhat.com> | 2019-10-10 15:17:40 +0200 |
commit | facfc94744e2f952f5058fb0693915bc674ff8c2 (patch) | |
tree | 83aa674ceff30a0bae5fa576df2da707114449f3 | |
parent | b58e4d311da630ea8d14f60ca3667710877e455d (diff) | |
parent | ec28f5b343816d6696f6a4994efcfa919b6f02b2 (diff) | |
download | NetworkManager-facfc94744e2f952f5058fb0693915bc674ff8c2.tar.gz |
device: merge branch 'bg/parent-mtu-rh1723690-part1'
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/merge_requests/273
-rw-r--r-- | src/devices/nm-device-ethernet.c | 6 | ||||
-rw-r--r-- | src/devices/nm-device-infiniband.c | 4 | ||||
-rw-r--r-- | src/devices/nm-device-ip-tunnel.c | 4 | ||||
-rw-r--r-- | src/devices/nm-device-macsec.c | 23 | ||||
-rw-r--r-- | src/devices/nm-device-macvlan.c | 30 | ||||
-rw-r--r-- | src/devices/nm-device-private.h | 6 | ||||
-rw-r--r-- | src/devices/nm-device-vlan.c | 23 | ||||
-rw-r--r-- | src/devices/nm-device-wireguard.c | 2 | ||||
-rw-r--r-- | src/devices/nm-device.c | 84 | ||||
-rw-r--r-- | src/devices/nm-device.h | 8 | ||||
-rw-r--r-- | src/devices/wifi/nm-device-iwd.c | 4 | ||||
-rw-r--r-- | src/devices/wifi/nm-device-wifi-p2p.c | 4 | ||||
-rw-r--r-- | src/devices/wifi/nm-device-wifi.c | 4 | ||||
-rw-r--r-- | src/devices/wwan/nm-modem.c | 4 | ||||
-rw-r--r-- | src/devices/wwan/nm-modem.h | 2 |
15 files changed, 165 insertions, 43 deletions
diff --git a/src/devices/nm-device-ethernet.c b/src/devices/nm-device-ethernet.c index 83f2f61cf4..ddd5132690 100644 --- a/src/devices/nm-device-ethernet.c +++ b/src/devices/nm-device-ethernet.c @@ -1329,13 +1329,15 @@ act_stage3_ip_config_start (NMDevice *device, } static guint32 -get_configured_mtu (NMDevice *device, NMDeviceMtuSource *out_source) +get_configured_mtu (NMDevice *device, + NMDeviceMtuSource *out_source, + gboolean *out_force) { /* MTU only set for plain ethernet */ if (NM_DEVICE_ETHERNET_GET_PRIVATE ((NMDeviceEthernet *) device)->ppp_manager) return 0; - return nm_device_get_configured_mtu_for_wired (device, out_source); + return nm_device_get_configured_mtu_for_wired (device, out_source, out_force); } static void diff --git a/src/devices/nm-device-infiniband.c b/src/devices/nm-device-infiniband.c index d9b83b4284..24593ff1f5 100644 --- a/src/devices/nm-device-infiniband.c +++ b/src/devices/nm-device-infiniband.c @@ -97,7 +97,9 @@ act_stage1_prepare (NMDevice *device, NMDeviceStateReason *out_failure_reason) } static guint32 -get_configured_mtu (NMDevice *device, NMDeviceMtuSource *out_source) +get_configured_mtu (NMDevice *device, + NMDeviceMtuSource *out_source, + gboolean *out_force) { return nm_device_get_configured_mtu_from_connection (device, NM_TYPE_SETTING_INFINIBAND, diff --git a/src/devices/nm-device-ip-tunnel.c b/src/devices/nm-device-ip-tunnel.c index 34c35fc5b8..0becb5e568 100644 --- a/src/devices/nm-device-ip-tunnel.c +++ b/src/devices/nm-device-ip-tunnel.c @@ -840,7 +840,9 @@ create_and_realize (NMDevice *device, } static guint32 -get_configured_mtu (NMDevice *device, NMDeviceMtuSource *out_source) +get_configured_mtu (NMDevice *device, + NMDeviceMtuSource *out_source, + gboolean *out_force) { return nm_device_get_configured_mtu_from_connection (device, NM_TYPE_SETTING_IP_TUNNEL, diff --git a/src/devices/nm-device-macsec.c b/src/devices/nm-device-macsec.c index 17ee53c565..c9592a4971 100644 --- a/src/devices/nm-device-macsec.c +++ b/src/devices/nm-device-macsec.c @@ -52,6 +52,7 @@ NM_GOBJECT_PROPERTIES_DEFINE (NMDeviceMacsec, typedef struct { NMPlatformLnkMacsec props; gulong parent_state_id; + gulong parent_mtu_id; Supplicant supplicant; guint supplicant_timeout_id; NMActRequestGetSecretsCallId *macsec_secrets_id; @@ -100,6 +101,17 @@ parent_state_changed (NMDevice *parent, } static void +parent_mtu_maybe_changed (NMDevice *parent, + GParamSpec *pspec, + gpointer user_data) +{ + /* the MTU of a MACsec device is limited by the parent's MTU. + * + * When the parent's MTU changes, try to re-set the MTU. */ + nm_device_commit_mtu (user_data); +} + +static void parent_changed_notify (NMDevice *device, int old_ifindex, NMDevice *old_parent, @@ -119,12 +131,16 @@ parent_changed_notify (NMDevice *device, * because NMDevice's dispose() will unset the parent, which in turn calls * parent_changed_notify(). */ nm_clear_g_signal_handler (old_parent, &priv->parent_state_id); + nm_clear_g_signal_handler (old_parent, &priv->parent_mtu_id); if (new_parent) { priv->parent_state_id = g_signal_connect (new_parent, NM_DEVICE_STATE_CHANGED, G_CALLBACK (parent_state_changed), device); + priv->parent_mtu_id = g_signal_connect (new_parent, "notify::" NM_DEVICE_MTU, + G_CALLBACK (parent_mtu_maybe_changed), device); + /* Set parent-dependent unmanaged flag */ nm_device_set_unmanaged_by_flags (device, @@ -779,11 +795,15 @@ static void dispose (GObject *object) { NMDeviceMacsec *self = NM_DEVICE_MACSEC (object); + NMDeviceMacsecPrivate *priv = NM_DEVICE_MACSEC_GET_PRIVATE (self); macsec_secrets_cancel (self); supplicant_interface_release (self); G_OBJECT_CLASS (nm_device_macsec_parent_class)->dispose (object); + + nm_assert (priv->parent_state_id == 0); + nm_assert (priv->parent_mtu_id == 0); } static const NMDBusInterfaceInfoExtended interface_info_device_macsec = { @@ -826,6 +846,7 @@ nm_device_macsec_class_init (NMDeviceMacsecClass *klass) device_class->connection_type_supported = NM_SETTING_MACSEC_SETTING_NAME; device_class->connection_type_check_compatible = NM_SETTING_MACSEC_SETTING_NAME; device_class->link_types = NM_DEVICE_DEFINE_LINK_TYPES (NM_LINK_TYPE_MACSEC); + device_class->mtu_parent_delta = 32; device_class->act_stage2_config = act_stage2_config; device_class->create_and_realize = create_and_realize; @@ -835,7 +856,7 @@ nm_device_macsec_class_init (NMDeviceMacsecClass *klass) device_class->is_available = is_available; device_class->parent_changed_notify = parent_changed_notify; device_class->state_changed = device_state_changed; - device_class->get_configured_mtu = nm_device_get_configured_mtu_for_wired; + device_class->get_configured_mtu = nm_device_get_configured_mtu_wired_parent; obj_properties[PROP_SCI] = g_param_spec_uint64 (NM_DEVICE_MACSEC_SCI, "", "", diff --git a/src/devices/nm-device-macvlan.c b/src/devices/nm-device-macvlan.c index f27211f5f5..3633f02d46 100644 --- a/src/devices/nm-device-macvlan.c +++ b/src/devices/nm-device-macvlan.c @@ -34,6 +34,7 @@ NM_GOBJECT_PROPERTIES_DEFINE (NMDeviceMacvlan, typedef struct { gulong parent_state_id; + gulong parent_mtu_id; NMPlatformLnkMacvlan props; } NMDeviceMacvlanPrivate; @@ -121,6 +122,17 @@ parent_state_changed (NMDevice *parent, } static void +parent_mtu_maybe_changed (NMDevice *parent, + GParamSpec *pspec, + gpointer user_data) +{ + /* the MTU of a macvlan/macvtap device is limited by the parent's MTU. + * + * When the parent's MTU changes, try to re-set the MTU. */ + nm_device_commit_mtu (user_data); +} + +static void parent_changed_notify (NMDevice *device, int old_ifindex, NMDevice *old_parent, @@ -136,12 +148,15 @@ parent_changed_notify (NMDevice *device, * because NMDevice's dispose() will unset the parent, which in turn calls * parent_changed_notify(). */ nm_clear_g_signal_handler (old_parent, &priv->parent_state_id); + nm_clear_g_signal_handler (old_parent, &priv->parent_mtu_id); if (new_parent) { priv->parent_state_id = g_signal_connect (new_parent, NM_DEVICE_STATE_CHANGED, G_CALLBACK (parent_state_changed), device); + priv->parent_mtu_id = g_signal_connect (new_parent, "notify::" NM_DEVICE_MTU, + G_CALLBACK (parent_mtu_maybe_changed), device); /* Set parent-dependent unmanaged flag */ nm_device_set_unmanaged_by_flags (device, @@ -447,6 +462,17 @@ nm_device_macvlan_init (NMDeviceMacvlan *self) { } +static void +dispose (GObject *object) +{ + NMDeviceMacvlanPrivate *priv = NM_DEVICE_MACVLAN_GET_PRIVATE (object); + + G_OBJECT_CLASS (nm_device_macvlan_parent_class)->dispose (object); + + nm_assert (priv->parent_state_id == 0); + nm_assert (priv->parent_mtu_id == 0); +} + static const NMDBusInterfaceInfoExtended interface_info_device_macvlan = { .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT ( NM_DBUS_INTERFACE_DEVICE_MACVLAN, @@ -470,6 +496,7 @@ nm_device_macvlan_class_init (NMDeviceMacvlanClass *klass) NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS (klass); NMDeviceClass *device_class = NM_DEVICE_CLASS (klass); + object_class->dispose = dispose; object_class->get_property = get_property; object_class->set_property = set_property; @@ -478,13 +505,14 @@ nm_device_macvlan_class_init (NMDeviceMacvlanClass *klass) device_class->connection_type_supported = NM_SETTING_MACVLAN_SETTING_NAME; device_class->connection_type_check_compatible = NM_SETTING_MACVLAN_SETTING_NAME; device_class->link_types = NM_DEVICE_DEFINE_LINK_TYPES (NM_LINK_TYPE_MACVLAN, NM_LINK_TYPE_MACVTAP); + device_class->mtu_parent_delta = 0; device_class->act_stage1_prepare_set_hwaddr_ethernet = TRUE; device_class->check_connection_compatible = check_connection_compatible; device_class->complete_connection = complete_connection; device_class->create_and_realize = create_and_realize; device_class->get_generic_capabilities = get_generic_capabilities; - device_class->get_configured_mtu = nm_device_get_configured_mtu_for_wired; + device_class->get_configured_mtu = nm_device_get_configured_mtu_wired_parent; device_class->is_available = is_available; device_class->link_changed = link_changed; device_class->parent_changed_notify = parent_changed_notify; diff --git a/src/devices/nm-device-private.h b/src/devices/nm-device-private.h index 4c38fa7a2a..e87733ef3f 100644 --- a/src/devices/nm-device-private.h +++ b/src/devices/nm-device-private.h @@ -166,7 +166,11 @@ guint32 nm_device_get_configured_mtu_from_connection (NMDevice *device, GType setting_type, NMDeviceMtuSource *out_source); -guint32 nm_device_get_configured_mtu_for_wired (NMDevice *self, NMDeviceMtuSource *out_source); +guint32 nm_device_get_configured_mtu_for_wired (NMDevice *self, NMDeviceMtuSource *out_source, gboolean *out_force); + +guint32 nm_device_get_configured_mtu_wired_parent (NMDevice *self, + NMDeviceMtuSource *out_source, + gboolean *out_force); void nm_device_commit_mtu (NMDevice *self); diff --git a/src/devices/nm-device-vlan.c b/src/devices/nm-device-vlan.c index 02262b21d6..b6efeb81a5 100644 --- a/src/devices/nm-device-vlan.c +++ b/src/devices/nm-device-vlan.c @@ -502,26 +502,6 @@ act_stage1_prepare (NMDevice *device, NMDeviceStateReason *out_failure_reason) return NM_ACT_STAGE_RETURN_SUCCESS; } -static guint32 -get_configured_mtu (NMDevice *self, NMDeviceMtuSource *out_source) -{ - guint32 mtu = 0; - int ifindex; - - mtu = nm_device_get_configured_mtu_for_wired (self, out_source); - if (*out_source != NM_DEVICE_MTU_SOURCE_NONE) - return mtu; - - /* Inherit the MTU from parent device, if any */ - ifindex = nm_device_parent_get_ifindex (self); - if (ifindex > 0) { - mtu = nm_platform_link_get_mtu (nm_device_get_platform (NM_DEVICE (self)), ifindex); - *out_source = NM_DEVICE_MTU_SOURCE_PARENT; - } - - return mtu; -} - /*****************************************************************************/ static void @@ -577,6 +557,7 @@ nm_device_vlan_class_init (NMDeviceVlanClass *klass) device_class->connection_type_supported = NM_SETTING_VLAN_SETTING_NAME; device_class->connection_type_check_compatible = NM_SETTING_VLAN_SETTING_NAME; device_class->link_types = NM_DEVICE_DEFINE_LINK_TYPES (NM_LINK_TYPE_VLAN); + device_class->mtu_parent_delta = 0; /* VLANs can have the same MTU of parent */ device_class->create_and_realize = create_and_realize; device_class->link_changed = link_changed; @@ -584,7 +565,7 @@ nm_device_vlan_class_init (NMDeviceVlanClass *klass) device_class->get_generic_capabilities = get_generic_capabilities; device_class->act_stage1_prepare_set_hwaddr_ethernet = TRUE; device_class->act_stage1_prepare = act_stage1_prepare; - device_class->get_configured_mtu = get_configured_mtu; + device_class->get_configured_mtu = nm_device_get_configured_mtu_wired_parent; device_class->is_available = is_available; device_class->parent_changed_notify = parent_changed_notify; diff --git a/src/devices/nm-device-wireguard.c b/src/devices/nm-device-wireguard.c index c769a86be3..d65607089b 100644 --- a/src/devices/nm-device-wireguard.c +++ b/src/devices/nm-device-wireguard.c @@ -1691,7 +1691,7 @@ act_stage3_ip_config_start (NMDevice *device, } static guint32 -get_configured_mtu (NMDevice *device, NMDeviceMtuSource *out_source) +get_configured_mtu (NMDevice *device, NMDeviceMtuSource *out_source, gboolean *out_force) { /* 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 diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index 1fe74b55e3..57de04d4db 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -9317,13 +9317,59 @@ nm_device_get_configured_mtu_from_connection (NMDevice *self, } guint32 -nm_device_get_configured_mtu_for_wired (NMDevice *self, NMDeviceMtuSource *out_source) +nm_device_get_configured_mtu_for_wired (NMDevice *self, + NMDeviceMtuSource *out_source, + gboolean *out_force) { return nm_device_get_configured_mtu_from_connection (self, NM_TYPE_SETTING_WIRED, out_source); } +guint32 +nm_device_get_configured_mtu_wired_parent (NMDevice *self, + NMDeviceMtuSource *out_source, + gboolean *out_force) +{ + guint32 mtu = 0; + guint32 parent_mtu = 0; + int ifindex; + + ifindex = nm_device_parent_get_ifindex (self); + if (ifindex > 0) { + parent_mtu = nm_platform_link_get_mtu (nm_device_get_platform (self), ifindex); + if (parent_mtu >= NM_DEVICE_GET_CLASS (self)->mtu_parent_delta) + parent_mtu -= NM_DEVICE_GET_CLASS (self)->mtu_parent_delta; + else + parent_mtu = 0; + } + + mtu = nm_device_get_configured_mtu_for_wired (self, out_source, NULL); + + if (parent_mtu && mtu > parent_mtu) { + /* Trying to set a MTU that is out of range from configuration: + * fall back to the parent MTU and set force flag so that it + * overrides an MTU with higher priority already configured. + */ + *out_source = NM_DEVICE_MTU_SOURCE_PARENT; + *out_force = TRUE; + return parent_mtu; + } + + if (*out_source != NM_DEVICE_MTU_SOURCE_NONE) { + nm_assert (mtu > 0); + return mtu; + } + + /* Inherit the MTU from parent device, if any */ + if (parent_mtu) { + mtu = parent_mtu; + *out_source = NM_DEVICE_MTU_SOURCE_PARENT; + } + + return mtu; +} + /*****************************************************************************/ static void @@ -9375,15 +9421,34 @@ _commit_mtu (NMDevice *self, const NMIP4Config *config) { guint32 mtu = 0; + gboolean force = FALSE; - /* preferably, get the MTU from explicit user-configuration. - * Only if that fails, look at the current @config (which contains - * MTUs from DHCP/PPP) or maybe fallback to a device-specific MTU. */ + /* We take the MTU from various sources: (in order of increasing + * priority) parent link, IP configuration (which contains the + * MTU from DHCP/PPP), connection profile. + * + * We could just compare it with the platform MTU and apply it + * when different, but this would revert at random times manual + * changes done by the user with the MTU from the connection. + * + * Instead, we remember the source of the currently configured + * MTU and apply the new one only when the new source has a + * higher priority, so that we don't set a MTU from same source + * multiple times. An exception to this is for the PARENT + * source, since we need to keep tracking the parent MTU when it + * changes. + * + * The subclass can set the @force argument to TRUE to signal that the + * returned MTU should be applied even if it has a lower priority. This + * is useful when the value from a lower source should + * preempt the one from higher ones. + */ if (NM_DEVICE_GET_CLASS (self)->get_configured_mtu) - mtu = NM_DEVICE_GET_CLASS (self)->get_configured_mtu (self, &source); + mtu = NM_DEVICE_GET_CLASS (self)->get_configured_mtu (self, &source, &force); if ( config + && !force && source < NM_DEVICE_MTU_SOURCE_IP_CONFIG && nm_ip4_config_get_mtu (config)) { mtu = nm_ip4_config_get_mtu (config); @@ -9392,14 +9457,16 @@ _commit_mtu (NMDevice *self, const NMIP4Config *config) if (mtu != 0) { _LOGT (LOGD_DEVICE, - "mtu: value %u from source '%s' (%u), current source '%s' (%u)", + "mtu: value %u from source '%s' (%u), current source '%s' (%u)%s", (guint) mtu, mtu_source_to_str (source), (guint) source, - mtu_source_to_str (priv->mtu_source), (guint) priv->mtu_source); + mtu_source_to_str (priv->mtu_source), (guint) priv->mtu_source, + force ? " (forced)" : ""); } if ( mtu != 0 - && ( source > priv->mtu_source + && ( force + || source > priv->mtu_source || (priv->mtu_source == NM_DEVICE_MTU_SOURCE_PARENT && source == priv->mtu_source))) mtu_desired = mtu; else { @@ -14845,6 +14912,7 @@ nm_device_cleanup (NMDevice *self, NMDeviceStateReason reason, CleanupType clean } priv->mtu_source = NM_DEVICE_MTU_SOURCE_NONE; + priv->ip6_mtu = 0; if (priv->mtu_initial || priv->ip6_mtu_initial) { ifindex = nm_device_get_ip_ifindex (self); diff --git a/src/devices/nm-device.h b/src/devices/nm-device.h index df8777b720..aa2de5a4de 100644 --- a/src/devices/nm-device.h +++ b/src/devices/nm-device.h @@ -225,6 +225,10 @@ typedef struct _NMDeviceClass { const NMLinkType *link_types; + /* if the device MTU is set based on parent's one, this specifies + * a delta in the MTU allowed value due the encapsulation overhead */ + guint16 mtu_parent_delta; + /* Whether the device type is a master-type. This depends purely on the * type (NMDeviceClass), not the actual device instance. */ bool is_master:1; @@ -321,7 +325,9 @@ typedef struct _NMDeviceClass { NMSettingsConnection *sett_conn, char **specific_object); - guint32 (*get_configured_mtu) (NMDevice *self, NMDeviceMtuSource *out_source); + guint32 (*get_configured_mtu) (NMDevice *self, + NMDeviceMtuSource *out_source, + gboolean *out_force); /* allow the subclass to overwrite the routing table. This is mainly useful * to change from partial mode (route-table=0) to full-sync mode (route-table=254). */ diff --git a/src/devices/wifi/nm-device-iwd.c b/src/devices/wifi/nm-device-iwd.c index 8e3aafda12..6b587e3f3b 100644 --- a/src/devices/wifi/nm-device-iwd.c +++ b/src/devices/wifi/nm-device-iwd.c @@ -1865,7 +1865,9 @@ out: } static guint32 -get_configured_mtu (NMDevice *device, NMDeviceMtuSource *out_source) +get_configured_mtu (NMDevice *device, + NMDeviceMtuSource *out_source, + gboolean *out_force) { return nm_device_get_configured_mtu_from_connection (device, NM_TYPE_SETTING_WIRELESS, diff --git a/src/devices/wifi/nm-device-wifi-p2p.c b/src/devices/wifi/nm-device-wifi-p2p.c index cd672f89da..34ff70fa0e 100644 --- a/src/devices/wifi/nm-device-wifi-p2p.c +++ b/src/devices/wifi/nm-device-wifi-p2p.c @@ -604,7 +604,9 @@ deactivate (NMDevice *device) } static guint32 -get_configured_mtu (NMDevice *device, NMDeviceMtuSource *out_source) +get_configured_mtu (NMDevice *device, + NMDeviceMtuSource *out_source, + gboolean *out_force) { *out_source = NM_DEVICE_MTU_SOURCE_NONE; return 0; diff --git a/src/devices/wifi/nm-device-wifi.c b/src/devices/wifi/nm-device-wifi.c index 04c90058a1..1d49ea4344 100644 --- a/src/devices/wifi/nm-device-wifi.c +++ b/src/devices/wifi/nm-device-wifi.c @@ -2895,7 +2895,9 @@ act_stage3_ip_config_start (NMDevice *device, } static guint32 -get_configured_mtu (NMDevice *device, NMDeviceMtuSource *out_source) +get_configured_mtu (NMDevice *device, + NMDeviceMtuSource *out_source, + gboolean *out_force) { return nm_device_get_configured_mtu_from_connection (device, NM_TYPE_SETTING_WIRELESS, diff --git a/src/devices/wwan/nm-modem.c b/src/devices/wwan/nm-modem.c index e49cffcfaf..ad6449b17e 100644 --- a/src/devices/wwan/nm-modem.c +++ b/src/devices/wwan/nm-modem.c @@ -910,7 +910,9 @@ nm_modem_stage3_ip6_config_start (NMModem *self, } guint32 -nm_modem_get_configured_mtu (NMDevice *self, NMDeviceMtuSource *out_source) +nm_modem_get_configured_mtu (NMDevice *self, + NMDeviceMtuSource *out_source, + gboolean *out_force) { NMConnection *connection; NMSetting *setting; diff --git a/src/devices/wwan/nm-modem.h b/src/devices/wwan/nm-modem.h index c83ca538b9..f2de990b80 100644 --- a/src/devices/wwan/nm-modem.h +++ b/src/devices/wwan/nm-modem.h @@ -275,7 +275,7 @@ void nm_modem_emit_ip6_config_result (NMModem *self, const char *nm_modem_ip_type_to_string (NMModemIPType ip_type); -guint32 nm_modem_get_configured_mtu (NMDevice *self, NMDeviceMtuSource *out_source); +guint32 nm_modem_get_configured_mtu (NMDevice *self, NMDeviceMtuSource *out_source, gboolean *out_force); void _nm_modem_set_operator_code (NMModem *self, const char *operator_code); void _nm_modem_set_apn (NMModem *self, const char *apn); |