IPv6-only SLAAC "dumb" APs

Here is a rough outline of my (desired) network:

┌─────┐
│ ISP │
└──┬──┘
┌──┴─────────────┐
│ OpenBSD Router │
└──┬─────────────┘
   │  ┌───────────────┐
   ├──┤ OpenWRT AP #1 │
   │  └───────────────┘
   │  ┌───────────────┐
   ├──┤ OpenWRT AP #2 │
   │  └───────────────┘
   │  ┌───────────────┐
   └──┤ OpenWRT AP #3 │
      └───────────────┘

I want this network to be IPv6 only configured via SLAAC. I receive a prefix delegation from my ISP and have my OpenBSD router configured for all my wired connections.

My router provides:

  • DNS (including DNS64)
  • NAT64 (via pf)
  • an IPv6 router advertisement daemon

Assume I'm a networking idiot—and definitely an OpenWRT n00b—but that I'm comfortable on the command line. I'm also pretty fresh to IPv6. :wink:

I'm working with ZyXel NWA50AX (https://openwrt.org/inbox/toh/zyxel/nwa50ax) devices for my APs, and have successfully flashed OpenWRT 23.05.0 onto them. As my network is IPv6 only, the default 192.168.1.1 address is un-routable, so nearly all of the guides for initial setup I've found online have not been helpful. I've been interacting with the APs using a UART (serial) connection.

What I would like is for the following:

  1. Each AP should be as dumb as possible (no DNS, no DHCPv6, no firewall, etc.) and allow wireless clients to configure their own IPv6 addresses via SLAAC like their wired counterparts.
  2. All three APs should be configured to make roaming between them as seamless as possible.
  3. All three APs should have IPv6 addresses of their own so I can SSH into them and/or load up LuCI and manage them remotely.

I haven't been able to piece together how I might accomplish this (or if it's even possible as I've described it). This guide (https://openwrt.org/docs/guide-user/network/wifi/dumbap) has been the closest I've gotten, but I haven't had my epiphany about how to translate it to my desired network.

If a setup like this is possible, could someone provide me with complete example config files and/or CLI instructions for how I might accomplish this, with explanations?

If a setup is not possible, could someone explain why and what I could change about my plan to make it possible?

Thanks very much for your time and attention.

Attach the AP's Ethernet port directly to a NIC on your PC (preferably a second NIC, such as a USB Ethernet adapter) and manually set the IP address of that NIC to something like 192.168.1.2. Then you can access 192.168.1.1 normally. This has the advantage of not interfering with the rest of the network while you initially configure the device. It will work even if the other NICs on the PC are IPv6 only.

The only things in that guide that needs translating to your network are the WiFi SSIDs/PSKs, the rest should "just work". Although you won't need to do step 1 for the NWA50AX because its bridge configuration should already be correct. (Step 1 is needed only if you're repurposing a wireless router as an AP.) If there's anything else about the guide that needs clarification, just ask.

The magic phrase you're looking for is 802.11r, also called "fast transition". OpenWrt already supports this out of the box with a checkbox:

