--- old/usr/src/lib/libipsecutil/common/ipsec_util.c	Tue Jan  9 14:03:19 2018
+++ new/usr/src/lib/libipsecutil/common/ipsec_util.c	Tue Jan  9 14:03:19 2018
@@ -23,6 +23,7 @@
  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  * Copyright 2012 Milan Juri. All rights reserved.
+ * Copyright 2017 Joyent, Inc.
  */
 
 #include <unistd.h>
@@ -1152,6 +1153,9 @@
  * not found).  Note that the returned label pointer points to a static
  * string, so the label will be overwritten by a subsequent call to the
  * function; the function is also not thread-safe as a result.
+ *
+ * Because this is possibly publically exported, do not change its name,
+ * but this is for all intents and purposes an IKEv1/in.iked function.
  */
 char *
 kmc_lookup_by_cookie(int cookie)
@@ -2591,13 +2595,32 @@
 {
 	char *cookie_label;
 
-	if ((cookie_label = kmc_lookup_by_cookie(kmc->sadb_x_kmc_cookie)) ==
-	    NULL)
-		cookie_label = dgettext(TEXT_DOMAIN, "<Label not found.>");
+	switch (kmc->sadb_x_kmc_proto) {
+	case SADB_X_KMP_IKE:
+		cookie_label = kmc_lookup_by_cookie(kmc->sadb_x_kmc_cookie);
+		if (cookie_label == NULL)
+			cookie_label =
+			    dgettext(TEXT_DOMAIN, "<Label not found.>");
+		(void) fprintf(file, dgettext(TEXT_DOMAIN,
+		    "%sProtocol %u, cookie=\"%s\" (%u)\n"), prefix,
+		    kmc->sadb_x_kmc_proto, cookie_label,
+		    kmc->sadb_x_kmc_cookie);
+		return;
+	case SADB_X_KMP_MANUAL:
+		cookie_label = dgettext(TEXT_DOMAIN, "Manual SA with cookie");
+		break;
+	/* case SADB_X_KMP_IKEV2: */
+	default:
+		cookie_label =
+		    dgettext(TEXT_DOMAIN, "<unknown KM protocol>");
+		break;
+	}
 
+	/* XXX KEBE ASKS... htonll() on generic kmc_cookie? */
 	(void) fprintf(file, dgettext(TEXT_DOMAIN,
-	    "%sProtocol %u, cookie=\"%s\" (%u)\n"), prefix,
-	    kmc->sadb_x_kmc_proto, cookie_label, kmc->sadb_x_kmc_cookie);
+	    "%sProtocol %u, cookie=\"%s\" (0x%"PRIx64"/%"PRIu64")\n"),
+	    prefix, kmc->sadb_x_kmc_proto, cookie_label,
+	    kmc->sadb_x_kmc_cookie64, kmc->sadb_x_kmc_cookie64);
 }
 
 /*
--- old/usr/src/lib/libipsecutil/common/ipsec_util.h	Tue Jan  9 14:03:19 2018
+++ new/usr/src/lib/libipsecutil/common/ipsec_util.h	Tue Jan  9 14:03:19 2018
@@ -22,6 +22,9 @@
  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
+/*
+ * Copyright 2017 Joyent, Inc.
+ */
 
 #ifndef	_IPSEC_UTIL_H
 #define	_IPSEC_UTIL_H
@@ -225,7 +228,7 @@
 void libcrypto_load(void);
 
 /*
- * functions to manipulate the kmcookie-label mapping file
+ * functions to manipulate the IKEv1 kmcookie-label mapping file
  */
 
 #define	KMCFILE		"/var/run/ipsec_kmc_map"
--- old/usr/src/pkg/manifests/system-test-ostest.mf	Tue Jan  9 14:03:19 2018
+++ new/usr/src/pkg/manifests/system-test-ostest.mf	Tue Jan  9 14:03:19 2018
@@ -43,6 +43,8 @@
 file path=opt/os-tests/tests/pf_key/acquire-compare mode=0555
 file path=opt/os-tests/tests/pf_key/acquire-spray mode=0555
 file path=opt/os-tests/tests/pf_key/eacq-enabler mode=0555
