Thanks for visiting! If you're new here, you may want to subscribe to my RSS feed. This blog posts regular tutorials, news, and study tips about networking, especially about Cisco CCIE related topics. Go ahead, subscribe to the rss feed! You can also receive updates from this blog via email. Thanks for visiting!
Lets face it, sooner or later we are going to move to IPv6. Probably closer to the sooner side than some of us are comfortable with. In this series of articles we will be introducing tunnels and taking a look at how they can be used as part of you migration towards IPv6. Working with IPv6 tunnels is also an important part of a CCIE candidate’s journey, so mastering them is important. In this article we will be looking at tunneling IPv6 over IPv4 using manual tunnels, specifically GRE and IPv6 in IPv4.
We will be using the following topology for this tutorial:

Dynagen .net configuration:
ghostios = True
sparsemem = True
model = 3640
[localhost]
[[3640]]
image = \Program Files\Dynamips\images\c3640-ik9o3s-mz.124-7.bin
# On Linux / Unix use forward slashes:
# image = /opt/7200-images/c7200-jk9o3s-mz.124-7a.image
ram = 96
[[ROUTER R1]]
f0/0 = LAN 1
s1/0 = FRAME 1
console = 2000
model = 3640
[[ROUTER R2]]
f0/0 = LAN 2
s1/0 = FRAME 2
console = 2001
model = 3640
[[ROUTER R3]]
f0/0 = LAN 3
s1/0 = FRAME 3
console = 2002
model = 3640
[[FRSW FRAME]]
1:102 = 2:201
1:103 = 3:301
You can download the dynagen/dynamips .net configuration file for this topology here.
Lets have a look at the basic configuration for this topology:
R1
hostname R1
!
ipv6 unicast-routing
!
interface Loopback0
ip address 10.10.10.10 255.255.255.255
!
interface FastEthernet0/0
no ip address
ipv6 address 2001:1:1:1::1/64
!
interface Serial1/0
ip address 10.1.123.1 255.255.255.0
encapsulation frame-relay
ip ospf network point-to-multipoint
frame-relay map ip 10.1.123.2 102 broadcast
frame-relay map ip 10.1.123.3 103 broadcast
no frame-relay inverse-arp
!
router ospf 1
router-id 10.10.10.10
log-adjacency-changes
network 0.0.0.0 255.255.255.255 area 0
R2
hostname R2
!
ipv6 unicast-routing
!
interface Loopback0
ip address 10.20.20.20 255.255.255.255
!
interface FastEthernet0/0
no ip address
ipv6 address 2001:2:2:2::2/64
!
interface Serial1/0
ip address 10.1.123.2 255.255.255.0
encapsulation frame-relay
ip ospf network point-to-multipoint
frame-relay map ip 10.1.123.1 201 broadcast
frame-relay map ip 10.1.123.3 201
no frame-relay inverse-arp
!
router ospf 1
router-id 10.20.20.20
log-adjacency-changes
network 0.0.0.0 255.255.255.255 area 0
R3
hostname R3
!
ipv6 unicast-routing
!
interface Loopback0
ip address 10.30.30.30 255.255.255.255
!
interface FastEthernet0/0
no ip address
ipv6 address 2001:3:3:3::3/64
!
interface Serial1/0
ip address 10.1.123.3 255.255.255.0
encapsulation frame-relay
ip ospf network point-to-multipoint
frame-relay map ip 10.1.123.1 301 broadcast
frame-relay map ip 10.1.123.2 301
no frame-relay inverse-arp
!
router ospf 1
router-id 10.30.30.30
log-adjacency-changes
network 0.0.0.0 255.255.255.255 area 0
You can see above that R1, R2 and R3 are connected via a hub and spoke frame-relay cloud. We will call the networks behind R1, R2, and R3 our “internal” networks. For the purposes of this article we will assume that in our organisation we have successfully migrated fully to IPv6 internally (you wish). IPv4 is used over our frame-relay cloud and this will simulate our WAN.
We are running OSPF over the frame cloud, and have advertised the routers loopback addresses into OSPF. We should have complete IPv4 connectivity between each of the routers the their corresponding loopbacks. Lets verify this:
R3#sh ip route
Codes: C - connected, S - static, R - RIP, M - mobile, B - BGP
D - EIGRP, EX - EIGRP external, O - OSPF, IA - OSPF inter area
N1 - OSPF NSSA external type 1, N2 - OSPF NSSA external type 2
E1 - OSPF external type 1, E2 - OSPF external type 2
i - IS-IS, su - IS-IS summary, L1 - IS-IS level-1, L2 - IS-IS level-2
ia - IS-IS inter area, * - candidate default, U - per-user static route
o - ODR, P - periodic downloaded static route
Gateway of last resort is not set
10.0.0.0/8 is variably subnetted, 6 subnets, 2 masks
O 10.10.10.10/32 [110/65] via 10.1.123.1, 00:15:53, Serial1/0
C 10.30.30.0/24 is directly connected, Loopback0
O 10.20.20.20/32 [110/129] via 10.1.123.1, 00:15:53, Serial1/0
C 10.1.123.0/24 is directly connected, Serial1/0
O 10.1.123.1/32 [110/64] via 10.1.123.1, 00:15:53, Serial1/0
O 10.1.123.2/32 [110/128] via 10.1.123.1, 00:15:53, Serial1/0
You can see above the R3 has routes to each of the three routers looback addresses. We are using a point-to-multipoint tunnel so we can see that each of the spokes has a corresponding /32 route (for a tutorial on OSPF point-to-multipoint network types over frame see this tutorial).
R1#ping 10.30.30.30 source lo0
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 10.30.30.30, timeout is 2 seconds:
Packet sent with a source address of 10.10.10.10
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 52/100/160 ms
So it looks like we have full connectivity between the hubs and spokes over IPv4, but what about our IPv6 networks? The routers will have no connectivity between the IPv6 networks yet because the IPv6 stack does not know how to reach the other networks.
It would be really cool if we could tell the router, to get to the ipv6 network behind R1 use the IPv4 address of R1. Something like:
ipv6 route 2001:1:1:1::/64 10.10.10.10
But that won’t work! To route IPv6 traffic for a particular IPv6 network we need an IPv6 destination. (We actually can do something like the above, but we’ll leave 6to4 tunnels for our next article!).
We need someone way of providing connectivity between the disconnected IPv6 networks. Enter the tunnel!
The first thing that we are going to configure is manual GRE tunnels to carry the IPv6 traffic over IPv4. Tunnels (along with static routes, and policy based routing) are the duct tape of networking :). They can be used to solve just about any tricky routing problem.
The way tunnels solve this, is by encapulating and carrying the IPv6 traffic inside an IPv4 header (or GRE in this case). Traffic between the tunnel end points just see standard IPv4 traffic. The tunnel itself can have an IPv6 address, so we can route IPv6 traffic over it.
Lets have a look at the basic GRE tunnel configuration:

R1
hostname R1
!
ipv6 unicast-routing
!
interface Tunnel12
no ip address
ipv6 address 2001:12:12:12::1/64
tunnel source Loopback0
tunnel destination 10.20.20.20
tunnel mode gre
!
interface Tunnel13
no ip address
ipv6 address 2001:13:13:13::1/64
tunnel source Loopback0
tunnel destination 10.30.30.30
tunnel mode gre
!
interface Loopback0
ip address 10.10.10.10 255.255.255.255
!
interface FastEthernet0/0
no ip address
duplex auto
speed auto
ipv6 address 2001:1:1:1::1/64
!
interface Serial1/0
ip address 10.1.123.1 255.255.255.0
encapsulation frame-relay
ip ospf network point-to-multipoint
frame-relay map ip 10.1.123.2 102 broadcast
frame-relay map ip 10.1.123.3 103 broadcast
no frame-relay inverse-arp
!
router ospf 1
router-id 10.10.10.10
log-adjacency-changes
network 0.0.0.0 255.255.255.255 area 0
!
ipv6 route 2001:2:2:2::/64 2001:12:12:12::2
ipv6 route 2001:3:3:3::/64 2001:13:13:13::3
!
You can see R1’s setup above. We have created two tunnel interfaces. Interface tunnel12 goes from R1’s loopback to R2’s loopback over IPv4. Interface tunnel13 will go from R1’s loopback to R3’s loopback. We have already verified that the routers have IPv4 connectivity between the loopbacks, now we are connecting the them via a tunnel. We are using GRE to encapulate anything we send down the tunnels. Anything we send down tunnel12 will end up on R2 and look like its coming from R1’s loopback.
You can see the ipv6 static routes at the end of that configuration. Here we are saying, to get to the ipv6 network behind R2, use the IPv6 address 2001:12:12:12::2. This is the address we will assign to the other end of the tunnel12 interface. R1’s tunnel12 interface has the address of 2001:12:12:12::1 which is in the same subnet. R1 will have connectivity to the other end of the tunnel because it is in the same subnet and is technically a directly connected interface.
Let’s configure R2, and R3:
R2
hostname R2
!
ipv6 unicast-routing
!
interface Tunnel12
no ip address
ipv6 address 2001:12:12:12::2/64
tunnel source Loopback0
tunnel destination 10.10.10.10
tunnel mode gre
!
interface Tunnel23
no ip address
ipv6 address 2001:23:23:23::2/64
tunnel source Loopback0
tunnel destination 10.30.30.30
tunnel mode gre
!
interface Loopback0
ip address 10.20.20.20 255.255.255.255
!
interface FastEthernet0/0
no ip address
ipv6 address 2001:2:2:2::2/64
!
interface Serial1/0
ip address 10.1.123.2 255.255.255.0
encapsulation frame-relay
ip ospf network point-to-multipoint
frame-relay map ip 10.1.123.1 201 broadcast
frame-relay map ip 10.1.123.3 201
no frame-relay inverse-arp
!
router ospf 1
router-id 10.20.20.20
log-adjacency-changes
network 0.0.0.0 255.255.255.255 area 0
!
ipv6 route 2001:1:1:1::/64 2001:12:12:12::1
ipv6 route 2001:3:3:3::/64 2001:23:23:23::3
!
R3
hostname R3
!
ipv6 unicast-routing
!
interface Tunnel13
no ip address
ipv6 address 2001:13:13:13::3/64
tunnel source Loopback0
tunnel destination 10.10.10.10
tunnel mode gre
!
interface Tunnel23
no ip address
ipv6 address 2001:23:23:23::3/64
tunnel source Loopback0
tunnel destination 10.20.20.20
tunnel mode gre
!
interface Loopback0
ip address 10.30.30.30 255.255.255.255
!
interface FastEthernet0/0
no ip address
duplex auto
speed auto
ipv6 address 2001:3:3:3::3/64
!
interface Serial1/0
ip address 10.1.123.3 255.255.255.0
encapsulation frame-relay
ip ospf network point-to-multipoint
frame-relay map ip 10.1.123.1 301 broadcast
frame-relay map ip 10.1.123.2 301
no frame-relay inverse-arp
!
router ospf 1
router-id 10.30.30.30
log-adjacency-changes
network 0.0.0.0 255.255.255.255 area 0
!
ipv6 route 2001:1:1:1::/64 2001:13:13:13::1
ipv6 route 2001:2:2:2::/64 2001:23:23:23::2
!
You can see we have set up a full mesh of tunnels between the routers. We should now have complete connectivity between the IPv6 networks.
Lets test this. To test it, we will use ipv4 packet debugging:
R1#debug ip packet detail
IP packet debugging is on (detailed)
R1#ping 2001:3:3:3::3
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 2001:3:3:3::3, timeout is 2 seconds:
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 52/100/160 ms
R1#
IP: s=10.10.10.10 (Tunnel13), d=10.30.30.30 (Serial1/0), len 124, sending, proto=47
IP: s=10.10.10.10 (Tunnel13), d=10.30.30.30 (Serial1/0), len 124, sending, proto=47
IP: s=10.10.10.10 (Tunnel13), d=10.30.30.30 (Serial1/0), len 124, sending, proto=47
IP: s=10.10.10.10 (Tunnel13), d=10.30.30.30 (Serial1/0), len 124, sending, proto=47
IP: s=10.10.10.10 (Tunnel13), d=10.30.30.30 (Serial1/0), len 124, sending, proto=47
You can see above that when we send a ping to the IPv6 network behind R3, we are actually sending IPv4 packets over the frame-relay cloud. The packets have a source of 10.10.10.10 (R1’s loopback0) and a destination of 10.30.30.30 (R3’s loopback0). The IPv6 packets have been encapsulated in a GRE header (protocol type 47).
When the packets arrive at R3, they will be unencapsulated and passed to R3’s IPv6 stack, which will respond back to the ping. The return packets will once again be encapulated over GRE and sent to R1.
Now the problem with the scenario above, is that it introduces a lot of overhead. We are taking an IPv6 packet, wrapping a GRE header around it, then wrapping a IPv4 header around that! That’s one fat packet.
Surely there must be a better way to do this and reduce the overhead? Well there is.
R3#conf t
Enter configuration commands, one per line. End with CNTL/Z.
R3(config)#int tu13
R3(config-if)#tunnel mode ?
aurp AURP TunnelTalk AppleTalk encapsulation
cayman Cayman TunnelTalk AppleTalk encapsulation
dvmrp DVMRP multicast tunnel
eon EON compatible CLNS tunnel
gre generic route encapsulation protocol
ipip IP over IP encapsulation
ipsec IPSec tunnel encapsulation
iptalk Apple IPTalk encapsulation
ipv6 Generic packet tunneling in IPv6
ipv6ip IPv6 over IP encapsulation
nos IP over IP encapsulation (KA9Q/NOS compatible)
rbscp RBSCP in IP tunnel
R3(config-if)#tunnel mode ipv6ip
There are a few different types of tunnels, and the one we are interested in here is the ipv6ip tunnel. With this we are going to encapsulate IPv6 inside IP, without the GRE overhead.
R1
interface Tunnel12
no ip address
ipv6 address 2001:12:12:12::1/64
tunnel source Loopback0
tunnel destination 10.20.20.20
tunnel mode ipv6ip
!
interface Tunnel13
no ip address
ipv6 address 2001:13:13:13::1/64
tunnel source Loopback0
tunnel destination 10.30.30.30
tunnel mode ipv6ip
!
R2
interface Tunnel12
no ip address
ipv6 address 2001:12:12:12::2/64
tunnel source Loopback0
tunnel destination 10.10.10.10
tunnel mode ipv6ip
!
interface Tunnel23
no ip address
ipv6 address 2001:23:23:23::2/64
tunnel source Loopback0
tunnel destination 10.30.30.30
tunnel mode ipv6ip
R3
interface Tunnel13
no ip address
ipv6 address 2001:13:13:13::3/64
tunnel source Loopback0
tunnel destination 10.10.10.10
tunnel mode ipv6ip
!
interface Tunnel23
no ip address
ipv6 address 2001:23:23:23::3/64
tunnel source Loopback0
tunnel destination 10.20.20.20
tunnel mode ipv6ip
You can see the configuration is simple. Just swap the tunnel mode on all the tunnel interfaces. IPv6IP tunnels use an IPv4 header with protocol type 41. The signifies that we are carrying IPv6. Let’s check it:
R1#debug ip packet detail
IP packet debugging is on (detailed)
R1#ping 2001:3:3:3::3
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 2001:3:3:3::3, timeout is 2 seconds:
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 108/159/256 ms
R1#
IP: s=10.10.10.10 (Tunnel13), d=10.30.30.30 (Serial1/0), len 120, sending, proto=41
IP: tableid=0, s=10.30.30.30 (Serial1/0), d=10.10.10.10 (Loopback0), routed via RIB
IP: s=10.30.30.30 (Serial1/0), d=10.10.10.10, len 120, rcvd 4, proto=41
IP: s=10.10.10.10 (Tunnel13), d=10.30.30.30 (Serial1/0), len 120, sending, proto=41
IP: tableid=0, s=10.30.30.30 (Serial1/0), d=10.10.10.10 (Loopback0), routed via RIB
IP: s=10.30.30.30 (Serial1/0), d=10.10.10.10, len 120, rcvd 4, proto=41
IP: s=10.10.10.10 (Tunnel13), d=10.30.30.30 (Serial1/0), len 120, sending, proto=41
R1#
IP: tableid=0, s=10.30.30.30 (Serial1/0), d=10.10.10.10 (Loopback0), routed via RIB
IP: s=10.30.30.30 (Serial1/0), d=10.10.10.10, len 120, rcvd 4, proto=41
IP: s=10.10.10.10 (Tunnel13), d=10.30.30.30 (Serial1/0), len 120, sending, proto=41
IP: tableid=0, s=10.30.30.30 (Serial1/0), d=10.10.10.10 (Loopback0), routed via RIB
IP: s=10.30.30.30 (Serial1/0), d=10.10.10.10, len 120, rcvd 4, proto=41
IP: s=10.10.10.10 (Tunnel13), d=10.30.30.30 (Serial1/0), len 120, sending, proto=41
IP: tableid=0, s=10.30.30.30 (Serial1/0), d=10.10.10.10 (Loopback0), routed via RIB
IP: s=10.30.30.30 (Serial1/0), d=10.10.10.10, len 120, rcvd 4, proto=41
You can see above that we have complete connectivity between the Router’s IPv6 networks. You can also see above that we are using protocol type 41 (IPv6IP). Cool huh?
In our next article in this series we will be using a special type of IPv6IP tunnel to do automatic 6to4 tunnels. HTH. Now back to labs!
Summary:
Resources:
I look forward to that day where we migrate to ipv6. I really appreciate effort in writing such good tutorials.