Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enabling IPv6 SLAAC option for arduino-esp32 by default #5624

Closed
sanmira opened this issue Sep 2, 2021 · 8 comments · Fixed by #9016
Closed

Enabling IPv6 SLAAC option for arduino-esp32 by default #5624

sanmira opened this issue Sep 2, 2021 · 8 comments · Fixed by #9016
Labels
Status: Awaiting triage Issue is waiting for triage Status: In Progress Issue is in progress Type: Feature request Feature request for Arduino ESP32
Milestone

Comments

@sanmira
Copy link

sanmira commented Sep 2, 2021

Hardware:

Board ESP32-POE
Core Installation version 2.0.0
IDE name Platform.io
Flash Frequency 40Mhz
PSRAM enabled no
Upload Speed 115200
Computer OS Windows 10

Description:

I was trying to configure IPv6 client on my ESP32 device and faced an issue with device's inability to obtain a global IPv6 address.
After investigation I've found that for the brebuilded ESP-IDF SDK "CONFIG_LWIP_IPV6_AUTOCONFIG" flag was not set (SLAAC option in the menuconfig).

I was able to rebuild the LwIP library manually with correct configuration. After that IPv6 started working as expected and I was able to get global IPv6 address using tcpip_adapter_get_ip6_global() function.

Can we enable the SLAAC option before building the ESP-IDF SDK for Arduino by default?
Because, without this option IPv6 client is unusable with Arduino if I understand it correctly.

@VojtechBartoska VojtechBartoska added Status: To be implemented Selected for Development Status: Awaiting triage Issue is waiting for triage Type: Feature request Feature request for Arduino ESP32 Status: Needs investigation We need to do some research before taking next steps on this issue and removed Status: To be implemented Selected for Development Status: Awaiting triage Issue is waiting for triage labels Mar 30, 2022
@VojtechBartoska
Copy link
Collaborator

Hello @sanmira, thanks for your feature request. It needs more investigation from our side. Are you able to provide a code for testing this?

nuclearcat added a commit to nuclearcat/esp32-arduino-lib-builder that referenced this issue May 7, 2022
To use IPv6 we need proper SLAAC support which is not possible without this option.
Compile tested on esp32, esp32s2, esp32s3, esp32c3
Functionality tested in esp32 BasicHttpClient with some minor patches, IPv6 start to work.

No significant sketch size increase (probably within rounding bounds):
Before:
Wrote 875328 bytes (558896 compressed) at 0x00010000 in 9.0 seconds (effective 779.4 kbit/s)...
After:
Wrote 875328 bytes (558942 compressed) at 0x00010000 in 9.0 seconds (effective 779.8 kbit/s)...

This patch part of the efforts mentioned in espressif/arduino-esp32#6242

Proper IPv6 support also was requested in:
espressif/arduino-esp32#6626
espressif/arduino-esp32#6590
espressif/arduino-esp32#6283
espressif/arduino-esp32#6703
espressif/arduino-esp32#5624
espressif/arduino-esp32#1261
And many others.

Signed-off-by: Denys Fedoryshchenko <denys.f@collabora.com>
nuclearcat added a commit to nuclearcat/esp32-arduino-lib-builder that referenced this issue May 10, 2022
To use IPv6 we need proper SLAAC support which is not possible without this option.
Compile tested on esp32, esp32s2, esp32s3, esp32c3
Functionality tested in esp32 BasicHttpClient with some minor patches, IPv6 start to work.

No significant sketch size increase (probably within rounding bounds):
Before:
Wrote 875328 bytes (558896 compressed) at 0x00010000 in 9.0 seconds (effective 779.4 kbit/s)...
After:
Wrote 875328 bytes (558942 compressed) at 0x00010000 in 9.0 seconds (effective 779.8 kbit/s)...

This patch part of the efforts mentioned in espressif/arduino-esp32#6242

Proper IPv6 support also was requested in:
espressif/arduino-esp32#6626
espressif/arduino-esp32#6590
espressif/arduino-esp32#6283
espressif/arduino-esp32#6703
espressif/arduino-esp32#5624
espressif/arduino-esp32#1261
And many others.

Signed-off-by: Denys Fedoryshchenko <denys.f@collabora.com>
nuclearcat added a commit to nuclearcat/esp32-arduino-lib-builder that referenced this issue May 23, 2022
To use IPv6 we need proper SLAAC support which is not possible without this option.
Compile tested on esp32, esp32s2, esp32s3, esp32c3
Functionality tested in esp32 BasicHttpClient with some minor patches, IPv6 start to work.

No significant sketch size increase (probably within rounding bounds):
Before:
Wrote 875328 bytes (558896 compressed) at 0x00010000 in 9.0 seconds (effective 779.4 kbit/s)...
After:
Wrote 875328 bytes (558942 compressed) at 0x00010000 in 9.0 seconds (effective 779.8 kbit/s)...

