Observing IPv6 link local addresses
Link local addresses play an important role in IPv6 since they enable hosts that are attached to the same subnet to directly exchange packets without requiring any configuration. When an IPv6 host or router boots, the first thing that it tries to do is to create a link-local address for each of its interfaces. It is interesting to observe how those link-local addresses are used in a very simple network.
We consider the most basic topology containing two hosts connected to one router:
h1 ---- r ---- h2
With IPMininet, this network can be created with a simple script
import ipmininet
from ipmininet.cli import IPCLI
from ipmininet.ipnet import IPNet
from ipmininet.router.config import RouterConfig
from ipmininet.iptopo import IPTopo
from mininet.log import lg
class NoIP(IPTopo):
def build(self, *args, **kwargs):
r = self.addRouter_v6('r', config=(RouterConfig))
h1 = self.addHost('h1')
h2 = self.addHost('h2')
self.addLink(r, h1)
self.addLink(r, h2)
def addRouter_v6(self, name, **kwargs):
return self.addRouter(name, use_v4=False, use_v6=True, **kwargs)
ipmininet.DEBUG_FLAG = True
lg.setLogLevel("info")
# Start network
net = IPNet(topo=NoIP(), use_v4=False, allocate_IPs=False)
try:
net.start()
IPCLI(net)
finally:
net.stop()
In this network, the simplest way to observe what happens when a host is attached to the network is to collect packet traces on the router with tcpdump.
tcpdump -i r-eth0 -n -vvv
Once packet capture has started, we can force a reconfiguration of host h1
manually by setting its interface down and up.
#ip link show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: h1-eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000
link/ether aa:a3:b6:e6:4b:1e brd ff:ff:ff:ff:ff:ff link-netnsid 0
Host h1
has two interfaces: a loopback and an Ethernet interface attached to router r
. We disable the interface h1-eth0
with the command ` ip link set h1-eth0 down`. At this point, the only remaining interface is the loopback interface.
We can now activate the h1-eth0
interface with command ` ip link set h1-eth0 up ` and observe the packets that are sent by h1
via tcpdump
on the router.
Once the link goes up, h1
automatically creates a link-local address
and attaches it to interface h1-eth0
.
# ip -6 addr show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 state UNKNOWN qlen 1
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: h1-eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 state UP qlen 1000
inet6 fe80::a8a3:b6ff:fee6:4b1e/64 scope link
valid_lft forever preferred_lft forever
This link-local address is created by concatenating the well-known fe80::/64
prefix specified in section 2.5.6 of RFC4291 with the
64 bits interface identifier. This identifier is constructed from the
MAC address of the interface.
#ip link show h1-eth0
2: h1-eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000
link/ether aa:a3:b6:e6:4b:1e brd ff:ff:ff:ff:ff:ff link-netnsid 0
The creation of the interface identifier from MAC address aa:a3:b6:e6:4b:1e
is specified
in section 2.5.1 of
RFC4291. The resulting
link-local address is fe80::a8a3:b6ff:fee6:4b1e
.
At this stage, host h1
needs to verify that no other device is using the
same link-local address on the subnet. tcpdump
running on the router observes
the following packet:
09:40:33.938113 IP6 (hlim 255, next-header ICMPv6 (58) payload length: 24) :: > ff02::1:ffe6:4b1e: [icmp6 sum ok] ICMP6, neighbor solicitation, length 24, who has fe80::a8a3:b6ff:fee6:4b1e
There are several points to note about this packet. First, its source IPv6
address is set to ::
, i.e. a block of 128 bits set to zero. This is the
unspecified address defined in section 2.5.2 of RFC4291. This
address must be used as a source address when a device does not have a
link-local address. The destination address is ff02::1:ffe6:4b1e:
which
is a solicited node-multicast address
which is defined in
section 2.7.1 of
RFC4291. This solicited node-multicast
address is created by appending the low order 24 bits of the link-local address
(in this case e6:4b1e
) to the FF02:0:0:0:0:1:FF00::/104
prefix.
An IPv6 node must listen to the IPv6 solicited node-multicast address that
corresponds to each of its addresses to be able to reply to any possible
ICMP message sent to this address. This reduces the load on the default
all-nodes IPv6 multicast addresses.
After some time without a response to this neighbor sollicitation, host
h1
considers that its link-local address is unique. It can then send an
ICMPv6 router sollicitation message.
09:40:34.956122 IP6 (hlim 255, next-header ICMPv6 (58) payload length: 16) fe80::a8a3:b6ff:fee6:4b1e > ff02::2: [icmp6 sum ok] ICMP6, router solicitation, length 16
source link-address option (1), length 8 (1): aa:a3:b6:e6:4b:1e
0x0000: aaa3 b6e6 4b1e
This ICMPv6 router sollicitation is sent from the link-local address of host h1
which is now considered as unique. The destination is ff02::2
which corresponds to all IPv6 routers. This router sollication message contains the MAC address
of the sender inside the source link-address option defined in section 4.6.1 of RFC4861.
As no router has been configured to send router advertisements in this network,
host h1
will not receive any answer. According to RFC4861, it should retransmit the router sollicitation message
up to 3 times with a delay of 4 seconds between retransmissions (see sections
10 and 6.3.7 of RFC4861](https://tools.ietf.org/html/rfc4861)