2016-06-21 14:42:50

by Alexander Aring

[permalink] [raw]
Subject: [PATCH linux-wpan/radvd 6lowpan] device-linux: detect 6LoWPAN lltype for hwaddr length

This patch will change the behaviour for 6LoWPAN interface to detect the
linklayer type via debugfs. Each L2 interface has a different address
length and need to be detected.

Signed-off-by: Alexander Aring <[email protected]>
---
We have two choices (or even more):

- Add lltype like this patch to detect the hwaddr length

or

- Add a UAPI to get the hwaddr length doesn't depend on lltype

I did the first choice now, because it works like the net core api which
also has no UAPI for addr length. To get the address length you need to
map it to the netdev type. But this also means that a netdev type should
not have different hardware addresses.

In 6LoWPAN this is different, the ARPHRD_6LOWPAN can have different address
lengths. Jukka please tell me if this is fine or not, I usually don't want
to make things for ARPHRD_6LOWPAN link-layer specific, but we need to add
some solution for this.

My different UAPI solution is shown above, don't know which is actually
better. I think we need for some cases an UAPI to get the link-layer
type anyway.

btw: as fallback it use the olf behaviour 64 bit's so if we fix btle 6lowpan
to work with dev->addr_len = 6 and introduce the UAPI it will be fixed
automatically.

Later we need to move this stuff to sysfs. Debugfs is also not namespace
aware and because that it forbids me to make some special testing stuff.

device-linux.c | 52 +++++++++++++++++++++++++++++++++++++++++++++++++++-
pathnames.h | 1 +
2 files changed, 52 insertions(+), 1 deletion(-)

diff --git a/device-linux.c b/device-linux.c
index 55f8522..3d18071 100644
--- a/device-linux.c
+++ b/device-linux.c
@@ -60,6 +60,42 @@ static uint16_t lowpan_get_short_addr(struct Interface *iface)
}

/*
+ * sync with kernel so far we have no uapi header
+ */
+enum lowpan_lltypes {
+ LOWPAN_LLTYPE_BTLE,
+ LOWPAN_LLTYPE_IEEE802154,
+};
+
+/*
+ * get 6lowpan link layer type identifier
+ */
+static uint32_t lowpan_get_lltype(struct Interface *iface)
+{
+ char path[PATH_MAX];
+ uint32_t lltype;
+ FILE *f;
+ int ret;
+
+ ret = sprintf(path, DEBUGFS_6LOWPAN_LLTYPE, iface->props.name);
+ if (ret < 0)
+ return UINT32_MAX;
+
+ f = fopen(path, "r");
+ if (!f)
+ return UINT32_MAX;
+
+ ret = fscanf(f, "%d", &lltype);
+ if (ferror(f)) {
+ fclose(f);
+ return UINT32_MAX;
+ }
+
+ fclose(f);
+ return lltype;
+}
+
+/*
* this function gets the hardware type and address of an interface,
* determines the link layer token length and checks it against
* the defined prefixes
@@ -115,7 +151,21 @@ int update_device_info(int sock, struct Interface *iface)
break;
#endif /* ARPHDR_ARCNET */
case ARPHRD_6LOWPAN:
- iface->sllao.if_hwaddr_len = 64;
+ /* hwaddr length differs on each L2 type lets detect them */
+ switch (lowpan_get_lltype(iface)) {
+ case LOWPAN_LLTYPE_BTLE:
+ iface->sllao.if_hwaddr_len = 48;
+ break;
+ case LOWPAN_LLTYPE_IEEE802154:
+ iface->sllao.if_hwaddr_len = 64;
+ break;
+ default:
+ /* TODO change to -1 if 6LoWPAN has better UAPI for that */
+ flog(LOG_WARNING, "WARNING, couldn't get 6LoWPAN link-layer type on %s, falling back to 64 bit hwaddr", iface->props.name);
+ iface->sllao.if_hwaddr_len = 64;
+ break;
+ }
+
iface->sllao.if_prefix_len = 64;
/* for 802.15.4 only, all others L2 should fail and assign invalid address */
iface->short_addr = lowpan_get_short_addr(iface);
diff --git a/pathnames.h b/pathnames.h
index 0d3017b..c597ea0 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 DEBUGFS_6LOWPAN_LLTYPE "/sys/kernel/debug/6lowpan/%s/lltype"
#define DEBUGFS_6LOWPAN_CTX_ACTIVE "/sys/kernel/debug/6lowpan/%s/contexts/%d/active"
#define DEBUGFS_6LOWPAN_CTX_COMPRESSION "/sys/kernel/debug/6lowpan/%s/contexts/%d/compression"
#define DEBUGFS_6LOWPAN_CTX_PREFIX "/sys/kernel/debug/6lowpan/%s/contexts/%d/prefix"
--
2.9.0



2016-07-28 12:20:53

by Alexander Aring

[permalink] [raw]
Subject: Re: [PATCH linux-wpan/radvd 6lowpan] device-linux: detect 6LoWPAN lltype for hwaddr length

Hi,

