From patchwork Thu Feb 16 17:19:46 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Luiz Augusto von Dentz X-Patchwork-Id: 9577761 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 6849460244 for ; Thu, 16 Feb 2017 17:20:02 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 57A772040D for ; Thu, 16 Feb 2017 17:20:02 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 4A9C42862C; Thu, 16 Feb 2017 17:20:02 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.3 required=2.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_HI, RCVD_IN_SORBS_SPAM, T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id A95462040D for ; Thu, 16 Feb 2017 17:20:01 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932645AbdBPRUB (ORCPT ); Thu, 16 Feb 2017 12:20:01 -0500 Received: from mail-lf0-f68.google.com ([209.85.215.68]:35978 "EHLO mail-lf0-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932585AbdBPRT6 (ORCPT ); Thu, 16 Feb 2017 12:19:58 -0500 Received: by mail-lf0-f68.google.com with SMTP id h65so1975257lfi.3; Thu, 16 Feb 2017 09:19:57 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=FfYy9EV2+lrUptME6Bkh/VqDzldN+HphtIPcApwvhDE=; b=P9d5RAH2x/zBjRrrbyPJkEqEqjqkboX0b8IoVRkO9KvXHyBd1LR4fZm2b7xuQgjyIf aSWitvlq6BmSDLBolncVfIV3edzejdDmzS5Z4+HXFsFJvx5jKtjp8m0WUFtEfZ/DusE5 DrI4x2GIhUV4+CmDmFq8uRP+67O5BdrOasuuO4puIeEcn/+CyRXOmuejzQjOKg5gMao0 Zbq7pw4ATgyjDJxx3iJ+Lb4yNy/rotC+Kbz+w6QbFCV2JuKdyDh1Z8I8NCy0/rM3Ryr6 NqQmMzOp4DlsjrFmRRu3QjxpHjGL7oPXILTibcwV9gMHmCsbtsUwVpyzjekC9+ABqeeg TZEg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=FfYy9EV2+lrUptME6Bkh/VqDzldN+HphtIPcApwvhDE=; b=jDEgPpNllzbq/8nKKkl2JmbcMPxoYNEobgi8emf1yZ/s1eQI+rH+qBWDiDcPOCg9mC 2pKV7O+0cN6N0H9MV2xJ8LB+xzNqPPHumOHJI76frD65SoCuA3tdb7duTfEzOnItTs4u A/Hw/P3RKG/VpmlVqNfjpxkgkFndu2uRsKAnDpLwMdtJUUZqxZpvfs16Mbwd2qk7Qg/X VhJ2gt9ZdceaPVB4/A298fYva9avaHAbAd3UnL0J9lKC1yc0dVfHVzHYdTU2XTKrpnrw dof/Gb7X0TXtSzVMN2ZfGudf6BWdVQy35iSEZNNIAzbQ2YyLwx0yhr8NuNnuOaIs77aY eCwQ== X-Gm-Message-State: AMke39nEOKnuIbUFzPod4Sz0kM4DS2Nruwx4J71+tTBdR3F+xBDyjs6y1dVeYN90PIvrnA== X-Received: by 10.46.69.7 with SMTP id s7mr952956lja.44.1487265596789; Thu, 16 Feb 2017 09:19:56 -0800 (PST) Received: from vudentzs-t460s.pp.htv.fi (89-27-7-11.bb.dnainternet.fi. [89.27.7.11]) by smtp.gmail.com with ESMTPSA id 187sm1874292ljj.7.2017.02.16.09.19.55 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 16 Feb 2017 09:19:55 -0800 (PST) From: Luiz Augusto von Dentz To: linux-bluetooth@vger.kernel.org Cc: patrik.flykt@linux.intel.com, aar@pengutronix.de, linux-wpan@vger.kernel.org Subject: [PATCH v2 5/5] 6lowpan: Use netdev addr_len to determine lladdr len Date: Thu, 16 Feb 2017 19:19:46 +0200 Message-Id: <20170216171946.5105-6-luiz.dentz@gmail.com> X-Mailer: git-send-email 2.9.3 In-Reply-To: <20170216171946.5105-1-luiz.dentz@gmail.com> References: <20170216171946.5105-1-luiz.dentz@gmail.com> Sender: linux-wpan-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wpan@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Luiz Augusto von Dentz This allow technologies such as Bluetooth to use its native lladdr which is eui48 instead of eui64 which was expected by functions like lowpan_header_decompress and lowpan_header_compress. Signed-off-by: Luiz Augusto von Dentz --- include/net/6lowpan.h | 19 +++++++++++++++++++ net/6lowpan/iphc.c | 49 +++++++++++++++++++++++++++++++++++++------------ net/bluetooth/6lowpan.c | 43 ++++++++++--------------------------------- 3 files changed, 66 insertions(+), 45 deletions(-) diff --git a/include/net/6lowpan.h b/include/net/6lowpan.h index 5ab4c99..c5792cb 100644 --- a/include/net/6lowpan.h +++ b/include/net/6lowpan.h @@ -198,6 +198,25 @@ static inline void lowpan_iphc_uncompress_eui64_lladdr(struct in6_addr *ipaddr, ipaddr->s6_addr[8] ^= 0x02; } +static inline void lowpan_iphc_uncompress_eui48_lladdr(struct in6_addr *ipaddr, + const void *lladdr) +{ + /* fe:80::XXXX:XXff:feXX:XXXX + * \_________________/ + * hwaddr + */ + ipaddr->s6_addr[0] = 0xFE; + ipaddr->s6_addr[1] = 0x80; + memcpy(&ipaddr->s6_addr[8], lladdr, 3); + ipaddr->s6_addr[11] = 0xFF; + ipaddr->s6_addr[12] = 0xFE; + memcpy(&ipaddr->s6_addr[13], lladdr + 3, 3); + /* second bit-flip (Universe/Local) + * is done according RFC2464 + */ + ipaddr->s6_addr[8] ^= 0x02; +} + #ifdef DEBUG /* print data in line */ static inline void raw_dump_inline(const char *caller, char *msg, diff --git a/net/6lowpan/iphc.c b/net/6lowpan/iphc.c index fb5f6fa..ddbeeb7 100644 --- a/net/6lowpan/iphc.c +++ b/net/6lowpan/iphc.c @@ -278,6 +278,22 @@ lowpan_iphc_ctx_get_by_mcast_addr(const struct net_device *dev, return ret; } +static void lowpan_iphc_uncompress_lladdr(const struct net_device *dev, + struct in6_addr *ipaddr, + const void *lladdr) +{ + switch (dev->addr_len) { + case ETH_ALEN: + lowpan_iphc_uncompress_eui48_lladdr(ipaddr, lladdr); + break; + case EUI64_ADDR_LEN: + lowpan_iphc_uncompress_eui64_lladdr(ipaddr, lladdr); + break; + default: + WARN_ON_ONCE(1); + } +} + /* Uncompress address function for source and * destination address(non-multicast). * @@ -320,8 +336,7 @@ static int lowpan_iphc_uncompress_addr(struct sk_buff *skb, lowpan_iphc_uncompress_802154_lladdr(ipaddr, lladdr); break; default: - lowpan_iphc_uncompress_eui64_lladdr(ipaddr, lladdr); - break; + lowpan_iphc_uncompress_lladdr(dev, ipaddr, lladdr); } break; default: @@ -381,7 +396,7 @@ static int lowpan_iphc_uncompress_ctx_addr(struct sk_buff *skb, lowpan_iphc_uncompress_802154_lladdr(ipaddr, lladdr); break; default: - lowpan_iphc_uncompress_eui64_lladdr(ipaddr, lladdr); + lowpan_iphc_uncompress_lladdr(dev, ipaddr, lladdr); break; } ipv6_addr_prefix_copy(ipaddr, &ctx->pfx, ctx->plen); @@ -810,6 +825,21 @@ lowpan_iphc_compress_ctx_802154_lladdr(const struct in6_addr *ipaddr, return lladdr_compress; } +static bool lowpan_iphc_addr_equal(const struct net_device *dev, + const struct lowpan_iphc_ctx *ctx, + const struct in6_addr *ipaddr, + const void *lladdr) +{ + struct in6_addr tmp = {}; + + lowpan_iphc_uncompress_lladdr(dev, &tmp, lladdr); + + if (ctx) + ipv6_addr_prefix_copy(&tmp, &ctx->pfx, ctx->plen); + + return ipv6_addr_equal(&tmp, ipaddr); +} + static u8 lowpan_compress_ctx_addr(u8 **hc_ptr, const struct net_device *dev, const struct in6_addr *ipaddr, const struct lowpan_iphc_ctx *ctx, @@ -827,13 +857,7 @@ static u8 lowpan_compress_ctx_addr(u8 **hc_ptr, const struct net_device *dev, } break; default: - /* check for SAM/DAM = 11 */ - memcpy(&tmp.s6_addr[8], lladdr, EUI64_ADDR_LEN); - /* second bit-flip (Universe/Local) is done according RFC2464 */ - tmp.s6_addr[8] ^= 0x02; - /* context information are always used */ - ipv6_addr_prefix_copy(&tmp, &ctx->pfx, ctx->plen); - if (ipv6_addr_equal(&tmp, ipaddr)) { + if (lowpan_iphc_addr_equal(dev, ctx, ipaddr, lladdr)) { dam = LOWPAN_IPHC_DAM_11; goto out; } @@ -929,11 +953,12 @@ static u8 lowpan_compress_addr_64(u8 **hc_ptr, const struct net_device *dev, } break; default: - if (is_addr_mac_addr_based(ipaddr, lladdr)) { - dam = LOWPAN_IPHC_DAM_11; /* 0-bits */ + if (lowpan_iphc_addr_equal(dev, NULL, ipaddr, lladdr)) { + dam = LOWPAN_IPHC_DAM_11; pr_debug("address compression 0 bits\n"); goto out; } + break; } diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c index 1456b01..d2a1aa5 100644 --- a/net/bluetooth/6lowpan.c +++ b/net/bluetooth/6lowpan.c @@ -64,7 +64,7 @@ struct lowpan_peer { struct l2cap_chan *chan; /* peer addresses in various formats */ - unsigned char eui64_addr[EUI64_ADDR_LEN]; + unsigned char lladdr[ETH_ALEN]; struct in6_addr peer_addr; }; @@ -80,8 +80,6 @@ struct lowpan_btle_dev { struct delayed_work notify_peers; }; -static void set_addr(u8 *eui, u8 *addr, u8 addr_type); - static inline struct lowpan_btle_dev * lowpan_btle_dev(const struct net_device *netdev) { @@ -277,7 +275,6 @@ static int iphc_decompress(struct sk_buff *skb, struct net_device *netdev, const u8 *saddr; struct lowpan_btle_dev *dev; struct lowpan_peer *peer; - unsigned char eui64_daddr[EUI64_ADDR_LEN]; dev = lowpan_btle_dev(netdev); @@ -287,10 +284,9 @@ static int iphc_decompress(struct sk_buff *skb, struct net_device *netdev, if (!peer) return -EINVAL; - saddr = peer->eui64_addr; - set_addr(&eui64_daddr[0], chan->src.b, chan->src_type); + saddr = peer->lladdr; - return lowpan_header_decompress(skb, netdev, &eui64_daddr, saddr); + return lowpan_header_decompress(skb, netdev, netdev->dev_addr, saddr); } static int recv_pkt(struct sk_buff *skb, struct net_device *dev, @@ -477,7 +473,7 @@ static int setup_header(struct sk_buff *skb, struct net_device *netdev, } } - daddr = peer->eui64_addr; + daddr = peer->lladdr; *peer_addr = addr; *peer_addr_type = addr_type; lowpan_cb(skb)->chan = peer->chan; @@ -663,27 +659,6 @@ static struct device_type bt_type = { .name = "bluetooth", }; -static void set_addr(u8 *eui, u8 *addr, u8 addr_type) -{ - /* addr is the BT address in little-endian format */ - eui[0] = addr[5]; - eui[1] = addr[4]; - eui[2] = addr[3]; - eui[3] = 0xFF; - eui[4] = 0xFE; - eui[5] = addr[2]; - eui[6] = addr[1]; - eui[7] = addr[0]; - - /* Universal/local bit set, BT 6lowpan draft ch. 3.2.1 */ - if (addr_type == BDADDR_LE_PUBLIC) - eui[0] &= ~0x02; - else - eui[0] |= 0x02; - - BT_DBG("type %d addr %*phC", addr_type, 8, eui); -} - static void ifup(struct net_device *netdev) { int err; @@ -762,14 +737,16 @@ static struct l2cap_chan *add_peer_chan(struct l2cap_chan *chan, peer->chan = chan; memset(&peer->peer_addr, 0, sizeof(struct in6_addr)); + baswap((void *)peer->lladdr, &chan->dst); + /* RFC 2464 ch. 5 */ peer->peer_addr.s6_addr[0] = 0xFE; peer->peer_addr.s6_addr[1] = 0x80; - set_addr((u8 *)&peer->peer_addr.s6_addr + 8, chan->dst.b, - chan->dst_type); - memcpy(&peer->eui64_addr, (u8 *)&peer->peer_addr.s6_addr + 8, - EUI64_ADDR_LEN); + memcpy(&peer->peer_addr.s6_addr[8], peer->lladdr, 3); + peer->peer_addr.s6_addr[11] = 0xFF; + peer->peer_addr.s6_addr[12] = 0xFE; + memcpy(&peer->peer_addr.s6_addr[13], peer->lladdr + 3, 3); /* IPv6 address needs to have the U/L bit set properly so toggle * it back here.