udev: introduce NAMING_STABLE_VIRTUAL_MACS (retroactively) 12807/head
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Mon, 17 Jun 2019 07:42:46 +0000 (09:42 +0200)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Mon, 17 Jun 2019 11:43:18 +0000 (13:43 +0200)
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
src/libsystemd-network/network-internal.c
src/libsystemd-network/network-internal.h
src/network/networkd-ipv4ll.c
src/udev/net/link-config.c
src/udev/net/naming-scheme.c
src/udev/net/naming-scheme.h

index 69d8ee9..4caac11 100644 (file)
           for a description of <varname>NamePolicy=</varname>.</para></listitem>
         </varlistentry>
 
+        <varlistentry>
+          <term><constant>v241</constant></term>
+
+          <listitem><para><option>MACAddressPolicy=persistent</option> was extended to set MAC addresses
+          based on the device name. Previously addresses were only based on the
+          <varname noindex='true'>ID_NET_NAME_*</varname> 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.</para>
+
+          <para>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.</para></listitem>
+        </varlistentry>
+
         <varlistentry>
           <term><constant>v243</constant></term>
 
index 1a588f1..9a1b2fb 100644 (file)
@@ -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),
index bb2bd8b..ebfb1c3 100644 (file)
@@ -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,
index 9df5646..738d22c 100644 (file)
@@ -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;
index a4e10ff..b983f28 100644 (file)
@@ -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);
         }
index 8223f9c..0d7f413 100644 (file)
@@ -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 … */
 };
index 584fea8..38dfa75 100644 (file)
@@ -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;