You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
IPv6 Support in micropython for ESP32 (or anything for that matter) #3683
It looks like LWIP in the ESP-IDF being used for micropython has IPv6 support.
Is there an effort to take advantage of the yet? I found some documentation which stated that IPv6 support was "port" dependent, but I have yet to find any port of micropython with IPv6 support enabled.
It looks like the current build has IPv6 capabilities in the usocket module, but it looks like there are no IPv6 capabilities in the network or WLAN class implementations which means that the interface can't get an IPv6 address, etc.
I'm willing to put some effort into trying to do the needful, but the existing API seems to be so thoroughly incapable of understanding that there could possibly be any protocol other than IPv4 that I'm unsure how to go about providing a mergeable codebase that wouldn't break people's existing code.
Further, I'd like to know if there are any standard APIs for IPv6 interface configuration that I should be following as the existing interface configuration capabilities in the ESP32 port are quite thoroughly incapable of such.
Any pointers (or ideally a solution already developed) greatly appreciated.
I found some documentation which stated that IPv6 support was "port" dependent, but I have yet to find any port of micropython with IPv6 support enabled.
The unix port supports IPv6: you can create sockets with family AF_INET6 (=10) and then connect them to a remote IPv6 address. This is how it would work on any port that supports IPv6.
it looks like there are no IPv6 capabilities in the network or WLAN class implementations which means that the interface can't get an IPv6 address, etc.
Most of the network module functions should be IP agnostic and allow you to connect to an IPv6 network. The ifconfig() method will need some enhancement to support IPv6.
The first step to get IPv6 working on the ESP32 would be to work out how to control the ESP IDF to get on a IPv6 network, then it can be seen how to incorporate this into the network module.
Most of the network module functions should be IP agnostic and allow you to connect to an IPv6 network. The ifconfig() method will need some enhancement to support IPv6.
The first step to get IPv6 working on the ESP32 would be to work out how to control the ESP IDF to get on a IPv6 network, then it can be seen how to incorporate this into the network module.
My understanding from looking at the ESP-IDF (admittedly, by far no expert) is that all of the existing LWIP libs include all the necessary IPv6 support and we just need to make the appropriate calls.
Unfortunately, from looking at the source for the ifconfig() PERL call in the ports/esp32 source code, I wasn't able to figure out how it crawled down into the LWIP code in the ESP-IDF to do its thing.
Further, I wasn't able to figure out enough about the generic WLAN startup code to figure out how to add IPv6 initialization so that it could "just work" with SLAAC (which is built into the LWIP code if we just turn on IPv6 AIUI).
Does the UNIX port have the ability to configure interfaces or does it depend on that being done outside of the MicroPython environment since it's running as an application inside an operating system instead of running as an operating system?
It doesn't have the network module so relies on network interfaces to be set up via the host OS.
Which then renders it a less than useful port for the purpose of identifying or finding example code for porting IPv6 to any form of MCU such as the ESP32.
Not trying to be obnoxious, but hoping to find some code examples or something I can use to help contribute IPv6 work towards the ESP32. I think that the ESP32 version of the sockets/usockets module(s) has IPv6 capabilities as well, but that doesn't do any good if I can't get an IPv6 address on the underlying interface in the network module.
Are there any Micropython ports where MP controls the hardware that have the ability to put IPv6 on an interface through the network module?
Are there any Micropython ports where MP controls the hardware that have the ability to put IPv6 on an interface through the network module?
No, not that I know of.
It's great that you want to help get IPv6 support working. The first place to start is understanding what calls to make to the ESP IDF to get the device connected on an IPv6 network and have it assigned an address. Wit that knowledge we can see how to incorporate it into the network module. Then move on to making socket work.
OK... I can definitely look into that. From what I understand, it should be pretty straight forward set of calls to LWIP, at least for SLAAC. I'm not sure if DHCPv6 is implemented in LWIP yet. I've seen conflicting reports, mostly negative.
#include "esp_system.h"
#include "esp_wifi.h"
#include "lwip/err.h"
#include "lwip/sockets.h"
#include "lwip/sys.h"
#include <lwip/netdb.h>
// Note the following examples are defined using "make menuconfig" in the ESP-IDF.
// Alternatively, just specify applicable values for your environment in the code directly
#define EXAMPLE_WIFI_SSID CONFIG_WIFI_SSID
#define EXAMPLE_WIFI_PASS CONFIG_WIFI_PASSWORD
#define UDP_PORT CONFIG_EXAMPLE_PORT
#define MULTICAST_LOOPBACK CONFIG_EXAMPLE_LOOPBACK
#define MULTICAST_TTL CONFIG_EXAMPLE_MULTICAST_TTL
#define MULTICAST_IPV4_ADDR CONFIG_EXAMPLE_MULTICAST_IPV4_ADDR
#define MULTICAST_IPV6_ADDR CONFIG_EXAMPLE_MULTICAST_IPV6_ADDR
#define LISTEN_DEFAULT_IF CONFIG_EXAMPLE_LISTEN_DEFAULT_IF
// Extracted from the event handler, normally triggered by different events denoting steps in the
// process of bringing up the interface:
esp_wifi_connect(); // Upon station start
tcpip_adapter_create_ip6_linklocal(TCPIP_ADAPTER_IF_STA); // Upon AP Association (STA_CONNECTED)
// Extracted from initialize_wifi function
tcpip_adapter_init();
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK( esp_wifi_init(&cfg) );
ESP_ERROR_CHECK( esp_wifi_set_storage(WIFI_STORAGE_RAM) );
wifi_config_t wifi_config = {
.sta = {
.ssid = EXAMPLE_WIFI_SSID,
.password = EXAMPLE_WIFI_PASS,
},
};
ESP_LOGI(TAG, "Setting WiFi configuration SSID %s...", wifi_config.sta.ssid);
ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_STA) );
ESP_ERROR_CHECK( esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config) );
ESP_ERROR_CHECK( esp_wifi_start() );
// The following statements come from a function called create_multicast_ipv6_socket()
struct sockaddr_in6 saddr = { 0 };
struct in6_addr if_inaddr = { 0 };
struct ip6_addr if_ipaddr = { 0 };
struct ip6_mreq v6imreq = { 0 };
int sock = -1;
int err = 0;
sock = socket(PF_INET6, SOCK_DGRAM, IPPROTO_IPV6);
// Standard error check applies if socket() fails.
saddr.sin6_family = AF_INET6;
saddr.sin6_port = htons(UDP_PORT);
bzero(&saddr.sin6_addr.un, sizeof(saddr.sin6_addr.un));
err = bind(sock, (struct sockaddr *)&saddr, sizeof(struct sockaddr_in6));
// Standard error check applies if bind() fails
bzero(&if_inaddr.un, sizeof(if_inaddr.un));
err = setsockopt(sock, IPPROTO_IPV6, IPV6_MULTICAST_IF, &if_inaddr,
sizeof(struct in6_addr));
uint8_t ttl = MULTICAST_TTL;
setsockopt(sock, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &ttl, sizeof(uint8_t));
// Standard error check(s) apply to above setsockopt() calls
v6imreq.imr_interface.s_addr = IPADDR_ANY;
err = setsockopt(sock, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP,
&v6imreq, sizeof(struct ip6_mreq));
// Standard error checks apply to above setsockopt() call
int only = 1; /* IPV6-only socket */
err = setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, &only, sizeof(int));
// Standard error checks apply to above setsockopt() call
return sock;
// The next function is called "mcast_example_task and takes a void pointer (*pvParameters)
// It calls the above socket creation function.
//Then it uses select() to wait for traffic.Upon receiving traffic, it hits this:
// First checks for an error returned from select()
else if (s > 0) {
if (FD_ISSET(sock, &rfds)) {
// Incoming datagram received
char recvbuf[48];
char raddr_name[32] = { 0 };
struct sockaddr_in6 raddr; // Large enough for both IPv4 or IPv6
socklen_t socklen = sizeof(raddr);
int len = recvfrom(sock, recvbuf, sizeof(recvbuf)-1, 0,
(struct sockaddr *)&raddr, &socklen);
//Usual error check on recvfrom()
if (raddr.sin6_family == PF_INET6) {
inet6_ntoa_r(raddr.sin6_addr, raddr_name, sizeof(raddr_name)-1);
}
ESP_LOGI(TAG, "received %d bytes from %s:", len, raddr_name);
recvbuf[len] = 0; // Null-terminate whatever we received and treat like a string...
ESP_LOGI(TAG, "%s", recvbuf);
//If timeout without receiving anything, something is sent using the following code:
static int send_count;
const char sendfmt[] = "Multicast #%d sent by ESP32\n";
char sendbuf[48];
char addrbuf[32] = { 0 };
int len = snprintf(sendbuf, sizeof(sendbuf), sendfmt, send_count++);
// Standard check for buffer overflow
struct addrinfo hints = {
.ai_flags = AI_PASSIVE,
.ai_socktype = SOCK_DGRAM,
};
struct addrinfo *res;
hints.ai_family = AF_INET6;
hints.ai_protocol = 0;
err = getaddrinfo(CONFIG_EXAMPLE_MULTICAST_IPV6_ADDR,
NULL,
&hints,
&res);
// Standard check for errors from getaddrinfo()
struct sockaddr_in6 *s6addr = (struct sockaddr_in6 *)res->ai_addr;
s6addr->sin6_port = htons(UDP_PORT);
inet6_ntoa_r(s6addr->sin6_addr, addrbuf, sizeof(addrbuf)-1);
ESP_LOGI(TAG, "Sending to IPV6 multicast address %s...", addrbuf);
err = sendto(sock, sendbuf, len, 0, res->ai_addr, res->ai_addrlen);
// Standard error check on sendto()
The app_main() function just calls the functions described above to initialize wifi and set up the multicast task.
Hopefully that's helpful. I apologize for my limited understanding here. I'm early in the process of learning some of this stuff. My previous experience is mostly on the application side, using these tools. This is my first real venture into contributing to them and I feel like I've fallen in the deep end.
Hi,
since some time has passed, I wanted to ask if there is any update on this. I would be very interested in having IPv6 support on Micropython because I see it as crucial.
Reacted by Volodymyr Shymanskyy, Jimmy Hedman, rmoriz, Wynton, Michael Gries, Sébastien RAMAGE, James Hannah, Sebastian, Steven A. Silva, Alexandre Cardim and 4 more
I just want to (not very helpfully) chime in that I'd like this too. IPv6 is the only way I can have random monitoring devices report back to my central reporting server reasonably
Activity
dpgeorge commentedon Mar 27, 2018
The unix port supports IPv6: you can create sockets with family AF_INET6 (=10) and then connect them to a remote IPv6 address. This is how it would work on any port that supports IPv6.
Most of the network module functions should be IP agnostic and allow you to connect to an IPv6 network. The ifconfig() method will need some enhancement to support IPv6.
The first step to get IPv6 working on the ESP32 would be to work out how to control the ESP IDF to get on a IPv6 network, then it can be seen how to incorporate this into the network module.
owendelong commentedon Mar 27, 2018
My understanding from looking at the ESP-IDF (admittedly, by far no expert) is that all of the existing LWIP libs include all the necessary IPv6 support and we just need to make the appropriate calls.
Unfortunately, from looking at the source for the ifconfig() PERL call in the ports/esp32 source code, I wasn't able to figure out how it crawled down into the LWIP code in the ESP-IDF to do its thing.
Further, I wasn't able to figure out enough about the generic WLAN startup code to figure out how to add IPv6 initialization so that it could "just work" with SLAAC (which is built into the LWIP code if we just turn on IPv6 AIUI).
owendelong commentedon Mar 27, 2018
Does the UNIX port have the ability to configure interfaces or does it depend on that being done outside of the MicroPython environment since it's running as an application inside an operating system instead of running as an operating system?
dpgeorge commentedon Mar 28, 2018
It doesn't have the
networkmodule so relies on network interfaces to be set up via the host OS.owendelong commentedon Mar 28, 2018
Which then renders it a less than useful port for the purpose of identifying or finding example code for porting IPv6 to any form of MCU such as the ESP32.
Not trying to be obnoxious, but hoping to find some code examples or something I can use to help contribute IPv6 work towards the ESP32. I think that the ESP32 version of the sockets/usockets module(s) has IPv6 capabilities as well, but that doesn't do any good if I can't get an IPv6 address on the underlying interface in the network module.
Are there any Micropython ports where MP controls the hardware that have the ability to put IPv6 on an interface through the network module?
dpgeorge commentedon Mar 28, 2018
No, not that I know of.
It's great that you want to help get IPv6 support working. The first place to start is understanding what calls to make to the ESP IDF to get the device connected on an IPv6 network and have it assigned an address. Wit that knowledge we can see how to incorporate it into the network module. Then move on to making socket work.
owendelong commentedon Mar 30, 2018
OK... I can definitely look into that. From what I understand, it should be pretty straight forward set of calls to LWIP, at least for SLAAC. I'm not sure if DHCPv6 is implemented in LWIP yet. I've seen conflicting reports, mostly negative.
The following page appears to have a workable code example for FreeRTOS: https://github.com/espressif/esp-idf/blob/master/examples/protocols/udp_multicast/main/udp_multicast_example_main.c
I think the relevant code snippets are:
The app_main() function just calls the functions described above to initialize wifi and set up the multicast task.
Hopefully that's helpful. I apologize for my limited understanding here. I'm early in the process of learning some of this stuff. My previous experience is mostly on the application side, using these tools. This is my first real venture into contributing to them and I feel like I've fallen in the deep end.
stucchimax commentedon Sep 17, 2019
Hi,
since some time has passed, I wanted to ask if there is any update on this. I would be very interested in having IPv6 support on Micropython because I see it as crucial.
HeMan commentedon Sep 23, 2019
Is there any branch or fork working on IPv6?
oclyke commentedon Jul 22, 2021
just submitted a very small PR aimed at supporting ipv6 in
uasyncio. would really appreciate input/feedback!#7563
johannes-mueller commentedon Dec 11, 2022
Any progress on this?
fireduck64 commentedon Mar 25, 2023
I just want to (not very helpfully) chime in that I'd like this too. IPv6 is the only way I can have random monitoring devices report back to my central reporting server reasonably
Carglglz commentedon Mar 26, 2023
@fireduck64 check #11111
digits122 commentedon Jul 12, 2023
Any progress now?
dpgeorge commentedon Mar 19, 2024
A new API for IPv6 on bare-metal lwIP ports has been implemented in 1c6012b
The next thing to do would be to implement that API for esp32.
wklaebe commentedon Mar 21, 2024
I'm interested too, especially together with mDNS. I want to have a microdot HTTP server reachable via a .local name via IPv6.
HeMan commentedon Mar 26, 2024
Has anyone started an implementation yet? I recently did some work with IPv6 on ESPHome and could probably help.
ADV1K commentedon Apr 19, 2024
Looking forward to the day when I could host my blog on ESP32 with IPv6!
sjlongland commentedon Jan 25, 2026
Can't comment on ESP32, but I have a RP2350 here (Pimironi Interstate 75W):
At the very least, SLAAC is working, but I am getting stuck with joining a multicast group because
socket.IPPROTO_IPV6isn't defined.