In a previous article, we built a network that included Cisco and Linux devices with a basic IPv6 infrastructure. In that network, the clients had proper addressing and name resolution and the native IPv6 communication inside the network established. In the real world, the situation still isn’t that simple: we have several IPv4-only devices inside and outside the network. Sometimes we need to communicate with them or we need to drive the traffic through them between two IPv6-only devices or networks. Moreover, we want our services and applications (web, email, FTP, and such) work as before. In this article, we’ll see some techniques to make it possible.

First, we’ll look at some methods to help the transition from traditional IPv4 to IPv6. There are the following main methods:

  • dual stack—The devices in the network run both addressing systems simultaneously, so we can connect to an IPv4-only device from any IPv4 device and to an IPv6 device from any IPv6 device. It’s easy to configure but it has several drawbacks; for example, an IPv4-only device still cannot communicate with an IPv6-only device by this method.
  • tunneling—This method has several implementations, but the basic idea is the same. We take an IPv6 packet and embed it into an IPv4 packet, which can travel through any IPv4 network (even the Internet). In this way we can connect IPv6 “islands”—IPv6 networks that are far from each other, separated by IPv4 networks.
  • address and protocol translation—These methods manipulate (translates) the IP packet headers and protocol information between the two addressing systems.

In the first lab, we’ll look at manual tunneling. The topology is the following:

We have two sites separated by the R2 router, which symbolizes an IPv4-only network. The LANs behind R1 and Debian1 are using native IPv6. We want to make it possible for the C1 host to reach C2. This can be done through a tunnel between R1 and Debian1: The packets in the tunnel are encapsulated IPv6 packets, which physically travel through R2 as well, but this router considers the traffic as normal IPv4 traffic.

Before we dive into the configuration, some words about the GNS3 implementation. The hosts are virtual PCs, which can be added by the Host node type to the topology. The Virtual PC Simulator is included in GNS3 and makes it possible to use up to nine virtual PCs, which are very limited in function, but sometimes it’s enough to prove that our configuration is correct. The most important information is the UDP port number, by which we can identify the instances: in the figure it’s the last number under the hosts, 20001 and 20002 respectively, which are virtual PC instances 2 and 3. More about this later.

Let’s begin with R1. This will be a dual-stack router, as Fa0/0 has an IPv6 address and Fa0/1 has an IPv4 address. We need IPv4 connectivity to Debian1, so we’ll define a static route to its network also:

On R2, we configure the Fa0/0 interface to and the Fa0/1 interface to address. We don’t even need any routing in this case.

On Debian1 we add the addressing information and default gateway, and we’ll test the reachability of R1:

Now configure the LAN PCs. Go to the Tools menu and launch VPCS. We’ll get a CLI window in which we can access the PCs by pressing numbers 1 to 9. Press 2 and issue the show ip command. It should display the LPORT: 20001 value indicating that we’re on the right place (on C1). Now configure it for IPv6 connectivity:

The ping should succeed to R1. Now go on to C2 (press 3) and give it the address of 2001:db8:2::2/64 and the IPv6 gateway of 2001:db8:2::1.

It’s time to create the connection between our two IPv6 networks. The already mentioned tunnel will be defined on R1 and Debian1. The first endpoint on R1 can be configured as follows:

First we create a virtual interface for the tunnel connection, then we define the source and destination of the tunnel. In the tunnel, the IPv6 packets will be encapsulated in IPv4 packets and, finally, the interface needs an IPv6 address also.

On Linux we can make a point-to-point tunnel by using the ip command:

The first command creates the tun0 interface (“sit” means “simple internet translation). Linux has a separate ping command for IPv6 and, as we can see, we can ping the other tunnel endpoint from this node. To make full connectivity, we need some IPv6 dynamic or static routing. This latter will do for us, so issue the following commands:

R1: ipv6 route 2001:db8:2::/64 2001:db8:e::2

Debian1: ip -6 route add 2001:db8:1::/64 via 2001:db8:e::1

On Linux, the IPv6 packet forwarding is disabled by default, so we have to issue another command:

echo 1 >/proc/sys/net/ipv6/conf/all/forwarding

This is another method if we don’t want to use the sysctl utility.

The last step is to check the connectivity from C1 to C2—the pings should succeed. If we want, we can do a packet capture at, for example, R2 to see the embedded IPv6 packets inside the IPv4 packets.

Still talking about tunneling, let me mention a quick way for IPv4-only hosts to access the IPv6 portion of the Internet. There are some ISPs that provide the so-called tunnel broker service. With this, a client usually installs some client software and uses it to connect to the ISP through a dynamically created tunnel. At the other end, the ISP then forwards the traffic as native IPv6 traffic to IPv6-only servers on the Internet. In this example, I’ll use the gogoCLIENT from This is multiplatform software which is easy to install and manage (especially on Windows). We’ll use the Linux version, so start a Debian VM in VirtualBox and connect its NIC to the Internet.

When the VM starts, check the IPv4 connectivity and go to We need to sign up to access the software. After signing in, go to the download page at and choose the source code package for Linux. You can donate to the project, but the download can be free also. The downloaded file needs extracting, so issue the following command in the download folder:

tar zxvf gogoc-version-RELEASE.tar.gz –C ~

