diff options
author | Amol Lad <amol.lad@4rf.com> | 2021-02-24 12:08:29 +0100 |
---|---|---|
committer | Reuben Dowle <reuben.dowle@4rf.com> | 2021-03-18 04:35:41 +0100 |
commit | 9c292647a94df1e224dc89d5d73c3c54b994f6f5 (patch) | |
tree | ded4ae2e4aed20c9960402fc6b340d6b365096c0 /nhrpd | |
parent | nhrpd: Add empty NAT extension header for Non Natted Spoke in Resolution-Reply (diff) | |
download | frr-9c292647a94df1e224dc89d5d73c3c54b994f6f5.tar.xz frr-9c292647a94df1e224dc89d5d73c3c54b994f6f5.zip |
nhrpd: parse multiple CIEs in NAT extension header
Cisco devices send can send multiple CIEs so we must search for the correct CIE
Signed-off-by: Reuben Dowle <reuben.dowle@4rf.com>
Diffstat (limited to 'nhrpd')
-rw-r--r-- | nhrpd/nhrp_shortcut.c | 43 |
1 files changed, 24 insertions, 19 deletions
diff --git a/nhrpd/nhrp_shortcut.c b/nhrpd/nhrp_shortcut.c index 32a7ccbc9..fd86ab996 100644 --- a/nhrpd/nhrp_shortcut.c +++ b/nhrpd/nhrp_shortcut.c @@ -212,7 +212,7 @@ static void nhrp_shortcut_recv_resolution_rep(struct nhrp_reqid *reqid, struct nhrp_cie_header *cie; struct nhrp_cache *c = NULL; struct nhrp_cache *c_dst_proto = NULL; - union sockunion *proto, cie_proto, *nbma, cie_nbma, nat_nbma, cie_proto_nat_ext; + union sockunion *proto, cie_proto, *nbma, cie_nbma, nat_nbma; struct prefix prefix, route_prefix; struct zbuf extpl; char buf[4][SU_ADDRSTRLEN]; @@ -237,17 +237,6 @@ static void nhrp_shortcut_recv_resolution_rep(struct nhrp_reqid *reqid, return; } - - /* Parse extensions */ - memset(&nat_nbma, 0, sizeof(nat_nbma)); - while ((ext = nhrp_ext_pull(&pp->extensions, &extpl)) != NULL) { - switch (htons(ext->type) & ~NHRP_EXTENSION_FLAG_COMPULSORY) { - case NHRP_EXTENSION_NAT_ADDRESS: - nhrp_cie_pull(&extpl, pp->hdr, &nat_nbma, &cie_proto_nat_ext); - break; - } - } - /* Minor sanity check */ prefix2sockunion(s->p, &cie_proto); if (!sockunion_same(&cie_proto, &pp->dst_proto)) { @@ -283,17 +272,33 @@ static void nhrp_shortcut_recv_resolution_rep(struct nhrp_reqid *reqid, prefix.prefixlen = route_prefix.prefixlen; } + /* Parse extensions */ + memset(&nat_nbma, 0, sizeof(nat_nbma)); + while ((ext = nhrp_ext_pull(&pp->extensions, &extpl)) != NULL) { + switch (htons(ext->type) & ~NHRP_EXTENSION_FLAG_COMPULSORY) { + case NHRP_EXTENSION_NAT_ADDRESS: { + struct nhrp_cie_header *cie_nat; + do { + union sockunion cie_nat_proto, cie_nat_nbma; + sockunion_family(&cie_nat_proto) = AF_UNSPEC; + sockunion_family(&cie_nat_nbma) = AF_UNSPEC; + cie_nat = nhrp_cie_pull(&extpl, pp->hdr, &cie_nat_nbma, &cie_nat_proto); + /* We are interested only in peer CIE */ + if (cie_nat && sockunion_same(&cie_nat_proto, proto)) { + nat_nbma = cie_nat_nbma; + } + } while (cie_nat); + } break; + default: + break; + } + } + /* Update cache entry for the protocol to nbma binding */ if (sockunion_family(&nat_nbma) != AF_UNSPEC) { debugf(NHRP_DEBUG_COMMON,"Remote Device is NATTED, NHRP NAT Extension present"); - debugf(NHRP_DEBUG_COMMON,"Client Protocol Address %s", sockunion2str(&cie_proto_nat_ext, buf[1], sizeof(buf[1]))); debugf(NHRP_DEBUG_COMMON,"Client NBMA Address %s", sockunion2str(&nat_nbma, buf[1], sizeof(buf[1]))); - if (!sockunion_same(&cie_proto_nat_ext, proto)) { - debugf(NHRP_DEBUG_COMMON,"NHRP NAT extension does not match proto %s", sockunion2str(proto, buf[0], sizeof(buf[0]))); - nbma = &cie_nbma; - } else { - nbma = &nat_nbma; - } + nbma = &nat_nbma; } /* For NHRP resolution reply the cie_nbma in mandatory part is the address of the actual address of the sender */ else if (!sockunion_same(&cie_nbma, &pp->peer->vc->remote.nbma) && !nhrp_nhs_match_ip(&pp->peer->vc->remote.nbma, nifp)) { |