DMVPN

DMVPN Phase 3 Configuration on Cisco IOS XE

DMVPN Phase 3 configuration feature image with next-hop-override route output
In: DMVPN, GRE, Labs

This is the complete, working DMVPN Phase 3 build: one hub, two spokes, a router simulating the internet underlay, EIGRP over the top, every command shown and every verification step captured from live IOS XE 17.18 devices. Nothing here is theoretical output; if a counter or a flag appears, a lab produced it. Concepts are covered in DMVPN explained and the phase logic in Phase 1 vs 2 vs 3; this article is the hands-on companion in the DMVPN cluster.

Topology and Addressing

Four routers. INET sits in the middle pretending to be the internet, with documentation-range /30s toward each site. Each site router has a loopback standing in for its LAN.

HUBunderlay e0/1 203.0.113.1/30tunnel 10.0.0.1LAN Lo1 10.0.100.1/24
SPOKE1underlay e0/1 198.51.100.1/30tunnel 10.0.0.2LAN Lo1 10.0.1.1/24
SPOKE2underlay e0/1 192.0.2.1/30tunnel 10.0.0.3LAN Lo1 10.0.2.1/24
INET203.0.113.2 / 198.51.100.2 / 192.0.2.2no routing protocol, connected routes only

The overlay is Tunnel0 on 10.0.0.0/24 everywhere. NHRP network-id 1, authentication string PLZ123, GRE tunnel key 100. If you are reproducing this in CML, iol-xe nodes boot in seconds and handle everything except IPsec (for encrypted tunnels use Catalyst 8000v, covered in the IPsec article).

Step 1: The Underlay

Spokes and hub each need exactly one thing from the underlay: reachability to each other's tunnel source addresses. A static default toward INET does it, mirroring a real internet edge:

! HUB
interface Ethernet0/1
 ip address 203.0.113.1 255.255.255.252
 no shutdown
ip route 0.0.0.0 0.0.0.0 203.0.113.2

! SPOKE1 (SPOKE2 mirrors with 192.0.2.x)
interface Ethernet0/1
 ip address 198.51.100.1 255.255.255.252
 no shutdown
ip route 0.0.0.0 0.0.0.0 198.51.100.2

Sanity check before touching any tunnel: every router must ping every other router's underlay address. Skipping this check is the number one way to spend an hour debugging NHRP when the actual problem is underlay routing.

Step 2: The Hub Tunnel

interface Tunnel0
 description DMVPN hub - mGRE
 ip address 10.0.0.1 255.255.255.0
 no ip redirects
 ip mtu 1400
 ip tcp adjust-mss 1360
 ip nhrp authentication PLZ123
 ip nhrp network-id 1
 ip nhrp redirect
 tunnel source Ethernet0/1
 tunnel mode gre multipoint
 tunnel key 100

Line by line, the ones that matter. tunnel mode gre multipoint makes this one interface serve every spoke. ip nhrp redirect is the Phase 3 half that belongs on the hub: it fires an NHRP redirect at any spoke whose traffic hairpins through this interface. ip mtu 1400 and ip tcp adjust-mss 1360 pre-empt fragmentation blackholes (GRE eats 24 bytes, IPsec eats more; the arithmetic is in GRE MTU and fragmentation). tunnel key 100 tags the GRE packets, which must match on every router in this cloud. On IOS XE 17.x you no longer need ip nhrp map multicast dynamic on an mGRE hub; it is the default and will not even appear in the running config. Notably absent: any mention of any spoke.

Step 3: The Spoke Tunnels

interface Tunnel0
 description DMVPN spoke - mGRE
 ip address 10.0.0.2 255.255.255.0
 no ip redirects
 ip mtu 1400
 ip tcp adjust-mss 1360
 ip nhrp authentication PLZ123
 ip nhrp map 10.0.0.1 203.0.113.1
 ip nhrp map multicast 203.0.113.1
 ip nhrp network-id 1
 ip nhrp nhs 10.0.0.1
 ip nhrp shortcut
 tunnel source Ethernet0/1
 tunnel mode gre multipoint
 tunnel key 100

