udev-builtin-net_id.c revision 3058e017fced6d5c8712e10c8c1477421bc1e960
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering This file is part of systemd.
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering Copyright 2012 Kay Sievers <kay@vrfy.org>
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering systemd is free software; you can redistribute it and/or modify it
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering under the terms of the GNU Lesser General Public License as published by
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering the Free Software Foundation; either version 2.1 of the License, or
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering (at your option) any later version.
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering systemd is distributed in the hope that it will be useful, but
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering Lesser General Public License for more details.
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering You should have received a copy of the GNU Lesser General Public License
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering * Predictable network interface device names based on:
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering * - firmware/bios-provided index numbers for on-board devices
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering * - firmware-provided pci-express hotplug slot index number
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering * - physical/geographical location of the hardware
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering * - the interface's MAC address
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering * http://www.freedesktop.org/wiki/Software/systemd/PredictableNetworkInterfaceNames
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering * Two character prefixes based on the type of interface:
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering * en -- ethernet
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering * sl -- serial line IP (slip)
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering * Type of names:
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering * b<number> -- BCMA bus core number
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering * ccw<name> -- CCW bus group name
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering * o<index> -- on-board device index number
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering * s<slot>[f<function>][d<dev_port>] -- hotplug slot index number
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering * x<MAC> -- MAC address
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering * [P<domain>]p<bus>s<slot>[f<function>][d<dev_port>]
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering * -- PCI geographical location
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering * [P<domain>]p<bus>s<slot>[f<function>][u<port>][..][c<config>][i<interface>]
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering * -- USB port number chain
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering * All multi-function PCI devices will carry the [f<function>] number in the
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering * device name, including the function 0 device.
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering * When using PCI geography, The PCI domain is only prepended when it is not 0.
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering * For USB devices the full chain of port numbers of hubs is composed. If the
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering * name gets longer than the maximum number of 15 characters, the name is not
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering * The usual USB configuration == 1 and interface == 0 values are suppressed.
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering * PCI ethernet card with firmware index "1":
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering * ID_NET_NAME_ONBOARD=eno1
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering * ID_NET_NAME_ONBOARD_LABEL=Ethernet Port 1
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering * PCI ethernet card in hotplug slot with firmware index number:
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering * /sys/devices/pci0000:00/0000:00:1c.3/0000:05:00.0/net/ens1
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering * ID_NET_NAME_MAC=enx000000000466
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering * ID_NET_NAME_PATH=enp5s0
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering * ID_NET_NAME_SLOT=ens1
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering * PCI ethernet multi-function card with 2 ports:
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering * /sys/devices/pci0000:00/0000:00:1c.0/0000:02:00.0/net/enp2s0f0
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering * ID_NET_NAME_MAC=enx78e7d1ea46da
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering * ID_NET_NAME_PATH=enp2s0f0
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering * /sys/devices/pci0000:00/0000:00:1c.0/0000:02:00.1/net/enp2s0f1
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering * ID_NET_NAME_MAC=enx78e7d1ea46dc
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering * ID_NET_NAME_PATH=enp2s0f1
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering * PCI wlan card:
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering * /sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/net/wlp3s0
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering * ID_NET_NAME_MAC=wlx0024d7e31130
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering * ID_NET_NAME_PATH=wlp3s0
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering * USB built-in 3G modem:
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering * /sys/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.4/2-1.4:1.6/net/wwp0s29u1u4i6
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering * ID_NET_NAME_MAC=wwx028037ec0200
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering * ID_NET_NAME_PATH=wwp0s29u1u4i6
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering * USB Android phone:
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering * /sys/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2:1.0/net/enp0s29u1u2
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering * ID_NET_NAME_MAC=enxd626b3450fb5
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering * ID_NET_NAME_PATH=enp0s29u1u2
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering/* retrieve on-board index number and label from firmware */
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poetteringstatic int dev_pci_onboard(struct udev_device *dev, struct netnames *names) {
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering /* ACPI _DSM -- device specific method for naming a PCI or PCI Express device */
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering index = udev_device_get_sysattr_value(names->pcidev, "acpi_index");
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering /* SMBIOS type 41 -- Onboard Devices Extended Information */
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering index = udev_device_get_sysattr_value(names->pcidev, "index");
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering snprintf(names->pci_onboard, sizeof(names->pci_onboard), "o%d", idx);
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering names->pci_onboard_label = udev_device_get_sysattr_value(names->pcidev, "label");
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering/* read the 256 bytes PCI configuration space to check the multi-function bit */
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poetteringstatic bool is_pci_multifunction(struct udev_device *dev) {
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering snprintf(filename, sizeof(filename), "%s/config", udev_device_get_syspath(dev));
34829a324b1ffc6cb8405223329a9c55cd8de0eeLennart Poettering if (fread(&config, sizeof(config), 1, f) != 1)
multi = true;
out:
fclose(f);
return multi;
size_t l;
const char *attr;
if (sscanf(udev_device_get_sysname(names->pcidev), "%x:%x:%x.%u", &domain, &bus, &slot, &func) != 4)
return -ENOENT;
if (attr)
if (domain > 0)
if (dev_port > 0)
if (!pci) {
goto out;
if (!dir) {
goto out;
char *rest;
char *address;
hotplug_slot = i;
if (hotplug_slot > 0)
if (hotplug_slot > 0) {
if (domain > 0)
if (dev_port > 0)
out:
return err;
if (!parent)
return -ENOENT;
return -ENOENT;
char *ports;
char *config;
char *interf;
size_t l;
if (!usbdev)
return -ENOENT;
return -EINVAL;
return -EINVAL;
return -EINVAL;
s = ports;
return -ENAMETOOLONG;
unsigned int core;
if (!bcmadev)
return -ENOENT;
return -EINVAL;
if (core > 0)
const char *bus_id;
int rc;
if (!cdev)
return -ENOENT;
return -ENOENT;
if (!bus_id)
return -ENOENT;
return -EINVAL;
return EXIT_FAILURE;
return -ENOENT;
return -EINVAL;
return -EINVAL;
return -ENOENT;
return -EINVAL;
const char *devtype;
int err;
return EXIT_FAILURE;
case ARPHRD_ETHER:
case ARPHRD_SLIP:
return EXIT_FAILURE;
return EXIT_FAILURE;
if (!streq(s, p))
if (devtype) {
goto out;
if (err < 0)
goto out;
goto out;
if (snprintf(str, sizeof(str), "%s%s%s", prefix, names.pci_path, names.usb_ports) < (int)sizeof(str))
if (snprintf(str, sizeof(str), "%s%s%s", prefix, names.pci_slot, names.usb_ports) < (int)sizeof(str))
goto out;
if (snprintf(str, sizeof(str), "%s%s%s", prefix, names.pci_path, names.bcma_core) < (int)sizeof(str))
if (snprintf(str, sizeof(str), "%s%s%s", prefix, names.pci_slot, names.bcma_core) < (int)sizeof(str))
goto out;
out:
return EXIT_SUCCESS;