--- old/usr/src/cmd/ptools/pfiles/pfiles.c	Mon Aug  7 11:40:50 2017
+++ new/usr/src/cmd/ptools/pfiles/pfiles.c	Mon Aug  7 11:40:50 2017
@@ -24,7 +24,7 @@
  * Copyright 2012 DEY Storage Systems, Inc.  All rights reserved.
  */
 /*
- * Copyright (c) 2013 Joyent, Inc.  All Rights reserved.
+ * Copyright (c) 2017 Joyent, Inc.  All Rights reserved.
  */
 
 #include <stdio.h>
@@ -556,6 +556,8 @@
 	case AF_GOSIP:		p = "AF_GOSIP";		break;
 	case AF_IPX:		p = "AF_IPX";		break;
 	case AF_ROUTE:		p = "AF_ROUTE";		break;
+	case AF_KEY:            p = "AF_KEY";           break;
+	case AF_POLICY:         p = "AF_POLICY";        break;
 	case AF_LINK:		p = "AF_LINK";		break;
 	}
 
--- old/usr/src/uts/common/inet/ip/keysock.c	Mon Aug  7 11:40:50 2017
+++ new/usr/src/uts/common/inet/ip/keysock.c	Mon Aug  7 11:40:50 2017
@@ -22,6 +22,9 @@
  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
+/*
+ * Copyright 2017 Joyent, Inc.
+ */
 
 #include <sys/param.h>
 #include <sys/types.h>
@@ -892,6 +895,81 @@
 }
 
 /*
+ * Handle STREAMS ioctl copyin for getsockname() for both PF_KEY and
+ * PF_POLICY.
+ */
+void
+keysock_spdsock_wput_iocdata(queue_t *q, mblk_t *mp, sa_family_t family)
+{
+	mblk_t *mp1;
+	STRUCT_HANDLE(strbuf, sb);
+	/* What size of sockaddr do we need? */
+	const uint_t addrlen = sizeof (struct sockaddr);
+
+	/* We only handle TI_GET{MY,PEER}NAME (get{sock,peer}name()). */
+	switch (((struct iocblk *)mp->b_rptr)->ioc_cmd) {
+	case TI_GETMYNAME:
+	case TI_GETPEERNAME:
+		break;
+	default:
+		freemsg(mp);
+		return;
+	}
+
+	switch (mi_copy_state(q, mp, &mp1)) {
+	case -1:
+		return;
+	case MI_COPY_CASE(MI_COPY_IN, 1):
+		break;
+	case MI_COPY_CASE(MI_COPY_OUT, 1):
+		/*
+		 * The address has been copied out, so now
+		 * copyout the strbuf.
+		 */
+		mi_copyout(q, mp);
+		return;
+	case MI_COPY_CASE(MI_COPY_OUT, 2):
+		/*
+		 * The address and strbuf have been copied out.
+		 * We're done, so just acknowledge the original
+		 * M_IOCTL.
+		 */
+		mi_copy_done(q, mp, 0);
+		return;
+	default:
+		/*
+		 * Something strange has happened, so acknowledge
+		 * the original M_IOCTL with an EPROTO error.
+		 */
+		mi_copy_done(q, mp, EPROTO);
+		return;
+	}
+
+	/*
+	 * Now we have the strbuf structure for TI_GET{MY,PEER}NAME. Next we
+	 * copyout the requested address and then we'll copyout the strbuf.
+	 * Regardless of sockname or peername, we just return a sockaddr with
+	 * sa_family set.
+	 */
+	STRUCT_SET_HANDLE(sb, ((struct iocblk *)mp->b_rptr)->ioc_flag,
+	    (void *)mp1->b_rptr);
+
+	if (STRUCT_FGET(sb, maxlen) < addrlen) {
+		mi_copy_done(q, mp, EINVAL);
+		return;
+	}
+
+	mp1 = mi_copyout_alloc(q, mp, STRUCT_FGETP(sb, buf), addrlen, B_TRUE);
+	if (mp1 == NULL)
+		return;
+
+	STRUCT_FSET(sb, len, addrlen);
+	((struct sockaddr *)mp1->b_wptr)->sa_family = family;
+	mp1->b_wptr += addrlen;
+	mi_copyout(q, mp);
+}
+
+/*
  * Handle STREAMS messages.
  */
 static void
@@ -954,11 +1032,24 @@
 			break;
 		}
 		return;
