When most IPv6-capable computers join a network they attempt to automatically find a router on the network so they can figure out what addresses to use, how to set up routing, and so forth. On BSD systems like my router, the rtadvd(8) program manages the router’s side of this exchange. While rtadvd is rather flexible, its configuration file is frustratingly terse and its documentation assumes the reader has a fair amount of knowledge already.

For IPv4, my network uses DHCP to hand out addresses and DNS information. When rolling out IPv6, I wanted to set things up similarly, but without managing addresses centrally with DHCP since machines can configure themselves correctly without one. Configuration like this is the sort of thing that I tend to forget and have to re-learn periodically, so for reference, the rtadvd.conf file I used for that setup looked something like this:

vether0:\
    :addr="2001:db8:1221::":\
    :prefixlen#64:\
    :raflags#64:\
    :rdnss="2001:db8:1221::1,2001:4860:4860::8888,2001:4860:4860::8844":\
    :dnssl="internal.example.com":

This makes machines configure themselves for the network 2001:db8:1221::/64, DNS domain internal.example.com, and three DNS servers: a local one at 2001:db8:1221::1, and both of Google’s public servers.

The source of most of my confusion was figuring out the raflags option. raflags is a bit mask with two flags: M, which means a DHCP server manages addresses, and O, which means that non-address-related information (in this case, DNS information) is available that way even if addresses are not. This network setup requires the O flag to be set and the M flag to be unset, which means raflags has to be 64.

Now that I’ve rolled this out I get all the niceness of auto-configuration without the need for a central DHCP server to keep track of addresses. Well, for IPv6, at least.