Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 8 May 2011 09:11:59 +0000 (UTC)
From:      Michael Tuexen <tuexen@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r221627 - head/sys/netinet
Message-ID:  <201105080911.p489BxTW037814@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: tuexen
Date: Sun May  8 09:11:59 2011
New Revision: 221627
URL: http://svn.freebsd.org/changeset/base/221627

Log:
  Fix a locking issue showing up on Mac OS X when subscribing to
  authentication events. DTLS/SCTP renegotiations trigger the bug.
  
  MFC after: 2 weeks.

Modified:
  head/sys/netinet/sctp_auth.c
  head/sys/netinet/sctp_auth.h
  head/sys/netinet/sctp_indata.c
  head/sys/netinet/sctp_input.c
  head/sys/netinet/sctp_input.h
  head/sys/netinet/sctp_output.c
  head/sys/netinet/sctp_output.h
  head/sys/netinet/sctp_pcb.c
  head/sys/netinet/sctp_timer.c
  head/sys/netinet/sctp_usrreq.c
  head/sys/netinet/sctp_var.h
  head/sys/netinet/sctputil.c

Modified: head/sys/netinet/sctp_auth.c
==============================================================================
--- head/sys/netinet/sctp_auth.c	Sun May  8 09:11:04 2011	(r221626)
+++ head/sys/netinet/sctp_auth.c	Sun May  8 09:11:59 2011	(r221627)
@@ -598,7 +598,11 @@ sctp_auth_key_acquire(struct sctp_tcb *s
 }
 
 void
-sctp_auth_key_release(struct sctp_tcb *stcb, uint16_t key_id)
+sctp_auth_key_release(struct sctp_tcb *stcb, uint16_t key_id, int so_locked
+#if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING)
+    SCTP_UNUSED
+#endif
+)
 {
 	sctp_sharedkey_t *skey;
 
@@ -616,7 +620,7 @@ sctp_auth_key_release(struct sctp_tcb *s
 		if ((skey->refcount <= 1) && (skey->deactivated)) {
 			/* notify ULP that key is no longer used */
 			sctp_ulp_notify(SCTP_NOTIFY_AUTH_FREE_KEY, stcb,
-			    key_id, 0, SCTP_SO_LOCKED);
+			    key_id, 0, so_locked);
 			SCTPDBG(SCTP_DEBUG_AUTH2,
 			    "%s: stcb %p key %u no longer used, %d\n",
 			    __FUNCTION__, stcb, key_id, skey->refcount);

Modified: head/sys/netinet/sctp_auth.h
==============================================================================
--- head/sys/netinet/sctp_auth.h	Sun May  8 09:11:04 2011	(r221626)
+++ head/sys/netinet/sctp_auth.h	Sun May  8 09:11:59 2011	(r221627)
@@ -156,7 +156,9 @@ sctp_copy_skeylist(const struct sctp_key
 
 /* ref counts on shared keys, by key id */
 extern void sctp_auth_key_acquire(struct sctp_tcb *stcb, uint16_t keyid);
-extern void sctp_auth_key_release(struct sctp_tcb *stcb, uint16_t keyid);
+extern void 
+sctp_auth_key_release(struct sctp_tcb *stcb, uint16_t keyid,
+    int so_locked);
 
 
 /* hmac list handling */

Modified: head/sys/netinet/sctp_indata.c
==============================================================================
--- head/sys/netinet/sctp_indata.c	Sun May  8 09:11:04 2011	(r221626)
+++ head/sys/netinet/sctp_indata.c	Sun May  8 09:11:59 2011	(r221627)
@@ -375,7 +375,7 @@ abandon:
 				chk->data = NULL;
 			}
 			/* Now free the address and data */
-			sctp_free_a_chunk(stcb, chk);
+			sctp_free_a_chunk(stcb, chk, SCTP_SO_NOT_LOCKED);
 			/* sa_ignore FREED_MEMORY */
 		}
 		return;
@@ -479,7 +479,7 @@ abandon:
 		sctp_ucount_decr(asoc->cnt_on_reasm_queue);
 		/* free up the chk */
 		chk->data = NULL;
-		sctp_free_a_chunk(stcb, chk);
+		sctp_free_a_chunk(stcb, chk, SCTP_SO_NOT_LOCKED);
 
 		if (asoc->fragmented_delivery_inprogress == 0) {
 			/*
@@ -1011,7 +1011,7 @@ sctp_queue_data_for_reasm(struct sctp_tc
 				sctp_m_freem(chk->data);
 				chk->data = NULL;
 			}
-			sctp_free_a_chunk(stcb, chk);
+			sctp_free_a_chunk(stcb, chk, SCTP_SO_NOT_LOCKED);
 			return;
 		} else {
 			last_flags = at->rec.data.rcv_flags;
@@ -2416,7 +2416,7 @@ sctp_sack_check(struct sctp_tcb *stcb, i
 			    stcb->sctp_ep, stcb, NULL, SCTP_FROM_SCTP_INDATA + SCTP_LOC_18);
 		}
 		sctp_send_shutdown(stcb, stcb->asoc.primary_destination);
-		sctp_send_sack(stcb);
+		sctp_send_sack(stcb, SCTP_SO_NOT_LOCKED);
 	} else {
 		int is_a_gap;
 
@@ -2466,7 +2466,7 @@ sctp_sack_check(struct sctp_tcb *stcb, i
 				 * there are gaps or duplicates.
 				 */
 				(void)SCTP_OS_TIMER_STOP(&stcb->asoc.dack_timer.timer);
-				sctp_send_sack(stcb);
+				sctp_send_sack(stcb, SCTP_SO_NOT_LOCKED);
 			}
 		} else {
 			if (!SCTP_OS_TIMER_PENDING(&stcb->asoc.dack_timer.timer)) {
@@ -3993,7 +3993,7 @@ sctp_express_handle_sack(struct sctp_tcb
 					    SCTP_LOG_FREE_SENT);
 				}
 				asoc->sent_queue_cnt--;
-				sctp_free_a_chunk(stcb, tp1);
+				sctp_free_a_chunk(stcb, tp1, SCTP_SO_NOT_LOCKED);
 			} else {
 				break;
 			}
