f9eee43
diff --git a/include/ietf_constants.h b/include/ietf_constants.h
f9eee43
index 38fa4de..08c8d9e 100644
f9eee43
--- a/include/ietf_constants.h
f9eee43
+++ b/include/ietf_constants.h
f9eee43
@@ -1486,12 +1486,14 @@ typedef enum {
f9eee43
 	v2N_SENDER_REQUEST_ID = 16429, /* draft-yeung-g-ikev2 */
f9eee43
 	v2N_IKEV2_FRAGMENTATION_SUPPORTED = 16430, /* RFC-7383 */
f9eee43
 	v2N_SIGNATURE_HASH_ALGORITHMS = 16431, /* RFC-7427 */
f9eee43
-
f9eee43
-	v2N_USE_PPK = 40960,            /* draft-ietf-ipsecme-qr-ikev2-01 */
f9eee43
-	v2N_PPK_IDENTITY = 40961,       /* draft-ietf-ipsecme-qr-ikev2-01 */
f9eee43
-	v2N_NO_PPK_AUTH = 40962,        /* draft-ietf-ipsecme-qr-ikev2-01 */
f9eee43
-
f9eee43
-	/* 16432 - 40969 Unassigned */
f9eee43
+	v2N_CLONE_IKE_SA_SUPPORTED = 16432, /* RFC-7791 */
f9eee43
+	v2N_CLONE_IKE_SA = 16433, /* RFC-7791 */
f9eee43
+	v2N_PUZZLE = 16434, /* RFC-8019 */
f9eee43
+	v2N_USE_PPK = 16435, /* draft-ietf-ipsecme-qr-ikev2 */
f9eee43
+	v2N_PPK_IDENTITY = 16436, /* draft-ietf-ipsecme-qr-ikev2 */
f9eee43
+	v2N_NO_PPK_AUTH = 16437, /* draft-ietf-ipsecme-qr-ikev2 */
f9eee43
+
f9eee43
+	/* 16438 - 40969 Unassigned */
f9eee43
 	/* 40960 - 65535 Private Use */
f9eee43
 } v2_notification_t;
f9eee43
 
f9eee43
diff --git a/lib/libswan/constants.c b/lib/libswan/constants.c
f9eee43
index ab6db3e..a0dab63 100644
f9eee43
--- a/lib/libswan/constants.c
f9eee43
+++ b/lib/libswan/constants.c
f9eee43
@@ -1634,20 +1634,6 @@ static enum_names ikev2_ppk_id_type_names = {
f9eee43
 };
f9eee43
 */
f9eee43
 
f9eee43
-static const char *const ikev2_notify_name_private[] = {
f9eee43
-	"v2N_USE_PPK",
f9eee43
-	"v2N_PPK_IDENTITY",
f9eee43
-	"v2N_NO_PPK_AUTH",
f9eee43
-};
f9eee43
-
f9eee43
-static enum_names ikev2_notify_names_private = {
f9eee43
-	v2N_USE_PPK,
f9eee43
-	v2N_NO_PPK_AUTH,
f9eee43
-	ARRAY_REF(ikev2_notify_name_private),
f9eee43
-	"v2N_", /* prefix */
f9eee43
-	NULL
f9eee43
-};
f9eee43
-
f9eee43
 /* http://www.iana.org/assignments/ikev2-parameters/ikev2-parameters.xml#ikev2-parameters-13 */
