]> git.puffer.fish Git - matthieu/frr.git/commitdiff
nhrp: improve CIE prefix length handling
authorTimo Teräs <timo.teras@iki.fi>
Wed, 17 May 2017 22:36:07 +0000 (18:36 -0400)
committerDonald Sharp <sharpd@cumulusnetworks.com>
Wed, 17 May 2017 22:36:39 +0000 (18:36 -0400)
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.
Signed-off-by: Timo Teräs <timo.teras@iki.fi>
nhrpd/nhrp_nhs.c
nhrpd/nhrp_peer.c
nhrpd/nhrp_shortcut.c

index b926a8d7b25dd915a93ab74df1ce0e3697b5aa4d..76c591fd7997a0c11152acbbfe5f4b5f69ad00c8 100644 (file)
@@ -189,7 +189,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);
index 5f1e43a6084d7de6310b886aef5b1c7cff414064..d9e8627a14e4173e29cc4e2c08d9145bd62713ef 100644 (file)
@@ -386,11 +386,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;
@@ -412,13 +413,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;
                }
index 4a6cbce31fda0b84eb28730e7d2e642db1cddb8c..4faa9d786368082116070d62a4aa0d677c200ae3 100644 (file)
@@ -228,7 +228,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)