udev-builtin-net_id.c revision 5b8180d3f6598a1b2f296645690de41d726fd5ab
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering/***
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering This file is part of systemd.
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering Copyright 2012 Kay Sievers <kay@vrfy.org>
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering systemd is free software; you can redistribute it and/or modify it
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering under the terms of the GNU Lesser General Public License as published by
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering the Free Software Foundation; either version 2.1 of the License, or
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering (at your option) any later version.
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering systemd is distributed in the hope that it will be useful, but
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering Lesser General Public License for more details.
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering You should have received a copy of the GNU Lesser General Public License
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering***/
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering/*
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering * prefixes:
0c8570287400ba57d3705a2f62dd26039121ea6fLennart Poettering * en -- ethernet
0c8570287400ba57d3705a2f62dd26039121ea6fLennart Poettering * wl -- wlan
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering * ww -- wwan
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering *
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering * types:
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering * o<index> -- on-board device index
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering * s<slot>f<function> -- hotplug slot number
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering * x<MAC> -- MAC address
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering * p<bus>s<slot>f<function> -- PCI/physical location
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering *
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering * example:
0c8570287400ba57d3705a2f62dd26039121ea6fLennart Poettering * ID_NET_NAME_ONBOARD=eno1
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering * ID_NET_NAME_SLOT=ens1f0
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering * ID_NET_NAME_MAC=enxf0def180d479
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering * ID_NET_NAME_PATH=enp19s0f0
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering */
e7d179acb9f50dec4a16c6c222dd147d7e53c6bbLennart Poettering
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering#include <stdio.h>
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering#include <stdlib.h>
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering#include <stdarg.h>
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering#include <unistd.h>
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering#include <string.h>
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering#include <errno.h>
86e9cbcaeda647eb4f1db77333f7069d5bf549f1Lennart Poettering
86e9cbcaeda647eb4f1db77333f7069d5bf549f1Lennart Poettering#include "udev.h"
86e9cbcaeda647eb4f1db77333f7069d5bf549f1Lennart Poettering
86e9cbcaeda647eb4f1db77333f7069d5bf549f1Lennart Poettering/* retrieve on-board index number and label from firmware */
86e9cbcaeda647eb4f1db77333f7069d5bf549f1Lennart Poetteringstatic int dev_pci_onboard(struct udev_device *dev, struct udev_device *parent, const char *prefix, bool test) {
86e9cbcaeda647eb4f1db77333f7069d5bf549f1Lennart Poettering const char *index;
86e9cbcaeda647eb4f1db77333f7069d5bf549f1Lennart Poettering int idx;
86e9cbcaeda647eb4f1db77333f7069d5bf549f1Lennart Poettering const char *label;
86e9cbcaeda647eb4f1db77333f7069d5bf549f1Lennart Poettering char s[16];
86e9cbcaeda647eb4f1db77333f7069d5bf549f1Lennart Poettering int err;
86e9cbcaeda647eb4f1db77333f7069d5bf549f1Lennart Poettering
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering /* ACPI _DSM -- device specific method for naming a PCI or PCI Express device */
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering index = udev_device_get_sysattr_value(parent, "acpi_index");
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering /* SMBIOS type 41 -- Onboard Devices Extended Information */
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering if (!index)
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering index = udev_device_get_sysattr_value(parent, "index");
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering if (!index)
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering return -ENOENT;
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering idx = strtoul(index, NULL, 0);
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering if (idx <= 0)
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering return -EINVAL;
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering snprintf(s, sizeof(s), "%so%d", prefix, idx);
86e9cbcaeda647eb4f1db77333f7069d5bf549f1Lennart Poettering err = udev_builtin_add_property(dev, test, "ID_NET_NAME_ONBOARD", s);
86e9cbcaeda647eb4f1db77333f7069d5bf549f1Lennart Poettering if (err < 0)
86e9cbcaeda647eb4f1db77333f7069d5bf549f1Lennart Poettering return err;
86e9cbcaeda647eb4f1db77333f7069d5bf549f1Lennart Poettering
86e9cbcaeda647eb4f1db77333f7069d5bf549f1Lennart Poettering label = udev_device_get_sysattr_value(parent, "label");
d76f90f1711e55d23ee6c8c0957fa3db17927327Lennart Poettering if (label) {
d76f90f1711e55d23ee6c8c0957fa3db17927327Lennart Poettering err = udev_builtin_add_property(dev, test, "ID_NET_LABEL_ONBOARD", label);
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering if (err < 0)
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering return err;
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering }
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering return 0;
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering}
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poetteringstatic int dev_pci_slot(struct udev_device *dev, struct udev_device *parent, const char *prefix, bool test) {
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering struct udev *udev = udev_device_get_udev(dev);
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering unsigned int bus;
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering unsigned int slot;
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering unsigned int func;
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering struct udev_device *pci = NULL;
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering char slots[256];
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering DIR *dir;
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering struct dirent *dent;
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering char str[256];
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering int hotplug_slot = 0;
105e151299dc1208855380be2b22d0db2d66ebc6Lennart Poettering int err = 0;
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering /* compose a name based on the raw kernel's PCI bus, slot numbers */
0d2cd47617b423f37d7425be7a56ae2fca8ff9f6Lennart Poettering if (sscanf(udev_device_get_sysname(parent), "0000:%x:%x.%d", &bus, &slot, &func) != 3)
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering return -ENOENT;
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering snprintf(str, sizeof(str), "%sp%ds%df%d", prefix, bus, slot, func);
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering err = udev_builtin_add_property(dev, test, "ID_NET_NAME_PATH", str);
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering if (err < 0)
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering return err;
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering /* ACPI _SUN -- slot user number */
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering pci = udev_device_new_from_subsystem_sysname(udev, "subsystem", "pci");
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering if (!pci) {
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering err = -ENOENT;
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering goto out;
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering }
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering snprintf(slots, sizeof(slots), "%s/slots", udev_device_get_syspath(pci));
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering dir = opendir(slots);
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering if (!dir) {
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering err = -errno;
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering goto out;
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering }
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) {
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering int i;
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering char *rest;
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering char *address;
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering if (dent->d_name[0] == '.')
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering continue;
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering i = strtol(dent->d_name, &rest, 10);
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering if (rest[0] != '\0')
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering continue;
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering if (i < 1)
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering continue;
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering snprintf(str, sizeof(str), "%s/%s/address", slots, dent->d_name);
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering if (read_one_line_file(str, &address) >= 0) {
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering /* match slot address with device by stripping the function */
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering if (strncmp(address, udev_device_get_sysname(parent), strlen(address)) == 0)
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering hotplug_slot = i;
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering free(address);
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering }
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering if (hotplug_slot > 0)
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering break;
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering }
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering closedir(dir);
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering if (hotplug_slot > 0) {
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering snprintf(str, sizeof(str), "%ss%df%d", prefix, hotplug_slot, func);
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering err = udev_builtin_add_property(dev, test, "ID_NET_NAME_SLOT", str);
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering }
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poetteringout:
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering udev_device_unref(pci);
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering return err;
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering}
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poetteringstatic int dev_pci(struct udev_device *dev, const char *prefix, bool test) {
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering struct udev_device *parent;
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering /* skip other buses than direct PCI parents */
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering parent = udev_device_get_parent(dev);
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering if (!parent || !streq("pci", udev_device_get_subsystem(parent)))
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering return -ENOENT;
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering dev_pci_onboard(dev, parent, prefix, test);
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering dev_pci_slot(dev, parent, prefix, test);
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering return 0;
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering}
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poetteringstatic int dev_mac(struct udev_device *dev, const char *prefix, bool test) {
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering const char *s;
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering unsigned int i;
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering unsigned int a1, a2, a3, a4, a5, a6;
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering char str[16];
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering /* check for NET_ADDR_PERM, skip random MAC addresses */
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering s = udev_device_get_sysattr_value(dev, "addr_assign_type");
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering if (!s)
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering return EXIT_FAILURE;
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering i = strtoul(s, NULL, 0);
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering if (i != 0)
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering return 0;
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering s = udev_device_get_sysattr_value(dev, "address");
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering if (!s)
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering return -ENOENT;
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering if (sscanf(s, "%x:%x:%x:%x:%x:%x", &a1, &a2, &a3, &a4, &a5, &a6) != 6)
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering return -EINVAL;
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering /* skip empty MAC addresses */
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering if (a1 + a2 + a3 + a4 + a5 + a6 == 0)
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering return -EINVAL;
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering /* add IEEE Organizationally Unique Identifier */
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering snprintf(str, sizeof(str), "OUI:%X%X%X", a1, a2, a3);
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering udev_builtin_hwdb_lookup(dev, str, test);
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering snprintf(str, sizeof(str), "%sx%02x%02x%02x%02x%02x%02x", prefix, a1, a2, a3, a4, a5, a6);
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering return udev_builtin_add_property(dev, test, "ID_NET_NAME_MAC", str);
30c778094b90a637c6691c462a66df81eeb865b5Lennart Poettering}
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poetteringstatic int builtin_net_id(struct udev_device *dev, int argc, char *argv[], bool test) {
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering const char *s;
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering unsigned int i;
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering const char *devtype;
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering const char *prefix = "en";
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering /* handle only ARPHRD_ETHER devices */
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering s = udev_device_get_sysattr_value(dev, "type");
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering if (!s)
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering return EXIT_FAILURE;
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering i = strtoul(s, NULL, 0);
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering if (i != 1)
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering return 0;
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering devtype = udev_device_get_devtype(dev);
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering if (devtype) {
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering if (streq("wlan", devtype))
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering prefix = "wl";
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering else if (streq("wwan", devtype))
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering prefix = "ww";
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering }
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering dev_pci(dev, prefix, test);
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering dev_mac(dev, prefix, test);
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering return EXIT_SUCCESS;
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering}
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poetteringconst struct udev_builtin udev_builtin_net_id = {
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering .name = "net_id",
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering .cmd = builtin_net_id,
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering .help = "network device properties",
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering};
8e54f5d90a6b9dd1ff672fb97ea98de66c49e332Lennart Poettering