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.
Signed-off-by: Timo Teräs <timo.teras@iki.fi>
This commit is contained in:
Timo Teräs 2017-05-17 18:36:07 -04:00 committed by Donald Sharp
parent d258c885bd
commit 55fd6ee9ca
3 changed files with 10 additions and 5 deletions

View 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);

View 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;
}

View 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)