f9eee43
 static const char *const ikev2_notify_name_16384[] = {
f9eee43
 	"v2N_INITIAL_CONTACT",    /* 16384 */
f9eee43
@@ -1698,14 +1684,20 @@ static const char *const ikev2_notify_name_16384[] = {
f9eee43
 	"v2N_SENDER_REQUEST_ID",
f9eee43
 	"v2N_IKEV2_FRAGMENTATION_SUPPORTED",    /* 16430 */
f9eee43
 	"v2N_SIGNATURE_HASH_ALGORITHMS",
f9eee43
+	"v2N_CLONE_IKE_SA_SUPPORTED",
f9eee43
+	"v2N_CLONE_IKE_SA",
f9eee43
+	"v2N_PUZZLE",
f9eee43
+	"v2N_USE_PPK", /* 16435 */
f9eee43
+	"v2N_PPK_IDENTITY",
f9eee43
+	"v2N_NO_PPK_AUTH",
f9eee43
 };
f9eee43
 
f9eee43
 static enum_names ikev2_notify_names_16384 = {
f9eee43
 	v2N_INITIAL_CONTACT,
f9eee43
-	v2N_SIGNATURE_HASH_ALGORITHMS,
f9eee43
+	v2N_NO_PPK_AUTH,
f9eee43
 	ARRAY_REF(ikev2_notify_name_16384),
f9eee43
 	"v2N_", /* prefix */
f9eee43
-	&ikev2_notify_names_private
f9eee43
+	NULL
f9eee43
 };
f9eee43
 
f9eee43
 static const char *const ikev2_notify_name[] = {
f9eee43
diff --git a/programs/pluto/ikev2_parent.c b/programs/pluto/ikev2_parent.c
f9eee43
index 258ba85..b86eea8 100644
f9eee43
--- a/programs/pluto/ikev2_parent.c
f9eee43
+++ b/programs/pluto/ikev2_parent.c
f9eee43
@@ -3749,18 +3749,14 @@ stf_status ikev2_parent_inI2outR2_id_tail(struct msg_digest *md)
f9eee43
 				break;
f9eee43
 			}
f9eee43
 
f9eee43
-			if (LIN(POLICY_PPK_ALLOW, policy)) {
f9eee43
-				no_ppk_auth = alloc_chunk(len, "NO_PPK_AUTH");
f9eee43
+			no_ppk_auth = alloc_chunk(len, "NO_PPK_AUTH");
f9eee43
 
f9eee43
-				if (!in_raw(no_ppk_auth.ptr, len, &pbs, "NO_PPK_AUTH extract")) {
f9eee43
-					loglog(RC_LOG_SERIOUS, "Failed to extract %zd bytes of NO_PPK_AUTH from Notify payload", len);
f9eee43
-					return STF_FATAL;
f9eee43
-				}
f9eee43
-				DBG(DBG_PRIVATE, DBG_dump_chunk("NO_PPK_AUTH:", no_ppk_auth));
f9eee43
-				st->st_no_ppk_auth = no_ppk_auth;
f9eee43
-			} else {
f9eee43
-				libreswan_log("ignored received NO_PPK_AUTH - connection does not allow PPK");
f9eee43
+			if (!in_raw(no_ppk_auth.ptr, len, &pbs, "NO_PPK_AUTH extract")) {
f9eee43
+				loglog(RC_LOG_SERIOUS, "Failed to extract %zd bytes of NO_PPK_AUTH from Notify payload", len);
f9eee43
+				return STF_FATAL;
f9eee43
 			}
f9eee43
+			DBG(DBG_PRIVATE, DBG_dump_chunk("NO_PPK_AUTH:", no_ppk_auth));
f9eee43
+			st->st_no_ppk_auth = no_ppk_auth;
f9eee43
 			break;
f9eee43
 		}
f9eee43
 		case v2N_MOBIKE_SUPPORTED:
f9eee43
@@ -3774,8 +3770,11 @@ stf_status ikev2_parent_inI2outR2_id_tail(struct msg_digest *md)
f9eee43
 		}
f9eee43
 	}
f9eee43
 
f9eee43
-	/* if we found proper PPK ID, we should use that without fallback to no ppk */
f9eee43
-	if (found_ppk)
f9eee43
+	/*
f9eee43
+	 * If we found proper PPK ID and policy allows PPK, use that.
f9eee43
+	 * Otherwise use NO_PPK_AUTH
f9eee43
+	 */
f9eee43
+	if (found_ppk && LIN(POLICY_PPK_ALLOW, policy))
f9eee43
 		freeanychunk(st->st_no_ppk_auth);
f9eee43
 
f9eee43
 	if (!found_ppk && LIN(POLICY_PPK_INSIST, policy)) {