esp_now: avoid parsing IPv6 header in netdev driver#10581
esp_now: avoid parsing IPv6 header in netdev driver#10581miri64 merged 4 commits intoRIOT-OS:masterfrom TimoRoth:master
Conversation
|
@TimoRoth Thank you a for doing the rework of the ESP-NOW-netdev driver. Even though I was trying to understand more about the interaction of GNRC network layer and link layer implementations, as you can see from my questions, I'm really glad that you have already provided your changes. Some first remarks:
--- a/cpu/esp32/esp-now/esp_now_netdev.c
+++ b/cpu/esp32/esp-now/esp_now_netdev.c
@@ -16,7 +16,7 @@
* @author Gunar Schorcht <[email protected]>
*/
-#define ENABLE_DEBUG (0)
+#define ENABLE_DEBUG (1)
#include "debug.h"
#include "log.h"
#include "tools.h"
@@ -561,7 +561,7 @@ static int _recv(netdev_t *netdev, void *buf, size_t len, void *info)
#if ENABLE_DEBUG
printf ("%s: received %d byte from %02x:%02x:%02x:%02x:%02x:%02x\n",
- __func__, dev->rx_len,
+ __func__, dev->rx_pkt.len,
dev->rx_pkt.mac[0], dev->rx_pkt.mac[1], dev->rx_pkt.mac[2],
dev->rx_pkt.mac[3], dev->rx_pkt.mac[4], dev->rx_pkt.mac[5]);I have tried your changes. Unfortunatly, they are not working yet. The system hangs after initialization in |
|
@TimoRoth Don't worry, it is not easy to fulfill static check requirements the first time 😉 |
|
@TimoRoth Regarding |
|
Just now noticed you already started to review, sorry for the force pushes! The od_hexdump comes from the parts that are based on the cc110x. I can change the old parts of the code to use it as well. |
No problem. |
|
I traced the hang on startup back to esp_wifi_scan_get_ap_num() never returning. Not really sure why that is happening though. |
|
This generally works now. I can't ping my peers yet, but they do get a public IP auto-assigned from my Border-Router, so something has to be working. |
|
Works fine for me now. I can ping6 from the RIOT shell with large package sizes and observe how they get correctly fragmented and reassembled on the other end. One thing that doesn't seem to work is IPHC, but I'm not sure if it's supposed to. If I set the GNRC_NETIF_FLAGS_6LO_HC flag for the ESP_NOW device, all I get is an EXCEPTION on send. |
|
@TimoRoth
Are you using |
Yes, I already debugged it a bit, and at least at the lower levels, I can see the larger packages coming in just fine. Not sure where they get lost. |
|
Let me know if I can do anything to support you. I'm working on other RIOT parts at the moment, but I'm still responsible for the RIOT port to ESP32. |
|
I'd consider the remaining issues outside of the scope of this PR. I can send arbitrarily large packages with ping6 from the RIOT shell and they get fragmented and answered just fine. |
I can observe the same problem for link local addresses when pinging from an ESP32 board. Pinging global unicast addresses behaves even more strange, see issue #10594. |
|
One issue I just noticed is that very frequently esp_now_recv_cb drops incoming packages because the currently stored package hasn't been read yet. This is specially an issue with fragmented packages which tend to come in in very rapid succession. |
I would say yes, or at least the maximum packet length of 1280 byte which is supported by the netif. Memory shouldn't be an issue on the ESP32. But, when we start to port your changes to ESP8266, the memory will become a problem. |
|
With the ringbuffer in place I can now properly communicate through the router with packages up to the esp-now interface MTU of 1280 bytes(Assuming #10604 is applied as well). Decided to make it a bit larger by default, as the data is also slightly larger than the raw package data due to it also holding a length byte and the mac address for each package. Not 100% sure if I should squash this into the main commit, or leave it as independent change. |
|
@TimoRoth Is your ESP Router project up-to-date so that I could use it to test PRs #10581 and #10594 a bit more? |
I would say keep it as a separate commit until the review has been finished and you are asked for squashing. |
|
|
Chunk 1 looks like some pkt snip descriptor or netif header. I have a look tomorrow for more details. |
|
Double frees might also lead to such buffer dumps. I'll have a look for that as well. |
|
which ends at The chunk should have only have 85 bytes, but it has 336 bytes.
|
|
If there is a double release there can also be "garbage" within the chunks so if something doesn't make sense is a good hint this is happening. |
|
I tried to take a look for additional where the packet buffer is released in error cases. I have seen in and that packet buffer is not released in case of send errors. |
I meant |
|
Ok. Was able to reproduce this in |
|
Ups. |
I rather think since the packet isn't released in the error case when the send method is left RIOT/sys/net/gnrc/netif/gnrc_netif.c Lines 1295 to 1299 in 591092f that those implementations are errorneous. |
|
(but since both are only in a very rare edge case that I believe we don't hit I don't think that is the problem) |
Avoids parsing IPv6 packets to determine destination address. Allows using 6Lo over ESP-NOW, which is required due to the low MTU of ESP-NOW. Co-authored-by: Gunar Schorcht <[email protected]>
|
So it's not something this change causes, but some rare edge case somewhere in RIOT? |
Because of this, I don't believe this is an issue with this driver rework. Once @TimoRoth fixed the compiler issue pointed out in #10581 (review) (may be squashed immediately) we are good to go, I believe. |
Yes. I will allocate some time at the RIOT assembly @ 35C3 later to search for it. debugging race conditions time 💃 |
|
ACK from my side. Under normal conditions with low rates and small packets it should work without any problems. |
|
"falls through" change is already squashed into the relevant commit. |
miri64
left a comment
There was a problem hiding this comment.
Re-ACK. Is compilable on Arch again.
|
And go. |
Contribution description
Due to the very low MTU of ESP-NOW, it cannot use normal IPv6, which needs a way larger minimum packet size(See #10531).
These patches make ESP-NOW capable of being used with 6Lo instead. In turn they get rid of IPv6 header parsing inside of the netdev driver, which seemed very out of place there.
It provides a custom netif driver instead, that gets the regular l2 destination address from the netif header.
Testing procedure
Two esp32 boards with the gnrc_networking should still be able to communicate, although via 6Lo now instead of plain IPv6.
This also means that this patch does break backwards compatibility. A board with RIOT without these patches applied will not be able to communicate with one with them.
Issues/PRs references
Fixes #10531
Depends on #10536(Merged)