2016-06-20 07:49:49

by Patrik Flykt

[permalink] [raw]
Subject: [RFC 0/4] Fix BT 6lowpan point-to-point interface


Hi,

I made an effort some time ago to get the IPv6 ND messages working also
for Bluetooth Low Energy 6lowpan interfaces. The initial discovery was
that they get sent when the interface is not a point-to-point one. The
point-to-point interface flag is removed in patch 4/4.

In order to get the ND messages properly working, the MAC address for a
BTLE interface needs fixing, it's only 48 bits compared to the 64 bits
for 802.15.4. Patches 1/4 and 2/4 fix these common issues.

Patch 3/4, which is more hackish than the others, the patch uses an
array of length EUI64_ADDR_LEN to lowpan_header_decompress() in order
not to overwrite anything

These changes worked when tested against Zephyr, but that was on a
4.5.0-rc2 kernel. This time around I only forward-ported them to latest
and tested that they compiled successfully.

I hope these patches help with ND work moving forward in some way or
another.


Cheers,

Patrik


Patrik Flykt (4):
addrconf: Create EUI48 IPv6 addresses for BTLE 6LoWPAN
6lowpan: Set MAC address lenght according to LOWPAN_LLTYPE
bluetooth: Set 6 byte device addresses
bluetooth: Do not set IFF_POINTOPOINT

net/6lowpan/core.c | 11 ++++++++++-
net/bluetooth/6lowpan.c | 25 +++++++++++--------------
net/ipv6/addrconf.c | 4 ++++
3 files changed, 25 insertions(+), 15 deletions(-)

--
2.8.1



2016-06-20 12:56:31

by Luiz Augusto von Dentz

[permalink] [raw]
Subject: Re: [RFC 4/4] bluetooth: Do not set IFF_POINTOPOINT

Hi Patrik,

On Mon, Jun 20, 2016 at 10:49 AM, Patrik Flykt
<[email protected]> wrote:
> The IPv6 stack needs to send and receive Neighbor Discovery
> messages. Remove the IFF_POINTOPOINT flag.

I guess we can quote the https://tools.ietf.org/html/rfc7668#section-2.2:


' In Bluetooth LE, direct wireless communication only takes place
between a central and a peripheral. This means that inherently the
Bluetooth LE star represents a hub-and-spokes link model.
Nevertheless, two peripherals may communicate through the central by
using IP routing functionality per this specification.'

I guess this means the router should act as a hub, there is actually a
dedicated session for Neighbor Discovery:
https://tools.ietf.org/html/rfc7668#section-3.2.3

*We might have to check if we are conforming to things like not
publishing link-local addresses.


