Setting up IPv6 with ATT fiber and Ubiquiti USG

First off: Woo! It’s taken me several attempts over the last few months to get this working. I was curious if IPv6 had lower latency than IPv4, and so far the results are mixed, but I don’t think I’ll be going back to running just IPv4. Pings to my own website averaged 10-15ms lower latency, and that could be due to a whole number of factors, like routing, no NAT, fewer hops. Fewer hops doesn’t always result lower latency, but it can. I am excited about the lack of NAT with IPv6, which means I won’t have to forward ports for game servers if they’re IPv6 friendly. It looks like Factorio is.

Hardware overview

I’m using a Nokia BGW320-505 provided by ATT, and my Ubiquiti USG is hooked up to it. ATT wants you to use their hardware for fiber, and while there’s potentially ToS-breaking ways around that, I don’t have other hardware with an SFP and ONT. Once I turned off the WiFi radios and set up IPv4 passthrough the BGW320 works great with my network, the challenge was getting IPv6 working and it wasn’t clear how the BGW320 does prefix delegation (PD). I had read ATT gives PD a size of 60, but it turns out that’s given to the BGW320, which then gives router clients a PD size of 64. Which is why putting 60 instead of 64 into my USG didn’t work.

I found two methods to get IPv6 working:

Method 1 relies on automatic prefix delegation, which is ideal because it can survive global routing prefix changes. The global routing prefix is set by the ISP and is the first three hextets in an IPv6 address: 2xxx:xxxx:xxxx.

Method 2 relies on a static address. IPv6 is not static by design and relying on addresses to stay the same long-term would be painful. You can attempt to get a static IP using link-local addresses, which start with fe80: and often compute the interface identifier (the last 4 hextets) from the adapter’s MAC address—but not always! And as I understand it, link-local addresses can only talk to neighbors in their network and can’t be routed, which may be why using the gateway’s link-local address instead of the global routing prefix didn’t work for me.

Method 1: Prefix Delegation

In the Unifi controller:

  1. Head to SettingsInternet and select the WAN connected to the ATT router
  2. Under IPv6 Configuration, select DHCPv6
  3. Set Prefix Delegation Size to 64
  4. Save
  5. Head to SettingsNetworks and select your network
  6. Select the IPv6 tab and then Prefix Delegation
  7. Set Prefix Delegation ID to 0
  8. Set Prefix Delegation Interface to your ATT router
  9. Save

Wait about a minute, and then head over to test-ipv6.com. You should see a 10/10 score.

Method 2: Static subnet

This method might require you to redo the steps when your IPv6 address changes, so I’m not confident about using it long term. It may help however if the first method didn’t work and you want to rule some things out before adjusting.

In the ATT router:

  1. Browse to 192.168.1.254 (you may have changed this if you set up IPv4 passthrough earlier)
  2. Click Home Network and then scroll down to IPv6
  3. Look for IPv6 Delegated Prefix Subnet and take note of the address

In the Unifi controller:

  1. Head to SettingsInternet and select the WAN connected to the ATT router
  2. Under IPv6 Configuration, select DHCPv6
  3. Set Prefix Delegation Size to 64
  4. Save
  5. Head to SettingsNetworks and select your network
  6. Click the IPv6 tab and select Static
  7. Enter the delegated prefix subnet address from the ATT router, without the /64 on the end
  8. Set Netmask to 64
  9. Save

Pi-hole concerns

I run a Pi-hole on my network and using its link-local fe80: address in the DNS setting for the IPv6 network isn’t working. Using its global prefix address does, though that address could change. I found this article with a config.gateway.json for the USG that aims to solve this with Unique Local Addresses, but haven’t tried it yet. I think the ideal setup would be to try and solve the link-local issue.