changeset 12644:4f9a0cd40c5f

6939100 convert KSSL into a socket filter
author Anders Persson <Anders.Persson@Sun.COM>
date Thu, 17 Jun 2010 17:23:59 -0700
parents 044ff822d212
children 0de9ed7d05ab
files usr/src/cmd/cmd-inet/usr.sbin/Makefile usr/src/cmd/cmd-inet/usr.sbin/kssl/ksslcfg/kssl-proxy.xml usr/src/cmd/cmd-inet/usr.sbin/kssl/ksslcfg/ksslcfg.h usr/src/cmd/cmd-inet/usr.sbin/kssl/ksslcfg/ksslcfg_create.c usr/src/cmd/cmd-inet/usr.sbin/kssl/ksslcfg/ksslcfg_delete.c usr/src/cmd/cmd-inet/usr.sbin/socket-filter-kssl.xml usr/src/pkg/manifests/SUNWcs.mf usr/src/pkg/manifests/system-kernel.mf usr/src/uts/common/Makefile.files usr/src/uts/common/fs/sockfs/sockcommon_sops.c usr/src/uts/common/fs/sockfs/sockfilter.c usr/src/uts/common/fs/sockfs/sockssl.c usr/src/uts/common/fs/sockfs/sockstr.c usr/src/uts/common/fs/sockfs/socksyscalls.c usr/src/uts/common/fs/sockfs/socktpi.c usr/src/uts/common/fs/sockfs/socktpi.h usr/src/uts/common/inet/kssl/kssl.c usr/src/uts/common/inet/kssl/ksslapi.c usr/src/uts/common/inet/kssl/ksslapi.h usr/src/uts/common/inet/kssl/ksslfilter.c usr/src/uts/common/inet/kssl/ksslimpl.h usr/src/uts/common/inet/kssl/ksslproto.h usr/src/uts/common/inet/kssl/ksslrec.c usr/src/uts/common/inet/sockmods/sockmod_sdp.c usr/src/uts/common/inet/tcp.h usr/src/uts/common/inet/tcp/tcp.c usr/src/uts/common/inet/tcp/tcp_fusion.c usr/src/uts/common/inet/tcp/tcp_input.c usr/src/uts/common/inet/tcp/tcp_kssl.c usr/src/uts/common/inet/tcp/tcp_opt_data.c usr/src/uts/common/inet/tcp/tcp_output.c usr/src/uts/common/inet/tcp/tcp_socket.c usr/src/uts/common/inet/tcp/tcp_tpi.c usr/src/uts/common/sys/tihdr.h usr/src/uts/common/syscall/sendfile.c usr/src/uts/intel/Makefile.intel.shared usr/src/uts/intel/ia32/ml/modstubs.s usr/src/uts/intel/ksslf/Makefile usr/src/uts/sparc/Makefile.sparc.shared usr/src/uts/sparc/ksslf/Makefile usr/src/uts/sparc/ml/modstubs.s
diffstat 41 files changed, 1246 insertions(+), 1297 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/cmd/cmd-inet/usr.sbin/Makefile	Thu Jun 17 17:22:09 2010 -0700
+++ b/usr/src/cmd/cmd-inet/usr.sbin/Makefile	Thu Jun 17 17:23:59 2010 -0700
@@ -36,7 +36,7 @@
 		ndd $(SYNCPROG) $(DHCPPROG) $(XMODPROG)
 
 MANIFEST=	rarp.xml telnet.xml comsat.xml finger.xml \
-		login.xml shell.xml rexec.xml 
+		login.xml shell.xml rexec.xml socket-filter-kssl.xml
 SVCMETHOD=	svc-sockfilter
 
 ROOTFS_PROG=	hostconfig route soconfig
@@ -71,8 +71,8 @@
 		snoop sppptun traceroute wificonfig
 
 MSGSUBDIRS=	bootconfchk htable ifconfig ilbadm in.ftpd in.routed in.talkd \
-		inetadm inetconv ipadm ipmpstat ipqosconf ipsecutils kssl/ksslcfg \
-		nwamadm nwamcfg routeadm sppptun snoop wificonfig
+		inetadm inetconv ipadm ipmpstat ipqosconf ipsecutils \
+		kssl/ksslcfg nwamadm nwamcfg routeadm sppptun snoop wificonfig
 
 # As programs get lint-clean, add them here and to the 'lint' target.
 # Eventually this hack should go away, and all in PROG should be
@@ -85,8 +85,9 @@
 # with SUBDIRS.  Also (sigh) deal with the commented-out build lines
 # for the lint rule.
 LINTSUBDIRS=	bootconfchk ilbadm in.rdisc in.routed in.talkd inetadm \
-		inetconv ipmpstat ipqosconf ipsecutils nwamadm nwamcfg ping \
-		routeadm sppptun traceroute wificonfig
+		inetconv ipmpstat ipqosconf ipsecutils kssl/kssladm \
+		kssl/ksslcfg nwamadm nwamcfg ping routeadm sppptun traceroute \
+		wificonfig
 # And as programs are verified not to attempt to write into constants,
 # -xstrconst should be used to ensure they stay that way.
 CONSTCLEAN=
--- a/usr/src/cmd/cmd-inet/usr.sbin/kssl/ksslcfg/kssl-proxy.xml	Thu Jun 17 17:22:09 2010 -0700
+++ b/usr/src/cmd/cmd-inet/usr.sbin/kssl/ksslcfg/kssl-proxy.xml	Thu Jun 17 17:23:59 2010 -0700
@@ -1,15 +1,13 @@
 <?xml version="1.0"?>
 <!DOCTYPE service_bundle SYSTEM "/usr/share/lib/xml/dtd/service_bundle.dtd.1">
 <!--
-	Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
-	Use is subject to license terms.
+	Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
 
  CDDL HEADER START
 
  The contents of this file are subject to the terms of the
- Common Development and Distribution License, Version 1.0 only
- (the "License").  You may not use this file except in compliance
- with the License.
+ Common Development and Distribution License (the "License").
+ You may not use this file except in compliance with the License.
 
  You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  or http://www.opensolaris.org/os/licensing.
@@ -24,8 +22,6 @@
 
  CDDL HEADER END
 
-	ident	"%Z%%M%	%I%	%E% SMI"
-
 	NOTE:  This service manifest is not editable; its contents will
 	be overwritten by package or patch operations, including
 	operating system upgrade.  Make customizations in a different
@@ -40,6 +36,14 @@
 	version='1'>
 
 	<dependency
+	    name='socket-filter'
+	    grouping='require_all'
+	    restart_on='restart'
+	    type='service'>
+		<service_fmri value='svc:/network/socket-filter:kssl' />	
+	</dependency>
+
+	<dependency
 	    name='cryptosvc'
 	    grouping='require_all'
 	    restart_on='none'
--- a/usr/src/cmd/cmd-inet/usr.sbin/kssl/ksslcfg/ksslcfg.h	Thu Jun 17 17:22:09 2010 -0700
+++ b/usr/src/cmd/cmd-inet/usr.sbin/kssl/ksslcfg/ksslcfg.h	Thu Jun 17 17:23:59 2010 -0700
@@ -2,9 +2,8 @@
  * CDDL HEADER START
  *
  * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
  *
  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  * or http://www.opensolaris.org/os/licensing.
@@ -20,15 +19,12 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
 #ifndef _KSSLCFG_H
 #define	_KSSLCFG_H
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 /*
  * Common routines and variables used by ksslcfg files.
  */
@@ -49,6 +45,8 @@
 #define	INSTANCE_ANY_EXISTS	3
 #define	INSTANCE_OTHER_EXISTS	4
 
+#define	KSSL_FILTER_SVC_NAME	"svc:/network/socket-filter:kssl"
+
 extern const char *SERVICE_NAME;
 extern boolean_t verbose;
 
--- a/usr/src/cmd/cmd-inet/usr.sbin/kssl/ksslcfg/ksslcfg_create.c	Thu Jun 17 17:22:09 2010 -0700
+++ b/usr/src/cmd/cmd-inet/usr.sbin/kssl/ksslcfg/ksslcfg_create.c	Thu Jun 17 17:23:59 2010 -0700
@@ -20,13 +20,9 @@
  */
 
 /*
- * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
-
 #include <libscf.h>
 #include <netinet/in.h>
 #include <stdio.h>
@@ -41,26 +37,26 @@
 	if (do_print)
 		(void) fprintf(stderr, gettext("Usage:\n"));
 	(void) fprintf(stderr, "ksslcfg create"
-		" -f pkcs11 [-d softtoken_directory] -T <token_label>"
-		" -C <certificate_label> -x <proxy_port>"
-		" [-h <ca_certchain_file>]"
-		" [options] [<server_address>] <server_port>\n");
+	    " -f pkcs11 [-d softtoken_directory] -T <token_label>"
+	    " -C <certificate_label> -x <proxy_port>"
+	    " [-h <ca_certchain_file>]"
+	    " [options] [<server_address>] <server_port>\n");
 
 	(void) fprintf(stderr, "ksslcfg create"
-		" -f pkcs12 -i <cert_and_key_pk12file> -x <proxy_port>"
-		" [options] [<server_address>] <server_port>\n");
+	    " -f pkcs12 -i <cert_and_key_pk12file> -x <proxy_port>"
+	    " [options] [<server_address>] <server_port>\n");
 
 	(void) fprintf(stderr, "ksslcfg create"
-		" -f pem -i <cert_and_key_pemfile> -x <proxy_port>"
-		" [options] [<server_address>] <server_port>\n");
+	    " -f pem -i <cert_and_key_pemfile> -x <proxy_port>"
+	    " [options] [<server_address>] <server_port>\n");
 
 	(void) fprintf(stderr, gettext("options are:\n"));
 	(void) fprintf(stderr, "\t[-c <ciphersuites>]\n"
-		"\t[-p <password_file>]\n"
-		"\t[-t <ssl_session_cache_timeout>]\n"
-		"\t[-u <username>]\n"
-		"\t[-z <ssl_session_cache_size>]\n"
-		"\t[-v]\n");
+	    "\t[-p <password_file>]\n"
+	    "\t[-t <ssl_session_cache_timeout>]\n"
+	    "\t[-u <username>]\n"
+	    "\t[-z <ssl_session_cache_size>]\n"
+	    "\t[-v]\n");
 }
 
 static scf_propertygroup_t *
@@ -154,23 +150,23 @@
     const char *value_str)
 {
 	if ((add_new_property(handle, SCF_PROPERTY_USE_PROFILE,
-		SCF_TYPE_BOOLEAN, "false", tran) != SUCCESS) ||
+	    SCF_TYPE_BOOLEAN, "false", tran) != SUCCESS) ||
 	    (add_new_property(handle, SCF_PROPERTY_USER, SCF_TYPE_ASTRING,
-		value_str, tran) != SUCCESS) ||
+	    value_str, tran) != SUCCESS) ||
 	    (add_new_property(handle, SCF_PROPERTY_GROUP, SCF_TYPE_ASTRING,
-		":default", tran) != SUCCESS) ||
+	    ":default", tran) != SUCCESS) ||
 	    (add_new_property(handle, SCF_PROPERTY_LIMIT_PRIVILEGES,
-		SCF_TYPE_ASTRING, ":default", tran) != SUCCESS) ||
+	    SCF_TYPE_ASTRING, ":default", tran) != SUCCESS) ||
 	    (add_new_property(handle, SCF_PROPERTY_WORKING_DIRECTORY,
-		SCF_TYPE_ASTRING, ":default", tran) != SUCCESS) ||
+	    SCF_TYPE_ASTRING, ":default", tran) != SUCCESS) ||
 	    (add_new_property(handle, SCF_PROPERTY_SUPP_GROUPS,
-		SCF_TYPE_ASTRING, ":default", tran) != SUCCESS) ||
+	    SCF_TYPE_ASTRING, ":default", tran) != SUCCESS) ||
 	    (add_new_property(handle, SCF_PROPERTY_RESOURCE_POOL,
-		SCF_TYPE_ASTRING, ":default", tran) != SUCCESS) ||
+	    SCF_TYPE_ASTRING, ":default", tran) != SUCCESS) ||
 	    (add_new_property(handle, SCF_PROPERTY_PROJECT, SCF_TYPE_ASTRING,
-		":default", tran) != SUCCESS) ||
+	    ":default", tran) != SUCCESS) ||
 	    (add_new_property(handle, SCF_PROPERTY_PRIVILEGES,
-		SCF_TYPE_ASTRING, "basic,sys_net_config", tran) != SUCCESS))
+	    SCF_TYPE_ASTRING, "basic,sys_net_config", tran) != SUCCESS))
 		return (FAILURE);
 
 	return (SUCCESS);
@@ -340,11 +336,11 @@
 	KSSL_DEBUG("scf_service_add_instance succeeded\n");
 
 	if ((add_pg_method(handle, instance, kssl_entry, "start",
-		command, username) != SUCCESS) ||
+	    command, username) != SUCCESS) ||
 	    (add_pg_method(handle, instance, kssl_entry, "refresh",
-		command, username) != SUCCESS) ||
+	    command, username) != SUCCESS) ||
 	    (add_pg_method(handle, instance, kssl_entry, "stop",
-		"", username) != SUCCESS)) {
+	    "", username) != SUCCESS)) {
 		scf_instance_destroy(instance);
 		return (status);
 	}
@@ -657,6 +653,19 @@
 		}
 	}
 
+	/*
+	 * network/ssl/proxy depends on network/socket-filter:kssl;
+	 * enable that service now.
+	 */
+	if (smf_enable_instance(KSSL_FILTER_SVC_NAME, 0) != 0) {
+		KSSL_DEBUG(
+		    "smf_enable_instance failed: %s\n" KSSL_FILTER_SVC_NAME);
+		(void) fprintf(stderr, gettext(
+		    "Unable to enable required service \"%s\". Error: %s"),
+		    KSSL_FILTER_SVC_NAME, scf_strerror(scf_error()));
+		status = FAILURE;
+	}
+
 	free(instance_name);
 	free(inaddr_any_name);
 	free(buf);
--- a/usr/src/cmd/cmd-inet/usr.sbin/kssl/ksslcfg/ksslcfg_delete.c	Thu Jun 17 17:22:09 2010 -0700
+++ b/usr/src/cmd/cmd-inet/usr.sbin/kssl/ksslcfg/ksslcfg_delete.c	Thu Jun 17 17:23:59 2010 -0700
@@ -2,9 +2,8 @@
  * CDDL HEADER START
  *
  * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
  *
  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  * or http://www.opensolaris.org/os/licensing.
@@ -20,13 +19,11 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 #include <libscf.h>
+#include <libscf_priv.h>
 #include <stdio.h>
 #include <unistd.h>
 #include <stdlib.h>
@@ -83,6 +80,23 @@
 	    fmri);
 }
 