+file path=opt/os-tests/tests/pf_key/kmc-update mode=0555
+file path=opt/os-tests/tests/pf_key/kmc-updater mode=0555
 file path=opt/os-tests/tests/poll_test mode=0555
 file path=opt/os-tests/tests/sdevfs/sdevfs_eisdir mode=0555
 file path=opt/os-tests/tests/secflags/addrs-32 mode=0555
--- old/usr/src/test/os-tests/tests/pf_key/Makefile	Tue Jan  9 14:03:19 2018
+++ new/usr/src/test/os-tests/tests/pf_key/Makefile	Tue Jan  9 14:03:19 2018
@@ -18,9 +18,12 @@
 
 # Shell scripts...
 PROG =	acquire-spray \
-	acquire-compare
+	acquire-compare \
+	kmc-update
 
-PROG += eacq-enabler
+# Binaries
+PROG +=	eacq-enabler \
+	kmc-updater
 
 ROOTOPTPKG = $(ROOT)/opt/os-tests
 TESTDIR = $(ROOTOPTPKG)/tests/pf_key
--- /dev/null	Tue Jan  9 14:03:20 2018
+++ new/usr/src/test/os-tests/tests/pf_key/kmc-update.sh	Tue Jan  9 14:03:20 2018
@@ -0,0 +1,68 @@
+#!/usr/bin/ksh
+
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source.  A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+
+#
+# Copyright (c) 2017 Joyent, Inc.
+#
+
+if [ `id -u` -ne 0 ]; then
+	echo "Need to be root or have effective UID of root."
+	exit 255
+fi
+
+#
+# Two birds with one stone.
+#
+# 1.) Add some simple SAs.
+# 2.) Run C programs that use SADB_UPDATE to alter the SAs' KM cookies.
+#
+# This tests both SADB_UPDATE of an SA's KM cookie, and the C programs can
+# test (or not) cookie/cookie64 and the IKEv1 exception.
+#
+
+# Add two simple SAs.  Will delete them first, out of paranoia.
+
+ipseckey 2>&1 >/dev/null <<EOF
+delete ah spi 0x2112 dst 127.0.0.1
+delete ah spi 0x5150 dst 127.0.0.1
+add ah spi 0x2112 dst 127.0.0.1 authalg md5 authkey \
+	1234567890abcdeffedcba0987654321
+add ah spi 0x5150 dst 127.0.0.1 authalg md5 authkey \
+	abcdef01234567890123456789abcdef
+EOF
+
+# Run programs to see if UPDATE on their KM cookies works.  Both test
+# programs take an SPI value, and assume dst=127.0.0.1.
+
+TESTPATH=/opt/os-tests/tests/pf_key
+
+# Test IKEv1, including masking of the reserved 32-bits.
+$TESTPATH/kmc-updater 0x2112
+if [[ $? != 0 ]]; then
+    echo "IKEv1 32-bit KMC test failed."
+    exit 1
+fi
+echo "Passed IKEv1 32-bit KMC test."
+
+# Test a different one, using all 64-bits.
+$TESTPATH/kmc-updater 0x5150 64
+if [[ $? != 0 ]]; then
+    echo "64-bit KMC test failed."
+    exit 1
+fi
+echo "Passed 64-bit KMC test."
+
+ipseckey delete ah spi 0x2112 dst 127.0.0.1
+ipseckey delete ah spi 0x5150 dst 127.0.0.1
+
+exit 0
--- /dev/null	Tue Jan  9 14:03:20 2018
+++ new/usr/src/test/os-tests/tests/pf_key/kmc-updater.c	Tue Jan  9 14:03:20 2018
@@ -0,0 +1,221 @@
+/*
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source.  A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ */
+
+/*
+ * Copyright 2017 Joyent, Inc.
+ */
+
+#include <sys/socket.h>
+#include <net/pfkeyv2.h>
+#include <stdio.h>
+#include <errno.h>
+#include <err.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define	COOKIE64 0xc0ffee4afee01deaULL
+#define	COOKIE32 0x90125
+#define	RESERVED 0xc0ffee
+
+/*
+ * Exits app on failure.
+ */
+static void
+write_and_read(int s, sadb_msg_t *samsg, uint64_t *readbuf, int readlen,
+    char *msgtypestr)
+{
+	int rc;
+	uint8_t msgtype = samsg->sadb_msg_type;
+	pid_t pid = samsg->sadb_msg_pid;
+	uint8_t seq = samsg->sadb_msg_seq;
+
+	rc = write(s, samsg, SADB_64TO8(samsg->sadb_msg_len));
+	if (rc == -1)
+		err(-1, "%s write error", msgtypestr);
+
+	/* Yes, parameter re-use, but we're done writing. */
+	samsg = (sadb_msg_t *)readbuf;
+	do {
+		rc = read(s, readbuf, readlen);
+		if (rc == -1)
+			err(-1, "%s read reply error", msgtypestr);
+	} while (samsg->sadb_msg_seq != seq || samsg->sadb_msg_pid != pid ||
+	    samsg->sadb_msg_type != msgtype);
+
+	if (samsg->sadb_msg_errno != 0) {
+		errno = samsg->sadb_msg_errno;
+		err(-1, "%s reply has error (diag = %d)", msgtypestr,
+		    samsg->sadb_x_msg_diagnostic);
+	}
+}
+
+int
+main(int argc, char *argv[])
+{
+	uint32_t spi;
+	sadb_ext_t *ext;
+	sadb_sa_t *saext;
+	sadb_msg_t *samsg;
+	sadb_address_t *dstext, *srcext;
+	sadb_x_kmc_t *kmcext;
+	struct sockaddr_in *sin;
+	uint64_t writebuf[20];		/* PF_KEY likes 64-bit alignment. */
+	uint64_t readbuf[128];
+	uint64_t *extptr, *endptr;
+	pid_t pid = getpid();
+	boolean_t do_64_test;
+	int s;
+
+	if (argc != 2 && argc != 3) {
+		(void) fprintf(stderr, "Usage: %s <spi-value> {64}\n",
+		    argv[0]);
+		exit(-1);
+	}
+	do_64_test = (argc == 3);
+
+	spi = strtoul(argv[1], NULL, 0);
+	if (spi == 0) {
+		if (errno != 0) {
+			err(-1, "Argument %s is not a parsable number:",
+			    argv[1]);
+		} else {
+			errno = EINVAL;
+			err(-1, "Zero SPI not allowed:");
+		}
+	}
+
+	s = socket(PF_KEY, SOCK_RAW, PF_KEY_V2);
+	if (s == -1)
+		err(-1, "socket(PF_KEY)");
+
+	/* Base message. */
+	samsg = (sadb_msg_t *)writebuf;
+	samsg->sadb_msg_version = PF_KEY_V2;
+	samsg->sadb_msg_type = SADB_UPDATE;
+	samsg->sadb_msg_errno = 0;
+	samsg->sadb_msg_satype = SADB_SATYPE_AH;
+	samsg->sadb_msg_reserved = 0;
+	samsg->sadb_msg_seq = 1;
+	samsg->sadb_msg_pid = pid;
+	samsg->sadb_msg_len = SADB_8TO64(sizeof (*samsg) + sizeof (*saext) +
+	    2 * (sizeof (*dstext) + sizeof (*sin)) + sizeof (*kmcext));
+
+	/* SA extension. Only used to set the SPI. */
+	saext = (sadb_sa_t *)(samsg + 1);
+	memset(saext, 0, sizeof (*saext));
+	saext->sadb_sa_len = SADB_8TO64(sizeof (*saext));
+	saext->sadb_sa_exttype = SADB_EXT_SA;
+	saext->sadb_sa_spi = htonl(spi);
+	saext->sadb_sa_state = SADB_SASTATE_MATURE;
+
+	/* Destination IP, always 127.0.0.1 for this test. */
+	dstext = (sadb_address_t *)(saext + 1);
+	dstext->sadb_address_len = SADB_8TO64(sizeof (*dstext) + sizeof (*sin));
+	dstext->sadb_address_exttype = SADB_EXT_ADDRESS_DST;
+	dstext->sadb_address_proto = 0;
+	dstext->sadb_address_prefixlen = 0;
+	dstext->sadb_address_reserved = 0;
+	sin = (struct sockaddr_in *)(dstext + 1);
+	sin->sin_family = AF_INET;
+	sin->sin_port = 0;
+	sin->sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+
+	/* PF_KEY requires a source address, even if it's a wildcard. */
+	srcext = (sadb_address_t *)(sin + 1);
+	srcext->sadb_address_len = SADB_8TO64(sizeof (*srcext) + sizeof (*sin));
+	srcext->sadb_address_exttype = SADB_EXT_ADDRESS_SRC;
+	srcext->sadb_address_proto = 0;
+	srcext->sadb_address_prefixlen = 0;
+	srcext->sadb_address_reserved = 0;
+	sin = (struct sockaddr_in *)(srcext + 1);
+	sin->sin_family = AF_INET;
+	sin->sin_port = 0;
+	sin->sin_addr.s_addr = 0;
+
+	/*
+	 * KM cookie. Depending, either make it IKEv1, 32-bit, AND store
+	 * garbage in the reserved field, or just put a big 64-bit cookie in.
+	 */
+	kmcext = (sadb_x_kmc_t *)(sin + 1);
+	kmcext->sadb_x_kmc_len = SADB_8TO64(sizeof (*kmcext));
+	kmcext->sadb_x_kmc_exttype = SADB_X_EXT_KM_COOKIE;
+	if (do_64_test) {
+		/* 64-bit cookie test.  KINK is non-zero, and non-IKEv1. */
+		kmcext->sadb_x_kmc_proto = SADB_X_KMP_KINK;
+		kmcext->sadb_x_kmc_cookie64 = COOKIE64;
+	} else {
+		/* IKEv1 32-bit cookie test. */
+		kmcext->sadb_x_kmc_proto = SADB_X_KMP_IKE;
+		kmcext->sadb_x_kmc_cookie = COOKIE32;
+		kmcext->sadb_x_kmc_reserved = RESERVED;
+	}
+
+	write_and_read(s, samsg, readbuf, sizeof (readbuf), "SADB_UPDATE");
+
+	/*
+	 * Okay, it worked!  Now let's find the KMC reported back from the
+	 * kernel.
+	 */
+	samsg->sadb_msg_type = SADB_GET;
+	samsg->sadb_msg_len -= SADB_8TO64(sizeof (*kmcext));
+
+	/* Everything else in writebuf is good to go. */
+	write_and_read(s, samsg, readbuf, sizeof (readbuf), "SADB_GET");
+
+	/* Actually find the KMC extension. (expand for loop for readability) */
+	samsg = (sadb_msg_t *)readbuf;
+	extptr = (uint64_t *)(samsg + 1);
+	endptr = extptr + samsg->sadb_msg_len - SADB_8TO64(sizeof (*samsg));
+	ext = (sadb_ext_t *)extptr;
+
+	while ((extptr < endptr) &&
+	    (ext->sadb_ext_type != SADB_X_EXT_KM_COOKIE)) {
+		extptr += ext->sadb_ext_len;
+		ext = (sadb_ext_t *)extptr;
+	}
+
+	if (extptr == endptr) {
+		(void) fprintf(stderr, "Can't find KMC extension in reply.\n");
+		exit(-1);
+	}
+	kmcext = (sadb_x_kmc_t *)extptr;
+
+	if (do_64_test) {
+		if (kmcext->sadb_x_kmc_proto != SADB_X_KMP_KINK ||
+		    kmcext->sadb_x_kmc_cookie64 != COOKIE64) {
+			(void) fprintf(stderr, "Unexpected 64-bit results: "
+			    "KMC received was %d, expecting %d,\n",
+			    kmcext->sadb_x_kmc_proto, SADB_X_KMP_KINK);
+			(void) fprintf(stderr, "64-bit cookie recevied was "
+			    "0x%"PRIx64", expecting 0x%"PRIx64"\n",
+			    kmcext->sadb_x_kmc_cookie64, COOKIE64);
+			exit(1);
+		}
+	} else {
+		if (kmcext->sadb_x_kmc_proto != SADB_X_KMP_IKE ||
+		    kmcext->sadb_x_kmc_cookie != COOKIE32 ||
+		    kmcext->sadb_x_kmc_reserved != 0) {
+			(void) fprintf(stderr, "Unexpected IKE/32-bit results:"
+			    " KMC received was %d, expecting %d,\n",
+			    kmcext->sadb_x_kmc_proto, SADB_X_KMP_IKE);
+			(void) fprintf(stderr, "32-bit cookie recevied was "
+			    "0x%"PRIx32", expecting 0x%"PRIx32"\n",
+			    kmcext->sadb_x_kmc_cookie64, COOKIE32);
+			(void) fprintf(stderr, "32-bit reserved recevied was "
+			    "0x%"PRIx32", expecting 0\n",
+			    kmcext->sadb_x_kmc_cookie64);
+			exit(1);
+		}
+	}
+
+	exit(0);
+}
--- old/usr/src/uts/common/inet/ip/sadb.c	Tue Jan  9 14:03:20 2018
+++ new/usr/src/uts/common/inet/ip/sadb.c	Tue Jan  9 14:03:20 2018
@@ -1043,7 +1043,7 @@
  */
 
 static uint8_t *