On 06/21/2016 04:42 PM, Alexander Aring wrote:
> This patch will change the behaviour for 6LoWPAN interface to detect the
> linklayer type via debugfs. Each L2 interface has a different address
> length and need to be detected.
>
> Signed-off-by: Alexander Aring <[email protected]>
> ---
> We have two choices (or even more):
>
> - Add lltype like this patch to detect the hwaddr length
>
> or
>
> - Add a UAPI to get the hwaddr length doesn't depend on lltype
>
> I did the first choice now, because it works like the net core api which
> also has no UAPI for addr length. To get the address length you need to
> map it to the netdev type. But this also means that a netdev type should
> not have different hardware addresses.
>
> In 6LoWPAN this is different, the ARPHRD_6LOWPAN can have different address
> lengths. Jukka please tell me if this is fine or not, I usually don't want
> to make things for ARPHRD_6LOWPAN link-layer specific, but we need to add
> some solution for this.
>
> My different UAPI solution is shown above, don't know which is actually
> better. I think we need for some cases an UAPI to get the link-layer
> type anyway.
>
> btw: as fallback it use the olf behaviour 64 bit's so if we fix btle 6lowpan
> to work with dev->addr_len = 6 and introduce the UAPI it will be fixed
> automatically.
>
> Later we need to move this stuff to sysfs. Debugfs is also not namespace
> aware and because that it forbids me to make some special testing stuff.
>
> device-linux.c | 52 +++++++++++++++++++++++++++++++++++++++++++++++++++-
> pathnames.h | 1 +
> 2 files changed, 52 insertions(+), 1 deletion(-)
>
> diff --git a/device-linux.c b/device-linux.c
> index 55f8522..3d18071 100644
> --- a/device-linux.c
> +++ b/device-linux.c
> @@ -60,6 +60,42 @@ static uint16_t lowpan_get_short_addr(struct Interface *iface)

...

> * this function gets the hardware type and address of an interface,
> * determines the link layer token length and checks it against
> * the defined prefixes
> @@ -115,7 +151,21 @@ int update_device_info(int sock, struct Interface *iface)
> break;
> #endif /* ARPHDR_ARCNET */
> case ARPHRD_6LOWPAN:
> - iface->sllao.if_hwaddr_len = 64;
> + /* hwaddr length differs on each L2 type lets detect them */
> + switch (lowpan_get_lltype(iface)) {
> + case LOWPAN_LLTYPE_BTLE:
> + iface->sllao.if_hwaddr_len = 48;
> + break;
> + case LOWPAN_LLTYPE_IEEE802154:
> + iface->sllao.if_hwaddr_len = 64;
> + break;
> + default:
> + /* TODO change to -1 if 6LoWPAN has better UAPI for that */
> + flog(LOG_WARNING, "WARNING, couldn't get 6LoWPAN link-layer type on %s, falling back to 64 bit hwaddr", iface->props.name);
> + iface->sllao.if_hwaddr_len = 64;
> + break;
> + }
> +


I think to solve this issue, the best way currently is to evaluate:

/sys/class/net/$IFNAME/addr_len

which directly told us the dev->addr_len attribute in kernel. The only
thing that it could be that CONFIG_SYSFS isn't compiled. On 802.15.4 we
need to have SYSFS because iwpan and phy enumaration [0].

This solution should make radvd working with current mainline version
which does dev->addr_len == 8 and also with the version when we change
addr_len to 6.

Or we introduce an UAPI subtype mechanism? Maybe something which is
already set the NET_DEVTYPE stuff. Don't know I think we should go that
way, we can later still change it to some subtype (linklayer type)
evaluation if this information isn't enough for some linklayer types.

- Alex

[0] https://github.com/linux-wpan/wpan-tools/blob/master/src/iwpan.c#L221

2016-08-01 14:07:15

by Alexander Aring

[permalink] [raw]
Subject: Re: [PATCH linux-wpan/radvd 6lowpan] device-linux: detect 6LoWPAN lltype for hwaddr length


Hi,

On 07/28/2016 02:20 PM, Alexander Aring wrote:
> Hi,
>
> On 06/21/2016 04:42 PM, Alexander Aring wrote:
...
>
> I think to solve this issue, the best way currently is to evaluate:
>
> /sys/class/net/$IFNAME/addr_len
>
> which directly told us the dev->addr_len attribute in kernel. The only
> thing that it could be that CONFIG_SYSFS isn't compiled. On 802.15.4 we
> need to have SYSFS because iwpan and phy enumaration [0].
>
> This solution should make radvd working with current mainline version
> which does dev->addr_len == 8 and also with the version when we change
> addr_len to 6.

this doesn't work because the kernel stuff will put the device address
with U/L bitflip inside the address option. radvd will never do that
because this should never be the case...

Setting the U/L bit in radvd is a crazy behaviour inside the radvd code for
support bug compatible version of btle 6lowpan.

I currently try to catch all suggestions from the bluetooth 6lowpan
rework RFC and making a next round. Then maybe we can finding more
"issues" about using right dev->addr etc. :-)

Also I want to sent some RFC to fix radvd in upstream for 6LoWPAN.

- Alex