Skip to content

Commit

Permalink
Bluetooth: 6lowpan: check neighbour table for SLAAC
Browse files Browse the repository at this point in the history
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 <jukka.rissanen@linux.intel.com>
Tested-by: Michael Scott <mike@foundries.io>
Signed-off-by: Josua Mayer <josua.mayer@jm0.eu>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
  • Loading branch information
Josua Mayer authored and Marcel Holtmann committed Jul 6, 2019
1 parent b188b03 commit 5636376
Showing 1 changed file with 15 additions and 0 deletions.
15 changes: 15 additions & 0 deletions net/bluetooth/6lowpan.c
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,7 @@ static inline struct lowpan_peer *peer_lookup_dst(struct lowpan_btle_dev *dev,
int count = atomic_read(&dev->peer_count);
const struct in6_addr *nexthop;
struct lowpan_peer *peer;
struct neighbour *neigh;

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

Expand Down Expand Up @@ -215,6 +216,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;
Expand Down

0 comments on commit 5636376

Please sign in to comment.