alone develop against. It only ever hands out a single prefix and
would need a factory reset afterwards. It also does not route the
delegated prefix but depends on [[https://www.rfc-editor.org/rfc/rfc4389][ND Proxy.]]]. Time to hack on this.
* DHCPv6-PD
[[https://www.rfc-editor.org/rfc/rfc8415][DHCPv6]] is not wildly deployed outside of enterprise
networks[fn::Because of android refusing to implement it.]. DHCP for
Prefix Delegation (DHCPv6-PD) on the other hand is *the standard* to
get IPv6 prefixes into home networks. [[https://www.rfc-editor.org/rfc/rfc8415#section-6.3][RFC 8415]] has this:
#+begin_quote
It is appropriate for situations in which the delegating router (1)
does not have knowledge about the topology of the networks to which
the requesting router is attached and (2) does not require other
information aside from the identity of the requesting router to choose
a prefix for delegation. This mechanism is appropriate for use by an
ISP to delegate a prefix to a subscriber, where the delegated prefix
would possibly be subnetted and assigned to the links within the
subscriber's network.
#+end_quote
* Transmogrifying dhcpleased(8)
This not being my first rodeo, it took me about 4 hours over a weekend
to transmogrify [[https://man.openbsd.org/dhcpleased.8][=dhcpleased(8)=]] into =dhcp6leased(8)= and have it talk
to my Fritz!Box. I have also setup [[https://www.isc.org/kea/][ISC's Kea DHCP server]] for easier
development and to not risk my production network at home. Of course
it is not yet able to configure the system, but it can request a
prefix delegation from the server and parse the response. This is
enough to play with the protocol and work on the grammar for the
configuration file.
* Describing network topology
=dhcp6leased(8)= will not just request an IPv6 prefix delegation but
also use the delegated prefix to assign prefixes to downstream network
interfaces. [[https://man.openbsd.org/rad.8][rad(8)]] can then be used to send router advertisements for
clients to get IPv6 connectivity on different subnets in the home
network.
The typical use case is probably to have a few networks connected to
the OpenBSD router using vlans[fn::Maybe one vlan for WiFi, one for IOT
and one for guest WiFi.] and assign =/64= prefixes to each one of
them.
A more advanced use case would be to assign prefixes of different
lengths to the vlan interfaces. For example I have a whole (virtual)
network lab hanging off of an OpenBSD router which is not a single
flat network. I need to assign a =/60= to that interface[fn::The IETF
never managed to fully standardize this. I hear this is where homenet
failed. A less ambitious working group is working in this problem
space now: [[https://datatracker.ietf.org/wg/snac/about/][Stub Network Auto Configuration for IPv6 (snac)]]. But they
only want to deal with flat networks.] to have enough space to subnet
further.
Now, DHCPv6-PD allows us to request multiple prefixes. We could just
punt the problem of splitting a bigger prefix into smaller prefixes to
the DHCPv6 server. However, the [[https://www.rfc-editor.org/rfc/rfc8415#section-6.6][RFC has this]]:
#+begin_quote
In principle, DHCP allows a client to request new prefixes to be
delegated by sending additional IA_PD options (see Section 21.21).
However, a typical operator usually prefers to delegate a single,
larger prefix. In most deployments, it is recommended that the client
request a larger prefix in its initial transmissions rather than
request additional prefixes later on.
#+end_quote
And indeed, the Fritz!Box only gives us one prefix. We can hand the
prefix back and request a larger one, but it will only honour a single
=IA_PD= option in a solicit message.
This means we have to split up the prefix ourselves. This is perfectly
simple if we are only dealing with =/64= networks. Just count the
networks, round up to the nearest power of two and calculate the
required prefix size from that.
This gets more complicated if the prefix lengths for our sub-networks
are non-uniform, like in the more advanced use case.
I went a bit on a tangent and tried to solve this for the general
case. That means arbitrary subnet sizes and an optimal packing in the
delegated prefix. I think that would come down to the [[https://en.wikipedia.org/wiki/Bin_packing_problem][Bin packing
problem]] which is... annoying[fn::Otherwise known as NP-hard.].
I then noticed that we want a stable assignment, meaning when we add
or remove an interface we do not want to renumber all the existing and
remaining interfaces. Which would happen if try to come up with an
optimal solution because prefix assignments would most likely shift
around every time we change something.
* dhcpcd's solution
At this point I was somewhat stuck and I had a look at how dhcpcd
deals with this. While I was already using dhcpcd in my network, I had
not yet setup the more advanced use case with a =/60= and multiple
=/64=. I was pretty sure that dhcpcd can handle this, but I did not
yet know how.
Disclaimer: What follows are my notes on how I got it to work. It is
likely that I am doing things wrong and misunderstand some
parts. Unfortunately I no longer have access to GitHub[fn::An
alternative reading is: I refuse to use it because they decided I am a
suplier, which I am not. And they locked me out of my account.], so I
cannot open an issue with the project to ask for help with this. I am
very sorry.
Here is the relevant part from the [[https://man.freebsd.org/cgi/man.cgi?query=dhcpcd.conf&apropos=0&sektion=0&manpath=FreeBSD+14.0-RELEASE+and+Ports&arch=default&format=html][dhcpcd.conf man page:]]