[PATCH v4 1/1] netifd: add devtype to ubus call

Florian Eckert fe at dev.tdt.de
Tue Jan 11 06:42:59 PST 2022


Every network device has a type. 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> sring
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 at dev.tdt.de>
---
v2:
  - Remove debug log output
v3:
  - Use the information mainly from file 'uevent'.
  - If 'uevent' does not provide the information use file 'type'
v4:
  - Fix coding style
  - Merge arrays

 system-linux.c | 47 ++++++++++++++++++++++++++++++++++++
 system.h       | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 112 insertions(+)

diff --git a/system-linux.c b/system-linux.c
index e768853..e44058e 100644
--- a/system-linux.c
+++ b/system-linux.c
@@ -2395,6 +2395,51 @@ 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)
+{
+	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 +2475,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;
 }
 
diff --git a/system.h b/system.h
index 1f7037d..40ef2fe 100644
--- a/system.h
+++ b/system.h
@@ -23,6 +23,71 @@
 #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,
-- 
2.20.1




More information about the openwrt-devel mailing list