IPv6 Link-local
Time: 30 min
Needs: two OL9 PCs on one Ethernet switch
GNS3 project: ipv6-a1-linklocal
Info
Times listed are approximate and provided as timing guidelines only. Take as much time as you need to complete the activity.
Question
Where does a connected host get its IPv6 addresses from?
Do this — Build it
Cable two OL9 PC nodes named H1 and H2 to an Ethernet Switch (SW) and start the nodes.
On H1:
nmcli con add type ethernet ifname eth0 con-name eth0
nmcli con mod eth0 ipv4.method manual ipv4.addresses 192.168.10.11/24
nmcli con up eth0
On H2:
nmcli con add type ethernet ifname eth0 con-name eth0
nmcli con mod eth0 ipv4.method manual ipv4.addresses 192.168.10.12/24
nmcli con up eth0
On both H1 and H2, run this:
ip -6 addr show dev eth0
What just happened
- Both hosts have IPv6 addresses that you never configured.
- The addresses are prefixed with
fe80::. Every IPv6 interface gets one of these automatically, always, for as long as the link is up. It is called a link-local address, and IPv6 requires one- Link means the address is valid only for this segment.
- Local means packets using the address are not routed.
- Link-local addresses exist so that hosts sharing a wire can communicate before any "real" address has been configured - which turns out to be a prerequisite for everything else IPv6 does.
Do this — use it
Copy H2's link-local address, then ping in from H1:
Read H2's link-local address the same way, then from H1:
ping -c2 fe80::XXXX:XXXX:XXXX:XXXX
This fails. ping needs more information than just the address.
Try this:
ping -c2 fe80::XXXX:XXXX:XXXX:XXXX%eth0
What just happened
- The address alone was not enough information to send a packet. The reason is because
the
fe80::/64prefix is used by every interface (on hosts with more than one interface) so you need to tellpingout of which interface the packet should be sent out. %eth0is called scope identifier and it is used to disambiguate. It is a way to tell the host which interface to use when sending a packet. This matters only for link-local addresses.- You could also have run the command like so:
ping -I eth0 -c1 fe80::XXXX:XXXX:XXXX:XXXX
Do this
On H1:
nmcli con modify eth0 ipv6.addr-gen-mode eui64
nmcli con up eth0
ip link show eth0 | grep ether
ip -6 addr show dev eth0 | grep fe80
What just happened
- Notice the similarily between the MAC address the auto-configured IPv6 address
- EUI64 is one of the method devices can use to configure their own IPv6 addresses.
It lets devices derive the last 64 bits directly from the MAC address like so:
- split the six bytes in half
- insert the bits
ff:fein the middle - flip the 2nd bit (from the right) in the first byte.
- That was the original scheme, and it has an obvious problem; it is bad for privacy. Since your interface ID is built from your MAC address, it becomes a globally unique serial number that can be traced back to every network you join.
- So modern systems default to
stable-privacy: an interface ID that is stable per network but different on each one, and computed from a stored secret key rather than from hardware. - Put it back:
nmcli con mod eth0 ipv6.addr-gen-mode stable-privacy nmcli con up eth0
Do this
Start a capture on the H1 link, the ping H2 over both IPv4 and IPv6.
Select one ICMP packet and one ICMP6 packet and examine them closely. Can you describe what's different between them?
What just happened
- Up to Layer 2, both packets are similar.
- The frame's EtherType shows that Ethernet can carry both IPv4 and IPv6 with no changes to the frame's structure
- Above Ethernet, each protocol has their own header structure. Compare them; the differences are instructive.
Record
| Prefix of link-local addresses | |
Where the interface ID comes from under eui64 |
|
Why stable-privacy replaced it |
|
| EtherType for IPv4 / for IPv6 |