@@ -4709,7 +4709,7 @@ sctp_handle_sack(struct mbuf *m, int off
 			    0,
 			    SCTP_LOG_FREE_SENT);
 		}
-		sctp_free_a_chunk(stcb, tp1);
+		sctp_free_a_chunk(stcb, tp1, SCTP_SO_NOT_LOCKED);
 		wake_him++;
 	}
 	if (TAILQ_EMPTY(&asoc->sent_queue) && (asoc->total_flight > 0)) {
@@ -5260,7 +5260,7 @@ sctp_flush_reassm_for_str_seq(struct sct
 				sctp_m_freem(chk->data);
 				chk->data = NULL;
 			}
-			sctp_free_a_chunk(stcb, chk);
+			sctp_free_a_chunk(stcb, chk, SCTP_SO_NOT_LOCKED);
 		} else if (SCTP_SSN_GT(chk->rec.data.stream_seq, seq)) {
 			/*
 			 * If the stream_seq is > than the purging one, we
@@ -5431,7 +5431,7 @@ sctp_handle_forward_tsn(struct sctp_tcb 
 				sctp_m_freem(chk->data);
 				chk->data = NULL;
 			}
-			sctp_free_a_chunk(stcb, chk);
+			sctp_free_a_chunk(stcb, chk, SCTP_SO_NOT_LOCKED);
 		} else {
 			/*
 			 * Ok we have gone beyond the end of the fwd-tsn's

Modified: head/sys/netinet/sctp_input.c
==============================================================================
--- head/sys/netinet/sctp_input.c	Sun May  8 09:11:04 2011	(r221626)
+++ head/sys/netinet/sctp_input.c	Sun May  8 09:11:59 2011	(r221627)
@@ -193,7 +193,11 @@ outnow:
  */
 
 int
-sctp_is_there_unsent_data(struct sctp_tcb *stcb)
+sctp_is_there_unsent_data(struct sctp_tcb *stcb, int so_locked
+#if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING)
+    SCTP_UNUSED
+#endif
+)
 {
 	int unsent_data = 0;
 	unsigned int i;
@@ -242,7 +246,7 @@ sctp_is_there_unsent_data(struct sctp_tc
 					sctp_m_freem(sp->data);
 					sp->data = NULL;
 				}
-				sctp_free_a_strmoq(stcb, sp);
+				sctp_free_a_strmoq(stcb, sp, so_locked);
 			} else {
 				unsent_data++;
 				break;
@@ -301,7 +305,7 @@ sctp_process_init(struct sctp_init_chunk
 						chk->data = NULL;
 					}
 				}
-				sctp_free_a_chunk(stcb, chk);
+				sctp_free_a_chunk(stcb, chk, SCTP_SO_NOT_LOCKED);
 				/* sa_ignore FREED_MEMORY */
 			}
 		}
@@ -323,7 +327,7 @@ sctp_process_init(struct sctp_init_chunk
 						sp->net = NULL;
 					}
 					/* Free the chunk */
-					sctp_free_a_strmoq(stcb, sp);
+					sctp_free_a_strmoq(stcb, sp, SCTP_SO_NOT_LOCKED);
 					/* sa_ignore FREED_MEMORY */
 				}
 			}
@@ -902,7 +906,7 @@ sctp_handle_shutdown(struct sctp_shutdow
 		sctp_timer_stop(SCTP_TIMER_TYPE_SHUTDOWN, stcb->sctp_ep, stcb, net, SCTP_FROM_SCTP_INPUT + SCTP_LOC_8);
 	}
 	/* Now is there unsent data on a stream somewhere? */
