![]()
|
I have been an IPv6 Advocate since the early days of IPv6 support by BayNetworks back in 1998. And I know as much as anyone else, that 2128 is a really big number*. So it seems inconceivable that one could run out of IPv6 addresses, but I managed to do just that.
Let me explain. I am a co-organizer of a Network Special Interest Group (NetSIG), and setup labs to discuss networking. We cover issues such as Wifi, Mesh technologies, tunneling, containers, and routing. As an IPv6 advocate, I like to include IPv6 in our labs. However not surprisingly our meeting location has IPv4-only internet access.
I have overcome this IPv4-only problem by setting up a portable router with a WireGuard VPN connection back to my IPv6 enabled house. The router runs a split tunnel, with IPv4 going directly to the internet (through a few layers of NAT), and IPv6 going through the WG tunnel. There is extra latency on the IPv6 path, but it works.
Spoiler Alert: My house IPv6 address plan was inadequate to the task of running a remote lab at the end of a Wireguard VPN.
One of the key items when setting up an IPv6 network is address planning. Back in the old days (read: the 1990s) we had to do this with IPv4 as well, but it has become a lost art for the folks who grew up only knowing NAT.
Like many residential IPv6 services, I get a /56 from my ISP. Doing basic math, that is 2^8 or 256 prefixes. But like many residential services, there is no static prefix from the ISP. It can change any time, which makes Address Planning a little more of a challenge.
Fortunately, OpenWrt has some nice support for automatically splitting up IPv6 address space, and passing out chunks of prefixes to downstream routers.
OpenWrt uses the old HomeNet mechanism for allocating prefixes to downstream routers. Basically, it divides the number of LAN ports into the current prefix size on the router. So a standard home router with 4 ports, will divide the prefix on the router, say a /56 by 4 and Prefix Delegation (PD) will pass out /58's to the downstream routers.
As you can see if you think of the ISP allocated address space like the bottom layer of a wedding cake, each successive layer being 1/4 of the prefix space, you are going to run out of IPv6 prefixes!
Sadly, the OpenWrt default automagic prefix-slicing, doesn't adhere to best practices of splitting prefixes along nibble boundaries. Utilizing the ip6assign
and ip6hint
it is possible to make PD requests which do follow the nibble boundaries. However this reduces the number of layers in the PD cake to three!
OpenWrt helps correct this by allowing PD routers to request a hint and a prefix size. This can be configured in the web GUI (LuCI), or just added directly to the /etc/config/network file:
config interface 'lan'
...
option device 'br-lan.1'
option proto 'static'
option ipaddr '192.168.232.1'
option netmask '255.255.255.0'
option ip6hint '40' #PD hint
option ip6assign '60' #PD request size
option ip6weight '5' #Signals to the upstream router the order of multiple routers requesting PD
The last item, ip6weight
assists the upstream router in handing out PD when multiple downstream routers are making PD requests. This is needed because in a SOHO (Small Office Home Office) environment, it is possible to have the entire house lose power (black out). When the power is restored, there will be multiple routers making PD requests to the upstream router, the ip6weight
establishes an order (and hence prefix-slice) of allocation.
This all seems a bit complicated, and it kind of is. But the nice part is that it takes place all automagically. After a power failure, the network comes up, perhaps with a new /56 prefix from the ISP, and all the routers obtain the new prefix-slices, without user intervention.
In my network, I am using a hybrid address planning scheme, where the major networks: Production, Test, IPv6-only, DMZ and my Wireguard VPN all get a /60 each. This looks like the following:
Network | Prefix | Length |
---|---|---|
Production* | 2001:db8:cafe:fd00:: | /60 |
Test | 2001:db8:cafe:fd40:: | /60 |
DMZ | 2001:db8:cafe:fd80:: | /60 |
IPv6-only | 2001:db8:cafe:fd60:: | /60 |
WireGuard | 2001:db8:cafe:fdc0:: | /60 |
This scheme allows up to 16 major networks (all /60), each of which can have up to 4 downstream PD routers (not necessarily on nibble boundaries)
By the time the IPv6 network trickles down to the NetSIG lab, there was only a /63 available on the LAN. When we had a lab which setup cute but powerful NanoPi routers, I ran out of IPv6 GUA prefixes after two routers, and we had four NanoPis in the lab!
Naturally, this didn't go over so well in the lab. After all, all the NanoPi's did NAT for IPv4, and it was just another layer of NAT, but there was still IPv4 address space. How is IPv6 better?!? It just is, OK?
Clearly, I wasn't looking for a repeat of that problem in the lab. But how to get more addresses into the remote lab (remember there is a long line of routers back to my house)? After giving it some thought, the answer was to give the remote lab its own /60, but how-to do that with the prefix-slicing of OpenWrt?
Prefix Delegation (PD) is a great thing, automatically prefix-slicing to downstream routers. But how does it really work? PD performs two key functions:
The second function is pretty transparent, but the PD delegated network won't work without it, since the delegating router won't know where to send the packets.
As readers will know, I am a big proponent of RIPng for the SOHO. You pretty much turn it on, and it just works. With RIPng one doesn't have to be a router-jock knowing all the different types of Link-State Advertisements (LSAs) of Open Shortest Path First (OSPF) or Intermediate System to Intermediate System (IS-IS) levels.
Fortunately, OpenWrt makes it easy to assign a /60 to a router, which it will then hand out prefix-slices on the LAN. I gave the travel/lab router its own /60. Again, in the /etc/config/network file:
config interface 'wan6'
option device 'eth0.2'
option proto 'dhcpv6'
option reqprefix 'no'
list ip6prefix '2001:db8:cafe:fdd0::/60'
That takes care of #1 allocating a slice of prefix to the router, but still leaves the issue of #2, putting in route in the upstream router. Of course, I could have put a static route in. But I don't like static routes, they never change, and when the network goes wonky, they are still there trying to shove packets to places that may no longer be valid. And this is where RIPng come in.
The upstream WG router was already was running RIPng, so it was trivial to install the bird routing daemon and enable RIPng on the travel/lab router.
Assigning a /60 to the travel/lab router, makes a new major network on my house network, and now gives me 16 prefixes to use in the remote lab
Network | Prefix | Length |
---|---|---|
Remote Lab | 2001:db8:cafe:fdd0:: | /60 |
The advantage of running a dynamic routing protocol such as RIPng, is that when my travel/lab router drops off the network, the remote lab /60 is automatically removed from my network. I don't have to do any re-configuring, or worrying about static routes which a lying in wait, ready to burn me.
As I found out, there are corner cases where it is possible to run out of IPv6 address space. And this goes back to Address Planning in IPv6. Pretty much everyone's first IPv6 Address Plan will require reworking, as situations arise and corner cases appear. But don't let that prevent you from deploying IPv6. Yes, it may require tweaking, or even revamping your address plan. But that is OK, it is part of the IPv6 networking journey. We weren't born knowing IPv4, it is just that we have been using it for a while, and we are used to it.
My problem was that I was thinking too small in my address plan, and didn't allocate enough address space to my travel/lab router. Now I am ready for the next lab, bring on that army of NanoPi routers.
Happy IPv6 Holidays!
Notes:
9 December 2024