summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2018-11-02 12:07:09 +0100
committerThomas Haller <thaller@redhat.com>2018-11-13 19:09:34 +0100
commit7ffbf7127603a935236785f6a59a104583194df4 (patch)
tree082e275a7469ffeac7e81da9b9eaefbfe33a3dc0
parentab314065b8928c12347b40b25f200020c59fcbda (diff)
downloadNetworkManager-7ffbf7127603a935236785f6a59a104583194df4.tar.gz
all: add "${MAC}" substituion for "connection.stable-id"
We already had "${DEVICE}" which uses the interface name. In times of predictable interface naming, that works well. It allows the user to generate IDs per device which don't change when the hardware is replaced. "${MAC}" is similar, except that is uses the permanent MAC address of the device. The substitution results in the empty word, if the device has no permanent MAC address (like software devices). The per-device substitutions "${DEVICE}" and "${MAC}" are especially interesting with "connection.multi-connect=multiple".
-rw-r--r--clients/common/settings-docs.h.in2
-rw-r--r--libnm-core/nm-setting-connection.c4
-rw-r--r--src/devices/nm-device.c8
-rw-r--r--src/nm-core-utils.c3
-rw-r--r--src/nm-core-utils.h1
-rw-r--r--src/tests/test-general.c3
6 files changed, 17 insertions, 4 deletions
diff --git a/clients/common/settings-docs.h.in b/clients/common/settings-docs.h.in
index 8ce156e112..3030cc761c 100644
--- a/clients/common/settings-docs.h.in
+++ b/clients/common/settings-docs.h.in
@@ -144,7 +144,7 @@
#define DESCRIBE_DOC_NM_SETTING_CONNECTION_READ_ONLY N_("FALSE if the connection can be modified using the provided settings service's D-Bus interface with the right privileges, or TRUE if the connection is read-only and cannot be modified.")
#define DESCRIBE_DOC_NM_SETTING_CONNECTION_SECONDARIES N_("List of connection UUIDs that should be activated when the base connection itself is activated. Currently only VPN connections are supported.")
#define DESCRIBE_DOC_NM_SETTING_CONNECTION_SLAVE_TYPE N_("Setting name of the device type of this slave's master connection (eg, \"bond\"), or NULL if this connection is not a slave.")
-#define DESCRIBE_DOC_NM_SETTING_CONNECTION_STABLE_ID N_("This represents the identity of the connection used for various purposes. It allows to configure multiple profiles to share the identity. Also, the stable-id can contain placeholders that are substituted dynamically and deterministically depending on the context. The stable-id is used for generating IPv6 stable private addresses with ipv6.addr-gen-mode=stable-privacy. It is also used to seed the generated cloned MAC address for ethernet.cloned-mac-address=stable and wifi.cloned-mac-address=stable. It is also used as DHCP client identifier with ipv4.dhcp-client-id=stable and to derive the DHCP DUID with ipv6.dhcp-duid=stable-[llt,ll,uuid]. Note that depending on the context where it is used, other parameters are also seeded into the generation algorithm. For example, a per-host key is commonly also included, so that different systems end up generating different IDs. Or with ipv6.addr-gen-mode=stable-privacy, also the device's name is included, so that different interfaces yield different addresses. The '$' character is treated special to perform dynamic substitutions at runtime. Currently supported are \"${CONNECTION}\", \"${DEVICE}\", \"${BOOT}\", \"${RANDOM}\". These effectively create unique IDs per-connection, per-device, per-boot, or every time. Note that \"${DEVICE}\" corresponds the the interface name of the device. Any unrecognized patterns following '$' are treated verbatim, however are reserved for future use. You are thus advised to avoid '$' or escape it as \"$$\". For example, set it to \"${CONNECTION}-${BOOT}-${DEVICE}\" to create a unique id for this connection that changes with every reboot and differs depending on the interface where the profile activates. If the value is unset, a global connection default is consulted. If the value is still unset, the default is similar to \"${CONNECTION}\" and uses a unique, fixed ID for the connection.")
+#define DESCRIBE_DOC_NM_SETTING_CONNECTION_STABLE_ID N_("This represents the identity of the connection used for various purposes. It allows to configure multiple profiles to share the identity. Also, the stable-id can contain placeholders that are substituted dynamically and deterministically depending on the context. The stable-id is used for generating IPv6 stable private addresses with ipv6.addr-gen-mode=stable-privacy. It is also used to seed the generated cloned MAC address for ethernet.cloned-mac-address=stable and wifi.cloned-mac-address=stable. It is also used as DHCP client identifier with ipv4.dhcp-client-id=stable and to derive the DHCP DUID with ipv6.dhcp-duid=stable-[llt,ll,uuid]. Note that depending on the context where it is used, other parameters are also seeded into the generation algorithm. For example, a per-host key is commonly also included, so that different systems end up generating different IDs. Or with ipv6.addr-gen-mode=stable-privacy, also the device's name is included, so that different interfaces yield different addresses. The '$' character is treated special to perform dynamic substitutions at runtime. Currently supported are \"${CONNECTION}\", \"${DEVICE}\", \"${MAC}\", \"${BOOT}\", \"${RANDOM}\". These effectively create unique IDs per-connection, per-device, per-boot, or every time. Note that \"${DEVICE}\" corresponds the the interface name of the device and \"${MAC}\" is the permanent MAC address of the device. Any unrecognized patterns following '$' are treated verbatim, however are reserved for future use. You are thus advised to avoid '$' or escape it as \"$$\". For example, set it to \"${CONNECTION}-${BOOT}-${DEVICE}\" to create a unique id for this connection that changes with every reboot and differs depending on the interface where the profile activates. If the value is unset, a global connection default is consulted. If the value is still unset, the default is similar to \"${CONNECTION}\" and uses a unique, fixed ID for the connection.")
#define DESCRIBE_DOC_NM_SETTING_CONNECTION_TIMESTAMP N_("The time, in seconds since the Unix Epoch, that the connection was last _successfully_ fully activated. NetworkManager updates the connection timestamp periodically when the connection is active to ensure that an active connection has the latest timestamp. The property is only meant for reading (changes to this property will not be preserved).")
#define DESCRIBE_DOC_NM_SETTING_CONNECTION_TYPE N_("Base type of the connection. For hardware-dependent connections, should contain the setting name of the hardware-type specific setting (ie, \"802-3-ethernet\" or \"802-11-wireless\" or \"bluetooth\", etc), and for non-hardware dependent connections like VPN or otherwise, should contain the setting name of that setting type (ie, \"vpn\" or \"bridge\", etc).")
#define DESCRIBE_DOC_NM_SETTING_CONNECTION_UUID N_("A universally unique identifier for the connection, for example generated with libuuid. It should be assigned when the connection is created, and never changed as long as the connection still applies to the same network. For example, it should not be changed when the \"id\" property or NMSettingIP4Config changes, but might need to be re-created when the Wi-Fi SSID, mobile broadband network provider, or \"type\" property changes. The UUID must be in the format \"2815492f-7e56-435e-b2e9-246bd7cdc664\" (ie, contains only hexadecimal characters and \"-\").")
diff --git a/libnm-core/nm-setting-connection.c b/libnm-core/nm-setting-connection.c
index 1731afa66e..3c3a4dcee5 100644
--- a/libnm-core/nm-setting-connection.c
+++ b/libnm-core/nm-setting-connection.c
@@ -1626,11 +1626,11 @@ nm_setting_connection_class_init (NMSettingConnectionClass *klass)
* name is included, so that different interfaces yield different addresses.
*
* The '$' character is treated special to perform dynamic substitutions
- * at runtime. Currently supported are "${CONNECTION}", "${DEVICE}",
+ * at runtime. Currently supported are "${CONNECTION}", "${DEVICE}", "${MAC}",
* "${BOOT}", "${RANDOM}".
* These effectively create unique IDs per-connection, per-device, per-boot,
* or every time. Note that "${DEVICE}" corresponds the the interface name of the
- * device.
+ * device and "${MAC}" is the permanent MAC address of the device.
* Any unrecognized patterns following '$' are treated verbatim, however
* are reserved for future use. You are thus advised to avoid '$' or
* escape it as "$$".
diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c
index a0cdb3d235..862eb60c7c 100644
--- a/src/devices/nm-device.c
+++ b/src/devices/nm-device.c
@@ -1268,6 +1268,8 @@ _get_stable_id (NMDevice *self,
gs_free char *generated = NULL;
NMUtilsStableType stable_type;
NMSettingConnection *s_con;
+ gboolean hwaddr_is_fake;
+ const char *hwaddr;
const char *stable_id;
const char *uuid;
@@ -1284,8 +1286,14 @@ _get_stable_id (NMDevice *self,
uuid = nm_connection_get_uuid (connection);
+ /* the cloned-mac-address may be generated based on the stable-id.
+ * Thus, at this point, we can only use the permanant MAC address
+ * as seed. */
+ hwaddr = nm_device_get_permanent_hw_address_full (self, TRUE, &hwaddr_is_fake);
+
stable_type = nm_utils_stable_id_parse (stable_id,
nm_device_get_ip_iface (self),
+ !hwaddr_is_fake ? hwaddr : NULL,
nm_utils_get_boot_id_str (),
uuid,
&generated);
diff --git a/src/nm-core-utils.c b/src/nm-core-utils.c
index 6199465c16..0ad28c8244 100644
--- a/src/nm-core-utils.c
+++ b/src/nm-core-utils.c
@@ -2890,6 +2890,7 @@ _stable_id_append (GString *str,
NMUtilsStableType
nm_utils_stable_id_parse (const char *stable_id,
const char *deviceid,
+ const char *hwaddr,
const char *bootid,
const char *uuid,
char **out_generated)
@@ -2968,6 +2969,8 @@ nm_utils_stable_id_parse (const char *stable_id,
_stable_id_append (str, bootid);
else if (CHECK_PREFIX ("${DEVICE}"))
_stable_id_append (str, deviceid);
+ else if (CHECK_PREFIX ("${MAC}"))
+ _stable_id_append (str, hwaddr);
else if (g_str_has_prefix (&stable_id[i], "${RANDOM}")) {
/* RANDOM makes not so much sense for cloned-mac-address
* as the result is similar to specyifing "cloned-mac-address=random".
diff --git a/src/nm-core-utils.h b/src/nm-core-utils.h
index 0eedc8cabb..e59ef41d11 100644
--- a/src/nm-core-utils.h
+++ b/src/nm-core-utils.h
@@ -335,6 +335,7 @@ typedef enum {
NMUtilsStableType nm_utils_stable_id_parse (const char *stable_id,
const char *deviceid,
+ const char *hwaddr,
const char *bootid,
const char *uuid,
char **out_generated);
diff --git a/src/tests/test-general.c b/src/tests/test-general.c
index c54f27f9f5..a2fb1495c4 100644
--- a/src/tests/test-general.c
+++ b/src/tests/test-general.c
@@ -1739,7 +1739,7 @@ do_test_stable_id_parse (const char *stable_id,
else
g_assert (stable_id);
- stable_type = nm_utils_stable_id_parse (stable_id, "_DEVICE", "_BOOT", "_CONNECTION", &generated);
+ stable_type = nm_utils_stable_id_parse (stable_id, "_DEVICE", "_MAC", "_BOOT", "_CONNECTION", &generated);
g_assert_cmpint (expected_stable_type, ==, stable_type);
@@ -1778,6 +1778,7 @@ test_stable_id_parse (void)
_parse_generated ("x${BOOT}", "x${BOOT}=5{_BOOT}");
_parse_generated ("x${BOOT}${CONNECTION}", "x${BOOT}=5{_BOOT}${CONNECTION}=11{_CONNECTION}");
_parse_generated ("xX${BOOT}yY${CONNECTION}zZ", "xX${BOOT}=5{_BOOT}yY${CONNECTION}=11{_CONNECTION}zZ");
+ _parse_generated ("${MAC}x", "${MAC}=4{_MAC}x");
_parse_random ("${RANDOM}");
_parse_random (" ${RANDOM}");
_parse_random ("${BOOT}${RANDOM}");