DMVPN hub stops registering peers after any NHRP configuration modification

Hi!
I discovered that modification of any settings in the NHRP section triggers the issue which prevent recently registered spokes from registering again.

HUB:

set protocols nhrp tunnel tun1 cisco-authentication ‘LPDMVPN’
set protocols nhrp tunnel tun1 holding-time ‘300’
set protocols nhrp tunnel tun1 multicast ‘dynamic’

SPOKE:

set protocols nhrp tunnel tun10 cisco-authentication ‘LPDMVPN’
set protocols nhrp tunnel tun10 holding-time ‘300’
set protocols nhrp tunnel tun10 map 10.160.17.131/25 nbma-address ‘192.168.77.66’
set protocols nhrp tunnel tun10 map 10.160.17.131/25 register
set protocols nhrp tunnel tun10 multicast ‘nhs’

vyos@S1:~$ show nhrp tu
Status: ok

Interface: tun10
Type: local
Protocol-Address: 10.160.17.255/32
Alias-Address: 10.160.17.141
Flags: up

Interface: tun10
Type: local
Protocol-Address: 10.160.17.141/32
Flags: up

Interface: tun10
Type: static
Protocol-Address: 10.160.17.131/25
NBMA-Address: 192.168.77.66
Flags: up

Steps to reproduce on HUB:
**1. **
register a spoke;
**2. **
set protocols nhrp tunnel tun1 holding-time ‘200’
commit
set protocols nhrp tunnel tun1 holding-time ‘300’
commit
3. The spoke is out:

vyos@S1:~$ show nhrp tu
Status: ok

Interface: tun10
Type: local
Protocol-Address: 10.160.17.255/32
Alias-Address: 10.160.17.141
Flags: up

Interface: tun10
Type: local
Protocol-Address: 10.160.17.141/32
Flags: up

Interface: tun10
Type: incomplete
Protocol-Address: 10.160.17.151/32
Flags: used

Interface: tun10
Type: static
Protocol-Address: 10.160.17.131/25
NBMA-Address: 192.168.77.66
Flags: up

Hub logs:

Apr 21 18:32:31 opennhrp[9878]: Received Registration Request from proto src 10.160.17.151 to 10.160.17.131
Apr 21 18:32:31 opennhrp[9878]: [10.160.17.151] Peer registration failed: static entry exists
Apr 21 18:32:31 opennhrp[9878]: Sending Registration Reply from proto src 10.160.17.131 to 10.160.17.151 (0 bindings accepted, 1 rejected)
Apr 21 18:32:31 opennhrp[9878]: Sending packet 4, from: 10.160.17.151 (nbma 192.168.77.65), to: 10.160.17.131 (nbma 192.168.77.65)
Apr 21 18:32:32 opennhrp[9878]: NL-ARP(tun1) who-has 10.160.17.151
Apr 21 18:32:32 opennhrp[9878]: NL-ARP(tun1) who-has 10.160.17.141
Apr 21 18:32:33 opennhrp[9878]: NL-ARP(tun1) who-has 10.160.17.151
Apr 21 18:32:34 opennhrp[9878]: NL-ARP(tun1) who-has 10.160.17.141
Apr 21 18:32:34 opennhrp[9878]: NL-ARP(tun1) who-has 10.160.17.151
Apr 21 18:32:35 opennhrp[9878]: NL-ARP(tun1) who-has 10.160.17.151
Apr 21 18:32:35 opennhrp[9878]: NL-ARP(tun1) who-has 10.160.17.141
Apr 21 18:32:36 opennhrp[9878]: NL-ARP(tun1) who-has 10.160.17.151
Apr 21 18:32:36 opennhrp[9878]: Received Registration Request from proto src 10.160.17.141 to 10.160.17.131
Apr 21 18:32:36 opennhrp[9878]: [10.160.17.141] Peer registration failed: static entry exists
Apr 21 18:32:36 opennhrp[9878]: Sending Registration Reply from proto src 10.160.17.131 to 10.160.17.141 (0 bindings accepted, 1 rejected)
Apr 21 18:32:36 opennhrp[9878]: Sending packet 4, from: 10.160.17.141 (nbma 192.168.77.64), to: 10.160.17.131 (nbma 192.168.77.64)
Apr 21 18:32:37 opennhrp[9878]: NL-ARP(tun1) who-has 10.160.17.141
Apr 21 18:32:37 opennhrp[9878]: NL-ARP(tun1) who-has 10.160.17.151
Apr 21 18:32:38 opennhrp[9878]: NL-ARP(tun1) who-has 10.160.17.151
Apr 21 18:32:38 opennhrp[9878]: NL-ARP(tun1) who-has 10.160.17.141
Apr 21 18:32:39 opennhrp[9878]: NL-ARP(tun1) who-has 10.160.17.151
Apr 21 18:32:40 opennhrp[9878]: NL-ARP(tun1) who-has 10.160.17.141
Apr 21 18:32:40 opennhrp[9878]: NL-ARP(tun1) who-has 10.160.17.151
Apr 21 18:32:41 opennhrp[9878]: NL-ARP(tun1) who-has 10.160.17.151
Apr 21 18:32:41 opennhrp[9878]: NL-ARP(tun1) who-has 10.160.17.141

By googling and searching through logs I found a workaround. The HUB survives configuration modification if I edit the openNHRP.conf and explicitly define a routing table which tunnel interface belongs to:

sudo nano /usr/share/vyos/templates/nhrp/opennhrp.conf.j2:

{% if tunnel is vyos_defined %}
{% for name, tunnel_conf in tunnel.items() %}
{% set type = ‘spoke’ if tunnel_conf.map is vyos_defined or tunnel_conf.dynamic_map is vyos_defined else ‘hub’ %}
{% set profile_name = profile_map[name] if profile_map is vyos_defined and name in profile_map else ‘’ %}
interface {{ name }} #{{ type }} {{ profile_name }}
route-table 254
{% if tunnel_conf.map is vyos_defined %}
{% for map, map_conf in tunnel_conf.map.items() %}
{% set cisco = ’ cisco’ if map_conf.cisco is vyos_defined else ‘’ %}

Looks like it works, but it won’t persist through updates. Any ideas how solve it?

Versions that i’ve tested on:
1: 1.4-rolling-202304130846 - latest
2: 1.4-rolling-202211290318
3: 1.4-rolling-202301280924
4. Some 1.3x stable a couple of month ago. I can’t remember exactly, but it was quite the same.

Could you open a bug report and solution on https://vyos.dev/ ?
All changes should be done based on task
Thanks

Sure, I’ll do. I am not sure that the solution I found is 100% correct, though.

tested on 1.3.2. Needs fix too.