diff options
author | rrs <rrs@FreeBSD.org> | 2007-06-14 22:59:04 +0000 |
---|---|---|
committer | rrs <rrs@FreeBSD.org> | 2007-06-14 22:59:04 +0000 |
commit | 5db775aaced05bbda585e596739fe8150a74d68d (patch) | |
tree | 54d00675be01f15ab0ef5ba5c19c020edee43762 /sys/netinet/sctp_output.c | |
parent | 491996f8103df505e60bc52e817f90a4bccba59e (diff) | |
download | FreeBSD-src-5db775aaced05bbda585e596739fe8150a74d68d.zip FreeBSD-src-5db775aaced05bbda585e596739fe8150a74d68d.tar.gz |
- Fix so ifn's are properly deleted when the ref count goes to 0.
- Fix so VRF's will clean themselves up when no references are around.
- Allow sctp_ifa to be passed into inpcb_bind, addr_mgmt_ep_sa to bypass
normal validation checks.
- turn auto-asconf off for subset bound sockets
- Moves all logging to use KTR. This gets rid of most
of the logging #ifdef's with a few exceptions reducing
the number of config options for SCTP.
Diffstat (limited to 'sys/netinet/sctp_output.c')
-rw-r--r-- | sys/netinet/sctp_output.c | 210 |
1 files changed, 112 insertions, 98 deletions
diff --git a/sys/netinet/sctp_output.c b/sys/netinet/sctp_output.c index 1e1fc21..1c52c33 100644 --- a/sys/netinet/sctp_output.c +++ b/sys/netinet/sctp_output.c @@ -3295,6 +3295,7 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp, newm = sctp_get_mbuf_for_msg(sizeof(struct ip), 1, M_DONTWAIT, 1, MT_DATA); if (newm == NULL) { sctp_m_freem(m); + SCTP_LTRACE_ERR(inp, stcb, ENOMEM, 0); return (ENOMEM); } SCTP_ALIGN_TO_END(newm, sizeof(struct ip)); @@ -3450,6 +3451,7 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp, if (SCTP_GET_HEADER_FOR_OUTPUT(o_pak)) { /* failed to prepend data, give up */ sctp_m_freem(m); + SCTP_LTRACE_ERR(inp, stcb, ENOMEM, 0); return (ENOMEM); } #ifdef SCTP_PACKET_LOGGING @@ -3523,6 +3525,7 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp, newm = sctp_get_mbuf_for_msg(sizeof(struct ip6_hdr), 1, M_DONTWAIT, 1, MT_DATA); if (newm == NULL) { sctp_m_freem(m); + SCTP_LTRACE_ERR(inp, stcb, ENOMEM, 0); return (ENOMEM); } SCTP_ALIGN_TO_END(newm, sizeof(struct ip6_hdr)); @@ -3666,6 +3669,7 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp, if (SCTP_GET_HEADER_FOR_OUTPUT(o_pak)) { /* failed to prepend data, give up */ sctp_m_freem(m); + SCTP_LTRACE_ERR(inp, stcb, ENOMEM, 0); return (ENOMEM); } #ifdef SCTP_PACKET_LOGGING @@ -5343,6 +5347,7 @@ sctp_msg_append(struct sctp_tcb *stcb, } sctp_alloc_a_strmoq(stcb, sp); if (sp == NULL) { + SCTP_LTRACE_ERR(stcb->sctp_ep, stcb, ENOMEM, 0); error = ENOMEM; goto out_now; } @@ -5818,6 +5823,7 @@ sctp_sendall(struct sctp_inpcb *inp, struct uio *uio, struct mbuf *m, SCTP_M_COPYAL); if (ca == NULL) { sctp_m_freem(m); + SCTP_LTRACE_ERR(inp, NULL, ENOMEM, 0); return (ENOMEM); } memset(ca, 0, sizeof(struct sctp_copy_all)); @@ -5835,6 +5841,7 @@ sctp_sendall(struct sctp_inpcb *inp, struct uio *uio, struct mbuf *m, ca->m = sctp_copy_out_all(uio, ca->sndlen); if (ca->m == NULL) { SCTP_FREE(ca, SCTP_M_COPYAL); + SCTP_LTRACE_ERR(inp, NULL, ENOMEM, 0); return (ENOMEM); } } else { @@ -5980,19 +5987,19 @@ all_done: data_list[i]->sent = SCTP_DATAGRAM_SENT; data_list[i]->snd_count = 1; data_list[i]->rec.data.chunk_was_revoked = 0; -#ifdef SCTP_FLIGHT_LOGGING - sctp_misc_ints(SCTP_FLIGHT_LOG_UP, - data_list[i]->whoTo->flight_size, - data_list[i]->book_size, - (uintptr_t) data_list[i]->whoTo, - data_list[i]->rec.data.TSN_seq); -#endif + if (sctp_logging_level & SCTP_FLIGHT_LOGGING_ENABLE) { + sctp_misc_ints(SCTP_FLIGHT_LOG_UP, + data_list[i]->whoTo->flight_size, + data_list[i]->book_size, + (uintptr_t) data_list[i]->whoTo, + data_list[i]->rec.data.TSN_seq); + } sctp_flight_size_increase(data_list[i]); sctp_total_flight_increase(stcb, data_list[i]); -#ifdef SCTP_LOG_RWND - sctp_log_rwnd(SCTP_DECREASE_PEER_RWND, - asoc->peers_rwnd, data_list[i]->send_size, sctp_peer_chunk_oh); -#endif + if (sctp_logging_level & SCTP_LOG_RWND_ENABLE) { + sctp_log_rwnd(SCTP_DECREASE_PEER_RWND, + asoc->peers_rwnd, data_list[i]->send_size, sctp_peer_chunk_oh); + } asoc->peers_rwnd = sctp_sbspace_sub(asoc->peers_rwnd, (uint32_t) (data_list[i]->send_size + sctp_peer_chunk_oh)); if (asoc->peers_rwnd < stcb->sctp_ep->sctp_ep.sctp_sws_sender) { @@ -6827,9 +6834,9 @@ one_more_time: * copied out of the stream buffers. Note mostly * copy by reference (we hope). */ -#ifdef SCTP_CWND_LOGGING - sctp_log_cwnd(stcb, net, 0, SCTP_CWND_LOG_FILL_OUTQ_CALLED); -#endif + if (sctp_logging_level & SCTP_CWND_LOGGING_ENABLE) { + sctp_log_cwnd(stcb, net, 0, SCTP_CWND_LOG_FILL_OUTQ_CALLED); + } sctp_fill_outqueue(stcb, net, frag_point, eeor_mode); } if (start_at != TAILQ_FIRST(&asoc->nets)) { @@ -6890,9 +6897,9 @@ again_one_more_time: ifp = net->ro.ro_rt->rt_ifp; if ((ifp->if_snd.ifq_len + 2) >= ifp->if_snd.ifq_maxlen) { SCTP_STAT_INCR(sctps_ifnomemqueued); -#ifdef SCTP_LOG_MAXBURST - sctp_log_maxburst(stcb, net, ifp->if_snd.ifq_len, ifp->if_snd.ifq_maxlen, SCTP_MAX_IFP_APPLIED); -#endif + if (sctp_logging_level & SCTP_LOG_MAXBURST_ENABLE) { + sctp_log_maxburst(stcb, net, ifp->if_snd.ifq_len, ifp->if_snd.ifq_maxlen, SCTP_MAX_IFP_APPLIED); + } continue; } } @@ -6987,6 +6994,7 @@ again_one_more_time: chk->send_size, chk->copy_by_ref); if (outchain == NULL) { *reason_code = 8; + SCTP_LTRACE_ERR(inp, stcb, ENOMEM, 0); return (ENOMEM); } SCTP_STAT_INCR_COUNTER64(sctps_outcontrolchunks); @@ -7231,6 +7239,7 @@ again_one_more_time: sctp_timer_start(SCTP_TIMER_TYPE_SEND, inp, stcb, net); } *reason_code = 3; + SCTP_LTRACE_ERR(inp, stcb, ENOMEM, 0); return (ENOMEM); } /* upate our MTU size */ @@ -7428,9 +7437,9 @@ again_one_more_time: break; } } -#ifdef SCTP_CWND_LOGGING - sctp_log_cwnd(stcb, net, tsns_sent, SCTP_CWND_LOG_FROM_SEND); -#endif + if (sctp_logging_level & SCTP_CWND_LOGGING_ENABLE) { + sctp_log_cwnd(stcb, net, tsns_sent, SCTP_CWND_LOG_FROM_SEND); + } } if (old_startat == NULL) { old_startat = send_start_at; @@ -7441,9 +7450,9 @@ again_one_more_time: * At the end there should be no NON timed chunks hanging on this * queue. */ -#ifdef SCTP_CWND_LOGGING - sctp_log_cwnd(stcb, net, *num_out, SCTP_CWND_LOG_FROM_SEND); -#endif + if (sctp_logging_level & SCTP_CWND_LOGGING_ENABLE) { + sctp_log_cwnd(stcb, net, *num_out, SCTP_CWND_LOG_FROM_SEND); + } if ((*num_out == 0) && (*reason_code == 0)) { *reason_code = 4; } else { @@ -8140,6 +8149,7 @@ one_chunk_around: } m = sctp_copy_mbufchain(chk->data, m, &endofchain, 0, chk->send_size, chk->copy_by_ref); if (m == NULL) { + SCTP_LTRACE_ERR(inp, stcb, ENOMEM, 0); return (ENOMEM); } /* Do clear IP_DF ? */ @@ -8191,6 +8201,7 @@ one_chunk_around: } m = sctp_copy_mbufchain(fwd->data, m, &endofchain, 0, fwd->send_size, fwd->copy_by_ref); if (m == NULL) { + SCTP_LTRACE_ERR(inp, stcb, ENOMEM, 0); return (ENOMEM); } /* Do clear IP_DF ? */ @@ -8307,21 +8318,21 @@ one_chunk_around: } else { -#ifdef SCTP_LOG_RWND - sctp_log_rwnd(SCTP_DECREASE_PEER_RWND, - asoc->peers_rwnd, data_list[i]->send_size, sctp_peer_chunk_oh); -#endif + if (sctp_logging_level & SCTP_LOG_RWND_ENABLE) { + sctp_log_rwnd(SCTP_DECREASE_PEER_RWND, + asoc->peers_rwnd, data_list[i]->send_size, sctp_peer_chunk_oh); + } asoc->peers_rwnd = sctp_sbspace_sub(asoc->peers_rwnd, (uint32_t) (data_list[i]->send_size + sctp_peer_chunk_oh)); } -#ifdef SCTP_FLIGHT_LOGGING - sctp_misc_ints(SCTP_FLIGHT_LOG_UP_RSND, - data_list[i]->whoTo->flight_size, - data_list[i]->book_size, - (uintptr_t) data_list[i]->whoTo, - data_list[i]->rec.data.TSN_seq); -#endif + if (sctp_logging_level & SCTP_FLIGHT_LOGGING_ENABLE) { + sctp_misc_ints(SCTP_FLIGHT_LOG_UP_RSND, + data_list[i]->whoTo->flight_size, + data_list[i]->book_size, + (uintptr_t) data_list[i]->whoTo, + data_list[i]->rec.data.TSN_seq); + } sctp_flight_size_increase(data_list[i]); sctp_total_flight_increase(stcb, data_list[i]); if (asoc->peers_rwnd < stcb->sctp_ep->sctp_ep.sctp_sws_sender) { @@ -8348,9 +8359,9 @@ one_chunk_around: } } } -#ifdef SCTP_CWND_LOGGING - sctp_log_cwnd(stcb, net, tsns_sent, SCTP_CWND_LOG_FROM_RESEND); -#endif + if (sctp_logging_level & SCTP_CWND_LOGGING_ENABLE) { + sctp_log_cwnd(stcb, net, tsns_sent, SCTP_CWND_LOG_FROM_RESEND); + } #ifdef SCTP_AUDITING_ENABLED sctp_auditing(21, inp, stcb, NULL); #endif @@ -8562,13 +8573,12 @@ sctp_chunk_output(struct sctp_inpcb *inp, old_cwnd = net->cwnd; net->cwnd = (net->flight_size + (burst_limit * net->mtu)); -#ifdef SCTP_CWND_MONITOR - sctp_log_cwnd(stcb, net, (net->cwnd - old_cwnd), SCTP_CWND_LOG_FROM_BRST); -#endif - -#ifdef SCTP_LOG_MAXBURST - sctp_log_maxburst(stcb, net, 0, burst_limit, SCTP_MAX_BURST_APPLIED); -#endif + if (sctp_logging_level & SCTP_CWND_MONITOR_ENABLE) { + sctp_log_cwnd(stcb, net, (net->cwnd - old_cwnd), SCTP_CWND_LOG_FROM_BRST); + } + if (sctp_logging_level & SCTP_LOG_MAXBURST_ENABLE) { + sctp_log_maxburst(stcb, net, 0, burst_limit, SCTP_MAX_BURST_APPLIED); + } SCTP_STAT_INCR(sctps_maxburstqueued); } net->fast_retran_ip = 0; @@ -8589,26 +8599,25 @@ sctp_chunk_output(struct sctp_inpcb *inp, &now, &now_filled, frag_point); if (error) { SCTPDBG(SCTP_DEBUG_OUTPUT1, "Error %d was returned from med-c-op\n", error); -#ifdef SCTP_LOG_MAXBURST - sctp_log_maxburst(stcb, asoc->primary_destination, error, burst_cnt, SCTP_MAX_BURST_ERROR_STOP); -#endif -#ifdef SCTP_CWND_LOGGING - sctp_log_cwnd(stcb, NULL, error, SCTP_SEND_NOW_COMPLETES); - sctp_log_cwnd(stcb, NULL, 0xdeadbeef, SCTP_SEND_NOW_COMPLETES); -#endif - + if (sctp_logging_level & SCTP_LOG_MAXBURST_ENABLE) { + sctp_log_maxburst(stcb, asoc->primary_destination, error, burst_cnt, SCTP_MAX_BURST_ERROR_STOP); + } + if (sctp_logging_level & SCTP_CWND_LOGGING_ENABLE) { + sctp_log_cwnd(stcb, NULL, error, SCTP_SEND_NOW_COMPLETES); + sctp_log_cwnd(stcb, NULL, 0xdeadbeef, SCTP_SEND_NOW_COMPLETES); + } break; } SCTPDBG(SCTP_DEBUG_OUTPUT3, "m-c-o put out %d\n", num_out); tot_out += num_out; burst_cnt++; -#ifdef SCTP_CWND_LOGGING - sctp_log_cwnd(stcb, NULL, num_out, SCTP_SEND_NOW_COMPLETES); - if (num_out == 0) { - sctp_log_cwnd(stcb, NULL, reason_code, SCTP_SEND_NOW_COMPLETES); + if (sctp_logging_level & SCTP_CWND_LOGGING_ENABLE) { + sctp_log_cwnd(stcb, NULL, num_out, SCTP_SEND_NOW_COMPLETES); + if (num_out == 0) { + sctp_log_cwnd(stcb, NULL, reason_code, SCTP_SEND_NOW_COMPLETES); + } } -#endif if (nagle_on) { /*- * When nagle is on, we look at how much is un_sent, then @@ -8640,16 +8649,16 @@ sctp_chunk_output(struct sctp_inpcb *inp, if (burst_cnt >= burst_limit) { SCTP_STAT_INCR(sctps_maxburstqueued); asoc->burst_limit_applied = 1; -#ifdef SCTP_LOG_MAXBURST - sctp_log_maxburst(stcb, asoc->primary_destination, 0, burst_cnt, SCTP_MAX_BURST_APPLIED); -#endif + if (sctp_logging_level & SCTP_LOG_MAXBURST_ENABLE) { + sctp_log_maxburst(stcb, asoc->primary_destination, 0, burst_cnt, SCTP_MAX_BURST_APPLIED); + } } else { asoc->burst_limit_applied = 0; } } -#ifdef SCTP_CWND_LOGGING - sctp_log_cwnd(stcb, NULL, tot_out, SCTP_SEND_NOW_COMPLETES); -#endif + if (sctp_logging_level & SCTP_CWND_LOGGING_ENABLE) { + sctp_log_cwnd(stcb, NULL, tot_out, SCTP_SEND_NOW_COMPLETES); + } SCTPDBG(SCTP_DEBUG_OUTPUT1, "Ok, we have put out %d chunks\n", tot_out); @@ -10011,6 +10020,7 @@ sctp_send_str_reset_req(struct sctp_tcb *stcb, } sctp_alloc_a_chunk(stcb, chk); if (chk == NULL) { + SCTP_LTRACE_ERR(stcb->sctp_ep, stcb, ENOMEM, 0); return (ENOMEM); } chk->copy_by_ref = 0; @@ -10024,6 +10034,7 @@ sctp_send_str_reset_req(struct sctp_tcb *stcb, 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_LTRACE_ERR(stcb->sctp_ep, stcb, ENOMEM, 0); return (ENOMEM); } SCTP_BUF_RESV_UF(chk->data, SCTP_MIN_OVERHEAD); @@ -11130,10 +11141,10 @@ sctp_lower_sosend(struct socket *so, /* No room right no ! */ SOCKBUF_LOCK(&so->so_snd); while (SCTP_SB_LIMIT_SND(so) < (stcb->asoc.total_output_queue_size + sctp_add_more_threshold)) { -#ifdef SCTP_BLK_LOGGING - sctp_log_block(SCTP_BLOCK_LOG_INTO_BLKA, - so, asoc, uio->uio_resid); -#endif + if (sctp_logging_level & SCTP_BLK_LOGGING_ENABLE) { + sctp_log_block(SCTP_BLOCK_LOG_INTO_BLKA, + so, asoc, uio->uio_resid); + } be.error = 0; stcb->block_entry = &be; error = sbwait(&so->so_snd); @@ -11149,10 +11160,10 @@ sctp_lower_sosend(struct socket *so, SOCKBUF_UNLOCK(&so->so_snd); goto out_unlocked; } -#ifdef SCTP_BLK_LOGGING - sctp_log_block(SCTP_BLOCK_LOG_OUTOF_BLK, - so, asoc, stcb->asoc.total_output_queue_size); -#endif + if (sctp_logging_level & SCTP_BLK_LOGGING_ENABLE) { + sctp_log_block(SCTP_BLOCK_LOG_OUTOF_BLK, + so, asoc, stcb->asoc.total_output_queue_size); + } if (stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) { goto out_unlocked; } @@ -11394,25 +11405,28 @@ sctp_lower_sosend(struct socket *so, * Don't send anything and let SACKs drive out the * data unless wen have a "full" segment to send. */ -#ifdef SCTP_NAGLE_LOGGING - sctp_log_nagle_event(stcb, SCTP_NAGLE_APPLIED); -#endif + if (sctp_logging_level & SCTP_NAGLE_LOGGING_ENABLE) { + sctp_log_nagle_event(stcb, SCTP_NAGLE_APPLIED); + } SCTP_STAT_INCR(sctps_naglequeued); nagle_applies = 1; } else { -#ifdef SCTP_NAGLE_LOGGING - if (sctp_is_feature_off(inp, SCTP_PCB_FLAGS_NODELAY)) - sctp_log_nagle_event(stcb, SCTP_NAGLE_SKIPPED); -#endif + if (sctp_logging_level & SCTP_NAGLE_LOGGING_ENABLE) { + if (sctp_is_feature_off(inp, SCTP_PCB_FLAGS_NODELAY)) + sctp_log_nagle_event(stcb, SCTP_NAGLE_SKIPPED); + } SCTP_STAT_INCR(sctps_naglesent); nagle_applies = 0; } /* What about the INIT, send it maybe */ -#ifdef SCTP_BLK_LOGGING - sctp_misc_ints(SCTP_CWNDLOG_PRESEND, queue_only_for_init, queue_only, nagle_applies, un_sent); - sctp_misc_ints(SCTP_CWNDLOG_PRESEND, stcb->asoc.total_output_queue_size, stcb->asoc.total_flight, - stcb->asoc.chunks_on_out_queue, stcb->asoc.total_flight_count); -#endif + if (sctp_logging_level & SCTP_BLK_LOGGING_ENABLE) { + + sctp_misc_ints(SCTP_CWNDLOG_PRESEND, queue_only_for_init, queue_only, + nagle_applies, un_sent); + sctp_misc_ints(SCTP_CWNDLOG_PRESEND, stcb->asoc.total_output_queue_size, + stcb->asoc.total_flight, + stcb->asoc.chunks_on_out_queue, stcb->asoc.total_flight_count); + } if (queue_only_for_init) { if (hold_tcblock == 0) { SCTP_TCB_LOCK(stcb); @@ -11472,10 +11486,10 @@ sctp_lower_sosend(struct socket *so, * wakeup flag in place. */ if (SCTP_SB_LIMIT_SND(so) < (stcb->asoc.total_output_queue_size + sctp_add_more_threshold)) { -#ifdef SCTP_BLK_LOGGING - sctp_log_block(SCTP_BLOCK_LOG_INTO_BLK, - so, asoc, uio->uio_resid); -#endif + if (sctp_logging_level & SCTP_BLK_LOGGING_ENABLE) { + sctp_log_block(SCTP_BLOCK_LOG_INTO_BLK, + so, asoc, uio->uio_resid); + } be.error = 0; stcb->block_entry = &be; error = sbwait(&so->so_snd); @@ -11492,10 +11506,10 @@ sctp_lower_sosend(struct socket *so, SOCKBUF_UNLOCK(&so->so_snd); goto out_unlocked; } -#ifdef SCTP_BLK_LOGGING - sctp_log_block(SCTP_BLOCK_LOG_OUTOF_BLK, - so, asoc, stcb->asoc.total_output_queue_size); -#endif + if (sctp_logging_level & SCTP_BLK_LOGGING_ENABLE) { + sctp_log_block(SCTP_BLOCK_LOG_OUTOF_BLK, + so, asoc, stcb->asoc.total_output_queue_size); + } } SOCKBUF_UNLOCK(&so->so_snd); if (stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) { @@ -11658,16 +11672,16 @@ skip_out_eof: * Don't send anything and let SACKs drive out the * data unless wen have a "full" segment to send. */ -#ifdef SCTP_NAGLE_LOGGING - sctp_log_nagle_event(stcb, SCTP_NAGLE_APPLIED); -#endif + if (sctp_logging_level & SCTP_NAGLE_LOGGING_ENABLE) { + sctp_log_nagle_event(stcb, SCTP_NAGLE_APPLIED); + } SCTP_STAT_INCR(sctps_naglequeued); nagle_applies = 1; } else { -#ifdef SCTP_NAGLE_LOGGING - if (sctp_is_feature_off(inp, SCTP_PCB_FLAGS_NODELAY)) - sctp_log_nagle_event(stcb, SCTP_NAGLE_SKIPPED); -#endif + if (sctp_logging_level & SCTP_NAGLE_LOGGING_ENABLE) { + if (sctp_is_feature_off(inp, SCTP_PCB_FLAGS_NODELAY)) + sctp_log_nagle_event(stcb, SCTP_NAGLE_SKIPPED); + } SCTP_STAT_INCR(sctps_naglesent); nagle_applies = 0; } |