DMVPN with VRF's for the Internet interfaces and BGP

I’ve been playing with some different DMVPN configurations. In this scenario, I wanted the Internet facing interface to have a separate routing table, which I accomplished with a VRF. I also wanted to use a phase 2 DMVPN - which allows spokes to communicate directly to each other without having to send all traffic to the hub. The tricky part was getting the DMVPN tunnels to form over that interface. This is accomplished via the tunnel vrf command in the tunnel interface and specifying the vrf in the crypto keyring.

Here is my hub config:

DMVPN-HUB1-R1#$l0/0.102|interface Loopback0|interface Tunnel0|ip prefix-list 
ip vrf Internet
 rd 500:1
crypto keyring DMVPN vrf Internet
  pre-shared-key address 0.0.0.0 0.0.0.0 key test123
crypto isakmp policy 10
 authentication pre-share
 group 2
crypto ipsec transform-set DMVPN ah-sha-hmac esp-aes 256 
 mode transport
crypto ipsec profile DMVPN
 set transform-set DMVPN 
interface Loopback0
 ip vrf forwarding Internet
 ip address 151.0.0.1 255.255.255.0
interface Tunnel0
 bandwidth 1544
 ip address 10.0.1.1 255.255.255.0
 no ip redirects
 ip mtu 1400
 ip nhrp authentication test123
 ip nhrp map multicast dynamic
 ip nhrp network-id 1234
 ip tcp adjust-mss 1360
 load-interval 30
 cdp enable
 tunnel source Loopback0
 tunnel mode gre multipoint
 tunnel key 12345
 tunnel vrf Internet
 tunnel protection ipsec profile DMVPN
interface Serial0/0.102 point-to-point
 ip vrf forwarding Internet
 ip address 150.0.0.2 255.255.255.252
 frame-relay interface-dlci 102   
router bgp 500
 no synchronization
 bgp log-neighbor-changes
 neighbor 10.0.1.2 remote-as 600
 neighbor 10.0.1.2 prefix-list TUN out
 no auto-summary
 !
 address-family ipv4 vrf Internet
  neighbor 150.0.0.1 remote-as 100
  neighbor 150.0.0.1 activate
  neighbor 150.0.0.1 send-community
  no synchronization
  network 151.0.0.0 mask 255.255.255.0
 exit-address-family
ip prefix-list BGP seq 5 permit 151.0.0.0/24
ip prefix-list TUN seq 5 permit 10.0.1.0/24

Here is my spoke config:

DMVPN-SPOKE1-R4#$interface Serial0/1/0|interface Tunnel0|interface Loopback0 
ip vrf Internet
 rd 600:1
crypto keyring DMVPN vrf Internet
  pre-shared-key address 0.0.0.0 0.0.0.0 key test123
crypto isakmp policy 10
 authentication pre-share
 group 2
crypto ipsec transform-set DMVPN ah-sha-hmac esp-aes 256 
 mode transport
crypto ipsec profile DMVPN
 set transform-set DMVPN 
interface Loopback0
 ip vrf forwarding Internet
 ip address 152.0.0.1 255.255.255.0
interface Tunnel0
 bandwidth 1544
 ip address 10.0.1.2 255.255.255.0
 no ip redirects
 ip mtu 1400
 ip nhrp authentication test123
 ip nhrp map multicast dynamic
 ip nhrp map 10.0.1.1 151.0.0.1
 ip nhrp map multicast 151.0.0.1
 ip nhrp network-id 1234
 ip nhrp nhs 10.0.1.1
 ip tcp adjust-mss 1360
 load-interval 30
 cdp enable
 tunnel source Loopback0
 tunnel mode gre multipoint
 tunnel key 12345
 tunnel vrf Internet
 tunnel protection ipsec profile DMVPN
interface Serial0/1/0
 ip vrf forwarding Internet
 ip address 150.0.0.10 255.255.255.252
 encapsulation ppp
 clock rate 1024000
router bgp 600
 no synchronization
 bgp router-id 152.0.0.1
 bgp log-neighbor-changes
 neighbor 10.0.1.1 remote-as 500
 neighbor 10.0.1.1 prefix-list TUN out
 no auto-summary
 !
 address-family ipv4 vrf Internet
  neighbor 150.0.0.9 remote-as 100
  neighbor 150.0.0.9 activate
  no synchronization
  network 152.0.0.0 mask 255.255.255.0
 exit-address-family
ip prefix-list BGP seq 5 permit 152.0.0.0/24
ip prefix-list TUN seq 5 permit 10.0.1.0/24

One of the scenarios that I wanted to play with was having BGP dynamically create peers. However, my specific version of code doesn’t support dynamic BGP peers. If my code did support it, the BGP config would look something like:

! Configuration for the HUB
router bgp 500
 neighbor spokes peer-group
 bgp listen range 10.0.1.0/24 peer-group spokes
 neighbor spokes remote-as 600
 neighbor spokes next-hop-self
 neighbor spokes send-community

