-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
Add IPv6 support for Espressif #9436
Conversation
Otherwise, it was not possible to interact with a v6 address, as `lwip_getaddrinfo` wouldn't resolve it.
* metro esp32s2 only, because that's what I had handy * nothing is started at boot; I hung it on `start_dhcp()` which is dubious * I get a stateless address (which doesn't seem to work) and a dhcpv6 address (which does) ``` >>> wifi.radio.ipv6_addresses ('FE80::7EDF:A1FF:FE00:518C', 'FD5F:3F5C:FE50:0:7EDF:A1FF:FE00:518C') ``` * depending whether a v4 or v6 dns server is configured, DNS resolution breaks wrong ipv4_dns is first 4 bytes of the v6 dns server address: ``` >>> wifi.radio.ipv4_dns 253.95.63.92 ``` * I can connect to a v4 or v6 SSH server on the local network and read its banner >>> s.close(); s = socket.socket(socket.AF_INET6, socket.SOCK_STREAM); s.connect(("fd5f:3f5c:fe50:0:6d9:f5ff:fe1f:ce10", 22)) *** len[0]=28 *** len=28 family=10 port=5632 >>> s.recv_into(buf) 40 >>> bytes(buf) b'SSH-2.0-OpenSSH_9.2p1 Debian-2+deb12u3\r\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
only tested recvfrom_into as can't bind() v6 addresses yet wifi workflow may be broken by this or maybe it was broken before
.. & make web workflow bind to v6 if available. Binding v6 "any" address also allows v4 connections
to accomodate multiple servers some day
* v6 on by default * dhcp can start v4 & v6 separately * self documenting property for v4 & v6 support * v4 support is always on .. for now
|
Other modules & libraries may need to be updated in order to support v6. For instance, do adafruit_requests & adafruit_ntp work properly with v6 addresses & names? Since our focus is on v6 for matter support, I did not investigate this or file issues. |
good news! this does seem to set ipv6 mdns records:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A few questions. It all looks pretty good. Thanks for figuring this out!
I don't have an in-depth understanding of IPv6, so I could be off-base on this. Do we know if the It could be that the DHCP server will take care of this, but's that's dependent on the DHCP server implementation (https://media.defense.gov/2023/Jan/18/2003145994/-1/-1/1/CSI_IPv6_security_guidance_.PDF, p.2). |
I'm happy to change this to default v6 off until we understand the ramifications better. @tannewt say the word |
Found this:
This is probably the original SLAAC mechanism, and may be a permanent address embedding the hardware MAC address (could be verified with testing). Addendum:
>>> import wifi, os
>>>
>>> wifi.radio.connect(os.getenv("WIFI_SSID"), os.getenv("WIFI_PASSWORD"))
>>> wifi.radio.addresses
('192.168.6.243',)
>>> wifi.radio.start_dhcp()
>>> ':'.join('%02X' % _ for _ in wifi.radio.mac_address)
'F4:12:FA:RE:DA:CT'
>>> wifi.radio.addresses
('FE80::F612:FAFF:FERE:DACT', 'FD41:2E18:D0BA:9740:F612:FAFF:FERE:DACT', '192.168.6.243')
# ^^^^:^^. ^^:^^^^. ^^^^:^^. ^^:^^^^ Indeed, the IPv6 address contains the hardware MAC address (with a slight algorithmic manipulation common to SLAAC IPv6 creation). So I would encourage keeping IPv6 off by default. A partial workaround......could be to initially, and then periodically, randomize the MAC address: mac = bytearray()
for _ in range(0, 6):
mac.append(random.randrange(0, 256))
mac[0] = mac[0] | 0b00000010 # local on, if desired
mac[0] = mac[0] & 0b11111110 # multicast off
wifi.radio.mac_address = mac However, even with the partial workaround, the SLAAC IPv6 address still contains the local network prefix. |
Default off is fine with me. That'll make its use explicit which will make more sense if we throw an exception to say it is unsupported. |
* don't enable ipv6 by default due to privacy concerns * move list of board support for ipv6 to socketpool documentation * removed wifi.supports_ipvx properties * throw an exception when start_dhcp_client(ipv6=True) but not supported
OK, default is now off, non-standard attributes in wifi module are removed, and attempting to enable v6 dhcp when not supported gets an exception. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great! Thank you for digging into this.
What works:
presently you have tostart_dhcp
to get v6 addressesAddresses & ping:
I added name resolution to wifi ping (espressif only):
NTP manually:
http manually:
Todo (some may end up as subsequent PRs):
wifi.radio.start_dhcp()
but not on wifi workflow. not sure where dhcp4 is started{start,stop}_dhcp_client
to gain 2 kwarg-only arguments, defaulting to trueFuture PRs: