netifd: add devtype to ubus call
authorFlorian Eckert <fe@dev.tdt.de>
Tue, 11 Jan 2022 14:42:59 +0000 (15:42 +0100)
committerHans Dedecker <dedeckeh@gmail.com>
Wed, 12 Jan 2022 19:28:33 +0000 (20:28 +0100)
Every network device has a type but there is no standard interface here.
The type can be determined either from the file
'/sys/class/net/<device>/uevent' or, if no information is found
there, from the file '/sys/class/net/<device>/type'.

This new function first checks whether there is a DEVTYPE=<type> string
in the 'uevent' file and uses it. If it does not find this information,
the 'type' is used as a fallback and mapped the number to a character
sequence.

This new 'devtype' information can be found in the network.device ubus
call.

Command:
ubus call network.device status

Output:
{
    "eth0": {
        "devtype": "ethernet",

Signed-off-by: Florian Eckert <fe@dev.tdt.de>
Signed-off-by: Hans Dedecker <dedeckeh@gmail.com> [commit rewording]
system-linux.c
system.h

index e76885348278929f47aca68bfbb3457e57b9fb3d..654f2acdc00cdbb01552b1ad17630c0baae9a40c 100644 (file)
@@ -2395,6 +2395,58 @@ system_if_force_external(const char *ifname)
        return stat(dev_sysfs_path(ifname, "phy80211"), &s) == 0;
 }
 
+static const char *
+system_netdevtype_name(unsigned short dev_type)
+{
+       unsigned int i;
+
+       for (i = 0; i < ARRAY_SIZE(netdev_types); i++) {
+               if (netdev_types[i].id == dev_type)
+                       return netdev_types[i].name;
+       }
+
+       /* the last key is used by default */
+       i = ARRAY_SIZE(netdev_types) - 1;
+
+       return netdev_types[i].name;
+}
+
+static void
+system_add_devtype(struct blob_buf *b, const char *ifname)
+{
+       char buf[100];
+       bool found = false;
+
+       if (!system_get_dev_sysfs("uevent", ifname, buf, sizeof(buf))) {
+               const char *info = "DEVTYPE=";
+               char *context = NULL;
+               const char *line = strtok_r(buf, "\r\n", &context);
+
+               while (line != NULL) {
+                       char *index = strstr(line, info);
+
+                       if (index != NULL) {
+                               blobmsg_add_string(b, "devtype", index + strlen(info));
+                               found = true;
+                               break;
+                       }
+
+                       line = strtok_r(NULL, "\r\n", &context);
+               }
+       }
+
+       if (!found) {
+               unsigned short number = 0;
+               const char *name = NULL;
+
+               if (!system_get_dev_sysfs("type", ifname, buf, sizeof(buf))) {
+                       number = strtoul(buf, NULL, 0);
+                       name = system_netdevtype_name(number);
+                       blobmsg_add_string(b, "devtype", name);
+               }
+       }
+}
+
 int
 system_if_dump_info(struct device *dev, struct blob_buf *b)
 {
@@ -2430,6 +2482,8 @@ system_if_dump_info(struct device *dev, struct blob_buf *b)
                blobmsg_add_u8(b, "autoneg", !!ecmd.autoneg);
        }
 
+       system_add_devtype(b, dev->ifname);
+
        return 0;
 }
 
index 1f7037d8a63a0a6ccb70764dcec7329e7d7d2d65..40ef2fefc65630e064b8b65e31a5328256b81935 100644 (file)
--- a/system.h
+++ b/system.h
 #include "iprule.h"
 #include "utils.h"
 
+struct netdev_type {
+       unsigned short id;
+       const char *name;
+};
+
+static const struct netdev_type netdev_types[] = {
+       {ARPHRD_NETROM, "netrom"},
+       {ARPHRD_ETHER, "ethernet"},
+       {ARPHRD_EETHER, "eethernet"},
+       {ARPHRD_AX25, "ax25"},
+       {ARPHRD_PRONET, "pronet"},
+       {ARPHRD_CHAOS, "chaos"},
+       {ARPHRD_IEEE802, "ieee802"},
+       {ARPHRD_ARCNET, "arcnet"},
+       {ARPHRD_APPLETLK, "appletlk"},
+       {ARPHRD_DLCI, "dlci"},
+       {ARPHRD_ATM, "atm"},
+       {ARPHRD_METRICOM, "metricom"},
+       {ARPHRD_IEEE1394, "ieee1394"},
+       {ARPHRD_EUI64, "eui64"},
+       {ARPHRD_INFINIBAND, "infiniband"},
+       {ARPHRD_SLIP, "slip"},
+       {ARPHRD_CSLIP, "cslip"},
+       {ARPHRD_SLIP6, "slip6"},
+       {ARPHRD_CSLIP6, "cslip6"},
+       {ARPHRD_RSRVD, "rsrvd"},
+       {ARPHRD_ADAPT, "adapt"},
+       {ARPHRD_ROSE, "rose"},
+       {ARPHRD_X25, "x25"},
+       {ARPHRD_HWX25, "hwx25"},
+       {ARPHRD_PPP, "ppp"},
+       {ARPHRD_CISCO, "cisco"},
+       {ARPHRD_LAPB, "lapb"},
+       {ARPHRD_DDCMP, "ddcmp"},
+       {ARPHRD_RAWHDLC, "rawhdlc"},
+       {ARPHRD_TUNNEL, "tunnel"},
+       {ARPHRD_TUNNEL6, "tunnel6"},
+       {ARPHRD_FRAD, "frad"},
+       {ARPHRD_SKIP, "skip"},
+       {ARPHRD_LOOPBACK, "loopback"},
+       {ARPHRD_LOCALTLK, "localtlk"},
+       {ARPHRD_FDDI, "fddi"},
+       {ARPHRD_BIF, "bif"},
+       {ARPHRD_SIT, "sit"},
+       {ARPHRD_IPDDP, "ipddp"},
+       {ARPHRD_IPGRE, "ipgre"},
+       {ARPHRD_PIMREG,"pimreg"},
+       {ARPHRD_HIPPI, "hippi"},
+       {ARPHRD_ASH, "ash"},
+       {ARPHRD_ECONET, "econet"},
+       {ARPHRD_IRDA, "irda"},
+       {ARPHRD_FCPP, "fcpp"},
+       {ARPHRD_FCAL, "fcal"},
+       {ARPHRD_FCPL, "fcpl"},
+       {ARPHRD_FCFABRIC, "fcfabric"},
+       {ARPHRD_IEEE80211, "ieee80211"},
+       {ARPHRD_IEEE80211_PRISM, "ie80211-prism"},
+       {ARPHRD_IEEE80211_RADIOTAP, "ieee80211-radiotap"},
+       {ARPHRD_PHONET, "phonet"},
+       {ARPHRD_PHONET_PIPE, "phonet-pipe"},
+       {ARPHRD_IEEE802154, "ieee802154"},
+       {ARPHRD_VOID, "void"},
+       {ARPHRD_NONE, "none"}
+};
+
 enum tunnel_param {
        TUNNEL_ATTR_TYPE,
        TUNNEL_ATTR_REMOTE,