2017-02-24 12:14:34

by Luiz Augusto von Dentz

[permalink] [raw]
Subject: [PATCH v5 0/6] Bluetooth: 6LoWPAN: Fix lladdr length

From: Luiz Augusto von Dentz <[email protected]>

These patches fixes lladdr length to be 6 bytes long and not 8 which cause
neighbor advertisement to be sent with wrong lladdr including FF:FE filler
bytes for eui64.

Note: This does not fix some of the existing crashes which I hope to address
in a different set.

v2: Make all code paths that generate a link-local from lladdr use the same
code.
v3: Use lowpan_iphc_uncompress_eui48_lladdr to generate the remote ip address.
v4: Handle comments from Stefan Schmidt.
v5: Add patch to fix IID format for Bluetooth

Alexander Aring (2):
6lowpan: iphc: override l2 packet information
ipv6: addrconf: fix 48 bit 6lowpan autoconfiguration

Luiz Augusto von Dentz (2):
6lowpan: Use netdev addr_len to determine lladdr len
6lowpan: Fix IID format for Bluetooth

Patrik Flykt (2):
bluetooth: Set 6 byte device addresses
6lowpan: Set MAC address length according to LOWPAN_LLTYPE

include/net/6lowpan.h | 15 ++++++
net/6lowpan/core.c | 11 +++-
net/6lowpan/iphc.c | 57 +++++++++++++++++----
net/bluetooth/6lowpan.c | 130 ++++++++----------------------------------------
net/ipv6/addrconf.c | 17 +++++--
5 files changed, 104 insertions(+), 126 deletions(-)

--
2.9.3


2017-02-28 09:13:28

by Jukka Rissanen

[permalink] [raw]
Subject: Re: [PATCH v5 6/6] 6lowpan: Fix IID format for Bluetooth

Hi Luiz,

On Fri, 2017-02-24 at 14:14 +0200, Luiz Augusto von Dentz wrote:
> From: Luiz Augusto von Dentz <[email protected]>
>
> Accourding 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|bbbbbbbbbbbbbb
> bb|
>    +----------------+----------------+----------------+------------
> ----+
>
> 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 <[email protected]>
> ---
>  include/net/6lowpan.h   |  4 ---
>

Looks good.

Acked-by: Jukka Rissanen <[email protected]>


Cheers,
Jukka

2017-02-27 07:24:33

by Alexander Aring

[permalink] [raw]
Subject: Re: [PATCH v5 5/6] 6lowpan: Use netdev addr_len to determine lladdr len

H

On 02/27/2017 08:13 AM, Alexander Aring wrote:
> Hi,
>
> On 02/24/2017 01:14 PM, Luiz Augusto von Dentz wrote:
>> From: Luiz Augusto von Dentz <[email protected]>
>>
>> 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 <[email protected]>
>> Reviewed-by: Stefan Schmidt <[email protected]>
>> ---
>> include/net/6lowpan.h | 19 +++++++++++++++++++
>> net/6lowpan/iphc.c | 49 ++++++++++++++++++++++++++++++++++++++-----------
>> net/bluetooth/6lowpan.c | 42 ++++++------------------------------------
>> 3 files changed, 63 insertions(+), 47 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;
>> +}
>> +
>
> same thing here. I think you don't need u/l bitflip here, you argumented
> already that IID is without it in another patch, or?
>

ahhh, got it. You just moved the function into the header and patch 6/6
will remove the u/l handling. Sorry!

But then still patch 4/6 is wrong because it use u/l bitflip there.
(It's my patch yes :D, but I realized at first dev->addr_len should be 6
and not 8).

- Alex

2017-02-27 07:13:44

by Alexander Aring

[permalink] [raw]
Subject: Re: [PATCH v5 5/6] 6lowpan: Use netdev addr_len to determine lladdr len

Hi,

On 02/24/2017 01:14 PM, Luiz Augusto von Dentz wrote:
> From: Luiz Augusto von Dentz <[email protected]>
>
> 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 <[email protected]>
> Reviewed-by: Stefan Schmidt <[email protected]>
> ---
> include/net/6lowpan.h | 19 +++++++++++++++++++
> net/6lowpan/iphc.c | 49 ++++++++++++++++++++++++++++++++++++++-----------
> net/bluetooth/6lowpan.c | 42 ++++++------------------------------------
> 3 files changed, 63 insertions(+), 47 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;
> +}
> +

