Gentoo Logo
Gentoo Logo Side

Gentoo IPv6 Router Guide


1. Preliminaries

Basic Kernel Configuration 

Any of the 2.4 or 2.6 kernel trees availables in Gentoo will easily support IPv6 connections. The new USAGI IPv6 stack is integrated to the kernel since Linux 2.4.22 and Linux 2.6.0. Note that for older kernels, alpha-sources-2.4.21 and gentoo-sources-2.4.20 can have the USAGI patches applied, if you correctly set usagi in your USE variable.

Code Listing 1.1: Emerging a kernel

(for a 2.6 kernel)
# emerge gentoo-dev-sources
(or for a 2.4 one)
# emerge gentoo-sources

Now we are ready to enter the kernel source directory and begin our actual kernel configuration.

Code Listing 1.2: Configuring the Linux Kernel

# cd /usr/src/linux
# make menuconfig

Note: This assumes the symlink /usr/src/linux points to the sources you will be using.

Note: Make sure you have Prompt for development and/or incomplete code/drivers enabled in your kernel config.

Code Listing 1.3: 'make menuconfig' options

Device Drivers --->
Networking support --->
Networking options --->
   <*> The IPv6 protocol (EXPERIMENTAL)
(The IPv6 options beneath this one can be useful for many other applications,
but should not be needed for a basic setup)

(This option is only required if you are using ptrtd for 6to4 conversion)
[*] Network device support
   <*> Universal TUN/TAP device driver support

Testing IPv6 Support 

After enabling the recommended options, recompile your kernel and reboot into your new IPv6-enabled kernel.

If you don't already have iproute2 installed, we urge you to do it now. iproute2 is a network configuration suite that contains ip, the famous replacement for ifconfig, route, iptunnel and others...

Code Listing 1.4: Installing iproute2

# emerge sys-apps/iproute2

Warning: Use of ifconfig can cause serious headaches if you have multiple tunnel devices. You have to remove the tunnels in backorder, which means that the latest created must be removed first. You have been warned!

If IPv6 is working, the loopback device should show an IPv6 address:

Code Listing 1.5: Checking the loopback device

# ip -6 addr show lo
1: lo: <LOOPBACK,UP> mtu 16436
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
    (The above lines show things are working)

Before going any further, make sure that you add ipv6 to your list of USE variables in make.conf, so that future emerges of packages will include IPv6 support.

2. Tunnel Configuration

Basic Configuration 

Most ISPs still do not offer any native IPv6 connections. To get around this limitation, there are several "tunnel brokers" around the globe that offer free IPv6 tunnels. This will allow you to tunnel all your IPv6 connections through an IPv4 connection.

Broker Location
Hurricane Electric US/Canada
Freenet6 US
Sixxs Europe
Singnet Singapore
Aarnet Australia/South Pacific

Below are two examples for setting up a tunnel with two popular North American tunnels, Hurricane Electric (applies for non-heartbeat tunnels from as well) and Freenet6.

Hurricane Electric 

Hurricane Electric (HE for short) offers free IPv6 tunnels and allocates a /64 block of addresses for you. It also allows configuration of reverse DNS. Getting a tunnel from HE is as easy as going to and filling out a one page form.

Note: Registration includes listing information like your address and phone number.

Warning: Tunnels from HE take 24 hours to be activated. This is in order to curb abuse of the service.

After you have a tunnel approved and have a /64 block allocated, you can configure your Gentoo box. HE provides sample configurations based on ifconfig and the iproute utilities. The following two examples assume you have the following configuration:

Local IPv4 Address (eth0)
HE IPv4 Address
Local IPv6 tunnel Address 2001:470:1F00:FFFF::189
IPv6 Block 2001:470:1F00:296::/64

Using the iproute2 package and the ip command, you would do the following:

Code Listing 2.1: Configuration of an IPv6 tunnel