+static int
+count_inst_cb(void *arg, scf_walkinfo_t *wip)
+{
+	int *num_inst = arg;
+
+	if (wip->inst != NULL)
+		(*num_inst)++;
+
+	return (0);
+}
+
+/*ARGSUSED*/
+static void
+ign_err(const char *unused, ...)
+{
+}
+
 int
 delete_instance(const char *instance_name)
 {
@@ -94,6 +108,7 @@
 	scf_service_t *svc;
 	scf_handle_t *handle;
 	scf_instance_t *instance;
+	int num_inst = 0, exit_status = 0;
 
 	handle = scf_handle_create(SCF_VERSION);
 	if (handle == NULL) {
@@ -210,6 +225,22 @@
 		KSSL_DEBUG("deleted %s\n", instance_name);
 	}
 
+	if (scf_walk_fmri(handle, 1, (char **)&SERVICE_NAME,
+	    SCF_WALK_MULTIPLE, count_inst_cb, &num_inst, &exit_status,
+	    ign_err) == 0) {
+		/*
+		 * Disable the kssl socket filter if this is the last
+		 * kssl instance.
+		 */
+		if (num_inst == 0) {
+			if (smf_disable_instance(KSSL_FILTER_SVC_NAME, 0) != 0)
+				(void) fprintf(stderr,
+				    gettext("Unable to disable service \"%s\". "
+				    "Error: %s"), KSSL_FILTER_SVC_NAME,
+				    scf_strerror(scf_error()));
+		}
+	}
+
 	status = SUCCESS;
 
 out4:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/cmd/cmd-inet/usr.sbin/socket-filter-kssl.xml	Thu Jun 17 17:23:59 2010 -0700
@@ -0,0 +1,90 @@
+<?xml version="1.0"?>
+<!DOCTYPE service_bundle SYSTEM "/usr/share/lib/xml/dtd/service_bundle.dtd.1">
+<!--
+	Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+
+ CDDL HEADER START
+
+ The contents of this file are subject to the terms of the
+ Common Development and Distribution License (the "License").
+ You may not use this file except in compliance with the License.
+
+ You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ or http://www.opensolaris.org/os/licensing.
+ See the License for the specific language governing permissions
+ and limitations under the License.
+
+ When distributing Covered Code, include this CDDL HEADER in each
+ file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ If applicable, add the following below this CDDL HEADER, with the
+ fields enclosed by brackets "[]" replaced with your own identifying
+ information: Portions Copyright [yyyy] [name of copyright owner]
+
+ CDDL HEADER END
+
+	NOTE:  This service manifest is not editable; its contents will
+	be overwritten by package or patch operations, including
+	operating system upgrade.  Make customizations in a different
+	file.
+-->
+
+<service_bundle type='manifest' name='SUNWcs:socket-filter-kssl'>
+
+<service
+	name='network/socket-filter'
+	type='service'
+	version='1'>
+
+	<instance name='kssl' enabled='false'>
+		<dependency
+		    name='kssl-filter-filesystem-root'
+		    grouping='require_all'
+		    restart_on='none'
+		    type='service'>
+			<service_fmri value='svc:/system/filesystem/root' />	
+		</dependency>
+
+		<exec_method
+			type='method'
+			name='start'
+			exec='/lib/svc/method/svc-sockfilter start'
+			timeout_seconds='60' />
+
+		<exec_method
+			type='method'
+			name='stop'
+			exec='/lib/svc/method/svc-sockfilter stop'
+			timeout_seconds='60' />
+
+		<property_group name='startd' type='framework'>
+			<propval name='duration' type='astring'
+				value='transient' />
+		</property_group>
+
+		<property_group name='socket-filter' type='framework'>
+			<propval name='name' type='astring' value='ksslf' />
+			<propval name='module_name' type='astring'
+				value='ksslf' />
+			<propval name='attach_semantics' type='astring'
+				value='auto' />
+			<propval name='socket_tuples' type='astring'
+				value='2:2:0,2:2:6,26:2:0,26:2:6' />
+		</property_group>
+		
+		<template>
+			<common_name>
+				<loctext xml:lang='C'>
+				kernel SSL socket filter 
+				</loctext>
+			</common_name>
+			<documentation>
+				<manpage title='ksslcfg' section='1M'
+				    manpath='/usr/share/man' />
+			</documentation>
+		</template>
+	</instance>
+
+	<stability value='Unstable' />
+</service>
+
+</service_bundle>
--- a/usr/src/pkg/manifests/SUNWcs.mf	Thu Jun 17 17:22:09 2010 -0700
+++ b/usr/src/pkg/manifests/SUNWcs.mf	Thu Jun 17 17:23:59 2010 -0700
@@ -552,6 +552,7 @@
 file path=lib/svc/manifest/network/rpc/keyserv.xml group=sys mode=0444
 file path=lib/svc/manifest/network/shares/group.xml group=sys mode=0444
 file path=lib/svc/manifest/network/shares/reparsed.xml group=sys mode=0444
+file path=lib/svc/manifest/network/socket-filter-kssl.xml group=sys mode=0444
 file path=lib/svc/manifest/network/ssl/kssl-proxy.xml group=sys mode=0444
 file path=lib/svc/manifest/system/auditd.xml group=sys mode=0444
 file path=lib/svc/manifest/system/boot-archive-update.xml group=sys mode=0444
--- a/usr/src/pkg/manifests/system-kernel.mf	Thu Jun 17 17:22:09 2010 -0700
+++ b/usr/src/pkg/manifests/system-kernel.mf	Thu Jun 17 17:23:59 2010 -0700
@@ -716,8 +716,10 @@
 $(i386_ONLY)file path=kernel/sched/SDC group=sys mode=0755
 $(i386_ONLY)file path=kernel/sched/TS group=sys mode=0755
 $(i386_ONLY)file path=kernel/sched/TS_DPTBL group=sys mode=0755
+file path=kernel/socketmod/$(ARCH64)/ksslf group=sys mode=0755
 file path=kernel/socketmod/$(ARCH64)/socksctp group=sys mode=0755
 file path=kernel/socketmod/$(ARCH64)/trill group=sys mode=0755
+$(i386_ONLY)file path=kernel/socketmod/ksslf group=sys mode=0755
 $(i386_ONLY)file path=kernel/socketmod/socksctp group=sys mode=0755
 $(i386_ONLY)file path=kernel/socketmod/trill group=sys mode=0755
 file path=kernel/strmod/$(ARCH64)/bufmod group=sys mode=0755
--- a/usr/src/uts/common/Makefile.files	Thu Jun 17 17:22:09 2010 -0700
+++ b/usr/src/uts/common/Makefile.files	Thu Jun 17 17:23:59 2010 -0700
@@ -524,10 +524,9 @@
 
 IP_ICMP_OBJS =	icmp.o icmp_opt_data.o
 IP_RTS_OBJS =	rts.o rts_opt_data.o
-IP_TCP_OBJS =	tcp.o tcp_fusion.o tcp_kssl.o tcp_opt_data.o tcp_sack.o \
-		tcp_stats.o tcp_misc.o tcp_timers.o tcp_time_wait.o tcp_tpi.o \
-		tcp_output.o tcp_input.o tcp_socket.o tcp_bind.o tcp_cluster.o \
-		tcp_tunables.o
+IP_TCP_OBJS =	tcp.o tcp_fusion.o tcp_opt_data.o tcp_sack.o tcp_stats.o \
+		tcp_misc.o tcp_timers.o tcp_time_wait.o tcp_tpi.o tcp_output.o \
+		tcp_input.o tcp_socket.o tcp_bind.o tcp_cluster.o tcp_tunables.o
 IP_UDP_OBJS =	udp.o udp_opt_data.o udp_tunables.o
 IP_SCTP_OBJS =	sctp.o sctp_opt_data.o sctp_output.o \
 		sctp_init.o sctp_input.o sctp_cookie.o \
@@ -1258,7 +1257,7 @@
 SPEC_OBJS +=	specsubr.o	specvfsops.o	specvnops.o
 
 SOCK_OBJS +=	socksubr.o	sockvfsops.o	sockparams.o	\
-		socksyscalls.o	socktpi.o	sockstr.o	sockssl.o \
+		socksyscalls.o	socktpi.o	sockstr.o \
 		sockcommon_vnops.o	sockcommon_subr.o \
 		sockcommon_sops.o	sockcommon.o	\
 		sock_notsupp.o	socknotify.o \
@@ -1544,7 +1543,9 @@
 #
 #			kernel SSL
 #
-KSSL_OBJS +=	kssl.o ksslioctl.o ksslapi.o ksslrec.o
+KSSL_OBJS +=	kssl.o ksslioctl.o 
+
+KSSL_SOCKFIL_MOD_OBJS += ksslfilter.o ksslapi.o ksslrec.o
 
 #
 #			misc. modules
--- a/usr/src/uts/common/fs/sockfs/sockcommon_sops.c	Thu Jun 17 17:22:09 2010 -0700
+++ b/usr/src/uts/common/fs/sockfs/sockcommon_sops.c	Thu Jun 17 17:23:59 2010 -0700
@@ -54,8 +54,6 @@
 #include <fs/sockfs/sodirect.h>
 #include <sys/tihdr.h>
 #include <fs/sockfs/nl7c.h>
-#include <inet/kssl/ksslapi.h>
-
 
 extern int xnet_skip_checks;
 extern int xnet_check_print;
@@ -255,40 +253,6 @@
 			else
 				return (SOP_BIND(so, name, namelen, flags, cr));
 		}
-	} else if (so->so_type == SOCK_STREAM) {
-		/* Check if KSSL has been configured for this address */
-		kssl_ent_t ent;
-		kssl_endpt_type_t type;
-		struct T_bind_req bind_req;
-		mblk_t *mp;
-
-		/*
-		 * TODO: Check with KSSL team if we could add a function call
-		 * that only queries whether KSSL is enabled for the given
-		 * address.
-		 */
-		bind_req.PRIM_type = T_BIND_REQ;
-		bind_req.ADDR_length = namelen;
-		bind_req.ADDR_offset = (t_scalar_t)sizeof (bind_req);
-		mp = soallocproto2(&bind_req, sizeof (bind_req),
-		    name, namelen, 0, _ALLOC_SLEEP, cr);
-
-		type = kssl_check_proxy(mp, so, &ent);
-		freemsg(mp);
-
-		if (type != KSSL_NO_PROXY) {
-			/*
-			 * KSSL has been configured for this address, so
-			 * we must fall back to TPI.
-			 */
-			kssl_release_ent(ent, so, type);
-			error = so_tpi_fallback(so, cr);
-			SO_UNBLOCK_FALLBACK(so);
-			if (error)
-				return (error);
-			else
-				return (SOP_BIND(so, name, namelen, flags, cr));
-		}
 	}
 
 dobind:
--- a/usr/src/uts/common/fs/sockfs/sockfilter.c	Thu Jun 17 17:22:09 2010 -0700
+++ b/usr/src/uts/common/fs/sockfs/sockfilter.c	Thu Jun 17 17:23:59 2010 -0700
@@ -1768,3 +1768,45 @@
 	*flowctrld = (avail > 0) ? B_FALSE : B_TRUE;
 	return (error);
 }
+
+/*
+ * sof_newconn_move(handle, newparent)
+ *
+ * Private interface only to be used by KSSL.
+ *
+ * Moves the socket associated with `handle' from its current listening
+ * socket to the listener associated with `newparent'. The socket being
+ * moved must be in a deferred state and it is up to the consumer of the
+ * interface to ensure that the `newparent' does not go away while this
+ * operation is pending.
+ */
+boolean_t
+sof_newconn_move(sof_handle_t handle, sof_handle_t newparent)
+{
+	sof_instance_t *inst = (sof_instance_t *)handle;
+	sof_instance_t *newpinst = (sof_instance_t *)newparent;
+	struct sonode *so, *old, *new;
+
+	so = inst->sofi_sonode;
+	ASSERT(so->so_state & SS_FIL_DEFER);
+
+	if (inst->sofi_next != NULL || inst->sofi_prev != NULL ||
+	    !(so->so_state & SS_FIL_DEFER))
+		return (B_FALSE);
+
+	old = so->so_listener;
+	mutex_enter(&old->so_acceptq_lock);
+	list_remove(&old->so_acceptq_defer, so);
+	old->so_acceptq_len--;
+	mutex_exit(&old->so_acceptq_lock);
+
+	new = newpinst->sofi_sonode;
+	mutex_enter(&new->so_acceptq_lock);
+	list_insert_tail(&new->so_acceptq_defer, so);
+	new->so_acceptq_len++;
+	mutex_exit(&new->so_acceptq_lock);
+
+	so->so_listener = new;
+
+	return (B_TRUE);
+}
--- a/usr/src/uts/common/fs/sockfs/sockssl.c	Thu Jun 17 17:22:09 2010 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,114 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <sys/types.h>
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kmem.h>
-#include <sys/sysmacros.h>
-#include <sys/vnode.h>
-#include <sys/debug.h>
-#include <sys/errno.h>
-#include <sys/stream.h>
-#include <sys/strsubr.h>
-#include <sys/vtrace.h>
-#include <sys/strsun.h>
-#include <sys/cmn_err.h>
-
-#include <sys/socket.h>
-#include <sys/sockio.h>
-#include <sys/socketvar.h>
-
-#include <fs/sockfs/socktpi.h>
-
-#include <inet/kssl/ksslapi.h>
-
-/*
- * This routine is registered with the stream head to be called by kstrgetmsg()
- * with every packet received on the read queue, and before copying its
- * content to user buffers. kstrgetmsg() calls only once with the same
- * message.
- * If the message is successfully procssed, then it is returned.
- * A failed message will be freed.
- */
-/* ARGSUSED */
-mblk_t *
-strsock_kssl_input(vnode_t *vp, mblk_t *mp,
-		strwakeup_t *wakeups, strsigset_t *firstmsgsigs,
-		strsigset_t *allmsgsigs, strpollset_t *pollwakeups)
-{
-	struct sonode *so = VTOSO(vp);
-	kssl_ctx_t kssl_ctx = SOTOTPI(so)->sti_kssl_ctx;
-	kssl_cmd_t kssl_cmd;
-	mblk_t *out;
-
-	dprintso(so, 1, ("strsock_kssl_input(%p, %p)\n",
-	    (void *)vp, (void *)mp));
-
-	kssl_cmd = kssl_handle_mblk(kssl_ctx, &mp, &out);
-
-	switch (kssl_cmd) {
-	case KSSL_CMD_NONE:
-		return (NULL);
-
-	case KSSL_CMD_DELIVER_PROXY:
-		return (mp);
-
-	case KSSL_CMD_SEND: {
-		ASSERT(out != NULL);
-
-		putnext(vp->v_stream->sd_wrq, out);
-	}
-	/* FALLTHRU */
-	default:
-		/* transient error. */
-		return (NULL);
-	}
-}
-
-/*
- * This routine is registered with the stream head be called by
- * kstrmakedata() with every packet sent downstreams.
- * If the message is successfully processed, then it is returned.
- */
-/* ARGSUSED */
-mblk_t *
-strsock_kssl_output(vnode_t *vp, mblk_t *mp,
-		strwakeup_t *wakeups, strsigset_t *firstmsgsigs,
-		strsigset_t *allmsgsigs, strpollset_t *pollwakeups)
-{
-	struct sonode *so = VTOSO(vp);
-	kssl_ctx_t kssl_ctx = SOTOTPI(so)->sti_kssl_ctx;
-	mblk_t *recmp;
-
-	dprintso(so, 1, ("strsock_kssl_output(%p, %p)\n",
-	    (void *)vp, (void *)mp));
-
-	if ((recmp = kssl_build_record(kssl_ctx, mp)) == NULL) {
-		/* The caller will free the bogus message */
-		return (NULL);
-	}
-	return (recmp);
-}
--- a/usr/src/uts/common/fs/sockfs/sockstr.c	Thu Jun 17 17:22:09 2010 -0700
+++ b/usr/src/uts/common/fs/sockfs/sockstr.c	Thu Jun 17 17:23:59 2010 -0700
@@ -20,8 +20,7 @@
  */
 
 /*
- * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 1995, 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
 #include <sys/types.h>
@@ -64,8 +63,6 @@
 #define	_SUN_TPI_VERSION	2
 #include <sys/tihdr.h>
 
-#include <inet/kssl/ksslapi.h>
-
 #include <c2/audit.h>
 
 #include <fs/sockfs/socktpi.h>
@@ -1228,19 +1225,6 @@
 			so->so_error = ECONNABORTED;
 			mutex_exit(&so->so_lock);
 
-			/*
-			 * T_KSSL_PROXY_CONN_IND may carry a handle for
-			 * an SSL context, and needs to be released.
-			 */
-			if ((tci->PRIM_type == T_SSL_PROXY_CONN_IND) &&
-			    (mp->b_cont != NULL)) {
-				kssl_ctx_t kssl_ctx;
-
-				ASSERT(MBLKL(mp->b_cont) ==
-				    sizeof (kssl_ctx_t));
-				kssl_ctx = *((kssl_ctx_t *)mp->b_cont->b_rptr);
-				kssl_release_ctx(kssl_ctx);
-			}
 			freemsg(mp);
 			return (0);
 		}
@@ -2262,11 +2246,6 @@
 		return (NULL);
 	}
 
-	/*
-	 * Extra processing in case of an SSL proxy, before queuing or
-	 * forwarding to the fallback endpoint
-	 */
-	case T_SSL_PROXY_CONN_IND:
 	case T_CONN_IND:
 		/*
 		 * Verify the min size and queue the message on
@@ -2289,27 +2268,6 @@
 			return (NULL);
 		}
 
-		if (tpr->type == T_SSL_PROXY_CONN_IND && mp->b_cont == NULL) {
-			/* No context: need to fall back */
-			struct sonode *fbso;
-			stdata_t *fbstp;
-
-			tpr->type = T_CONN_IND;
-
-			fbso = kssl_find_fallback(sti->sti_kssl_ent);
-
-			/*
-			 * No fallback: the remote will timeout and
-			 * disconnect.
-			 */
-			if (fbso == NULL) {
-				freemsg(mp);
-				return (NULL);
-			}
-			fbstp = SOTOV(fbso)->v_stream;
-			qreply(fbstp->sd_wrq->q_next, mp);
-			return (NULL);
-		}
 		soqueueconnind(so, mp);
 		*allmsgsigs = S_INPUT | S_RDNORM;
 		*pollwakeups = POLLIN | POLLRDNORM;
