diff mbox

[RFC,bluetooth-next,01/20] 6lowpan: ndisc: don't remove short address

Message ID 20160711195044.25343-2-aar@pengutronix.de (mailing list archive)
State Superseded
Headers show

Commit Message

Alexander Aring July 11, 2016, 7:50 p.m. UTC
This patch removes handling to remove short address for a neigbour entry
if RS/RA/NS/NA doesn't contain a short address. If these messages
doesn't has any short address option, the existing short address from
ndisc cache will be used.

Signed-off-by: Alexander Aring <aar@pengutronix.de>
---
 net/6lowpan/ndisc.c | 2 --
 1 file changed, 2 deletions(-)

Comments

Michael Richardson July 19, 2016, 1:19 p.m. UTC | #1
{cutting many from the CC}
I realized while reading your patches that I don't think we have a way for an
application to tell if a packet (such as an ICMPv6 packet received on a raw
IP socket) arrives with a 2-byte or 8-byte address, or for an application to
ask for 8-byte address, despite there being a 2-byte address available.

Do you think we could do this via neighbour caches for directly connected
nodes?  For not directly connected nodes part of an RPL mesh, the RPL daemon
would install routes using the router's 2-byte address if it can anyway.

This will matter for handling of ND, in particular the DAR/DAC processing.

I also wonder: if we configure an IPv6 address via SLAAC with our 8-byte
EUI64, and we configure another v6 address via SLAAC with our 2-byte address,
if we should:
   a) always use the 2-byte layer-2 when there is a matching 2-byte v6
      address in the source.  and vv for 8-byte EUI64s
   b) preference the 2-byte layer-3 address so that it is chosen by
      source address selection.

I think that the above probably gets us all the mechanisms we need for
transmit.   For receive, I think that we have no APIs that will give you the
layer-2 address for an incoming packet the way that IPV6_RECVPKTINFO will
do for layer-3 addresses and extensions.   It would be nice to have such
an API.

What do others think?

--
]               Never tell me the odds!                 | ipv6 mesh networks [
]   Michael Richardson, Sandelman Software Works        | network architect  [
]     mcr@sandelman.ca  http://www.sandelman.ca/        |   ruby on rails    [
Alexander Aring July 19, 2016, 6:03 p.m. UTC | #2
Hi,

On 07/19/2016 03:19 PM, Michael Richardson wrote:
> 
> {cutting many from the CC}

ok.

> I realized while reading your patches that I don't think we have a way for an
> application to tell if a packet (such as an ICMPv6 packet received on a raw
> IP socket) arrives with a 2-byte or 8-byte address, or for an application to
> ask for 8-byte address, despite there being a 2-byte address available.
> 

Yes this isn't possible. The 6lowpan interface has raw IPv6 view, no L2
part isn't involved.

Currently what we do is to have some "best-fit" strategy according to
using the best compression method which depends on L3 address.

I can understand that you want to decide from userspace which L2 address
you want to use. We should have some way to overwrite the best fit
strategy and you can control it somehow from userspace.

The "best-fit" strategy will be used then if a "overwrite strategy"
isn't given, so we have no dependency on that we MUST need to set short
or extended from socket side. Otherwise we put 802.15.4 dependencies
into IPv6 userspace applications.

> Do you think we could do this via neighbour caches for directly connected
> nodes?  For not directly connected nodes part of an RPL mesh, the RPL daemon
> would install routes using the router's 2-byte address if it can anyway.
> 

I can imagine that if a neighbour has both address types "short and extended"
then we run into the possibility that you can decide "if using short xor
extended address" while generating 6LoWPAN+L2 headers.

So you want to have such "flag":

"please force use short address always if short available" and
"please force use extended address always (if short address is available)"

_per_ neighbour? If this fits to your use-case then I think it could work.

At last you need to have some "neighbour add" netlink event listener
which reacts on if neighbours will be added and then set such flag for
the neighbour (which is indicated by L3 address).

