diff mbox

[linux-wpan/radvd,for-upstream,2/2] device-linux: get address length via sysfs

Message ID 20160802143752.12831-3-aar@pengutronix.de (mailing list archive)
State Not Applicable
Headers show

Commit Message

Alexander Aring Aug. 2, 2016, 2:37 p.m. UTC
This patch will change the behaviour for 6LoWPAN interface to detect the
linklayer address length via sysfs. The usually way to get the address
length is via a mapping from ARPHRD device type. This doesn't work for
6LoWPAN interfaces, we need at least some other mechanism. This patch
adds the mechanism to read out the sysfs UAPI to get the addr_len
attribute of net_device. This will not work if there are two 6LoWPAN
link-layer types with the same address length but need different
handling in userspace. For that reason I think a linklayer type would be
better, this requires a 6lowpan netlink API which doesn't exist right
now. So we use this simple way now.

Signed-off-by: Alexander Aring <aar@pengutronix.de>
---
 device-linux.c | 38 ++++++++++++++++++++++++++++++++++++--
 pathnames.h    |  1 +
 2 files changed, 37 insertions(+), 2 deletions(-)

Comments

Alexander Aring Aug. 2, 2016, 2:59 p.m. UTC | #1
Hi,

On 08/02/2016 04:37 PM, Alexander Aring wrote:
> This patch will change the behaviour for 6LoWPAN interface to detect the
> linklayer address length via sysfs. The usually way to get the address
> length is via a mapping from ARPHRD device type. This doesn't work for
> 6LoWPAN interfaces, we need at least some other mechanism. This patch
> adds the mechanism to read out the sysfs UAPI to get the addr_len
> attribute of net_device. This will not work if there are two 6LoWPAN
> link-layer types with the same address length but need different
> handling in userspace. For that reason I think a linklayer type would be
> better, this requires a 6lowpan netlink API which doesn't exist right
> now. So we use this simple way now.
> 
> Signed-off-by: Alexander Aring <aar@pengutronix.de>

I need to remove this signed off. That's not radvd commit style. :-)

---

After talking shortly with Marcel, RTNL netlink has already the same
stuff what we can get from sysfs entry here. See [0] kernel and [1]
userspace.

Over RTA_PAYLOAD(tb[IFLA_ADDRESS]) [1], we should be able to get the
dev->addr_len which is given by [0]... I make now a new version with
netlink as UAPI mechanism.

- Alex

[0] http://lxr.free-electrons.com/source/net/core/rtnetlink.c#L1247
[1] https://github.com/shemminger/iproute2/blob/master/lib/ll_map.c#L84
--
To unsubscribe from this list: send the line "unsubscribe linux-wpan" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/device-linux.c b/device-linux.c
index 7301927..c483952 100644
--- a/device-linux.c
+++ b/device-linux.c
@@ -29,6 +29,34 @@ 
 static char const *hwstr(unsigned short sa_family);
 
 /*
+ * get interface address length over sysfs
+ */
+static int get_device_addr_len(struct Interface *iface)
+{
+	char path[PATH_MAX];
+	uint32_t addr_len;
+	FILE *f;
+	int ret;
+
+	ret = sprintf(path, SYS_CLASS_NET_ADDRLEN, iface->props.name);
+	if (ret < 0)
+		return -1;
+
+	f = fopen(path, "r");
+	if (!f)
+		return -1;
+
+	ret = fscanf(f, "%u", &addr_len);
+	if (ferror(f)) {
+		fclose(f);
+		return -1;
+	}
+
+	fclose(f);
+	return addr_len;
+}
+
+/*
  * this function gets the hardware type and address of an interface,
  * determines the link layer token length and checks it against
  * the defined prefixes
@@ -84,8 +112,14 @@  int update_device_info(int sock, struct Interface *iface)
 		break;
 #endif				/* ARPHDR_ARCNET */
 	case ARPHRD_6LOWPAN:
-		iface->sllao.if_hwaddr_len = 64;
-		iface->sllao.if_prefix_len = 64;
+		iface->sllao.if_hwaddr_len = get_device_addr_len(iface);
+		if (iface->sllao.if_hwaddr_len != -1) {
+			iface->sllao.if_hwaddr_len *= 8;
+			iface->sllao.if_prefix_len = 64;
+		} else {
+			iface->sllao.if_prefix_len = -1;
+		}
+
 		break;
 	default:
 		iface->sllao.if_hwaddr_len = -1;
diff --git a/pathnames.h b/pathnames.h
index 580e2b2..152bb7a 100644
--- a/pathnames.h
+++ b/pathnames.h
@@ -40,6 +40,7 @@ 
 #define PROC_SYS_IP6_BASEREACHTIME "/proc/sys/net/ipv6/neigh/%s/base_reachable_time"
 #define PROC_SYS_IP6_RETRANSTIMER_MS "/proc/sys/net/ipv6/neigh/%s/retrans_time_ms"
 #define PROC_SYS_IP6_RETRANSTIMER "/proc/sys/net/ipv6/neigh/%s/retrans_time"
+#define SYS_CLASS_NET_ADDRLEN "/sys/class/net/%s/addr_len"
 #else				/* BSD */
 #define SYSCTL_IP6_FORWARDING CTL_NET, PF_INET6, IPPROTO_IPV6, IPV6CTL_FORWARDING
 #endif