(Create a tunnel between the local (eth0) IPv4 and HE's remote IPv4 address)
# ip tunnel add sixbone mode sit remote local ttl 64 dev eth0
(Extract the tunneling overhead from the MTU)
# ip link set sixbone mtu 1280
(Bring the tunnel up)
# ip link set sixbone up
(Assign the IPv6 address to it)
# ip addr add 2001:470:1F00:FFFF::189 dev sixbone
(Route all global unicast IPv6 addresses through our 'sixbone' tunnel device)
# ip route add 2000::/3 dev sixbone


Freenet6 is another free tunnel broker. Registration only requires a username and a valid email address. They have chosen to turn the tunnel management into a client/server setup and have created the tspc client. The client is available in portage. To install it do:

Code Listing 2.2: Installing the Freenet6 client

# emerge freenet6

Now you need to configure freenet6 by editing /etc/freenet6/tspc.conf. You should only have to edit the userid and passwd fields to match those assigned from Freenet6. Below is a complete sample config file.

Code Listing 2.3: tspc.conf example


Testing your connection 

Now that your tunnel is configured, you can test your connection. The easiest way to do this is to use the ping6 utility and try to ping an IPv6 host.

Code Listing 2.4: Testing the connection

# emerge iputils
# ping6
PING 56 data bytes
64 bytes from icmp_seq=1 ttl=52 time=290 ms
64 bytes from icmp_seq=2 ttl=52 time=277 ms
64 bytes from icmp_seq=3 ttl=52 time=280 ms
64 bytes from icmp_seq=4 ttl=52 time=279 ms
64 bytes from icmp_seq=5 ttl=52 time=277 ms

--- ping statistics ---
5 packets transmitted, 5 received, 0% packet loss, time 4038ms
rtt min/avg/max/mdev = 277.040/281.041/290.046/4.699 ms

Further work is currently in progress to add better IPv6 support to the network init scripts. If you'd like to know the status of this and/or help out, email [email protected].

3. IPv6 Support in Applications

Re-emerging packages 

Unless you had USE="ipv6" in your /etc/make.conf previously, you probably need to re-emerge a bunch of packages to compile in IPv6 support for them. To get a list of all the installed packages which leverage the ipv6 USE variable, you can run the below line.

Code Listing 3.1: Candidates for re-emerging

# emerge -epv world | grep ipv6 | sed "s:^.*\] ::; s:-[0-9]\+.*::" | cut -d' ' -f1

To easily re-emerge some selected packages, do:

Code Listing 3.2: Candidates for re-emerging

# emerge -epv world | grep ipv6 | sed "s:^.*\] ::; s:-[0-9]\+.*::" | \
> cut -d' ' -f1 > packages

Next, edit the packages file to remove any packages you don't want to recompile at this time. Then simply run:

Code Listing 3.3

# emerge `cat packages`

Note: Some packages detect IPv6 support automagically and hence have no ipv6 USE flag. Thus not all packages, which should support IPv6, will support it if you have not compiled it with an IPv6 enabled kernel.

IPv6 Specific Packages 

There are a few packages which specifically deal with IPv6 items. Most of these are located in /usr/portage/net-misc.

Package Description
net-misc/ipv6calc Converts an IPv6 address to a compressed format
net-misc/nc6 netcat version that supports IPv6 and IPv4
dev-perl/Socket6 IPv6 related part of the C socket.h defines and structure manipulators

4. DNS setup

IPv6 and DNS 

Just as DNS for IPv4 uses A records, DNS for IPv6 uses AAAA records. (This is because IPv4 is an address space of 2^32 while IPv6 is an address space of 2^128). For reverse DNS, the INT standard is deprecated but still widely supported. ARPA is the latest standard. Support for the ARPA format will be described here.

BIND configuration 

Recent versions of BIND include excellent IPv6 support. This section will assume you have at least minimal knowledge about the configuration and use of BIND. We will assume you are not running bind in a chroot. If you are, simply append the chroot prefix to most of the paths in the following section.

First you need to add entries for both forward and reverse DNS zone files in /etc/bind/named.conf.

Code Listing 4.1: named.conf entries

(We allow bind to listen to IPv6 addresses.
Using 'any' is the only way to do it prior to bind-9.3)
options {
    listen-on-v6 { any; }
(This will provide the forward DNS for the domain '':)
zone "" IN {
    type master;
    file "pri/";
(This format for reverse DNS is "bitwise." It's done by taking the IPv6 prefix,
reversing the order of the numbers and putting a period between each number)
zone "" {
        type master;
        file "pri/";

Now we must create those zone files and add entries for all of our hosts:

Code Listing 4.2: pri/

$TTL    2h
@       IN      SOA  (
                                2003052501 ; Serial
                                28800      ; Refresh
                                14400      ; Retry
                                3600000    ; Expire
                                86400 )    ; Minimum

        IN      AAAA    2001:470:1f00:296::1 ; address for
host1   IN      AAAA    2001:470:1f00:296::2 ; address for
host2   IN      AAAA    2001:470:1f00:296::3:3 ; address for

Code Listing 4.3: pri/

$TTL 3d ; Default TTL (bind 8 needs this, bind 9 ignores it)
@       IN SOA (
                        2003052501      ; Serial number (YYYYMMdd)
                        24h             ; Refresh time
                        30m             ; Retry time
                        2d              ; Expire time
                        3d )            ; Default TTL
        IN      NS
; IPv6 PTR entries
$ORIGIN IN      PTR IN      PTR IN      PTR

DJBDNS configuration 

There are currently some third-party patches to DJBDNS available at that allow it to do IPv6 nameserving. DJBDNS can be installed with these patches by emerging it with ipv6 in your USE variables.

Warning: Not all record types are support yet with these patches. In particular, NS and MX records are not supported.

Code Listing 4.4: Installing djbdns

# emerge djbdns

After djbdns is installed, it can be setup by running tinydns-setup and answering a few questions about which IP addresses to bind to, where to install tinydns, etc.

Code Listing 4.5: Setting up tinydns

# tinydns-setup

Assuming we've installed tinydns into /var/tinydns, we can now edit /var/tinydns/root/data. This file will contain all the data needed to get tinydns handling DNS for your IPv6 delegation.

Code Listing 4.6: sample data file

// * is authoritatively handled by
// Authoritative reverse DNS for 2001:470:1f00:296::/64
// Specify the IPs for host1 and host2
// Point www to host1

Lines prefixed with a 6 will have both an AAAA and a PTR record created. Those prefixed with a 3 will only have an AAAA record created. Besides manually editing the data file, you can use the scripts add-host6 and add-alias6 to add new entries. After changes are made to the data file, you simply need to run make from /var/tinydns/root. This will create /var/tinydns/root/data.cfb, which tinydns will use as its source of information for DNS requests.

5. IPv6 Router

Configure routing 

Further configuration is required if we want to use our system as a router for other clients wishing to connect to the outside world with IPv6. We need to enable forwarding of IPv6 packets. We can do this in one of two ways.

Code Listing 5.1: Enabling forwarding

# echo 1 > /proc/sys/net/ipv6/conf/all/forwarding
# sysctl -w net.ipv6.conf.all.forwarding=1

Warning: The radvd init script enables (and disables) forwarding, making the next step unnecessary.

To enable forwarding at boot, you'll need to edit /etc/sysctl.conf and add the following line.

Code Listing 5.2: sysctl.conf addition


Traffic should now be forwarded from this box through the tunnel we've established with our broker.

To assign IPv6 addresses to clients, the IPv6 specification allows for both stateless and stateful IP assignment. Stateless assignment uses a process called Router Advertisement and allows clients to obtain an IP and a default route by simply bringing an interface up. It is called "stateless" because there is no record of IPs assigned and the host they are assigned to. Stateful assignment is handled by DHCPv6. It is "stateful" because the server keeps a state of the clients who've requested IPs and received them.

Stateless Configuration 

Stateless configuration is easily accomplished using the Router Advertisement Daemon, or radvd.

Code Listing 5.3: Configuring radvd

# emerge radvd

After having emerged radvd, we need to create /etc/radvd/radvd.conf that contains information about what IP block to assign IPs from. Here is a sample radvd.conf file using the prefix we've been assigned from our tunnel broker.

Code Listing 5.4: Sample radvd.conf

interface eth1
        // Send advertisement messages to other hosts
        AdvSendAdvert on;
        // Fragmentation is bad(tm)
        AdvLinkMTU 1280;
        MaxRtrAdvInterval 300;
        // IPv6 subnet prefix we've been assigned by our PoP
        prefix 2001:470:1F00:296::/64
                AdvOnLink on;
                AdvAutonomous on;

Warning: Make sure the interface on the first line is correct so you broadcast router advertisement to your intranet and not to your ISP!

Further information is available in man radvd.conf. We can now start radvd and set it to start at boot.

Code Listing 5.5: Starting up radvd

# /etc/init.d/radvd start
# rc-update add radvd default

Stateful Configuration 

If you'd like to use stateful configuration, you'll need to install and configure dhcpv6.

Code Listing 5.6: Installing dhcpv6

# emerge dhcpv6

Next we must configure the DHCPv6 server by editing /etc/dhcp6s.conf.

Code Listing 5.7: Sample dhcp6s.conf

prefer-life-time 10000;
valid-life-time 20000;
renew-time 5000;
rebind-time 8000;
interface eth1 {
    link AAA {
        allow unicast;
        send unicast;
        allow rapid-commit;
        send server-preference 5;
        renew-time 1000;
        rebind-time 2400;
        prefer-life-time 2000;
        valid-life-time 3000;
            range 2001:470:1f00:296::10 to 2001:470:1f00:296::110/64;
            prefix 2001:470:1f00:296::/64;

We can now start dhcp6s, and configure it to start at boot.

Code Listing 5.8: Starting dhcp6s

# /etc/init.d/dhcp6s start
# rc-update add dhcp6s default

6. IPv6 Clients

Using radvd 

Clients behind this router should now be able to connect to the rest of the net via IPv6. If using radvd, configuring hosts should be as easy as bringing the interface up. (This is probably already done by your net.ethX init scripts).

Code Listing 6.1: Connecting through IPv6

# ip link set eth0 up
# ip addr show eth0
1: eth0: <BROADCAST,MULTICAST,UP> mtu 1400 qdisc pfifo_fast qlen 1000
    link/ether 00:01:03:2f:27:89 brd ff:ff:ff:ff:ff:ff
    inet6 2001:470:1f00:296:209:6bff:fe06:b7b4/128 scope global
       valid_lft forever preferred_lft forever
    inet6 fe80::209:6bff:fe06:b7b4/64 scope link
       valid_lft forever preferred_lft forever
    inet6 ff02::1/128 scope global
       valid_lft forever preferred_lft forever

using DHCPv6 

If your router is set up to use DHCPv6, your clients will also need to have the dhcpv6 package installed. After having done this, you need to configure your client by editing /etc/dhcp6c.conf.

Code Listing 6.2: Sample dhcp6c.conf

interface eth0 {
        send rapid-commit;
        request prefix-delegation;
        request domain-name-servers;
        request temp-address;
        iaid 11111;
        renew-time 11000;
        rebind-time 21000;

7. Using 6to4 Conversion

Basic principles 

6to4 conversion can be used if you want to have hosts that talk to IPv4 hosts over a purely IPv6 connection. Thus you can have an entirely IPv6 internal network, with one host dealing with connecting to the outside IPv4/IPv6 world.

DNS configuration 

To get 6to4 conversion working, a DNS proxy, totd, need to be configured that will send you AAAA records for sites that really only have A records. These AAAA records will point to IPv6 addresses which don't actually exist, but which will get routed through a 6to4 proxy.

Since totd is still ~x86 masked pending further testing, you'll have to unmask it by appending the following line to your /etc/portage/package.keywords file (see "man portage" for more informations about this file).

Code Listing 7.1: Permanently unmask totd in package.keywords

net-misc/totd ~x86

Then simply run emerge:

Code Listing 7.2: Installing totd

# emerge totd

Next, we need to setup /etc/totd.conf with some basic configuration information.

Code Listing 7.3: Sample /etc/totd.conf

(Points to a real DNS nameserver)
forwarder port 53
(What prefix to put before faked AAAA records)
prefix 3ffe:abcd:1234:9876::
(What port to run totd on)
port 5005
(What PID file to use)
pidfile /var/run/
(Actually do 6to4 stuff)

Note: totd must be set to use a port different than port 53 if another nameserver is running on the same machine.

6to4 proxy 

ptrtd will be used as a 6to4 proxy, enabling connections between the internal IPv6 host and the outside IPv4 host.

Code Listing 7.4: Installing ptrtd

# emerge ptrtd

We now need to configure ptrtd, telling it what fake prefix (the one we setup totd to use) to create proxy connections for. Edit /etc/conf.d/ptrtd and set IPV6_PREFIX. This should be the same prefix as was configured with totd.

Code Listing 7.5: Sample /etc/ptrtd.conf


You can now start totd, and enable it to start at boot.

Code Listing 7.6: Starting totd

# /etc/init.d/totd start
# rc-update add totd default

Client configuration and testing 

Clients may now be configured to connect to both IPv4 and IPv6 hosts through an IPv6 only connection. Assuming that the clients are already receiving an IP address from radvd, we simply need to add a new DNS resolver entry, and add a default route for those "fake addresses". First, add an entry at the top of your /etc/resolv.conf pointing to the machine running totd.

Code Listing 7.7: /etc/resolv.conf sample

nameserver 2001:470:1f00:296::1 (The server running totd)

To test name resolution, request an AAAA record for a known IPv4 only site.

Code Listing 7.8: Testing name resolution

# dig aaaa
;; ANSWER SECTION:             300     IN      AAAA     3ffe:abcd:1234:9876::d8ef:3364             300     IN      AAAA     3ffe:abcd:1234:9876::d8ef:3564

We will now add a default route for all addresses prefixed with our chosen fake prefix.

Code Listing 7.9: Adding the default route

(Assuming your IPv6 interface is eth0)
# ip route add 3ffe:abcd:1234:9876::/64 via 2001:470:1f00:296::1 dev eth0

Finally, use ping6 to ping at it's fake IPv6 location.

Code Listing 7.10: Testing 6to4

# ping6 -c 2
PING 3ffe:abcd:1234:9876::d8ef:3364(3ffe:abcd:1234:9876::d8ef:3364) 56 data bytes
64 bytes from 3ffe:abcd:1234:9876::d8ef:3364: icmp_seq=1 ttl=54 time=0.106 ms
64 bytes from 3ffe:abcd:1234:9876::d8ef:3364: icmp_seq=2 ttl=54 time=0.090 ms

--- 3ffe:abcd:1234:9876::d8ef:3364 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1000ms
rtt min/avg/max/mdev = 0.090/0.098/0.106/0.008 ms

Note: The router running ptrtd is actually replying, but this at least tells us things are working.

8. Other Resources

There are many excellent resources online pertaining to IPv6.

Websites Resources General IPv6 Information USAGI Project Linux/IPv6 site All things IPv6 German IPv6 site *BSD implementation

On IRC, you can try #gentoo-ipv6 or #ipv6 on Freenode. You can connect to the Freenode servers using an IPv6 enabled client by connecting to

The contents of this document are licensed under the Creative Commons - Attribution / Share Alike license.
Updated July 27, 2004
Peter Johanson

Jorge Paulo

Sven Vermeulen
Editor, Reviewer

Camille Huot

Pasi Valminen

Summary:  This guide shows how to setup IPv6 on a Gentoo system. This includes establishing a tunnel with a tunnel broker, some basic DNS configuration and configuring clients to use the system to connect to IPv6 addresses.
The Gentoo Linux Store
Copyright 2001-2004 Gentoo Foundation, Inc. Questions, Comments, Corrections? Email [email protected].