--- a/usr/src/uts/common/fs/sockfs/socksyscalls.c	Thu Jun 17 17:22:09 2010 -0700
+++ b/usr/src/uts/common/fs/sockfs/socksyscalls.c	Thu Jun 17 17:23:59 2010 -0700
@@ -2091,18 +2091,12 @@
 		iosize = (int)MIN(sr->sr_maxpsz, size);
 
 		/*
-		 * For sockets acting as an SSL proxy, we
-		 * need to adjust the size to the maximum
-		 * SSL record size set in the stream head.
-		 *
 		 * Socket filters can limit the mblk size,
 		 * so limit reads to maxblk if there are
 		 * filters present.
 		 */
 		if (vp->v_type == VSOCK &&
-		    (!SOCK_IS_NONSTR(so) &&
-		    SOTOTPI(so)->sti_kssl_ctx != NULL) ||
-		    (so->so_filter_active > 0 && maxblk != INFPSZ))
+		    so->so_filter_active > 0 && maxblk != INFPSZ)
 			iosize = (int)MIN(iosize, maxblk);
 
 		if (is_system_labeled()) {
@@ -2704,16 +2698,11 @@
 		iosize = (int)MIN(maxpsz, size);
 
 		/*
-		 * For sockets acting as an SSL proxy, we
-		 * need to adjust the size to the maximum
-		 * SSL record size set in the stream head.
-		 *
 		 * Socket filters can limit the mblk size,
 		 * so limit reads to maxblk if there are
+		 * filters present.
 		 */
 		if (vp->v_type == VSOCK &&
-		    (!SOCK_IS_NONSTR(so) &&
-		    SOTOTPI(so)->sti_kssl_ctx != NULL) ||
 		    so->so_filter_active > 0 && maxblk != INFPSZ)
 			iosize = (int)MIN(iosize, maxblk);
 
--- a/usr/src/uts/common/fs/sockfs/socktpi.c	Thu Jun 17 17:22:09 2010 -0700
+++ b/usr/src/uts/common/fs/sockfs/socktpi.c	Thu Jun 17 17:23:59 2010 -0700
@@ -79,8 +79,6 @@
 #include <fs/sockfs/nl7c.h>
 #include <fs/sockfs/nl7curi.h>
 
-#include <inet/kssl/ksslapi.h>
-
 #include <fs/sockfs/sockcommon.h>
 #include <fs/sockfs/socktpi.h>
 #include <fs/sockfs/socktpi_impl.h>
@@ -197,12 +195,6 @@
 extern	void sigintr(k_sigset_t *, int);
 extern	void sigunintr(k_sigset_t *);
 
-/* Sockets acting as an in-kernel SSL proxy */
-extern mblk_t	*strsock_kssl_input(vnode_t *, mblk_t *, strwakeup_t *,
-		    strsigset_t *, strsigset_t *, strpollset_t *);
-extern mblk_t	*strsock_kssl_output(vnode_t *, mblk_t *, strwakeup_t *,
-		    strsigset_t *, strsigset_t *, strpollset_t *);
-
 static int	sotpi_unbind(struct sonode *, int);
 
 /* TPI sockfs sonode operations */
@@ -1088,38 +1080,6 @@
 	/* Done using sti_laddr_sa - can drop the lock */
 	mutex_exit(&so->so_lock);
 
-	/*
-	 * Intercept the bind_req message here to check if this <address/port>
-	 * was configured as an SSL proxy server, or if another endpoint was
-	 * already configured to act as a proxy for us.
-	 *
-	 * Note, only if NL7C not enabled for this socket.
-	 */
-	if (nl7c == NULL &&
-	    (so->so_family == AF_INET || so->so_family == AF_INET6) &&
-	    so->so_type == SOCK_STREAM) {
-
-		if (sti->sti_kssl_ent != NULL) {
-			kssl_release_ent(sti->sti_kssl_ent, so,
-			    sti->sti_kssl_type);
-			sti->sti_kssl_ent = NULL;
-		}
-
-		sti->sti_kssl_type = kssl_check_proxy(mp, so,
-		    &sti->sti_kssl_ent);
-		switch (sti->sti_kssl_type) {
-		case KSSL_NO_PROXY:
-			break;
-
-		case KSSL_HAS_PROXY:
-			mutex_enter(&so->so_lock);
-			goto skip_transport;
-
-		case KSSL_IS_PROXY:
-			break;
-		}
-	}
-
 	error = kstrputmsg(SOTOV(so), mp, NULL, 0, 0,
 	    MSG_BAND|MSG_HOLDSIG|MSG_IGNERROR, 0);
 	if (error) {
@@ -1135,7 +1095,6 @@
 		eprintsoline(so, error);
 		goto done;
 	}
-skip_transport:
 	ASSERT(mp);
 	/*
 	 * Even if some TPI message (e.g. T_DISCON_IND) was received in
@@ -1493,17 +1452,6 @@
 		vnode_t *vp;
 
 		if ((vp = sti->sti_ux_bound_vp) != NULL) {
-
-			/* Undo any SSL proxy setup */
-			if ((so->so_family == AF_INET ||
-			    so->so_family == AF_INET6) &&
-			    (so->so_type == SOCK_STREAM) &&
-			    (sti->sti_kssl_ent != NULL)) {
-				kssl_release_ent(sti->sti_kssl_ent, so,
-				    sti->sti_kssl_type);
-				sti->sti_kssl_ent = NULL;
-				sti->sti_kssl_type = KSSL_NO_PROXY;
-			}
 			sti->sti_ux_bound_vp = NULL;
 			vn_rele_stream(vp);
 		}
@@ -1694,7 +1642,7 @@
 	struct T_conn_ind	*conn_ind;
 	struct T_conn_res	*conn_res;
 	int			error = 0;
-	mblk_t			*mp, *ctxmp, *ack_mp;
+	mblk_t			*mp, *ack_mp;
 	struct sonode		*nso;
 	vnode_t			*nvp;
 	void			*src;
@@ -1726,7 +1674,6 @@
 
 	ASSERT(mp != NULL);
 	conn_ind = (struct T_conn_ind *)mp->b_rptr;
-	ctxmp = mp->b_cont;
 
 	/*
 	 * Save SEQ_number for error paths.
@@ -1818,23 +1765,6 @@
 	nvp = SOTOV(nso);
 	nsti = SOTOTPI(nso);
 
-	/*
-	 * If the transport sent up an SSL connection context, then attach
-	 * it the new socket, and set the (sd_wputdatafunc)() and
-	 * (sd_rputdatafunc)() stream head hooks to intercept and process
-	 * SSL records.
-	 */
-	if (ctxmp != NULL) {
-		/*
-		 * This kssl_ctx_t is already held for us by the transport.
-		 * So, we don't need to do a kssl_hold_ctx() here.
-		 */
-		nsti->sti_kssl_ctx = *((kssl_ctx_t *)ctxmp->b_rptr);
-		freemsg(ctxmp);
-		mp->b_cont = NULL;
-		strsetrwputdatahooks(nvp, strsock_kssl_input,
-		    strsock_kssl_output);
-	}
 #ifdef DEBUG
 	/*
 	 * SO_DEBUG is used to trigger the dprint* and eprint* macros thus
@@ -5767,19 +5697,6 @@
 			sti->sti_ux_bound_vp = NULL;
 			vn_rele_stream(ux_vp);
 		}
-		if (so->so_family == AF_INET || so->so_family == AF_INET6) {
-			strsetrwputdatahooks(SOTOV(so), NULL, NULL);
-			if (sti->sti_kssl_ent != NULL) {
-				kssl_release_ent(sti->sti_kssl_ent, so,
-				    sti->sti_kssl_type);
-				sti->sti_kssl_ent = NULL;
-			}
-			if (sti->sti_kssl_ctx != NULL) {
-				kssl_release_ctx(sti->sti_kssl_ctx);
-				sti->sti_kssl_ctx = NULL;
-			}
-			sti->sti_kssl_type = KSSL_NO_PROXY;
-		}
 		error = strclose(vp, flag, cr);
 		vp->v_stream = NULL;
 		mutex_enter(&so->so_lock);
@@ -6749,11 +6666,6 @@
 
 	ASSERT(sti->sti_conn_ind_head == NULL);
 	ASSERT(sti->sti_conn_ind_tail == NULL);
-
-	/* Initialize the kernel SSL proxy fields */
-	sti->sti_kssl_type = KSSL_NO_PROXY;
-	sti->sti_kssl_ent = NULL;
-	sti->sti_kssl_ctx = NULL;
 }
 
 /*
--- a/usr/src/uts/common/fs/sockfs/socktpi.h	Thu Jun 17 17:22:09 2010 -0700
+++ b/usr/src/uts/common/fs/sockfs/socktpi.h	Thu Jun 17 17:23:59 2010 -0700
@@ -26,8 +26,6 @@
 #ifndef _SOCKFS_SOCKTPI_H
 #define	_SOCKFS_SOCKTPI_H
 
-#include <inet/kssl/ksslapi.h>
-
 #ifdef	__cplusplus
 extern "C" {
 #endif
@@ -245,11 +243,6 @@
 	void		*sti_nl7c_uri;
 	time_t		sti_nl7c_rtime;
 	void		*sti_nl7c_addr;
-
-	/* For sockets acting as an in-kernel SSL proxy */
-	kssl_endpt_type_t	sti_kssl_type;	/* is proxy/is proxied/none */
-	kssl_ent_t		sti_kssl_ent;	/* SSL config entry */
-	kssl_ctx_t		sti_kssl_ctx;	/* SSL session context */
 } sotpi_info_t;
 
 struct T_capability_ack;
--- a/usr/src/uts/common/inet/kssl/kssl.c	Thu Jun 17 17:22:09 2010 -0700
+++ b/usr/src/uts/common/inet/kssl/kssl.c	Thu Jun 17 17:23:59 2010 -0700
@@ -19,8 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
 
@@ -145,8 +144,10 @@
 };
 
 struct kmem_cache *kssl_cache;
+static crypto_notify_handle_t prov_update_handle = NULL;
 
 static void kssl_global_init();
+static void kssl_global_fini();
 static void kssl_init_mechs();
 static void kssl_event_callback(uint32_t, void *);
 
@@ -156,7 +157,31 @@
 int
 _init(void)
 {
-	return (mod_install(&modlinkage));
+	int error;
+
+	kssl_global_init();
+
+	if ((error = mod_install(&modlinkage)) != 0) {
+		kssl_global_fini();
+		return (error);
+	}
+	return (0);
+}
+
+int
+_fini(void)
+{
+	int error;
+
+	if ((error = mod_remove(&modlinkage)) != 0)
+		return (error);
+
+	if (prov_update_handle != NULL)
+		crypto_unnotify_events(prov_update_handle);
+
+	kssl_global_fini();
+
+	return (0);
 }
 
 int
@@ -203,8 +228,6 @@
 
 	kssl_dip = dip;
 
-	kssl_global_init();
-
 	return (DDI_SUCCESS);
 }
 
@@ -216,29 +239,16 @@
 	if (cmd != DDI_DETACH)
 		return (DDI_FAILURE);
 
-	if (kssl_entry_tab_nentries != 0 || kssl_cache_count != 0)
+	if (kssl_entry_tab_nentries != 0)
 		return (DDI_FAILURE);
 
-	mutex_destroy(&kssl_tab_mutex);
 	kssl_dip = NULL;
 
-	if (kssl_cache != NULL) {
-		kmem_cache_destroy(kssl_cache);
-		kssl_cache = NULL;
-	}
-
-	if (kssl_ksp != NULL) {
-		kstat_delete(kssl_ksp);
-		kssl_ksp = NULL;
-	}
-
 	ddi_remove_minor_node(dip, NULL);
 
 	return (DDI_SUCCESS);
 }
 
-static crypto_notify_handle_t prov_update_handle = NULL;
-
 /* ARGSUSED */
 static int
 kssl_open(dev_t *devp, int flag, int otyp, cred_t *credp)
@@ -586,6 +596,22 @@
 	};
 }
 
+static void
+kssl_global_fini(void)
+{
+	mutex_destroy(&kssl_tab_mutex);
+
+	if (kssl_cache != NULL) {
+		kmem_cache_destroy(kssl_cache);
+		kssl_cache = NULL;
+	}
+
+	if (kssl_ksp != NULL) {
+		kstat_delete(kssl_ksp);
+		kssl_ksp = NULL;
+	}
+}
+
 /*ARGSUSED*/
 static int
 kssl_constructor(void *buf, void *arg, int kmflags)
@@ -593,6 +619,7 @@
 	ssl_t *ssl = buf;
 
 	mutex_init(&ssl->kssl_lock, NULL, MUTEX_DEFAULT, NULL);
+	cv_init(&ssl->async_cv, NULL, CV_DEFAULT, NULL);
 
 	return (0);
 }
@@ -603,6 +630,7 @@
 {
 	ssl_t *ssl = buf;
 	mutex_destroy(&ssl->kssl_lock);
+	cv_destroy(&ssl->async_cv);
 }
 
 /*
--- a/usr/src/uts/common/inet/kssl/ksslapi.c	Thu Jun 17 17:22:09 2010 -0700
+++ b/usr/src/uts/common/inet/kssl/ksslapi.c	Thu Jun 17 17:23:59 2010 -0700
@@ -48,7 +48,7 @@
 static kssl_status_t kssl_build_single_record(ssl_t *ssl, mblk_t *mp);
 
 /*
- * The socket T_bind_req message is intercepted and re-routed here
+ * The socket bind request is intercepted and re-routed here
  * to see is there is SSL relevant job to do, based on the kssl config
  * in the kssl_entry_tab.
  * Looks up the kernel SSL proxy table, to find an entry that matches the
@@ -72,14 +72,14 @@
  */
 
 kssl_endpt_type_t
-kssl_check_proxy(mblk_t *bindmp, void *cookie, kssl_ent_t *ksslent)
+kssl_check_proxy(struct sockaddr *addr, socklen_t len, void *cookie,
+    kssl_ent_t *ksslent)
 {
 	int i;
 	kssl_endpt_type_t ret;
 	kssl_entry_t *ep;
 	sin_t *sin;
 	sin6_t *sin6;
-	struct T_bind_req *tbr;
 	in6_addr_t mapped_v4addr;
 	in6_addr_t *v6addr;
 	in_port_t in_port;
@@ -89,11 +89,9 @@
 	}
 
 	ret = KSSL_NO_PROXY;
+	sin = (struct sockaddr_in *)addr;
 
