mirror of
https://github.com/freebsd/freebsd-src
synced 2024-09-29 05:04:50 +00:00
Fix the switching on/off of CMT using sysctl and socket option.
Fix the switching on/off of PF and NR-SACKs using sysctl. Add minor improvement in handling malloc failures. Improve the address checks when sending. MFC after: 4 weeks
This commit is contained in:
parent
6d8fedda2c
commit
20083c2eb1
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=211944
|
@ -155,10 +155,8 @@ struct sctp_paramhdr {
|
|||
/* CMT ON/OFF socket option */
|
||||
#define SCTP_CMT_ON_OFF 0x00001200
|
||||
#define SCTP_CMT_USE_DAC 0x00001201
|
||||
/* EY - NR_SACK on/off socket option */
|
||||
#define SCTP_NR_SACK_ON_OFF 0x00001300
|
||||
/* JRS - Pluggable Congestion Control Socket option */
|
||||
#define SCTP_PLUGGABLE_CC 0x00001202
|
||||
#define SCTP_PLUGGABLE_CC 0x00001202
|
||||
|
||||
/* read only */
|
||||
#define SCTP_GET_SNDBUF_USE 0x00001101
|
||||
|
|
|
@ -71,7 +71,8 @@ sctp_cwnd_update_after_fr(struct sctp_tcb *stcb,
|
|||
* (net->fast_retran_loss_recovery == 0)))
|
||||
*/
|
||||
TAILQ_FOREACH(net, &asoc->nets, sctp_next) {
|
||||
if ((asoc->fast_retran_loss_recovery == 0) || (SCTP_BASE_SYSCTL(sctp_cmt_on_off) == 1)) {
|
||||
if ((asoc->fast_retran_loss_recovery == 0) ||
|
||||
(asoc->sctp_cmt_on_off == 1)) {
|
||||
/* out of a RFC2582 Fast recovery window? */
|
||||
if (net->net_ack > 0) {
|
||||
/*
|
||||
|
@ -232,11 +233,11 @@ sctp_cwnd_update_after_sack(struct sctp_tcb *stcb,
|
|||
*
|
||||
* Should we stop any running T3 timer here?
|
||||
*/
|
||||
if (SCTP_BASE_SYSCTL(sctp_cmt_on_off) &&
|
||||
SCTP_BASE_SYSCTL(sctp_cmt_pf) &&
|
||||
if ((asoc->sctp_cmt_on_off == 1) &&
|
||||
(asoc->sctp_cmt_pf > 0) &&
|
||||
((net->dest_state & SCTP_ADDR_PF) == SCTP_ADDR_PF)) {
|
||||
net->dest_state &= ~SCTP_ADDR_PF;
|
||||
net->cwnd = net->mtu * SCTP_BASE_SYSCTL(sctp_cmt_pf);
|
||||
net->cwnd = net->mtu * asoc->sctp_cmt_pf;
|
||||
SCTPDBG(SCTP_DEBUG_INDATA1, "Destination %p moved from PF to reachable with cwnd %d.\n",
|
||||
net, net->cwnd);
|
||||
/*
|
||||
|
@ -260,7 +261,9 @@ sctp_cwnd_update_after_sack(struct sctp_tcb *stcb,
|
|||
*/
|
||||
#endif
|
||||
|
||||
if (asoc->fast_retran_loss_recovery && will_exit == 0 && SCTP_BASE_SYSCTL(sctp_cmt_on_off) == 0) {
|
||||
if (asoc->fast_retran_loss_recovery &&
|
||||
(will_exit == 0) &&
|
||||
(asoc->sctp_cmt_on_off == 0)) {
|
||||
/*
|
||||
* If we are in loss recovery we skip any cwnd
|
||||
* update
|
||||
|
@ -271,7 +274,8 @@ sctp_cwnd_update_after_sack(struct sctp_tcb *stcb,
|
|||
* CMT: CUC algorithm. Update cwnd if pseudo-cumack has
|
||||
* moved.
|
||||
*/
|
||||
if (accum_moved || (SCTP_BASE_SYSCTL(sctp_cmt_on_off) && net->new_pseudo_cumack)) {
|
||||
if (accum_moved ||
|
||||
((asoc->sctp_cmt_on_off == 1) && net->new_pseudo_cumack)) {
|
||||
/* If the cumulative ack moved we can proceed */
|
||||
if (net->cwnd <= net->ssthresh) {
|
||||
/* We are in slow start */
|
||||
|
@ -697,7 +701,8 @@ sctp_hs_cwnd_update_after_fr(struct sctp_tcb *stcb,
|
|||
* (net->fast_retran_loss_recovery == 0)))
|
||||
*/
|
||||
TAILQ_FOREACH(net, &asoc->nets, sctp_next) {
|
||||
if ((asoc->fast_retran_loss_recovery == 0) || (SCTP_BASE_SYSCTL(sctp_cmt_on_off) == 1)) {
|
||||
if ((asoc->fast_retran_loss_recovery == 0) ||
|
||||
(asoc->sctp_cmt_on_off == 1)) {
|
||||
/* out of a RFC2582 Fast recovery window? */
|
||||
if (net->net_ack > 0) {
|
||||
/*
|
||||
|
@ -850,11 +855,11 @@ sctp_hs_cwnd_update_after_sack(struct sctp_tcb *stcb,
|
|||
*
|
||||
* Should we stop any running T3 timer here?
|
||||
*/
|
||||
if (SCTP_BASE_SYSCTL(sctp_cmt_on_off) &&
|
||||
SCTP_BASE_SYSCTL(sctp_cmt_pf) &&
|
||||
if ((asoc->sctp_cmt_on_off == 1) &&
|
||||
(asoc->sctp_cmt_pf > 0) &&
|
||||
((net->dest_state & SCTP_ADDR_PF) == SCTP_ADDR_PF)) {
|
||||
net->dest_state &= ~SCTP_ADDR_PF;
|
||||
net->cwnd = net->mtu * SCTP_BASE_SYSCTL(sctp_cmt_pf);
|
||||
net->cwnd = net->mtu * asoc->sctp_cmt_pf;
|
||||
SCTPDBG(SCTP_DEBUG_INDATA1, "Destination %p moved from PF to reachable with cwnd %d.\n",
|
||||
net, net->cwnd);
|
||||
/*
|
||||
|
@ -878,7 +883,9 @@ sctp_hs_cwnd_update_after_sack(struct sctp_tcb *stcb,
|
|||
*/
|
||||
#endif
|
||||
|
||||
if (asoc->fast_retran_loss_recovery && will_exit == 0 && SCTP_BASE_SYSCTL(sctp_cmt_on_off) == 0) {
|
||||
if (asoc->fast_retran_loss_recovery &&
|
||||
(will_exit == 0) &&
|
||||
(asoc->sctp_cmt_on_off == 0)) {
|
||||
/*
|
||||
* If we are in loss recovery we skip any cwnd
|
||||
* update
|
||||
|
@ -889,7 +896,8 @@ sctp_hs_cwnd_update_after_sack(struct sctp_tcb *stcb,
|
|||
* CMT: CUC algorithm. Update cwnd if pseudo-cumack has
|
||||
* moved.
|
||||
*/
|
||||
if (accum_moved || (SCTP_BASE_SYSCTL(sctp_cmt_on_off) && net->new_pseudo_cumack)) {
|
||||
if (accum_moved ||
|
||||
((asoc->sctp_cmt_on_off == 1) && net->new_pseudo_cumack)) {
|
||||
/* If the cumulative ack moved we can proceed */
|
||||
if (net->cwnd <= net->ssthresh) {
|
||||
/* We are in slow start */
|
||||
|
@ -1333,11 +1341,11 @@ sctp_htcp_cwnd_update_after_sack(struct sctp_tcb *stcb,
|
|||
*
|
||||
* Should we stop any running T3 timer here?
|
||||
*/
|
||||
if (SCTP_BASE_SYSCTL(sctp_cmt_on_off) &&
|
||||
SCTP_BASE_SYSCTL(sctp_cmt_pf) &&
|
||||
if ((asoc->sctp_cmt_on_off == 1) &&
|
||||
(asoc->sctp_cmt_pf > 0) &&
|
||||
((net->dest_state & SCTP_ADDR_PF) == SCTP_ADDR_PF)) {
|
||||
net->dest_state &= ~SCTP_ADDR_PF;
|
||||
net->cwnd = net->mtu * SCTP_BASE_SYSCTL(sctp_cmt_pf);
|
||||
net->cwnd = net->mtu * asoc->sctp_cmt_pf;
|
||||
SCTPDBG(SCTP_DEBUG_INDATA1, "Destination %p moved from PF to reachable with cwnd %d.\n",
|
||||
net, net->cwnd);
|
||||
/*
|
||||
|
@ -1361,7 +1369,9 @@ sctp_htcp_cwnd_update_after_sack(struct sctp_tcb *stcb,
|
|||
*/
|
||||
#endif
|
||||
|
||||
if (asoc->fast_retran_loss_recovery && will_exit == 0 && SCTP_BASE_SYSCTL(sctp_cmt_on_off) == 0) {
|
||||
if (asoc->fast_retran_loss_recovery &&
|
||||
will_exit == 0 &&
|
||||
(asoc->sctp_cmt_on_off == 0)) {
|
||||
/*
|
||||
* If we are in loss recovery we skip any cwnd
|
||||
* update
|
||||
|
@ -1372,7 +1382,8 @@ sctp_htcp_cwnd_update_after_sack(struct sctp_tcb *stcb,
|
|||
* CMT: CUC algorithm. Update cwnd if pseudo-cumack has
|
||||
* moved.
|
||||
*/
|
||||
if (accum_moved || (SCTP_BASE_SYSCTL(sctp_cmt_on_off) && net->new_pseudo_cumack)) {
|
||||
if (accum_moved ||
|
||||
((asoc->sctp_cmt_on_off == 1) && net->new_pseudo_cumack)) {
|
||||
htcp_cong_avoid(stcb, net);
|
||||
measure_achieved_throughput(stcb, net);
|
||||
} else {
|
||||
|
@ -1412,7 +1423,8 @@ sctp_htcp_cwnd_update_after_fr(struct sctp_tcb *stcb,
|
|||
* (net->fast_retran_loss_recovery == 0)))
|
||||
*/
|
||||
TAILQ_FOREACH(net, &asoc->nets, sctp_next) {
|
||||
if ((asoc->fast_retran_loss_recovery == 0) || (SCTP_BASE_SYSCTL(sctp_cmt_on_off) == 1)) {
|
||||
if ((asoc->fast_retran_loss_recovery == 0) ||
|
||||
(asoc->sctp_cmt_on_off == 1)) {
|
||||
/* out of a RFC2582 Fast recovery window? */
|
||||
if (net->net_ack > 0) {
|
||||
/*
|
||||
|
|
|
@ -2475,7 +2475,7 @@ sctp_sack_check(struct sctp_tcb *stcb, int was_a_gap, int *abort_flag)
|
|||
(stcb->asoc.data_pkts_seen >= stcb->asoc.sack_freq) /* hit limit of pkts */
|
||||
) {
|
||||
|
||||
if ((SCTP_BASE_SYSCTL(sctp_cmt_on_off)) &&
|
||||
if ((stcb->asoc.sctp_cmt_on_off == 1) &&
|
||||
(SCTP_BASE_SYSCTL(sctp_cmt_use_dac)) &&
|
||||
(stcb->asoc.send_sack == 0) &&
|
||||
(stcb->asoc.numduptsns == 0) &&
|
||||
|
@ -3265,7 +3265,8 @@ sctp_strike_gap_ack_chunks(struct sctp_tcb *stcb, struct sctp_association *asoc,
|
|||
}
|
||||
|
||||
/* CMT DAC algo: finding out if SACK is a mixed SACK */
|
||||
if (SCTP_BASE_SYSCTL(sctp_cmt_on_off) && SCTP_BASE_SYSCTL(sctp_cmt_use_dac)) {
|
||||
if ((asoc->sctp_cmt_on_off == 1) &&
|
||||
SCTP_BASE_SYSCTL(sctp_cmt_use_dac)) {
|
||||
TAILQ_FOREACH(net, &asoc->nets, sctp_next) {
|
||||
if (net->saw_newack)
|
||||
num_dests_sacked++;
|
||||
|
@ -3381,7 +3382,8 @@ sctp_strike_gap_ack_chunks(struct sctp_tcb *stcb, struct sctp_association *asoc,
|
|||
if (tp1->sent < SCTP_DATAGRAM_RESEND) {
|
||||
tp1->sent++;
|
||||
}
|
||||
if (SCTP_BASE_SYSCTL(sctp_cmt_on_off) && SCTP_BASE_SYSCTL(sctp_cmt_use_dac)) {
|
||||
if ((asoc->sctp_cmt_on_off == 1) &&
|
||||
SCTP_BASE_SYSCTL(sctp_cmt_use_dac)) {
|
||||
/*
|
||||
* CMT DAC algorithm: If SACK flag is set to
|
||||
* 0, then lowest_newack test will not pass
|
||||
|
@ -3405,7 +3407,8 @@ sctp_strike_gap_ack_chunks(struct sctp_tcb *stcb, struct sctp_association *asoc,
|
|||
tp1->sent++;
|
||||
}
|
||||
}
|
||||
} else if ((tp1->rec.data.doing_fast_retransmit) && (SCTP_BASE_SYSCTL(sctp_cmt_on_off) == 0)) {
|
||||
} else if ((tp1->rec.data.doing_fast_retransmit) &&
|
||||
(asoc->sctp_cmt_on_off == 0)) {
|
||||
/*
|
||||
* For those that have done a FR we must take
|
||||
* special consideration if we strike. I.e the
|
||||
|
@ -3445,7 +3448,8 @@ sctp_strike_gap_ack_chunks(struct sctp_tcb *stcb, struct sctp_association *asoc,
|
|||
tp1->sent++;
|
||||
}
|
||||
strike_flag = 1;
|
||||
if (SCTP_BASE_SYSCTL(sctp_cmt_on_off) && SCTP_BASE_SYSCTL(sctp_cmt_use_dac)) {
|
||||
if ((asoc->sctp_cmt_on_off == 1) &&
|
||||
SCTP_BASE_SYSCTL(sctp_cmt_use_dac)) {
|
||||
/*
|
||||
* CMT DAC algorithm: If
|
||||
* SACK flag is set to 0,
|
||||
|
@ -3505,7 +3509,8 @@ sctp_strike_gap_ack_chunks(struct sctp_tcb *stcb, struct sctp_association *asoc,
|
|||
if (tp1->sent < SCTP_DATAGRAM_RESEND) {
|
||||
tp1->sent++;
|
||||
}
|
||||
if (SCTP_BASE_SYSCTL(sctp_cmt_on_off) && SCTP_BASE_SYSCTL(sctp_cmt_use_dac)) {
|
||||
if ((asoc->sctp_cmt_on_off == 1) &&
|
||||
SCTP_BASE_SYSCTL(sctp_cmt_use_dac)) {
|
||||
/*
|
||||
* CMT DAC algorithm: If SACK flag is set to
|
||||
* 0, then lowest_newack test will not pass
|
||||
|
@ -3584,7 +3589,7 @@ sctp_strike_gap_ack_chunks(struct sctp_tcb *stcb, struct sctp_association *asoc,
|
|||
SCTP_STAT_INCR(sctps_sendmultfastretrans);
|
||||
}
|
||||
sctp_ucount_incr(stcb->asoc.sent_queue_retran_cnt);
|
||||
if (SCTP_BASE_SYSCTL(sctp_cmt_on_off)) {
|
||||
if (asoc->sctp_cmt_on_off == 1) {
|
||||
/*
|
||||
* CMT: Using RTX_SSTHRESH policy for CMT.
|
||||
* If CMT is being used, then pick dest with
|
||||
|
@ -3593,7 +3598,7 @@ sctp_strike_gap_ack_chunks(struct sctp_tcb *stcb, struct sctp_association *asoc,
|
|||
tp1->no_fr_allowed = 1;
|
||||
alt = tp1->whoTo;
|
||||
/* sa_ignore NO_NULL_CHK */
|
||||
if (SCTP_BASE_SYSCTL(sctp_cmt_on_off) && SCTP_BASE_SYSCTL(sctp_cmt_pf)) {
|
||||
if (asoc->sctp_cmt_pf > 0) {
|
||||
/*
|
||||
* JRS 5/18/07 - If CMT PF is on,
|
||||
* use the PF version of
|
||||
|
@ -4800,7 +4805,7 @@ sctp_handle_sack(struct mbuf *m, int offset_seg, int offset_dup,
|
|||
/*******************************************/
|
||||
/* cancel ALL T3-send timer if accum moved */
|
||||
/*******************************************/
|
||||
if (SCTP_BASE_SYSCTL(sctp_cmt_on_off)) {
|
||||
if (asoc->sctp_cmt_on_off == 1) {
|
||||
TAILQ_FOREACH(net, &asoc->nets, sctp_next) {
|
||||
if (net->new_pseudo_cumack)
|
||||
sctp_timer_stop(SCTP_TIMER_TYPE_SEND, stcb->sctp_ep,
|
||||
|
@ -5100,7 +5105,9 @@ sctp_handle_sack(struct mbuf *m, int offset_seg, int offset_dup,
|
|||
* to be done. Setting this_sack_lowest_newack to the cum_ack will
|
||||
* automatically ensure that.
|
||||
*/
|
||||
if (SCTP_BASE_SYSCTL(sctp_cmt_on_off) && SCTP_BASE_SYSCTL(sctp_cmt_use_dac) && (cmt_dac_flag == 0)) {
|
||||
if ((asoc->sctp_cmt_on_off == 1) &&
|
||||
SCTP_BASE_SYSCTL(sctp_cmt_use_dac) &&
|
||||
(cmt_dac_flag == 0)) {
|
||||
this_sack_lowest_newack = cum_ack;
|
||||
}
|
||||
if ((num_seg > 0) || (num_nr_seg > 0)) {
|
||||
|
|
|
@ -618,16 +618,16 @@ sctp_handle_heartbeat_ack(struct sctp_heartbeat_chunk *cp,
|
|||
* timer is running, for the destination, stop the timer because a
|
||||
* PF-heartbeat was received.
|
||||
*/
|
||||
if (SCTP_BASE_SYSCTL(sctp_cmt_on_off) &&
|
||||
SCTP_BASE_SYSCTL(sctp_cmt_pf) &&
|
||||
(net->dest_state & SCTP_ADDR_PF) == SCTP_ADDR_PF) {
|
||||
if ((stcb->asoc.sctp_cmt_on_off == 1) &&
|
||||
(stcb->asoc.sctp_cmt_pf > 0) &&
|
||||
((net->dest_state & SCTP_ADDR_PF) == SCTP_ADDR_PF)) {
|
||||
if (SCTP_OS_TIMER_PENDING(&net->rxt_timer.timer)) {
|
||||
sctp_timer_stop(SCTP_TIMER_TYPE_SEND, stcb->sctp_ep,
|
||||
stcb, net,
|
||||
SCTP_FROM_SCTP_INPUT + SCTP_LOC_5);
|
||||
}
|
||||
net->dest_state &= ~SCTP_ADDR_PF;
|
||||
net->cwnd = net->mtu * SCTP_BASE_SYSCTL(sctp_cmt_pf);
|
||||
net->cwnd = net->mtu * stcb->asoc.sctp_cmt_pf;
|
||||
SCTPDBG(SCTP_DEBUG_INPUT1, "Destination %p moved from PF to reachable with cwnd %d.\n",
|
||||
net, net->cwnd);
|
||||
}
|
||||
|
@ -2723,6 +2723,7 @@ sctp_handle_cookie_echo(struct mbuf *m, int iphlen, int offset,
|
|||
inp->sctp_mobility_features = (*inp_p)->sctp_mobility_features;
|
||||
inp->sctp_socket = so;
|
||||
inp->sctp_frag_point = (*inp_p)->sctp_frag_point;
|
||||
inp->sctp_cmt_on_off = (*inp_p)->sctp_cmt_on_off;
|
||||
inp->partial_delivery_point = (*inp_p)->partial_delivery_point;
|
||||
inp->sctp_context = (*inp_p)->sctp_context;
|
||||
inp->inp_starting_point_for_iterator = NULL;
|
||||
|
@ -3067,7 +3068,7 @@ process_chunk_drop(struct sctp_tcb *stcb, struct sctp_chunk_desc *desc,
|
|||
struct sctp_nets *net, uint8_t flg)
|
||||
{
|
||||
switch (desc->chunk_type) {
|
||||
case SCTP_DATA:
|
||||
case SCTP_DATA:
|
||||
/* find the tsn to resend (possibly */
|
||||
{
|
||||
uint32_t tsn;
|
||||
|
@ -4586,8 +4587,6 @@ __attribute__((noinline))
|
|||
return (NULL);
|
||||
break;
|
||||
case SCTP_SELECTIVE_ACK:
|
||||
SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_SACK\n");
|
||||
SCTP_STAT_INCR(sctps_recvsacks);
|
||||
{
|
||||
struct sctp_sack_chunk *sack;
|
||||
int abort_now = 0;
|
||||
|
@ -4597,6 +4596,8 @@ __attribute__((noinline))
|
|||
int offset_seg, offset_dup;
|
||||
int nonce_sum_flag;
|
||||
|
||||
SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_SACK\n");
|
||||
SCTP_STAT_INCR(sctps_recvsacks);
|
||||
if (stcb == NULL) {
|
||||
SCTPDBG(SCTP_DEBUG_INDATA1, "No stcb when processing SACK chunk\n");
|
||||
break;
|
||||
|
@ -4673,8 +4674,6 @@ __attribute__((noinline))
|
|||
* nr_sack chunk
|
||||
*/
|
||||
case SCTP_NR_SELECTIVE_ACK:
|
||||
SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_NR_SACK\n");
|
||||
SCTP_STAT_INCR(sctps_recvsacks);
|
||||
{
|
||||
struct sctp_nr_sack_chunk *nr_sack;
|
||||
int abort_now = 0;
|
||||
|
@ -4684,13 +4683,10 @@ __attribute__((noinline))
|
|||
int offset_seg, offset_dup;
|
||||
int nonce_sum_flag;
|
||||
|
||||
/*
|
||||
* EY nr_sacks have not been negotiated but
|
||||
* the peer end sent an nr_sack, silently
|
||||
* discard the chunk
|
||||
*/
|
||||
if (!(SCTP_BASE_SYSCTL(sctp_nr_sack_on_off) &&
|
||||
stcb->asoc.peer_supports_nr_sack)) {
|
||||
SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_NR_SACK\n");
|
||||
SCTP_STAT_INCR(sctps_recvsacks);
|
||||
if ((stcb->asoc.sctp_nr_sack_on_off == 0) ||
|
||||
(stcb->asoc.peer_supports_nr_sack == 0)) {
|
||||
goto unknown_chunk;
|
||||
}
|
||||
if (stcb == NULL) {
|
||||
|
|
|
@ -3686,7 +3686,8 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp,
|
|||
* Stop any running T3
|
||||
* timers here?
|
||||
*/
|
||||
if (SCTP_BASE_SYSCTL(sctp_cmt_on_off) && SCTP_BASE_SYSCTL(sctp_cmt_pf)) {
|
||||
if ((stcb->asoc.sctp_cmt_on_off == 1) &&
|
||||
(stcb->asoc.sctp_cmt_pf > 0)) {
|
||||
net->dest_state &= ~SCTP_ADDR_PF;
|
||||
SCTPDBG(SCTP_DEBUG_OUTPUT1, "Destination %p moved from PF to unreachable.\n",
|
||||
net);
|
||||
|
@ -4323,11 +4324,7 @@ sctp_send_initiate(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int so_locked
|
|||
if (!SCTP_BASE_SYSCTL(sctp_auth_disable)) {
|
||||
pr_supported->chunk_types[num_ext++] = SCTP_AUTHENTICATION;
|
||||
}
|
||||
/*
|
||||
* EY if the initiator supports nr_sacks, need to report that to
|
||||
* responder in INIT chunk
|
||||
*/
|
||||
if (SCTP_BASE_SYSCTL(sctp_nr_sack_on_off)) {
|
||||
if (stcb->asoc.sctp_nr_sack_on_off == 1) {
|
||||
pr_supported->chunk_types[num_ext++] = SCTP_NR_SELECTIVE_ACK;
|
||||
}
|
||||
p_len = sizeof(*pr_supported) + num_ext;
|
||||
|
@ -5447,10 +5444,6 @@ sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
|
|||
pr_supported->chunk_types[num_ext++] = SCTP_STREAM_RESET;
|
||||
if (!SCTP_BASE_SYSCTL(sctp_auth_disable))
|
||||
pr_supported->chunk_types[num_ext++] = SCTP_AUTHENTICATION;
|
||||
/*
|
||||
* EY if the sysctl variable is set, tell the assoc. initiator that
|
||||
* we do nr_sack
|
||||
*/
|
||||
if (SCTP_BASE_SYSCTL(sctp_nr_sack_on_off))
|
||||
pr_supported->chunk_types[num_ext++] = SCTP_NR_SELECTIVE_ACK;
|
||||
p_len = sizeof(*pr_supported) + num_ext;
|
||||
|
@ -7267,7 +7260,8 @@ sctp_fill_outqueue(struct sctp_tcb *stcb,
|
|||
if (sp == NULL) {
|
||||
break;
|
||||
}
|
||||
if ((sp->net != net) && (SCTP_BASE_SYSCTL(sctp_cmt_on_off) == 0)) {
|
||||
if ((sp->net != net) &&
|
||||
(asoc->sctp_cmt_on_off == 0)) {
|
||||
/* none for this network */
|
||||
if (locked) {
|
||||
break;
|
||||
|
@ -7326,11 +7320,11 @@ sctp_fill_outqueue(struct sctp_tcb *stcb,
|
|||
*quit_now = 1;
|
||||
|
||||
if (total_moved == 0) {
|
||||
if ((SCTP_BASE_SYSCTL(sctp_cmt_on_off) == 0) &&
|
||||
if ((stcb->asoc.sctp_cmt_on_off == 0) &&
|
||||
(net == stcb->asoc.primary_destination)) {
|
||||
/* ran dry for primary network net */
|
||||
SCTP_STAT_INCR(sctps_primary_randry);
|
||||
} else if (SCTP_BASE_SYSCTL(sctp_cmt_on_off)) {
|
||||
} else if (stcb->asoc.sctp_cmt_on_off == 1) {
|
||||
/* ran dry with CMT on */
|
||||
SCTP_STAT_INCR(sctps_cmt_randry);
|
||||
}
|
||||
|
@ -7363,7 +7357,8 @@ sctp_move_to_an_alt(struct sctp_tcb *stcb,
|
|||
* destination using the PF algorithm for finding alternate
|
||||
* destinations.
|
||||
*/
|
||||
if (SCTP_BASE_SYSCTL(sctp_cmt_on_off) && SCTP_BASE_SYSCTL(sctp_cmt_pf)) {
|
||||
if ((asoc->sctp_cmt_on_off == 1) &&
|
||||
(asoc->sctp_cmt_pf > 0)) {
|
||||
a_net = sctp_find_alternate_net(stcb, net, 2);
|
||||
} else {
|
||||
a_net = sctp_find_alternate_net(stcb, net, 0);
|
||||
|
@ -7499,7 +7494,8 @@ sctp_med_chunk_output(struct sctp_inpcb *inp,
|
|||
}
|
||||
continue;
|
||||
}
|
||||
if ((SCTP_BASE_SYSCTL(sctp_cmt_on_off) == 0) && (net->ref_count < 2)) {
|
||||
if ((asoc->sctp_cmt_on_off == 0) &&
|
||||
(net->ref_count < 2)) {
|
||||
/* nothing can be in queue for this guy */
|
||||
if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_CWND_LOGGING_ENABLE) {
|
||||
sctp_log_cwnd(stcb, net, 2,
|
||||
|
@ -7534,7 +7530,7 @@ sctp_med_chunk_output(struct sctp_inpcb *inp,
|
|||
*reason_code = 8;
|
||||
return (0);
|
||||
}
|
||||
if (SCTP_BASE_SYSCTL(sctp_cmt_on_off)) {
|
||||
if (asoc->sctp_cmt_on_off == 1) {
|
||||
/* get the last start point */
|
||||
start_at = asoc->last_net_cmt_send_started;
|
||||
if (start_at == NULL) {
|
||||
|
@ -7560,7 +7556,7 @@ sctp_med_chunk_output(struct sctp_inpcb *inp,
|
|||
break;
|
||||
}
|
||||
tsns_sent = 0xa;
|
||||
if ((SCTP_BASE_SYSCTL(sctp_cmt_on_off) == 0) && (net->ref_count < 2)) {
|
||||
if ((asoc->sctp_cmt_on_off == 0) && (net->ref_count < 2)) {
|
||||
/*
|
||||
* Ref-count of 1 so we cannot have data or control
|
||||
* queued to this address. Skip it (non-CMT).
|
||||
|
@ -8034,15 +8030,15 @@ sctp_med_chunk_output(struct sctp_inpcb *inp,
|
|||
}
|
||||
}
|
||||
/* JRI: if dest is in PF state, do not send data to it */
|
||||
if (SCTP_BASE_SYSCTL(sctp_cmt_on_off) &&
|
||||
SCTP_BASE_SYSCTL(sctp_cmt_pf) &&
|
||||
if ((asoc->sctp_cmt_on_off == 1) &&
|
||||
(asoc->sctp_cmt_pf > 0) &&
|
||||
(net->dest_state & SCTP_ADDR_PF)) {
|
||||
goto no_data_fill;
|
||||
}
|
||||
if (net->flight_size >= net->cwnd) {
|
||||
goto no_data_fill;
|
||||
}
|
||||
if ((SCTP_BASE_SYSCTL(sctp_cmt_on_off)) &&
|
||||
if ((asoc->sctp_cmt_on_off == 1) &&
|
||||
(net->flight_size > max_rwnd_per_dest)) {
|
||||
goto no_data_fill;
|
||||
}
|
||||
|
@ -8096,7 +8092,7 @@ sctp_med_chunk_output(struct sctp_inpcb *inp,
|
|||
break;
|
||||
}
|
||||
nchk = TAILQ_NEXT(chk, sctp_next);
|
||||
if (SCTP_BASE_SYSCTL(sctp_cmt_on_off)) {
|
||||
if (asoc->sctp_cmt_on_off == 1) {
|
||||
if (chk->whoTo != net) {
|
||||
/*
|
||||
* For CMT, steal the data
|
||||
|
@ -8271,8 +8267,8 @@ sctp_med_chunk_output(struct sctp_inpcb *inp,
|
|||
* restart it.
|
||||
*/
|
||||
sctp_timer_start(SCTP_TIMER_TYPE_SEND, inp, stcb, net);
|
||||
} else if (SCTP_BASE_SYSCTL(sctp_cmt_on_off) &&
|
||||
SCTP_BASE_SYSCTL(sctp_cmt_pf) &&
|
||||
} else if ((asoc->sctp_cmt_on_off == 1) &&
|
||||
(asoc->sctp_cmt_pf > 0) &&
|
||||
pf_hbflag &&
|
||||
((net->dest_state & SCTP_ADDR_PF) == SCTP_ADDR_PF) &&
|
||||
(!SCTP_OS_TIMER_PENDING(&net->rxt_timer.timer))) {
|
||||
|
@ -9579,8 +9575,8 @@ sctp_chunk_output(struct sctp_inpcb *inp,
|
|||
*/
|
||||
if (net->ref_count > 1)
|
||||
sctp_move_to_an_alt(stcb, asoc, net);
|
||||
} else if (SCTP_BASE_SYSCTL(sctp_cmt_on_off) &&
|
||||
SCTP_BASE_SYSCTL(sctp_cmt_pf) &&
|
||||
} else if ((asoc->sctp_cmt_on_off == 1) &&
|
||||
(asoc->sctp_cmt_pf > 0) &&
|
||||
((net->dest_state & SCTP_ADDR_PF) == SCTP_ADDR_PF)) {
|
||||
/*
|
||||
* JRS 5/14/07 - If CMT PF is on and the current
|
||||
|
@ -9926,8 +9922,8 @@ sctp_send_sack(struct sctp_tcb *stcb)
|
|||
uint8_t flags;
|
||||
uint8_t type;
|
||||
|
||||
if (SCTP_BASE_SYSCTL(sctp_nr_sack_on_off) &&
|
||||
stcb->asoc.peer_supports_nr_sack) {
|
||||
if ((stcb->asoc.sctp_nr_sack_on_off == 1) &&
|
||||
(stcb->asoc.peer_supports_nr_sack == 1)) {
|
||||
type = SCTP_NR_SELECTIVE_ACK;
|
||||
} else {
|
||||
type = SCTP_SELECTIVE_ACK;
|
||||
|
@ -10071,7 +10067,8 @@ sctp_send_sack(struct sctp_tcb *stcb)
|
|||
else
|
||||
flags = 0;
|
||||
|
||||
if (SCTP_BASE_SYSCTL(sctp_cmt_on_off) && SCTP_BASE_SYSCTL(sctp_cmt_use_dac)) {
|
||||
if ((asoc->sctp_cmt_on_off == 1) &&
|
||||
SCTP_BASE_SYSCTL(sctp_cmt_use_dac)) {
|
||||
/*-
|
||||
* CMT DAC algorithm: If 2 (i.e., 0x10) packets have been
|
||||
* received, then set high bit to 1, else 0. Reset
|
||||
|
@ -10839,7 +10836,8 @@ sctp_send_hb(struct sctp_tcb *stcb, int user_req, struct sctp_nets *u_net)
|
|||
* heartbeat is being sent is in PF state, do NOT do threshold
|
||||
* management.
|
||||
*/
|
||||
if ((SCTP_BASE_SYSCTL(sctp_cmt_pf) == 0) || ((net->dest_state & SCTP_ADDR_PF) != SCTP_ADDR_PF)) {
|
||||
if ((stcb->asoc.sctp_cmt_pf == 0) ||
|
||||
((net->dest_state & SCTP_ADDR_PF) != SCTP_ADDR_PF)) {
|
||||
/* ok we have a destination that needs a beat */
|
||||
/* lets do the theshold management Qiaobing style */
|
||||
if (sctp_threshold_management(stcb->sctp_ep, stcb, net,
|
||||
|
@ -12105,7 +12103,7 @@ sctp_sosend(struct socket *so,
|
|||
struct sctp_sndrcvinfo srcv;
|
||||
struct sockaddr *addr_to_use;
|
||||
|
||||
#ifdef INET6
|
||||
#if defined(INET) && defined(INET6)
|
||||
struct sockaddr_in sin;
|
||||
|
||||
#endif
|
||||
|
@ -12120,7 +12118,7 @@ sctp_sosend(struct socket *so,
|
|||
}
|
||||
}
|
||||
addr_to_use = addr;
|
||||
#if defined(INET6) && !defined(__Userspace__) /* TODO port in6_sin6_2_sin */
|
||||
#if defined(INET) && defined(INET6)
|
||||
if ((addr) && (addr->sa_family == AF_INET6)) {
|
||||
struct sockaddr_in6 *sin6;
|
||||
|
||||
|
@ -12212,20 +12210,33 @@ sctp_lower_sosend(struct socket *so,
|
|||
SCTPDBG(SCTP_DEBUG_OUTPUT1, "Send called addr:%p send length %d\n",
|
||||
addr,
|
||||
sndlen);
|
||||
/*-
|
||||
/**
|
||||
* Pre-screen address, if one is given the sin-len
|
||||
* must be set correctly!
|
||||
*/
|
||||
if (addr) {
|
||||
if ((addr->sa_family == AF_INET) &&
|
||||
(addr->sa_len != sizeof(struct sockaddr_in))) {
|
||||
SCTP_LTRACE_ERR_RET(inp, stcb, net, SCTP_FROM_SCTP_OUTPUT, EINVAL);
|
||||
error = EINVAL;
|
||||
goto out_unlocked;
|
||||
} else if ((addr->sa_family == AF_INET6) &&
|
||||
(addr->sa_len != sizeof(struct sockaddr_in6))) {
|
||||
SCTP_LTRACE_ERR_RET(inp, stcb, net, SCTP_FROM_SCTP_OUTPUT, EINVAL);
|
||||
error = EINVAL;
|
||||
switch (addr->sa_family) {
|
||||
#if defined(INET)
|
||||
case AF_INET:
|
||||
if (addr->sa_len != sizeof(struct sockaddr_in)) {
|
||||
SCTP_LTRACE_ERR_RET(inp, stcb, net, SCTP_FROM_SCTP_OUTPUT, EINVAL);
|
||||
error = EINVAL;
|
||||
goto out_unlocked;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
#if defined(INET6)
|
||||
case AF_INET6:
|
||||
if (addr->sa_len != sizeof(struct sockaddr_in6)) {
|
||||
SCTP_LTRACE_ERR_RET(inp, stcb, net, SCTP_FROM_SCTP_OUTPUT, EINVAL);
|
||||
error = EINVAL;
|
||||
goto out_unlocked;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
SCTP_LTRACE_ERR_RET(inp, stcb, net, SCTP_FROM_SCTP_OUTPUT, EAFNOSUPPORT);
|
||||
error = EAFNOSUPPORT;
|
||||
goto out_unlocked;
|
||||
}
|
||||
}
|
||||
|
@ -12657,7 +12668,8 @@ sctp_lower_sosend(struct socket *so,
|
|||
error = EINVAL;
|
||||
goto out_unlocked;
|
||||
}
|
||||
if ((net->flight_size > net->cwnd) && (SCTP_BASE_SYSCTL(sctp_cmt_on_off) == 0)) {
|
||||
if ((net->flight_size > net->cwnd) &&
|
||||
(asoc->sctp_cmt_on_off == 0)) {
|
||||
/*-
|
||||
* CMT: Added check for CMT above. net above is the primary
|
||||
* dest. If CMT is ON, sender should always attempt to send
|
||||
|
@ -13075,7 +13087,7 @@ sctp_lower_sosend(struct socket *so,
|
|||
goto skip_out_eof;
|
||||
}
|
||||
if ((net->flight_size > net->cwnd) &&
|
||||
(SCTP_BASE_SYSCTL(sctp_cmt_on_off) == 0)) {
|
||||
(asoc->sctp_cmt_on_off == 0)) {
|
||||
queue_only = 1;
|
||||
} else if (asoc->ifp_had_enobuf) {
|
||||
SCTP_STAT_INCR(sctps_ifnomemqueued);
|
||||
|
@ -13349,7 +13361,7 @@ sctp_lower_sosend(struct socket *so,
|
|||
some_on_control = 1;
|
||||
}
|
||||
if ((net->flight_size > net->cwnd) &&
|
||||
(SCTP_BASE_SYSCTL(sctp_cmt_on_off) == 0)) {
|
||||
(stcb->asoc.sctp_cmt_on_off == 0)) {
|
||||
queue_only = 1;
|
||||
} else if (asoc->ifp_had_enobuf) {
|
||||
SCTP_STAT_INCR(sctps_ifnomemqueued);
|
||||
|
|
|
@ -2385,6 +2385,7 @@ sctp_inpcb_alloc(struct socket *so, uint32_t vrf_id)
|
|||
inp->sctp_associd_counter = 1;
|
||||
inp->partial_delivery_point = SCTP_SB_LIMIT_RCV(so) >> SCTP_PARTIAL_DELIVERY_SHIFT;
|
||||
inp->sctp_frag_point = SCTP_DEFAULT_MAXSEGMENT;
|
||||
inp->sctp_cmt_on_off = SCTP_BASE_SYSCTL(sctp_cmt_on_off);
|
||||
/* init the small hash table we use to track asocid <-> tcb */
|
||||
inp->sctp_asocidhash = SCTP_HASH_INIT(SCTP_STACK_VTAG_HASH_SIZE, &inp->hashasocidmark);
|
||||
if (inp->sctp_asocidhash == NULL) {
|
||||
|
@ -6241,10 +6242,7 @@ sctp_load_addresses_from_init(struct sctp_tcb *stcb, struct mbuf *m,
|
|||
stcb->asoc.peer_supports_pktdrop = 1;
|
||||
break;
|
||||
case SCTP_NR_SELECTIVE_ACK:
|
||||
if (SCTP_BASE_SYSCTL(sctp_nr_sack_on_off))
|
||||
stcb->asoc.peer_supports_nr_sack = 1;
|
||||
else
|
||||
stcb->asoc.peer_supports_nr_sack = 0;
|
||||
stcb->asoc.peer_supports_nr_sack = 1;
|
||||
break;
|
||||
case SCTP_STREAM_RESET:
|
||||
stcb->asoc.peer_supports_strreset = 1;
|
||||
|
|
|
@ -389,6 +389,7 @@ struct sctp_inpcb {
|
|||
uint32_t sctp_frag_point;
|
||||
uint32_t partial_delivery_point;
|
||||
uint32_t sctp_context;
|
||||
uint32_t sctp_cmt_on_off;
|
||||
struct sctp_nonpad_sndrcvinfo def_send;
|
||||
/*-
|
||||
* These three are here for the sosend_dgram
|
||||
|
|
|
@ -112,6 +112,7 @@ sctp_do_peeloff(struct socket *head, struct socket *so, sctp_assoc_t assoc_id)
|
|||
n_inp->sctp_features = inp->sctp_features;
|
||||
n_inp->sctp_mobility_features = inp->sctp_mobility_features;
|
||||
n_inp->sctp_frag_point = inp->sctp_frag_point;
|
||||
n_inp->sctp_cmt_on_off = inp->sctp_cmt_on_off;
|
||||
n_inp->partial_delivery_point = inp->partial_delivery_point;
|
||||
n_inp->sctp_context = inp->sctp_context;
|
||||
n_inp->inp_starting_point_for_iterator = NULL;
|
||||
|
@ -183,6 +184,7 @@ sctp_get_peeloff(struct socket *head, sctp_assoc_t assoc_id, int *error)
|
|||
(SCTP_PCB_COPY_FLAGS & inp->sctp_flags));
|
||||
n_inp->sctp_features = inp->sctp_features;
|
||||
n_inp->sctp_frag_point = inp->sctp_frag_point;
|
||||
n_inp->sctp_cmt_on_off = inp->sctp_cmt_on_off;
|
||||
n_inp->partial_delivery_point = inp->partial_delivery_point;
|
||||
n_inp->sctp_context = inp->sctp_context;
|
||||
n_inp->inp_starting_point_for_iterator = NULL;
|
||||
|
|
|
@ -215,7 +215,8 @@ sctp_threshold_management(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
|
|||
* not in PF state.
|
||||
*/
|
||||
/* Stop any running T3 timers here? */
|
||||
if (SCTP_BASE_SYSCTL(sctp_cmt_on_off) && SCTP_BASE_SYSCTL(sctp_cmt_pf)) {
|
||||
if ((stcb->asoc.sctp_cmt_on_off == 1) &&
|
||||
(stcb->asoc.sctp_cmt_pf > 0)) {
|
||||
net->dest_state &= ~SCTP_ADDR_PF;
|
||||
SCTPDBG(SCTP_DEBUG_TIMER4, "Destination %p moved from PF to unreachable.\n",
|
||||
net);
|
||||
|
@ -419,7 +420,7 @@ sctp_find_alternate_net(struct sctp_tcb *stcb,
|
|||
return (net);
|
||||
}
|
||||
min_errors_net->dest_state &= ~SCTP_ADDR_PF;
|
||||
min_errors_net->cwnd = min_errors_net->mtu * SCTP_BASE_SYSCTL(sctp_cmt_pf);
|
||||
min_errors_net->cwnd = min_errors_net->mtu * stcb->asoc.sctp_cmt_pf;
|
||||
if (SCTP_OS_TIMER_PENDING(&min_errors_net->rxt_timer.timer)) {
|
||||
sctp_timer_stop(SCTP_TIMER_TYPE_SEND, stcb->sctp_ep,
|
||||
stcb, min_errors_net,
|
||||
|
@ -843,7 +844,7 @@ sctp_mark_all_for_resend(struct sctp_tcb *stcb,
|
|||
/*
|
||||
* CMT: Do not allow FRs on retransmitted TSNs.
|
||||
*/
|
||||
if (SCTP_BASE_SYSCTL(sctp_cmt_on_off) == 1) {
|
||||
if (stcb->asoc.sctp_cmt_on_off == 1) {
|
||||
chk->no_fr_allowed = 1;
|
||||
}
|
||||
#ifdef THIS_SHOULD_NOT_BE_DONE
|
||||
|
@ -1038,7 +1039,8 @@ sctp_t3rxt_timer(struct sctp_inpcb *inp,
|
|||
* addition, find an alternate destination with PF-based
|
||||
* find_alt_net().
|
||||
*/
|
||||
if (SCTP_BASE_SYSCTL(sctp_cmt_on_off) && SCTP_BASE_SYSCTL(sctp_cmt_pf)) {
|
||||
if ((stcb->asoc.sctp_cmt_on_off == 1) &&
|
||||
(stcb->asoc.sctp_cmt_pf > 0)) {
|
||||
if ((net->dest_state & SCTP_ADDR_PF) != SCTP_ADDR_PF) {
|
||||
net->dest_state |= SCTP_ADDR_PF;
|
||||
net->last_active = sctp_get_tick_count();
|
||||
|
@ -1046,7 +1048,7 @@ sctp_t3rxt_timer(struct sctp_inpcb *inp,
|
|||
net);
|
||||
}
|
||||
alt = sctp_find_alternate_net(stcb, net, 2);
|
||||
} else if (SCTP_BASE_SYSCTL(sctp_cmt_on_off)) {
|
||||
} else if (stcb->asoc.sctp_cmt_on_off == 1) {
|
||||
/*
|
||||
* CMT: Using RTX_SSTHRESH policy for CMT. If CMT is being
|
||||
* used, then pick dest with largest ssthresh for any
|
||||
|
@ -1162,7 +1164,9 @@ sctp_t3rxt_timer(struct sctp_inpcb *inp,
|
|||
net->dest_state |= SCTP_ADDR_WAS_PRIMARY;
|
||||
}
|
||||
}
|
||||
} else if (SCTP_BASE_SYSCTL(sctp_cmt_on_off) && SCTP_BASE_SYSCTL(sctp_cmt_pf) && (net->dest_state & SCTP_ADDR_PF) == SCTP_ADDR_PF) {
|
||||
} else if ((stcb->asoc.sctp_cmt_on_off == 1) &&
|
||||
(stcb->asoc.sctp_cmt_pf > 0) &&
|
||||
((net->dest_state & SCTP_ADDR_PF) == SCTP_ADDR_PF)) {
|
||||
/*
|
||||
* JRS 5/14/07 - If the destination hasn't failed completely
|
||||
* but is in PF state, a PF-heartbeat needs to be sent
|
||||
|
|
|
@ -300,7 +300,8 @@ sctp_notify(struct sctp_inpcb *inp,
|
|||
* PF state.
|
||||
*/
|
||||
/* Stop any running T3 timers here? */
|
||||
if (SCTP_BASE_SYSCTL(sctp_cmt_on_off) && SCTP_BASE_SYSCTL(sctp_cmt_pf)) {
|
||||
if ((stcb->asoc.sctp_cmt_on_off == 1) &&
|
||||
(stcb->asoc.sctp_cmt_pf > 0)) {
|
||||
net->dest_state &= ~SCTP_ADDR_PF;
|
||||
SCTPDBG(SCTP_DEBUG_TIMER4, "Destination %p moved from PF to unreachable.\n",
|
||||
net);
|
||||
|
@ -1736,42 +1737,14 @@ sctp_getopt(struct socket *so, int optname, void *optval, size_t *optsize,
|
|||
struct sctp_assoc_value *av;
|
||||
|
||||
SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, *optsize);
|
||||
if (SCTP_BASE_SYSCTL(sctp_cmt_on_off)) {
|
||||
SCTP_FIND_STCB(inp, stcb, av->assoc_id);
|
||||
if (stcb) {
|
||||
av->assoc_value = stcb->asoc.sctp_cmt_on_off;
|
||||
SCTP_TCB_UNLOCK(stcb);
|
||||
|
||||
} else {
|
||||
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOTCONN);
|
||||
error = ENOTCONN;
|
||||
}
|
||||
SCTP_FIND_STCB(inp, stcb, av->assoc_id);
|
||||
if (stcb) {
|
||||
av->assoc_value = stcb->asoc.sctp_cmt_on_off;
|
||||
SCTP_TCB_UNLOCK(stcb);
|
||||
} else {
|
||||
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOPROTOOPT);
|
||||
error = ENOPROTOOPT;
|
||||
}
|
||||
*optsize = sizeof(*av);
|
||||
}
|
||||
break;
|
||||
/* EY - set socket option for nr_sacks */
|
||||
case SCTP_NR_SACK_ON_OFF:
|
||||
{
|
||||
struct sctp_assoc_value *av;
|
||||
|
||||
SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, *optsize);
|
||||
if (SCTP_BASE_SYSCTL(sctp_nr_sack_on_off)) {
|
||||
SCTP_FIND_STCB(inp, stcb, av->assoc_id);
|
||||
if (stcb) {
|
||||
av->assoc_value = stcb->asoc.sctp_nr_sack_on_off;
|
||||
SCTP_TCB_UNLOCK(stcb);
|
||||
|
||||
} else {
|
||||
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOTCONN);
|
||||
error = ENOTCONN;
|
||||
}
|
||||
} else {
|
||||
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOPROTOOPT);
|
||||
error = ENOPROTOOPT;
|
||||
SCTP_INP_RLOCK(inp);
|
||||
av->assoc_value = inp->sctp_cmt_on_off;
|
||||
SCTP_INP_RUNLOCK(inp);
|
||||
}
|
||||
*optsize = sizeof(*av);
|
||||
}
|
||||
|
@ -2846,44 +2819,28 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
|
|||
}
|
||||
break;
|
||||
case SCTP_CMT_ON_OFF:
|
||||
{
|
||||
if (SCTP_BASE_SYSCTL(sctp_cmt_on_off)) {
|
||||
struct sctp_assoc_value *av;
|
||||
|
||||
SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, optsize);
|
||||
if (SCTP_BASE_SYSCTL(sctp_cmt_on_off)) {
|
||||
SCTP_FIND_STCB(inp, stcb, av->assoc_id);
|
||||
if (stcb) {
|
||||
stcb->asoc.sctp_cmt_on_off = (uint8_t) av->assoc_value;
|
||||
SCTP_TCB_UNLOCK(stcb);
|
||||
} else {
|
||||
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOTCONN);
|
||||
error = ENOTCONN;
|
||||
}
|
||||
SCTP_FIND_STCB(inp, stcb, av->assoc_id);
|
||||
if (stcb) {
|
||||
if (av->assoc_value != 0)
|
||||
stcb->asoc.sctp_cmt_on_off = 1;
|
||||
else
|
||||
stcb->asoc.sctp_cmt_on_off = 0;
|
||||
SCTP_TCB_UNLOCK(stcb);
|
||||
} else {
|
||||
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOPROTOOPT);
|
||||
error = ENOPROTOOPT;
|
||||
}
|
||||
}
|
||||
break;
|
||||
/* EY nr_sack_on_off socket option */
|
||||
case SCTP_NR_SACK_ON_OFF:
|
||||
{
|
||||
struct sctp_assoc_value *av;
|
||||
|
||||
SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, optsize);
|
||||
if (SCTP_BASE_SYSCTL(sctp_nr_sack_on_off)) {
|
||||
SCTP_FIND_STCB(inp, stcb, av->assoc_id);
|
||||
if (stcb) {
|
||||
stcb->asoc.sctp_nr_sack_on_off = (uint8_t) av->assoc_value;
|
||||
SCTP_TCB_UNLOCK(stcb);
|
||||
} else {
|
||||
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOTCONN);
|
||||
error = ENOTCONN;
|
||||
}
|
||||
} else {
|
||||
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOPROTOOPT);
|
||||
error = ENOPROTOOPT;
|
||||
SCTP_INP_WLOCK(inp);
|
||||
if (av->assoc_value != 0)
|
||||
inp->sctp_cmt_on_off = 1;
|
||||
else
|
||||
inp->sctp_cmt_on_off = 0;
|
||||
SCTP_INP_WUNLOCK(inp);
|
||||
}
|
||||
} else {
|
||||
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOPROTOOPT);
|
||||
error = ENOPROTOOPT;
|
||||
}
|
||||
break;
|
||||
/* JRS - Set socket option for pluggable congestion control */
|
||||
|
|
|
@ -893,10 +893,8 @@ sctp_init_asoc(struct sctp_inpcb *m, struct sctp_tcb *stcb,
|
|||
asoc->max_burst = m->sctp_ep.max_burst;
|
||||
asoc->heart_beat_delay = TICKS_TO_MSEC(m->sctp_ep.sctp_timeoutticks[SCTP_TIMER_HEARTBEAT]);
|
||||
asoc->cookie_life = m->sctp_ep.def_cookie_life;
|
||||
asoc->sctp_cmt_on_off = (uint8_t) SCTP_BASE_SYSCTL(sctp_cmt_on_off);
|
||||
/* EY Init nr_sack variable */
|
||||
asoc->sctp_cmt_on_off = m->sctp_cmt_on_off;
|
||||
asoc->sctp_nr_sack_on_off = (uint8_t) SCTP_BASE_SYSCTL(sctp_nr_sack_on_off);
|
||||
/* JRS 5/21/07 - Init CMT PF variables */
|
||||
asoc->sctp_cmt_pf = (uint8_t) SCTP_BASE_SYSCTL(sctp_cmt_pf);
|
||||
asoc->sctp_frag_point = m->sctp_frag_point;
|
||||
#ifdef INET
|
||||
|
@ -4213,7 +4211,7 @@ void
|
|||
sctp_print_address_pkt(struct ip *iph, struct sctphdr *sh)
|
||||
{
|
||||
switch (iph->ip_v) {
|
||||
case IPVERSION:
|
||||
case IPVERSION:
|
||||
{
|
||||
struct sockaddr_in lsa, fsa;
|
||||
|
||||
|
|
|
@ -414,7 +414,8 @@ sctp6_notify(struct sctp_inpcb *inp,
|
|||
* PF state.
|
||||
*/
|
||||
/* Stop any running T3 timers here? */
|
||||
if (SCTP_BASE_SYSCTL(sctp_cmt_on_off) && SCTP_BASE_SYSCTL(sctp_cmt_pf)) {
|
||||
if ((stcb->asoc.sctp_cmt_on_off == 1) &&
|
||||
(stcb->asoc.sctp_cmt_pf > 0)) {
|
||||
net->dest_state &= ~SCTP_ADDR_PF;
|
||||
SCTPDBG(SCTP_DEBUG_TIMER4, "Destination %p moved from PF to unreachable.\n",
|
||||
net);
|
||||
|
@ -1069,6 +1070,8 @@ sctp6_getaddr(struct socket *so, struct sockaddr **addr)
|
|||
* Do the malloc first in case it blocks.
|
||||
*/
|
||||
SCTP_MALLOC_SONAME(sin6, struct sockaddr_in6 *, sizeof *sin6);
|
||||
if (sin6 == NULL)
|
||||
return ENOMEM;
|
||||
sin6->sin6_family = AF_INET6;
|
||||
sin6->sin6_len = sizeof(*sin6);
|
||||
|
||||
|
@ -1173,6 +1176,8 @@ sctp6_peeraddr(struct socket *so, struct sockaddr **addr)
|
|||
return (ENOTCONN);
|
||||
}
|
||||
SCTP_MALLOC_SONAME(sin6, struct sockaddr_in6 *, sizeof *sin6);
|
||||
if (sin6 == NULL)
|
||||
return (ENOMEM);
|
||||
sin6->sin6_family = AF_INET6;
|
||||
sin6->sin6_len = sizeof(*sin6);
|
||||
|
||||
|
|
Loading…
Reference in a new issue