Auto Draft

DMVPN Phase 2 Configuration on Cisco IOS-XE: Hub-and-Spoke with Direct Spoke-to-Spoke Tunnels

What Is DMVPN and Why Phase 2 Matters

Dynamic Multipoint VPN (DMVPN) is one of Cisco’s most elegant solutions for building scalable, hub-and-spoke overlay networks. Unlike static GRE tunnels or full-mesh IPSEC, DMVPN lets spokes register dynamically with the hub and — in Phase 2 — build on-demand spoke-to-spoke tunnels without any traffic hairpinning through the hub router. If you’ve ever watched traceroutes traverse three extra hops through a data center just to reach a branch 10 miles away, you already know exactly why this matters.

This guide covers DMVPN Phase 2 end-to-end: mGRE tunnel configuration, NHRP registration, IPsec protection with IKEv2, OSPF or EIGRP overlay routing, and the common failure modes you’ll hit in production. All examples use Cisco IOS-XE syntax verified on a Cat8000V and CSR1000V running 17.x code.

If you’re new to the Cisco IOS/IOS-XE software train differences, check out our IOS vs IOS-XE vs IOS-XR comparison before diving in.


DMVPN Phase Comparison: 1 vs 2 vs 3

Before committing to Phase 2, it’s worth understanding what each phase does — and doesn’t — give you:

  • Phase 1: All spoke-to-spoke traffic routes through the hub. Simple but creates latency and bandwidth bottlenecks. Hub is the next-hop for all routes.
  • Phase 2: Spokes can initiate direct tunnels to other spokes dynamically via NHRP resolution. The hub still advertises routes, but the next-hop IP preserves the original spoke address so traffic bypasses the hub once the tunnel is up.
  • Phase 3: Adds NHRP route redirect and shortcut switching. Spokes only need a default route pointing to the hub; Phase 3 installs more-specific host routes for spoke-to-spoke paths. More scalable but adds complexity.

Phase 2 is the sweet spot for medium-sized deployments (5–100 spokes): direct spoke-to-spoke paths without requiring the more complex redirect/shortcut mechanism of Phase 3.


Lab Topology

For this guide, we’re working with the following layout:

  • HUB1 — 203.0.113.1 (public) / 10.0.0.1 (tunnel)
  • SPOKE1 — 198.51.100.1 (public) / 10.0.0.11 (tunnel)
  • SPOKE2 — 198.51.100.2 (public) / 10.0.0.12 (tunnel)
  • Tunnel network: 10.0.0.0/24
  • Spoke LAN behind SPOKE1: 192.168.11.0/24
  • Spoke LAN behind SPOKE2: 192.168.12.0/24

Step 1: IPsec IKEv2 Profile (Hub and Spokes)

Configure IPsec before building the mGRE tunnel. Using IKEv2 here — no reason to run IKEv1 on modern IOS-XE. Apply this configuration identically on all routers, adjusting the keyring peer address as appropriate.

! IKEv2 Keyring - defines pre-shared keys
crypto ikev2 keyring DMVPN-KEYRING
 peer ANY
  address 0.0.0.0 0.0.0.0
  pre-shared-key local Sup3rS3cr3tDMVPN!
  pre-shared-key remote Sup3rS3cr3tDMVPN!
 !

! IKEv2 Proposal
crypto ikev2 proposal DMVPN-PROP
 encryption aes-cbc-256
 integrity sha256
 group 14
!

! IKEv2 Policy
crypto ikev2 policy DMVPN-POL
 proposal DMVPN-PROP
!

! IKEv2 Profile
crypto ikev2 profile DMVPN-IKEv2-PROFILE
 match identity remote address 0.0.0.0
 authentication remote pre-share
 authentication local 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 (referenced by tunnel interface)
crypto ipsec profile DMVPN-IPSEC-PROFILE
 set transform-set DMVPN-TS
 set ikev2-profile DMVPN-IKEv2-PROFILE
!

Note: We use mode transport here because the outer GRE tunnel provides the encapsulation — IPsec only needs to encrypt the GRE payload, not add a new IP header.


Step 2: Hub mGRE Tunnel Interface

The hub uses a multipoint GRE (mGRE) tunnel interface. This single interface handles all spoke registrations dynamically.

! HUB1 configuration
interface Tunnel0
 description DMVPN-PHASE2-HUB
 ip address 10.0.0.1 255.255.255.0
 no ip redirects
 ip nhrp authentication DMVPN2026
 ip nhrp map multicast dynamic
 ip nhrp network-id 100
 ip nhrp holdtime 300
 ip ospf network point-to-multipoint
 tunnel source GigabitEthernet0/0/0
 tunnel mode gre multipoint
 tunnel key 100
 tunnel protection ipsec profile DMVPN-IPSEC-PROFILE
!

Key parameters explained:

  • ip nhrp map multicast dynamic — tells the hub to dynamically learn which spokes should receive multicast (needed for routing protocol hellos)
  • ip nhrp network-id 100 — must match across all routers in this DMVPN cloud
  • ip nhrp holdtime 300 — how long NHRP entries are considered valid; tune based on NAT timeout if spokes are behind NAT
  • no ip redirects — critical for Phase 2; prevents the hub from sending ICMP redirects that confuse spoke-to-spoke paths
  • tunnel key 100 — disambiguates when multiple DMVPN clouds share the same tunnel source

Step 3: Spoke mGRE Tunnel Interface

Spokes also use mGRE (not point-to-point GRE) to support dynamic spoke-to-spoke tunnels. Each spoke needs an NHRP mapping to the hub’s public address and an NHS (Next Hop Server) entry pointing to the hub.

! SPOKE1 configuration (repeat on SPOKE2 with adjusted IPs)
interface Tunnel0
 description DMVPN-PHASE2-SPOKE
 ip address 10.0.0.11 255.255.255.0
 no ip redirects
 ip nhrp authentication DMVPN2026
 ip nhrp map 10.0.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.0.0.1
 ip ospf network point-to-multipoint
 tunnel source GigabitEthernet0/0/0
 tunnel mode gre multipoint
 tunnel key 100
 tunnel protection ipsec profile DMVPN-IPSEC-PROFILE
!

The two critical lines for spoke-to-hub reachability:

  • ip nhrp map 10.0.0.1 203.0.113.1 — static mapping: tunnel IP → NBMA (public) IP of the hub
  • ip nhrp nhs 10.0.0.1 — designates 10.0.0.1 as the NHS the spoke registers with

Step 4: OSPF Overlay Routing (Phase 2 Next-Hop Preservation)

This is the configuration step where most Phase 2 deployments go wrong. For spoke-to-spoke tunnels to form, the routing protocol must not change the next-hop to the hub’s tunnel IP. If OSPF overwrites the next-hop, traffic will still flow through the hub even though NHRP can resolve spoke public addresses.

! Hub OSPF config
router ospf 1
 network 10.0.0.0 0.0.0.255 area 0
 network 192.168.0.0 0.0.255.255 area 0
!
! Spoke OSPF config (identical on all spokes)
router ospf 1
 network 10.0.0.0 0.0.0.255 area 0
 network 192.168.11.0 0.0.0.255 area 0
!

The ip ospf network point-to-multipoint setting on the tunnel interface is doing the heavy lifting here. In point-to-multipoint mode, OSPF advertises each neighbor relationship as a host route (/32), and — critically — preserves the original next-hop IP rather than replacing it with the hub’s tunnel address. This is what enables NHRP to trigger a spoke-to-spoke tunnel when traffic is destined for 192.168.12.0/24 via SPOKE2’s tunnel IP.

Verify OSPF neighbors are forming on the hub:

HUB1# show ip ospf neighbor

Neighbor ID     Pri   State           Dead Time   Address         Interface
10.0.0.11         1   FULL/  -        00:01:39    10.0.0.11       Tunnel0
10.0.0.12         1   FULL/  -        00:01:42    10.0.0.12       Tunnel0

Step 5: Verify NHRP Registration

After bringing up all routers, verify NHRP registrations on the hub:

HUB1# show ip nhrp

10.0.0.11/32 via 10.0.0.11
   Tunnel0 created 00:03:12, expire 00:04:47
   Type: dynamic, Flags: registered nhop
   NBMA address: 198.51.100.1

10.0.0.12/32 via 10.0.0.12
   Tunnel0 created 00:02:55, expire 00:05:04
   Type: dynamic, Flags: registered nhop
   NBMA address: 198.51.100.2

Both spokes have registered their public (NBMA) addresses. The hub now knows that tunnel IP 10.0.0.11 maps to public IP 198.51.100.1 — this is the information it will hand to SPOKE2 when SPOKE2 needs to reach SPOKE1 directly.

Check the NHRP cache on a spoke:

SPOKE1# show ip nhrp detail

10.0.0.1/32 via 10.0.0.1
   Tunnel0 created 00:05:01, never expire
   Type: static, Flags: used nhop
   NBMA address: 203.0.113.1

10.0.0.12/32 via 10.0.0.12
   Tunnel0 created 00:00:08, expire 00:01:51
   Type: dynamic, Flags: router nhop rib
   NBMA address: 198.51.100.2

The dynamic entry for 10.0.0.12 appeared automatically after SPOKE1 tried to forward traffic toward SPOKE2’s LAN — this is Phase 2 in action. NHRP resolved the public address and a direct IPsec/GRE tunnel was negotiated between the two spokes.


Step 6: Verifying Spoke-to-Spoke Tunnels

SPOKE1# traceroute 192.168.12.1 source 192.168.11.1

Type escape sequence to abort.
Tracing the route to 192.168.12.1
VRF info: (vrf in name/id, vrf out name/id)
  1 10.0.0.12 28 msec 24 msec 26 msec

One hop directly to SPOKE2’s tunnel interface — no hub hairpin. Compare this to Phase 1 where you’d see the hub (10.0.0.1) as an intermediate hop.

View the crypto session to confirm a direct IPsec SA is established between spokes:

SPOKE1# show crypto session

Crypto session current status

Interface: Tunnel0
Profile: DMVPN-IKEv2-PROFILE
Uptime: 00:00:41
Session status: UP-ACTIVE
Peer: 203.0.113.1 port 500
  Session ID: 1
  IKEv2 SA: local 198.51.100.1/500 remote 203.0.113.1/500 Active
  IPSEC FLOW: permit 47 host 198.51.100.1 host 203.0.113.1
        Active SAs: 2, origin: crypto map

Interface: Tunnel0
Profile: DMVPN-IKEv2-PROFILE
Uptime: 00:00:08
Session status: UP-ACTIVE
Peer: 198.51.100.2 port 500
  Session ID: 2
  IKEv2 SA: local 198.51.100.1/500 remote 198.51.100.2/500 Active
  IPSEC FLOW: permit 47 host 198.51.100.1 host 198.51.100.2
        Active SAs: 2, origin: crypto map

Session ID 2 is the direct SPOKE1→SPOKE2 IPsec SA. Phase 2 working exactly as intended.


Common Failure Modes and Fixes

1. Spokes Not Registering with the Hub

Symptom: show ip nhrp on the hub shows no dynamic entries after spokes come up.

Debug on the hub:

HUB1# debug nhrp detail
*Jun  3 12:01:15.203: NHRP: Receive Registration Request via Tunnel0 vrf 0, packet size: 116
*Jun  3 12:01:15.203: src: 198.51.100.1, dst: 203.0.113.1
*Jun  3 12:01:15.204: NHRP: Authentication string mismatch

Fix: Verify the ip nhrp authentication string matches exactly on all routers (case-sensitive). Also check the NHRP network-id — mismatched IDs cause silent registration failures.

2. Traffic Still Hairpinning Through Hub (Phase 2 Not Activating)

Symptom: Traceroutes to remote spoke LANs show two hops (hub tunnel IP, then spoke LAN).

Root cause 90% of the time: routing protocol is overwriting the next-hop. Verify on SPOKE1:

SPOKE1# show ip route 192.168.12.0

Routing entry for 192.168.12.0/24
  Known via "ospf 1", distance 110, metric 2
  Last update from 10.0.0.1 on Tunnel0, 00:02:14 ago
  Routing Descriptor Blocks:
  * 10.0.0.1, from 10.0.0.12, 00:02:14 ago, via Tunnel0

The next-hop shows 10.0.0.1 (the hub) — this is the problem. The “from” field correctly shows 10.0.0.12, but the next-hop has been overwritten. Verify ip ospf network point-to-multipoint is set on the Tunnel0 interface on all routers. A single spoke missing this setting can cause asymmetric behavior.

Correct route with next-hop preserved:

  * 10.0.0.12, from 10.0.0.12, 00:00:05 ago, via Tunnel0

3. Spoke-to-Spoke Tunnels Forming but Dropping Quickly

Symptom: NHRP cache shows dynamic entries that expire and aren’t renewed; spoke-to-spoke sessions flap.

Check NHRP holdtime vs. actual traffic patterns. If spoke-to-spoke traffic is intermittent, the NHRP cache entry expires before next use. The tunnel teardown and re-initiation introduces latency for that first packet.

! Increase holdtime on all routers (hub and spokes)
interface Tunnel0
 ip nhrp holdtime 600

For environments where spoke-to-spoke traffic is consistently active, bump the holdtime to match your traffic patterns. Note that ip nhrp redirect is a Phase 3 feature (shortcut switching) and should not be added to a Phase 2 deployment — it changes the NHRP signaling model and can break Phase 2 spoke-to-spoke behavior.

4. IPsec Tunnel Up but No Traffic Passing

Check MTU and fragmentation. GRE adds 24 bytes of overhead; IPsec in transport mode adds ~50 bytes on top. On a standard 1500-byte MTU WAN link, this means your effective payload MTU is around 1420 bytes. Without proper TCP MSS clamping, large TCP sessions will stall:

interface Tunnel0
 ip tcp adjust-mss 1360

Set this on the tunnel interface. Also set on LAN-facing interfaces if you’re seeing only small packets passing:

interface GigabitEthernet0/0/1
 ip tcp adjust-mss 1360

DMVPN Behind NAT: Spoke NAT Traversal

Branch routers are often behind a customer NAT device. IKEv2 handles NAT-T automatically on port 4500 when a NAT is detected, but you need to confirm:

SPOKE1# show crypto ikev2 sa detail | include NAT

NAT-T is enabled

If spokes are behind NAT, reduce the NHRP holdtime to something shorter than the NAT mapping timeout (typically 120–180 seconds on stateful firewalls):

interface Tunnel0
 ip nhrp holdtime 120
 ip nhrp registration timeout 60

The registration timeout forces spokes to re-register every 60 seconds, keeping NAT bindings alive and ensuring the hub always has a current public IP mapping for each spoke.


Adding a Second Hub (Dual-Hub DMVPN)

Production deployments typically use two hubs for redundancy. Each hub operates an independent DMVPN cloud with a different network-id, and spokes participate in both. The example below shows the key differentiators — apply all the NHRP authentication, holdtime, and OSPF point-to-multipoint settings from the single-hub config to both tunnel interfaces:

! SPOKE1 - Dual-hub config
interface Tunnel0
 description DMVPN-HUB1
 ip address 10.0.0.11 255.255.255.0
 ip nhrp network-id 100
 ip nhrp nhs 10.0.0.1
 ip nhrp map 10.0.0.1 203.0.113.1
 ip nhrp map multicast 203.0.113.1
 tunnel source GigabitEthernet0/0/0
 tunnel mode gre multipoint
 tunnel protection ipsec profile DMVPN-IPSEC-PROFILE
