chiark / gitweb /
Use initalization instead of explicit zeroing
[elogind.git] / src / udev / udev-builtin-net_id.c
index 7c9564f4cdb3056eb62b86a9356898917851a4b9..5719021e93bca5f0e6fe40e929b22880e3a743fc 100644 (file)
@@ -24,6 +24,8 @@
  *  - physical/geographical location of the hardware
  *  - the interface's MAC address
  *
+ * http://www.freedesktop.org/wiki/Software/systemd/PredictableNetworkInterfaceNames
+ *
  * Two character prefixes based on the type of interface:
  *   en -- ethernet
  *   wl -- wlan
 #include <linux/pci_regs.h>
 
 #include "udev.h"
+#include "fileio.h"
 
 enum netname_type{
         NET_UNDEF,
         NET_PCI,
         NET_USB,
+        NET_BCMA,
 };
 
 struct netnames {
@@ -108,8 +112,9 @@ struct netnames {
         char pci_onboard[IFNAMSIZ];
         const char *pci_onboard_label;
 
-        struct udev_device *usbdev;
         char usb_ports[IFNAMSIZ];
+
+        char bcma_core[IFNAMSIZ];
 };
 
 /* retrieve on-board index number and label from firmware */
@@ -183,11 +188,11 @@ static int dev_pci_slot(struct udev_device *dev, struct netnames *names) {
 
         /* compose a name based on the raw kernel's PCI bus, slot numbers */
         s = names->pci_path;
-        l = util_strpcpyf(&s, sizeof(names->pci_path), "p%ds%d", bus, slot);
+        l = strpcpyf(&s, sizeof(names->pci_path), "p%ds%d", bus, slot);
         if (func > 0 || is_pci_multifunction(names->pcidev))
-                l = util_strpcpyf(&s, l, "f%d", func);
+                l = strpcpyf(&s, l, "f%d", func);
         if (dev_id > 0)
-                l = util_strpcpyf(&s, l, "d%d", dev_id);
+                l = strpcpyf(&s, l, "d%d", dev_id);
         if (l == 0)
                 names->pci_path[0] = '\0';
 
@@ -219,7 +224,7 @@ static int dev_pci_slot(struct udev_device *dev, struct netnames *names) {
                 snprintf(str, sizeof(str), "%s/%s/address", slots, dent->d_name);
                 if (read_one_line_file(str, &address) >= 0) {
                         /* match slot address with device by stripping the function */
-                        if (strncmp(address, udev_device_get_sysname(names->pcidev), strlen(address)) == 0)
+                        if (strneq(address, udev_device_get_sysname(names->pcidev), strlen(address)))
                                 hotplug_slot = i;
                         free(address);
                 }
@@ -231,11 +236,11 @@ static int dev_pci_slot(struct udev_device *dev, struct netnames *names) {
 
         if (hotplug_slot > 0) {
                 s = names->pci_slot;
-                l = util_strpcpyf(&s, sizeof(names->pci_slot), "s%d", hotplug_slot);
+                l = strpcpyf(&s, sizeof(names->pci_slot), "s%d", hotplug_slot);
                 if (func > 0 || is_pci_multifunction(names->pcidev))
-                        l = util_strpcpyf(&s, l, "f%d", func);
+                        l = strpcpyf(&s, l, "f%d", func);
                 if (dev_id > 0)
-                        l = util_strpcpyf(&s, l, "d%d", dev_id);
+                        l = strpcpyf(&s, l, "d%d", dev_id);
                 if (l == 0)
                         names->pci_path[0] = '\0';
         }
@@ -251,7 +256,7 @@ static int names_pci(struct udev_device *dev, struct netnames *names) {
         if (!parent)
                 return -ENOENT;
         /* check if our direct parent is a PCI device with no other bus in-between */
-        if (streq("pci", udev_device_get_subsystem(parent))) {
+        if (streq_ptr("pci", udev_device_get_subsystem(parent))) {
                 names->type = NET_PCI;
                 names->pcidev = parent;
         } else {
@@ -265,6 +270,7 @@ static int names_pci(struct udev_device *dev, struct netnames *names) {
 }
 
 static int names_usb(struct udev_device *dev, struct netnames *names) {
+        struct udev_device *usbdev;
         char name[256];
         char *ports;
         char *config;
@@ -272,12 +278,12 @@ static int names_usb(struct udev_device *dev, struct netnames *names) {
         size_t l;
         char *s;
 
-        names->usbdev = udev_device_get_parent_with_subsystem_devtype(dev, "usb", "usb_interface");
-        if (!names->usbdev)
+        usbdev = udev_device_get_parent_with_subsystem_devtype(dev, "usb", "usb_interface");
+        if (!usbdev)
                 return -ENOENT;
 
         /* get USB port number chain, configuration, interface */
-        util_strscpy(name, sizeof(name), udev_device_get_sysname(names->usbdev));
+        strscpy(name, sizeof(name), udev_device_get_sysname(usbdev));
         s = strchr(name, '-');
         if (!s)
                 return -EINVAL;
@@ -300,15 +306,15 @@ static int names_usb(struct udev_device *dev, struct netnames *names) {
         while ((s = strchr(s, '.')))
                 s[0] = 'u';
         s = names->usb_ports;
-        l = util_strpcpyl(&s, sizeof(names->usb_ports), "u", ports, NULL);
+        l = strpcpyl(&s, sizeof(names->usb_ports), "u", ports, NULL);
 
         /* append USB config number, suppress the common config == 1 */
         if (!streq(config, "1"))
-                l = util_strpcpyl(&s, sizeof(names->usb_ports), "c", config, NULL);
+                l = strpcpyl(&s, sizeof(names->usb_ports), "c", config, NULL);
 
         /* append USB interface number, suppress the interface == 0 */
         if (!streq(interf, "0"))
-                l = util_strpcpyl(&s, sizeof(names->usb_ports), "i", interf, NULL);
+                l = strpcpyl(&s, sizeof(names->usb_ports), "i", interf, NULL);
         if (l == 0)
                 return -ENAMETOOLONG;
 
@@ -316,6 +322,25 @@ static int names_usb(struct udev_device *dev, struct netnames *names) {
         return 0;
 }
 
+static int names_bcma(struct udev_device *dev, struct netnames *names) {
+        struct udev_device *bcmadev;
+        unsigned int core;
+
+        bcmadev = udev_device_get_parent_with_subsystem_devtype(dev, "bcma", NULL);
+        if (!bcmadev)
+                return -ENOENT;
+
+        /* bus num:core num */
+        if (sscanf(udev_device_get_sysname(bcmadev), "bcma%*d:%d", &core) != 1)
+                return -EINVAL;
+        /* suppress the common core == 0 */
+        if (core > 0)
+                snprintf(names->bcma_core, sizeof(names->bcma_core), "b%d", core);
+
+        names->type = NET_BCMA;
+        return 0;
+}
+
 static int names_mac(struct udev_device *dev, struct netnames *names) {
         const char *s;
         unsigned int i;
@@ -371,7 +396,7 @@ static int builtin_net_id(struct udev_device *dev, int argc, char *argv[], bool
         unsigned int i;
         const char *devtype;
         const char *prefix = "en";
-        struct netnames names;
+        struct netnames names = {};
         int err;
 
         /* handle only ARPHRD_ETHER devices */
@@ -389,7 +414,7 @@ static int builtin_net_id(struct udev_device *dev, int argc, char *argv[], bool
         p = udev_device_get_sysattr_value(dev, "iflink");
         if (!p)
                 return EXIT_FAILURE;
-        if (strcmp(s, p) != 0)
+        if (!streq(s, p))
                 return 0;
 
         devtype = udev_device_get_devtype(dev);
@@ -400,7 +425,6 @@ static int builtin_net_id(struct udev_device *dev, int argc, char *argv[], bool
                         prefix = "ww";
         }
 
-        zero(names);
         err = names_mac(dev, &names);
         if (err >= 0 && names.mac_valid) {
                 char str[IFNAMSIZ];
@@ -452,7 +476,24 @@ static int builtin_net_id(struct udev_device *dev, int argc, char *argv[], bool
                 if (names.pci_slot[0])
                         if (snprintf(str, sizeof(str), "%s%s%s", prefix, names.pci_slot, names.usb_ports) < (int)sizeof(str))
                                 udev_builtin_add_property(dev, test, "ID_NET_NAME_SLOT", str);
+                goto out;
+        }
+
+        /* Broadcom bus */
+        err = names_bcma(dev, &names);
+        if (err >= 0 && names.type == NET_BCMA) {
+                char str[IFNAMSIZ];
+
+                if (names.pci_path[0])
+                        if (snprintf(str, sizeof(str), "%s%s%s", prefix, names.pci_path, names.bcma_core) < (int)sizeof(str))
+                                udev_builtin_add_property(dev, test, "ID_NET_NAME_PATH", str);
+
+                if (names.pci_slot[0])
+                        if (snprintf(str, sizeof(str), "%s%s%s", prefix, names.pci_slot, names.bcma_core) < (int)sizeof(str))
+                                udev_builtin_add_property(dev, test, "ID_NET_NAME_SLOT", str);
+                goto out;
         }
+
 out:
         return EXIT_SUCCESS;
 }