IPv6 on Linux with U-Verse

I recently decided to replace my wireless router with a linux PC.  I had gone through several iterations:
  • Old netgear (circa ~2005) that supported the Tomato firmware - which I really liked, but couldn't push more than ~10mbit/sec over the wifi (older wifi).  This wasn't a problem when I had ~4mbit DSL (didn't even notice it) - but was quickly a bottleneck when I upgraded to the 25mbit DSL.
  • Replaced it with a much faster wifi router, but I didn't notice that it couldn't support OpenWRT or Tomato or DD-WRT until after purchase.  So was stuck with the stock Netgear firmware, which isn't ideal.
I've got an Intel NUC running Ubuntu 14 and decided to make it my gateway, similar to:
Netgear (WiFi, no routing)   ---  [p2p1] NUC [eth0] ---  UVerse Router -- DSL

"UVerse" is technically provided through Sonic.Net (the bills come from Sonic.Net, but the traceroute goes through AT&T).  I'm not sure if people who have UVerse instead of Sonic would see technically anything different here. (Probably not).

The UVerse router/modem is a Pace 5031NV, running firmware version 10 at the moment. DMZ Passthrough is NOT enabled, though I do have port 22 forwarded to my linux box for remote management.

Enabling IPv4 is straightforward.  Use DHCP to learn the external interface, add a DHCP server internally, and use NAT.

net.ipv4.ip_forward = 1
/sbin/iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

Enabling IPv6 is more complex.  The configuration on my netgear was "IPv6 Passthrough" with no documentation as to what that actually did.  (Other than it just worked).

I was able to get it working though with DHCPv6-PD (prefix delegation). The Status page of the AT&T router shows a /60 being delegated to the router (using 6rd), and it assigns a /64 to the link from the AT&T router - so the trick is to just get a second /64 assigned off the router so it can go on the back-end network.

I installed the wide-dhcpv6 client and set it up with the following config:

profile default
  request domain-name-servers;
  request domain-name;

  script "/etc/wide-dhcpv6/dhcp6c-script";

interface eth0 {
    send ia-na 0;
    send ia-pd 0;

id-assoc na 0 { };

id-assoc pd 0 {
    prefix ::/64 infinity;

    # Internal interface (LAN)
    prefix-interface p2p1 {
        sla-len 0;
        sla-id 0;

I went through a couple iterations of the config to get it working.  I'm basically requesting a /64 delegation, and then assigning that to my p2p1 interface.  I did find I had to reboot the AT&T router before it started working; the symptoms before the reboot was the DHCPv6 response coming back with "no PD prefixes assigned".  I suspect that was happening because it had given out all its prefixes, but I'm not clear on that.

Once this is in place, installing radvd and configuring it allows the box to advertise RAs to clients:

aptitude install radvd

# cat /etc/radvd.conf
interface p2p1
   AdvSendAdvert on;
   prefix ::/64
        AdvOnLink on;
        AdvAutonomous on;

And, for reference, my /etc/network/interfaces:

auto p2p1
iface p2p1 inet static
        address MYADDR
        broadcast MYBROADCAST

iface p2p1 inet6 manual

auto eth0
iface eth0 inet dhcp
iface eth0 inet6 auto
        sysctl -w net.ipv6.conf.eth0.accept_ra=2