+	case M_IOCDATA:
+		keysock_spdsock_wput_iocdata(q, mp, PF_KEY);
+		return;
 	case M_IOCTL:
 		iocp = (struct iocblk *)mp->b_rptr;
 		error = EINVAL;
 
 		switch (iocp->ioc_cmd) {
+		case TI_GETMYNAME:
+		case TI_GETPEERNAME:
+			/*
+			 * For pfiles(1) observability with getsockname().
+			 * See keysock_spdsock_wput_iocdata() for the rest of
+			 * this.
+			 */
+			mi_copyin(q, mp, NULL,
+			    SIZEOF_STRUCT(strbuf, iocp->ioc_flag));
+			return;
 		case ND_SET:
 		case ND_GET:
 			if (nd_getset(q, keystack->keystack_g_nd, mp)) {
--- old/usr/src/uts/common/inet/ip/spdsock.c	Mon Aug  7 11:40:50 2017
+++ new/usr/src/uts/common/inet/ip/spdsock.c	Mon Aug  7 11:40:50 2017
@@ -21,6 +21,7 @@
 /*
  * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
  * Copyright (c) 2012 Nexenta Systems, Inc. All rights reserved.
+ * Copyright 2017 Joyent, Inc.
  */
 
 #include <sys/param.h>
@@ -34,6 +35,7 @@
 #include <sys/sysmacros.h>
 #define	_SUN_TPI_VERSION 2
 #include <sys/tihdr.h>
+#include <sys/timod.h>
 #include <sys/ddi.h>
 #include <sys/sunddi.h>
 #include <sys/mkdev.h>
@@ -3404,11 +3406,24 @@
 			break;
 		}
 		return;
+	case M_IOCDATA:
+		keysock_spdsock_wput_iocdata(q, mp, PF_POLICY);
+		return;
 	case M_IOCTL:
 		iocp = (struct iocblk *)mp->b_rptr;
 		error = EINVAL;
 
 		switch (iocp->ioc_cmd) {
+		case TI_GETMYNAME:
+		case TI_GETPEERNAME:
+			/*
+			 * For pfiles(1) observability with getsockname().
+			 * See keysock_spdsock_wput_iocdata() for the rest of
+			 * this.
+			 */
+			mi_copyin(q, mp, NULL,
+			    SIZEOF_STRUCT(strbuf, iocp->ioc_flag));
+			return;
 		case ND_SET:
 		case ND_GET:
 			if (nd_getset(q, spds->spds_g_nd, mp)) {
--- old/usr/src/uts/common/inet/ipsec_impl.h	Mon Aug  7 11:40:50 2017
+++ new/usr/src/uts/common/inet/ipsec_impl.h	Mon Aug  7 11:40:50 2017
@@ -22,6 +22,7 @@
  * Copyright 2009 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_IPSEC_IMPL_H
@@ -110,6 +111,9 @@
 extern boolean_t keysock_extended_reg(netstack_t *);
 extern uint32_t keysock_next_seq(netstack_t *);
 
+/* Common-code for spdsock and keysock. */
+extern void keysock_spdsock_wput_iocdata(queue_t *, mblk_t *, sa_family_t);
+
 /*
  * Locking for ipsec policy rules:
  *
--- old/usr/src/uts/intel/ia32/ml/modstubs.s	Mon Aug  7 11:40:50 2017
+++ new/usr/src/uts/intel/ia32/ml/modstubs.s	Mon Aug  7 11:40:50 2017
@@ -21,7 +21,7 @@
 
 /*
  * Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2015, Joyent, Inc. All rights reserved.
+ * Copyright (c) 2017, Joyent, Inc. All rights reserved.
  */
 
 #include <sys/asm_linkage.h>
@@ -518,7 +518,7 @@
 	WSTUB(ipsecah,	ipsecah_icmp_error,	nomod_zero);
 	END_MODULE(ipsecah);
 #endif
-	
+
 #ifndef	IPSECESP_MODULE
 	MODULE(ipsecesp,drv);
 	WSTUB(ipsecesp,	ipsecesp_fill_defs,	nomod_zero);
@@ -529,9 +529,10 @@
 	WSTUB(ipsecesp,	ipsecesp_send_keepalive,	nomod_zero);
 	END_MODULE(ipsecesp);
 #endif
-	
+
 #ifndef	KEYSOCK_MODULE
 	MODULE(keysock,	drv);
+	WSTUB(keysock,	keysock_spdsock_wput_iocdata,	nomod_void);
 	WSTUB(keysock,	keysock_plumb_ipsec,	nomod_zero);
 	WSTUB(keysock,	keysock_extended_reg,	nomod_zero);
 	WSTUB(keysock,	keysock_next_seq,	nomod_zero);
--- old/usr/src/uts/sparc/ml/modstubs.s	Mon Aug  7 11:40:50 2017
+++ new/usr/src/uts/sparc/ml/modstubs.s	Mon Aug  7 11:40:50 2017
@@ -21,8 +21,8 @@
 
 /*
  * Copyright (c) 1990, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2015, Joyent, Inc. All rights reserved.
  * Copyright 2016 Nexenta Systems, Inc.
+ * Copyright (c) 2017, Joyent, Inc. All rights reserved.
  */
 
 #if !defined(lint)
@@ -422,6 +422,7 @@
 
 #ifndef KEYSOCK_MODULE
 	MODULE(keysock,drv);
+	WSTUB(keysock,	keysock_spdsock_wput_iocdata,	nomod_void);
 	WSTUB(keysock,	keysock_plumb_ipsec,	nomod_zero);
 	WSTUB(keysock,	keysock_extended_reg,	nomod_zero);
 	WSTUB(keysock,	keysock_next_seq,	nomod_zero);
