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@xxxxxxxxxxxxxx> --- device-linux.c | 38 ++++++++++++++++++++++++++++++++++++-- pathnames.h | 1 + 2 files changed, 37 insertions(+), 2 deletions(-) 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 -- 2.9.0 -- To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html