1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2012 Kay Sievers <kay@vrfy.org>
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
23 * Predictable network interface device names based on:
24 * - firmware/bios-provided index numbers for on-board devices
25 * - firmware-provided pci-express hotplug slot index number
26 * - physical/geographical location of the hardware
27 * - the interface's MAC address
29 * http://www.freedesktop.org/wiki/Software/systemd/PredictableNetworkInterfaceNames
31 * Two character prefixes based on the type of interface:
33 * sl -- serial line IP (slip)
38 * b<number> -- BCMA bus core number
39 * c<bus_id> -- CCW bus group name, without leading zeros [s390]
40 * o<index>[d<dev_port>] -- on-board device index number
41 * s<slot>[f<function>][d<dev_port>] -- hotplug slot index number
42 * x<MAC> -- MAC address
43 * [P<domain>]p<bus>s<slot>[f<function>][d<dev_port>]
44 * -- PCI geographical location
45 * [P<domain>]p<bus>s<slot>[f<function>][u<port>][..][c<config>][i<interface>]
46 * -- USB port number chain
48 * All multi-function PCI devices will carry the [f<function>] number in the
49 * device name, including the function 0 device.
51 * When using PCI geography, The PCI domain is only prepended when it is not 0.
53 * For USB devices the full chain of port numbers of hubs is composed. If the
54 * name gets longer than the maximum number of 15 characters, the name is not
56 * The usual USB configuration == 1 and interface == 0 values are suppressed.
58 * PCI Ethernet card with firmware index "1":
59 * ID_NET_NAME_ONBOARD=eno1
60 * ID_NET_NAME_ONBOARD_LABEL=Ethernet Port 1
62 * PCI Ethernet card in hotplug slot with firmware index number:
63 * /sys/devices/pci0000:00/0000:00:1c.3/0000:05:00.0/net/ens1
64 * ID_NET_NAME_MAC=enx000000000466
65 * ID_NET_NAME_PATH=enp5s0
66 * ID_NET_NAME_SLOT=ens1
68 * PCI Ethernet multi-function card with 2 ports:
69 * /sys/devices/pci0000:00/0000:00:1c.0/0000:02:00.0/net/enp2s0f0
70 * ID_NET_NAME_MAC=enx78e7d1ea46da
71 * ID_NET_NAME_PATH=enp2s0f0
72 * /sys/devices/pci0000:00/0000:00:1c.0/0000:02:00.1/net/enp2s0f1
73 * ID_NET_NAME_MAC=enx78e7d1ea46dc
74 * ID_NET_NAME_PATH=enp2s0f1
77 * /sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/net/wlp3s0
78 * ID_NET_NAME_MAC=wlx0024d7e31130
79 * ID_NET_NAME_PATH=wlp3s0
81 * USB built-in 3G modem:
82 * /sys/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.4/2-1.4:1.6/net/wwp0s29u1u4i6
83 * ID_NET_NAME_MAC=wwx028037ec0200
84 * ID_NET_NAME_PATH=wwp0s29u1u4i6
87 * /sys/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2:1.0/net/enp0s29u1u2
88 * ID_NET_NAME_MAC=enxd626b3450fb5
89 * ID_NET_NAME_PATH=enp0s29u1u2
95 #include <net/if_arp.h>
101 #include <linux/pci_regs.h>
105 #include "stdio-util.h"
106 #include "string-util.h"
109 #define ONBOARD_INDEX_MAX (16*1024-1)
121 enum netname_type type
;
126 struct udev_device
*pcidev
;
127 char pci_slot
[IFNAMSIZ
];
128 char pci_path
[IFNAMSIZ
];
129 char pci_onboard
[IFNAMSIZ
];
130 const char *pci_onboard_label
;
132 char usb_ports
[IFNAMSIZ
];
133 char bcma_core
[IFNAMSIZ
];
134 char ccw_group
[IFNAMSIZ
];
137 /* retrieve on-board index number and label from firmware */
138 static int dev_pci_onboard(struct udev_device
*dev
, struct netnames
*names
) {
139 unsigned dev_port
= 0;
145 /* ACPI _DSM -- device specific method for naming a PCI or PCI Express device */
146 attr
= udev_device_get_sysattr_value(names
->pcidev
, "acpi_index");
147 /* SMBIOS type 41 -- Onboard Devices Extended Information */
149 attr
= udev_device_get_sysattr_value(names
->pcidev
, "index");
153 idx
= strtoul(attr
, NULL
, 0);
157 /* Some BIOSes report rubbish indexes that are excessively high (2^24-1 is an index VMware likes to report for
158 * example). Let's define a cut-off where we don't consider the index reliable anymore. We pick some arbitrary
159 * cut-off, which is somewhere beyond the realistic number of physical network interface a system might
160 * have. Ideally the kernel would already filter his crap for us, but it doesn't currently. */
161 if (idx
> ONBOARD_INDEX_MAX
)
164 /* kernel provided port index for multiple ports on a single PCI function */
165 attr
= udev_device_get_sysattr_value(dev
, "dev_port");
167 dev_port
= strtol(attr
, NULL
, 10);
169 s
= names
->pci_onboard
;
170 l
= sizeof(names
->pci_onboard
);
171 l
= strpcpyf(&s
, l
, "o%d", idx
);
173 l
= strpcpyf(&s
, l
, "d%d", dev_port
);
175 names
->pci_onboard
[0] = '\0';
177 names
->pci_onboard_label
= udev_device_get_sysattr_value(names
->pcidev
, "label");
182 /* read the 256 bytes PCI configuration space to check the multi-function bit */
183 static bool is_pci_multifunction(struct udev_device
*dev
) {
184 _cleanup_close_
int fd
= -1;
185 const char *filename
;
188 filename
= strjoina(udev_device_get_syspath(dev
), "/config");
189 fd
= open(filename
, O_RDONLY
| O_CLOEXEC
);
192 if (read(fd
, &config
, sizeof(config
)) != sizeof(config
))
195 /* bit 0-6 header type, bit 7 multi/single function device */
196 if ((config
[PCI_HEADER_TYPE
] & 0x80) != 0)
202 static int dev_pci_slot(struct udev_device
*dev
, struct netnames
*names
) {
203 struct udev
*udev
= udev_device_get_udev(names
->pcidev
);
204 unsigned domain
, bus
, slot
, func
, dev_port
= 0;
208 struct udev_device
*pci
= NULL
;
209 char slots
[256], str
[256];
210 _cleanup_closedir_
DIR *dir
= NULL
;
212 int hotplug_slot
= 0, err
= 0;
214 if (sscanf(udev_device_get_sysname(names
->pcidev
), "%x:%x:%x.%u", &domain
, &bus
, &slot
, &func
) != 4)
217 /* kernel provided port index for multiple ports on a single PCI function */
218 attr
= udev_device_get_sysattr_value(dev
, "dev_port");
220 dev_port
= strtol(attr
, NULL
, 10);
222 /* compose a name based on the raw kernel's PCI bus, slot numbers */
224 l
= sizeof(names
->pci_path
);
226 l
= strpcpyf(&s
, l
, "P%u", domain
);
227 l
= strpcpyf(&s
, l
, "p%us%u", bus
, slot
);
228 if (func
> 0 || is_pci_multifunction(names
->pcidev
))
229 l
= strpcpyf(&s
, l
, "f%u", func
);
231 l
= strpcpyf(&s
, l
, "d%u", dev_port
);
233 names
->pci_path
[0] = '\0';
235 /* ACPI _SUN -- slot user number */
236 pci
= udev_device_new_from_subsystem_sysname(udev
, "subsystem", "pci");
241 xsprintf(slots
, "%s/slots", udev_device_get_syspath(pci
));
242 dir
= opendir(slots
);
248 for (dent
= readdir(dir
); dent
!= NULL
; dent
= readdir(dir
)) {
253 if (dent
->d_name
[0] == '.')
255 i
= strtol(dent
->d_name
, &rest
, 10);
260 xsprintf(str
, "%s/%s/address", slots
, dent
->d_name
);
261 if (read_one_line_file(str
, &address
) >= 0) {
262 /* match slot address with device by stripping the function */
263 if (strneq(address
, udev_device_get_sysname(names
->pcidev
), strlen(address
)))
268 if (hotplug_slot
> 0)
272 if (hotplug_slot
> 0) {
274 l
= sizeof(names
->pci_slot
);
276 l
= strpcpyf(&s
, l
, "P%d", domain
);
277 l
= strpcpyf(&s
, l
, "s%d", hotplug_slot
);
278 if (func
> 0 || is_pci_multifunction(names
->pcidev
))
279 l
= strpcpyf(&s
, l
, "f%d", func
);
281 l
= strpcpyf(&s
, l
, "d%d", dev_port
);
283 names
->pci_slot
[0] = '\0';
286 udev_device_unref(pci
);
290 static int names_pci(struct udev_device
*dev
, struct netnames
*names
) {
291 struct udev_device
*parent
;
296 parent
= udev_device_get_parent(dev
);
298 /* there can only ever be one virtio bus per parent device, so we can
299 safely ignore any virtio buses. see
300 <http://lists.linuxfoundation.org/pipermail/virtualization/2015-August/030331.html> */
301 while (parent
&& streq_ptr("virtio", udev_device_get_subsystem(parent
)))
302 parent
= udev_device_get_parent(parent
);
307 /* check if our direct parent is a PCI device with no other bus in-between */
308 if (streq_ptr("pci", udev_device_get_subsystem(parent
))) {
309 names
->type
= NET_PCI
;
310 names
->pcidev
= parent
;
312 names
->pcidev
= udev_device_get_parent_with_subsystem_devtype(dev
, "pci", NULL
);
316 dev_pci_onboard(dev
, names
);
317 dev_pci_slot(dev
, names
);
321 static int names_usb(struct udev_device
*dev
, struct netnames
*names
) {
322 struct udev_device
*usbdev
;
333 usbdev
= udev_device_get_parent_with_subsystem_devtype(dev
, "usb", "usb_interface");
337 /* get USB port number chain, configuration, interface */
338 strscpy(name
, sizeof(name
), udev_device_get_sysname(usbdev
));
339 s
= strchr(name
, '-');
344 s
= strchr(ports
, ':');
350 s
= strchr(config
, '.');
356 /* prefix every port number in the chain with "u" */
358 while ((s
= strchr(s
, '.')))
360 s
= names
->usb_ports
;
361 l
= strpcpyl(&s
, sizeof(names
->usb_ports
), "u", ports
, NULL
);
363 /* append USB config number, suppress the common config == 1 */
364 if (!streq(config
, "1"))
365 l
= strpcpyl(&s
, sizeof(names
->usb_ports
), "c", config
, NULL
);
367 /* append USB interface number, suppress the interface == 0 */
368 if (!streq(interf
, "0"))
369 l
= strpcpyl(&s
, sizeof(names
->usb_ports
), "i", interf
, NULL
);
371 return -ENAMETOOLONG
;
373 names
->type
= NET_USB
;
377 static int names_bcma(struct udev_device
*dev
, struct netnames
*names
) {
378 struct udev_device
*bcmadev
;
384 bcmadev
= udev_device_get_parent_with_subsystem_devtype(dev
, "bcma", NULL
);
388 /* bus num:core num */
389 if (sscanf(udev_device_get_sysname(bcmadev
), "bcma%*u:%u", &core
) != 1)
391 /* suppress the common core == 0 */
393 xsprintf(names
->bcma_core
, "b%u", core
);
395 names
->type
= NET_BCMA
;
399 static int names_ccw(struct udev_device
*dev
, struct netnames
*names
) {
400 struct udev_device
*cdev
;
408 /* Retrieve the associated CCW device */
409 cdev
= udev_device_get_parent(dev
);
413 /* Network devices are always grouped CCW devices */
414 if (!streq_ptr("ccwgroup", udev_device_get_subsystem(cdev
)))
417 /* Retrieve bus-ID of the grouped CCW device. The bus-ID uniquely
418 * identifies the network device on the Linux on System z channel
419 * subsystem. Note that the bus-ID contains lowercase characters.
421 bus_id
= udev_device_get_sysname(cdev
);
425 /* Check the length of the bus-ID. Rely on that the kernel provides
426 * a correct bus-ID; alternatively, improve this check and parse and
427 * verify each bus-ID part...
429 bus_id_len
= strlen(bus_id
);
430 if (!bus_id_len
|| bus_id_len
< 8 || bus_id_len
> 9)
433 /* Strip leading zeros from the bus id for aesthetic purposes. This
434 * keeps the ccw names stable, yet much shorter in general case of
435 * bus_id 0.0.0600 -> 600. This is similar to e.g. how PCI domain is
436 * not prepended when it is zero.
438 bus_id
+= strspn(bus_id
, ".0");
440 /* Store the CCW bus-ID for use as network device name */
441 rc
= snprintf(names
->ccw_group
, sizeof(names
->ccw_group
), "c%s", bus_id
);
442 if (rc
>= 0 && rc
< (int)sizeof(names
->ccw_group
))
443 names
->type
= NET_CCWGROUP
;
447 static int names_mac(struct udev_device
*dev
, struct netnames
*names
) {
450 unsigned int a1
, a2
, a3
, a4
, a5
, a6
;
452 /* check for NET_ADDR_PERM, skip random MAC addresses */
453 s
= udev_device_get_sysattr_value(dev
, "addr_assign_type");
456 i
= strtoul(s
, NULL
, 0);
460 s
= udev_device_get_sysattr_value(dev
, "address");
463 if (sscanf(s
, "%x:%x:%x:%x:%x:%x", &a1
, &a2
, &a3
, &a4
, &a5
, &a6
) != 6)
466 /* skip empty MAC addresses */
467 if (a1
+ a2
+ a3
+ a4
+ a5
+ a6
== 0)
476 names
->mac_valid
= true;
480 /* IEEE Organizationally Unique Identifier vendor string */
481 static int ieee_oui(struct udev_device
*dev
, struct netnames
*names
, bool test
) {
484 if (!names
->mac_valid
)
486 /* skip commonly misused 00:00:00 (Xerox) prefix */
487 if (memcmp(names
->mac
, "\0\0\0", 3) == 0)
489 xsprintf(str
, "OUI:%02X%02X%02X%02X%02X%02X", names
->mac
[0],
490 names
->mac
[1], names
->mac
[2], names
->mac
[3], names
->mac
[4],
492 udev_builtin_hwdb_lookup(dev
, NULL
, str
, NULL
, test
);
496 static int builtin_net_id(struct udev_device
*dev
, int argc
, char *argv
[], bool test
) {
501 const char *prefix
= "en";
502 struct netnames names
= {};
505 /* handle only ARPHRD_ETHER and ARPHRD_SLIP devices */
506 s
= udev_device_get_sysattr_value(dev
, "type");
509 i
= strtoul(s
, NULL
, 0);
521 /* skip stacked devices, like VLANs, ... */
522 s
= udev_device_get_sysattr_value(dev
, "ifindex");
525 p
= udev_device_get_sysattr_value(dev
, "iflink");
531 devtype
= udev_device_get_devtype(dev
);
533 if (streq("wlan", devtype
))
535 else if (streq("wwan", devtype
))
539 err
= names_mac(dev
, &names
);
540 if (err
>= 0 && names
.mac_valid
) {
543 xsprintf(str
, "%sx%02x%02x%02x%02x%02x%02x", prefix
,
544 names
.mac
[0], names
.mac
[1], names
.mac
[2],
545 names
.mac
[3], names
.mac
[4], names
.mac
[5]);
546 udev_builtin_add_property(dev
, test
, "ID_NET_NAME_MAC", str
);
548 ieee_oui(dev
, &names
, test
);
551 /* get path names for Linux on System z network devices */
552 err
= names_ccw(dev
, &names
);
553 if (err
>= 0 && names
.type
== NET_CCWGROUP
) {
556 if (snprintf(str
, sizeof(str
), "%s%s", prefix
, names
.ccw_group
) < (int)sizeof(str
))
557 udev_builtin_add_property(dev
, test
, "ID_NET_NAME_PATH", str
);
561 /* get PCI based path names, we compose only PCI based paths */
562 err
= names_pci(dev
, &names
);
566 /* plain PCI device */
567 if (names
.type
== NET_PCI
) {
570 if (names
.pci_onboard
[0])
571 if (snprintf(str
, sizeof(str
), "%s%s", prefix
, names
.pci_onboard
) < (int)sizeof(str
))
572 udev_builtin_add_property(dev
, test
, "ID_NET_NAME_ONBOARD", str
);
574 if (names
.pci_onboard_label
)
575 if (snprintf(str
, sizeof(str
), "%s%s", prefix
, names
.pci_onboard_label
) < (int)sizeof(str
))
576 udev_builtin_add_property(dev
, test
, "ID_NET_LABEL_ONBOARD", str
);
578 if (names
.pci_path
[0])
579 if (snprintf(str
, sizeof(str
), "%s%s", prefix
, names
.pci_path
) < (int)sizeof(str
))
580 udev_builtin_add_property(dev
, test
, "ID_NET_NAME_PATH", str
);
582 if (names
.pci_slot
[0])
583 if (snprintf(str
, sizeof(str
), "%s%s", prefix
, names
.pci_slot
) < (int)sizeof(str
))
584 udev_builtin_add_property(dev
, test
, "ID_NET_NAME_SLOT", str
);
589 err
= names_usb(dev
, &names
);
590 if (err
>= 0 && names
.type
== NET_USB
) {
593 if (names
.pci_path
[0])
594 if (snprintf(str
, sizeof(str
), "%s%s%s", prefix
, names
.pci_path
, names
.usb_ports
) < (int)sizeof(str
))
595 udev_builtin_add_property(dev
, test
, "ID_NET_NAME_PATH", str
);
597 if (names
.pci_slot
[0])
598 if (snprintf(str
, sizeof(str
), "%s%s%s", prefix
, names
.pci_slot
, names
.usb_ports
) < (int)sizeof(str
))
599 udev_builtin_add_property(dev
, test
, "ID_NET_NAME_SLOT", str
);
604 err
= names_bcma(dev
, &names
);
605 if (err
>= 0 && names
.type
== NET_BCMA
) {
608 if (names
.pci_path
[0])
609 if (snprintf(str
, sizeof(str
), "%s%s%s", prefix
, names
.pci_path
, names
.bcma_core
) < (int)sizeof(str
))
610 udev_builtin_add_property(dev
, test
, "ID_NET_NAME_PATH", str
);
612 if (names
.pci_slot
[0])
613 if (snprintf(str
, sizeof(str
), "%s%s%s", prefix
, names
.pci_slot
, names
.bcma_core
) < (int)sizeof(str
))
614 udev_builtin_add_property(dev
, test
, "ID_NET_NAME_SLOT", str
);
621 const struct udev_builtin udev_builtin_net_id
= {
623 .cmd
= builtin_net_id
,
624 .help
= "Network device properties",