udev-builtin-net_id.c revision 984c4348ff14d29c526d3d372daa82e278eeb5b4
a660c63c551b88136ac6176855b5907cc533e848Kay Sievers/***
a660c63c551b88136ac6176855b5907cc533e848Kay Sievers This file is part of systemd.
a660c63c551b88136ac6176855b5907cc533e848Kay Sievers
a660c63c551b88136ac6176855b5907cc533e848Kay Sievers Copyright 2012 Kay Sievers <kay@vrfy.org>
a660c63c551b88136ac6176855b5907cc533e848Kay Sievers
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
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
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/>.
a660c63c551b88136ac6176855b5907cc533e848Kay Sievers***/
a660c63c551b88136ac6176855b5907cc533e848Kay Sievers
d23965a64eb5c2c97b839dc2e3e79fc1613994f1Kay Sievers/*
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
472780d8b1ec3f3f4ff78eb21a013136e5aa1cfeKay Sievers *
25da63b9dac8f166ebf390ca92d1de18fbfc9d11Kay Sievers * Two character prefixes based on the type of interface:
25da63b9dac8f166ebf390ca92d1de18fbfc9d11Kay Sievers * en -- ethernet
ad37f393fa97f4274cc3bf97a0d8c388a429037eKay Sievers * wl -- wlan
0035597a30d120f70df2dd7da3d6128fb8ba6051Kay Sievers * ww -- wwan
e0d4a0ac06afb856c9370c5c256f0f7bb7efdc8eHendrik Brueckner *
0035597a30d120f70df2dd7da3d6128fb8ba6051Kay Sievers * Type of names:
0035597a30d120f70df2dd7da3d6128fb8ba6051Kay Sievers * o<index> -- on-board device index number
d23965a64eb5c2c97b839dc2e3e79fc1613994f1Kay Sievers * s<slot>[f<function>][d<dev_id>] -- hotplug slot index number
ad37f393fa97f4274cc3bf97a0d8c388a429037eKay Sievers * x<MAC> -- MAC address
d4b687c96adf207f0878aebf3ce3371f6160687fKay Sievers * p<bus>s<slot>[f<function>][d<dev_id>] -- PCI geographical location
d4b687c96adf207f0878aebf3ce3371f6160687fKay Sievers * p<bus>s<slot>[f<function>][u<port>][..][c<config>][i<interface>]
c0a43734ca84a3c9170d4a2d7f4d329b9ef47abcTom Gundersen * -- USB port number chain
3058e017fced6d5c8712e10c8c1477421bc1e960Thadeu Lima de Souza Cascardo *
1328f66ad16b5afeb5684858c27e121a46c1959eKay Sievers * All multi-function PCI devices will carry the [f<function>] number in the
3058e017fced6d5c8712e10c8c1477421bc1e960Thadeu Lima de Souza Cascardo * device name, including the function 0 device.
214daa72cb0c72ea78d1eccd5ffe630a1e04b2f7Sean McGovern *
214daa72cb0c72ea78d1eccd5ffe630a1e04b2f7Sean McGovern * For USB devices the full chain of port numbers of hubs is composed. If the
1328f66ad16b5afeb5684858c27e121a46c1959eKay Sievers * name gets longer than the maximum number of 15 characters, the name is not
472780d8b1ec3f3f4ff78eb21a013136e5aa1cfeKay Sievers * exported.
ad37f393fa97f4274cc3bf97a0d8c388a429037eKay Sievers * The usual USB configuration == 1 and interface == 0 values are suppressed.
472780d8b1ec3f3f4ff78eb21a013136e5aa1cfeKay Sievers *
d23965a64eb5c2c97b839dc2e3e79fc1613994f1Kay Sievers * PCI ethernet card with firmware index "1":
214daa72cb0c72ea78d1eccd5ffe630a1e04b2f7Sean McGovern * ID_NET_NAME_ONBOARD=eno1
214daa72cb0c72ea78d1eccd5ffe630a1e04b2f7Sean McGovern * ID_NET_NAME_ONBOARD_LABEL=Ethernet Port 1
0d6ce9236f61cb991d7e8f2359d818e41ead0cf5Kay Sievers *
0d6ce9236f61cb991d7e8f2359d818e41ead0cf5Kay Sievers * PCI ethernet card in hotplug slot with firmware index number:
0d6ce9236f61cb991d7e8f2359d818e41ead0cf5Kay Sievers * /sys/devices/pci0000:00/0000:00:1c.3/0000:05:00.0/net/ens1
0d6ce9236f61cb991d7e8f2359d818e41ead0cf5Kay Sievers * ID_NET_NAME_MAC=enx000000000466
ad37f393fa97f4274cc3bf97a0d8c388a429037eKay Sievers * ID_NET_NAME_PATH=enp5s0
decd634e801bee2c554edb35383cc9d43417a850Kay Sievers * ID_NET_NAME_SLOT=ens1
0035597a30d120f70df2dd7da3d6128fb8ba6051Kay Sievers *
f610d6de38119b372b377ec41b2a6089872d3294Kay Sievers * PCI ethernet multi-function card with 2 ports:
f610d6de38119b372b377ec41b2a6089872d3294Kay Sievers * /sys/devices/pci0000:00/0000:00:1c.0/0000:02:00.0/net/enp2s0f0
ad37f393fa97f4274cc3bf97a0d8c388a429037eKay Sievers * ID_NET_NAME_MAC=enx78e7d1ea46da
f610d6de38119b372b377ec41b2a6089872d3294Kay Sievers * ID_NET_NAME_PATH=enp2s0f0
f610d6de38119b372b377ec41b2a6089872d3294Kay Sievers * /sys/devices/pci0000:00/0000:00:1c.0/0000:02:00.1/net/enp2s0f1
f610d6de38119b372b377ec41b2a6089872d3294Kay Sievers * ID_NET_NAME_MAC=enx78e7d1ea46dc
de892aea1c486b59e04884268b612081d1660514Kay Sievers * ID_NET_NAME_PATH=enp2s0f1
f610d6de38119b372b377ec41b2a6089872d3294Kay Sievers *
decd634e801bee2c554edb35383cc9d43417a850Kay Sievers * PCI wlan card:
decd634e801bee2c554edb35383cc9d43417a850Kay Sievers * /sys/devices/pci0000:00/0000:00:1c.1/0000:03:00.0/net/wlp3s0
decd634e801bee2c554edb35383cc9d43417a850Kay Sievers * ID_NET_NAME_MAC=wlx0024d7e31130
decd634e801bee2c554edb35383cc9d43417a850Kay Sievers * ID_NET_NAME_PATH=wlp3s0
decd634e801bee2c554edb35383cc9d43417a850Kay Sievers *
decd634e801bee2c554edb35383cc9d43417a850Kay Sievers * USB built-in 3G modem:
decd634e801bee2c554edb35383cc9d43417a850Kay Sievers * /sys/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.4/2-1.4:1.6/net/wwp0s29u1u4i6
decd634e801bee2c554edb35383cc9d43417a850Kay Sievers * ID_NET_NAME_MAC=wwx028037ec0200
f610d6de38119b372b377ec41b2a6089872d3294Kay Sievers * ID_NET_NAME_PATH=wwp0s29u1u4i6
f610d6de38119b372b377ec41b2a6089872d3294Kay Sievers *
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
f610d6de38119b372b377ec41b2a6089872d3294Kay Sievers */
f610d6de38119b372b377ec41b2a6089872d3294Kay Sievers
f610d6de38119b372b377ec41b2a6089872d3294Kay Sievers#include <stdio.h>
f610d6de38119b372b377ec41b2a6089872d3294Kay Sievers#include <stdlib.h>
f610d6de38119b372b377ec41b2a6089872d3294Kay Sievers#include <stdarg.h>
f610d6de38119b372b377ec41b2a6089872d3294Kay Sievers#include <unistd.h>
f610d6de38119b372b377ec41b2a6089872d3294Kay Sievers#include <string.h>
f610d6de38119b372b377ec41b2a6089872d3294Kay Sievers#include <errno.h>
d23965a64eb5c2c97b839dc2e3e79fc1613994f1Kay Sievers#include <net/if.h>
d23965a64eb5c2c97b839dc2e3e79fc1613994f1Kay Sievers#include <linux/pci_regs.h>
a660c63c551b88136ac6176855b5907cc533e848Kay Sievers
a660c63c551b88136ac6176855b5907cc533e848Kay Sievers#include "udev.h"
a660c63c551b88136ac6176855b5907cc533e848Kay Sievers
a660c63c551b88136ac6176855b5907cc533e848Kay Sieversenum netname_type{
a660c63c551b88136ac6176855b5907cc533e848Kay Sievers NET_UNDEF,
a660c63c551b88136ac6176855b5907cc533e848Kay Sievers NET_PCI,
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers NET_USB,
19aa72f74e41045510b4af3f1415b419d42ff20bTom Gundersen NET_BCMA,
de892aea1c486b59e04884268b612081d1660514Kay Sievers};
a660c63c551b88136ac6176855b5907cc533e848Kay Sievers
a660c63c551b88136ac6176855b5907cc533e848Kay Sieversstruct netnames {
a5c32cff1f56afe6f0c6c70d91a88a7a8238b2d7Harald Hoyer enum netname_type type;
a660c63c551b88136ac6176855b5907cc533e848Kay Sievers
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers uint8_t mac[6];
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers bool mac_valid;
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers struct udev_device *pcidev;
984c4348ff14d29c526d3d372daa82e278eeb5b4Kay Sievers char pci_slot[IFNAMSIZ];
e3d563346c4237af23335cc6904e0662efdf62adTom Gundersen char pci_path[IFNAMSIZ];
e0d4a0ac06afb856c9370c5c256f0f7bb7efdc8eHendrik Brueckner char pci_onboard[IFNAMSIZ];
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers const char *pci_onboard_label;
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers char usb_ports[IFNAMSIZ];
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers char bcma_core[IFNAMSIZ];
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers};
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers/* retrieve on-board index number and label from firmware */
0260944060426d54d9ecb40930baad985cbd02a1Kay Sieversstatic int dev_pci_onboard(struct udev_device *dev, struct netnames *names) {
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers const char *index;
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers int idx;
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers /* ACPI _DSM -- device specific method for naming a PCI or PCI Express device */
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers index = udev_device_get_sysattr_value(names->pcidev, "acpi_index");
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers /* SMBIOS type 41 -- Onboard Devices Extended Information */
984c4348ff14d29c526d3d372daa82e278eeb5b4Kay Sievers if (!index)
d4b687c96adf207f0878aebf3ce3371f6160687fKay Sievers index = udev_device_get_sysattr_value(names->pcidev, "index");
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers if (!index)
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers return -ENOENT;
0035597a30d120f70df2dd7da3d6128fb8ba6051Kay Sievers idx = strtoul(index, NULL, 0);
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers if (idx <= 0)
c0a43734ca84a3c9170d4a2d7f4d329b9ef47abcTom Gundersen return -EINVAL;
c0a43734ca84a3c9170d4a2d7f4d329b9ef47abcTom Gundersen snprintf(names->pci_onboard, sizeof(names->pci_onboard), "o%d", idx);
c0a43734ca84a3c9170d4a2d7f4d329b9ef47abcTom Gundersen
c0a43734ca84a3c9170d4a2d7f4d329b9ef47abcTom Gundersen names->pci_onboard_label = udev_device_get_sysattr_value(names->pcidev, "label");
0035597a30d120f70df2dd7da3d6128fb8ba6051Kay Sievers return 0;
a660c63c551b88136ac6176855b5907cc533e848Kay Sievers}
0035597a30d120f70df2dd7da3d6128fb8ba6051Kay Sievers
c0a43734ca84a3c9170d4a2d7f4d329b9ef47abcTom Gundersen/* read the 256 bytes PCI configuration space to check the multi-function bit */
01d183ddae6fb3445c4519cf1d90c6575f17292eKay Sieversstatic bool is_pci_multifunction(struct udev_device *dev) {
c0a43734ca84a3c9170d4a2d7f4d329b9ef47abcTom Gundersen char filename[256];
c0a43734ca84a3c9170d4a2d7f4d329b9ef47abcTom Gundersen FILE *f = NULL;
c0a43734ca84a3c9170d4a2d7f4d329b9ef47abcTom Gundersen char config[64];
0035597a30d120f70df2dd7da3d6128fb8ba6051Kay Sievers bool multi = false;
c0a43734ca84a3c9170d4a2d7f4d329b9ef47abcTom Gundersen
c0a43734ca84a3c9170d4a2d7f4d329b9ef47abcTom Gundersen snprintf(filename, sizeof(filename), "%s/config", udev_device_get_syspath(dev));
0035597a30d120f70df2dd7da3d6128fb8ba6051Kay Sievers f = fopen(filename, "re");
0035597a30d120f70df2dd7da3d6128fb8ba6051Kay Sievers if (!f)
c0a43734ca84a3c9170d4a2d7f4d329b9ef47abcTom Gundersen goto out;
309b578d313b363974b99e48f0e378111cc1fa91Tom Gundersen if (fread(&config, sizeof(config), 1, f) != 1)
c0a43734ca84a3c9170d4a2d7f4d329b9ef47abcTom Gundersen goto out;
c0a43734ca84a3c9170d4a2d7f4d329b9ef47abcTom Gundersen
c0a43734ca84a3c9170d4a2d7f4d329b9ef47abcTom Gundersen /* bit 0-6 header type, bit 7 multi/single function device */
c0a43734ca84a3c9170d4a2d7f4d329b9ef47abcTom Gundersen if ((config[PCI_HEADER_TYPE] & 0x80) != 0)
c0a43734ca84a3c9170d4a2d7f4d329b9ef47abcTom Gundersen multi = true;
c0a43734ca84a3c9170d4a2d7f4d329b9ef47abcTom Gundersenout:
c0a43734ca84a3c9170d4a2d7f4d329b9ef47abcTom Gundersen if(f)
c0a43734ca84a3c9170d4a2d7f4d329b9ef47abcTom Gundersen fclose(f);
c0a43734ca84a3c9170d4a2d7f4d329b9ef47abcTom Gundersen return multi;
c0a43734ca84a3c9170d4a2d7f4d329b9ef47abcTom Gundersen}
c0a43734ca84a3c9170d4a2d7f4d329b9ef47abcTom Gundersen
d23965a64eb5c2c97b839dc2e3e79fc1613994f1Kay Sieversstatic int dev_pci_slot(struct udev_device *dev, struct netnames *names) {
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers struct udev *udev = udev_device_get_udev(names->pcidev);
c0a43734ca84a3c9170d4a2d7f4d329b9ef47abcTom Gundersen unsigned int bus;
0035597a30d120f70df2dd7da3d6128fb8ba6051Kay Sievers unsigned int slot;
0035597a30d120f70df2dd7da3d6128fb8ba6051Kay Sievers unsigned int func;
d23965a64eb5c2c97b839dc2e3e79fc1613994f1Kay Sievers unsigned int dev_id = 0;
137661d87525a3c339afd2804e577532d58d3fbcKay Sievers size_t l;
1328f66ad16b5afeb5684858c27e121a46c1959eKay Sievers char *s;
1cb5d1f31909c731d93568eb4838cb86e033d783Lennart Poettering const char *attr;
1cb5d1f31909c731d93568eb4838cb86e033d783Lennart Poettering struct udev_device *pci = NULL;
1cb5d1f31909c731d93568eb4838cb86e033d783Lennart Poettering char slots[256];
de892aea1c486b59e04884268b612081d1660514Kay Sievers DIR *dir;
63c372cb9df3bee01e3bf8cd7f96f336bddda846Lennart Poettering struct dirent *dent;
de892aea1c486b59e04884268b612081d1660514Kay Sievers char str[256];
de892aea1c486b59e04884268b612081d1660514Kay Sievers int hotplug_slot = 0;
1cb5d1f31909c731d93568eb4838cb86e033d783Lennart Poettering int err = 0;
de892aea1c486b59e04884268b612081d1660514Kay Sievers
1cb5d1f31909c731d93568eb4838cb86e033d783Lennart Poettering if (sscanf(udev_device_get_sysname(names->pcidev), "0000:%x:%x.%d", &bus, &slot, &func) != 3)
de892aea1c486b59e04884268b612081d1660514Kay Sievers return -ENOENT;
de892aea1c486b59e04884268b612081d1660514Kay Sievers
1328f66ad16b5afeb5684858c27e121a46c1959eKay Sievers /* kernel provided multi-device index */
1cb5d1f31909c731d93568eb4838cb86e033d783Lennart Poettering attr = udev_device_get_sysattr_value(dev, "dev_id");
1cb5d1f31909c731d93568eb4838cb86e033d783Lennart Poettering if (attr)
1cb5d1f31909c731d93568eb4838cb86e033d783Lennart Poettering dev_id = strtol(attr, NULL, 16);
de892aea1c486b59e04884268b612081d1660514Kay Sievers
de892aea1c486b59e04884268b612081d1660514Kay Sievers /* compose a name based on the raw kernel's PCI bus, slot numbers */
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers s = names->pci_path;
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers l = strpcpyf(&s, sizeof(names->pci_path), "p%ds%d", bus, slot);
3058e017fced6d5c8712e10c8c1477421bc1e960Thadeu Lima de Souza Cascardo if (func > 0 || is_pci_multifunction(names->pcidev))
1328f66ad16b5afeb5684858c27e121a46c1959eKay Sievers l = strpcpyf(&s, l, "f%d", func);
1328f66ad16b5afeb5684858c27e121a46c1959eKay Sievers if (dev_id > 0)
1328f66ad16b5afeb5684858c27e121a46c1959eKay Sievers l = strpcpyf(&s, l, "d%d", dev_id);
0035597a30d120f70df2dd7da3d6128fb8ba6051Kay Sievers if (l == 0)
b5dd8148730db080b48b874c214f8f74ae787d6bZbigniew Jędrzejewski-Szmek names->pci_path[0] = '\0';
b5dd8148730db080b48b874c214f8f74ae787d6bZbigniew Jędrzejewski-Szmek
0035597a30d120f70df2dd7da3d6128fb8ba6051Kay Sievers /* ACPI _SUN -- slot user number */
b5dd8148730db080b48b874c214f8f74ae787d6bZbigniew Jędrzejewski-Szmek pci = udev_device_new_from_subsystem_sysname(udev, "subsystem", "pci");
0035597a30d120f70df2dd7da3d6128fb8ba6051Kay Sievers if (!pci) {
b5dd8148730db080b48b874c214f8f74ae787d6bZbigniew Jędrzejewski-Szmek err = -ENOENT;
0035597a30d120f70df2dd7da3d6128fb8ba6051Kay Sievers goto out;
1328f66ad16b5afeb5684858c27e121a46c1959eKay Sievers }
309b578d313b363974b99e48f0e378111cc1fa91Tom Gundersen snprintf(slots, sizeof(slots), "%s/slots", udev_device_get_syspath(pci));
3058e017fced6d5c8712e10c8c1477421bc1e960Thadeu Lima de Souza Cascardo dir = opendir(slots);
1328f66ad16b5afeb5684858c27e121a46c1959eKay Sievers if (!dir) {
3058e017fced6d5c8712e10c8c1477421bc1e960Thadeu Lima de Souza Cascardo err = -errno;
1328f66ad16b5afeb5684858c27e121a46c1959eKay Sievers goto out;
1328f66ad16b5afeb5684858c27e121a46c1959eKay Sievers }
1328f66ad16b5afeb5684858c27e121a46c1959eKay Sievers
214daa72cb0c72ea78d1eccd5ffe630a1e04b2f7Sean McGovern for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) {
214daa72cb0c72ea78d1eccd5ffe630a1e04b2f7Sean McGovern int i;
1fa2f38f0f011010bf57522b42fcc168856a7003Zbigniew Jędrzejewski-Szmek char *rest;
1fa2f38f0f011010bf57522b42fcc168856a7003Zbigniew Jędrzejewski-Szmek char *address;
1328f66ad16b5afeb5684858c27e121a46c1959eKay Sievers
1fa2f38f0f011010bf57522b42fcc168856a7003Zbigniew Jędrzejewski-Szmek if (dent->d_name[0] == '.')
3058e017fced6d5c8712e10c8c1477421bc1e960Thadeu Lima de Souza Cascardo continue;
1fa2f38f0f011010bf57522b42fcc168856a7003Zbigniew Jędrzejewski-Szmek i = strtol(dent->d_name, &rest, 10);
1328f66ad16b5afeb5684858c27e121a46c1959eKay Sievers if (rest[0] != '\0')
1328f66ad16b5afeb5684858c27e121a46c1959eKay Sievers continue;
d23965a64eb5c2c97b839dc2e3e79fc1613994f1Kay Sievers if (i < 1)
0035597a30d120f70df2dd7da3d6128fb8ba6051Kay Sievers continue;
0035597a30d120f70df2dd7da3d6128fb8ba6051Kay Sievers snprintf(str, sizeof(str), "%s/%s/address", slots, dent->d_name);
0035597a30d120f70df2dd7da3d6128fb8ba6051Kay Sievers if (read_one_line_file(str, &address) >= 0) {
0035597a30d120f70df2dd7da3d6128fb8ba6051Kay Sievers /* match slot address with device by stripping the function */
0035597a30d120f70df2dd7da3d6128fb8ba6051Kay Sievers if (strncmp(address, udev_device_get_sysname(names->pcidev), strlen(address)) == 0)
0035597a30d120f70df2dd7da3d6128fb8ba6051Kay Sievers hotplug_slot = i;
0035597a30d120f70df2dd7da3d6128fb8ba6051Kay Sievers free(address);
0035597a30d120f70df2dd7da3d6128fb8ba6051Kay Sievers }
0035597a30d120f70df2dd7da3d6128fb8ba6051Kay Sievers
0035597a30d120f70df2dd7da3d6128fb8ba6051Kay Sievers if (hotplug_slot > 0)
0035597a30d120f70df2dd7da3d6128fb8ba6051Kay Sievers break;
d23965a64eb5c2c97b839dc2e3e79fc1613994f1Kay Sievers }
d23965a64eb5c2c97b839dc2e3e79fc1613994f1Kay Sievers closedir(dir);
0035597a30d120f70df2dd7da3d6128fb8ba6051Kay Sievers
0035597a30d120f70df2dd7da3d6128fb8ba6051Kay Sievers if (hotplug_slot > 0) {
0035597a30d120f70df2dd7da3d6128fb8ba6051Kay Sievers s = names->pci_slot;
0035597a30d120f70df2dd7da3d6128fb8ba6051Kay Sievers l = strpcpyf(&s, sizeof(names->pci_slot), "s%d", hotplug_slot);
0035597a30d120f70df2dd7da3d6128fb8ba6051Kay Sievers if (func > 0 || is_pci_multifunction(names->pcidev))
0035597a30d120f70df2dd7da3d6128fb8ba6051Kay Sievers l = strpcpyf(&s, l, "f%d", func);
0035597a30d120f70df2dd7da3d6128fb8ba6051Kay Sievers if (dev_id > 0)
0035597a30d120f70df2dd7da3d6128fb8ba6051Kay Sievers l = strpcpyf(&s, l, "d%d", dev_id);
0035597a30d120f70df2dd7da3d6128fb8ba6051Kay Sievers if (l == 0)
0035597a30d120f70df2dd7da3d6128fb8ba6051Kay Sievers names->pci_path[0] = '\0';
0035597a30d120f70df2dd7da3d6128fb8ba6051Kay Sievers }
0035597a30d120f70df2dd7da3d6128fb8ba6051Kay Sieversout:
0035597a30d120f70df2dd7da3d6128fb8ba6051Kay Sievers udev_device_unref(pci);
0035597a30d120f70df2dd7da3d6128fb8ba6051Kay Sievers return err;
0035597a30d120f70df2dd7da3d6128fb8ba6051Kay Sievers}
641906e9366891e0ad3e6e38b7396a427678c4cfThomas Hindoe Paaboel Andersen
0035597a30d120f70df2dd7da3d6128fb8ba6051Kay Sieversstatic int names_pci(struct udev_device *dev, struct netnames *names) {
0035597a30d120f70df2dd7da3d6128fb8ba6051Kay Sievers struct udev_device *parent;
0035597a30d120f70df2dd7da3d6128fb8ba6051Kay Sievers
0035597a30d120f70df2dd7da3d6128fb8ba6051Kay Sievers parent = udev_device_get_parent(dev);
0035597a30d120f70df2dd7da3d6128fb8ba6051Kay Sievers if (!parent)
0035597a30d120f70df2dd7da3d6128fb8ba6051Kay Sievers return -ENOENT;
0035597a30d120f70df2dd7da3d6128fb8ba6051Kay Sievers /* check if our direct parent is a PCI device with no other bus in-between */
d23965a64eb5c2c97b839dc2e3e79fc1613994f1Kay Sievers if (streq("pci", udev_device_get_subsystem(parent))) {
0035597a30d120f70df2dd7da3d6128fb8ba6051Kay Sievers names->type = NET_PCI;
1328f66ad16b5afeb5684858c27e121a46c1959eKay Sievers names->pcidev = parent;
214daa72cb0c72ea78d1eccd5ffe630a1e04b2f7Sean McGovern } else {
214daa72cb0c72ea78d1eccd5ffe630a1e04b2f7Sean McGovern names->pcidev = udev_device_get_parent_with_subsystem_devtype(dev, "pci", NULL);
214daa72cb0c72ea78d1eccd5ffe630a1e04b2f7Sean McGovern if (!names->pcidev)
214daa72cb0c72ea78d1eccd5ffe630a1e04b2f7Sean McGovern return -ENOENT;
1328f66ad16b5afeb5684858c27e121a46c1959eKay Sievers }
d5a89d7dc17a5ba5cf4fc71f82963c5c94a31c3dKay Sievers dev_pci_onboard(dev, names);
3058e017fced6d5c8712e10c8c1477421bc1e960Thadeu Lima de Souza Cascardo dev_pci_slot(dev, names);
3058e017fced6d5c8712e10c8c1477421bc1e960Thadeu Lima de Souza Cascardo return 0;
1328f66ad16b5afeb5684858c27e121a46c1959eKay Sievers}
16f948cb208f1db9a1665f07ac9b22e416dc19d4Tom Gundersen
d23965a64eb5c2c97b839dc2e3e79fc1613994f1Kay Sieversstatic int names_usb(struct udev_device *dev, struct netnames *names) {
0035597a30d120f70df2dd7da3d6128fb8ba6051Kay Sievers struct udev_device *usbdev;
0035597a30d120f70df2dd7da3d6128fb8ba6051Kay Sievers char name[256];
0035597a30d120f70df2dd7da3d6128fb8ba6051Kay Sievers char *ports;
0035597a30d120f70df2dd7da3d6128fb8ba6051Kay Sievers char *config;
0035597a30d120f70df2dd7da3d6128fb8ba6051Kay Sievers char *interf;
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers size_t l;
5b8180d3f6598a1b2f296645690de41d726fd5abKay Sievers char *s;
0035597a30d120f70df2dd7da3d6128fb8ba6051Kay Sievers
5b8180d3f6598a1b2f296645690de41d726fd5abKay Sievers usbdev = udev_device_get_parent_with_subsystem_devtype(dev, "usb", "usb_interface");
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers if (!usbdev)
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers return -ENOENT;
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers
bb26309dd042c79de907f103d83f398b9436cde0Rob Clark /* get USB port number chain, configuration, interface */
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers strscpy(name, sizeof(name), udev_device_get_sysname(usbdev));
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers s = strchr(name, '-');
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers if (!s)
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers return -EINVAL;
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers ports = s+1;
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers s = strchr(ports, ':');
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers if (!s)
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers return -EINVAL;
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers s[0] = '\0';
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers config = s+1;
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers s = strchr(config, '.');
984c4348ff14d29c526d3d372daa82e278eeb5b4Kay Sievers if (!s)
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers return -EINVAL;
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers s[0] = '\0';
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers interf = s+1;
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers /* prefix every port number in the chain with "u"*/
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers s = ports;
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers while ((s = strchr(s, '.')))
984c4348ff14d29c526d3d372daa82e278eeb5b4Kay Sievers s[0] = 'u';
984c4348ff14d29c526d3d372daa82e278eeb5b4Kay Sievers s = names->usb_ports;
0035597a30d120f70df2dd7da3d6128fb8ba6051Kay Sievers l = strpcpyl(&s, sizeof(names->usb_ports), "u", ports, NULL);
0035597a30d120f70df2dd7da3d6128fb8ba6051Kay Sievers
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers /* append USB config number, suppress the common config == 1 */
984c4348ff14d29c526d3d372daa82e278eeb5b4Kay Sievers if (!streq(config, "1"))
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers l = strpcpyl(&s, sizeof(names->usb_ports), "c", config, NULL);
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers /* append USB interface number, suppress the interface == 0 */
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers if (!streq(interf, "0"))
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers l = strpcpyl(&s, sizeof(names->usb_ports), "i", interf, NULL);
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers if (l == 0)
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers return -ENAMETOOLONG;
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers names->type = NET_USB;
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers return 0;
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers}
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers
0260944060426d54d9ecb40930baad985cbd02a1Kay Sieversstatic int names_bcma(struct udev_device *dev, struct netnames *names) {
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers struct udev_device *bcmadev;
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers unsigned int core;
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers bcmadev = udev_device_get_parent_with_subsystem_devtype(dev, "bcma", NULL);
f7340ab269828d917cd1281e33e6dd4fdfee67b3Torstein Husebø if (!bcmadev)
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers return -ENOENT;
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers /* bus num, core num */
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers if (sscanf(udev_device_get_sysname(bcmadev), "bcma%*d:%d", &core) != 1)
d5a89d7dc17a5ba5cf4fc71f82963c5c94a31c3dKay Sievers return -EINVAL;
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers snprintf(names->bcma_core, sizeof(names->bcma_core), "b%d", core);
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers names->type = NET_BCMA;
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers return 0;
d5a89d7dc17a5ba5cf4fc71f82963c5c94a31c3dKay Sievers}
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers
0260944060426d54d9ecb40930baad985cbd02a1Kay Sieversstatic int names_mac(struct udev_device *dev, struct netnames *names) {
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers const char *s;
d5a89d7dc17a5ba5cf4fc71f82963c5c94a31c3dKay Sievers unsigned int i;
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers unsigned int a1, a2, a3, a4, a5, a6;
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers /* check for NET_ADDR_PERM, skip random MAC addresses */
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers s = udev_device_get_sysattr_value(dev, "addr_assign_type");
d23965a64eb5c2c97b839dc2e3e79fc1613994f1Kay Sievers if (!s)
d23965a64eb5c2c97b839dc2e3e79fc1613994f1Kay Sievers return EXIT_FAILURE;
d23965a64eb5c2c97b839dc2e3e79fc1613994f1Kay Sievers i = strtoul(s, NULL, 0);
984c4348ff14d29c526d3d372daa82e278eeb5b4Kay Sievers if (i != 0)
984c4348ff14d29c526d3d372daa82e278eeb5b4Kay Sievers return 0;
984c4348ff14d29c526d3d372daa82e278eeb5b4Kay Sievers
984c4348ff14d29c526d3d372daa82e278eeb5b4Kay Sievers s = udev_device_get_sysattr_value(dev, "address");
984c4348ff14d29c526d3d372daa82e278eeb5b4Kay Sievers if (!s)
984c4348ff14d29c526d3d372daa82e278eeb5b4Kay Sievers return -ENOENT;
984c4348ff14d29c526d3d372daa82e278eeb5b4Kay Sievers if (sscanf(s, "%x:%x:%x:%x:%x:%x", &a1, &a2, &a3, &a4, &a5, &a6) != 6)
984c4348ff14d29c526d3d372daa82e278eeb5b4Kay Sievers return -EINVAL;
f4ddacbd4de0f159ec598f8ad690466a84787ec5Kay Sievers
b5dd8148730db080b48b874c214f8f74ae787d6bZbigniew Jędrzejewski-Szmek /* skip empty MAC addresses */
984c4348ff14d29c526d3d372daa82e278eeb5b4Kay Sievers if (a1 + a2 + a3 + a4 + a5 + a6 == 0)
f4ddacbd4de0f159ec598f8ad690466a84787ec5Kay Sievers return -EINVAL;
f4ddacbd4de0f159ec598f8ad690466a84787ec5Kay Sievers
b5dd8148730db080b48b874c214f8f74ae787d6bZbigniew Jędrzejewski-Szmek names->mac[0] = a1;
f4ddacbd4de0f159ec598f8ad690466a84787ec5Kay Sievers names->mac[1] = a2;
984c4348ff14d29c526d3d372daa82e278eeb5b4Kay Sievers names->mac[2] = a3;
984c4348ff14d29c526d3d372daa82e278eeb5b4Kay Sievers names->mac[3] = a4;
984c4348ff14d29c526d3d372daa82e278eeb5b4Kay Sievers names->mac[4] = a5;
984c4348ff14d29c526d3d372daa82e278eeb5b4Kay Sievers names->mac[5] = a6;
e0d4a0ac06afb856c9370c5c256f0f7bb7efdc8eHendrik Brueckner names->mac_valid = true;
e0d4a0ac06afb856c9370c5c256f0f7bb7efdc8eHendrik Brueckner return 0;
e0d4a0ac06afb856c9370c5c256f0f7bb7efdc8eHendrik Brueckner}
e0d4a0ac06afb856c9370c5c256f0f7bb7efdc8eHendrik Brueckner
e0d4a0ac06afb856c9370c5c256f0f7bb7efdc8eHendrik Brueckner/* IEEE Organizationally Unique Identifier vendor string */
e0d4a0ac06afb856c9370c5c256f0f7bb7efdc8eHendrik Bruecknerstatic int ieee_oui(struct udev_device *dev, struct netnames *names, bool test) {
e0d4a0ac06afb856c9370c5c256f0f7bb7efdc8eHendrik Brueckner char str[32];
e0d4a0ac06afb856c9370c5c256f0f7bb7efdc8eHendrik Brueckner
e0d4a0ac06afb856c9370c5c256f0f7bb7efdc8eHendrik Brueckner if (!names->mac_valid)
e0d4a0ac06afb856c9370c5c256f0f7bb7efdc8eHendrik Brueckner return -ENOENT;
e0d4a0ac06afb856c9370c5c256f0f7bb7efdc8eHendrik Brueckner /* skip commonly misused 00:00:00 (Xerox) prefix */
e0d4a0ac06afb856c9370c5c256f0f7bb7efdc8eHendrik Brueckner if (memcmp(names->mac, "\0\0\0", 3) == 0)
e0d4a0ac06afb856c9370c5c256f0f7bb7efdc8eHendrik Brueckner return -EINVAL;
e0d4a0ac06afb856c9370c5c256f0f7bb7efdc8eHendrik Brueckner snprintf(str, sizeof(str), "OUI:%02X%02X%02X%02X%02X%02X",
e0d4a0ac06afb856c9370c5c256f0f7bb7efdc8eHendrik Brueckner names->mac[0], names->mac[1], names->mac[2],
e0d4a0ac06afb856c9370c5c256f0f7bb7efdc8eHendrik Brueckner names->mac[3], names->mac[4], names->mac[5]);
e0d4a0ac06afb856c9370c5c256f0f7bb7efdc8eHendrik Brueckner udev_builtin_hwdb_lookup(dev, str, test);
e0d4a0ac06afb856c9370c5c256f0f7bb7efdc8eHendrik Brueckner return 0;
e0d4a0ac06afb856c9370c5c256f0f7bb7efdc8eHendrik Brueckner}
e0d4a0ac06afb856c9370c5c256f0f7bb7efdc8eHendrik Brueckner
e0d4a0ac06afb856c9370c5c256f0f7bb7efdc8eHendrik Bruecknerstatic int builtin_net_id(struct udev_device *dev, int argc, char *argv[], bool test) {
e0d4a0ac06afb856c9370c5c256f0f7bb7efdc8eHendrik Brueckner const char *s;
e0d4a0ac06afb856c9370c5c256f0f7bb7efdc8eHendrik Brueckner const char *p;
e0d4a0ac06afb856c9370c5c256f0f7bb7efdc8eHendrik Brueckner unsigned int i;
e0d4a0ac06afb856c9370c5c256f0f7bb7efdc8eHendrik Brueckner const char *devtype;
e0d4a0ac06afb856c9370c5c256f0f7bb7efdc8eHendrik Brueckner const char *prefix = "en";
e0d4a0ac06afb856c9370c5c256f0f7bb7efdc8eHendrik Brueckner struct netnames names;
e0d4a0ac06afb856c9370c5c256f0f7bb7efdc8eHendrik Brueckner int err;
e0d4a0ac06afb856c9370c5c256f0f7bb7efdc8eHendrik Brueckner
e0d4a0ac06afb856c9370c5c256f0f7bb7efdc8eHendrik Brueckner /* handle only ARPHRD_ETHER devices */
e0d4a0ac06afb856c9370c5c256f0f7bb7efdc8eHendrik Brueckner s = udev_device_get_sysattr_value(dev, "type");
e0d4a0ac06afb856c9370c5c256f0f7bb7efdc8eHendrik Brueckner if (!s)
d4b687c96adf207f0878aebf3ce3371f6160687fKay Sievers return EXIT_FAILURE;
d4b687c96adf207f0878aebf3ce3371f6160687fKay Sievers i = strtoul(s, NULL, 0);
e0d4a0ac06afb856c9370c5c256f0f7bb7efdc8eHendrik Brueckner if (i != 1)
e0d4a0ac06afb856c9370c5c256f0f7bb7efdc8eHendrik Brueckner return 0;
e0d4a0ac06afb856c9370c5c256f0f7bb7efdc8eHendrik Brueckner
e0d4a0ac06afb856c9370c5c256f0f7bb7efdc8eHendrik Brueckner /* skip stacked devices, like VLANs, ... */
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers s = udev_device_get_sysattr_value(dev, "ifindex");
d23965a64eb5c2c97b839dc2e3e79fc1613994f1Kay Sievers if (!s)
d23965a64eb5c2c97b839dc2e3e79fc1613994f1Kay Sievers return EXIT_FAILURE;
d23965a64eb5c2c97b839dc2e3e79fc1613994f1Kay Sievers p = udev_device_get_sysattr_value(dev, "iflink");
d23965a64eb5c2c97b839dc2e3e79fc1613994f1Kay Sievers if (!p)
d23965a64eb5c2c97b839dc2e3e79fc1613994f1Kay Sievers return EXIT_FAILURE;
d23965a64eb5c2c97b839dc2e3e79fc1613994f1Kay Sievers if (strcmp(s, p) != 0)
d23965a64eb5c2c97b839dc2e3e79fc1613994f1Kay Sievers return 0;
d23965a64eb5c2c97b839dc2e3e79fc1613994f1Kay Sievers
d23965a64eb5c2c97b839dc2e3e79fc1613994f1Kay Sievers devtype = udev_device_get_devtype(dev);
d23965a64eb5c2c97b839dc2e3e79fc1613994f1Kay Sievers if (devtype) {
d23965a64eb5c2c97b839dc2e3e79fc1613994f1Kay Sievers if (streq("wlan", devtype))
d23965a64eb5c2c97b839dc2e3e79fc1613994f1Kay Sievers prefix = "wl";
d23965a64eb5c2c97b839dc2e3e79fc1613994f1Kay Sievers else if (streq("wwan", devtype))
d23965a64eb5c2c97b839dc2e3e79fc1613994f1Kay Sievers prefix = "ww";
d23965a64eb5c2c97b839dc2e3e79fc1613994f1Kay Sievers }
d23965a64eb5c2c97b839dc2e3e79fc1613994f1Kay Sievers
d23965a64eb5c2c97b839dc2e3e79fc1613994f1Kay Sievers zero(names);
d23965a64eb5c2c97b839dc2e3e79fc1613994f1Kay Sievers err = names_mac(dev, &names);
d23965a64eb5c2c97b839dc2e3e79fc1613994f1Kay Sievers if (err >= 0 && names.mac_valid) {
d23965a64eb5c2c97b839dc2e3e79fc1613994f1Kay Sievers char str[IFNAMSIZ];
a660c63c551b88136ac6176855b5907cc533e848Kay Sievers
a660c63c551b88136ac6176855b5907cc533e848Kay Sievers snprintf(str, sizeof(str), "%sx%02x%02x%02x%02x%02x%02x", prefix,
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers names.mac[0], names.mac[1], names.mac[2],
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers names.mac[3], names.mac[4], names.mac[5]);
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers udev_builtin_add_property(dev, test, "ID_NET_NAME_MAC", str);
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers ieee_oui(dev, &names, test);
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers }
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers /* get PCI based path names, we compose only PCI based paths */
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers err = names_pci(dev, &names);
d23965a64eb5c2c97b839dc2e3e79fc1613994f1Kay Sievers if (err < 0)
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers goto out;
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers
971e7fb62548f2c9c4e32684bb13409e6579dc6aKay Sievers /* plain PCI device */
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers if (names.type == NET_PCI) {
971e7fb62548f2c9c4e32684bb13409e6579dc6aKay Sievers char str[IFNAMSIZ];
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers if (names.pci_onboard[0])
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
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers if (names.pci_onboard_label)
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers if (snprintf(str, sizeof(str), "%s%s", prefix, names.pci_onboard_label) < (int)sizeof(str))
a4bbef099209d4e3bccd913cd30da536f8971064Kay Sievers udev_builtin_add_property(dev, test, "ID_NET_LABEL_ONBOARD", str);
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers
a660c63c551b88136ac6176855b5907cc533e848Kay Sievers if (names.pci_path[0])
a660c63c551b88136ac6176855b5907cc533e848Kay Sievers if (snprintf(str, sizeof(str), "%s%s", prefix, names.pci_path) < (int)sizeof(str))
a660c63c551b88136ac6176855b5907cc533e848Kay Sievers udev_builtin_add_property(dev, test, "ID_NET_NAME_PATH", str);
d23965a64eb5c2c97b839dc2e3e79fc1613994f1Kay Sievers
72bc96f07868d532596477604b6fb41633ebd124Kay Sievers if (names.pci_slot[0])
d23965a64eb5c2c97b839dc2e3e79fc1613994f1Kay Sievers if (snprintf(str, sizeof(str), "%s%s", prefix, names.pci_slot) < (int)sizeof(str))
d23965a64eb5c2c97b839dc2e3e79fc1613994f1Kay Sievers udev_builtin_add_property(dev, test, "ID_NET_NAME_SLOT", str);
d23965a64eb5c2c97b839dc2e3e79fc1613994f1Kay Sievers goto out;
b92bea5d2a9481de69bb627a7b442a9f58fca43dZbigniew Jędrzejewski-Szmek }
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers
d23965a64eb5c2c97b839dc2e3e79fc1613994f1Kay Sievers /* USB device */
e0d4a0ac06afb856c9370c5c256f0f7bb7efdc8eHendrik Brueckner err = names_usb(dev, &names);
d23965a64eb5c2c97b839dc2e3e79fc1613994f1Kay Sievers if (err >= 0 && names.type == NET_USB) {
d23965a64eb5c2c97b839dc2e3e79fc1613994f1Kay Sievers char str[IFNAMSIZ];
d23965a64eb5c2c97b839dc2e3e79fc1613994f1Kay Sievers
d23965a64eb5c2c97b839dc2e3e79fc1613994f1Kay Sievers if (names.pci_path[0])
e0d4a0ac06afb856c9370c5c256f0f7bb7efdc8eHendrik Brueckner if (snprintf(str, sizeof(str), "%s%s%s", prefix, names.pci_path, names.usb_ports) < (int)sizeof(str))
19aa72f74e41045510b4af3f1415b419d42ff20bTom Gundersen udev_builtin_add_property(dev, test, "ID_NET_NAME_PATH", str);
e0d4a0ac06afb856c9370c5c256f0f7bb7efdc8eHendrik Brueckner
e0d4a0ac06afb856c9370c5c256f0f7bb7efdc8eHendrik Brueckner if (names.pci_slot[0])
19aa72f74e41045510b4af3f1415b419d42ff20bTom Gundersen if (snprintf(str, sizeof(str), "%s%s%s", prefix, names.pci_slot, names.usb_ports) < (int)sizeof(str))
e0d4a0ac06afb856c9370c5c256f0f7bb7efdc8eHendrik Brueckner udev_builtin_add_property(dev, test, "ID_NET_NAME_SLOT", str);
e0d4a0ac06afb856c9370c5c256f0f7bb7efdc8eHendrik Brueckner goto out;
e0d4a0ac06afb856c9370c5c256f0f7bb7efdc8eHendrik Brueckner }
d23965a64eb5c2c97b839dc2e3e79fc1613994f1Kay Sievers
e0d4a0ac06afb856c9370c5c256f0f7bb7efdc8eHendrik Brueckner /* Broadcom bus */
d23965a64eb5c2c97b839dc2e3e79fc1613994f1Kay Sievers err = names_bcma(dev, &names);
72bc96f07868d532596477604b6fb41633ebd124Kay Sievers if (err >= 0 && names.type == NET_BCMA) {
72bc96f07868d532596477604b6fb41633ebd124Kay Sievers char str[IFNAMSIZ];
72bc96f07868d532596477604b6fb41633ebd124Kay Sievers
72bc96f07868d532596477604b6fb41633ebd124Kay Sievers if (names.pci_path[0])
72bc96f07868d532596477604b6fb41633ebd124Kay Sievers if (snprintf(str, sizeof(str), "%s%s%s", prefix, names.pci_path, names.bcma_core) < (int)sizeof(str))
72bc96f07868d532596477604b6fb41633ebd124Kay Sievers udev_builtin_add_property(dev, test, "ID_NET_NAME_PATH", str);
72bc96f07868d532596477604b6fb41633ebd124Kay Sievers
090be8653471e1abe3f1cdd32eaad0fbd65f85cdThomas Hindoe Paaboel Andersen if (names.pci_slot[0])
72bc96f07868d532596477604b6fb41633ebd124Kay Sievers if (snprintf(str, sizeof(str), "%s%s%s", prefix, names.pci_slot, names.bcma_core) < (int)sizeof(str))
72bc96f07868d532596477604b6fb41633ebd124Kay Sievers udev_builtin_add_property(dev, test, "ID_NET_NAME_SLOT", str);
d23965a64eb5c2c97b839dc2e3e79fc1613994f1Kay Sievers goto out;
d23965a64eb5c2c97b839dc2e3e79fc1613994f1Kay Sievers }
d23965a64eb5c2c97b839dc2e3e79fc1613994f1Kay Sievers
d23965a64eb5c2c97b839dc2e3e79fc1613994f1Kay Sieversout:
d23965a64eb5c2c97b839dc2e3e79fc1613994f1Kay Sievers return EXIT_SUCCESS;
d23965a64eb5c2c97b839dc2e3e79fc1613994f1Kay Sievers}
d23965a64eb5c2c97b839dc2e3e79fc1613994f1Kay Sievers
d23965a64eb5c2c97b839dc2e3e79fc1613994f1Kay Sieversconst struct udev_builtin udev_builtin_net_id = {
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers .name = "net_id",
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers .cmd = builtin_net_id,
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers .help = "network device properties",
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers};
0260944060426d54d9ecb40930baad985cbd02a1Kay Sievers