DMVPN Phase 2 on Cisco IOS-XE: Direct Spoke-to-Spoke Tunnels, NHRP, and Troubleshooting

DMVPN Phase 2 on Cisco IOS-XE: Direct Spoke-to-Spoke Tunnels, NHRP, and Troubleshooting

Dynamic Multipoint VPN (DMVPN) is one of the most elegant technologies Cisco has ever shipped. Phase 2 is where it gets really useful: instead of routing all spoke-to-spoke traffic through the hub, spokes build on-demand direct tunnels to each other. The result is lower latency, less hub CPU, and a design that scales naturally as your site count grows. This guide walks through a full Phase 2 deployment on Cisco IOS-XE, including NHRP registration, mGRE tunnel configuration, EIGRP tuning, and the debugs you need when something goes wrong.

DMVPN Phase 1 vs Phase 2 vs Phase 3 — What Actually Changes

Before touching the CLI, understand what separates the phases:

  • Phase 1: Spokes register with the hub. All traffic, including spoke-to-spoke, flows through the hub. Simple, but the hub is a bottleneck.
  • Phase 2: Spokes can still reach each other via the hub initially, but NHRP resolution allows them to discover each other’s public IP and build a direct mGRE tunnel. The hub participates in forwarding only for the initial setup.
  • Phase 3: Adds NHRP redirect and shortcut switching so even the initial packet triggers a shortcut — more scalable for large deployments, but Phase 2 is the sweet spot for most real-world networks.

Phase 2 is the most commonly deployed variant. You will see it on enterprise WAN designs, service provider managed CE environments, and CCIE lab topologies alike.

Lab Topology

Our test environment uses three IOS-XE routers (CSR1000v, 17.x train):

  • HUB1 — Public IP: 203.0.113.1 (simulated internet-facing interface)
  • SPOKE1 — Public IP: 203.0.113.10
  • SPOKE2 — Public IP: 203.0.113.20

Tunnel network: 10.100.0.0/24
Hub tunnel IP: 10.100.0.1
Spoke1 tunnel IP: 10.100.0.10
Spoke2 tunnel IP: 10.100.0.20

LAN subnets behind each site will be advertised via EIGRP so spokes can route to each other.

Step 1: Hub Configuration

The hub is the NHRP server (NHS). It holds the authoritative mapping of tunnel IP → public IP for all registered spokes. Configure the mGRE interface first:

HUB1# configure terminal

interface Tunnel0
 description DMVPN-HUB
 ip address 10.100.0.1 255.255.255.0
 no ip redirects
 ip nhrp authentication DMVPN_KEY
 ip nhrp map multicast dynamic
 ip nhrp network-id 100
 ip nhrp holdtime 300
 ip nhrp server-only
 tunnel source GigabitEthernet1
 tunnel mode gre multipoint
 tunnel key 100
 tunnel protection ipsec profile DMVPN_PROFILE
!

Key points on those options:

  • ip nhrp server-only — the hub will not resolve its own tunnel IP via NHRP (it IS the server). Omitting this on the hub can cause strange resolution loops.
  • ip nhrp map multicast dynamic — allows spokes to register and receive multicast replication automatically. This is what lets EIGRP hellos reach all registered spokes without a static multicast map per spoke.
  • tunnel key 100 — differentiates multiple DMVPN tunnels on the same router. Always set this if you run more than one tunnel interface.
  • no ip redirects — critical for Phase 2. Without this, the hub will suppress ICMP redirects that spokes need to learn direct spoke-to-spoke paths.

IPsec Profile (Recommended)

You can run DMVPN without encryption for lab purposes, but production always uses IPsec. Here is a minimal IKEv2 + AES-256-GCM setup:

! IKEv2 Keyring
crypto ikev2 keyring DMVPN_KEYRING
 peer ANY
  address 0.0.0.0 0.0.0.0
  pre-shared-key local DMVPN_PSK_HUB
  pre-shared-key remote DMVPN_PSK_HUB
!

! IKEv2 Profile
crypto ikev2 profile DMVPN_IKEv2_PROFILE
 match identity remote address 0.0.0.0
 authentication local pre-share
 authentication remote pre-share
 keyring local DMVPN_KEYRING
!

! IPsec Transform Set
crypto ipsec transform-set DMVPN_TS esp-aes 256 esp-sha256-hmac
 mode transport
!

