From 90fed1d88e0a0f1e1a33904c4b71fbb9c29f46c6 Mon Sep 17 00:00:00 2001 From: Michael Tuexen Date: Wed, 26 Jan 2011 19:49:03 +0000 Subject: [PATCH] Change infrastructure for SCTP_MAX_BURST to allow compliance with the latest socket API ID. Especially it can be disabled. Full compliance needs changing the structure used in the socket option. Since this breaks the API, it will be a seperate commit which will not be MFCed to stable/8. MFC after: 3 months. --- sys/netinet/sctp_cc_functions.c | 7 +++-- sys/netinet/sctp_output.c | 53 ++++++++++++++++++--------------- sys/netinet/sctp_pcb.h | 2 +- sys/netinet/sctp_structs.h | 2 +- sys/netinet/sctp_sysctl.h | 2 +- sys/netinet/sctp_usrreq.c | 10 ++++--- 6 files changed, 43 insertions(+), 33 deletions(-) diff --git a/sys/netinet/sctp_cc_functions.c b/sys/netinet/sctp_cc_functions.c index 272e05b95bbe..28bbe5a5ced5 100644 --- a/sys/netinet/sctp_cc_functions.c +++ b/sys/netinet/sctp_cc_functions.c @@ -601,8 +601,11 @@ sctp_cwnd_update_after_packet_dropped(struct sctp_tcb *stcb, * Take 1/4 of the space left or max burst up .. whichever * is less. */ - incr = min((bw_avail - *on_queue) >> 2, - stcb->asoc.max_burst * net->mtu); + incr = (bw_avail - *on_queue) >> 2; + if ((stcb->asoc.max_burst > 0) && + (stcb->asoc.max_burst * net->mtu < incr)) { + incr = stcb->asoc.max_burst * net->mtu; + } net->cwnd += incr; } if (net->cwnd > bw_avail) { diff --git a/sys/netinet/sctp_output.c b/sys/netinet/sctp_output.c index 027204b5c18b..20eb35441bfb 100644 --- a/sys/netinet/sctp_output.c +++ b/sys/netinet/sctp_output.c @@ -9322,7 +9322,7 @@ sctp_chunk_output(struct sctp_inpcb *inp, struct sctp_association *asoc; struct sctp_nets *net; int error = 0, num_out = 0, tot_out = 0, ret = 0, reason_code = 0, - burst_cnt = 0, burst_limit = 0; + burst_cnt = 0; struct timeval now; int now_filled = 0; int nagle_on = 0; @@ -9425,12 +9425,11 @@ sctp_chunk_output(struct sctp_inpcb *inp, &now, &now_filled, frag_point, so_locked); return; } - if (tot_frs > asoc->max_burst) { + if ((asoc->max_burst > 0) && (tot_frs > asoc->max_burst)) { /* Hit FR burst limit */ return; } if ((num_out == 0) && (ret == 0)) { - /* No more retrans to send */ break; } @@ -9439,7 +9438,6 @@ sctp_chunk_output(struct sctp_inpcb *inp, sctp_auditing(12, inp, stcb, NULL); #endif /* Check for bad destinations, if they exist move chunks around. */ - burst_limit = asoc->max_burst; TAILQ_FOREACH(net, &asoc->nets, sctp_next) { if ((net->dest_state & SCTP_ADDR_NOT_REACHABLE) == SCTP_ADDR_NOT_REACHABLE) { @@ -9468,24 +9466,29 @@ sctp_chunk_output(struct sctp_inpcb *inp, * { burst_limit = asoc->max_burst * * SCTP_SAT_NETWORK_BURST_INCR; } */ - if (SCTP_BASE_SYSCTL(sctp_use_cwnd_based_maxburst)) { - if ((net->flight_size + (burst_limit * net->mtu)) < net->cwnd) { - /* - * JRS - Use the congestion control - * given in the congestion control - * module - */ - asoc->cc_functions.sctp_cwnd_update_after_output(stcb, net, burst_limit); - if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LOG_MAXBURST_ENABLE) { - sctp_log_maxburst(stcb, net, 0, burst_limit, SCTP_MAX_BURST_APPLIED); + if (asoc->max_burst > 0) { + if (SCTP_BASE_SYSCTL(sctp_use_cwnd_based_maxburst)) { + if ((net->flight_size + (asoc->max_burst * net->mtu)) < net->cwnd) { + /* + * JRS - Use the congestion + * control given in the + * congestion control module + */ + asoc->cc_functions.sctp_cwnd_update_after_output(stcb, net, asoc->max_burst); + if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LOG_MAXBURST_ENABLE) { + sctp_log_maxburst(stcb, net, 0, asoc->max_burst, SCTP_MAX_BURST_APPLIED); + } + SCTP_STAT_INCR(sctps_maxburstqueued); + } + net->fast_retran_ip = 0; + } else { + if (net->flight_size == 0) { + /* + * Should be decaying the + * cwnd here + */ + ; } - SCTP_STAT_INCR(sctps_maxburstqueued); - } - net->fast_retran_ip = 0; - } else { - if (net->flight_size == 0) { - /* Should be decaying the cwnd here */ - ; } } } @@ -9540,11 +9543,13 @@ sctp_chunk_output(struct sctp_inpcb *inp, /* Nothing left to send */ break; } - } while (num_out && (SCTP_BASE_SYSCTL(sctp_use_cwnd_based_maxburst) || - (burst_cnt < burst_limit))); + } while (num_out && + ((asoc->max_burst == 0) || + SCTP_BASE_SYSCTL(sctp_use_cwnd_based_maxburst) || + (burst_cnt < asoc->max_burst))); if (SCTP_BASE_SYSCTL(sctp_use_cwnd_based_maxburst) == 0) { - if (burst_cnt >= burst_limit) { + if ((asoc->max_burst > 0) && (burst_cnt >= asoc->max_burst)) { SCTP_STAT_INCR(sctps_maxburstqueued); asoc->burst_limit_applied = 1; if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LOG_MAXBURST_ENABLE) { diff --git a/sys/netinet/sctp_pcb.h b/sys/netinet/sctp_pcb.h index 29f724c7b471..e199eb7154bc 100644 --- a/sys/netinet/sctp_pcb.h +++ b/sys/netinet/sctp_pcb.h @@ -317,7 +317,7 @@ struct sctp_pcb { uint32_t initial_sequence_debug; uint32_t adaptation_layer_indicator; uint32_t store_at; - uint8_t max_burst; + uint32_t max_burst; char current_secret_number; char last_secret_number; }; diff --git a/sys/netinet/sctp_structs.h b/sys/netinet/sctp_structs.h index 639a6cea94ff..be2c213699f0 100644 --- a/sys/netinet/sctp_structs.h +++ b/sys/netinet/sctp_structs.h @@ -1058,7 +1058,7 @@ struct sctp_association { uint8_t send_sack; /* max burst after fast retransmit completes */ - uint8_t max_burst; + uint32_t max_burst; uint8_t sat_network; /* RTT is in range of sat net or greater */ uint8_t sat_network_lockout; /* lockout code */ diff --git a/sys/netinet/sctp_sysctl.h b/sys/netinet/sctp_sysctl.h index ea17af1b4256..fe16ba883338 100644 --- a/sys/netinet/sctp_sysctl.h +++ b/sys/netinet/sctp_sysctl.h @@ -184,7 +184,7 @@ struct sctp_sysctl { /* maxburst: Default max burst for sctp endpoints */ #define SCTPCTL_MAXBURST_DESC "Default max burst for sctp endpoints" -#define SCTPCTL_MAXBURST_MIN 1 +#define SCTPCTL_MAXBURST_MIN 0 #define SCTPCTL_MAXBURST_MAX 0xFFFFFFFF #define SCTPCTL_MAXBURST_DEFAULT SCTP_DEF_MAX_BURST diff --git a/sys/netinet/sctp_usrreq.c b/sys/netinet/sctp_usrreq.c index d5d50e4b7f70..9db33fb9895b 100644 --- a/sys/netinet/sctp_usrreq.c +++ b/sys/netinet/sctp_usrreq.c @@ -1972,7 +1972,11 @@ flags_out: SCTP_CHECK_AND_CAST(value, optval, uint8_t, *optsize); SCTP_INP_RLOCK(inp); - *value = inp->sctp_ep.max_burst; + if (inp->sctp_ep.max_burst < 256) { + *value = inp->sctp_ep.max_burst; + } else { + *value = 255; + } SCTP_INP_RUNLOCK(inp); *optsize = sizeof(uint8_t); } @@ -3591,9 +3595,7 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize, SCTP_CHECK_AND_CAST(burst, optval, uint8_t, optsize); SCTP_INP_WLOCK(inp); - if (*burst) { - inp->sctp_ep.max_burst = *burst; - } + inp->sctp_ep.max_burst = *burst; SCTP_INP_WUNLOCK(inp); } break;