SPOKE2 is identical except its own addresses (tunnel IP 10.0.0.3, source e0/1 on 192.0.2.1). The five NHRP lines do all the work: map bootstraps the hub's overlay-to-underlay binding, map multicast lets routing protocol hellos reach the hub, nhs declares who to register with, and shortcut is the Phase 3 half that belongs on spokes, accepting redirects and installing shortcut routes. Spokes never reference other spokes; that is the entire point.

Step 4: Verify Registration Before Routing

Within seconds of the tunnels coming up, both spokes register. On the hub:

HUB# show dmvpn
Type:Hub, NHRP Peers:2,

 # Ent  Peer NBMA Addr Peer Tunnel Add State  UpDn Tm Attrb
 ----- --------------- --------------- ----- -------- -----
     1 198.51.100.1           10.0.0.2    UP 00:01:35     D
     1 192.0.2.1              10.0.0.3    UP 00:01:31     D

Both peers UP and D (dynamically learned). If a peer sits in NHRP state instead, stop and fix registration first (troubleshooting DMVPN diagnoses the three classic causes with captures). Routing on a broken NHRP layer is wasted effort.

Step 5: EIGRP Named Mode Over the Tunnel

! HUB
router eigrp PINGLABZ
 address-family ipv4 unicast autonomous-system 100
  af-interface Tunnel0
   no split-horizon
  exit-af-interface
  network 10.0.0.0 0.0.0.255
  network 10.0.100.0 0.0.0.255
 exit-address-family

! SPOKE1 (SPOKE2 mirrors with 10.0.2.0)
router eigrp PINGLABZ
 address-family ipv4 unicast autonomous-system 100
  network 10.0.0.0 0.0.0.255
  network 10.0.1.0 0.0.0.255
 exit-address-family

The single non-default line is no split-horizon on the hub's tunnel af-interface: without it, EIGRP refuses to re-advertise SPOKE1's routes back out Tunnel0 to SPOKE2, and the spokes never learn each other's LANs. Next-hop-self stays at its default (enabled), which is correct for Phase 3. Both spokes come up as neighbors over the multicast maps:

HUB# show ip eigrp neighbors
H   Address                 Interface              Hold Uptime   SRTT   RTO  Q  Seq
1   10.0.0.3                Tu0                      11 00:01:30   11  1398  0  3
0   10.0.0.2                Tu0                      11 00:01:35    7  1398  0  4

And the spoke RIB shows every remote prefix via the hub, which is the correct resting state for Phase 3 (the design trade-offs, including the OSPF alternative, are in routing over DMVPN):

SPOKE1# show ip route eigrp
D        10.0.2.0/24 [90/102400640] via 10.0.0.1, 00:00:29, Tunnel0
D        10.0.100.0/24 [90/76800640] via 10.0.0.1, 00:00:29, Tunnel0

Step 6: Watch the Shortcut Form

Send spoke-to-spoke traffic and run the same traceroute twice. The first flows through the hub and triggers the redirect; the second goes direct:

SPOKE1# traceroute 10.0.2.1 source Loopback1 numeric
  1 10.0.0.1 2 msec 1 msec 2 msec
  2 10.0.0.3 3 msec *  2 msec
SPOKE1# traceroute 10.0.2.1 source Loopback1 numeric
  1  *
    10.0.0.3 4 msec *

Three commands prove what happened. The NHRP cache now holds a shortcut for the remote prefix (nho flag) and the resolved peer (nhop rib):

SPOKE1# show ip nhrp
10.0.0.3/32 via 10.0.0.3
   Tunnel0 created 00:00:09, expire 00:09:50
   Type: dynamic, Flags: router nhop rib
   NBMA address: 192.0.2.1
10.0.2.0/24 via 10.0.0.3
   Tunnel0 created 00:00:09, expire 00:09:50
   Type: dynamic, Flags: router used rib nho
   NBMA address: 192.0.2.1

The RIB keeps the EIGRP route at the hub and overrides its next hop (the % and [NHO] markers, plus an H route for the peer):

SPOKE1# show ip route next-hop-override
H        10.0.0.3/32 is directly connected, 00:00:09, Tunnel0
D   %    10.0.2.0/24 [90/102400640] via 10.0.0.1, 00:00:57, Tunnel0
                     [NHO][90/255] via 10.0.0.3, 00:00:09, Tunnel0

And show dmvpn shows the two shortcut entry types, route-installed and next-hop-override:

