This post will look at how Neighbor Discovery works in IPv6. The topology is shown below:

First we will configure the MAC address of each router’s interface to 0000.0000.XXXX where X is the router number in order to make EUI-64 format addresses easier to work with:

R1:

interface FastEthernet0/0

mac-address 0000.0000.1111



R2:

interface FastEthernet0/0

mac-address 0000.0000.2222



R3:

interface FastEthernet0/0

mac-address 0000.0000.3333



Next we will configure a global unicast address on R1:

R1:

interface FastEthernet0/0

ipv6 address 2001:123::1/64



R1 assigns itself the configured address as well as a link-local address using the EUI-64 format:

We can see the sequence of events that takes place when the address configuration command is entered using debug ipv6 nd:



R1#debug ipv6 nd

*Mar 1 00:48:09.683: ICMPv6-ND: Adding prefix 2001:123::1/64 to FastEthernet0/0

*Mar 1 00:48:10.683: ICMPv6-ND: Sending NS for FE80::200:FF:FE00:1111 on FastEthernet0/0

*Mar 1 00:48:11.683: ICMPv6-ND: DAD: FE80::200:FF:FE00:1111 is unique.

*Mar 1 00:48:11.683: ICMPv6-ND: Sending NA for FE80::200:FF:FE00:1111 on FastEthernet0/0

*Mar 1 00:48:11.683: ICMPv6-ND: Address FE80::200:FF:FE00:1111/10 is up on FastEthernet0/0

*Mar 1 00:48:11.691: ICMPv6-ND: Sending NS for 2001:123::1 on FastEthernet0/0

*Mar 1 00:48:12.691: ICMPv6-ND: DAD: 2001:123::1 is unique.

*Mar 1 00:48:12.691: ICMPv6-ND: Sending NA for 2001:123::1 on FastEthernet0/0

*Mar 1 00:48:12.691: ICMPv6-ND: Address 2001:123::1/64 is up on FastEthernet0/0



We will examine this process step by step in a moment when we configure R2 to act as a host on the network. For now, we will configure R1 to act as a router on the network:

R1:

ipv6 unicast-routing



After entering this, we can see that several new lines appear at the bottom of the show ipv6 interface output:

This information relates to the sending of Router Advertisement (RA) messages by R1. As soon as ipv6 unicast-routing is configured, R1 begins sending unsolicited RA messages approximately every 200 seconds:

R1#debug ipv6 nd

*Mar 1 00:55:55.031: ICMPv6-ND: Sending RA to FF02::1 on FastEthernet0/0

*Mar 1 00:55:55.031: ICMPv6-ND: MTU = 1500

*Mar 1 00:55:55.035: ICMPv6-ND: prefix = 2001:123::/64 onlink autoconfig

*Mar 1 00:55:55.035: ICMPv6-ND: 2592000/604800 (valid/preferred)



These RAs are sourced from R1’s link local address and sent to the all IPv6 nodes multicast group:

The ICMPv6 Type value identifies the message as an RA. There are several other pieces of information within the RA that could be important to hosts on the link. The main one we are interested in right now is the first flag bit, which has not been set. This tells hosts they should attempt to use stateless autoconfiguration to obtain their IPv6 addresses. We can also see that 3 optional TLVs have been included in the RA message in order to tell hosts on the link about the router’s MAC address, the MTU of the link, and the global prefix used on the link:

Next, let’s configure R2 to automatically obtain an IPv6 address through stateless autoconfiguration:

R2:

interface FastEthernet0/0

ipv6 address autoconfig



A similar sequence of events takes place on R2 after entering the address command to what we saw earlier on R1:

R2#debug ipv6 nd

*Mar 1 01:45:52.175: ICMPv6-ND: Sending NS for FE80::200:FF:FE00:2222 on FastEthernet0/0

*Mar 1 01:45:53.175: ICMPv6-ND: DAD: FE80::200:FF:FE00:2222 is unique.

*Mar 1 01:45:53.175: ICMPv6-ND: Sending NA for FE80::200:FF:FE00:2222 on FastEthernet0/0

*Mar 1 01:45:53.175: ICMPv6-ND: Address FE80::200:FF:FE00:2222/10 is up on FastEthernet0/0

*Mar 1 01:45:55.179: ICMPv6-ND: Sending RS on FastEthernet0/0

*Mar 1 01:45:55.199: ICMPv6-ND: Received RA from FE80::200:FF:FE00:1111 on FastEthernet0/0

*Mar 1 01:45:55.203: ICMPv6-ND: DELETE -> INCMP: FE80::200:FF:FE00:1111

*Mar 1 01:45:55.203: ICMPv6-ND: INCMP -> STALE: FE80::200:FF:FE00:1111

*Mar 1 01:45:55.207: ICMPv6-ND: Sending NS for 2001:123::200:FF:FE00:2222 on FastEthernet0/0

*Mar 1 01:45:55.207: ICMPv6-ND: Autoconfiguring 2001:123::200:FF:FE00:2222 on FastEthernet0/0

*Mar 1 01:45:56.207: ICMPv6-ND: DAD: 2001:123::200:FF:FE00:2222 is unique.