---

Maybe another idea to avoid a event handling mechanism is to keep some
hash table in table with the L3 address as key and then sets such flag,
do not depend on neighbour exists or not.

But the neighbour cache is already a hash with L3 address as key. I
think the neighbour cache should be used for such use-case. What do you
think.

> This will matter for handling of ND, in particular the DAR/DAC processing.
> 

ah, ok. So for sending out DAR/DAC we need to control somehow to use
short or extended address?

You want to send these messages via userspace? In kernelspace we could
handle it (I think), lowpan interface knows the wpan interface and we
could decide somehow to force using short xor extended when generating
mac header for DAR/DAC.

> I also wonder: if we configure an IPv6 address via SLAAC with our 8-byte
> EUI64, and we configure another v6 address via SLAAC with our 2-byte address,
> if we should:
>    a) always use the 2-byte layer-2 when there is a matching 2-byte v6
>       address in the source.  and vv for 8-byte EUI64s
>    b) preference the 2-byte layer-3 address so that it is chosen by
>       source address selection.
> 

If I understand correctly, we do at the moment a) case.
By "Looking at L3 address and choose the L2 address according to which
best address do more compression", isn't it?

I already implemented this stuff, the only one think is... it's more
than looking into L3 address only. It depends also on fragmentation. We
can compress maybe lot of bytes in FRAG1 which contains 6LoWPAN header
with the right L3 address by doing extended address. But if we have ~3
fragments (didn't calculate the number of necessary fragments now) then
it's better to use short address, because you can compress more bytes by
using short addresses in the fragments.

---

The method b) would be something that you can set some attribute
_per_ interface to force use short address xor extended as _source_.

RIOT-OS has something like that which is the "src_len" attribute of the
netdev2 interface.

---

What I would like the see is maybe a similar handling like the "estimate
the daddr L2 address". Doing a) by default, because it will choose the
best option to compress data, but you can do b) (by some netlink command)
to overwrite the handling of a).

The b) stuff will work then _per_ interface. Would be maybe nice to
have this per socket. I would say per socket would be nicer, because you
can overwrite the setting for exactly your use-case and all other
applications still do a). Currently I have no idea how to getting such
information from IPv6 socket to the 6LoWPAN layer but this should be
possible. This will also no add any 802.15.4 dependency for IPv6
applications, default handling should be still a).

> I think that the above probably gets us all the mechanisms we need for
> transmit.   For receive, I think that we have no APIs that will give you the
> layer-2 address for an incoming packet the way that IPV6_RECVPKTINFO will
> do for layer-3 addresses and extensions.   It would be nice to have such
> an API.

I also have no idea to get L2 receive information to the userspace at
the IPv6 socket yet. Need to take a look into ipv6 sockets,
IPV6_RECVPKTINFO is a nice hint, if we can easly extend this information.

> 
> What do others think?

In short what I described above:

Make a reasonable default handling which looks for "what we need to do
to doing the best 6LoWPAN compression", but there exists the possibility
to overwrite this handling and force a different handling.


I hope it's clear what I mean, otherwise we can chat.

- Alex
--
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
Alexander Aring July 21, 2016, 6:37 a.m. UTC | #3
Hi,

On 07/19/2016 08:03 PM, Alexander Aring wrote:
...
> 
>> I think that the above probably gets us all the mechanisms we need for
>> transmit.   For receive, I think that we have no APIs that will give you the
>> layer-2 address for an incoming packet the way that IPV6_RECVPKTINFO will
>> do for layer-3 addresses and extensions.   It would be nice to have such
>> an API.
> 
> I also have no idea to get L2 receive information to the userspace at
> the IPv6 socket yet. Need to take a look into ipv6 sockets,
> IPV6_RECVPKTINFO is a nice hint, if we can easly extend this information.
>

I looked into that and believe to know how the IPV6_RECVPKTINFO handling
works. Then we need to add something add [0]. For example:

unsigned char llsaddr[32];
unsigned char lldaddr[32];

where 32 is the current MAX_ADDR_LEN and put some 802.15.4 6LoWPAN
specific UAPI in there for representing the 802.15.4 address, should be
"struct ieee802154_addr". This requires to get dev->type and subtype
before.

I found some example code [1] for that and it seems that they using for a
similar use-case which we have:

 - We don't have working neighbour discovery yet
 - We want to do our own neighbour discovery in userspace

That's what libndp do also somehow as a library. In our case we need:

 - We need to control somehow from userspace side which mac address
   should be used (tx) or was used (rx), in case of 802.15.4 different
   mac addresses stuff.

To evaluate the "(struct in6_pktinfo *)" I found [2]. I think for
receive side this should working. I don't know how netdev people reacts
when we want to put L2 information into "in6_pktinfo". We simple need to
try that, L2 information requires to evaluate the device types before.

---

Another issue is that it's currently not possible to get mac header
inside the IPv6 subsystem. We should parse the mac header again there to
get the address, we need that to fill "in6_pktinfo".

So why this is not working currently? Because IPHC will overwrite the
mac header :-) while uncompression. We need to work with skb fragments
there and linearlize the skb afterwards to fiddle new data in the
middle of that again.

This is currently a bug and I want to look for that anyway, because skb
fragments should handle some parts better when doing NHC.

---

For the transmit side, I think receive side would be _per_ _socket_
then, if we using in6_pktinfo. For the transmit side we should have it
also per socket then.

My idea with "using neighbour discovery with flags" will not work!
Because if we doing our own neighbour over IPv6 RAW sockets then we
don't have a neighbour discovery yet.

The other solution might work with the "own" hash table and daddr as key
to map which l2 address will be used, but I think we should be able to
do this somehow like "IPV6_RECVPKTINFO" just for the tx side.

- Alex

[0] http://lxr.free-electrons.com/source/include/uapi/linux/ipv6.h#L19
[1] https://github.com/jpirko/libndp
[2] https://github.com/jpirko/libndp/blob/master/libndp/libndp.c#L174
--
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
Alexander Aring July 21, 2016, 7:10 a.m. UTC | #4
Hi,

On 07/21/2016 08:37 AM, Alexander Aring wrote:
> 
...
> ---
> 
> For the transmit side, I think receive side would be _per_ _socket_
> then, if we using in6_pktinfo. For the transmit side we should have it
> also per socket then.
> 
> My idea with "using neighbour discovery with flags" will not work!
> Because if we doing our own neighbour over IPv6 RAW sockets then we
> don't have a neighbour discovery yet.
> 
> The other solution might work with the "own" hash table and daddr as key
> to map which l2 address will be used, but I think we should be able to
> do this somehow like "IPV6_RECVPKTINFO" just for the tx side.
> 

The b) case and I think this is to control source address as "interface"
attribute to prefer short or extended will be complicated. I currently
think about if you doing that fast while a current socket connection.

You can't control it because sockets have queues (so far I know).
Maybe I am wrong and synced send handling will wait until "xmit
callback" of the interface will be called (It's a zero queue interface).
Zero queue means that there is no qdisc but socket queues exists, so far
I know.

It should be possible to tell somehow over IPv6 raw sockets which
destination address for the l2 address should be used, or? I think the
solution is maybe somewhere in libndp.c I didn't found it yet. We just
need to add support for the 802.15.4 short or extended addr.

Our current implementation will not work with disabled kernelspace
neighbour discovery yet and currently I don't know how it can work when
holding the complete cache inside the userspace. :-/

Disable ndisc handling in kernelspace and do handling in userspace
(RS/RA/NS/NA) but using the neighbour cache in kernel. Means: fill the
neighbour entries in the cache with netlink might work. Don't know which
way we should going here. I need to look into libndp, I think we should
extend it that we can handle short+extended handling from userspace side.