SPOKE1# show dmvpn
 # Ent  Peer NBMA Addr Peer Tunnel Add State  UpDn Tm Attrb
 ----- --------------- --------------- ----- -------- -----
     1 203.0.113.1            10.0.0.1    UP 00:02:26     S
     2 192.0.2.1              10.0.0.3    UP 00:00:09   DT1
                              10.0.0.3    UP 00:00:09   DT2

Leave the traffic idle for the NHRP holdtime (10 minutes by default) and all of it unwinds: the dynamic entries expire, forwarding falls back to the hub, and the next traffic burst rebuilds the shortcut. That self-cleaning behavior is Phase 3 working as designed. The message-level mechanics behind the redirect are in the NHRP deep dive.

The Mistakes That Cost the Most Lab Time

Having built this exact topology more than once, here is where the time actually goes. Forgetting ip nhrp map multicast on a spoke: pings to the hub work, EIGRP never forms, and you debug the routing protocol for an hour when the problem is NHRP replication. Mismatched tunnel key: both interfaces up/up, everything dead, hub logs nothing, because GRE drops keyed packets before NHRP sees them. Forgetting no split-horizon on the hub: both spokes neighbor with the hub and learn the hub's LAN, but never each other's, which looks exactly like a filtering problem. Testing with unsourced pings: ping 10.0.2.1 from SPOKE1 sources from the tunnel interface and works even when LAN-to-LAN forwarding is broken, so always test with source Loopback1 the way the captures here do. And impatience with the shortcut: the redirect only fires on hairpinned data traffic, so a freshly cleared cache legitimately shows the hub path on the first packets. Each of these produces a distinct capture signature, all cataloged in troubleshooting DMVPN.

Worth repeating from the phase article because it defuses a common review comment: the NHRP network-id does not need to match between routers. Ours matches everywhere because uniformity is easier to operate, not because the protocol requires it. What must genuinely match across the cloud: the NHRP authentication string, the tunnel key, and the overlay subnet.

Verifying From a Real Host (bridge1)

Loopbacks prove routing; a real client proves the design. In our lab, the hub's e0/0 faces an external connector at 192.168.99.1/24 with a Debian VM at 192.168.99.100 behind it, and that subnet rides the same EIGRP process over the tunnel (network 192.168.99.0 in the hub's address-family). The spokes learn it like any other prefix:

SPOKE1# show ip route eigrp
D     192.168.99.0/24 [90/77312000] via 10.0.0.1, 00:00:29, Tunnel0

Add a static route on the VM pointing 10.0.0.0/16 at 192.168.99.1 and the Linux host can reach every spoke LAN across the overlay. The same pattern (real host, external connector, overlay route) upgrades any CML lab from ping-between-loopbacks to something you can drive iperf and packet captures through.

Production Deltas

Four gaps between this lab and a deployable design. Encryption: internet transport means IPsec, added purely with a tunnel protection profile and an IKEv2 policy, no DMVPN changes (full build here). Summarization: with more than a handful of spokes, advertise a summary or default from the hub instead of individual prefixes; Phase 3 shortcuts keep working because NHRP resolution carries the specifics. Hub redundancy: a second hub is a second ip nhrp nhs line on every spoke (priorities and clusters control preference). Front-door VRF: production designs usually put the underlay in an fVRF (tunnel vrf INTERNET) so the default route toward the ISP cannot collide with the overlay's routing, a recursion problem explained in GRE tunnel troubleshooting.

Key Takeaways

A Phase 3 DMVPN is startlingly little configuration: an mGRE tunnel with five NHRP lines per spoke, two Phase 3 commands (redirect on the hub, shortcut on spokes), one split-horizon exception in EIGRP, and MTU/MSS clamps. Verify in layers, in order: underlay pings, then show dmvpn registration on the hub, then routing adjacencies, then the two-traceroute shortcut test with show ip route next-hop-override as the receipt. The hub scales because it knows nothing about individual spokes, and the shortcuts self-expire because they are cache entries, not routes. Next steps in the cluster: encrypt it, then break it on purpose, with the full map in the DMVPN complete guide.

Written by
More from Ping Labz
Great! You’ve successfully signed up.
Welcome back! You've successfully signed in.
You've successfully subscribed to Ping Labz.
Your link has expired.
Success! Check your email for magic link to sign-in.
Success! Your billing info has been updated.
Your billing was not updated.