policy: allow reset of dhcp hostname in "dhcp" hostname-mode config.

When dhcp hostname-mode is selected, NetworkManager will just update the
hostname with information available from DHCP (if any).
So, when a connection providing a DHCP host-name option is brought up we
update the transient hostname. When it is later teared down, this will
trigger NetworkManager to update the hostname: this time no DHCP host-name
option will be found and so the hostname will not be changed, keeping
the obsoleted one from the disappeared DHCP option.
In order to fix this we have to keep track if the last hostname set was
retrieved from the DHCP host-name option: in this case NetworkManager
will be able to reset it by applying back the previous hostname.
This commit is contained in:
Francesco Giudici 2017-03-03 18:32:08 +01:00
parent 2eba42b4ab
commit 8ffc68cc0e

View file

@ -91,6 +91,7 @@ typedef struct {
char *cur_hostname; /* hostname we want to assign */
char *last_hostname; /* last hostname NM set (to detect if someone else changed it in the meanwhile) */
gboolean changing_hostname; /* hostname set operation still in progress */
gboolean dhcp_hostname; /* current hostname was set from dhcp */
GArray *ip6_prefix_delegations; /* pool of ip6 prefixes delegated to all devices */
} NMPolicyPrivate;
@ -608,6 +609,7 @@ update_system_hostname (NMPolicy *self, NMDevice *best4, NMDevice *best6)
external_hostname = TRUE;
_LOGI (LOGD_DNS, "current hostname was changed outside NetworkManager: '%s'",
temp_hostname);
priv->dhcp_hostname = FALSE;
if (!nm_streq0 (temp_hostname, priv->orig_hostname)) {
/* Update original (fallback) hostname */
@ -633,6 +635,7 @@ update_system_hostname (NMPolicy *self, NMDevice *best4, NMDevice *best6)
g_object_get (G_OBJECT (priv->manager), NM_MANAGER_HOSTNAME, &configured_hostname, NULL);
if (configured_hostname && nm_utils_is_specific_hostname (configured_hostname)) {
_set_hostname (self, configured_hostname, "from system configuration");
priv->dhcp_hostname = FALSE;
g_free (configured_hostname);
return;
}
@ -656,6 +659,7 @@ update_system_hostname (NMPolicy *self, NMDevice *best4, NMDevice *best6)
while (*p) {
if (!g_ascii_isspace (*p++)) {
_set_hostname (self, p-1, "from DHCPv4");
priv->dhcp_hostname = TRUE;
return;
}
}
@ -675,6 +679,7 @@ update_system_hostname (NMPolicy *self, NMDevice *best4, NMDevice *best6)
while (*p) {
if (!g_ascii_isspace (*p++)) {
_set_hostname (self, p-1, "from DHCPv6");
priv->dhcp_hostname = TRUE;
return;
}
}
@ -688,8 +693,20 @@ update_system_hostname (NMPolicy *self, NMDevice *best4, NMDevice *best6)
if (external_hostname)
return;
if (priv->hostname_mode == NM_POLICY_HOSTNAME_MODE_DHCP)
if (priv->hostname_mode == NM_POLICY_HOSTNAME_MODE_DHCP) {
/* In dhcp hostname-mode, the hostname is updated only if it comes from
* a DHCP host-name option: if last set was from a host-name option and
* we are here than that connection is gone (with its host-name option),
* so reset the hostname to the previous value
*/
if (priv->dhcp_hostname) {
_set_hostname (self, priv->orig_hostname, "reset dhcp hostname");
priv->dhcp_hostname = FALSE;
}
return;
}
priv->dhcp_hostname = FALSE;
if (!best4 && !best6) {
/* No best device; fall back to the last hostname set externally