Every Cisco engineer eventually inherits a router with four different VPN styles bolted onto it: a crypto map for the legacy branch, a static VTI for the partner link, DMVPN for the regional spokes, and EzVPN for the handful of teleworkers who never got a proper laptop image. Four configuration models, four troubleshooting workflows, four sets of gotchas. FlexVPN exists to collapse all of that into one. It is the modern Cisco answer to the question "how should I build IPsec on IOS XE today", and it sits at the top of the IPsec VPN cluster for a reason.
The single most surprising thing about FlexVPN, and the thing that makes it click once you see it, is this: IKEv2 itself carries the addresses and the routes. There is no IGP running over the overlay. No OSPF adjacency, no EIGRP neighbor, no BGP session. The tunnel comes up, and the routes are simply there. This article walks through why that works, using real output from our CML lab (HUB, SPOKE1, and SPOKE2, all cat8000v running IOS XE 17.18.02).
The Zoo FlexVPN Replaces
Before FlexVPN, Cisco IPsec was a collection of unrelated configuration dialects. Each one solved a real problem, and each one was configured completely differently from the others.
Look at what those four have in common: every single one is IPsec, and every single one needs to authenticate a peer, negotiate policy, decide what traffic to protect, and get routes across. FlexVPN's insight is that all four are the same problem wearing different clothes, and that IKEv2 already has the machinery to solve it in one model.
FlexVPN Is a Framework, Not a Protocol
This trips people up constantly, so let us be blunt: there is no FlexVPN protocol. Nothing on the wire says "FlexVPN". Run a packet capture on a FlexVPN tunnel and you will see standards-based IKEv2 (RFC 7296) and standards-based ESP. That is it.
FlexVPN is Cisco's name for a configuration framework: a consistent set of IOS XE building blocks that use IKEv2's own features (the configuration payload, the authorization exchange, and IKEv2 route injection) to do the work that crypto maps, static VTIs, DMVPN, and EzVPN each did their own way. Because the framework leans on IKEv2 rather than on Cisco-proprietary glue, the same config model covers a hub-and-spoke fabric, a point-to-point site-to-site tunnel, and a remote-access client. That is the "flex" part.
The Building Blocks
A FlexVPN head end is assembled from five pieces. Learn these five and the rest is variation.
local (our lab) or a RADIUS server (production, per-user policy).The Headline Feature: IKEv2 Pushes the Routes
Here is the hub configuration from our lab. Read the authorization policy carefully, because those three lines are the entire routing design.
aaa new-model
aaa authorization network PLZ-FLEX-LIST local
ip local pool PLZ-FLEX-POOL 10.0.9.10 10.0.9.100
ip access-list standard PLZ-FLEX-ROUTES
permit 10.20.10.0 0.0.0.255
permit 192.168.99.0 0.0.0.255
permit 10.30.0.0 0.0.255.255
crypto ikev2 authorization policy PLZ-AUTHOR-POL
pool PLZ-FLEX-POOL
route set interface
route set access-list PLZ-FLEX-ROUTES
crypto ikev2 profile PLZ-FLEX-PROF
match identity remote fqdn domain pinglabz.lab
identity local fqdn hub.pinglabz.lab
authentication local pre-share
authentication remote pre-share
keyring local PLZ-FLEX-KEYRING
aaa authorization group psk list PLZ-FLEX-LIST PLZ-AUTHOR-POL
virtual-template 1route set interface tells IKEv2 to advertise the address on the tunnel interface itself. route set access-list PLZ-FLEX-ROUTES tells it to advertise every prefix permitted by that standard ACL. Those routes are then delivered to the peer inside the IKEv2 authorization exchange, as attributes, during tunnel setup.
Once both spokes connect, the hub's routing table looks like this:
HUB#show ip route | include Virtual-Access
S 10.0.9.24/32 is directly connected, Virtual-Access1
S 10.0.9.25/32 is directly connected, Virtual-Access2
S 10.30.10.0/24 is directly connected, Virtual-Access1
S 10.30.20.0/24 is directly connected, Virtual-Access2SPOKE1's LAN (10.30.10.0/24) is reachable via Virtual-Access1. SPOKE2's LAN (10.30.20.0/24) is reachable via Virtual-Access2. The hub learned both, plus each spoke's assigned tunnel address, without a single line of routing protocol configuration.
The spoke side is the mirror image. Here is SPOKE1's static route table (and remember, the only static route we typed was the default toward the ISP):
SPOKE1#show ip route static
S* 0.0.0.0/0 [1/0] via 198.51.100.1
S 10.20.10.0/24 is directly connected, Tunnel0
S 10.30.0.0/16 is directly connected, Tunnel0
S 10.255.0.1/32 is directly connected, Tunnel0
S 192.168.99.0/24 is directly connected, Tunnel0Every one of those tunnel routes came from the hub. 10.20.10.0/24 and 192.168.99.0/24 and 10.30.0.0/16 are exactly the three lines in PLZ-FLEX-ROUTES, and 10.255.0.1/32 is the hub's tunnel address, delivered by route set interface. Say it plainly: no OSPF, no EIGRP, no BGP. The IKEv2 AAA authorization policy injected all of it.
That has real operational consequences. Adding a new subnet to the hub site is one line in a standard ACL, and every spoke picks it up on its next rekey or reconnect. There is no adjacency to babysit, no overlay flap to chase, no "why is my EIGRP neighbor bouncing over the DMVPN cloud" ticket. For a hub-and-spoke topology where the routing is fundamentally hierarchical anyway, running a full IGP over the tunnel was always a bit of an overreach.
Dynamic Addressing Is the Same Mechanism as Remote Access
Look at the spoke's tunnel interface:
interface Tunnel0
ip address negotiated
ip nhrp network-id 1
ip nhrp shortcut virtual-template 1
tunnel source GigabitEthernet2
tunnel mode ipsec ipv4
tunnel destination 203.0.113.1
tunnel protection ipsec profile PLZ-FLEX-IPSECip address negotiated. The spoke has no idea what its own tunnel address is until IKEv2 tells it. On the hub, ip local pool PLZ-FLEX-POOL 10.0.9.10 10.0.9.100 plus the pool line in the authorization policy hands one out. Check the pool after both spokes are up:
HUB#show ip local pool PLZ-FLEX-POOL
Pool Begin End Free In use
PLZ-FLEX-POOL 10.0.9.10 10.0.9.100 89 2
Inuse addresses:
10.0.9.24 IKEv2 Addr IDB
10.0.9.25 IKEv2 Addr IDBNote the label: IKEv2 Addr IDB. IOS XE is telling you exactly who allocated those addresses. This is the IKEv2 configuration payload (CFG_REQUEST / CFG_REPLY in RFC 7296), and it is precisely the same mechanism a remote-access VPN client uses when it dials into a head end and gets an inside address, a DNS server, and a split-tunnel list.
That is the whole reason one framework can cover both worlds. To the hub, a branch router with ip address negotiated and a laptop running an IKEv2 client are the same kind of thing: a peer that authenticates, requests configuration, and gets an address and a set of routes. Swap pre-share for certificates and EAP, point the AAA list at RADIUS instead of local, and the identical head-end config serves remote-access users. Nothing else changes.
Virtual-Access: Cloning a Tunnel Per Peer
The hub never has a Tunnel interface for each spoke. It has one Virtual-Template1, and IOS XE clones it:
interface Virtual-Template1 type tunnel
ip unnumbered Loopback0
ip nhrp network-id 1
ip nhrp redirect
tunnel source GigabitEthernet2
tunnel mode ipsec ipv4
tunnel protection ipsec profile PLZ-FLEX-IPSECWhen SPOKE1 authenticates, IOS XE stamps out a copy of that template as Virtual-Access1, fills in the tunnel destination from the IKEv2 session, and brings it up. When SPOKE2 authenticates, it gets Virtual-Access2. Both spokes up:
HUB#show ip interface brief | include Virtual-Access
Virtual-Access1 10.255.0.1 YES unset up up
Virtual-Access2 10.255.0.1 YES unset up up
HUB#show crypto session
Interface: Virtual-Access1
Session status: UP-ACTIVE
Peer: 198.51.100.2 port 500
Interface: Virtual-Access2
Session status: UP-ACTIVE
Peer: 198.51.100.6 port 500Both Virtual-Access interfaces share the same IP (10.255.0.1) because the template is ip unnumbered Loopback0. That is normal and correct. The per-peer state that makes them distinct is the tunnel destination, the IPsec SA, and the routes installed behind them. Add a hundred spokes and you get a hundred Virtual-Access interfaces, from that one template, with no additional hub configuration.
The Gotcha We Actually Hit
Our first attempt at the Virtual-Template omitted tunnel source and tunnel mode. IKEv2 authenticated perfectly. The debug showed the authorization request going through cleanly. And yet the tunnel refused to stay up, cycling in a loop:
%LINK-3-UPDOWN: Interface Virtual-Access1, changed state to down
%DMVPN-5-NHRP_NETID_UNCONFIGURED: Virtual-Access1: NETID : 1 Unconfigured (Tunnel: 0.0.0.0 NBMA: UNKNOWN)Read that message closely: Tunnel: 0.0.0.0 NBMA: UNKNOWN. The cloned Virtual-Access had no idea what its own source address was, because the template never told it. It came up, discovered it was an incomplete tunnel, and died. Then IKEv2 (still perfectly happy) rebuilt the session, which cloned a new Virtual-Access, which also died.
The trap is that this looks like a crypto failure. You are staring at a VPN that will not come up, so you go debug IKEv2, and IKEv2 tells you everything is fine (you will see IKEv2:Using mlist PLZ-FLEX-LIST and username PLZ-AUTHOR-POL for group author request in the debug output, which is IKEv2 saying "authorization done, over to you"). It is not a crypto problem. It is an interface problem. The fix was adding the two missing lines to the template:
interface Virtual-Template1 type tunnel
tunnel source GigabitEthernet2
tunnel mode ipsec ipv4The general lesson: in FlexVPN, a Virtual-Access is only ever as complete as the Virtual-Template it was cloned from. If the tunnel is flapping but IKEv2 says READY, stop debugging crypto and go read show derived-config interface Virtual-Access1 to see what IOS XE actually built.
FlexVPN vs DMVPN
These two overlap heavily, and the honest answer is that both are good. Neither one is deprecated, and DMVPN is not going anywhere.
The short version: if you already run DMVPN at scale and it works, FlexVPN is not a reason to rip it out. If you are building green field on modern IOS XE, or if you need site-to-site and remote access to share one head end and one policy engine, FlexVPN is the cleaner starting point. If you want the deep dive on the other option, our DMVPN cluster covers mGRE, NHRP, and all three phases with working lab output.
Where FlexVPN Fits
Four deployment shapes, one framework:
- Hub-and-spoke. The canonical FlexVPN design and the one in this article. Hub runs a virtual-template, spokes run a static Tunnel with a tunnel destination, IKEv2 hands out addresses and routes.
- Point-to-point site-to-site. A degenerate hub-and-spoke with one spoke, or a pair of routers that each run a static tunnel. Covered step by step in FlexVPN site-to-site configuration.
- Remote access. Same head end, certificates or EAP instead of a pre-shared key, AAA pointed at RADIUS. The client is just another peer requesting a config payload.
- Spoke-to-spoke. NHRP shortcut and redirect let two spokes build a direct tunnel and bypass the hub. Worth being honest here: in our lab, on cat8000v 17.18.02, spoke-to-spoke traffic worked but only by hairpinning through the hub, and the NHRP shortcut never formed (every NHRP counter stayed at zero). We wrote up exactly what we could and could not prove in FlexVPN spoke-to-spoke, including the traceroute that shows the two-hop path.
Key Takeaways
- FlexVPN is not a protocol. It is a Cisco configuration framework built entirely on standards-based IKEv2 and ESP. Nothing proprietary crosses the wire.
- One model replaces four. Crypto maps, static VTIs, DMVPN, and EzVPN each solved one shape of the problem. FlexVPN covers all of them with the same building blocks.
- IKEv2 carries the routes.
route set interfaceandroute set access-listin the IKEv2 authorization policy inject prefixes into the peer's routing table during tunnel setup. Our hub learned both spoke LANs, and both spokes learned the hub's networks, with no OSPF, EIGRP, or BGP anywhere. - IKEv2 carries the addresses too.
ip address negotiatedon the spoke plusip local poolon the hub is the IKEv2 configuration payload, the same mechanism that gives a remote-access client its inside address. That is why one framework spans site-to-site and RA. - Virtual-Access interfaces are cloned, not configured. One Virtual-Template becomes one Virtual-Access per authenticated peer, created and destroyed with the session.
- If the tunnel flaps but IKEv2 says READY, it is not crypto. A Virtual-Template missing
tunnel sourceortunnel modeclones a broken Virtual-Access that comes up and dies in a loop, and theNHRP_NETID_UNCONFIGUREDmessage is your clue. - DMVPN is still fine. Pick FlexVPN for green field, for IKEv2-native designs, and when remote access and site-to-site should share a head end. Pick DMVPN when you need a battle-tested spoke-to-spoke fabric with a routing protocol you already run.
FlexVPN is the piece that makes the rest of the modern Cisco IPsec story hang together. If you want the full picture, from ESP and IKE fundamentals through crypto maps, VTIs, and IKEv2 itself, start at the IPsec VPN pillar and work outward.