-	tbr = (struct T_bind_req *)bindmp->b_rptr;
-	sin = (sin_t *)(bindmp->b_rptr + tbr->ADDR_offset);
-
-	switch (tbr->ADDR_length) {
+	switch (len) {
 	case sizeof (sin_t):
 		in_port = ntohs(sin->sin_port);
 		IN6_IPADDR_TO_V4MAPPED(sin->sin_addr.s_addr, &mapped_v4addr);
@@ -138,13 +136,6 @@
 					break;
 				}
 
-				/*
-				 * Now transform the T_BIND_REQ into
-				 * a T_BIND_ACK.
-				 */
-				tbr->PRIM_type = T_BIND_ACK;
-				bindmp->b_datap->db_type = M_PCPROTO;
-
 				KSSL_ENTRY_REFHOLD(ep);
 				*ksslent = (kssl_ent_t)ep;
 
@@ -154,27 +145,10 @@
 
 			/* This is a proxy port. */
 			if (ep->ke_proxy_port == in_port) {
-				mblk_t *entmp;
-
-				/* Append this entry to the bind_req mblk */
-
-				entmp = allocb(sizeof (kssl_entry_t),
-				    BPRI_MED);
-				if (entmp == NULL)
-					break;
-				*((kssl_entry_t **)entmp->b_rptr) = ep;
-
-				entmp->b_wptr = entmp->b_rptr +
-				    sizeof (kssl_entry_t);
-
-				bindmp->b_cont = entmp;
-
 				/* Add the caller's cookie to proxies list */
 
 				if (!kssl_enqueue((kssl_chain_t **)
 				    &(ep->ke_proxy_head), cookie)) {
-					freeb(bindmp->b_cont);
-					bindmp->b_cont = NULL;
 					break;
 				}
 
@@ -184,8 +158,6 @@
 				 */
 				sin->sin_port = htons(ep->ke_ssl_port);
 
-				tbr->PRIM_type = T_SSL_PROXY_BIND_REQ;
-
 				KSSL_ENTRY_REFHOLD(ep);
 				*ksslent = (kssl_ent_t)ep;
 
@@ -310,23 +282,26 @@
 }
 
 /*
- * Holds the kssl context
- */
-void
-kssl_hold_ctx(kssl_ctx_t ksslctx)
-{
-	ssl_t *ssl = (ssl_t *)ksslctx;
-
-	KSSL_SSL_REFHOLD(ssl);
-}
-
-/*
  * Releases the kssl_context
  */
 void
 kssl_release_ctx(kssl_ctx_t ksslctx)
 {
-	KSSL_SSL_REFRELE((ssl_t *)ksslctx);
+	kssl_free_context((ssl_t *)ksslctx);
+}
+
+/*
+ * Done with asynchronous processing
+ */
+void
+kssl_async_done(kssl_ctx_t ksslctx)
+{
+	ssl_t *ssl = (ssl_t *)ksslctx;
+
+	mutex_enter(&ssl->kssl_lock);
+	if (--ssl->async_ops_pending == 0)
+		cv_signal(&ssl->async_cv);
+	mutex_exit(&ssl->kssl_lock);
 }
 
 /*
@@ -403,7 +378,6 @@
 
 			if ((mp->b_cont == NULL) && (mplen == rec_sz)) {
 
-				DB_FLAGS(mp) &= ~DBLK_COOKED;
 				*decrmp = mp;
 				mutex_exit(&ssl->kssl_lock);
 				return (KSSL_CMD_DELIVER_PROXY);
@@ -541,19 +515,8 @@
 }
 
 /*
- * Process mblk b_cont chain returned from stream head. The chain could
- * contain a mixture (albeit continuous) of processed and unprocessed
- * mblks. This situation could happen when more data was available in
- * stream head queue than requested. In such case the rest of processed
- * data would be putback().
- *
- * Processed mblks in this function contain either a full or partial portion
- * of a decrypted and verified SSL record. The former case is produced
- * by the function itself, the latter case is explained above.
- *
- * In case of unprocessed mblks, decrypt and verify the MAC of an incoming
- * chain of application_data record. Each block has exactly one SSL record.
- * This routine recycles incoming mblks, and flags them as DBLK_COOKED.
+ * Decrypt and verify the MAC of an incoming chain of application_data record.
+ * Each block has exactly one SSL record.
  */
 kssl_cmd_t
 kssl_handle_mblk(kssl_ctx_t ctx, mblk_t **mpp, mblk_t **outmp)
@@ -579,23 +542,10 @@
 
 	mp = firstmp = *mpp;
 	*outmp = NULL;
-
-	/*
-	 * Skip over already processed mblks. This prevents a case where
-	 * struiocopyout() copies unprocessed data to userland.
-	 */
-	while ((mp != NULL) && (DB_FLAGS(mp) & DBLK_COOKED)) {
-		ASSERT(DB_TYPE(mp) == M_DATA);
-		DTRACE_PROBE1(kssl_mblk__already_processed_mblk, mblk_t *, mp);
-		mp = mp->b_cont;
-	}
-
 more:
 
 	while (mp != NULL) {
-		/* only unprocessed mblks should reach us */
 		ASSERT(DB_TYPE(mp) == M_DATA);
-		ASSERT(!(DB_FLAGS(mp) & DBLK_COOKED));
 
 		if (DB_REF(mp) > 1) {
 			/*
@@ -771,7 +721,6 @@
 		}
 		mp->b_wptr = recend;
 
-		DB_FLAGS(mp) |= DBLK_COOKED;
 		DTRACE_PROBE1(kssl_mblk__dblk_cooked, mblk_t *, mp);
 		KSSL_COUNTER(appdata_record_ins, 1);
 
@@ -1186,26 +1135,26 @@
  * address. The ssl structure is returned held.
  */
 kssl_status_t
-kssl_init_context(kssl_ent_t kssl_ent, void *addr, boolean_t is_v4,
-    int mss, kssl_ctx_t *kssl_ctxp)
+kssl_init_context(kssl_ent_t kssl_ent, struct sockaddr *addr, int mss,
+    kssl_ctx_t *kssl_ctxp)
 {
 	ssl_t *ssl = kmem_cache_alloc(kssl_cache, KM_NOSLEEP);
+	struct sockaddr_in *sin = (struct sockaddr_in *)addr;
 
 	if (ssl == NULL) {
 		return (KSSL_STS_ERR);
 	}
 
-	kssl_cache_count++;
-
 	bzero(ssl, sizeof (ssl_t));
 
 	ssl->kssl_entry = (kssl_entry_t *)kssl_ent;
 	KSSL_ENTRY_REFHOLD(ssl->kssl_entry);
 
-	if (is_v4) {
-		IN6_IPADDR_TO_V4MAPPED(*((ipaddr_t *)addr), &ssl->faddr);
+	if (sin->sin_family == AF_INET) {
+		IN6_IPADDR_TO_V4MAPPED(sin->sin_addr.s_addr, &ssl->faddr);
 	} else {
-		ssl->faddr = *((in6_addr_t *)addr);	/* struct assignment */
+		/* struct assignment */
+		ssl->faddr = ((struct sockaddr_in6 *)addr)->sin6_addr;
 	}
 	ssl->tcp_mss = mss;
 	ssl->sendalert_level = alert_warning;
@@ -1213,10 +1162,16 @@
 	ssl->sid.cached = B_FALSE;
 
 	*kssl_ctxp = (kssl_ctx_t)ssl;
-	KSSL_SSL_REFHOLD(ssl);
 	return (KSSL_STS_OK);
 }
 
+void
+kssl_set_mss(kssl_ctx_t ctx, uint32_t mss)
+{
+	ssl_t *ssl = (ssl_t *)ctx;
+	ssl->tcp_mss = mss;
+}
+
 /*
  * Builds SSL records out of the chain of mblks, and returns it.
  * Takes a copy of the message before encrypting it if it has another
--- a/usr/src/uts/common/inet/kssl/ksslapi.h	Thu Jun 17 17:22:09 2010 -0700
+++ b/usr/src/uts/common/inet/kssl/ksslapi.h	Thu Jun 17 17:23:59 2010 -0700
@@ -19,8 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
 #ifndef	_INET_KSSL_KSSLAPI_H
@@ -74,17 +73,19 @@
 #define	SSL3_MAX_RECORD_LEN	16384 - 1 - SSL3_HDR_LEN - SSL3_MAX_TAIL_LEN
 
 
-kssl_endpt_type_t kssl_check_proxy(mblk_t *, void *, kssl_ent_t *);
+kssl_endpt_type_t kssl_check_proxy(struct sockaddr *, socklen_t, void *,
+    kssl_ent_t *);
 
-kssl_status_t kssl_init_context(kssl_ent_t, void *, boolean_t,
-    int, kssl_ctx_t *);
+kssl_status_t kssl_init_context(kssl_ent_t, struct sockaddr *, int,
+    kssl_ctx_t *);
+void kssl_set_mss(kssl_ctx_t, uint32_t);
 
 void kssl_hold_ent(kssl_ent_t);
 void kssl_release_ent(kssl_ent_t, void *, kssl_endpt_type_t);
 void *kssl_find_fallback(kssl_ent_t);
 
-void kssl_hold_ctx(kssl_ctx_t);
 void kssl_release_ctx(kssl_ctx_t);
+void kssl_async_done(kssl_ctx_t);
 
 typedef void (*kssl_callback_t)(void *arg, mblk_t *mp, kssl_cmd_t cmd);
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/uts/common/inet/kssl/ksslfilter.c	Thu Jun 17 17:23:59 2010 -0700
@@ -0,0 +1,578 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ */
+
+#include <sys/systm.h>
+#include <sys/cmn_err.h>
+#include <sys/stropts.h>
+#include <sys/strsun.h>
+#include <sys/socketvar.h>
+#include <sys/sockfilter.h>
+#include <inet/kssl/ksslapi.h>
+#include <sys/note.h>
+#include <sys/taskq.h>
+
+/*
+ * Name of the KSSL filter
+ */
+#define	KSSL_FILNAME	"ksslf"
+
+static struct modlmisc ksslf_modlmisc = {
+	&mod_miscops,
+	"Kernel SSL socket filter"
+};
+
+static struct modlinkage ksslf_modlinkage = {
+	MODREV_1,
+	&ksslf_modlmisc,
+	NULL
+};
+
+/*
+ * kssl filter cookie
+ */
+typedef struct ksslf {
+	boolean_t	ksslf_pending;		/* waiting for 1st SSL rec. */
+	boolean_t	ksslf_inhandshake;	/* during SSL handshake */
+	kssl_ent_t	ksslf_ent;		/* SSL table entry */
+	kssl_ctx_t	ksslf_ctx;		/* SSL session */
+	kssl_endpt_type_t ksslf_type;		/* is proxy/is proxied/none */
+	struct sockaddr_in6 ksslf_laddr;	/* local address */
+	socklen_t	ksslf_laddrlen;
+	struct ksslf	*ksslf_listener;
+} ksslf_t;
+
+static void kssl_input_callback(void *, mblk_t *, kssl_cmd_t);
+
+/*
+ * Allocate kssl state
+ */
+sof_rval_t
+kssl_attach_passive_cb(sof_handle_t handle, sof_handle_t ph,
+    void *parg, struct sockaddr *laddr, socklen_t laddrlen,
+    struct sockaddr *faddr, socklen_t faddrlen, void **cookiep)
+{
+	ksslf_t *listener = (ksslf_t *)parg;
+	ksslf_t *new;
+
+	_NOTE(ARGUNUSED(handle, ph, faddrlen, laddr, laddrlen));
+
+	if (listener == NULL || listener->ksslf_ent == NULL)
+		return (SOF_RVAL_DETACH);
+	/*
+	 * Only way for a fallback listener to receive connections is when
+	 * a handshake fails and socket is moved from the proxy to the fallback.
+	 * Connections that come in directly on the fallback are denied.
+	 */
+	if (listener->ksslf_type == KSSL_HAS_PROXY)
+		return (SOF_RVAL_EACCES);
+
+	/* Allocate the SSL context for the new connection */
+	new = kmem_zalloc(sizeof (ksslf_t), KM_NOSLEEP);
+	if (new == NULL)
+		return (SOF_RVAL_ENOMEM);
+
+	/*
+	 * The mss is initialized to SSL3_MAX_RECORD_LEN, but might be
+	 * updated by the mblk_prop callback.
+	 */
+	if (kssl_init_context(listener->ksslf_ent, faddr, SSL3_MAX_RECORD_LEN,
+	    &new->ksslf_ctx) != KSSL_STS_OK)
+		return (SOF_RVAL_ENOMEM);
+
+	new->ksslf_pending = B_TRUE;
+	new->ksslf_inhandshake = B_TRUE;
+	ASSERT(laddrlen <= sizeof (new->ksslf_laddr));
+	new->ksslf_laddrlen = laddrlen;
+	bcopy(laddr, &new->ksslf_laddr, laddrlen);
+	new->ksslf_laddr.sin6_port = listener->ksslf_laddr.sin6_port;
+	new->ksslf_listener = listener;
+
+	*cookiep = new;
+	/*
+	 * We are in handshake, defer the notification of this connection
+	 * until it is completed.
+	 */
+	return (SOF_RVAL_DEFER);
+}
+
+void
+kssl_detach_cb(sof_handle_t handle, void *cookie, cred_t *cr)
+{
+	ksslf_t *kssl = (ksslf_t *)cookie;
+
+	_NOTE(ARGUNUSED(handle, cr));
+
+	if (kssl == NULL)
+		return;
+
+	if (kssl->ksslf_ent != NULL) {
+		kssl_release_ent(kssl->ksslf_ent, handle, kssl->ksslf_type);
+		kssl->ksslf_ent = NULL;
+	}
+	if (kssl->ksslf_ctx != NULL) {
+		kssl_release_ctx(kssl->ksslf_ctx);
+		kssl->ksslf_ctx = NULL;
+	}
+
+	kmem_free(kssl, sizeof (ksslf_t));
+}
+
+sof_rval_t
+kssl_bind_cb(sof_handle_t handle, void *cookie, struct sockaddr *name,
+    socklen_t *namelen, cred_t *cr)
+{
+	kssl_ent_t ent;
+	kssl_endpt_type_t type;
+	ksslf_t *kssl;
+	in_port_t origport;
+
+	_NOTE(ARGUNUSED(cr));
+
+	if (cookie != NULL)
+		return (SOF_RVAL_EINVAL);
+
+	if (*namelen < sizeof (struct sockaddr_in)) {
+		sof_bypass(handle);
+		return (SOF_RVAL_CONTINUE);
+	}
+
+	origport = ((struct sockaddr_in *)name)->sin_port;
+	/* Check if KSSL has been configured for this address */
+	type = kssl_check_proxy(name, *namelen, handle, &ent);
+
+	switch (type) {
+	case KSSL_NO_PROXY:
+		sof_bypass(handle);
+		break;
+	case KSSL_HAS_PROXY:
+	case KSSL_IS_PROXY:
+		kssl = kmem_zalloc(sizeof (ksslf_t), KM_SLEEP);
+		kssl->ksslf_type = type;
+		kssl->ksslf_ent = ent;
+
+		/*
+		 * In the unlikely event that there are multiple simultaneous
+		 * bind requests, and the cookie was already swapped out, then
+		 * just drop this cookie and let the bind continue unmodified.
+		 */
+		if (sof_cas_cookie(handle, cookie, kssl) != cookie) {
+			kssl_release_ent(ent, handle, type);
+			kmem_free(kssl, sizeof (ksslf_t));
+			((struct sockaddr_in *)name)->sin_port = origport;
+			break;
+		}
+
+		kssl->ksslf_laddrlen = *namelen;
+		bcopy(name, &kssl->ksslf_laddr, kssl->ksslf_laddrlen);
+		kssl->ksslf_laddr.sin6_port = origport;
+		/*
+		 * kssl_check_proxy updated the sockaddr, so just
+		 * pass it along to the protocol.
+		 */
+		return ((type == KSSL_HAS_PROXY) ? SOF_RVAL_RETURN :
+		    SOF_RVAL_CONTINUE);
+	}
+	return (SOF_RVAL_CONTINUE);
+}
+
+sof_rval_t
+kssl_listen_cb(sof_handle_t handle, void *cookie, int *backlog, cred_t *cr)
+{
+	ksslf_t *kssl = (ksslf_t *)cookie;
+
+	_NOTE(ARGUNUSED(backlog, cr));
+
+	/*
+	 * The cookie can be NULL in the unlikely event of an application doing
+	 * listen() without binding to an address. Those listeners are of no
+	 * interest.
+	 */
+	if (kssl == NULL) {
+		sof_bypass(handle);
+		return (SOF_RVAL_CONTINUE);
+	}
+
+	return (SOF_RVAL_CONTINUE);
+
+}
+
+/*
+ * Outgoing connections are not of interest, so just bypass the filter.
+ */
+sof_rval_t
+kssl_connect_cb(sof_handle_t handle, void *cookie, struct sockaddr *name,
+    socklen_t *namelen, cred_t *cr)
+{
+	_NOTE(ARGUNUSED(cookie, name, namelen, cr));
+
+	sof_bypass(handle);
+	return (SOF_RVAL_CONTINUE);
+}
+
+static void
+kssl_mblk_prop_cb(sof_handle_t handle, void *cookie, ssize_t *maxblk,
+    ushort_t *wroff, ushort_t *tail)
+{
+	ksslf_t *kssl = (ksslf_t *)cookie;
+
+	_NOTE(ARGUNUSED(handle));
+
+	/* only care about passively opened sockets */
+	if (kssl == NULL || !kssl->ksslf_pending)
+		return;
+	/*
+	 * If this is endpoint is handling SSL, then reserve extra
+	 * offset and space at the end. Also have sockfs allocate
+	 * SSL3_MAX_RECORD_LEN packets, overriding the previous setting.
+	 * The extra cost of signing and encrypting multiple MSS-size
+	 * records (12 of them with Ethernet), instead of a single
+	 * contiguous one by the stream head largely outweighs the
+	 * statistical reduction of ACKs, when applicable. The peer
+	 * will also save on decryption and verification costs.
+	 */
+	if (*maxblk == INFPSZ || *maxblk > SSL3_MAX_RECORD_LEN)
+		*maxblk = SSL3_MAX_RECORD_LEN;
+	else
+		kssl_set_mss(kssl->ksslf_ctx, *maxblk);
+	*wroff += SSL3_WROFFSET;
+	*tail += SSL3_MAX_TAIL_LEN;
+}
+
+sof_rval_t
+kssl_getsockname_cb(sof_handle_t handle, void *cookie, struct sockaddr *addr,
+    socklen_t *addrlen, cred_t *cr)
+{
+	ksslf_t *kssl = (ksslf_t *)cookie;
+
+	_NOTE(ARGUNUSED(handle, cr));
+
+	if (kssl == NULL)
+		return (SOF_RVAL_CONTINUE);
+
+	if (*addrlen < kssl->ksslf_laddrlen)
+		return (SOF_RVAL_EINVAL);
+
+	*addrlen = kssl->ksslf_laddrlen;
+	bcopy(&kssl->ksslf_laddr, addr, kssl->ksslf_laddrlen);
+
+	return (SOF_RVAL_RETURN);
+}
+
+/*
+ * Called for every packet sent to the protocol.
+ * If the message is successfully processed, then it is returned.
+ */
+mblk_t *
+kssl_data_out_cb(sof_handle_t handle, void *cookie, mblk_t *mp,
+    struct nmsghdr *msg, cred_t *cr, sof_rval_t *rv)
+{
+	ksslf_t *kssl = (ksslf_t *)cookie;
+	kssl_ctx_t kssl_ctx = kssl->ksslf_ctx;
+	mblk_t *recmp;
+
+	_NOTE(ARGUNUSED(handle, msg, cr));
+
+	*rv = SOF_RVAL_CONTINUE;
+	if (kssl_ctx == NULL)
+		return (mp);
+
+	if ((recmp = kssl_build_record(kssl_ctx, mp)) == NULL) {
+		freemsg(mp);
+		*rv = SOF_RVAL_EINVAL;
+		return (NULL);
+	}
+	return (recmp);
+}
+
+/*
+ * Called for each incoming segment.
+ *
+ * A packet may carry multiple SSL records, so the function calls
+ * kssl_input() in a loop, until all records are handled.
+ */
+mblk_t *
+kssl_data_in_cb(sof_handle_t handle, void *cookie, mblk_t *mp, int flags,
+    size_t *lenp)
+{
+	ksslf_t		*kssl = cookie;
+	kssl_cmd_t	kssl_cmd;
+	mblk_t		*outmp, *retmp = NULL, **tail = &retmp;
+	boolean_t	more = B_FALSE;
+	boolean_t	flowctrld;
+
+	_NOTE(ARGUNUSED(flags));
+
+	if (kssl == NULL || kssl->ksslf_ctx == NULL) {
+		sof_bypass(handle);
+		return (mp);
+	}
+
+	*lenp = 0;
+	do {
+		kssl_cmd = kssl_input(kssl->ksslf_ctx, mp, &outmp,
+		    &more, kssl_input_callback, (void *)handle);
+
+		switch (kssl_cmd) {
+		case KSSL_CMD_SEND: {
+			struct nmsghdr msg;
+
+			DTRACE_PROBE(kssl_cmd_send);
+			bzero(&msg, sizeof (msg));
+			(void) sof_inject_data_out(handle, outmp, &msg,
+			    &flowctrld);
+		}
+		/* FALLTHROUGH */
+		case KSSL_CMD_NONE:
+			DTRACE_PROBE(kssl_cmd_none);
+			if (kssl->ksslf_pending) {
+				kssl->ksslf_pending = B_FALSE;
+				sof_newconn_ready(handle);
+			}
+			break;
+
+		case KSSL_CMD_QUEUED:
+			DTRACE_PROBE(kssl_cmd_queued);
+			break;
+
+		case KSSL_CMD_DELIVER_PROXY:
+		case KSSL_CMD_DELIVER_SSL:
+			DTRACE_PROBE(kssl_cmd_proxy__ssl);
+			/*
+			 * We're at a phase where records are sent upstreams,
+			 * past the handshake
+			 */
+			kssl->ksslf_inhandshake = B_FALSE;
+
+			*tail = outmp;
+			*lenp += MBLKL(outmp);
+			while (outmp->b_cont != NULL) {
+				outmp = outmp->b_cont;
+				*lenp += MBLKL(outmp);
+			}
+			tail = &outmp->b_cont;
+			break;
+
+		case KSSL_CMD_NOT_SUPPORTED: {
+			ksslf_t *listener = kssl->ksslf_listener;
+			sof_handle_t fallback;
+
+			DTRACE_PROBE(kssl_cmd_not_supported);
+			/*
+			 * Stop the SSL processing by the proxy, and
+			 * switch to the userland SSL
+			 */
+			if (kssl->ksslf_pending) {
+				kssl->ksslf_pending = B_FALSE;
+
+				DTRACE_PROBE1(kssl_no_can_do, sof_handle_t,
+				    handle);
+
+				sof_bypass(handle);
+
+				ASSERT(listener->ksslf_ent != NULL);
+				fallback =
+				    kssl_find_fallback(listener->ksslf_ent);
+				/*
+				 * No fallback: the remote will timeout and
+				 * disconnect.
+				 */
+				if (fallback != NULL &&
+				    sof_newconn_move(handle, fallback))
+					sof_newconn_ready(handle);
+			}
+			if (mp != NULL) {
+				*tail = mp;
+				*lenp += MBLKL(mp);
+				while (mp->b_cont != NULL) {
+					mp = mp->b_cont;
+					*lenp += MBLKL(mp);
+				}
+				tail = &mp->b_cont;
+			}
+			break;
+		}
+		}
+		mp = NULL;
+	} while (more);
+
+	return (retmp);
+}
+
+/*
+ * Process queued data before it's copied by the user.
+ *
+ * If the message is successfully processed, then it is returned.
+ * A failed message will be freed.
+ */
+mblk_t *
+kssl_data_in_proc_cb(sof_handle_t handle, void *cookie, mblk_t *mp,
+    cred_t *cr, size_t *lenp)
+{
+	ksslf_t *kssl = (ksslf_t *)cookie;
+	kssl_ctx_t kssl_ctx = kssl->ksslf_ctx;
+	kssl_cmd_t kssl_cmd;
+	mblk_t *out;
+
+	_NOTE(ARGUNUSED(cr));
+
+	*lenp = 0;
+
+	kssl_cmd = kssl_handle_mblk(kssl_ctx, &mp, &out);
+
+	switch (kssl_cmd) {
+	case KSSL_CMD_NONE:
+		return (NULL);
+	case KSSL_CMD_DELIVER_PROXY:
+		*lenp = msgdsize(mp);
+		return (mp);
+	case KSSL_CMD_SEND: {
+		struct nmsghdr msg;
+		boolean_t flowctrld;
+
+		ASSERT(out != NULL);
+		bzero(&msg, sizeof (msg));
+
+		(void) sof_inject_data_out(handle, out, &msg,
+		    &flowctrld);
+		return (NULL);
+	}
+	default:
+		/* transient error. */
+		return (NULL);
+	}
+}
+
+/*
+ * Continue processing the incoming flow after an asynchronous callback.
+ */
+static void
+kssl_input_asynch(void *arg)
+{
+	sof_handle_t handle = (sof_handle_t)arg;
+	ksslf_t *kssl = (ksslf_t *)sof_get_cookie(handle);
+	size_t len = 0;
+	boolean_t flowctrld;
+	mblk_t *mp;
+
+	if ((mp = kssl_data_in_cb(handle, kssl, NULL, 0, &len)) != NULL) {
+		ASSERT(len != 0);
+		(void) sof_inject_data_in(handle, mp, len, 0, &flowctrld);
+	}
+	kssl_async_done(kssl->ksslf_ctx);
+}
+
+/*
+ * Callback function for the cases kssl_input() had to submit an asynchronous
+ * job and need to come back when done to carry on the input processing.
+ * This routine follows the conentions of timeout and interrupt handlers.
+ * (no blocking, ...)
+ */
+static void
+kssl_input_callback(void *arg, mblk_t *mp, kssl_cmd_t kssl_cmd)
+{
+	sof_handle_t handle = (sof_handle_t)arg;
+	ksslf_t *kssl = (ksslf_t *)sof_get_cookie(handle);
+	boolean_t flowctrld;
+
+	ASSERT(kssl != NULL);
+
+	switch (kssl_cmd) {
+	case KSSL_CMD_SEND: {
+		struct nmsghdr msg;
+
+		if (mp == NULL)
+			break;
+		bzero(&msg, sizeof (msg));
+
+		(void) sof_inject_data_out(handle, mp, &msg, &flowctrld);
+	}
+	/* FALLTHROUGH */
+	case KSSL_CMD_NONE:
+		break;
+
+	case KSSL_CMD_DELIVER_PROXY:
+	case KSSL_CMD_DELIVER_SSL:
+		(void) sof_inject_data_in(handle, mp, msgdsize(mp), 0,
+		    &flowctrld);
+		break;
+
+	case KSSL_CMD_NOT_SUPPORTED:
+		/* Stop the SSL processing */
+		sof_bypass(handle);
+	}
+	/*
+	 * Process any input that may have accumulated while we're waiting for
+	 * the call-back. This must be done by a taskq because kssl_input might
+	 * block when handling client_finish messages.
+	 */
+	if (taskq_dispatch(system_taskq, kssl_input_asynch, handle,
+	    TQ_NOSLEEP) == NULL) {
+		DTRACE_PROBE(kssl_err__taskq_dispatch_failed);
+		kssl_async_done(kssl->ksslf_ctx);
+	}
+}
+
+sof_ops_t ksslf_ops = {
+	.sofop_attach_passive = kssl_attach_passive_cb,
+	.sofop_detach = kssl_detach_cb,
+	.sofop_bind = kssl_bind_cb,
+	.sofop_connect = kssl_connect_cb,
+	.sofop_listen = kssl_listen_cb,
+	.sofop_data_in = kssl_data_in_cb,
+	.sofop_data_in_proc = kssl_data_in_proc_cb,
+	.sofop_data_out = kssl_data_out_cb,
+	.sofop_mblk_prop = kssl_mblk_prop_cb,
+	.sofop_getsockname = kssl_getsockname_cb,
+};
+
+int
+_init(void)
+{
+	int error;
+
+	if ((error = sof_register(SOF_VERSION, KSSL_FILNAME,
+	    &ksslf_ops, 0)) != 0)
+		return (error);
+	if ((error = mod_install(&ksslf_modlinkage)) != 0)
+		(void) sof_unregister(KSSL_FILNAME);
+
+	return (error);
+}
+
+int
+_fini(void)
+{
+	int error;
+
+	if ((error = sof_unregister(KSSL_FILNAME)) != 0)
+		return (error);
+
+	return (mod_remove(&ksslf_modlinkage));
+}
+
+int
+_info(struct modinfo *modinfop)
+{
+	return (mod_info(&ksslf_modlinkage, modinfop));
+}
--- a/usr/src/uts/common/inet/kssl/ksslimpl.h	Thu Jun 17 17:22:09 2010 -0700
+++ b/usr/src/uts/common/inet/kssl/ksslimpl.h	Thu Jun 17 17:23:59 2010 -0700
@@ -19,8 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
 #ifndef	_INET_KSSL_KSSLIMPL_H
@@ -136,21 +135,6 @@
 	}								\
 }
 
-#define	KSSL_SSL_REFHOLD(ssl) {						\
-	atomic_add_32(&(ssl)->kssl_refcnt, 1);				\
-	ASSERT((ssl)->kssl_refcnt != 0);				\
-	ASSERT((ssl)->kssl_refcnt < 100000);				\
-}
-
-#define	KSSL_SSL_REFRELE(ssl) {						\
-	ASSERT((ssl)->kssl_refcnt != 0);				\
-	ASSERT((ssl)->kssl_refcnt < 100000);				\
-	membar_exit();							\
-	if (atomic_add_32_nv(&(ssl)->kssl_refcnt, -1) == 0) {		\
-		kssl_free_context((ssl));				\
-	}								\
-}
-
 #define	CRYPTO_ERR(r) ((r) != CRYPTO_SUCCESS && (r) != CRYPTO_QUEUED)
 
 /*
@@ -181,7 +165,6 @@
 extern crypto_call_flag_t kssl_call_flag;
 extern KSSLCipherDef cipher_defs[];
 
-extern int kssl_cache_count;
 extern struct kmem_cache *kssl_cache;
 
 #define	KSSL_TAB_INITSIZE	4
--- a/usr/src/uts/common/inet/kssl/ksslproto.h	Thu Jun 17 17:22:09 2010 -0700
+++ b/usr/src/uts/common/inet/kssl/ksslproto.h	Thu Jun 17 17:23:59 2010 -0700
@@ -275,14 +275,13 @@
 } KSSLCipherSpec;
 
 /*
- * SSL connection state. This one hangs off of a tcp_t structure.
+ * SSL connection state. This one hangs off of a ksslf_t structure.
  */
 typedef struct ssl_s {
 	kmutex_t		kssl_lock;
 	struct kssl_entry_s	*kssl_entry;
 	mblk_t			*rec_ass_head;
 	mblk_t			*rec_ass_tail;
-	uint_t			kssl_refcnt;
 	in6_addr_t		faddr;
 	uint32_t		tcp_mss;
 	SSL3WaitState		hs_waitstate;
@@ -320,6 +319,8 @@
 	uchar_t			major_version;
 	uchar_t			minor_version;
 	boolean_t		secure_renegotiation;
+	uint_t			async_ops_pending;
+	kcondvar_t		async_cv;
 } ssl_t;
 
 #define	IS_TLS(s) (s->major_version == 3 && s->minor_version == 1)
