IPv6 Neighbor Discovery and Router Advertisements: Config Guide - 夜莺博客

IPv6 Neighbor Discovery and Router Advertisements: Config Guide

In IPv6 there is no ARP, no DHCP requirement and no default gateway field to type in - Neighbor Discovery (ND) does all three jobs at once using ICMPv6. That makes ND the single most important protocol to understand when IPv6 "just does not work": hosts get an address with the wrong prefix lifetime, ignore your router, or keep talking to a stale neighbor entry. This guide covers the five message types, router advertisement flags, duplicate address detection, the neighbor cache, and the verification commands that isolate ND problems quickly.

The five messages

Message Purpose Analogy in IPv4
Router Solicitation (RS) Host asks for configuration immediately at boot None - DHCP DISCOVER, roughly
Router Advertisement (RA) Router announces prefix, flags and lifetimes DHCP offer + default gateway
Neighbor Solicitation (NS) Resolve a link-layer address, or verify reachability ARP request
Neighbor Advertisement (NA) Answer with the link-layer address ARP reply
Redirect Tell the host a better first hop exists ICMP redirect

Router advertisement fields that change host behaviour

An RA is not just a prefix and a default route. The flags and options inside the message decide whether a host forms its own address, asks DHCPv6 for one, uses a different resolver, or picks a smaller MTU. Reading the message field by field is the difference between guessing and knowing.

Field or option Values Effect on the host
Cur Hop Limit 0, or 1-255 Default hop limit for outgoing packets. Zero means the host chooses; 64 is the usual convention and matches IPv4 practice.
M flag (managed) 0 or 1 1 tells hosts to use DHCPv6 for addressing. The host still processes the prefix for on-link determination, but expects a DHCPv6 server to supply its address.
O flag (other) 0 or 1 1 tells hosts to fetch other parameters, typically DNS servers and search domains, from DHCPv6 while still forming the address themselves.
A flag (autonomous) 0 or 1 Inside the prefix option: 1 permits SLAAC on that prefix, 0 advertises it as on-link only, which is how you keep hosts from forming addresses on a prefix you still want to route.
L flag (on-link) 0 or 1 1 marks the prefix as directly reachable, so hosts do not send traffic for it through the default router.
Prefix lifetime preferred, valid Deprecation and expiry timing, covered in detail below. Getting the two backwards breaks working networks.
Router lifetime seconds How long the sender may be used as a default router. Zero means "do not use me as a default gateway", which is useful for a device that should only advertise a prefix.
Reachable time and retrans timer milliseconds Timing knobs for neighbour unreachability detection.
MTU option bytes Advertises the link MTU. On a segment smaller than the 1500-byte default, this option is what stops hosts black-holing large packets.
RDNSS and DNSSL addresses, names Deliver DNS resolvers and search domains without DHCPv6, the usual companion of a SLAAC-only design.

Two practical warnings. Setting the M flag while no DHCPv6 server is actually reachable leaves hosts with no address at all, which is the most common IPv6 outage in a fresh deployment. And if neither RDNSS nor DHCPv6 delivers a resolver, hosts fall back to their own defaults, which is why so many "IPv6 is slow" reports turn out to be a DNS problem - see systemd-resolved and resolvectl troubleshooting and BIND9 zone configuration for the server side.

Router advertisement configuration

# Junos: enable RA on the interface and tune lifetimes
set protocols router-advertisement interface ge-0/0/0.0 prefix 2001:db8:100::/64
set protocols router-advertisement interface ge-0/0/0.0 max-advertisement-interval 30
set protocols router-advertisement interface ge-0/0/0.0 min-advertisement-interval 10
set protocols router-advertisement interface ge-0/0/0.0 current-hop-limit 64
set protocols router-advertisement interface ge-0/0/0.0 managed-configuration
set protocols router-advertisement interface ge-0/0/0.0 other-stateful-configuration
run show ipv6 router-advertisement
run show ipv6 neighbors
run show ipv6 interface ge-0/0/0.0 detail

