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

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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@xxxxxxxxxxxxxxx>
Tested-by: Michael Scott <mike@xxxxxxxxxxxx>
Signed-off-by: Josua Mayer <josua.mayer@xxxxxx>
---
 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




[Index of Archives]     [Bluez Devel]     [Linux Wireless Networking]     [Linux Wireless Personal Area Networking]     [Linux ATH6KL]     [Linux USB Devel]     [Linux Media Drivers]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Big List of Linux Books]

  Powered by Linux