From 96848152fa5e502673f31361ba998701aaa9bda3 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Mon, 17 Jun 2019 09:42:46 +0200 Subject: [PATCH] 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; -- 2.39.2