# Cisco IOS XE
Router(config)# interface GigabitEthernet0/0
Router(config-if)# ipv6 address 2001:db8:100::1/64
Router(config-if)# ipv6 nd ra interval 30
Router(config-if)# ipv6 nd ra lifetime 1800
Router(config-if)# ipv6 nd prefix 2001:db8:100::/64 2592000 604800
Router(config-if)# ipv6 nd managed-config-flag
Router(config-if)# ipv6 nd other-config-flag
Router(config-if)# ipv6 nd ra suppress
Router# show ipv6 interface GigabitEthernet0/0
Router# show ipv6 routers
Router# show ipv6 neighbors

The M flag tells hosts to get addresses from DHCPv6; the O flag tells them to get other parameters (like DNS) from DHCPv6 while still forming their own address via SLAAC. Which combination you choose is your address management policy - see our comparison of SLAAC vs stateful and stateless DHCPv6 before setting them.

Timing rules: how often RAs are sent and how long they live

RA timing is governed by a small set of rules that make the protocol self-healing without being chatty.

  • MaxRtrAdvInterval is the ceiling between unsolicited advertisements. The usable range is roughly 4 to 1800 seconds, with 200 seconds as the common default and 30 seconds typical where fast convergence matters.
  • MinRtrAdvInterval is normally one third of the maximum with a floor of 3 seconds. The router sends at a random point inside the window so that several routers on one link do not synchronise their advertisements.
  • Router lifetime should be at least three times MaxRtrAdvInterval. Advertising every 30 seconds means a lifetime of at least 90 seconds; a lifetime shorter than three intervals makes hosts delete a perfectly healthy default route.
  • Initial advertisements are burst at boot, up to a few within the first seconds, so a host that has just come up does not wait a full interval.

Long intervals save CPU and bandwidth but slow discovery of a new router. On a link where a first-hop redundancy protocol provides the gateway, measure convergence end to end rather than only in the FHRP logs, because it is the host's ARP and ND behaviour that users actually feel. The same timing thinking appears in other protocols: our Cisco HSRP priority, preempt and track guide and the MTU, MSS and PMTUD guide both come down to the same question - how long does a client wait before it decides the network is broken.

Flags, lifetimes and what hosts actually do

ndp -r                       # FreeBSD
ip -6 neigh show             # Linux
sysctl net.ipv6.conf.eth0.accept_ra          # 1 = accept RAs, 2 = accept even with forwarding
sysctl net.ipv6.conf.eth0.accept_ra_defrtr
sysctl net.ipv6.conf.eth0.ra_defrtr_metric

tcpdump -i eth0 -nn 'icmp6 and (ip6[40] == 134 or ip6[40] == 133)'   # RA / RS only
tcpdump -i eth0 -nn 'icmp6 and ip6[40] == 135'                       # NS

Prefix lifetimes matter more than most people expect. The preferred lifetime must be shorter than the valid lifetime, and a host keeps using a deprecated address (existing connections) until the valid lifetime expires. If you shorten the valid lifetime carelessly during a renumbering project, you will break long-lived sessions; if you lengthen it too much, stale addresses linger for weeks.

The host state machine: tentative, preferred, deprecated, invalid

An address a host forms from an RA moves through four states, and most confusing "IPv6 is flaky" reports are a host sitting in a state nobody expected.

State What the host does
Tentative The address is formed but not usable. Duplicate Address Detection is running and new connections must not use it.
Preferred Fully usable for new and existing connections. This is the normal state.
Deprecated Usable for connections that already exist, but not for new ones. This is what happens when the preferred lifetime expires while the valid lifetime has not.
Invalid Removed from the interface, because both lifetimes have expired.

Deprecated is the state that catches people out during renumbering. Shorten a prefix's preferred lifetime first, leave the valid lifetime long, and existing sessions keep working on the old address while new sessions use the new one - exactly what a clean migration looks like. Shorten the valid lifetime as well and you will cut long-lived sessions such as database replication or a backup transfer that is still using the old address.

# Linux: address state and remaining lifetimes
ip -6 addr show dev eth0

# FreeBSD and macOS: prefix, lifetimes and flags
ifconfig -L em0 | grep -i "pltime\|vltime"

# Cisco IOS XE
Router# show ipv6 interface GigabitEthernet0/0 | include lifetime
Router# show ipv6 interface brief

When you change a lifetime, watch the addresses transition rather than assuming they did. A host that stays deprecated longer than planned is usually a second RA on the link refreshing the old prefix.

