IPv6 Neighbor Discovery Protocol (NDP): How Devices Find Each Other
Deep dive into NDP, the protocol that replaces ARP in IPv6. Learn about Router Solicitation, Neighbor Solicitation, and how address resolution works.
NDP Replaces More Than Just ARP#
In IPv4, address resolution uses ARP—a separate layer 2 protocol. Router discovery uses ICMP Router Discovery or DHCP. Redirect messages use ICMP. Duplicate address detection doesn't exist at all.
IPv6 consolidates all these functions into Neighbor Discovery Protocol. NDP handles:
- Address resolution (ARP's job)
- Router discovery (finding default gateways)
- Prefix discovery (learning network prefixes for autoconfiguration)
- Parameter discovery (MTU, hop limit)
- Address autoconfiguration (SLAAC)
- Duplicate Address Detection (preventing conflicts)
- Neighbor reachability (is my neighbor still there?)
- Next-hop determination (which router should I use?)
- Redirect messages (better routes exist)
NDP runs entirely over ICMPv6, using five message types (133-137). It's not optional. Block NDP and IPv6 stops working.
TL;DR - Quick Summary
Key Points:
- NDP consolidates ARP, router discovery, and autoconfiguration into one protocol running over ICMPv6
- Five message types (133-137) handle everything from address resolution to router advertisements
- Security: All NDP messages require Hop Limit 255 to prevent off-link attacks
Skip to: Router Advertisement for SLAAC details, Address Resolution in Action for practical examples, or Troubleshooting for common problems.
The Five NDP Message Types#
All NDP messages are ICMPv6 packets with specific type numbers. Understanding these five messages means understanding how IPv6 networks operate at the fundamental level.
| Type | Name | Sent By | Purpose | Destination |
|---|---|---|---|---|
| 133 | Router Solicitation (RS) | Hosts | Request router information | ff02::2 (all-routers) |
| 134 | Router Advertisement (RA) | Routers | Announce presence and config | ff02::1 (all-nodes) or unicast |
| 135 | Neighbor Solicitation (NS) | Any node | Address resolution, reachability | Solicited-node multicast or unicast |
| 136 | Neighbor Advertisement (NA) | Any node | Response to NS | Unicast or ff02::1 |
| 137 | Redirect | Routers | Better next-hop exists | Unicast (original sender) |
Every NDP message has a common security requirement: Hop Limit must be 255. This prevents off-link attacks because routers decrement hop limit. Packets from remote attackers arrive with hop limit < 255 and get dropped.
Router Solicitation (Type 133)#
Hosts send Router Solicitations when they want routers to announce themselves immediately instead of waiting for the next scheduled Router Advertisement.
ICMPv6 structure:
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Type | Code | Checksum |
| (133) | (0) | |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Reserved |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Options ...
+-+-+-+-+-+-+-+-+-+-+-+-Fields:
- Type: 133
- Code: 0
- Reserved: 32 bits, must be zero
- Options: Source Link-Layer Address (optional, include if source address is not ::)
When sent:
- Interface comes up
- Host boots
- IPv6 stack initializes
- Host needs configuration quickly
Source address:
- Link-local address (if configured)
- :: (unspecified, if no address yet)
Destination: ff02::2 (all-routers multicast address)
Hop Limit: 255 (required)
Example packet:
IPv6 Header:
Source: fe80::a4b2:c3d4:e5f6:7890
Destination: ff02::2
Next Header: 58 (ICMPv6)
Hop Limit: 255
ICMPv6:
Type: 133 (Router Solicitation)
Code: 0
Options:
Source Link-Layer Address: 00:1a:2b:3c:4d:5eThis packet requests router information on the local link. The source link-layer address option allows routers to update their neighbor cache immediately.
Rate limiting:
Hosts must not send Router Solicitations too frequently. RFC 4861 recommends maximum one per 3 seconds. This prevents flooding routers during network instability.
Why it matters:
Without RS, hosts would wait for periodic Router Advertisements (sent every few minutes). RS allows hosts to get configuration in seconds instead of minutes, speeding up network initialization.
Router Advertisement (Type 134)#
Routers send Router Advertisements to announce their presence, advertise network prefixes, and provide configuration parameters. This is the foundation of Stateless Address Autoconfiguration (SLAAC).
ICMPv6 structure:
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Type | Code | Checksum |
| (134) | (0) | |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Cur Hop Limit |M|O|H|Prf|Resvd| Router Lifetime |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Reachable Time |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Retrans Timer |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Options ...
+-+-+-+-+-+-+-+-+-+-+-+-Fields:
Cur Hop Limit (8 bits): Recommended value for Hop Limit field in outgoing packets. Typically 64. Hosts copy this into their IPv6 header Hop Limit field.
Flags (8 bits):
- M (Managed Address Configuration): Use DHCPv6 for addresses
- O (Other Configuration): Use DHCPv6 for other configuration (DNS, NTP, etc.)
- H (Home Agent): Router is a mobile IPv6 home agent (rarely used)
- Prf (Router Preference): 2-bit preference (00=medium, 01=high, 11=low)
- Reserved: 3 bits
Router Lifetime (16 bits): How long (in seconds) to use this router as default gateway. 0 means "not a default router". Max 9000 seconds (2.5 hours).
Reachable Time (32 bits): How long (in milliseconds) to consider a neighbor reachable after receiving a reachability confirmation. 0 means unspecified (use default or previously received value).
Retrans Timer (32 bits): Time between retransmitting Neighbor Solicitations (in milliseconds). Used for address resolution and Neighbor Unreachability Detection.
Common options:
Source Link-Layer Address (Type 1): Router's MAC address. Allows hosts to skip Neighbor Solicitation for the router.
MTU (Type 5): Recommended MTU for the link. Typically 1500.
Prefix Information (Type 3): Network prefixes for address autoconfiguration. This is the critical option for SLAAC.
RDNSS (Type 25): Recursive DNS Server addresses. RFC 8106.
DNSSL (Type 31): DNS Search List. RFC 8106.
When sent:
- Periodically (every 200-600 seconds, typically 200)
- In response to Router Solicitation
- When router configuration changes
Source: Router's link-local address (fe80::/10)
Destination:
- ff02::1 (all-nodes multicast) for periodic announcements
- Unicast to soliciting host when responding to RS
Hop Limit: 255 (required)
Example packet:
IPv6 Header:
Source: fe80::1
Destination: ff02::1
Next Header: 58 (ICMPv6)
Hop Limit: 255
ICMPv6:
Type: 134 (Router Advertisement)
Code: 0
Cur Hop Limit: 64
Flags: M=0, O=0 (SLAAC only)
Router Lifetime: 1800 seconds (30 minutes)
Reachable Time: 30000 ms
Retrans Timer: 1000 ms
Options:
Source Link-Layer Address: 00:11:22:33:44:55
MTU: 1500
Prefix Information:
Prefix: 2001:db8:1234:5678::/64
Valid Lifetime: 86400 (24 hours)
Preferred Lifetime: 14400 (4 hours)
Flags: L=1 (on-link), A=1 (autonomous/SLAAC)
RDNSS:
Lifetime: 3600
Addresses: 2001:4860:4860::8888, 2001:4860:4860::8844Flag combinations:
| M | O | Behavior |
|---|---|---|
| 0 | 0 | SLAAC only, no DHCPv6 (most common) |
| 0 | 1 | SLAAC for addresses, DHCPv6 for DNS/NTP/etc. |
| 1 | 0 | DHCPv6 for addresses (unusual, rarely used) |
| 1 | 1 | DHCPv6 for everything (enterprise networks) |
Prefix Information Option:
This option is what makes SLAAC possible. It tells hosts what network prefix to use when autoconfiguring addresses.
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Type | Length | Prefix Length |L|A|R|Reserved1|
| (3) | (4) | | | | | |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Valid Lifetime |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Preferred Lifetime |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Reserved2 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| |
+ +
| |
+ Prefix +
| |
+ +
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+Fields:
- Prefix Length: Usually 64 for SLAAC
- L flag: On-link (prefix is on local link)
- A flag: Autonomous (use for SLAAC)
- R flag: Router Address (prefix contains router's interface ID)
- Valid Lifetime: How long addresses are valid (typically 86400 = 24 hours)
- Preferred Lifetime: How long to use addresses for new connections (typically 14400 = 4 hours)
- Prefix: The actual network prefix (e.g., 2001:db8:1234:5678::)
When A=1, hosts generate addresses by combining the prefix with an interface identifier:
Prefix from RA: 2001:db8:1234:5678::/64
Interface ID: a4b2:c3d4:e5f6:7890 (derived from MAC or random)
Resulting address: 2001:db8:1234:5678:a4b2:c3d4:e5f6:7890Router Advertisements Are Critical
Block ICMPv6 type 134 and SLAAC stops working. Hosts will have link-local addresses only (fe80::/10) with no global connectivity. This is one of the most common IPv6 misconfigurations—firewalls that block all ICMPv6 without understanding which types are essential.
Neighbor Solicitation (Type 135)#
Neighbor Solicitation is IPv6's replacement for ARP. It resolves IPv6 addresses to link-layer (MAC) addresses and verifies that neighbors are still reachable.
ICMPv6 structure:
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Type | Code | Checksum |
| (135) | (0) | |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Reserved |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| |
+ +
| |
+ Target Address +
| |
+ +
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Options ...
+-+-+-+-+-+-+-+-+-+-+-+-Fields:
- Type: 135
- Code: 0
- Reserved: 32 bits, must be zero
- Target Address: IPv6 address being queried
- Options: Source Link-Layer Address (included unless source is ::)
Three use cases:
1. Address Resolution (ARP Replacement)#
Host A needs to send a packet to host B on the same link but doesn't know B's MAC address.
Process:
- A checks its neighbor cache—no entry for B
- A sends NS to B's solicited-node multicast address
- B receives NS and responds with NA containing its MAC
- A caches the mapping and sends the original packet
Example:
# Host A wants to send to 2001:db8::10
IPv6 Header:
Source: 2001:db8::1
Destination: ff02::1:ff00:10 (solicited-node multicast)
Hop Limit: 255
ICMPv6:
Type: 135 (Neighbor Solicitation)
Target Address: 2001:db8::10
Options:
Source Link-Layer Address: 00:1a:2b:3c:4d:5eThis NS is sent to the solicited-node multicast address, not broadcast, reducing unnecessary traffic.
Solicited-node multicast address calculation:
IPv6 uses solicited-node multicast instead of broadcast for efficiency. Only hosts with similar addresses listen to each solicited-node group.
Formula: ff02::1:ff + last 24 bits of target address
Examples:
2001:db8::10 -> ff02::1:ff00:10
2001:db8::a4b2:c3d4:e5f6:7890 -> ff02::1:ff:f6:7890
fe80::1 -> ff02::1:ff00:1This reduces unnecessary processing. In IPv4, ARP broadcasts reach every host on the network. In IPv6, only hosts whose addresses end with the same 24 bits join the multicast group and receive the NS.
2. Neighbor Unreachability Detection (NUD)#
Verify that a previously reachable neighbor is still reachable.
Process:
- Host hasn't received traffic from neighbor recently
- Host sends NS (unicast) to neighbor
- If NA received, neighbor is reachable
- If no response after retries, neighbor is considered unreachable
Example:
IPv6 Header:
Source: 2001:db8::1
Destination: 2001:db8::10 (unicast to neighbor)
Hop Limit: 255
ICMPv6:
Type: 135 (Neighbor Solicitation)
Target Address: 2001:db8::10
Options:
Source Link-Layer Address: 00:1a:2b:3c:4d:5eNUD runs automatically in the background. When hosts send traffic, they track whether neighbors respond. If a neighbor goes silent, NUD verifies reachability before declaring it dead.
3. Duplicate Address Detection (DAD)#
Before using an IPv6 address, hosts perform DAD to ensure no other node is using it. This prevents address conflicts in SLAAC.
Process:
- Host generates tentative address (via SLAAC, DHCPv6, or manual config)
- Host sends NS with source :: and target = tentative address
- If someone responds with NA, address is already in use (conflict)
- If no response after timeout, address is unique and can be used
Example:
# Host wants to use 2001:db8::a4b2:c3d4:e5f6:7890
# Sends DAD NS first
IPv6 Header:
Source: :: (unspecified address—host has no address yet)
Destination: ff02::1:ff:f6:7890 (solicited-node multicast)
Hop Limit: 255
ICMPv6:
Type: 135 (Neighbor Solicitation)
Target Address: 2001:db8::a4b2:c3d4:e5f6:7890
Options: (none—source is ::)If another host is using that address, it sends a Neighbor Advertisement. The requesting host detects the conflict and must choose a different address.
DAD timeout: Typically 1 second. Host waits this long for a response. If silent, the address is assumed unique.
Security issue: DAD has no authentication. An attacker can respond to every DAD request, preventing hosts from configuring addresses. This is called a DAD DoS attack. Solutions include SEND (Secure Neighbor Discovery) or RA Guard, but adoption is limited.
Neighbor Advertisement (Type 136)#
Sent in response to Neighbor Solicitation or unsolicited to announce address/link-layer changes.
ICMPv6 structure:
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Type | Code | Checksum |
| (136) | (0) | |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|R|S|O| Reserved |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| |
+ +
| |
+ Target Address +
| |
+ +
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Options ...
+-+-+-+-+-+-+-+-+-+-+-+-Fields:
Flags:
- R (Router): Sender is a router
- S (Solicited): Advertisement is a response to NS
- O (Override): Override existing cache entry
Target Address: Address for which this advertisement is sent
Options: Target Link-Layer Address (MAC address)
When sent:
- Response to Neighbor Solicitation (S=1)
- Unsolicited announcement of address change (S=0)
- Gratuitous NA to update neighbors after link-layer address change
Destination:
- Unicast to soliciting node (when responding to NS)
- ff02::1 (all-nodes) for unsolicited announcements
Hop Limit: 255 (required)
Example response to NS:
IPv6 Header:
Source: 2001:db8::10
Destination: 2001:db8::1 (unicast to requester)
Hop Limit: 255
ICMPv6:
Type: 136 (Neighbor Advertisement)
Flags: R=0, S=1 (solicited response), O=1 (override)
Target Address: 2001:db8::10
Options:
Target Link-Layer Address: 00:aa:bb:cc:dd:eeThis NA informs the requester of the MAC address, allowing communication to proceed.
Flag meanings:
S=1: This is a response to your NS. Update your cache.
S=0: Unsolicited announcement. I changed something.
O=1: Override your existing cache entry with this info.
O=0: Only update cache if no entry exists.
Unsolicited NA example:
Host changes its MAC address (rare, but happens with virtual machines or interface reconfiguration). It sends unsolicited NA to update neighbors:
IPv6 Header:
Source: 2001:db8::10
Destination: ff02::1 (all-nodes)
Hop Limit: 255
ICMPv6:
Type: 136 (Neighbor Advertisement)
Flags: R=0, S=0 (unsolicited), O=1 (override)
Target Address: 2001:db8::10
Options:
Target Link-Layer Address: 00:ff:ee:dd:cc:bb (new MAC)All neighbors receive this and update their caches.
Redirect (Type 137)#
Routers send Redirect messages to inform hosts that a better first-hop router exists for a specific destination.
ICMPv6 structure:
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Type | Code | Checksum |
| (137) | (0) | |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Reserved |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| |
+ +
| |
+ Target Address +
| |
+ +
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| |
+ +
| |
+ Destination Address +
| |
+ +
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Options ...
+-+-+-+-+-+-+-+-+-+-+-+-Fields:
- Type: 137
- Code: 0
- Target Address: Better next-hop router (or destination if on-link)
- Destination Address: Destination that should use the better route
- Options: Target Link-Layer Address, Redirected Header (portion of original packet)
When sent:
Router R1 receives a packet from Host A destined for Host B. R1 knows Router R2 (on the same link as A) is a better next-hop for B. R1 forwards the packet to R2 AND sends a Redirect to A telling it to use R2 directly in the future.
Example scenario:
Network topology:
Host A: 2001:db8:1::10
Router R1: 2001:db8:1::1 (default gateway for A)
Router R2: 2001:db8:1::2 (better route to 2001:db8:2::/64)
Destination B: 2001:db8:2::20
Flow:
1. A sends packet to B via R1 (default gateway)
2. R1 sees that R2 is a better next-hop for 2001:db8:2::/64
3. R1 forwards packet to R2
4. R1 sends Redirect to A:
Target Address: 2001:db8:1::2 (R2)
Destination Address: 2001:db8:2::20 (B)
5. A updates routing table: use R2 for 2001:db8:2::/64
6. A's future packets to B go directly to R2Redirect message from R1 to A:
IPv6 Header:
Source: fe80::1 (R1's link-local)
Destination: 2001:db8:1::10 (Host A)
Hop Limit: 255
ICMPv6:
Type: 137 (Redirect)
Target Address: fe80::2 (R2—better next-hop)
Destination Address: 2001:db8:2::20 (B—destination to reach via R2)
Options:
Target Link-Layer Address: 00:11:22:33:44:55 (R2's MAC)
Redirected Header: (original packet header that triggered redirect)Security considerations:
Redirect messages can be abused. An attacker on the local link could send malicious Redirects to:
- Route traffic through attacker's machine (man-in-the-middle)
- Blackhole traffic by redirecting to nonexistent router
- Create routing loops
Protections:
- SEND (Secure Neighbor Discovery) authenticates Redirect messages
- Many hosts ignore Redirects from non-default-gateway routers
- Some security-conscious networks disable Redirect processing entirely
- Redirects must come from current first-hop router (checked by hosts)
Should you allow Redirects?
Home/small networks: Safe. Optimizes routing when multiple routers exist.
Enterprise networks: Often disabled. Controlled routing tables and potential security risks outweigh benefits.
Data centers: Usually disabled. Static routing or dynamic protocols (BGP, OSPF) manage routes.
Address Resolution in Action#
Let's trace the complete process of Host A sending a packet to Host B on the same link.
Initial state:
- Host A: 2001:db8::1 (MAC: aa:aa:aa:aa:aa:aa)
- Host B: 2001:db8::10 (MAC: bb:bb:bb:bb:bb:bb)
- A's neighbor cache is empty
Step 1: Application initiates connection
# On Host A
ping6 2001:db8::10Step 2: Check neighbor cache
# A checks neighbor cache
ip -6 neigh show 2001:db8::10
# (empty—no entry)Step 3: Send Neighbor Solicitation
A sends NS to solicited-node multicast address:
IPv6 Header:
Source: 2001:db8::1
Destination: ff02::1:ff00:10 (solicited-node for 2001:db8::10)
Hop Limit: 255
Ethernet Header:
Source MAC: aa:aa:aa:aa:aa:aa
Dest MAC: 33:33:ff:00:00:10 (multicast MAC for ff02::1:ff00:10)
ICMPv6:
Type: 135 (Neighbor Solicitation)
Target Address: 2001:db8::10
Options:
Source Link-Layer Address: aa:aa:aa:aa:aa:aaStep 4: B receives NS
Host B is listening to ff02::1:ff00:10 (because its address ends with :10). It receives the NS and processes it.
Step 5: B sends Neighbor Advertisement
IPv6 Header:
Source: 2001:db8::10
Destination: 2001:db8::1 (unicast to A)
Hop Limit: 255
Ethernet Header:
Source MAC: bb:bb:bb:bb:bb:bb
Dest MAC: aa:aa:aa:aa:aa:aa
ICMPv6:
Type: 136 (Neighbor Advertisement)
Flags: R=0, S=1 (solicited), O=1 (override)
Target Address: 2001:db8::10
Options:
Target Link-Layer Address: bb:bb:bb:bb:bb:bbStep 6: A updates neighbor cache
# A's neighbor cache now has entry
ip -6 neigh show 2001:db8::10
# 2001:db8::10 dev eth0 lladdr bb:bb:bb:bb:bb:bb REACHABLEStep 7: A sends original packet
Now that A knows B's MAC, it sends the ping packet:
IPv6 Header:
Source: 2001:db8::1
Destination: 2001:db8::10
Ethernet Header:
Source MAC: aa:aa:aa:aa:aa:aa
Dest MAC: bb:bb:bb:bb:bb:bb (learned from NA)
ICMPv6:
Type: 128 (Echo Request)Total time: Milliseconds. The process is invisible to applications.
Neighbor Cache States#
Neighbor cache entries go through several states as NUD tracks reachability.
| State | Meaning | Next Action |
|---|---|---|
| INCOMPLETE | NS sent, waiting for NA | Timeout or receive NA |
| REACHABLE | NA received recently, confirmed reachable | Send traffic or timeout |
| STALE | Entry old, not confirmed recently | Send traffic (triggers probe) |
| DELAY | Traffic sent to stale entry, waiting | Timeout triggers probe |
| PROBE | Sending NS to verify reachability | Receive NA or timeout |
| FAILED | No response to probes | Remove entry |
State transitions:
INCOMPLETE --NA received--> REACHABLE
REACHABLE --timeout--> STALE
STALE --traffic sent--> DELAY
DELAY --timeout--> PROBE
PROBE --NA received--> REACHABLE
PROBE --timeout--> FAILEDCheck neighbor cache (Linux):
ip -6 neigh show
# Example output:
# 2001:db8::1 dev eth0 lladdr aa:aa:aa:aa:aa:aa REACHABLE
# 2001:db8::10 dev eth0 lladdr bb:bb:bb:bb:bb:bb STALE
# fe80::1 dev eth0 lladdr cc:cc:cc:cc:cc:cc DELAYTimers:
- REACHABLE timeout: 30 seconds (configurable, from RA Reachable Time)
- DELAY timeout: 5 seconds before transitioning to PROBE
- Retransmit interval: 1 second (configurable, from RA Retrans Timer)
- MAX_MULTICAST_SOLICIT: 3 attempts before declaring FAILED
These ensure that dead neighbors are detected quickly while minimizing unnecessary NUD traffic.
SLAAC: Address Autoconfiguration#
Combining Router Advertisements with Duplicate Address Detection creates Stateless Address Autoconfiguration. Hosts configure themselves without DHCP servers.
Complete SLAAC process:
Step 1: Interface comes up
Host enables IPv6 on interface eth0.
Step 2: Generate link-local address
fe80:: + interface identifier
fe80::a4b2:c3d4:e5f6:7890 (if using MAC-derived IID)
fe80::1234:5678:9abc:def0 (if using random IID)Step 3: Perform DAD on link-local
Send NS with source :: to verify fe80:: address is unique.
Step 4: Send Router Solicitation
IPv6 Header:
Source: fe80::a4b2:c3d4:e5f6:7890
Destination: ff02::2
Hop Limit: 255
ICMPv6:
Type: 133 (Router Solicitation)This requests immediate router configuration information.
Step 5: Receive Router Advertisement
ICMPv6:
Type: 134 (Router Advertisement)
Flags: M=0, O=0 (SLAAC)
Prefix Information:
Prefix: 2001:db8:1234:5678::/64
Flags: A=1 (autonomous)
Valid Lifetime: 86400
Preferred Lifetime: 14400Step 6: Generate global address
Prefix: 2001:db8:1234:5678::/64
IID: a4b2:c3d4:e5f6:7890
Result: 2001:db8:1234:5678:a4b2:c3d4:e5f6:7890Step 7: Perform DAD on global address
Send NS to verify 2001:db8:1234:5678:a4b2:c3d4:e5f6:7890 is unique.
Step 8: Configure address
ip -6 addr show eth0
# Output:
# inet6 2001:db8:1234:5678:a4b2:c3d4:e5f6:7890/64 scope global dynamic
# inet6 fe80::a4b2:c3d4:e5f6:7890/64 scope linkStep 9: Set default route
Use router's link-local address as default gateway:
ip -6 route show
# Output:
# default via fe80::1 dev eth0 metric 1024
# 2001:db8:1234:5678::/64 dev eth0 proto kernel metric 256Total time: A few seconds.
Privacy Extensions (RFC 4941):
MAC-derived interface IDs are trackable across networks. Privacy Extensions generate random IIDs that change periodically.
Original: 2001:db8:1234:5678:a4b2:c3d4:e5f6:7890 (static)
Privacy: 2001:db8:1234:5678:1a2b:3c4d:5e6f:7a8b (changes daily)Most modern OSes enable privacy extensions by default for outgoing connections while keeping the stable address for incoming connections.
Security Considerations#
NDP has vulnerabilities because it was designed assuming trusted local networks. Attackers on the same link can:
Rogue Router Advertisements#
Attacker sends fake RAs with:
- Wrong prefix (blackhole traffic or route through attacker)
- Short lifetimes (force frequent RA processing)
- M=1 flag (force DHCPv6 to attacker's server)
Impact: Complete control over host configuration.
Mitigation:
- RA Guard: Switch feature that blocks RAs from non-router ports
- SEND (Secure Neighbor Discovery): Cryptographic authentication (complex, rarely deployed)
- Router preference: Use high-preference values on legitimate routers
Neighbor Advertisement Spoofing#
Attacker sends fake NAs claiming to be another host.
Impact: Man-in-the-middle attacks, traffic interception.
Mitigation:
- SEND: Authenticates NAs
- Port security: Switches enforce MAC address bindings
- Monitoring: Detect duplicate MAC addresses
DAD DoS#
Attacker responds to every DAD request, preventing address configuration.
Impact: Hosts can't get addresses, no connectivity.
Mitigation:
- SEND: Authenticates DAD messages
- Rate limiting: Limit NAs from single source
- Static addresses: Bypass SLAAC entirely (not scalable)
Redirect Attacks#
Attacker sends fake Redirects routing traffic through attacker.
Impact: Man-in-the-middle, traffic interception.
Mitigation:
- Disable Redirects: Many OSes allow disabling Redirect processing
- SEND: Authenticates Redirects
- Verify source: Hosts should verify Redirects come from current first-hop router
Reality: Most networks don't use SEND due to complexity. RA Guard on switches is the practical defense for enterprise networks.
Troubleshooting NDP Issues#
Host has no global address#
Symptoms:
- Only fe80:: addresses
- Can ping link-local, not global
- No default route
Diagnosis:
# Check for Router Advertisements
sudo tcpdump -i eth0 -vv 'icmp6 && ip6[40] == 134'This captures RA messages. If none appear, routers aren't advertising.
# Check RA acceptance
sysctl net.ipv6.conf.eth0.accept_ra
# Should be 1 or 2 for hosts# Manually send RS
rdisc6 eth0This requests an immediate RA from routers.
Common causes:
- No router on link
- Firewall blocking type 134
- accept_ra disabled
- IPv6 forwarding enabled (disables RA processing)
Fix: Enable router, allow ICMPv6 type 134, set accept_ra=1.
Neighbor cache always FAILED#
Symptoms:
- Can't reach neighbors
- NS sent but no NA received
- Neighbor cache shows FAILED
Diagnosis:
# Watch NS/NA exchange
sudo tcpdump -i eth0 -vv 'icmp6 && (ip6[40] == 135 || ip6[40] == 136)'This shows neighbor solicitation and advertisement messages.
# Check neighbor cache
ip -6 neigh show# Manual NS (Linux ndisc6 tool)
ndisc6 2001:db8::10 eth0This manually performs address resolution.
Common causes:
- Firewall blocking types 135/136
- Target host IPv6 disabled
- Switch filtering multicast
- Wrong link (target on different subnet)
Fix: Allow NDP through firewalls, verify IPv6 enabled on target.
DAD failures#
Symptoms:
- Address shows "dadfailed"
- Interface can't configure address
- Kernel logs show DAD conflicts
Diagnosis:
# Check address status
ip -6 addr show eth0
# Example output with DAD failure:
# inet6 2001:db8::10/64 scope global tentative dadfailed# Check for duplicate
ping6 -c 1 2001:db8::10If someone responds, the address is already in use.
Common causes:
- Another host using the same address
- Attacker spoofing NA (DAD DoS)
- Virtual machines with cloned MAC addresses
Fix: Change address, investigate duplicate hosts, check VM configuration.
Practical Examples with Tools#
Monitoring NDP with tcpdump#
# All NDP traffic
sudo tcpdump -i eth0 -vv 'icmp6 && ip6[40] >= 133 && ip6[40] <= 137'This captures all five NDP message types.
# Router Advertisements only
sudo tcpdump -i eth0 -vv 'icmp6 && ip6[40] == 134'# Address resolution (NS/NA)
sudo tcpdump -i eth0 -vv 'icmp6 && (ip6[40] == 135 || ip6[40] == 136)'# Filter by target address
sudo tcpdump -i eth0 -vv 'icmp6 && ip6[40] == 135' | grep '2001:db8::10'Manual neighbor cache management#
# Show all neighbors
ip -6 neigh show# Show specific neighbor
ip -6 neigh show 2001:db8::10# Delete entry (force re-resolution)
sudo ip -6 neigh del 2001:db8::10 dev eth0# Add static entry
sudo ip -6 neigh add 2001:db8::10 lladdr aa:bb:cc:dd:ee:ff dev eth0Testing SLAAC#
# Flush addresses
sudo ip -6 addr flush dev eth0This removes all IPv6 addresses from the interface.
# Re-enable IPv6
sudo sysctl -w net.ipv6.conf.eth0.disable_ipv6=0# Watch autoconfiguration
ip -6 addr show eth0
ip -6 route showWatch as the interface generates link-local, sends RS, receives RA, and configures global addresses.
Related Articles#
- ICMPv6 Explained - NDP runs over ICMPv6. Understand the underlying protocol.
- IPv6 Address Types - Learn about link-local, solicited-node multicast, and other address types used by NDP.
- IPv6 Security - Secure NDP against attacks while allowing essential functionality.
Test NDP in Action
Use our Ping tool to trigger address resolution and Traceroute to see how hosts discover next-hop routers.
Frequently Asked Questions#
Why does NDP use multicast instead of broadcast like ARP?
Multicast is more efficient. ARP broadcasts hit every host on the network—all must process the frame even if they're not the target. NDP uses solicited-node multicast addresses computed from the target's IPv6 address. Only hosts with matching addresses join that multicast group and receive the packet. Hosts filter non-matching multicasts in hardware (NIC), reducing CPU load. On large networks with thousands of hosts, this makes a significant performance difference.
Can I disable NDP like I can disable ARP?
No. NDP is mandatory for IPv6 operation. It handles address resolution, router discovery, and autoconfiguration. Disable NDP and IPv6 stops working entirely. Unlike IPv4 where you can use static ARP entries, IPv6 requires NDP for Router Advertisements (which provide default gateways and prefixes). Even with static neighbors, you'd have no way to learn routers or autoconfigure addresses.
How does Duplicate Address Detection prevent conflicts?
Before using any address, hosts send a Neighbor Solicitation with source address :: (unspecified) and target set to the address they want to use. If another host is already using that address, it responds with a Neighbor Advertisement. The requesting host sees the response, detects the conflict, and must choose a different address. If no response arrives within ~1 second, the address is assumed unique. DAD runs for both link-local and global addresses.
What are solicited-node multicast addresses?
Solicited-node multicast addresses are derived from the last 24 bits of an IPv6 address using the formula ff02::1:ff:XX:XXXX. Every IPv6 address automatically joins its corresponding solicited-node multicast group. When performing address resolution, the sender sends NS to the solicited-node address instead of broadcast. Only hosts with addresses ending in the same 24 bits receive it. This reduces unnecessary processing compared to broadcast-based ARP.
Why must NDP packets have Hop Limit 255?
Security. Legitimate NDP always originates on the local link and sets Hop Limit to 255. Routers decrement Hop Limit when forwarding, so packets from remote attackers arrive with Hop Limit < 255. By rejecting NDP packets with Hop Limit != 255, hosts protect against off-link attackers sending spoofed Router Advertisements, Neighbor Advertisements, or Redirects. This simple check prevents many remote attacks without requiring complex authentication.
Should I deploy SEND (Secure Neighbor Discovery)?
Probably not. SEND provides cryptographic authentication for NDP using public-key cryptography, preventing spoofing attacks. In theory it's great. In practice it's complex, requires PKI infrastructure, has poor OS support, and adds latency to time-sensitive operations like address resolution. Most networks use simpler mitigations: RA Guard on switches (blocks RAs from non-router ports), monitoring for rogue RAs, and physical/link-layer security. SEND is suited for high-security environments willing to invest in the infrastructure and complexity.