[quagga-dev 16610] Re: Quagga NHRPD / Cisco IOS 15.5(2)T

Timo Teras timo.teras at iki.fi
Wed May 3 06:46:11 BST 2017


Hi,

Can you test the patch in the end of the mail.

Thanks,
Timo

On Wed, 3 May 2017 06:32:35 +0200
Patrick Oeschger <patrick.oeschger at bluewin.ch> wrote:

> thanks for your reply
> sample cisco nhrp capture in attachment
> first two packets are cisco - second two packets are quagga
> 
> On 01.05.2017 07:39, Timo Teras wrote:
> > Hi,
> >
> > On Mon, 1 May 2017 07:21:26 +0200
> > Patrick Oeschger <patrick.oeschger at bluewin.ch> wrote:
> >
> >> Anybody 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.
> >
> >> Another 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)
-- 
2.12.2



More information about the Quagga-dev mailing list