Hi Hurd,
I wrote a few patches for lwip. After Roy Marples reworked the Hurd port,
the interfaces in the Hurd are now configured via hooks instead of ioctls.
The pfinet hook uses fsysopts to reconfigure the stack, and I thought we could
reuse it for lwip as well. However, lwip doesn't respond to fsysopts the same
way
pfinet does. Pfinet merges the new config received via ioctls with its previous
config, so you only need to configure the delta. This is what the dhcpcd hook
does:
`fsysopts /servers/socket/2 -i "$ifxname" -a "$new_ip_address" $flags`
Lwip always removes the old config and replaces it with the received one. So,
to be able to apply a delta, we'd need something like:
`fsysopts /servers/socket/2 $(fsysopts /servers/socket/2) -i "$ifxname" -a
"$new_ip_address" $flags`
I haven't tested this, I thought it would be better to just make lwip translator
mimic what pfinet does. So I wrote the attached patches.
During the process, I found a few bugs and inconsistencies in the lwip
translator,
and fixed them. Below is description for each patch:
- [PATCH 1/4] lwip: switch inquire_device()/configure_device() to
ip4_addr_t/ip6_addr_t
`inquire_device()` and `configure_device()` are two functions I copied from
the pfinet translator and adapted them to work with lwip. They accept a few
parameters type `uint32_t` to get/set the IP config. In lwip that requires
back-and-forth conversion, and some pointer arithmetic to ensure everything
is written in the right place. Besides, it doesn't always work because the
structures in lwip can have different fields and size based on some macros
being defined or not.
The patch updates the prototypes to use the lwip native types `ip4_addr_t`
and `ip6_addr_t` to reduce complexity.
It also removes the ipv6 prefix param for `configure_device`, since lwip
doesn't accept setting this field
- [PATCH 2/4] lwip: clean up IPv6 address handling in init_ifs and
inquire_device
This is a cleanup after the previous patch. It fixes some bugs and
inconsistencies:
1. Don't set IPv6 as tentative after calling `netif_add_ip6_address`, since
it's done automatically by the stack
2. Don't set multicast IPv6 addresses to any interface. We already set this
control in `init_ifs` (called when iface is reconfigured via fsysopts). We
add it here in `update_if` (called when iface is reconfigured via ioctls),
for consistency.
3. Removed dead code in `update_if` that was writing the ipv6 prefixes to
nowhere. Also, now is consistent with `init_ifs`.
4. Memset all ipv6 slots to 0 in `inquire_device`. Some ipv6 addresses were
leaking between interfaces due to missing this step.
5. Don't return invalid addresses in `inquire_device`
6. Simplify ipv6 assignment in `inquire_device` now we use native types
7. For the prefix, lwip sets fixed values, 64 when the address is stati,
(set by the user, or link-local) 128 otherwise (received via SLAAC)
- [PATCH 3/4] lwip: load existing interface config before parsing
fsysopts
This is the patch that mimics pfinet behavior, merging instead of replacing.
Just a new function to load existing config before parsing the new one. Then
the full new config is sent to `init_ifs`.
- [PATCH 4/4] lwip: treat zero/invalid IPv4 addresses as unset in
init_ifs
This is also for consistency, `update_if` (when ioctls) already does this:
https://cgit.git.savannah.gnu.org/cgit/hurd/hurd.git/commit/?id=ecbc38df9f62ecffd1349b6f3b4fd234dbc08fe4
This is the same but for `init_ifs` (when fsysopts). Dhcdcd needs this when
it wants to unconfigure an interface.