In the good old days of IPv4, an interface on a host could have only one IPv4 IP address. Things were very simple, every IP host would use that one address as the source IP for all communication. When we get into IPv6, each interface can have multiple IPv6 addresses. These addresses have different scopes such as global, unique-local and link-local. If an IPv6 enabled host would like to send a packets to another host, which source IPv6 address does it choose? What if it has four addresses: 2001:10::3/64 (Global from ISP A), 2001:23::3/64 (Global from ISP B), fc00:23::3/64 (Unique-Local) and fe80:23::3 (Link-Local)?
As with almost everything there is a nice RFC written on this topic. RFC6724 Default Address Selection for Internet Protocol Version 6 (IPv6) defines how to select a source IPv6 address. It mentions eight rules for source selection, here is the summary and translation:
Rule 1: Prefer same address
Rule 2: Prefer appropriate scope
Rule 3: Avoid deprecated addresses
Rule 4: Prefer home addresses
Rule 5: Prefer outgoing interface
Rule 6: Prefer matching label
Rule 7: Prefer temporary addresses
Rule 8: Use longest matching prefix
In the remainder of this post, I’ll use the simple topology from figure 1. I’ll test the IPv6 source selection on Cisco IOS devices by pinging a particular destination and observing which source address was selected with debug ipv6 icmp.
Figure 1 – IPv6 Example Topology
Rule 1: Prefer same address – if you receive a packet, use its destination address to respond. That one makes sense, the other host already made the decision for you.
For example, if R2 pings R3, R3 will use the source address that was the destination address from R2. In this example 2001:23::3 was selected as the source of reply to R2.
R2#ping 2001:23::3 repeat 1
R3# debug ipv6 icmp ICMPv6: Received echo request, Src=2001:23::2, Dst=2001:23::3 ICMPv6: Sent echo reply, Src=2001:23::3, Dst=2001:23::2
Rule 2: Prefer appropriate scope – this one basically says try to use the same scope if possible. For example if the destination address is Link-Local, use your own link-local address. If the destination is Global address, use your Global address if available, if not use Unique-Local. If the destination is Unique-Local use Unique-Local, if not available use Global.
Example 1 – use link-local address as the destination and expect link-local address to be picked as the source. In this example FE80:23::2 was selected to ping FE80:23::3.
R2#ping FE80:23::3 repeat 1 Output Interface: GigabitEthernet3/0 Type escape sequence to abort. Sending 1, 100-byte ICMP Echos to FE80:23::3, timeout is 2 seconds: Packet sent with a source address of FE80:23::2%GigabitEthernet3/0 ! Success rate is 100 percent (1/1),round-trip min/avg/max = 40/40/40 ms R2# ICMPv6: Sent echo request, Src=FE80:23::2, Dst=FE80:23::3 ICMPv6: Received echo reply, Src=FE80:23::3, Dst=FE80:23::2
Example 2 – use unique local address as destination and expect unique local address to be selected as the source. In this example FC00:23::2 was selected to ping FC00:23::3.
R2#ping FC00:23::3 repeat 1 Type escape sequence to abort. Sending 1, 100-byte ICMP Echos to FC00:23::3, timeout is 2 seconds: ! Success rate is 100 percent (1/1),round-trip min/avg/max = 96/96/96 ms R2# ICMPv6: Sent echo request, Src=FC00:23::2, Dst=FC00:23::3 ICMPv6: Received echo reply, Src=FC00:23::3, Dst=FC00:23::2
Example 3 – use global address as destination and expect global address to be selected as the source. In this example 2001:23::2 was selected to ping 2001:23::3.
R2#ping 2001:23::3 repeat 1 Type escape sequence to abort. Sending 1, 100-byte ICMP Echos to 2001:23::3, timeout is 2 seconds: ! Success rate is 100 percent (1/1),round-trip min/avg/max = 32/32/32 ms R2# ICMPv6: Sent echo request, Src=2001:23::2, Dst=2001:23::3 ICMPv6: Received echo reply, Src=2001:23::3, Dst=2001:23::2
Example 4 – R1 does not have a global address, but only a unique local and link-local. It will select the unique local as the source. In this example FC00:12::1 was selected to ping 2001:23::3.
R1#ping 2001:23::3 repeat 1 Type escape sequence to abort. Sending 1, 100-byte ICMP Echos to 2001:23::3, timeout is 2 seconds: ! Success rate is 100 percent (1/1),round-trip min/avg/max = 60/60/60 ms R1# ICMPv6: Sent echo request, Src=FC00:12::1, Dst=2001:23::3 ICMPv6: Received echo reply, Src=2001:23::3, Dst=FC00:12::1
Rule 3: Avoid deprecated addresses – RFC4862 does a very good job describing what a deprecated address is in this case:
IPv6 addresses are leased to an interface for a fixed (possibly infinite) length of time. Each address has an associated lifetime that indicates how long the address is bound to an interface. When a lifetime expires, the binding (and address) become invalid and the address may be reassigned to another interface elsewhere in the Internet. To handle the expiration of address bindings gracefully, an address goes through two distinct phases while assigned to an interface. Initially, an address is “preferred“, meaning that its use in arbitrary communication is unrestricted. Later, an address becomes “deprecated” in anticipation that its current interface binding will become invalid. While an address is in a deprecated state, its use is discouraged, but not strictly forbidden. New communication (e.g., the opening of a new TCP connection) should use a preferred address when possible. A deprecated address should be used only by applications that have been using it and would have difficulty switching to another address without a service disruption.
Rule 4: Prefer home addresses – This rule applies to Mobile IP hosts. In Mobile IP a mobile node has two addresses: home-address and care-of-address. For IPv6 source selection, preference is given to the home-address.
Rule 5: Prefer outgoing interface – If you have two interfaces, use the IPv6 address of the outgoing interface instead of another interface.
Rule 6: Prefer matching label – There are methods to define custom policies which specify the preference of source address. I don’t think this is widely used but has to be done with DHCPv6.
Rule 7: Prefer temporary addresses – Temporary addresses provide better privacy by not including the MAC address in the host-id portion of an IPv6 address. It generates a pseudo-random host-id that changes over time. Microsoft support it on their OS and I don’t think Cisco supports that feature for its devices. For more info on temporary IPv6 addresses check out RFC4941 – Privacy Extensions for Stateless Address Autoconfiguration in IPv6.
Rule 8: Use longest matching prefix – This rule refers to a situation if an interface has two IPv6 address of the same scope. For example if R3 would like to ping R2’s IPv6 address 2001:12::2, which one of its two global addresses would it pick: 2001:10::3/64 (Global from ISP A) or 2001:23::3/64 (Global from ISP B)?
The longest matching prefix between the destination and all sources is /31 for source address 2001:10::3. The other address (2001:23::3) match up to the /26th bit, which is much shorter than /31.
R3#ping 2001:12::2 repeat 1 Type escape sequence to abort. Sending 1, 100-byte ICMP Echos to 2001:12::2, timeout is 2 seconds: ! Success rate is 100 percent (1/1),round-trip min/avg/max = 40/40/40 ms R3# ICMPv6: Sent echo request, Src=2001:10::3, Dst=2001:12::2 ICMPv6: Received echo reply, Src=2001:12::2, Dst=2001:10::3
Hopefully now you’ll have a better idea how a host with multiple IPv6 addresses will pick its source address.