-	some_on_streamwheel = sctp_is_there_unsent_data(stcb);
+	some_on_streamwheel = sctp_is_there_unsent_data(stcb, SCTP_SO_NOT_LOCKED);
 
 	if (!TAILQ_EMPTY(&asoc->send_queue) ||
 	    !TAILQ_EMPTY(&asoc->sent_queue) ||
@@ -3127,7 +3131,7 @@ sctp_handle_ecn_cwr(struct sctp_cwr_chun
 				chk->data = NULL;
 			}
 			stcb->asoc.ctrl_queue_cnt--;
-			sctp_free_a_chunk(stcb, chk);
+			sctp_free_a_chunk(stcb, chk, SCTP_SO_NOT_LOCKED);
 			if (override == 0) {
 				break;
 			}
@@ -3367,7 +3371,7 @@ process_chunk_drop(struct sctp_tcb *stcb
 	case SCTP_SELECTIVE_ACK:
 	case SCTP_NR_SELECTIVE_ACK:
 		/* resend the sack */
-		sctp_send_sack(stcb);
+		sctp_send_sack(stcb, SCTP_SO_NOT_LOCKED);
 		break;
 	case SCTP_HEARTBEAT_REQUEST:
 		/* resend a demand HB */
@@ -3376,7 +3380,7 @@ process_chunk_drop(struct sctp_tcb *stcb
 			 * Only retransmit if we KNOW we wont destroy the
 			 * tcb
 			 */
-			(void)sctp_send_hb(stcb, 1, net);
+			(void)sctp_send_hb(stcb, 1, net, SCTP_SO_NOT_LOCKED);
 		}
 		break;
 	case SCTP_SHUTDOWN:
@@ -3547,7 +3551,7 @@ sctp_clean_up_stream_reset(struct sctp_t
 		chk->data = NULL;
 	}
 	asoc->ctrl_queue_cnt--;
-	sctp_free_a_chunk(stcb, chk);
+	sctp_free_a_chunk(stcb, chk, SCTP_SO_NOT_LOCKED);
 	/* sa_ignore NO_NULL_CHK */
 	stcb->asoc.str_reset = NULL;
 }
@@ -3987,7 +3991,7 @@ strres_nochunk:
 			sctp_m_freem(chk->data);
 			chk->data = NULL;
 		}
-		sctp_free_a_chunk(stcb, chk);
+		sctp_free_a_chunk(stcb, chk, SCTP_SO_NOT_LOCKED);
 		return (ret_code);
 	}
 	SCTP_BUF_RESV_UF(chk->data, SCTP_MIN_OVERHEAD);

Modified: head/sys/netinet/sctp_input.h
==============================================================================
--- head/sys/netinet/sctp_input.h	Sun May  8 09:11:04 2011	(r221626)
+++ head/sys/netinet/sctp_input.h	Sun May  8 09:11:59 2011	(r221627)
@@ -53,7 +53,7 @@ sctp_reset_in_stream(struct sctp_tcb *st
     uint16_t * list);
 
 
-int sctp_is_there_unsent_data(struct sctp_tcb *stcb);
+int sctp_is_there_unsent_data(struct sctp_tcb *stcb, int so_locked);
 
 #endif
 #endif

Modified: head/sys/netinet/sctp_output.c
==============================================================================
--- head/sys/netinet/sctp_output.c	Sun May  8 09:11:04 2011	(r221626)
+++ head/sys/netinet/sctp_output.c	Sun May  8 09:11:59 2011	(r221627)
@@ -6178,7 +6178,7 @@ sctp_sendall_iterator(struct sctp_inpcb 
 			/* shutdown this assoc */
 			int cnt;
 
-			cnt = sctp_is_there_unsent_data(stcb);
+			cnt = sctp_is_there_unsent_data(stcb, SCTP_SO_NOT_LOCKED);
 
 			if (TAILQ_EMPTY(&asoc->send_queue) &&
 			    TAILQ_EMPTY(&asoc->sent_queue) &&
@@ -6425,7 +6425,7 @@ sctp_toss_old_cookies(struct sctp_tcb *s
 				chk->data = NULL;
 			}
 			asoc->ctrl_queue_cnt--;
-			sctp_free_a_chunk(stcb, chk);
+			sctp_free_a_chunk(stcb, chk, SCTP_SO_NOT_LOCKED);
 		}
 	}
 }
@@ -6454,7 +6454,7 @@ sctp_toss_old_asconf(struct sctp_tcb *st
 				chk->data = NULL;
 			}
 			asoc->ctrl_queue_cnt--;
-			sctp_free_a_chunk(stcb, chk);
+			sctp_free_a_chunk(stcb, chk, SCTP_SO_NOT_LOCKED);
 		}
 	}
 }
@@ -6553,7 +6553,11 @@ all_done:
 }
 
 static void
