From: Josua Mayer <josua.mayer97@xxxxxxxxx> A peer may have multiple addresses, one being the link-local address based on its Bluetooth MAC address, and then some assigned dynamically from router advertisements, and published by neighbour advertisements. For direct peers neither routes nor gateways are known. Maybe the destination peer should be matched by the mac address from the table of ipv6 neighbours. As a quick hack, match only the last 64 bit of the address to ensure that addresses using SLAAC can be mapped to their corresponding peer. Clearly this hack is plain wrong. What is the proper method for finding the peer that advertised a given address? --- net/bluetooth/6lowpan.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c index f706b8a13fad..989e5685b3df 100644 --- a/net/bluetooth/6lowpan.c +++ b/net/bluetooth/6lowpan.c @@ -172,6 +172,17 @@ static inline struct lowpan_peer *peer_lookup_dst(struct lowpan_btle_dev *dev, struct rt6_info *rt = (struct rt6_info *)skb_dst(skb); int count = atomic_read(&dev->peer_count); + // match only host part of address + struct in6_addr hostmask; + hostmask.s6_addr16[0] = 0x0000; + hostmask.s6_addr16[1] = 0x0000; + hostmask.s6_addr16[2] = 0x0000; + hostmask.s6_addr16[3] = 0x0000; + hostmask.s6_addr16[4] = 0xFFFF; + hostmask.s6_addr16[5] = 0xFFFF; + hostmask.s6_addr16[6] = 0xFFFF; + hostmask.s6_addr16[7] = 0xFFFF; + BT_DBG("peers %d addr %pI6c rt %p", count, daddr, rt); /* If we have multiple 6lowpan peers, then check where we should @@ -216,7 +227,8 @@ static inline struct lowpan_peer *peer_lookup_dst(struct lowpan_btle_dev *dev, &peer->chan->dst, peer->chan->dst_type, &peer->peer_addr); - if (!ipv6_addr_cmp(&peer->peer_addr, nexthop)) { + if (!ipv6_masked_addr_cmp(&peer->peer_addr, &hostmask, nexthop)) { + BT_DBG("!ipv6_masked_addr_cmp(%pI6c, %pI6c, %pI6c)", &peer->peer_addr, &hostmask, nexthop); rcu_read_unlock(); return peer; } -- 2.20.1