Roll out IPv6 on AT&T
Abstract
Wrangling IPv6 on AT&T. Deployment tips for Prefix Delegation, Router Advertisements, Neighbor Discovery, and stateful firewalling.
The Low-Down
This post walks through IPv6 for AT&T Internet (a non-SLA service behind an AT&T residential gateway). Unlike Spectrum, which hands out a generous /56, AT&T delegates a single /64. Yep. One measly /64. Needlessly stingy, but we can work with it.
Goal is isolated IPv6 connectivity for a single Windows test VM, with the MikroTik handling the prefix and the firewall keeping the rest of the world out.
Network Topology
- ISP: AT&T Business Internet (non-SLA)
- Upstream Edge: AT&T Residential Gateway (RG)
- Core Router: MikroTik CCR2004-16G-2S+ (RouterOS 7.20)
- CCR WAN Interface: ether1_untrust
- CCR LAN Bridge: bridge_ipv6
- CCR Physical Port: ether16_ipv6
- Hypervisor: Microsoft Hyper-V host running a Windows VM
This example works for any RouterOS hardware. ether16_ipv6 is assigned to bridge_ipv6 and patches directly into a dedicated Hyper-V virtual switch isolated from hypervisor management.
Note: IPv4 IP passthrough does not affect IPv6. The AT&T gateway handles IPv6 routing and prefix delegation independent of IPv4. You cannot bypass its IPv6 stack entirely.
Requesting the Prefix
Configure the IPv6 client to request a prefix on the WAN interface:
/ipv6 dhcp-client
add interface=ether1_untrust \
request=prefix \
pool-name=att_pd \
pool-prefix-length=64 \
add-default-route=yes \
accept-prefix-without-address=yes
Breakdown:
- request=prefix — Requests DHCPv6 Prefix Delegation (IA_PD).
- pool-name=att_pd — Creates a dynamic IPv6 pool named att_pd.
- pool-prefix-length=64 — Controls the subnet size RouterOS carves out of the pool for downstream interfaces (not the size the ISP gives you).
- accept-prefix-without-address=yes — Accepts a delegated prefix even if AT&T does not hand out an IA_NA address on the WAN.
- add-default-route=yes — Installs an IPv6 default route via the DHCPv6 client.
Verify the binding:
/ipv6 dhcp-client print detail
Expected output:
interface=ether1_untrust status=bound dhcp-server-v6=fe80::3aa0:67ff:fe81:d662 request=prefix pool-name=att_pd pool-prefix-length=64 prefix=2600:1700:1335:452f::/64
A /64 is the smallest routable subnet, so options are limited: DHCPv6 server, SLAAC, or Unique Local Addresses if you need to route beyond this single segment. ULAs are not used in this lab.
Assign the PD to the LAN Bridge
Bind the /64 to the bridge so it stays current if the ISP renumbers:
/ipv6 address
add interface=bridge_ipv6 \
from-pool=att_pd \
advertise=yes
Verify:
/ipv6 address print
2600:1700:1335:452f::/64 FROM-POOL=att_pd INTERFACE=bridge_ipv6 ADVERTISE=yes
RouterOS shows the network address by default for pool assignments. If you want to ping the router itself (for example ::1), explicitly bind that ID:
/ipv6 address add interface=bridge_ipv6 from-pool=att_pd eui-64=::1
Dynamic and static in one.
Router Advertisements and SLAAC
Unlike IPv4, IPv6 clients can auto-configure with SLAAC. The router advertises the prefix via Neighbor Discovery and the clients build their own addresses.
/ipv6 nd
add interface=bridge_ipv6 \
advertise-dns=yes \
managed-address-configuration=no \
other-configuration=no
Check existing ND settings first (/ipv6 nd print detail). RouterOS includes a default *all entry. Make sure you are not advertising back out ether1_untrust toward the AT&T gateway.
Windows natively supports DNS from RAs. Point RDNSS at your preferred resolvers:
/ipv6 nd
set [find where interface=bridge_ipv6] \
dns=2001:4860:4860::8888,2001:4860:4860::8844 \
advertise-dns=yes
Not every device supports RDNSS. Android and Xbox often need dual-stack and fall back to IPv4 DNS. Plan accordingly.
Neighbor Discovery Quick Refresher
IPv4 finds neighbors with broadcasts (ARP). IPv6 uses multicast and ICMPv6 Neighbor Discovery.
- Router Discovery (Types 133/134): Client multicasts a Router Solicitation to ff02::2. Router replies with a Router Advertisement containing default routes, MTU, lifetimes, and prefixes.
- Address Resolution (Types 135/136): Replaces ARP. Uses Neighbor Solicitations to a solicited-node multicast address derived from the target IP. Far less noise than broadcast ARP.
The CCR handles WAN-side NDP to the AT&T gateway automatically over link-local addresses (fe80::/10). No static neighbor entries needed on the WAN.
Hardening IPv6
Global addresses expose devices directly to the Internet. Stateful firewall rules on the WAN are required.
Input chain (protect the router):
/ipv6 firewall filter add chain=input action=accept connection-state=established,related comment="Accept established/related" add chain=input action=drop connection-state=invalid comment="Drop invalid" add chain=input action=accept protocol=icmpv6 comment="Accept essential ICMPv6" add chain=input action=accept in-interface=ether1_untrust protocol=udp src-port=547 dst-port=546 comment="Allow DHCPv6 reply from RG" add chain=input action=accept in-interface-list=trust comment="Allow trusted management" add chain=input action=drop in-interface=ether1_untrust comment="Drop all other unsolicited WAN input"
Forward chain (protect the LAN):
/ipv6 firewall filter add chain=forward action=accept connection-state=established,related comment="Accept established/related" add chain=forward action=drop connection-state=invalid comment="Drop invalid" add chain=forward action=accept protocol=icmpv6 comment="Allow ICMPv6 pass-through" add chain=forward action=accept in-interface=bridge_ipv6 out-interface=ether1_untrust comment="Allow test LAN outbound" add chain=forward action=drop in-interface=ether1_untrust out-interface=bridge_ipv6 comment="Block unsolicited WAN to LAN"
Do not drop link-local traffic on the WAN. This rule looks tempting and breaks everything:
# DO NOT USE /ipv6 firewall raw add chain=prerouting action=drop in-interface=ether1_untrust src-address=fe80::/10
Legitimate control traffic (RAs, Neighbor Discovery, DHCPv6-PD) relies on fe80::/10 sources. Dropping it collapses the protocol between the WAN interface and the AT&T gateway.
Validate
From the Windows test VM:
ipconfig /all
Look for:
- Valid fe80:: link-local address
- Valid global address matching the AT&T /64
- Default gateway set to the MikroTik’s link-local address
- RDNSS DNS resolvers
Quick checks:
ping -6 2001:4860:4860::8888 nslookup google.com 2001:4860:4860::8888 tracert -6 2001:4860:4860::8888
Don’t panic if tracert shows asterisks. Many transit routers deprioritize or drop ICMPv6 Time Exceeded while still forwarding traffic at line rate.
Troubleshooting
During testing I hit an intermittent failure:
- The test VM could ping the local bridge and the AT&T RG’s internal interface.
- Outbound packets left ether1_untrust.
- Public IPv6 traffic died. Replies never came back.
- Opening the firewall completely did not fix it.
The fix was simple: renew the DHCPv6 client.
/ipv6 dhcp-client renew 0
RouterOS re-bound to the same prefix and the AT&T gateway immediately started forwarding again. Short-term workaround is to schedule that renew every few hours. Long-term is getting AT&T to look at the residential gateway.
This points to stale routing or NDP state inside the AT&T box. It kept the DHCPv6 lease but dropped the dynamic route or neighbor entry until a fresh exchange forced an update.
Two client tweaks worth testing:
- use-interface-duid=yes — Builds the DUID from the WAN interface MAC instead of the router-wide base DUID.
- allow-reconfigure=yes — Accepts server-initiated reconfigure requests so the upstream gateway can trigger a renewal.
Summary
IPv6 on RouterOS 7 behind AT&T works once the control plane is sorted:
- DHCPv6-PD brings the prefix from the ISP; SLAAC hands addresses to clients via RAs.
- Build explicit stateful filters on input and forward. Never drop fe80::/10 on the WAN.
- Dynamic GUAs from the pool keep the LAN current if the prefix changes.
- Watch the upstream gateway. A simple DHCPv6 renew clears the occasional stuck state.
That’s all folks.






