In my last article I went over the aspects of the IPv6 address format and some common issues with displaying, matching and searching through IPv6 addresses that are represented in different formats. There are some tricks for operators around being able to look at an IPv6 address and know if it represents a network (think of a prefix as an IPv4 subnet) or an actual IPv6 address. The reason this is important is that when you are trying to debug or troubleshoot a networking issues or trying to provide information to colleagues being able to identify a networking prefix verses an address quickly proves to be very helpful.
Tom Coffeen’s book IPv6 Address Planning from O’Reilly Media provides some great tips on IPv6 allocation and some useful spreadsheets that demonstrate how to make it a bit clearer if an IPv6 address is representing a prefix verses a specific address. I am borrowing the content from that part of the book to highlight how the method used can make your life a bit easier. Tom lists out an address plan that reserves the first and last prefix in a given prefix range and holds it in reserve. While not as aggressive of a method as bisection and sparse allocation, it does allow for some nice side benefits. The benefits are specifically related to representing prefixes and knowing that you will NOT have a host with an address in the all zeros section of an IPv6 network prefix. Here is a sample diagram going over that specific point (that is borrowed from Tom’s book):
Notice from the above /48 allocation the all zeros section is reserved. The first usable allocation from that address range is <32-bit prefix>:1000::/52. This means that we will never have an “all-zeros” address in that prefix. This simplifies greatly the routing table entries and the operator understanding of what is being displayed. If you see 2001:db8:a1d5:: even without the /48 or other prefix length values you know it will be a prefix and NOT an address. It is a natural byproduct of how your address plan was done. It also means that we should not see any “all-zero” prefixes because the first usable /52 prefix would actually be:
2001:db8:a1d5:1000::/52
Equally, the same would apply to the /64 and the first useable prefix would be:
2001:db8:a1d5:1111::/64
This may seem confusing at first, but once you get used to what is being done, you quickly realize when looking at a routing table what is an address verse what is a prefix. It helps to do this method to reduce a bit of confusion even though we are “wasting” some IPv6 prefix address space. I believe the operational benefits are worth the tradeoff of the address space use, assuming you obtained the appropriate sized prefix for your organization.
Now that we understand the reasons to do this, we can jump into the display issues and how to really understand the difference. Let’s cover some specifics around how to display a prefix verses an address.
2001:db8:a1d5::
How can you tell if this is an IPv6 address or a prefix? How is it different from the following prefixes?
2001:db8:a1d5::/48
2001:db8:a1d5::/52
2001:db8:a1d5::/64
The only way to know for sure is to have some shared agreement on conventions for displaying an address verse a prefix. The easy answer is anything displaying a “/” notation is a prefix and anything without a “/” is an address. This means in the case of the first example, it is an address and fully expanded it is:
2001:db8:a1d5:0000:0000:0000:0000:0000
That represents a completely legitimate IPv6 address that can be used on a host without any issue. IPv6 is a bit more confusing because we don’t have the concept of a network and broadcast address (top and bottom addresses in IPv4 for a given subnet that are held in reserve to “describe” the network and the all hosts). Therefore, a zero value for the last nibble is completely acceptable and with zero compression means that you can have very short addresses. Some great examples are the unspecified and loopback addresses in IPv6. They are:
::
::1
Uncompressed fully-expanded they are written as:
0000:0000:0000:0000:0000:0000:0000:0000
0000:0000:0000:0000:0000:0000:0000:0001
The difference for the address verses a prefix, which we would use in a routing table for instance, is a bit clearer when we look at how the default route is represented in IPv6.
::/0
That represents a prefix of all zeros with no significate network bits. Therefore it encompasses all IPv6 addresses. In IPv4 we use 0.0.0.0/0.0.0.0 to represent the default route, but to help avoid confusion we chose to use ::/0 to represent the exact same concept in IPv6.
Now we can review through the three example prefixes to try and understand the difference of what is being represented in each one. They were:
2001:db8:a1d5::/48
2001:db8:a1d5::/52
2001:db8:a1d5::/64
With zero compression removed to highlight the point of their significant prefix nibble they become:
2001:db8:a1d5::/48
2001:db8:a1d5:0000::/52
2001:db8:a1d5:0000::/64
Perhaps an uncompressed prefix with some identifiers will help. Switching to a fixed length font to line things up!
2001:db8:a1d5:0000:0000:00000:0000:0000
^
48-bits
2001:db8:a1d5:0000:0000:00000:0000:0000
^
52-bits
2001:db8:a1d5:0000:0000:00000:0000:0000
^
64-bits
So what does this mean in terms of understanding the different prefixes when represented in a routing table? And how can we avoid this sort of display confusion to help reduce the impact of operational issues?
First, you must pay attention to the prefix that is displayed in the routing table. In fact, this is no different than IPv4 but is worth emphasizing.
Second, be cognizant how you document, display and store information around an IPv6 address verse a prefix is now important.
Third, you have to decide if you are using /127 and /128 prefixes if you will include the prefix with an address to highlight they are NOT the default /64.
Fourth, avoid “all-zero” addresses so that it is easier to tell the difference between a prefix and an address. This is an operations principal to help reduce errors and mistakes.
One of the challenges (as shown in the diagram) is how to properly allocate and summarize /127 (links) and /128 (loopback) prefixes. There are two schools of thought.
One is to allocate /127 network prefixes from a single /64 and allocate /128 addresses from an additional /64. This seems reasonable until you start to look at the summarization issues and the impact of /127 and /128 sized prefixes on your routing tables.
The second is to allocate a /64 for each link (/127) and loopback (/128) allowing efficient prefix entries. You use more network prefixes to accomplish this (what some would consider wasting address space) but you gain consistent prefix length entries in a routing table.
Regardless of which method you use, you should consider at routing boundaries have your longest prefix advertisement to be a /64. Ideally, if possible, it would be nice to have your longest prefix be the allocation you use for a single data center, branch, campus or building (such as a /60 or perhaps a /48).
One practice that is not as common for IPv4 networks (except perhaps service provider) is to build out a separate infrastructure address prefix. For IPv6, due to the abundance of network prefix space, an organization should consider allocating a /48 just for infrastructure per site. This allows the separation of services and the underlying infrastructure that runs the actual data center, building, or campus. Some operators chose to allocate a /64 or several /64’s out of the /48 that is allocated for that site to do this function but I find this limiting of what could be done in the long term. Remember, as technologies like OpenStack, Containers and Orchestration technologies are deployed on top of data center environments it becomes more important to have isolation between the underlay (infrastructure) and the services that operate in the overlay.
There are some additional consideration in loopback addresses and around the impact of link-local addresses and the routing table. Because the next hop from one router to the next router will utilize a link-local address it is often useful to include more information in your loopback address. I covered this in my previous post “The operation trouble with the IPv6 address format” but in summary you will likely want to include information like VLAN and/or router id. It makes it easier to understand in a local routing table which route is going to which router. This might make sense to also do in your global unicast addresses used for loopback, having some sort of embedded information to identify the router makes things easier to comprehend which troubleshooting or documenting a network.
You can find me on twitter as @ehorley and remember…
IPv6 is the future and the future is now!
– Ed