2019-02-08 15:32:01

by Ing. Josua Mayer

[permalink] [raw]
Subject: [PATCH 0/3] bluetooth: 6lowpan: multiple peers and addresses

Dear maintainers,

This patch set deals with an issue I reported earlier this year, where
1) packets addressed to a non-link-local address
2) any packets when at least 2 peers are connected
were not delivered if they matched a direct peer i.e. no routing.

The full explanation of the issue including steps to reproduce are:
https://www.spinics.net/lists/linux-bluetooth/msg78486.html

Please comment if I am on the right track here, especially on the
second patch in this series where I am nto completely sure if I found
the right api call to the neighbour cache.

Josua Mayer (3):
bluetooth: 6lowpan: search for destination address in all peers
bluetooth: 6lowpan: check neighbour table for SLAAC
bluetooth: 6lowpan: always check destination address

net/bluetooth/6lowpan.c | 40 ++++++++++++++++++++++++----------------
1 file changed, 24 insertions(+), 16 deletions(-)

--
2.20.1



2019-02-08 15:31:57

by Ing. Josua Mayer

[permalink] [raw]
Subject: [PATCH 1/3] bluetooth: 6lowpan: search for destination address in all peers

Handle overlooked case where the target address is assigned to a peer
and neither route nor gateway exist.

For one peer, no checks are performed to see if it is meant to receive
packets for a given address.

As soon as there is a second peer however, checks are performed
to deal with routes and gatways for handling complex setups with
multiple hops to a target address.
This logic assumed that no route and no gatway imply that the
destination address can not be reached, which is false in case of a
direct peer.

Signed-off-by: Josua Mayer <[email protected]>
---
net/bluetooth/6lowpan.c | 14 ++++++++++----
1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c
index 9d79c7de234a..553dc719afde 100644
--- a/net/bluetooth/6lowpan.c
+++ b/net/bluetooth/6lowpan.c
@@ -187,10 +187,16 @@ static inline struct lowpan_peer *peer_lookup_dst(struct lowpan_btle_dev *dev,
}

