Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / IPv6

Subnetting with IPv6 Part 1/2

5.00/5 (19 votes)
9 Jun 2022BSD7 min read 57.3K  
In this article I try to explain how IPv6 subnetting works by giving examples.

Introduction

We are in the transition phase from IPv4 to IPv6 addressing structure, and I believe that the network engineers should easily plan their IPv6 addressing /subnetting infrastructure without any error. In this article, I tried to explain how IPv6 subnetting works by giving examples.

I also wrote and distributed a free IPv6 Subnetting Tool / Calculator both with C# and Java JDK 17 application frameworks. It lets you plan/subnet your assigned address for all 128bits. You can find the applications in the second part of this article.

I distributed the applications in the hope that it will be useful for your subnet calculations. I will try to develop the software continuously, so please don't hesitate to comment/inform for any bugs or new feature suggestions.

1. How Does '/' (slash or prefix-length notation) Work with IPv6?

The '/' indicates the number of bits which are fixed for your subnetwork. Fixed means that you do not have any control on these bits, you must not change them (I like to call them "don't touch only watch bits"). IPv6 is 128 bits long and your network/organization is assigned "128 minus /prefix-lengthValue" and these are the bits given under your control. You can do your subnetting with these bits and assign addresses to your computer/car/mobile/etc.

For example, assume that the prefix '2001:db8:1234::/48' is assigned to your network by your service provider (or by RIPE, ARIN, etc). In this case, /48 indicates that starting from the left-most bit up to and including the 48th bit, these bits are fixed and must not be changed (don't touch only watch). And the rest of the bits which have the length of 128-48=80bits are given to your control, i.e., for addressing and subnetting.

So, the importance of '/' prefix-length is that it indicates the boundary of your network. In other words, from which number your assigned network starts and at which number it ends.

2. Finding IPv6 Start and End Addresses of our Subnet

If we have for example 192.168.3.0/24 subnet prefix, then 24 bits are fixed. You must not change these bits. And our netmask will be 255.255.255.0, we can do subnetting by using 32-24=8bits by taking care of subnet and broadcast addresses, as we all know very well with our IPv4 experience.

2.1 Three Useful Bitwise Operators: & , | , ~

& (AND), | (OR), ~ (NOT or bit INVERTER): We will use these three bitwise operators in our calculations. I think everybody is familiar -at least from university digital logic courses- and knows how they operate. I will not explain the details here again. You can search for 'bitwise operators' for further information.

Now with our IPv6 subnet-prefix assigned, how can we find our subnets and starting and end addresses of it? We can easily calculate them with the help of these three logic operators as follows. I will try to demonstrate on both IPv4 and IPv6.

With IPv4

What is our mask if we have '/24'? Remember CIDR notation, it is simply 255.255.255.0 which is 24 bits all 'set' or 'all one' starting from the left-most bit up to and including 24th bit.

Finding Start Address is to 'AND' the address with your mask which is:

(192.168.3.5) & (255.255.255.0) = 192.168.3.0 

This is our Starting Address, or as we call Network address.

Finding End Address is to 'OR' the address with your inverted (NOT) mask which is:

(192.168.3.5) | ~(255.255.255.0) = 192.168.3.255 

This is our End Address, or as we call Broadcast address.

With IPv6

What is our mask if we have '/48'? Simply it is ffff:ffff:ffff:: for which all 48 bits are 'set' or 'all one' starting from the left-most bits up to and including 48th bit. As you can see, the evaluation way of the mask is exactly the same as in IPv4. As for our IPv6 subnet prefix '2001:db8:1234::/48', again the same calculation method applies. It is also useful to remember that we always use 'hexadecimal' instead of decimal numbers for addressing since IPv6 is completely based on hexadecimal numbers. So,

Finding Start Address is to 'AND' the address with your mask which is:

(2001:db8:1234::) & (ffff:ffff:ffff::) = 2001:db8:1234::

Finding End Address is to 'OR' the address with your inverted (NOT) mask which is:

(2001:db8:1234::) | ~(ffff:ffff:ffff::) = 2001:db8:1234:ffff:ffff:ffff:ffff:ffff

As a result, for the subnet-prefix '2001:db8:1234::/48' we have the range or interval of our subnet:

IPv6 subnet Start Address> 2001:db8:1234:0:0:0:0:0 (or compressing zeros 2001:db8:1234::) 
IPv6 subnet   End Address> 2001:db8:1234:ffff:ffff:ffff:ffff:ffff

Also remember that we don't have broadcast mechanism in IPv6, so we don't have broadcast address.

3. How to Subnet with IPv6 Subnet-prefix?

As we know, our first prefix-length indicates the fixed bits and we can borrow bits starting from (but excluding) prefix-length value towards the right-most bit (from left to right).

Example

Let's use the subnet-prefix '2001:db8:1234::/48', and borrow 2 bits for subnetting.

The beauty of number conversion shows itself when we do hexadecimal to binary conversion. When converting from hex-to-binary or vice versa, you can simply and directly convert each hex-digit into binary form without caring about the digit weights. In hexadecimal notation, each hex-digit corresponds to 4 bits, usually called as 'nibble'. Our example address in expanded form and with nibbles are:

  2    0    0    1  :   0    d    b    8  :   1    2    3    4  :  0    0   ...(the rest zeros)

0010 0000 0000 0001 : 0000 1101 1011 1000 : 0001 0010 0011 0100 : 0000 0000 ...(the rest zeros)

Let's borrow 2 bits which are 49th and 50th bits:

0010 0000 0000 0001 : 0000 1101 1011 1000 : 0001 0010 0011 0100 : 0000 ... (all the rest zeros)

By borrowing 2 bits, we can have 22= 4 unique subnets, which are:

0010 0000 0000 0001 : 0000 1101 1011 1000 : 0001 0010 0011 0100 : 0000 ...(the rest zeros)
0010 0000 0000 0001 : 0000 1101 1011 1000 : 0001 0010 0011 0100 : 0100 ...(the rest zeros) 
0010 0000 0000 0001 : 0000 1101 1011 1000 : 0001 0010 0011 0100 : 1000 ...(the rest zeros) 
0010 0000 0000 0001 : 0000 1101 1011 1000 : 0001 0010 0011 0100 : 1100 ...(the rest zeros) 

Let's convert these numbers back into hexadecimal and see the result:

2001:db8:1234:0000::/50 (First subnet)    
2001:db8:1234:4000::/50 (Second subnet)   
2001:db8:1234:8000::/50 (Third subnet)    
2001:db8:1234:c000::/50 (Fourth subnet)   

If you are a service provider, you can assign these subnet-prefixes to your customers one by one with '/50' prefix-length, e.g., 2001:db8:1234:0000::/50 for one customer, and 2001:db8:1234:4000::/50 for other, etc.

And now your customers should know the End of their assigned address space. At this point, remember finding Start and End addresses of our subnet and perform the calculations.

First of all, your customers will have mask of '/50' which is all 50 bits 'set' or all 50 bits are 'ones' giving us the mask of 'ffff:ffff:ffff:c000::'. Now using this mask, we can easily calculate the start-end addresses, i.e., the range or interval of our subnet. Let's do it one by one.

1st. Customer subnet Start address= 
(2001:db8:1234:0000::) & (ffff:ffff:ffff:c000::) = 2001:db8:1234:0000:0:0:0:0 = 2001:db8:1234::
1st. Customer subnet End address= 
(2001:db8:1234:0000::) |~(ffff:ffff:ffff:c000::) = 2001:db8:1234:3fff:ffff:ffff:ffff:ffff

2nd. Customer subnet Start address= 
(2001:db8:1234:4000::) & (ffff:ffff:ffff:c000::) = 
                  2001:db8:1234:4000:0:0:0:0 = 2001:db8:1234:4000::
2nd. Customer subnet End address= 
(2001:db8:1234:4000::) |~(ffff:ffff:ffff:c000::) = 2001:db8:1234:7fff:ffff:ffff:ffff:ffff

3rd. Customer subnet Start address= 
(2001:db8:1234:8000::) & (ffff:ffff:ffff:c000::) = 
                  2001:db8:1234:8000:0:0:0:0 = 2001:db8:1234:8000::
3rd. Customer subnet End address= 
(2001:db8:1234:8000::) |~(ffff:ffff:ffff:c000::) = 2001:db8:1234:bfff:ffff:ffff:ffff:ffff

4th. Customer subnet Start address= 
(2001:db8:1234:c000::) & (ffff:ffff:ffff:c000::) = 
                  2001:db8:1234:c000:0:0:0:0= 2001:db8:1234:c000::
4th. Customer subnet End address= 
(2001:db8:1234:c000::) |~(ffff:ffff:ffff:c000::) = 2001:db8:1234:ffff:ffff:ffff:ffff:ffff

Notice that each of the subnet-prefixes can also be used again to perform subnetting. For example, the 4th customer may use the subnet-prefix '2001:db8:1234:d000::/50' to do subnetting by borrowing bits again say from /50 to /54, according to their needs of course.

4. Idea of Parent (or root) prefix

When you apply to your service provider (or RIPE, ARIN, APNIC, LACNIC, etc.) for an IPv6 prefix range, they will assign a prefix for you with '/xy' prefix-length. For example, assume that '2001:db8:1234::/48' was assigned for your network infrastructure. In this case, '2001:db8:1234::/48' will be your parent (or root) prefix since all your sub-assignments must be created under your parent prefix. It is similar to the parent (root) node of a tree data structure – similarly used in our internet DNS system.

In addition, when you create new subnet prefixes, each of them may also be called as 'parent (or root)'. We may say that it’s similar to 'network address' of a subnet that we use in IPv4. But keep in mind that we don’t have network or broadcast address mechanism in IPv6.

Let’s give an example: Assume that you have the prefix '2001:db8:1234:4000::/50' and created 4 new sub-prefixes by borrowing 2 bits (similar to subnetting example above), which are:

p0> 2001:db8:1234:4000::/52
p1> 2001:db8:1234:5000::/52
p2> 2001:db8:1234:6000::/52
p3> 2001:db8:1234:7000::/52

Here we can say that '2001:db8:1234:4000::/50' is the parent of the four prefixes above.

 (Parent or root prefix)
2001:db8:1234:4000::/50     (Child prefixes)
                      \__ 2001:db8:1234:4000::/52
                       |_ 2001:db8:1234:5000::/52
                       |_ 2001:db8:1234:6000::/52
                       |_ 2001:db8:1234:7000::/52

Notice that each child prefix may also be a parent prefix. When you use the application, the prefix (first trackbar) value will define the parent prefix. If you use database with the application, parent prefixes are automatically inserted into the database as equal prefix and parent prefix values.

Summary

In order to find the starting and end address of your subnet, you only need to know IPv6 address and prefix-length value. Remember these bitwise operations (which are also valid for IPv4):

(IPv6 Address) &  (/prefix-length mask) is equal to (IPv6 subnet Start address)
(IPv6 Address) | ~(/prefix-length mask) is equal to (IPv6 subnet End address)

(Follow the link for the second part of this article: Subnetting with IPv6 Part 2/2[^] )

History

  • 28th September, 2013: v1.0
  • 26th January, 2014, v1.1: A few typing corrections
  • 13th November, 2017, v2.0: Java application is based on JavaFX
  • 23rd October, 2019: C# v4.0 (based on .NET 4.7.2) and JavaFX v3.3
  • 6th January, 2020: C# v4.1 (based on .NET 4.8 and with IPv4 mode available)
  • 9th June, 2022: C# v5.0 and Java v4.0 based on Java JDK 17 (JavaFX will not be used)

License

This article, along with any associated source code and files, is licensed under The BSD License