! IPsec Profile
crypto ipsec profile DMVPN_PROFILE
 set transform-set DMVPN_TS
 set ikev2-profile DMVPN_IKEv2_PROFILE
!

Note mode transport — with mGRE the outer GRE header provides encapsulation, so IPsec transport mode is appropriate and avoids double-encapsulation overhead.

Step 2: Spoke Configuration

Spokes are NHRP clients. They register their public IP with the hub on startup and query the hub when they need to reach another spoke directly.

SPOKE1# configure terminal

interface Tunnel0
 description DMVPN-SPOKE
 ip address 10.100.0.10 255.255.255.0
 no ip redirects
 no ip split-horizon eigrp 1
 ip nhrp authentication DMVPN_KEY
 ip nhrp map 10.100.0.1 203.0.113.1
 ip nhrp map multicast 203.0.113.1
 ip nhrp network-id 100
 ip nhrp holdtime 300
 ip nhrp nhs 10.100.0.1
 tunnel source GigabitEthernet1
 tunnel mode gre multipoint
 tunnel key 100
 tunnel protection ipsec profile DMVPN_PROFILE
!

SPOKE2 is identical — change ip address to 10.100.0.20.

The critical lines on spokes:

  • ip nhrp map 10.100.0.1 203.0.113.1 — static mapping of the hub tunnel IP to its public IP. Spokes need this to bootstrap the NHRP registration.
  • ip nhrp map multicast 203.0.113.1 — tells the spoke to send multicast (EIGRP hellos) to the hub’s public IP.
  • ip nhrp nhs 10.100.0.1 — designates the hub as the Next-Hop Server.
  • no ip split-horizon eigrp 1 — IMPORTANT for Phase 2. Without disabling split horizon on spoke tunnel interfaces, EIGRP will not advertise routes learned from one spoke to other spokes through the hub. This is the most common Phase 2 misconfiguration.

Step 3: EIGRP Configuration

EIGRP is the most natural routing protocol for DMVPN Phase 2. For Phase 2 to work correctly, you must disable split horizon on the tunnel interface and set the EIGRP next-hop to preserve spoke addresses:

! On HUB1
router eigrp 1
 no auto-summary
 network 10.100.0.0 0.0.0.255
 network 192.168.1.0 0.0.0.255   ! Hub LAN
!
interface Tunnel0
 no ip split-horizon eigrp 1
 no ip next-hop-self eigrp 1
!

! On SPOKE1
router eigrp 1
 no auto-summary
 network 10.100.0.0 0.0.0.255
 network 192.168.10.0 0.0.0.255  ! Spoke1 LAN
!

! On SPOKE2
router eigrp 1
 no auto-summary
 network 10.100.0.0 0.0.0.255
 network 192.168.20.0 0.0.0.255  ! Spoke2 LAN
!

no ip next-hop-self eigrp 1 on the hub tunnel interface is equally important: it preserves the spoke’s tunnel IP as the next-hop in EIGRP updates sent to other spokes. If the hub rewrites the next-hop to itself, spoke-to-spoke traffic will always flow through the hub — defeating Phase 2 entirely.

Step 4: Verify NHRP Registration

After bringing up all three routers, check the NHRP cache on the hub first:

HUB1# show ip nhrp
10.100.0.10/32 via 10.100.0.10
   Tunnel0 created 00:03:12, expire 00:04:47
   Type: dynamic, Flags: registered used nhop
   NBMA address: 203.0.113.10
10.100.0.20/32 via 10.100.0.20
   Tunnel0 created 00:02:55, expire 00:05:04
   Type: dynamic, Flags: registered used nhop
   NBMA address: 203.0.113.20

Both spokes are registered. The registered flag confirms successful NHRP registration. Now check adjacencies:

HUB1# show ip eigrp neighbors
EIGRP-IPv4 Neighbors for AS(1)
H   Address         Interface       Hold Uptime   SRTT   RTO  Q  Seq
                                    (sec)         (ms)       Cnt Num
1   10.100.0.20     Tu0               13 00:02:48   12   100  0  8
0   10.100.0.10     Tu0               11 00:03:01   14   100  0  9

Both spokes are EIGRP neighbors. Now test the spoke-to-spoke trigger. From SPOKE1, ping SPOKE2’s LAN:

SPOKE1# ping 192.168.20.1 repeat 10
Type escape sequence to abort.
Sending 10, 100-byte ICMP Echos to 192.168.20.1, timeout is 2 seconds:
.!!!!!!!!!
Success rate is 90 percent (9/10), round-trip min/avg/max = 2/3/4 ms