(Screenshot from https://parkercs.tech/enabling-802-11r-fast-roaming-transition-on-openwrt/)

You need to set a mobility domain for each AP, which is a 4-digit hexadecimal number. It can be any number, but it needs to be the same for all APs.

  1. Ensure your RA daemon advertises a ULA prefix alongside the GUA prefix delegated by your ISP. Use this website to generate one for your network. We'll use fd8d:f78e:9538::/48 as an example. The advantage of the ULA prefix is that it never changes, unlike the GUA prefix.

  2. Configure the router such that it has a static IP like fd8d:f78e:9538::1.

  3. Assign an IPv6 suffix to each AP. I haven't tested this, but I believe it would involve something like:

    config interface lan
        option proto static
        option ip6ifaceid ::101        # 101 for AP 1, 102 for AP 2, etc.
        option ip6gw fd8d:f78e:9538::1 # router's ULA address
        option dns fd8d:f78e:9538::1   # router's ULA address
        ...
    
  4. Then you could access each AP via addresses like fd8d:f78e:9538::101, fd8d:f78e:9538::102, and fd8d:f78e:9538::103 for APs #1, #2, and #3, respectively.

  5. Even better is to configure the DNS server on your router to provide an AAAA record for each AP. For example, you could map the ap1.lan domain to fd8d:f78e:9538::101, so you could ssh root@ap1.lan which makes things way easier to manage.

If you want to go the extra mile, set up a DHCPv6 server on the router. Clients could then run a DHCPv6 client which sends their hostname to the router when obtaining a lease. This allows automatic mapping of hostnames to IP addresses. Dnsmasq does this out of the box (because it's a DNS/DHCP/RA all-in-one server).

You could also set static leases for your APs this way, allowing you to manage your AP's addresses in one place. I actually recommend this method for this reason, but the steps I've outlined above could work with your current setup.

Thanks for the thorough reply!

Attach the AP's Ethernet port directly to a NIC on your PC (preferably a second NIC, such as a USB Ethernet adapter) and manually set the IP address of that NIC to something like 192.168.1.2. Then you can access 192.168.1.1 normally. This has the advantage of not interfering with the rest of the network while you initially configure the device. It will work even if the other NICs on the PC are IPv6 only.

Ah, I forgot that I have another power adaptor. I was previously connected using PoE so thought I had to go through my network. facepalm

The magic phrase you're looking for is 802.11r, also called "fast transition". OpenWrt already supports this out of the box with a checkbox:

Thanks! I think the checkbox is on its own tab as of 23.05; my screen didn't match your screenshot exactly, but I found it.

All three APs should have IPv6 addresses of their own so I can SSH into them and/or load up LuCI and manage them remotely.

I still have been unable to get an IPv6 address. I wanted to try not using ULA's initially, but I still am not getting a IPv6 address assignment on the AP.

Here's what I have for the lan interface atm:

config interface 'lan'
    option device 'br-lan'
    option proto 'static'
    option ipaddr '192.168.1.202'
    option netmask '255.255.255.0'
    list dns 'xxxx:xxxx:xxxx:xxxx::xxxx'

Logging in with SSH to the AP only shows a link-local IPv6 address, not one from my router. Other wired clients (non-OpenWRT) are behaving as expected. I tried manually assigning an IPv6 address similar to my other wired clients to no avail:

config interface 'lan'
    option device 'br-lan'
    option proto 'static'
    option ipaddr '192.168.1.202'
    option netmask '255.255.255.0'
    option ip6addr 'xxxx:xxxx:xxxx::xxxx/64'
    list dns 'xxxx:xxxx:xxxx:xxxx::xxxx'

Am I missing something here?

I still have been unable to get an IPv6 address. I wanted to try not using ULA's initially, but I still am not getting a IPv6 address assignment on the AP.

Of course as soon as I type all that I realized I forgot to include ip6gw in my config. I think IPv6 connectivity is working now.

One thing I haven't been able to figure out is why clients on my new wireless network are still getting IPv4 assignments, in the 192.0.0.0-255 range. Do you know how to turn these off?

On a v6 only connection, Android will create an internal 464 interface (which is useful for v4 compatibility if the ISP offers NAT464). The 192.0.0 IP does not exist outside the phone.

For v4 and v6 IPs to exist on the same interface, use an alias interface-- a second config interface block with option device '@lan'. This also allows one family to be static and one DHCP client for example. See the default setup of wan.

You can always reach the APs over their link-local IPs. This also means that all the wireless users, being part of the same L2 segment, can also reach your APs on their link-local IPs. It may be good to firewall that out and only allow admin access through a Wireguard tunnel.

Ahh, that makes sense. Likely iOS does something similar.

Thanks. I only kept the IPv4 assignment during initial setup. Now that I can address it via IPv6, I removed the IPv4 address.

Thanks for the reminder!

You can also use a PoE injector to power the AP without connecting it to the main network. It's what I used to power my Ubiquiti U6+ when I was adding OpenWrt support to it, because U6+ doesn't have a DC barrel jack. Also could be useful for bench testing PoE devices.

Note that your APs now refer to the router and DNS via literal IP addresses, so if you configure using GUA addresses with dynamic GUA prefixes, then your AP's connectivity will break if the ISP changes the prefix. ULA addresses is one way to guarantee this won't happen. (By the way, OpenWrt advertises a ULA prefix by default, so we know this works well.)

Note that connecting to a device using its link-local address require specifying its zone index. ULA address don't require this. But it is very useful if the RA is completely broken for some reason.

Hey, coming back to this after some IPv6 troubles with my ISP. My previous configuration hard-coded the IPv6 address, but I couldn't get the configuration above (in the quote) to work.

The interface br-lan never gets an IP assignment. I can manually assign one with ip6addr.

Other machines on the same network are able to get addresses, so I'm pretty sure my router advertisements are going out as expected.

Any other thoughts?

@elbertmai I'm likely grasping at straws here, but is odhcpd used for configuring the OpenWRT host itself? I see the docs say "... to configure clients ..." and I didn't know if the OpenWRT host counted as a "client."

Honestly this doesn't feel right, but I'd thought I'd ask anyways.


When I said earlier I could get it working with ip6addr, that was only true if I used a GUA address. ip6addr does not appear to work with a statically-configured ULA address—the address gets assigned, but I have no routes to anything (can't ping, etc.). I'm guessing this is because I do not have NAT66 setup on my router for my ULA prefix, nor do I much want to.

Ideally I'd have OpenWRT autoconfigure GUA & ULA addresses via SLAAC, then use the ULA addresses for internal networking only.

Just noticing this in the logs:

daemon.warn netifd: You have delegated IPv6-prefixes but haven't assigned them to any interface. Did you forget to set option ip6assign on your lan-interfaces?

I have this for lan currently:

config interface 'lan'
    option device 'br-lan'
    option proto 'static'
    option ip6assign 64
    list ip6class wan local
    option ip6gw fdd0:c720:85fa:100::1

Is this warning relevant?

odhcpd is OpenWrt's RA and DHCP server implementation and it is meant to serve an entire network. Since you're already running a RA server on your OpenBSD box, odhcpd should not be running at all on any of your OpenWrt APs. If it is, you need to disable it.

NAT66 is almost always the wrong answer in "typical" deployments. If pinging a ULA address doesn't work, I would double check if your RA daemon is correctly advertising the ULA prefix. In particular the RA needs to tell the nodes that the prefix is on-link (the L bit) and can be used for SLAAC (the A bit).

Do a Wireshark capture for Neighbor Discovery packets and look at the Router Advertisements. Check that the ULA prefix is provided and that both L and A bits are set for the prefix. I don't know what RA daemon you're using so I can't give specific instructions on how to configure this.

Prefix delegation only takes place between routers and requires DHCPv6. So option ip6assign and list ip6class should not be set in any of your APs.

Got it. Disabled.

Here's what I get from tcpdump, when listening on the ethernet interface on my router that is connected to my AP (tcpdump -nevvvi igc3 ip6[40] == 134):

23:48:38.675892 a8:b8:e0:01:d0:54 33:33:00:00:00:01 86dd 158: fe80::aab8:e0ff:fe01:d054 > ff02::1: icmp6: router advertisement(chlim=0, pref=medium, router_ltime=1800, reachable_time=0, retrans_time=0)(prefix info: LA valid_ltime=5400, preferred_ltime=2700, prefix=gua1:xxxx:xxxx:cf02::/64)[ndp opt] (len 104, hlim 255)

I see one of these for my GUA prefix, but not another one for my ULA prefix. It looks like the L & A flags are set. I'm running rad(8) as my RAD daemon.

Other machines on my network are getting ULA addresses automatically, and I can ping my gateway via the ULA address of my router successfully on other machines.

Just not the AP.

Got it. Removed.

My configuration for /etc/config/network now looks like:

config interface 'loopback'
        option device 'lo'
        option proto 'static'
        option ipaddr '127.0.0.1'
        option netmask '255.0.0.0'

config globals 'globals'
        option packet_steering '1'

config device
        option name 'br-lan'
        option type 'bridge'
        list ports 'lan'

config interface 'lan'
        option device 'br-lan'
        option proto 'static'
        option ip6ifaceid ::101
        option ip6gw gua1:xxxx:xxxx:cf02::1
        option dns gua1:xxxx:xxxx:cf02::1

I restarted networking with /etc/init.d/network restart and... no IPv6 address assigned to any interface other than the link-local address. No errors or warnings in the output for logread that I could see.

What should I try next?

These two facts are contradictory. If ULA addressing is working on the other machines then the RA daemon is sending the advertisements correctly. You probably just missed that particular packet.

I'm most likely not understanding how ip6ifaceid works. I've looked this up again on the OpenWrt wiki and I realized this might only work in router configurations. Instead, I would actually try this:

config interface 'lan'
        option proto 'dhcpv6'
        option device 'br-lan'
        option reqaddress 'try'
        option reqprefix 'no'

Yes, I know you're not using DHCPv6, but I have this configuration on my APs and they also get addresses by SLAAC. Perhaps it also works in SLAAC-only deployments. It's worth a try.

ip6ifaceid is relevant only to SLAAC assignments meaning that proto would need to be dhcpv6. For proto static you'd assign the entire IPv6 address, the prefix along with the last 64 bits, statically.

1 Like

This was my first thought as well! I would've expected there to be a 'slaac' protocol here, but there isn't. :face_with_raised_eyebrow:

This worked! For both GUA and ULA addresses. I am thoroughly confused why proto has to be set to dhcpv6 when I'm not running a DHCPv6 server, but I'm happy to chalk this up to "the way OpenWRT does things." :man_shrugging:

You're probably right. I set up the tcpdump listener, then restarted rad, and that's what came out. When I made the above changes and restarted OpenWRT, I was also listening, and got no RA packets, yet OpenWRT clearly received them because it configured itself fine. I'll look into this later.

Ugh, I spoke too soon. This did indeed work when I tried /etc/init.d/network restart, but it did not survive a full device power cycle.

I noticed the following in the output for logread:

Fri Mar 29 16:10:12 2024 daemon.err odhcp6c[2681]: Failed to send RS (Address not available)
Fri Mar 29 16:10:13 2024 daemon.err odhcp6c[2681]: Failed to send SOLICIT message to ff02::1:2 (Address not available)

Configuration of 'lan' is the same from the message above.

Looking more closely at the logs, it appears odhcp6c attempted to send the RS before 'lan' was fully up, so it failed initially, but waiting a few more minutes it succeeded.

I thought it wasn't working after the power cycle because I was looking at eth0 instead of br-lan. :man_facepalming:

Pretty sure this is actually working... :crossed_fingers: The proof is that I posted this reply while being on the new network provided by the AP & OpenWRT. :sunglasses:

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.