a660c63c551b88136ac6176855b5907cc533e848Kay Sievers This file is part of systemd.
a660c63c551b88136ac6176855b5907cc533e848Kay Sievers Copyright 2012 Kay Sievers <kay@vrfy.org>
a660c63c551b88136ac6176855b5907cc533e848Kay Sievers systemd is free software; you can redistribute it and/or modify it
a660c63c551b88136ac6176855b5907cc533e848Kay Sievers under the terms of the GNU Lesser General Public License as published by
a660c63c551b88136ac6176855b5907cc533e848Kay Sievers the Free Software Foundation; either version 2.1 of the License, or
a660c63c551b88136ac6176855b5907cc533e848Kay Sievers (at your option) any later version.
a660c63c551b88136ac6176855b5907cc533e848Kay Sievers systemd is distributed in the hope that it will be useful, but
a660c63c551b88136ac6176855b5907cc533e848Kay Sievers WITHOUT ANY WARRANTY; without even the implied warranty of
a660c63c551b88136ac6176855b5907cc533e848Kay Sievers MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
a660c63c551b88136ac6176855b5907cc533e848Kay Sievers Lesser General Public License for more details.
a660c63c551b88136ac6176855b5907cc533e848Kay Sievers You should have received a copy of the GNU Lesser General Public License
a660c63c551b88136ac6176855b5907cc533e848Kay Sievers along with systemd; If not, see <http://www.gnu.org/licenses/>.
ad37f393fa97f4274cc3bf97a0d8c388a429037eKay Sievers * Predictable network interface device names based on:
472780d8b1ec3f3f4ff78eb21a013136e5aa1cfeKay Sievers * - firmware/bios-provided index numbers for on-board devices
472780d8b1ec3f3f4ff78eb21a013136e5aa1cfeKay Sievers * - firmware-provided pci-express hotplug slot index number
472780d8b1ec3f3f4ff78eb21a013136e5aa1cfeKay Sievers * - physical/geographical location of the hardware
472780d8b1ec3f3f4ff78eb21a013136e5aa1cfeKay Sievers * - the interface's MAC address
25da63b9dac8f166ebf390ca92d1de18fbfc9d11Kay Sievers * http://www.freedesktop.org/wiki/Software/systemd/PredictableNetworkInterfaceNames
ad37f393fa97f4274cc3bf97a0d8c388a429037eKay Sievers * Two character prefixes based on the type of interface:
a8eaaee72a2f06e0fb64fb71de3b71ecba31dafbJan Engelhardt * en -- Ethernet
e0d4a0ac06afb856c9370c5c256f0f7bb7efdc8eHendrik Brueckner * sl -- serial line IP (slip)
0035597a30d120f70df2dd7da3d6128fb8ba6051Kay Sievers * wl -- wlan
0035597a30d120f70df2dd7da3d6128fb8ba6051Kay Sievers * ww -- wwan
ad37f393fa97f4274cc3bf97a0d8c388a429037eKay Sievers * Type of names:
d4b687c96adf207f0878aebf3ce3371f6160687fKay Sievers * b<number> -- BCMA bus core number
0037a669ac9a2bbedccdb2f483111351e8ff4659Dimitri John Ledkov * c<bus_id> -- CCW bus group name, without leading zeros [s390]
c0a43734ca84a3c9170d4a2d7f4d329b9ef47abcTom Gundersen * o<index>[d<dev_port>] -- on-board device index number
3058e017fced6d5c8712e10c8c1477421bc1e960Thadeu Lima de Souza Cascardo * s<slot>[f<function>][d<dev_port>] -- hotplug slot index number
1328f66ad16b5afeb5684858c27e121a46c1959eKay Sievers * x<MAC> -- MAC address
3058e017fced6d5c8712e10c8c1477421bc1e960Thadeu Lima de Souza Cascardo * [P<domain>]p<bus>s<slot>[f<function>][d<dev_port>]
214daa72cb0c72ea78d1eccd5ffe630a1e04b2f7Sean McGovern * -- PCI geographical location
214daa72cb0c72ea78d1eccd5ffe630a1e04b2f7Sean McGovern * [P<domain>]p<bus>s<slot>[f<function>][u<port>][..][c<config>][i<interface>]
1328f66ad16b5afeb5684858c27e121a46c1959eKay Sievers * -- USB port number chain
ad37f393fa97f4274cc3bf97a0d8c388a429037eKay Sievers * All multi-function PCI devices will carry the [f<function>] number in the
472780d8b1ec3f3f4ff78eb21a013136e5aa1cfeKay Sievers * device name, including the function 0 device.
214daa72cb0c72ea78d1eccd5ffe630a1e04b2f7Sean McGovern * When using PCI geography, The PCI domain is only prepended when it is not 0.
0d6ce9236f61cb991d7e8f2359d818e41ead0cf5Kay Sievers * For USB devices the full chain of port numbers of hubs is composed. If the
0d6ce9236f61cb991d7e8f2359d818e41ead0cf5Kay Sievers * name gets longer than the maximum number of 15 characters, the name is not
0d6ce9236f61cb991d7e8f2359d818e41ead0cf5Kay Sievers * The usual USB configuration == 1 and interface == 0 values are suppressed.
a8eaaee72a2f06e0fb64fb71de3b71ecba31dafbJan Engelhardt * PCI Ethernet card with firmware index "1":
0035597a30d120f70df2dd7da3d6128fb8ba6051Kay Sievers * ID_NET_NAME_ONBOARD=eno1
f610d6de38119b372b377ec41b2a6089872d3294Kay Sievers * ID_NET_NAME_ONBOARD_LABEL=Ethernet Port 1
a8eaaee72a2f06e0fb64fb71de3b71ecba31dafbJan Engelhardt * PCI Ethernet card in hotplug slot with firmware index number:
f610d6de38119b372b377ec41b2a6089872d3294Kay Sievers * /sys/devices/pci0000:00/0000:00:1c.3/0000:05:00.0/net/ens1
f610d6de38119b372b377ec41b2a6089872d3294Kay Sievers * ID_NET_NAME_MAC=enx000000000466
f610d6de38119b372b377ec41b2a6089872d3294Kay Sievers * ID_NET_NAME_PATH=enp5s0
de892aea1c486b59e04884268b612081d1660514Kay Sievers * ID_NET_NAME_SLOT=ens1
a8eaaee72a2f06e0fb64fb71de3b71ecba31dafbJan Engelhardt * PCI Ethernet multi-function card with 2 ports:
decd634e801bee2c554edb35383cc9d43417a850Kay Sievers * /sys/devices/pci0000:00/0000:00:1c.0/0000:02:00.0/net/enp2s0f0
decd634e801bee2c554edb35383cc9d43417a850Kay Sievers * ID_NET_NAME_MAC=enx78e7d1ea46da
decd634e801bee2c554edb35383cc9d43417a850Kay Sievers * ID_NET_NAME_PATH=enp2s0f0
decd634e801bee2c554edb35383cc9d43417a850Kay Sievers * /sys/devices/pci0000:00/0000:00:1c.0/0000:02:00.1/net/enp2s0f1
decd634e801bee2c554edb35383cc9d43417a850Kay Sievers * ID_NET_NAME_MAC=enx78e7d1ea46dc
decd634e801bee2c554edb35383cc9d43417a850Kay Sievers * ID_NET_NAME_PATH=enp2s0f1
f610d6de38119b372b377ec41b2a6089872d3294Kay Sievers * PCI wlan card:
f610d6de38119b372b377ec41b2a6089872d3294Kay Sievers * /sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/net/wlp3s0
f610d6de38119b372b377ec41b2a6089872d3294Kay Sievers * ID_NET_NAME_MAC=wlx0024d7e31130
f610d6de38119b372b377ec41b2a6089872d3294Kay Sievers * ID_NET_NAME_PATH=wlp3s0
f610d6de38119b372b377ec41b2a6089872d3294Kay Sievers * USB built-in 3G modem:
f610d6de38119b372b377ec41b2a6089872d3294Kay Sievers * /sys/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.4/2-1.4:1.6/net/wwp0s29u1u4i6
f610d6de38119b372b377ec41b2a6089872d3294Kay Sievers * ID_NET_NAME_MAC=wwx028037ec0200
f610d6de38119b372b377ec41b2a6089872d3294Kay Sievers * ID_NET_NAME_PATH=wwp0s29u1u4i6
f610d6de38119b372b377ec41b2a6089872d3294Kay Sievers * USB Android phone:
f610d6de38119b372b377ec41b2a6089872d3294Kay Sievers * /sys/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2:1.0/net/enp0s29u1u2
f610d6de38119b372b377ec41b2a6089872d3294Kay Sievers * ID_NET_NAME_MAC=enxd626b3450fb5
f610d6de38119b372b377ec41b2a6089872d3294Kay Sievers * ID_NET_NAME_PATH=enp0s29u1u2
0035597a30d120f70df2dd7da3d6128fb8ba6051Kay Sievers/* retrieve on-board index number and label from firmware */
0260944060426d54d9ecb40930baad985cbd02a1Kay Sieversstatic int dev_pci_onboard(struct udev_device *dev, struct netnames *names) {
0035597a30d120f70df2dd7da3d6128fb8ba6051Kay Sievers /* ACPI _DSM -- device specific method for naming a PCI or PCI Express device */
c0a43734ca84a3c9170d4a2d7f4d329b9ef47abcTom Gundersen attr = udev_device_get_sysattr_value(names->pcidev, "acpi_index");
01d183ddae6fb3445c4519cf1d90c6575f17292eKay Sievers /* SMBIOS type 41 -- Onboard Devices Extended Information */
c0a43734ca84a3c9170d4a2d7f4d329b9ef47abcTom Gundersen attr = udev_device_get_sysattr_value(names->pcidev, "index");
6c1e69f9456d022f14dd00737126cfa4d9cca10cLennart Poettering /* Some BIOSes report rubbish indexes that are excessively high (2^24-1 is an index VMware likes to report for
6c1e69f9456d022f14dd00737126cfa4d9cca10cLennart Poettering * example). Let's define a cut-off where we don't consider the index reliable anymore. We pick some arbitrary
6c1e69f9456d022f14dd00737126cfa4d9cca10cLennart Poettering * cut-off, which is somewhere beyond the realistic number of physical network interface a system might
6c1e69f9456d022f14dd00737126cfa4d9cca10cLennart Poettering * have. Ideally the kernel would already filter his crap for us, but it doesn't currently. */
309b578d313b363974b99e48f0e378111cc1fa91Tom Gundersen /* kernel provided port index for multiple ports on a single PCI function */
c0a43734ca84a3c9170d4a2d7f4d329b9ef47abcTom Gundersen attr = udev_device_get_sysattr_value(dev, "dev_port");
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers names->pci_onboard_label = udev_device_get_sysattr_value(names->pcidev, "label");
137661d87525a3c339afd2804e577532d58d3fbcKay Sievers/* read the 256 bytes PCI configuration space to check the multi-function bit */
1328f66ad16b5afeb5684858c27e121a46c1959eKay Sieversstatic bool is_pci_multifunction(struct udev_device *dev) {
63c372cb9df3bee01e3bf8cd7f96f336bddda846Lennart Poettering filename = strjoina(udev_device_get_syspath(dev), "/config");
0454229c100a2113ba82df55703436d6cb2c492bJason S. McMullan fd = open(filename, O_RDONLY | O_CLOEXEC);
0454229c100a2113ba82df55703436d6cb2c492bJason S. McMullan if (read(fd, &config, sizeof(config)) != sizeof(config))
de892aea1c486b59e04884268b612081d1660514Kay Sievers /* bit 0-6 header type, bit 7 multi/single function device */
0260944060426d54d9ecb40930baad985cbd02a1Kay Sieversstatic int dev_pci_slot(struct udev_device *dev, struct netnames *names) {
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers struct udev *udev = udev_device_get_udev(names->pcidev);
3058e017fced6d5c8712e10c8c1477421bc1e960Thadeu Lima de Souza Cascardo unsigned domain, bus, slot, func, dev_port = 0;
b5dd8148730db080b48b874c214f8f74ae787d6bZbigniew Jędrzejewski-Szmek _cleanup_closedir_ DIR *dir = NULL;
b5dd8148730db080b48b874c214f8f74ae787d6bZbigniew Jędrzejewski-Szmek if (sscanf(udev_device_get_sysname(names->pcidev), "%x:%x:%x.%u", &domain, &bus, &slot, &func) != 4)
309b578d313b363974b99e48f0e378111cc1fa91Tom Gundersen /* kernel provided port index for multiple ports on a single PCI function */
3058e017fced6d5c8712e10c8c1477421bc1e960Thadeu Lima de Souza Cascardo attr = udev_device_get_sysattr_value(dev, "dev_port");
3058e017fced6d5c8712e10c8c1477421bc1e960Thadeu Lima de Souza Cascardo dev_port = strtol(attr, NULL, 10);
1328f66ad16b5afeb5684858c27e121a46c1959eKay Sievers /* compose a name based on the raw kernel's PCI bus, slot numbers */
1fa2f38f0f011010bf57522b42fcc168856a7003Zbigniew Jędrzejewski-Szmek l = strpcpyf(&s, l, "P%u", domain);
1fa2f38f0f011010bf57522b42fcc168856a7003Zbigniew Jędrzejewski-Szmek l = strpcpyf(&s, l, "p%us%u", bus, slot);
1328f66ad16b5afeb5684858c27e121a46c1959eKay Sievers if (func > 0 || is_pci_multifunction(names->pcidev))
1fa2f38f0f011010bf57522b42fcc168856a7003Zbigniew Jędrzejewski-Szmek l = strpcpyf(&s, l, "f%u", func);
1fa2f38f0f011010bf57522b42fcc168856a7003Zbigniew Jędrzejewski-Szmek l = strpcpyf(&s, l, "d%u", dev_port);
0035597a30d120f70df2dd7da3d6128fb8ba6051Kay Sievers /* ACPI _SUN -- slot user number */
0035597a30d120f70df2dd7da3d6128fb8ba6051Kay Sievers pci = udev_device_new_from_subsystem_sysname(udev, "subsystem", "pci");
d054f0a4d451120c26494263fc4dc175bfd405b1Daniel Mack xsprintf(slots, "%s/slots", udev_device_get_syspath(pci));
0035597a30d120f70df2dd7da3d6128fb8ba6051Kay Sievers for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) {
d054f0a4d451120c26494263fc4dc175bfd405b1Daniel Mack xsprintf(str, "%s/%s/address", slots, dent->d_name);
0035597a30d120f70df2dd7da3d6128fb8ba6051Kay Sievers /* match slot address with device by stripping the function */
641906e9366891e0ad3e6e38b7396a427678c4cfThomas Hindoe Paaboel Andersen if (strneq(address, udev_device_get_sysname(names->pcidev), strlen(address)))
1328f66ad16b5afeb5684858c27e121a46c1959eKay Sievers if (func > 0 || is_pci_multifunction(names->pcidev))
3058e017fced6d5c8712e10c8c1477421bc1e960Thadeu Lima de Souza Cascardo l = strpcpyf(&s, l, "d%d", dev_port);
0260944060426d54d9ecb40930baad985cbd02a1Kay Sieversstatic int names_pci(struct udev_device *dev, struct netnames *names) {
54683f0f9b97a8f88aaf4fbb45b4d729057b101cTom Gundersen /* there can only ever be one virtio bus per parent device, so we can
54683f0f9b97a8f88aaf4fbb45b4d729057b101cTom Gundersen safely ignore any virtio buses. see
54683f0f9b97a8f88aaf4fbb45b4d729057b101cTom Gundersen <http://lists.linuxfoundation.org/pipermail/virtualization/2015-August/030331.html> */
54683f0f9b97a8f88aaf4fbb45b4d729057b101cTom Gundersen while (parent && streq_ptr("virtio", udev_device_get_subsystem(parent)))
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers /* check if our direct parent is a PCI device with no other bus in-between */
bb26309dd042c79de907f103d83f398b9436cde0Rob Clark if (streq_ptr("pci", udev_device_get_subsystem(parent))) {
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers names->pcidev = udev_device_get_parent_with_subsystem_devtype(dev, "pci", NULL);
0260944060426d54d9ecb40930baad985cbd02a1Kay Sieversstatic int names_usb(struct udev_device *dev, struct netnames *names) {
984c4348ff14d29c526d3d372daa82e278eeb5b4Kay Sievers usbdev = udev_device_get_parent_with_subsystem_devtype(dev, "usb", "usb_interface");
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers /* get USB port number chain, configuration, interface */
984c4348ff14d29c526d3d372daa82e278eeb5b4Kay Sievers strscpy(name, sizeof(name), udev_device_get_sysname(usbdev));
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers s[0] = '\0';
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers s[0] = '\0';
f7340ab269828d917cd1281e33e6dd4fdfee67b3Torstein Husebø /* prefix every port number in the chain with "u" */
d5a89d7dc17a5ba5cf4fc71f82963c5c94a31c3dKay Sievers l = strpcpyl(&s, sizeof(names->usb_ports), "u", ports, NULL);
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers /* append USB config number, suppress the common config == 1 */
d5a89d7dc17a5ba5cf4fc71f82963c5c94a31c3dKay Sievers l = strpcpyl(&s, sizeof(names->usb_ports), "c", config, NULL);
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers /* append USB interface number, suppress the interface == 0 */
d5a89d7dc17a5ba5cf4fc71f82963c5c94a31c3dKay Sievers l = strpcpyl(&s, sizeof(names->usb_ports), "i", interf, NULL);
984c4348ff14d29c526d3d372daa82e278eeb5b4Kay Sieversstatic int names_bcma(struct udev_device *dev, struct netnames *names) {
984c4348ff14d29c526d3d372daa82e278eeb5b4Kay Sievers bcmadev = udev_device_get_parent_with_subsystem_devtype(dev, "bcma", NULL);
f4ddacbd4de0f159ec598f8ad690466a84787ec5Kay Sievers /* bus num:core num */
b5dd8148730db080b48b874c214f8f74ae787d6bZbigniew Jędrzejewski-Szmek if (sscanf(udev_device_get_sysname(bcmadev), "bcma%*u:%u", &core) != 1)
f4ddacbd4de0f159ec598f8ad690466a84787ec5Kay Sievers /* suppress the common core == 0 */
e0d4a0ac06afb856c9370c5c256f0f7bb7efdc8eHendrik Bruecknerstatic int names_ccw(struct udev_device *dev, struct netnames *names) {
e0d4a0ac06afb856c9370c5c256f0f7bb7efdc8eHendrik Brueckner /* Retrieve the associated CCW device */
e0d4a0ac06afb856c9370c5c256f0f7bb7efdc8eHendrik Brueckner /* Network devices are always grouped CCW devices */
e0d4a0ac06afb856c9370c5c256f0f7bb7efdc8eHendrik Brueckner if (!streq_ptr("ccwgroup", udev_device_get_subsystem(cdev)))
e0d4a0ac06afb856c9370c5c256f0f7bb7efdc8eHendrik Brueckner /* Retrieve bus-ID of the grouped CCW device. The bus-ID uniquely
e0d4a0ac06afb856c9370c5c256f0f7bb7efdc8eHendrik Brueckner * identifies the network device on the Linux on System z channel
e0d4a0ac06afb856c9370c5c256f0f7bb7efdc8eHendrik Brueckner * subsystem. Note that the bus-ID contains lowercase characters.
e0d4a0ac06afb856c9370c5c256f0f7bb7efdc8eHendrik Brueckner /* Check the length of the bus-ID. Rely on that the kernel provides
e0d4a0ac06afb856c9370c5c256f0f7bb7efdc8eHendrik Brueckner * a correct bus-ID; alternatively, improve this check and parse and
e0d4a0ac06afb856c9370c5c256f0f7bb7efdc8eHendrik Brueckner * verify each bus-ID part...
e0d4a0ac06afb856c9370c5c256f0f7bb7efdc8eHendrik Brueckner if (!bus_id_len || bus_id_len < 8 || bus_id_len > 9)
0037a669ac9a2bbedccdb2f483111351e8ff4659Dimitri John Ledkov /* Strip leading zeros from the bus id for aesthetic purposes. This
0037a669ac9a2bbedccdb2f483111351e8ff4659Dimitri John Ledkov * keeps the ccw names stable, yet much shorter in general case of
0037a669ac9a2bbedccdb2f483111351e8ff4659Dimitri John Ledkov * bus_id 0.0.0600 -> 600. This is similar to e.g. how PCI domain is
0037a669ac9a2bbedccdb2f483111351e8ff4659Dimitri John Ledkov * not prepended when it is zero.
e0d4a0ac06afb856c9370c5c256f0f7bb7efdc8eHendrik Brueckner /* Store the CCW bus-ID for use as network device name */
0037a669ac9a2bbedccdb2f483111351e8ff4659Dimitri John Ledkov rc = snprintf(names->ccw_group, sizeof(names->ccw_group), "c%s", bus_id);
d4b687c96adf207f0878aebf3ce3371f6160687fKay Sievers if (rc >= 0 && rc < (int)sizeof(names->ccw_group))
0260944060426d54d9ecb40930baad985cbd02a1Kay Sieversstatic int names_mac(struct udev_device *dev, struct netnames *names) {
d23965a64eb5c2c97b839dc2e3e79fc1613994f1Kay Sievers const char *s;
d23965a64eb5c2c97b839dc2e3e79fc1613994f1Kay Sievers unsigned int i;
d23965a64eb5c2c97b839dc2e3e79fc1613994f1Kay Sievers /* check for NET_ADDR_PERM, skip random MAC addresses */
d23965a64eb5c2c97b839dc2e3e79fc1613994f1Kay Sievers s = udev_device_get_sysattr_value(dev, "addr_assign_type");
d23965a64eb5c2c97b839dc2e3e79fc1613994f1Kay Sievers s = udev_device_get_sysattr_value(dev, "address");
d23965a64eb5c2c97b839dc2e3e79fc1613994f1Kay Sievers if (sscanf(s, "%x:%x:%x:%x:%x:%x", &a1, &a2, &a3, &a4, &a5, &a6) != 6)
d23965a64eb5c2c97b839dc2e3e79fc1613994f1Kay Sievers /* skip empty MAC addresses */
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers/* IEEE Organizationally Unique Identifier vendor string */
0260944060426d54d9ecb40930baad985cbd02a1Kay Sieversstatic int ieee_oui(struct udev_device *dev, struct netnames *names, bool test) {
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers /* skip commonly misused 00:00:00 (Xerox) prefix */
d054f0a4d451120c26494263fc4dc175bfd405b1Daniel Mack xsprintf(str, "OUI:%02X%02X%02X%02X%02X%02X", names->mac[0],
d054f0a4d451120c26494263fc4dc175bfd405b1Daniel Mack names->mac[1], names->mac[2], names->mac[3], names->mac[4],
a4bbef099209d4e3bccd913cd30da536f8971064Kay Sievers udev_builtin_hwdb_lookup(dev, NULL, str, NULL, test);
a660c63c551b88136ac6176855b5907cc533e848Kay Sieversstatic int builtin_net_id(struct udev_device *dev, int argc, char *argv[], bool test) {
d23965a64eb5c2c97b839dc2e3e79fc1613994f1Kay Sievers const char *s;
72bc96f07868d532596477604b6fb41633ebd124Kay Sievers const char *p;
d23965a64eb5c2c97b839dc2e3e79fc1613994f1Kay Sievers unsigned int i;
e0d4a0ac06afb856c9370c5c256f0f7bb7efdc8eHendrik Brueckner /* handle only ARPHRD_ETHER and ARPHRD_SLIP devices */
72bc96f07868d532596477604b6fb41633ebd124Kay Sievers /* skip stacked devices, like VLANs, ... */
72bc96f07868d532596477604b6fb41633ebd124Kay Sievers s = udev_device_get_sysattr_value(dev, "ifindex");
72bc96f07868d532596477604b6fb41633ebd124Kay Sievers p = udev_device_get_sysattr_value(dev, "iflink");
d054f0a4d451120c26494263fc4dc175bfd405b1Daniel Mack xsprintf(str, "%sx%02x%02x%02x%02x%02x%02x", prefix,
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers udev_builtin_add_property(dev, test, "ID_NET_NAME_MAC", str);
e0d4a0ac06afb856c9370c5c256f0f7bb7efdc8eHendrik Brueckner /* get path names for Linux on System z network devices */
e0d4a0ac06afb856c9370c5c256f0f7bb7efdc8eHendrik Brueckner if (err >= 0 && names.type == NET_CCWGROUP) {
d4b687c96adf207f0878aebf3ce3371f6160687fKay Sievers if (snprintf(str, sizeof(str), "%s%s", prefix, names.ccw_group) < (int)sizeof(str))
e0d4a0ac06afb856c9370c5c256f0f7bb7efdc8eHendrik Brueckner udev_builtin_add_property(dev, test, "ID_NET_NAME_PATH", str);
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers /* get PCI based path names, we compose only PCI based paths */
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers /* plain PCI device */
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers if (snprintf(str, sizeof(str), "%s%s", prefix, names.pci_onboard) < (int)sizeof(str))
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers udev_builtin_add_property(dev, test, "ID_NET_NAME_ONBOARD", str);
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers if (snprintf(str, sizeof(str), "%s%s", prefix, names.pci_onboard_label) < (int)sizeof(str))
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers udev_builtin_add_property(dev, test, "ID_NET_LABEL_ONBOARD", str);
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers if (snprintf(str, sizeof(str), "%s%s", prefix, names.pci_path) < (int)sizeof(str))
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers udev_builtin_add_property(dev, test, "ID_NET_NAME_PATH", str);
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers if (snprintf(str, sizeof(str), "%s%s", prefix, names.pci_slot) < (int)sizeof(str))
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers udev_builtin_add_property(dev, test, "ID_NET_NAME_SLOT", str);
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers /* USB device */
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers if (snprintf(str, sizeof(str), "%s%s%s", prefix, names.pci_path, names.usb_ports) < (int)sizeof(str))
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers udev_builtin_add_property(dev, test, "ID_NET_NAME_PATH", str);
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers if (snprintf(str, sizeof(str), "%s%s%s", prefix, names.pci_slot, names.usb_ports) < (int)sizeof(str))
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers udev_builtin_add_property(dev, test, "ID_NET_NAME_SLOT", str);
984c4348ff14d29c526d3d372daa82e278eeb5b4Kay Sievers /* Broadcom bus */
984c4348ff14d29c526d3d372daa82e278eeb5b4Kay Sievers if (snprintf(str, sizeof(str), "%s%s%s", prefix, names.pci_path, names.bcma_core) < (int)sizeof(str))
984c4348ff14d29c526d3d372daa82e278eeb5b4Kay Sievers udev_builtin_add_property(dev, test, "ID_NET_NAME_PATH", str);
984c4348ff14d29c526d3d372daa82e278eeb5b4Kay Sievers if (snprintf(str, sizeof(str), "%s%s%s", prefix, names.pci_slot, names.bcma_core) < (int)sizeof(str))
984c4348ff14d29c526d3d372daa82e278eeb5b4Kay Sievers udev_builtin_add_property(dev, test, "ID_NET_NAME_SLOT", str);