- Alex
--
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
Michael Richardson July 21, 2016, 8:44 a.m. UTC | #5
Alexander Aring <aar@pengutronix.de> wrote:
    > So you want to have such "flag":

    > "please force use short address always if short available" and
    > "please force use extended address always (if short address is
    > available)"

    > _per_ neighbour? If this fits to your use-case then I think it could
    > work.

yes, I think this is what I want.

    > At last you need to have some "neighbour add" netlink event listener
    > which reacts on if neighbours will be added and then set such flag for
    > the neighbour (which is indicated by L3 address).

Yes.

    > But the neighbour cache is already a hash with L3 address as key. I
    > think the neighbour cache should be used for such use-case. What do you
    > think.

I think it's an appropriate use.

    >> This will matter for handling of ND, in particular the DAR/DAC
    >> processing.

    > ah, ok. So for sending out DAR/DAC we need to control somehow to use
    > short or extended address?

Here, I think it's that we need the layer-2 address in the NA to validate the
ARO option in the NA, so that we can send the DAR with confidence.
I have to re-read https://tools.ietf.org/html/rfc6775#section-8.2.3 carefully
to see if I really need this or not.

    > You want to send these messages via userspace? In kernelspace we could
    > handle it (I think), lowpan interface knows the wpan interface and we
    > could decide somehow to force using short xor extended when generating
    > mac header for DAR/DAC.

I think that there is too much long-term state and policy to do this in the
kernel.

    > If I understand correctly, we do at the moment a) case.
    > By "Looking at L3 address and choose the L2 address according to which
    > best address do more compression", isn't it?

yeah...

    > I already implemented this stuff, the only one think is... it's more
    > than looking into L3 address only. It depends also on fragmentation. We
    > can compress maybe lot of bytes in FRAG1 which contains 6LoWPAN header
    > with the right L3 address by doing extended address. But if we have ~3
    > fragments (didn't calculate the number of necessary fragments now) then
    > it's better to use short address, because you can compress more bytes by
    > using short addresses in the fragments.

Yes, i recall discussing this with you.

    > The b) stuff will work then _per_ interface. Would be maybe nice to
    > have this per socket. I would say per socket would be nicer, because you
    > can overwrite the setting for exactly your use-case and all other
    > applications still do a). Currently I have no idea how to getting such
    > information from IPv6 socket to the 6LoWPAN layer but this should be
    > possible. This will also no add any 802.15.4 dependency for IPv6
    > applications, default handling should be still a).

setsockopt() is the normal way to indicate this down.  It gets into the
skbuff in a way that I don't recall.  Probably skbuff->sock or some such.

    > I also have no idea to get L2 receive information to the userspace at
    > the IPv6 socket yet. Need to take a look into ipv6 sockets,
    > IPV6_RECVPKTINFO is a nice hint, if we can easly extend this information.

that's the right mechanism, you send it up as aux data.


--
]               Never tell me the odds!                 | ipv6 mesh networks [
]   Michael Richardson, Sandelman Software Works        | network architect  [
]     mcr@sandelman.ca  http://www.sandelman.ca/        |   ruby on rails    [
diff mbox

Patch

diff --git a/net/6lowpan/ndisc.c b/net/6lowpan/ndisc.c
index 86450b7..941df2f 100644
--- a/net/6lowpan/ndisc.c
+++ b/net/6lowpan/ndisc.c
@@ -101,8 +101,6 @@  static void lowpan_ndisc_802154_update(struct neighbour *n, u32 flags,
 		ieee802154_be16_to_le16(&neigh->short_addr, lladdr_short);
 		if (!lowpan_802154_is_valid_src_short_addr(neigh->short_addr))
 			neigh->short_addr = cpu_to_le16(IEEE802154_ADDR_SHORT_UNSPEC);
-	} else {
-		neigh->short_addr = cpu_to_le16(IEEE802154_ADDR_SHORT_UNSPEC);
 	}
 	write_unlock_bh(&n->lock);
 }