1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
4 * Predictable network interface device names based on:
5 * - firmware/bios-provided index numbers for on-board devices
6 * - firmware-provided pci-express hotplug slot index number
7 * - physical/geographical location of the hardware
8 * - the interface's MAC address
10 * https://systemd.io/PREDICTABLE_INTERFACE_NAMES
12 * When the code here is changed, man/systemd.net-naming-scheme.xml must be updated too.
15 /* Make sure the net/if.h header is included before any linux/ one */
22 #include <linux/if_arp.h>
23 #include <linux/netdevice.h>
24 #include <linux/pci_regs.h>
26 #include "alloc-util.h"
28 #include "device-private.h"
29 #include "device-util.h"
30 #include "dirent-util.h"
31 #include "ether-addr-util.h"
34 #include "glyph-util.h"
35 #include "netif-naming-scheme.h"
36 #include "parse-util.h"
37 #include "proc-cmdline.h"
38 #include "stdio-util.h"
39 #include "string-util.h"
42 #include "udev-builtin.h"
44 #define ONBOARD_14BIT_INDEX_MAX ((1U << 14) - 1)
45 #define ONBOARD_16BIT_INDEX_MAX ((1U << 16) - 1)
47 /* skip intermediate virtio devices */
48 static sd_device
*device_skip_virtio(sd_device
*dev
) {
49 /* there can only ever be one virtio bus per parent device, so we can
50 * safely ignore any virtio buses. see
51 * http://lists.linuxfoundation.org/pipermail/virtualization/2015-August/030331.html */
53 if (!device_in_subsystem(dev
, "virtio"))
56 if (sd_device_get_parent(dev
, &dev
) < 0)
63 static int get_matching_parent(
65 char * const *parent_subsystems
,
74 r
= sd_device_get_parent(dev
, &parent
);
79 /* skip virtio subsystem if present */
80 parent
= device_skip_virtio(parent
);
85 /* check if our direct parent is in an expected subsystem. */
86 STRV_FOREACH(s
, parent_subsystems
)
87 if (device_in_subsystem(parent
, *s
)) {
96 static int get_first_syspath_component(sd_device
*dev
, const char *prefix
, char **ret
) {
97 _cleanup_free_
char *buf
= NULL
;
98 const char *syspath
, *p
, *q
;
105 r
= sd_device_get_syspath(dev
, &syspath
);
109 p
= path_startswith(syspath
, prefix
);
113 r
= path_find_first_component(&p
, /* accept_dot_dot = */ false, &q
);
121 *ret
= TAKE_PTR(buf
);
122 return r
; /* return the length of the string */
125 static int get_virtfn_info(sd_device
*pcidev
, sd_device
**ret_physfn_pcidev
, char **ret_suffix
) {
126 _cleanup_(sd_device_unrefp
) sd_device
*physfn_pcidev
= NULL
;
127 const char *syspath
, *name
;
131 assert(ret_physfn_pcidev
);
134 r
= sd_device_get_syspath(pcidev
, &syspath
);
138 /* Get physical function's pci device. */
139 r
= sd_device_new_child(&physfn_pcidev
, pcidev
, "physfn");
143 /* Find the virtual function number by finding the right virtfn link. */
144 FOREACH_DEVICE_CHILD_WITH_SUFFIX(physfn_pcidev
, child
, name
) {
147 /* Only accepts e.g. virtfn0, virtfn1, and so on. */
148 n
= startswith(name
, "virtfn");
149 if (isempty(n
) || !in_charset(n
, DIGITS
))
152 if (sd_device_get_syspath(child
, &s
) < 0)
155 if (streq(s
, syspath
)) {
158 suffix
= strjoin("v", n
);
162 *ret_physfn_pcidev
= sd_device_ref(physfn_pcidev
);
163 *ret_suffix
= suffix
;
171 static int get_dev_port(sd_device
*dev
, bool fallback_to_dev_id
, unsigned *ret
) {
178 /* Get kernel provided port index for the case when multiple ports on a single PCI function. */
180 r
= device_get_sysattr_unsigned_filtered(dev
, "dev_port", &v
);
184 /* Found a positive index. Let's use it. */
186 return 1; /* positive */
190 /* With older kernels IP-over-InfiniBand network interfaces sometimes erroneously provide the port
191 * number in the 'dev_id' sysfs attribute instead of 'dev_port', which thus stays initialized as 0. */
193 if (fallback_to_dev_id
) {
196 r
= device_get_sysattr_unsigned_filtered(dev
, "type", &iftype
);
200 fallback_to_dev_id
= (iftype
== ARPHRD_INFINIBAND
);
203 if (fallback_to_dev_id
)
204 return device_get_sysattr_unsigned_filtered(dev
, "dev_id", ret
);
206 /* Otherwise, return the original index 0. */
211 static int get_port_specifier(sd_device
*dev
, bool fallback_to_dev_id
, char **ret
) {
212 const char *phys_port_name
;
220 /* First, try to use the kernel provided front panel port name for multiple port PCI device. */
221 r
= device_get_sysattr_value_filtered(dev
, "phys_port_name", &phys_port_name
);
222 if (r
>= 0 && !isempty(phys_port_name
)) {
223 if (naming_scheme_has(NAMING_SR_IOV_R
)) {
226 /* Check if phys_port_name indicates virtual device representor. */
227 (void) sscanf(phys_port_name
, "pf%*uvf%d", &vf_id
);
230 /* For VF representor append 'r<VF_NUM>'. */
231 if (asprintf(&buf
, "r%d", vf_id
) < 0)
232 return log_oom_debug();
239 /* Otherwise, use phys_port_name as is. */
240 buf
= strjoin("n", phys_port_name
);
242 return log_oom_debug();
248 /* Then, try to use the kernel provided port index for the case when multiple ports on a single PCI
250 r
= get_dev_port(dev
, fallback_to_dev_id
, &dev_port
);
252 return log_device_debug_errno(dev
, r
, "Failed to get device port index: %m");
254 assert(dev_port
> 0);
255 if (asprintf(&buf
, "d%u", dev_port
) < 0)
256 return log_oom_debug();
266 static bool is_valid_onboard_index(unsigned idx
) {
267 /* Some BIOSes report rubbish indexes that are excessively high (2^24-1 is an index VMware likes to
268 * report for example). Let's define a cut-off where we don't consider the index reliable anymore. We
269 * pick some arbitrary cut-off, which is somewhere beyond the realistic number of physical network
270 * interface a system might have. Ideally the kernel would already filter this crap for us, but it
271 * doesn't currently. The initial cut-off value (2^14-1) was too conservative for s390 PCI which
272 * allows for index values up 2^16-1 which is now enabled with the NAMING_16BIT_INDEX naming flag. */
273 return idx
<= (naming_scheme_has(NAMING_16BIT_INDEX
) ? ONBOARD_16BIT_INDEX_MAX
: ONBOARD_14BIT_INDEX_MAX
);
276 static int pci_get_onboard_index(sd_device
*dev
, unsigned *ret
) {
283 /* ACPI _DSM — device specific method for naming a PCI or PCI Express device */
284 r
= device_get_sysattr_unsigned_filtered(dev
, "acpi_index", &idx
);
286 /* SMBIOS type 41 — Onboard Devices Extended Information */
287 r
= device_get_sysattr_unsigned_filtered(dev
, "index", &idx
);
289 return log_device_debug_errno(dev
, r
, "Could not obtain onboard index: %m");
291 if (idx
== 0 && !naming_scheme_has(NAMING_ZERO_ACPI_INDEX
))
292 return log_device_debug_errno(dev
, SYNTHETIC_ERRNO(EINVAL
),
293 "Naming scheme does not allow onboard index==0.");
294 if (!is_valid_onboard_index(idx
))
295 return log_device_debug_errno(dev
, SYNTHETIC_ERRNO(ENOENT
),
296 "Not a valid onboard index: %u", idx
);
302 static int names_pci_onboard(sd_device
*dev
, sd_device
*pci_dev
, const char *prefix
, const char *suffix
, EventMode mode
) {
303 _cleanup_free_
char *port
= NULL
;
304 unsigned idx
= 0; /* avoid false maybe-uninitialized warning */
311 /* retrieve on-board index number from firmware */
312 r
= pci_get_onboard_index(pci_dev
, &idx
);
316 r
= get_port_specifier(dev
, /* fallback_to_dev_id = */ false, &port
);
320 char str
[ALTIFNAMSIZ
];
321 if (snprintf_ok(str
, sizeof str
, "%so%u%s%s", prefix
, idx
, strempty(port
), strempty(suffix
)))
322 udev_builtin_add_property(dev
, mode
, "ID_NET_NAME_ONBOARD", str
);
324 log_device_debug(dev
, "Onboard index identifier: index=%u port=%s %s %s",
326 special_glyph(SPECIAL_GLYPH_ARROW_RIGHT
), empty_to_na(str
));
331 static int names_pci_onboard_label(sd_device
*dev
, sd_device
*pci_dev
, const char *prefix
, EventMode mode
) {
338 /* retrieve on-board label from firmware */
339 r
= device_get_sysattr_value_filtered(pci_dev
, "label", &label
);
341 return log_device_debug_errno(pci_dev
, r
, "Failed to get PCI onboard label: %m");
343 char str
[ALTIFNAMSIZ
];
344 if (snprintf_ok(str
, sizeof str
, "%s%s",
345 naming_scheme_has(NAMING_LABEL_NOPREFIX
) ? "" : prefix
,
347 udev_builtin_add_property(dev
, mode
, "ID_NET_LABEL_ONBOARD", str
);
349 log_device_debug(dev
, "Onboard label from PCI device: %s", label
);
353 /* read the 256 bytes PCI configuration space to check the multi-function bit */
354 static int is_pci_multifunction(sd_device
*dev
) {
355 _cleanup_free_
uint8_t *config
= NULL
;
356 const char *filename
, *syspath
;
362 r
= sd_device_get_syspath(dev
, &syspath
);
366 filename
= strjoina(syspath
, "/config");
367 r
= read_virtual_file(filename
, PCI_HEADER_TYPE
+ 1, (char **) &config
, &len
);
370 if (len
< PCI_HEADER_TYPE
+ 1)
373 #ifndef PCI_HEADER_TYPE_MULTIFUNC
374 #define PCI_HEADER_TYPE_MULTIFUNC 0x80
377 /* bit 0-6 header type, bit 7 multi/single function device */
378 return config
[PCI_HEADER_TYPE
] & PCI_HEADER_TYPE_MULTIFUNC
;
381 static bool is_pci_ari_enabled(sd_device
*dev
) {
384 return device_get_sysattr_bool_filtered(dev
, "ari_enabled") > 0;
387 static bool is_pci_bridge(sd_device
*dev
) {
392 if (device_get_sysattr_value_filtered(dev
, "modalias", &v
) < 0)
395 if (!startswith(v
, "pci:"))
404 /* PCI device subclass 04 corresponds to PCI bridge */
405 bool b
= strneq(p
+ 2, "04", 2);
407 log_device_debug(dev
, "Device is a PCI bridge.");
411 static int parse_hotplug_slot_from_function_id(sd_device
*dev
, int slots_dirfd
, uint32_t *ret
) {
412 uint64_t function_id
;
413 char filename
[NAME_MAX
+1];
417 /* The <sysname>/function_id attribute is unique to the s390 PCI driver. If present, we know that the
418 * slot's directory name for this device is /sys/bus/pci/slots/XXXXXXXX/ where XXXXXXXX is the fixed
419 * length 8 hexadecimal character string representation of function_id. Therefore we can short cut
420 * here and just check for the existence of the slot directory. As this directory has to exist, we're
421 * emitting a debug message for the unlikely case it's not found. Note that the domain part doesn't
422 * belong to the slot name here because there's a 1-to-1 relationship between PCI function and its
423 * hotplug slot. See https://docs.kernel.org/s390/pci.html for more details. */
426 assert(slots_dirfd
>= 0);
429 if (!naming_scheme_has(NAMING_SLOT_FUNCTION_ID
)) {
434 if (device_get_sysattr_value_filtered(dev
, "function_id", &attr
) < 0) {
439 r
= safe_atou64(attr
, &function_id
);
441 return log_device_debug_errno(dev
, r
, "Failed to parse function_id, ignoring: %s", attr
);
443 if (function_id
<= 0 || function_id
> UINT32_MAX
)
444 return log_device_debug_errno(dev
, SYNTHETIC_ERRNO(EINVAL
),
445 "Invalid function id (0x%"PRIx64
"), ignoring.",
448 if (!snprintf_ok(filename
, sizeof(filename
), "%08"PRIx64
, function_id
))
449 return log_device_debug_errno(dev
, SYNTHETIC_ERRNO(ENAMETOOLONG
),
450 "PCI slot path is too long, ignoring.");
452 if (faccessat(slots_dirfd
, filename
, F_OK
, 0) < 0)
453 return log_device_debug_errno(dev
, errno
, "Cannot access %s under pci slots, ignoring: %m", filename
);
455 *ret
= (uint32_t) function_id
;
456 return 1; /* Found. We should ignore domain part. */
459 static int pci_get_hotplug_slot_from_address(
473 r
= sd_device_get_sysname(dev
, &sysname
);
475 return log_device_debug_errno(dev
, r
, "Failed to get sysname: %m");
478 FOREACH_DIRENT_ALL(de
, dir
, break) {
479 _cleanup_free_
char *path
= NULL
;
483 if (dot_or_dot_dot(de
->d_name
))
486 if (de
->d_type
!= DT_DIR
)
489 r
= safe_atou32(de
->d_name
, &slot
);
490 if (r
< 0 || slot
<= 0)
493 path
= path_join("slots", de
->d_name
, "address");
495 return log_oom_debug();
497 if (device_get_sysattr_value_filtered(pci
, path
, &address
) < 0)
500 /* match slot address with device by stripping the function */
501 if (!startswith(sysname
, address
))
505 return 1; /* found */
509 return 0; /* not found */
512 static int pci_get_hotplug_slot(sd_device
*dev
, uint32_t *ret
) {
513 _cleanup_(sd_device_unrefp
) sd_device
*pci
= NULL
;
514 _cleanup_closedir_
DIR *dir
= NULL
;
520 /* ACPI _SUN — slot user number */
521 r
= sd_device_new_from_subsystem_sysname(&pci
, "subsystem", "pci");
523 return log_debug_errno(r
, "Failed to create sd_device object for pci subsystem: %m");
525 r
= device_opendir(pci
, "slots", &dir
);
527 return log_device_debug_errno(dev
, r
, "Cannot open 'slots' subdirectory: %m");
529 for (sd_device
*slot_dev
= dev
; slot_dev
; ) {
530 uint32_t slot
= 0; /* avoid false maybe-uninitialized warning */
532 r
= parse_hotplug_slot_from_function_id(slot_dev
, dirfd(dir
), &slot
);
537 return 1; /* domain should be ignored. */
540 r
= pci_get_hotplug_slot_from_address(slot_dev
, pci
, dir
, &slot
);
544 /* We found the match between PCI device and slot. However, we won't use the slot
545 * index if the device is a PCI bridge, because it can have other child devices that
546 * will try to claim the same index and that would create name collision. */
547 if (naming_scheme_has(NAMING_BRIDGE_NO_SLOT
) && is_pci_bridge(slot_dev
)) {
548 if (naming_scheme_has(NAMING_BRIDGE_MULTIFUNCTION_SLOT
) && is_pci_multifunction(dev
) <= 0)
549 return log_device_debug_errno(dev
, SYNTHETIC_ERRNO(ESTALE
),
550 "Not using slot information because the PCI device associated with "
551 "the hotplug slot is a bridge and the PCI device has a single function.");
553 if (!naming_scheme_has(NAMING_BRIDGE_MULTIFUNCTION_SLOT
))
554 return log_device_debug_errno(dev
, SYNTHETIC_ERRNO(ESTALE
),
555 "Not using slot information because the PCI device is a bridge.");
559 return 0; /* domain can be still used. */
562 if (sd_device_get_parent_with_subsystem_devtype(slot_dev
, "pci", NULL
, &slot_dev
) < 0)
569 static int get_pci_slot_specifiers(
572 char **ret_bus_and_slot
,
575 _cleanup_free_
char *domain_spec
= NULL
, *bus_and_slot_spec
= NULL
, *func_spec
= NULL
;
576 unsigned domain
, bus
, slot
, func
;
582 assert(ret_bus_and_slot
);
585 r
= sd_device_get_sysname(dev
, &sysname
);
587 return log_device_debug_errno(dev
, r
, "Failed to get sysname: %m");
589 r
= sscanf(sysname
, "%x:%x:%x.%u", &domain
, &bus
, &slot
, &func
);
591 return log_device_debug_errno(dev
, SYNTHETIC_ERRNO(EINVAL
),
592 "Failed to parse slot information from PCI device sysname.");
594 if (naming_scheme_has(NAMING_NPAR_ARI
) &&
595 is_pci_ari_enabled(dev
))
596 /* ARI devices support up to 256 functions on a single device ("slot"), and interpret the
597 * traditional 5-bit slot and 3-bit function number as a single 8-bit function number,
598 * where the slot makes up the upper 5 bits. */
601 if (domain
> 0 && asprintf(&domain_spec
, "P%u", domain
) < 0)
602 return log_oom_debug();
604 if (asprintf(&bus_and_slot_spec
, "p%us%u", bus
, slot
) < 0)
605 return log_oom_debug();
607 if ((func
> 0 || is_pci_multifunction(dev
) > 0) &&
608 asprintf(&func_spec
, "f%u", func
) < 0)
609 return log_oom_debug();
611 *ret_domain
= TAKE_PTR(domain_spec
);
612 *ret_bus_and_slot
= TAKE_PTR(bus_and_slot_spec
);
613 *ret_func
= TAKE_PTR(func_spec
);
617 static int names_pci_slot(sd_device
*dev
, sd_device
*pci_dev
, const char *prefix
, const char *suffix
, EventMode mode
) {
618 _cleanup_free_
char *domain
= NULL
, *bus_and_slot
= NULL
, *func
= NULL
, *port
= NULL
;
619 uint32_t hotplug_slot
= 0; /* avoid false maybe-uninitialized warning */
620 char str
[ALTIFNAMSIZ
];
627 r
= get_pci_slot_specifiers(pci_dev
, &domain
, &bus_and_slot
, &func
);
631 r
= get_port_specifier(dev
, /* fallback_to_dev_id = */ true, &port
);
635 /* compose a name based on the raw kernel's PCI bus, slot numbers */
636 if (snprintf_ok(str
, sizeof str
, "%s%s%s%s%s%s",
637 prefix
, strempty(domain
), bus_and_slot
, strempty(func
), strempty(port
), strempty(suffix
)))
638 udev_builtin_add_property(dev
, mode
, "ID_NET_NAME_PATH", str
);
640 log_device_debug(dev
, "PCI path identifier: domain=%s bus_and_slot=%s func=%s port=%s %s %s",
641 strna(domain
), bus_and_slot
, strna(func
), strna(port
),
642 special_glyph(SPECIAL_GLYPH_ARROW_RIGHT
), empty_to_na(str
));
644 r
= pci_get_hotplug_slot(pci_dev
, &hotplug_slot
);
648 /* If the hotplug slot is found through the function ID, then drop the domain from the name.
649 * See comments in parse_hotplug_slot_from_function_id(). */
650 domain
= mfree(domain
);
652 if (snprintf_ok(str
, sizeof str
, "%s%ss%"PRIu32
"%s%s%s",
653 prefix
, strempty(domain
), hotplug_slot
, strempty(func
), strempty(port
), strempty(suffix
)))
654 udev_builtin_add_property(dev
, mode
, "ID_NET_NAME_SLOT", str
);
656 log_device_debug(dev
, "Slot identifier: domain=%s slot=%"PRIu32
" func=%s port=%s %s %s",
657 strna(domain
), hotplug_slot
, strna(func
), strna(port
),
658 special_glyph(SPECIAL_GLYPH_ARROW_RIGHT
), empty_to_na(str
));
663 static int names_vio(sd_device
*dev
, const char *prefix
, EventMode mode
) {
664 _cleanup_free_
char *s
= NULL
;
671 /* get ibmveth/ibmvnic slot-based names. */
673 /* check if our direct parent is a VIO device with no other bus in-between */
674 if (get_matching_parent(dev
, STRV_MAKE("vio"), /* skip_virtio = */ false, NULL
) < 0)
677 log_device_debug(dev
, "Parent device is in the vio subsystem.");
679 /* The devices' $DEVPATH number is tied to (virtual) hardware (slot id
680 * selected in the HMC), thus this provides a reliable naming (e.g.
681 * "/devices/vio/30000002/net/eth1"); we ignore the bus number, as
682 * there should only ever be one bus, and then remove leading zeros. */
683 r
= get_first_syspath_component(dev
, "/sys/devices/vio/", &s
);
685 return log_device_debug_errno(dev
, r
, "Failed to get VIO bus ID and slot ID: %m");
688 return log_device_debug_errno(dev
, SYNTHETIC_ERRNO(EINVAL
),
689 "VIO bus ID and slot ID have invalid length: %s", s
);
691 if (!in_charset(s
, HEXDIGITS
))
692 return log_device_debug_errno(dev
, SYNTHETIC_ERRNO(EINVAL
),
693 "VIO bus ID and slot ID contain invalid characters: %s", s
);
695 /* Parse only slot ID (the last 4 hexdigits). */
696 r
= safe_atou_full(s
+ 4, 16, &slotid
);
698 return log_device_debug_errno(dev
, r
, "Failed to parse VIO slot from '%s': %m", s
);
700 char str
[ALTIFNAMSIZ
];
701 if (snprintf_ok(str
, sizeof str
, "%sv%u", prefix
, slotid
))
702 udev_builtin_add_property(dev
, mode
, "ID_NET_NAME_SLOT", str
);
703 log_device_debug(dev
, "Vio slot identifier: slotid=%u %s %s",
704 slotid
, special_glyph(SPECIAL_GLYPH_ARROW_RIGHT
), str
+ strlen(prefix
));
708 static int names_platform(sd_device
*dev
, const char *prefix
, EventMode mode
) {
709 _cleanup_free_
char *p
= NULL
;
710 const char *validchars
;
711 char *vendor
, *model_str
, *instance_str
;
712 unsigned model
, instance
;
718 /* get ACPI path names for ARM64 platform devices */
720 /* check if our direct parent is a platform device with no other bus in-between */
721 if (get_matching_parent(dev
, STRV_MAKE("platform"), /* skip_virtio = */ false, NULL
) < 0)
724 log_device_debug(dev
, "Parent device is in the platform subsystem.");
726 r
= get_first_syspath_component(dev
, "/sys/devices/platform/", &p
);
728 return log_device_debug_errno(dev
, r
, "Failed to get platform ID: %m");
730 /* Platform devices are named after ACPI table match, and instance id
731 * eg. "/sys/devices/platform/HISI00C2:00"
732 * The Vendor (3 or 4 char), followed by hexadecimal model number : instance id. */
733 if (r
== 10 && p
[7] == ':') {
734 /* 3 char vendor string */
735 vendor
= strndupa_safe(p
, 3);
736 model_str
= strndupa_safe(p
+ 3, 4);
737 instance_str
= strndupa_safe(p
+ 8, 2);
738 validchars
= UPPERCASE_LETTERS
;
739 } else if (r
== 11 && p
[8] == ':') {
740 /* 4 char vendor string */
741 vendor
= strndupa_safe(p
, 4);
742 model_str
= strndupa_safe(p
+ 4, 4);
743 instance_str
= strndupa_safe(p
+ 9, 2);
744 validchars
= UPPERCASE_LETTERS DIGITS
;
748 if (!in_charset(vendor
, validchars
))
749 return log_device_debug_errno(dev
, SYNTHETIC_ERRNO(ENOENT
),
750 "Platform vendor contains invalid characters: %s", vendor
);
752 ascii_strlower(vendor
);
754 r
= safe_atou_full(model_str
, 16, &model
);
756 return log_device_debug_errno(dev
, r
, "Failed to parse model number \"%s\": %m", model_str
);
758 r
= safe_atou_full(instance_str
, 16, &instance
);
760 return log_device_debug_errno(dev
, r
, "Failed to parse instance id \"%s\": %m", instance_str
);
762 char str
[ALTIFNAMSIZ
];
763 if (snprintf_ok(str
, sizeof str
, "%sa%s%xi%u", prefix
, vendor
, model
, instance
))
764 udev_builtin_add_property(dev
, mode
, "ID_NET_NAME_PATH", str
);
765 log_device_debug(dev
, "Platform identifier: vendor=%s model=%x instance=%u %s %s",
766 vendor
, model
, instance
, special_glyph(SPECIAL_GLYPH_ARROW_RIGHT
), str
+ strlen(prefix
));
770 static int names_devicetree(sd_device
*dev
, const char *prefix
, EventMode mode
) {
771 _cleanup_(sd_device_unrefp
) sd_device
*aliases_dev
= NULL
, *ofnode_dev
= NULL
, *devicetree_dev
= NULL
;
772 const char *ofnode_path
, *ofnode_syspath
, *devicetree_syspath
;
779 if (!naming_scheme_has(NAMING_DEVICETREE_ALIASES
))
782 /* only ethernet supported for now */
783 if (!streq(prefix
, "en"))
786 /* check if our direct parent has an of_node */
787 r
= sd_device_get_parent(dev
, &parent
);
789 return log_device_debug_errno(dev
, r
, "Failed to get parent device: %m");
791 r
= sd_device_new_child(&ofnode_dev
, parent
, "of_node");
793 return log_device_debug_errno(parent
, r
, "Failed to get 'of_node' child device: %m");
795 r
= sd_device_get_syspath(ofnode_dev
, &ofnode_syspath
);
797 return log_device_debug_errno(ofnode_dev
, r
, "Failed to get syspath: %m");
799 /* /proc/device-tree should be a symlink to /sys/firmware/devicetree/base. */
800 r
= sd_device_new_from_path(&devicetree_dev
, "/proc/device-tree");
802 return log_debug_errno(r
, "Failed to create sd-device object from '/proc/device-tree': %m");
804 r
= sd_device_get_syspath(devicetree_dev
, &devicetree_syspath
);
806 return log_device_debug_errno(devicetree_dev
, r
, "Failed to get syspath: %m");
810 * devicetree_syspath = /sys/firmware/devicetree/base
811 * ofnode_syspath = /sys/firmware/devicetree/base/soc/ethernet@deadbeef
812 * ofnode_path = soc/ethernet@deadbeef
814 ofnode_path
= path_startswith(ofnode_syspath
, devicetree_syspath
);
816 return log_device_debug_errno(ofnode_dev
, SYNTHETIC_ERRNO(EINVAL
),
817 "The device '%s' is not a child device of '%s': %m",
818 ofnode_syspath
, devicetree_syspath
);
820 /* Get back our leading / to match the contents of the aliases */
822 assert(path_is_absolute(ofnode_path
));
824 r
= sd_device_new_child(&aliases_dev
, devicetree_dev
, "aliases");
826 return log_device_debug_errno(devicetree_dev
, r
,
827 "Failed to get 'aliases' child device: %m");
829 FOREACH_DEVICE_SYSATTR(aliases_dev
, alias
) {
830 const char *alias_path
, *alias_index
, *conflict
;
833 alias_index
= startswith(alias
, "ethernet");
837 if (device_get_sysattr_value_filtered(aliases_dev
, alias
, &alias_path
) < 0)
840 if (!path_equal(ofnode_path
, alias_path
))
843 /* If there's no index, we default to 0... */
844 if (isempty(alias_index
)) {
846 conflict
= "ethernet0";
848 r
= safe_atou(alias_index
, &i
);
850 return log_device_debug_errno(dev
, r
,
851 "Could not get index of alias %s: %m", alias
);
852 conflict
= "ethernet";
855 /* ...but make sure we don't have an alias conflict */
856 if (i
== 0 && device_get_sysattr_value_filtered(aliases_dev
, conflict
, NULL
) >= 0)
857 return log_device_debug_errno(dev
, SYNTHETIC_ERRNO(EEXIST
),
858 "Ethernet alias conflict: ethernet and ethernet0 both exist");
860 char str
[ALTIFNAMSIZ
];
861 if (snprintf_ok(str
, sizeof str
, "%sd%u", prefix
, i
))
862 udev_builtin_add_property(dev
, mode
, "ID_NET_NAME_ONBOARD", str
);
863 log_device_debug(dev
, "devicetree identifier: alias_index=%u %s \"%s\"",
864 i
, special_glyph(SPECIAL_GLYPH_ARROW_RIGHT
), str
+ strlen(prefix
));
871 static int names_pci(sd_device
*dev
, const char *prefix
, EventMode mode
) {
872 _cleanup_(sd_device_unrefp
) sd_device
*physfn_pcidev
= NULL
;
873 _cleanup_free_
char *virtfn_suffix
= NULL
;
879 /* check if our direct parent is a PCI device with no other bus in-between */
880 if (get_matching_parent(dev
, STRV_MAKE("pci"), /* skip_virtio = */ true, &parent
) < 0)
883 /* If this is an SR-IOV virtual device, get base name using physical device and add virtfn suffix. */
884 if (naming_scheme_has(NAMING_SR_IOV_V
) &&
885 get_virtfn_info(parent
, &physfn_pcidev
, &virtfn_suffix
) >= 0)
886 parent
= physfn_pcidev
;
888 (void) names_pci_onboard_label(dev
, parent
, prefix
, mode
);
890 (void) names_pci_onboard(dev
, parent
, prefix
, virtfn_suffix
, mode
);
891 (void) names_pci_slot(dev
, parent
, prefix
, virtfn_suffix
, mode
);
895 static int get_usb_specifier(sd_device
*dev
, char **ret
) {
896 char *ports
, *config
, *interf
, *s
, *buf
;
903 r
= sd_device_get_sysname(dev
, &sysname
);
905 return log_device_debug_errno(dev
, r
, "Failed to get sysname: %m");
907 /* get USB port number chain, configuration, interface */
908 s
= strchr(sysname
, '-');
910 return log_device_debug_errno(dev
, SYNTHETIC_ERRNO(EINVAL
),
911 "sysname \"%s\" does not have '-' in the expected place.", sysname
);
913 ports
= strdupa_safe(s
+ 1);
914 s
= strchr(ports
, ':');
916 return log_device_debug_errno(dev
, SYNTHETIC_ERRNO(EINVAL
),
917 "sysname \"%s\" does not have ':' in the expected place.", sysname
);
921 s
= strchr(config
, '.');
923 return log_device_debug_errno(dev
, SYNTHETIC_ERRNO(EINVAL
),
924 "sysname \"%s\" does not have '.' in the expected place.", sysname
);
929 /* prefix every port number in the chain with "u" */
930 string_replace_char(ports
, '.', 'u');
932 /* suppress the common config == 1 */
933 if (streq(config
, "1"))
936 /* suppress the interface == 0 */
937 if (streq(interf
, "0"))
940 buf
= strjoin("u", ports
,
941 config
? "c" : "", strempty(config
),
942 interf
? "i" : "", strempty(interf
));
944 return log_oom_debug();
946 log_device_debug(dev
, "USB name identifier: ports=%s config=%s interface=%s %s %s",
947 ports
, strna(config
), strna(interf
),
948 special_glyph(SPECIAL_GLYPH_ARROW_RIGHT
), buf
);
954 static int names_usb(sd_device
*dev
, const char *prefix
, EventMode mode
) {
955 _cleanup_free_
char *suffix
= NULL
;
956 sd_device
*usbdev
, *pcidev
;
964 r
= sd_device_get_parent_with_subsystem_devtype(dev
, "usb", "usb_interface", &usbdev
);
966 return log_device_debug_errno(dev
, r
, "Could not find usb parent device: %m");
968 r
= get_usb_specifier(usbdev
, &suffix
);
972 /* If the USB bus is on PCI bus, then suffix the USB specifier to the name based on the PCI bus. */
973 r
= sd_device_get_parent_with_subsystem_devtype(usbdev
, "pci", NULL
, &pcidev
);
975 return names_pci_slot(dev
, pcidev
, prefix
, suffix
, mode
);
977 if (r
!= -ENOENT
|| !naming_scheme_has(NAMING_USB_HOST
))
978 return log_device_debug_errno(usbdev
, r
, "Failed to get parent PCI bus: %m");
980 /* Otherwise, e.g. on-chip asics that have USB ports, use the USB specifier as is. */
981 char str
[ALTIFNAMSIZ
];
982 if (snprintf_ok(str
, sizeof str
, "%s%s", prefix
, suffix
))
983 udev_builtin_add_property(dev
, mode
, "ID_NET_NAME_PATH", str
);
988 static int get_bcma_specifier(sd_device
*dev
, char **ret
) {
997 r
= sd_device_get_sysname(dev
, &sysname
);
999 return log_device_debug_errno(dev
, r
, "Failed to get sysname: %m");
1001 /* bus num:core num */
1002 r
= sscanf(sysname
, "bcma%*u:%u", &core
);
1004 return log_device_debug_errno(dev
, SYNTHETIC_ERRNO(EINVAL
),
1005 "Failed to parse bcma device information.");
1007 /* suppress the common core == 0 */
1008 if (core
> 0 && asprintf(&buf
, "b%u", core
) < 0)
1009 return log_oom_debug();
1011 log_device_debug(dev
, "BCMA core identifier: core=%u %s \"%s\"",
1012 core
, special_glyph(SPECIAL_GLYPH_ARROW_RIGHT
), strna(buf
));
1018 static int names_bcma(sd_device
*dev
, const char *prefix
, EventMode mode
) {
1019 _cleanup_free_
char *suffix
= NULL
;
1020 sd_device
*bcmadev
, *pcidev
;
1026 r
= sd_device_get_parent_with_subsystem_devtype(dev
, "bcma", NULL
, &bcmadev
);
1028 return log_device_debug_errno(dev
, r
, "Could not get bcma parent device: %m");
1030 r
= sd_device_get_parent_with_subsystem_devtype(bcmadev
, "pci", NULL
, &pcidev
);
1032 return log_device_debug_errno(dev
, r
, "Could not get pci parent device: %m");
1034 r
= get_bcma_specifier(bcmadev
, &suffix
);
1038 return names_pci_slot(dev
, pcidev
, prefix
, suffix
, mode
);
1041 static int names_ccw(sd_device
*dev
, const char *prefix
, EventMode mode
) {
1044 size_t bus_id_start
, bus_id_len
;
1050 /* get path names for Linux on System z network devices */
1052 if (get_matching_parent(dev
, STRV_MAKE("ccwgroup", "ccw"), /* skip_virtio = */ true, &cdev
) < 0)
1055 log_device_debug(dev
, "Device is CCW.");
1057 /* Retrieve bus-ID of the CCW device. The bus-ID uniquely
1058 * identifies the network device on the Linux on System z channel
1059 * subsystem. Note that the bus-ID contains lowercase characters.
1061 r
= sd_device_get_sysname(cdev
, &bus_id
);
1063 return log_device_debug_errno(cdev
, r
, "Failed to get sysname: %m");
1065 /* Check the length of the bus-ID. Rely on the fact that the kernel provides a correct bus-ID;
1066 * alternatively, improve this check and parse and verify each bus-ID part...
1068 bus_id_len
= strlen(bus_id
);
1069 if (!IN_SET(bus_id_len
, 8, 9))
1070 return log_device_debug_errno(cdev
, SYNTHETIC_ERRNO(EINVAL
), "Invalid bus_id: %s", bus_id
);
1072 /* Strip leading zeros from the bus id for aesthetic purposes. This
1073 * keeps the ccw names stable, yet much shorter in general case of
1074 * bus_id 0.0.0600 -> 600. This is similar to e.g. how PCI domain is
1075 * not prepended when it is zero. Preserve the last 0 for 0.0.0000.
1077 bus_id_start
= strspn(bus_id
, ".0");
1078 bus_id
+= bus_id_start
< bus_id_len
? bus_id_start
: bus_id_len
- 1;
1080 /* Use the CCW bus-ID as network device name */
1081 char str
[ALTIFNAMSIZ
];
1082 if (snprintf_ok(str
, sizeof str
, "%sc%s", prefix
, bus_id
))
1083 udev_builtin_add_property(dev
, mode
, "ID_NET_NAME_PATH", str
);
1084 log_device_debug(dev
, "CCW identifier: ccw_busid=%s %s \"%s\"",
1085 bus_id
, special_glyph(SPECIAL_GLYPH_ARROW_RIGHT
), str
+ strlen(prefix
));
1089 /* IEEE Organizationally Unique Identifier vendor string */
1090 static int ieee_oui(sd_device
*dev
, const struct hw_addr_data
*hw_addr
, EventMode mode
) {
1096 if (hw_addr
->length
!= 6)
1099 /* skip commonly misused 00:00:00 (Xerox) prefix */
1100 if (hw_addr
->bytes
[0] == 0 &&
1101 hw_addr
->bytes
[1] == 0 &&
1102 hw_addr
->bytes
[2] == 0)
1105 xsprintf(str
, "OUI:%02X%02X%02X%02X%02X%02X",
1113 return udev_builtin_hwdb_lookup(dev
, NULL
, str
, NULL
, mode
);
1116 static int names_mac(sd_device
*dev
, const char *prefix
, EventMode mode
) {
1117 unsigned iftype
, assign_type
;
1118 struct hw_addr_data hw_addr
;
1125 r
= device_get_sysattr_unsigned_filtered(dev
, "type", &iftype
);
1127 return log_device_debug_errno(dev
, r
, "Failed to read 'type' attribute: %m");
1129 /* The persistent part of a hardware address of an InfiniBand NIC is 8 bytes long. We cannot
1130 * fit this much in an iface name.
1131 * TODO: but it can be used as alternative names?? */
1132 if (iftype
== ARPHRD_INFINIBAND
)
1133 return log_device_debug_errno(dev
, SYNTHETIC_ERRNO(EOPNOTSUPP
),
1134 "Not generating MAC name for infiniband device.");
1136 /* check for NET_ADDR_PERM, skip random MAC addresses */
1137 r
= device_get_sysattr_unsigned_filtered(dev
, "addr_assign_type", &assign_type
);
1139 return log_device_debug_errno(dev
, r
, "Failed to read/parse addr_assign_type: %m");
1141 if (assign_type
!= NET_ADDR_PERM
)
1142 return log_device_debug_errno(dev
, SYNTHETIC_ERRNO(EINVAL
),
1143 "addr_assign_type=%u, MAC address is not permanent.", assign_type
);
1145 r
= device_get_sysattr_value_filtered(dev
, "address", &s
);
1147 return log_device_debug_errno(dev
, r
, "Failed to read 'address' attribute: %m");
1149 r
= parse_hw_addr(s
, &hw_addr
);
1151 return log_device_debug_errno(dev
, r
, "Failed to parse 'address' attribute: %m");
1153 if (hw_addr
.length
!= 6)
1154 return log_device_debug_errno(dev
, SYNTHETIC_ERRNO(EOPNOTSUPP
),
1155 "Not generating MAC name for device with MAC address of length %zu.",
1158 char str
[ALTIFNAMSIZ
];
1159 xsprintf(str
, "%sx%s", prefix
, HW_ADDR_TO_STR_FULL(&hw_addr
, HW_ADDR_TO_STRING_NO_COLON
));
1160 udev_builtin_add_property(dev
, mode
, "ID_NET_NAME_MAC", str
);
1161 log_device_debug(dev
, "MAC address identifier: hw_addr=%s %s %s",
1162 HW_ADDR_TO_STR(&hw_addr
),
1163 special_glyph(SPECIAL_GLYPH_ARROW_RIGHT
), str
+ strlen(prefix
));
1165 (void) ieee_oui(dev
, &hw_addr
, mode
);
1169 static int names_netdevsim(sd_device
*dev
, const char *prefix
, EventMode mode
) {
1170 sd_device
*netdevsimdev
;
1171 const char *sysnum
, *phys_port_name
;
1178 /* get netdevsim path names */
1180 if (!naming_scheme_has(NAMING_NETDEVSIM
))
1183 r
= sd_device_get_parent_with_subsystem_devtype(dev
, "netdevsim", NULL
, &netdevsimdev
);
1187 r
= sd_device_get_sysnum(netdevsimdev
, &sysnum
);
1189 return log_device_debug_errno(netdevsimdev
, r
, "Failed to get device sysnum: %m");
1191 r
= safe_atou(sysnum
, &addr
);
1193 return log_device_debug_errno(netdevsimdev
, r
, "Failed to parse device sysnum: %m");
1195 r
= device_get_sysattr_value_filtered(dev
, "phys_port_name", &phys_port_name
);
1197 return log_device_debug_errno(dev
, r
, "Failed to get 'phys_port_name' attribute: %m");
1198 if (isempty(phys_port_name
))
1199 return log_device_debug_errno(dev
, SYNTHETIC_ERRNO(EOPNOTSUPP
),
1200 "The 'phys_port_name' attribute is empty.");
1202 char str
[ALTIFNAMSIZ
];
1203 if (snprintf_ok(str
, sizeof str
, "%si%un%s", prefix
, addr
, phys_port_name
))
1204 udev_builtin_add_property(dev
, mode
, "ID_NET_NAME_PATH", str
);
1205 log_device_debug(dev
, "Netdevsim identifier: address=%u, port_name=%s %s %s",
1206 addr
, phys_port_name
, special_glyph(SPECIAL_GLYPH_ARROW_RIGHT
), str
+ strlen(prefix
));
1210 static int names_xen(sd_device
*dev
, const char *prefix
, EventMode mode
) {
1211 _cleanup_free_
char *vif
= NULL
;
1219 /* get xen vif "slot" based names. */
1221 if (!naming_scheme_has(NAMING_XEN_VIF
))
1224 /* check if our direct parent is a Xen VIF device with no other bus in-between */
1225 if (get_matching_parent(dev
, STRV_MAKE("xen"), /* skip_virtio = */ false, NULL
) < 0)
1228 /* Use the vif-n name to extract "n" */
1229 r
= get_first_syspath_component(dev
, "/sys/devices/", &vif
);
1231 return log_device_debug_errno(dev
, r
, "Failed to get Xen VIF name: %m");
1233 p
= startswith(vif
, "vif-");
1235 return log_device_debug_errno(dev
, SYNTHETIC_ERRNO(EINVAL
), "Invalid vif name: %s: %m", vif
);
1237 r
= safe_atou_full(p
, SAFE_ATO_REFUSE_PLUS_MINUS
| SAFE_ATO_REFUSE_LEADING_ZERO
|
1238 SAFE_ATO_REFUSE_LEADING_WHITESPACE
| 10, &id
);
1240 return log_device_debug_errno(dev
, r
, "Failed to parse vif index from '%s': %m", p
);
1242 char str
[ALTIFNAMSIZ
];
1243 if (snprintf_ok(str
, sizeof str
, "%sX%u", prefix
, id
))
1244 udev_builtin_add_property(dev
, mode
, "ID_NET_NAME_SLOT", str
);
1245 log_device_debug(dev
, "Xen identifier: id=%u %s %s",
1246 id
, special_glyph(SPECIAL_GLYPH_ARROW_RIGHT
), str
+ strlen(prefix
));
1250 static int get_ifname_prefix(sd_device
*dev
, const char **ret
) {
1257 r
= device_get_sysattr_unsigned_filtered(dev
, "type", &iftype
);
1261 /* handle only ARPHRD_ETHER, ARPHRD_SLIP and ARPHRD_INFINIBAND devices */
1263 case ARPHRD_ETHER
: {
1264 if (device_is_devtype(dev
, "wlan"))
1266 else if (device_is_devtype(dev
, "wwan"))
1272 case ARPHRD_INFINIBAND
:
1273 if (!naming_scheme_has(NAMING_INFINIBAND
))
1288 static int device_is_stacked(sd_device
*dev
) {
1289 int ifindex
, iflink
, r
;
1293 r
= sd_device_get_ifindex(dev
, &ifindex
);
1297 r
= device_get_sysattr_int_filtered(dev
, "iflink", &iflink
);
1301 return ifindex
!= iflink
;
1304 static int builtin_net_id(UdevEvent
*event
, int argc
, char *argv
[]) {
1305 sd_device
*dev
= ASSERT_PTR(ASSERT_PTR(event
)->dev
);
1309 /* skip stacked devices, like VLANs, ... */
1310 r
= device_is_stacked(dev
);
1312 return log_device_debug_errno(dev
, r
, "Failed to check if the device is stacked: %m");
1316 r
= get_ifname_prefix(dev
, &prefix
);
1318 log_device_debug_errno(dev
, r
, "Failed to determine prefix for network interface naming, ignoring: %m");
1322 udev_builtin_add_property(dev
, event
->event_mode
, "ID_NET_NAMING_SCHEME", naming_scheme()->name
);
1324 (void) names_mac(dev
, prefix
, event
->event_mode
);
1325 (void) names_devicetree(dev
, prefix
, event
->event_mode
);
1326 (void) names_ccw(dev
, prefix
, event
->event_mode
);
1327 (void) names_vio(dev
, prefix
, event
->event_mode
);
1328 (void) names_platform(dev
, prefix
, event
->event_mode
);
1329 (void) names_netdevsim(dev
, prefix
, event
->event_mode
);
1330 (void) names_xen(dev
, prefix
, event
->event_mode
);
1331 (void) names_pci(dev
, prefix
, event
->event_mode
);
1332 (void) names_usb(dev
, prefix
, event
->event_mode
);
1333 (void) names_bcma(dev
, prefix
, event
->event_mode
);
1338 static int builtin_net_id_init(void) {
1339 /* Load naming scheme here to suppress log messages in workers. */
1344 const UdevBuiltin udev_builtin_net_id
= {
1346 .cmd
= builtin_net_id
,
1347 .init
= builtin_net_id_init
,
1348 .help
= "Network device properties",