]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
udev: add debug logging about the choice of MAC
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Sat, 19 Jan 2019 14:19:03 +0000 (15:19 +0100)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Mon, 21 Jan 2019 16:33:53 +0000 (17:33 +0100)
src/udev/net/link-config.c

index 0fda4d16b9a02c9b98abe082a5abd0b50222c613..60da08a86ff390c28e6cccbc7a34c118c0a88545 100644 (file)
@@ -187,19 +187,19 @@ static bool enable_name_policy(void) {
         return proc_cmdline_get_bool("net.ifnames", &b) <= 0 || b;
 }
 
-static int link_name_type(sd_device *device, unsigned *type) {
+static int link_unsigned_attribute(sd_device *device, const char *attr, unsigned *type) {
         const char *s;
         int r;
 
-        r = sd_device_get_sysattr_value(device, "name_assign_type", &s);
+        r = sd_device_get_sysattr_value(device, attr, &s);
         if (r < 0)
-                return log_device_debug_errno(device, r, "Failed to query name_assign_type: %m");
+                return log_device_debug_errno(device, r, "Failed to query %s: %m", attr);
 
         r = safe_atou(s, type);
         if (r < 0)
-                return log_device_warning_errno(device, r, "Failed to parse name_assign_type \"%s\": %m", s);
+                return log_device_warning_errno(device, r, "Failed to parse %s \"%s\": %m", attr, s);
 
-        log_device_debug(device, "Device has name_assign_type=%d", *type);
+        log_device_debug(device, "Device has %s=%u", attr, *type);
         return 0;
 }
 
@@ -265,11 +265,9 @@ int link_config_get(link_config_ctx *ctx, sd_device *device, link_config **ret)
                                      devtype,
                                      sysname)) {
                         if (link->match_name) {
-                                unsigned char name_assign_type = NET_NAME_UNKNOWN;
-                                const char *attr_value;
+                                unsigned name_assign_type = NET_NAME_UNKNOWN;
 
-                                if (sd_device_get_sysattr_value(device, "name_assign_type", &attr_value) >= 0)
-                                        (void) safe_atou8(attr_value, &name_assign_type);
+                                (void) link_unsigned_attribute(device, "name_assign_type", &name_assign_type);
 
                                 if (name_assign_type == NET_NAME_ENUM) {
                                         log_warning("Config file %s applies to device based on potentially unpredictable interface name '%s'",
@@ -297,33 +295,41 @@ int link_config_get(link_config_ctx *ctx, sd_device *device, link_config **ret)
         return -ENOENT;
 }
 
-static bool mac_is_random(sd_device *device) {
-        const char *s;
-        unsigned type;
+static int get_mac(sd_device *device, MACPolicy policy, struct ether_addr *mac) {
+        unsigned addr_type;
+        bool want_random = policy == MACPOLICY_RANDOM;
         int r;
 
-        /* if we can't get the assign type, assume it is not random */
-        if (sd_device_get_sysattr_value(device, "addr_assign_type", &s) < 0)
-                return false;
+        assert(IN_SET(policy, MACPOLICY_RANDOM, MACPOLICY_PERSISTENT));
 
-        r = safe_atou(s, &type);
+        r = link_unsigned_attribute(device, "addr_assign_type", &addr_type);
         if (r < 0)
-                return false;
-
-        return type == NET_ADDR_RANDOM;
-}
+                return r;
+        switch (addr_type) {
+        case NET_ADDR_SET:
+                return log_device_debug(device, "MAC on the device already set by userspace");
+        case NET_ADDR_STOLEN:
+                return log_device_debug(device, "MAC on the device already set based on another device");
+        case NET_ADDR_RANDOM:
+        case NET_ADDR_PERM:
+                break;
+        default:
+                return log_device_warning(device, "Unknown addr_assign_type %u, ignoring", addr_type);
+        }
 
-static int get_mac(sd_device *device, bool want_random, struct ether_addr *mac) {
-        int r;
+        if (want_random == (addr_type == NET_ADDR_RANDOM))
+                return log_device_debug(device, "MAC on the device already matches policy *%s*",
+                                        mac_policy_to_string(policy));
 
-        if (want_random)
+        if (want_random) {
+                log_device_debug(device, "Using random bytes to generate MAC");
                 random_bytes(mac->ether_addr_octet, ETH_ALEN);
-        else {
+        else {
                 uint64_t result;
 
                 r = net_get_unique_predictable_data(device, &result);
                 if (r < 0)
-                        return r;
+                        return log_device_warning_errno(device, r, "Could not generate persistent MAC: %m");
 
                 assert_cc(ETH_ALEN <= sizeof(result));
                 memcpy(mac->ether_addr_octet, &result, ETH_ALEN);
@@ -332,8 +338,7 @@ static int get_mac(sd_device *device, bool want_random, struct ether_addr *mac)
         /* see eth_random_addr in the kernel */
         mac->ether_addr_octet[0] &= 0xfe;  /* clear multicast bit */
         mac->ether_addr_octet[0] |= 0x02;  /* set local assignment bit (IEEE802) */
-
-        return 0;
+        return 1;
 }
 
 int link_config_apply(link_config_ctx *ctx, link_config *config,
@@ -397,7 +402,7 @@ int link_config_apply(link_config_ctx *ctx, link_config *config,
                 return log_device_warning_errno(device, r, "Could not find ifindex: %m");
 
 
-        (void) link_name_type(device, &name_type);
+        (void) link_unsigned_attribute(device, "name_assign_type", &name_type);
 
         if (IN_SET(name_type, NET_NAME_USER, NET_NAME_RENAMED)
             && !naming_scheme_has(NAMING_ALLOW_RERENAMES)) {
@@ -454,33 +459,11 @@ int link_config_apply(link_config_ctx *ctx, link_config *config,
                 log_device_debug(device, "Policies didn't yield a name and Name= is not given, not renaming.");
  no_rename:
 
-        switch (config->mac_policy) {
-                case MACPOLICY_PERSISTENT:
-                        if (mac_is_random(device)) {
-                                r = get_mac(device, false, &generated_mac);
-                                if (r == -ENODATA) {
-                                        log_warning_errno(r, "Could not generate persistent MAC address for %s: %m", old_name);
-                                        break;
-                                } else if (r < 0)
-                                        return r;
-                                mac = &generated_mac;
-                        }
-                        break;
-                case MACPOLICY_RANDOM:
-                        if (!mac_is_random(device)) {
-                                r = get_mac(device, true, &generated_mac);
-                                if (r == -ENODATA) {
-                                        log_warning_errno(r, "Could not generate random MAC address for %s: %m", old_name);
-                                        break;
-                                } else if (r < 0)
-                                        return r;
-                                mac = &generated_mac;
-                        }
-                        break;
-                case MACPOLICY_NONE:
-                default:
-                        mac = config->mac;
-        }
+        if (IN_SET(config->mac_policy, MACPOLICY_PERSISTENT, MACPOLICY_RANDOM)) {
+                if (get_mac(device, config->mac_policy, &generated_mac) > 0)
+                        mac = &generated_mac;
+        } else
+                mac = config->mac;
 
         r = rtnl_set_link_properties(&ctx->rtnl, ifindex, config->alias, mac, config->mtu);
         if (r < 0)