This uncompresses and extracts the source files to our home directory into a folder named gogoc-version-RELEASE and we need to compile them. Before this, it is necessary to install the build-essential and libssl-dev packages. Moreover, on some Ubuntu and Debian versions have a bug that prevents compiling. To fix it, enter the root directory of the sources and open the message.h file from the ./gogoc-messaging/gogocmessaging directory, locate the line “#include <pal.h>”, then insert the following above this line:

#include <stddef.h>

Save the file, enter the gogoc-tsp directory from the root of the sources, and issue the following command:

make all

After the successful compiling, we need to install the software:

make installdir=/usr/local/gogoc install

Finally, we just have to start the client:

If we issue the ifconfig command, we can see a new device called tun which has an IPv6 address assigned by the ISP. Now we can access any IPv6-only server on the Internet. The first test can be the following: ping6 If it works, then you can use even the IPv6 version of Google to search for IPv6 stuff.

Communication from our native IPv6 network to an IPv4 network can be made by address and protocol translation mechanisms also. There are several methods (some of them are obsolete, like NAT-PT), but one of the best is called NAT64, which, when combined with DNS64, gives us the opportunity to access an IPv4-only service from an IPv6 network. NAT64 has two forms, stateful and stateless, and in the next lab we’ll use Linux software called Tayga to provide stateless NAT64 for our LAN (without DNS64). In this case, we’ll map IPv4 addresses to IPv6 addresses and vice versa. The IPv6 addresses typically have the /96 prefix in these scenarios: The remaining 32 bits come from the IPv4 address of the destination. Let’s clarify this by an example. We’ll use the following topology:

The IPv6-only LAN is on the left side. Debian1 will provide NAT64 and is connected to router ip4 on the right side. We want to access from C1 and C2 to ip4 (by pinging and telnetting).

First of all, we need Tayga, the NAT64 software from (download the .tar.bz2 file, which is an archived Bzip2 file). Extract it like the gogoCLIENT in the previous example, but with the following command (because it’s bzip2 and not gzip format):

tar jxvf tayga-version.tar.bz2 –C ~

Enter the tayga source directory, then issue the following commands:



make install

Create a data directory for the software:

mkdir –p /var/db/tayga

Now we can create the configuration file, which by default is in /usr/local/etc/tayga.conf, and put the following into it:

The first line defines the tunnel device used by the software. We can make this by issuing the tayga –mktun command. The program needs an IPv4 address which comes from the pool of IPv4 addresses used for mapping. The prefix keyword defines the IPv6, while the dynamic-pool keyword defines the IPv4 address space used for the mapping. The data-dir will contain a file for persistent storage of the mappings.

We need to set up the NAT64 tunnel interface:

The IPv4 and IPv6 address can be any value. Next we have to ensure that the traffic goes to the interface:

The Linux box needs to forward both IPv4 and IPv6 packets, so make sure to enable this feature. Check it (note that to enable IPv4 forwarding there is an alternate way):

Finally, we can start the software by issuing tayga –d (the –d switch is useful for the first time for debugging):

On the LAN routers, configure static IPv6 addressing and a default IPv6 gateway of 2001:db8:1::1 and try to ping the IPv6 address of Tayga at 2001:db8:1:ffff::c0a8:ff01. It should succeed. But where does this address comes from? The prefix is what we’ve defined in tayga.conf file. Now look at the last two hextets. When we convert 192 to hexadecimal, we get C0; converting 168, we get A8 and so on. So the last 32 bits really is the IPv4 address of Tayga defined in the configuration file. Guess what happens when we ping 2001:db8:1:ffff::c801:0101? Yes, it’s the public address ( of Debian1 converted to IPv6. But when we want to ping 2001:db8:1:ffff::c801:0102, the mapped address of ip4 router, that doesn’t work. Why? First look at the output of Tayga; we can see similar lines:

assigned new pool address (2001:db8:1::10)

This means that, when a request comes into the NAT64 device from the LAN (from 2001:db8:1::10 in this case), the software maps the source address to to be able to forward to the IPv4 network. But this is a private address and cannot be forwarded on the public Internet. The solution is really simple: We’ll configure the good old IPv4 NAT to translate it to a public address. The very simplest command to achieve this is the following:

iptables –t nat –A POSTROUTING –o eth1 –j MASQUERADE

NAT is by default in the Linux kernel as part of Netfilter, which can be used for firewalling, NAT-ing and packet mangling. We need NAT, so we replace the source address of the packet after routing decisions for every packet that leaves the device through eth1, and the keyword MASQUERADE enables dynamic NAT (or PAT in Cisco’s terms). After issuing that command, we’ll be able to ping the ip4 device and access other services as well; try telnet, for example.

Lastly some words about the ordinary services under IPv6. Nowadays, the well-known servers (Apache, OpenSSH, ProFTPd, and so on) all support native IPv6. We can get more information about them in the IPv6 “Howto” (link is at the end). On the client side, the situation is the same; it’s very uncommon that the newest versions don’t support IPv6. Probably one important thing to consider: If we use IPv6 addresses rather than domain names (in case of DNS failure or during testing), maybe we can use brackets around them. For example when entering an URL in the browser, we need to use the following form:


Guess which site has this address?

I hope that by now IPv6 is more familiar – get to know and use the technique of the future.

Useful Links

List of tunnel brokers:

Linux IPv6 Howto: