summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBeniamino Galvani <bgalvani@redhat.com>2019-10-21 10:52:56 +0200
committerBeniamino Galvani <bgalvani@redhat.com>2019-11-11 10:33:31 +0100
commit37a10e9ba4529246d6d2f6b7992df4d2be0a8862 (patch)
treec42054f6556ae8cd2db98364c06234976f04df90
parent6f16e524be3c7a6c79599f9b938d84131026a926 (diff)
downloadNetworkManager-bg/dhcp-iaid-rh1749358.tar.gz
all: support 'stable' DHCP IAIDbg/dhcp-iaid-rh1749358
Support a new DHCP IAID special value 'stable' that generates the IAID based on the stable-id, a per-host key and the interface name.
-rw-r--r--clients/common/settings-docs.h.in4
-rw-r--r--libnm-core/nm-setting-ip-config.c18
-rw-r--r--shared/nm-libnm-core-intern/nm-common-macros.h4
-rw-r--r--src/devices/nm-device.c23
4 files changed, 38 insertions, 11 deletions
diff --git a/clients/common/settings-docs.h.in b/clients/common/settings-docs.h.in
index 93e732481a..774adcbb17 100644
--- a/clients/common/settings-docs.h.in
+++ b/clients/common/settings-docs.h.in
@@ -207,7 +207,7 @@
#define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_DHCP_CLIENT_ID N_("A string sent to the DHCP server to identify the local machine which the DHCP server may use to customize the DHCP lease and options. When the property is a hex string ('aa:bb:cc') it is interpreted as a binary client ID, in which case the first byte is assumed to be the 'type' field as per RFC 2132 section 9.14 and the remaining bytes may be an hardware address (e.g. '01:xx:xx:xx:xx:xx:xx' where 1 is the Ethernet ARP type and the rest is a MAC address). If the property is not a hex string it is considered as a non-hardware-address client ID and the 'type' field is set to 0. The special values \"mac\" and \"perm-mac\" are supported, which use the current or permanent MAC address of the device to generate a client identifier with type ethernet (01). Currently, these options only work for ethernet type of links. The special value \"duid\" generates a RFC4361-compliant client identifier based on a hash of the interface name as IAID and /etc/machine-id. The special value \"stable\" is supported to generate a type 0 client identifier based on the stable-id (see connection.stable-id) and a per-host key. If you set the stable-id, you may want to include the \"${DEVICE}\" or \"${MAC}\" specifier to get a per-device key. If unset, a globally configured default is used. If still unset, the default depends on the DHCP plugin.")
#define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_DHCP_FQDN N_("If the \"dhcp-send-hostname\" property is TRUE, then the specified FQDN will be sent to the DHCP server when acquiring a lease. This property and \"dhcp-hostname\" are mutually exclusive and cannot be set at the same time.")
#define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_DHCP_HOSTNAME N_("If the \"dhcp-send-hostname\" property is TRUE, then the specified name will be sent to the DHCP server when acquiring a lease. This property and \"dhcp-fqdn\" are mutually exclusive and cannot be set at the same time.")
-#define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_DHCP_IAID N_("A string containing the \"Identity Association Identifier\" (IAID) used by the DHCP client. The property is a 32-bit decimal value or a special value among \"mac\", \"perm-mac\" and \"ifname\". When set to \"mac\" (or \"perm-mac\"), the last 4 bytes of the current (or permanent) MAC address are used as IAID. When set to \"ifname\", the IAID is computed by hashing the interface name. When unset, the value from global configuration is used; if no global default is set then the IAID is assumed to be \"ifname\". Note that at the moment this property is ignored for IPv6 by dhclient, which always derives the IAID from the MAC address.")
+#define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_DHCP_IAID N_("A string containing the \"Identity Association Identifier\" (IAID) used by the DHCP client. The property is a 32-bit decimal value or a special value among \"mac\", \"perm-mac\", \"ifname\" and \"stable\". When set to \"mac\" (or \"perm-mac\"), the last 4 bytes of the current (or permanent) MAC address are used as IAID. When set to \"ifname\", the IAID is computed by hashing the interface name. The special value \"stable\" can be used to generate an IAID based on the stable-id (see connection.stable-id), a per-host key and the interface name. When the property is unset, the value from global configuration is used; if no global default is set then the IAID is assumed to be \"ifname\". Note that at the moment this property is ignored for IPv6 by dhclient, which always derives the IAID from the MAC address.")
#define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_DHCP_SEND_HOSTNAME N_("If TRUE, a hostname is sent to the DHCP server when acquiring a lease. Some DHCP servers use this hostname to update DNS databases, essentially providing a static hostname for the computer. If the \"dhcp-hostname\" property is NULL and this property is TRUE, the current persistent hostname of the computer is sent.")
#define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_DHCP_TIMEOUT N_("A timeout for a DHCP transaction in seconds.")
#define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_DNS N_("Array of IP addresses of DNS servers.")
@@ -228,7 +228,7 @@
#define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_DAD_TIMEOUT N_("Timeout in milliseconds used to check for the presence of duplicate IP addresses on the network. If an address conflict is detected, the activation will fail. A zero value means that no duplicate address detection is performed, -1 means the default value (either configuration ipvx.dad-timeout override or zero). A value greater than zero is a timeout in milliseconds. The property is currently implemented only for IPv4.")
#define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_DHCP_DUID N_("A string containing the DHCPv6 Unique Identifier (DUID) used by the dhcp client to identify itself to DHCPv6 servers (RFC 3315). The DUID is carried in the Client Identifier option. If the property is a hex string ('aa:bb:cc') it is interpreted as a binary DUID and filled as an opaque value in the Client Identifier option. The special value \"lease\" will retrieve the DUID previously used from the lease file belonging to the connection. If no DUID is found and \"dhclient\" is the configured dhcp client, the DUID is searched in the system-wide dhclient lease file. If still no DUID is found, or another dhcp client is used, a global and permanent DUID-UUID (RFC 6355) will be generated based on the machine-id. The special values \"llt\" and \"ll\" will generate a DUID of type LLT or LL (see RFC 3315) based on the current MAC address of the device. In order to try providing a stable DUID-LLT, the time field will contain a constant timestamp that is used globally (for all profiles) and persisted to disk. The special values \"stable-llt\", \"stable-ll\" and \"stable-uuid\" will generate a DUID of the corresponding type, derived from the connection's stable-id and a per-host unique key. You may want to include the \"${DEVICE}\" or \"${MAC}\" specifier in the stable-id, in case this profile gets activated on multiple devices. So, the link-layer address of \"stable-ll\" and \"stable-llt\" will be a generated address derived from the stable id. The DUID-LLT time value in the \"stable-llt\" option will be picked among a static timespan of three years (the upper bound of the interval is the same constant timestamp used in \"llt\"). When the property is unset, the global value provided for \"ipv6.dhcp-duid\" is used. If no global value is provided, the default \"lease\" value is assumed.")
#define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_DHCP_HOSTNAME N_("If the \"dhcp-send-hostname\" property is TRUE, then the specified name will be sent to the DHCP server when acquiring a lease. This property and \"dhcp-fqdn\" are mutually exclusive and cannot be set at the same time.")
-#define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_DHCP_IAID N_("A string containing the \"Identity Association Identifier\" (IAID) used by the DHCP client. The property is a 32-bit decimal value or a special value among \"mac\", \"perm-mac\" and \"ifname\". When set to \"mac\" (or \"perm-mac\"), the last 4 bytes of the current (or permanent) MAC address are used as IAID. When set to \"ifname\", the IAID is computed by hashing the interface name. When unset, the value from global configuration is used; if no global default is set then the IAID is assumed to be \"ifname\". Note that at the moment this property is ignored for IPv6 by dhclient, which always derives the IAID from the MAC address.")
+#define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_DHCP_IAID N_("A string containing the \"Identity Association Identifier\" (IAID) used by the DHCP client. The property is a 32-bit decimal value or a special value among \"mac\", \"perm-mac\", \"ifname\" and \"stable\". When set to \"mac\" (or \"perm-mac\"), the last 4 bytes of the current (or permanent) MAC address are used as IAID. When set to \"ifname\", the IAID is computed by hashing the interface name. The special value \"stable\" can be used to generate an IAID based on the stable-id (see connection.stable-id), a per-host key and the interface name. When the property is unset, the value from global configuration is used; if no global default is set then the IAID is assumed to be \"ifname\". Note that at the moment this property is ignored for IPv6 by dhclient, which always derives the IAID from the MAC address.")
#define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_DHCP_SEND_HOSTNAME N_("If TRUE, a hostname is sent to the DHCP server when acquiring a lease. Some DHCP servers use this hostname to update DNS databases, essentially providing a static hostname for the computer. If the \"dhcp-hostname\" property is NULL and this property is TRUE, the current persistent hostname of the computer is sent.")
#define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_DHCP_TIMEOUT N_("A timeout for a DHCP transaction in seconds.")
#define DESCRIBE_DOC_NM_SETTING_IP6_CONFIG_DNS N_("Array of IP addresses of DNS servers.")
diff --git a/libnm-core/nm-setting-ip-config.c b/libnm-core/nm-setting-ip-config.c
index e1d54e78b5..f966a53743 100644
--- a/libnm-core/nm-setting-ip-config.c
+++ b/libnm-core/nm-setting-ip-config.c
@@ -5823,14 +5823,16 @@ nm_setting_ip_config_class_init (NMSettingIPConfigClass *klass)
*
* A string containing the "Identity Association Identifier" (IAID) used
* by the DHCP client. The property is a 32-bit decimal value or a
- * special value among "mac", "perm-mac" and "ifname". When set to "mac"
- * (or "perm-mac"), the last 4 bytes of the current (or permanent) MAC
- * address are used as IAID. When set to "ifname", the IAID is computed
- * by hashing the interface name. When unset, the value from global
- * configuration is used; if no global default is set then the IAID is
- * assumed to be "ifname". Note that at the moment this property is
- * ignored for IPv6 by dhclient, which always derives the IAID from
- * the MAC address.
+ * special value among "mac", "perm-mac", "ifname" and "stable". When
+ * set to "mac" (or "perm-mac"), the last 4 bytes of the current (or
+ * permanent) MAC address are used as IAID. When set to "ifname", the
+ * IAID is computed by hashing the interface name. The special value
+ * "stable" can be used to generate an IAID based on the stable-id (see
+ * connection.stable-id), a per-host key and the interface name. When
+ * the property is unset, the value from global configuration is used;
+ * if no global default is set then the IAID is assumed to be
+ * "ifname". Note that at the moment this property is ignored for IPv6
+ * by dhclient, which always derives the IAID from the MAC address.
*
* Since: 1.22
**/
diff --git a/shared/nm-libnm-core-intern/nm-common-macros.h b/shared/nm-libnm-core-intern/nm-common-macros.h
index 09a9822cd7..9c5ed9796f 100644
--- a/shared/nm-libnm-core-intern/nm-common-macros.h
+++ b/shared/nm-libnm-core-intern/nm-common-macros.h
@@ -44,6 +44,7 @@ NM_CLONED_MAC_IS_SPECIAL (const char *str)
#define NM_IAID_MAC "mac"
#define NM_IAID_PERM_MAC "perm-mac"
#define NM_IAID_IFNAME "ifname"
+#define NM_IAID_STABLE "stable"
static inline gboolean
NM_IAID_IS_SPECIAL (const char *str)
@@ -51,7 +52,8 @@ NM_IAID_IS_SPECIAL (const char *str)
return NM_IN_STRSET (str,
NM_IAID_MAC,
NM_IAID_PERM_MAC,
- NM_IAID_IFNAME);
+ NM_IAID_IFNAME,
+ NM_IAID_STABLE);
}
/*****************************************************************************/
diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c
index ee8ffd1f98..7c6e89fd53 100644
--- a/src/devices/nm-device.c
+++ b/src/devices/nm-device.c
@@ -7987,6 +7987,29 @@ dhcp_get_iaid (NMDevice *self,
iaid = unaligned_read_be32 (&hwaddr_buf[hwaddr_len - 4]);
goto out_good;
+ } else if (nm_streq (iaid_str, "stable")) {
+ nm_auto_free_checksum GChecksum *sum = NULL;
+ guint8 digest[NM_UTILS_CHECKSUM_LENGTH_SHA1];
+ NMUtilsStableType stable_type;
+ const char *stable_id;
+ guint32 salted_header;
+ const guint8 *host_id;
+ gsize host_id_len;
+
+ stable_id = _get_stable_id (self, connection, &stable_type);
+ salted_header = htonl (53390459 + stable_type);
+ nm_utils_host_id_get (&host_id, &host_id_len);
+ iface = nm_device_get_ip_iface (self);
+
+ sum = g_checksum_new (G_CHECKSUM_SHA1);
+ g_checksum_update (sum, (const guchar *) &salted_header, sizeof (salted_header));
+ g_checksum_update (sum, (const guchar *) stable_id, strlen (stable_id) + 1);
+ g_checksum_update (sum, (const guchar *) iface, strlen (iface) + 1);
+ g_checksum_update (sum, (const guchar *) host_id, host_id_len);
+ nm_utils_checksum_get_digest (sum, digest);
+
+ iaid = unaligned_read_be32 (digest);
+ goto out_good;
} else if ((iaid = _nm_utils_ascii_str_to_int64 (iaid_str, 10, 0, G_MAXUINT32, -1)) != -1) {
goto out_good;
} else {