summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authort00fcxen <t00fcxen@9df1edf5-d72c-5b5f-11c0-5f5209eb73f7>2014-08-02 22:05:33 +0000
committert00fcxen <t00fcxen@9df1edf5-d72c-5b5f-11c0-5f5209eb73f7>2014-08-02 22:05:33 +0000
commita8657c4fc04fb9cc82100f648810d51ec6ab155a (patch)
tree7f47b188adee398cf03b506bed63312846efd6af
parentaba62ccbe62e9d5694e5ac85d8aaca0e72d3fd67 (diff)
downloadusrsctplib-a8657c4fc04fb9cc82100f648810d51ec6ab155a.tar.gz
Sync with Mavericks sources.
git-svn-id: http://sctp-refimpl.googlecode.com/svn/trunk/KERN/usrsctp/usrsctplib@8944 9df1edf5-d72c-5b5f-11c0-5f5209eb73f7
-rwxr-xr-xnetinet/sctp.h3
-rwxr-xr-xnetinet/sctp_indata.c16
-rwxr-xr-xnetinet/sctp_input.c7
-rwxr-xr-xnetinet/sctp_output.c44
-rwxr-xr-xnetinet/sctp_pcb.c11
-rwxr-xr-xnetinet/sctp_pcb.h3
-rwxr-xr-xnetinet/sctp_peeloff.c4
-rwxr-xr-xnetinet/sctp_structs.h7
-rwxr-xr-xnetinet/sctp_sysctl.c12
-rwxr-xr-xnetinet/sctp_sysctl.h9
-rwxr-xr-xnetinet/sctp_timer.c10
-rwxr-xr-xnetinet/sctp_usrreq.c60
-rwxr-xr-xnetinet/sctputil.c5
-rwxr-xr-xuser_socket.c2
-rw-r--r--usrsctp.h1
15 files changed, 144 insertions, 50 deletions
diff --git a/netinet/sctp.h b/netinet/sctp.h
index 4db083b..885cf89 100755
--- a/netinet/sctp.h
+++ b/netinet/sctp.h
@@ -32,7 +32,7 @@
#ifdef __FreeBSD__
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/netinet/sctp.h 269436 2014-08-02 17:35:13Z tuexen $");
+__FBSDID("$FreeBSD: head/sys/netinet/sctp.h 269448 2014-08-02 21:36:40Z tuexen $");
#endif
#ifndef _NETINET_SCTP_H_
@@ -132,6 +132,7 @@ struct sctp_paramhdr {
#define SCTP_PEER_ADDR_THLDS 0x00000023
#define SCTP_REMOTE_UDP_ENCAPS_PORT 0x00000024
#define SCTP_ECN_SUPPORTED 0x00000025
+#define SCTP_PR_SUPPORTED 0x00000026
/*
* read-only options
diff --git a/netinet/sctp_indata.c b/netinet/sctp_indata.c
index cbc8546..22a551f 100755
--- a/netinet/sctp_indata.c
+++ b/netinet/sctp_indata.c
@@ -32,7 +32,7 @@
#ifdef __FreeBSD__
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/netinet/sctp_indata.c 269376 2014-08-01 12:42:37Z tuexen $");
+__FBSDID("$FreeBSD: head/sys/netinet/sctp_indata.c 269448 2014-08-02 21:36:40Z tuexen $");
#endif
#include <netinet/sctp_os.h>
@@ -2978,7 +2978,7 @@ sctp_strike_gap_ack_chunks(struct sctp_tcb *stcb, struct sctp_association *asoc,
num_dests_sacked++;
}
}
- if (stcb->asoc.peer_supports_prsctp) {
+ if (stcb->asoc.prsctp_supported) {
(void)SCTP_GETTIME_TIMEVAL(&now);
}
TAILQ_FOREACH(tp1, &asoc->sent_queue, sctp_next) {
@@ -2999,7 +2999,7 @@ sctp_strike_gap_ack_chunks(struct sctp_tcb *stcb, struct sctp_association *asoc,
/* done */
break;
}
- if (stcb->asoc.peer_supports_prsctp) {
+ if (stcb->asoc.prsctp_supported) {
if ((PR_SCTP_TTL_ENABLED(tp1->flags)) && tp1->sent < SCTP_DATAGRAM_ACKED) {
/* Is it expired? */
#ifndef __FreeBSD__
@@ -3252,7 +3252,7 @@ sctp_strike_gap_ack_chunks(struct sctp_tcb *stcb, struct sctp_association *asoc,
/* remove from the total flight */
sctp_total_flight_decrease(stcb, tp1);
- if ((stcb->asoc.peer_supports_prsctp) &&
+ if ((stcb->asoc.prsctp_supported) &&
(PR_SCTP_RTX_ENABLED(tp1->flags))) {
/* Has it been retransmitted tv_sec times? - we store the retran count there. */
if (tp1->snd_count > tp1->rec.data.timetodrop.tv_sec) {
@@ -3384,7 +3384,7 @@ sctp_try_advance_peer_ack_point(struct sctp_tcb *stcb,
struct timeval now;
int now_filled = 0;
- if (asoc->peer_supports_prsctp == 0) {
+ if (asoc->prsctp_supported == 0) {
return (NULL);
}
TAILQ_FOREACH_SAFE(tp1, &asoc->sent_queue, sctp_next, tp2) {
@@ -4068,7 +4068,7 @@ again:
asoc->advanced_peer_ack_point = cumack;
}
/* PR-Sctp issues need to be addressed too */
- if ((asoc->peer_supports_prsctp) && (asoc->pr_sctp_cnt > 0)) {
+ if ((asoc->prsctp_supported) && (asoc->pr_sctp_cnt > 0)) {
struct sctp_tmit_chunk *lchk;
uint32_t old_adv_peer_ack_point;
@@ -4506,7 +4506,7 @@ sctp_handle_sack(struct mbuf *m, int offset_seg, int offset_dup,
sctp_free_bufspace(stcb, asoc, tp1, 1);
sctp_m_freem(tp1->data);
tp1->data = NULL;
- if (asoc->peer_supports_prsctp && PR_SCTP_BUF_ENABLED(tp1->flags)) {
+ if (asoc->prsctp_supported && PR_SCTP_BUF_ENABLED(tp1->flags)) {
asoc->sent_queue_cnt_removeable--;
}
}
@@ -4941,7 +4941,7 @@ again:
asoc->advanced_peer_ack_point = cum_ack;
}
/* C2. try to further move advancedPeerAckPoint ahead */
- if ((asoc->peer_supports_prsctp) && (asoc->pr_sctp_cnt > 0)) {
+ if ((asoc->prsctp_supported) && (asoc->pr_sctp_cnt > 0)) {
struct sctp_tmit_chunk *lchk;
uint32_t old_adv_peer_ack_point;
diff --git a/netinet/sctp_input.c b/netinet/sctp_input.c
index 1f4e29c..53c4755 100755
--- a/netinet/sctp_input.c
+++ b/netinet/sctp_input.c
@@ -32,7 +32,7 @@
#ifdef __FreeBSD__
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/netinet/sctp_input.c 269436 2014-08-02 17:35:13Z tuexen $");
+__FBSDID("$FreeBSD: head/sys/netinet/sctp_input.c 269448 2014-08-02 21:36:40Z tuexen $");
#endif
#include <netinet/sctp_os.h>
@@ -1122,7 +1122,7 @@ sctp_process_unrecog_chunk(struct sctp_tcb *stcb, struct sctp_paramhdr *phdr,
sctp_asconf_cleanup(stcb, net);
break;
case SCTP_FORWARD_CUM_TSN:
- stcb->asoc.peer_supports_prsctp = 0;
+ stcb->asoc.prsctp_supported = 0;
break;
default:
SCTPDBG(SCTP_DEBUG_INPUT2,
@@ -1146,7 +1146,7 @@ sctp_process_unrecog_param(struct sctp_tcb *stcb, struct sctp_paramhdr *phdr)
switch (ntohs(pbad->param_type)) {
/* pr-sctp draft */
case SCTP_PRSCTP_SUPPORTED:
- stcb->asoc.peer_supports_prsctp = 0;
+ stcb->asoc.prsctp_supported = 0;
break;
case SCTP_SUPPORTED_CHUNK_EXT:
break;
@@ -2927,6 +2927,7 @@ sctp_handle_cookie_echo(struct mbuf *m, int iphlen, int offset,
inp->sctp_frag_point = (*inp_p)->sctp_frag_point;
inp->sctp_cmt_on_off = (*inp_p)->sctp_cmt_on_off;
inp->ecn_supported = (*inp_p)->ecn_supported;
+ inp->prsctp_supported = (*inp_p)->prsctp_supported;
inp->partial_delivery_point = (*inp_p)->partial_delivery_point;
inp->sctp_context = (*inp_p)->sctp_context;
inp->local_strreset_support = (*inp_p)->local_strreset_support;
diff --git a/netinet/sctp_output.c b/netinet/sctp_output.c
index dba19be..cc73e61 100755
--- a/netinet/sctp_output.c
+++ b/netinet/sctp_output.c
@@ -32,7 +32,7 @@
#ifdef __FreeBSD__
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/netinet/sctp_output.c 269436 2014-08-02 17:35:13Z tuexen $");
+__FBSDID("$FreeBSD: head/sys/netinet/sctp_output.c 269448 2014-08-02 21:36:40Z tuexen $");
#endif
#include <netinet/sctp_os.h>
@@ -5143,12 +5143,14 @@ sctp_send_initiate(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int so_locked
chunk_len += parameter_len;
}
- /* And now tell the peer we do support PR-SCTP. */
- parameter_len = (uint16_t)sizeof(struct sctp_paramhdr);
- ph = (struct sctp_paramhdr *)(mtod(m, caddr_t) + chunk_len);
- ph->param_type = htons(SCTP_PRSCTP_SUPPORTED);
- ph->param_length = htons(parameter_len);
- chunk_len += parameter_len;
+ /* PR-SCTP supported parameter */
+ if (stcb->asoc.prsctp_supported == 1) {
+ parameter_len = (uint16_t)sizeof(struct sctp_paramhdr);
+ ph = (struct sctp_paramhdr *)(mtod(m, caddr_t) + chunk_len);
+ ph->param_type = htons(SCTP_PRSCTP_SUPPORTED);
+ ph->param_length = htons(parameter_len);
+ chunk_len += parameter_len;
+ }
/* Add NAT friendly parameter. */
if (SCTP_BASE_SYSCTL(sctp_inits_include_nat_friendly)) {
@@ -5165,7 +5167,9 @@ sctp_send_initiate(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int so_locked
pr_supported->ph.param_type = htons(SCTP_SUPPORTED_CHUNK_EXT);
pr_supported->chunk_types[num_ext++] = SCTP_ASCONF;
pr_supported->chunk_types[num_ext++] = SCTP_ASCONF_ACK;
- pr_supported->chunk_types[num_ext++] = SCTP_FORWARD_CUM_TSN;
+ if (stcb->asoc.prsctp_supported == 1) {
+ pr_supported->chunk_types[num_ext++] = SCTP_FORWARD_CUM_TSN;
+ }
pr_supported->chunk_types[num_ext++] = SCTP_PACKET_DROPPED;
pr_supported->chunk_types[num_ext++] = SCTP_STREAM_RESET;
if (!SCTP_BASE_SYSCTL(sctp_auth_disable)) {
@@ -6307,12 +6311,15 @@ sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
chunk_len += parameter_len;
}
- /* And now tell the peer we do pr-sctp */
- parameter_len = (uint16_t)sizeof(struct sctp_paramhdr);
- ph = (struct sctp_paramhdr *)(mtod(m, caddr_t) + chunk_len);
- ph->param_type = htons(SCTP_PRSCTP_SUPPORTED);
- ph->param_length = htons(parameter_len);
- chunk_len += parameter_len;
+ /* PR-SCTP supported parameter */
+ if (((asoc != NULL) && (asoc->prsctp_supported == 1)) ||
+ ((asoc == NULL) && (inp->prsctp_supported == 1))) {
+ parameter_len = (uint16_t)sizeof(struct sctp_paramhdr);
+ ph = (struct sctp_paramhdr *)(mtod(m, caddr_t) + chunk_len);
+ ph->param_type = htons(SCTP_PRSCTP_SUPPORTED);
+ ph->param_length = htons(parameter_len);
+ chunk_len += parameter_len;
+ }
/* Add NAT friendly parameter */
if (nat_friendly) {
@@ -6329,7 +6336,10 @@ sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
pr_supported->ph.param_type = htons(SCTP_SUPPORTED_CHUNK_EXT);
pr_supported->chunk_types[num_ext++] = SCTP_ASCONF;
pr_supported->chunk_types[num_ext++] = SCTP_ASCONF_ACK;
- pr_supported->chunk_types[num_ext++] = SCTP_FORWARD_CUM_TSN;
+ if (((asoc != NULL) && (asoc->prsctp_supported == 1)) ||
+ ((asoc == NULL) && (inp->prsctp_supported == 1))) {
+ pr_supported->chunk_types[num_ext++] = SCTP_FORWARD_CUM_TSN;
+ }
pr_supported->chunk_types[num_ext++] = SCTP_PACKET_DROPPED;
pr_supported->chunk_types[num_ext++] = SCTP_STREAM_RESET;
if (!SCTP_BASE_SYSCTL(sctp_auth_disable)) {
@@ -6515,7 +6525,7 @@ sctp_prune_prsctp(struct sctp_tcb *stcb,
struct sctp_tmit_chunk *chk, *nchk;
SCTP_TCB_LOCK_ASSERT(stcb);
- if ((asoc->peer_supports_prsctp) &&
+ if ((asoc->prsctp_supported) &&
(asoc->sent_queue_cnt_removeable > 0)) {
TAILQ_FOREACH(chk, &asoc->sent_queue, sctp_next) {
/*
@@ -13954,7 +13964,7 @@ skip_preblock:
continue;
}
/* PR-SCTP? */
- if ((asoc->peer_supports_prsctp) && (asoc->sent_queue_cnt_removeable > 0)) {
+ if ((asoc->prsctp_supported) && (asoc->sent_queue_cnt_removeable > 0)) {
/* This is ugly but we must assure locking order */
if (hold_tcblock == 0) {
SCTP_TCB_LOCK(stcb);
diff --git a/netinet/sctp_pcb.c b/netinet/sctp_pcb.c
index bd394b4..a31c5fa 100755
--- a/netinet/sctp_pcb.c
+++ b/netinet/sctp_pcb.c
@@ -32,7 +32,7 @@
#ifdef __FreeBSD__
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/netinet/sctp_pcb.c 269436 2014-08-02 17:35:13Z tuexen $");
+__FBSDID("$FreeBSD: head/sys/netinet/sctp_pcb.c 269448 2014-08-02 21:36:40Z tuexen $");
#endif
#include <netinet/sctp_os.h>
@@ -2842,6 +2842,7 @@ sctp_inpcb_alloc(struct socket *so, uint32_t vrf_id)
inp->sctp_frag_point = SCTP_DEFAULT_MAXSEGMENT;
inp->sctp_cmt_on_off = SCTP_BASE_SYSCTL(sctp_cmt_on_off);
inp->ecn_supported = (uint8_t)SCTP_BASE_SYSCTL(sctp_ecn_enable);
+ inp->prsctp_supported = (uint8_t)SCTP_BASE_SYSCTL(sctp_pr_enable);
#if defined(__Userspace__)
inp->ulp_info = NULL;
inp->recv_callback = NULL;
@@ -7107,6 +7108,7 @@ sctp_load_addresses_from_init(struct sctp_tcb *stcb, struct mbuf *m,
uint32_t keylen;
int got_random = 0, got_hmacs = 0, got_chklist = 0;
uint8_t ecn_supported;
+ uint8_t prsctp_supported;
#ifdef INET
struct sockaddr_in sin;
#endif
@@ -7138,6 +7140,7 @@ sctp_load_addresses_from_init(struct sctp_tcb *stcb, struct mbuf *m,
}
/* Turn off ECN until we get through all params */
ecn_supported = 0;
+ prsctp_supported = 0;
TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
/* mark all addresses that we have currently on the list */
net->dest_state |= SCTP_ADDR_NOT_IN_ASSOC;
@@ -7460,7 +7463,7 @@ sctp_load_addresses_from_init(struct sctp_tcb *stcb, struct mbuf *m,
stcb->asoc.peer_supports_nat = 1;
} else if (ptype == SCTP_PRSCTP_SUPPORTED) {
/* Peer supports pr-sctp */
- stcb->asoc.peer_supports_prsctp = 1;
+ prsctp_supported = 1;
} else if (ptype == SCTP_SUPPORTED_CHUNK_EXT) {
/* A supported extension chunk */
struct sctp_supported_chunk_types_param *pr_supported;
@@ -7473,7 +7476,6 @@ sctp_load_addresses_from_init(struct sctp_tcb *stcb, struct mbuf *m,
return (-25);
}
stcb->asoc.peer_supports_asconf = 0;
- stcb->asoc.peer_supports_prsctp = 0;
stcb->asoc.peer_supports_pktdrop = 0;
stcb->asoc.peer_supports_strreset = 0;
stcb->asoc.peer_supports_nr_sack = 0;
@@ -7487,7 +7489,7 @@ sctp_load_addresses_from_init(struct sctp_tcb *stcb, struct mbuf *m,
stcb->asoc.peer_supports_asconf = 1;
break;
case SCTP_FORWARD_CUM_TSN:
- stcb->asoc.peer_supports_prsctp = 1;
+ prsctp_supported = 1;
break;
case SCTP_PACKET_DROPPED:
stcb->asoc.peer_supports_pktdrop = 1;
@@ -7637,6 +7639,7 @@ sctp_load_addresses_from_init(struct sctp_tcb *stcb, struct mbuf *m,
}
}
stcb->asoc.ecn_supported &= ecn_supported;
+ stcb->asoc.prsctp_supported &= prsctp_supported;
/* validate authentication required parameters */
if (got_random && got_hmacs) {
stcb->asoc.peer_supports_auth = 1;
diff --git a/netinet/sctp_pcb.h b/netinet/sctp_pcb.h
index 3b4dbac..7ba6dec 100755
--- a/netinet/sctp_pcb.h
+++ b/netinet/sctp_pcb.h
@@ -32,7 +32,7 @@
#ifdef __FreeBSD__
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/netinet/sctp_pcb.h 269436 2014-08-02 17:35:13Z tuexen $");
+__FBSDID("$FreeBSD: head/sys/netinet/sctp_pcb.h 269448 2014-08-02 21:36:40Z tuexen $");
#endif
#ifndef _NETINET_SCTP_PCB_H_
@@ -481,6 +481,7 @@ struct sctp_inpcb {
uint8_t local_strreset_support;
uint32_t sctp_cmt_on_off;
uint8_t ecn_supported;
+ uint8_t prsctp_supported;
struct sctp_nonpad_sndrcvinfo def_send;
/*-
* These three are here for the sosend_dgram
diff --git a/netinet/sctp_peeloff.c b/netinet/sctp_peeloff.c
index 1cc505a..d184a25 100755
--- a/netinet/sctp_peeloff.c
+++ b/netinet/sctp_peeloff.c
@@ -32,7 +32,7 @@
#ifdef __FreeBSD__
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/netinet/sctp_peeloff.c 269436 2014-08-02 17:35:13Z tuexen $");
+__FBSDID("$FreeBSD: head/sys/netinet/sctp_peeloff.c 269448 2014-08-02 21:36:40Z tuexen $");
#endif
#include <netinet/sctp_os.h>
@@ -126,6 +126,7 @@ sctp_do_peeloff(struct socket *head, struct socket *so, sctp_assoc_t assoc_id)
n_inp->sctp_frag_point = inp->sctp_frag_point;
n_inp->sctp_cmt_on_off = inp->sctp_cmt_on_off;
n_inp->ecn_supported = inp->ecn_supported;
+ n_inp->prsctp_supported = inp->prsctp_supported;
n_inp->partial_delivery_point = inp->partial_delivery_point;
n_inp->sctp_context = inp->sctp_context;
n_inp->local_strreset_support = inp->local_strreset_support;
@@ -235,6 +236,7 @@ sctp_get_peeloff(struct socket *head, sctp_assoc_t assoc_id, int *error)
n_inp->sctp_frag_point = inp->sctp_frag_point;
n_inp->sctp_cmt_on_off = inp->sctp_cmt_on_off;
n_inp->ecn_supported = inp->ecn_supported;
+ n_inp->prsctp_supported = inp->prsctp_supported;
n_inp->partial_delivery_point = inp->partial_delivery_point;
n_inp->sctp_context = inp->sctp_context;
n_inp->local_strreset_support = inp->local_strreset_support;
diff --git a/netinet/sctp_structs.h b/netinet/sctp_structs.h
index 91e26c5..9ef1c2b 100755
--- a/netinet/sctp_structs.h
+++ b/netinet/sctp_structs.h
@@ -32,7 +32,7 @@
#ifdef __FreeBSD__
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/netinet/sctp_structs.h 269436 2014-08-02 17:35:13Z tuexen $");
+__FBSDID("$FreeBSD: head/sys/netinet/sctp_structs.h 269448 2014-08-02 21:36:40Z tuexen $");
#endif
#ifndef _NETINET_SCTP_STRUCTS_H_
@@ -1200,8 +1200,9 @@ struct sctp_association {
* sum is updated as well.
*/
- /* Flag to tell if ECN is allowed */
+ /* Flags whether an extension is supported or not */
uint8_t ecn_supported;
+ uint8_t prsctp_supported;
/* Did the peer make the stream config (add out) request */
uint8_t peer_req_out;
@@ -1210,8 +1211,6 @@ struct sctp_association {
uint8_t peer_supports_asconf;
/* EY - flag to indicate if peer can do nr_sack*/
uint8_t peer_supports_nr_sack;
- /* pr-sctp support flag */
- uint8_t peer_supports_prsctp;
/* peer authentication support flag */
uint8_t peer_supports_auth;
/* stream resets are supported by the peer */
diff --git a/netinet/sctp_sysctl.c b/netinet/sctp_sysctl.c
index 29aee2a..b8114c5 100755
--- a/netinet/sctp_sysctl.c
+++ b/netinet/sctp_sysctl.c
@@ -32,7 +32,7 @@
#ifdef __FreeBSD__
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/netinet/sctp_sysctl.c 269396 2014-08-01 20:49:27Z tuexen $");
+__FBSDID("$FreeBSD: head/sys/netinet/sctp_sysctl.c 269448 2014-08-02 21:36:40Z tuexen $");
#endif
#include <netinet/sctp_os.h>
@@ -61,6 +61,7 @@ sctp_init_sysctls()
SCTP_BASE_SYSCTL(sctp_auto_asconf) = SCTPCTL_AUTOASCONF_DEFAULT;
SCTP_BASE_SYSCTL(sctp_multiple_asconfs) = SCTPCTL_MULTIPLEASCONFS_DEFAULT;
SCTP_BASE_SYSCTL(sctp_ecn_enable) = SCTPCTL_ECN_ENABLE_DEFAULT;
+ SCTP_BASE_SYSCTL(sctp_pr_enable) = SCTPCTL_PR_ENABLE_DEFAULT;
SCTP_BASE_SYSCTL(sctp_strict_sacks) = SCTPCTL_STRICT_SACKS_DEFAULT;
#if !(defined(__FreeBSD__) && __FreeBSD_version >= 800000)
#if !defined(SCTP_WITH_NO_CSUM)
@@ -772,6 +773,7 @@ sysctl_sctp_check(SYSCTL_HANDLER_ARGS)
RANGECHK(SCTP_BASE_SYSCTL(sctp_auto_asconf), SCTPCTL_AUTOASCONF_MIN, SCTPCTL_AUTOASCONF_MAX);
#endif
RANGECHK(SCTP_BASE_SYSCTL(sctp_ecn_enable), SCTPCTL_ECN_ENABLE_MIN, SCTPCTL_ECN_ENABLE_MAX);
+ RANGECHK(SCTP_BASE_SYSCTL(sctp_pr_enable), SCTPCTL_PR_ENABLE_MIN, SCTPCTL_PR_ENABLE_MAX);
RANGECHK(SCTP_BASE_SYSCTL(sctp_strict_sacks), SCTPCTL_STRICT_SACKS_MIN, SCTPCTL_STRICT_SACKS_MAX);
#if !(defined(__FreeBSD__) && __FreeBSD_version >= 800000)
#if !defined(SCTP_WITH_NO_CSUM)
@@ -1081,6 +1083,10 @@ SYSCTL_VNET_PROC(_net_inet_sctp, OID_AUTO, ecn_enable, CTLTYPE_UINT|CTLFLAG_RW,
&SCTP_BASE_SYSCTL(sctp_ecn_enable), 0, sysctl_sctp_check, "IU",
SCTPCTL_ECN_ENABLE_DESC);
+SYSCTL_VNET_PROC(_net_inet_sctp, OID_AUTO, pr_enable, CTLTYPE_UINT|CTLFLAG_RW,
+ &SCTP_BASE_SYSCTL(sctp_pr_enable), 0, sysctl_sctp_check, "IU",
+ SCTPCTL_PR_ENABLE_DESC);
+
SYSCTL_VNET_PROC(_net_inet_sctp, OID_AUTO, strict_sacks, CTLTYPE_UINT|CTLFLAG_RW,
&SCTP_BASE_SYSCTL(sctp_strict_sacks), 0, sysctl_sctp_check, "IU",
SCTPCTL_STRICT_SACKS_DESC);
@@ -1420,6 +1426,10 @@ void sysctl_setup_sctp(void)
&SCTP_BASE_SYSCTL(sctp_ecn_enable), 0, sysctl_sctp_check,
SCTPCTL_ECN_ENABLE_DESC);
+ sysctl_add_oid(&sysctl_oid_top, "pr_enable", CTLTYPE_INT|CTLFLAG_RW,
+ &SCTP_BASE_SYSCTL(sctp_pr_enable), 0, sysctl_sctp_check,
+ SCTPCTL_PR_ENABLE_DESC);
+
sysctl_add_oid(&sysctl_oid_top, "strict_sacks", CTLTYPE_INT|CTLFLAG_RW,
&SCTP_BASE_SYSCTL(sctp_strict_sacks), 0, sysctl_sctp_check,
SCTPCTL_STRICT_SACKS_DESC);
diff --git a/netinet/sctp_sysctl.h b/netinet/sctp_sysctl.h
index 54a8cbd..21acb20 100755
--- a/netinet/sctp_sysctl.h
+++ b/netinet/sctp_sysctl.h
@@ -32,7 +32,7 @@
#ifdef __FreeBSD__
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/netinet/sctp_sysctl.h 269396 2014-08-01 20:49:27Z tuexen $");
+__FBSDID("$FreeBSD: head/sys/netinet/sctp_sysctl.h 269448 2014-08-02 21:36:40Z tuexen $");
#endif
#ifndef _NETINET_SCTP_SYSCTL_H_
@@ -47,6 +47,7 @@ struct sctp_sysctl {
uint32_t sctp_auto_asconf;
uint32_t sctp_multiple_asconfs;
uint32_t sctp_ecn_enable;
+ uint32_t sctp_pr_enable;
uint32_t sctp_fr_max_burst_default;
uint32_t sctp_strict_sacks;
#if !(defined(__FreeBSD__) && __FreeBSD_version >= 800000)
@@ -171,6 +172,12 @@ struct sctp_sysctl {
#define SCTPCTL_ECN_ENABLE_MAX 1
#define SCTPCTL_ECN_ENABLE_DEFAULT 1
+/* pr_enable: Enable PR-SCTP */
+#define SCTPCTL_PR_ENABLE_DESC "Enable PR-SCTP"
+#define SCTPCTL_PR_ENABLE_MIN 0
+#define SCTPCTL_PR_ENABLE_MAX 1
+#define SCTPCTL_PR_ENABLE_DEFAULT 1
+
/* strict_sacks: Enable SCTP Strict SACK checking */
#define SCTPCTL_STRICT_SACKS_DESC "Enable SCTP Strict SACK checking"
#define SCTPCTL_STRICT_SACKS_MIN 0
diff --git a/netinet/sctp_timer.c b/netinet/sctp_timer.c
index 29f94f3..574a213 100755
--- a/netinet/sctp_timer.c
+++ b/netinet/sctp_timer.c
@@ -32,7 +32,7 @@
#ifdef __FreeBSD__
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/netinet/sctp_timer.c 268526 2014-07-11 06:52:48Z tuexen $");
+__FBSDID("$FreeBSD: head/sys/netinet/sctp_timer.c 269448 2014-08-02 21:36:40Z tuexen $");
#endif
#define _IP_VHL
@@ -441,7 +441,7 @@ sctp_recover_sent_list(struct sctp_tcb *stcb)
sctp_free_bufspace(stcb, asoc, chk, 1);
sctp_m_freem(chk->data);
chk->data = NULL;
- if (asoc->peer_supports_prsctp && PR_SCTP_BUF_ENABLED(chk->flags)) {
+ if (asoc->prsctp_supported && PR_SCTP_BUF_ENABLED(chk->flags)) {
asoc->sent_queue_cnt_removeable--;
}
}
@@ -599,7 +599,7 @@ sctp_mark_all_for_resend(struct sctp_tcb *stcb,
continue;
}
}
- if (stcb->asoc.peer_supports_prsctp && PR_SCTP_TTL_ENABLED(chk->flags)) {
+ if (stcb->asoc.prsctp_supported && PR_SCTP_TTL_ENABLED(chk->flags)) {
/* Is it expired? */
#ifndef __FreeBSD__
if (timercmp(&now, &chk->rec.data.timetodrop, >)) {
@@ -617,7 +617,7 @@ sctp_mark_all_for_resend(struct sctp_tcb *stcb,
continue;
}
}
- if (stcb->asoc.peer_supports_prsctp && PR_SCTP_RTX_ENABLED(chk->flags)) {
+ if (stcb->asoc.prsctp_supported && PR_SCTP_RTX_ENABLED(chk->flags)) {
/* Has it been retransmitted tv_sec times? */
if (chk->snd_count > chk->rec.data.timetodrop.tv_sec) {
if (chk->data) {
@@ -964,7 +964,7 @@ sctp_t3rxt_timer(struct sctp_inpcb *inp,
sctp_timer_start(SCTP_TIMER_TYPE_SEND, inp, stcb, net);
return (0);
}
- if (stcb->asoc.peer_supports_prsctp) {
+ if (stcb->asoc.prsctp_supported) {
struct sctp_tmit_chunk *lchk;
lchk = sctp_try_advance_peer_ack_point(stcb, &stcb->asoc);
diff --git a/netinet/sctp_usrreq.c b/netinet/sctp_usrreq.c
index 3431751..63eb913 100755
--- a/netinet/sctp_usrreq.c
+++ b/netinet/sctp_usrreq.c
@@ -32,7 +32,7 @@
#ifdef __FreeBSD__
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/netinet/sctp_usrreq.c 269436 2014-08-02 17:35:13Z tuexen $");
+__FBSDID("$FreeBSD: head/sys/netinet/sctp_usrreq.c 269448 2014-08-02 21:36:40Z tuexen $");
#endif
#include <netinet/sctp_os.h>
@@ -4029,6 +4029,33 @@ sctp_getopt(struct socket *so, int optname, void *optval, size_t *optsize,
}
break;
}
+ case SCTP_PR_SUPPORTED:
+ {
+ struct sctp_assoc_value *av;
+
+ SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, *optsize);
+ SCTP_FIND_STCB(inp, stcb, av->assoc_id);
+
+ if (stcb) {
+ av->assoc_value = stcb->asoc.prsctp_supported;
+ SCTP_TCB_UNLOCK(stcb);
+ } else {
+ if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
+ (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
+ (av->assoc_id == SCTP_FUTURE_ASSOC)) {
+ SCTP_INP_RLOCK(inp);
+ av->assoc_value = inp->prsctp_supported;
+ SCTP_INP_RUNLOCK(inp);
+ } else {
+ SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
+ error = EINVAL;
+ }
+ }
+ if (error == 0) {
+ *optsize = sizeof(struct sctp_assoc_value);
+ }
+ break;
+ }
case SCTP_ENABLE_STREAM_RESET:
{
struct sctp_assoc_value *av;
@@ -6808,7 +6835,36 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
if (av->assoc_value == 0) {
inp->ecn_supported = 0;
} else {
- inp->ecn_supported = 0;
+ inp->ecn_supported = 1;
+ }
+ SCTP_INP_WUNLOCK(inp);
+ } else {
+ SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
+ error = EINVAL;
+ }
+ }
+ break;
+ }
+ case SCTP_PR_SUPPORTED:
+ {
+ struct sctp_assoc_value *av;
+
+ SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, optsize);
+ SCTP_FIND_STCB(inp, stcb, av->assoc_id);
+
+ if (stcb) {
+ SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
+ error = EINVAL;
+ SCTP_TCB_UNLOCK(stcb);
+ } else {
+ if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
+ (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
+ (av->assoc_id == SCTP_FUTURE_ASSOC)) {
+ SCTP_INP_WLOCK(inp);
+ if (av->assoc_value == 0) {
+ inp->prsctp_supported = 0;
+ } else {
+ inp->prsctp_supported = 1;
}
SCTP_INP_WUNLOCK(inp);
} else {
diff --git a/netinet/sctputil.c b/netinet/sctputil.c
index b1007c9..5e4887c 100755
--- a/netinet/sctputil.c
+++ b/netinet/sctputil.c
@@ -32,7 +32,7 @@
#ifdef __FreeBSD__
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/netinet/sctputil.c 269436 2014-08-02 17:35:13Z tuexen $");
+__FBSDID("$FreeBSD: head/sys/netinet/sctputil.c 269448 2014-08-02 21:36:40Z tuexen $");
#endif
#include <netinet/sctp_os.h>
@@ -973,6 +973,7 @@ sctp_init_asoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
asoc->cookie_life = inp->sctp_ep.def_cookie_life;
asoc->sctp_cmt_on_off = inp->sctp_cmt_on_off;
asoc->ecn_supported = inp->ecn_supported;
+ asoc->prsctp_supported = inp->prsctp_supported;
asoc->sctp_nr_sack_on_off = (uint8_t)SCTP_BASE_SYSCTL(sctp_nr_sack_on_off);
asoc->sctp_cmt_pf = (uint8_t)0;
asoc->sctp_frag_point = inp->sctp_frag_point;
@@ -2739,7 +2740,7 @@ sctp_notify_assoc_change(uint16_t state, struct sctp_tcb *stcb,
if (notif_len > sizeof(struct sctp_assoc_change)) {
if ((state == SCTP_COMM_UP) || (state == SCTP_RESTART)) {
i = 0;
- if (stcb->asoc.peer_supports_prsctp) {
+ if (stcb->asoc.prsctp_supported) {
sac->sac_info[i++] = SCTP_ASSOC_SUPPORTS_PR;
}
if (stcb->asoc.peer_supports_auth) {
diff --git a/user_socket.c b/user_socket.c
index b771e62..07ff67d 100755
--- a/user_socket.c
+++ b/user_socket.c
@@ -3247,6 +3247,7 @@ USRSCTP_SYSCTL_SET_DEF(sctp_recvspace)
USRSCTP_SYSCTL_SET_DEF(sctp_auto_asconf)
USRSCTP_SYSCTL_SET_DEF(sctp_multiple_asconfs)
USRSCTP_SYSCTL_SET_DEF(sctp_ecn_enable)
+USRSCTP_SYSCTL_SET_DEF(sctp_pr_enable)
USRSCTP_SYSCTL_SET_DEF(sctp_strict_sacks)
#if !defined(SCTP_WITH_NO_CSUM)
USRSCTP_SYSCTL_SET_DEF(sctp_no_csum_on_loopback)
@@ -3325,6 +3326,7 @@ USRSCTP_SYSCTL_GET_DEF(sctp_recvspace)
USRSCTP_SYSCTL_GET_DEF(sctp_auto_asconf)
USRSCTP_SYSCTL_GET_DEF(sctp_multiple_asconfs)
USRSCTP_SYSCTL_GET_DEF(sctp_ecn_enable)
+USRSCTP_SYSCTL_GET_DEF(sctp_pr_enable)
USRSCTP_SYSCTL_GET_DEF(sctp_strict_sacks)
#if !defined(SCTP_WITH_NO_CSUM)
USRSCTP_SYSCTL_GET_DEF(sctp_no_csum_on_loopback)
diff --git a/usrsctp.h b/usrsctp.h
index a3446de..24741b9 100644
--- a/usrsctp.h
+++ b/usrsctp.h
@@ -992,6 +992,7 @@ USRSCTP_SYSCTL_DECL(sctp_recvspace)
USRSCTP_SYSCTL_DECL(sctp_auto_asconf)
USRSCTP_SYSCTL_DECL(sctp_multiple_asconfs)
USRSCTP_SYSCTL_DECL(sctp_ecn_enable)
+USRSCTP_SYSCTL_DECL(sctp_pr_enable)
USRSCTP_SYSCTL_DECL(sctp_strict_sacks)
#if !defined(SCTP_WITH_NO_CSUM)
USRSCTP_SYSCTL_DECL(sctp_no_csum_on_loopback)