--- a/usr/src/uts/common/inet/kssl/ksslrec.c	Thu Jun 17 17:22:09 2010 -0700
+++ b/usr/src/uts/common/inet/kssl/ksslrec.c	Thu Jun 17 17:23:59 2010 -0700
@@ -110,7 +110,6 @@
     0x5c, 0x5c, 0x5c, 0x5c
 };
 
-int kssl_cache_count;
 static boolean_t kssl_synchronous = B_FALSE;
 
 static void kssl_update_handshake_hashes(ssl_t *, uchar_t *, uint_t);
@@ -232,14 +231,12 @@
 
 		/*
 		 * The calling context can tolerate a blocking call here.
-		 * For outgoing traffic, we are in user context
-		 * when called from strsock_kssl_output(). For incoming
-		 * traffic past the SSL handshake, we are in user
-		 * context when called from strsock_kssl_input(). During the
-		 * SSL handshake, we are called for client_finished message
-		 * handling from a squeue worker thread that gets scheduled
-		 * by an SQ_FILL call. This thread is not in interrupt
-		 * context and so can block.
+		 * For outgoing traffic, we are in user context when called
+		 * from kssl_data_out_cb(). For incoming traffic past the
+		 * SSL handshake, we are in user context when called from
+		 * kssl_data_in_proc_cb(). During the SSL handshake, we are
+		 * called for client_finished message handling from a taskq
+		 * thread.
 		 */
 		rv = crypto_mac(&spec->hmac_mech, &dd, &spec->hmac_key,
 		    NULL, &mac, NULL);
@@ -1077,7 +1074,7 @@
 {
 	int rv = 0;
 	uchar_t A1[MAX_HASH_LEN], result[MAX_HASH_LEN];
-	int bytes_left = datalen;
+	int bytes_left = (int)datalen;
 	crypto_data_t dd, mac;
 	crypto_context_t ctx;
 
@@ -1625,7 +1622,7 @@
 	uchar_t *rstart;
 	uchar_t *versionp;
 	SSL3Hashes ssl3hashes;
-	size_t finish_len;
+	uchar_t finish_len;
 	int ret;
 	uint16_t adj_len = 0;
 
@@ -1912,9 +1909,6 @@
 		creq.cr_callback_func = kssl_cke_done;
 		creq.cr_callback_arg = ssl;
 
-		/* The callback routine will release this one */
-		KSSL_SSL_REFHOLD(ssl);
-
 		creqp = &creq;
 	}
 
@@ -2295,22 +2289,15 @@
 
 	ssl->activeinput = B_FALSE;
 
-	/* If we're the only ones left, then we won't callback */
-	if (ssl->kssl_refcnt == 1) {
-		mutex_exit(&ssl->kssl_lock);
-		KSSL_SSL_REFRELE(ssl);
-		return;
-	}
-
 	cbfn = ssl->cke_callback_func;
 	cbarg = ssl->cke_callback_arg;
 	alertmp = ssl->alert_sendbuf;
 	ssl->alert_sendbuf = NULL;
 
+	/* dropped by callback when it has completed */
+	ssl->async_ops_pending++;
 	mutex_exit(&ssl->kssl_lock);
 
-	KSSL_SSL_REFRELE(ssl);
-
 	/* Now call the callback routine */
 	(*(cbfn))(cbarg, alertmp, kssl_cmd);
 }
@@ -2485,20 +2472,42 @@
 void
 kssl_free_context(ssl_t *ssl)
 {
+	crypto_req_id_t reqid;
+
 	ASSERT(ssl != NULL);
 	if (!(MUTEX_HELD(&ssl->kssl_lock))) {
 		/* we're coming from an external API entry point */
 		mutex_enter(&ssl->kssl_lock);
 	}
 
-	if (ssl->job.kjob != NULL) {
-		crypto_cancel_req(ssl->job.kjob);
-		kmem_free(ssl->job.buf, ssl->job.buflen);
+	/*
+	 * Cancel any active crypto request and wait for pending async
+	 * operations to complete. We loop here because the async thread
+	 * might submit a new cryto request.
+	 */
+	do {
+		if (ssl->job.kjob != NULL) {
+			/*
+			 * Drop the lock before canceling the request;
+			 * otherwise we might deadlock if the completion
+			 * callback is running.
+			 */
+			reqid = ssl->job.kjob;
+			mutex_exit(&ssl->kssl_lock);
+			crypto_cancel_req(reqid);
+			mutex_enter(&ssl->kssl_lock);
 
-		ssl->job.kjob = 0;
-		ssl->job.buf = NULL;
-		ssl->job.buflen = 0;
-	}
+			/* completion callback might have done the cleanup */
+			if (ssl->job.kjob != NULL) {
+				kmem_free(ssl->job.buf, ssl->job.buflen);
+				ssl->job.kjob = 0;
+				ssl->job.buf = NULL;
+				ssl->job.buflen = 0;
+			}
+		}
+		while (ssl->async_ops_pending > 0)
+			cv_wait(&ssl->async_cv, &ssl->kssl_lock);
+	} while (ssl->job.kjob != NULL);
 
 	kssl_mblksfree(ssl);
 	kssl_specsfree(ssl);
@@ -2509,5 +2518,4 @@
 	mutex_exit(&ssl->kssl_lock);
 
 	kmem_cache_free(kssl_cache, ssl);
-	kssl_cache_count--;
 }
--- a/usr/src/uts/common/inet/sockmods/sockmod_sdp.c	Thu Jun 17 17:22:09 2010 -0700
+++ b/usr/src/uts/common/inet/sockmods/sockmod_sdp.c	Thu Jun 17 17:23:59 2010 -0700
@@ -20,8 +20,7 @@
  */
 
 /*
- * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
 #include <sys/sysmacros.h>
@@ -30,10 +29,7 @@
 #include <sys/socketvar.h>
 #include <sys/modctl.h>
 #include <sys/cmn_err.h>
-#include <sys/tihdr.h>
 #include <sys/vfs.h>
-#include <fs/sockfs/nl7c.h>
-#include <inet/kssl/ksslapi.h>
 #include <inet/sdp_itf.h>
 #include <fs/sockfs/sockcommon.h>
 #include "socksdp.h"
--- a/usr/src/uts/common/inet/tcp.h	Thu Jun 17 17:22:09 2010 -0700
+++ b/usr/src/uts/common/inet/tcp.h	Thu Jun 17 17:23:59 2010 -0700
@@ -43,7 +43,6 @@
 #include <inet/mib2.h>
 #include <inet/tcp_stack.h>
 #include <inet/tcp_sack.h>
-#include <inet/kssl/ksslapi.h>
 
 /* TCP states */
 #define	TCPS_CLOSED		-6
@@ -423,13 +422,6 @@
 
 	/* protected by the tcp_non_sq_lock lock */
 	uint32_t	tcp_squeue_bytes;
-	/*
-	 * Kernel SSL session information
-	 */
-	boolean_t		tcp_kssl_pending; /* waiting for 1st SSL rec. */
-	boolean_t		tcp_kssl_inhandshake; /* during SSL handshake */
-	kssl_ent_t		tcp_kssl_ent;	/* SSL table entry */
-	kssl_ctx_t		tcp_kssl_ctx;	/* SSL session */
 
 	/*
 	 * tcp_closemp_used is protected by listener's tcp_eager_lock
--- a/usr/src/uts/common/inet/tcp/tcp.c	Thu Jun 17 17:22:09 2010 -0700
+++ b/usr/src/uts/common/inet/tcp/tcp.c	Thu Jun 17 17:23:59 2010 -0700
@@ -95,7 +95,6 @@
 #include <inet/ip_netinfo.h>
 #include <sys/squeue_impl.h>
 #include <sys/squeue.h>
-#include <inet/kssl/ksslapi.h>
 #include <sys/tsol/label.h>
 #include <sys/tsol/tnet.h>
 #include <rpc/pmap_prot.h>
@@ -527,18 +526,6 @@
 
 	tcp_free(tcp);
 
-	/* Release any SSL context */
-	if (tcp->tcp_kssl_ent != NULL) {
-		kssl_release_ent(tcp->tcp_kssl_ent, NULL, KSSL_NO_PROXY);
-		tcp->tcp_kssl_ent = NULL;
-	}
-
-	if (tcp->tcp_kssl_ctx != NULL) {
-		kssl_release_ctx(tcp->tcp_kssl_ctx);
-		tcp->tcp_kssl_ctx = NULL;
-	}
-	tcp->tcp_kssl_pending = B_FALSE;
-
 	/*
 	 * Since we will bzero the entire structure, we need to
 	 * remove it and reinsert it in global hash list. We
@@ -1355,17 +1342,6 @@
 	ASSERT(tcp->tcp_time_wait_prev == NULL);
 	ASSERT(tcp->tcp_time_wait_expire == 0);
 
-	/* Release any SSL context */
-	if (tcp->tcp_kssl_ent != NULL) {
-		kssl_release_ent(tcp->tcp_kssl_ent, NULL, KSSL_NO_PROXY);
-		tcp->tcp_kssl_ent = NULL;
-	}
-	if (tcp->tcp_kssl_ctx != NULL) {
-		kssl_release_ctx(tcp->tcp_kssl_ctx);
-		tcp->tcp_kssl_ctx = NULL;
-	}
-	tcp->tcp_kssl_pending = B_FALSE;
-
 	tcp_ipsec_cleanup(tcp);
 }
 