same thing here. I think you don't need u/l bitflip here, you argumented
already that IID is without it in another patch, or?

btw: making static inline function -> then remove link-local setting
here before. Then we can use this function for ipv6/sateful/stateless
IPHC compression/decompression to generate IID.
And better with a function before that evaluates lltype (or dev->addr_len,
see below why not).

another thing is:
__ipv6_addr_set_half(&addr.s6_addr32[0], htonl(0xFE800000), 0);

should be used here, but this need to be cleanuped everywhere in 6lowpan
code. :-)

---

What I mean such function placed in 6lowpan header should only set the
IID according a ipaddr.
Such function can also be used then in IPv6 IID generation.

And DON'T make such handling depending on address size, this is in my
opinion wrong. Because the link-layer 6lowpan adaption RFC describes how
to generate the IID and not depending on a address size.
Means another link-layer e.g. has eui48 but will set a u/l bitflip here.
You should use the lltype of 6lowpan netdev private area for that.

This means also the name "eui48" in the function is also semantic wrong,
at my point of view.
(Okay, I don't care about function names right now).

Anyway, I agree that doesn't matter currently because we have only two
adaptions right now.
... and yes, I know (already more about ~one year) BTLE 6LoWPAN is
broken (races/rfc stuff) and I am happy that somebody fix that now.
So I would also ack patches which makes it depending on dev->addr_len.
Otherwise broken things will never be fixed...

- Alex


2017-02-26 06:38:38

by Alexander Aring

[permalink] [raw]
Subject: Re: [PATCH v5 4/6] ipv6: addrconf: fix 48 bit 6lowpan autoconfiguration


Hi,

okay now I am finally confused.

On 02/24/2017 01:14 PM, Luiz Augusto von Dentz wrote:
> From: Alexander Aring <[email protected]>
>
> This patch adds support for 48 bit 6LoWPAN address length
> autoconfiguration which is the case for BTLE 6LoWPAN.
>
> Signed-off-by: Alexander Aring <[email protected]>
> Signed-off-by: Luiz Augusto von Dentz <[email protected]>
> Reviewed-by: Stefan Schmidt <[email protected]>
> ---
> net/ipv6/addrconf.c | 17 ++++++++++++-----
> 1 file changed, 12 insertions(+), 5 deletions(-)
>
> diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
> index 3a2025f..7756640 100644
> --- a/net/ipv6/addrconf.c
> +++ b/net/ipv6/addrconf.c
> @@ -2052,12 +2052,19 @@ static void addrconf_leave_anycast(struct inet6_ifaddr *ifp)
> __ipv6_dev_ac_dec(ifp->idev, &addr);
> }
>
> -static int addrconf_ifid_eui64(u8 *eui, struct net_device *dev)
> +static int addrconf_ifid_6lowpan(u8 *eui, struct net_device *dev)
> {
> - if (dev->addr_len != EUI64_ADDR_LEN)
> + switch (dev->addr_len) {
> + case ETH_ALEN:
> + return addrconf_ifid_eui48(eui, dev);

You need to make the same thing here like what we discusss in antoher
mail.

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|
+----------------+----------------+----------------+----------------+

The function addrconf_ifid_eui48 will do a u/l bitflip. You need to change
that otherwise transparent 6lowpan adaptiation will not match on your
local address.

Making u/l bit here, but not in IPHC code -> will not work together.

---

btw: That's why I think we should provide some function _once_ to
generate the IID for iphc code and ipv6. Then such mistakes will not
happen.

So we don't want to have some module dependency of 6lowpan in ipv6.
My first idea is to make a callback in 6lowpan private data of
netdevice. :-/

- Alex

2017-02-26 06:25:03

by Alexander Aring

[permalink] [raw]
Subject: Re: [PATCH v5 6/6] 6lowpan: Fix IID format for Bluetooth


Hi,

On 02/26/2017 07:05 AM, Alexander Aring wrote:
>
> Hi,
>
> On 02/24/2017 01:14 PM, Luiz Augusto von Dentz wrote:
>> From: Luiz Augusto von Dentz <[email protected]>
>>
>> Accourding 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.
>>
>
> I am still not quite 100% of this and want to leave my opinion about this
> handling which can be interpreted in a different way.
>
> The RFC says here:
>
> Following the guidance of [RFC7136], a 64-bit
> Interface Identifier (IID) is formed from the 48-bit Bluetooth device
> address by inserting two octets, with hexadecimal values of 0xFF and
> 0xFE in the middle of the 48-bit Bluetooth device address as shown in
> Figure 6.

Okay, they said from IID from the 48-bit address.

And IID is what you need here and what [RFC7136] describes as result,
so I think you are right.

There is no need for special u/l bitflip or link-layer multicast handling.

- Alex

2017-02-26 06:05:39

by Alexander Aring

[permalink] [raw]
Subject: Re: [PATCH v5 6/6] 6lowpan: Fix IID format for Bluetooth


Hi,

On 02/24/2017 01:14 PM, Luiz Augusto von Dentz wrote:
> From: Luiz Augusto von Dentz <[email protected]>
>
> Accourding 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.
>

I am still not quite 100% of this and want to leave my opinion about this
handling which can be interpreted in a different way.

The RFC says here:

Following the guidance of [RFC7136], a 64-bit
Interface Identifier (IID) is formed from the 48-bit Bluetooth device
address by inserting two octets, with hexadecimal values of 0xFF and
0xFE in the middle of the 48-bit Bluetooth device address as shown in
Figure 6. In the figure, letter 'b' represents a bit from the
Bluetooth device address, copied as is without any changes on any
bit.

You cut the important part "Following the guidance of [RFC7136]".

---

What you describe is "How to see the link layer address from L3 layer"
and then it clearly said "there is no bit which indicate something
special that the address is public/random, whatever".

---

At my point of you the RFC tells here: grab the L2 layer in the way how
you quote above, but then apply [RFC7136] which is L3 handling.

I simple cc now some 6lo ietf stuff and others 6lowpan hackers, maybe we
have luck and somebody can answer this question.

---

And when we already about to start a discussion about that, what is do
to with the multicast bit of L2 address? I know you told it's not an
EUI-48 address. Are you sure?

If it's really EUI-48 then I think [RFC7136] should be applied.

- Alex

2017-02-24 14:00:12

by Stefan Schmidt

[permalink] [raw]
Subject: Re: [PATCH v5 6/6] 6lowpan: Fix IID format for Bluetooth

Hello.

On 02/24/2017 01:14 PM, Luiz Augusto von Dentz wrote:
> From: Luiz Augusto von Dentz <[email protected]>
>
> Accourding 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 <[email protected]>
> ---
> include/net/6lowpan.h | 4 ---
> net/bluetooth/6lowpan.c | 79 ++++++++-----------------------------------------
> 2 files changed, 12 insertions(+), 71 deletions(-)
>
> diff --git a/include/net/6lowpan.h b/include/net/6lowpan.h
> index c5792cb..a713780 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,
> 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
> diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c
> index 0b68cfc..ec89c55 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)
> return err;
> }
>
> -static u8 get_addr_type_from_eui64(u8 byte)
> -{
> - /* Is universal(0) or local(1) bit */
> - return ((byte & 0x02) ? BDADDR_LE_RANDOM : BDADDR_LE_PUBLIC);
> -}
> -
> -static void copy_to_bdaddr(struct in6_addr *ip6_daddr, bdaddr_t *addr)
> -{
> - u8 *eui64 = ip6_daddr->s6_addr + 8;
> -
> - addr->b[0] = eui64[7];
> - addr->b[1] = eui64[6];
> - addr->b[2] = eui64[5];
> - addr->b[3] = eui64[2];
> - addr->b[4] = eui64[1];
> - addr->b[5] = eui64[0];
> -}
> -
> -static void convert_dest_bdaddr(struct in6_addr *ip6_daddr,
> - bdaddr_t *addr, u8 *addr_type)
> -{
> - copy_to_bdaddr(ip6_daddr, addr);
> -
> - /* We need to toggle the U/L bit that we got from IPv6 address
> - * so that we get the proper address and type of the BD address.
> - */
> - addr->b[5] ^= 0x02;
> -
> - *addr_type = get_addr_type_from_eui64(addr->b[5]);
> -}
> -
> static int setup_header(struct sk_buff *skb, struct net_device *netdev,
> bdaddr_t *peer_addr, u8 *peer_addr_type)
> {
> @@ -436,8 +405,7 @@ static int setup_header(struct sk_buff *skb, struct net_device *netdev,
> struct ipv6hdr *hdr;
> struct lowpan_btle_dev *dev;
> struct lowpan_peer *peer;
> - bdaddr_t addr, *any = BDADDR_ANY;
> - u8 *daddr = any->b;
> + u8 *daddr;
> int err, status = 0;
>
> hdr = ipv6_hdr(skb);
> @@ -448,34 +416,24 @@ static int setup_header(struct sk_buff *skb, struct net_device *netdev,
>
> if (ipv6_addr_is_multicast(&ipv6_daddr)) {
> lowpan_cb(skb)->chan = NULL;
> + daddr = NULL;
> } else {
> - u8 addr_type;
> + BT_DBG("dest IP %pI6c", &ipv6_daddr);
>
> - /* Get destination BT device from skb.
> - * If there is no such peer then discard the packet.
> + /* The packet might be sent to 6lowpan interface
> + * because of routing (either via default route
> + * or user set route) so get peer according to
> + * the destination address.
> */
> - convert_dest_bdaddr(&ipv6_daddr, &addr, &addr_type);
> -
> - BT_DBG("dest addr %pMR type %d IP %pI6c", &addr,
> - addr_type, &ipv6_daddr);
> -
> - peer = peer_lookup_ba(dev, &addr, addr_type);
> + peer = peer_lookup_dst(dev, &ipv6_daddr, skb);
> if (!peer) {
> - /* The packet might be sent to 6lowpan interface
> - * because of routing (either via default route
> - * or user set route) so get peer according to
> - * the destination address.
> - */
> - peer = peer_lookup_dst(dev, &ipv6_daddr, skb);
> - if (!peer) {
> - BT_DBG("no such peer %pMR found", &addr);
> - return -ENOENT;
> - }
> + BT_DBG("no such peer");
> + return -ENOENT;
> }
>
> daddr = peer->lladdr;
> - *peer_addr = addr;
> - *peer_addr_type = addr_type;
> + peer_addr = &peer->chan->dst;
> + *peer_addr_type = peer->chan->dst_type;
> lowpan_cb(skb)->chan = peer->chan;
>
> status = 1;
> @@ -717,14 +675,6 @@ static struct l2cap_chan *chan_create(void)
> return chan;
> }
>
> -static void set_ip_addr_bits(u8 addr_type, u8 *addr)
> -{
> - if (addr_type == BDADDR_LE_PUBLIC)
> - *addr |= 0x02;
> - else
> - *addr &= ~0x02;
> -}
> -
> static struct l2cap_chan *add_peer_chan(struct l2cap_chan *chan,
> struct lowpan_btle_dev *dev)
> {
> @@ -741,11 +691,6 @@ static struct l2cap_chan *add_peer_chan(struct l2cap_chan *chan,
>
> lowpan_iphc_uncompress_eui48_lladdr(&peer->peer_addr, peer->lladdr);
>
> - /* IPv6 address needs to have the U/L bit set properly so toggle
> - * it back here.
> - */
> - set_ip_addr_bits(chan->dst_type, (u8 *)&peer->peer_addr.s6_addr + 8);
> -
> spin_lock(&devices_lock);
> INIT_LIST_HEAD(&peer->list);
> peer_add(dev, peer);
>

Reviewed-by: Stefan Schmidt <[email protected]>

regards
Stefan Schmidt

2017-02-24 12:14:35

by Luiz Augusto von Dentz

[permalink] [raw]
Subject: [PATCH v5 1/6] bluetooth: Set 6 byte device addresses

From: Patrik Flykt <[email protected]>

Set BTLE MAC addresses that are 6 bytes long and not 8 bytes
that are used in other places with 6lowpan.

Signed-off-by: Patrik Flykt <[email protected]>
Signed-off-by: Luiz Augusto von Dentz <[email protected]>
Reviewed-by: Stefan Schmidt <[email protected]>
---
net/bluetooth/6lowpan.c | 19 ++++++++-----------
1 file changed, 8 insertions(+), 11 deletions(-)

diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c
index 1904a93..1456b01 100644
--- a/net/bluetooth/6lowpan.c
+++ b/net/bluetooth/6lowpan.c
@@ -80,6 +80,8 @@ 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)
{
@@ -272,9 +274,10 @@ static int give_skb_to_upper(struct sk_buff *skb, struct net_device *dev)
static int iphc_decompress(struct sk_buff *skb, struct net_device *netdev,
struct l2cap_chan *chan)
{
- const u8 *saddr, *daddr;
+ const u8 *saddr;
struct lowpan_btle_dev *dev;
struct lowpan_peer *peer;
+ unsigned char eui64_daddr[EUI64_ADDR_LEN];

dev = lowpan_btle_dev(netdev);

@@ -285,9 +288,9 @@ static int iphc_decompress(struct sk_buff *skb, struct net_device *netdev,
return -EINVAL;

saddr = peer->eui64_addr;
- daddr = dev->netdev->dev_addr;
+ set_addr(&eui64_daddr[0], chan->src.b, chan->src_type);

- return lowpan_header_decompress(skb, netdev, daddr, saddr);
+ return lowpan_header_decompress(skb, netdev, &eui64_daddr, saddr);
}

static int recv_pkt(struct sk_buff *skb, struct net_device *dev,
@@ -681,13 +684,6 @@ static void set_addr(u8 *eui, u8 *addr, u8 addr_type)
BT_DBG("type %d addr %*phC", addr_type, 8, eui);
}

-static void set_dev_addr(struct net_device *netdev, bdaddr_t *addr,
- u8 addr_type)
-{
- netdev->addr_assign_type = NET_ADDR_PERM;
- set_addr(netdev->dev_addr, addr->b, addr_type);
-}
-
static void ifup(struct net_device *netdev)
{
int err;
@@ -803,7 +799,8 @@ static int setup_netdev(struct l2cap_chan *chan, struct lowpan_btle_dev **dev)
if (!netdev)
return -ENOMEM;

- set_dev_addr(netdev, &chan->src, chan->src_type);
+ netdev->addr_assign_type = NET_ADDR_PERM;
+ baswap((void *)netdev->dev_addr, &chan->src);

netdev->netdev_ops = &netdev_ops;
SET_NETDEV_DEV(netdev, &chan->conn->hcon->hdev->dev);
--
2.9.3

2017-02-24 12:14:37

by Luiz Augusto von Dentz

[permalink] [raw]
Subject: [PATCH v5 3/6] 6lowpan: iphc: override l2 packet information

From: Alexander Aring <[email protected]>

The skb->pkt_type need to be set by L2, but on 6LoWPAN there exists L2
e.g. BTLE which doesn't has multicast addressing. If it's a multicast or
not is detected by IPHC headers multicast bit. The IPv6 layer will
evaluate this pkt_type, so we force set this type while uncompressing.
Should be okay for 802.15.4 as well.

Signed-off-by: Alexander Aring <[email protected]>
Reviewed-by: Stefan Schmidt <[email protected]>
---
net/6lowpan/iphc.c | 8 ++++++++
1 file changed, 8 insertions(+)

diff --git a/net/6lowpan/iphc.c b/net/6lowpan/iphc.c
index 79f1fa2..fb5f6fa 100644
--- a/net/6lowpan/iphc.c
+++ b/net/6lowpan/iphc.c
@@ -666,6 +666,8 @@ int lowpan_header_decompress(struct sk_buff *skb, const struct net_device *dev,

switch (iphc1 & (LOWPAN_IPHC_M | LOWPAN_IPHC_DAC)) {
case LOWPAN_IPHC_M | LOWPAN_IPHC_DAC:
+ skb->pkt_type = PACKET_BROADCAST;
+
spin_lock_bh(&lowpan_dev(dev)->ctx.lock);
ci = lowpan_iphc_ctx_get_by_id(dev, LOWPAN_IPHC_CID_DCI(cid));
if (!ci) {
@@ -681,11 +683,15 @@ int lowpan_header_decompress(struct sk_buff *skb, const struct net_device *dev,
spin_unlock_bh(&lowpan_dev(dev)->ctx.lock);
break;
case LOWPAN_IPHC_M:
+ skb->pkt_type = PACKET_BROADCAST;
+
/* multicast */
err = lowpan_uncompress_multicast_daddr(skb, &hdr.daddr,
iphc1 & LOWPAN_IPHC_DAM_MASK);
break;
case LOWPAN_IPHC_DAC:
+ skb->pkt_type = PACKET_HOST;
+
spin_lock_bh(&lowpan_dev(dev)->ctx.lock);
ci = lowpan_iphc_ctx_get_by_id(dev, LOWPAN_IPHC_CID_DCI(cid));
if (!ci) {
@@ -701,6 +707,8 @@ int lowpan_header_decompress(struct sk_buff *skb, const struct net_device *dev,
spin_unlock_bh(&lowpan_dev(dev)->ctx.lock);
break;
default:
+ skb->pkt_type = PACKET_HOST;
+
err = lowpan_iphc_uncompress_addr(skb, dev, &hdr.daddr,
iphc1 & LOWPAN_IPHC_DAM_MASK,
daddr);
--
2.9.3

2017-02-24 12:14:38

by Luiz Augusto von Dentz

[permalink] [raw]
Subject: [PATCH v5 4/6] ipv6: addrconf: fix 48 bit 6lowpan autoconfiguration

From: Alexander Aring <[email protected]>

This patch adds support for 48 bit 6LoWPAN address length
autoconfiguration which is the case for BTLE 6LoWPAN.

Signed-off-by: Alexander Aring <[email protected]>
Signed-off-by: Luiz Augusto von Dentz <[email protected]>
Reviewed-by: Stefan Schmidt <[email protected]>
---
net/ipv6/addrconf.c | 17 ++++++++++++-----
1 file changed, 12 insertions(+), 5 deletions(-)

diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 3a2025f..7756640 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -2052,12 +2052,19 @@ static void addrconf_leave_anycast(struct inet6_ifaddr *ifp)
__ipv6_dev_ac_dec(ifp->idev, &addr);
}

-static int addrconf_ifid_eui64(u8 *eui, struct net_device *dev)
+static int addrconf_ifid_6lowpan(u8 *eui, struct net_device *dev)
{
- if (dev->addr_len != EUI64_ADDR_LEN)
+ switch (dev->addr_len) {
+ case ETH_ALEN:
+ return addrconf_ifid_eui48(eui, dev);
+ case EUI64_ADDR_LEN:
+ memcpy(eui, dev->dev_addr, EUI64_ADDR_LEN);
+ eui[0] ^= 2;
+ break;
+ default:
return -1;
- memcpy(eui, dev->dev_addr, EUI64_ADDR_LEN);
- eui[0] ^= 2;
+ }
+
return 0;
}

@@ -2149,7 +2156,7 @@ static int ipv6_generate_eui64(u8 *eui, struct net_device *dev)
case ARPHRD_TUNNEL:
return addrconf_ifid_gre(eui, dev);
case ARPHRD_6LOWPAN:
- return addrconf_ifid_eui64(eui, dev);
+ return addrconf_ifid_6lowpan(eui, dev);
case ARPHRD_IEEE1394:
return addrconf_ifid_ieee1394(eui, dev);
case ARPHRD_TUNNEL6:
--
2.9.3


2017-02-24 12:14:36

by Luiz Augusto von Dentz

[permalink] [raw]
Subject: [PATCH v5 2/6] 6lowpan: Set MAC address length according to LOWPAN_LLTYPE

From: Patrik Flykt <[email protected]>

Set MAC address length according to the 6LoWPAN link layer in use.
Bluetooth Low Energy uses 48 bit addressing while IEEE802.15.4 uses
64 bits.

Signed-off-by: Patrik Flykt <[email protected]>
Reviewed-by: Stefan Schmidt <[email protected]>
---
net/6lowpan/core.c | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/net/6lowpan/core.c b/net/6lowpan/core.c
index 5945f7e..5f9909a 100644
--- a/net/6lowpan/core.c
+++ b/net/6lowpan/core.c
@@ -23,7 +23,16 @@ int lowpan_register_netdevice(struct net_device *dev,
{
int i, ret;

- dev->addr_len = EUI64_ADDR_LEN;
+ switch (lltype) {
+ case LOWPAN_LLTYPE_IEEE802154:
+ dev->addr_len = EUI64_ADDR_LEN;
+ break;
+
+ case LOWPAN_LLTYPE_BTLE:
+ dev->addr_len = ETH_ALEN;
+ break;
+ }
+
dev->type = ARPHRD_6LOWPAN;
dev->mtu = IPV6_MIN_MTU;
dev->priv_flags |= IFF_NO_QUEUE;
--
2.9.3

2017-02-24 12:14:39

by Luiz Augusto von Dentz

[permalink] [raw]
Subject: [PATCH v5 5/6] 6lowpan: Use netdev addr_len to determine lladdr len

From: Luiz Augusto von Dentz <[email protected]>

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 <[email protected]>
Reviewed-by: Stefan Schmidt <[email protected]>
---
include/net/6lowpan.h | 19 +++++++++++++++++++
net/6lowpan/iphc.c | 49 ++++++++++++++++++++++++++++++++++++++-----------
net/bluetooth/6lowpan.c | 42 ++++++------------------------------------
3 files changed, 63 insertions(+), 47 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..6b1042e 100644
--- a/net/6lowpan/iphc.c
+++ b/net/6lowpan/iphc.c
@@ -278,6 +278,23 @@ 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);
+ break;
+ }
+}
+
/* Uncompress address function for source and
* destination address(non-multicast).
*
@@ -320,7 +337,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);
+ lowpan_iphc_uncompress_lladdr(dev, ipaddr, lladdr);
break;
}
break;
@@ -381,7 +398,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 +827,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 +859,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 +955,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..0b68cfc 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,9 @@ static struct l2cap_chan *add_peer_chan(struct l2cap_chan *chan,
peer->chan = chan;
memset(&peer->peer_addr, 0, sizeof(struct in6_addr));

- /* 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);
+ baswap((void *)peer->lladdr, &chan->dst);

- memcpy(&peer->eui64_addr, (u8 *)&peer->peer_addr.s6_addr + 8,
- EUI64_ADDR_LEN);
+ lowpan_iphc_uncompress_eui48_lladdr(&peer->peer_addr, peer->lladdr);

/* IPv6 address needs to have the U/L bit set properly so toggle
* it back here.
--
2.9.3

2017-02-24 12:14:40

by Luiz Augusto von Dentz

[permalink] [raw]
Subject: [PATCH v5 6/6] 6lowpan: Fix IID format for Bluetooth

From: Luiz Augusto von Dentz <[email protected]>

Accourding 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 <[email protected]>
---
include/net/6lowpan.h | 4 ---
net/bluetooth/6lowpan.c | 79 ++++++++-----------------------------------------
2 files changed, 12 insertions(+), 71 deletions(-)

diff --git a/include/net/6lowpan.h b/include/net/6lowpan.h
index c5792cb..a713780 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,
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
diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c
index 0b68cfc..ec89c55 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)
return err;
}

-static u8 get_addr_type_from_eui64(u8 byte)
-{
- /* Is universal(0) or local(1) bit */
- return ((byte & 0x02) ? BDADDR_LE_RANDOM : BDADDR_LE_PUBLIC);
-}
-
-static void copy_to_bdaddr(struct in6_addr *ip6_daddr, bdaddr_t *addr)
-{
- u8 *eui64 = ip6_daddr->s6_addr + 8;
-
- addr->b[0] = eui64[7];
- addr->b[1] = eui64[6];
- addr->b[2] = eui64[5];
- addr->b[3] = eui64[2];
- addr->b[4] = eui64[1];
- addr->b[5] = eui64[0];
-}
-
-static void convert_dest_bdaddr(struct in6_addr *ip6_daddr,
- bdaddr_t *addr, u8 *addr_type)
-{
- copy_to_bdaddr(ip6_daddr, addr);
-
- /* We need to toggle the U/L bit that we got from IPv6 address
- * so that we get the proper address and type of the BD address.
- */
- addr->b[5] ^= 0x02;
-
- *addr_type = get_addr_type_from_eui64(addr->b[5]);
-}
-
static int setup_header(struct sk_buff *skb, struct net_device *netdev,
bdaddr_t *peer_addr, u8 *peer_addr_type)
{
@@ -436,8 +405,7 @@ static int setup_header(struct sk_buff *skb, struct net_device *netdev,
struct ipv6hdr *hdr;
struct lowpan_btle_dev *dev;
struct lowpan_peer *peer;
- bdaddr_t addr, *any = BDADDR_ANY;
- u8 *daddr = any->b;
+ u8 *daddr;
int err, status = 0;

hdr = ipv6_hdr(skb);
@@ -448,34 +416,24 @@ static int setup_header(struct sk_buff *skb, struct net_device *netdev,

if (ipv6_addr_is_multicast(&ipv6_daddr)) {
lowpan_cb(skb)->chan = NULL;
+ daddr = NULL;
} else {
- u8 addr_type;
+ BT_DBG("dest IP %pI6c", &ipv6_daddr);

- /* Get destination BT device from skb.
- * If there is no such peer then discard the packet.
+ /* The packet might be sent to 6lowpan interface
+ * because of routing (either via default route
+ * or user set route) so get peer according to
+ * the destination address.
*/
- convert_dest_bdaddr(&ipv6_daddr, &addr, &addr_type);
-
- BT_DBG("dest addr %pMR type %d IP %pI6c", &addr,
- addr_type, &ipv6_daddr);
-
- peer = peer_lookup_ba(dev, &addr, addr_type);
+ peer = peer_lookup_dst(dev, &ipv6_daddr, skb);
if (!peer) {
- /* The packet might be sent to 6lowpan interface
- * because of routing (either via default route
- * or user set route) so get peer according to
- * the destination address.
- */
- peer = peer_lookup_dst(dev, &ipv6_daddr, skb);
- if (!peer) {
- BT_DBG("no such peer %pMR found", &addr);
- return -ENOENT;
- }
+ BT_DBG("no such peer");
+ return -ENOENT;
}

daddr = peer->lladdr;
- *peer_addr = addr;
- *peer_addr_type = addr_type;
+ peer_addr = &peer->chan->dst;
+ *peer_addr_type = peer->chan->dst_type;
lowpan_cb(skb)->chan = peer->chan;

status = 1;
@@ -717,14 +675,6 @@ static struct l2cap_chan *chan_create(void)
return chan;
}

-static void set_ip_addr_bits(u8 addr_type, u8 *addr)
-{
- if (addr_type == BDADDR_LE_PUBLIC)
- *addr |= 0x02;
- else
- *addr &= ~0x02;
-}
-
static struct l2cap_chan *add_peer_chan(struct l2cap_chan *chan,
struct lowpan_btle_dev *dev)
{
@@ -741,11 +691,6 @@ static struct l2cap_chan *add_peer_chan(struct l2cap_chan *chan,

lowpan_iphc_uncompress_eui48_lladdr(&peer->peer_addr, peer->lladdr);

- /* IPv6 address needs to have the U/L bit set properly so toggle
- * it back here.
- */
- set_ip_addr_bits(chan->dst_type, (u8 *)&peer->peer_addr.s6_addr + 8);
-
spin_lock(&devices_lock);
INIT_LIST_HEAD(&peer->list);
peer_add(dev, peer);
--
2.9.3


2017-03-01 11:09:40

by Luiz Augusto von Dentz

[permalink] [raw]
Subject: Re: [PATCH v5 4/6] ipv6: addrconf: fix 48 bit 6lowpan autoconfiguration

Hi Alex,

On Sun, Feb 26, 2017 at 8:38 AM, Alexander Aring <[email protected]> wrote:
>
> Hi,
>
> okay now I am finally confused.
>
> On 02/24/2017 01:14 PM, Luiz Augusto von Dentz wrote:
>> From: Alexander Aring <[email protected]>
>>
>> This patch adds support for 48 bit 6LoWPAN address length
>> autoconfiguration which is the case for BTLE 6LoWPAN.
>>
>> Signed-off-by: Alexander Aring <[email protected]>
>> Signed-off-by: Luiz Augusto von Dentz <[email protected]>
>> Reviewed-by: Stefan Schmidt <[email protected]>
>> ---
>> net/ipv6/addrconf.c | 17 ++++++++++++-----
>> 1 file changed, 12 insertions(+), 5 deletions(-)
>>
>> diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
>> index 3a2025f..7756640 100644
>> --- a/net/ipv6/addrconf.c
>> +++ b/net/ipv6/addrconf.c
>> @@ -2052,12 +2052,19 @@ static void addrconf_leave_anycast(struct inet6_ifaddr *ifp)
>> __ipv6_dev_ac_dec(ifp->idev, &addr);
>> }
>>
>> -static int addrconf_ifid_eui64(u8 *eui, struct net_device *dev)
>> +static int addrconf_ifid_6lowpan(u8 *eui, struct net_device *dev)
>> {
>> - if (dev->addr_len != EUI64_ADDR_LEN)
>> + switch (dev->addr_len) {
>> + case ETH_ALEN:
>> + return addrconf_ifid_eui48(eui, dev);
>
> You need to make the same thing here like what we discusss in antoher
> mail.
>
> 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|
> +----------------+----------------+----------------+----------------+
>
> The function addrconf_ifid_eui48 will do a u/l bitflip. You need to change
> that otherwise transparent 6lowpan adaptiation will not match on your
> local address.
>
> Making u/l bit here, but not in IPHC code -> will not work together.
>
> ---
>
> btw: That's why I think we should provide some function _once_ to
> generate the IID for iphc code and ipv6. Then such mistakes will not
> happen.
>
> So we don't want to have some module dependency of 6lowpan in ipv6.
> My first idea is to make a callback in 6lowpan private data of
> netdevice. :-/

Well if we will be introducing new fields why not introduce an iid
field directly into net_device? That way we don't need to keep
generating it in several places.

--
Luiz Augusto von Dentz