*Mar 1 01:45:56.207: ICMPv6-ND: Sending NA for 2001:123::200:FF:FE00:2222 on FastEthernet0/0

*Mar 1 01:45:56.211: ICMPv6-ND: Address 2001:123::200:FF:FE00:2222/64 is up on FastEthernet0/0



Let’s look at this process step by step. After telling R2 to use autoconfiguration to obtain an address, R2 first calculates it’s EUI-64 interface ID on F0/0 from it’s MAC address and appends this to the link local prefix (FE80::/10). R2 marks this address as tentative (shown as ‘TEN’) and sends a neighbor solicitation (NS) message to this address to verify that it isn’t a duplicate before R2 starts to use it:

*Mar 1 01:45:52.175: ICMPv6-ND: Sending NS for FE80::200:FF:FE00:2222 on FastEthernet0/0

The NS message is sourced from an unspecified IPv6 address (::) since R2 does not have a valid IPv6 address yet and is sent to the solicited node multicast group for the tentative address (FF02::1:FF00:2222).

Any node with an address that ended in the same 24 bits would be required to join this group and would hear the NS message. The node would then examine the target address contained within the NS to see if the full address matched it’s own or not, and if it did would prevent R2 from using it. Since no other nodes are using this address, R2 does not get a reply back. After waiting 1 second without a reply, R2 determines that the address must be unique:

*Mar 1 01:45:53.175: ICMPv6-ND: DAD: FE80::200:FF:FE00:2222 is unique.



At the same time R2 begins using the address and removes the tentative marker from it. R2 also sends an unsolicited neighbor advertisement (NA) to advertise it’s new link-local address:

*Mar 1 01:45:53.175: ICMPv6-ND: Sending NA for FE80::200:FF:FE00:2222 on FastEthernet0/0

*Mar 1 01:45:53.175: ICMPv6-ND: Address FE80::200:FF:FE00:2222/10 is up on FastEthernet0/0



The source address is set to R2’s link local address and the destination address is the all IPv6 nodes multicast address. The target address is set to R2’s link local so other nodes know which address the advertisement is for, and the NA message includes an option TLV to specify R2’s MAC address. The override flag has also been set, telling receivers that this information should override the information in their neighbor cache for this entry.

After a couple seconds, R2 sends a router solicitation (RS) to request that any routers on the link send an RA:

*Mar 1 01:45:55.179: ICMPv6-ND: Sending RS on FastEthernet0/0



R2 uses it’s link-local address as the source and the all routers IPv6 multicast address as the destination. R2 also includes it’s MAC address as an option TLV:

R1 receives the RS and sends a solicited RA in response rather than waiting up to 200 seconds for it’s next unsolicited RA. Some sources say that this is unicast to the IPv6 address of the node that sent the RS, but my tests showed that the destination address (FF02::1) and every other part of the packet was identical to an unsolicted RA. R2 receives the RA from R1 a few milliseconds after sending it’s RS:

*Mar 1 01:45:55.199: ICMPv6-ND: Received RA from FE80::200:FF:FE00:1111 on FastEthernet0/0



The next two debug messages relate to the neighbor cache, which we will ignore for now. R2 learns R1’s link-local address and adds it as a default router. R2 also learns the link prefix from the received RA and prepends it to it’s EUI-64 interface ID. Just like with the link-local address, R2 marks the address as tentative and sends an NS as part of the Duplicate Address Detection procedure:





*Mar 1 01:45:55.207: ICMPv6-ND: Sending NS for 2001:123::200:FF:FE00:2222 on FastEthernet0/0

*Mar 1 01:45:55.207: ICMPv6-ND: Autoconfiguring 2001:123::200:FF:FE00:2222 on FastEthernet0/0



The NS packet is identical to the one shown earlier, other than the target address now being set to R2’s tentative global unicast address instead of the link-local address. When no reply for the address comes back after 1 second, R2 determines that this address is also unique:

*Mar 1 01:45:56.207: ICMPv6-ND: DAD: 2001:123::200:FF:FE00:2222 is unique.



R2 then sends an unsolicited NA to advertise it’s new address. The NA is identical to the one that R2 sent for it’s link-local address earlier other than the source IPv6 address and target address in the ICMPv6 option being set to R2’s global unicast address instead of the link-local address:

*Mar 1 01:45:56.207: ICMPv6-ND: Sending NA for 2001:123::200:FF:FE00:2222 on FastEthernet0/0



Finally, R2 is able to remove the tentative marking on the address:

*Mar 1 01:45:56.211: ICMPv6-ND: Address 2001:123::200:FF:FE00:2222/64 is up on FastEthernet0/0



If multiple prefixes are configured on the link, R1 includes an additional TLV in it’s RA messages for each prefix:

R1:

interface FastEthernet0/0

ipv6 address 3001:123::1/64



R1#debug ipv6 nd

*Mar 1 01:31:19.691: ICMPv6-ND: Sending RA to FF02::1 on FastEthernet0/0

*Mar 1 01:31:19.691: ICMPv6-ND: MTU = 1500

*Mar 1 01:31:19.691: ICMPv6-ND: prefix = 2001:123::/64 onlink autoconfig

*Mar 1 01:31:19.691: ICMPv6-ND: 2592000/604800 (valid/preferred)

*Mar 1 01:31:19.695: ICMPv6-ND: prefix = 3001:123::/64 onlink autoconfig

*Mar 1 01:31:19.695: ICMPv6-ND: 2592000/604800 (valid/preferred)



R2 goes through the same process detailed above for the new prefix and configures itself a global address using that prefix as well:

If another node on the link attempts to use the same IPv6 address, Duplicate Address Detection prevents this from happening. Before testing this out, first we will get rid of the additional prefix that we created:

R1:

interface FastEthernet0/0

no ipv6 address 3001:123::1/64



R2:

interface FastEthernet0/0

no ipv6 address autoconfig



A few seconds later…

R2:

interface FastEthernet0/0

ipv6 address autoconfig



Next we will configure R3 to use the same MAC address as R2 and to obtain an IPv6 address through stateless autoconfiguration:

R3:

interface FastEthernet0/0

mac-address 0000.0000.2222

ipv6 address autoconfig



R3#debug ipv6 nd

*Mar 1 01:48:21.775: ICMPv6-ND: Sending NS for FE80::200:FF:FE00:2222 on FastEthernet0/0

*Mar 1 01:48:21.907: ICMPv6-ND: Received NA for FE80::200:FF:FE00:2222 on FastEthernet0/0 from FE80::200:FF:FE00:2222

*Mar 1 01:48:21.915: ICMPv6-ND: DAD: duplicate link-local FE80::200:FF:FE00:2222 on FastEthernet0/0,interface stalled

*Mar 1 01:48:21.915: %IPV6-4-DUPLICATE: Duplicate address FE80::200:FF:FE00:2222 on FastEthernet0/0





R3 follows the same process shown earlier, calculating it’s EUI-64 interface ID and appending the interface ID to the link-local prefix. R3 then sends a NS for the tentative address that it came up with to the solicited-node multicast group. Since R2 has joined this group, it receives the NS and finds it’s own address as the target. R2 sends an NA immediately to the all nodes multicast address. R3 receives the NA from R2 before it’s 1 second DAD timer expires, and R3 realizes the address is a duplicate. R3 marks the address as a duplicate and does not begin using it:

The MAC address would have to be changed on R3 or a different IPv6 address would have to be manually configured. Notice also that R3 does not even attempt to assign itself a global address through autoconfiguration until it has a non-duplicate link-local address. If we change the link-local address used on R3 manually and continue to use stateless autoconfiguration, this not only fixes the duplicate link-local address but also results in R3 assigning itself a non-duplicate global address:

R3:

interface FastEthernet0/0

ipv6 address FE80::3 link-local



*Mar 1 02:10:27.483: ICMPv6-ND: Sending NS for FE80::3 on FastEthernet0/0

*Mar 1 02:10:28.483: ICMPv6-ND: DAD: FE80::3 is unique.

*Mar 1 02:10:28.483: ICMPv6-ND: Sending NA for FE80::3 on FastEthernet0/0

*Mar 1 02:10:28.483: ICMPv6-ND: Address FE80::3/10 is up on FastEthernet0/0

*Mar 1 02:10:30.483: ICMPv6-ND: Sending RS on FastEthernet0/0

*Mar 1 02:10:30.523: ICMPv6-ND: Received RA from FE80::200:FF:FE00:1111 on FastEthernet0/0

*Mar 1 02:10:30.523: ICMPv6-ND: DELETE -> INCMP: FE80::200:FF:FE00:1111

*Mar 1 02:10:30.527: ICMPv6-ND: INCMP -> STALE: FE80::200:FF:FE00:1111

*Mar 1 02:10:30.527: ICMPv6-ND: Sending NS for 2001:123::3 on FastEthernet0/0

*Mar 1 02:10:30.531: ICMPv6-ND: Autoconfiguring 2001:123::3 on FastEthernet0/0

*Mar 1 02:10:31.527: ICMPv6-ND: DAD: 2001:123::3 is unique.

*Mar 1 02:10:31.527: ICMPv6-ND: Sending NA for 2001:123::3 on FastEthernet0/0

*Mar 1 02:10:31.531: ICMPv6-ND: Address 2001:123::3/64 is up on FastEthernet0/0



This shows that the interface ID for the link-local address is derived from the MAC address unless manually configured. The interface ID for a global address, however, is derived from the interface ID used for the link-local address – so if the link-local address has been manually configured, global addresses will use the same interface ID rather than applying the MAC to EUI-64 conversion to obtain an interface ID. This applies to interfaces that are manually configured to use EUI-64 as well:

R3:

interface FastEthernet0/0

no ipv6 address



A few seconds later…

R3:

interface FastEthernet0/0

ipv6 address 2001:123::/64 eui-64



*Mar 1 02:26:49.463: ICMPv6-ND: Adding prefix 2001:123::200:FF:FE00:2222/64 to FastEthernet0/0

*Mar 1 02:26:50.463: ICMPv6-ND: Sending NS for FE80::200:FF:FE00:2222 on FastEthernet0/0

*Mar 1 02:26:50.515: ICMPv6-ND: Received NA for FE80::200:FF:FE00:2222 on FastEthernet0/0 from FE80::200:FF:FE00:2222

*Mar 1 02:26:50.523: ICMPv6-ND: DAD: duplicate link-local FE80::200:FF:FE00:2222 on FastEthernet0/0,interface stalled

*Mar 1 02:26:50.523: %IPV6-4-DUPLICATE: Duplicate address FE80::200:FF:FE00:2222 on FastEthernet0/0



R3:

interface FastEthernet0/0

ipv6 address FE80::3 link-local



*Mar 1 02:30:37.027: ICMPv6-ND: Sending NS for FE80::3 on FastEthernet0/0

*Mar 1 02:30:38.027: ICMPv6-ND: DAD: FE80::3 is unique.

*Mar 1 02:30:38.027: ICMPv6-ND: Sending NA for FE80::3 on FastEthernet0/0

*Mar 1 02:30:38.027: ICMPv6-ND: Address FE80::3/10 is up on FastEthernet0/0

*Mar 1 02:30:38.031: ICMPv6-ND: Sending NS for 2001:123::3 on FastEthernet0/0

*Mar 1 02:30:39.031: ICMPv6-ND: DAD: 2001:123::3 is unique.

*Mar 1 02:30:39.031: ICMPv6-ND: Sending NA for 2001:123::3 on FastEthernet0/0

*Mar 1 02:30:39.031: ICMPv6-ND: Address 2001:123::3/64 is up on FastEthernet0/0

Next, we will add a second router to the link. R1 and R2 will be configured as routers:

R1:

ipv6 unicast-routing

!

interface FastEthernet0/0

mac-address 0000.0000.1111

ipv6 address 2001:123::1/64

ipv6 address FE80::1 link-local



R2:

ipv6 unicast-routing

!

interface FastEthernet0/0

mac-address 0000.0000.2222

ipv6 address 2001:123::2/64

ipv6 address FE80::2 link-local



R3 will be configured to use stateless autoconfiguration:

R3:

interface FastEthernet0/0

mac-address 0000.0000.3333

ipv6 address FE80::3 link-local

ipv6 address autoconfig



When R3 sends out an RS, it receives an RA from both R1 and R2. In this case, the RA from R2 arrives a few milliseconds before the RA from R1:

R3#debug ipv6 nd

*Mar 1 02:45:26.139: ICMPv6-ND: Received RA from FE80::2 on FastEthernet0/0

*Mar 1 02:45:26.147: ICMPv6-ND: Received RA from FE80::1 on FastEthernet0/0



What a host does when there are multiple routers is implementation specific; for a Cisco router acting as a host, it appears that only the first RA received is used as the default router:

Next we will look at how Neighbor Unreachability Detection works. The Layer-2 address for IPv6 nodes is stored in the neighbor cache, similar to the ARP cache of IPv4. The current neighbor cache of R3 is shown below:

R3 has entries for R1 and R2’s link-local addresses, both in a STALE state. This means that these addresses were reachable previously, but the Reachable Time has expired since the last confirmation of their reachability. Let’s try to ping R1’s link-local address on R3:

R3#debug ipv6 icmp

R3#debug ipv6 nd

Mar 1 03:47:37.073: ICMPv6: Sending echo request to FE80::1

Mar 1 03:47:37.073: ICMPv6-ND: STALE -> DELAY: FE80::1

Mar 1 03:47:37.117: ICMPv6: Received echo reply from FE80::1

Mar 1 03:47:42.073: ICMPv6-ND: DELAY -> PROBE: FE80::1

Mar 1 03:47:42.073: ICMPv6-ND: Sending NS for FE80::1 on FastEthernet0/0

Mar 1 03:47:42.169: ICMPv6: Received ICMPv6 packet from FE80::1, type 135

Mar 1 03:47:42.173: ICMPv6-ND: Received NS for FE80::3 on FastEthernet0/0 from FE80::1

Mar 1 03:47:42.173: ICMPv6-ND: Sending NA for FE80::3 on FastEthernet0/0

Mar 1 03:47:42.173: ICMPv6: Received ICMPv6 packet from FE80::1, type 136

Mar 1 03:47:42.173: ICMPv6-ND: Received NA for FE80::1 on FastEthernet0/0 from FE80::1

Mar 1 03:47:42.177: ICMPv6-ND: PROBE -> REACH: FE80::1

Mar 1 03:48:12.179: ICMPv6-ND: REACH -> STALE: FE80::1



R1#debug ipv6 icmp

R1#debug ipv6 nd

Mar 1 03:47:37.095: ICMPv6: Received echo request from FE80::3

Mar 1 03:47:37.095: ICMPv6: Sending echo reply to FE80::3

Mar 1 03:47:37.095: ICMPv6-ND: STALE -> DELAY: FE80::3

Mar 1 03:47:42.095: ICMPv6-ND: DELAY -> PROBE: FE80::3

Mar 1 03:47:42.095: ICMPv6-ND: Sending NS for FE80::3 on FastEthernet0/0

Mar 1 03:47:42.115: ICMPv6: Received ICMPv6 packet from FE80::3, type 135

Mar 1 03:47:42.119: ICMPv6-ND: Received NS for FE80::1 on FastEthernet0/0 from FE80::3

Mar 1 03:47:42.119: ICMPv6-ND: Sending NA for FE80::1 on FastEthernet0/0

Mar 1 03:47:42.215: ICMPv6: Received ICMPv6 packet from FE80::3, type 136

Mar 1 03:47:42.215: ICMPv6-ND: Received NA for FE80::3 on FastEthernet0/0 from FE80::3

Mar 1 03:47:42.215: ICMPv6-ND: PROBE -> REACH: FE80::3

Mar 1 03:48:12.215: ICMPv6-ND: REACH -> STALE: FE80::3



R3 sends an echo request to R1 immediately, using the Layer-2 address from the STALE entry in the neighbor cache. R3 also changes the state of the entry from STALE to DELAY, meaning at least 1 packet has been sent to this address and R3 is now awaiting confirmation of reachability:

R3:

Mar 1 03:47:37.073: ICMPv6: Sending echo request to FE80::1

Mar 1 03:47:37.073: ICMPv6-ND: STALE -> DELAY: FE80::1



R1 receives the echo request a few milliseconds later and sends an echo reply back, also using the STALE entry that it has in the neighbor cache for R3. Sending an echo reply causes the state to change to DELAY since R1 is now awaiting confirmation of reachability:

R1:

Mar 1 03:47:37.095: ICMPv6: Received echo request from FE80::3

Mar 1 03:47:37.095: ICMPv6: Sending echo reply to FE80::3

Mar 1 03:47:37.095: ICMPv6-ND: STALE -> DELAY: FE80::3



R3 receives the echo reply from R1 a few milliseconds later:

R3:

Mar 1 03:47:37.117: ICMPv6: Received echo reply from FE80::1



However, this does not count as a confirmation of reachablity and the cache entry remains in the DELAY state. The only ways that reachability can be confirmed are:

1. Hints from an upper-layer protocol show that the connection is making forward progress – for example increasing, non-duplicate TCP acknowledgements are received.

2. A solicited NA is received in response to an NS. The NA must be solicited because an unsolicited NA would only confirm 1-way reachability.

Since reachability has not been confirmed, R3 stays in the DELAY state waiting for reachability confirmation for a total of 5 seconds. After 5 seconds, R3 changes to the PROBE state and actively tries to confirm reachability by sending an NS to the address in question:

R3:

Mar 1 03:47:42.073: ICMPv6-ND: DELAY -> PROBE: FE80::1

Mar 1 03:47:42.073: ICMPv6-ND: Sending NS for FE80::1 on FastEthernet0/0



R1’s 5 second timer expires just a few milliseconds later and it also changes the entry to the PROBE state and sends an NS to R1’s address:

R1:

Mar 1 03:47:42.095: ICMPv6-ND: DELAY -> PROBE: FE80::3

Mar 1 03:47:42.095: ICMPv6-ND: Sending NS for FE80::3 on FastEthernet0/0

R1 receives R3’s NS and sends an NA with the solicited flag set:

R1:

Mar 1 03:47:42.115: ICMPv6: Received ICMPv6 packet from FE80::3, type 135

Mar 1 03:47:42.119: ICMPv6-ND: Received NS for FE80::1 on FastEthernet0/0 from FE80::3

Mar 1 03:47:42.119: ICMPv6-ND: Sending NA for FE80::1 on FastEthernet0/0



R3 also receives R1’s NS and sends an NA with the solicited flag set:

R3:

Mar 1 03:47:42.169: ICMPv6: Received ICMPv6 packet from FE80::1, type 135

Mar 1 03:47:42.173: ICMPv6-ND: Received NS for FE80::3 on FastEthernet0/0 from FE80::1

Mar 1 03:47:42.173: ICMPv6-ND: Sending NA for FE80::3 on FastEthernet0/0



R3 receives the solicited NA from R1. This confirms 2-way reachability, so R3 changes the state of the entry to REACH:

R3:

Mar 1 03:47:42.173: ICMPv6: Received ICMPv6 packet from FE80::1, type 136

Mar 1 03:47:42.173: ICMPv6-ND: Received NA for FE80::1 on FastEthernet0/0 from FE80::1

Mar 1 03:47:42.177: ICMPv6-ND: PROBE -> REACH: FE80::1



Likewise, R1 receives the solicited NA from R3 and now has confirmed 2-way reachability, so R1 changes the state of the entry to REACH:

R1:

Mar 1 03:47:42.215: ICMPv6: Received ICMPv6 packet from FE80::3, type 136

Mar 1 03:47:42.215: ICMPv6-ND: Received NA for FE80::3 on FastEthernet0/0 from FE80::3

Mar 1 03:47:42.215: ICMPv6-ND: PROBE -> REACH: FE80::3



After the Reachable Time expires (30 seconds by default) without further 2-way reachability confirmation, the state of the entry changes back to STALE:

R3:

Mar 1 03:48:12.179: ICMPv6-ND: REACH -> STALE: FE80::1



R1:

Mar 1 03:48:12.215: ICMPv6-ND: REACH -> STALE: FE80::3



For traffic that does not offer a positive confirmation of 2-way reachability, this results in each device sending an NS and solicited NA to each other approximately every 35 seconds (Reachable Time + Delay time):

R3#ping fe80::1 repeat 1000000



R1#debug ipv6 nd

Mar 1 04:36:48.634: ICMPv6-ND: STALE -> DELAY: FE80::3

Mar 1 04:36:53.622: ICMPv6-ND: Received NS for FE80::1 on FastEthernet0/0 from FE80::3

Mar 1 04:36:53.622: ICMPv6-ND: Sending NA for FE80::1 on FastEthernet0/0

Mar 1 04:36:53.634: ICMPv6-ND: DELAY -> PROBE: FE80::3

Mar 1 04:36:53.634: ICMPv6-ND: Sending NS for FE80::3 on FastEthernet0/0

Mar 1 04:36:53.710: ICMPv6-ND: Received NA for FE80::3 on FastEthernet0/0 from FE80::3

Mar 1 04:36:53.710: ICMPv6-ND: PROBE -> REACH: FE80::3

Mar 1 04:37:23.710: ICMPv6-ND: REACH -> STALE: FE80::3

Mar 1 04:37:23.714: ICMPv6-ND: STALE -> DELAY: FE80::3

Mar 1 04:37:28.666: ICMPv6-ND: Received NS for FE80::1 on FastEthernet0/0 from FE80::3

Mar 1 04:37:28.666: ICMPv6-ND: Sending NA for FE80::1 on FastEthernet0/0

Mar 1 04:37:28.710: ICMPv6-ND: DELAY -> PROBE: FE80::3

Mar 1 04:37:28.710: ICMPv6-ND: Sending NS for FE80::3 on FastEthernet0/0

Mar 1 04:37:28.738: ICMPv6-ND: Received NA for FE80::3 on FastEthernet0/0 from FE80::3

Mar 1 04:37:28.742: ICMPv6-ND: PROBE -> REACH: FE80::3

Mar 1 04:37:58.742: ICMPv6-ND: REACH -> STALE: FE80::3

Mar 1 04:37:58.762: ICMPv6-ND: STALE -> DELAY: FE80::3

Mar 1 04:38:03.754: ICMPv6-ND: Received NS for FE80::1 on FastEthernet0/0 from FE80::3

Mar 1 04:38:03.758: ICMPv6-ND: Sending NA for FE80::1 on FastEthernet0/0

Mar 1 04:38:03.762: ICMPv6-ND: DELAY -> PROBE: FE80::3

Mar 1 04:38:03.762: ICMPv6-ND: Sending NS for FE80::3 on FastEthernet0/0

Mar 1 04:38:03.818: ICMPv6-ND: Received NA for FE80::3 on FastEthernet0/0 from FE80::3

Mar 1 04:38:03.818: ICMPv6-ND: PROBE -> REACH: FE80::3



The Reachable Time can be advertised in RAs so that hosts know what value to use. However, Cisco routers that are acting as hosts do not seem to learn the timer from their default router. R1 and R2 begin advertising a 10 second Reachable Time in RAs, but R3 continues using 30 seconds:

R1:

interface FastEthernet0/0

ipv6 nd reachable-time 10000



R2:

interface FastEthernet0/0

ipv6 nd reachable-time 10000



R3#ping fe80::1 repeat 1



R1:

Mar 1 05:04:55.730: ICMPv6-ND: PROBE -> REACH: FE80::3

Mar 1 05:05:05.730: ICMPv6-ND: REACH -> STALE: FE80::3



R3:

Mar 1 05:04:55.646: ICMPv6-ND: PROBE -> REACH: FE80::1

Mar 1 05:05:25.647: ICMPv6-ND: REACH -> STALE: FE80::1



The only way to get R3 to use a non-default Reachable Time is to manually configure it in the same way as R1 and R2.

Next, let’s try to ping R1’s global unicast address from R3. R1 and R3 both start with STALE entries for the link-local addresses of the other 2 devices in their neighbor cache:

The following sequence of events takes place after sending the echo request from R3:

R3#debug ipv6 nd

Mar 1 06:01:00.486: ICMPv6-ND: DELETE -> INCMP: 2001:123::1

Mar 1 06:01:00.486: ICMPv6-ND: Sending NS for 2001:123::1 on FastEthernet0/0

Mar 1 06:01:00.642: ICMPv6-ND: Received NA for 2001:123::1 on FastEthernet0/0 from 2001:123::1

Mar 1 06:01:00.642: ICMPv6-ND: INCMP -> REACH: 2001:123::1

Mar 1 06:01:05.594: ICMPv6-ND: Received NS for 2001:123::3 on FastEthernet0/0 from FE80::1

Mar 1 06:01:05.594: ICMPv6-ND: Sending NA for 2001:123::3 on FastEthernet0/0

Mar 1 06:01:05.594: ICMPv6-ND: STALE -> DELAY: FE80::1

Mar 1 06:01:10.595: ICMPv6-ND: DELAY -> PROBE: FE80::1

Mar 1 06:01:10.595: ICMPv6-ND: Sending NS for FE80::1 on FastEthernet0/0

Mar 1 06:01:10.639: ICMPv6-ND: Received NA for FE80::1 on FastEthernet0/0 from FE80::1

Mar 1 06:01:10.639: ICMPv6-ND: PROBE -> REACH: FE80::1

Mar 1 06:01:15.615: ICMPv6-ND: Received NS for FE80::3 on FastEthernet0/0 from FE80::1

Mar 1 06:01:15.615: ICMPv6-ND: Sending NA for FE80::3 on FastEthernet0/0

Mar 1 06:01:30.716: ICMPv6-ND: REACH -> STALE: 2001:123::1

Mar 1 06:01:40.641: ICMPv6-ND: REACH -> STALE: FE80::1



R1#debug ipv6 nd

Mar 1 06:01:00.578: ICMPv6-ND: Received NS for 2001:123::1 on FastEthernet0/0 from 2001:123::3

Mar 1 06:01:00.578: ICMPv6-ND: DELETE -> INCMP: 2001:123::3

Mar 1 06:01:00.578: ICMPv6-ND: INCMP -> STALE: 2001:123::3

Mar 1 06:01:00.578: ICMPv6-ND: Sending NA for 2001:123::1 on FastEthernet0/0

Mar 1 06:01:00.582: ICMPv6-ND: STALE -> DELAY: 2001:123::3

Mar 1 06:01:05.582: ICMPv6-ND: DELAY -> PROBE: 2001:123::3

Mar 1 06:01:05.582: ICMPv6-ND: Sending NS for 2001:123::3 on FastEthernet0/0

Mar 1 06:01:05.626: ICMPv6-ND: Received NA for 2001:123::3 on FastEthernet0/0 from 2001:123::3

Mar 1 06:01:05.626: ICMPv6-ND: PROBE -> REACH: 2001:123::3

Mar 1 06:01:10.610: ICMPv6-ND: Received NS for FE80::1 on FastEthernet0/0 from FE80::3

Mar 1 06:01:10.610: ICMPv6-ND: Sending NA for FE80::1 on FastEthernet0/0

Mar 1 06:01:10.610: ICMPv6-ND: STALE -> DELAY: FE80::3

Mar 1 06:01:15.610: ICMPv6-ND: DELAY -> PROBE: FE80::3

Mar 1 06:01:15.610: ICMPv6-ND: Sending NS for FE80::3 on FastEthernet0/0

Mar 1 06:01:15.754: ICMPv6-ND: Received NA for FE80::3 on FastEthernet0/0 from FE80::3

Mar 1 06:01:15.754: ICMPv6-ND: PROBE -> REACH: FE80::3

Mar 1 06:01:35.626: ICMPv6-ND: REACH -> STALE: 2001:123::3

Mar 1 06:01:45.754: ICMPv6-ND: REACH -> STALE: FE80::3



There are a few differences here compared to when we pinged R1’s link-local address. R3 does not know what Layer-2 address to use yet for 2001:123::1. R3 creates an incomplete (INCMP) entry for the address in the neighbor cache and sends an NS for the address. When R1 receives the NS, it creates an entry for R3’s global address and answers with a solicited NA. R3 receives the solicited NA which confirms reachability and tells R3 the Layer-2 address to use. R3 can now send the echo request to R1. R1 does not receive confirmation of 2-way reachability to R3’s global unicast address however, so 5 seconds after sending the NA to R3, R1 sends an NS for R3’s global unicast address sourced from R1’s link-local address which starts a chain reaction. R3 replies to the NS with a solicited NA, which confirms reachability on R1 to R3’s global unicast address and causes the entry on R3 for R1’s link-local to change to the DELAY state. After another 5 seconds, R3 sends an NS sourced from it’s link-local address for R1’s link-local address since it has not received reachability confirmation yet. R1 replies with a solicited NA, confirming reachability for R3 to R1’s link-local address and causing R1 to change the state of R3’s link-local entry to DELAY. After 5 seconds, R1 sends an NS for R3’s link-local and R3 answers with a solicited NA to confirm reachability. In total, 4 NS and 4 solicited NA were sent between the 2 devices:

Yet another situation occurs when the devices already have an entry for the address in their neighbor cache. In this case, R1 and R3 both have an entry for the other’s global unicast address since it was just pinged:

This time, the following sequence of events occurs:

R3#debug ipv6 nd

Mar 1 06:38:39.142: ICMPv6-ND: STALE -> DELAY: 2001:123::1

Mar 1 06:38:39.234: ICMPv6-ND: ULP indication 2001:123::1

Mar 1 06:38:39.234: ICMPv6-ND: DELAY -> REACH: 2001:123::1

Mar 1 06:38:44.146: ICMPv6-ND: Received NS for 2001:123::3 on FastEthernet0/0 from FE80::1

Mar 1 06:38:44.146: ICMPv6-ND: Sending NA for 2001:123::3 on FastEthernet0/0

Mar 1 06:38:44.146: ICMPv6-ND: STALE -> DELAY: FE80::1

Mar 1 06:38:49.146: ICMPv6-ND: DELAY -> PROBE: FE80::1

Mar 1 06:38:49.146: ICMPv6-ND: Sending NS for FE80::1 on FastEthernet0/0

Mar 1 06:38:49.182: ICMPv6-ND: Received NA for FE80::1 on FastEthernet0/0 from FE80::1

Mar 1 06:38:49.182: ICMPv6-ND: PROBE -> REACH: FE80::1

Mar 1 06:38:54.206: ICMPv6-ND: Received NS for FE80::3 on FastEthernet0/0 from FE80::1

Mar 1 06:38:54.206: ICMPv6-ND: Sending NA for FE80::3 on FastEthernet0/0

Mar 1 06:39:09.234: ICMPv6-ND: REACH -> STALE: 2001:123::1

Mar 1 06:39:19.182: ICMPv6-ND: REACH -> STALE: FE80::1



R1#debug ipv6 nd

Mar 1 06:38:39.130: ICMPv6-ND: STALE -> DELAY: 2001:123::3

Mar 1 06:38:44.130: ICMPv6-ND: DELAY -> PROBE: 2001:123::3

Mar 1 06:38:44.130: ICMPv6-ND: Sending NS for 2001:123::3 on FastEthernet0/0

Mar 1 06:38:44.166: ICMPv6-ND: Received NA for 2001:123::3 on FastEthernet0/0 from 2001:123::3

Mar 1 06:38:44.166: ICMPv6-ND: PROBE -> REACH: 2001:123::3

Mar 1 06:38:49.166: ICMPv6-ND: Received NS for FE80::1 on FastEthernet0/0 from FE80::3

Mar 1 06:38:49.166: ICMPv6-ND: Sending NA for FE80::1 on FastEthernet0/0

Mar 1 06:38:49.166: ICMPv6-ND: STALE -> DELAY: FE80::3

Mar 1 06:38:54.166: ICMPv6-ND: DELAY -> PROBE: FE80::3

Mar 1 06:38:54.166: ICMPv6-ND: Sending NS for FE80::3 on FastEthernet0/0

Mar 1 06:38:54.198: ICMPv6-ND: Received NA for FE80::3 on FastEthernet0/0 from FE80::3

Mar 1 06:38:54.198: ICMPv6-ND: PROBE -> REACH: FE80::3

Mar 1 06:39:14.166: ICMPv6-ND: REACH -> STALE: 2001:123::3

Mar 1 06:39:24.198: ICMPv6-ND: REACH -> STALE: FE80::3



This time, R3 does not have to send an NS before it can send the echo request because it already has a STALE entry for R1’s global address. The most interesting difference, however, is in the 2nd and 3rd debug messages shown on R3:

R3:

Mar 1 06:38:39.234: ICMPv6-ND: ULP indication 2001:123::1

Mar 1 06:38:39.234: ICMPv6-ND: DELAY -> REACH: 2001:123::1



When R3 receives an echo reply from R1, it considers this to be confirmation of reachability (shown as ‘ULP indication’) and immediately changes the entry to the REACH state. For whatever reason, an echo reply to an echo request from a global unicast address counts as upper-layer protocol confirmation, but an echo reply to an echo request from a link-local address does not (as we saw earlier). In total 3 NS and 3 solicited NA are sent between the 2 devices:

Next let’s look at an example of redirects being used as part of NDP in IPv6. R3 is still using R2 as it’s default router, so we will create a loopback on R1 and advertise it to R2 with OSPFv3:

R1:

ipv6 router ospf 1

router-id 1.1.1.1

!

interface Loopback0

ipv6 address 2001:1::1/64

ipv6 ospf network point-to-point

ipv6 ospf 1 area 0

!

interface FastEthernet0/0

ipv6 ospf 1 area 0



R2:

ipv6 router ospf 1

router-id 2.2.2.2

!

interface FastEthernet0/0

ipv6 ospf 1 area 0



R2 now has a route to R1’s loopback using R1’s link-local as the next hop:

On R3, we attempt to ping R1’s loopback:

R3 sends the packet to it’s default router, R2. R2 sends the packet to R1 and also sends a redirect back to R3 telling it to use R1 in the future for that address:

R2#debug ipv6 icmp

Mar 1 07:00:27.290: ICMPv6: Sending REDIRECT for 2001:1::1, target FE80::1 on FastEthernet0/0



Several NS and solicited NA are also sent between the 3 devices to confirm reachability:

According to RFC 2461 on IPv6 Neighbor Discovery:

A host receiving a valid redirect SHOULD update its Destination Cache accordingly so that subsequent traffic goes to the specified target. If no Destination Cache entry exists for the destination, an implementation SHOULD create such an entry.

However, a Cisco router acting as a host apparently does not follow this recommendation, as R3 continues trying to send all traffic for R1’s loopback to R2 and R2 continues sending redirects.