mirror of
https://git.FreeBSD.org/src.git
synced 2025-01-19 15:33:56 +00:00
sctp: get rid of stcb send lock
Just use the stcb lock instead to simplify locking. Reported by: syzbot+d00b202063150f85b110@syzkaller.appspotmail.com Reported by: syzbot+87f268a0a6d2d6383306@syzkaller.appspotmail.com MFC after: 3 days
This commit is contained in:
parent
c1970a7eba
commit
5ac91821f5
@ -179,6 +179,8 @@ sctp_is_there_unsent_data(struct sctp_tcb *stcb, int so_locked)
|
||||
struct sctp_stream_queue_pending *sp;
|
||||
struct sctp_association *asoc;
|
||||
|
||||
SCTP_TCB_LOCK_ASSERT(stcb);
|
||||
|
||||
/*
|
||||
* This function returns if any stream has true unsent data on it.
|
||||
* Note that as it looks through it will clean up any places that
|
||||
@ -186,7 +188,6 @@ sctp_is_there_unsent_data(struct sctp_tcb *stcb, int so_locked)
|
||||
*/
|
||||
asoc = &stcb->asoc;
|
||||
unsent_data = 0;
|
||||
SCTP_TCB_SEND_LOCK(stcb);
|
||||
if (!stcb->asoc.ss_functions.sctp_ss_is_empty(stcb, asoc)) {
|
||||
/* Check to see if some data queued */
|
||||
for (i = 0; i < stcb->asoc.streamoutcnt; i++) {
|
||||
@ -234,7 +235,6 @@ sctp_is_there_unsent_data(struct sctp_tcb *stcb, int so_locked)
|
||||
}
|
||||
}
|
||||
}
|
||||
SCTP_TCB_SEND_UNLOCK(stcb);
|
||||
return (unsent_data);
|
||||
}
|
||||
|
||||
@ -246,6 +246,8 @@ sctp_process_init(struct sctp_init_chunk *cp, struct sctp_tcb *stcb)
|
||||
struct sctp_nets *lnet;
|
||||
unsigned int i;
|
||||
|
||||
SCTP_TCB_LOCK_ASSERT(stcb);
|
||||
|
||||
init = &cp->init;
|
||||
asoc = &stcb->asoc;
|
||||
/* save off parameters */
|
||||
@ -263,7 +265,6 @@ sctp_process_init(struct sctp_init_chunk *cp, struct sctp_tcb *stcb)
|
||||
}
|
||||
}
|
||||
}
|
||||
SCTP_TCB_SEND_LOCK(stcb);
|
||||
if (asoc->pre_open_streams > ntohs(init->num_inbound_streams)) {
|
||||
unsigned int newcnt;
|
||||
struct sctp_stream_out *outs;
|
||||
@ -323,7 +324,6 @@ sctp_process_init(struct sctp_init_chunk *cp, struct sctp_tcb *stcb)
|
||||
/* cut back the count */
|
||||
asoc->pre_open_streams = newcnt;
|
||||
}
|
||||
SCTP_TCB_SEND_UNLOCK(stcb);
|
||||
asoc->streamoutcnt = asoc->pre_open_streams;
|
||||
if (asoc->strmout) {
|
||||
for (i = 0; i < asoc->streamoutcnt; i++) {
|
||||
@ -1808,8 +1808,6 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset,
|
||||
SCTP_TCB_LOCK(stcb);
|
||||
atomic_subtract_int(&stcb->asoc.refcnt, 1);
|
||||
/* send up all the data */
|
||||
SCTP_TCB_SEND_LOCK(stcb);
|
||||
|
||||
sctp_report_all_outbound(stcb, 0, SCTP_SO_LOCKED);
|
||||
for (i = 0; i < stcb->asoc.streamoutcnt; i++) {
|
||||
stcb->asoc.strmout[i].chunks_on_queues = 0;
|
||||
@ -1896,7 +1894,6 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset,
|
||||
*/
|
||||
LIST_INSERT_HEAD(head, stcb, sctp_asocs);
|
||||
|
||||
SCTP_TCB_SEND_UNLOCK(stcb);
|
||||
SCTP_INP_WUNLOCK(stcb->sctp_ep);
|
||||
SCTP_INP_INFO_WUNLOCK();
|
||||
asoc->total_flight = 0;
|
||||
|
@ -337,28 +337,6 @@ __FBSDID("$FreeBSD$");
|
||||
#define SCTP_ASOC_CREATE_LOCK_CONTENDED(_inp) \
|
||||
((_inp)->inp_create_mtx.mtx_lock & MTX_CONTESTED)
|
||||
|
||||
#define SCTP_TCB_SEND_LOCK_INIT(_tcb) do { \
|
||||
mtx_init(&(_tcb)->tcb_send_mtx, "sctp-send-tcb", "tcbs", \
|
||||
MTX_DEF | MTX_DUPOK); \
|
||||
} while (0)
|
||||
|
||||
#define SCTP_TCB_SEND_LOCK_DESTROY(_tcb) do { \
|
||||
mtx_destroy(&(_tcb)->tcb_send_mtx); \
|
||||
} while (0)
|
||||
|
||||
#define SCTP_TCB_SEND_LOCK(_tcb) do { \
|
||||
mtx_lock(&(_tcb)->tcb_send_mtx); \
|
||||
} while (0)
|
||||
|
||||
#define SCTP_TCB_SEND_UNLOCK(_tcb) do { \
|
||||
mtx_unlock(&(_tcb)->tcb_send_mtx); \
|
||||
} while (0)
|
||||
|
||||
#define SCTP_TCB_SEND_LOCK_ASSERT(_tcb) do { \
|
||||
KASSERT(mtx_owned(&(_tcb)->tcb_send_mtx), \
|
||||
("Don't own TCB send lock")); \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* For the majority of things (once we have found the association) we will
|
||||
* lock the actual association mutex. This will protect all the assoiciation
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -4326,7 +4326,6 @@ sctp_aloc_assoc_locked(struct sctp_inpcb *inp, struct sockaddr *firstaddr,
|
||||
asoc = &stcb->asoc;
|
||||
|
||||
SCTP_TCB_LOCK_INIT(stcb);
|
||||
SCTP_TCB_SEND_LOCK_INIT(stcb);
|
||||
stcb->rport = rport;
|
||||
/* setup back pointer's */
|
||||
stcb->sctp_ep = inp;
|
||||
@ -4334,7 +4333,6 @@ sctp_aloc_assoc_locked(struct sctp_inpcb *inp, struct sockaddr *firstaddr,
|
||||
if ((err = sctp_init_asoc(inp, stcb, override_tag, initial_tsn, vrf_id, o_streams))) {
|
||||
/* failed */
|
||||
SCTP_TCB_LOCK_DESTROY(stcb);
|
||||
SCTP_TCB_SEND_LOCK_DESTROY(stcb);
|
||||
SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_asoc), stcb);
|
||||
SCTP_DECR_ASOC_COUNT();
|
||||
*error = err;
|
||||
@ -4365,7 +4363,6 @@ sctp_aloc_assoc_locked(struct sctp_inpcb *inp, struct sockaddr *firstaddr,
|
||||
SCTP_DECR_ASOC_COUNT();
|
||||
SCTP_TCB_UNLOCK(stcb);
|
||||
SCTP_TCB_LOCK_DESTROY(stcb);
|
||||
SCTP_TCB_SEND_LOCK_DESTROY(stcb);
|
||||
LIST_REMOVE(stcb, sctp_asocs);
|
||||
LIST_REMOVE(stcb, sctp_tcbasocidhash);
|
||||
SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_asoc), stcb);
|
||||
@ -4702,6 +4699,7 @@ sctp_free_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int from_inpcbfre
|
||||
struct socket *so;
|
||||
|
||||
/* first, lets purge the entry from the hash table. */
|
||||
SCTP_TCB_LOCK_ASSERT(stcb);
|
||||
|
||||
#ifdef SCTP_LOG_CLOSING
|
||||
sctp_log_closing(inp, stcb, 6);
|
||||
@ -4713,7 +4711,6 @@ sctp_free_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int from_inpcbfre
|
||||
/* there is no asoc, really TSNH :-0 */
|
||||
return (1);
|
||||
}
|
||||
SCTP_TCB_SEND_LOCK(stcb);
|
||||
if (stcb->asoc.alternate) {
|
||||
sctp_free_remote_addr(stcb->asoc.alternate);
|
||||
stcb->asoc.alternate = NULL;
|
||||
@ -4748,7 +4745,6 @@ sctp_free_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int from_inpcbfre
|
||||
/* nope, reader or writer in the way */
|
||||
sctp_timer_start(SCTP_TIMER_TYPE_ASOCKILL, inp, stcb, NULL);
|
||||
/* no asoc destroyed */
|
||||
SCTP_TCB_SEND_UNLOCK(stcb);
|
||||
SCTP_TCB_UNLOCK(stcb);
|
||||
#ifdef SCTP_LOG_CLOSING
|
||||
sctp_log_closing(inp, stcb, 8);
|
||||
@ -4826,7 +4822,6 @@ sctp_free_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int from_inpcbfre
|
||||
sctp_sorwakeup(inp, so);
|
||||
sctp_sowwakeup(inp, so);
|
||||
}
|
||||
SCTP_TCB_SEND_UNLOCK(stcb);
|
||||
SCTP_TCB_UNLOCK(stcb);
|
||||
|
||||
#ifdef SCTP_LOG_CLOSING
|
||||
@ -4851,12 +4846,10 @@ sctp_free_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int from_inpcbfre
|
||||
if (from_inpcbfree == SCTP_NORMAL_PROC) {
|
||||
atomic_add_int(&stcb->asoc.refcnt, 1);
|
||||
|
||||
SCTP_TCB_SEND_UNLOCK(stcb);
|
||||
SCTP_TCB_UNLOCK(stcb);
|
||||
SCTP_INP_INFO_WLOCK();
|
||||
SCTP_INP_WLOCK(inp);
|
||||
SCTP_TCB_LOCK(stcb);
|
||||
SCTP_TCB_SEND_LOCK(stcb);
|
||||
}
|
||||
/* Double check the GONE flag */
|
||||
if ((inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) ||
|
||||
@ -4904,7 +4897,6 @@ sctp_free_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int from_inpcbfre
|
||||
SCTP_INP_INFO_WUNLOCK();
|
||||
SCTP_INP_WUNLOCK(inp);
|
||||
}
|
||||
SCTP_TCB_SEND_UNLOCK(stcb);
|
||||
SCTP_TCB_UNLOCK(stcb);
|
||||
return (0);
|
||||
}
|
||||
@ -5169,10 +5161,8 @@ sctp_free_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int from_inpcbfre
|
||||
/* Insert new items here :> */
|
||||
|
||||
/* Get rid of LOCK */
|
||||
SCTP_TCB_SEND_UNLOCK(stcb);
|
||||
SCTP_TCB_UNLOCK(stcb);
|
||||
SCTP_TCB_LOCK_DESTROY(stcb);
|
||||
SCTP_TCB_SEND_LOCK_DESTROY(stcb);
|
||||
if (from_inpcbfree == SCTP_NORMAL_PROC) {
|
||||
SCTP_INP_INFO_WUNLOCK();
|
||||
SCTP_INP_RLOCK(inp);
|
||||
|
@ -53,7 +53,7 @@ sctp_ss_default_init(struct sctp_tcb *stcb, struct sctp_association *asoc)
|
||||
{
|
||||
uint16_t i;
|
||||
|
||||
SCTP_TCB_SEND_LOCK_ASSERT(stcb);
|
||||
SCTP_TCB_LOCK_ASSERT(stcb);
|
||||
|
||||
asoc->ss_data.locked_on_sending = NULL;
|
||||
asoc->ss_data.last_out_stream = NULL;
|
||||
@ -75,7 +75,7 @@ static void
|
||||
sctp_ss_default_clear(struct sctp_tcb *stcb, struct sctp_association *asoc,
|
||||
bool clear_values SCTP_UNUSED)
|
||||
{
|
||||
SCTP_TCB_SEND_LOCK_ASSERT(stcb);
|
||||
SCTP_TCB_LOCK_ASSERT(stcb);
|
||||
|
||||
while (!TAILQ_EMPTY(&asoc->ss_data.out.wheel)) {
|
||||
struct sctp_stream_out *strq;
|
||||
@ -92,6 +92,8 @@ sctp_ss_default_clear(struct sctp_tcb *stcb, struct sctp_association *asoc,
|
||||
static void
|
||||
sctp_ss_default_init_stream(struct sctp_tcb *stcb, struct sctp_stream_out *strq, struct sctp_stream_out *with_strq)
|
||||
{
|
||||
SCTP_TCB_LOCK_ASSERT(stcb);
|
||||
|
||||
if (with_strq != NULL) {
|
||||
if (stcb->asoc.ss_data.locked_on_sending == with_strq) {
|
||||
stcb->asoc.ss_data.locked_on_sending = strq;
|
||||
@ -109,7 +111,7 @@ sctp_ss_default_add(struct sctp_tcb *stcb, struct sctp_association *asoc,
|
||||
struct sctp_stream_out *strq,
|
||||
struct sctp_stream_queue_pending *sp SCTP_UNUSED)
|
||||
{
|
||||
SCTP_TCB_SEND_LOCK_ASSERT(stcb);
|
||||
SCTP_TCB_LOCK_ASSERT(stcb);
|
||||
|
||||
/* Add to wheel if not already on it and stream queue not empty */
|
||||
if (!TAILQ_EMPTY(&strq->outqueue) && !strq->ss_params.scheduled) {
|
||||
@ -123,6 +125,8 @@ sctp_ss_default_add(struct sctp_tcb *stcb, struct sctp_association *asoc,
|
||||
static bool
|
||||
sctp_ss_default_is_empty(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_association *asoc)
|
||||
{
|
||||
SCTP_TCB_LOCK_ASSERT(stcb);
|
||||
|
||||
return (TAILQ_EMPTY(&asoc->ss_data.out.wheel));
|
||||
}
|
||||
|
||||
@ -131,7 +135,7 @@ sctp_ss_default_remove(struct sctp_tcb *stcb, struct sctp_association *asoc,
|
||||
struct sctp_stream_out *strq,
|
||||
struct sctp_stream_queue_pending *sp SCTP_UNUSED)
|
||||
{
|
||||
SCTP_TCB_SEND_LOCK_ASSERT(stcb);
|
||||
SCTP_TCB_LOCK_ASSERT(stcb);
|
||||
|
||||
/*
|
||||
* Remove from wheel if stream queue is empty and actually is on the
|
||||
@ -165,6 +169,8 @@ sctp_ss_default_select(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_nets *net,
|
||||
{
|
||||
struct sctp_stream_out *strq, *strqt;
|
||||
|
||||
SCTP_TCB_LOCK_ASSERT(stcb);
|
||||
|
||||
if (asoc->ss_data.locked_on_sending != NULL) {
|
||||
KASSERT(asoc->ss_data.locked_on_sending->ss_params.scheduled,
|
||||
("locked_on_sending %p not scheduled",
|
||||
@ -223,6 +229,8 @@ sctp_ss_default_scheduled(struct sctp_tcb *stcb,
|
||||
|
||||
KASSERT(strq != NULL, ("strq is NULL"));
|
||||
KASSERT(strq->ss_params.scheduled, ("strq %p is not scheduled", (void *)strq));
|
||||
SCTP_TCB_LOCK_ASSERT(stcb);
|
||||
|
||||
asoc->ss_data.last_out_stream = strq;
|
||||
if (asoc->idata_supported == 0) {
|
||||
sp = TAILQ_FIRST(&strq->outqueue);
|
||||
@ -241,6 +249,8 @@ static void
|
||||
sctp_ss_default_packet_done(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_nets *net SCTP_UNUSED,
|
||||
struct sctp_association *asoc SCTP_UNUSED)
|
||||
{
|
||||
SCTP_TCB_LOCK_ASSERT(stcb);
|
||||
|
||||
/* Nothing to be done here */
|
||||
return;
|
||||
}
|
||||
@ -249,6 +259,8 @@ static int
|
||||
sctp_ss_default_get_value(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_association *asoc SCTP_UNUSED,
|
||||
struct sctp_stream_out *strq SCTP_UNUSED, uint16_t *value SCTP_UNUSED)
|
||||
{
|
||||
SCTP_TCB_LOCK_ASSERT(stcb);
|
||||
|
||||
/* Nothing to be done here */
|
||||
return (-1);
|
||||
}
|
||||
@ -257,6 +269,8 @@ static int
|
||||
sctp_ss_default_set_value(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_association *asoc SCTP_UNUSED,
|
||||
struct sctp_stream_out *strq SCTP_UNUSED, uint16_t value SCTP_UNUSED)
|
||||
{
|
||||
SCTP_TCB_LOCK_ASSERT(stcb);
|
||||
|
||||
/* Nothing to be done here */
|
||||
return (-1);
|
||||
}
|
||||
@ -267,6 +281,8 @@ sctp_ss_default_is_user_msgs_incomplete(struct sctp_tcb *stcb SCTP_UNUSED, struc
|
||||
struct sctp_stream_out *strq;
|
||||
struct sctp_stream_queue_pending *sp;
|
||||
|
||||
SCTP_TCB_LOCK_ASSERT(stcb);
|
||||
|
||||
if (asoc->stream_queue_cnt != 1) {
|
||||
return (false);
|
||||
}
|
||||
@ -292,7 +308,7 @@ sctp_ss_rr_add(struct sctp_tcb *stcb, struct sctp_association *asoc,
|
||||
{
|
||||
struct sctp_stream_out *strqt;
|
||||
|
||||
SCTP_TCB_SEND_LOCK_ASSERT(stcb);
|
||||
SCTP_TCB_LOCK_ASSERT(stcb);
|
||||
|
||||
if (!TAILQ_EMPTY(&strq->outqueue) && !strq->ss_params.scheduled) {
|
||||
if (TAILQ_EMPTY(&asoc->ss_data.out.wheel)) {
|
||||
@ -322,6 +338,8 @@ static struct sctp_stream_out *
|
||||
sctp_ss_rrp_select(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_nets *net SCTP_UNUSED,
|
||||
struct sctp_association *asoc)
|
||||
{
|
||||
SCTP_TCB_LOCK_ASSERT(stcb);
|
||||
|
||||
return (asoc->ss_data.last_out_stream);
|
||||
}
|
||||
|
||||
@ -331,6 +349,8 @@ sctp_ss_rrp_packet_done(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_nets *net
|
||||
{
|
||||
struct sctp_stream_out *strq, *strqt;
|
||||
|
||||
SCTP_TCB_LOCK_ASSERT(stcb);
|
||||
|
||||
strqt = asoc->ss_data.last_out_stream;
|
||||
KASSERT(strqt == NULL || strqt->ss_params.scheduled,
|
||||
("last_out_stream %p not scheduled", (void *)strqt));
|
||||
@ -381,7 +401,7 @@ static void
|
||||
sctp_ss_prio_clear(struct sctp_tcb *stcb, struct sctp_association *asoc,
|
||||
bool clear_values)
|
||||
{
|
||||
SCTP_TCB_SEND_LOCK_ASSERT(stcb);
|
||||
SCTP_TCB_LOCK_ASSERT(stcb);
|
||||
|
||||
while (!TAILQ_EMPTY(&asoc->ss_data.out.wheel)) {
|
||||
struct sctp_stream_out *strq;
|
||||
@ -401,6 +421,8 @@ sctp_ss_prio_clear(struct sctp_tcb *stcb, struct sctp_association *asoc,
|
||||
static void
|
||||
sctp_ss_prio_init_stream(struct sctp_tcb *stcb, struct sctp_stream_out *strq, struct sctp_stream_out *with_strq)
|
||||
{
|
||||
SCTP_TCB_LOCK_ASSERT(stcb);
|
||||
|
||||
if (with_strq != NULL) {
|
||||
if (stcb->asoc.ss_data.locked_on_sending == with_strq) {
|
||||
stcb->asoc.ss_data.locked_on_sending = strq;
|
||||
@ -424,7 +446,7 @@ sctp_ss_prio_add(struct sctp_tcb *stcb, struct sctp_association *asoc,
|
||||
{
|
||||
struct sctp_stream_out *strqt;
|
||||
|
||||
SCTP_TCB_SEND_LOCK_ASSERT(stcb);
|
||||
SCTP_TCB_LOCK_ASSERT(stcb);
|
||||
|
||||
/* Add to wheel if not already on it and stream queue not empty */
|
||||
if (!TAILQ_EMPTY(&strq->outqueue) && !strq->ss_params.scheduled) {
|
||||
@ -450,7 +472,7 @@ static void
|
||||
sctp_ss_prio_remove(struct sctp_tcb *stcb, struct sctp_association *asoc,
|
||||
struct sctp_stream_out *strq, struct sctp_stream_queue_pending *sp SCTP_UNUSED)
|
||||
{
|
||||
SCTP_TCB_SEND_LOCK_ASSERT(stcb);
|
||||
SCTP_TCB_LOCK_ASSERT(stcb);
|
||||
|
||||
/*
|
||||
* Remove from wheel if stream queue is empty and actually is on the
|
||||
@ -484,6 +506,8 @@ sctp_ss_prio_select(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_nets *net,
|
||||
{
|
||||
struct sctp_stream_out *strq, *strqt, *strqn;
|
||||
|
||||
SCTP_TCB_LOCK_ASSERT(stcb);
|
||||
|
||||
if (asoc->ss_data.locked_on_sending != NULL) {
|
||||
KASSERT(asoc->ss_data.locked_on_sending->ss_params.scheduled,
|
||||
("locked_on_sending %p not scheduled",
|
||||
@ -538,6 +562,8 @@ static int
|
||||
sctp_ss_prio_get_value(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_association *asoc SCTP_UNUSED,
|
||||
struct sctp_stream_out *strq, uint16_t *value)
|
||||
{
|
||||
SCTP_TCB_LOCK_ASSERT(stcb);
|
||||
|
||||
if (strq == NULL) {
|
||||
return (-1);
|
||||
}
|
||||
@ -549,6 +575,8 @@ static int
|
||||
sctp_ss_prio_set_value(struct sctp_tcb *stcb, struct sctp_association *asoc,
|
||||
struct sctp_stream_out *strq, uint16_t value)
|
||||
{
|
||||
SCTP_TCB_LOCK_ASSERT(stcb);
|
||||
|
||||
if (strq == NULL) {
|
||||
return (-1);
|
||||
}
|
||||
@ -566,7 +594,7 @@ static void
|
||||
sctp_ss_fb_clear(struct sctp_tcb *stcb, struct sctp_association *asoc,
|
||||
bool clear_values)
|
||||
{
|
||||
SCTP_TCB_SEND_LOCK_ASSERT(stcb);
|
||||
SCTP_TCB_LOCK_ASSERT(stcb);
|
||||
|
||||
while (!TAILQ_EMPTY(&asoc->ss_data.out.wheel)) {
|
||||
struct sctp_stream_out *strq;
|
||||
@ -586,6 +614,8 @@ sctp_ss_fb_clear(struct sctp_tcb *stcb, struct sctp_association *asoc,
|
||||
static void
|
||||
sctp_ss_fb_init_stream(struct sctp_tcb *stcb, struct sctp_stream_out *strq, struct sctp_stream_out *with_strq)
|
||||
{
|
||||
SCTP_TCB_LOCK_ASSERT(stcb);
|
||||
|
||||
if (with_strq != NULL) {
|
||||
if (stcb->asoc.ss_data.locked_on_sending == with_strq) {
|
||||
stcb->asoc.ss_data.locked_on_sending = strq;
|
||||
@ -607,7 +637,7 @@ static void
|
||||
sctp_ss_fb_add(struct sctp_tcb *stcb, struct sctp_association *asoc,
|
||||
struct sctp_stream_out *strq, struct sctp_stream_queue_pending *sp SCTP_UNUSED)
|
||||
{
|
||||
SCTP_TCB_SEND_LOCK_ASSERT(stcb);
|
||||
SCTP_TCB_LOCK_ASSERT(stcb);
|
||||
|
||||
if (!TAILQ_EMPTY(&strq->outqueue) && !strq->ss_params.scheduled) {
|
||||
if (strq->ss_params.ss.fb.rounds < 0)
|
||||
@ -622,7 +652,7 @@ static void
|
||||
sctp_ss_fb_remove(struct sctp_tcb *stcb, struct sctp_association *asoc,
|
||||
struct sctp_stream_out *strq, struct sctp_stream_queue_pending *sp SCTP_UNUSED)
|
||||
{
|
||||
SCTP_TCB_SEND_LOCK_ASSERT(stcb);
|
||||
SCTP_TCB_LOCK_ASSERT(stcb);
|
||||
|
||||
/*
|
||||
* Remove from wheel if stream queue is empty and actually is on the
|
||||
@ -656,6 +686,8 @@ sctp_ss_fb_select(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_nets *net,
|
||||
{
|
||||
struct sctp_stream_out *strq = NULL, *strqt;
|
||||
|
||||
SCTP_TCB_LOCK_ASSERT(stcb);
|
||||
|
||||
if (asoc->ss_data.locked_on_sending != NULL) {
|
||||
KASSERT(asoc->ss_data.locked_on_sending->ss_params.scheduled,
|
||||
("locked_on_sending %p not scheduled",
|
||||
@ -699,6 +731,8 @@ sctp_ss_fb_scheduled(struct sctp_tcb *stcb, struct sctp_nets *net SCTP_UNUSED,
|
||||
struct sctp_stream_out *strqt;
|
||||
int subtract;
|
||||
|
||||
SCTP_TCB_LOCK_ASSERT(stcb);
|
||||
|
||||
if (asoc->idata_supported == 0) {
|
||||
sp = TAILQ_FIRST(&strq->outqueue);
|
||||
if ((sp != NULL) && (sp->some_taken == 1)) {
|
||||
@ -740,7 +774,7 @@ sctp_ss_fcfs_init(struct sctp_tcb *stcb, struct sctp_association *asoc)
|
||||
struct sctp_stream_queue_pending *sp;
|
||||
uint16_t i;
|
||||
|
||||
SCTP_TCB_SEND_LOCK_ASSERT(stcb);
|
||||
SCTP_TCB_LOCK_ASSERT(stcb);
|
||||
|
||||
TAILQ_INIT(&asoc->ss_data.out.list);
|
||||
/*
|
||||
@ -774,7 +808,7 @@ sctp_ss_fcfs_clear(struct sctp_tcb *stcb, struct sctp_association *asoc,
|
||||
{
|
||||
struct sctp_stream_queue_pending *sp;
|
||||
|
||||
SCTP_TCB_SEND_LOCK_ASSERT(stcb);
|
||||
SCTP_TCB_LOCK_ASSERT(stcb);
|
||||
|
||||
while (!TAILQ_EMPTY(&asoc->ss_data.out.list)) {
|
||||
sp = TAILQ_FIRST(&asoc->ss_data.out.list);
|
||||
@ -789,6 +823,8 @@ sctp_ss_fcfs_clear(struct sctp_tcb *stcb, struct sctp_association *asoc,
|
||||
static void
|
||||
sctp_ss_fcfs_init_stream(struct sctp_tcb *stcb, struct sctp_stream_out *strq, struct sctp_stream_out *with_strq)
|
||||
{
|
||||
SCTP_TCB_LOCK_ASSERT(stcb);
|
||||
|
||||
if (with_strq != NULL) {
|
||||
if (stcb->asoc.ss_data.locked_on_sending == with_strq) {
|
||||
stcb->asoc.ss_data.locked_on_sending = strq;
|
||||
@ -805,7 +841,7 @@ static void
|
||||
sctp_ss_fcfs_add(struct sctp_tcb *stcb, struct sctp_association *asoc,
|
||||
struct sctp_stream_out *strq SCTP_UNUSED, struct sctp_stream_queue_pending *sp)
|
||||
{
|
||||
SCTP_TCB_SEND_LOCK_ASSERT(stcb);
|
||||
SCTP_TCB_LOCK_ASSERT(stcb);
|
||||
|
||||
if (!sp->scheduled) {
|
||||
TAILQ_INSERT_TAIL(&asoc->ss_data.out.list, sp, ss_next);
|
||||
@ -817,6 +853,8 @@ sctp_ss_fcfs_add(struct sctp_tcb *stcb, struct sctp_association *asoc,
|
||||
static bool
|
||||
sctp_ss_fcfs_is_empty(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_association *asoc)
|
||||
{
|
||||
SCTP_TCB_LOCK_ASSERT(stcb);
|
||||
|
||||
return (TAILQ_EMPTY(&asoc->ss_data.out.list));
|
||||
}
|
||||
|
||||
@ -824,7 +862,7 @@ static void
|
||||
sctp_ss_fcfs_remove(struct sctp_tcb *stcb, struct sctp_association *asoc,
|
||||
struct sctp_stream_out *strq SCTP_UNUSED, struct sctp_stream_queue_pending *sp)
|
||||
{
|
||||
SCTP_TCB_SEND_LOCK_ASSERT(stcb);
|
||||
SCTP_TCB_LOCK_ASSERT(stcb);
|
||||
|
||||
if (sp->scheduled) {
|
||||
TAILQ_REMOVE(&asoc->ss_data.out.list, sp, ss_next);
|
||||
@ -840,6 +878,8 @@ sctp_ss_fcfs_select(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_nets *net,
|
||||
struct sctp_stream_out *strq;
|
||||
struct sctp_stream_queue_pending *sp;
|
||||
|
||||
SCTP_TCB_LOCK_ASSERT(stcb);
|
||||
|
||||
if (asoc->ss_data.locked_on_sending) {
|
||||
return (asoc->ss_data.locked_on_sending);
|
||||
}
|
||||
|
@ -855,8 +855,8 @@ sctp_sysctl_handle_trace_log_clear(SYSCTL_HANDLER_ARGS)
|
||||
return (error); \
|
||||
} \
|
||||
SYSCTL_PROC(_net_inet_sctp, OID_AUTO, mib_name, \
|
||||
CTLFLAG_VNET | CTLTYPE_UINT | CTLFLAG_RW | CTLFLAG_NEEDGIANT, \
|
||||
NULL, 0, sctp_sysctl_handle_##mib_name, "UI", prefix##_DESC);
|
||||
CTLFLAG_VNET|CTLTYPE_UINT|CTLFLAG_RW, NULL, 0, \
|
||||
sctp_sysctl_handle_##mib_name, "UI", prefix##_DESC);
|
||||
|
||||
/*
|
||||
* sysctl definitions
|
||||
@ -867,14 +867,10 @@ SCTP_UINT_SYSCTL(recvspace, sctp_recvspace, SCTPCTL_RECVSPACE)
|
||||
SCTP_UINT_SYSCTL(auto_asconf, sctp_auto_asconf, SCTPCTL_AUTOASCONF)
|
||||
SCTP_UINT_SYSCTL(ecn_enable, sctp_ecn_enable, SCTPCTL_ECN_ENABLE)
|
||||
SCTP_UINT_SYSCTL(pr_enable, sctp_pr_enable, SCTPCTL_PR_ENABLE)
|
||||
SYSCTL_PROC(_net_inet_sctp, OID_AUTO, auth_enable,
|
||||
CTLFLAG_VNET | CTLTYPE_UINT | CTLFLAG_RW | CTLFLAG_NEEDGIANT,
|
||||
NULL, 0, sctp_sysctl_handle_auth, "IU",
|
||||
SCTPCTL_AUTH_ENABLE_DESC);
|
||||
SYSCTL_PROC(_net_inet_sctp, OID_AUTO, asconf_enable,
|
||||
CTLFLAG_VNET | CTLTYPE_UINT | CTLFLAG_RW | CTLFLAG_NEEDGIANT,
|
||||
NULL, 0, sctp_sysctl_handle_asconf, "IU",
|
||||
SCTPCTL_ASCONF_ENABLE_DESC);
|
||||
SYSCTL_PROC(_net_inet_sctp, OID_AUTO, auth_enable, CTLFLAG_VNET | CTLTYPE_UINT | CTLFLAG_RW,
|
||||
NULL, 0, sctp_sysctl_handle_auth, "IU", SCTPCTL_AUTH_ENABLE_DESC);
|
||||
SYSCTL_PROC(_net_inet_sctp, OID_AUTO, asconf_enable, CTLFLAG_VNET | CTLTYPE_UINT | CTLFLAG_RW,
|
||||
NULL, 0, sctp_sysctl_handle_asconf, "IU", SCTPCTL_ASCONF_ENABLE_DESC);
|
||||
SCTP_UINT_SYSCTL(reconfig_enable, sctp_reconfig_enable, SCTPCTL_RECONFIG_ENABLE)
|
||||
SCTP_UINT_SYSCTL(nrsack_enable, sctp_nrsack_enable, SCTPCTL_NRSACK_ENABLE)
|
||||
SCTP_UINT_SYSCTL(pktdrop_enable, sctp_pktdrop_enable, SCTPCTL_PKTDROP_ENABLE)
|
||||
@ -924,19 +920,13 @@ SCTP_UINT_SYSCTL(default_frag_interleave, sctp_default_frag_interleave, SCTPCTL_
|
||||
SCTP_UINT_SYSCTL(mobility_base, sctp_mobility_base, SCTPCTL_MOBILITY_BASE)
|
||||
SCTP_UINT_SYSCTL(mobility_fasthandoff, sctp_mobility_fasthandoff, SCTPCTL_MOBILITY_FASTHANDOFF)
|
||||
#if defined(SCTP_LOCAL_TRACE_BUF)
|
||||
SYSCTL_PROC(_net_inet_sctp, OID_AUTO, log,
|
||||
CTLFLAG_VNET | CTLTYPE_STRUCT | CTLFLAG_RD | CTLFLAG_NEEDGIANT,
|
||||
NULL, 0, sctp_sysctl_handle_trace_log, "S,sctplog"a
|
||||
, "SCTP logging (struct sctp_log)");
|
||||
SYSCTL_PROC(_net_inet_sctp, OID_AUTO, clear_trace,
|
||||
CTLFLAG_VNET | CTLTYPE_UINT | CTLFLAG_RW | CTLFLAG_NEEDGIANT,
|
||||
NULL, 0, sctp_sysctl_handle_trace_log_clear, "IU",
|
||||
"Clear SCTP Logging buffer");
|
||||
SYSCTL_PROC(_net_inet_sctp, OID_AUTO, log, CTLFLAG_VNET | CTLTYPE_STRUCT | CTLFLAG_RD,
|
||||
NULL, 0, sctp_sysctl_handle_trace_log, "S,sctplog", "SCTP logging (struct sctp_log)");
|
||||
SYSCTL_PROC(_net_inet_sctp, OID_AUTO, clear_trace, CTLFLAG_VNET | CTLTYPE_UINT | CTLFLAG_RW,
|
||||
NULL, 0, sctp_sysctl_handle_trace_log_clear, "IU", "Clear SCTP Logging buffer");
|
||||
#endif
|
||||
SYSCTL_PROC(_net_inet_sctp, OID_AUTO, udp_tunneling_port,
|
||||
CTLFLAG_VNET | CTLTYPE_UINT | CTLFLAG_RW | CTLFLAG_NEEDGIANT,
|
||||
NULL, 0, sctp_sysctl_handle_udp_tunneling, "IU",
|
||||
SCTPCTL_UDP_TUNNELING_PORT_DESC);
|
||||
SYSCTL_PROC(_net_inet_sctp, OID_AUTO, udp_tunneling_port, CTLFLAG_VNET | CTLTYPE_UINT | CTLFLAG_RW,
|
||||
NULL, 0, sctp_sysctl_handle_udp_tunneling, "IU", SCTPCTL_UDP_TUNNELING_PORT_DESC);
|
||||
SCTP_UINT_SYSCTL(enable_sack_immediately, sctp_enable_sack_immediately, SCTPCTL_SACK_IMMEDIATELY_ENABLE)
|
||||
SCTP_UINT_SYSCTL(nat_friendly_init, sctp_inits_include_nat_friendly, SCTPCTL_NAT_FRIENDLY_INITS)
|
||||
SCTP_UINT_SYSCTL(vtag_time_wait, sctp_vtag_time_wait, SCTPCTL_TIME_WAIT)
|
||||
@ -953,11 +943,7 @@ SCTP_UINT_SYSCTL(diag_info_code, sctp_diag_info_code, SCTPCTL_DIAG_INFO_CODE)
|
||||
#ifdef SCTP_DEBUG
|
||||
SCTP_UINT_SYSCTL(debug, sctp_debug_on, SCTPCTL_DEBUG)
|
||||
#endif
|
||||
SYSCTL_PROC(_net_inet_sctp, OID_AUTO, stats,
|
||||
CTLFLAG_VNET | CTLTYPE_STRUCT | CTLFLAG_RW | CTLFLAG_NEEDGIANT,
|
||||
NULL, 0, sctp_sysctl_handle_stats, "S,sctpstat",
|
||||
"SCTP statistics (struct sctp_stat)");
|
||||
SYSCTL_PROC(_net_inet_sctp, OID_AUTO, assoclist,
|
||||
CTLFLAG_VNET | CTLTYPE_OPAQUE | CTLFLAG_RD | CTLFLAG_NEEDGIANT,
|
||||
NULL, 0, sctp_sysctl_handle_assoclist, "S,xassoc",
|
||||
"List of active SCTP associations");
|
||||
SYSCTL_PROC(_net_inet_sctp, OID_AUTO, stats, CTLFLAG_VNET | CTLTYPE_STRUCT | CTLFLAG_RW,
|
||||
NULL, 0, sctp_sysctl_handle_stats, "S,sctpstat", "SCTP statistics (struct sctp_stat)");
|
||||
SYSCTL_PROC(_net_inet_sctp, OID_AUTO, assoclist, CTLFLAG_VNET | CTLTYPE_OPAQUE | CTLFLAG_RD,
|
||||
NULL, 0, sctp_sysctl_handle_assoclist, "S,xassoc", "List of active SCTP associations");
|
||||
|
@ -1352,8 +1352,7 @@ sctp_audit_stream_queues_for_size(struct sctp_inpcb *inp, struct sctp_tcb *stcb)
|
||||
|
||||
KASSERT(inp != NULL, ("inp is NULL"));
|
||||
KASSERT(stcb != NULL, ("stcb is NULL"));
|
||||
|
||||
SCTP_TCB_SEND_LOCK(stcb);
|
||||
SCTP_TCB_LOCK_ASSERT(stcb);
|
||||
KASSERT(TAILQ_EMPTY(&stcb->asoc.send_queue), ("send_queue not empty"));
|
||||
KASSERT(TAILQ_EMPTY(&stcb->asoc.sent_queue), ("sent_queue not empty"));
|
||||
|
||||
@ -1387,7 +1386,6 @@ sctp_audit_stream_queues_for_size(struct sctp_inpcb *inp, struct sctp_tcb *stcb)
|
||||
SCTP_PRINTF("Hmm, stream queue cnt at %d I counted %d in stream out wheel\n",
|
||||
stcb->asoc.stream_queue_cnt, chks_in_queue);
|
||||
}
|
||||
SCTP_TCB_SEND_UNLOCK(stcb);
|
||||
if (chks_in_queue) {
|
||||
/* call the output queue function */
|
||||
sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_T3, SCTP_SO_NOT_LOCKED);
|
||||
|
@ -1259,7 +1259,7 @@ int
|
||||
sctp_lower_sosend(struct socket *so,
|
||||
struct sockaddr *addr,
|
||||
struct uio *uio,
|
||||
struct mbuf *i_pak,
|
||||
struct mbuf *top,
|
||||
struct mbuf *control,
|
||||
int flags,
|
||||
struct sctp_sndrcvinfo *srcv
|
||||
|
@ -4068,12 +4068,10 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
|
||||
}
|
||||
SCTP_FIND_STCB(inp, stcb, av->assoc_id);
|
||||
if (stcb) {
|
||||
SCTP_TCB_SEND_LOCK(stcb);
|
||||
stcb->asoc.ss_functions.sctp_ss_clear(stcb, &stcb->asoc, true);
|
||||
stcb->asoc.ss_functions = sctp_ss_functions[av->assoc_value];
|
||||
stcb->asoc.stream_scheduling_module = av->assoc_value;
|
||||
stcb->asoc.ss_functions.sctp_ss_init(stcb, &stcb->asoc);
|
||||
SCTP_TCB_SEND_UNLOCK(stcb);
|
||||
SCTP_TCB_UNLOCK(stcb);
|
||||
} else {
|
||||
if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
|
||||
@ -4091,12 +4089,10 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
|
||||
SCTP_INP_RLOCK(inp);
|
||||
LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) {
|
||||
SCTP_TCB_LOCK(stcb);
|
||||
SCTP_TCB_SEND_LOCK(stcb);
|
||||
stcb->asoc.ss_functions.sctp_ss_clear(stcb, &stcb->asoc, true);
|
||||
stcb->asoc.ss_functions = sctp_ss_functions[av->assoc_value];
|
||||
stcb->asoc.stream_scheduling_module = av->assoc_value;
|
||||
stcb->asoc.ss_functions.sctp_ss_init(stcb, &stcb->asoc);
|
||||
SCTP_TCB_SEND_UNLOCK(stcb);
|
||||
SCTP_TCB_UNLOCK(stcb);
|
||||
}
|
||||
SCTP_INP_RUNLOCK(inp);
|
||||
|
@ -1288,7 +1288,7 @@ sctp_init_asoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
|
||||
SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTPUTIL, ENOMEM);
|
||||
return (ENOMEM);
|
||||
}
|
||||
SCTP_TCB_SEND_LOCK(stcb);
|
||||
SCTP_TCB_LOCK(stcb);
|
||||
for (i = 0; i < asoc->streamoutcnt; i++) {
|
||||
/*
|
||||
* inbound side must be set to 0xffff, also NOTE when we get
|
||||
@ -1317,7 +1317,7 @@ sctp_init_asoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
|
||||
asoc->strmout[i].state = SCTP_STREAM_OPENING;
|
||||
}
|
||||
asoc->ss_functions.sctp_ss_init(stcb, asoc);
|
||||
SCTP_TCB_SEND_UNLOCK(stcb);
|
||||
SCTP_TCB_UNLOCK(stcb);
|
||||
|
||||
/* Now the mapping array */
|
||||
asoc->mapping_array_size = SCTP_INITIAL_MAPPING_ARRAY;
|
||||
@ -4331,6 +4331,8 @@ sctp_abort_notification(struct sctp_tcb *stcb, bool from_peer, bool timeout,
|
||||
if (stcb == NULL) {
|
||||
return;
|
||||
}
|
||||
SCTP_TCB_LOCK_ASSERT(stcb);
|
||||
|
||||
if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
|
||||
((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) &&
|
||||
(stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_CONNECTED))) {
|
||||
@ -4341,11 +4343,9 @@ sctp_abort_notification(struct sctp_tcb *stcb, bool from_peer, bool timeout,
|
||||
(stcb->asoc.state & SCTP_STATE_CLOSED_SOCKET)) {
|
||||
return;
|
||||
}
|
||||
SCTP_TCB_SEND_LOCK(stcb);
|
||||
SCTP_ADD_SUBSTATE(stcb, SCTP_STATE_WAS_ABORTED);
|
||||
/* Tell them we lost the asoc */
|
||||
sctp_report_all_outbound(stcb, error, so_locked);
|
||||
SCTP_TCB_SEND_UNLOCK(stcb);
|
||||
if (from_peer) {
|
||||
sctp_ulp_notify(SCTP_NOTIFY_ASSOC_REM_ABORTED, stcb, error, abort, so_locked);
|
||||
} else {
|
||||
@ -5041,6 +5041,8 @@ sctp_release_pr_sctp_chunk(struct sctp_tcb *stcb, struct sctp_tmit_chunk *tp1,
|
||||
int notdone;
|
||||
int do_wakeup_routine = 0;
|
||||
|
||||
SCTP_TCB_LOCK_ASSERT(stcb);
|
||||
|
||||
sid = tp1->rec.data.sid;
|
||||
mid = tp1->rec.data.mid;
|
||||
if (sent || !(tp1->rec.data.rcv_flags & SCTP_DATA_FIRST_FRAG)) {
|
||||
@ -5151,7 +5153,6 @@ sctp_release_pr_sctp_chunk(struct sctp_tcb *stcb, struct sctp_tmit_chunk *tp1,
|
||||
* Still no eom found. That means there is stuff left on the
|
||||
* stream out queue.. yuck.
|
||||
*/
|
||||
SCTP_TCB_SEND_LOCK(stcb);
|
||||
strq = &stcb->asoc.strmout[sid];
|
||||
sp = TAILQ_FIRST(&strq->outqueue);
|
||||
if (sp != NULL) {
|
||||
@ -5233,7 +5234,6 @@ sctp_release_pr_sctp_chunk(struct sctp_tcb *stcb, struct sctp_tmit_chunk *tp1,
|
||||
sp->length = 0;
|
||||
}
|
||||
}
|
||||
SCTP_TCB_SEND_UNLOCK(stcb);
|
||||
}
|
||||
if (do_wakeup_routine) {
|
||||
sctp_sowwakeup(stcb->sctp_ep, stcb->sctp_socket);
|
||||
|
Loading…
Reference in New Issue
Block a user