I’ve already set up an IPv6 tunnel on three platforms: Vyatta, Cisco and Windows Server. This time, the same on OpenBSD. I’m not going to repeat myself, so for details about an IPv6 tunnel and how to get one, check the IPv6 tunnel article. I’ll be using  the same example values again:
Local IPv6 subnet:  2001:0:0:1234::/64
Tunnel subnet: 2001:0:0:1235::/64, with ::2 on our side and ::1 on the other endpoint side.
IPv6 DNS: 2000::2000
Device IPv4 address:
Tunnel endpoint:
Gateway to ISP:

I assume routing and IPv4 is configured properly already, with IP’s on interfaces and a default route towards the internet. If not, you’ve missed part I. Before starting the IPv6 part, remember that you’ll be creating a tunnel over an existing IPv4 network, so make sure pf allows the tunnel. I’ve added the following rules in /etc/pf.conf:

pass out quick on em0 from to
pass in quick on em0 from to

You’ll need to pass both ipv6ip and icmp, but since it’s just one trusted IP address, I’m doing a general rule. Don’t forget to activate the rule with ‘pfctl -f /etc/pf.conf’!

Next, creating the tunnel interface. In OpenBSD this is a ‘gif’, generic interface. To make it persist between reboots, create a /etc/hostname.gif0 file, zero for the first tunnel interface. The following lines go in the file:

!ifconfig gif0 inet6 alias 2001:0:0:1235::2 2001:0:0:1234::1 prefixlen 128
!route add -inet6 default 2001:0:0:1235::1

The internal IP is automatically translated by my router, but this may not always be the case. If not, use your external IP. The prefix length in the second line is 128, which is advised in the tunnelbroker configuration sample, but I’m not sure why. It wouldn’t work with 64 though. Finally, the third line adds a default route into the tunnel.

At this point the tunnel is up and running, but from the OpenBSD only. The devices on the connected subnet are not aware an IPv6 router is present. For this, the OpenBSD will have to send router advertisements. First, configure an IPv6 address on the interface, by adding the following line to /etc/hostname.em1:

!ifconfig em1 inet6 alias 2000:0:0:1234::1 prefixlen 64

Next, do the actual advertisements using the rtadvd deamon. In /etc/rc.conf, find the ‘rtadvd_flags:NO’ and change the ‘NO’ to the interface(s) that need it enabled, e.g. em1. Then create the file /etc/rtadvd.conf’ and enter the following:


This advertises the /64 prefix on the interface. A lot of other options are possible, such as the other-config-flag and managed-config-flag for DHCP options and a IPv6 DNS server, but I will not go into detail about that now. Finally, keep in mind icmp is used for router advertisements and neighbor discovery (the ARP replacement), so you’ll need to allow these. In /etc/pf.conf:

pass out quick on em1 inet6 proto icmp6
pass in quick on em1 inet6 proto icmp6

Finally, add some rules based on what you want to filter, e.g. a general rule blocking everything IPv6 inbound, and allowing outgoing connection of any kind (for now):

pass out quick on gif0 inet6 from 2000:0:0:1234::/64 to any
block in on gif0

After this, surfing to ipv6.google.com is possible from any computer in the local subnet.