@@ -1996,20 +1972,6 @@
 	ASSERT(tcp->tcp_time_wait_prev == NULL);
 	ASSERT(tcp->tcp_time_wait_expire == 0);
 
-	if (tcp->tcp_kssl_pending) {
-		tcp->tcp_kssl_pending = B_FALSE;
-
-		/* Don't reset if the initialized by bind. */
-		if (tcp->tcp_kssl_ent != NULL) {
-			kssl_release_ent(tcp->tcp_kssl_ent, NULL,
-			    KSSL_NO_PROXY);
-		}
-	}
-	if (tcp->tcp_kssl_ctx != NULL) {
-		kssl_release_ctx(tcp->tcp_kssl_ctx);
-		tcp->tcp_kssl_ctx = NULL;
-	}
-
 	/*
 	 * Reset/preserve other values
 	 */
@@ -2335,10 +2297,6 @@
 
 	PRESERVE(tcp->tcp_squeue_bytes);
 
-	ASSERT(tcp->tcp_kssl_ctx == NULL);
-	ASSERT(!tcp->tcp_kssl_pending);
-	PRESERVE(tcp->tcp_kssl_ent);
-
 	tcp->tcp_closemp_used = B_FALSE;
 
 	PRESERVE(tcp->tcp_rsrv_mp);
@@ -2583,10 +2541,7 @@
 		 * chunks.  We round up the buffer size to the nearest SMSS.
 		 */
 		maxpsz = MSS_ROUNDUP(connp->conn_sndbuf, mss);