-sadb_make_kmc_ext(uint8_t *cur, uint8_t *end, uint32_t kmp, uint32_t kmc)
+sadb_make_kmc_ext(uint8_t *cur, uint8_t *end, uint32_t kmp, uint64_t kmc)
 {
 	sadb_x_kmc_t *kmcext = (sadb_x_kmc_t *)cur;
 
@@ -1058,8 +1058,7 @@
 	kmcext->sadb_x_kmc_len = SADB_8TO64(sizeof (*kmcext));
 	kmcext->sadb_x_kmc_exttype = SADB_X_EXT_KM_COOKIE;
 	kmcext->sadb_x_kmc_proto = kmp;
-	kmcext->sadb_x_kmc_cookie = kmc;
-	kmcext->sadb_x_kmc_reserved = 0;
+	kmcext->sadb_x_kmc_cookie64 = kmc;
 
 	return (cur);
 }
@@ -2330,8 +2329,13 @@
 	sq->kmp = 0;
 
 	if ((match & IPSA_Q_KMC) && (sq->kmcext)) {
-		sq->kmc = sq->kmcext->sadb_x_kmc_cookie;
 		sq->kmp = sq->kmcext->sadb_x_kmc_proto;
+		/* Be liberal in what we receive.  Special-case IKEv1. */
+		if (sq->kmp == SADB_X_KMP_IKE) {
+			/* Just in case in.iked is misbehaving... */
+			sq->kmcext->sadb_x_kmc_reserved = 0;
+		}
+		sq->kmc = sq->kmcext->sadb_x_kmc_cookie64;
 		*mfpp++ = sadb_match_kmc;
 	}
 
