Vladimir Sedach

Have Emacs - Will Hack

July 31, 2018

IPv6 home LAN with OpenBSD part 2: connecting to the IPv6 Internet

The previous post covered how to set up IPv6 on a LAN. The next step is to connect the LAN to the Internet.

My ISP hands out IPv6 addresses using DHCPv6. I have read that most ISPs do the same. DHCPv6 can be used to hand out either individual addresses (non-temporary address allocation) or whole network prefixes (prefix delegation). My ISP hands out generous /8 prefixes.

The router's LAN-facing interface, vether0, will be assigned an IP address by the DHCPv6 client prefix-delegation request. vether0 will hand out /64 host addresses to hosts on the LAN using IPv6 autoconfiguration.

The most complicated part of the configuration turned out to be the DHCPv6 client settings. I found I had to request a non-temporary address lease for the egress interface, in addition to a lease for my network prefix. The prefix goes to your local network, so the router becomes reachable on both the address leased to the egress interface (em3), and on one or more of the addresses assigned from the prefix to the internal interface (vether0).

OpenBSD 6.3 does not come with a DHCPv6 client, but there are several ones available in ports. I went with wide-dhcpv6.

interface em3 {
	send ia-pd 0;
	send ia-na 1;

id-assoc pd 0 {
	prefix ::/56 31536000 31536000;
	prefix-interface vether0 {
		sla-id 1;
		sla-len 8;

id-assoc na 1 {

sla-len should match the prefix value (they should add up to 64, the number of bits identifying the network part of a global unicast address). The two 31536000 (1 year in seconds) values are the preferred and valid lifetimes that you would like to request for the prefix. Your ISP's server will probably ignore them; mine does and hands out one week leases. sla-id is the actual prefix number that will be assigned on that interface. It can be anything from 0 up to the size of the prefix you are assigned. Of course you get control of the whole prefix and can use the rest of the subnets too.

You can check the configuration and see what the DHCPv6 server hands out to you by running dhcp6c(8) in the foreground with a debug flag: dhcp6c -d -f em3. Note the preferred and valid lifetime values assigned - you can use these to set rtadvd(8) settings for handing out addresses on your LAN as an extra sanity check to prevent stale addresses from sticking around.

Route setup is done with autoconf and not DHCPv6 (unlike IPv4, where DHCP is responsible for providing the default gateway), so you still need to turn on autoconf for the egress interface to get the default route automatically configured.

inet6 autoconf
!/usr/local/sbin/dhcp6c $if

The wide-dhcpv6 package does not come with an rc.d file; sticking it in hostname.X works.

At this point, vether0 should be assigned an address from the leased prefix, and route -n show should show the link-local address of your ISP router as the default route:

Destination                        Gateway                        Flags   Refs      Use   Mtu  Prio Iface
default                            fe80::AAAA:AAAA:AAAA:AAAA%em3  UGS        0       11     -    56 em3

Now you can start handing out IPv6 addresses on your internal network:


Here we specify the autoconfigured address valid time to one week (maximum for which my ISP leases a prefix).


Note that rtadvd(8) will be replaced with rad(8) in OpenBSD 6.4.

Don't forget to make sure pf NAT is applied only to IPv4 (inet) traffic:

pass out on em3 inet from vether0:network to any nat-to (em3)

Run pfctl -s rules to look for any other rules that are being inadvertently applied to IPv6 traffic, and to see which rules are not and should be.

On the client side:

inet6 autoconf

route -n show should show the link-local address of vether0 as the default route:

Destination                        Gateway                        Flags   Refs      Use   Mtu  Prio Iface
default                            fe80::BBBB:BBBB:BBBB:BBBB%bge0 UGS        0       18     -    56 bge0

Hopefully now you can view this site via IPv6. I recommend installing the SixOrNot Firefox extension and configuring it to display which protocol you are using to load a website.