The first packet fails (dot) — it goes hub-routed while NHRP resolution occurs. The remaining nine succeed via the direct spoke-to-spoke tunnel. Check the NHRP cache on SPOKE1 to confirm:

SPOKE1# show ip nhrp
10.100.0.1/32 via 10.100.0.1
   Tunnel0 created 00:04:01, never expire
   Type: static, Flags: used
   NBMA address: 203.0.113.1
10.100.0.20/32 via 10.100.0.20
   Tunnel0 created 00:00:12, expire 00:01:47
   Type: dynamic, Flags: router nhop rib
   NBMA address: 203.0.113.20

The dynamic entry for 10.100.0.20 with NBMA address 203.0.113.20 — SPOKE2’s public IP — confirms the direct tunnel is established.

Step 5: Routing Table Validation

SPOKE1# show ip route eigrp
Codes: L - local, C - connected, S - static, R - RIP, M - mobile, B - BGP
       D - EIGRP, EX - EIGRP external

D     192.168.1.0/24 [90/27008000] via 10.100.0.1, 00:03:15, Tunnel0
D     192.168.20.0/24 [90/27776000] via 10.100.0.20, 00:00:14, Tunnel0

Notice 192.168.20.0 has next-hop 10.100.0.20 — the spoke tunnel IP, not the hub. This is the expected behavior with no ip next-hop-self eigrp 1 on the hub. If the next-hop were 10.100.0.1, your Phase 2 would be broken.

Troubleshooting DMVPN Phase 2: Common Failures

Problem 1: Spoke-to-Spoke Traffic Always Through Hub

Symptoms: pings work but show ip nhrp on spokes never shows dynamic entries for other spokes.

Check list:

  1. no ip redirects missing on hub tunnel? Add it.
  2. no ip next-hop-self eigrp 1 missing on hub? EIGRP is rewriting next-hop.
  3. Firewall blocking UDP 4500 (NAT-T) or GRE (IP protocol 47) between spoke public IPs?
HUB1# debug ip nhrp detail
NHRP: Receive Registration Request via Tunnel0 vrf 0, packet size: 116
NHRP: NHRP successfully registered 10.100.0.10 NBMA 203.0.113.10

Problem 2: NHRP Registration Failing

SPOKE1# debug ip nhrp
NHRP: Attempting to send NHRP Registration Request to NHS 10.100.0.1
NHRP: No route to NBMA address 203.0.113.1

The spoke cannot reach the hub’s public IP. Verify the underlay routing — the spoke’s physical interface must have a route to the hub’s public IP before the tunnel can form.

Problem 3: EIGRP Neighbors Flap

If hold timers are too aggressive relative to the mGRE tunnel setup time, EIGRP neighbors will flap every time a spoke reconnects. Tune hello and hold intervals:

interface Tunnel0
 ip hello-interval eigrp 1 20
 ip hold-time eigrp 1 60

The default hello/hold (5/15 seconds) is too aggressive for WAN links with variable latency. 20/60 is a safe starting point.

Problem 4: IPsec SA Not Establishing

SPOKE1# show crypto ikev2 sa
 IPv4 Crypto IKEv2  SA

Tunnel-id Local                 Remote                fvrf/ivrf            Status
1         203.0.113.10/500      203.0.113.20/500      none/none            READY

If the SA shows DELETE or is missing entirely:

SPOKE1# debug crypto ikev2
IKEV2:(SESSION ID = 2):Sending IKE_INIT_SA REQUEST
IKEV2: ERROR: Failed to find matching policy

Mismatch in IKEv2 policy or transform set between hub and spokes. Verify the transform set and profile names match exactly across all devices.

DMVPN Phase 2 with OSPF (Alternate Routing Protocol)

OSPF requires more care than EIGRP in DMVPN because of LSA flooding and DR/BDR elections. If you prefer OSPF:

! On ALL routers (hub and spokes)
interface Tunnel0
 ip ospf network point-to-multipoint
 ip ospf 1 area 0
 ip ospf priority 0    ! Only on spokes — hub keeps default priority 1
!
router ospf 1
 router-id 10.100.0.1   ! Use unique per-router
 network 10.100.0.0 0.0.0.255 area 0
 network 192.168.1.0 0.0.0.255 area 0