! Configuration for the Spokes
router bgp 600
 neighbor 10.0.1.1 remote-as 500
 neighbor 10.0.1.1 allowas-in 1

Update:

I had an interesting idea. Having the hub’s and the spokes in the same BGP ASN. Having the DMVPN hubs act as BGP route reflectors and having the spoke connect to the hubs. As the hubs are route reflectors, they will propagate all routes about the spokes to all other spokes. In a DMVPN phase 2 scenario, this would allow the spokes to communicate next to each other as the spokes know about each other through BGP next-hop. I set it up in my lab and it actually works pretty well.

Here the BGP configuration from my hub:

DMVPN-HUB1-R1#sh run | s router bgp
router bgp 500
 template peer-policy spokes
  route-reflector-client
  soft-reconfiguration inbound
  send-community
 exit-peer-policy
 !
 template peer-session spokes
  remote-as 500
 exit-peer-session
 !
 no synchronization
 bgp cluster-id 10.0.1.1
 bgp log-neighbor-changes
 network 10.10.10.0 mask 255.255.255.0
 neighbor spokes peer-group
 neighbor 10.0.1.2 inherit peer-session spokes
 neighbor 10.0.1.2 inherit peer-policy spokes
 neighbor 10.0.1.3 inherit peer-session spokes
 neighbor 10.0.1.3 inherit peer-policy spokes
 no auto-summary
 !
 address-family ipv4 vrf Internet
  neighbor 150.0.0.1 remote-as 100
  neighbor 150.0.0.1 activate
  neighbor 150.0.0.1 send-community
  neighbor 150.0.0.1 allowas-in
  no synchronization
  network 151.0.0.0 mask 255.255.255.0
 exit-address-family

Here is the BGP configuration from one of my spokes:

DMVPN-SPOKE1-R4#sh run | s router bgp
router bgp 500
 template peer-policy hub
  prefix-list TUN out
  soft-reconfiguration inbound
  send-community
 exit-peer-policy
 !
 template peer-session hub
  remote-as 500
 exit-peer-session
 !
 no synchronization
 bgp log-neighbor-changes
 network 10.10.20.0 mask 255.255.255.0
 neighbor 10.0.1.1 inherit peer-session hub
 neighbor 10.0.1.1 inherit peer-policy hub
 no auto-summary
 !
 address-family ipv4 vrf Internet
  neighbor 150.0.0.9 remote-as 100
  neighbor 150.0.0.9 activate
  neighbor 150.0.0.9 send-community
  neighbor 150.0.0.9 allowas-in
  no synchronization
  network 152.0.0.0 mask 255.255.255.0
 exit-address-family

Here is the isakmp session status, BGP table, and trace route to a neighbor spoke from the DMVPN-SPOKE1-R4 spoke.

DMVPN-SPOKE1-R4#sh crypto isakmp sa
dst             src             state          conn-id slot status
151.0.0.1       152.0.0.1       QM_IDLE              1    0 ACTIVE
152.0.0.1       153.0.0.1       QM_IDLE              2    0 ACTIVE

DMVPN-SPOKE1-R4#sh ip bgp sum
BGP router identifier 10.10.20.1, local AS number 500
BGP table version is 14, main routing table version 14
3 network entries using 351 bytes of memory
3 path entries using 156 bytes of memory
6/2 BGP path/bestpath attribute entries using 744 bytes of memory
1 BGP rrinfo entries using 24 bytes of memory
2 BGP AS-PATH entries using 48 bytes of memory
0 BGP route-map cache entries using 0 bytes of memory
0 BGP filter-list cache entries using 0 bytes of memory
BGP using 1323 total bytes of memory
BGP activity 14/6 prefixes, 18/10 paths, scan interval 60 secs

Neighbor        V    AS MsgRcvd MsgSent   TblVer  InQ OutQ Up/Down  State/PfxRcd
10.0.1.1        4   500     263     252       14    0    0 03:42:25        2
DMVPN-SPOKE1-R4#sh ip bgp 
BGP table version is 14, local router ID is 10.10.20.1
Status codes: s suppressed, d damped, h history, * valid, > best, i - internal,
              r RIB-failure, S Stale
Origin codes: i - IGP, e - EGP, ? - incomplete

   Network          Next Hop            Metric LocPrf Weight Path
*>i10.10.10.0/24    10.0.1.1                 0    100      0 i
*> 10.10.20.0/24    0.0.0.0                  0         32768 i
*>i10.10.30.0/24    10.0.1.3                 0    100      0 i
DMVPN-SPOKE1-R4#ping 10.10.30.1

Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 10.10.30.1, timeout is 2 seconds:
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 4/13/24 ms
DMVPN-SPOKE1-R4#tracero
DMVPN-SPOKE1-R4#traceroute 10.10.30.1

Type escape sequence to abort.
Tracing the route to 10.10.30.1

  1 10.0.1.3 4 msec 4 msec * 

One way to make this scale, without manual intervention of having to add neighbor relationships in BGP would be to have the dynamic neighbor relations statement in the DMVPN hubs. In my lab set up, BGP works pretty well in a DMVPN environment.