summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--nhrpd/nhrp_interface.c12
-rw-r--r--nhrpd/nhrp_nhs.c14
-rw-r--r--nhrpd/nhrp_peer.c4
-rw-r--r--nhrpd/nhrpd.h4
-rw-r--r--nhrpd/vici.c21
5 files changed, 51 insertions, 4 deletions
diff --git a/nhrpd/nhrp_interface.c b/nhrpd/nhrp_interface.c
index f86dbe3d29..b348cc0def 100644
--- a/nhrpd/nhrp_interface.c
+++ b/nhrpd/nhrp_interface.c
@@ -464,16 +464,22 @@ void nhrp_interface_set_protection(struct interface *ifp, const char *profile,
{
struct nhrp_interface *nifp = ifp->info;
- if (nifp->ipsec_profile)
+ if (nifp->ipsec_profile) {
+ vici_terminate_vc_by_profile_name(nifp->ipsec_profile);
+ nhrp_vc_reset();
free(nifp->ipsec_profile);
+ }
nifp->ipsec_profile = profile ? strdup(profile) : NULL;
- if (nifp->ipsec_fallback_profile)
+ if (nifp->ipsec_fallback_profile) {
+ vici_terminate_vc_by_profile_name(nifp->ipsec_fallback_profile);
+ nhrp_vc_reset();
free(nifp->ipsec_fallback_profile);
+ }
nifp->ipsec_fallback_profile =
fallback_profile ? strdup(fallback_profile) : NULL;
- notifier_call(&nifp->notifier_list, NOTIFY_INTERFACE_ADDRESS_CHANGED);
+ notifier_call(&nifp->notifier_list, NOTIFY_INTERFACE_IPSEC_CHANGED);
}
void nhrp_interface_set_source(struct interface *ifp, const char *ifname)
diff --git a/nhrpd/nhrp_nhs.c b/nhrpd/nhrp_nhs.c
index 9ed03098ac..de1bdbd16a 100644
--- a/nhrpd/nhrp_nhs.c
+++ b/nhrpd/nhrp_nhs.c
@@ -116,8 +116,20 @@ static int nhrp_reg_timeout(struct thread *t)
}
r->timeout <<= 1;
- if (r->timeout > 64)
+ if (r->timeout > 64) {
+ /* If registration fails repeatedly, this may be because the
+ * IPSec connection is not working. Close the connection so it
+ * can be re-established correctly
+ */
+ if (r->peer && r->peer->vc && r->peer->vc->ike_uniqueid) {
+ debugf(NHRP_DEBUG_COMMON,
+ "Terminating IPSec Connection for %d\n",
+ r->peer->vc->ike_uniqueid);
+ vici_terminate_vc_by_ike_id(r->peer->vc->ike_uniqueid);
+ r->peer->vc->ike_uniqueid = 0;
+ }
r->timeout = 2;
+ }
thread_add_timer_msec(master, nhrp_reg_send_req, r, 10, &r->t_register);
return 0;
diff --git a/nhrpd/nhrp_peer.c b/nhrpd/nhrp_peer.c
index 5e9929adeb..0d589e3056 100644
--- a/nhrpd/nhrp_peer.c
+++ b/nhrpd/nhrp_peer.c
@@ -147,6 +147,10 @@ static void nhrp_peer_ifp_notify(struct notifier_block *n, unsigned long cmd)
case NOTIFY_INTERFACE_ADDRESS_CHANGED:
notifier_call(&p->notifier_list, NOTIFY_PEER_IFCONFIG_CHANGED);
break;
+ case NOTIFY_INTERFACE_IPSEC_CHANGED:
+ __nhrp_peer_check(p);
+ notifier_call(&p->notifier_list, NOTIFY_PEER_IFCONFIG_CHANGED);
+ break;
case NOTIFY_INTERFACE_MTU_CHANGED:
notifier_call(&p->notifier_list, NOTIFY_PEER_MTU_CHANGED);
break;
diff --git a/nhrpd/nhrpd.h b/nhrpd/nhrpd.h
index a36d0c445d..3655463152 100644
--- a/nhrpd/nhrpd.h
+++ b/nhrpd/nhrpd.h
@@ -105,6 +105,7 @@ enum nhrp_notify_type {
NOTIFY_INTERFACE_ADDRESS_CHANGED,
NOTIFY_INTERFACE_NBMA_CHANGED,
NOTIFY_INTERFACE_MTU_CHANGED,
+ NOTIFY_INTERFACE_IPSEC_CHANGED,
NOTIFY_VC_IPSEC_CHANGED,
NOTIFY_VC_IPSEC_UPDATE_NBMA,
@@ -125,6 +126,7 @@ enum nhrp_notify_type {
struct nhrp_vc {
struct notifier_list notifier_list;
uint32_t ipsec;
+ uint32_t ike_uniqueid;
uint8_t updating;
uint8_t abort_migration;
@@ -399,6 +401,8 @@ void nhrp_vc_reset(void);
void vici_init(void);
void vici_terminate(void);
+void vici_terminate_vc_by_profile_name(char *profile_name);
+void vici_terminate_vc_by_ike_id(unsigned int ike_id);
void vici_request_vc(const char *profile, union sockunion *src,
union sockunion *dst, int prio);
diff --git a/nhrpd/vici.c b/nhrpd/vici.c
index 86554f53dc..9b117ddf0d 100644
--- a/nhrpd/vici.c
+++ b/nhrpd/vici.c
@@ -200,6 +200,7 @@ static void parse_sa_message(struct vici_message_ctx *ctx,
nhrp_vc_ipsec_updown(
sactx->child_uniqueid,
vc);
+ vc->ike_uniqueid = sactx->ike_uniqueid;
}
} else {
nhrp_vc_ipsec_updown(sactx->child_uniqueid, 0);
@@ -521,6 +522,26 @@ void vici_terminate(void)
{
}
+void vici_terminate_vc_by_profile_name(char *profile_name)
+{
+ struct vici_conn *vici = &vici_connection;
+
+ debugf(NHRP_DEBUG_VICI, "Terminate profile = %s", profile_name);
+ vici_submit_request(vici, "terminate", VICI_KEY_VALUE, "ike",
+ strlen(profile_name), profile_name, VICI_END);
+}
+
+void vici_terminate_vc_by_ike_id(unsigned int ike_id)
+{
+ struct vici_conn *vici = &vici_connection;
+ char ike_id_str[10];
+
+ snprintf(ike_id_str, sizeof(ike_id_str), "%d", ike_id);
+ debugf(NHRP_DEBUG_VICI, "Terminate ike_id_str = %s", ike_id_str);
+ vici_submit_request(vici, "terminate", VICI_KEY_VALUE, "ike-id",
+ strlen(ike_id_str), ike_id_str, VICI_END);
+}
+
void vici_request_vc(const char *profile, union sockunion *src,
union sockunion *dst, int prio)
{