ip ospf network point-to-multipoint is the correct OSPF network type for DMVPN. It eliminates the DR/BDR election, sends hellos unicast to each NHRP-registered neighbor, and handles next-hop correctly without the Phase 2 caveats that plague broadcast mode.

With OSPF point-to-multipoint, spoke-to-spoke routing works differently from EIGRP: routes will still show hub as next-hop in the OSPF table, and Phase 2 NHRP resolution kicks in to create the direct tunnel anyway based on the NHRP cache. Some operators find this behavior less transparent than EIGRP — use EIGRP if you want the routing table to clearly reflect the direct spoke tunnel.

Scaling Considerations and Production Hardening

NHRP Cache Limits

On large deployments (100+ spokes), the hub’s NHRP cache can grow significantly. Set explicit cache limits:

interface Tunnel0
 ip nhrp max-send 1000 every 10
 ip nhrp redirect

Monitor with show ip nhrp summary on the hub to catch cache exhaustion before it causes spoke registration failures.

Dead Peer Detection

Enable IKEv2 DPD so stale IPsec SAs are cleaned up quickly when a spoke goes offline:

crypto ikev2 profile DMVPN_IKEv2_PROFILE
 dpd 30 5 periodic

This sends a DPD keepalive every 30 seconds, retries 5 times, then clears the SA if the peer is unresponsive.

QoS on DMVPN Tunnels

DMVPN tunnels are ideal candidates for QoS marking. Apply a service policy on the physical interface (not the tunnel) using the GRE/IPsec DSCP markings that traverse the underlay. For a full breakdown of QoS implementation for voice and video traffic in IOS-XE, see our Cisco QoS Practical Guide.

Redundancy: Dual-Hub DMVPN

Production DMVPN deployments use two hubs. Each hub runs a separate DMVPN tunnel, and spokes register with both. EIGRP metrics (via bandwidth/delay tuning) determine the primary hub. Failover is automatic when the primary hub NHRP registrations expire.

! SPOKE1 - second NHS (HUB2)
interface Tunnel1
 description DMVPN-SPOKE-BACKUP
 ip address 10.200.0.10 255.255.255.0
 ip nhrp nhs 10.200.0.1
 ip nhrp map 10.200.0.1 203.0.113.2
 ip nhrp map multicast 203.0.113.2
 tunnel source GigabitEthernet1
 tunnel mode gre multipoint
 tunnel key 200
 tunnel protection ipsec profile DMVPN_PROFILE

For automated failover between ISP links (not just hub redundancy), the Cisco EEM Scripts approach lets you trigger NHRP re-registration events and route adjustments programmatically.

Final Verification Checklist

Before signing off a DMVPN Phase 2 deployment, run through this checklist:

! 1. Hub sees both spokes registered
HUB1# show ip nhrp | include registered

! 2. Spokes have EIGRP neighbor with hub
SPOKE1# show ip eigrp neighbors

! 3. Routing table shows spoke LAN next-hops pointing to OTHER spoke tunnel IPs
SPOKE1# show ip route eigrp | include 192.168.20

! 4. After a ping, dynamic NHRP entry appears on originating spoke
SPOKE1# show ip nhrp dynamic

! 5. IPsec SAs are READY (not DELETE or absent)
SPOKE1# show crypto ikev2 sa detail

! 6. Traceroute from spoke1 LAN to spoke2 LAN shows single hop (no hub transit)
SPOKE1# traceroute 192.168.20.1 source 192.168.10.1

If traceroute shows two hops (spoke → hub → spoke), Phase 2 is not working. Re-check no ip redirects, no ip next-hop-self eigrp 1, and the NHRP dynamic cache.

Wrapping Up

DMVPN Phase 2 is a mature, production-proven technology that remains relevant even as SD-WAN alternatives proliferate — particularly in environments where you need direct spoke-to-spoke connectivity without a vendor-managed overlay. The configuration is not complex, but the failure modes are specific: split horizon, next-hop preservation, and ICMP redirect suppression are the three places where most Phase 2 deployments stumble.

For hands-on network automation to manage DMVPN configurations at scale across dozens of spoke routers, check out the Network Automation with Python, Netmiko, and NAPALM guide — pushing NHRP and IPsec config via Netmiko saves significant time when your spoke count is in the double digits.

Got a DMVPN deployment or troubleshooting scenario you want to dig into? Drop it in the comments.

Enjoying this post?

Get more guides like this delivered straight to your inbox. No spam, just tech and trails.