From 2ebe027b448ce729f696e0715456a054ec4a824f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Mon, 17 Jun 2019 09:21:57 +0200 Subject: [PATCH 1/3] man: clean up naming scheme description a bit This is in preparation for later changes. Let's change the documentation of net.naming-scheme= to also say that it applies to MAC addresses. This commit doesn't actually implement that though. --- man/systemd.net-naming-scheme.xml | 45 ++++++++++++++++--------------- src/udev/net/naming-scheme.h | 14 +++++----- 2 files changed, 30 insertions(+), 29 deletions(-) diff --git a/man/systemd.net-naming-scheme.xml b/man/systemd.net-naming-scheme.xml index eb8faad254e..69d8ee9b282 100644 --- a/man/systemd.net-naming-scheme.xml +++ b/man/systemd.net-naming-scheme.xml @@ -22,29 +22,30 @@ Description - Network interfaces may be renamed to give them predictable names when there's enough information to - generate appropriate names and the use of certain types of names is configured. This page describes the - first part, i.e. what possible names may be generated. Those names are generated by the + Network interfaces names and MAC addresses may be generated based on certain stable interface + attributes. This is possible when there is enough information about the device to generate those + attributes and the use of this information is configured. This page describes interface naming, i.e. what + possible names may be generated. Those names are generated by the systemd-udevd.service8 builtin net_id and exported as udev properties (ID_NET_NAME_ONBOARD=, ID_NET_LABEL_ONBOARD=, ID_NET_NAME_PATH=, ID_NET_NAME_SLOT=). - Names are derived from various device metadata attributes. Newer versions of udev take more of - these attributes into account, improving (and thus possibly changing) the names used for the same - devices. Differents version of the naming rules are called "naming schemes". The default naming scheme is - chosen at compilation time. Usually this will be the latest implemented version, but it is also possible - to set one of the older versions to preserve compatibility. This may be useful for example for - distributions, which may introduce new versions of systemd in stable releases without changing the naming - scheme. The naming scheme may also be overriden using the net.naming-scheme= kernel - command line switch, see + Names and MAC addresses are derived from various stable device metadata attributes. Newer versions + of udev take more of these attributes into account, improving (and thus possibly changing) the names and + addresses used for the same devices. Different versions of those generation rules are called "naming + schemes". The default naming scheme is chosen at compilation time. Usually this will be the latest + implemented version, but it is also possible to set one of the older versions to preserve + compatibility. This may be useful for example for distributions, which may introduce new versions of + systemd in stable releases without changing the naming scheme. The naming scheme may also be overriden + using the net.naming-scheme= kernel command line switch, see systemd-udevd.service8. Available naming schemes are described below. After the udev proprties have been generated, appropriate udev rules may be used to actually rename - devices based on those properties. See the description of NamePolicy= in - systemd.link5. - + devices based on those properties. See the description of NamePolicy= and + MACAddressPolicy= in + systemd.link5. @@ -288,7 +289,7 @@ v240 - The ib prefix and stable names for infiniband devices are + The ib prefix and stable names for infiniband devices are introduced. Previously those devices were not renamed. The ACPI index field (used in ID_NET_NAME_ONBOARD=) is now also used when @@ -301,22 +302,22 @@ configuration, even if they have been renamed already, if keep is not specified as the naming policy in the .link file. See systemd.link5 - for a description of NamePolicy=. + for a description of NamePolicy=. v243 - Support for netdevsim (simulated networking devices) was added. Previously those devices were - not renamed. + Support for renaming netdevsim (simulated networking) devices was added. Previously + those devices were not renamed. Previously two-letter interface type prefix was prepended to - ID_NET_LABEL_ONBOARD=. This is not done anymore. + ID_NET_LABEL_ONBOARD=. This is not done anymore. - - Note that latest may be used to denote the latest scheme known (to this - particular version of systemd. + + Note that latest may be used to denote the latest scheme known (to this + particular version of systemd. diff --git a/src/udev/net/naming-scheme.h b/src/udev/net/naming-scheme.h index 4061eec99e7..584fea876c2 100644 --- a/src/udev/net/naming-scheme.h +++ b/src/udev/net/naming-scheme.h @@ -22,13 +22,13 @@ * OS versions, but not fully stabilize them. */ typedef enum NamingSchemeFlags { /* First, the individual features */ - NAMING_SR_IOV_V = 1 << 0, /* Use "v" suffix for SR-IOV, see 609948c7043a40008b8299529c978ed8e11de8f6*/ - NAMING_NPAR_ARI = 1 << 1, /* Use NPAR "ARI", see 6bc04997b6eab35d1cb9fa73889892702c27be09 */ - NAMING_INFINIBAND = 1 << 2, /* Use "ib" prefix for infiniband, see 938d30aa98df887797c9e05074a562ddacdcdf5e */ - NAMING_ZERO_ACPI_INDEX = 1 << 3, /* Use zero acpi_index field, see d81186ef4f6a888a70f20a1e73a812d6acb9e22f */ - NAMING_ALLOW_RERENAMES = 1 << 4, /* Allow re-renaming of devices, see #9006 */ - NAMING_NETDEVSIM = 1 << 5, /* Generate names for netdevsim devices, see eaa9d507d85509c8bf727356e3884ec54b0fc646 */ - NAMING_LABEL_NOPREFIX = 1 << 6, /* Don't prepend ID_NET_LABEL_ONBOARD with interface type prefix */ + NAMING_SR_IOV_V = 1 << 0, /* Use "v" suffix for SR-IOV, see 609948c7043a */ + NAMING_NPAR_ARI = 1 << 1, /* Use NPAR "ARI", see 6bc04997b6ea */ + NAMING_INFINIBAND = 1 << 2, /* Use "ib" prefix for infiniband, see 938d30aa98df */ + NAMING_ZERO_ACPI_INDEX = 1 << 3, /* Use zero acpi_index field, see d81186ef4f6a */ + NAMING_ALLOW_RERENAMES = 1 << 4, /* Allow re-renaming of devices, see #9006 */ + NAMING_NETDEVSIM = 1 << 5, /* Generate names for netdevsim devices, see eaa9d507d855 */ + NAMING_LABEL_NOPREFIX = 1 << 6, /* Don't prepend ID_NET_LABEL_ONBOARD with interface type prefix */ /* And now the masks that combine the features above */ NAMING_V238 = 0, From b889a0ded8ef41e19ea0e64d0afa657e864134ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Mon, 17 Jun 2019 13:38:40 +0200 Subject: [PATCH 2/3] libsystemd-network: rename net_get_name() to net_get_name_persistent() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reflect its role better. (I didn't use …_persistent_name(), because which name is actually used depends on the policy. So it's better not to make this sound like it returns *the* persistent name.) --- src/libsystemd-network/dhcp-identifier.c | 2 +- src/libsystemd-network/network-internal.c | 8 ++++---- src/libsystemd-network/network-internal.h | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/libsystemd-network/dhcp-identifier.c b/src/libsystemd-network/dhcp-identifier.c index 0c1ff34e5de..c01c1cf6d6f 100644 --- a/src/libsystemd-network/dhcp-identifier.c +++ b/src/libsystemd-network/dhcp-identifier.c @@ -190,7 +190,7 @@ int dhcp_identifier_set_iaid( /* device is under renaming */ return -EBUSY; - name = net_get_name(device); + name = net_get_name_persistent(device); } } diff --git a/src/libsystemd-network/network-internal.c b/src/libsystemd-network/network-internal.c index a112b9f70f9..1a588f10d36 100644 --- a/src/libsystemd-network/network-internal.c +++ b/src/libsystemd-network/network-internal.c @@ -24,7 +24,7 @@ #include "utf8.h" #include "util.h" -const char *net_get_name(sd_device *device) { +const char *net_get_name_persistent(sd_device *device) { const char *name, *field; assert(device); @@ -47,9 +47,9 @@ int net_get_unique_predictable_data(sd_device *device, uint64_t *result) { assert(device); - /* net_get_name() will return one of the device names based on stable information about the - * device. If this is not available, we fall back to using the device name. */ - name = net_get_name(device); + /* net_get_name_persistent() will return one of the device names based on stable information about + * the device. If this is not available, we fall back to using the actual device name. */ + name = net_get_name_persistent(device); if (!name) (void) sd_device_get_sysname(device, &name); if (!name) diff --git a/src/libsystemd-network/network-internal.h b/src/libsystemd-network/network-internal.h index 62f5a4a76c5..bb2bd8b35b1 100644 --- a/src/libsystemd-network/network-internal.h +++ b/src/libsystemd-network/network-internal.h @@ -33,7 +33,7 @@ CONFIG_PARSER_PROTOTYPE(config_parse_ifalias); CONFIG_PARSER_PROTOTYPE(config_parse_bridge_port_priority); int net_get_unique_predictable_data(sd_device *device, uint64_t *result); -const char *net_get_name(sd_device *device); +const char *net_get_name_persistent(sd_device *device); size_t serialize_in_addrs(FILE *f, const struct in_addr *addresses, From 96848152fa5e502673f31361ba998701aaa9bda3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Mon, 17 Jun 2019 09:42:46 +0200 Subject: [PATCH 3/3] udev: introduce NAMING_STABLE_VIRTUAL_MACS (retroactively) This is for 6d3646406560. It turns out that this is causing more problems than expected. Let's retroactively introduce naming scheme v241 to conditionalize this change. Follow-up for #12792 and 6d36464065601f7. See also https://bugzilla.suse.com/show_bug.cgi?id=1136600. $ SYSTEMD_LOG_LEVEL=debug NET_NAMING_SCHEME=v240 build/udevadm test-builtin net_setup_link /sys/class/net/br11 $ SYSTEMD_LOG_LEVEL=debug NET_NAMING_SCHEME=v241 build/udevadm test-builtin net_setup_link /sys/class/net/br11 ... @@ -20,11 +20,13 @@ link_config: could not set ethtool features for br11 Could not set offload features of br11: Operation not permitted br11: Device has name_assign_type=3 -Using interface naming scheme 'v240'. +Using interface naming scheme 'v241'. br11: Policy *keep*: keeping existing userspace name br11: Device has addr_assign_type=1 -br11: No stable identifying information found -br11: Could not generate persistent MAC: No data available +br11: Using "br11" as stable identifying information +br11: Using generated persistent MAC address +Could not set Alias=, MACAddress= or MTU= on br11: Operation not permitted +br11: Could not apply link config, ignoring: Operation not permitted Unload module index Unloaded link configuration context. ID_NET_DRIVER=bridge --- man/systemd.net-naming-scheme.xml | 15 +++++++++++++++ src/libsystemd-network/network-internal.c | 4 ++-- src/libsystemd-network/network-internal.h | 2 +- src/network/networkd-ipv4ll.c | 2 +- src/udev/net/link-config.c | 5 ++++- src/udev/net/naming-scheme.c | 1 + src/udev/net/naming-scheme.h | 8 +++++--- 7 files changed, 29 insertions(+), 8 deletions(-) diff --git a/man/systemd.net-naming-scheme.xml b/man/systemd.net-naming-scheme.xml index 69d8ee9b282..4caac111562 100644 --- a/man/systemd.net-naming-scheme.xml +++ b/man/systemd.net-naming-scheme.xml @@ -305,6 +305,21 @@ for a description of NamePolicy=. + + v241 + + was extended to set MAC addresses + based on the device name. Previously addresses were only based on the + ID_NET_NAME_* attributes, which meant that interface names would + never be generated for virtual devices. Now a persistent address will be generated for most + devices, including in particular bridges. + + Note: when userspace does not set a MAC address for a bridge device, the kernel will + initially assign a random address, and then change it when the first device is enslaved to the + bridge. With this naming policy change, bridges get a persistent MAC address based on the bridge + name instead of the first enslaved device. + + v243 diff --git a/src/libsystemd-network/network-internal.c b/src/libsystemd-network/network-internal.c index 1a588f10d36..9a1b2fba89b 100644 --- a/src/libsystemd-network/network-internal.c +++ b/src/libsystemd-network/network-internal.c @@ -39,7 +39,7 @@ const char *net_get_name_persistent(sd_device *device) { #define HASH_KEY SD_ID128_MAKE(d3,1e,48,fa,90,fe,4b,4c,9d,af,d5,d7,a1,b1,2e,8a) -int net_get_unique_predictable_data(sd_device *device, uint64_t *result) { +int net_get_unique_predictable_data(sd_device *device, bool use_sysname, uint64_t *result) { size_t l, sz = 0; const char *name; int r; @@ -50,7 +50,7 @@ int net_get_unique_predictable_data(sd_device *device, uint64_t *result) { /* net_get_name_persistent() will return one of the device names based on stable information about * the device. If this is not available, we fall back to using the actual device name. */ name = net_get_name_persistent(device); - if (!name) + if (!name && use_sysname) (void) sd_device_get_sysname(device, &name); if (!name) return log_device_debug_errno(device, SYNTHETIC_ERRNO(ENODATA), diff --git a/src/libsystemd-network/network-internal.h b/src/libsystemd-network/network-internal.h index bb2bd8b35b1..ebfb1c3c754 100644 --- a/src/libsystemd-network/network-internal.h +++ b/src/libsystemd-network/network-internal.h @@ -32,7 +32,7 @@ CONFIG_PARSER_PROTOTYPE(config_parse_ifnames); CONFIG_PARSER_PROTOTYPE(config_parse_ifalias); CONFIG_PARSER_PROTOTYPE(config_parse_bridge_port_priority); -int net_get_unique_predictable_data(sd_device *device, uint64_t *result); +int net_get_unique_predictable_data(sd_device *device, bool use_sysname, uint64_t *result); const char *net_get_name_persistent(sd_device *device); size_t serialize_in_addrs(FILE *f, diff --git a/src/network/networkd-ipv4ll.c b/src/network/networkd-ipv4ll.c index 9df5646a7e6..738d22cb5bc 100644 --- a/src/network/networkd-ipv4ll.c +++ b/src/network/networkd-ipv4ll.c @@ -210,7 +210,7 @@ int ipv4ll_configure(Link *link) { } if (link->sd_device && - net_get_unique_predictable_data(link->sd_device, &seed) >= 0) { + net_get_unique_predictable_data(link->sd_device, true, &seed) >= 0) { r = sd_ipv4ll_set_address_seed(link->ipv4ll, seed); if (r < 0) return r; diff --git a/src/udev/net/link-config.c b/src/udev/net/link-config.c index a4e10ff988b..b983f28f2fb 100644 --- a/src/udev/net/link-config.c +++ b/src/udev/net/link-config.c @@ -318,10 +318,13 @@ static int get_mac(sd_device *device, MACAddressPolicy policy, struct ether_addr } else { uint64_t result; - r = net_get_unique_predictable_data(device, &result); + r = net_get_unique_predictable_data(device, + naming_scheme_has(NAMING_STABLE_VIRTUAL_MACS), + &result); if (r < 0) return log_device_warning_errno(device, r, "Could not generate persistent MAC: %m"); + log_device_debug(device, "Using generated persistent MAC address"); assert_cc(ETH_ALEN <= sizeof(result)); memcpy(mac->ether_addr_octet, &result, ETH_ALEN); } diff --git a/src/udev/net/naming-scheme.c b/src/udev/net/naming-scheme.c index 8223f9cda17..0d7f413e9e0 100644 --- a/src/udev/net/naming-scheme.c +++ b/src/udev/net/naming-scheme.c @@ -8,6 +8,7 @@ static const NamingScheme naming_schemes[] = { { "v238", NAMING_V238 }, { "v239", NAMING_V239 }, { "v240", NAMING_V240 }, + { "v241", NAMING_V241 }, { "v243", NAMING_V243 }, /* … add more schemes here, as the logic to name devices is updated … */ }; diff --git a/src/udev/net/naming-scheme.h b/src/udev/net/naming-scheme.h index 584fea876c2..38dfa75f9bf 100644 --- a/src/udev/net/naming-scheme.h +++ b/src/udev/net/naming-scheme.h @@ -27,14 +27,16 @@ typedef enum NamingSchemeFlags { NAMING_INFINIBAND = 1 << 2, /* Use "ib" prefix for infiniband, see 938d30aa98df */ NAMING_ZERO_ACPI_INDEX = 1 << 3, /* Use zero acpi_index field, see d81186ef4f6a */ NAMING_ALLOW_RERENAMES = 1 << 4, /* Allow re-renaming of devices, see #9006 */ - NAMING_NETDEVSIM = 1 << 5, /* Generate names for netdevsim devices, see eaa9d507d855 */ - NAMING_LABEL_NOPREFIX = 1 << 6, /* Don't prepend ID_NET_LABEL_ONBOARD with interface type prefix */ + NAMING_STABLE_VIRTUAL_MACS = 1 << 5, /* Use device name to generate MAC, see 6d3646406560 */ + NAMING_NETDEVSIM = 1 << 6, /* Generate names for netdevsim devices, see eaa9d507d855 */ + NAMING_LABEL_NOPREFIX = 1 << 7, /* Don't prepend ID_NET_LABEL_ONBOARD with interface type prefix */ /* And now the masks that combine the features above */ NAMING_V238 = 0, NAMING_V239 = NAMING_V238 | NAMING_SR_IOV_V | NAMING_NPAR_ARI, NAMING_V240 = NAMING_V239 | NAMING_INFINIBAND | NAMING_ZERO_ACPI_INDEX | NAMING_ALLOW_RERENAMES, - NAMING_V243 = NAMING_V240 | NAMING_NETDEVSIM | NAMING_LABEL_NOPREFIX, + NAMING_V241 = NAMING_V240 | NAMING_STABLE_VIRTUAL_MACS, + NAMING_V243 = NAMING_V241 | NAMING_NETDEVSIM | NAMING_LABEL_NOPREFIX, _NAMING_SCHEME_FLAGS_INVALID = -1, } NamingSchemeFlags;