Hi
Patch tested - looks better but there seems to remain a 'route inject'
issue on the spoke router (Cisco IOS).
NHRP Cache on hub:
quagga-router# sh ip nhrp cache
Iface Type Protocol NBMA
Flags Identity
tun1 local 10.0.0.1 - -
tun1 dynamic 10.0.0.3 178.197.232.6
UT 192.168.8.100
tun1 dynamic 10.0.0.2 194.209.75.35
UT 194.209.75.35
tun1 dynamic 10.0.0.4 194.209.75.37
UT 194.209.75.37 *** rem: cisco device ***
Registration for Cisco router (194.209.75.37) works fine :)
Ping to 10.0.0.4 is encapsulated correctly on hub ...
$ sudo tcpdump -i tun1 -n -c10 host 10.0.0.4
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on tun1, link-type LINUX_SLL (Linux cooked), capture size
262144 bytes
07:54:10.997424 IP 10.0.0.1 > 10.0.0.4: ICMP echo request, id 14763, seq
1, length 64
07:54:11.997530 IP 10.0.0.1 > 10.0.0.4: ICMP echo request, id 14763, seq
2, length 64
$ sudo tcpdump -i ens160 -n -c10 host 194.209.75.37
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on ens160, link-type EN10MB (Ethernet), capture size 262144 bytes
07:55:07.637959 IP 217.193.211.21 > 194.209.75.37:
ESP(spi=0x84308476,seq=0xd), length 136
07:55:08.637647 IP 217.193.211.21 > 194.209.75.37:
ESP(spi=0x84308476,seq=0xe), length 136
IPSec SA up and running
dmvpn: #154, ESTABLISHED, IKEv1, ca7cf85e9433ee25_i f2ed204c5f9e2296_r*
local '217.193.211.21' @ 217.193.211.21[500]
remote '194.209.75.37' @ 194.209.75.37[500]
AES_CBC-256/HMAC_SHA2_256_128/PRF_HMAC_SHA2_256/MODP_2048
established 370s ago, reauth in 45770s
dmvpn: #992, reqid 28, INSTALLED, TRANSPORT,
ESP:AES_CBC-256/HMAC_SHA2_256_128
installed 370s ago, rekeying in 3072s, expires in 3590s
in c638adaa, 96 bytes, 1 packets, 370s ago
out 1caf43f8, 644 bytes, 7 packets, 2s ago
local 217.193.211.21/32[gre]
remote 194.209.75.37/32[gre]
routing OK as well on hub side ...
$ ip route list
default via 217.193.211.17 dev ens160 onlink
10.0.0.2 dev tun1 proto zebra scope link metric 20
10.0.0.3 dev tun1 proto zebra scope link metric 20
10.0.0.4 dev tun1 proto zebra scope link metric 20
192.168.40.0/24 via 10.0.0.3 dev tun1 proto zebra metric 20
217.193.211.16/28 dev ens160 proto kernel scope link src 217.193.211.21
debug log on Cisco router
*May 22 06:06:24.681: NHRP: Setting retrans delay to 1 for nhs dst 10.0.0.1
*May 22 06:06:24.681: NHRP: nhrp_ifcache: Avl Root:0
*May 22 06:06:24.681: NHRP-MPLS: Could not find AVL node for tableid: 0
vrf:
*May 22 06:06:24.681: NHRP: Attempting to send packet through interface
Tunnel10 via DEST dst 10.0.0.4
*May 22 06:06:24.681: NHRP: Send Registration Request via Tunnel10 vrf
0, packet size: 92
*May 22 06:06:24.681: src: 10.0.0.4, dst: 10.0.0.4
*May 22 06:06:24.681: NHRP: Switching directly using pre-set NBMA
217.193.211.21
*May 22 06:06:24.681: NHRP: Encapsulation succeeded. Sending NHRP
Control Packet NBMA Address: 217.193.211.21
*May 22 06:06:24.681: NHRP: 116 bytes out Tunnel10
*May 22 06:06:24.681: NHRP-ATTR: ext_type: 32771, ext_len : 20
*May 22 06:06:24.681: NHRP-ATTR: ext_type: 32772, ext_len : 0
*May 22 06:06:24.681: NHRP-ATTR: ext_type: 32773, ext_len : 0
*May 22 06:06:24.681: NHRP-ATTR: ext_type: 9, ext_len : 20
*May 22 06:06:24.681: NHRP-ATTR: ext_type: 32768, ext_len : 0
*May 22 06:06:24.681: NHRP: Receive Registration Reply via Tunnel10 vrf
0, packet size: 112
*May 22 06:06:24.681: NHRP: netid_in = 0, to_us = 1
*May 22 06:06:24.681: NHRP: No NHRP subblock found in packet
*May 22 06:06:24.681: NHRP: nhrp_ifcache: Avl Root:0
*May 22 06:06:24.681: NHRP-MPLS: Could not find AVL node for tableid: 0
vrf:
*May 22 06:06:24.681: NHRP: Enqueued static mapping to start of list
*May 22 06:06:24.681: NHRP: Tu10: Creating nhs mapping for 10.0.0.1/32
NBMA: 217.193.211.21
*May 22 06:06:24.681: NHRP: nhrp_ifcache: Avl Root:0
*May 22 06:06:24.681: NHRP-MPLS: Could not find AVL node for tableid: 0
vrf:
*May 22 06:06:24.681: NHRP: NHRP AVL root is NULL
*May 22 06:06:24.681: NHRP-MPLS: Inserted AVL node tableid: 0 vrf:
*May 22 06:06:24.681: NHRP-MPLS: Success: initialized cache radix tree
head tableid: 0 vrf:
*May 22 06:06:24.681: NHRP: Attempting to create instance PDB for (0x0)
*May 22 06:06:24.681: NHRP: Initialized cache with AVL root:2C69D948
*May 22 06:06:24.681: NHRP: swidb Tunnel10, nhrp_cache_update
*May 22 06:06:24.681: NHRP-MPLS: tableid: 0 vrf:
*May 22 06:06:24.681: NHRP: nhrp_ifcache: Avl Root:2C69D948
*May 22 06:06:24.681: NHRP: Tunnel10: Cache add for target 10.0.0.1/32
next-hop 10.0.0.1
*May 22 06:06:24.681: 217.193.211.21
*May 22 06:06:24.681: NHRP: nhrp_ifcache: Avl Root:2C69D948
*May 22 06:06:24.681: NHRP: Adding Tunnel Endpoints (VPN: 10.0.0.1,
NBMA: 217.193.211.21)
*May 22 06:06:24.685: NHRP: Successfully attached NHRP subblock for
Tunnel Endpoints (VPN: 10.0.0.1, NBMA: 217.193.211.21)
*May 22 06:06:24.685: NHRP: No peer data updated in NHRP subblock for
Tunnel Endpoints (VPN: 10.0.0.1, NBMA: 217.193.211.21)
*May 22 06:06:24.685: NHRP: Inserted subblock node for cache: Target
10.0.0.1/32 nhop 10.0.0.1
*May 22 06:06:24.685: NHRP: Converted internal static cache entry for
10.0.0.1/32 interface Tunnel10 to external
*May 22 06:06:24.685: NHRP-MPLS: tableid: 0 vrf:
*May 22 06:06:24.685: NHRP: nhrp_ifcache: Avl Root:2C69D948
*May 22 06:06:24.685: NHRP: NHS-UP: 10.0.0.1
*May 22 06:06:24.685: NHRP: nhrp_ifcache: Avl Root:2C69D948
*May 22 06:06:24.685: NHRP: nhrp_ifcache: Avl Root:2C69D948
*May 22 06:06:24.685: NHRP: Updating our cache with NBMA:
217.193.211.21, NBMA_ALT: 194.209.75.37
NHRP route on Cisco router seems to be missing...
#sh ip route
Codes: L - local, C - connected, S - static, R - RIP, M - mobile, B - BGP
D - EIGRP, EX - EIGRP external, O - OSPF, IA - OSPF inter area
N1 - OSPF NSSA external type 1, N2 - OSPF NSSA external type 2
E1 - OSPF external type 1, E2 - OSPF external type 2
i - IS-IS, su - IS-IS summary, L1 - IS-IS level-1, L2 - IS-IS level-2
ia - IS-IS inter area, * - candidate default, U - per-user static
route
o - ODR, P - periodic downloaded static route, H - NHRP, l - LISP
a - application route
+ - replicated route, % - next hop override
Gateway of last resort is 194.209.75.33 to network 0.0.0.0
S* 0.0.0.0/0 [1/0] via 194.209.75.33
10.0.0.0/32 is subnetted, 1 subnets
C 10.0.0.4 is directly connected, Tunnel10
194.209.75.0/24 is variably subnetted, 2 subnets, 2 masks
C 194.209.75.32/28 is directly connected, GigabitEthernet0/0
L 194.209.75.37/32 is directly connected, GigabitEthernet0/0
my 2cents ...
/pat
Post by Timo TerasHi,
Can you test the patch in the end of the mail.
Thanks,
Timo
On Wed, 3 May 2017 06:32:35 +0200
thanks for your reply
sample cisco nhrp capture in attachment
first two packets are cisco - second two packets are quagga
Post by Timo TerasHi,
On Mon, 1 May 2017 07:21:26 +0200
Post by Patrick OeschgerAnybody with experience in connecting Cisco IOS to Quagga NHRPD?
I did extensive testing of opennhrp vs. Cisco, but quagga/nhrp is
mostly tested against itself and opennhrp only. I have not had
opportunity to do testing against Cisco, so this is good info.
Post by Patrick OeschgerAnother Linux box connects to DMVPN hub without any issues.
Config should be fine but there seems to be an incompatibility
between Quagga and IOS.
Any inputs/experiences with this issue?
Just saw one thing in source code ... quagga expects prefix 0xff
and IOS seems to report prefix 0x20 (32)
Happy to help dev and test patches if needed :)
Your observation is correct. This makes the difference. RFC2332
states that if prefix length must be set to 0xff if unique bit is
set - and now reading the code I must've been writing only the
unique mode handling. Since that is usually the desired
functionality.
Now looking at your Cisco config (there's no "ip nhrp registration
non-unique"), the unique bit should be set, and prefix length
should be 0xff. So Cisco might be breaking RFC here. Perhaps you
could get a packet capture to display what's going on?
opennhrp did handle 0xff and a host sized prefix length equally. So
perhaps we should do same in quagga/nhrp.
Quagga/NHRP could also be improved to handle non-unique things. This
seems to be requirement since Cisco expects this mode if the spoke
is having a dynamic IP that may change often. Cisco treats
non-unique mode as "replace the previous IP".
Subject: [PATCH] nhrp: improve CIE prefix length handling
RFC2332 states that prefix length MUST be 0xff for unique bindings.
However, it seems at least some Cisco firmwares use host prefix
length instead (which on wire level makes sense). Relax the handling
of prefix length to treat all value longer than address length as
0xff. Additionally treat 0x00 the same way too, this is required
by the RFC. This also fixes the prefix length address family to be
checked against protocol address.
---
nhrpd/nhrp_nhs.c | 2 +-
nhrpd/nhrp_peer.c | 11 ++++++++---
nhrpd/nhrp_shortcut.c | 2 +-
3 files changed, 10 insertions(+), 5 deletions(-)
diff --git a/nhrpd/nhrp_nhs.c b/nhrpd/nhrp_nhs.c
index 7a5d2393..535f9559 100644
--- a/nhrpd/nhrp_nhs.c
+++ b/nhrpd/nhrp_nhs.c
@@ -181,7 +181,7 @@ static int nhrp_reg_send_req(struct thread *t)
hdr->flags |= htons(NHRP_FLAG_REGISTRATION_NAT);
ext = nhrp_ext_push(zb, hdr, NHRP_EXTENSION_NAT_ADDRESS);
cie = nhrp_cie_push(zb, NHRP_CODE_SUCCESS, &nifp->nbma, &if_ad->addr);
- cie->prefix_length = 8 * sockunion_get_addrlen(&nifp->nbma);
+ cie->prefix_length = 8 * sockunion_get_addrlen(&if_ad->addr);
nhrp_ext_complete(zb, ext);
nhrp_packet_complete(zb, hdr);
diff --git a/nhrpd/nhrp_peer.c b/nhrpd/nhrp_peer.c
index 728fa1c4..5095d55a 100644
--- a/nhrpd/nhrp_peer.c
+++ b/nhrpd/nhrp_peer.c
@@ -383,11 +383,12 @@ static void nhrp_handle_registration_request(struct nhrp_packet_parser *p)
struct nhrp_extension_header *ext;
struct nhrp_cache *c;
union sockunion cie_nbma, cie_proto, *proto_addr, *nbma_addr, *nbma_natoa;
- int holdtime, natted = 0;
+ int holdtime, prefix_len, hostprefix_len, natted = 0;
size_t paylen;
void *pay;
debugf(NHRP_DEBUG_COMMON, "Parsing and replying to Registration Req");
+ hostprefix_len = 8 * sockunion_get_addrlen(&p->if_ad->addr);
if (!sockunion_same(&p->src_nbma, &p->peer->vc->remote.nbma))
natted = 1;
@@ -409,13 +410,17 @@ static void nhrp_handle_registration_request(struct nhrp_packet_parser *p)
zbuf_init(&payload, pay, paylen, paylen);
while ((cie = nhrp_cie_pull(&payload, hdr, &cie_nbma, &cie_proto)) != NULL) {
- if (cie->prefix_length != 0xff && !(p->hdr->flags & htons(NHRP_FLAG_REGISTRATION_UNIQUE))) {
+ prefix_len = cie->prefix_length;
+ if (prefix_len == 0 || prefix_len >= hostprefix_len)
+ prefix_len = hostprefix_len;
+
+ if (prefix_len != hostprefix_len && !(p->hdr->flags & htons(NHRP_FLAG_REGISTRATION_UNIQUE))) {
cie->code = NHRP_CODE_BINDING_NON_UNIQUE;
continue;
}
/* We currently support only unique prefix registrations */
- if (cie->prefix_length != 0xff) {
+ if (prefix_len != hostprefix_len) {
cie->code = NHRP_CODE_ADMINISTRATIVELY_PROHIBITED;
continue;
}
diff --git a/nhrpd/nhrp_shortcut.c b/nhrpd/nhrp_shortcut.c
index 421f2886..60c63929 100644
--- a/nhrpd/nhrp_shortcut.c
+++ b/nhrpd/nhrp_shortcut.c
@@ -224,7 +224,7 @@ static void nhrp_shortcut_recv_resolution_rep(struct nhrp_reqid *reqid, void *ar
prefix.prefixlen = cie->prefix_length;
/* Sanity check prefix length */
- if (prefix.prefixlen >= 8*prefix_blen(&prefix)) {
+ if (prefix.prefixlen >= 8*prefix_blen(&prefix) || prefix.prefixlen == 0) {
prefix.prefixlen = 8*prefix_blen(&prefix);
} else if (nhrp_route_address(NULL, &pp->dst_proto, &route_prefix, NULL) == NHRP_ROUTE_NBMA_NEXTHOP) {
if (prefix.prefixlen < route_prefix.prefixlen)