ipv6/rpl: add hop-by-hop extension handling#7231
ipv6/rpl: add hop-by-hop extension handling#7231BytesGalore wants to merge 3 commits intoRIOT-OS:masterfrom
Conversation
22acdac to
e61fb52
Compare
| bool encapsulate = false; | ||
|
|
||
| for ( size_t i = 0; i < sizeof(ext_demux); ++i ) { | ||
| gnrc_netreg_entry_t *call = gnrc_netreg_lookup(GNRC_NETAPI_MSG_TYPE_SND, ext_demux[i]); |
There was a problem hiding this comment.
GNRC_NETAPI_MSG_TYPE_SND isn't a NETTYPE
There was a problem hiding this comment.
Hm, seems I didn't pushed it. It should be GNRC_NETTYPE_IPV6
There was a problem hiding this comment.
Even then this doesn't seem to make sense, since you are not sending here but building headers. Why not just use functions or if you absolutely have to use IPC (which I think would slow-down the sending process majorly), use raw IPC?
There was a problem hiding this comment.
I don't like the fact that IPv6 needs to know something about, say RPL.
Additionally it would require some handshaking which is not needed by using IPC.
use raw IPC
I do, I iterate all interested PIDs with gnrc_netreg_lookup() and use plain message passing here.
| encapsulate = true; | ||
| } | ||
| msg.content.ptr = pkt; | ||
| msg_send_receive(&msg, &rcv, call->target.pid); |
There was a problem hiding this comment.
I'm not sure if you use NETAPI_SND here, because above you use NETAPI_SND in a weird context, but NETAPI_SND uses asynchronous API, so this messes up things.
There was a problem hiding this comment.
The idea here is to consecutively send a blocking message to allow each interested thread to add their extension header to the IPv6 packet and inform the IPv6 thread back when its done.
This way all extension headers can be inserted in a single packet.
Trying this asynchronously would result in sending a multitude of copies of the packet, since all threads do a copy-on-write operation to the packet when inserting an extension header.
There was a problem hiding this comment.
That's why I stated below, that this is a misuse of NETAPI_SND. You are not sending here, you are building headers, so I think a callback function to the header builders would be more sensible here.
| gnrc_pktsnip_t* tmp = pkt; | ||
| pkt = gnrc_ipv6_hdr_build(pkt, &hdr->src, &hdr->dst); | ||
| if (pkt == NULL) { | ||
| /* revert but what do we now */ |
| msg_reply(&msg, &reply); | ||
| break; | ||
|
|
||
| case GNRC_IPV6_EXT_HANDLE_NEXT_HDR: |
There was a problem hiding this comment.
Why not do all below in gnrc_ipv6_ext_demux()?
There was a problem hiding this comment.
This is a direct reply of a thread using plain msg passing when parsing an extension from a received IPv6 packet is finished.
The *handle is used as an iteration message by the thread to point to the next header to be processed, which is eventually dispatched in gnrc_ipv6_ext_demux().
The IPv6 thread needs to wait forwarding the IPv6 packet further until all extensions has been processed by all interested threads.
There was a problem hiding this comment.
Ok, but in this case please surround the case with a suitable #ifdef MODULE_...
| _send(reversed_pkt, false); | ||
| return; | ||
| } | ||
| else { |
There was a problem hiding this comment.
We must prevent to forward the packet before all extension headers have been processed.
Currently I moved the responsibility for preparing the packet as above to the thread that processed the last extension header.
But as you stated, the IPv6 thread is the responsible one for doing it and we should keep it that way.
There was a problem hiding this comment.
I migrated the responsibility back to IPv6 [1].
The actual forwarding of the packet is now performed when the demultiplexing is finished [2].
[1] https://github.com/RIOT-OS/RIOT/pull/7231/files#diff-74976d45a42eaa063e3561b5fd36f615R146
[2] https://github.com/RIOT-OS/RIOT/pull/7231/files#diff-74976d45a42eaa063e3561b5fd36f615R255
|
This whole PR seems very intrusive into |
I disagree, |
But it changes the semantics of that mechanics and their API significantly, which can have unforeseen side-effects and makes potential refactoring work harder. I also don't think that handling IPv6 extension headers in any other thread than the IPv6 handling thread is a good idea. Every synchronous context switch demands time and message queue space (thus blocking the queue for other packages). I'm actually currently trying to reduce those within the stack. If you absolutely want to use |
I don't see your point. Using the Could you rephrase your proposition for using |
|
I was talking about this function, that used to have a
Yes. |
sys/include/net/netopt.h
Outdated
| /** | ||
| * @brief Type for sequiential processing of IPv6 extension headers | ||
| * | ||
| * On GET it requests a thread to insert an extension header. |
There was a problem hiding this comment.
Why does get not just return a gnrc_pktsnip_t and the IPv6 thread inserts the header?
There was a problem hiding this comment.
(then it still could be used like the other get/set calls ;-)).
There was a problem hiding this comment.
ok, I gave it a shot
| * i.e. in front of hdr->next. | ||
| * We bend hdr->next to point to ext. | ||
| */ | ||
| pkt->next = data; |
There was a problem hiding this comment.
Don't you need to append the old payload of pkt as well?
There was a problem hiding this comment.
Ah got it. The handler already does that for you.
There was a problem hiding this comment.
It depends how the pktsnip is created.
When we create it with the pkt prepending to pkt->next I would expect that the former content is appended behind the newly created snip.
e.g. gnrc_pktbuf_add(pkt->next, ....);
sys/include/net/netopt.h
Outdated
| /** | ||
| * @brief Type for sequiential processing of IPv6 extension headers | ||
| * | ||
| * On GET it requests a thread to provide an extension header. |
There was a problem hiding this comment.
"and appends it to the the given (IPv6) header" "and prepends it to the given payload of the given (IPv6) packet"
| * | ||
| * When the header is done the thread replies to the call. | ||
| * The result is the pktsnip_t with the extension header | ||
| * The result is NULL if no extension header is passed. |
There was a problem hiding this comment.
You hand over a pointer (not a pointer of a pointer) below, so this should be impossible. Why not use the numeric return-value of NETAPI_GET (which is returned by gnrc_netapi_get())?, e.g. sizeof(gnrc_pktsnip_t) on success, -ENOMEM (or whatever is applicable) on error.
There was a problem hiding this comment.
not a pointer of a pointer
true, it would require some wrapping.
You mean exploiting the int return type for pointer passing, why not.
20dab9b to
7326be9
Compare
|
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. If you want me to ignore this issue, please mark it with the "State: don't stale" label. Thank you for your contributions. |
|
ping @BytesGalore, should someone take over? |
|
From what I can tell, parts of RFC |
|
@miri64 don't see any problems taking this over ... |
|
Started migration in https://github.com/miri64/RIOT/tree/gnrc_rpl_opt/feat/initial. |
@miri64 They might be deprecated yes. However, nobody will use the RPI option uncompressed anyway when RIOT finally implements the 6LoRH specified by RFC 8138. However, I don't think anybody is working on implementing 6LoRH currently, is there? |
AFAIK, no, but we need the option and support for the paging dispatch first, right? |
|
@miri64 correct, paging dispatch is needed first |
|
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. If you want me to ignore this issue, please mark it with the "State: don't stale" label. Thank you for your contributions. |
|
Since this PR has been stale for almost four years, but still contains useful code and discussion for follow-up, I'll convert it to a draft. Please feel free to remove the draft state if anyone wants to pick this up again. |
|
Maybe could be interesting for @elenaf9? |
This PR introduces hop-by-hop header handling for RPL,
which includes an adjustment to extension header processing in
gnrc_ipv6.For receiving packets the adjustment introduces a sequential procedure which enables all interested threads to evaluate an extension and react before the packet is forwarded further.
When sending a packet all interested threads will be called to insert their extension before the packet is sent.