udev-builtin-net_id.c revision 137661d87525a3c339afd2804e577532d58d3fbc
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering/***
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering This file is part of systemd.
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering Copyright 2012 Kay Sievers <kay@vrfy.org>
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering systemd is free software; you can redistribute it and/or modify it
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering under the terms of the GNU Lesser General Public License as published by
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering the Free Software Foundation; either version 2.1 of the License, or
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering (at your option) any later version.
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering systemd is distributed in the hope that it will be useful, but
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering Lesser General Public License for more details.
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering You should have received a copy of the GNU Lesser General Public License
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering***/
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering/*
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering * predictable network interface device names based on:
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering * - firmware/bios-provided index numbers for on-board devices
4871690d9e32608bbd9b18505b5326c2079c9690Allin Cottrell * - firmware-provided pci-express hotplug slot index number
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering * - physical/geographical location of the hardware
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering * - the interface's MAC address
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering *
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering * two character prefixes based on the type of interface:
1dfa7e79a60de680086b1d93fcc3629b463f58bdLennart Poettering * en -- ethernet
d682b3a7e7c7c2941a4d3e193f1e330dbc9fae89Lennart Poettering * wl -- wlan
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek * ww -- wwan
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering *
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering * type of names:
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering * o<index> -- on-board device index number
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering * s<slot>[f<function>] -- hotplug slot index number
40b71e89bae4e51768db4dc50ec64c1e9c96eec4Sebastian Thorarensen * x<MAC> -- MAC address
73843b52585d42cc1a970a1c664818ece6942e9eLennart Poettering * p<bus>s<slot>[f<function>] -- PCI geographical location
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering *
d18d46ecea80a7f07415edb9264af6a254fd70bbZbigniew Jędrzejewski-Szmek * All multi-function devices will carry the [f<function>] number in the
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering * device name, including the function 0 device.
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering *
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering * examples:
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering * ID_NET_NAME_ONBOARD=eno1
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering * ID_NET_NAME_SLOT=ens1
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering * ID_NET_NAME_SLOT=ens2f0
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering * ID_NET_NAME_SLOT=ens2f1
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering * ID_NET_NAME_MAC=enxf0def180d479
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering * ID_NET_NAME_PATH=enp0s25
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering * ID_NET_NAME_PATH=enp19s3f0
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering * ID_NET_NAME_PATH=enp19s3f1
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering */
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering#include <stdio.h>
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering#include <stdlib.h>
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering#include <stdarg.h>
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering#include <unistd.h>
d18d46ecea80a7f07415edb9264af6a254fd70bbZbigniew Jędrzejewski-Szmek#include <string.h>
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering#include <errno.h>
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering#include <linux/pci_regs.h>
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering#include "udev.h"
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering/* retrieve on-board index number and label from firmware */
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poetteringstatic int dev_pci_onboard(struct udev_device *dev, struct udev_device *parent, const char *prefix, bool test) {
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering const char *index;
d18d46ecea80a7f07415edb9264af6a254fd70bbZbigniew Jędrzejewski-Szmek int idx;
d18d46ecea80a7f07415edb9264af6a254fd70bbZbigniew Jędrzejewski-Szmek const char *label;
d18d46ecea80a7f07415edb9264af6a254fd70bbZbigniew Jędrzejewski-Szmek char s[16];
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering int err;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering /* ACPI _DSM -- device specific method for naming a PCI or PCI Express device */
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering index = udev_device_get_sysattr_value(parent, "acpi_index");
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering /* SMBIOS type 41 -- Onboard Devices Extended Information */
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek if (!index)
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek index = udev_device_get_sysattr_value(parent, "index");
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek if (!index)
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek return -ENOENT;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering idx = strtoul(index, NULL, 0);
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering if (idx <= 0)
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering return -EINVAL;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering snprintf(s, sizeof(s), "%so%d", prefix, idx);
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering err = udev_builtin_add_property(dev, test, "ID_NET_NAME_ONBOARD", s);
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering if (err < 0)
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering return err;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek label = udev_device_get_sysattr_value(parent, "label");
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering if (label) {
874bc134ac6504c45e94174e37af13ff21a6bfe2Zbigniew Jędrzejewski-Szmek err = udev_builtin_add_property(dev, test, "ID_NET_LABEL_ONBOARD", label);
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering if (err < 0)
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering return err;
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek }
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering return 0;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering}
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering/* read the 256 bytes PCI configuration space to check the multi-function bit */
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poetteringstatic bool is_pci_singlefunction(struct udev_device *dev) {
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering char filename[256];
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering FILE *f;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering char config[256];
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering bool single = false;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering snprintf(filename, sizeof(filename), "%s/config", udev_device_get_syspath(dev));
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering f = fopen(filename, "re");
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering if (!f)
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering goto out;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering if (fread(&config, sizeof(config), 1, f) != 1)
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering goto out;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering /* bit 0-6 header type, bit 7 multi/single function device */
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering if ((config[PCI_HEADER_TYPE] & 0x80) == 0)
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering single = true;
874bc134ac6504c45e94174e37af13ff21a6bfe2Zbigniew Jędrzejewski-Szmekout:
874bc134ac6504c45e94174e37af13ff21a6bfe2Zbigniew Jędrzejewski-Szmek fclose(f);
8c0b803b97bb0ee6603d9be85fb6b69cd6081eafLennart Poettering return single;
874bc134ac6504c45e94174e37af13ff21a6bfe2Zbigniew Jędrzejewski-Szmek}
874bc134ac6504c45e94174e37af13ff21a6bfe2Zbigniew Jędrzejewski-Szmek
874bc134ac6504c45e94174e37af13ff21a6bfe2Zbigniew Jędrzejewski-Szmekstatic int dev_pci_slot(struct udev_device *dev, struct udev_device *parent, const char *prefix, bool test) {
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek struct udev *udev = udev_device_get_udev(dev);
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering unsigned int bus;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering unsigned int slot;
874bc134ac6504c45e94174e37af13ff21a6bfe2Zbigniew Jędrzejewski-Szmek unsigned int func;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering struct udev_device *pci = NULL;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering char slots[256];
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering DIR *dir;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering struct dirent *dent;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering char str[256];
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering int hotplug_slot = 0;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering int err = 0;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering /* compose a name based on the raw kernel's PCI bus, slot numbers */
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering if (sscanf(udev_device_get_sysname(parent), "0000:%x:%x.%d", &bus, &slot, &func) != 3)
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering return -ENOENT;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering if (func == 0 && is_pci_singlefunction(parent))
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering snprintf(str, sizeof(str), "%sp%ds%d", prefix, bus, slot);
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering else
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering snprintf(str, sizeof(str), "%sp%ds%df%d", prefix, bus, slot, func);
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering err = udev_builtin_add_property(dev, test, "ID_NET_NAME_PATH", str);
f6422def2c10aa0dea1b872d2f187853e61bd015Michal Schmidt if (err < 0)
8c0b803b97bb0ee6603d9be85fb6b69cd6081eafLennart Poettering return err;
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek /* ACPI _SUN -- slot user number */
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering pci = udev_device_new_from_subsystem_sysname(udev, "subsystem", "pci");
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering if (!pci) {
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering err = -ENOENT;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering goto out;
d18d46ecea80a7f07415edb9264af6a254fd70bbZbigniew Jędrzejewski-Szmek }
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering snprintf(slots, sizeof(slots), "%s/slots", udev_device_get_syspath(pci));
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering dir = opendir(slots);
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering if (!dir) {
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering err = -errno;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering goto out;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering }
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) {
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering int i;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering char *rest;
874bc134ac6504c45e94174e37af13ff21a6bfe2Zbigniew Jędrzejewski-Szmek char *address;
a174f94d529c7ae9be589867308b669ec9b4dcc0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering if (dent->d_name[0] == '.')
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering continue;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering i = strtol(dent->d_name, &rest, 10);
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering if (rest[0] != '\0')
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering continue;
2a0e0692565f0435657c93498e09cbb2d3517152Shawn Landden if (i < 1)
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering continue;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering snprintf(str, sizeof(str), "%s/%s/address", slots, dent->d_name);
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering if (read_one_line_file(str, &address) >= 0) {
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering /* match slot address with device by stripping the function */
2a0e0692565f0435657c93498e09cbb2d3517152Shawn Landden if (strncmp(address, udev_device_get_sysname(parent), strlen(address)) == 0)
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering hotplug_slot = i;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering free(address);
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering }
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
2a0e0692565f0435657c93498e09cbb2d3517152Shawn Landden if (hotplug_slot > 0)
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering break;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering }
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering closedir(dir);
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering if (hotplug_slot > 0) {
2a0e0692565f0435657c93498e09cbb2d3517152Shawn Landden if (func == 0 && is_pci_singlefunction(parent))
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering snprintf(str, sizeof(str), "%ss%d", prefix, hotplug_slot);
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering else
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering snprintf(str, sizeof(str), "%ss%df%d", prefix, hotplug_slot, func);
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering err = udev_builtin_add_property(dev, test, "ID_NET_NAME_SLOT", str);
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering }
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poetteringout:
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering udev_device_unref(pci);
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering return err;
2a0e0692565f0435657c93498e09cbb2d3517152Shawn Landden}
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poetteringstatic int dev_pci(struct udev_device *dev, const char *prefix, bool test) {
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering struct udev_device *parent;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering /* skip other buses than direct PCI parents */
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering parent = udev_device_get_parent(dev);
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering if (!parent || !streq("pci", udev_device_get_subsystem(parent)))
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek return -ENOENT;
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek
2a0e0692565f0435657c93498e09cbb2d3517152Shawn Landden dev_pci_onboard(dev, parent, prefix, test);
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek dev_pci_slot(dev, parent, prefix, test);
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek return 0;
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek}
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmekstatic int dev_mac(struct udev_device *dev, const char *prefix, bool test) {
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek const char *s;
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek unsigned int i;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering unsigned int a1, a2, a3, a4, a5, a6;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering char str[16];
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering /* check for NET_ADDR_PERM, skip random MAC addresses */
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering s = udev_device_get_sysattr_value(dev, "addr_assign_type");
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering if (!s)
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering return EXIT_FAILURE;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering i = strtoul(s, NULL, 0);
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering if (i != 0)
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering return 0;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering s = udev_device_get_sysattr_value(dev, "address");
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering if (!s)
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering return -ENOENT;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering if (sscanf(s, "%x:%x:%x:%x:%x:%x", &a1, &a2, &a3, &a4, &a5, &a6) != 6)
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering return -EINVAL;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering /* skip empty MAC addresses */
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering if (a1 + a2 + a3 + a4 + a5 + a6 == 0)
505b6a61c22d5565e9308045c7b9bf79f7d0517eLennart Poettering return -EINVAL;
fa1c4b518ec7d8ec2d647213ee651cde4d6c9d7eZbigniew Jędrzejewski-Szmek
505b6a61c22d5565e9308045c7b9bf79f7d0517eLennart Poettering /*
505b6a61c22d5565e9308045c7b9bf79f7d0517eLennart Poettering * IEEE Organizationally Unique Identifier vendor string
505b6a61c22d5565e9308045c7b9bf79f7d0517eLennart Poettering * skip commonly misused 00:00:00 (Xerox) prefix
505b6a61c22d5565e9308045c7b9bf79f7d0517eLennart Poettering */
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering if (a1 + a2 + a3 > 0) {
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering snprintf(str, sizeof(str), "OUI:%02X%02X%02X", a1, a2, a3);
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering udev_builtin_hwdb_lookup(dev, str, test);
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering }
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering snprintf(str, sizeof(str), "%sx%02x%02x%02x%02x%02x%02x", prefix, a1, a2, a3, a4, a5, a6);
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering return udev_builtin_add_property(dev, test, "ID_NET_NAME_MAC", str);
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering}
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poetteringstatic int builtin_net_id(struct udev_device *dev, int argc, char *argv[], bool test) {
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering const char *s;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering unsigned int i;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering const char *devtype;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering const char *prefix = "en";
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
d18d46ecea80a7f07415edb9264af6a254fd70bbZbigniew Jędrzejewski-Szmek /* handle only ARPHRD_ETHER devices */
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering s = udev_device_get_sysattr_value(dev, "type");
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering if (!s)
874bc134ac6504c45e94174e37af13ff21a6bfe2Zbigniew Jędrzejewski-Szmek return EXIT_FAILURE;
a174f94d529c7ae9be589867308b669ec9b4dcc0Lennart Poettering i = strtoul(s, NULL, 0);
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering if (i != 1)
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering return 0;
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering devtype = udev_device_get_devtype(dev);
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering if (devtype) {
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering if (streq("wlan", devtype))
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering prefix = "wl";
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering else if (streq("wwan", devtype))
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering prefix = "ww";
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering }
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering dev_pci(dev, prefix, test);
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering dev_mac(dev, prefix, test);
874bc134ac6504c45e94174e37af13ff21a6bfe2Zbigniew Jędrzejewski-Szmek return EXIT_SUCCESS;
874bc134ac6504c45e94174e37af13ff21a6bfe2Zbigniew Jędrzejewski-Szmek}
874bc134ac6504c45e94174e37af13ff21a6bfe2Zbigniew Jędrzejewski-Szmek
874bc134ac6504c45e94174e37af13ff21a6bfe2Zbigniew Jędrzejewski-Szmekconst struct udev_builtin udev_builtin_net_id = {
874bc134ac6504c45e94174e37af13ff21a6bfe2Zbigniew Jędrzejewski-Szmek .name = "net_id",
874bc134ac6504c45e94174e37af13ff21a6bfe2Zbigniew Jędrzejewski-Szmek .cmd = builtin_net_id,
874bc134ac6504c45e94174e37af13ff21a6bfe2Zbigniew Jędrzejewski-Szmek .help = "network device properties",
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering};
0153028ae379eb7c9a463c548ef73ea392c6cdb0Lennart Poettering