summaryrefslogtreecommitdiffstats
path: root/nhrpd/nhrp_peer.c
diff options
context:
space:
mode:
Diffstat (limited to 'nhrpd/nhrp_peer.c')
-rw-r--r--nhrpd/nhrp_peer.c235
1 files changed, 154 insertions, 81 deletions
diff --git a/nhrpd/nhrp_peer.c b/nhrpd/nhrp_peer.c
index dfede1d7d..9899b4fa0 100644
--- a/nhrpd/nhrp_peer.c
+++ b/nhrpd/nhrp_peer.c
@@ -183,8 +183,7 @@ static void *nhrp_peer_create(void *data)
.ref = 0,
.ifp = key->ifp,
.vc = key->vc,
- .notifier_list =
- NOTIFIER_LIST_INITIALIZER(&p->notifier_list),
+ .notifier_list = NOTIFIER_LIST_INITIALIZER(&p->notifier_list),
};
nhrp_vc_notify_add(p->vc, &p->vc_notifier, nhrp_peer_vc_notify);
nhrp_interface_notify_add(p->ifp, &p->ifp_notifier,
@@ -293,15 +292,19 @@ static int nhrp_peer_defer_vici_request(struct thread *t)
char buf[256];
THREAD_OFF(p->t_timer);
- if(p->online) {
- debugf(NHRP_DEBUG_COMMON, "IPsec connection to %s already established\n", sockunion2str(&vc->remote.nbma, buf, sizeof(buf)) ? buf : "NULL");
- }
- else {
- vici_request_vc(nifp->ipsec_profile, &vc->local.nbma, &vc->remote.nbma,
- p->prio);
- thread_add_timer(master, nhrp_peer_request_timeout, p,
- (nifp->ipsec_fallback_profile && !p->prio) ? 15 : 30,
- &p->t_fallback);
+ if (p->online) {
+ debugf(NHRP_DEBUG_COMMON,
+ "IPsec connection to %s already established\n",
+ sockunion2str(&vc->remote.nbma, buf, sizeof(buf))
+ ? buf
+ : "NULL");
+ } else {
+ vici_request_vc(nifp->ipsec_profile, &vc->local.nbma,
+ &vc->remote.nbma, p->prio);
+ thread_add_timer(
+ master, nhrp_peer_request_timeout, p,
+ (nifp->ipsec_fallback_profile && !p->prio) ? 15 : 30,
+ &p->t_fallback);
}
return 0;
}
@@ -329,20 +332,24 @@ int nhrp_peer_check(struct nhrp_peer *p, int establish)
p->prio = establish > 1;
p->requested = 1;
- //All NHRP registration requests are prioritized
- if(p->prio)
- {
- vici_request_vc(nifp->ipsec_profile, &vc->local.nbma, &vc->remote.nbma,
- p->prio);
- thread_add_timer(master, nhrp_peer_request_timeout, p,
- (nifp->ipsec_fallback_profile && !p->prio) ? 15 : 30,
- &p->t_fallback);
- }
- else
- {
- int r_time_ms = rand() % 1000; //Maximum timeout is 1 seconds
- debugf(NHRP_DEBUG_COMMON, "Initiating IPsec connection request to %s after %d ms:\n", sockunion2str(&vc->remote.nbma, buf, sizeof(buf)) ? buf : "NULL", r_time_ms);
- thread_add_timer_msec(master, nhrp_peer_defer_vici_request, p, r_time_ms, &p->t_timer);
+ /* All NHRP registration requests are prioritized */
+ if (p->prio) {
+ vici_request_vc(nifp->ipsec_profile, &vc->local.nbma,
+ &vc->remote.nbma, p->prio);
+ thread_add_timer(
+ master, nhrp_peer_request_timeout, p,
+ (nifp->ipsec_fallback_profile && !p->prio) ? 15 : 30,
+ &p->t_fallback);
+ } else {
+ int r_time_ms = rand() % 1000; // Maximum timeout is 1 seconds
+ debugf(NHRP_DEBUG_COMMON,
+ "Initiating IPsec connection request to %s after %d ms:\n",
+ sockunion2str(&vc->remote.nbma, buf, sizeof(buf))
+ ? buf
+ : "NULL",
+ r_time_ms);
+ thread_add_timer_msec(master, nhrp_peer_defer_vici_request,
+ p, r_time_ms, &p->t_timer);
}
return 0;
@@ -376,7 +383,9 @@ void nhrp_peer_send(struct nhrp_peer *p, struct zbuf *zb)
zbuf_reset(zb);
}
-static void nhrp_process_nat_extension(struct nhrp_packet_parser *pp, union sockunion *proto, union sockunion *cie_nbma)
+static void nhrp_process_nat_extension(struct nhrp_packet_parser *pp,
+ union sockunion *proto,
+ union sockunion *cie_nbma)
{
char buf[2][256];
union sockunion cie_proto;
@@ -385,31 +394,46 @@ static void nhrp_process_nat_extension(struct nhrp_packet_parser *pp, union sock
struct zbuf *extensions;
- if(!proto || !cie_nbma || sockunion_family(proto) == AF_UNSPEC)
+ if (!proto || !cie_nbma || sockunion_family(proto) == AF_UNSPEC)
return;
sockunion_family(cie_nbma) = AF_UNSPEC;
/* Handle extensions */
extensions = zbuf_alloc(zbuf_used(&pp->extensions));
- if(extensions)
- {
- zbuf_copy_peek(extensions, &pp->extensions, zbuf_used(&pp->extensions));
+ if (extensions) {
+ zbuf_copy_peek(extensions, &pp->extensions,
+ zbuf_used(&pp->extensions));
while ((ext = nhrp_ext_pull(extensions, &payload)) != NULL) {
- switch (htons(ext->type) & ~NHRP_EXTENSION_FLAG_COMPULSORY) {
+ switch (htons(ext->type)
+ & ~NHRP_EXTENSION_FLAG_COMPULSORY) {
case NHRP_EXTENSION_NAT_ADDRESS:
- /* Process the NBMA and proto address in NAT extension and update the cache
- * without which the neighbor table in the kernel contains the source NBMA address
- * which is not reachable since it is behind a NAT device */
- debugf(NHRP_DEBUG_COMMON,"Processing NAT Extension for %s", sockunion2str(proto, buf[0], sizeof(buf[0])) ? buf[0] : "NULL");
- while (nhrp_cie_pull(&payload, pp->hdr, cie_nbma, &cie_proto))
- {
- if(sockunion_family(&cie_proto) == AF_UNSPEC)
+ /* Process the NBMA and proto address in NAT
+ * extension and update the cache without which
+ * the neighbor table in the kernel contains the
+ * source NBMA address which is not reachable
+ * since it is behind a NAT device */
+ debugf(NHRP_DEBUG_COMMON,
+ "Processing NAT Extension for %s",
+ sockunion2str(proto, buf[0],
+ sizeof(buf[0]))
+ ? buf[0]
+ : "NULL");
+ while (nhrp_cie_pull(&payload, pp->hdr,
+ cie_nbma, &cie_proto)) {
+ if (sockunion_family(&cie_proto)
+ == AF_UNSPEC)
continue;
- if(!sockunion_cmp(proto, &cie_proto))
- {
- debugf(NHRP_DEBUG_COMMON,"cie_nbma for proto %s is %s", buf[0] ? buf[0] : "NULL", sockunion2str(cie_nbma, buf[1], sizeof(buf[1])) ? buf[1] : "NULL");
+ if (!sockunion_cmp(proto, &cie_proto)) {
+ debugf(NHRP_DEBUG_COMMON,
+ "cie_nbma for proto %s is %s",
+ buf[0] ? buf[0] : "NULL",
+ sockunion2str(
+ cie_nbma, buf[1],
+ sizeof(buf[1]))
+ ? buf[1]
+ : "NULL");
break;
}
}
@@ -427,7 +451,8 @@ static void nhrp_handle_resolution_req(struct nhrp_packet_parser *pp)
struct nhrp_cie_header *cie;
struct nhrp_extension_header *ext;
struct nhrp_cache *c;
- union sockunion cie_nbma, cie_nbma_nat, cie_proto, *proto_addr, *nbma_addr, *claimed_nbma_addr;
+ union sockunion cie_nbma, cie_nbma_nat, cie_proto, *proto_addr,
+ *nbma_addr, *claimed_nbma_addr;
int holdtime, prefix_len, hostprefix_len;
struct nhrp_interface *nifp = ifp->info;
struct nhrp_peer *peer;
@@ -486,31 +511,43 @@ static void nhrp_handle_resolution_req(struct nhrp_packet_parser *pp)
? &pp->src_proto
: &cie_proto;
- /* Check if there is an entry for this proto_addr in NHRP_NAT_EXTENSION */
+ /* Check if there is an entry for this proto_addr in
+ * NHRP_NAT_EXTENSION */
nhrp_process_nat_extension(pp, proto_addr, &cie_nbma_nat);
- if(sockunion_family(&cie_nbma_nat) == AF_UNSPEC)
- {
- /* It may be possible that this resolution reply is coming directly from NATTED Spoke
- * and there is not NAT Extension present */
- debugf(NHRP_DEBUG_COMMON,"No NAT Extension for %s", sockunion2str(proto_addr, buf, sizeof(buf)) ? buf : "NULL");
-
- if (!sockunion_same(&pp->src_nbma, &pp->peer->vc->remote.nbma) && !nhrp_nhs_match_ip(&pp->peer->vc->remote.nbma, nifp))
- {
- debugf(NHRP_DEBUG_COMMON,"Remote Device is NATTED");
+ if (sockunion_family(&cie_nbma_nat) == AF_UNSPEC) {
+ /* It may be possible that this resolution reply is
+ * coming directly from NATTED Spoke and there is not
+ * NAT Extension present */
+ debugf(NHRP_DEBUG_COMMON, "No NAT Extension for %s",
+ sockunion2str(proto_addr, buf, sizeof(buf))
+ ? buf
+ : "NULL");
+
+ if (!sockunion_same(&pp->src_nbma,
+ &pp->peer->vc->remote.nbma)
+ && !nhrp_nhs_match_ip(&pp->peer->vc->remote.nbma,
+ nifp)) {
+ debugf(NHRP_DEBUG_COMMON,
+ "Remote Device is NATTED");
cie_nbma_nat = pp->peer->vc->remote.nbma;
- debugf(NHRP_DEBUG_COMMON,"Device is natted using %s as cie_nbma", sockunion2str(&cie_nbma_nat, buf, sizeof(buf)) ? buf : "NULL");
+ debugf(NHRP_DEBUG_COMMON,
+ "Device is natted using %s as cie_nbma",
+ sockunion2str(&cie_nbma_nat, buf,
+ sizeof(buf))
+ ? buf
+ : "NULL");
}
}
- if(sockunion_family(&cie_nbma_nat) != AF_UNSPEC)
+ if (sockunion_family(&cie_nbma_nat) != AF_UNSPEC)
nbma_addr = &cie_nbma_nat;
- else if(sockunion_family(&cie_nbma) != AF_UNSPEC)
+ else if (sockunion_family(&cie_nbma) != AF_UNSPEC)
nbma_addr = &cie_nbma;
else
nbma_addr = &pp->src_nbma;
- if(sockunion_family(&cie_nbma) != AF_UNSPEC)
+ if (sockunion_family(&cie_nbma) != AF_UNSPEC)
claimed_nbma_addr = &cie_nbma;
else
claimed_nbma_addr = &pp->src_nbma;
@@ -536,9 +573,10 @@ static void nhrp_handle_resolution_req(struct nhrp_packet_parser *pp)
debugf(NHRP_DEBUG_COMMON,
"shortcut res_rep: updating binding for nmba addr %s",
nbma_addr ? buf : "(NULL)");
- if (!nhrp_cache_update_binding(c, NHRP_CACHE_DYNAMIC, holdtime,
- nhrp_peer_get(pp->ifp, nbma_addr),
- htons(cie->mtu), nbma_addr, claimed_nbma_addr)) {
+ if (!nhrp_cache_update_binding(
+ c, NHRP_CACHE_DYNAMIC, holdtime,
+ nhrp_peer_get(pp->ifp, nbma_addr), htons(cie->mtu),
+ nbma_addr, claimed_nbma_addr)) {
cie->code = NHRP_CODE_ADMINISTRATIVELY_PROHIBITED;
continue;
}
@@ -580,7 +618,8 @@ static void nhrp_handle_resolution_req(struct nhrp_packet_parser *pp)
goto err;
if (sockunion_family(&nifp->nat_nbma) != AF_UNSPEC) {
cie = nhrp_cie_push(zb, NHRP_CODE_SUCCESS,
- &nifp->nat_nbma, &pp->if_ad->addr);
+ &nifp->nat_nbma,
+ &pp->if_ad->addr);
if (!cie)
goto err;
cie->mtu = htons(pp->if_ad->mtu);
@@ -665,9 +704,11 @@ static void nhrp_handle_registration_request(struct nhrp_packet_parser *p)
: &cie_nbma;
nbma_natoa = NULL;
if (natted) {
- nbma_natoa = (sockunion_family(&p->peer->vc->remote.nbma) == AF_UNSPEC)
- ? nbma_addr
- : &p->peer->vc->remote.nbma;
+ nbma_natoa =
+ (sockunion_family(&p->peer->vc->remote.nbma)
+ == AF_UNSPEC)
+ ? nbma_addr
+ : &p->peer->vc->remote.nbma;
}
holdtime = htons(cie->holding_time);
@@ -682,7 +723,8 @@ static void nhrp_handle_registration_request(struct nhrp_packet_parser *p)
if (!nhrp_cache_update_binding(c, NHRP_CACHE_DYNAMIC, holdtime,
nhrp_peer_ref(p->peer),
- htons(cie->mtu), nbma_natoa, nbma_addr)) {
+ htons(cie->mtu), nbma_natoa,
+ nbma_addr)) {
cie->code = NHRP_CODE_ADMINISTRATIVELY_PROHIBITED;
continue;
}
@@ -701,8 +743,11 @@ static void nhrp_handle_registration_request(struct nhrp_packet_parser *p)
zbuf_copy(zb, &payload, zbuf_used(&payload));
if (natted) {
cie = nhrp_cie_push(zb, NHRP_CODE_SUCCESS,
- &p->peer->vc->remote.nbma,
- &p->src_proto);
+ &p->peer->vc->remote.nbma,
+ &p->src_proto);
+ cie->prefix_length =
+ 8 * sockunion_get_addrlen(
+ &p->if_ad->addr);
cie->mtu = htons(p->if_ad->mtu);
}
nhrp_ext_complete(zb, ext);
@@ -909,7 +954,8 @@ static void nhrp_peer_forward(struct nhrp_peer *p,
struct nhrp_cie_header *cie;
struct nhrp_interface *nifp = pp->ifp->info;
struct nhrp_afi_data *if_ad = pp->if_ad;
- union sockunion cie_nbma, cie_protocol, cie_protocol_mandatory, *proto = NULL;
+ union sockunion cie_nbma, cie_protocol, cie_protocol_mandatory,
+ *proto = NULL;
uint16_t type, len;
struct nhrp_cache *c;
char buf[SU_ADDRSTRLEN];
@@ -971,32 +1017,59 @@ static void nhrp_peer_forward(struct nhrp_peer *p,
}
break;
case NHRP_EXTENSION_NAT_ADDRESS:
- /* if NAT extension is not empty then copy it across else attempt to populate it */
+ /* if NAT extension is not empty then copy it across
+ * else attempt to populate it */
if (len > 0) {
zbuf_copy(zb, &extpl, len);
} else {
- if(packet_types[hdr->type].type == PACKET_REQUEST) {
- debugf(NHRP_DEBUG_COMMON,"Processing NHRP_EXTENSION_NAT_ADDRESS while forwarding the request packet");
+ if (packet_types[hdr->type].type
+ == PACKET_REQUEST) {
+ debugf(NHRP_DEBUG_COMMON,
+ "Processing NHRP_EXTENSION_NAT_ADDRESS while forwarding the request packet");
proto = &pp->src_proto;
- } else if(packet_types[hdr->type].type == PACKET_REPLY) {
- debugf(NHRP_DEBUG_COMMON,"Processing NHRP_EXTENSION_NAT_ADDRESS while forwarding the reply packet");
- /* For reply packet use protocol specified in CIE of mandatory part for cache lookup */
- if(sockunion_family(&cie_protocol_mandatory) != AF_UNSPEC)
+ } else if (packet_types[hdr->type].type
+ == PACKET_REPLY) {
+ debugf(NHRP_DEBUG_COMMON,
+ "Processing NHRP_EXTENSION_NAT_ADDRESS while forwarding the reply packet");
+ /* For reply packet use protocol
+ * specified in CIE of mandatory part
+ * for cache lookup */
+ if (sockunion_family(
+ &cie_protocol_mandatory)
+ != AF_UNSPEC)
proto = &cie_protocol_mandatory;
}
- if(proto) {
- debugf(NHRP_DEBUG_COMMON,"Proto is %s", sockunion2str(proto, buf, sizeof(buf)));
+ if (proto) {
+ debugf(NHRP_DEBUG_COMMON, "Proto is %s",
+ sockunion2str(proto, buf,
+ sizeof(buf)));
c = nhrp_cache_get(nifp->ifp, proto, 0);
- if(c) {
- debugf(NHRP_DEBUG_COMMON,"c->cur.remote_nbma_natoa is %s", sockunion2str(&c->cur.remote_nbma_natoa, buf, sizeof(buf)) ? buf : "NULL");
- if (sockunion_family(&c->cur.remote_nbma_natoa) != AF_UNSPEC) {
- cie = nhrp_cie_push(zb, NHRP_CODE_SUCCESS,&c->cur.remote_nbma_natoa, proto);
+ if (c) {
+ debugf(NHRP_DEBUG_COMMON,
+ "c->cur.remote_nbma_natoa is %s",
+ sockunion2str(
+ &c->cur.remote_nbma_natoa,
+ buf, sizeof(buf))
+ ? buf
+ : "NULL");
+ if (sockunion_family(
+ &c->cur.remote_nbma_natoa)
+ != AF_UNSPEC) {
+ cie = nhrp_cie_push(
+ zb,
+ NHRP_CODE_SUCCESS,
+ &c->cur.remote_nbma_natoa,
+ proto);
if (!cie)
goto err;
}
} else {
- debugf(NHRP_DEBUG_COMMON,"No cache entry for Proto is %s", sockunion2str(proto, buf, sizeof(buf)));
+ debugf(NHRP_DEBUG_COMMON,
+ "No cache entry for Proto is %s",
+ sockunion2str(
+ proto, buf,
+ sizeof(buf)));
zbuf_put(zb, extpl.head, len);
}
} else {