This patch part of the efforts mentioned in espressif/arduino-esp32#6242

Proper IPv6 support also was requested in:
espressif/arduino-esp32#6626
espressif/arduino-esp32#6590
espressif/arduino-esp32#6283
espressif/arduino-esp32#6703
espressif/arduino-esp32#5624
espressif/arduino-esp32#1261
And many others.

Signed-off-by: Denys Fedoryshchenko <denys.f@collabora.com>
me-no-dev pushed a commit to espressif/esp32-arduino-lib-builder that referenced this issue Jun 12, 2022
To use IPv6 we need proper SLAAC support which is not possible without this option.
Compile tested on esp32, esp32s2, esp32s3, esp32c3
Functionality tested in esp32 BasicHttpClient with some minor patches, IPv6 start to work.

No significant sketch size increase (probably within rounding bounds):
Before:
Wrote 875328 bytes (558896 compressed) at 0x00010000 in 9.0 seconds (effective 779.4 kbit/s)...
After:
Wrote 875328 bytes (558942 compressed) at 0x00010000 in 9.0 seconds (effective 779.8 kbit/s)...

This patch part of the efforts mentioned in espressif/arduino-esp32#6242

Proper IPv6 support also was requested in:
espressif/arduino-esp32#6626
espressif/arduino-esp32#6590
espressif/arduino-esp32#6283
espressif/arduino-esp32#6703
espressif/arduino-esp32#5624
espressif/arduino-esp32#1261
And many others.

Signed-off-by: Denys Fedoryshchenko <denys.f@collabora.com>
@VojtechBartoska
Copy link
Collaborator

Please check merged PR which can solve your issue.

espressif/esp32-arduino-lib-builder#67

It will be available in next release 2.0.4.

@VojtechBartoska VojtechBartoska added Resolution: Awaiting response Waiting for response of author and removed Status: Needs investigation We need to do some research before taking next steps on this issue labels Jun 14, 2022
@VojtechBartoska
Copy link
Collaborator

@sanmira Did you retest your code under 2.0.4 release? Thanks

@fryefryefrye
Copy link

fryefryefrye commented Jul 30, 2022

With 2.0.4 still can not get public IPv6 address,only local link address.

[337040][D][WiFiGeneric.cpp:929] _eventCallback(): Arduino Event: 8 - STA_GOT_IP6
STA IPv6: fe80:0000:0000:0000:a6cf:12ff:fe99:eabc
Update:
IPv6Address WiFiSTAClass::localIPv6() will only return linklocal address. 
May be we need a another function like  IPv6Address WiFiSTAClass::GlobalIPv6(). and Update the example code.

@fryefryefrye
Copy link

I was able to rebuild the LwIP library manually with correct configuration. After that IPv6 started working as expected and I was able to get global IPv6 address using tcpip_adapter_get_ip6_global() function.

With 2.0.4, I also get "global IPv6 address for ESP32". But i faced problem on communication with IPv6.

Using following simply code, IPv6 comunication is OK between two ESP8266 board.

Send:

m_WiFiUDP.beginPacket("240e:3a1:2e6:ee6:42f5:20ff:fe30:a6b3", 5050);
m_WiFiUDP.write((const char*)&TestStruData, sizeof(tTestStruData));
m_WiFiUDP.endPacket(); 

Receive

m_WiFiUDP.parsePacket(); 
unsigned int UdpAvailable = m_WiFiUDP.available();
printf("m_WiFiUDP.available() = %d\r\n",UdpAvailable);

But when I use ESP32 as the Receiver. It will never have available bytes from IPv6. (IPv4 is OK).

@sgryphon
Copy link
Contributor

sgryphon commented Aug 25, 2022

I suggest not trying to patch in support for just one additional address, but recognise that with IPv6 a device will usually have varying numbers of multiple addresses.

e.g. Have a signature like IPAddress localIP(int8_t index = 0) that returns as many addresses as are available (or NONE once they have run out). Maybe also have a signature like int8_t getLocalIPs(IPAddress ipAddresses[], int8_t max) that will fill an array (up to max), and return the number of addresses.

Note that ArduinoCore-API now has IPAddress that supports both v4 and v6. Generally the client code doesn't want to care about which version of IP is being used.

Note that local means this end of the connection (as opposed to the remote end), and is different from link-local.

As discussed above, link-local are addresses starting with "fe80:". The equivalent in IPv4 is a "169.254" address, which is only assigned when there is no network, whereas with IPv6 they are always assigned.

In IPv4 and endpoint usually only has one address, e.g. either a global address, private network address, or if no network then a link-local address (e.g. used in point-to-point connections).

