diff -Naur libreswan-3.19-orig/programs/pluto/connections.c libreswan-3.19/programs/pluto/connections.c --- libreswan-3.19-orig/programs/pluto/connections.c 2017-01-15 14:34:34.000000000 -0500 +++ libreswan-3.19/programs/pluto/connections.c 2017-02-03 17:44:29.009703914 -0500 @@ -4334,3 +4334,27 @@ unroute_connection(c); /* --unroute */ } } + +/* + * When replacing an old existing connection, suppress sending delete notify + */ +void suppress_delete(struct connection *c) +{ + struct state *pst = state_with_serialno(c->newest_isakmp_sa); + struct state *cst = state_with_serialno(c->newest_ipsec_sa); + if (pst != NULL) { + pst->st_ikev2_no_del = TRUE; + DBG(DBG_CONTROL, DBG_log("Marked IKE state #%lu to suppress sending delete notify", + c->newest_isakmp_sa)); + } else { + libreswan_log("did not find old IKE state to mark for suppressing delete"); + } + + if (cst != NULL) { + cst->st_ikev2_no_del = TRUE; + DBG(DBG_CONTROL, DBG_log("Marked IPSEC state #%lu to suppress sending delete notify", + c->newest_ipsec_sa)); + } else { + libreswan_log("did not find old IPsec state to mark for suppressing delete"); + } +} diff -Naur libreswan-3.19-orig/programs/pluto/connections.h libreswan-3.19/programs/pluto/connections.h --- libreswan-3.19-orig/programs/pluto/connections.h 2017-01-15 14:34:34.000000000 -0500 +++ libreswan-3.19/programs/pluto/connections.h 2017-02-03 17:44:29.009703914 -0500 @@ -383,6 +383,7 @@ extern void terminate_connection(const char *name); extern void release_connection(struct connection *c, bool relations); extern void delete_connection(struct connection *c, bool relations); +extern void suppress_delete(struct connection *c); extern void delete_connections_by_name(const char *name, bool strict); extern void delete_every_connection(void); extern char *add_group_instance(struct connection *group, diff -Naur libreswan-3.19-orig/programs/pluto/initiate.c libreswan-3.19/programs/pluto/initiate.c --- libreswan-3.19-orig/programs/pluto/initiate.c 2017-02-03 17:41:48.704575766 -0500 +++ libreswan-3.19/programs/pluto/initiate.c 2017-02-03 17:44:34.470674213 -0500 @@ -978,6 +978,7 @@ same_id(&c->spd.that.id, &d->spd.that.id))) { DBG(DBG_CONTROL, DBG_log("Unorienting old connection with same IDs")); + suppress_delete(d); /* don't send a delete */ release_connection(d, FALSE); } d = next; diff -Naur libreswan-3.19-orig/programs/pluto/state.c libreswan-3.19/programs/pluto/state.c --- libreswan-3.19-orig/programs/pluto/state.c 2017-01-15 14:34:34.000000000 -0500 +++ libreswan-3.19/programs/pluto/state.c 2017-02-03 17:44:34.471674208 -0500 @@ -880,8 +880,8 @@ } /* tell the other side of any IPSEC SAs that are going down */ - if (IS_IPSEC_SA_ESTABLISHED(st->st_state) || - IS_ISAKMP_SA_ESTABLISHED(st->st_state)) { + if (!st->st_ikev2_no_del && (IS_IPSEC_SA_ESTABLISHED(st->st_state) || + IS_ISAKMP_SA_ESTABLISHED(st->st_state))) { if (st->st_ikev2 && IS_CHILD_SA(st) && state_with_serialno(st->st_clonedfrom) == NULL) { /* ??? in v2, there must be a parent */ diff -Naur libreswan-3.19-orig/programs/pluto/state.h libreswan-3.19/programs/pluto/state.h --- libreswan-3.19-orig/programs/pluto/state.h 2017-01-15 14:34:34.000000000 -0500 +++ libreswan-3.19/programs/pluto/state.h 2017-02-03 17:44:34.471674208 -0500 @@ -245,6 +245,7 @@ bool has_pam_thread; /* per state PAM thread flag */ bool st_ikev2; /* is this an IKEv2 state? */ + bool st_ikev2_no_del; /* suppress sending DELETE - eg replaced conn */ bool st_rekeytov2; /* true if this IKEv1 is about * to be replaced with IKEv2 */