extmod/modlwip: Support IPv6.

With these changes IPv6 works on the rp2 port (and possibly others that use
the lwIP socket implementation).

Things that have been tested and work:
- Neighbour solicitation for v6 link local address.
- Ping of v6 link-local address.
- Receiving a SLAAC address via router advertisement.
- Ping a v6 address allocated via SLAAC.
- Perform an outgoing connection to a routed v6-address (via default
  gateway).
- Create a listening IPv6 wildcard socked bound to ::, and trying to access
  it via link-local, SLAAC, and IPv4 (to ensure the dual-stack binding
  works).

Things that could be improved:
- socket.socket().getaddrinfo only returns the v4 address.  It could also
  return v6 addresses (getaddrinfo is actively programmed to only return a
  single address, and this is the v4-address by default, with fallback to
  the v6 address if both are enabled).

Signed-off-by: Felix Dörre <felix@dogcraft.de>
This commit is contained in:
Felix Dörre
2022-08-25 17:25:08 +00:00
committed by Damien George
parent 866fc3447c
commit 628abf8f25
3 changed files with 60 additions and 33 deletions

View File

@@ -113,7 +113,7 @@ static void dhcp_socket_free(struct udp_pcb **udp) {
static int dhcp_socket_bind(struct udp_pcb **udp, uint32_t ip, uint16_t port) {
ip_addr_t addr;
IP4_ADDR(&addr, ip >> 24 & 0xff, ip >> 16 & 0xff, ip >> 8 & 0xff, ip & 0xff);
IP_ADDR4(&addr, ip >> 24 & 0xff, ip >> 16 & 0xff, ip >> 8 & 0xff, ip & 0xff);
// TODO convert lwIP errors to errno
return udp_bind(*udp, &addr, port);
}
@@ -131,7 +131,7 @@ static int dhcp_socket_sendto(struct udp_pcb **udp, struct netif *netif, const v
memcpy(p->payload, buf, len);
ip_addr_t dest;
IP4_ADDR(&dest, ip >> 24 & 0xff, ip >> 16 & 0xff, ip >> 8 & 0xff, ip & 0xff);
IP_ADDR4(&dest, ip >> 24 & 0xff, ip >> 16 & 0xff, ip >> 8 & 0xff, ip & 0xff);
err_t err;
if (netif != NULL) {
err = udp_sendto_if(*udp, p, &dest, port, netif);
@@ -205,7 +205,7 @@ static void dhcp_server_process(void *arg, struct udp_pcb *upcb, struct pbuf *p,
}
dhcp_msg.op = DHCPOFFER;
memcpy(&dhcp_msg.yiaddr, &d->ip.addr, 4);
memcpy(&dhcp_msg.yiaddr, &ip_2_ip4(&d->ip)->addr, 4);
uint8_t *opt = (uint8_t *)&dhcp_msg.options;
opt += 4; // assume magic cookie: 99, 130, 83, 99
@@ -248,7 +248,7 @@ static void dhcp_server_process(void *arg, struct udp_pcb *upcb, struct pbuf *p,
// Should be NACK
goto ignore_request;
}
if (memcmp(o + 2, &d->ip.addr, 3) != 0) {
if (memcmp(o + 2, &ip_2_ip4(&d->ip)->addr, 3) != 0) {
// Should be NACK
goto ignore_request;
}
@@ -280,9 +280,9 @@ static void dhcp_server_process(void *arg, struct udp_pcb *upcb, struct pbuf *p,
goto ignore_request;
}
opt_write_n(&opt, DHCP_OPT_SERVER_ID, 4, &d->ip.addr);
opt_write_n(&opt, DHCP_OPT_SUBNET_MASK, 4, &d->nm.addr);
opt_write_n(&opt, DHCP_OPT_ROUTER, 4, &d->ip.addr); // aka gateway; can have multiple addresses
opt_write_n(&opt, DHCP_OPT_SERVER_ID, 4, &ip_2_ip4(&d->ip)->addr);
opt_write_n(&opt, DHCP_OPT_SUBNET_MASK, 4, &ip_2_ip4(&d->nm)->addr);
opt_write_n(&opt, DHCP_OPT_ROUTER, 4, &ip_2_ip4(&d->ip)->addr); // aka gateway; can have multiple addresses
opt_write_u32(&opt, DHCP_OPT_DNS, DEFAULT_DNS); // can have multiple addresses
opt_write_u32(&opt, DHCP_OPT_IP_LEASE_TIME, DEFAULT_LEASE_TIME_S);
*opt++ = DHCP_OPT_END;