As I was doing a Vol2 workbook lab the other day I found out that even if I have learned IPv6 tunneling before I was unable to configure it properly. That is why I have decided to make a post on IPv6 tunneling and I will especially focus on the protocol 6to4 described in RFC 3056 which facilate the deployment of IPv6 over IPv4 networks through tunnels. I will also talk briefly of RIPng, EIGRPv6 and IPv6 MP-BGP.
I will first talk about some static tunnel mechanisms and then I will explore 6to4 in more details. For this topic I will use the following topology:
IGP: EIGRP AS 100
Platform/IOS: Cisco 2691/12.4(15)T11 Adv IP services
In the topology, there are 3 IPv6 only sites and these sites have been allocated an 2002:ipv4-address::/48 prefix from the ISP where the IPv4-address is a public address. 6to4 prefixes are all based on the 2002::/16 address space assigned by the IANA.
All the loopbacks IP address have been advertised intro EIGRP and will be used as the source tunnel IP for static tunnels.
IPv6 Static tunnels
IPv6 can be transported across IPv4 clouds using various tunneling techniques. The most common are static point-to-point tunnels, using either GRE (Generic routing encapsulation), or IPv6 in IPv4 encapsulation (a special protocol type designed to carry only IPv6 packets). While GRE can encapsulate multiple protocol payload it has a slightly larger overhead than IPv6 in IPv4 encapsulation which can limit its use on high bandwidth link.
Let´s start by using GRE in order to encapsulate IPv6 traffic from the 3 different sites so they will be able to reach each other. On all the routers (R1, R2, R3) we use the following GRE template:
X corresponds to the site number and Y at the site destination number. So On R1 we get the following configuration:
Side note: As soon as the routing process is able to resolve the destination IP address in the routing table and find an outbound interface the line protocol of the tunnel will come up. It doesn’t mean that on the other side, the tunnel is actually configured yet.
Let´s configure the other tunnels on R2 and R3 so each site has 2 tunnels as these static GRE tunnels are point-to-point tunnels.
Tunnel 12 is between R1 and R2.
Tunnel 13 is between R1 and R3.
I have used the 2002::/16 6to4 format for simplicity in the topology in order to avoid configuring another IPv6 range and change it again when I am going to cover 6to4. We could have use any Aggregable Global Unicast address instead in the range of 2001::/16 which is the range defined for IPV6 Internet production.
Now that the tunnels are configured let´s check the connectivity between the sites from R2 perspective:
So R2 and R1 are able to ping each other IPv6 address configured on the tunnel interface. Let´s see how the packet looks like when transiting from R2 to R1:
From the above Wireshark capture we can see that the total length of the IP packet is 74 Bytes which is calculated as follows:
24 for IP/GRE header, 40 Bytes for IPv6 header, and 10 Bytes for payload.
The total frame is 78 Bytes accounting for the HDLC header but the HDLC header is 7 bytes so Wireshark is somehow not accounting for the remaining 4 Bytes of the HDLC header. Although I have sent a ping with a size of 50 Bytes the router is accounting for the whole IPv4 payload as being 50 Bytes which leaves only 10 Bytes for the IPv6 ping data as IPv6 has a header of 40 Bytes.
As we can see in the Wireshark output, GRE has an IP protocol number of 47. Actually if we do some debug ip packet detail on R1 (use ACL to remove EIGRP packets from output) we can see the following when pinging from R2 to R1:
So we can also confirm with the debug command which kind of tunnel protocol is being used. It can be useful to know when troubleshooting if there are Firewall in the path that could eventually filter this kind of traffic out.
Finally let´s verify connectivity to R3 from R2:
So now each Site is able to send IPv6 traffic over the IPv4 network. Let´s look at one of the tunnel interface on R1:
So we can verify with the above output that the transport protocol is IP and the Tunnel protocol is GRE which is the default mode. Next let´s see how the same tunnel interface is configured at IPv6 L3:
We can see that the interface has different type of IPv6 address assigned:
- FE80::/16: Link-Local address: Scoped unicast address only used between nodes connected on the same local-link. Never routed between interfaces. This address is automatically assigned to an interface when it is enabled for IPv6. This address is also Used by control plane protocols such as IPv6 routing protocols.
- 2002:6401:1:12::/64: Aggregable Global Unicast. Used and reserved for 6to4 tunnel protocol. In this case we use it also for static tunneling for simplicity to avoid renumbering all the sites when I will talk about 6to4.
We could change the tunnel mode to IPv6 over IPv6IP tunnel mode. Let´s try quickly on two sites only to see the difference (site 1 and site 2). We configure the following on the tunnel 12 on R1 and R2:
When we ping from R2 to R1 we can see the following packet format:
So now the encapsulating protocol is 41 which means that IPv6 over IPv6IP tunnel is used but this tunnel protocol cannot support other type of payload in the tunnel than IP unlike GRE. On the other head there is less overhead as we can see in the above Wireshark capture (-4 bytes) compare to GRE.
Let´s set the tunnel protocol to GRE again before we move on.
If you look at the topology you will see that there is 3 IPv6 clients, one at each site. In order to get IPv6 connectivity between them we could use static route but in this example and also for simplicity we will use RIPng to propagate routing information over the tunnels.
So let´s configure RIPng on all tunnel interfaces as well as the FastEthernet interface configured only for IPv6 at each site. Here is the RIPng configuration example at R1:
RIPng is enabled on a per-link basis. Once we have enabled RIPng on all sites we can have a look at a Wireshark capture and see what is the format of a RIPng multicast packet sent from R1 to R3:
As we can observe from the output above RIPng packet are multicast to IPv6 address ff02::9 and use source/destination UDP port 521 (520 for RIP IPv4). We can also see the different prefixes being advertised. Let´s check now the IPv6 routing table of R1 to check if it has learned the IPv6 networks from site 3 and site 2 where both Client 2 an Client 3 are attached:
Alright! So now we should have connectivity to these IPv6 clients. Let´s try to ping them from Client1:
IPv6 Client 1 has connectivity to Client 2 and Client 3 and site 2 and 3 respectively.
Side note: An interesting fact is that I haven´t configured an IPv6 default route on the clients. In IPv6, nodes use the default router when no specific route is present in the routing table. When pinging from Client 1 to Client 2 we can observe that Client 2 is sending traffic to Client 1 based on the default router:
R2 is multicasting to all nodes (FF02::1) present on the same link his presence using ICMPv6 Type 134 (Router Advertisement). The source IP of these RA announcements is the link-local IPv6 address of the router. So even if the prefix is renumbered on Client 2 the router can always be reached as the link-local address of the router will not change.
So the solution with static tunnel works but it is not really scalable if there are many sites. In this case we need 2 tunnels per site in order to have a full mesh. There is a more scalable solution which is to use Automatic 6to4 tunnels. Let´s see how it works.
IPv6 6to4 tunneling
6to4 is an automatic method to deploy tunnels between sites made up of IPV6 nodes. Automatic 6to4 tunnels are multipoint by design. The idea is to allow automatic routing across an IPv4 cloud based on the part of the destination IPv6 address. The format of the IPv6 address is as follows:
2002(16 bits):IPv4 address (32 bits):Subnet ID (16 bits):Interface ID (64 bits)
6to4 is the simplest way to tunnel between your networks over the public Internet. Even if you are running MPLS service and you don´t want the ISP to be involved with your IPv6 routing you can configure a 6to4 tunnel which is a multipoint IPv6 IP site to site tunnel.
When a packet is routed across the 6to4 tunnel, the router extracts the IPv4 address embedded in the IPv6 address and uses it to build the IPv4 destination address of the tunnel header. The receiving router strips the header, extracts the IPv6 packet, and routes it based on the IPv6 routing table.
6to4 has some addressing restrictions as you need to use the 2002::/16 prefix as it is the common reservation for all 6to4 deployments. Moreover you need to select the public IPv4 address used to create the /48 prefix. It is common to pick any interface of the border router and then allocate the /64 subnets to other devices on the network, as long as the address is publicly routable.
6to4 is not good solution if you want to run globaly routable address space. So this solution is a temporary stop gap for transitioning from IPv4to IPv6.
In our example each site gets a /48 prefix which is based on the public IPv4 address of each edge router which are R1,R2,R3. Let´s see the different /48 prefix for each site (have a look at the topology at the beginning of the post):
- Site 1: Public IPv4 address: 126.96.36.199 /24. Conversion in Hexadecimal gives: 64:1:0:1 So if we inject this result in the 6to4 prefix format we get: 2002:6401:1::/48. An IPv6 address is made of 8 blocks of 16 bytes which is 128 bits in total. So the /48 prefix for Site 1 is: 2002:6401:1::/48
- Site 2: Public IPv4 address: 188.8.131.52 /24. So the /48 prefix for Site 2 is : 2002:6401:2::/48
- Site 3: Public IPv4 address: 184.108.40.206 /24. So the /48 prefix for Site 2 is : 2002:6401:3::/48
Then for each site I have subnetted the /48 prefix into a /64 which gives up to 2^16 possible subnets, that is to say 65536 possible subnets. So the clients at each site get the following IP:
- Site 1: Client 1 gets the following IPv6 address: 2002:6401:1:1::2 /64
- Site 2: Client 2 gets the following IPv6 address: 2002:6401:2:2::2 /64
- Site 3: Client 2 gets the following IPv6 address: 2002:6401:3:2::2 /64
You could also use this command to make the router generate an automatically 6to4 /48 prefix based on the public IPv4 address of the WAN interface :
I would like to explain what is happening on an end-to-end IPv6 ping between Client 1 and Client 2 when running 6to4 tunneling:
Client 1 pings the IPv6 address of Client 2 which is 2002:6401:2:2::2 and send the packet with the source of 2002:6401:1:1::2 /64. The IPV6 packet is delivered natively over IPv6 toward the defult router R1 at site 1 which acts as a 6to4 router. Then R1 looks at the packet´s destination IPv6 address and extracts the IPv4 address embedded in the destination IPv6 address so in our case the destination IPv4 address of 2002:6401:2:2::2 will be 220.127.116.11. R1 uses this IPv4 address as the destination of the IPv6 tunneled packets. That is why is called automatic 6to4 as you don´t need to configure the destination IPv4 address on the tunnel interface as the 6to4 process will do it automatically by extracting the destination IPv4 address.
Once the extraction is done R1 encapsulate the IPv6 packet into an IPV4 packet with a source IP corresponding to the WAN interface of R1 and a destination IP based on the extracted IPv4 address. This destination IPv4 address represents Site 2 public IP address.
The 6to4 R2 router at Site 2 receives the encapsulated packet, decapsulates the IPv6 packets and route it to Client 2. Then the same process happens again in the opposite direction.
So let´s try to configure 6to4 on all three routers, R1,R2,R3. First I will remove all the tunnels previous configured as well as the IPv6 routing protocol RIPng we used before for testing static IPv6 tunneling. Once everything is removed I will apply the following tunnel configuration template on R1,R2,R3:
Where X is the site number. In this case I use subnet 0 for the tunnel IPv6 address. Once configured the configuration on R1 looks like this:
The Clients are already configured with the IPv6 address shown on the topology so actually everything should be find to test. However note that the different tunnels will only be established when the Clients are sending traffic to each other. Actually we miss one thing. We have to tell the edge routers where to route the IPv6 traffic received from their LAN interface with a destination of 2002::/16 in the destination IPv6 header. We simply configured the following IPv6 route on R1,R2 and R3 pointing the 6to4 tunnel:
So no routing protocols is needed as we route the whole 2002::/16 prefix out the tunnel interface and 6to4 prefixes are based on the globally unique IPv4 addresses.
Let´s test the connectivity between Client1 and Client 2:
Let´s try now from Client1 to Client 3:
If we look again at the format of the packet when Client 1 ping Client 2 the output is the following in Wireshark:
We can clearly see that the 6to4 process extract the destination IP from the IPv6 destination IP 2002:6401:2:2::2 which is 18.104.22.168.
So we have achieved IPv6 connectivity between the 3 sites using 6to4. The big advantage is that future subnet in the IPv6 range of each site will be automatically routed between the different sites thanks to the automatic nature of 6to4. On the other hand only the 2002 prefix will be automatically routed which force the use of this IPv6 range for 6to4 to work. What if some sites use a Global IPv6 address not in the 2002::/16 range prefix and want to advertise this prefix over the 6t04 tunnel?
Well, we cannot use IGP routing protocol like EIGRP IPv6 because the destination address which is multicast FF02::A (for EIGRP IPv6) cannot be routed out the 6to4 tunnel. It is because 6to4 process is unable to extract a valid destination IPv4 address from the multicast address FF02::A as this address doesn´t have the 2002::/16 prefix format. See an example bellow when enabling EIGRP v6 on tunnel interface on R1:
The router is unable to route the packet as there is no destination IPv4 address in the encapsulating IPv4 header.
But what about BGP? Ok let´s try 😉
IPv6 6to4 tunneling with MP-BGP
So let´s go ahead and configure IPv6 MP-BGP on R1 and R2 with AS 100 and 200 respectively. We create a loopback interface on R1 with IPv6 Unique Local address (similar to RFC1918 in IPv4) of : FC00:1::1/64. This Prefix will be announced into BGP.
Configuration of BGP on R1 and R2:
Multi-protocol extensions for BGP adds supports for the IPv6 address family, which essentially means that IPv6 prefixes and attributes can be exchanged over a normal TCP based BGP peering. Technically it is the same process used in IPv4 peering, but the normal global BGP process automatically refers to the address-family IPv4 unicast and the command bgp default ipv4-unicast is enabled by default which means that all unicast IPv4 peers are automatically activated.
Let´s check once the BGP session is established if R2 has received the IPv6 prefix for the loopback of R1:
So yes it did! The next hop here is really important as 6to4 is gonna use this information for resolving the IPv4 destination IP address of the tunnel.
Let´s try to ping from Client 2 to FC00:1::1 which is the IPv6 address of the loopback of R1.
So there is connectivity to the loopback of R1 although this prefix is not in the range of the 6to4 2002::/16 prefix and this is thanks to BGP next hop recursion process. For every packet routed to a prefix learned via BGP over a 6to4 tunnel, the next hop will be built based on the NEXT_HOP attribute and proper tunnel header will be constructed. This allows for scalable overlay 6to4 networks.
Actually if we look at a Wireshark capture while pinging from Client 2 to FC00:1::1 there is no information regarding the “destination 6to4 Gateway IPv4” like we saw before as now 6to4 use the next-hop IPv6 address to resolve the destination IPv4 address of the tunnel header:
Thanks for reading!