@@ -3133,7 +3137,12 @@
 
 	if (kmcext != NULL) {
 		newbie->ipsa_kmp = kmcext->sadb_x_kmc_proto;
-		newbie->ipsa_kmc = kmcext->sadb_x_kmc_cookie;
+		/* Be liberal in what we receive.  Special-case IKEv1. */
+		if (newbie->ipsa_kmp == SADB_X_KMP_IKE) {
+			/* Just in case in.iked is misbehaving... */
+			kmcext->sadb_x_kmc_reserved = 0;
+		}
+		newbie->ipsa_kmc = kmcext->sadb_x_kmc_cookie64;
 	}
 
 	/*
@@ -4436,7 +4445,7 @@
 sadb_check_kmc(ipsa_query_t *sq, ipsa_t *sa, int *diagnostic)
 {
 	uint32_t kmp = sq->kmp;
-	uint32_t kmc = sq->kmc;
+	uint64_t kmc = sq->kmc;
 
 	if (sa == NULL)
 		return (0);
@@ -4444,12 +4453,12 @@
 	if (sa->ipsa_state == IPSA_STATE_DEAD)
 		return (ESRCH);	/* DEAD == Not there, in this case. */
 
-	if ((kmp != 0) && ((sa->ipsa_kmp != 0) || (sa->ipsa_kmp != kmp))) {
+	if ((kmp != 0) && (sa->ipsa_kmp != 0) && (sa->ipsa_kmp != kmp)) {
 		*diagnostic = SADB_X_DIAGNOSTIC_DUPLICATE_KMP;
 		return (EINVAL);
 	}
 
-	if ((kmc != 0) && ((sa->ipsa_kmc != 0) || (sa->ipsa_kmc != kmc))) {
+	if ((kmc != 0) && (sa->ipsa_kmc != 0) && (sa->ipsa_kmc != kmc)) {
 		*diagnostic = SADB_X_DIAGNOSTIC_DUPLICATE_KMC;
 		return (EINVAL);
 	}
@@ -4464,7 +4473,7 @@
 sadb_update_kmc(ipsa_query_t *sq, ipsa_t *sa)
 {
 	uint32_t kmp = sq->kmp;
-	uint32_t kmc = sq->kmc;
+	uint64_t kmc = sq->kmc;
 
 	if (kmp != 0)
 		sa->ipsa_kmp = kmp;
@@ -4501,7 +4510,8 @@
 
 	sq.spp = spp;		/* XXX param */
 	int error = sadb_form_query(ksi, IPSA_Q_SRC|IPSA_Q_DST|IPSA_Q_SA,
-	    IPSA_Q_SRC|IPSA_Q_DST|IPSA_Q_SA|IPSA_Q_INBOUND|IPSA_Q_OUTBOUND,
+	    IPSA_Q_SRC|IPSA_Q_DST|IPSA_Q_SA|IPSA_Q_INBOUND|IPSA_Q_OUTBOUND|
+	    IPSA_Q_KMC,
 	    &sq, diagnostic);
 
 	if (error != 0)
@@ -5107,7 +5117,8 @@
 	    emaxbits, replay;
 	uint64_t softbytes, hardbytes, softaddtime, hardaddtime, softusetime,
 	    hardusetime;
-	uint32_t kmc = 0, kmp = 0;
+	uint64_t kmc = 0;
+	uint32_t kmp = 0;
 
 	/*
 	 * Since it's an rwlock read, AND writing to the IPsec algorithms is
@@ -5297,7 +5308,6 @@
 /*
  * Generate an extended ACQUIRE's extended-proposal extension.
  */
-/* ARGSUSED */
 static mblk_t *
 sadb_acquire_extended_prop(ipsec_action_t *ap, netstack_t *ns)
 {
@@ -5305,7 +5315,8 @@
 	uint8_t *cur, *end;
 	mblk_t *mp;
 	int allocsize, numecombs = 0, numalgdescs = 0;
-	uint32_t kmc = 0, kmp = 0, replay = 0;
+	uint32_t kmp = 0, replay = 0;
+	uint64_t kmc = 0;
 	ipsec_action_t *walker;
 
 	allocsize = sizeof (*eprop);
--- old/usr/src/uts/common/inet/ipsec_impl.h	Tue Jan  9 14:03:20 2018
+++ new/usr/src/uts/common/inet/ipsec_impl.h	Tue Jan  9 14:03:20 2018
@@ -236,7 +236,7 @@
 	uint16_t	ipp_espa_minbits;	 /* ESP auth: min keylen */
 	uint16_t	ipp_espa_maxbits;	 /* ESP auth: max keylen */
 	uint32_t	ipp_km_proto;		 /* key mgmt protocol */
-	uint32_t	ipp_km_cookie;		 /* key mgmt cookie */
+	uint64_t	ipp_km_cookie;		 /* key mgmt cookie */
 	uint32_t	ipp_replay_depth;	 /* replay window */
 	/* XXX add lifetimes */
 } ipsec_prot_t;
--- old/usr/src/uts/common/inet/sadb.h	Tue Jan  9 14:03:20 2018
+++ new/usr/src/uts/common/inet/sadb.h	Tue Jan  9 14:03:20 2018
@@ -22,6 +22,7 @@
  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  * Copyright (c) 2012 Nexenta Systems, Inc. All rights reserved.
+ * Copyright 2017 Joyent, Inc.
  */
 
 #ifndef	_INET_SADB_H
@@ -247,7 +248,7 @@
 	uint32_t ipsa_spi;	/* Security parameters index. */
 	uint32_t ipsa_replay;	/* Highest seen replay value for this SA. */
 	uint32_t ipsa_kmp;	/* key management proto */
-	uint32_t ipsa_kmc;	/* key management cookie */
+	uint64_t ipsa_kmc;	/* key management cookie (now 64-bit) */
 
 	boolean_t ipsa_haspeer;		/* Has peer in another table. */
 
@@ -690,7 +691,8 @@
 	sa_family_t af;
 	uint32_t *srcaddr, *dstaddr;
 	uint32_t ifindex;
-	uint32_t kmc, kmp;
+	uint32_t kmp;
+	uint64_t kmc;
 	char *didstr, *sidstr;
 	uint16_t didtype, sidtype;
 	sadbp_t *spp;
--- old/usr/src/uts/common/net/pfkeyv2.h	Tue Jan  9 14:03:21 2018
+++ new/usr/src/uts/common/net/pfkeyv2.h	Tue Jan  9 14:03:21 2018
@@ -22,6 +22,9 @@
  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
+/*
+ * Copyright 2017 Joyent, Inc.
+ */
 
 #ifndef	_NET_PFKEYV2_H
 #define	_NET_PFKEYV2_H
@@ -477,10 +480,11 @@
 			uint32_t sadb_x_kmc_ucookie;	/* KMP-specific */
 			uint32_t sadb_x_kmc_ureserved;	/* Must be zero */
 		} sadb_x_kmc_actual;
-		uint64_t sadb_x_kmc_alignment;
+		uint64_t sadb_x_kmc_ucookie64;
 	} sadb_x_kmc_u;
 #define	sadb_x_kmc_cookie sadb_x_kmc_u.sadb_x_kmc_actual.sadb_x_kmc_ucookie
 #define	sadb_x_kmc_reserved sadb_x_kmc_u.sadb_x_kmc_actual.sadb_x_kmc_ureserved
+#define	sadb_x_kmc_cookie64 sadb_x_kmc_u.sadb_x_kmc_ucookie64
 } sadb_x_kmc_t;
 
 typedef struct sadb_x_pair {
@@ -834,7 +838,7 @@
 
 /* Key management protocol for sadb_x_kmc above... */
 
-#define	SADB_X_KMP_MANUAL	0
+#define	SADB_X_KMP_MANUAL	0	/* Cookie is ignored. */
 #define	SADB_X_KMP_IKE		1
 #define	SADB_X_KMP_KINK		2
 