-sctp_clean_up_ctl(struct sctp_tcb *stcb, struct sctp_association *asoc)
+sctp_clean_up_ctl(struct sctp_tcb *stcb, struct sctp_association *asoc, int so_locked
+#if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING)
+    SCTP_UNUSED
+#endif
+)
 {
 	struct sctp_tmit_chunk *chk, *nchk;
 
@@ -6580,7 +6584,7 @@ sctp_clean_up_ctl(struct sctp_tcb *stcb,
 			asoc->ctrl_queue_cnt--;
 			if (chk->rec.chunk_id.id == SCTP_FORWARD_CUM_TSN)
 				asoc->fwd_tsn_cnt--;
-			sctp_free_a_chunk(stcb, chk);
+			sctp_free_a_chunk(stcb, chk, so_locked);
 		} else if (chk->rec.chunk_id.id == SCTP_STREAM_RESET) {
 			/* special handling, we must look into the param */
 			if (chk != asoc->str_reset) {
@@ -6660,7 +6664,12 @@ sctp_move_to_outqueue(struct sctp_tcb *s
     int *locked,
     int *giveup,
     int eeor_mode,
-    int *bail)
+    int *bail,
+    int so_locked
+#if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING)
+    SCTP_UNUSED
+#endif
+)
 {
 	/* Move from the stream to the send_queue keeping track of the total */
 	struct sctp_association *asoc;
@@ -6731,7 +6740,7 @@ one_more_time:
 				sctp_m_freem(sp->data);
 				sp->data = NULL;
 			}
-			sctp_free_a_strmoq(stcb, sp);
+			sctp_free_a_strmoq(stcb, sp, so_locked);
 			/* we can't be locked to it */
 			*locked = 0;
 			stcb->asoc.locked_on_sending = NULL;
@@ -6897,7 +6906,7 @@ dont_do_it:
 		chk->last_mbuf = NULL;
 		if (chk->data == NULL) {
 			sp->some_taken = some_taken;
-			sctp_free_a_chunk(stcb, chk);
+			sctp_free_a_chunk(stcb, chk, so_locked);
 			*bail = 1;
 			to_move = 0;
 			goto out_of;
@@ -7001,7 +7010,7 @@ dont_do_it:
 			atomic_add_int(&sp->length, to_move);
 			chk->data = NULL;
 			*bail = 1;
-			sctp_free_a_chunk(stcb, chk);
+			sctp_free_a_chunk(stcb, chk, so_locked);
 			to_move = 0;
 			goto out_of;
 		} else {
@@ -7018,7 +7027,7 @@ dont_do_it:
 		panic("prepend failes HELP?");
 #else
 		SCTP_PRINTF("prepend fails HELP?\n");
-		sctp_free_a_chunk(stcb, chk);
+		sctp_free_a_chunk(stcb, chk, so_locked);
 #endif
 		*bail = 1;
 		to_move = 0;
@@ -7140,7 +7149,7 @@ dont_do_it:
 			sctp_m_freem(sp->data);
 			sp->data = NULL;
 		}
-		sctp_free_a_strmoq(stcb, sp);
+		sctp_free_a_strmoq(stcb, sp, so_locked);
 
 		/* we can't be locked to it */
 		*locked = 0;
@@ -7163,7 +7172,11 @@ out_of:
 
 static void
 sctp_fill_outqueue(struct sctp_tcb *stcb,
-    struct sctp_nets *net, int frag_point, int eeor_mode, int *quit_now)
+    struct sctp_nets *net, int frag_point, int eeor_mode, int *quit_now, int so_locked
+#if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING)
+    SCTP_UNUSED
+#endif
+)
 {
 	struct sctp_association *asoc;
 	struct sctp_stream_out *strq, *strqn;
@@ -7200,7 +7213,7 @@ sctp_fill_outqueue(struct sctp_tcb *stcb
 		giveup = 0;
 		bail = 0;
 		moved_how_much = sctp_move_to_outqueue(stcb, strq, goal_mtu, frag_point, &locked,
-		    &giveup, eeor_mode, &bail);
+		    &giveup, eeor_mode, &bail, so_locked);
 		if (moved_how_much)
 			stcb->asoc.ss_functions.sctp_ss_scheduled(stcb, net, asoc, strq, moved_how_much);
 
@@ -7440,7 +7453,7 @@ nothing_to_send:
 			if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_CWND_LOGGING_ENABLE) {
 				sctp_log_cwnd(stcb, net, 4, SCTP_CWND_LOG_FILL_OUTQ_CALLED);
 			}
-			sctp_fill_outqueue(stcb, net, frag_point, eeor_mode, &quit_now);
+			sctp_fill_outqueue(stcb, net, frag_point, eeor_mode, &quit_now, so_locked);
 			if (quit_now) {
 				/* memory alloc failure */
 				no_data_chunks = 1;
@@ -8378,7 +8391,7 @@ no_data_fill:
 	} else {
 		*reason_code = 5;
 	}
-	sctp_clean_up_ctl(stcb, asoc);
+	sctp_clean_up_ctl(stcb, asoc, so_locked);
 	return (0);
 }
 
@@ -8403,7 +8416,7 @@ sctp_queue_op_err(struct sctp_tcb *stcb,
 	chk->copy_by_ref = 0;
 	SCTP_BUF_PREPEND(op_err, sizeof(struct sctp_chunkhdr), M_DONTWAIT);
 	if (op_err == NULL) {
-		sctp_free_a_chunk(stcb, chk);
+		sctp_free_a_chunk(stcb, chk, SCTP_SO_NOT_LOCKED);
 		return;
 	}
 	chk->send_size = 0;
@@ -8992,7 +9005,7 @@ sctp_chunk_retransmission(struct sctp_in
 			return (0);
 		} else {
 			/* Clean up the fwd-tsn list */
-			sctp_clean_up_ctl(stcb, asoc);
+			sctp_clean_up_ctl(stcb, asoc, so_locked);
 			return (0);
 		}
 	}