if (!rt) {
- nexthop = &lowpan_cb(skb)->gw;
-
- if (ipv6_addr_any(nexthop))
- return NULL;
+ if (ipv6_addr_any(&lowpan_cb(skb)->gw)) {
+ /* There is neither route nor gateway,
+ * probably the destination is a direct peer.
+ */
+ nexthop = daddr;
+ } else {
+ /* There is a known gateway
+ */
+ nexthop = &lowpan_cb(skb)->gw;
+ }
} else {
nexthop = rt6_nexthop(rt, daddr);

--
2.20.1


2019-02-08 15:32:04

by Ing. Josua Mayer

[permalink] [raw]
Subject: [PATCH 2/3] bluetooth: 6lowpan: check neighbour table for SLAAC

Like any IPv6 capable device, 6LNs can have multiple addresses assigned
using SLAAC and made known through neighbour advertisements.
After checking the destination address against all peers link-local
addresses, consult the neighbour cache for additional known addresses.

RFC7668 defines the scope of Neighbor Advertisements in Section 3.2.3:
1. "A Bluetooth LE 6LN MUST NOT register its link-local address"
2. "A Bluetooth LE 6LN MUST register its non-link-local addresses with
the 6LBR by sending Neighbor Solicitation (NS) messages ..."

Due to these constranits both the link-local addresses tracked in the
list of 6lowpan peers, and the neighbour cache have to be used when
identifying the 6lowpan peer for a destination address.

Signed-off-by: Josua Mayer <[email protected]>
---
net/bluetooth/6lowpan.c | 14 ++++++++++++++
1 file changed, 14 insertions(+)

diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c
index 553dc719afde..4e14db230793 100644
--- a/net/bluetooth/6lowpan.c
+++ b/net/bluetooth/6lowpan.c
@@ -171,6 +171,7 @@ static inline struct lowpan_peer *peer_lookup_dst(struct lowpan_btle_dev *dev,
struct in6_addr *nexthop;
struct rt6_info *rt = (struct rt6_info *)skb_dst(skb);
int count = atomic_read(&dev->peer_count);
+ struct neighbour *neigh;

BT_DBG("peers %d addr %pI6c rt %p", count, daddr, rt);

@@ -222,6 +223,19 @@ static inline struct lowpan_peer *peer_lookup_dst(struct lowpan_btle_dev *dev,
}
}

+ // use the neighbout cache for matching addresses assigned by SLAAC
+ neigh = __ipv6_neigh_lookup(dev->netdev, nexthop);
+ if (neigh) {
+ list_for_each_entry_rcu(peer, &dev->peers, list) {
+ if (!memcmp(neigh->ha, peer->lladdr, ETH_ALEN)) {
+ neigh_release(neigh);
+ rcu_read_unlock();
+ return peer;
+ }
+ }
+ neigh_release(neigh);
+ }
+
rcu_read_unlock();

return NULL;
--
2.20.1


2019-02-08 15:32:19

by Ing. Josua Mayer

[permalink] [raw]
Subject: [PATCH 3/3] bluetooth: 6lowpan: always check destination address

BLE based 6LoWPAN networks are highly constrained in bandwidth.
Do not take a short-cut, always check if the destination address is
known to belong to a peer.

As a side-effect this also removes any behavioral differences between
one, and two or more connected peers.

Signed-off-by: Josua Mayer <[email protected]>
---
net/bluetooth/6lowpan.c | 12 ------------
1 file changed, 12 deletions(-)

diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c
index 4e14db230793..62b57d3bc0c0 100644
--- a/net/bluetooth/6lowpan.c
+++ b/net/bluetooth/6lowpan.c
@@ -175,18 +175,6 @@ static inline struct lowpan_peer *peer_lookup_dst(struct lowpan_btle_dev *dev,

BT_DBG("peers %d addr %pI6c rt %p", count, daddr, rt);

- /* If we have multiple 6lowpan peers, then check where we should
- * send the packet. If only one peer exists, then we can send the
- * packet right away.
- */
- if (count == 1) {
- rcu_read_lock();
- peer = list_first_or_null_rcu(&dev->peers, struct lowpan_peer,
- list);
- rcu_read_unlock();
- return peer;
- }
-
if (!rt) {
if (ipv6_addr_any(&lowpan_cb(skb)->gw)) {
/* There is neither route nor gateway,
--
2.20.1


2019-02-28 20:00:40

by Ing. Josua Mayer

[permalink] [raw]
Subject: Re: [PATCH 0/3] bluetooth: 6lowpan: multiple peers and addresses

Ping

Did anyone get a chance to look at this yet?
@Jukka I have added you in CC since this is about both 6lowpan and ble.

Am 08.02.19 um 16:25 schrieb Josua Mayer:
> Dear maintainers,
>
> This patch set deals with an issue I reported earlier this year, where
> 1) packets addressed to a non-link-local address
> 2) any packets when at least 2 peers are connected
> were not delivered if they matched a direct peer i.e. no routing.
>
> The full explanation of the issue including steps to reproduce are:
> https://www.spinics.net/lists/linux-bluetooth/msg78486.html
>
> Please comment if I am on the right track here, especially on the
> second patch in this series where I am nto completely sure if I found
> the right api call to the neighbour cache.
>
> Josua Mayer (3):
> bluetooth: 6lowpan: search for destination address in all peers
> bluetooth: 6lowpan: check neighbour table for SLAAC
> bluetooth: 6lowpan: always check destination address
>
> net/bluetooth/6lowpan.c | 40 ++++++++++++++++++++++++----------------
> 1 file changed, 24 insertions(+), 16 deletions(-)
>

2019-02-28 20:30:48

by Michael Scott

[permalink] [raw]
Subject: Re: [PATCH 0/3] bluetooth: 6lowpan: multiple peers and addresses

Hi Josua,

On 2/28/19 12:00 PM, Josua Mayer wrote:
> Ping
>
> Did anyone get a chance to look at this yet?
> @Jukka I have added you in CC since this is about both 6lowpan and ble.
>
> Am 08.02.19 um 16:25 schrieb Josua Mayer:
>> Dear maintainers,
>>
>> This patch set deals with an issue I reported earlier this year, where
>> 1) packets addressed to a non-link-local address
>> 2) any packets when at least 2 peers are connected
>> were not delivered if they matched a direct peer i.e. no routing.
>>
>> The full explanation of the issue including steps to reproduce are:
>> https://www.spinics.net/lists/linux-bluetooth/msg78486.html

Thank you for submitting these patches!  I've been debugging what seems
to be the very same issue.

My setup:
- a Linux-based gateway running a fairly recent kernel (4.18) connected
to my local network (and the internet) via wifi/ethernet.
- several Zephyr(RTOS)-based devices (mostly Nordic) connected via BLE
6lowpan to the gateway
- the gateway provides DNS64 and NAT64 translation, so that the
IPv6-based nodes can communicate with IPv4 services

Much as you describe, everything works flawlessly when only 1 BLE
6lowpan node is connected.

Once a 2nd node is connected, all non-link local communication fails. 
Using tcpdump to watch bt0 interface traffic on the gateway: it *looks*
like the packets are being sent back to the various nodes.  However, on
the node side those packets are never received.   The very second you
bring the 2nd node down so that only 1 node is connected, communication
on non-link local IPs is immediately restored.

NOTE: I can reproduce the same behavior on a 4.20 kernel using my
laptop, so this issue is still valid.

I should be able to apply these patches to my local setup today or
tomorrow, and I'll write back regarding the experience.

Thank you again,

- Mike

>>
>> Please comment if I am on the right track here, especially on the
>> second patch in this series where I am nto completely sure if I found
>> the right api call to the neighbour cache.
>>
>> Josua Mayer (3):
>> bluetooth: 6lowpan: search for destination address in all peers
>> bluetooth: 6lowpan: check neighbour table for SLAAC
>> bluetooth: 6lowpan: always check destination address
>>
>> net/bluetooth/6lowpan.c | 40 ++++++++++++++++++++++++----------------
>> 1 file changed, 24 insertions(+), 16 deletions(-)
>>
--
Michael Scott
Embedded Software Engineer at Foundries.io
"microPlatforms™ for Connected Products"
E: [email protected]
W: https://www.foundries.io


2019-03-06 18:10:54

by Michael Scott

[permalink] [raw]
Subject: Re: [PATCH 0/3] bluetooth: 6lowpan: multiple peers and addresses

Josua,

On 2/28/19 12:30 PM, Michael Scott wrote:
> Hi Josua,
>
> On 2/28/19 12:00 PM, Josua Mayer wrote:
>> Ping
>>
>> Did anyone get a chance to look at this yet?
>> @Jukka I have added you in CC since this is about both 6lowpan and ble.
>>
>> Am 08.02.19 um 16:25 schrieb Josua Mayer:
>>> Dear maintainers,
>>>
>>> This patch set deals with an issue I reported earlier this year, where
>>> 1) packets addressed to a non-link-local address
>>> 2) any packets when at least 2 peers are connected
>>> were not delivered if they matched a direct peer i.e. no routing.
>>>
>>> The full explanation of the issue including steps to reproduce are:
>>> https://www.spinics.net/lists/linux-bluetooth/msg78486.html
>
> Thank you for submitting these patches!  I've been debugging what
> seems to be the very same issue.
>
> My setup:
> - a Linux-based gateway running a fairly recent kernel (4.18)
> connected to my local network (and the internet) via wifi/ethernet.
> - several Zephyr(RTOS)-based devices (mostly Nordic) connected via BLE
> 6lowpan to the gateway
> - the gateway provides DNS64 and NAT64 translation, so that the
> IPv6-based nodes can communicate with IPv4 services
>
> Much as you describe, everything works flawlessly when only 1 BLE
> 6lowpan node is connected.
>
> Once a 2nd node is connected, all non-link local communication fails. 
> Using tcpdump to watch bt0 interface traffic on the gateway: it
> *looks* like the packets are being sent back to the various nodes. 
> However, on the node side those packets are never received.   The very
> second you bring the 2nd node down so that only 1 node is connected,
> communication on non-link local IPs is immediately restored.
>
> NOTE: I can reproduce the same behavior on a 4.20 kernel using my
> laptop, so this issue is still valid.
>
> I should be able to apply these patches to my local setup today or
> tomorrow, and I'll write back regarding the experience.

Apologies for the delay, work has been very busy.

I was able to test these patches and everything works well on my end. 
Feel free to add my Tested-By:

Tested-by: Michael Scott <[email protected]>

>
> Thank you again,
>
> - Mike
>
>>>
>>> Please comment if I am on the right track here, especially on the
>>> second patch in this series where I am nto completely sure if I found
>>> the right api call to the neighbour cache.
>>>
>>> Josua Mayer (3):
>>>    bluetooth: 6lowpan: search for destination address in all peers
>>>    bluetooth: 6lowpan: check neighbour table for SLAAC
>>>    bluetooth: 6lowpan: always check destination address
>>>
>>>   net/bluetooth/6lowpan.c | 40 ++++++++++++++++++++++++----------------
>>>   1 file changed, 24 insertions(+), 16 deletions(-)
>>>
--
Michael Scott
Embedded Software Engineer at Foundries.io
"microPlatforms™ for Connected Products"
E: [email protected]
W: https://www.foundries.io


2019-03-07 09:16:07

by Jukka Rissanen

[permalink] [raw]
Subject: Re: [PATCH 0/3] bluetooth: 6lowpan: multiple peers and addresses

Thanks Mike & Josua,

On Wed, 2019-03-06 at 10:10 -0800, Michael Scott wrote:
> Josua,
>
> On 2/28/19 12:30 PM, Michael Scott wrote:
> > Hi Josua,
> >
> > On 2/28/19 12:00 PM, Josua Mayer wrote:
> > > Ping
> > >
> > > Did anyone get a chance to look at this yet?
> > > @Jukka I have added you in CC since this is about both 6lowpan
> > > and ble.
> > >

The patches looked ok.

Acked-by: Jukka Rissanen <[email protected]>


Cheers,
Jukka



2019-03-07 10:41:19

by Johan Hedberg

[permalink] [raw]
Subject: Re: [PATCH 2/3] bluetooth: 6lowpan: check neighbour table for SLAAC

Hi Josua,

Your patches look fine to me in general, just a very minor thing with
this one:

On Fri, Feb 08, 2019, Josua Mayer wrote:
> + // use the neighbout cache for matching addresses assigned by SLAAC

C++ comment style isn't used - use /* ... */ instead.

Johan

2019-03-12 16:23:21

by Ing. Josua Mayer

[permalink] [raw]
Subject: Re: [PATCH 2/3] bluetooth: 6lowpan: check neighbour table for SLAAC

Hi Johan,

Am 07.03.19 um 11:41 schrieb Johan Hedberg:
> Hi Josua,
>
> Your patches look fine to me in general, just a very minor thing with
> this one:
>
> On Fri, Feb 08, 2019, Josua Mayer wrote:
>> + // use the neighbout cache for matching addresses assigned by SLAAC
>
> C++ comment style isn't used - use /* ... */ instead.
Will change that, and submit a v2 later today, thanks!
>
> Johan
>

2019-03-12 19:18:15

by Ing. Josua Mayer

[permalink] [raw]
Subject: [PATCH v2 3/3] bluetooth: 6lowpan: always check destination address

BLE based 6LoWPAN networks are highly constrained in bandwidth.
Do not take a short-cut, always check if the destination address is
known to belong to a peer.

As a side-effect this also removes any behavioral differences between
one, and two or more connected peers.

Acked-by: Jukka Rissanen <[email protected]>
Tested-by: Michael Scott <[email protected]>
Signed-off-by: Josua Mayer <[email protected]>
---
net/bluetooth/6lowpan.c | 12 ------------
1 file changed, 12 deletions(-)

diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c
index 29a4f3d65348..0f64e9ef1a3a 100644
--- a/net/bluetooth/6lowpan.c
+++ b/net/bluetooth/6lowpan.c
@@ -175,18 +175,6 @@ static inline struct lowpan_peer *peer_lookup_dst(struct lowpan_btle_dev *dev,

BT_DBG("peers %d addr %pI6c rt %p", count, daddr, rt);

- /* If we have multiple 6lowpan peers, then check where we should
- * send the packet. If only one peer exists, then we can send the
- * packet right away.
- */
- if (count == 1) {
- rcu_read_lock();
- peer = list_first_or_null_rcu(&dev->peers, struct lowpan_peer,
- list);
- rcu_read_unlock();
- return peer;
- }
-
if (!rt) {
if (ipv6_addr_any(&lowpan_cb(skb)->gw)) {
/* There is neither route nor gateway,
--
2.21.0


2019-03-12 19:19:42

by Ing. Josua Mayer

[permalink] [raw]
Subject: [PATCH v2 2/3] bluetooth: 6lowpan: check neighbour table for SLAAC

Like any IPv6 capable device, 6LNs can have multiple addresses assigned
using SLAAC and made known through neighbour advertisements.
After checking the destination address against all peers link-local
addresses, consult the neighbour cache for additional known addresses.

RFC7668 defines the scope of Neighbor Advertisements in Section 3.2.3:
1. "A Bluetooth LE 6LN MUST NOT register its link-local address"
2. "A Bluetooth LE 6LN MUST register its non-link-local addresses with
the 6LBR by sending Neighbor Solicitation (NS) messages ..."

Due to these constranits both the link-local addresses tracked in the
list of 6lowpan peers, and the neighbour cache have to be used when
identifying the 6lowpan peer for a destination address.

Acked-by: Jukka Rissanen <[email protected]>
Tested-by: Michael Scott <[email protected]>
Signed-off-by: Josua Mayer <[email protected]>
---
net/bluetooth/6lowpan.c | 15 +++++++++++++++
1 file changed, 15 insertions(+)

diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c
index 50530561da98..29a4f3d65348 100644
--- a/net/bluetooth/6lowpan.c
+++ b/net/bluetooth/6lowpan.c
@@ -171,6 +171,7 @@ static inline struct lowpan_peer *peer_lookup_dst(struct lowpan_btle_dev *dev,
struct in6_addr *nexthop;
struct rt6_info *rt = (struct rt6_info *)skb_dst(skb);
int count = atomic_read(&dev->peer_count);
+ struct neighbour *neigh;

BT_DBG("peers %d addr %pI6c rt %p", count, daddr, rt);

@@ -222,6 +223,20 @@ static inline struct lowpan_peer *peer_lookup_dst(struct lowpan_btle_dev *dev,
}
}

+ /* use the neighbour cache for matching addresses assigned by SLAAC
+ */
+ neigh = __ipv6_neigh_lookup(dev->netdev, nexthop);
+ if (neigh) {
+ list_for_each_entry_rcu(peer, &dev->peers, list) {
+ if (!memcmp(neigh->ha, peer->lladdr, ETH_ALEN)) {
+ neigh_release(neigh);
+ rcu_read_unlock();
+ return peer;
+ }
+ }
+ neigh_release(neigh);
+ }
+
rcu_read_unlock();

return NULL;
--
2.21.0


2019-03-12 19:19:45

by Ing. Josua Mayer

[permalink] [raw]
Subject: [PATCH v2 1/3] bluetooth: 6lowpan: search for destination address in all peers

Handle overlooked case where the target address is assigned to a peer
and neither route nor gateway exist.

For one peer, no checks are performed to see if it is meant to receive
packets for a given address.

As soon as there is a second peer however, checks are performed
to deal with routes and gateways for handling complex setups with
multiple hops to a target address.
This logic assumed that no route and no gateway imply that the
destination address can not be reached, which is false in case of a
direct peer.

Acked-by: Jukka Rissanen <[email protected]>
Tested-by: Michael Scott <[email protected]>
Signed-off-by: Josua Mayer <[email protected]>
---
net/bluetooth/6lowpan.c | 14 ++++++++++----
1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c
index a7cd23f00bde..50530561da98 100644
--- a/net/bluetooth/6lowpan.c
+++ b/net/bluetooth/6lowpan.c
@@ -187,10 +187,16 @@ static inline struct lowpan_peer *peer_lookup_dst(struct lowpan_btle_dev *dev,
}

if (!rt) {
- nexthop = &lowpan_cb(skb)->gw;
-
- if (ipv6_addr_any(nexthop))
- return NULL;
+ if (ipv6_addr_any(&lowpan_cb(skb)->gw)) {
+ /* There is neither route nor gateway,
+ * probably the destination is a direct peer.
+ */
+ nexthop = daddr;
+ } else {
+ /* There is a known gateway
+ */
+ nexthop = &lowpan_cb(skb)->gw;
+ }
} else {
nexthop = rt6_nexthop(rt, daddr);

--
2.21.0


2019-03-12 19:22:56

by Ing. Josua Mayer

[permalink] [raw]
Subject: [PATCH v2 0/3] bluetooth: 6lowpan: multiple peers and addresses

This patch set deals with an issue I reported earlier this year, where
1) packets addressed to a non-link-local address
2) any packets when at least 2 peers are connected
were not delivered if they matched a direct peer i.e. no routing.

The full explanation of the issue including steps to reproduce are:
https://www.spinics.net/lists/linux-bluetooth/msg78486.html

Changes since v1:
- changed comment style to c++

Josua Mayer (3):
bluetooth: 6lowpan: search for destination address in all peers
bluetooth: 6lowpan: check neighbour table for SLAAC
bluetooth: 6lowpan: always check destination address

net/bluetooth/6lowpan.c | 41 +++++++++++++++++++++++++----------------
1 file changed, 25 insertions(+), 16 deletions(-)

--
2.21.0


2019-03-30 15:52:05

by Ing. Josua Mayer

[permalink] [raw]
Subject: Re: [PATCH v2 0/3] bluetooth: 6lowpan: multiple peers and addresses

Has anyone had another chance to look at this? Just hoping it hasn't
ended up in a spam folder ...

Am 12.03.19 um 20:16 schrieb Josua Mayer:
> This patch set deals with an issue I reported earlier this year, where
> 1) packets addressed to a non-link-local address
> 2) any packets when at least 2 peers are connected
> were not delivered if they matched a direct peer i.e. no routing.
>
> The full explanation of the issue including steps to reproduce are:
> https://www.spinics.net/lists/linux-bluetooth/msg78486.html
>
> Changes since v1:
> - changed comment style to c++
>
> Josua Mayer (3):
> bluetooth: 6lowpan: search for destination address in all peers
> bluetooth: 6lowpan: check neighbour table for SLAAC
> bluetooth: 6lowpan: always check destination address
>
> net/bluetooth/6lowpan.c | 41 +++++++++++++++++++++++++----------------
> 1 file changed, 25 insertions(+), 16 deletions(-)
>

2019-05-13 10:30:42

by Ing. Josua Mayer

[permalink] [raw]
Subject: [PATCH RESEND v2 0/3] bluetooth: 6lowpan: multiple peers and addresses

This patch set deals with an issue I reported earlier this year, where
1) packets addressed to a non-link-local address
2) any packets when at least 2 peers are connected
were not delivered if they matched a direct peer i.e. no routing.

The full explanation of the issue including steps to reproduce are:
https://www.spinics.net/lists/linux-bluetooth/msg78486.html

Changes since v1:
- changed comment style to c++

Josua Mayer (3):
bluetooth: 6lowpan: search for destination address in all peers
bluetooth: 6lowpan: check neighbour table for SLAAC
bluetooth: 6lowpan: always check destination address

net/bluetooth/6lowpan.c | 41 +++++++++++++++++++++++++----------------
1 file changed, 25 insertions(+), 16 deletions(-)

--
2.21.0

2019-05-13 10:30:42

by Ing. Josua Mayer

[permalink] [raw]
Subject: [PATCH RESEND v2 3/3] bluetooth: 6lowpan: always check destination address

BLE based 6LoWPAN networks are highly constrained in bandwidth.
Do not take a short-cut, always check if the destination address is
known to belong to a peer.

As a side-effect this also removes any behavioral differences between
one, and two or more connected peers.

Acked-by: Jukka Rissanen <[email protected]>
Tested-by: Michael Scott <[email protected]>
Signed-off-by: Josua Mayer <[email protected]>
---
net/bluetooth/6lowpan.c | 12 ------------
1 file changed, 12 deletions(-)

diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c
index 29a4f3d65348..0f64e9ef1a3a 100644
--- a/net/bluetooth/6lowpan.c
+++ b/net/bluetooth/6lowpan.c
@@ -175,18 +175,6 @@ static inline struct lowpan_peer
*peer_lookup_dst(struct lowpan_btle_dev *dev,
BT_DBG("peers %d addr %pI6c rt %p", count, daddr, rt);
- /* If we have multiple 6lowpan peers, then check where we should
- * send the packet. If only one peer exists, then we can send the
- * packet right away.
- */
- if (count == 1) {
- rcu_read_lock();
- peer = list_first_or_null_rcu(&dev->peers, struct lowpan_peer,
- list);
- rcu_read_unlock();
- return peer;
- }
-
if (!rt) {
if (ipv6_addr_any(&lowpan_cb(skb)->gw)) {
/* There is neither route nor gateway,
--
2.21.0

2019-05-13 10:30:42

by Ing. Josua Mayer

[permalink] [raw]
Subject: [PATCH RESEND v2 2/3] bluetooth: 6lowpan: check neighbour table for SLAAC

Like any IPv6 capable device, 6LNs can have multiple addresses assigned
using SLAAC and made known through neighbour advertisements.
After checking the destination address against all peers link-local
addresses, consult the neighbour cache for additional known addresses.

RFC7668 defines the scope of Neighbor Advertisements in Section 3.2.3:
1. "A Bluetooth LE 6LN MUST NOT register its link-local address"
2. "A Bluetooth LE 6LN MUST register its non-link-local addresses with
the 6LBR by sending Neighbor Solicitation (NS) messages ..."

Due to these constranits both the link-local addresses tracked in the
list of 6lowpan peers, and the neighbour cache have to be used when
identifying the 6lowpan peer for a destination address.

Acked-by: Jukka Rissanen <[email protected]>
Tested-by: Michael Scott <[email protected]>
Signed-off-by: Josua Mayer <[email protected]>
---
net/bluetooth/6lowpan.c | 15 +++++++++++++++
1 file changed, 15 insertions(+)

diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c
index 50530561da98..29a4f3d65348 100644
--- a/net/bluetooth/6lowpan.c
+++ b/net/bluetooth/6lowpan.c
@@ -171,6 +171,7 @@ static inline struct lowpan_peer
*peer_lookup_dst(struct lowpan_btle_dev *dev,
struct in6_addr *nexthop;
struct rt6_info *rt = (struct rt6_info *)skb_dst(skb);
int count = atomic_read(&dev->peer_count);
+ struct neighbour *neigh;
BT_DBG("peers %d addr %pI6c rt %p", count, daddr, rt);
@@ -222,6 +223,20 @@ static inline struct lowpan_peer
*peer_lookup_dst(struct lowpan_btle_dev *dev,
}
}
+ /* use the neighbour cache for matching addresses assigned by SLAAC
+ */
+ neigh = __ipv6_neigh_lookup(dev->netdev, nexthop);
+ if (neigh) {
+ list_for_each_entry_rcu(peer, &dev->peers, list) {
+ if (!memcmp(neigh->ha, peer->lladdr, ETH_ALEN)) {
+ neigh_release(neigh);
+ rcu_read_unlock();
+ return peer;
+ }
+ }
+ neigh_release(neigh);
+ }
+
rcu_read_unlock();
return NULL;
--
2.21.0

2019-05-13 10:30:56

by Ing. Josua Mayer

[permalink] [raw]
Subject: [PATCH RESEND v2 1/3] bluetooth: 6lowpan: search for destination address in all peers

Handle overlooked case where the target address is assigned to a peer
and neither route nor gateway exist.

For one peer, no checks are performed to see if it is meant to receive
packets for a given address.

As soon as there is a second peer however, checks are performed
to deal with routes and gateways for handling complex setups with
multiple hops to a target address.
This logic assumed that no route and no gateway imply that the
destination address can not be reached, which is false in case of a
direct peer.

Acked-by: Jukka Rissanen <[email protected]>
Tested-by: Michael Scott <[email protected]>
Signed-off-by: Josua Mayer <[email protected]>
---
net/bluetooth/6lowpan.c | 14 ++++++++++----
1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c
index a7cd23f00bde..50530561da98 100644
--- a/net/bluetooth/6lowpan.c
+++ b/net/bluetooth/6lowpan.c
@@ -187,10 +187,16 @@ static inline struct lowpan_peer
*peer_lookup_dst(struct lowpan_btle_dev *dev,
}
if (!rt) {
- nexthop = &lowpan_cb(skb)->gw;
-
- if (ipv6_addr_any(nexthop))
- return NULL;
+ if (ipv6_addr_any(&lowpan_cb(skb)->gw)) {
+ /* There is neither route nor gateway,
+ * probably the destination is a direct peer.
+ */
+ nexthop = daddr;
+ } else {
+ /* There is a known gateway
+ */
+ nexthop = &lowpan_cb(skb)->gw;
+ }
} else {
nexthop = rt6_nexthop(rt, daddr);
-- 2.21.0

2019-07-06 11:11:51

by Marcel Holtmann

[permalink] [raw]
Subject: Re: [PATCH RESEND v2 0/3] bluetooth: 6lowpan: multiple peers and addresses

Hi Josua,

> This patch set deals with an issue I reported earlier this year, where
> 1) packets addressed to a non-link-local address
> 2) any packets when at least 2 peers are connected
> were not delivered if they matched a direct peer i.e. no routing.
>
> The full explanation of the issue including steps to reproduce are:
> https://www.spinics.net/lists/linux-bluetooth/msg78486.html
>
> Changes since v1:
> - changed comment style to c++
>
> Josua Mayer (3):
> bluetooth: 6lowpan: search for destination address in all peers
> bluetooth: 6lowpan: check neighbour table for SLAAC
> bluetooth: 6lowpan: always check destination address
>
> net/bluetooth/6lowpan.c | 41 +++++++++++++++++++++++++----------------
> 1 file changed, 25 insertions(+), 16 deletions(-)

the patches no longer apply cleanly to bluetooth-next. Can you please update them. Thanks.

Regards

Marcel