If you’re building your own Linux based router to connect to BT Infinity you’ll probably want IPv6 working too. Address assignment works differently in IPv6 to IPv4 – we aren’t going to be given a single address we are going to be given a 56 bit prefix. From a 128 bit address that leave us a lot of bits available to use to address hosts on many sub-networks in our network. We are going to assign 64 bit prefixes to our interfaces (we can create 256 prefixes at 64 bits each) each with vastly more addresses than the entire IPv4 address space. To get our prefix from BT and delegate prefixes to our own networks we need an IPv6 DHCP client. This is where lots of other guides, forum posts, and the like, are a bit out of date (or don’t apply to BT Infinity) using wide-dhcpv6, dibbler, radvd, sysctl settings and custom scripts. Having played with various options I’ve found what works for BT Infinity in 2017, resulting in a really clean and simple method that boils down to a very simple configuration.
First the basic internet connection
I’m using a white OpenReach modem, as originally supplied for BT Infinity, connected to eth0. If you don’t have one of these excellent VDSL modems you can pick them up cheaply on eBay.
Install pppoe with “apt-get install pppoe”
iface eth0 inet manual mtu 1508 auto vdsl iface vdsl inet ppp provider bt pre-up /sbin/ifconfig eth0 up mtu 1508 post-down /sbin/ifconfig eth0 down
# Secrets for authentication using CHAP # client server secret IP addresses "firstname.lastname@example.org" * "password"
#BT Broadband # Use the pppoe kernel module. plugin rp-pppoe.so eth0 # Name this connection as ppp0. unit 0 user email@example.com # No default IP; allocated dynamically by ISP. noipdefault # Try to get name servers from ISP. usepeerdns # Use this connection as the default route. defaultroute # Replace the default route if already present replacedefaultroute # There is an 8 byte overhead for PPPoE; however, # we are using baby jumbo frames of 1508 on eth0 # to account for the extra 8 byte overhead. mtu 1500 mru 1500 # Exclude password string when logging packet contents. hide-password noauth # Try to reopen the connection if it is terminated. persist ipv6 ,
Run “ifup vdsl” to connect.
Then run “ifconfig” and check a new interface named ppp0 has appeared and got an IP v4 address (there will also be a link local IPv6 address (starting fe80:), but no public IPv6 address yet). You should now be able to “ping www.google.com”.
Points to note:
- The space and comma on that last line of
/etc/ppp/peers/bt– they are needed!
- We are able to pass full sized Ethernet frames (1500) through to the internet, despite the 8 byte added header of pppoe. This is because we increased the mtu of eth0 (over which this pppoe connection runs) to 1508 (instead of the default 1500) in
- Although we defined an interface called vdsl, this name is only used if you call ifup / ifdown to start or stop the connection. In ifconfig and firewall rules our internet interface will be named ppp0.
- Credit to https://alasdairsmith.uk/bt-infinity-with-my-linux-router for the basic Infinity Configuration, all I’ve added to this config is IPv6 support.
Install dhcpcd5 with “apt-get install dhcpcd5”
duid option rapid_commit option domain_name_servers, domain_name, domain_search, host_name option classless_static_routes require dhcp_server_identifier nohook lookup-hostname ipv6only noipv6rs allowinterfaces ppp0 eth1 eth1.9 interface ppp0 ipv6rs ipv6only ia_pd 1 ppp0/0 eth1/1 eth1.9/9
Now restart dhcpcd with “systemclt restart dhcpcd” (you only need to do this now because the config has been changed, you don’t need to start it manually normally):
Now run “ifconfig” and look at the output, you should see ppp0, eth1 & eth1.9 all have real world IPv6 addresses (output trimmed for brevity and censored):
eth0 Link encap:Ethernet HWaddr xx:xx:xx:xx:xx:xx inet6 addr: fe80::20e:c4ff:fece:db8b/64 Scope:Link eth1 Link encap:Ethernet HWaddr xx:xx:xx:xx:xx:xx inet addr:192.168.1.1 Bcast:192.168.1.255 Mask:255.255.255.0 inet6 addr: 2a00:xxxx:xxxx:xx01:20e:c4ff:fece:db8c/64 Scope:Global inet6 addr: fe80::20e:c4ff:fece:db8c/64 Scope:Link eth1.9 Link encap:Ethernet HWaddr xx:xx:xx:xx:xx:xx inet addr:192.168.9.1 Bcast:192.168.9.255 Mask:255.255.255.0 inet6 addr: 2a00:xxxx:xxxx:xx09:20e:c4ff:fece:db8c/64 Scope:Global inet6 addr: fe80::20e:c4ff:fece:db8c/64 Scope:Link lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 inet6 addr: ::1/128 Scope:Host ppp0 Link encap:Point-to-Point Protocol inet addr:86.xxx.xxx.xxx P-t-P:172.xxx.xxx.xxx Mask:255.255.255.255 inet6 addr: 2a00:xxxx:xxxx:xx00:3583:3ff4:c30c:e6f3/64 Scope:Global inet6 addr: fe80::3583:3ff4:c30c:e6f3/10 Scope:Link
You should now be able to “ping6 www.google.com”
Points to note:
- This is obviously just an example adjust your network interfaces to suit. If you use different interfaces in the “ia_pd” line remember to update “allowinterfaces” too!
- In the line “ia_pd 1 ppp0/0 eth1/1 eth1.9/9” you specify the interfaces you want to assign prefixes to. The number after the / is the prefix number – note it corresponds to the next 8 bytes of the network address after the 56 byte prefix supplied by BT (mostly censored out in the above). I like to make them match the third octet of my class C IPv4 networks, but they don’t have to.
- Don’t change the 1 in “ia_pd 1 …”