IPv6 prefix delegation on FreeBSD router
Goal
I’m attempting to set up a router box in order to replace my SFR router on a home network. As my SFR plan has native IPv6, this box will request a prefix delegation and set up IPv6 routing for the computers on the home network. It will also handle NAT for IPv4.
This is supposed to be a drop-in replacement for the SFR provided box, so it will have to:
- Get an IPv4 via DHCP
- Get an IPv6 PD via DHCPv6
- Announce itself as an IPv6 router to the internal network via SLAAC
How this works
- The router box will ask for a prefix from the provider. This is usually a /56 or larger.
- The router configures an IP from a subprefix of the provided prefix on the internal interfaces.
- The router then advertises this prefix as well as itself to clients over the internal interface.
Prerequisites
This is based on the following:
- A box with two or more network interfaces
- FreeBSD 11.2 (tested on FreeBSD 11.2-release-p2)
- KAME DHCP6 (tested on dhcp6-20080615.2)
- rtadvd (from base installation)
Configuration
The following examples are based on the following convention:
re0
is the wan interface, going to my ISP.re1
is the lan interface, going to my internal network.bridge0
is an internal bridge for hosting VMs that run on the router.
System
Set the following sysctls in /etc/sysctl.conf
:
|
|
This is not strictly necessary, as it is handled by ipv6_cpe_wanif
in rc.conf
.
Set up interfaces and enable routing in rc.conf
(see manual):
|
|
DHCPv6 client
This is required to request a prefix delegation from the ISP. Note that this won’t setup a routable address on the wan interface. As this is supposed to be a router, it’s not required. IPv6 communication to the router is done via link local addresses.
Install KAME/WIDE dhcp6c client with pkg (or from net/dhcp6 in ports):
|
|
Add to /usr/local/etc/dhcp6c.conf
(see manual):
|
|
My ISP delegates me a /56. If I want to obtain a /64, I have to cut 8 bits from it. This is what the sla-len 8
statement does.
What basically happens is it builds an IPv6 of the following form: prefix:sla:local_addr
. This is then configured on the interface corresponding to the prefix-interface
statement. This is on the client side.
The sla becomes part of the prefix as advertised to the client subnets.
rtadvd
This is a daemon that works on the client side of the router and handles host autoconfiguration via SLAAC:
- It announces the prefix of the interface to the hosts connected to that interface by periodically sending router advertisements and responding to router solicitations.
- It announces itself as the router for the segment by replying to neighbour solicitations and sending gratuitious neighbour advertisments.
rtadvd is part of the FreeBSD base system. It expects its configuration in /etc/rtadvd.conf
(see manual):
|
|
If the prefixes on the client side are dynamic, as is the case when handled via dhcp6c, there is no need to specify them in the configuration file. rtadvd will use the ones configured on the interface and handle prefix changes.
If you need different settings per interface, you can specify the interface name instead of default in the config file.
Firewall
If you’re using PF, be sure to only NAT IPv4 packets. The below configuration shows what’s required to allow IPv6 autoconfiguration.
|
|
As dhcp6c doesn’t get a route, it’s necessary that the router be able to send router solicitations and receive advertisments on the wan interface (see entry for ipv6_cpe_wanif
in rc.conf manual).
Add other firewall rules as necessary. The above rules won’t allow ping for example.
References
Resources that have helped me along the way: