+static bool enable_name_policy(void) {
+ _cleanup_free_ char *line;
+ char *w, *state;
+ int r;
+ size_t l;
+
+ r = read_one_line_file("/proc/cmdline", &line);
+ if (r < 0) {
+ log_warning("Failed to read /proc/cmdline, ignoring: %s", strerror(-r));
+ return true; /* something is very wrong, let's not make it worse */
+ }
+
+ FOREACH_WORD_QUOTED(w, l, line, state)
+ if (strneq(w, "net.ifnames=0", l))
+ return false;
+
+ return true;
+}
+
+static bool mac_is_random(struct udev_device *device) {
+ const char *s;
+ unsigned type;
+ int r;
+
+ s = udev_device_get_sysattr_value(device, "addr_assign_type");
+ if (!s)
+ return false; /* if we don't know, assume it is not random */
+ r = safe_atou(s, &type);
+ if (r < 0)
+ return false;
+
+ /* check for NET_ADDR_RANDOM */
+ return type == 1;
+}
+
+static bool mac_is_permanent(struct udev_device *device) {
+ const char *s;
+ unsigned type;
+ int r;
+
+ s = udev_device_get_sysattr_value(device, "addr_assign_type");
+ if (!s)
+ return true; /* if we don't know, assume it is permanent */
+ r = safe_atou(s, &type);
+ if (r < 0)
+ return true;
+
+ /* check for NET_ADDR_PERM */
+ return type == 0;
+}
+
+static int get_mac(struct udev_device *device, bool want_random, struct ether_addr *mac) {
+ unsigned int seed;
+ int r, i;
+
+ if (want_random)
+ seed = random_u();
+ else {
+ const char *name;
+ sd_id128_t machine;
+ char machineid_buf[33];
+ const char *seed_str;
+
+ /* fetch some persistent data unique (on this machine) to this device */
+ name = udev_device_get_property_value(device, "ID_NET_NAME_ONBOARD");
+ if (!name) {
+ name = udev_device_get_property_value(device, "ID_NET_NAME_SLOT");
+ if (!name) {
+ name = udev_device_get_property_value(device, "ID_NET_NAME_PATH");
+ if (!name)
+ return -ENOENT;
+ }
+ }
+ /* fetch some persistent data unique to this machine */
+ r = sd_id128_get_machine(&machine);
+ if (r < 0)
+ return r;
+
+ /* combine the data */
+ seed_str = strappenda(name, sd_id128_to_string(machine, machineid_buf));
+
+ /* hash to get seed */
+ seed = string_hash_func(seed_str);
+ }
+
+ srandom(seed);
+
+ for(i = 0; i < ETH_ALEN; i++) {
+ mac->ether_addr_octet[i] = random();
+ }
+
+ /* 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;
+}
+