Your message has been sent.
This article has been saved to your account.
Go to my account
This article has been emailed to your Kindle.
Send this article
Today, everyone knows that the internet is running out of IP addresses. In fact, the current infrastructure of the internet is running over legacy IP (aka IPv4) protocol that was not designed for such wide-spread and complicated use (for example, IPv4 was not designed to run in a refrigerator).
The original design of Internet Protocol (IPv4) is not efficient for today's networks. And even worse, we are running out of IPv4 addresses in a few years!
FreeBSD uses the IPv6 code from the KAME project. The KAME project (see www.kame.net) has been inactive since 2005, and FreeBSD developers have eversince maintained the IPv6 protocol stack.
In this article by Babak Farrokhi, we will look into the following:
- IPv6 facts
- Using IPv6
- Routing IPv6
- Multicast routing
Several methods were introduced to reduce the usage of IP addresses in the internet including:
- Classless Interdomain Routing (CIDR): This introduced the death of classful addressing (for example Class A, B, C) by a new subnetting method which is not limited, unlike the classful method.
- Network Address Translation (NAT): Using NAT you do not need to use public IP addresses on your internal hosts.
Using CIDR subnets and NAT only helped IPv4 to live a few years longer, but was not the ultimate cure to the problem. Besides the addressing issues, there were other problems with IPv4 which could not be easily solved. These issues include the following:
- The size of internet routing tables was growing rapidly and this forced backbone providers to upgrade their networking gears.
- The IPv4 was very inefficient for high throughput links and did not support QoS by nature.
Back in the early 90s, IETF had started a workgroup to solve the deficiencies of the IP protocol. In 1995, the IETF published the initial drafts of IPv6 as the next generation IP. Since then, the protocol has matured enormously and been implemented in many operating systems.
If you are not familiar with IPv6, here is a very quick look at the difference between IPv4 and IPv6. (For a more detailed insight into IPv6 and its configuration in various operating systems, it is recommended that you read Running IPv6 book by Iljitsch van Beijnum).
Addressing in IPv6 is quite different from legacy IPv4 addresses. IPv6 uses 128-bit address space unlike the 32-bit addressing system in IPv4. A typical IPv6 address would look like—2002:a00:1:5353:20a:95ff:fef5:246e
Fact Two—Address Types
There are 4 types of addresses in IPv6:
- Unicast: A typical IPv6 address you use on a host.
- Multicast: Addresses that start with ff:: are equivalent to IPv4 multicast.
- Anycast: A typical IPv6 address that is used on a router.
- Reserved: Includes loopback, link-local, site-local, and so on.
There is no ARP! MAC to IP mapping is no longer needed as MAC addresses are embedded into IPv6 addresses. Instead, ND is born. ND is used to auto-configure addresses on hosts, duplicated detection, and so on.
Fact Four—Interface Configuration
If you are new to IPv6, you will be shocked to see an IPv6 address, telling yourself that you are in trouble assigning addresses to interfaces or remembering the addresses. However, it is not all that hard. In most cases, you can have your host autoconfigure IPv6 address on its interfaces. Typically, you should set this up only on your network gateway (router) manually.
Running FreeBSD 7, the kernel is already IPv6 enabled. However, you should manually enable IPv6 in the UserLand, by adding the following line to the /etc/rc.conf configuration file:
And manually start the appropriate rc script (or reboot the system) for the changes to take effect:
# /etc/rc.d/network_ipv6 start
This will enable IPv6 on all interfaces that are IPv6 capable. This behavior is changed by modifying the following variable in the /etc/rc.conf file:
This will enable IPv6 support on specified interfaces. The default value for this variable is auto.
Once you enable IPv6, interfaces will discover the IPv6 enabled routers on the network and build their own IPv6 addresses based on the network prefix they receive from the router.
In a typical scenario, IPv6 network stack will automatically look for an IPv6 enabled router on the same network for each interface and try to automatically configure the IPv6 address on the interface.
The following is an example of an automatically configured interface(replace the $ with %):
# ifconfig ed0
ed0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric
0 mtu 1500
inet6 fe80::21c:42ff:fe8d:5dbf$ed0 prefixlen 64 scopeid 0x1
inet 192.168.0.225 netmask 0xffffff00 broadcast 192.168.0.255
inet6 2a01:3c8::21c:42ff:fe8d:5dbf prefixlen 64 autoconf
media: Ethernet autoselect (10baseT/UTP)
Beside the IPv4 address, there are two IPv6 addresses on the interface. One address begins with fe80:: and identified with the scopeid 0x1 tag, which is called a link-local address. Another address begins with 2a01:3c8::, which is the unicast address of this interface.
The unicast address prefix is obtained from the IPv6 router on the network. The whole address is created using the 64 bits Extended Unique Identifier (EUI-64) algorithm, which consists of the hosts MAC address with some minor modifications.
The link-local address (that is from the reserved address pool) always starts with fe80:: and is used for local network usage. This can be compared with RFC1819 private addresses that are suitable for local use. The network stack will automatically assign a link-local address to each IPv6 enabled interface, regardless whether an IPv6 router is discovered on the network. This means that in a scenario of a home network or a lab network, you do not need to run an IPv6 router or have a valid IPv6 prefix in order to establish an IPv6 network. All the hosts will be automatically provisioned with a link-local address, so they can exchange IPv6 traffic.
The network discovery protocol (NDP) helps the host find the router on the network and then create a unicast address for the interface. NDP is known as the equivalent to ARP protocol in IPv6. The ndp(8) utility is used to control the behavior of this protocol:
# ndp -a
Neighbor Linklayer Address Netif Expire S Flags
2a01:3c8:: 0:16:cb:98:d4:bf ed0 20s R R
2a01:3c8::21c:42ff:fe8d:5dbf 0:1c:42:8d:5d:bf ed0 permanent R
fe80::216:cbff:fe98:d4bf$ed0 0:16:cb:98:d4:bf ed0 23h58m48s S R
fe80::21c:42ff:fe8d:5dbf$ed0 0:1c:42:8d:5d:bf ed0 permanent R
fe80::1%lo0 (incomplete) lo0 permanent R
The above example shows the discovered IPv6 hosts(replace the $ with %). The ed0 interface is connected to an IPv6 enabled network and receives a valid prefix via a router (the first entry of the list). The second entry is the unicast address of the ed0. The third and the fourth entries are link-local address for the router and our host. And the last entry belongs to the local host.
As you have seen so far, there are some special (reserved) IPv6 addresses. The following table shows a list of reserved addresses:
Equivalent to 0.0.0.0 in Pv4
Equivalent to 127.0.0.1 in IPv4
In case you want to configure the static IPv6 address on an interface, it can be done as in a typical IPv4 scenario:
# ifconfig vr0 inet6 2a01:3c8::21c:42ff:dead:beef prefixlen 64
This will manually configure an IP address on the specified interface. Note the prefixlen keyword that is equivalent to subnet mask in IPv4.
eBook Price: £14.99
Book Price: £24.99
Similar to IPv4, your host does not automatically forward IPv6 traffic between interfaces, by default. In order to enable packet forwarding between the two IPv6 enabled interfaces, you should modify the net.inet6.ip6.forwarding sysctl variable:
# sysctl net.inet6.ip6.forwarding=1
This can also be achieved by adding the following variable to the /etc/rc.conf file:
After enabling IPv6 forwarding in the /etc/rc.conf file, you should reboot your system or run relevant rc script:
# /etc/rc.d/network_ipv6 restart
The rtadvd(8) daemon is another component that you may want to enable on a IPv6 router. As mentioned earlier, the hosts automatically configure the IPv6 addresses on their interface, based on the advertisements they receive from the IPv6 enabled routers on the same subnet. These advertisements are called Router Advertisement (RA) packets. The rtadvd(8) daemon sends router advertisements on the specified network interfaces, helping hosts to automatically configure IPv6 address on their interfaces. This is done based on the IPv6 prefix it advertises, as well as identifying itself as the gateway for the network.
To enable rtadvd(8), add the following lines to /etc/rc.conf (ensuring that your host is also configured to forward IPv6 traffic):
Make sure that you only enable transmission of RA packets on interfaces that you need to do. This can be done using the rtadvd_interfaces variable.
Now you should create a configuration file for the rtadvd(8) daemon. This file controls the behavior of the rtadvd(8) daemon. The rtadvd daemon reads /etc/rtadvd.conf upon start up, to find out how it should send RA packets. A sample rtadvd.conf file looks like the following:
This tells rtadvd daemon to advertise itself as a router for subnet 3ca1:511:ffff:4000::/64.
Please see the rtadvd.conf(5) manual pages for more information about various options that you can use in this configuration file.
It would be a good idea to use the tcpdump(1) utility to see how the RA packets are being sent
Please note that in this case your machine is configured as a router and not a host, which has a special meaning in IPv6. In IPv6 terminology, a host is a machine that sends Router Solicitation messages or listens for RA packets to figure out its IPv6 address configuration as well as its gateway. On the other hand, a router is a machine that sends RA packets and is able to forward packets to the correct destination.
FreeBSD 7 has built-in routing daemons that support RIPv1 and RIPv2 for IPv4 and RIPng or RIP6 (RFC 2080) for IPv6. The routing daemon that supports RIP6 is routed6d(8).
The route6d(8) daemon is almost equivalent to its IPv4 counterpart and can be enabled by setting the following variable in the /etc/rc.conf file:
The ability to route multicast traffic in FreeBSD 7 is available using third-party software that can be used from ports collection. The net/mcast-tools port allows Protocol Independent Multicast Sparse-Mode (PIM-SM Version 2), PIM-Source-Specific Multicast (SSM using PIM-SM), and Protocol Independent Multicast Dense-Mode (PIM-DM Version 2) routing.
Once installed, the functionality is enabled by adding this line to /etc/rc.conf:
This will automatically enable the pim6dd(8) (dense mode) daemon. If you are planning to use pim6sd(8) (sparse mode), you should also add the following line to /etc/rc.conf:
There are certain cases where you want to set up a tunnel to transport IPv6 traffic over your existing IPv4 network. This can be a site-to-site VPN between two IPv6 enabled networks, or getting IPv6 connectivity to an IPv6 service provider. There are different methods by which you can set up such tunnels. The most popular methods are gif(4), faith(4), and stf(4).
There are chances that you do not have native IPv6 connectivity to the internet. In that case, you can still set up a non-native (tunneled) IPv6 connection to the internet.
There are several services that offer tunneling to IPv6 networks, such as www.sixxs.net. The only thing you should do is to sign up for such a service and set up a tunnel internet according to their instructions.
This is mostly done by encapsulating IPv6 traffic over a gif(4) tunnel that is established over IPv4 to the other end. In most cases, setting up such connectivity is pretty straightforward.
A sample tunnel setup would look like this:
# ifconfig gif0 create
# ifconfig gif0 tunnel x.x.x.x y.y.y.y
# ifconfig gif0 inet6 2001:470:1F03:26c::2 2001:470:1F03:26c::1
# route -n add -inet6 default 2001:470:1F03:26c::1
# ifconfig gif0 up
In the above example, a gif interface is created and established between x.x.x.x (your IPv4 address) and y.y.y.y (your tunnel broker's IPv4 address). Then you should assign IPv6 addresses to the tunnel. In this case, 2001:470:1F03:26c::2 is assigned to your side of the tunnel and 2001:470:1F03:26c::1 to the other side of the tunnel. The latter is used as your IPv6 gateway as well.
The tricky part is setting up a default gateway for all IPv6 traffic to the other side of the tunnel, which is done using the route command (note the -inet6 flag).
Once you have finished setting up the tunnel, you may want to test your connectivity by pinging the other side of the tunnel using the ping6(8) utility.
FreeBSD has had IPv6 support in the base operating system since its early versions. This support has become more mature in recent releases. Since we covered basic configuration for IPv6 in this article, you may want to do more complex things that are not covered here. There are a few useful and up-to-date resources that you can find on the net—one of them being the FreeBSD handbook section on IPv6 and IPv6 internals in the developer's handbook. It is also recommended that you read Running IPv6 book, which contains detailed explanations of deploying the IPv6 network, with examples involving various operating systems, including the FreeBSD.
eBook Price: £14.99
Book Price: £24.99
About the Author :
Babak Farrokhi is an experienced UNIX system administrator and Network Engineer who worked 12 years in the IT industry in carrier-level network service providers. He discovered FreeBSD around 1997 and since then he has been using it on a daily basis. He is also an experienced Solaris administrator and has extensive experience in TCP/IP networks.
In his spare time he contributes to the open source community and develops his skills to keep himself in the cutting edge.