IPv6 Next Hop

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