From 1aa36dde94dfb32a7172815ecb918b662aa9253b Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Mon, 11 Sep 2017 10:43:48 +0200 Subject: device: enable support for ipv6.dhcp-timeout - cleanup data type and use guint32 consistently. We might want to introduce a new "infinity" value. But since libnm's NM_SETTING_IP_CONFIG_DHCP_TIMEOUT asserts against the range 0 - G_MAXINT32, we cannot express it as -1 anyway. So, infinity will have the numerical value G_MAXINT32, hence guint32 is just fine. - make use of existing ipv6.dhcp-timeout setting and add global default configuration in NetworkManager.conf - instead of having subclasses call nm_device_set_dhcp_timeout(), add a virtual function get_dhcp_timeout(). --- man/NetworkManager.conf.xml | 5 +++ src/devices/nm-device-private.h | 1 - src/devices/nm-device.c | 82 +++++++++++++++++++--------------- src/devices/nm-device.h | 3 ++ src/devices/wifi/nm-device-olpc-mesh.c | 11 +++-- src/devices/wwan/nm-device-modem.c | 24 +++++----- src/dhcp/nm-dhcp-client.c | 9 ++-- src/dhcp/nm-dhcp-client.h | 2 + src/dhcp/nm-dhcp-manager.c | 4 +- src/nm-iface-helper.c | 2 +- 10 files changed, 81 insertions(+), 62 deletions(-) diff --git a/man/NetworkManager.conf.xml b/man/NetworkManager.conf.xml index d8fa1b3b95..25fe1ba4d4 100644 --- a/man/NetworkManager.conf.xml +++ b/man/NetworkManager.conf.xml @@ -682,6 +682,11 @@ ipv6.ip6-privacy=0 ipv4.route-metric + + ipv6.dhcp-timeout + If left unspecified, the default value for + the interface type is used. + ipv6.ip6-privacy If ipv6.ip6-privacy is unset, use the content of diff --git a/src/devices/nm-device-private.h b/src/devices/nm-device-private.h index a884faa2bf..28702f8af3 100644 --- a/src/devices/nm-device-private.h +++ b/src/devices/nm-device-private.h @@ -85,7 +85,6 @@ gboolean nm_device_activate_ip6_state_in_conf (NMDevice *device); gboolean nm_device_activate_ip6_state_in_wait (NMDevice *device); gboolean nm_device_activate_ip6_state_done (NMDevice *device); -void nm_device_set_dhcp_timeout (NMDevice *device, guint32 timeout); void nm_device_set_dhcp_anycast_address (NMDevice *device, const char *addr); gboolean nm_device_dhcp4_renew (NMDevice *device, gboolean release); diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index 9cb29cf27f..aff5184d21 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -338,7 +338,6 @@ typedef struct _NMDevicePrivate { NMDeviceSysIfaceState sys_iface_state:2; /* Generic DHCP stuff */ - guint32 dhcp_timeout; char * dhcp_anycast_address; char * current_stable_id; @@ -533,7 +532,7 @@ static gboolean queued_ip4_config_change (gpointer user_data); static gboolean queued_ip6_config_change (gpointer user_data); static void ip_check_ping_watch_cb (GPid pid, gint status, gpointer user_data); static gboolean ip_config_valid (NMDeviceState state); -static NMActStageReturn dhcp4_start (NMDevice *self, NMConnection *connection); +static NMActStageReturn dhcp4_start (NMDevice *self); static gboolean dhcp6_start (NMDevice *self, gboolean wait_for_ll); static void nm_device_start_ip_check (NMDevice *self); static void realize_start_setup (NMDevice *self, @@ -5733,15 +5732,13 @@ dhcp4_restart_cb (gpointer user_data) { NMDevice *self = user_data; NMDevicePrivate *priv; - NMConnection *connection; g_return_val_if_fail (NM_IS_DEVICE (self), FALSE); priv = NM_DEVICE_GET_PRIVATE (self); priv->dhcp4.restart_id = 0; - connection = nm_device_get_applied_connection (self); - if (dhcp4_start (self, connection) == NM_ACT_STAGE_RETURN_FAILURE) + if (dhcp4_start (self) == NM_ACT_STAGE_RETURN_FAILURE) dhcp_schedule_restart (self, AF_INET, NULL); return FALSE; @@ -5868,36 +5865,60 @@ dhcp4_state_changed (NMDhcpClient *client, } static int -dhcp4_get_timeout (NMDevice *self, NMSettingIP4Config *s_ip4) +get_dhcp_timeout (NMDevice *self, int addr_family) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - gs_free char *value = NULL; - int timeout; + NMDeviceClass *klass; + NMConnection *connection; + NMSettingIPConfig *s_ip; + guint32 timeout; - timeout = nm_setting_ip_config_get_dhcp_timeout (NM_SETTING_IP_CONFIG (s_ip4)); - if (timeout) - return timeout; + nm_assert (NM_IS_DEVICE (self)); + nm_assert (NM_IN_SET (addr_family, AF_INET, AF_INET6)); - value = nm_config_data_get_connection_default (NM_CONFIG_GET_DATA, - "ipv4.dhcp-timeout", - self); - timeout = _nm_utils_ascii_str_to_int64 (value, 10, - 0, G_MAXINT32, 0); + connection = nm_device_get_applied_connection (self); + + if (addr_family == AF_INET) + s_ip = nm_connection_get_setting_ip4_config (connection); + else + s_ip = nm_connection_get_setting_ip6_config (connection); + + timeout = nm_setting_ip_config_get_dhcp_timeout (s_ip); if (timeout) return timeout; - return priv->dhcp_timeout; + { + gs_free char *value = NULL; + + value = nm_config_data_get_connection_default (NM_CONFIG_GET_DATA, + addr_family == AF_INET + ? "ipv4.dhcp-timeout" + : "ipv6.dhcp-timeout", + self); + timeout = _nm_utils_ascii_str_to_int64 (value, 10, + 0, G_MAXINT32, 0); + if (timeout) + return timeout; + } + + klass = NM_DEVICE_GET_CLASS (self); + if (klass->get_dhcp_timeout) + timeout = klass->get_dhcp_timeout (self, addr_family); + + return timeout ?: NM_DHCP_TIMEOUT_DEFAULT; } static NMActStageReturn -dhcp4_start (NMDevice *self, - NMConnection *connection) +dhcp4_start (NMDevice *self) { NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); NMSettingIPConfig *s_ip4; const guint8 *hw_addr; size_t hw_addr_len = 0; GByteArray *tmp = NULL; + NMConnection *connection; + + connection = nm_device_get_applied_connection (self); + g_return_val_if_fail (connection, FALSE); s_ip4 = nm_connection_get_setting_ip4_config (connection); @@ -5924,7 +5945,7 @@ dhcp4_start (NMDevice *self, nm_setting_ip_config_get_dhcp_hostname (s_ip4), nm_setting_ip4_config_get_dhcp_fqdn (NM_SETTING_IP4_CONFIG (s_ip4)), nm_setting_ip4_config_get_dhcp_client_id (NM_SETTING_IP4_CONFIG (s_ip4)), - dhcp4_get_timeout (self, NM_SETTING_IP4_CONFIG (s_ip4)), + get_dhcp_timeout (self, AF_INET), priv->dhcp_anycast_address, NULL); @@ -5952,7 +5973,6 @@ gboolean nm_device_dhcp4_renew (NMDevice *self, gboolean release) { NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - NMConnection *connection; g_return_val_if_fail (priv->dhcp4.client != NULL, FALSE); @@ -5961,11 +5981,8 @@ nm_device_dhcp4_renew (NMDevice *self, gboolean release) /* Terminate old DHCP instance and release the old lease */ dhcp4_cleanup (self, CLEANUP_TYPE_DECONFIGURE, release); - connection = nm_device_get_applied_connection (self); - g_return_val_if_fail (connection, FALSE); - /* Start DHCP again on the interface */ - return dhcp4_start (self, connection) != NM_ACT_STAGE_RETURN_FAILURE; + return dhcp4_start (self) != NM_ACT_STAGE_RETURN_FAILURE; } /*****************************************************************************/ @@ -6173,7 +6190,7 @@ act_stage3_ip4_config_start (NMDevice *self, /* Start IPv4 addressing based on the method requested */ if (strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_AUTO) == 0) { - ret = dhcp4_start (self, connection); + ret = dhcp4_start (self); if (ret == NM_ACT_STAGE_RETURN_FAILURE) NM_SET_OUT (out_failure_reason, NM_DEVICE_STATE_REASON_DHCP_START_FAILED); } else if (strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL) == 0) { @@ -6671,7 +6688,7 @@ dhcp6_start_with_link_ready (NMDevice *self, NMConnection *connection) nm_device_get_ip6_route_metric (self), nm_setting_ip_config_get_dhcp_send_hostname (s_ip6), nm_setting_ip_config_get_dhcp_hostname (s_ip6), - priv->dhcp_timeout, + get_dhcp_timeout (self, AF_INET6), priv->dhcp_anycast_address, (priv->dhcp6.mode == NM_NDISC_DHCP_LEVEL_OTHERCONF) ? TRUE : FALSE, nm_setting_ip6_config_get_ip6_privacy (NM_SETTING_IP6_CONFIG (s_ip6)), @@ -11360,14 +11377,6 @@ nm_device_set_unmanaged_by_quitting (NMDevice *self) /*****************************************************************************/ -void -nm_device_set_dhcp_timeout (NMDevice *self, guint32 timeout) -{ - g_return_if_fail (NM_IS_DEVICE (self)); - - NM_DEVICE_GET_PRIVATE (self)->dhcp_timeout = timeout; -} - void nm_device_set_dhcp_anycast_address (NMDevice *self, const char *addr) { @@ -13656,7 +13665,6 @@ nm_device_init (NMDevice *self) priv->capabilities = NM_DEVICE_CAP_NM_SUPPORTED; priv->state = NM_DEVICE_STATE_UNMANAGED; priv->state_reason = NM_DEVICE_STATE_REASON_NONE; - priv->dhcp_timeout = 0; priv->rfkill_type = RFKILL_TYPE_UNKNOWN; priv->unmanaged_flags = NM_UNMANAGED_PLATFORM_INIT; priv->unmanaged_mask = priv->unmanaged_flags; diff --git a/src/devices/nm-device.h b/src/devices/nm-device.h index 811fc258ec..ffd5b847de 100644 --- a/src/devices/nm-device.h +++ b/src/devices/nm-device.h @@ -406,6 +406,9 @@ typedef struct { void (* reapply_connection) (NMDevice *self, NMConnection *con_old, NMConnection *con_new); + + guint32 (* get_dhcp_timeout) (NMDevice *self, + int addr_family); } NMDeviceClass; typedef void (*NMDeviceAuthRequestFunc) (NMDevice *device, diff --git a/src/devices/wifi/nm-device-olpc-mesh.c b/src/devices/wifi/nm-device-olpc-mesh.c index 082c573674..b305f76376 100644 --- a/src/devices/wifi/nm-device-olpc-mesh.c +++ b/src/devices/wifi/nm-device-olpc-mesh.c @@ -425,6 +425,13 @@ state_changed (NMDevice *device, find_companion (NM_DEVICE_OLPC_MESH (device)); } +static guint32 +get_dhcp_timeout (NMDevice *device, int addr_family) +{ + /* shorter timeout for mesh connectivity */ + return 20; +} + /*****************************************************************************/ static void @@ -467,9 +474,6 @@ constructed (GObject *object) g_signal_connect (priv->manager, "device-added", G_CALLBACK (device_added_cb), self); g_signal_connect (priv->manager, "device-removed", G_CALLBACK (device_removed_cb), self); - - /* shorter timeout for mesh connectivity */ - nm_device_set_dhcp_timeout (NM_DEVICE (self), 20); } NMDevice * @@ -519,6 +523,7 @@ nm_device_olpc_mesh_class_init (NMDeviceOlpcMeshClass *klass) parent_class->act_stage1_prepare = act_stage1_prepare; parent_class->act_stage2_config = act_stage2_config; parent_class->state_changed = state_changed; + parent_class->get_dhcp_timeout = get_dhcp_timeout; obj_properties[PROP_COMPANION] = g_param_spec_string (NM_DEVICE_OLPC_MESH_COMPANION, "", "", diff --git a/src/devices/wwan/nm-device-modem.c b/src/devices/wwan/nm-device-modem.c index 4a4d2f2c3b..0b0b0a1bb8 100644 --- a/src/devices/wwan/nm-device-modem.c +++ b/src/devices/wwan/nm-device-modem.c @@ -664,6 +664,16 @@ set_modem (NMDeviceModem *self, NMModem *modem) g_signal_connect (modem, "notify::" NM_MODEM_SIM_OPERATOR_ID, G_CALLBACK (ids_changed_cb), self); } +static guint32 +get_dhcp_timeout (NMDevice *device, int addr_family) +{ + /* DHCP is always done by the modem firmware, not by the network, and + * by the time we get around to DHCP the firmware should already know + * the IP addressing details. So the DHCP timeout can be much shorter. + */ + return 15; +} + /*****************************************************************************/ static void @@ -718,18 +728,6 @@ nm_device_modem_init (NMDeviceModem *self) { } -static void -constructed (GObject *object) -{ - G_OBJECT_CLASS (nm_device_modem_parent_class)->constructed (object); - - /* DHCP is always done by the modem firmware, not by the network, and - * by the time we get around to DHCP the firmware should already know - * the IP addressing details. So the DHCP timeout can be much shorter. - */ - nm_device_set_dhcp_timeout (NM_DEVICE (object), 15); -} - NMDevice * nm_device_modem_new (NMModem *modem) { @@ -786,7 +784,6 @@ nm_device_modem_class_init (NMDeviceModemClass *mclass) object_class->dispose = dispose; object_class->get_property = get_property; object_class->set_property = set_property; - object_class->constructed = constructed; device_class->get_generic_capabilities = get_generic_capabilities; device_class->get_type_description = get_type_description; @@ -807,6 +804,7 @@ nm_device_modem_class_init (NMDeviceModemClass *mclass) device_class->is_available = is_available; device_class->get_ip_iface_identifier = get_ip_iface_identifier; device_class->get_configured_mtu = nm_modem_get_configured_mtu; + device_class->get_dhcp_timeout = get_dhcp_timeout; device_class->state_changed = device_state_changed; diff --git a/src/dhcp/nm-dhcp-client.c b/src/dhcp/nm-dhcp-client.c index b08e05051d..e409fb4f3f 100644 --- a/src/dhcp/nm-dhcp-client.c +++ b/src/dhcp/nm-dhcp-client.c @@ -441,7 +441,7 @@ nm_dhcp_client_start_ip4 (NMDhcpClient *self, g_return_val_if_fail (priv->ipv6 == FALSE, FALSE); g_return_val_if_fail (priv->uuid != NULL, FALSE); - _LOGI ("activation: beginning transaction (timeout in %d seconds)", priv->timeout); + _LOGI ("activation: beginning transaction (timeout in %u seconds)", (guint) priv->timeout); if (dhcp_client_id) tmp = nm_dhcp_utils_client_id_string_to_bytes (dhcp_client_id); @@ -556,8 +556,8 @@ nm_dhcp_client_start_ip6 (NMDhcpClient *self, priv->info_only = info_only; - _LOGI ("activation: beginning transaction (timeout in %d seconds)", - priv->timeout); + _LOGI ("activation: beginning transaction (timeout in %u seconds)", + (guint) priv->timeout); return NM_DHCP_CLIENT_GET_CLASS (self)->ip6_start (self, dhcp_anycast_addr, @@ -894,6 +894,7 @@ set_property (GObject *object, guint prop_id, priv->priority = g_value_get_uint (value); break; case PROP_TIMEOUT: + /* construct-only */ priv->timeout = g_value_get_uint (value); break; default: @@ -1007,7 +1008,7 @@ nm_dhcp_client_class_init (NMDhcpClientClass *client_class) obj_properties[PROP_TIMEOUT] = g_param_spec_uint (NM_DHCP_CLIENT_TIMEOUT, "", "", - 0, G_MAXUINT, 45, + 1, G_MAXINT32, NM_DHCP_TIMEOUT_DEFAULT, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); diff --git a/src/dhcp/nm-dhcp-client.h b/src/dhcp/nm-dhcp-client.h index 890c5ff595..9e71b1c0e8 100644 --- a/src/dhcp/nm-dhcp-client.h +++ b/src/dhcp/nm-dhcp-client.h @@ -24,6 +24,8 @@ #include "nm-ip4-config.h" #include "nm-ip6-config.h" +#define NM_DHCP_TIMEOUT_DEFAULT ((guint32) 45) /* default DHCP timeout, in seconds */ + #define NM_TYPE_DHCP_CLIENT (nm_dhcp_client_get_type ()) #define NM_DHCP_CLIENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DHCP_CLIENT, NMDhcpClient)) #define NM_DHCP_CLIENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DHCP_CLIENT, NMDhcpClientClass)) diff --git a/src/dhcp/nm-dhcp-manager.c b/src/dhcp/nm-dhcp-manager.c index 42ec390860..ae4c3f97e9 100644 --- a/src/dhcp/nm-dhcp-manager.c +++ b/src/dhcp/nm-dhcp-manager.c @@ -39,8 +39,6 @@ #include "nm-config.h" #include "NetworkManagerUtils.h" -#define DHCP_TIMEOUT 45 /* default DHCP timeout, in seconds */ - /*****************************************************************************/ typedef struct { @@ -205,7 +203,7 @@ client_start (NMDhcpManager *self, NM_DHCP_CLIENT_IPV6, ipv6, NM_DHCP_CLIENT_UUID, uuid, NM_DHCP_CLIENT_PRIORITY, priority, - NM_DHCP_CLIENT_TIMEOUT, timeout ? timeout : DHCP_TIMEOUT, + NM_DHCP_CLIENT_TIMEOUT, (guint) timeout, NULL); g_hash_table_insert (NM_DHCP_MANAGER_GET_PRIVATE (self)->clients, client, g_object_ref (client)); g_signal_connect (client, NM_DHCP_CLIENT_SIGNAL_STATE_CHANGED, G_CALLBACK (client_state_changed), self); diff --git a/src/nm-iface-helper.c b/src/nm-iface-helper.c index f7741f5736..9f6ba72407 100644 --- a/src/nm-iface-helper.c +++ b/src/nm-iface-helper.c @@ -446,7 +446,7 @@ main (int argc, char *argv[]) global_opt.dhcp4_hostname, global_opt.dhcp4_fqdn, global_opt.dhcp4_clientid, - 45, + NM_DHCP_TIMEOUT_DEFAULT, NULL, global_opt.dhcp4_address); g_assert (dhcp4_client); -- cgit v1.2.1