@@ -9446,7 +9459,7 @@ sctp_chunk_output(struct sctp_inpcb *inp
 	 * running, if so piggy-back the sack.
 	 */
 	if (SCTP_OS_TIMER_PENDING(&stcb->asoc.dack_timer.timer)) {
-		sctp_send_sack(stcb);
+		sctp_send_sack(stcb, so_locked);
 		(void)SCTP_OS_TIMER_STOP(&stcb->asoc.dack_timer.timer);
 	}
 	while (asoc->sent_queue_retran_cnt) {
@@ -9730,7 +9743,7 @@ send_forward_tsn(struct sctp_tcb *stcb,
 	chk->whoTo = NULL;
 	chk->data = sctp_get_mbuf_for_msg(MCLBYTES, 0, M_DONTWAIT, 1, MT_DATA);
 	if (chk->data == NULL) {
-		sctp_free_a_chunk(stcb, chk);
+		sctp_free_a_chunk(stcb, chk, SCTP_SO_NOT_LOCKED);
 		return;
 	}
 	SCTP_BUF_RESV_UF(chk->data, SCTP_MIN_OVERHEAD);
@@ -9875,7 +9888,11 @@ sctp_fill_in_rest:
 }
 
 void
-sctp_send_sack(struct sctp_tcb *stcb)
+sctp_send_sack(struct sctp_tcb *stcb, int so_locked
+#if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING)
+    SCTP_UNUSED
+#endif
+)
 {
 	/*-
 	 * Queue up a SACK or NR-SACK in the control queue.
@@ -10017,7 +10034,7 @@ sctp_send_sack(struct sctp_tcb *stcb)
 			sctp_m_freem(a_chk->data);
 			a_chk->data = NULL;
 		}
-		sctp_free_a_chunk(stcb, a_chk);
+		sctp_free_a_chunk(stcb, a_chk, so_locked);
 		/* sa_ignore NO_NULL_CHK */
 		if (stcb->asoc.delayed_ack) {
 			sctp_timer_stop(SCTP_TIMER_TYPE_RECV,
@@ -10691,7 +10708,11 @@ sctp_select_hb_destination(struct sctp_t
 }
 
 int
-sctp_send_hb(struct sctp_tcb *stcb, int user_req, struct sctp_nets *u_net)
+sctp_send_hb(struct sctp_tcb *stcb, int user_req, struct sctp_nets *u_net, int so_locked
+#if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING)
+    SCTP_UNUSED
+#endif
+)
 {
 	struct sctp_tmit_chunk *chk;
 	struct sctp_nets *net;
@@ -10747,7 +10768,7 @@ sctp_send_hb(struct sctp_tcb *stcb, int 
 
 	chk->data = sctp_get_mbuf_for_msg(chk->send_size, 0, M_DONTWAIT, 1, MT_HEADER);
 	if (chk->data == NULL) {
-		sctp_free_a_chunk(stcb, chk);
+		sctp_free_a_chunk(stcb, chk, so_locked);
 		return (0);
 	}
 	SCTP_BUF_RESV_UF(chk->data, SCTP_MIN_OVERHEAD);
@@ -10836,7 +10857,7 @@ sctp_send_hb(struct sctp_tcb *stcb, int 
 				sctp_free_remote_addr(chk->whoTo);
 				chk->whoTo = NULL;
 			}
-			sctp_free_a_chunk((struct sctp_tcb *)NULL, chk);
+			sctp_free_a_chunk((struct sctp_tcb *)NULL, chk, so_locked);
 			return (-1);
 		}
 	}
@@ -10892,7 +10913,7 @@ sctp_send_ecn_echo(struct sctp_tcb *stcb
 	chk->send_size = sizeof(struct sctp_ecne_chunk);
 	chk->data = sctp_get_mbuf_for_msg(chk->send_size, 0, M_DONTWAIT, 1, MT_HEADER);
 	if (chk->data == NULL) {
-		sctp_free_a_chunk(stcb, chk);
+		sctp_free_a_chunk(stcb, chk, SCTP_SO_NOT_LOCKED);
 		return;
 	}
 	SCTP_BUF_RESV_UF(chk->data, SCTP_MIN_OVERHEAD);
@@ -10955,7 +10976,7 @@ sctp_send_packet_dropped(struct sctp_tcb
 	chk->copy_by_ref = 0;
 	iph = mtod(m, struct ip *);
 	if (iph == NULL) {
-		sctp_free_a_chunk(stcb, chk);
+		sctp_free_a_chunk(stcb, chk, SCTP_SO_NOT_LOCKED);
 		return;
 	}
 	switch (iph->ip_v) {
@@ -10995,7 +11016,7 @@ sctp_send_packet_dropped(struct sctp_tcb
 			 * INIT-ACK, because we can't know if the initiation
 			 * tag is correct or not.
 			 */
-			sctp_free_a_chunk(stcb, chk);
+			sctp_free_a_chunk(stcb, chk, SCTP_SO_NOT_LOCKED);
 			return;
 		default:
 			break;
@@ -11018,7 +11039,7 @@ sctp_send_packet_dropped(struct sctp_tcb
 	chk->data = sctp_get_mbuf_for_msg(MCLBYTES, 0, M_DONTWAIT, 1, MT_DATA);
 	if (chk->data == NULL) {
 jump_out:
-		sctp_free_a_chunk(stcb, chk);
+		sctp_free_a_chunk(stcb, chk, SCTP_SO_NOT_LOCKED);
 		return;
 	}
 	SCTP_BUF_RESV_UF(chk->data, SCTP_MIN_OVERHEAD);
@@ -11129,7 +11150,7 @@ sctp_send_cwr(struct sctp_tcb *stcb, str
 	chk->send_size = sizeof(struct sctp_cwr_chunk);
 	chk->data = sctp_get_mbuf_for_msg(chk->send_size, 0, M_DONTWAIT, 1, MT_HEADER);
 	if (chk->data == NULL) {
-		sctp_free_a_chunk(stcb, chk);
+		sctp_free_a_chunk(stcb, chk, SCTP_SO_NOT_LOCKED);
 		return;
 	}
 	SCTP_BUF_RESV_UF(chk->data, SCTP_MIN_OVERHEAD);
@@ -11418,7 +11439,7 @@ sctp_send_str_reset_req(struct sctp_tcb 
 
 	chk->data = sctp_get_mbuf_for_msg(MCLBYTES, 0, M_DONTWAIT, 1, MT_DATA);
 	if (chk->data == NULL) {
-		sctp_free_a_chunk(stcb, chk);
+		sctp_free_a_chunk(stcb, chk, SCTP_SO_LOCKED);
 		SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTP_OUTPUT, ENOMEM);
 		return (ENOMEM);
 	}
@@ -12108,7 +12129,7 @@ sctp_copy_it_in(struct sctp_tcb *stcb,
 	*error = sctp_copy_one(sp, uio, resv_in_first);
 skip_copy:
 	if (*error) {
-		sctp_free_a_strmoq(stcb, sp);
+		sctp_free_a_strmoq(stcb, sp, SCTP_SO_LOCKED);
 		sp = NULL;
 	} else {
 		if (sp->sinfo_flags & SCTP_ADDR_OVER) {
@@ -13206,7 +13227,7 @@ dataless_eof:
 			SCTP_TCB_LOCK(stcb);
 			hold_tcblock = 1;
 		}
-		cnt = sctp_is_there_unsent_data(stcb);
+		cnt = sctp_is_there_unsent_data(stcb, SCTP_SO_LOCKED);
 		if (TAILQ_EMPTY(&asoc->send_queue) &&
 		    TAILQ_EMPTY(&asoc->sent_queue) &&
 		    (cnt == 0)) {

Modified: head/sys/netinet/sctp_output.h
==============================================================================
--- head/sys/netinet/sctp_output.h	Sun May  8 09:11:04 2011	(r221626)
+++ head/sys/netinet/sctp_output.h	Sun May  8 09:11:59 2011	(r221627)
@@ -152,9 +152,9 @@ sctp_send_abort_tcb(struct sctp_tcb *, s
 
 void send_forward_tsn(struct sctp_tcb *, struct sctp_association *);
 
-void sctp_send_sack(struct sctp_tcb *);
+void sctp_send_sack(struct sctp_tcb *, int);
 
-int sctp_send_hb(struct sctp_tcb *, int, struct sctp_nets *);
+int sctp_send_hb(struct sctp_tcb *, int, struct sctp_nets *, int);
 
 void sctp_send_ecn_echo(struct sctp_tcb *, struct sctp_nets *, uint32_t);
 

Modified: head/sys/netinet/sctp_pcb.c
==============================================================================
--- head/sys/netinet/sctp_pcb.c	Sun May  8 09:11:04 2011	(r221626)
+++ head/sys/netinet/sctp_pcb.c	Sun May  8 09:11:59 2011	(r221627)
@@ -4988,7 +4988,7 @@ sctp_free_assoc(struct sctp_inpcb *inp, 
 			}
 			sctp_free_spbufspace(stcb, asoc, sp);
 			if (sp->holds_key_ref)
-				sctp_auth_key_release(stcb, sp->auth_keyid);
+				sctp_auth_key_release(stcb, sp->auth_keyid, SCTP_SO_LOCKED);
 			/* Free the zone stuff  */
 			SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_strmoq), sp);
 			SCTP_DECR_STRMOQ_COUNT();
@@ -5021,7 +5021,7 @@ sctp_free_assoc(struct sctp_inpcb *inp, 
 			chk->data = NULL;
 		}
 		if (chk->holds_key_ref)
-			sctp_auth_key_release(stcb, chk->auth_keyid);
+			sctp_auth_key_release(stcb, chk->auth_keyid, SCTP_SO_LOCKED);
 		SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_chunk), chk);
 		SCTP_DECR_CHK_COUNT();
 		atomic_subtract_int(&SCTP_BASE_INFO(ipi_free_chunks), 1);
@@ -5043,7 +5043,7 @@ sctp_free_assoc(struct sctp_inpcb *inp, 
 			}
 		}
 		if (chk->holds_key_ref)
-			sctp_auth_key_release(stcb, chk->auth_keyid);
+			sctp_auth_key_release(stcb, chk->auth_keyid, SCTP_SO_LOCKED);
 		if (chk->whoTo) {
 			sctp_free_remote_addr(chk->whoTo);
 			chk->whoTo = NULL;
@@ -5067,7 +5067,7 @@ sctp_free_assoc(struct sctp_inpcb *inp, 
 			}
 		}
 		if (chk->holds_key_ref)
-			sctp_auth_key_release(stcb, chk->auth_keyid);
+			sctp_auth_key_release(stcb, chk->auth_keyid, SCTP_SO_LOCKED);
 		sctp_free_remote_addr(chk->whoTo);
 		SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_chunk), chk);
 		SCTP_DECR_CHK_COUNT();
@@ -5081,7 +5081,7 @@ sctp_free_assoc(struct sctp_inpcb *inp, 
 			chk->data = NULL;
 		}
 		if (chk->holds_key_ref)
-			sctp_auth_key_release(stcb, chk->auth_keyid);
+			sctp_auth_key_release(stcb, chk->auth_keyid, SCTP_SO_LOCKED);
 		sctp_free_remote_addr(chk->whoTo);
 		SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_chunk), chk);
 		SCTP_DECR_CHK_COUNT();
@@ -5095,7 +5095,7 @@ sctp_free_assoc(struct sctp_inpcb *inp, 
 			chk->data = NULL;
 		}
 		if (chk->holds_key_ref)
-			sctp_auth_key_release(stcb, chk->auth_keyid);
+			sctp_auth_key_release(stcb, chk->auth_keyid, SCTP_SO_LOCKED);
 		sctp_free_remote_addr(chk->whoTo);
 		SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_chunk), chk);
 		SCTP_DECR_CHK_COUNT();
@@ -5108,7 +5108,7 @@ sctp_free_assoc(struct sctp_inpcb *inp, 
 			chk->data = NULL;
 		}
 		if (chk->holds_key_ref)
-			sctp_auth_key_release(stcb, chk->auth_keyid);
+			sctp_auth_key_release(stcb, chk->auth_keyid, SCTP_SO_LOCKED);
 		sctp_free_remote_addr(chk->whoTo);
 		SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_chunk), chk);
 		SCTP_DECR_CHK_COUNT();
@@ -6895,7 +6895,7 @@ sctp_drain_mbufs(struct sctp_inpcb *inp,
 				sctp_m_freem(chk->data);
 				chk->data = NULL;
 			}
-			sctp_free_a_chunk(stcb, chk);
+			sctp_free_a_chunk(stcb, chk, SCTP_SO_NOT_LOCKED);
 		}
 	}
 	/* Ok that was fun, now we will drain all the inbound streams? */