!
interface Tunnel1
 description DMVPN-HUB2
 ip address 10.1.0.11 255.255.255.0
 ip nhrp network-id 200
 ip nhrp nhs 10.1.0.1
 ip nhrp map 10.1.0.1 203.0.113.2
 ip nhrp map multicast 203.0.113.2
 tunnel source GigabitEthernet0/0/0
 tunnel mode gre multipoint
 tunnel protection ipsec profile DMVPN-IPSEC-PROFILE
!

Use OSPF cost manipulation to prefer one hub over the other under normal conditions, with failover to the secondary hub if the primary drops:

interface Tunnel0
 ip ospf cost 10

interface Tunnel1
 ip ospf cost 20

Monitoring DMVPN Health

Key commands for ongoing monitoring:

! NHRP cache on hub (expect all spoke registrations)
show ip nhrp

! Detailed NHRP with timestamps and flags
show ip nhrp detail

! All current crypto sessions (hub and spokes)
show crypto session

! IKEv2 SA details
show crypto ikev2 sa detail

! OSPF neighbor state on tunnel interface
show ip ospf neighbor detail

! Interface packet counters (look for input/output errors)
show interface Tunnel0

! DMVPN-specific summary
show dmvpn detail

The show dmvpn command (available on 15.x+ and all IOS-XE 16+) gives a clean summary of the NHRP state for each peer:

HUB1# show dmvpn

Legend: Attrb --> S - Static, D - Dynamic, I - Incomplete
        N - NATed, L - Local, X - No Socket
        T1 - Route Installed, T2 - Nexthop-override

# Ent  Peer NBMA Addr Peer Tunnel Add State  UpDn Tm Attrb
----- --------------- --------------- ----- -------- -----
    1 198.51.100.1        10.0.0.11    UP    00:12:44  D
    1 198.51.100.2        10.0.0.12    UP    00:12:31  D

For deeper inspection of what’s happening during spoke-to-spoke tunnel negotiation, the NHRP debug is invaluable — but be selective in production, as it’s verbose:

debug nhrp condition peer nbma 198.51.100.2
debug nhrp detail

DMVPN and QoS Considerations

Traffic classification and QoS must be applied to the physical interface, not the tunnel interface, because by the time a packet hits the WAN interface it’s already encapsulated in GRE+IPsec. Use NBAR2 to classify the original application before encryption if you need per-application QoS. For a deeper look at QoS fundamentals on IOS-XE, the QoS voice and video guide covers DSCP marking and queuing strategies that complement DMVPN deployments nicely.

If you’re thinking about network automation to manage DMVPN at scale — spinning up spoke configs via templates, auto-generating NHRP maps, or monitoring registration state — take a look at our Python automation guide with Netmiko, NAPALM, and Nornir.


Summary

DMVPN Phase 2 is a mature, well-understood technology that solves the spoke-to-spoke latency problem elegantly. The critical success factors are:

  1. OSPF point-to-multipoint on tunnel interfaces — without this, next-hop overwrite kills spoke-to-spoke paths
  2. Consistent NHRP authentication and network-id across all routers — mismatches cause silent failures
  3. TCP MSS clamping — skip this and large file transfers will stall in ways that are painful to diagnose
  4. NAT holdtime tuning — if any spokes are behind NAT, the registration timeout must stay below the NAT mapping TTL

Phase 2 scales comfortably to 50–100 spokes on modest hub hardware. Beyond that, look at Phase 3 (NHRP shortcut) or SD-WAN solutions that offload the tunnel management plane entirely. For now, DMVPN Phase 2 remains one of the most cost-effective ways to give branch offices direct, encrypted connectivity without a full mesh of static tunnels.

Enjoying this post?

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