changeset 9953:b354e1e8b863

6762261 The system panic occurred in rw_destroy() called from ipsec_polhead_free().
author Vladimir Kotal <Vladimir.Kotal@Sun.COM>
date Tue, 23 Jun 2009 10:40:30 +0200
parents 1dcbfc9c84b6
children 26dc94cffbd1
files usr/src/uts/common/inet/ip/spd.c
diffstat 1 files changed, 19 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/uts/common/inet/ip/spd.c	Mon Jun 22 23:03:47 2009 -0700
+++ b/usr/src/uts/common/inet/ip/spd.c	Tue Jun 23 10:40:30 2009 +0200
@@ -2558,6 +2558,7 @@
 	ipsec_stack_t	*ipss;
 	ip_stack_t	*ipst;
 	netstack_t	*ns;
+	ipsec_policy_head_t *policy_head;
 
 	ASSERT(connp != NULL);
 	ns = connp->conn_netstack;
@@ -2620,7 +2621,11 @@
 			}
 		} else {
 			uchar_t db_type;
-
+			policy_head = connp->conn_policy;
+
+			/* Hold a reference in case the conn is closing */
+			if (policy_head != NULL)
+				IPPH_REFHOLD(policy_head);
 			mutex_exit(&connp->conn_lock);
 			/*
 			 * As this is a non-hardbound connection we need
@@ -2634,6 +2639,8 @@
 			mp->b_datap->db_type = M_DATA;
 			first_mp = ipsec_check_global_policy(first_mp, connp,
 			    ipha, ip6h, mctl_present, ns);
+			if (policy_head != NULL)
+				IPPH_REFRELE(policy_head, ns);
 			if (first_mp != NULL)
 				mp->b_datap->db_type = db_type;
 			return (first_mp);
@@ -2678,6 +2685,12 @@
 	 * as the earlier initialization was done only in the cleartext case.
 	 */
 	if ((ipl = connp->conn_latch) == NULL) {
+		mblk_t *retmp;
+		policy_head = connp->conn_policy;
+
+		/* Hold a reference in case the conn is closing */
+		if (policy_head != NULL)
+			IPPH_REFHOLD(policy_head);
 		mutex_exit(&connp->conn_lock);
 		/*
 		 * We don't have policies cached in the conn
@@ -2685,8 +2698,11 @@
 		 * policy. It will check against conn or global
 		 * depending on whichever is stronger.
 		 */
-		return (ipsec_check_global_policy(first_mp, connp,
-		    ipha, ip6h, mctl_present, ns));
+		retmp = ipsec_check_global_policy(first_mp, connp,
+		    ipha, ip6h, mctl_present, ns);
+		if (policy_head != NULL)
+			IPPH_REFRELE(policy_head, ns);
+		return (retmp);
 	}
 
 	IPLATCH_REFHOLD(ipl);