> Signed-off-by: Patrik Flykt <[email protected]>
> ---
> net/bluetooth/6lowpan.c | 3 +--
> 1 file changed, 1 insertion(+), 2 deletions(-)
>
> diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c
> index 2dddb2b..1a70312 100644
> --- a/net/bluetooth/6lowpan.c
> +++ b/net/bluetooth/6lowpan.c
> @@ -650,8 +650,7 @@ static void netdev_setup(struct net_device *dev)
> {
> dev->hard_header_len = 0;
> dev->needed_tailroom = 0;
> - dev->flags = IFF_RUNNING | IFF_POINTOPOINT |
> - IFF_MULTICAST;
> + dev->flags = IFF_RUNNING | IFF_MULTICAST;
> dev->watchdog_timeo = 0;
>
> dev->netdev_ops = &netdev_ops;
> --
> 2.8.1
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
> the body of a message to [email protected]
> More majordomo info at http://vger.kernel.org/majordomo-info.html



--
Luiz Augusto von Dentz

2016-06-20 11:18:31

by Alexander Aring

[permalink] [raw]
Subject: Re: [RFC 2/4] 6lowpan: Set MAC address lenght according to LOWPAN_LLTYPE


Hi,

On 06/20/2016 09:49 AM, Patrik Flykt wrote:
> Set MAC address length according to the 6LoWPAN link layer in use.
> Bluetooth Low Energy uses 48 bit addressing while IEEE802.15.4 uses
> 64 bits.
>
> Signed-off-by: Patrik Flykt <[email protected]>
> ---
> net/6lowpan/core.c | 11 ++++++++++-
> 1 file changed, 10 insertions(+), 1 deletion(-)
>
> diff --git a/net/6lowpan/core.c b/net/6lowpan/core.c
> index 5945f7e..5f9909a 100644
> --- a/net/6lowpan/core.c
> +++ b/net/6lowpan/core.c
> @@ -23,7 +23,16 @@ int lowpan_register_netdevice(struct net_device *dev,
> {
> int i, ret;
>
> - dev->addr_len = EUI64_ADDR_LEN;
> + switch (lltype) {
> + case LOWPAN_LLTYPE_IEEE802154:
> + dev->addr_len = EUI64_ADDR_LEN;
> + break;
> +
> + case LOWPAN_LLTYPE_BTLE:
> + dev->addr_len = ETH_ALEN;
> + break;
> + }
> +

btw: this patch breaks a lot of things where net/bluetooth/6lowpan.c
access the dev->addr_len as eui64. e.g. [0].

Seems to fixed in PATCH 3/4, but dev->addr is also used in IPHC code,
e.g. [1], which still handle it as 8 byte address.

I think you need to fixup the whole thing into one patch, to not break
anything in the middle.

btw: if we change that, we need to add some stuff in radvd that they
know it's 48 bit hardware address not 64. See [2], but I think we can
use struct ifreq for that, to get the dev->addr_len in userspace.

- Alex

[0] http://lxr.free-electrons.com/source/net/bluetooth/6lowpan.c#L674
[1] http://lxr.free-electrons.com/source/net/bluetooth/6lowpan.c#L479
[2] https://github.com/linux-wpan/radvd/blob/6lowpan/device-linux.c#L118

2016-06-20 11:08:36

by Alexander Aring

[permalink] [raw]
Subject: Re: [RFC 3/4] bluetooth: Set 6 byte device addresses


Hi,

On 06/20/2016 09:49 AM, Patrik Flykt wrote:
> Set BTLE MAC addresses that are 6 bytes long and not 8 bytes
> that are used in other places with 6lowpan.
>
> Signed-off-by: Patrik Flykt <[email protected]>
> This patch needs to be cleaned up but worksforme.
> ---
> net/bluetooth/6lowpan.c | 22 ++++++++++------------
> 1 file changed, 10 insertions(+), 12 deletions(-)
>
> diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c
> index d020299..2dddb2b 100644
> --- a/net/bluetooth/6lowpan.c
> +++ b/net/bluetooth/6lowpan.c
> @@ -80,6 +80,8 @@ struct lowpan_btle_dev {
> struct delayed_work notify_peers;
> };
>
> +static void set_addr(u8 *eui, u8 *addr, u8 addr_type);
> +
> static inline struct lowpan_btle_dev *
> lowpan_btle_dev(const struct net_device *netdev)
> {
> @@ -272,9 +274,10 @@ static int give_skb_to_upper(struct sk_buff *skb, struct net_device *dev)
> static int iphc_decompress(struct sk_buff *skb, struct net_device *netdev,
> struct l2cap_chan *chan)
> {
> - const u8 *saddr, *daddr;
> + const u8 *saddr;
> struct lowpan_btle_dev *dev;
> struct lowpan_peer *peer;
> + unsigned char eui64_daddr[EUI64_ADDR_LEN];

I know it's currently saved still as 8 byte address in L2 btle 6LoWPAN
handling, but this isn't really necessary or? Correct would be to change
all the code to really save the 6 byte bluetooth device address only.
Not the FFFE u/l stuff anymore. All l2 addresses which should be stored
somehow should be 6 byte.

>
> dev = lowpan_btle_dev(netdev);
>
> @@ -285,9 +288,9 @@ static int iphc_decompress(struct sk_buff *skb, struct net_device *netdev,
> return -EINVAL;
>
> saddr = peer->eui64_addr;
> - daddr = dev->netdev->dev_addr;
> + set_addr(&eui64_daddr[0], chan->src.b, chan->src_type);
>

I have still issues with that:

Okay, the current setup which I also had done is the following:

A <-----> B

I suppose bdaddr A is:

peer->eui64_addr

B is:

chan->src.b

This is true point to point communcation.
But isn't the following setup not also possible? Questions for bluetooth
experts:

A <-----> B
A <-----> C
A <-----> ...

Which is still point-to-point, but the "chan->src.b" is some variable
where it depends if it's B or C... or even more.

If the last setup with "two chan->src.b" is possible, then don't use
your own saved bluetooth device address which you saved while creating
some 6lowpan connection (I suppose this is how it's currently saved in
chan->src.b").

You need to use the destination address which comes from the neighbour
discovery cache.

You cannot decide at this point to which L3 address the L2 address comes
from, only the ndisc cache knows it. The same also if:

A <-----> B

you don't use ndisc daddr, you use your own stored one. And of course remove
the reconstruction of L2 address from L3 address which doesn't work in some
cases, use the L2 from ndisc. [0]

> - return lowpan_header_decompress(skb, netdev, daddr, saddr);
> + return lowpan_header_decompress(skb, netdev, &eui64_daddr, saddr);

In this case saddr and daddr should now the 6-bytes address of bluetooth
device address, right? But then I don't get why eui64_daddr is still
EUI64_ADDR_LEN.

Then you need to update the IPHC SAM/DAM = 11 handling, e.g. [1]. Note,
there exists more compression/uncompression for L2 addresses.

> }
>
> static int recv_pkt(struct sk_buff *skb, struct net_device *dev,
> @@ -681,13 +684,6 @@ static void set_addr(u8 *eui, u8 *addr, u8 addr_type)
> BT_DBG("type %d addr %*phC", addr_type, 8, eui);
> }
>
> -static void set_dev_addr(struct net_device *netdev, bdaddr_t *addr,
> - u8 addr_type)
> -{
> - netdev->addr_assign_type = NET_ADDR_PERM;
> - set_addr(netdev->dev_addr, addr->b, addr_type);
> -}
> -
> static void ifup(struct net_device *netdev)
> {
> int err;
> @@ -795,7 +791,7 @@ static struct l2cap_chan *add_peer_chan(struct l2cap_chan *chan,
> static int setup_netdev(struct l2cap_chan *chan, struct lowpan_btle_dev **dev)
> {
> struct net_device *netdev;
> - int err = 0;
> + int i, err = 0;
>
> netdev = alloc_netdev(LOWPAN_PRIV_SIZE(sizeof(struct lowpan_btle_dev)),
> IFACE_NAME_TEMPLATE, NET_NAME_UNKNOWN,
> @@ -803,7 +799,9 @@ static int setup_netdev(struct l2cap_chan *chan, struct lowpan_btle_dev **dev)
> if (!netdev)
> return -ENOMEM;
>
> - set_dev_addr(netdev, &chan->src, chan->src_type);
> + netdev->addr_assign_type = NET_ADDR_PERM;
> + for (i = 0; i < sizeof(chan->src); i++)
> + netdev->dev_addr[i] = chan->src.b[sizeof(chan->src) - 1 - i];
>
> netdev->netdev_ops = &netdev_ops;
> SET_NETDEV_DEV(netdev, &chan->conn->hcon->hdev->dev);
>

- Alex

[0] http://lxr.free-electrons.com/source/net/bluetooth/6lowpan.c#L452
[1] http://lxr.free-electrons.com/source/net/6lowpan/iphc.c#L327

2016-06-20 10:46:12

by Alexander Aring

[permalink] [raw]
Subject: Re: [RFC 2/4] 6lowpan: Set MAC address lenght according to LOWPAN_LLTYPE


Hi,

On 06/20/2016 09:49 AM, Patrik Flykt wrote:
> Set MAC address length according to the 6LoWPAN link layer in use.
> Bluetooth Low Energy uses 48 bit addressing while IEEE802.15.4 uses
> 64 bits.
>
> Signed-off-by: Patrik Flykt <[email protected]>
> ---
> net/6lowpan/core.c | 11 ++++++++++-
> 1 file changed, 10 insertions(+), 1 deletion(-)
>
> diff --git a/net/6lowpan/core.c b/net/6lowpan/core.c
> index 5945f7e..5f9909a 100644
> --- a/net/6lowpan/core.c
> +++ b/net/6lowpan/core.c
> @@ -23,7 +23,16 @@ int lowpan_register_netdevice(struct net_device *dev,
> {
> int i, ret;
>
> - dev->addr_len = EUI64_ADDR_LEN;
> + switch (lltype) {
> + case LOWPAN_LLTYPE_IEEE802154:
> + dev->addr_len = EUI64_ADDR_LEN;
> + break;

remove this case.

> +
> + case LOWPAN_LLTYPE_BTLE:
> + dev->addr_len = ETH_ALEN;
> + break;
> + }
> +

I would add here an default branch which does the EUI64 handling. EUI64
should be the normal case, all others doesn't has a EUI64 and then there
exists some mechanism to create the EUI64 from e.g. EUI48 address.

Switch case with one case branch makes not really sense, maybe use if
here.

Also cc linux-wpan for net/6lowpan/ patches.

- Alex

2016-06-20 07:49:52

by Patrik Flykt

[permalink] [raw]
Subject: [RFC 3/4] bluetooth: Set 6 byte device addresses

Set BTLE MAC addresses that are 6 bytes long and not 8 bytes
that are used in other places with 6lowpan.

Signed-off-by: Patrik Flykt <[email protected]>
This patch needs to be cleaned up but worksforme.
---
net/bluetooth/6lowpan.c | 22 ++++++++++------------
1 file changed, 10 insertions(+), 12 deletions(-)

diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c
index d020299..2dddb2b 100644
--- a/net/bluetooth/6lowpan.c
+++ b/net/bluetooth/6lowpan.c
@@ -80,6 +80,8 @@ struct lowpan_btle_dev {
struct delayed_work notify_peers;
};

+static void set_addr(u8 *eui, u8 *addr, u8 addr_type);
+
static inline struct lowpan_btle_dev *
lowpan_btle_dev(const struct net_device *netdev)
{
@@ -272,9 +274,10 @@ static int give_skb_to_upper(struct sk_buff *skb, struct net_device *dev)
static int iphc_decompress(struct sk_buff *skb, struct net_device *netdev,
struct l2cap_chan *chan)
{
- const u8 *saddr, *daddr;
+ const u8 *saddr;
struct lowpan_btle_dev *dev;
struct lowpan_peer *peer;
+ unsigned char eui64_daddr[EUI64_ADDR_LEN];

dev = lowpan_btle_dev(netdev);

@@ -285,9 +288,9 @@ static int iphc_decompress(struct sk_buff *skb, struct net_device *netdev,
return -EINVAL;

saddr = peer->eui64_addr;
- daddr = dev->netdev->dev_addr;
+ set_addr(&eui64_daddr[0], chan->src.b, chan->src_type);

- return lowpan_header_decompress(skb, netdev, daddr, saddr);
+ return lowpan_header_decompress(skb, netdev, &eui64_daddr, saddr);
}

static int recv_pkt(struct sk_buff *skb, struct net_device *dev,
@@ -681,13 +684,6 @@ static void set_addr(u8 *eui, u8 *addr, u8 addr_type)
BT_DBG("type %d addr %*phC", addr_type, 8, eui);
}

-static void set_dev_addr(struct net_device *netdev, bdaddr_t *addr,
- u8 addr_type)
-{
- netdev->addr_assign_type = NET_ADDR_PERM;
- set_addr(netdev->dev_addr, addr->b, addr_type);
-}
-
static void ifup(struct net_device *netdev)
{
int err;
@@ -795,7 +791,7 @@ static struct l2cap_chan *add_peer_chan(struct l2cap_chan *chan,
static int setup_netdev(struct l2cap_chan *chan, struct lowpan_btle_dev **dev)
{
struct net_device *netdev;
- int err = 0;
+ int i, err = 0;

netdev = alloc_netdev(LOWPAN_PRIV_SIZE(sizeof(struct lowpan_btle_dev)),
IFACE_NAME_TEMPLATE, NET_NAME_UNKNOWN,
@@ -803,7 +799,9 @@ static int setup_netdev(struct l2cap_chan *chan, struct lowpan_btle_dev **dev)
if (!netdev)
return -ENOMEM;

- set_dev_addr(netdev, &chan->src, chan->src_type);
+ netdev->addr_assign_type = NET_ADDR_PERM;
+ for (i = 0; i < sizeof(chan->src); i++)
+ netdev->dev_addr[i] = chan->src.b[sizeof(chan->src) - 1 - i];

netdev->netdev_ops = &netdev_ops;
SET_NETDEV_DEV(netdev, &chan->conn->hcon->hdev->dev);
--
2.8.1


2016-06-20 07:49:50

by Patrik Flykt

[permalink] [raw]
Subject: [RFC 1/4] addrconf: Create EUI48 IPv6 addresses for BTLE 6LoWPAN

Create EUI48 IPv6 addresses for 6LoWPAN over Bluetooth Low Energy.
Both IEEE802.15.4 and Bluetooth Low Energy use a netdevice type of
ARPHRD_6LOWPAN, therefore generate the IPv6 address based on the
MAC address length.

Signed-off-by: Patrik Flykt <[email protected]>
---
net/ipv6/addrconf.c | 4 ++++
1 file changed, 4 insertions(+)

diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 6c8fc3f..6697fe6 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -2055,6 +2055,10 @@ static int ipv6_generate_eui64(u8 *eui, struct net_device *dev)
case ARPHRD_IPGRE:
return addrconf_ifid_gre(eui, dev);
case ARPHRD_6LOWPAN:
+ /* 6LoWPAN over BTLE */
+ if (dev->addr_len == ETH_ALEN)
+ return addrconf_ifid_eui48(eui, dev);
+
return addrconf_ifid_eui64(eui, dev);
case ARPHRD_IEEE1394:
return addrconf_ifid_ieee1394(eui, dev);
--
2.8.1


2016-06-20 07:49:51

by Patrik Flykt

[permalink] [raw]
Subject: [RFC 2/4] 6lowpan: Set MAC address lenght according to LOWPAN_LLTYPE

Set MAC address length according to the 6LoWPAN link layer in use.
Bluetooth Low Energy uses 48 bit addressing while IEEE802.15.4 uses
64 bits.

Signed-off-by: Patrik Flykt <[email protected]>
---
net/6lowpan/core.c | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/net/6lowpan/core.c b/net/6lowpan/core.c
index 5945f7e..5f9909a 100644
--- a/net/6lowpan/core.c
+++ b/net/6lowpan/core.c
@@ -23,7 +23,16 @@ int lowpan_register_netdevice(struct net_device *dev,
{
int i, ret;

- dev->addr_len = EUI64_ADDR_LEN;
+ switch (lltype) {
+ case LOWPAN_LLTYPE_IEEE802154:
+ dev->addr_len = EUI64_ADDR_LEN;
+ break;
+
+ case LOWPAN_LLTYPE_BTLE:
+ dev->addr_len = ETH_ALEN;
+ break;
+ }
+
dev->type = ARPHRD_6LOWPAN;
dev->mtu = IPV6_MIN_MTU;
dev->priv_flags |= IFF_NO_QUEUE;
--
2.8.1


2016-06-20 07:49:53

by Patrik Flykt

[permalink] [raw]
Subject: [RFC 4/4] bluetooth: Do not set IFF_POINTOPOINT

The IPv6 stack needs to send and receive Neighbor Discovery
messages. Remove the IFF_POINTOPOINT flag.

Signed-off-by: Patrik Flykt <[email protected]>
---
net/bluetooth/6lowpan.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c
index 2dddb2b..1a70312 100644
--- a/net/bluetooth/6lowpan.c
+++ b/net/bluetooth/6lowpan.c
@@ -650,8 +650,7 @@ static void netdev_setup(struct net_device *dev)
{
dev->hard_header_len = 0;
dev->needed_tailroom = 0;
- dev->flags = IFF_RUNNING | IFF_POINTOPOINT |
- IFF_MULTICAST;
+ dev->flags = IFF_RUNNING | IFF_MULTICAST;
dev->watchdog_timeo = 0;

dev->netdev_ops = &netdev_ops;
--
2.8.1


2016-11-22 15:28:52

by Alexander Aring

[permalink] [raw]
Subject: Re: [RFC 1/4] addrconf: Create EUI48 IPv6 addresses for BTLE 6LoWPAN


Hi,

On 11/22/2016 01:26 PM, Luiz Augusto von Dentz wrote:
> Hi,
>
> On Mon, Jun 20, 2016 at 10:49 AM, Patrik Flykt
> <[email protected]> wrote:
>> Create EUI48 IPv6 addresses for 6LoWPAN over Bluetooth Low Energy.
>> Both IEEE802.15.4 and Bluetooth Low Energy use a netdevice type of
>> ARPHRD_6LOWPAN, therefore generate the IPv6 address based on the
>> MAC address length.
>>
>> Signed-off-by: Patrik Flykt <[email protected]>
>> ---
>> net/ipv6/addrconf.c | 4 ++++
>> 1 file changed, 4 insertions(+)
>>
>> diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
>> index 6c8fc3f..6697fe6 100644
>> --- a/net/ipv6/addrconf.c
>> +++ b/net/ipv6/addrconf.c
>> @@ -2055,6 +2055,10 @@ static int ipv6_generate_eui64(u8 *eui, struct net_device *dev)
>> case ARPHRD_IPGRE:
>> return addrconf_ifid_gre(eui, dev);
>> case ARPHRD_6LOWPAN:
>> + /* 6LoWPAN over BTLE */
>> + if (dev->addr_len == ETH_ALEN)
>> + return addrconf_ifid_eui48(eui, dev);
>> +
>> return addrconf_ifid_eui64(eui, dev);
>> case ARPHRD_IEEE1394:
>> return addrconf_ifid_ieee1394(eui, dev);
>> --
>> 2.8.1
>
> This still seems to be broken.
>

I know. RFC-Series [0] fix that and more...

I think I need to rework the patch series but I think I didn't get much
review from bluetooth side yet.

E.g. what address type to use, etc.

I currently write my thesis so I have time for that maybe beginning of
april. Sorry, but Jukka can take the patches and send them I can
review/test it. So far I know Jukka is very busy with zephyr... so it
will be broken until april.

Or will somebody else catch the patches?

- Alex

[0] http://www.spinics.net/lists/linux-wpan/msg04124.html

2016-11-22 12:26:16

by Luiz Augusto von Dentz

[permalink] [raw]
Subject: Re: [RFC 1/4] addrconf: Create EUI48 IPv6 addresses for BTLE 6LoWPAN

Hi,

On Mon, Jun 20, 2016 at 10:49 AM, Patrik Flykt
<[email protected]> wrote:
> Create EUI48 IPv6 addresses for 6LoWPAN over Bluetooth Low Energy.
> Both IEEE802.15.4 and Bluetooth Low Energy use a netdevice type of
> ARPHRD_6LOWPAN, therefore generate the IPv6 address based on the
> MAC address length.
>
> Signed-off-by: Patrik Flykt <[email protected]>
> ---
> net/ipv6/addrconf.c | 4 ++++
> 1 file changed, 4 insertions(+)
>
> diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
> index 6c8fc3f..6697fe6 100644
> --- a/net/ipv6/addrconf.c
> +++ b/net/ipv6/addrconf.c
> @@ -2055,6 +2055,10 @@ static int ipv6_generate_eui64(u8 *eui, struct net_device *dev)
> case ARPHRD_IPGRE:
> return addrconf_ifid_gre(eui, dev);
> case ARPHRD_6LOWPAN:
> + /* 6LoWPAN over BTLE */
> + if (dev->addr_len == ETH_ALEN)
> + return addrconf_ifid_eui48(eui, dev);
> +
> return addrconf_ifid_eui64(eui, dev);
> case ARPHRD_IEEE1394:
> return addrconf_ifid_ieee1394(eui, dev);
> --
> 2.8.1

This still seems to be broken.

--
Luiz Augusto von Dentz