@@ -6958,7 +6958,7 @@ sctp_drain_mbufs(struct sctp_inpcb *inp,
 		asoc->last_revoke_count = cnt;
 		(void)SCTP_OS_TIMER_STOP(&stcb->asoc.dack_timer.timer);
 		/* sa_ignore NO_NULL_CHK */
-		sctp_send_sack(stcb);
+		sctp_send_sack(stcb, SCTP_SO_NOT_LOCKED);
 		sctp_chunk_output(stcb->sctp_ep, stcb, SCTP_OUTPUT_FROM_DRAIN, SCTP_SO_NOT_LOCKED);
 		reneged_asoc_ids[reneged_at] = sctp_get_associd(stcb);
 		reneged_at++;

Modified: head/sys/netinet/sctp_timer.c
==============================================================================
--- head/sys/netinet/sctp_timer.c	Sun May  8 09:11:04 2011	(r221626)
+++ head/sys/netinet/sctp_timer.c	Sun May  8 09:11:59 2011	(r221627)
@@ -597,7 +597,7 @@ sctp_recover_sent_list(struct sctp_tcb *
 				}
 			}
 			asoc->sent_queue_cnt--;
-			sctp_free_a_chunk(stcb, chk);
+			sctp_free_a_chunk(stcb, chk, SCTP_SO_NOT_LOCKED);
 		}
 	}
 	SCTP_PRINTF("after recover order is as follows\n");