-		if (tcp->tcp_kssl_ctx == NULL)
-			mss = INFPSZ;
-		else
-			mss = SSL3_MAX_RECORD_LEN;
+		mss = INFPSZ;
 	} else {
 		/*
 		 * Set sd_qn_maxpsz to approx half the (receivers) buffer
@@ -3183,28 +3138,6 @@
 		    (tcp->tcp_loopback ? 0 : tcp->tcp_tcps->tcps_wroff_xtra);
 	}
 
-	/*
-	 * If this is endpoint is handling SSL, then reserve extra
-	 * offset and space at the end.
-	 * Also have the stream head allocate SSL3_MAX_RECORD_LEN packets,
-	 * overriding the previous setting. The extra cost of signing and
-	 * encrypting multiple MSS-size records (12 of them with Ethernet),
-	 * instead of a single contiguous one by the stream head
-	 * largely outweighs the statistical reduction of ACKs, when
-	 * applicable. The peer will also save on decryption and verification
-	 * costs.
-	 */
-	if (tcp->tcp_kssl_ctx != NULL) {
-		sopp.sopp_wroff += SSL3_WROFFSET;
-
-		sopp.sopp_flags |= SOCKOPT_TAIL;
-		sopp.sopp_tail = SSL3_MAX_TAIL_LEN;
-
-		sopp.sopp_flags |= SOCKOPT_ZCOPY;
-		sopp.sopp_zcopyflag = ZCVMUNSAFE;
-
-		sopp.sopp_maxblk = SSL3_MAX_RECORD_LEN;
-	}
 	if (tcp->tcp_loopback) {
 		sopp->sopp_flags |= SOCKOPT_LOOPBACK;
 		sopp->sopp_loopback = B_TRUE;
--- a/usr/src/uts/common/inet/tcp/tcp_fusion.c	Thu Jun 17 17:22:09 2010 -0700
+++ b/usr/src/uts/common/inet/tcp/tcp_fusion.c	Thu Jun 17 17:23:59 2010 -0700
@@ -153,21 +153,18 @@
 	/*
 	 * Fuse the endpoints; we perform further checks against both
 	 * tcp endpoints to ensure that a fusion is allowed to happen.
-	 * In particular we bail out if kernel SSL exists.
 	 */
 	ns = tcps->tcps_netstack;
 	ipst = ns->netstack_ip;
 
 	if (!tcp->tcp_unfusable && !peer_tcp->tcp_unfusable &&
-	    (tcp->tcp_kssl_ent == NULL) && (tcp->tcp_xmit_head == NULL) &&
-	    (peer_tcp->tcp_xmit_head == NULL)) {
+	    tcp->tcp_xmit_head == NULL && peer_tcp->tcp_xmit_head == NULL) {
 		mblk_t *mp;
 		queue_t *peer_rq = peer_connp->conn_rq;
 
 		ASSERT(!TCP_IS_DETACHED(peer_tcp));
 		ASSERT(tcp->tcp_fused_sigurg_mp == NULL);
 		ASSERT(peer_tcp->tcp_fused_sigurg_mp == NULL);
-		ASSERT(tcp->tcp_kssl_ctx == NULL);
 
 		/*
 		 * We need to drain data on both endpoints during unfuse.
--- a/usr/src/uts/common/inet/tcp/tcp_input.c	Thu Jun 17 17:22:09 2010 -0700
+++ b/usr/src/uts/common/inet/tcp/tcp_input.c	Thu Jun 17 17:23:59 2010 -0700
@@ -165,8 +165,6 @@
 static void	tcp_set_rto(tcp_t *, time_t);
 static void	tcp_setcred_data(mblk_t *, ip_recv_attr_t *);
 
-extern void	tcp_kssl_input(tcp_t *, mblk_t *, cred_t *);
-
 /*
  * Set the MSS associated with a particular tcp based on its current value,
  * and a new one passed in. Observe minimums and maximums, and reset other
@@ -1535,13 +1533,6 @@
 		mblk_setcred(tpi_mp, ira->ira_cred, ira->ira_cpid);
 
 	eager->tcp_conn.tcp_eager_conn_ind = tpi_mp;
-
-	/* Inherit the listener's SSL protection state */
-	if ((eager->tcp_kssl_ent = listener->tcp_kssl_ent) != NULL) {
-		kssl_hold_ent(eager->tcp_kssl_ent);
-		eager->tcp_kssl_pending = B_TRUE;
-	}
-
 	ASSERT(eager->tcp_ordrel_mp == NULL);
 
 	/* Inherit the listener's non-STREAMS flag */
@@ -2014,13 +2005,6 @@
 #ifdef DEBUG
 		cnt += msgdsize(mp);
 #endif
-		/* Does this need SSL processing first? */
-		if ((tcp->tcp_kssl_ctx != NULL) && (DB_TYPE(mp) == M_DATA)) {
-			DTRACE_PROBE1(kssl_mblk__ksslinput_rcvdrain,
-			    mblk_t *, mp);
-			tcp_kssl_input(tcp, mp, NULL);
-			continue;
-		}
 		putnext(q, mp);
 	}
 #ifdef DEBUG
@@ -2787,22 +2771,7 @@
 	    (seg_len > 0 && SEQ_GT(seg_seq + seg_len, tcp->tcp_rnxt))) {
 		TCPS_BUMP_MIB(tcps, tcpInClosed);
 		DTRACE_PROBE2(tcp__trace__recv, mblk_t *, mp, tcp_t *, tcp);
-
 		freemsg(mp);
-		/*
-		 * This could be an SSL closure alert. We're detached so just
-		 * acknowledge it this last time.
-		 */
-		if (tcp->tcp_kssl_ctx != NULL) {
-			kssl_release_ctx(tcp->tcp_kssl_ctx);
-			tcp->tcp_kssl_ctx = NULL;
-
-			tcp->tcp_rnxt += seg_len;
-			tcp->tcp_tcpha->tha_ack = htonl(tcp->tcp_rnxt);
-			flags |= TH_ACK_NEEDED;
-			goto ack_check;
-		}
-
 		tcp_xmit_ctl("new data when detached", tcp,
 		    tcp->tcp_snxt, 0, TH_RST);
 		(void) tcp_clean_death(tcp, EPROTO);
@@ -3647,8 +3616,7 @@
 			DTRACE_TCP5(accept__established, mlbk_t *, NULL,
 			    ip_xmit_attr_t *, connp->conn_ixa, void_ip_t *,
 			    iphdr, tcp_t *, tcp, tcph_t *, tcpha);
-		} else if (((tcp->tcp_kssl_ent == NULL) ||
-		    !tcp->tcp_kssl_pending)) {
+		} else {
 			/*
 			 * 3-way handshake complete - this is a STREAMS based
 			 * socket, so pass up the T_CONN_IND.
@@ -4629,9 +4597,6 @@
 	if (IPCL_IS_NONSTR(connp)) {
 		/*
 		 * Non-STREAMS socket
-		 *
-		 * Note that no KSSL processing is done here, because
-		 * KSSL is not supported for non-STREAMS sockets.
 		 */
 		boolean_t push = flags & (TH_PUSH|TH_FIN);
 		int error;
@@ -4661,13 +4626,7 @@
 		 *	Making M_PCPROTO and MARK messages skip the eager case
 		 */
 
-		if (tcp->tcp_kssl_pending) {
-			DTRACE_PROBE1(kssl_mblk__ksslinput_pending,
-			    mblk_t *, mp);
-			tcp_kssl_input(tcp, mp, ira->ira_cred);
-		} else {
-			tcp_rcv_enqueue(tcp, mp, seg_len, ira->ira_cred);
-		}
+		tcp_rcv_enqueue(tcp, mp, seg_len, ira->ira_cred);
 	} else {
 		/* Active STREAMS socket */
 		if (mp->b_datap->db_type != M_DATA ||
@@ -4689,25 +4648,12 @@
 				flags &= ~TH_MARKNEXT_NEEDED;
 			}
 
-			/* Does this need SSL processing first? */
-			if ((tcp->tcp_kssl_ctx != NULL) &&
-			    (DB_TYPE(mp) == M_DATA)) {
-				DTRACE_PROBE1(kssl_mblk__ksslinput_data1,
-				    mblk_t *, mp);
-				tcp_kssl_input(tcp, mp, ira->ira_cred);
-			} else {
-				if (is_system_labeled())
-					tcp_setcred_data(mp, ira);
-
-				putnext(connp->conn_rq, mp);
-				if (!canputnext(connp->conn_rq))
-					tcp->tcp_rwnd -= seg_len;
-			}
-		} else if ((tcp->tcp_kssl_ctx != NULL) &&
-		    (DB_TYPE(mp) == M_DATA)) {
-			/* Does this need SSL processing first? */
-			DTRACE_PROBE1(kssl_mblk__ksslinput_data2, mblk_t *, mp);
-			tcp_kssl_input(tcp, mp, ira->ira_cred);
+			if (is_system_labeled())
+				tcp_setcred_data(mp, ira);
+
+			putnext(connp->conn_rq, mp);
+			if (!canputnext(connp->conn_rq))
+				tcp->tcp_rwnd -= seg_len;
 		} else if ((flags & (TH_PUSH|TH_FIN)) ||
 		    tcp->tcp_rcv_cnt + seg_len >= connp->conn_rcvbuf >> 3) {
 			if (tcp->tcp_rcv_list != NULL) {
--- a/usr/src/uts/common/inet/tcp/tcp_kssl.c	Thu Jun 17 17:22:09 2010 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,425 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <sys/types.h>
-#include <sys/stream.h>
-#include <sys/strsubr.h>
-#include <sys/stropts.h>
-#include <sys/cmn_err.h>
-#include <sys/debug.h>
-#include <sys/vtrace.h>
-#include <sys/kmem.h>
-#include <sys/zone.h>
-#include <sys/tihdr.h>
-
-#include <netinet/in.h>
-#include <netinet/tcp.h>
-
-#include <inet/common.h>
-#include <inet/optcom.h>
-#include <inet/ipclassifier.h>
-#include <inet/ip.h>
-#include <inet/ip6.h>
-#include <inet/mib2.h>
-#include <inet/tcp.h>
-#include <inet/ipsec_impl.h>
-#include <inet/ipdrop.h>
-#include <inet/tcp_impl.h>
-
-#include <sys/squeue_impl.h>
-#include <sys/squeue.h>
-#include <inet/kssl/ksslapi.h>
-
-/*
- * For the Kernel SSL proxy
- *
- * Routines in this file are called on tcp's incoming path,
- * tcp_input_data() mainly, and right before the message is
- * to be putnext()'ed upstreams.
- */
-
-static void	tcp_kssl_input_callback(void *, mblk_t *, kssl_cmd_t);
-static void	tcp_kssl_input_asynch(void *, mblk_t *, void *,
-    ip_recv_attr_t *);
-
-extern void	tcp_output(void *, mblk_t *, void *, ip_recv_attr_t *);
-extern void	tcp_send_conn_ind(void *, mblk_t *, void *);
-
-/*
- * tcp_input_data() calls this routine for all packet destined to a
- * connection to the SSL port, when the SSL kernel proxy is configured
- * to intercept and process those packets.
- * A packet may carry multiple SSL records, so the function
- * calls kssl_input() in a loop, until all records are
- * handled.
- * As long as this connection is in handshake, that is until the first
- * time kssl_input() returns a record to be delivered ustreams,
- * we maintain the tcp_kssl_inhandshake, and keep an extra reference on
- * the tcp/connp across the call to kssl_input(). The reason is, that
- * function may return KSSL_CMD_QUEUED after scheduling an asynchronous
- * request and cause tcp_kssl_callback() to be called on a different CPU,
- * which could decrement the conn/tcp reference before we get to increment it.
- */
-void
-tcp_kssl_input(tcp_t *tcp, mblk_t *mp, cred_t *cr)
-{
-	struct conn_s	*connp = tcp->tcp_connp;
-	tcp_t		*listener;
-	mblk_t		*ind_mp;
-	kssl_cmd_t	kssl_cmd;
-	mblk_t		*outmp;
-	struct		T_conn_ind *tci;
-	boolean_t	more = B_FALSE;
-	boolean_t	conn_held = B_FALSE;
-	boolean_t	is_v4;
-	void		*addr;
-
-	if (is_system_labeled() && mp != NULL) {
-		ASSERT(cr != NULL || msg_getcred(mp, NULL) != NULL);
-		/*
-		 * Provide for protocols above TCP such as RPC. NOPID leaves
-		 * db_cpid unchanged.
-		 * The cred could have already been set.
-		 */
-		if (cr != NULL)
-			mblk_setcred(mp, cr, NOPID);
-	}
-
-	/* First time here, allocate the SSL context */
-	if (tcp->tcp_kssl_ctx == NULL) {
-		ASSERT(tcp->tcp_kssl_pending);
-
-		is_v4 = (connp->conn_ipversion == IPV4_VERSION);
-		if (is_v4) {
-			addr = &connp->conn_faddr_v4;
-		} else {
-			addr = &connp->conn_faddr_v6;
-		}
-
-		if (kssl_init_context(tcp->tcp_kssl_ent,
-		    addr, is_v4, tcp->tcp_mss,
-		    &(tcp->tcp_kssl_ctx)) != KSSL_STS_OK) {
-			tcp->tcp_kssl_pending = B_FALSE;
-			kssl_release_ent(tcp->tcp_kssl_ent, NULL,
-			    KSSL_NO_PROXY);
-			tcp->tcp_kssl_ent = NULL;
-			goto no_can_do;
-		}
-		tcp->tcp_kssl_inhandshake = B_TRUE;
-
-		/* we won't be needing this one after now */
-		kssl_release_ent(tcp->tcp_kssl_ent, NULL, KSSL_NO_PROXY);
-		tcp->tcp_kssl_ent = NULL;
-
-	}
-
-	if (tcp->tcp_kssl_inhandshake) {
-		CONN_INC_REF(connp);
-		conn_held = B_TRUE;
-	}
-
-	do {
-		kssl_cmd = kssl_input(tcp->tcp_kssl_ctx, mp, &outmp,
-		    &more, tcp_kssl_input_callback, (void *)tcp);
-
-		switch (kssl_cmd) {
-		case KSSL_CMD_SEND:
-			DTRACE_PROBE(kssl_cmd_send);
-			/*
-			 * We need to increment tcp_squeue_bytes to account
-			 * for the extra bytes internally injected to the
-			 * outgoing flow. tcp_output() will decrement it
-			 * as they are sent out.
-			 */
-			mutex_enter(&tcp->tcp_non_sq_lock);
-			tcp->tcp_squeue_bytes += msgdsize(outmp);
-			mutex_exit(&tcp->tcp_non_sq_lock);
-			tcp_output(connp, outmp, NULL, NULL);
-
-		/* FALLTHROUGH */
-		case KSSL_CMD_NONE:
-			DTRACE_PROBE(kssl_cmd_none);
-			if (tcp->tcp_kssl_pending) {
-				mblk_t *ctxmp;
-
-				/*
-				 * SSL handshake successfully started -
-				 * pass up the T_CONN_IND
-				 */
-
-				mp = NULL;
-
-				listener = tcp->tcp_listener;
-				tcp->tcp_kssl_pending = B_FALSE;
-
-				ind_mp = tcp->tcp_conn.tcp_eager_conn_ind;
-				ASSERT(ind_mp != NULL);
-
-				ctxmp = allocb(sizeof (kssl_ctx_t), BPRI_MED);
-
-				/*
-				 * Give this session a chance to fall back to
-				 * userland SSL
-				 */
-				if (ctxmp == NULL)
-					goto no_can_do;
-
-				/*
-				 * attach the kssl_ctx to the conn_ind and
-				 * transform it to a T_SSL_PROXY_CONN_IND.
-				 * Hold it so that it stays valid till it
-				 * reaches the stream head.
-				 */
-				kssl_hold_ctx(tcp->tcp_kssl_ctx);
-				*((kssl_ctx_t *)ctxmp->b_rptr) =
-				    tcp->tcp_kssl_ctx;
-				ctxmp->b_wptr = ctxmp->b_rptr +
-				    sizeof (kssl_ctx_t);
-
-				ind_mp->b_cont = ctxmp;
-
-				tci = (struct T_conn_ind *)ind_mp->b_rptr;
-				tci->PRIM_type = T_SSL_PROXY_CONN_IND;
-
-				/*
-				 * The code below is copied from tcp_input_data
-				 * delivering the T_CONN_IND on a TCPS_SYN_RCVD,
-				 * and all conn ref cnt comments apply.
-				 */
-				tcp->tcp_conn.tcp_eager_conn_ind = NULL;
-				tcp->tcp_tconnind_started = B_TRUE;
-
-				CONN_INC_REF(connp);
-
-				CONN_INC_REF(listener->tcp_connp);
-				if (listener->tcp_connp->conn_sqp ==
-				    connp->conn_sqp) {
-					tcp_send_conn_ind(listener->tcp_connp,
-					    ind_mp,
-					    listener->tcp_connp->conn_sqp);
-					CONN_DEC_REF(listener->tcp_connp);
-				} else {
-					SQUEUE_ENTER_ONE(
-					    listener->tcp_connp->conn_sqp,
-					    ind_mp, tcp_send_conn_ind,
-					    listener->tcp_connp, NULL, SQ_FILL,
-					    SQTAG_TCP_CONN_IND);
-				}
-			}
-			break;
-
-		case KSSL_CMD_QUEUED:
-			DTRACE_PROBE(kssl_cmd_queued);
-			/*
-			 * We hold the conn_t here because an asynchronous
-			 * request have been queued and
-			 * tcp_kssl_input_callback() will be called later.
-			 * It will release the conn_t
-			 */
-			CONN_INC_REF(connp);
-			break;
-
-		case KSSL_CMD_DELIVER_PROXY:
-		case KSSL_CMD_DELIVER_SSL:
-			DTRACE_PROBE(kssl_cmd_proxy__ssl);
-			/*
-			 * Keep accumulating if not yet accepted.
-			 */
-			if (tcp->tcp_listener != NULL) {
-				DTRACE_PROBE1(kssl_mblk__input_rcv_enqueue,
-				    mblk_t *, outmp);
-				tcp_rcv_enqueue(tcp, outmp, msgdsize(outmp),
-				    NULL);
-			} else {
-				DTRACE_PROBE1(kssl_mblk__input_putnext,
-				    mblk_t *, outmp);
-				putnext(connp->conn_rq, outmp);
-			}
-			/*
-			 * We're at a phase where records are sent upstreams,
-			 * past the handshake
-			 */
-			tcp->tcp_kssl_inhandshake = B_FALSE;
-			break;
-
-		case KSSL_CMD_NOT_SUPPORTED:
-			DTRACE_PROBE(kssl_cmd_not_supported);
-			/*
-			 * Stop the SSL processing by the proxy, and
-			 * switch to the userland SSL
-			 */
-			if (tcp->tcp_kssl_pending) {
-
-				tcp->tcp_kssl_pending = B_FALSE;
-
-no_can_do:
-				DTRACE_PROBE1(kssl_no_can_do, tcp_t *, tcp);
-				listener = tcp->tcp_listener;
-				ind_mp = tcp->tcp_conn.tcp_eager_conn_ind;
-				ASSERT(ind_mp != NULL);
-
-				if (tcp->tcp_kssl_ctx != NULL) {
-					kssl_release_ctx(tcp->tcp_kssl_ctx);
-					tcp->tcp_kssl_ctx = NULL;
-				}
-
-				/*
-				 * Make this a T_SSL_PROXY_CONN_IND, for the
-				 * stream head to deliver it to the SSL
-				 * fall-back listener
-				 */
-				tci = (struct T_conn_ind *)ind_mp->b_rptr;
-				tci->PRIM_type = T_SSL_PROXY_CONN_IND;
-
-				/*
-				 * The code below is copied from tcp_input_data
-				 * delivering the T_CONN_IND on a TCPS_SYN_RCVD,
-				 * and all conn ref cnt comments apply.
-				 */
-				tcp->tcp_conn.tcp_eager_conn_ind = NULL;
-				tcp->tcp_tconnind_started = B_TRUE;
-
-				CONN_INC_REF(connp);
-
-				CONN_INC_REF(listener->tcp_connp);
-				if (listener->tcp_connp->conn_sqp ==
-				    connp->conn_sqp) {
-					tcp_send_conn_ind(listener->tcp_connp,
-					    ind_mp,
-					    listener->tcp_connp->conn_sqp);
-					CONN_DEC_REF(listener->tcp_connp);
-				} else {
-					SQUEUE_ENTER_ONE(
-					    listener->tcp_connp->conn_sqp,
-					    ind_mp, tcp_send_conn_ind,
-					    listener->tcp_connp, NULL,
-					    SQ_FILL, SQTAG_TCP_CONN_IND);
-				}
-			}
-			if (mp != NULL)
-				tcp_rcv_enqueue(tcp, mp, msgdsize(mp), NULL);
-			break;
-		}
-		mp = NULL;
-	} while (more);
-
-	if (conn_held) {
-		CONN_DEC_REF(connp);
-	}
-}
-
-/*
- * Callback function for the cases kssl_input() had to submit an asynchronous
- * job and need to come back when done to carry on the input processing.
- * This routine follows the conventions of timeout and interrupt handlers.
- * (no blocking, ...)
- */
-static void
-tcp_kssl_input_callback(void *arg, mblk_t *mp, kssl_cmd_t kssl_cmd)
-{
-	tcp_t	*tcp = (tcp_t *)arg;
-	conn_t	*connp;
-	mblk_t	*sqmp;
-
-	ASSERT(tcp != NULL);
-
-	connp = tcp->tcp_connp;
-
-	ASSERT(connp != NULL);
-
-	switch (kssl_cmd) {
-	case KSSL_CMD_SEND:
-		/* I'm coming from an outside perimeter */
-		if (mp != NULL) {
-			/*
-			 * See comment in tcp_kssl_input() call to tcp_output()
-			 */
-			mutex_enter(&tcp->tcp_non_sq_lock);
-			tcp->tcp_squeue_bytes += msgdsize(mp);
-			mutex_exit(&tcp->tcp_non_sq_lock);
-		}
-		CONN_INC_REF(connp);
-		SQUEUE_ENTER_ONE(connp->conn_sqp, mp, tcp_output, connp,
-		    NULL, tcp_squeue_flag, SQTAG_TCP_OUTPUT);
-
-	/* FALLTHROUGH */
-	case KSSL_CMD_NONE:
-		break;
-
-	case KSSL_CMD_DELIVER_PROXY:
-	case KSSL_CMD_DELIVER_SSL:
-		/*
-		 * Keep accumulating if not yet accepted.
-		 */
-		if (tcp->tcp_listener != NULL) {
-			tcp_rcv_enqueue(tcp, mp, msgdsize(mp), NULL);
-		} else {
-			putnext(connp->conn_rq, mp);
-		}
-		break;
-
-	case KSSL_CMD_NOT_SUPPORTED:
-		/* Stop the SSL processing */
-		kssl_release_ctx(tcp->tcp_kssl_ctx);
-		tcp->tcp_kssl_ctx = NULL;
-	}
-	/*
-	 * Process any input that may have accumulated while we're waiting for
-	 * the call-back.
-	 * We need to re-enter the squeue for this connp, and a new mp is
-	 * necessary.
-	 */
-	if ((sqmp = allocb(1, BPRI_MED)) != NULL) {
-		CONN_INC_REF(connp);
-		SQUEUE_ENTER_ONE(connp->conn_sqp, sqmp, tcp_kssl_input_asynch,
-		    connp, NULL, SQ_FILL, SQTAG_TCP_KSSL_INPUT);
-	} else {
-		DTRACE_PROBE(kssl_err__allocb_failed);
-	}
-	CONN_DEC_REF(connp);
-}
-
-/*
- * Needed by tcp_kssl_input_callback() to continue processing the incoming
- * flow on a tcp_t after an asynchronous callback call.
- */
-/* ARGSUSED */
-void
-tcp_kssl_input_asynch(void *arg, mblk_t *mp, void *arg2, ip_recv_attr_t *dummy)
-{
-	conn_t	*connp = (conn_t *)arg;
-	tcp_t *tcp = connp->conn_tcp;
-
-	ASSERT(connp != NULL);
-	freemsg(mp);
-
-	/*
-	 * NULL tcp_kssl_ctx means this connection is getting/was closed
-	 * while we're away
-	 */
-	if (tcp->tcp_kssl_ctx != NULL) {
-		tcp_kssl_input(tcp, NULL, NULL);
-	}
-}
--- a/usr/src/uts/common/inet/tcp/tcp_opt_data.c	Thu Jun 17 17:22:09 2010 -0700
+++ b/usr/src/uts/common/inet/tcp/tcp_opt_data.c	Thu Jun 17 17:23:59 2010 -0700
@@ -620,7 +620,6 @@
 		case SO_SND_COPYAVOID:
 			if (!checkonly) {
 				if (tcp->tcp_loopback ||
-				    (tcp->tcp_kssl_ctx != NULL) ||
 				    (onoff != 1) || !tcp_zcopy_check(tcp)) {
 					*outlenp = 0;
 					return (EOPNOTSUPP);
--- a/usr/src/uts/common/inet/tcp/tcp_output.c	Thu Jun 17 17:22:09 2010 -0700
+++ b/usr/src/uts/common/inet/tcp/tcp_output.c	Thu Jun 17 17:23:59 2010 -0700
@@ -933,28 +933,6 @@
 non_urgent_data:
 
 	switch ((int)tprim->type) {
-	case T_SSL_PROXY_BIND_REQ:	/* an SSL proxy endpoint bind request */
-		/*
-		 * save the kssl_ent_t from the next block, and convert this
-		 * back to a normal bind_req.
-		 */
-		if (mp->b_cont != NULL) {
-			ASSERT(MBLKL(mp->b_cont) >= sizeof (kssl_ent_t));
-
-			if (tcp->tcp_kssl_ent != NULL) {
-				kssl_release_ent(tcp->tcp_kssl_ent, NULL,
-				    KSSL_NO_PROXY);
-				tcp->tcp_kssl_ent = NULL;
-			}
-			bcopy(mp->b_cont->b_rptr, &tcp->tcp_kssl_ent,
-			    sizeof (kssl_ent_t));
-			kssl_hold_ent(tcp->tcp_kssl_ent);
-			freemsg(mp->b_cont);
-			mp->b_cont = NULL;
-		}
-		tprim->type = T_BIND_REQ;
-
-	/* FALLTHROUGH */
 	case O_T_BIND_REQ:	/* bind request */
 	case T_BIND_REQ:	/* new semantics bind request */
 		tcp_tpi_bind(tcp, mp);
--- a/usr/src/uts/common/inet/tcp/tcp_socket.c	Thu Jun 17 17:22:09 2010 -0700
+++ b/usr/src/uts/common/inet/tcp/tcp_socket.c	Thu Jun 17 17:23:59 2010 -0700
@@ -131,13 +131,19 @@
 	conn_t *lconnp, *econnp;
 	tcp_t *listener, *eager;
 
-	lconnp = (conn_t *)lproto_handle;
-	listener = lconnp->conn_tcp;
-	ASSERT(listener->tcp_state == TCPS_LISTEN);
+	/*
+	 * KSSL can move a socket from one listener to another, in which
+	 * case `lproto_handle' points to the new listener. To ensure that
+	 * the original listener is used the information is obtained from
+	 * the eager.
+	 */
 	econnp = (conn_t *)eproto_handle;
 	eager = econnp->conn_tcp;
+	ASSERT(IPCL_IS_NONSTR(econnp));
 	ASSERT(eager->tcp_listener != NULL);
-	ASSERT(IPCL_IS_NONSTR(econnp));
+	listener = eager->tcp_listener;
+	lconnp = (conn_t *)listener->tcp_connp;
+	ASSERT(listener->tcp_state == TCPS_LISTEN);
 	ASSERT(lconnp->conn_upper_handle != NULL);
 
 	/*
--- a/usr/src/uts/common/inet/tcp/tcp_tpi.c	Thu Jun 17 17:22:09 2010 -0700
+++ b/usr/src/uts/common/inet/tcp/tcp_tpi.c	Thu Jun 17 17:23:59 2010 -0700
@@ -1141,14 +1141,6 @@
 	stropt->so_wroff = sopp.sopp_wroff;
 	stropt->so_maxblk = sopp.sopp_maxblk;
 
-	if (sopp.sopp_flags & SOCKOPT_TAIL) {
-		ASSERT(tcp->tcp_kssl_ctx != NULL);
-
-		stropt->so_flags |= SO_TAIL | SO_COPYOPT;
-		stropt->so_tail = sopp.sopp_tail;
-		stropt->so_copyopt = sopp.sopp_zcopyflag;
-	}
-
 	/* Send the options up */
 	putnext(q, mp);
 
@@ -1224,6 +1216,71 @@
 	    (connp->conn_fanout == NULL && connp->conn_ref >= 3));
 }
 
+/*
+ * Pull a deferred connection indication off of the listener. The caller
+ * must verify that there is a deferred conn ind under eager_lock before
+ * calling this function.
+ */
+static mblk_t *
+tcp_get_def_conn_ind(tcp_t *listener)
+{
+	tcp_t *tail;
+	tcp_t *tcp;
+	mblk_t *conn_ind;
+
+	ASSERT(MUTEX_HELD(&listener->tcp_eager_lock));
+	ASSERT(listener->tcp_eager_prev_q0->tcp_conn_def_q0);
+
+	tcp = listener->tcp_eager_prev_q0;
+	/*
+	 * listener->tcp_eager_prev_q0 points to the TAIL of the
+	 * deferred T_conn_ind queue. We need to get to the head
+	 * of the queue in order to send up T_conn_ind the same
+	 * order as how the 3WHS is completed.
+	 */
+	while (tcp != listener) {
+		if (!tcp->tcp_eager_prev_q0->tcp_conn_def_q0)
+			break;
+		else
+			tcp = tcp->tcp_eager_prev_q0;
+	}
+
+	conn_ind = tcp->tcp_conn.tcp_eager_conn_ind;
+	tcp->tcp_conn.tcp_eager_conn_ind = NULL;
+	/* Move from q0 to q */
+	ASSERT(listener->tcp_conn_req_cnt_q0 > 0);
+	listener->tcp_conn_req_cnt_q0--;
+	listener->tcp_conn_req_cnt_q++;
+	tcp->tcp_eager_next_q0->tcp_eager_prev_q0 =
+	    tcp->tcp_eager_prev_q0;
+	tcp->tcp_eager_prev_q0->tcp_eager_next_q0 =
+	    tcp->tcp_eager_next_q0;
+	tcp->tcp_eager_prev_q0 = NULL;
+	tcp->tcp_eager_next_q0 = NULL;
+	tcp->tcp_conn_def_q0 = B_FALSE;
+
+	/* Make sure the tcp isn't in the list of droppables */
+	ASSERT(tcp->tcp_eager_next_drop_q0 == NULL &&
+	    tcp->tcp_eager_prev_drop_q0 == NULL);
+
+	/*
+	 * Insert at end of the queue because sockfs sends
+	 * down T_CONN_RES in chronological order. Leaving
+	 * the older conn indications at front of the queue
+	 * helps reducing search time.
+	 */
+	tail = listener->tcp_eager_last_q;
+	if (tail != NULL) {
+		tail->tcp_eager_next_q = tcp;
+	} else {
+		listener->tcp_eager_next_q = tcp;
+	}
+	listener->tcp_eager_last_q = tcp;
+	tcp->tcp_eager_next_q = NULL;
+
+	return (conn_ind);
+}
+
 
 /*
  * Reply to a clients T_CONN_RES TPI message. This function
@@ -1236,7 +1293,6 @@
 {
 	tcp_t		*acceptor;
 	tcp_t		*eager;
-	tcp_t   	*tcp;
 	struct T_conn_res	*tcr;
 	t_uscalar_t	acceptor_id;
 	t_scalar_t	seqnum;
@@ -1564,7 +1620,6 @@
 
 	mutex_enter(&listener->tcp_eager_lock);
 	if (listener->tcp_eager_prev_q0->tcp_conn_def_q0) {
-		tcp_t	*tail;
 		mblk_t	*conn_ind;
 
 		/*
@@ -1572,56 +1627,9 @@
 		 * acceptor streams are the same.
 		 */
 		ASSERT(listener != acceptor);
-
-		tcp = listener->tcp_eager_prev_q0;
-		/*
-		 * listener->tcp_eager_prev_q0 points to the TAIL of the
-		 * deferred T_conn_ind queue. We need to get to the head of
-		 * the queue in order to send up T_conn_ind the same order as
-		 * how the 3WHS is completed.
-		 */
-		while (tcp != listener) {
-			if (!tcp->tcp_eager_prev_q0->tcp_conn_def_q0)
-				break;
-			else
-				tcp = tcp->tcp_eager_prev_q0;
-		}
-		ASSERT(tcp != listener);
-		conn_ind = tcp->tcp_conn.tcp_eager_conn_ind;
-		ASSERT(conn_ind != NULL);
-		tcp->tcp_conn.tcp_eager_conn_ind = NULL;
-
-		/* Move from q0 to q */
-		ASSERT(listener->tcp_conn_req_cnt_q0 > 0);
-		listener->tcp_conn_req_cnt_q0--;
-		listener->tcp_conn_req_cnt_q++;
-		tcp->tcp_eager_next_q0->tcp_eager_prev_q0 =
-		    tcp->tcp_eager_prev_q0;
-		tcp->tcp_eager_prev_q0->tcp_eager_next_q0 =
-		    tcp->tcp_eager_next_q0;
-		tcp->tcp_eager_prev_q0 = NULL;
-		tcp->tcp_eager_next_q0 = NULL;
-		tcp->tcp_conn_def_q0 = B_FALSE;
-
-		/* Make sure the tcp isn't in the list of droppables */
-		ASSERT(tcp->tcp_eager_next_drop_q0 == NULL &&
-		    tcp->tcp_eager_prev_drop_q0 == NULL);
-
-		/*
-		 * Insert at end of the queue because sockfs sends
-		 * down T_CONN_RES in chronological order. Leaving
-		 * the older conn indications at front of the queue
-		 * helps reducing search time.
-		 */
-		tail = listener->tcp_eager_last_q;
-		if (tail != NULL)
-			tail->tcp_eager_next_q = tcp;
-		else
-			listener->tcp_eager_next_q = tcp;
-		listener->tcp_eager_last_q = tcp;
-		tcp->tcp_eager_next_q = NULL;
+		conn_ind = tcp_get_def_conn_ind(listener);
 		mutex_exit(&listener->tcp_eager_lock);
-		putnext(tcp->tcp_connp->conn_rq, conn_ind);
+		putnext(listener->tcp_connp->conn_rq, conn_ind);
 	} else {
 		mutex_exit(&listener->tcp_eager_lock);
 	}
@@ -1783,69 +1791,14 @@
 
 		mutex_enter(&listener->tcp_eager_lock);
 		if (listener->tcp_eager_prev_q0->tcp_conn_def_q0) {
-
-			tcp_t *tail;
-			tcp_t *tcp;
-			mblk_t *mp1;
-
-			tcp = listener->tcp_eager_prev_q0;
-			/*
-			 * listener->tcp_eager_prev_q0 points to the TAIL of the
-			 * deferred T_conn_ind queue. We need to get to the head
-			 * of the queue in order to send up T_conn_ind the same
-			 * order as how the 3WHS is completed.
-			 */
-			while (tcp != listener) {
-				if (!tcp->tcp_eager_prev_q0->tcp_conn_def_q0 &&
-				    !tcp->tcp_kssl_pending)
-					break;
-				else
-					tcp = tcp->tcp_eager_prev_q0;
-			}
-			/* None of the pending eagers can be sent up now */
-			if (tcp == listener)
-				goto no_more_eagers;
-
-			mp1 = tcp->tcp_conn.tcp_eager_conn_ind;
-			tcp->tcp_conn.tcp_eager_conn_ind = NULL;
-			/* Move from q0 to q */
-			ASSERT(listener->tcp_conn_req_cnt_q0 > 0);
-			listener->tcp_conn_req_cnt_q0--;
-			listener->tcp_conn_req_cnt_q++;
-			tcp->tcp_eager_next_q0->tcp_eager_prev_q0 =
-			    tcp->tcp_eager_prev_q0;
-			tcp->tcp_eager_prev_q0->tcp_eager_next_q0 =
-			    tcp->tcp_eager_next_q0;
-			tcp->tcp_eager_prev_q0 = NULL;
-			tcp->tcp_eager_next_q0 = NULL;
-			tcp->tcp_conn_def_q0 = B_FALSE;
-
-			/* Make sure the tcp isn't in the list of droppables */
-			ASSERT(tcp->tcp_eager_next_drop_q0 == NULL &&
-			    tcp->tcp_eager_prev_drop_q0 == NULL);
-
-			/*
-			 * Insert at end of the queue because sockfs sends
-			 * down T_CONN_RES in chronological order. Leaving
-			 * the older conn indications at front of the queue
-			 * helps reducing search time.
-			 */
-			tail = listener->tcp_eager_last_q;
-			if (tail != NULL) {
-				tail->tcp_eager_next_q = tcp;
-			} else {
-				listener->tcp_eager_next_q = tcp;
-			}
-			listener->tcp_eager_last_q = tcp;
-			tcp->tcp_eager_next_q = NULL;
+			mblk_t *conn_ind = tcp_get_def_conn_ind(listener);
 
 			/* Need to get inside the listener perimeter */
 			CONN_INC_REF(listener->tcp_connp);
-			SQUEUE_ENTER_ONE(listener->tcp_connp->conn_sqp, mp1,
-			    tcp_send_pending, listener->tcp_connp, NULL,
-			    SQ_FILL, SQTAG_TCP_SEND_PENDING);
+			SQUEUE_ENTER_ONE(listener->tcp_connp->conn_sqp,
+			    conn_ind, tcp_send_pending, listener->tcp_connp,
+			    NULL, SQ_FILL, SQTAG_TCP_SEND_PENDING);
 		}
-no_more_eagers:
 		tcp_eager_unlink(eager);
 		mutex_exit(&listener->tcp_eager_lock);
 
--- a/usr/src/uts/common/sys/tihdr.h	Thu Jun 17 17:22:09 2010 -0700
+++ b/usr/src/uts/common/sys/tihdr.h	Thu Jun 17 17:23:59 2010 -0700
@@ -2,9 +2,8 @@
  * CDDL HEADER START
  *
  * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
  *
  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  * or http://www.opensolaris.org/os/licensing.
@@ -24,15 +23,12 @@
 
 
 /*
- * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 1988, 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
 #ifndef _SYS_TIHDR_H
 #define	_SYS_TIHDR_H
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"	/* from SVr4.0 11.4 */
-
 #include <sys/types.h>
 /*
  * Include declarations implicit to TPI and shared with user level code
@@ -171,8 +167,7 @@
 #ifdef _KERNEL
 /*
  * Sun private TPI extensions. They are currently used for transparently
- * passing options through the connection-oriented loopback transport,
- * and for setting the kernel SSL proxy.
+ * passing options through the connection-oriented loopback transport.
  * Values assigned to them may change.
  *
  * T_EXTCONN_IND (extended T_CONN_IND) is used to return dst as well as
@@ -182,11 +177,6 @@
 #define	T_OPTDATA_IND	0x1002	/* data (with options) indication */
 #define	T_EXTCONN_IND	0x1003	/* extended T_CONN_IND to return dst as well */
 
-#define	T_SSL_PROXY_BIND_REQ	0x1004	/* extended T_BIND_REQ to carry a */
-					/* kssl_entry_t to the transport. */
-#define	T_SSL_PROXY_CONN_IND	0x1005	/* conn_ind from an SSL proxy */
-					/* endpoint, carrying a kssl_ctx_t */
-
 #endif /* _KERNEL */
 
 /*
--- a/usr/src/uts/common/syscall/sendfile.c	Thu Jun 17 17:22:09 2010 -0700
+++ b/usr/src/uts/common/syscall/sendfile.c	Thu Jun 17 17:23:59 2010 -0700
@@ -785,11 +785,8 @@
 					 * size, so limit reads to maxblk if
 					 * there are filters present.
 					 */
-					if ((!SOCK_IS_NONSTR(so) &&
-					    _SOTOTPI(so)->sti_kssl_ctx
-					    != NULL) ||
-					    (so->so_filter_active > 0 &&
-					    maxblk != INFPSZ))
+					if (so->so_filter_active > 0 &&
+					    maxblk != INFPSZ)
 						iov_len = MIN(iov_len, maxblk);
 
 					aiov.iov_len = iov_len;
@@ -941,10 +938,8 @@
 				 * so limit reads to maxblk if there are
 				 * filters present.
 				 */
-				if ((!SOCK_IS_NONSTR(so) &&
-				    _SOTOTPI(so)->sti_kssl_ctx != NULL) ||
-				    (so->so_filter_active > 0 &&
-				    maxblk != INFPSZ))
+				if (so->so_filter_active > 0 &&
+				    maxblk != INFPSZ)
 					size = MIN(size, maxblk);
 
 				if (vn_has_flocks(readvp) ||
--- a/usr/src/uts/intel/Makefile.intel.shared	Thu Jun 17 17:22:09 2010 -0700
+++ b/usr/src/uts/intel/Makefile.intel.shared	Thu Jun 17 17:23:59 2010 -0700
@@ -724,6 +724,7 @@
 SOCKET_KMODS	+= socksctp
 SOCKET_KMODS    += socksdp
 SOCKET_KMODS	+= sockrds
+SOCKET_KMODS	+= ksslf
 
 #
 #	kiconv modules (/kernel/kiconv):
--- a/usr/src/uts/intel/ia32/ml/modstubs.s	Thu Jun 17 17:22:09 2010 -0700
+++ b/usr/src/uts/intel/ia32/ml/modstubs.s	Thu Jun 17 17:23:59 2010 -0700
@@ -1295,24 +1295,6 @@
 #endif
 
 /*
- * Stubs for kssl, the kernel SSL proxy
- */
-#ifndef KSSL_MODULE
-	MODULE(kssl,drv);
-	NO_UNLOAD_STUB(kssl, kssl_check_proxy, nomod_zero);
-	NO_UNLOAD_STUB(kssl, kssl_handle_mblk, nomod_zero);
-	NO_UNLOAD_STUB(kssl, kssl_input, nomod_zero);
-	NO_UNLOAD_STUB(kssl, kssl_build_record, nomod_zero);
-	NO_UNLOAD_STUB(kssl, kssl_hold_ent, nomod_void);
-	NO_UNLOAD_STUB(kssl, kssl_release_ent, nomod_void);
-	NO_UNLOAD_STUB(kssl, kssl_find_fallback, nomod_zero);
-	NO_UNLOAD_STUB(kssl, kssl_init_context, nomod_zero);
-	NO_UNLOAD_STUB(kssl, kssl_hold_ctx, nomod_void);
-	NO_UNLOAD_STUB(kssl, kssl_release_ctx, nomod_void);
-	END_MODULE(kssl);
-#endif
-
-/*
  * Stubs for dcopy, for Intel IOAT KAPIs
  */
 #ifndef DCOPY_MODULE
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/uts/intel/ksslf/Makefile	Thu Jun 17 17:23:59 2010 -0700
@@ -0,0 +1,94 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+#
+#	This makefile drives the production of the kssl socket filter
+#	kernel module.
+#
+#	intel architecture dependent
+#
+
+#
+#	Path to the base of the uts directory tree (usually /usr/src/uts).
+#
+UTSBASE	= ../..
+
+#
+#	Define the module and object file sets.
+#
+MODULE		= ksslf
+OBJECTS		= $(KSSL_SOCKFIL_MOD_OBJS:%=$(OBJS_DIR)/%)
+LINTS		= $(KSSL_SOCKFIL_MOD_OBJS:%.o=$(LINTS_DIR)/%.ln)
+ROOTMODULE	= $(ROOT_SOCK_DIR)/$(MODULE)
+
+#
+#	Include common rules.
+#
+include $(UTSBASE)/intel/Makefile.intel
+
+#
+#	Define targets
+#
+ALL_TARGET	= $(BINARY)
+LINT_TARGET	= $(MODULE).lint
+INSTALL_TARGET	= $(BINARY) $(ROOTMODULE)
+
+#
+# lint pass one enforcement and OS version
+#
+CFLAGS += $(CCVERBOSE)
+
+LDFLAGS += -dy -Nmisc/md5 -Nmisc/kcf -Ndrv/kssl -Nfs/sockfs
+
+#
+# For now, disable these lint checks; maintainers should endeavor
+# to investigate and remove these for maximum lint coverage.
+# Please do not carry these forward to new Makefiles.
+#
+LINTTAGS	+= -erroff=E_BAD_PTR_CAST_ALIGN
+LINTTAGS	+= -erroff=E_PTRDIFF_OVERFLOW
+
+#
+#	Default build targets.
+#
+.KEEP_STATE:
+
+def:		$(DEF_DEPS)
+
+all:		$(ALL_DEPS)
+
+clean:		$(CLEAN_DEPS)
+
+clobber:	$(CLOBBER_DEPS)
+
+lint:		$(LINT_DEPS)
+
+modlintlib:	$(MODLINTLIB_DEPS)
+
+clean.lint:	$(CLEAN_LINT_DEPS)
+
+install:	$(INSTALL_DEPS)
+
+#
+#	Include common targets.
+#
+include $(UTSBASE)/intel/Makefile.targ
--- a/usr/src/uts/sparc/Makefile.sparc.shared	Thu Jun 17 17:22:09 2010 -0700
+++ b/usr/src/uts/sparc/Makefile.sparc.shared	Thu Jun 17 17:23:59 2010 -0700
@@ -504,6 +504,7 @@
 SOCKET_KMODS	+= socksctp
 SOCKET_KMODS	+= socksdp
 SOCKET_KMODS	+= sockrds
+SOCKET_KMODS	+= ksslf
 
 #
 #	kiconv modules (/kernel/kiconv):
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/uts/sparc/ksslf/Makefile	Thu Jun 17 17:23:59 2010 -0700
@@ -0,0 +1,94 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+#
+#	This makefile drives the production of the kssl socket filter 
+#	kernel module.
+#
+#	sparc architecture dependent
+#
+
+#
+#	Path to the base of the uts directory tree (usually /usr/src/uts).
+#
+UTSBASE	= ../..
+
+#
+#	Define the module and object file sets.
+#
+MODULE		= ksslf
+OBJECTS		= $(KSSL_SOCKFIL_MOD_OBJS:%=$(OBJS_DIR)/%)
+LINTS		= $(KSSL_SOCKFIL_MOD_OBJS:%.o=$(LINTS_DIR)/%.ln)
+ROOTMODULE	= $(ROOT_SOCK_DIR)/$(MODULE)
+
+#
+#	Include common rules.
+#
+include $(UTSBASE)/sparc/Makefile.sparc
+
+#
+#	Define targets
+#
+ALL_TARGET	= $(BINARY)
+LINT_TARGET	= $(MODULE).lint
+INSTALL_TARGET	= $(BINARY) $(ROOTMODULE)
+
+#
+# lint pass one enforcement and OS version
+#
+CFLAGS += $(CCVERBOSE)
+
+LDFLAGS += -dy -Nmisc/md5 -Nmisc/kcf -Ndrv/kssl -Nfs/sockfs
+
+#
+# For now, disable these lint checks; maintainers should endeavor
+# to investigate and remove these for maximum lint coverage.
+# Please do not carry these forward to new Makefiles.
+#
+LINTTAGS	+= -erroff=E_BAD_PTR_CAST_ALIGN
+LINTTAGS	+= -erroff=E_PTRDIFF_OVERFLOW
+
+#
+#	Default build targets.
+#
+.KEEP_STATE:
+
+def:		$(DEF_DEPS)
+
+all:		$(ALL_DEPS)
+
+clean:		$(CLEAN_DEPS)
+
+clobber:	$(CLOBBER_DEPS)
+
+lint:		$(LINT_DEPS)
+
+modlintlib:	$(MODLINTLIB_DEPS)
+
+clean.lint:	$(CLEAN_LINT_DEPS)
+
+install:	$(INSTALL_DEPS)
+
+#
+#	Include common targets.
+#
+include $(UTSBASE)/sparc/Makefile.targ
--- a/usr/src/uts/sparc/ml/modstubs.s	Thu Jun 17 17:22:09 2010 -0700
+++ b/usr/src/uts/sparc/ml/modstubs.s	Thu Jun 17 17:23:59 2010 -0700
@@ -1219,24 +1219,6 @@
 #endif
 
 /*
- * Stubs for kssl, the kernel SSL proxy
- */
-#ifndef KSSL_MODULE
-	MODULE(kssl,drv);
-	NO_UNLOAD_STUB(kssl, kssl_check_proxy, nomod_zero);
-	NO_UNLOAD_STUB(kssl, kssl_handle_mblk, nomod_zero);
-	NO_UNLOAD_STUB(kssl, kssl_input, nomod_zero);
-	NO_UNLOAD_STUB(kssl, kssl_build_record, nomod_zero);
-	NO_UNLOAD_STUB(kssl, kssl_hold_ent, nomod_void);
-	NO_UNLOAD_STUB(kssl, kssl_release_ent, nomod_void);
-	NO_UNLOAD_STUB(kssl, kssl_find_fallback, nomod_zero);
-	NO_UNLOAD_STUB(kssl, kssl_init_context, nomod_zero);
-	NO_UNLOAD_STUB(kssl, kssl_hold_ctx, nomod_void);
-	NO_UNLOAD_STUB(kssl, kssl_release_ctx, nomod_void);
-	END_MODULE(kssl);
-#endif
-
-/*
  * Stubs for dcopy, for Intel IOAT KAPIs
  */
 #ifndef DCOPY_MODULE