diff options
| -rw-r--r-- | nhrpd/nhrp_interface.c | 12 | ||||
| -rw-r--r-- | nhrpd/nhrp_nhs.c | 14 | ||||
| -rw-r--r-- | nhrpd/nhrp_peer.c | 4 | ||||
| -rw-r--r-- | nhrpd/nhrpd.h | 4 | ||||
| -rw-r--r-- | nhrpd/vici.c | 21 | 
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)  {  | 