@@ -1056,7 +1056,7 @@ sctp_t3rxt_timer(struct sctp_inpcb *inp,
 					 * no recent feed back in an RTO or
 					 * more, request a RTT update
 					 */
-					if (sctp_send_hb(stcb, 1, net) < 0)
+					if (sctp_send_hb(stcb, 1, net, SCTP_SO_NOT_LOCKED) < 0)
 						/*
 						 * Less than 0 means we lost
 						 * the assoc
@@ -1120,7 +1120,7 @@ sctp_t3rxt_timer(struct sctp_inpcb *inp,
 		 * but is in PF state, a PF-heartbeat needs to be sent
 		 * manually.
 		 */
-		if (sctp_send_hb(stcb, 1, net) < 0)
+		if (sctp_send_hb(stcb, 1, net, SCTP_SO_NOT_LOCKED) < 0)
 			/* Return less than 0 means we lost the association */
 			return (1);
 	}
@@ -1598,7 +1598,7 @@ sctp_heartbeat_timer(struct sctp_inpcb *
 	}
 	/* Send a new HB, this will do threshold managment, pick a new dest */
 	if (cnt_of_unconf == 0) {
-		if (sctp_send_hb(stcb, 0, NULL) < 0) {
+		if (sctp_send_hb(stcb, 0, NULL, SCTP_SO_NOT_LOCKED) < 0) {
 			return (1);
 		}
 	} else {
@@ -1620,7 +1620,7 @@ sctp_heartbeat_timer(struct sctp_inpcb *
 						net->src_addr_selected = 0;
 					}
 				}
-				ret = sctp_send_hb(stcb, 1, net);
+				ret = sctp_send_hb(stcb, 1, net, SCTP_SO_NOT_LOCKED);
 				if (ret < 0)
 					return 1;
 				else if (ret == 0) {

Modified: head/sys/netinet/sctp_usrreq.c
==============================================================================
--- head/sys/netinet/sctp_usrreq.c	Sun May  8 09:11:04 2011	(r221626)
+++ head/sys/netinet/sctp_usrreq.c	Sun May  8 09:11:59 2011	(r221627)
@@ -3997,7 +3997,7 @@ sctp_setopt(struct socket *so, int optna
 					/************************NET SPECIFIC SET ******************/
 					if (paddrp->spp_flags & SPP_HB_DEMAND) {
 						/* on demand HB */
-						if (sctp_send_hb(stcb, 1, net) < 0) {
+						if (sctp_send_hb(stcb, 1, net, SCTP_SO_LOCKED) < 0) {
 							/* asoc destroyed */
 							SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
 							error = EINVAL;

Modified: head/sys/netinet/sctp_var.h
==============================================================================
--- head/sys/netinet/sctp_var.h	Sun May  8 09:11:04 2011	(r221626)
+++ head/sys/netinet/sctp_var.h	Sun May  8 09:11:59 2011	(r221627)
@@ -87,9 +87,9 @@ extern struct pr_usrreqs sctp_usrreqs;
 	} \
 }
 
-#define sctp_free_a_strmoq(_stcb, _strmoq) { \
+#define sctp_free_a_strmoq(_stcb, _strmoq, _so_locked) { \
 	if ((_strmoq)->holds_key_ref) { \
-		sctp_auth_key_release(stcb, sp->auth_keyid); \
+		sctp_auth_key_release(stcb, sp->auth_keyid, _so_locked); \
 		(_strmoq)->holds_key_ref = 0; \
 	} \
 	SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_strmoq), (_strmoq)); \
@@ -105,9 +105,9 @@ extern struct pr_usrreqs sctp_usrreqs;
  	} \
 }
 
