Using an OpenWRT router for 2degrees (Snap) IPv6

2degrees Broadband (previously Snap) offer IPv6 to all their residential customers, with the preferred method to use one of their CPEs the Fritzbox 7340 or the Fritzbox 7390. These devices come with a price premium, so I decided to look for a cheaper alternative with what I already have. I have a Draytek Vigor 120 and a TP-Link TL-WR1043ND with OpenWRT installed. I use the Vigor 120 in bridged mode to allow my WR1032ND to hold up the connection using PPPoE. This should work on their ADSL2+, and UFB connections (you can VLAN tag the WAN port as VLAN10 which I believe is required for UFB, but I won’t go into how to do this). I am unsure if it will work with VDSL2 however.

I am unsure whether this method will work with a non bridged modem (unless of course it’s capable of doing IPv6 itself, in which case you probably don’t want this tutorial), but I suspect it won’t as your PPP session needs to be assigned a link-local IPv6 address.

This assumes you are already using PPPoE to connect via an OpenWRT box, if you’re not I advise setting this up first. The OpenWRT website provides excellent instructions on how to do this.

The first step needed is to install the required packages into OpenWRT. I am using Attitude Adjustment, but have previously used Backfire so these settings should still work.

ppp-mod-pppoe for pppoe connectivity
kmod-ipv6
wide-dhcpv6-client
radvd

The first step to do is to enable IPv6 negotiation on your PPP link. This can be done through luci under Network > Interfaces > WAN > Advanced Settings and selecting Enable IPv6 negotiation on the PPP link. Alternatively if you prefer to edit the configuration files you can add option ipv6 ‘1’ to your /etc/config/network file under config interface ‘wan’

Snap use DHCPv6 to allocate you a dynamic IPv6 prefix (they don’t provide static IPv6 prefixes yet, they really should but I understand this is a work in progress). Therefore you need to use a DHCPv6 client to get it.

The /etc/config/dhcp6c file should already exist. Edit it and change the enabled, interface, pd, and config interface ‘lan’ settings to be the same. Do not configure a prefix on the WAN interface. I find it causes IPv6 to not work. If it doesn’t create it and copy the following into it.

config 'dhcp6c' 'basic'
        option 'enabled' '1'                            # 1 = enabled; 0 = disabled
        option 'interface' 'wan'                        # This is the interface the DHCPv6 client will run on
        option 'dns' 'dnsmasq'                          # Which DNS server you run (only dnsmasq currently supported)
        option 'debug' '0'                              # 1 = enable debugging; 0 = disable debugging

        # Send options (1 = send; 0 = do not send)
        option 'pd' '1'                                 # Prefix Delegation
        option 'na' '0'                                 # Non-Temporary Address
        option 'rapid_commit' '1'                       # Rapid Commit

        # Request options (1 = request; 0 = do not request)
        option 'domain_name_servers' '0'
        option 'domain_name' '0'
        option 'ntp_servers' '0'
        option 'sip_server_address' '0'
        option 'sip_server_domain_name' '0'
        option 'nis_server_address' '0'
        option 'nis_domain_name' '0'
        option 'nisp_server_address' '0'
        option 'nisp_domain_name' '0'
        option 'bcmcs_server_address' '0'
        option 'bcmcs_server_domain_name' '0'

        # Override the used DUID, by default it is derived from the interface MAC
        # The given value must be uppercase and globally unique!
        #option 'duid' '00:03:00:06:D8:5D:4C:A5:03:F2'

        # Script to run when a reply is received
        option 'script' '/usr/bin/dhcp6c-state'

# Define one or more interfaces on which prefixes should be assigned
config 'interface' 'loopback'
        option 'enabled' '1'                            # 1 = enabled; 0 = disabled
        option 'sla_id' '0'                             # Site level aggregator identifier specified in decimal (subnet)
        option 'sla_len' '16' # Site level aggregator length (64 - size of prefix being delegated Snap is 64-48 = 16)

config 'interface' 'lan'
        option 'enabled' '1'
        option 'sla_id' '1'
        option 'sla_len' '16'

Now if you restart your router you should get a IPv6 prefix assigned to your LAN interface. Great! That’s what we wanted, but it’s not much use if we can’t tell the machines on our network what our IPv6 prefix is.

That is where radvd comes in. It’s a router advertisement daemon, that can be used to distribute our prefix to our clients. To configure radvd edit the /etc/config/radvd file and update the settings to match below. You must NOT put a prefix in the list prefix because we are assigned a dynamic prefix and we need radvd to work out what prefix to advertise to our connected devices.

config interface
        option interface        'lan'
        option AdvSendAdvert    1
        option AdvManagedFlag   0
        option AdvOtherConfigFlag 1
        list client             ''
        option ignore           0

config prefix
        option interface        'lan'
        # If not specified, a non-link-local prefix of the interface is used
        list prefix             ''
        option AdvOnLink        1
        option AdvAutonomous    1
        option AdvRouterAddr    0
        option ignore           0
        option AdvValidLifetime 3600
        option AdvPreferredLifetime 600

config route
        option interface        'lan'
        list prefix             ''
        option ignore           1

If you prefer change AdvValidLifetime and AdvPreferredLifetime to something higher. I did this because I often restart my router and am given a new prefix, and my machines will prefer and use the old one until expiry, meaning I can’t establish IPv6 connections. My recommendation is to use something like 3600 for both if you have a stable connection that rarely gets rebooted.

Save that file and restart your router, everything should work and you should have IPv6 connectivity on your machines. Be aware that your machines will not get a IPv6 DNS server so all the DNS queries will still be executed over IPv4. This generally isn’t a problem as DNS servers should still return IPv6 records to you regardless of the version used to access them.

As all your devices that support IPv6 now have a globally routable address I recommend having firewalls turned on on everything. However sometimes we have phones etc that don’t have firewalls and you perhaps you want to only allow incoming traffic to that device if there has been outgoing traffic first. OpenWRT can handle this in iptables. Installing the following packages and reboot should do the trick. I say should as I can’t exactly remember whether I had to do more, but if it doesn’t work leave a comment and I’ll investigate my configuration.

ip6tables
kmod-ip6tables