Over the last two weeks I’ve been focusing on strengthening my knowledge of IPv6 and it got me thinking about usage of link local addresses as the next hop for routing. It became apparent that this difference from IPv4 makes it possible to have equal cost next hops via the same output interface and for the opposite to be possible, one single next hop reachable via two local interfaces. Without demonstration, that’s all gibberish but hopefully it will make sense soon.
Demo Network
Consider the topology below. The loopback IPv6 addresses are annotated, and the router physical interfaces only have IPv6 link local addresses. EIGRP for IPv6 is enabled on the router physical interfaces and loopbacks. The switch has no configuration other than a hostname.
This topology means that R1 will have two different next hop addresses via G0/0 to reach R2’s loopback and that R2 will have one next hop that is reachable via two different interfaces to reach R1’s loopback. This wouldn’t be easily achieved in IPv4 because R2’s physical interfaces would need overlapping subnets.
Configs
Before examining the RIB and FIB, let’s take a quick look at the interface configuration and addressing.
Notice that R1 G0/0 only has no IPv6 address configuration. “IPv6 enable” causes the interface to assign itself a link local address using EUI-64, show below. “ipv6 eigrp 1” enables EIGRP autonomous system 1 on the interfaces.
R1#show running-config interface gigabitEthernet 0/0
Building configuration...
Current configuration : 120 bytes
!
interface GigabitEthernet0/0
no ip address
duplex auto
speed auto
media-type rj45
ipv6 enable
ipv6 eigrp 1
end
R1#show ipv6 interface brief gigabitEthernet 0/0
GigabitEthernet0/0 [up/up]
FE80::5054:FF:FE0E:B4EF
R1s loopback is statically configured with an IPv6 global unicast address and was also automatically assigned a link local address derived from EUI-64.
R1#show running-config interface loopback 1
Building configuration...
Current configuration : 86 bytes
!
interface Loopback1
no ip address
ipv6 address 2001:DB8::1/128
ipv6 eigrp 1
end
R1#show ipv6 interface brief loopback 1
Loopback1 [up/up]
FE80::5054:FF:FE0E:B4EF
2001:DB8::1
R2 is configured in the same manner, except it has two physical interfaces that only have link local addressing. I’ll spare you from looking at the interface configurations. Below are R2s IPv6 addresses.
R2#show ipv6 interface brief gigabitEthernet 0/0
GigabitEthernet0/0 [up/up]
FE80::5054:FF:FE18:23AA
R2#show ipv6 interface brief gigabitEthernet 0/1
GigabitEthernet0/1 [up/up]
FE80::5054:FF:FE18:30BB
R2#show ipv6 interface brief loopback 1
Loopback1 [up/up]
FE80::5054:FF:FE18:23AA
2001:DB8::2
EIGRP
Now that we’ve seen the topology and relevant configuration and addressing let’s dig into how EIGRP and routing operate in this network.
R1 has two EIGRP neighbors on Gi0/0, the neighbor addresses are R2’s link local addresses on Gi0/0 and Gi0/1.
R1#show ipv6 eigrp neighbors
EIGRP-IPv6 Neighbors for AS(1)
H Address Interface Hold Uptime SRTT RTO Q Seq
(sec) (ms) Cnt Num
1 Link-local address: Gi0/0 14 01:09:00 1277 5000 0 11
FE80::5054:FF:FE18:30BB
0 Link-local address: Gi0/0 14 01:09:00 1588 5000 0 12
FE80::5054:FF:FE18:23AA
R2’s EIGRP neighbor adjacencies are a little more interesting and not as initially obvious. R2 has 4 EIGRP neighbors. Two with R1 via each of its physical interfaces, and two with itself via each of its physical interfaces.
R2#show ipv6 eigrp neighbors
EIGRP-IPv6 Neighbors for AS(1)
H Address Interface Hold Uptime SRTT RTO Q Seq
(sec) (ms) Cnt Num
3 Link-local address: Gi0/1 10 01:09:18 24 144 0 5
FE80::5054:FF:FE0E:B4EF
2 Link-local address: Gi0/0 10 01:09:18 22 132 0 5
FE80::5054:FF:FE0E:B4EF
1 Link-local address: Gi0/1 14 01:09:32 1288 5000 0 12
FE80::5054:FF:FE18:23AA
0 Link-local address: Gi0/0 13 01:09:32 21 126 0 11
FE80::5054:FF:FE18:30BB
The RIB
Now let’s look at the routing table on R1 and R2 to reach each other’s IPv6 global unicast loopback interface addresses.
R1 has two next hops to reach 2001:db8::2/128 via Gi0/0. These next hop addresses are R2’s link local addresses.
R1#show ipv6 route 2001:db8::2
Routing entry for 2001:DB8::2/128
Known via "eigrp 1", distance 90, metric 130816, type internal
Route count is 2/2, share count 0
Routing paths:
FE80::5054:FF:FE18:23AA, GigabitEthernet0/0
From FE80::5054:FF:FE18:23AA
Last updated 00:32:21 ago
FE80::5054:FF:FE18:30BB, GigabitEthernet0/0
From FE80::5054:FF:FE18:30BB
Last updated 00:32:21 ago
Over on R2 we see an entry for two outgoing interfaces, both sharing the same IPv6 link local next hop address. This is R1’s Gi0/0 link local address.
R2#show ipv6 route 2001:db8::1
Routing entry for 2001:DB8::1/128
Known via "eigrp 1", distance 90, metric 130816, type internal
Route count is 2/2, share count 0
Routing paths:
FE80::5054:FF:FE0E:B4EF, GigabitEthernet0/1
From FE80::5054:FF:FE0E:B4EF
Last updated 00:32:53 ago
FE80::5054:FF:FE0E:B4EF, GigabitEthernet0/0
From FE80::5054:FF:FE0E:B4EF
Last updated 00:32:48 ago
The FIB
We’ve seen the routing table entries, so let’s verify how these entries are programmed in the forwarding table with some CEF show commands.
Starting on R1 with “show ipv6 cef internal” we can see that it has two hash buckets allocated on Gi0/0 to reach R2’s loopback. This should provide equal cost multipath forwarding, even though only part of the topology is truly multipath.
R1#show ipv6 cef 2001:db8::2/128 internal
2001:DB8::2/128, epoch 0, RIB[O], refcnt 4, per-destination sharing
sources: RIB
feature space:
IPRM: 0x00028000
ifnums:
GigabitEthernet0/0(2): FE80::5054:FF:FE18:23AA, FE80::5054:FF:FE18:30BB
path list 10D97DAC, 3 locks, per-destination, flags 0x49 [shble, rif, hwcn]
path 107216D0, share 1/1, type attached nexthop, for IPv6
nexthop FE80::5054:FF:FE18:23AA GigabitEthernet0/0, IPV6 adj out of GigabitEthernet0/0, addr FE80::5054:FF:FE18:23AA 0F9F3EF8
path 10721664, share 1/1, type attached nexthop, for IPv6
nexthop FE80::5054:FF:FE18:30BB GigabitEthernet0/0, IPV6 adj out of GigabitEthernet0/0, addr FE80::5054:FF:FE18:30BB 0F9F3DC8
output chain:
loadinfo 0F35866C, per-session, 2 choices, flags 0085, 5 locks
flags [Per-session, for-rx-IPv6, 2buckets]
2 hash buckets
< 0 > IPV6 adj out of GigabitEthernet0/0, addr FE80::5054:FF:FE18:23AA 0F9F3EF8
< 1 > IPV6 adj out of GigabitEthernet0/0, addr FE80::5054:FF:FE18:30BB 0F9F3DC8
Subblocks:
None
Using “show ipv6 cef exact-route” we can see the result of R1’s ECMP hashing with various source addresses to reach the R2 loopback. Notice that the output interface is the same, but the link local next hops are different.
R1#show ipv6 cef exact-route 2001:db8::1 2001:db8::2
2001:DB8::1 -> 2001:DB8::2 =>IPV6 adj out of GigabitEthernet0/0, addr FE80::5054:FF:FE18:30BB
R1#show ipv6 cef exact-route 2001:db8::3 2001:db8::2
2001:DB8::3 -> 2001:DB8::2 =>IPV6 adj out of GigabitEthernet0/0, addr FE80::5054:FF:FE18:23AA
R1#show ipv6 cef exact-route 2001:db8::4 2001:db8::2
2001:DB8::4 -> 2001:DB8::2 =>IPV6 adj out of GigabitEthernet0/0, addr FE80::5054:FF:FE18:30BB
R1#show ipv6 cef exact-route 2001:db8::5 2001:db8::2
2001:DB8::5 -> 2001:DB8::2 =>IPV6 adj out of GigabitEthernet0/0, addr FE80::5054:FF:FE18:23AA
Now we can see R2’s forwarding logic to reach the R1 loopback using the same commands.
R2 has two hash bucket entries to reach 2001:db8::1/128 via both physical interfaces that share the same IPv6 link local next hop
R2#show ipv6 cef 2001:db8::1/128 internal
2001:DB8::1/128, epoch 0, RIB[O], refcnt 4, per-destination sharing
sources: RIB
feature space:
IPRM: 0x00028000
ifnums:
GigabitEthernet0/0(2): FE80::5054:FF:FE0E:B4EF
GigabitEthernet0/1(3): FE80::5054:FF:FE0E:B4EF
path list 10883424, 3 locks, per-destination, flags 0x49 [shble, rif, hwcn]
path 108838DC, share 1/1, type attached nexthop, for IPv6
nexthop FE80::5054:FF:FE0E:B4EF GigabitEthernet0/0, IPV6 adj out of GigabitEthernet0/0, addr FE80::5054:FF:FE0E:B4EF 0D0BFC38
path 10883948, share 1/1, type attached nexthop, for IPv6
nexthop FE80::5054:FF:FE0E:B4EF GigabitEthernet0/1, IPV6 adj out of GigabitEthernet0/1, addr FE80::5054:FF:FE0E:B4EF 0D0BFB08
output chain:
loadinfo 0F35866C, per-session, 2 choices, flags 0085, 5 locks
flags [Per-session, for-rx-IPv6, 2buckets]
2 hash buckets
< 0 > IPV6 adj out of GigabitEthernet0/0, addr FE80::5054:FF:FE0E:B4EF 0D0BFC38
< 1 > IPV6 adj out of GigabitEthernet0/1, addr FE80::5054:FF:FE0E:B4EF 0D0BFB08
Subblocks:
None
Just like on R1, “show ipv6 cef exact-route” lets us see the ECMP hashing result to reach R1’s loopback. Note that the egress interfaces change but the next hop is always R1’s Gi0/0 link local address.
R2#show ipv6 cef exact-route 2001:db8::2 2001:db8::1
2001:DB8::2 -> 2001:DB8::1 =>IPV6 adj out of GigabitEthernet0/0, addr FE80::5054:FF:FE0E:B4EF
R2#show ipv6 cef exact-route 2001:db8::3 2001:db8::1
2001:DB8::3 -> 2001:DB8::1 =>IPV6 adj out of GigabitEthernet0/0, addr FE80::5054:FF:FE0E:B4EF
R2#show ipv6 cef exact-route 2001:db8::4 2001:db8::1
2001:DB8::4 -> 2001:DB8::1 =>IPV6 adj out of GigabitEthernet0/1, addr FE80::5054:FF:FE0E:B4EF
R2#show ipv6 cef exact-route 2001:db8::5 2001:db8::1
2001:DB8::5 -> 2001:DB8::1 =>IPV6 adj out of GigabitEthernet0/0, addr FE80::5054:FF:FE0E:B4EF
R2#show ipv6 cef exact-route 2001:db8::6 2001:db8::1
2001:DB8::6 -> 2001:DB8::1 =>IPV6 adj out of GigabitEthernet0/1, addr FE80::5054:FF:FE0E:B4EF