[prev in list] [next in list] [prev in thread] [next in thread]
List: linux-wpan
Subject: Re: [PATCH v2 5/5] 6lowpan: Use netdev addr_len to determine lladdr len
From: Luiz Augusto von Dentz <luiz.dentz () gmail ! com>
Date: 2017-02-17 9:32:21
Message-ID: CABBYNZ+dB1JR7mA3i6BzeSyHPrWPLXVKF+YBRGHGGzPwdW-_Zg () mail ! gmail ! com
[Download RAW message or body]
Hi Alex,
On Fri, Feb 17, 2017 at 9:40 AM, Alexander Aring <aar@pengutronix.de> wrote:
>
> Hi Luiz,
>
> iphc code looks fine and better as before so far I see. Thanks!
>
> On 02/16/2017 06:19 PM, Luiz Augusto von Dentz wrote:
>> From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
>>
>> 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 <luiz.von.dentz@intel.com>
>> ---
>> 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;
>
> why removing this 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);
>> }
>>
>
> This is something which I don't understand.
>
> protoype of this function:
>
> int lowpan_header_decompress(struct sk_buff *skb, const struct net_device *dev,
> const void *daddr, const void *saddr)
>
> your daddr pointer is "netdev->dev_addr", but this contains normally the L2 source
> address of your transceiver.
> You don't set the destination L2 address in your dev->dev_addr. (I hope)
>
> For me it looks like daddr == saddr, or should saddr be daddr, but then
> saddr (meaning here the saddr which should named daddr then, if it is daddr)
> should be as 3. parameter.
This is for decompressing a received packet and it actually don't
change the order of the parameters, the dev_addr is in fact the
chan->src byte swapped to be used as a MAC address if the interface,
there is nothing new in this regard. The only change that caused by
this is that we no longer convert the MAC into an IID.
>
>> 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);
>>
>
> You need to explain me why you add FFFE here again, why you need to
> generate an address here on ifup?
This is just maintaining the same logic as there was in set_addr since
we no longer have the address as 8 bytes it needed to introduce the
filler bytes, I can actually replace this with a call to
lowpan_iphc_uncompress_eui48_lladdr which does contain the exact same
code.
> Normally this should not be needed inside 6LoWPAN L2 implementation...
> but I suppose this is a next step to fixing BTLE 6LoWPAN.
It is perhaps not necessary to generate an IP address here, but I did
not want to add unrelated changes, this might actually come in a
following patch if we deem necessary.
--
Luiz Augusto von Dentz
--
To unsubscribe from this list: send the line "unsubscribe linux-wpan" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic