summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLuiz Augusto von Dentz <luiz.von.dentz@intel.com>2017-03-12 04:19:38 -0400
committerMarcel Holtmann <marcel@holtmann.org>2017-04-12 16:02:36 -0400
commit9dae2e030319811e9cdaa260faaa151cf0866186 (patch)
tree9aab9db1ff2b0d6501567905467b6d7fc90dadab
parentfa09ae661fb5ab6f9826545d5128f2b7393bcf4a (diff)
6lowpan: Fix IID format for Bluetooth
According to RFC 7668 U/L bit shall not be used: https://wiki.tools.ietf.org/html/rfc7668#section-3.2.2 [Page 10]: In the figure, letter 'b' represents a bit from the Bluetooth device address, copied as is without any changes on any bit. This means that no bit in the IID indicates whether the underlying Bluetooth device address is public or random. |0 1|1 3|3 4|4 6| |0 5|6 1|2 7|8 3| +----------------+----------------+----------------+----------------+ |bbbbbbbbbbbbbbbb|bbbbbbbb11111111|11111110bbbbbbbb|bbbbbbbbbbbbbbbb| +----------------+----------------+----------------+----------------+ Because of this the code cannot figure out the address type from the IP address anymore thus it makes no sense to use peer_lookup_ba as it needs the peer address type. Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> Reviewed-by: Stefan Schmidt <stefan@osg.samsung.com> Acked-by: Jukka Rissanen <jukka.rissanen@linux.intel.com> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
-rw-r--r--include/net/6lowpan.h4
-rw-r--r--net/bluetooth/6lowpan.c79
-rw-r--r--net/ipv6/addrconf.c6
3 files changed, 17 insertions, 72 deletions
diff --git a/include/net/6lowpan.h b/include/net/6lowpan.h
index c5792cb6c3eb..a71378007e61 100644
--- a/include/net/6lowpan.h
+++ b/include/net/6lowpan.h
@@ -211,10 +211,6 @@ static inline void lowpan_iphc_uncompress_eui48_lladdr(struct in6_addr *ipaddr,
211 ipaddr->s6_addr[11] = 0xFF; 211 ipaddr->s6_addr[11] = 0xFF;
212 ipaddr->s6_addr[12] = 0xFE; 212 ipaddr->s6_addr[12] = 0xFE;
213 memcpy(&ipaddr->s6_addr[13], lladdr + 3, 3); 213 memcpy(&ipaddr->s6_addr[13], lladdr + 3, 3);
214 /* second bit-flip (Universe/Local)
215 * is done according RFC2464
216 */
217 ipaddr->s6_addr[8] ^= 0x02;
218} 214}
219 215
220#ifdef DEBUG 216#ifdef DEBUG
diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c
index 54bf4d765a7d..24348c8579dd 100644
--- a/net/bluetooth/6lowpan.c
+++ b/net/bluetooth/6lowpan.c
@@ -398,37 +398,6 @@ static int chan_recv_cb(struct l2cap_chan *chan, struct sk_buff *skb)
398 return err; 398 return err;
399} 399}
400 400
401static u8 get_addr_type_from_eui64(u8 byte)
402{
403 /* Is universal(0) or local(1) bit */
404 return ((byte & 0x02) ? BDADDR_LE_RANDOM : BDADDR_LE_PUBLIC);
405}
406
407static void copy_to_bdaddr(struct in6_addr *ip6_daddr, bdaddr_t *addr)
408{
409 u8 *eui64 = ip6_daddr->s6_addr + 8;
410
411 addr->b[0] = eui64[7];
412 addr->b[1] = eui64[6];
413 addr->b[2] = eui64[5];
414 addr->b[3] = eui64[2];
415 addr->b[4] = eui64[1];
416 addr->b[5] = eui64[0];
417}
418
419static void convert_dest_bdaddr(struct in6_addr *ip6_daddr,
420 bdaddr_t *addr, u8 *addr_type)
421{
422 copy_to_bdaddr(ip6_daddr, addr);
423
424 /* We need to toggle the U/L bit that we got from IPv6 address
425 * so that we get the proper address and type of the BD address.
426 */
427 addr->b[5] ^= 0x02;
428
429 *addr_type = get_addr_type_from_eui64(addr->b[5]);
430}
431
432static int setup_header(struct sk_buff *skb, struct net_device *netdev, 401static int setup_header(struct sk_buff *skb, struct net_device *netdev,
433 bdaddr_t *peer_addr, u8 *peer_addr_type) 402 bdaddr_t *peer_addr, u8 *peer_addr_type)
434{ 403{
@@ -436,8 +405,7 @@ static int setup_header(struct sk_buff *skb, struct net_device *netdev,
436 struct ipv6hdr *hdr; 405 struct ipv6hdr *hdr;
437 struct lowpan_btle_dev *dev; 406 struct lowpan_btle_dev *dev;
438 struct lowpan_peer *peer; 407 struct lowpan_peer *peer;
439 bdaddr_t addr, *any = BDADDR_ANY; 408 u8 *daddr;
440 u8 *daddr = any->b;
441 int err, status = 0; 409 int err, status = 0;
442 410
443 hdr = ipv6_hdr(skb); 411 hdr = ipv6_hdr(skb);
@@ -448,34 +416,24 @@ static int setup_header(struct sk_buff *skb, struct net_device *netdev,
448 416
449 if (ipv6_addr_is_multicast(&ipv6_daddr)) { 417 if (ipv6_addr_is_multicast(&ipv6_daddr)) {
450 lowpan_cb(skb)->chan = NULL; 418 lowpan_cb(skb)->chan = NULL;
419 daddr = NULL;
451 } else { 420 } else {
452 u8 addr_type; 421 BT_DBG("dest IP %pI6c", &ipv6_daddr);
453 422
454 /* Get destination BT device from skb. 423 /* The packet might be sent to 6lowpan interface
455 * If there is no such peer then discard the packet. 424 * because of routing (either via default route
425 * or user set route) so get peer according to
426 * the destination address.
456 */ 427 */
457 convert_dest_bdaddr(&ipv6_daddr, &addr, &addr_type); 428 peer = peer_lookup_dst(dev, &ipv6_daddr, skb);
458
459 BT_DBG("dest addr %pMR type %d IP %pI6c", &addr,
460 addr_type, &ipv6_daddr);
461
462 peer = peer_lookup_ba(dev, &addr, addr_type);
463 if (!peer) { 429 if (!peer) {
464 /* The packet might be sent to 6lowpan interface 430 BT_DBG("no such peer");
465 * because of routing (either via default route 431 return -ENOENT;
466 * or user set route) so get peer according to
467 * the destination address.
468 */
469 peer = peer_lookup_dst(dev, &ipv6_daddr, skb);
470 if (!peer) {
471 BT_DBG("no such peer %pMR found", &addr);
472 return -ENOENT;
473 }
474 } 432 }
475 433
476 daddr = peer->lladdr; 434 daddr = peer->lladdr;
477 *peer_addr = addr; 435 peer_addr = &peer->chan->dst;
478 *peer_addr_type = addr_type; 436 *peer_addr_type = peer->chan->dst_type;
479 lowpan_cb(skb)->chan = peer->chan; 437 lowpan_cb(skb)->chan = peer->chan;
480 438
481 status = 1; 439 status = 1;
@@ -717,14 +675,6 @@ static struct l2cap_chan *chan_create(void)
717 return chan; 675 return chan;
718} 676}
719 677
720static void set_ip_addr_bits(u8 addr_type, u8 *addr)
721{
722 if (addr_type == BDADDR_LE_PUBLIC)
723 *addr |= 0x02;
724 else
725 *addr &= ~0x02;
726}
727
728static struct l2cap_chan *add_peer_chan(struct l2cap_chan *chan, 678static struct l2cap_chan *add_peer_chan(struct l2cap_chan *chan,
729 struct lowpan_btle_dev *dev) 679 struct lowpan_btle_dev *dev)
730{ 680{
@@ -741,11 +691,6 @@ static struct l2cap_chan *add_peer_chan(struct l2cap_chan *chan,
741 691
742 lowpan_iphc_uncompress_eui48_lladdr(&peer->peer_addr, peer->lladdr); 692 lowpan_iphc_uncompress_eui48_lladdr(&peer->peer_addr, peer->lladdr);
743 693
744 /* IPv6 address needs to have the U/L bit set properly so toggle
745 * it back here.
746 */
747 set_ip_addr_bits(chan->dst_type, (u8 *)&peer->peer_addr.s6_addr + 8);
748
749 spin_lock(&devices_lock); 694 spin_lock(&devices_lock);
750 INIT_LIST_HEAD(&peer->list); 695 INIT_LIST_HEAD(&peer->list);
751 peer_add(dev, peer); 696 peer_add(dev, peer);
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index b22796e707d3..3650f6e829e8 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -2077,7 +2077,11 @@ static int addrconf_ifid_6lowpan(u8 *eui, struct net_device *dev)
2077{ 2077{
2078 switch (dev->addr_len) { 2078 switch (dev->addr_len) {
2079 case ETH_ALEN: 2079 case ETH_ALEN:
2080 return addrconf_ifid_eui48(eui, dev); 2080 memcpy(eui, dev->dev_addr, 3);
2081 eui[3] = 0xFF;
2082 eui[4] = 0xFE;
2083 memcpy(eui + 5, dev->dev_addr + 3, 3);
2084 break;
2081 case EUI64_ADDR_LEN: 2085 case EUI64_ADDR_LEN:
2082 memcpy(eui, dev->dev_addr, EUI64_ADDR_LEN); 2086 memcpy(eui, dev->dev_addr, EUI64_ADDR_LEN);
2083 eui[0] ^= 2; 2087 eui[0] ^= 2;