Duplicate Address Detection and neighbor cache

DAD sends NS messages from the tentative address; if another host replies, the address is marked duplicate and the interface stays unconfigured. On virtualised and clustered hosts this is often caused by MAC address reuse rather than a real conflict:

# Linux
sysctl net.ipv6.conf.eth0.dad_transmits
sysctl net.ipv6.conf.all.use_tempaddr
nmcli con mod eth0 ipv6.dad-timeout 1000
ip -6 addr show dev eth0

# clear a poisoned neighbor entry
ip -6 neigh flush dev eth0
ip -6 neigh replace 2001:db8:100::20 lladdr 00:11:22:33:44:55 dev eth0 nud reachable

The neighbor cache has a limited size and stale entries cause intermittent failure that looks like packet loss. Monitor with ip -6 neigh show nud failed and show ipv6 neighbors, and raise net.ipv6.neigh.default.gc_thresh3 on routers with many neighbors - beyond that threshold the kernel logs "neighbour table overflow" and drops traffic.

Securing ND: RA Guard and neighbour inspection

ND has no built-in authentication. Any device on the link can send an RA and become the default router for every host in the segment, which is precisely what an attacker does in order to intercept traffic. The first line of defence belongs on the access switch, not on the host.

  • RA Guard drops router advertisements that arrive on ports where a router does not belong. Configure it on host-facing access ports, and mark the port that faces your real router as a router port.
  • ND inspection and DHCPv6 Guard extend the same idea to NS and NA messages, blocking address spoofing and rogue DHCPv6 servers.
  • Port ACLs are the blunt fallback: block ICMPv6 types 134 and 137 on host-facing ports on platforms without RA Guard.

Whatever you deploy, never block ICMPv6 types 133 to 137 wholesale. ND, DAD and Path MTU Discovery all depend on those messages, and a firewall rule that drops them breaks IPv6 in ways that look nothing like a firewall problem.

More than one router on the link

IPv6 intentionally supports several default routers and hosts pick among them by reachability, so you do not strictly need a first-hop redundancy protocol: two routers advertising the same prefix give hosts two default routes and automatic failover. What you do need is consistency. Both routers must advertise the same prefix with the same lifetimes, or hosts build a confusing mix of addresses and routes. Where you want a single virtual gateway with a shared address, use the IPv6 mode of your FHRP instead - see ArubaOS-CX VRRP and active-gateway and Cisco HSRP priority, preempt and track. One detail decides whether that works: with VRRPv3 for IPv6 the RA has to be sourced from the virtual link-local address, not the physical one, otherwise the default router the host learned is an address that disappears at failover.

ND in virtualised and containerised environments

Virtual switches and bridges change ND behaviour in ways that surprise people. A Linux host with IPv6 forwarding enabled will not accept RAs unless accept_ra is set to 2, which is why a virtualisation node sometimes has no IPv6 default route even when RAs are clearly visible on the wire. Containers and virtual machines on a bridge each form a link-local address and run DAD, and the neighbour table of a busy hypervisor fills quickly; when it overflows the kernel logs "neighbour table overflow" and silently drops traffic.

# a bridge or router host still needs to accept RAs from an upstream router
sysctl -w net.ipv6.conf.all.forwarding=1
sysctl -w net.ipv6.conf.eth0.accept_ra=2

# neighbour table sizing for a bridge with many virtual interfaces
sysctl net.ipv6.neigh.default.gc_thresh1
sysctl net.ipv6.neigh.default.gc_thresh2
sysctl net.ipv6.neigh.default.gc_thresh3
sysctl -w net.ipv6.neigh.default.gc_thresh3=8192

For the host side of that picture, see Linux network namespaces and veth pairs and systemd-networkd configuration for VLANs, bonds and bridges.

Diagnostics checklist

First confirm the host sees the RA (show ipv6 routers, tcpdump), then confirm a valid address and prefix length (ip -6 addr), then confirm a default route (ip -6 route), then neighbor resolution (ip -6 neigh). If the address exists but traffic fails, the fault is almost always the router's forwarding or a firewall dropping ICMPv6 - never block ICMPv6 133-137, the protocol depends on it. Related: Linux ip neigh and ARP table management, systemd-networkd configuration and inter-VLAN routing.

