summaryrefslogtreecommitdiffstats
path: root/net/bluetooth
diff options
context:
space:
mode:
authorJosua Mayer <josua.mayer@jm0.eu>2019-07-06 11:54:47 -0400
committerMarcel Holtmann <marcel@holtmann.org>2019-07-06 15:33:55 -0400
commit5636376c26502c39260853e529e9467f79f95931 (patch)
tree3d2c1a58b55197596b8580fec3466015abb777b2 /net/bluetooth
parentb188b03270b7f8568fc714101ce82fbf5e811c5a (diff)
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 <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>
Diffstat (limited to 'net/bluetooth')
-rw-r--r--net/bluetooth/6lowpan.c15
1 files changed, 15 insertions, 0 deletions
diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c
index 9001bf331d56..f4e548e7b985 100644
--- a/net/bluetooth/6lowpan.c
+++ b/net/bluetooth/6lowpan.c
@@ -164,6 +164,7 @@ static inline struct lowpan_peer *peer_lookup_dst(struct lowpan_btle_dev *dev,
164 int count = atomic_read(&dev->peer_count); 164 int count = atomic_read(&dev->peer_count);
165 const struct in6_addr *nexthop; 165 const struct in6_addr *nexthop;
166 struct lowpan_peer *peer; 166 struct lowpan_peer *peer;
167 struct neighbour *neigh;
167 168
168 BT_DBG("peers %d addr %pI6c rt %p", count, daddr, rt); 169 BT_DBG("peers %d addr %pI6c rt %p", count, daddr, rt);
169 170
@@ -215,6 +216,20 @@ static inline struct lowpan_peer *peer_lookup_dst(struct lowpan_btle_dev *dev,
215 } 216 }
216 } 217 }
217 218
219 /* use the neighbour cache for matching addresses assigned by SLAAC
220 */
221 neigh = __ipv6_neigh_lookup(dev->netdev, nexthop);
222 if (neigh) {
223 list_for_each_entry_rcu(peer, &dev->peers, list) {
224 if (!memcmp(neigh->ha, peer->lladdr, ETH_ALEN)) {
225 neigh_release(neigh);
226 rcu_read_unlock();
227 return peer;
228 }
229 }
230 neigh_release(neigh);
231 }
232
218 rcu_read_unlock(); 233 rcu_read_unlock();
219 234
220 return NULL; 235 return NULL;