Fedora-based router with DHCPv6-PD support

I threw together some hardware I had on hand to make a PC-based router.


Getting IPv4 working was easy, I just needed to set ZONE=external and ZONE=trusted on the wan/lan interface ifcfg-* files. I threw net.ipv4.ip_forward=1 in /etc/sysctl.conf as well.

I setup a private subnet for my lan interface, and configured and started dnsmasq. More detail on the dnsmasq configuration is down in the "IPv6 (DHCPv6 server/RA)" section.

For port forwarding, I add the statement below to /etc/firewalld/zones/external.xml and reload the firewall with: firewall-cmd --reload

<forward-port to-addr="" to-port="1234" protocol="tcp" port="4321"/>


For IPv6, I needed to add IPV6FORWARDING=yes in /etc/sysconfig/network, and the following lines on my wan interface ifcfg-* file:


IPv6 (DHCPv6 client/Prefix Delegation)

I had to add the DHCPv6 protocol to the firewall: firewall-cmd --zone=external --add-service=dhcpv6-client --permanent

I first tried with dhclient's DHCPv6 support, but I ran into this bug: Prefix Delegation and Address assignment do not work together.

I installed the wide-dhcpv6 package, and use this as my /etc/wide-dhcpv6/dhcp6c.conf file:

interface enp4s0 { # wan interface
    send ia-na 1; # request an interface address to satisfy "id-assoc na 1" below
    send ia-pd 1; # request a prefix to satisfy "id-assoc pd 1" below
    script "/etc/wide-dhcpv6/dhcp6c-script"; # this script handles IPv6 recursive DNS

id-assoc pd 1 {
  prefix-interface enp5s0 { # lan interface
    sla-id 0; # use the 1st subnet from the PD
    ifid 1; # use ::1 as the local address
    sla-len 0; # since we requested a /64, use all of it

id-assoc na 1 {
  # interface address options

I then setup a startup script /etc/systemd/system/dhcp6c@.service:

Description=DHCPv6 client on %I

ExecStart=/sbin/dhcp6c -c /etc/wide-dhcpv6/dhcp6c.conf -p /var/run/dhcp6c-%I.pid %I -f


I then told systemd to start this script on the wan interface: systemctl enable dhcp6c\@enp4s0; systemctl start dhcp6c\@enp4s0

This gave me an IPv6 address on my wan interface and a subnet on my lan interface. The downside of doing it this way is the dhcpv6 client doesn't automatically restart if I down the interface and bring it back up.

IPv6 (DHCPv6 server/RA)

Next, I wanted to use dnsmasq as my DHCP server for both v4 and v6, as well as sending RAs. I chose to use SLAAC instead of managed v6 addresses. My /etc/dnsmasq.conf:

# listen on the lan interface
# publish /etc/hosts and DHCPv4 hostnames as *.lan
# is the lan subnet
# pick up the lan v6 subnet from the interface, use SLAAC, auto-detect the v6 addresses of DHCPv4 clients
dhcp-range=::2,::400,constructor:enp5s0, ra-stateless, ra-names

I then set dnsmasq to start: systemctl enable dnsmasq; systemctl start dnsmasq

Bandwidth usage

I setup vnstat to collect bandwidth usage info. The only change to /etc/vnstat.conf was the Interface. Then I started it: systemctl enable vnstat ; systemctl start vnstat

Power usage

I setup a script to limit the cpu frequency, to limit power usage (48W at 1ghz idle, ~100W at 2.3ghz), /etc/systemd/system/powersave.service

Description=powersave - lower power usage
After=systemd-readahead-collect.service systemd-readahead-replay.service

ExecStart=/bin/sh -c "/bin/cat /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_min_freq >/sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq"



Even at 1ghz, this system can handle around 700Mbit/s. So that's plenty fast for me. Unfortunatly, it's using 9x more electricity than the MIPS or the ARM router (which are both in the 5W range). This is around $38/year more in electricity, so that's not too bad. I suspect the motherboard is using most of the power, as the CPU heatsink is cool to the touch while the northbridge heatsink is hot. The CPU itself is rated as "65W", but I don't think a lower power CPU would help as much as a motherboard designed for lower power.