Common misconfigurations and their symptoms

Symptom Likely configuration cause
Hosts get an address but no default route RA suppressed on the interface, or router lifetime advertised as zero
Hosts have a link-local address only Prefix option missing from the RA, or the A flag cleared while no DHCPv6 server answers
Hosts have no address at all M flag set with no reachable DHCPv6 server, or DAD failing on every candidate address
IPv6 works, name resolution does not No RDNSS option and no DHCPv6 parameter delivery, so hosts have no IPv6-capable resolver
Large transfers stall, small ones work An MTU mismatch on the path and an RA that advertises a link MTU larger than the tunnel or circuit carries
Addresses vanish after a change Valid lifetime shortened below what existing sessions needed
Behaviour changes at random A second router on the link advertising a different prefix or a shorter lifetime

Worked example: a host that will not use IPv6

Work through it in this order and stop when the evidence changes.

  1. Is the RA arriving? Capture on the host with tcpdump -i eth0 -nn 'icmp6 and ip6[40] == 134'. If nothing appears, the fault is upstream of the host.
  2. Does the router think it is advertising? On the router, the interface details show the RA configuration and the flags in use.
  3. Does the host show a global address in the preferred state? ip -6 addr show dev eth0. A tentative address with a duplicate flag means DAD, not a missing RA.
  4. Is there a default route? ip -6 route show default. A route pointing at a link-local address that cannot be resolved means the neighbour never answered.
  5. Does the neighbour resolve? ip -6 neigh show. FAILED or INCOMPLETE entries point at filtering, very often a firewall dropping ICMPv6.

One further check resolves a surprising number of cases: is there a second router on the link advertising a different prefix or a shorter lifetime? Two RAs competing produce hosts whose behaviour appears to change at random. Capturing both solicitations and advertisements with tcpdump -i eth0 -nn 'icmp6 and (ip6[40] == 133 or ip6[40] == 134)' makes the conflict obvious.

Design notes for dual stack

Treat IPv6 as a parallel policy rather than a mirror of IPv4. Address management, DNS delivery and firewall rules all have IPv6-specific answers, and the fastest route to a stable deployment is to decide three things up front: how addresses are assigned (SLAAC, DHCPv6, or both - the comparison linked earlier covers the trade-offs), how DNS reachability is delivered (RDNSS in the RA, or DHCPv6), and how the first hop is made redundant (several RAs, or an FHRP with a virtual link-local address). Decide those before the first interface is configured, and the rest is mechanical. The neighbour table itself is worth a look too: Linux ip neigh and ARP table management covers the IPv4 and IPv6 cache commands side by side, and ISC DHCP server configuration covers the DHCPv6 side if you go stateful.

Generating and inspecting RAs with radvd

On Linux the RA is often the kernel's own feature, but radvd makes the timing rules explicit and is the fastest way to build a lab that reproduces a production advertisement byte for byte.

# /etc/radvd.conf
interface eth0 {
    AdvSendAdvert on;
    MinRtrAdvInterval 10;        # >= 3s, normally MaxRtrAdvInterval / 3
    MaxRtrAdvInterval 30;
    AdvManagedFlag off;          # M flag: off = SLAAC
    AdvOtherConfigFlag on;       # O flag: DNS etc. via DHCPv6
    prefix 2001:db8:100::/64 {
        AdvOnLink on; AdvAutonomous on;
        AdvValidLifetime 2592000; AdvPreferredLifetime 604800;
    };
    RDNSS 2001:db8:100::53 { AdvRDNSSLifetime 600; };
};

sudo radvd --configtest /etc/radvd.conf
sudo systemctl restart radvd
sudo tcpdump -i eth0 -nn -v 'icmp6 and ip6[40] == 134'

radvd is also the cleanest way to prove what the M and O flags do before you set them on a real router: flip AdvManagedFlag on and watch a Linux host stop forming a SLAAC address and start waiting for DHCPv6. Because the file maps one to one onto the lifetimes described above, it is a safe place to rehearse a renumbering before it touches production. See SLAAC versus stateful and stateless DHCPv6 and Linux ip neigh and ARP table management.

原文链接:https://www.juniper.net/documentation/us/en/software/junos/neighbor-discovery/topics/topic-map/ipv6-neighbor-discovery.html