How to subnet IPv6 ?

Subnetting IPv6 sounds very complex but to be true - it is very easy! All you need to do is to understand basics of IPv6 addressesing - how an address is formed and how to efficiently use CIDR notation.   Firstly how an IPv6 address looks like? (good to clear fundamentals first!) An IPv6 address has 8 sections seprated by coloums and each sections has carries 4 hexadecimal digits. So an IPv6 address is something like: xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx - Each x can have a hexa decimal value i.e from 0 to 9 and a to f. Thus 16 possible values for each x. Since each each x is stored in binary i.e 0 or 1 (that is 2 possible value) - number of bits per section turns out to be 2x2x2x2 = 16bits. Thus we have now each section with 16 bits per section and 8 sections in total. This turns out to be 16 + 16 + 16 + 16 + 16 + 16 + 16 + 16 bits = 128bit. This is why an IPv6 address has 128bits. This means total possible addresses in IPv6 space is 2^128 = 340 282 366 920 938 463 463 374 607 431 768 211 456 addresses. Next, an important point to remember here is  - in IPv6 address clients are mostly based on /64 subnet which means first 64 bits go to network part while next 64 bits go to the host part i.e usage IPv6 addresses which are allocated to end machines.  

Now getting back on main question on how to subnet IPv6?

In most of cases RIRs like ARIN/APNIC allocate a /32 IPv6 block. This means first 2 sections 16+16 bits are reserved and rest 6 sections i.e 128-32 = 96 bits are available for use.   E.g let’s pick example of Google’s block. Google has a allocation of 2404:6800::/32 from APNIC in Asia. Now this is HUGE chunk. First let’s understand what is range of 2404:6800::/32 looks like. :: here means that zeros are skipped and thus we can fill zeros to understand block. 2404:6800::/32 means = 2404:6800:0000:0000:0000:0000:0000:0000/32 and since only first 32 bits (16 bit per section) are reserved - we have first 2 sections reversed while rest 6 sections are available and we can fill any hexa decimal value in those sections. Thus block 2404:6800::/32 goes from 2404:6800:0000:0000:0000:0000:0000:0000 to 2404:6800:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF   Now that’s a huge number of address space. You can simply count it by doing 2 to the power 96 (128-32) which will be 792 281 625 142 643 375 935 439 503 36 unique possible addresses!  

Breaking it down further…

  1. If you have multi datacenter setup - it is very likely that you would like to use IPv6 space across multiple locations and thus doing a BGP announcement for whole /32 isn’t a very good idea.
  2. Many people on NANOG mailing list suggested me to use /48 block as it works well with BGP and most of ISPs do accept a /48 block.
  3. Most of servers are allocated /64 block of IPv6 further down.

So in idea situation - you would have to break your /32 allocation into multiple /48s - which you can annouce from BGP and further /64s out of /48 for allocation per server/per client.   At this point it is likely that will think of how many such small blocks are possible out of main bigger block?   Ok - here’s the answer. You can break /32 into 65,6536 /48s. Each can represent a separate network below a BGP session. Next, you can further break /48 block into 65,536 /64s and each /64 you can allocate to a client. Thus each client will have 2^64 addresses i.e 184 467 440 737 095 516 16 addresses per client!  

Let’s break it!

Coming back on example of Google’s block - 2404:6800::/32 here to get /48s out of the block - all you need to do is to change the 3rd section. Remember as each section represents 16bits, altering 3rd section gives 16+16+16 = 48 bits. Thus possible /48s out of 2404:6800::/32 will be 2404:6800:1::/48 2404:6800:2::/48 2404:6800:3::/48 also since it takes hexadecimal values, we can put a,b,c,d,e & f. 2404:6800:a::/48 2404:6800:b::/48 one can also use complete combination to fill all 4 digits i.e 2404:6800:XXXX::/48 here XXXX can take hexa decimal values of 65,536. next, in similar manner altering 4th section gives /64s. Possible /64s out of Google’s IPv6 block: 2404:6800:1:1::/64 2404:6800:1:2::/64 2404:6800:1:3::/64   Next, each client can alter last 4 sections - and generate ton of IPv6 addresses! E.g unique IP addresses 2404:6800:1:1::1 which is 2404:6800:1:1:0000:0000:0000:0001  2404:6800:1b11:21dd:00ab:0030:0020:0001  or just anything!  

Quick point to remember here:

  1. If you alter JUST the last i.e 8th section you can have 65,536 (2^16) IPs.
  2. If characters in hexa decimal values confuse you, you can simply take last section values from 0 to 9999 i.e 10k possible IPs by just altering last section without hexa decimal.
  3. Its a good idea to alter just last section and fill zeros in 5th, 6th and 7th section because 10k IPs would be sufficient per server and one can always add more later.
  4. Also when filling 0 in 5th, 6th and 7th section, one can simply use double coloumn notation i.e  2404:6800:1:1:0000:0000:0000:0001 can be written as 2404:6800:1:1::1 skipping all zeros!

    Well that’s all about IPv6 addressing. Hope you will find it useful! :)