-#define sctp_free_a_chunk(_stcb, _chk) { \
+#define sctp_free_a_chunk(_stcb, _chk, _so_locked) { \
 	if ((_chk)->holds_key_ref) {\
-		sctp_auth_key_release((_stcb), (_chk)->auth_keyid); \
+		sctp_auth_key_release((_stcb), (_chk)->auth_keyid, _so_locked); \
 		(_chk)->holds_key_ref = 0; \
 	} \
         if (_stcb) { \

Modified: head/sys/netinet/sctputil.c
==============================================================================
--- head/sys/netinet/sctputil.c	Sun May  8 09:11:04 2011	(r221626)
+++ head/sys/netinet/sctputil.c	Sun May  8 09:11:59 2011	(r221627)
@@ -1634,7 +1634,7 @@ sctp_timeout_handler(void *t)
 		} {
 			SCTP_STAT_INCR(sctps_timosack);
 			stcb->asoc.timosack++;
-			sctp_send_sack(stcb);
+			sctp_send_sack(stcb, SCTP_SO_NOT_LOCKED);
 		}
 #ifdef SCTP_AUDITING_ENABLED
 		sctp_auditing(4, inp, stcb, net);
@@ -3656,7 +3656,7 @@ sctp_report_all_outbound(struct sctp_tcb
 				chk->data = NULL;
 			}
 		}
-		sctp_free_a_chunk(stcb, chk);
+		sctp_free_a_chunk(stcb, chk, so_locked);
 		/* sa_ignore FREED_MEMORY */
 	}
 	/* pending send queue SHOULD be empty */
@@ -3672,7 +3672,7 @@ sctp_report_all_outbound(struct sctp_tcb
 				chk->data = NULL;
 			}
 		}
-		sctp_free_a_chunk(stcb, chk);
+		sctp_free_a_chunk(stcb, chk, so_locked);
 		/* sa_ignore FREED_MEMORY */
 	}
 	for (i = 0; i < asoc->streamoutcnt; i++) {
@@ -3697,7 +3697,7 @@ sctp_report_all_outbound(struct sctp_tcb
 				sp->net = NULL;
 			}
 			/* Free the chunk */
-			sctp_free_a_strmoq(stcb, sp);
+			sctp_free_a_strmoq(stcb, sp, so_locked);
 			/* sa_ignore FREED_MEMORY */
 		}
 	}
@@ -5033,7 +5033,7 @@ sctp_user_rcvd(struct sctp_tcb *stcb, ui
 			goto out;
 		}
 		SCTP_STAT_INCR(sctps_wu_sacks_sent);
-		sctp_send_sack(stcb);
+		sctp_send_sack(stcb, SCTP_SO_LOCKED);
 
 		sctp_chunk_output(stcb->sctp_ep, stcb,
 		    SCTP_OUTPUT_FROM_USR_RCVD, SCTP_SO_LOCKED);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201105080911.p489BxTW037814>