With IPv6 an endpoint will usually have multiple local addresses -- a link-local address (autogenerated), as well as one or more global scope addresses, including both globally routeable addresses and maybe unique local addresses ("fd.."), both stateless/EUI-64 addresses and maybe DHCP assigned addresses, and with privacy extensions possibly also some additional rotating addresses.

For example, my local machine has 1x IPv4, and 7x IPv6 addresses.

Although Arduino/lwIP may not yet support all these types of addresses, then interface should prepare for varying numbers of addresses.

Generally when getting a single address, i.e. localIP() it is probably to display to the user (or in a log) as the address, useful for checking connections at the other end, etc.

Without any knowledge of the intended destination, I suggest ordering local IP addresses as if the destination is a global address, if possible, i.e. preference global addresses (globally routable or unique local addresses) over link-local, and IPv6 over IPv4 (see RFC 6724).

This won't always be what the user wants (e.g. in a dual stack network maybe they want to check the address in the logs of an IPv4 only destination), but if you only return a single address then you can't always know what will be needed.

@sgryphon
Copy link
Contributor

With IPv4 you generally have only a single local address, but with IPv6 you will have many, so the question is "which one should localIP() return?", which depends on what you want it for.

Generally you don't want to care about specific IP addresses, but some reasons might be (a) to display (log or screen) so that you can check destinations logs/connections to investigate and debug, or (b) to display (log or screen) so it can be usde to configure another device to connect to the first as a server.

IPv6 has multiple addresses and uses the address pair with the smallest scope for connections, based on RFC 6724. Generally the destination address selection is followed by the DNS system when returning a list of addresses, and the source address selection is done by the outgoing network stack.

The rules in RFC 6724 prefer smaller scopes where possible, e.g. if both source and destination are local-link, then use that; this means the source address used will depend on the destination.

As localIP() address does not know the destination we need to make some assumption, such as it is most likely to be a public address, e.g. v4v6.ipv6-test.com. We can then apply the RFC 6724 rules and show the address that is the one that would be used for public connections. If our actual connection is private it will be wrong, but if we only return one address it has to be the public one.

Generally RFC 6724 prefers temporary addresses, for privacy, but that may not be the best for scenario (b), and even for scenario (a) a temporary address shown now may not match the one used in the logs later. RFC 6724 does allow for a mechanism to reverse this ordering, and I suggest we want to do this and for localIP() we want to return the public address over a temporary address.

The general priority for global scope (i.e. assuming a global destination) is: IPv6, IPv4, 6to4 tunnel (2002::/16), Teredo tunnel (2001::/32), ULA (fc00::/7)

For my local machine this ordering would produce the following:

Global:
inet6 2407:8800:bc61:1300::8e6
inet6 2407:8800:bc61:1300:4a23:22d5:6c48:f0e8
inet6 2407:8800:bc61:1300:4df2:1392:9dd7:d2d7
inet6 2407:8800:bc61:1300:ee48:5c84:ad87:c65c
inet 192.168.1.195
inet6 fd7c:e25e:67e8::8e6
inet6 fd7c:e25e:67e8:0:2c73:36d3:d325:93df
inet6 fd7c:e25e:67e8:0:a9ed:c900:59fa:5449
inet6 fd7c:e25e:67e8:0:9ac7:63c9:5f26:b026

Then Link-Local:
inet6 fe80::5f65:961a:14b4:6263

When connecting to https://ipv6-test.com/, one of the temporary addresses will actually be used (e.g. 2407:8800:bc61:1300:ee48:5c84:ad87:c65c), but for scenario (b) it would be better to use 2407:8800:bc61:1300::8e6 for configuring connections, so I think it is better to show that.

Note that for many constrained devices they may not support privacy extensions, etc, so often have two IPv6 addresses: one public and one link-local, but for proper debugging, etc, we would need to list them all if available.

@VojtechBartoska VojtechBartoska added this to the 3.0.0 milestone Oct 24, 2022
@VojtechBartoska VojtechBartoska added Status: In Progress Issue is in progress and removed Resolution: Awaiting response Waiting for response of author labels Feb 23, 2023
@VojtechBartoska VojtechBartoska modified the milestones: 3.0.0, 3.0.0-RC1 Dec 21, 2023
@VojtechBartoska VojtechBartoska added the Status: Awaiting triage Issue is waiting for triage label Dec 21, 2023
@VojtechBartoska
Copy link
Collaborator

Adding to 3.0.0-RC1, should be relevant for ipv6 support addition.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Status: Awaiting triage Issue is waiting for triage Status: In Progress Issue is in progress Type: Feature request Feature request for Arduino ESP32
Projects
Development

Successfully merging a pull request may close this issue.

4 participants