summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPrimiano Tucci <primiano@google.com>2014-09-30 14:46:36 +0100
committerPrimiano Tucci <primiano@google.com>2014-09-30 14:46:36 +0100
commit6306c865a9a058a72d461702e959cd853f9f134d (patch)
treeccbf50fa007be0752f9d1ada900d8cfc01698021
parented9a6fb519aa7606cab965b2c4218756e849ddb6 (diff)
parent793f45e9442f232795b0a33a22de234710c06613 (diff)
downloadusrsctplib-lollipop-mr1-release.tar.gz
This commit was generated by merge_to_master.py. Change-Id: Id2579b1aabf6c5e804383e7c1fc9fb39de3dad8d
-rwxr-xr-xnetinet/sctp.h11
-rwxr-xr-xnetinet/sctp_asconf.c140
-rwxr-xr-xnetinet/sctp_auth.c29
-rwxr-xr-xnetinet/sctp_auth.h3
-rwxr-xr-xnetinet/sctp_constants.h35
-rwxr-xr-xnetinet/sctp_header.h8
-rwxr-xr-xnetinet/sctp_indata.c33
-rwxr-xr-xnetinet/sctp_input.c267
-rwxr-xr-xnetinet/sctp_output.c603
-rwxr-xr-xnetinet/sctp_pcb.c211
-rwxr-xr-xnetinet/sctp_pcb.h12
-rwxr-xr-xnetinet/sctp_peeloff.c18
-rwxr-xr-xnetinet/sctp_structs.h45
-rwxr-xr-xnetinet/sctp_sysctl.c1179
-rwxr-xr-xnetinet/sctp_sysctl.h82
-rwxr-xr-xnetinet/sctp_timer.c26
-rwxr-xr-xnetinet/sctp_uio.h24
-rwxr-xr-xnetinet/sctp_usrreq.c512
-rwxr-xr-xnetinet/sctp_var.h80
-rwxr-xr-xnetinet/sctputil.c188
-rwxr-xr-xnetinet/sctputil.h32
-rw-r--r--netinet6/sctp6_usrreq.c16
-rwxr-xr-xuser_socket.c19
-rw-r--r--usrsctp.h11
24 files changed, 2063 insertions, 1521 deletions
diff --git a/netinet/sctp.h b/netinet/sctp.h
index b4a1fe9..a2ab878 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 264679 2014-04-19 19:21:06Z tuexen $");
+__FBSDID("$FreeBSD: head/sys/netinet/sctp.h 269945 2014-08-13 15:50:16Z tuexen $");
#endif
#ifndef _NETINET_SCTP_H_
@@ -131,6 +131,13 @@ struct sctp_paramhdr {
#define SCTP_DEFAULT_PRINFO 0x00000022
#define SCTP_PEER_ADDR_THLDS 0x00000023
#define SCTP_REMOTE_UDP_ENCAPS_PORT 0x00000024
+#define SCTP_ECN_SUPPORTED 0x00000025
+#define SCTP_PR_SUPPORTED 0x00000026
+#define SCTP_AUTH_SUPPORTED 0x00000027
+#define SCTP_ASCONF_SUPPORTED 0x00000028
+#define SCTP_RECONFIG_SUPPORTED 0x00000029
+#define SCTP_NRSACK_SUPPORTED 0x00000030
+#define SCTP_PKTDROP_SUPPORTED 0x00000031
/*
* read-only options
@@ -143,6 +150,8 @@ struct sctp_paramhdr {
#define SCTP_GET_ASSOC_NUMBER 0x00000104 /* ro */
#define SCTP_GET_ASSOC_ID_LIST 0x00000105 /* ro */
#define SCTP_TIMEOUTS 0x00000106
+#define SCTP_PR_STREAM_STATUS 0x00000107
+#define SCTP_PR_ASSOC_STATUS 0x00000108
/*
* user socket options: BSD implementation specific
diff --git a/netinet/sctp_asconf.c b/netinet/sctp_asconf.c
index 0f35ae1..a0d5cee 100755
--- a/netinet/sctp_asconf.c
+++ b/netinet/sctp_asconf.c
@@ -32,7 +32,7 @@
#ifdef __FreeBSD__
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/netinet/sctp_asconf.c 267674 2014-06-20 13:26:49Z tuexen $");
+__FBSDID("$FreeBSD: head/sys/netinet/sctp_asconf.c 271228 2014-09-07 17:07:19Z tuexen $");
#endif
#include <netinet/sctp_os.h>
@@ -153,7 +153,7 @@ sctp_process_asconf_add_ip(struct sockaddr *src, struct sctp_asconf_paramhdr *ap
{
struct sctp_nets *net;
struct mbuf *m_reply = NULL;
- struct sockaddr_storage sa_store;
+ union sctp_sockstore store;
struct sctp_paramhdr *ph;
uint16_t param_type, aparam_length;
#if defined(INET) || defined(INET6)
@@ -177,7 +177,7 @@ sctp_process_asconf_add_ip(struct sockaddr *src, struct sctp_asconf_paramhdr *ap
#if defined(INET) || defined(INET6)
param_length = ntohs(ph->param_length);
#endif
- sa = (struct sockaddr *)&sa_store;
+ sa = &store.sa;
switch (param_type) {
#ifdef INET
case SCTP_IPV4_ADDRESS:
@@ -186,7 +186,7 @@ sctp_process_asconf_add_ip(struct sockaddr *src, struct sctp_asconf_paramhdr *ap
return (NULL);
}
v4addr = (struct sctp_ipv4addr_param *)ph;
- sin = (struct sockaddr_in *)&sa_store;
+ sin = &store.sin;
bzero(sin, sizeof(*sin));
sin->sin_family = AF_INET;
#ifdef HAVE_SIN_LEN
@@ -211,7 +211,7 @@ sctp_process_asconf_add_ip(struct sockaddr *src, struct sctp_asconf_paramhdr *ap
return (NULL);
}
v6addr = (struct sctp_ipv6addr_param *)ph;
- sin6 = (struct sockaddr_in6 *)&sa_store;
+ sin6 = &store.sin6;
bzero(sin6, sizeof(*sin6));
sin6->sin6_family = AF_INET6;
#ifdef HAVE_SIN6_LEN
@@ -307,7 +307,7 @@ sctp_process_asconf_delete_ip(struct sockaddr *src,
struct sctp_tcb *stcb, int response_required)
{
struct mbuf *m_reply = NULL;
- struct sockaddr_storage sa_store;
+ union sctp_sockstore store;
struct sctp_paramhdr *ph;
uint16_t param_type, aparam_length;
#if defined(INET) || defined(INET6)
@@ -331,7 +331,7 @@ sctp_process_asconf_delete_ip(struct sockaddr *src,
#if defined(INET) || defined(INET6)
param_length = ntohs(ph->param_length);
#endif
- sa = (struct sockaddr *)&sa_store;
+ sa = &store.sa;
switch (param_type) {
#ifdef INET
case SCTP_IPV4_ADDRESS:
@@ -340,7 +340,7 @@ sctp_process_asconf_delete_ip(struct sockaddr *src,
return (NULL);
}
v4addr = (struct sctp_ipv4addr_param *)ph;
- sin = (struct sockaddr_in *)&sa_store;
+ sin = &store.sin;
bzero(sin, sizeof(*sin));
sin->sin_family = AF_INET;
#ifdef HAVE_SIN_LEN
@@ -362,7 +362,7 @@ sctp_process_asconf_delete_ip(struct sockaddr *src,
return (NULL);
}
v6addr = (struct sctp_ipv6addr_param *)ph;
- sin6 = (struct sockaddr_in6 *)&sa_store;
+ sin6 = &store.sin6;
bzero(sin6, sizeof(*sin6));
sin6->sin6_family = AF_INET6;
#ifdef HAVE_SIN6_LEN
@@ -429,7 +429,7 @@ sctp_process_asconf_delete_ip(struct sockaddr *src,
aparam_length);
} else {
if (response_required) {
- m_reply = sctp_asconf_success_response(aph->correlation_id);
+ m_reply = sctp_asconf_success_response(aph->correlation_id);
}
/* notify upper layer */
sctp_ulp_notify(SCTP_NOTIFY_ASCONF_DELETE_IP, stcb, 0, sa, SCTP_SO_NOT_LOCKED);
@@ -443,7 +443,7 @@ sctp_process_asconf_set_primary(struct sockaddr *src,
struct sctp_tcb *stcb, int response_required)
{
struct mbuf *m_reply = NULL;
- struct sockaddr_storage sa_store;
+ union sctp_sockstore store;
struct sctp_paramhdr *ph;
uint16_t param_type, aparam_length;
#if defined(INET) || defined(INET6)
@@ -466,7 +466,7 @@ sctp_process_asconf_set_primary(struct sockaddr *src,
#if defined(INET) || defined(INET6)
param_length = ntohs(ph->param_length);
#endif
- sa = (struct sockaddr *)&sa_store;
+ sa = &store.sa;
switch (param_type) {
#ifdef INET
case SCTP_IPV4_ADDRESS:
@@ -475,7 +475,7 @@ sctp_process_asconf_set_primary(struct sockaddr *src,
return (NULL);
}
v4addr = (struct sctp_ipv4addr_param *)ph;
- sin = (struct sockaddr_in *)&sa_store;
+ sin = &store.sin;
bzero(sin, sizeof(*sin));
sin->sin_family = AF_INET;
#ifdef HAVE_SIN_LEN
@@ -495,7 +495,7 @@ sctp_process_asconf_set_primary(struct sockaddr *src,
return (NULL);
}
v6addr = (struct sctp_ipv6addr_param *)ph;
- sin6 = (struct sockaddr_in6 *)&sa_store;
+ sin6 = &store.sin6;
bzero(sin6, sizeof(*sin6));
sin6->sin6_family = AF_INET6;
#ifdef HAVE_SIN6_LEN
@@ -552,11 +552,11 @@ sctp_process_asconf_set_primary(struct sockaddr *src,
are transmitted to the new primary destination. (by micchie)
*/
if ((sctp_is_mobility_feature_on(stcb->sctp_ep,
- SCTP_MOBILITY_BASE) ||
+ SCTP_MOBILITY_BASE) ||
sctp_is_mobility_feature_on(stcb->sctp_ep,
- SCTP_MOBILITY_FASTHANDOFF)) &&
+ SCTP_MOBILITY_FASTHANDOFF)) &&
sctp_is_mobility_feature_on(stcb->sctp_ep,
- SCTP_MOBILITY_PRIM_DELETED) &&
+ SCTP_MOBILITY_PRIM_DELETED) &&
(stcb->asoc.primary_destination->dest_state &
SCTP_ADDR_UNCONFIRMED) == 0) {
@@ -731,13 +731,11 @@ sctp_handle_asconf(struct mbuf *m, unsigned int offset,
}
switch (param_type) {
case SCTP_ADD_IP_ADDRESS:
- asoc->peer_supports_asconf = 1;
m_result = sctp_process_asconf_add_ip(src, aph, stcb,
(cnt < SCTP_BASE_SYSCTL(sctp_hb_maxburst)), error);
cnt++;
break;
case SCTP_DEL_IP_ADDRESS:
- asoc->peer_supports_asconf = 1;
m_result = sctp_process_asconf_delete_ip(src, aph, stcb,
error);
break;
@@ -745,7 +743,6 @@ sctp_handle_asconf(struct mbuf *m, unsigned int offset,
/* not valid in an ASCONF chunk */
break;
case SCTP_SET_PRIM_ADDR:
- asoc->peer_supports_asconf = 1;
m_result = sctp_process_asconf_set_primary(src, aph,
stcb, error);
break;
@@ -936,8 +933,6 @@ sctp_addr_match(struct sctp_paramhdr *ph, struct sockaddr *sa)
void
sctp_asconf_cleanup(struct sctp_tcb *stcb, struct sctp_nets *net)
{
- /* mark peer as ASCONF incapable */
- stcb->asoc.peer_supports_asconf = 0;
/*
* clear out any existing asconfs going out
*/
@@ -1099,7 +1094,7 @@ sctp_path_check_and_react(struct sctp_tcb *stcb, struct sctp_ifa *newifa)
}
/* Retransmit unacknowledged DATA chunks immediately */
if (sctp_is_mobility_feature_on(stcb->sctp_ep,
- SCTP_MOBILITY_FASTHANDOFF)) {
+ SCTP_MOBILITY_FASTHANDOFF)) {
sctp_net_immediate_retrans(stcb, net);
}
/* also, SET PRIMARY is maybe already sent */
@@ -1157,7 +1152,7 @@ sctp_path_check_and_react(struct sctp_tcb *stcb, struct sctp_ifa *newifa)
continue;
/* Retransmit unacknowledged DATA chunks immediately */
if (sctp_is_mobility_feature_on(stcb->sctp_ep,
- SCTP_MOBILITY_FASTHANDOFF)) {
+ SCTP_MOBILITY_FASTHANDOFF)) {
sctp_net_immediate_retrans(stcb, net);
}
/* Send SET PRIMARY for this new address */
@@ -1193,9 +1188,9 @@ sctp_asconf_addr_mgmt_ack(struct sctp_tcb *stcb, struct sctp_ifa *addr, uint32_t
#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__Userspace__)
if (sctp_is_mobility_feature_on(stcb->sctp_ep,
- SCTP_MOBILITY_BASE) ||
+ SCTP_MOBILITY_BASE) ||
sctp_is_mobility_feature_on(stcb->sctp_ep,
- SCTP_MOBILITY_FASTHANDOFF)) {
+ SCTP_MOBILITY_FASTHANDOFF)) {
sctp_path_check_and_react(stcb, addr);
return;
}
@@ -1281,7 +1276,7 @@ sctp_asconf_queue_mgmt(struct sctp_tcb *stcb, struct sctp_ifa *ifa,
{
struct sockaddr_in6 *sin6;
- sin6 = (struct sockaddr_in6 *)&ifa->address.sa;
+ sin6 = &ifa->address.sin6;
aa->ap.addrp.ph.param_type = SCTP_IPV6_ADDRESS;
aa->ap.addrp.ph.param_length = (sizeof(struct sctp_ipv6addr_param));
aa->ap.aph.ph.param_length = sizeof(struct sctp_asconf_paramhdr) +
@@ -1296,7 +1291,7 @@ sctp_asconf_queue_mgmt(struct sctp_tcb *stcb, struct sctp_ifa *ifa,
{
struct sockaddr_in *sin;
- sin = (struct sockaddr_in *)&ifa->address.sa;
+ sin = &ifa->address.sin;
aa->ap.addrp.ph.param_type = SCTP_IPV4_ADDRESS;
aa->ap.addrp.ph.param_length = (sizeof(struct sctp_ipv4addr_param));
aa->ap.aph.ph.param_length = sizeof(struct sctp_asconf_paramhdr) +
@@ -1348,7 +1343,7 @@ sctp_asconf_queue_add(struct sctp_tcb *stcb, struct sctp_ifa *ifa,
int pending_delete_queued = 0;
/* see if peer supports ASCONF */
- if (stcb->asoc.peer_supports_asconf == 0) {
+ if (stcb->asoc.asconf_supported == 0) {
return (-1);
}
@@ -1440,7 +1435,7 @@ sctp_asconf_queue_sa_delete(struct sctp_tcb *stcb, struct sockaddr *sa)
return (-1);
}
/* see if peer supports ASCONF */
- if (stcb->asoc.peer_supports_asconf == 0) {
+ if (stcb->asoc.asconf_supported == 0) {
return (-1);
}
/* make sure the request isn't already in the queue */
@@ -1560,7 +1555,7 @@ sctp_asconf_find_param(struct sctp_tcb *stcb, uint32_t correlation_id)
* notifications based on the error response
*/
static void
-sctp_asconf_process_error(struct sctp_tcb *stcb,
+sctp_asconf_process_error(struct sctp_tcb *stcb SCTP_UNUSED,
struct sctp_asconf_paramhdr *aph)
{
struct sctp_error_cause *eh;
@@ -1598,10 +1593,7 @@ sctp_asconf_process_error(struct sctp_tcb *stcb,
switch (param_type) {
case SCTP_ADD_IP_ADDRESS:
case SCTP_DEL_IP_ADDRESS:
- stcb->asoc.peer_supports_asconf = 0;
- break;
case SCTP_SET_PRIM_ADDR:
- stcb->asoc.peer_supports_asconf = 0;
break;
default:
break;
@@ -1637,8 +1629,6 @@ sctp_asconf_process_param_ack(struct sctp_tcb *stcb,
SCTPDBG(SCTP_DEBUG_ASCONF1,
"process_param_ack: set primary IP address\n");
/* nothing to do... peer may start using this addr */
- if (flag == 0)
- stcb->asoc.peer_supports_asconf = 0;
break;
default:
/* should NEVER happen */
@@ -1656,11 +1646,11 @@ sctp_asconf_process_param_ack(struct sctp_tcb *stcb,
* cleanup from a bad asconf ack parameter
*/
static void
-sctp_asconf_ack_clear(struct sctp_tcb *stcb)
+sctp_asconf_ack_clear(struct sctp_tcb *stcb SCTP_UNUSED)
{
/* assume peer doesn't really know how to do asconfs */
- stcb->asoc.peer_supports_asconf = 0;
/* XXX we could free the pending queue here */
+
}
void
@@ -1950,7 +1940,7 @@ sctp_addr_mgmt_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
{
struct sockaddr_in6 *sin6;
- sin6 = (struct sockaddr_in6 *)&ifa->address.sin6;
+ sin6 = &ifa->address.sin6;
if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
/* we skip unspecifed addresses */
return;
@@ -1983,7 +1973,7 @@ sctp_addr_mgmt_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
SCTP_IPV6_V6ONLY(inp6))
return;
- sin = (struct sockaddr_in *)&ifa->address.sa;
+ sin = &ifa->address.sin;
if (sin->sin_addr.s_addr == 0) {
/* we skip unspecifed addresses */
return;
@@ -2003,7 +1993,7 @@ sctp_addr_mgmt_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
/* queue an asconf for this address add/delete */
if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_DO_ASCONF)) {
/* does the peer do asconf? */
- if (stcb->asoc.peer_supports_asconf) {
+ if (stcb->asoc.asconf_supported) {
/* queue an asconf for this addr */
status = sctp_asconf_queue_add(stcb, ifa, type);
@@ -2141,7 +2131,7 @@ sctp_asconf_iterator_stcb(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
else
continue;
}
- sin6 = (struct sockaddr_in6 *)&ifa->address.sin6;
+ sin6 = &ifa->address.sin6;
if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
/* we skip unspecifed addresses */
continue;
@@ -2177,7 +2167,7 @@ sctp_asconf_iterator_stcb(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
SCTP_IPV6_V6ONLY(inp6))
continue;
- sin = (struct sockaddr_in *)&ifa->address.sa;
+ sin = &ifa->address.sin;
if (sin->sin_addr.s_addr == 0) {
/* we skip unspecifed addresses */
continue;
@@ -2257,7 +2247,7 @@ sctp_asconf_iterator_stcb(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
}
/* queue an asconf for this address add/delete */
if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_DO_ASCONF) &&
- stcb->asoc.peer_supports_asconf) {
+ stcb->asoc.asconf_supported == 1) {
/* queue an asconf for this addr */
status = sctp_asconf_queue_add(stcb, ifa, type);
/*
@@ -2308,7 +2298,7 @@ sctp_asconf_iterator_end(void *ptr, uint32_t val SCTP_UNUSED)
int32_t
sctp_set_primary_ip_address_sa(struct sctp_tcb *stcb, struct sockaddr *sa)
{
- uint32_t vrf_id;
+ uint32_t vrf_id;
struct sctp_ifa *ifa;
/* find the ifa for the desired set primary */
@@ -2496,7 +2486,7 @@ sctp_find_valid_localaddr(struct sctp_tcb *stcb, int addr_locked)
if (stcb->asoc.scope.ipv4_addr_legal) {
struct sockaddr_in *sin;
- sin = (struct sockaddr_in *)&sctp_ifa->address.sa;
+ sin = &sctp_ifa->address.sin;
if (sin->sin_addr.s_addr == 0) {
/* skip unspecifed addresses */
continue;
@@ -2530,7 +2520,7 @@ sctp_find_valid_localaddr(struct sctp_tcb *stcb, int addr_locked)
continue;
}
- sin6 = (struct sockaddr_in6 *)&sctp_ifa->address.sa;
+ sin6 = &sctp_ifa->address.sin6;
if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
/* we skip unspecifed addresses */
continue;
@@ -2798,15 +2788,13 @@ sctp_process_initack_addresses(struct sctp_tcb *stcb, struct mbuf *m,
struct sctp_paramhdr tmp_param, *ph;
uint16_t plen, ptype;
struct sctp_ifa *sctp_ifa;
+ union sctp_sockstore store;
#ifdef INET6
struct sctp_ipv6addr_param addr6_store;
- struct sockaddr_in6 sin6;
#endif
#ifdef INET
struct sctp_ipv4addr_param addr4_store;
- struct sockaddr_in sin;
#endif
- struct sockaddr *sa;
uint32_t vrf_id;
SCTPDBG(SCTP_DEBUG_ASCONF2, "processing init-ack addresses\n");
@@ -2819,25 +2807,6 @@ sctp_process_initack_addresses(struct sctp_tcb *stcb, struct mbuf *m,
if ((offset + sizeof(struct sctp_paramhdr)) > length) {
return;
}
- /* init the addresses */
-#ifdef INET6
- bzero(&sin6, sizeof(sin6));
- sin6.sin6_family = AF_INET6;
-#ifdef HAVE_SIN6_LEN
- sin6.sin6_len = sizeof(sin6);
-#endif
- sin6.sin6_port = stcb->rport;
-#endif
-
-#ifdef INET
- bzero(&sin, sizeof(sin));
- sin.sin_family = AF_INET;
-#ifdef HAVE_SIN_LEN
- sin.sin_len = sizeof(sin);
-#endif
- sin.sin_port = stcb->rport;
-#endif
-
/* go through the addresses in the init-ack */
ph = (struct sctp_paramhdr *)
sctp_m_getptr(m, offset, sizeof(struct sctp_paramhdr),
@@ -2860,9 +2829,13 @@ sctp_process_initack_addresses(struct sctp_tcb *stcb, struct mbuf *m,
a6p == NULL) {
return;
}
- memcpy(&sin6.sin6_addr, a6p->addr,
- sizeof(struct in6_addr));
- sa = (struct sockaddr *)&sin6;
+ memset(&store, 0, sizeof(union sctp_sockstore));
+ store.sin6.sin6_family = AF_INET6;
+#ifdef HAVE_SIN6_LEN
+ store.sin6.sin6_len = sizeof(struct sockaddr_in6);
+#endif
+ store.sin6.sin6_port = stcb->rport;
+ memcpy(&store.sin6.sin6_addr, a6p->addr, sizeof(struct in6_addr));
break;
}
#endif
@@ -2879,8 +2852,13 @@ sctp_process_initack_addresses(struct sctp_tcb *stcb, struct mbuf *m,
a4p == NULL) {
return;
}
- sin.sin_addr.s_addr = a4p->addr;
- sa = (struct sockaddr *)&sin;
+ memset(&store, 0, sizeof(union sctp_sockstore));
+ store.sin.sin_family = AF_INET;
+#ifdef HAVE_SIN_LEN
+ store.sin.sin_len = sizeof(struct sockaddr_in);
+#endif
+ store.sin.sin_port = stcb->rport;
+ store.sin.sin_addr.s_addr = a4p->addr;
break;
}
#endif
@@ -2894,7 +2872,7 @@ sctp_process_initack_addresses(struct sctp_tcb *stcb, struct mbuf *m,
} else {
vrf_id = SCTP_DEFAULT_VRFID;
}
- sctp_ifa = sctp_find_ifa_by_addr(sa, vrf_id,
+ sctp_ifa = sctp_find_ifa_by_addr(&store.sa, vrf_id,
SCTP_ADDR_NOT_LOCKED);
if (sctp_ifa == NULL) {
/* address doesn't exist anymore */
@@ -2903,9 +2881,9 @@ sctp_process_initack_addresses(struct sctp_tcb *stcb, struct mbuf *m,
/* are ASCONFs allowed ? */
if ((sctp_is_feature_on(stcb->sctp_ep,
SCTP_PCB_FLAGS_DO_ASCONF)) &&
- stcb->asoc.peer_supports_asconf) {
+ stcb->asoc.asconf_supported) {
/* queue an ASCONF DEL_IP_ADDRESS */
- status = sctp_asconf_queue_sa_delete(stcb, sa);
+ status = sctp_asconf_queue_sa_delete(stcb, &store.sa);
/*
* if queued ok, and in correct state, send
* out the ASCONF.
@@ -2939,7 +2917,7 @@ next_addr:
if ((offset + sizeof(struct sctp_paramhdr)) > length)
return;
ph = (struct sctp_paramhdr *)sctp_m_getptr(m, offset,
- sizeof(struct sctp_paramhdr), (uint8_t *) & tmp_param);
+ sizeof(struct sctp_paramhdr), (uint8_t *)&tmp_param);
} /* while */
}
@@ -3151,7 +3129,7 @@ sctp_check_address_list_all(struct sctp_tcb *stcb, struct mbuf *m, int offset,
switch (sctp_ifa->address.sa.sa_family) {
#ifdef INET
case AF_INET:
- sin = (struct sockaddr_in *)&sctp_ifa->address.sin;
+ sin = &sctp_ifa->address.sin;
#if defined(__FreeBSD__)
if (prison_check_ip4(stcb->sctp_ep->ip_inp.inp.inp_cred,
&sin->sin_addr) != 0) {
@@ -3167,7 +3145,7 @@ sctp_check_address_list_all(struct sctp_tcb *stcb, struct mbuf *m, int offset,
#endif
#ifdef INET6
case AF_INET6:
- sin6 = (struct sockaddr_in6 *)&sctp_ifa->address.sin6;
+ sin6 = &sctp_ifa->address.sin6;
#if defined(__FreeBSD__)
if (prison_check_ip6(stcb->sctp_ep->ip_inp.inp.inp_cred,
&sin6->sin6_addr) != 0) {
@@ -3250,7 +3228,7 @@ sctp_addr_mgmt_ep_sa(struct sctp_inpcb *inp, struct sockaddr *sa,
#endif
if (sctp_ifap) {
ifa = sctp_ifap;
- } else if (type == SCTP_ADD_IP_ADDRESS) {
+ } else if (type == SCTP_ADD_IP_ADDRESS) {
/* For an add the address MUST be on the system */
ifa = sctp_find_ifa_by_addr(sa, vrf_id, SCTP_ADDR_NOT_LOCKED);
} else if (type == SCTP_DEL_IP_ADDRESS) {
diff --git a/netinet/sctp_auth.c b/netinet/sctp_auth.c
index dfad97e..00ff978 100755
--- a/netinet/sctp_auth.c
+++ b/netinet/sctp_auth.c
@@ -32,7 +32,7 @@
#ifdef __FreeBSD__
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/netinet/sctp_auth.c 257804 2013-11-07 18:50:11Z tuexen $");
+__FBSDID("$FreeBSD: head/sys/netinet/sctp_auth.c 269858 2014-08-12 11:30:16Z tuexen $");
#endif
#include <netinet/sctp_os.h>
@@ -135,11 +135,6 @@ sctp_auth_delete_chunk(uint8_t chunk, sctp_auth_chklist_t *list)
if (list == NULL)
return (-1);
- /* is chunk restricted? */
- if ((chunk == SCTP_ASCONF) ||
- (chunk == SCTP_ASCONF_ACK)) {
- return (-1);
- }
if (list->chunks[chunk] == 1) {
list->chunks[chunk] = 0;
list->num_chunks--;
@@ -160,16 +155,6 @@ sctp_auth_get_chklist_size(const sctp_auth_chklist_t *list)
}
/*
- * set the default list of chunks requiring AUTH
- */
-void
-sctp_auth_set_default_chunks(sctp_auth_chklist_t *list)
-{
- (void)sctp_auth_add_chunk(SCTP_ASCONF, list);
- (void)sctp_auth_add_chunk(SCTP_ASCONF_ACK, list);
-}
-
-/*
* return the current number and list of required chunks caller must
* guarantee ptr has space for up to 256 bytes
*/
@@ -397,9 +382,9 @@ sctp_compare_key(sctp_key_t *key1, sctp_key_t *key2)
val1 = (i < (maxlen - key1len)) ? 0 : *(key_1++);
val2 = (i < (maxlen - key2len)) ? 0 : *(key_2++);
if (val1 > val2) {
- return (1);
+ return (1);
} else if (val1 < val2) {
- return (-1);
+ return (-1);
}
}
/* keys are equal value, so check lengths */
@@ -800,7 +785,7 @@ sctp_verify_hmac_param (struct sctp_auth_hmac_algo *hmacs, uint32_t num_hmacs)
for (i = 0; i < num_hmacs; i++) {
if (ntohs(hmacs->hmac_ids[i]) == SCTP_AUTH_HMAC_ID_SHA1) {
- return (0);
+ return (0);
}
}
return (-1);
@@ -1554,7 +1539,7 @@ sctp_auth_get_cookie_params(struct sctp_tcb *stcb, struct mbuf *m,
}
}
if (stcb->asoc.authinfo.random != NULL)
- sctp_free_key(stcb->asoc.authinfo.random);
+ sctp_free_key(stcb->asoc.authinfo.random);
stcb->asoc.authinfo.random = new_key;
stcb->asoc.authinfo.random_len = random_len;
sctp_clear_cachedkeys(stcb, stcb->asoc.authinfo.assoc_keyid);
@@ -1818,6 +1803,7 @@ sctp_notify_authentication(struct sctp_tcb *stcb, uint32_t indication,
SCTP_BUF_LEN(m_notify) = 0;
auth = mtod(m_notify, struct sctp_authkey_event *);
+ memset(auth, 0, sizeof(struct sctp_authkey_event));
auth->auth_type = SCTP_AUTHENTICATION_EVENT;
auth->auth_flags = 0;
auth->auth_length = sizeof(*auth);
@@ -1975,8 +1961,7 @@ sctp_validate_init_auth_params(struct mbuf *m, int offset, int limit)
"SCTP: peer sent chunk list w/o AUTH\n");
return (-1);
}
- if (!SCTP_BASE_SYSCTL(sctp_asconf_auth_nochk) && peer_supports_asconf &&
- !peer_supports_auth) {
+ if (peer_supports_asconf && !peer_supports_auth) {
SCTPDBG(SCTP_DEBUG_AUTH1,
"SCTP: peer supports ASCONF but not AUTH\n");
return (-1);
diff --git a/netinet/sctp_auth.h b/netinet/sctp_auth.h
index eeff278..04649ad 100755
--- a/netinet/sctp_auth.h
+++ b/netinet/sctp_auth.h
@@ -32,7 +32,7 @@
#ifdef __FreeBSD__
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/netinet/sctp_auth.h 257804 2013-11-07 18:50:11Z tuexen $");
+__FBSDID("$FreeBSD: head/sys/netinet/sctp_auth.h 269858 2014-08-12 11:30:16Z tuexen $");
#endif
#ifndef _NETINET_SCTP_AUTH_H_
@@ -116,7 +116,6 @@ extern sctp_auth_chklist_t *sctp_copy_chunklist(sctp_auth_chklist_t *chklist);
extern int sctp_auth_add_chunk(uint8_t chunk, sctp_auth_chklist_t *list);
extern int sctp_auth_delete_chunk(uint8_t chunk, sctp_auth_chklist_t *list);
extern size_t sctp_auth_get_chklist_size(const sctp_auth_chklist_t *list);
-extern void sctp_auth_set_default_chunks(sctp_auth_chklist_t *list);
extern int sctp_serialize_auth_chunks(const sctp_auth_chklist_t *list,
uint8_t *ptr);
extern int sctp_pack_auth_chunks(const sctp_auth_chklist_t *list,
diff --git a/netinet/sctp_constants.h b/netinet/sctp_constants.h
index 12e0c13..ff4874d 100755
--- a/netinet/sctp_constants.h
+++ b/netinet/sctp_constants.h
@@ -32,7 +32,7 @@
#ifdef __FreeBSD__
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/netinet/sctp_constants.h 263921 2014-03-29 20:21:36Z tuexen $");
+__FBSDID("$FreeBSD: head/sys/netinet/sctp_constants.h 271204 2014-09-06 19:12:14Z tuexen $");
#endif
#ifndef _NETINET_SCTP_CONSTANTS_H_
@@ -272,42 +272,9 @@ extern void getwintimeofday(struct timeval *tv);
/* how many addresses per assoc remote and local */
#define SCTP_SCALE_FOR_ADDR 2
-/* default AUTO_ASCONF mode enable(1)/disable(0) value (sysctl) */
-#if defined(__APPLE__)
-#if !defined(SCTP_APPLE_AUTO_ASCONF)
-#define SCTP_DEFAULT_AUTO_ASCONF 0
-#else
-#define SCTP_DEFAULT_AUTO_ASCONF 1
-#endif
-#else
-#define SCTP_DEFAULT_AUTO_ASCONF 1
-#endif
-
/* default MULTIPLE_ASCONF mode enable(1)/disable(0) value (sysctl) */
#define SCTP_DEFAULT_MULTIPLE_ASCONFS 0
-/* default MOBILITY_BASE mode enable(1)/disable(0) value (sysctl) */
-#if defined(__APPLE__)
-#if !defined(SCTP_APPLE_MOBILITY_BASE)
-#define SCTP_DEFAULT_MOBILITY_BASE 0
-#else
-#define SCTP_DEFAULT_MOBILITY_BASE 1
-#endif
-#else
-#define SCTP_DEFAULT_MOBILITY_BASE 0
-#endif
-
-/* default MOBILITY_FASTHANDOFF mode enable(1)/disable(0) value (sysctl) */
-#if defined(__APPLE__)
-#if !defined(SCTP_APPLE_MOBILITY_FASTHANDOFF)
-#define SCTP_DEFAULT_MOBILITY_FASTHANDOFF 0
-#else
-#define SCTP_DEFAULT_MOBILITY_FASTHANDOFF 1
-#endif
-#else
-#define SCTP_DEFAULT_MOBILITY_FASTHANDOFF 0
-#endif
-
/*
* Theshold for rwnd updates, we have to read (sb_hiwat >>
* SCTP_RWND_HIWAT_SHIFT) before we will look to see if we need to send a
diff --git a/netinet/sctp_header.h b/netinet/sctp_header.h
index e6f441c..a860c18 100755
--- a/netinet/sctp_header.h
+++ b/netinet/sctp_header.h
@@ -32,7 +32,7 @@
#ifdef __FreeBSD__
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/netinet/sctp_header.h 240198 2012-09-07 13:36:42Z tuexen $");
+__FBSDID("$FreeBSD: head/sys/netinet/sctp_header.h 269376 2014-08-01 12:42:37Z tuexen $");
#endif
#ifndef _NETINET_SCTP_HEADER_H_
@@ -94,12 +94,6 @@ struct sctp_supported_addr_param {
uint16_t addr_type[2]; /* array of supported address types */
} SCTP_PACKED;
-/* ECN parameter */
-struct sctp_ecn_supported_param {
- struct sctp_paramhdr ph;/* type=SCTP_ECN_CAPABLE */
-} SCTP_PACKED;
-
-
/* heartbeat info parameter */
struct sctp_heartbeat_info_param {
struct sctp_paramhdr ph;
diff --git a/netinet/sctp_indata.c b/netinet/sctp_indata.c
index 125c82f..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 264838 2014-04-23 21:20:55Z tuexen $");
+__FBSDID("$FreeBSD: head/sys/netinet/sctp_indata.c 269448 2014-08-02 21:36:40Z tuexen $");
#endif
#include <netinet/sctp_os.h>
@@ -261,6 +261,11 @@ sctp_build_ctl_nchunk(struct sctp_inpcb *inp, struct sctp_sndrcvinfo *sinfo)
#else
cmh = mtod(ret, struct cmsghdr *);
#endif
+ /*
+ * Make sure that there is no un-initialized padding between
+ * the cmsg header and cmsg data and after the cmsg data.
+ */
+ memset(cmh, 0, len);
if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_RECVRCVINFO)) {
cmh->cmsg_level = IPPROTO_SCTP;
cmh->cmsg_len = CMSG_LEN(sizeof(struct sctp_rcvinfo));
@@ -411,7 +416,7 @@ sctp_service_reassembly(struct sctp_tcb *stcb, struct sctp_association *asoc)
}
/* Now free the address and data */
sctp_free_a_chunk(stcb, chk, SCTP_SO_NOT_LOCKED);
- /*sa_ignore FREED_MEMORY*/
+ /*sa_ignore FREED_MEMORY*/
}
return;
}
@@ -665,8 +670,8 @@ sctp_queue_data_to_stream(struct sctp_tcb *stcb, struct sctp_association *asoc,
* Ok, we did not deliver this guy, find the correct place
* to put it on the queue.
*/
- if (SCTP_TSN_GE(asoc->cumulative_tsn, control->sinfo_tsn)) {
- goto protocol_error;
+ if (SCTP_TSN_GE(asoc->cumulative_tsn, control->sinfo_tsn)) {
+ goto protocol_error;
}
if (TAILQ_EMPTY(&strm->inqueue)) {
/* Empty queue */
@@ -871,7 +876,7 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc,
snprintf(msg, sizeof(msg),
"Expected B-bit for TSN=%8.8x, SID=%4.4x, SSN=%4.4x",
chk->rec.data.TSN_seq,
- chk->rec.data.stream_number,
+ chk->rec.data.stream_number,
chk->rec.data.stream_seq);
op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg);
stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA+SCTP_LOC_2;
@@ -888,7 +893,7 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc,
snprintf(msg, sizeof(msg),
"Didn't expect B-bit for TSN=%8.8x, SID=%4.4x, SSN=%4.4x",
chk->rec.data.TSN_seq,
- chk->rec.data.stream_number,
+ chk->rec.data.stream_number,
chk->rec.data.stream_seq);
op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg);
stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA+SCTP_LOC_3;
@@ -2522,7 +2527,7 @@ sctp_process_data(struct mbuf **mm, int iphlen, int *offset, int length,
SCTP_BUF_LEN(merr) = sizeof(*phd);
SCTP_BUF_NEXT(merr) = SCTP_M_COPYM(m, *offset, chk_length, M_NOWAIT);
if (SCTP_BUF_NEXT(merr)) {
- if (sctp_pad_lastmbuf(SCTP_BUF_NEXT(merr), SCTP_SIZE32(chk_length) - chk_length, NULL)) {
+ if (sctp_pad_lastmbuf(SCTP_BUF_NEXT(merr), SCTP_SIZE32(chk_length) - chk_length, NULL) == NULL) {
sctp_m_freem(merr);
} else {
sctp_queue_op_err(stcb, merr);
@@ -2973,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) {
@@ -2994,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__
@@ -3247,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) {
@@ -3379,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) {
@@ -4063,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;
@@ -4501,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--;
}
}
@@ -4936,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 df244e8..cb7968f 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 263237 2014-03-16 12:32:16Z tuexen $");
+__FBSDID("$FreeBSD: head/sys/netinet/sctp_input.c 271230 2014-09-07 18:05:37Z tuexen $");
#endif
#include <netinet/sctp_os.h>
@@ -49,7 +49,7 @@ __FBSDID("$FreeBSD: head/sys/netinet/sctp_input.c 263237 2014-03-16 12:32:16Z tu
#include <netinet/sctp_bsd_addr.h>
#include <netinet/sctp_timer.h>
#include <netinet/sctp_crc32.h>
-#if defined INET || defined INET6
+#if defined(INET) || defined(INET6)
#if !defined(__Userspace_os_Windows)
#include <netinet/udp.h>
#endif
@@ -507,7 +507,7 @@ sctp_process_init_ack(struct mbuf *m, int iphlen, int offset,
return (-1);
}
/* if the peer doesn't support asconf, flush the asconf queue */
- if (asoc->peer_supports_asconf == 0) {
+ if (asoc->asconf_supported == 0) {
struct sctp_asconf_addr *param, *nparam;
TAILQ_FOREACH_SAFE(param, &asoc->asconf_queue, next, nparam) {
@@ -593,20 +593,11 @@ static void
sctp_handle_heartbeat_ack(struct sctp_heartbeat_chunk *cp,
struct sctp_tcb *stcb, struct sctp_nets *net)
{
- struct sockaddr_storage store;
+ union sctp_sockstore store;
struct sctp_nets *r_net, *f_net;
struct timeval tv;
int req_prim = 0;
uint16_t old_error_counter;
-#ifdef INET
- struct sockaddr_in *sin;
-#endif
-#ifdef INET6
- struct sockaddr_in6 *sin6;
-#endif
-#if defined(__Userspace__)
- struct sockaddr_conn *sconn;
-#endif
if (ntohs(cp->ch.chunk_length) != sizeof(struct sctp_heartbeat_chunk)) {
/* Invalid length */
@@ -618,14 +609,13 @@ sctp_handle_heartbeat_ack(struct sctp_heartbeat_chunk *cp,
#ifdef INET
case AF_INET:
if (cp->heartbeat.hb_info.addr_len == sizeof(struct sockaddr_in)) {
- sin = (struct sockaddr_in *)&store;
- sin->sin_family = cp->heartbeat.hb_info.addr_family;
+ store.sin.sin_family = cp->heartbeat.hb_info.addr_family;
#ifdef HAVE_SIN_LEN
- sin->sin_len = cp->heartbeat.hb_info.addr_len;
+ store.sin.sin_len = cp->heartbeat.hb_info.addr_len;
#endif
- sin->sin_port = stcb->rport;
- memcpy(&sin->sin_addr, cp->heartbeat.hb_info.address,
- sizeof(sin->sin_addr));
+ store.sin.sin_port = stcb->rport;
+ memcpy(&store.sin.sin_addr, cp->heartbeat.hb_info.address,
+ sizeof(store.sin.sin_addr));
} else {
return;
}
@@ -634,14 +624,12 @@ sctp_handle_heartbeat_ack(struct sctp_heartbeat_chunk *cp,
#ifdef INET6
case AF_INET6:
if (cp->heartbeat.hb_info.addr_len == sizeof(struct sockaddr_in6)) {
- sin6 = (struct sockaddr_in6 *)&store;
- sin6->sin6_family = cp->heartbeat.hb_info.addr_family;
+ store.sin6.sin6_family = cp->heartbeat.hb_info.addr_family;
#ifdef HAVE_SIN6_LEN
- sin6->sin6_len = cp->heartbeat.hb_info.addr_len;
+ store.sin6.sin6_len = cp->heartbeat.hb_info.addr_len;
#endif
- sin6->sin6_port = stcb->rport;
- memcpy(&sin6->sin6_addr, cp->heartbeat.hb_info.address,
- sizeof(sin6->sin6_addr));
+ store.sin6.sin6_port = stcb->rport;
+ memcpy(&store.sin6.sin6_addr, cp->heartbeat.hb_info.address, sizeof(struct in6_addr));
} else {
return;
}
@@ -650,14 +638,12 @@ sctp_handle_heartbeat_ack(struct sctp_heartbeat_chunk *cp,
#if defined(__Userspace__)
case AF_CONN:
if (cp->heartbeat.hb_info.addr_len == sizeof(struct sockaddr_conn)) {
- sconn = (struct sockaddr_conn *)&store;
- sconn->sconn_family = cp->heartbeat.hb_info.addr_family;
+ store.sconn.sconn_family = cp->heartbeat.hb_info.addr_family;
#ifdef HAVE_SCONN_LEN
- sconn->sconn_len = cp->heartbeat.hb_info.addr_len;
+ store.sconn.sconn_len = cp->heartbeat.hb_info.addr_len;
#endif
- sconn->sconn_port = stcb->rport;
- memcpy(&sconn->sconn_addr, cp->heartbeat.hb_info.address,
- sizeof(sconn->sconn_addr));
+ store.sconn.sconn_port = stcb->rport;
+ memcpy(&store.sconn.sconn_addr, cp->heartbeat.hb_info.address, sizeof(void *));
} else {
return;
}
@@ -666,7 +652,7 @@ sctp_handle_heartbeat_ack(struct sctp_heartbeat_chunk *cp,
default:
return;
}
- r_net = sctp_findnet(stcb, (struct sockaddr *)&store);
+ r_net = sctp_findnet(stcb, &store.sa);
if (r_net == NULL) {
SCTPDBG(SCTP_DEBUG_INPUT1, "Huh? I can't find the address I sent it to, discard\n");
return;
@@ -730,11 +716,11 @@ sctp_handle_heartbeat_ack(struct sctp_heartbeat_chunk *cp,
/* Mobility adaptation */
if (req_prim) {
if ((sctp_is_mobility_feature_on(stcb->sctp_ep,
- SCTP_MOBILITY_BASE) ||
- sctp_is_mobility_feature_on(stcb->sctp_ep,
- SCTP_MOBILITY_FASTHANDOFF)) &&
- sctp_is_mobility_feature_on(stcb->sctp_ep,
- SCTP_MOBILITY_PRIM_DELETED)) {
+ SCTP_MOBILITY_BASE) ||
+ sctp_is_mobility_feature_on(stcb->sctp_ep,
+ SCTP_MOBILITY_FASTHANDOFF)) &&
+ sctp_is_mobility_feature_on(stcb->sctp_ep,
+ SCTP_MOBILITY_PRIM_DELETED)) {
sctp_timer_stop(SCTP_TIMER_TYPE_PRIM_DELETED, stcb->sctp_ep, stcb, NULL, SCTP_FROM_SCTP_TIMER+SCTP_LOC_7);
if (sctp_is_mobility_feature_on(stcb->sctp_ep,
@@ -796,17 +782,16 @@ sctp_handle_nat_colliding_state(struct sctp_tcb *stcb)
static int
sctp_handle_nat_missing_state(struct sctp_tcb *stcb,
struct sctp_nets *net)
-
{
- /* return 0 means we want you to proceed with the abort
- * non-zero means no abort processing
- */
- if (stcb->asoc.peer_supports_auth == 0) {
- SCTPDBG(SCTP_DEBUG_INPUT2, "sctp_handle_nat_missing_state: Peer does not support AUTH, cannot send an asconf\n");
- return (0);
- }
- sctp_asconf_send_nat_state_update(stcb, net);
- return (1);
+ /* return 0 means we want you to proceed with the abort
+ * non-zero means no abort processing
+ */
+ if (stcb->asoc.auth_supported == 0) {
+ SCTPDBG(SCTP_DEBUG_INPUT2, "sctp_handle_nat_missing_state: Peer does not support AUTH, cannot send an asconf\n");
+ return (0);
+ }
+ sctp_asconf_send_nat_state_update(stcb, net);
+ return (1);
}
@@ -1122,7 +1107,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,
@@ -1136,6 +1121,7 @@ sctp_process_unrecog_chunk(struct sctp_tcb *stcb, struct sctp_paramhdr *phdr,
* Skip past the param header and then we will find the param that caused the
* problem. There are a number of param's in a ASCONF OR the prsctp param
* these will turn of specific features.
+ * XXX: Is this the right thing to do?
*/
static void
sctp_process_unrecog_param(struct sctp_tcb *stcb, struct sctp_paramhdr *phdr)
@@ -1146,7 +1132,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;
@@ -1157,14 +1143,14 @@ sctp_process_unrecog_param(struct sctp_tcb *stcb, struct sctp_paramhdr *phdr)
case SCTP_ADD_IP_ADDRESS:
case SCTP_DEL_IP_ADDRESS:
case SCTP_SET_PRIM_ADDR:
- stcb->asoc.peer_supports_asconf = 0;
+ stcb->asoc.asconf_supported = 0;
break;
case SCTP_SUCCESS_REPORT:
case SCTP_ERROR_CAUSE_IND:
SCTPDBG(SCTP_DEBUG_INPUT2, "Huh, the peer does not support success? or error cause?\n");
SCTPDBG(SCTP_DEBUG_INPUT2,
"Turning off ASCONF to this strange peer\n");
- stcb->asoc.peer_supports_asconf = 0;
+ stcb->asoc.asconf_supported = 0;
break;
default:
SCTPDBG(SCTP_DEBUG_INPUT2,
@@ -1523,6 +1509,9 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset,
int retval;
int spec_flag = 0;
uint32_t how_indx;
+#if defined(SCTP_DETAILED_STR_STATS)
+ int j;
+#endif
net = *netp;
/* I know that the TCB is non-NULL from the caller */
@@ -1605,7 +1594,7 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset,
return (NULL);
}
- switch (SCTP_GET_STATE(asoc)) {
+ switch (SCTP_GET_STATE(asoc)) {
case SCTP_STATE_COOKIE_WAIT:
case SCTP_STATE_COOKIE_ECHOED:
/*
@@ -1662,7 +1651,7 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset,
atomic_add_int(&stcb->asoc.refcnt, -1);
if (stcb->asoc.state & SCTP_STATE_CLOSED_SOCKET) {
SCTP_SOCKET_UNLOCK(so, 1);
- return (NULL);
+ return (NULL);
}
#endif
soisconnected(stcb->sctp_socket);
@@ -1983,6 +1972,15 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset,
sctp_report_all_outbound(stcb, 0, 1, SCTP_SO_LOCKED);
for (i = 0; i < stcb->asoc.streamoutcnt; i++) {
stcb->asoc.strmout[i].chunks_on_queues = 0;
+#if defined(SCTP_DETAILED_STR_STATS)
+ for (j = 0; j < SCTP_PR_SCTP_MAX + 1; j++) {
+ asoc->strmout[i].abandoned_sent[j] = 0;
+ asoc->strmout[i].abandoned_unsent[j] = 0;
+ }
+#else
+ asoc->strmout[i].abandoned_sent[0] = 0;
+ asoc->strmout[i].abandoned_unsent[0] = 0;
+#endif
stcb->asoc.strmout[i].stream_no = i;
stcb->asoc.strmout[i].next_sequence_send = 0;
stcb->asoc.strmout[i].last_msg_incomplete = 0;
@@ -2070,22 +2068,12 @@ sctp_process_cookie_new(struct mbuf *m, int iphlen, int offset,
struct sctp_tcb *stcb;
struct sctp_init_chunk *init_cp, init_buf;
struct sctp_init_ack_chunk *initack_cp, initack_buf;
- struct sockaddr_storage sa_store;
- struct sockaddr *initack_src = (struct sockaddr *)&sa_store;
+ union sctp_sockstore store;
struct sctp_association *asoc;
int init_offset, initack_offset, initack_limit;
int retval;
int error = 0;
uint8_t auth_chunk_buf[SCTP_PARAM_BUFFER_SIZE];
-#ifdef INET
- struct sockaddr_in *sin;
-#endif
-#ifdef INET6
- struct sockaddr_in6 *sin6;
-#endif
-#if defined(__Userspace__)
- struct sockaddr_conn *sconn;
-#endif
#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
struct socket *so;
@@ -2325,39 +2313,35 @@ sctp_process_cookie_new(struct mbuf *m, int iphlen, int offset,
#ifdef INET
case SCTP_IPV4_ADDRESS:
/* source addr is IPv4 */
- sin = (struct sockaddr_in *)initack_src;
- memset(sin, 0, sizeof(*sin));
- sin->sin_family = AF_INET;
+ memset(&store.sin, 0, sizeof(struct sockaddr_in));
+ store.sin.sin_family = AF_INET;
#ifdef HAVE_SIN_LEN
- sin->sin_len = sizeof(struct sockaddr_in);
+ store.sin.sin_len = sizeof(struct sockaddr_in);
#endif
- sin->sin_addr.s_addr = cookie->laddress[0];
+ store.sin.sin_addr.s_addr = cookie->laddress[0];
break;
#endif
#ifdef INET6
case SCTP_IPV6_ADDRESS:
/* source addr is IPv6 */
- sin6 = (struct sockaddr_in6 *)initack_src;
- memset(sin6, 0, sizeof(*sin6));
- sin6->sin6_family = AF_INET6;
+ memset(&store.sin6, 0, sizeof(struct sockaddr_in6));
+ store.sin6.sin6_family = AF_INET6;
#ifdef HAVE_SIN6_LEN
- sin6->sin6_len = sizeof(struct sockaddr_in6);
+ store.sin6.sin6_len = sizeof(struct sockaddr_in6);
#endif
- sin6->sin6_scope_id = cookie->scope_id;
- memcpy(&sin6->sin6_addr, cookie->laddress,
- sizeof(sin6->sin6_addr));
+ store.sin6.sin6_scope_id = cookie->scope_id;
+ memcpy(&store.sin6.sin6_addr, cookie->laddress, sizeof(struct in6_addr));
break;
#endif
#if defined(__Userspace__)
case SCTP_CONN_ADDRESS:
- /* source addr is IPv4 */
- sconn = (struct sockaddr_conn *)initack_src;
- memset(sconn, 0, sizeof(struct sockaddr_conn));
- sconn->sconn_family = AF_CONN;
+ /* source addr is conn */
+ memset(&store.sconn, 0, sizeof(struct sockaddr_conn));
+ store.sconn.sconn_family = AF_CONN;
#ifdef HAVE_SCONN_LEN
- sconn->sconn_len = sizeof(struct sockaddr_conn);
+ store.sconn.sconn_len = sizeof(struct sockaddr_conn);
#endif
- memcpy(&sconn->sconn_addr, cookie->laddress, sizeof(void *));
+ memcpy(&store.sconn.sconn_addr, cookie->laddress, sizeof(void *));
break;
#endif
default:
@@ -2438,7 +2422,7 @@ sctp_process_cookie_new(struct mbuf *m, int iphlen, int offset,
sctp_check_address_list(stcb, m,
initack_offset + sizeof(struct sctp_init_ack_chunk),
initack_limit - (initack_offset + sizeof(struct sctp_init_ack_chunk)),
- initack_src, cookie->local_scope, cookie->site_scope,
+ &store.sa, cookie->local_scope, cookie->site_scope,
cookie->ipv4_scope, cookie->loopback_scope);
@@ -2840,7 +2824,7 @@ sctp_handle_cookie_echo(struct mbuf *m, int iphlen, int offset,
sctp_ulp_notify(notification, *stcb, 0, NULL, SCTP_SO_NOT_LOCKED);
if (send_int_conf) {
sctp_ulp_notify(SCTP_NOTIFY_INTERFACE_CONFIRMED,
- (*stcb), 0, (void *)netl, SCTP_SO_NOT_LOCKED);
+ (*stcb), 0, (void *)netl, SCTP_SO_NOT_LOCKED);
}
return (m);
}
@@ -2918,7 +2902,7 @@ sctp_handle_cookie_echo(struct mbuf *m, int iphlen, int offset,
inp->sctp_flags = (SCTP_PCB_FLAGS_TCPTYPE |
SCTP_PCB_FLAGS_CONNECTED |
SCTP_PCB_FLAGS_IN_TCPPOOL |
- SCTP_PCB_FLAGS_UNBOUND |
+ SCTP_PCB_FLAGS_UNBOUND |
(SCTP_PCB_COPY_FLAGS & (*inp_p)->sctp_flags) |
SCTP_PCB_FLAGS_DONT_WAKE);
inp->sctp_features = (*inp_p)->sctp_features;
@@ -2926,7 +2910,13 @@ sctp_handle_cookie_echo(struct mbuf *m, int iphlen, int offset,
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->sctp_ecn_enable = (*inp_p)->sctp_ecn_enable;
+ inp->ecn_supported = (*inp_p)->ecn_supported;
+ inp->prsctp_supported = (*inp_p)->prsctp_supported;
+ inp->auth_supported = (*inp_p)->auth_supported;
+ inp->asconf_supported = (*inp_p)->asconf_supported;
+ inp->reconfig_supported = (*inp_p)->reconfig_supported;
+ inp->nrsack_supported = (*inp_p)->nrsack_supported;
+ inp->pktdrop_supported = (*inp_p)->pktdrop_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;
@@ -3031,8 +3021,9 @@ sctp_handle_cookie_ack(struct sctp_cookie_ack_chunk *cp SCTP_UNUSED,
SCTPDBG(SCTP_DEBUG_INPUT2,
"sctp_handle_cookie_ack: handling COOKIE-ACK\n");
- if (stcb == NULL)
+ if ((stcb == NULL) || (net == NULL)) {
return;
+ }
asoc = &stcb->asoc;
@@ -3108,7 +3099,7 @@ sctp_handle_cookie_ack(struct sctp_cookie_ack_chunk *cp SCTP_UNUSED,
* in flight)
*/
if ((sctp_is_feature_on(stcb->sctp_ep, SCTP_PCB_FLAGS_DO_ASCONF)) &&
- (stcb->asoc.peer_supports_asconf) &&
+ (stcb->asoc.asconf_supported == 1) &&
(!TAILQ_EMPTY(&stcb->asoc.asconf_queue))) {
#ifdef SCTP_TIMER_BASED_ASCONF
sctp_timer_start(SCTP_TIMER_TYPE_ASCONF,
@@ -4570,7 +4561,7 @@ sctp_process_control(struct mbuf *m, int iphlen, int *offset, int length,
*/
if ((ch->chunk_type == SCTP_AUTHENTICATION) &&
(stcb == NULL) &&
- !SCTP_BASE_SYSCTL(sctp_auth_disable)) {
+ (inp->auth_supported == 1)) {
/* save this chunk for later processing */
auth_skipped = 1;
auth_offset = *offset;
@@ -4842,7 +4833,7 @@ sctp_process_control(struct mbuf *m, int iphlen, int *offset, int length,
/* check to see if this chunk required auth, but isn't */
if ((stcb != NULL) &&
- !SCTP_BASE_SYSCTL(sctp_auth_disable) &&
+ (stcb->asoc.auth_supported == 1) &&
sctp_auth_is_required_chunk(ch->chunk_type, stcb->asoc.local_auth_chunks) &&
!stcb->asoc.authenticated) {
/* "silently" ignore */
@@ -4897,7 +4888,7 @@ sctp_process_control(struct mbuf *m, int iphlen, int *offset, int length,
SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_INIT-ACK\n");
if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) {
/* We are not interested anymore */
- if ((stcb) && (stcb->asoc.total_output_queue_size)) {
+ if ((stcb) && (stcb->asoc.total_output_queue_size)) {
;
} else {
if (locked_tcb != stcb) {
@@ -5051,8 +5042,7 @@ sctp_process_control(struct mbuf *m, int iphlen, int *offset, int length,
SCTPDBG(SCTP_DEBUG_INDATA1, "No stcb when processing NR-SACK chunk\n");
break;
}
- if ((stcb->asoc.sctp_nr_sack_on_off == 0) ||
- (stcb->asoc.peer_supports_nr_sack == 0)) {
+ if (stcb->asoc.nrsack_supported == 0) {
goto unknown_chunk;
}
if (chk_length < sizeof(struct sctp_nr_sack_chunk)) {
@@ -5367,6 +5357,9 @@ sctp_process_control(struct mbuf *m, int iphlen, int *offset, int length,
return (NULL);
}
if (stcb) {
+ if (stcb->asoc.ecn_supported == 0) {
+ goto unknown_chunk;
+ }
if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_THRESHOLD_LOGGING) {
sctp_misc_ints(SCTP_THRESHOLD_CLEAR,
stcb->asoc.overall_error_count,
@@ -5392,6 +5385,9 @@ sctp_process_control(struct mbuf *m, int iphlen, int *offset, int length,
return (NULL);
}
if (stcb) {
+ if (stcb->asoc.ecn_supported == 0) {
+ goto unknown_chunk;
+ }
if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_THRESHOLD_LOGGING) {
sctp_misc_ints(SCTP_THRESHOLD_CLEAR,
stcb->asoc.overall_error_count,
@@ -5425,6 +5421,9 @@ sctp_process_control(struct mbuf *m, int iphlen, int *offset, int length,
SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_ASCONF\n");
/* He's alive so give him credit */
if (stcb) {
+ if (stcb->asoc.asconf_supported == 0) {
+ goto unknown_chunk;
+ }
if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_THRESHOLD_LOGGING) {
sctp_misc_ints(SCTP_THRESHOLD_CLEAR,
stcb->asoc.overall_error_count,
@@ -5449,6 +5448,9 @@ sctp_process_control(struct mbuf *m, int iphlen, int *offset, int length,
return (NULL);
}
if ((stcb) && netp && *netp) {
+ if (stcb->asoc.asconf_supported == 0) {
+ goto unknown_chunk;
+ }
/* He's alive so give him credit */
if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_THRESHOLD_LOGGING) {
sctp_misc_ints(SCTP_THRESHOLD_CLEAR,
@@ -5478,6 +5480,10 @@ sctp_process_control(struct mbuf *m, int iphlen, int *offset, int length,
/* He's alive so give him credit */
if (stcb) {
int abort_flag = 0;
+
+ if (stcb->asoc.prsctp_supported == 0) {
+ goto unknown_chunk;
+ }
stcb->asoc.overall_error_count = 0;
if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_THRESHOLD_LOGGING) {
sctp_misc_ints(SCTP_THRESHOLD_CLEAR,
@@ -5532,13 +5538,8 @@ sctp_process_control(struct mbuf *m, int iphlen, int *offset, int length,
*offset = length;
return (NULL);
}
- if (stcb->asoc.peer_supports_strreset == 0) {
- /*
- * hmm, peer should have announced this, but
- * we will turn it on since he is sending us
- * a stream reset.
- */
- stcb->asoc.peer_supports_strreset = 1;
+ if (stcb->asoc.reconfig_supported == 0) {
+ goto unknown_chunk;
}
if (sctp_handle_stream_reset(stcb, m, *offset, ch)) {
/* stop processing */
@@ -5560,6 +5561,9 @@ sctp_process_control(struct mbuf *m, int iphlen, int *offset, int length,
if (ch && (stcb) && netp && (*netp)) {
+ if (stcb->asoc.pktdrop_supported == 0) {
+ goto unknown_chunk;
+ }
sctp_handle_packet_dropped((struct sctp_pktdrop_chunk *)ch,
stcb, *netp,
min(chk_length, (sizeof(chunk_buf) - 4)));
@@ -5567,12 +5571,8 @@ sctp_process_control(struct mbuf *m, int iphlen, int *offset, int length,
}
break;
-
case SCTP_AUTHENTICATION:
SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_AUTHENTICATION\n");
- if (SCTP_BASE_SYSCTL(sctp_auth_disable))
- goto unknown_chunk;
-
if (stcb == NULL) {
/* save the first AUTH for later processing */
if (auth_skipped == 0) {
@@ -5583,6 +5583,9 @@ sctp_process_control(struct mbuf *m, int iphlen, int *offset, int length,
/* skip this chunk (temporarily) */
goto next_chunk;
}
+ if (stcb->asoc.auth_supported == 0) {
+ goto unknown_chunk;
+ }
if ((chk_length < (sizeof(struct sctp_auth_chunk))) ||
(chk_length > (sizeof(struct sctp_auth_chunk) +
SCTP_AUTH_DIGEST_LEN_MAX))) {
@@ -5632,7 +5635,7 @@ sctp_process_control(struct mbuf *m, int iphlen, int *offset, int length,
SCTP_BUF_LEN(mm) = sizeof(*phd);
SCTP_BUF_NEXT(mm) = SCTP_M_COPYM(m, *offset, chk_length, M_NOWAIT);
if (SCTP_BUF_NEXT(mm)) {
- if (sctp_pad_lastmbuf(SCTP_BUF_NEXT(mm), SCTP_SIZE32(chk_length) - chk_length, NULL)) {
+ if (sctp_pad_lastmbuf(SCTP_BUF_NEXT(mm), SCTP_SIZE32(chk_length) - chk_length, NULL) == NULL) {
sctp_m_freem(mm);
} else {
#ifdef SCTP_MBUF_LOGGING
@@ -5756,7 +5759,7 @@ sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset, int lengt
calc_check, check, (void *)m, length, iphlen);
stcb = sctp_findassociation_addr(m, offset, src, dst,
sh, ch, &inp, &net, vrf_id);
-#if defined INET || defined INET6
+#if defined(INET) || defined(INET6)
if ((net != NULL) && (port != 0)) {
if (net->port == 0) {
sctp_pathmtu_adjustment(stcb, net->mtu - sizeof(struct udphdr));
@@ -5791,7 +5794,7 @@ sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset, int lengt
}
stcb = sctp_findassociation_addr(m, offset, src, dst,
sh, ch, &inp, &net, vrf_id);
-#if defined INET || defined INET6
+#if defined(INET) || defined(INET6)
if ((net != NULL) && (port != 0)) {
if (net->port == 0) {
sctp_pathmtu_adjustment(stcb, net->mtu - sizeof(struct udphdr));
@@ -5898,7 +5901,7 @@ sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset, int lengt
* timer is clearing out the assoc, we should
* NOT respond to any packet.. its OOTB.
*/
- SCTP_TCB_UNLOCK(stcb);
+ SCTP_TCB_UNLOCK(stcb);
stcb = NULL;
snprintf(msg, sizeof(msg), "OOTB, %s:%d at %s\n", __FILE__, __LINE__, __FUNCTION__);
op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code),
@@ -5907,7 +5910,7 @@ sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset, int lengt
#if defined(__FreeBSD__)
use_mflowid, mflowid,
#endif
- vrf_id, port);
+ vrf_id, port);
goto out;
}
@@ -5919,15 +5922,15 @@ sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset, int lengt
src, dst, sh, ch,
inp, stcb, &net, &fwd_tsn_seen,
#if defined(__FreeBSD__)
- use_mflowid, mflowid,
+ use_mflowid, mflowid,
#endif
vrf_id, port);
if (stcb) {
/* This covers us if the cookie-echo was there
* and it changes our INP.
*/
- inp = stcb->sctp_ep;
-#if defined INET || defined INET6
+ inp = stcb->sctp_ep;
+#if defined(INET) || defined(INET6)
if ((net) && (port)) {
if (net->port == 0) {
sctp_pathmtu_adjustment(stcb, net->mtu - sizeof(struct udphdr));
@@ -5948,7 +5951,7 @@ sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset, int lengt
* chunks
*/
if ((stcb != NULL) &&
- !SCTP_BASE_SYSCTL(sctp_auth_disable) &&
+ (stcb->asoc.auth_supported == 1) &&
sctp_auth_is_required_chunk(SCTP_DATA, stcb->asoc.local_auth_chunks)) {
/* "silently" ignore */
SCTP_STAT_INCR(sctps_recvauthmissing);
@@ -5993,7 +5996,7 @@ sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset, int lengt
*/
if ((length > offset) &&
(stcb != NULL) &&
- !SCTP_BASE_SYSCTL(sctp_auth_disable) &&
+ (stcb->asoc.auth_supported == 1) &&
sctp_auth_is_required_chunk(SCTP_DATA, stcb->asoc.local_auth_chunks) &&
!stcb->asoc.authenticated) {
/* "silently" ignore */
@@ -6079,7 +6082,7 @@ sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset, int lengt
/* take care of ecn */
if ((data_processed == 1) &&
- (stcb->asoc.ecn_allowed == 1) &&
+ (stcb->asoc.ecn_supported == 1) &&
((ecn_bits & SCTP_CE_BITS) == SCTP_CE_BITS)) {
/* Yep, we need to add a ECNE */
sctp_send_ecn_echo(stcb, net, high_tsn);
@@ -6381,17 +6384,28 @@ sctp_input(i_pak, va_alist)
extern int *sctp_cpuarry;
#endif
+#if defined(__FreeBSD__) && __FreeBSD_version >= 1100020
+int
+sctp_input(struct mbuf **mp, int *offp, int proto SCTP_UNUSED)
+{
+ struct mbuf *m;
+ int off;
+
+ m = *mp;
+ off = *offp;
+#else
void
sctp_input(struct mbuf *m, int off)
{
+#endif
#if defined(__FreeBSD__) && defined(SCTP_MCORE_INPUT) && defined(SMP)
- struct ip *ip;
- struct sctphdr *sh;
- int offset;
- int cpu_to_use;
- uint32_t flowid, tag;
-
if (mp_ncpus > 1) {
+ struct ip *ip;
+ struct sctphdr *sh;
+ int offset;
+ int cpu_to_use;
+ uint32_t flowid, tag;
+
if (m->m_flags & M_FLOWID) {
flowid = m->m_pkthdr.flowid;
} else {
@@ -6402,7 +6416,11 @@ sctp_input(struct mbuf *m, int off)
if (SCTP_BUF_LEN(m) < offset) {
if ((m = m_pullup(m, offset)) == NULL) {
SCTP_STAT_INCR(sctps_hdrops);
+#if defined(__FreeBSD__) && __FreeBSD_version >= 1100020
+ return (IPPROTO_DONE);
+#else
return;
+#endif
}
}
ip = mtod(m, struct ip *);
@@ -6414,10 +6432,17 @@ sctp_input(struct mbuf *m, int off)
}
cpu_to_use = sctp_cpuarry[flowid % mp_ncpus];
sctp_queue_to_mcore(m, off, cpu_to_use);
+#if defined(__FreeBSD__) && __FreeBSD_version >= 1100020
+ return (IPPROTO_DONE);
+#else
return;
+#endif
}
#endif
sctp_input_with_port(m, off, 0);
+#if defined(__FreeBSD__) && __FreeBSD_version >= 1100020
+ return (IPPROTO_DONE);
+#endif
}
#endif
#endif
diff --git a/netinet/sctp_output.c b/netinet/sctp_output.c
index 14f2cc0..a305ea5 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 267674 2014-06-20 13:26:49Z tuexen $");
+__FBSDID("$FreeBSD: head/sys/netinet/sctp_output.c 271230 2014-09-07 18:05:37Z tuexen $");
#endif
#include <netinet/sctp_os.h>
@@ -57,7 +57,7 @@ __FBSDID("$FreeBSD: head/sys/netinet/sctp_output.c 267674 2014-06-20 13:26:49Z t
#if defined(__Userspace_os_Linux)
#define __FAVOR_BSD /* (on Ubuntu at least) enables UDP header field names like BSD in RFC 768 */
#endif
-#if defined INET || defined INET6
+#if defined(INET) || defined(INET6)
#if !defined(__Userspace_os_Windows)
#include <netinet/udp.h>
#endif
@@ -1908,7 +1908,7 @@ sctp_is_address_in_scope(struct sctp_ifa *ifa,
if (scope->ipv4_addr_legal) {
struct sockaddr_in *sin;
- sin = (struct sockaddr_in *)&ifa->address.sin;
+ sin = &ifa->address.sin;
if (sin->sin_addr.s_addr == 0) {
/* not in scope , unspecified */
return (0);
@@ -1940,7 +1940,7 @@ sctp_is_address_in_scope(struct sctp_ifa *ifa,
return (0);
}
/* ok to use deprecated addresses? */
- sin6 = (struct sockaddr_in6 *)&ifa->address.sin6;
+ sin6 = &ifa->address.sin6;
if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
/* skip unspecifed addresses */
return (0);
@@ -2021,7 +2021,7 @@ sctp_add_addr_to_mbuf(struct mbuf *m, struct sctp_ifa *ifa, uint16_t *len)
struct sctp_ipv4addr_param *ipv4p;
struct sockaddr_in *sin;
- sin = (struct sockaddr_in *)&ifa->address.sin;
+ sin = &ifa->address.sin;
ipv4p = (struct sctp_ipv4addr_param *)parmh;
parmh->param_type = htons(SCTP_IPV4_ADDRESS);
parmh->param_length = htons(plen);
@@ -2036,7 +2036,7 @@ sctp_add_addr_to_mbuf(struct mbuf *m, struct sctp_ifa *ifa, uint16_t *len)
struct sctp_ipv6addr_param *ipv6p;
struct sockaddr_in6 *sin6;
- sin6 = (struct sockaddr_in6 *)&ifa->address.sin6;
+ sin6 = &ifa->address.sin6;
ipv6p = (struct sctp_ipv6addr_param *)parmh;
parmh->param_type = htons(SCTP_IPV6_ADDRESS);
parmh->param_length = htons(plen);
@@ -2103,14 +2103,14 @@ sctp_add_addresses_to_i_ia(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
if ((sctp_ifap->address.sa.sa_family == AF_INET) &&
(prison_check_ip4(inp->ip_inp.inp.inp_cred,
&sctp_ifap->address.sin.sin_addr) != 0)) {
- continue;
+ continue;
}
#endif
#ifdef INET6
if ((sctp_ifap->address.sa.sa_family == AF_INET6) &&
(prison_check_ip6(inp->ip_inp.inp.inp_cred,
&sctp_ifap->address.sin6.sin6_addr) != 0)) {
- continue;
+ continue;
}
#endif
#endif
@@ -2153,14 +2153,14 @@ sctp_add_addresses_to_i_ia(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
if ((sctp_ifap->address.sa.sa_family == AF_INET) &&
(prison_check_ip4(inp->ip_inp.inp.inp_cred,
&sctp_ifap->address.sin.sin_addr) != 0)) {
- continue;
+ continue;
}
#endif
#ifdef INET6
if ((sctp_ifap->address.sa.sa_family == AF_INET6) &&
(prison_check_ip6(inp->ip_inp.inp.inp_cred,
&sctp_ifap->address.sin6.sin6_addr) != 0)) {
- continue;
+ continue;
}
#endif
#endif
@@ -2210,7 +2210,7 @@ sctp_add_addresses_to_i_ia(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
continue;
}
if (laddr->ifa->localifa_flags & SCTP_BEING_DELETED)
- /* Address being deleted by the system, dont
+ /* Address being deleted by the system, dont
* list.
*/
continue;
@@ -2671,7 +2671,7 @@ sctp_choose_boundspecific_stcb(struct sctp_inpcb *inp,
sctp_ifn = sctp_find_ifn( ifn, ifn_index);
/*
- * first question, is the ifn we will emit on in our list? If so,
+ * first question, is the ifn we will emit on in our list? If so,
* we want that one. First we look for a preferred. Second, we go
* for an acceptable.
*/
@@ -3707,6 +3707,9 @@ sctp_process_cmsgs_for_init(struct sctp_tcb *stcb, struct mbuf *control, int *er
if (stcb->asoc.streamoutcnt < stcb->asoc.pre_open_streams) {
struct sctp_stream_out *tmp_str;
unsigned int i;
+#if defined(SCTP_DETAILED_STR_STATS)
+ int j;
+#endif
/* Default is NOT correct */
SCTPDBG(SCTP_DEBUG_OUTPUT1, "Ok, default:%d pre_open:%d\n",
@@ -3728,6 +3731,15 @@ sctp_process_cmsgs_for_init(struct sctp_tcb *stcb, struct mbuf *control, int *er
TAILQ_INIT(&stcb->asoc.strmout[i].outqueue);
stcb->asoc.strmout[i].chunks_on_queues = 0;
stcb->asoc.strmout[i].next_sequence_send = 0;
+#if defined(SCTP_DETAILED_STR_STATS)
+ for (j = 0; j < SCTP_PR_SCTP_MAX + 1; j++) {
+ stcb->asoc.strmout[i].abandoned_sent[j] = 0;
+ stcb->asoc.strmout[i].abandoned_unsent[j] = 0;
+ }
+#else
+ stcb->asoc.strmout[i].abandoned_sent[0] = 0;
+ stcb->asoc.strmout[i].abandoned_unsent[0] = 0;
+#endif
stcb->asoc.strmout[i].stream_no = i;
stcb->asoc.strmout[i].last_msg_incomplete = 0;
stcb->asoc.ss_functions.sctp_ss_init_stream(&stcb->asoc.strmout[i], NULL);
@@ -4013,7 +4025,7 @@ sctp_add_cookie(struct mbuf *init, int init_offset,
static uint8_t
sctp_get_ect(struct sctp_tcb *stcb)
{
- if ((stcb != NULL) && (stcb->asoc.ecn_allowed == 1)) {
+ if ((stcb != NULL) && (stcb->asoc.ecn_supported == 1)) {
return (SCTP_ECT0_BIT);
} else {
return (0);
@@ -5042,7 +5054,7 @@ sctp_send_initiate(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int so_locked
#endif
)
{
- struct mbuf *m;
+ struct mbuf *m, *m_last;
struct sctp_nets *net;
struct sctp_init_chunk *init;
struct sctp_supported_addr_param *sup_addr;
@@ -5102,12 +5114,6 @@ sctp_send_initiate(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int so_locked
}
chunk_len = (uint16_t)sizeof(struct sctp_init_chunk);
padding_len = 0;
- /*
- * assume peer supports asconf in order to be able to queue
- * local address changes while an INIT is in flight and before
- * the assoc is established.
- */
- stcb->asoc.peer_supports_asconf = 1;
/* Now lets put the chunk header in place */
init = mtod(m, struct sctp_init_chunk *);
/* now the chunk header */
@@ -5124,125 +5130,74 @@ sctp_send_initiate(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int so_locked
init->init.num_inbound_streams = htons(stcb->asoc.max_inbound_streams);
init->init.initial_tsn = htonl(stcb->asoc.init_seq_number);
- if (stcb->asoc.scope.ipv4_addr_legal || stcb->asoc.scope.ipv6_addr_legal) {
- uint8_t i;
-
- parameter_len = (uint16_t)sizeof(struct sctp_paramhdr);
- if (stcb->asoc.scope.ipv4_addr_legal) {
- parameter_len += (uint16_t)sizeof(uint16_t);
- }
- if (stcb->asoc.scope.ipv6_addr_legal) {
- parameter_len += (uint16_t)sizeof(uint16_t);
- }
- sup_addr = (struct sctp_supported_addr_param *)(mtod(m, caddr_t) + chunk_len);
- sup_addr->ph.param_type = htons(SCTP_SUPPORTED_ADDRTYPE);
- sup_addr->ph.param_length = htons(parameter_len);
- i = 0;
- if (stcb->asoc.scope.ipv4_addr_legal) {
- sup_addr->addr_type[i++] = htons(SCTP_IPV4_ADDRESS);
- }
- if (stcb->asoc.scope.ipv6_addr_legal) {
- sup_addr->addr_type[i++] = htons(SCTP_IPV6_ADDRESS);
- }
- padding_len = 4 - 2 * i;
- chunk_len += parameter_len;
- }
-
/* Adaptation layer indication parameter */
if (inp->sctp_ep.adaptation_layer_indicator_provided) {
- if (padding_len > 0) {
- memset(mtod(m, caddr_t) + chunk_len, 0, padding_len);
- chunk_len += padding_len;
- padding_len = 0;
- }
parameter_len = (uint16_t)sizeof(struct sctp_adaptation_layer_indication);
ali = (struct sctp_adaptation_layer_indication *)(mtod(m, caddr_t) + chunk_len);
ali->ph.param_type = htons(SCTP_ULP_ADAPTATION);
ali->ph.param_length = htons(parameter_len);
- ali->indication = ntohl(inp->sctp_ep.adaptation_layer_indicator);
+ ali->indication = htonl(inp->sctp_ep.adaptation_layer_indicator);
chunk_len += parameter_len;
}
- if (SCTP_BASE_SYSCTL(sctp_inits_include_nat_friendly)) {
- /* Add NAT friendly parameter. */
- if (padding_len > 0) {
- memset(mtod(m, caddr_t) + chunk_len, 0, padding_len);
- chunk_len += padding_len;
- padding_len = 0;
- }
+ /* ECN parameter */
+ if (stcb->asoc.ecn_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_HAS_NAT_SUPPORT);
+ ph->param_type = htons(SCTP_ECN_CAPABLE);
ph->param_length = htons(parameter_len);
chunk_len += parameter_len;
}
- /* now any cookie time extensions */
- if (stcb->asoc.cookie_preserve_req) {
- struct sctp_cookie_perserve_param *cookie_preserve;
-
- if (padding_len > 0) {
- memset(mtod(m, caddr_t) + chunk_len, 0, padding_len);
- chunk_len += padding_len;
- padding_len = 0;
- }
- parameter_len = (uint16_t)sizeof(struct sctp_cookie_perserve_param);
- cookie_preserve = (struct sctp_cookie_perserve_param *)(mtod(m, caddr_t) + chunk_len);
- cookie_preserve->ph.param_type = htons(SCTP_COOKIE_PRESERVE);
- cookie_preserve->ph.param_length = htons(parameter_len);
- cookie_preserve->time = htonl(stcb->asoc.cookie_preserve_req);
- stcb->asoc.cookie_preserve_req = 0;
+ /* 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;
}
- /* ECN parameter */
- if (stcb->asoc.ecn_allowed == 1) {
- if (padding_len > 0) {
- memset(mtod(m, caddr_t) + chunk_len, 0, padding_len);
- chunk_len += padding_len;
- padding_len = 0;
- }
+ /* Add NAT friendly parameter. */
+ if (SCTP_BASE_SYSCTL(sctp_inits_include_nat_friendly)) {
parameter_len = (uint16_t)sizeof(struct sctp_paramhdr);
ph = (struct sctp_paramhdr *)(mtod(m, caddr_t) + chunk_len);
- ph->param_type = htons(SCTP_ECN_CAPABLE);
+ ph->param_type = htons(SCTP_HAS_NAT_SUPPORT);
ph->param_length = htons(parameter_len);
chunk_len += parameter_len;
}
- /* And now tell the peer we do support PR-SCTP. */
- if (padding_len > 0) {
- memset(mtod(m, caddr_t) + chunk_len, 0, padding_len);
- chunk_len += padding_len;
- padding_len = 0;
- }
- 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;
-
- /* And now tell the peer we do all the extensions */
- pr_supported = (struct sctp_supported_chunk_types_param *)(mtod(m, caddr_t) + chunk_len);
- pr_supported->ph.param_type = htons(SCTP_SUPPORTED_CHUNK_EXT);
+ /* And now tell the peer which extensions we support */
num_ext = 0;
- 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;
- 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)) {
+ pr_supported = (struct sctp_supported_chunk_types_param *)(mtod(m, caddr_t) + chunk_len);
+ if (stcb->asoc.prsctp_supported == 1) {
+ pr_supported->chunk_types[num_ext++] = SCTP_FORWARD_CUM_TSN;
+ }
+ if (stcb->asoc.auth_supported == 1) {
pr_supported->chunk_types[num_ext++] = SCTP_AUTHENTICATION;
}
- if (stcb->asoc.sctp_nr_sack_on_off == 1) {
+ if (stcb->asoc.asconf_supported == 1) {
+ pr_supported->chunk_types[num_ext++] = SCTP_ASCONF;
+ pr_supported->chunk_types[num_ext++] = SCTP_ASCONF_ACK;
+ }
+ if (stcb->asoc.reconfig_supported == 1) {
+ pr_supported->chunk_types[num_ext++] = SCTP_STREAM_RESET;
+ }
+ if (stcb->asoc.nrsack_supported == 1) {
pr_supported->chunk_types[num_ext++] = SCTP_NR_SELECTIVE_ACK;
}
- parameter_len = (uint16_t)sizeof(struct sctp_supported_chunk_types_param) + num_ext;
- pr_supported->ph.param_length = htons(parameter_len);
- padding_len = SCTP_SIZE32(parameter_len) - parameter_len;
- chunk_len += parameter_len;
-
+ if (stcb->asoc.pktdrop_supported == 1) {
+ pr_supported->chunk_types[num_ext++] = SCTP_PACKET_DROPPED;
+ }
+ if (num_ext > 0) {
+ parameter_len = (uint16_t)sizeof(struct sctp_supported_chunk_types_param) + num_ext;
+ pr_supported->ph.param_type = htons(SCTP_SUPPORTED_CHUNK_EXT);
+ pr_supported->ph.param_length = htons(parameter_len);
+ padding_len = SCTP_SIZE32(parameter_len) - parameter_len;
+ chunk_len += parameter_len;
+ }
/* add authentication parameters */
- if (!SCTP_BASE_SYSCTL(sctp_auth_disable)) {
+ if (stcb->asoc.auth_supported) {
/* attach RANDOM parameter, if available */
if (stcb->asoc.authinfo.random != NULL) {
struct sctp_auth_random *randp;
@@ -5260,8 +5215,7 @@ sctp_send_initiate(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int so_locked
chunk_len += parameter_len;
}
/* add HMAC_ALGO parameter */
- if ((stcb->asoc.local_hmacs != NULL) &&
- (stcb->asoc.local_hmacs->num_algo > 0)) {
+ if (stcb->asoc.local_hmacs != NULL) {
struct sctp_auth_hmac_algo *hmacs;
if (padding_len > 0) {
@@ -5279,7 +5233,7 @@ sctp_send_initiate(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int so_locked
chunk_len += parameter_len;
}
/* add CHUNKS parameter */
- if (sctp_auth_get_chklist_size(stcb->asoc.local_auth_chunks) > 0) {
+ if (stcb->asoc.local_auth_chunks != NULL) {
struct sctp_auth_chunk_list *chunks;
if (padding_len > 0) {
@@ -5297,8 +5251,55 @@ sctp_send_initiate(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int so_locked
chunk_len += parameter_len;
}
}
- SCTP_BUF_LEN(m) = chunk_len;
+ /* now any cookie time extensions */
+ if (stcb->asoc.cookie_preserve_req) {
+ struct sctp_cookie_perserve_param *cookie_preserve;
+
+ if (padding_len > 0) {
+ memset(mtod(m, caddr_t) + chunk_len, 0, padding_len);
+ chunk_len += padding_len;
+ padding_len = 0;
+ }
+ parameter_len = (uint16_t)sizeof(struct sctp_cookie_perserve_param);
+ cookie_preserve = (struct sctp_cookie_perserve_param *)(mtod(m, caddr_t) + chunk_len);
+ cookie_preserve->ph.param_type = htons(SCTP_COOKIE_PRESERVE);
+ cookie_preserve->ph.param_length = htons(parameter_len);
+ cookie_preserve->time = htonl(stcb->asoc.cookie_preserve_req);
+ stcb->asoc.cookie_preserve_req = 0;
+ chunk_len += parameter_len;
+ }
+
+ if (stcb->asoc.scope.ipv4_addr_legal || stcb->asoc.scope.ipv6_addr_legal) {
+ uint8_t i;
+
+ if (padding_len > 0) {
+ memset(mtod(m, caddr_t) + chunk_len, 0, padding_len);
+ chunk_len += padding_len;
+ padding_len = 0;
+ }
+ parameter_len = (uint16_t)sizeof(struct sctp_paramhdr);
+ if (stcb->asoc.scope.ipv4_addr_legal) {
+ parameter_len += (uint16_t)sizeof(uint16_t);
+ }
+ if (stcb->asoc.scope.ipv6_addr_legal) {
+ parameter_len += (uint16_t)sizeof(uint16_t);
+ }
+ sup_addr = (struct sctp_supported_addr_param *)(mtod(m, caddr_t) + chunk_len);
+ sup_addr->ph.param_type = htons(SCTP_SUPPORTED_ADDRTYPE);
+ sup_addr->ph.param_length = htons(parameter_len);
+ i = 0;
+ if (stcb->asoc.scope.ipv4_addr_legal) {
+ sup_addr->addr_type[i++] = htons(SCTP_IPV4_ADDRESS);
+ }
+ if (stcb->asoc.scope.ipv6_addr_legal) {
+ sup_addr->addr_type[i++] = htons(SCTP_IPV6_ADDRESS);
+ }
+ padding_len = 4 - 2 * i;
+ chunk_len += parameter_len;
+ }
+
+ SCTP_BUF_LEN(m) = chunk_len;
/* now the addresses */
/* To optimize this we could put the scoping stuff
* into a structure and remove the individual uint8's from
@@ -5306,18 +5307,13 @@ sctp_send_initiate(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int so_locked
* address within the stcb. But for now this is a quick
* hack to get the address stuff teased apart.
*/
- sctp_add_addresses_to_i_ia(inp, stcb, &stcb->asoc.scope, m, cnt_inits_to, &padding_len, &chunk_len);
+ m_last = sctp_add_addresses_to_i_ia(inp, stcb, &stcb->asoc.scope,
+ m, cnt_inits_to,
+ &padding_len, &chunk_len);
init->ch.chunk_length = htons(chunk_len);
if (padding_len > 0) {
- struct mbuf *m_at, *mp_last;
-
- mp_last = NULL;
- for (m_at = m; m_at; m_at = SCTP_BUF_NEXT(m_at)) {
- if (SCTP_BUF_NEXT(m_at) == NULL)
- mp_last = m_at;
- }
- if ((mp_last == NULL) || sctp_add_pad_tombuf(mp_last, padding_len)) {
+ if (sctp_add_pad_tombuf(m_last, padding_len) == NULL) {
sctp_m_freem(m);
return;
}
@@ -5453,10 +5449,9 @@ sctp_arethere_unrecognized_parameters(struct mbuf *in_initpkt,
at += padded_size;
break;
case SCTP_HAS_NAT_SUPPORT:
- *nat_friendly = 1;
- /* fall through */
+ *nat_friendly = 1;
+ /* fall through */
case SCTP_PRSCTP_SUPPORTED:
-
if (padded_size != sizeof(struct sctp_paramhdr)) {
SCTPDBG(SCTP_DEBUG_OUTPUT1, "Invalid size - error prsctp/nat support %d\n", plen);
goto invalid_size;
@@ -5464,7 +5459,7 @@ sctp_arethere_unrecognized_parameters(struct mbuf *in_initpkt,
at += padded_size;
break;
case SCTP_ECN_CAPABLE:
- if (padded_size != sizeof(struct sctp_ecn_supported_param)) {
+ if (padded_size != sizeof(struct sctp_paramhdr)) {
SCTPDBG(SCTP_DEBUG_OUTPUT1, "Invalid size - error ecn %d\n", plen);
goto invalid_size;
}
@@ -5848,13 +5843,13 @@ sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
uint32_t vrf_id, uint16_t port, int hold_inp_lock)
{
struct sctp_association *asoc;
- struct mbuf *m, *m_at, *m_tmp, *m_cookie, *op_err, *mp_last;
+ struct mbuf *m, *m_tmp, *m_last, *m_cookie, *op_err;
struct sctp_init_ack_chunk *initack;
struct sctp_adaptation_layer_indication *ali;
- struct sctp_ecn_supported_param *ecn;
- struct sctp_prsctp_supported_param *prsctp;
struct sctp_supported_chunk_types_param *pr_supported;
+ struct sctp_paramhdr *ph;
union sctp_sockstore *over_addr;
+ struct sctp_scoping scp;
#ifdef INET
struct sockaddr_in *dst4 = (struct sockaddr_in *)dst;
struct sockaddr_in *src4 = (struct sockaddr_in *)src;
@@ -5876,18 +5871,16 @@ sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
uint8_t *signature = NULL;
int cnt_inits_to = 0;
uint16_t his_limit, i_want;
- int abort_flag, padval;
- int num_ext;
- int p_len;
+ int abort_flag;
int nat_friendly = 0;
struct socket *so;
+ uint16_t num_ext, chunk_len, padding_len, parameter_len;
if (stcb) {
asoc = &stcb->asoc;
} else {
asoc = NULL;
}
- mp_last = NULL;
if ((asoc != NULL) &&
(SCTP_GET_STATE(asoc) != SCTP_STATE_COOKIE_WAIT) &&
(sctp_are_there_new_addresses(asoc, init_pkt, offset, src))) {
@@ -5934,7 +5927,8 @@ sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
sctp_m_freem(op_err);
return;
}
- SCTP_BUF_LEN(m) = sizeof(struct sctp_init_chunk);
+ chunk_len = (uint16_t)sizeof(struct sctp_init_ack_chunk);
+ padding_len = 0;
/*
* We might not overwrite the identification[] completely and on
@@ -6311,161 +6305,183 @@ sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
/* adaptation layer indication parameter */
if (inp->sctp_ep.adaptation_layer_indicator_provided) {
- ali = (struct sctp_adaptation_layer_indication *)((caddr_t)initack + sizeof(*initack));
+ parameter_len = (uint16_t)sizeof(struct sctp_adaptation_layer_indication);
+ ali = (struct sctp_adaptation_layer_indication *)(mtod(m, caddr_t) + chunk_len);
ali->ph.param_type = htons(SCTP_ULP_ADAPTATION);
- ali->ph.param_length = htons(sizeof(*ali));
- ali->indication = ntohl(inp->sctp_ep.adaptation_layer_indicator);
- SCTP_BUF_LEN(m) += sizeof(*ali);
- ecn = (struct sctp_ecn_supported_param *)((caddr_t)ali + sizeof(*ali));
- } else {
- ecn = (struct sctp_ecn_supported_param *)((caddr_t)initack + sizeof(*initack));
+ ali->ph.param_length = htons(parameter_len);
+ ali->indication = htonl(inp->sctp_ep.adaptation_layer_indicator);
+ chunk_len += parameter_len;
}
/* ECN parameter */
- if (((asoc != NULL) && (asoc->ecn_allowed == 1)) ||
- (inp->sctp_ecn_enable == 1)) {
- ecn->ph.param_type = htons(SCTP_ECN_CAPABLE);
- ecn->ph.param_length = htons(sizeof(*ecn));
- SCTP_BUF_LEN(m) += sizeof(*ecn);
-
- prsctp = (struct sctp_prsctp_supported_param *)((caddr_t)ecn +
- sizeof(*ecn));
- } else {
- prsctp = (struct sctp_prsctp_supported_param *)((caddr_t)ecn);
+ if (((asoc != NULL) && (asoc->ecn_supported == 1)) ||
+ ((asoc == NULL) && (inp->ecn_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_ECN_CAPABLE);
+ 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;
}
- /* And now tell the peer we do pr-sctp */
- prsctp->ph.param_type = htons(SCTP_PRSCTP_SUPPORTED);
- prsctp->ph.param_length = htons(sizeof(*prsctp));
- SCTP_BUF_LEN(m) += sizeof(*prsctp);
- if (nat_friendly) {
- /* Add NAT friendly parameter */
- struct sctp_paramhdr *ph;
- ph = (struct sctp_paramhdr *)(mtod(m, caddr_t) + SCTP_BUF_LEN(m));
+ /* Add NAT friendly parameter */
+ if (nat_friendly) {
+ parameter_len = (uint16_t)sizeof(struct sctp_paramhdr);
+ ph = (struct sctp_paramhdr *)(mtod(m, caddr_t) + chunk_len);
ph->param_type = htons(SCTP_HAS_NAT_SUPPORT);
- ph->param_length = htons(sizeof(struct sctp_paramhdr));
- SCTP_BUF_LEN(m) += sizeof(struct sctp_paramhdr);
+ ph->param_length = htons(parameter_len);
+ chunk_len += parameter_len;
}
- /* And now tell the peer we do all the extensions */
- pr_supported = (struct sctp_supported_chunk_types_param *)(mtod(m, caddr_t) + SCTP_BUF_LEN(m));
- pr_supported->ph.param_type = htons(SCTP_SUPPORTED_CHUNK_EXT);
+
+ /* And now tell the peer which extensions we support */
num_ext = 0;
- 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;
- 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))
+ pr_supported = (struct sctp_supported_chunk_types_param *)(mtod(m, caddr_t) + chunk_len);
+ if (((asoc != NULL) && (asoc->prsctp_supported == 1)) ||
+ ((asoc == NULL) && (inp->prsctp_supported == 1))) {
+ pr_supported->chunk_types[num_ext++] = SCTP_FORWARD_CUM_TSN;
+ }
+ if (((asoc != NULL) && (asoc->auth_supported == 1)) ||
+ ((asoc == NULL) && (inp->auth_supported == 1))) {
pr_supported->chunk_types[num_ext++] = SCTP_AUTHENTICATION;
- if (SCTP_BASE_SYSCTL(sctp_nr_sack_on_off))
+ }
+ if (((asoc != NULL) && (asoc->asconf_supported == 1)) ||
+ ((asoc == NULL) && (inp->asconf_supported == 1))) {
+ pr_supported->chunk_types[num_ext++] = SCTP_ASCONF;
+ pr_supported->chunk_types[num_ext++] = SCTP_ASCONF_ACK;
+ }
+ if (((asoc != NULL) && (asoc->reconfig_supported == 1)) ||
+ ((asoc == NULL) && (inp->reconfig_supported == 1))) {
+ pr_supported->chunk_types[num_ext++] = SCTP_STREAM_RESET;
+ }
+ if (((asoc != NULL) && (asoc->nrsack_supported == 1)) ||
+ ((asoc == NULL) && (inp->nrsack_supported == 1))) {
pr_supported->chunk_types[num_ext++] = SCTP_NR_SELECTIVE_ACK;
- p_len = sizeof(*pr_supported) + num_ext;
- pr_supported->ph.param_length = htons(p_len);
- bzero((caddr_t)pr_supported + p_len, SCTP_SIZE32(p_len) - p_len);
- SCTP_BUF_LEN(m) += SCTP_SIZE32(p_len);
-
+ }
+ if (((asoc != NULL) && (asoc->pktdrop_supported == 1)) ||
+ ((asoc == NULL) && (inp->pktdrop_supported == 1))) {
+ pr_supported->chunk_types[num_ext++] = SCTP_PACKET_DROPPED;
+ }
+ if (num_ext > 0) {
+ parameter_len = (uint16_t)sizeof(struct sctp_supported_chunk_types_param) + num_ext;
+ pr_supported->ph.param_type = htons(SCTP_SUPPORTED_CHUNK_EXT);
+ pr_supported->ph.param_length = htons(parameter_len);
+ padding_len = SCTP_SIZE32(parameter_len) - parameter_len;
+ chunk_len += parameter_len;
+ }
+
/* add authentication parameters */
- if (!SCTP_BASE_SYSCTL(sctp_auth_disable)) {
+ if (((asoc != NULL) && (asoc->auth_supported == 1)) ||
+ ((asoc == NULL) && (inp->auth_supported == 1))) {
struct sctp_auth_random *randp;
struct sctp_auth_hmac_algo *hmacs;
struct sctp_auth_chunk_list *chunks;
- uint16_t random_len;
+ if (padding_len > 0) {
+ memset(mtod(m, caddr_t) + chunk_len, 0, padding_len);
+ chunk_len += padding_len;
+ padding_len = 0;
+ }
/* generate and add RANDOM parameter */
- random_len = SCTP_AUTH_RANDOM_SIZE_DEFAULT;
- randp = (struct sctp_auth_random *)(mtod(m, caddr_t) + SCTP_BUF_LEN(m));
+ randp = (struct sctp_auth_random *)(mtod(m, caddr_t) + chunk_len);
+ parameter_len = (uint16_t)sizeof(struct sctp_auth_random) +
+ SCTP_AUTH_RANDOM_SIZE_DEFAULT;
randp->ph.param_type = htons(SCTP_RANDOM);
- p_len = sizeof(*randp) + random_len;
- randp->ph.param_length = htons(p_len);
- SCTP_READ_RANDOM(randp->random_data, random_len);
- /* zero out any padding required */
- bzero((caddr_t)randp + p_len, SCTP_SIZE32(p_len) - p_len);
- SCTP_BUF_LEN(m) += SCTP_SIZE32(p_len);
+ randp->ph.param_length = htons(parameter_len);
+ SCTP_READ_RANDOM(randp->random_data, SCTP_AUTH_RANDOM_SIZE_DEFAULT);
+ padding_len = SCTP_SIZE32(parameter_len) - parameter_len;
+ chunk_len += parameter_len;
+ if (padding_len > 0) {
+ memset(mtod(m, caddr_t) + chunk_len, 0, padding_len);
+ chunk_len += padding_len;
+ padding_len = 0;
+ }
/* add HMAC_ALGO parameter */
- hmacs = (struct sctp_auth_hmac_algo *)(mtod(m, caddr_t) + SCTP_BUF_LEN(m));
- p_len = sctp_serialize_hmaclist(inp->sctp_ep.local_hmacs,
- (uint8_t *) hmacs->hmac_ids);
- if (p_len > 0) {
- p_len += sizeof(*hmacs);
- hmacs->ph.param_type = htons(SCTP_HMAC_LIST);
- hmacs->ph.param_length = htons(p_len);
- /* zero out any padding required */
- bzero((caddr_t)hmacs + p_len, SCTP_SIZE32(p_len) - p_len);
- SCTP_BUF_LEN(m) += SCTP_SIZE32(p_len);
+ hmacs = (struct sctp_auth_hmac_algo *)(mtod(m, caddr_t) + chunk_len);
+ parameter_len = (uint16_t)sizeof(struct sctp_auth_hmac_algo) +
+ sctp_serialize_hmaclist(inp->sctp_ep.local_hmacs,
+ (uint8_t *)hmacs->hmac_ids);
+ hmacs->ph.param_type = htons(SCTP_HMAC_LIST);
+ hmacs->ph.param_length = htons(parameter_len);
+ padding_len = SCTP_SIZE32(parameter_len) - parameter_len;
+ chunk_len += parameter_len;
+
+ if (padding_len > 0) {
+ memset(mtod(m, caddr_t) + chunk_len, 0, padding_len);
+ chunk_len += padding_len;
+ padding_len = 0;
}
/* add CHUNKS parameter */
- chunks = (struct sctp_auth_chunk_list *)(mtod(m, caddr_t) + SCTP_BUF_LEN(m));
- p_len = sctp_serialize_auth_chunks(inp->sctp_ep.local_auth_chunks,
- chunks->chunk_types);
- if (p_len > 0) {
- p_len += sizeof(*chunks);
- chunks->ph.param_type = htons(SCTP_CHUNK_LIST);
- chunks->ph.param_length = htons(p_len);
- /* zero out any padding required */
- bzero((caddr_t)chunks + p_len, SCTP_SIZE32(p_len) - p_len);
- SCTP_BUF_LEN(m) += SCTP_SIZE32(p_len);
- }
+ chunks = (struct sctp_auth_chunk_list *)(mtod(m, caddr_t) + chunk_len);
+ parameter_len = (uint16_t)sizeof(struct sctp_auth_chunk_list) +
+ sctp_serialize_auth_chunks(inp->sctp_ep.local_auth_chunks,
+ chunks->chunk_types);
+ chunks->ph.param_type = htons(SCTP_CHUNK_LIST);
+ chunks->ph.param_length = htons(parameter_len);
+ padding_len = SCTP_SIZE32(parameter_len) - parameter_len;
+ chunk_len += parameter_len;
}
- m_at = m;
+ SCTP_BUF_LEN(m) = chunk_len;
+ m_last = m;
/* now the addresses */
- {
- struct sctp_scoping scp;
- /* To optimize this we could put the scoping stuff
- * into a structure and remove the individual uint8's from
- * the stc structure. Then we could just sifa in the
- * address within the stc.. but for now this is a quick
- * hack to get the address stuff teased apart.
- */
- scp.ipv4_addr_legal = stc.ipv4_addr_legal;
- scp.ipv6_addr_legal = stc.ipv6_addr_legal;
+ /* To optimize this we could put the scoping stuff
+ * into a structure and remove the individual uint8's from
+ * the stc structure. Then we could just sifa in the
+ * address within the stc.. but for now this is a quick
+ * hack to get the address stuff teased apart.
+ */
+ scp.ipv4_addr_legal = stc.ipv4_addr_legal;
+ scp.ipv6_addr_legal = stc.ipv6_addr_legal;
#if defined(__Userspace__)
- scp.conn_addr_legal = stc.conn_addr_legal;
-#endif
- scp.loopback_scope = stc.loopback_scope;
- scp.ipv4_local_scope = stc.ipv4_scope;
- scp.local_scope = stc.local_scope;
- scp.site_scope = stc.site_scope;
- m_at = sctp_add_addresses_to_i_ia(inp, stcb, &scp, m_at, cnt_inits_to, NULL, NULL);
+ scp.conn_addr_legal = stc.conn_addr_legal;
+#endif
+ scp.loopback_scope = stc.loopback_scope;
+ scp.ipv4_local_scope = stc.ipv4_scope;
+ scp.local_scope = stc.local_scope;
+ scp.site_scope = stc.site_scope;
+ m_last = sctp_add_addresses_to_i_ia(inp, stcb, &scp, m_last,
+ cnt_inits_to,
+ &padding_len, &chunk_len);
+ /* padding_len can only be positive, if no addresses have been added */
+ if (padding_len > 0) {
+ memset(mtod(m, caddr_t) + chunk_len, 0, padding_len);
+ chunk_len += padding_len;
+ SCTP_BUF_LEN(m) += padding_len;
+ padding_len = 0;
}
/* tack on the operational error if present */
if (op_err) {
- struct mbuf *ol;
- int llen;
- llen = 0;
- ol = op_err;
-
- while (ol) {
- llen += SCTP_BUF_LEN(ol);
- ol = SCTP_BUF_NEXT(ol);
- }
- if (llen % 4) {
- /* must add a pad to the param */
- uint32_t cpthis = 0;
- int padlen;
-
- padlen = 4 - (llen % 4);
- m_copyback(op_err, llen, padlen, (caddr_t)&cpthis);
- }
- while (SCTP_BUF_NEXT(m_at) != NULL) {
- m_at = SCTP_BUF_NEXT(m_at);
+ parameter_len = 0;
+ for (m_tmp = op_err; m_tmp != NULL; m_tmp = SCTP_BUF_NEXT(m_tmp)) {
+ parameter_len += SCTP_BUF_LEN(m_tmp);
}
- SCTP_BUF_NEXT(m_at) = op_err;
- while (SCTP_BUF_NEXT(m_at) != NULL) {
- m_at = SCTP_BUF_NEXT(m_at);
+ padding_len = SCTP_SIZE32(parameter_len) - parameter_len;
+ SCTP_BUF_NEXT(m_last) = op_err;
+ while (SCTP_BUF_NEXT(m_last) != NULL) {
+ m_last = SCTP_BUF_NEXT(m_last);
}
+ chunk_len += parameter_len;
}
- /* pre-calulate the size and update pkt header and chunk header */
- p_len = 0;
- for (m_tmp = m; m_tmp; m_tmp = SCTP_BUF_NEXT(m_tmp)) {
- p_len += SCTP_BUF_LEN(m_tmp);
- if (SCTP_BUF_NEXT(m_tmp) == NULL) {
- /* m_tmp should now point to last one */
- break;
+ if (padding_len > 0) {
+ m_last = sctp_add_pad_tombuf(m_last, padding_len);
+ if (m_last == NULL) {
+ /* Houston we have a problem, no space */
+ sctp_m_freem(m);
+ return;
}
+ chunk_len += padding_len;
+ padding_len = 0;
}
-
/* Now we must build a cookie */
m_cookie = sctp_add_cookie(init_pkt, offset, m, 0, &stc, &signature);
if (m_cookie == NULL) {
@@ -6474,20 +6490,21 @@ sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
return;
}
/* Now append the cookie to the end and update the space/size */
- SCTP_BUF_NEXT(m_tmp) = m_cookie;
-
- for (m_tmp = m_cookie; m_tmp; m_tmp = SCTP_BUF_NEXT(m_tmp)) {
- p_len += SCTP_BUF_LEN(m_tmp);
+ SCTP_BUF_NEXT(m_last) = m_cookie;
+ parameter_len = 0;
+ for (m_tmp = m_cookie; m_tmp != NULL; m_tmp = SCTP_BUF_NEXT(m_tmp)) {
+ parameter_len += SCTP_BUF_LEN(m_tmp);
if (SCTP_BUF_NEXT(m_tmp) == NULL) {
- /* m_tmp should now point to last one */
- mp_last = m_tmp;
- break;
+ m_last = m_tmp;
}
}
+ padding_len = SCTP_SIZE32(parameter_len) - parameter_len;
+ chunk_len += parameter_len;
+
/* Place in the size, but we don't include
* the last pad (if any) in the INIT-ACK.
*/
- initack->ch.chunk_length = htons(p_len);
+ initack->ch.chunk_length = htons(chunk_len);
/* Time to sign the cookie, we don't sign over the cookie
* signature though thus we set trailer.
@@ -6500,11 +6517,8 @@ sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
* We sifa 0 here to NOT set IP_DF if its IPv4, we ignore the return
* here since the timer will drive a retranmission.
*/
- padval = p_len % 4;
- if ((padval) && (mp_last)) {
- /* see my previous comments on mp_last */
- if (sctp_add_pad_tombuf(mp_last, (4 - padval))) {
- /* Houston we have a problem, no space */
+ if (padding_len > 0) {
+ if (sctp_add_pad_tombuf(m_last, padding_len) == NULL) {
sctp_m_freem(m);
return;
}
@@ -6537,7 +6551,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) {
/*
@@ -7944,7 +7958,6 @@ re_look:
sctp_auth_key_acquire(stcb, chk->auth_keyid);
chk->holds_key_ref = 1;
}
-
#if defined(__FreeBSD__) || defined(__Panda__)
chk->rec.data.TSN_seq = atomic_fetchadd_int(&asoc->sending_seq, 1);
#else
@@ -7993,12 +8006,10 @@ re_look:
int pads;
pads = SCTP_SIZE32(chk->book_size) - chk->send_size;
- if (sctp_pad_lastmbuf(chk->data, pads, chk->last_mbuf) == 0) {
- chk->pad_inplace = 1;
- }
- if ((lm = SCTP_BUF_NEXT(chk->last_mbuf)) != NULL) {
- /* pad added an mbuf */
+ lm = sctp_pad_lastmbuf(chk->data, pads, chk->last_mbuf);
+ if (lm != NULL) {
chk->last_mbuf = lm;
+ chk->pad_inplace = 1;
}
chk->send_size += pads;
}
@@ -8239,7 +8250,6 @@ sctp_med_chunk_output(struct sctp_inpcb *inp,
#endif
*num_out = 0;
auth_keyid = stcb->asoc.authinfo.active_keyid;
-
if ((asoc->state & SCTP_STATE_SHUTDOWN_PENDING) ||
(asoc->state & SCTP_STATE_SHUTDOWN_RECEIVED) ||
(sctp_is_feature_on(inp, SCTP_PCB_FLAGS_EXPLICIT_EOR))) {
@@ -10443,7 +10453,7 @@ sctp_chunk_output (struct sctp_inpcb *inp,
/* Do we have something to send, data or control AND
* a sack timer running, if so piggy-back the sack.
*/
- if (SCTP_OS_TIMER_PENDING(&stcb->asoc.dack_timer.timer)) {
+ if (SCTP_OS_TIMER_PENDING(&stcb->asoc.dack_timer.timer)) {
sctp_send_sack(stcb, so_locked);
(void)SCTP_OS_TIMER_STOP(&stcb->asoc.dack_timer.timer);
}
@@ -10458,7 +10468,7 @@ sctp_chunk_output (struct sctp_inpcb *inp,
* by peer that carried data. Send cookie-ack only
* and then the next call with get the retran's.
*/
- (void)sctp_med_chunk_output(inp, stcb, asoc, &num_out, &reason_code, 1,
+ (void)sctp_med_chunk_output(inp, stcb, asoc, &num_out, &reason_code, 1,
from_where,
&now, &now_filled, frag_point, so_locked);
return;
@@ -10912,8 +10922,7 @@ sctp_send_sack(struct sctp_tcb *stcb, int so_locked
uint8_t type;
uint8_t tsn_map;
- if ((stcb->asoc.sctp_nr_sack_on_off == 1) &&
- (stcb->asoc.peer_supports_nr_sack == 1)) {
+ if (stcb->asoc.nrsack_supported == 1) {
type = SCTP_NR_SELECTIVE_ACK;
} else {
type = SCTP_SELECTIVE_ACK;
@@ -11374,7 +11383,8 @@ sctp_send_abort_tcb(struct sctp_tcb *stcb, struct mbuf *operr, int so_locked
abort->ch.chunk_length = htons(chunk_len);
/* Add padding, if necessary. */
if (padding_len > 0) {
- if ((m_last == NULL) || sctp_add_pad_tombuf(m_last, padding_len)) {
+ if ((m_last == NULL) ||
+ (sctp_add_pad_tombuf(m_last, padding_len) == NULL)) {
sctp_m_freem(m_out);
return;
}
@@ -11488,7 +11498,7 @@ sctp_send_resp_msg(struct sockaddr *src, struct sockaddr *dst,
padding_len = 4 - padding_len;
}
if (padding_len != 0) {
- if (sctp_add_pad_tombuf(m_last, padding_len)) {
+ if (sctp_add_pad_tombuf(m_last, padding_len) == NULL) {
sctp_m_freem(cause);
return;
}
@@ -11512,7 +11522,7 @@ sctp_send_resp_msg(struct sockaddr *src, struct sockaddr *dst,
default:
break;
}
-#if defined INET || defined INET6
+#if defined(INET) || defined(INET6)
if (port) {
len += sizeof(struct udphdr);
}
@@ -11621,7 +11631,7 @@ sctp_send_resp_msg(struct sockaddr *src, struct sockaddr *dst,
shout = mtod(mout, struct sctphdr *);
break;
}
-#if defined INET || defined INET6
+#if defined(INET) || defined(INET6)
if (port) {
if (htons(SCTP_BASE_SYSCTL(sctp_udp_tunneling_port)) == 0) {
sctp_m_freem(mout);
@@ -12066,7 +12076,7 @@ sctp_send_packet_dropped(struct sctp_tcb *stcb, struct sctp_nets *net,
}
asoc = &stcb->asoc;
SCTP_TCB_LOCK_ASSERT(stcb);
- if (asoc->peer_supports_pktdrop == 0) {
+ if (asoc->pktdrop_supported == 0) {
/*-
* peer must declare support before I send one.
*/
@@ -12573,6 +12583,9 @@ sctp_send_str_reset_req(struct sctp_tcb *stcb,
struct sctp_stream_out *oldstream;
struct sctp_stream_queue_pending *sp, *nsp;
int i;
+#if defined(SCTP_DETAILED_STR_STATS)
+ int j;
+#endif
oldstream = stcb->asoc.strmout;
/* get some more */
@@ -12617,6 +12630,15 @@ sctp_send_str_reset_req(struct sctp_tcb *stcb,
for (i = stcb->asoc.streamoutcnt; i < (stcb->asoc.streamoutcnt + adding_o); i++) {
TAILQ_INIT(&stcb->asoc.strmout[i].outqueue);
stcb->asoc.strmout[i].chunks_on_queues = 0;
+#if defined(SCTP_DETAILED_STR_STATS)
+ for (j = 0; j < SCTP_PR_SCTP_MAX + 1; j++) {
+ stcb->asoc.strmout[i].abandoned_sent[j] = 0;
+ stcb->asoc.strmout[i].abandoned_unsent[j] = 0;
+ }
+#else
+ stcb->asoc.strmout[i].abandoned_sent[0] = 0;
+ stcb->asoc.strmout[i].abandoned_unsent[0] = 0;
+#endif
stcb->asoc.strmout[i].next_sequence_send = 0x0;
stcb->asoc.strmout[i].stream_no = i;
stcb->asoc.strmout[i].last_msg_incomplete = 0;
@@ -13977,7 +13999,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);
@@ -14476,12 +14498,7 @@ sctp_add_auth_chunk(struct mbuf *m, struct mbuf **m_end,
(stcb == NULL))
return (m);
- /* sysctl disabled auth? */
- if (SCTP_BASE_SYSCTL(sctp_auth_disable))
- return (m);
-
- /* peer doesn't do auth... */
- if (!stcb->asoc.peer_supports_auth) {
+ if (stcb->asoc.auth_supported == 0) {
return (m);
}
/* does the requested chunk require auth? */
@@ -14590,7 +14607,7 @@ sctp_v4src_match_nexthop(struct sctp_ifa *sifa, sctp_route_t *ro)
}
ifa = (struct ifaddr *)sifa->ifa;
mask = (struct sockaddr_in *)(ifa->ifa_netmask);
- sin = (struct sockaddr_in *)&sifa->address.sin;
+ sin = &sifa->address.sin;
srcnetaddr.s_addr = (sin->sin_addr.s_addr & mask->sin_addr.s_addr);
SCTPDBG(SCTP_DEBUG_OUTPUT1, "match_nexthop4: src address is ");
SCTPDBG_ADDR(SCTP_DEBUG_OUTPUT2, &sifa->address.sa);
diff --git a/netinet/sctp_pcb.c b/netinet/sctp_pcb.c
index a7f8b85..ffe8f62 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 267674 2014-06-20 13:26:49Z tuexen $");
+__FBSDID("$FreeBSD: head/sys/netinet/sctp_pcb.c 271230 2014-09-07 18:05:37Z tuexen $");
#endif
#include <netinet/sctp_os.h>
@@ -52,7 +52,7 @@ __FBSDID("$FreeBSD: head/sys/netinet/sctp_pcb.c 267674 2014-06-20 13:26:49Z tuex
#if defined(__FreeBSD__) && __FreeBSD_version >= 803000
#include <netinet/sctp_dtrace_define.h>
#endif
-#if defined INET || defined INET6
+#if defined(INET) || defined(INET6)
#if !defined(__Userspace_os_Windows)
#include <netinet/udp.h>
#endif
@@ -224,8 +224,8 @@ sctp_allocate_vrf(int vrf_id)
}
SCTP_MALLOC(vrf, struct sctp_vrf *, sizeof(struct sctp_vrf),
SCTP_M_VRF);
- if (vrf == NULL) {
- /* No memory */
+ if (vrf == NULL) {
+ /* No memory */
#ifdef INVARIANTS
panic("No memory for VRF:%d", vrf_id);
#endif
@@ -243,7 +243,7 @@ sctp_allocate_vrf(int vrf_id)
vrf->vrf_addr_hash = SCTP_HASH_INIT(SCTP_VRF_ADDR_HASH_SIZE,
&vrf->vrf_addr_hashmark);
if (vrf->vrf_addr_hash == NULL) {
- /* No memory */
+ /* No memory */
#ifdef INVARIANTS
panic("No memory for VRF:%d", vrf_id);
#endif
@@ -656,7 +656,7 @@ sctp_add_addr_to_vrf(uint32_t vrf_id, void *ifn, uint32_t ifn_index,
sctp_remove_ifa_from_ifn(sctp_ifap);
/* move the address over to the new ifn */
sctp_add_ifa_to_ifn(sctp_ifnp, sctp_ifap);
- goto exit_stage_left;
+ goto exit_stage_left;
} else {
/* repair ifnp which was NULL ? */
sctp_ifap->localifa_flags = SCTP_ADDR_VALID;
@@ -713,7 +713,7 @@ sctp_add_addr_to_vrf(uint32_t vrf_id, void *ifn, uint32_t ifn_index,
{
struct sockaddr_in *sin;
- sin = (struct sockaddr_in *)&sctp_ifap->address.sin;
+ sin = &sctp_ifap->address.sin;
if (SCTP_IFN_IS_IFT_LOOP(sctp_ifap->ifn_p) ||
(IN4_ISLOOPBACK_ADDRESS(&sin->sin_addr))) {
sctp_ifap->src_is_loop = 1;
@@ -733,7 +733,7 @@ sctp_add_addr_to_vrf(uint32_t vrf_id, void *ifn, uint32_t ifn_index,
/* ok to use deprecated addresses? */
struct sockaddr_in6 *sin6;
- sin6 = (struct sockaddr_in6 *)&sctp_ifap->address.sin6;
+ sin6 = &sctp_ifap->address.sin6;
if (SCTP_IFN_IS_IFT_LOOP(sctp_ifap->ifn_p) ||
(IN6_IS_ADDR_LOOPBACK(&sin6->sin6_addr))) {
sctp_ifap->src_is_loop = 1;
@@ -1097,7 +1097,7 @@ sctp_does_stcb_own_this_addr(struct sctp_tcb *stcb, struct sockaddr *to)
{
struct sockaddr_in *sin, *rsin;
- sin = (struct sockaddr_in *)&laddr->ifa->address.sin;
+ sin = &laddr->ifa->address.sin;
rsin = (struct sockaddr_in *)to;
if (sin->sin_addr.s_addr == rsin->sin_addr.s_addr) {
SCTP_IPI_ADDR_RUNLOCK();
@@ -1111,7 +1111,7 @@ sctp_does_stcb_own_this_addr(struct sctp_tcb *stcb, struct sockaddr *to)
{
struct sockaddr_in6 *sin6, *rsin6;
- sin6 = (struct sockaddr_in6 *)&laddr->ifa->address.sin6;
+ sin6 = &laddr->ifa->address.sin6;
rsin6 = (struct sockaddr_in6 *)to;
if (SCTP6_ARE_ADDR_EQUAL(sin6, rsin6)) {
SCTP_IPI_ADDR_RUNLOCK();
@@ -1126,7 +1126,7 @@ sctp_does_stcb_own_this_addr(struct sctp_tcb *stcb, struct sockaddr *to)
{
struct sockaddr_conn *sconn, *rsconn;
- sconn = (struct sockaddr_conn *)&laddr->ifa->address.sconn;
+ sconn = &laddr->ifa->address.sconn;
rsconn = (struct sockaddr_conn *)to;
if (sconn->sconn_addr == rsconn->sconn_addr) {
SCTP_IPI_ADDR_RUNLOCK();
@@ -2680,7 +2680,7 @@ sctp_findassociation_ep_asconf(struct mbuf *m, int offset,
struct sctp_inpcb **inp_p, struct sctp_nets **netp, uint32_t vrf_id)
{
struct sctp_tcb *stcb;
- struct sockaddr_storage remote_store;
+ union sctp_sockstore remote_store;
struct sctp_paramhdr parm_buf, *phdr;
int ptype;
int zero_address = 0;
@@ -2719,7 +2719,7 @@ sctp_findassociation_ep_asconf(struct mbuf *m, int offset,
__FUNCTION__);
return (NULL);
}
- sin6 = (struct sockaddr_in6 *)&remote_store;
+ sin6 = &remote_store.sin6;
sin6->sin6_family = AF_INET6;
#ifdef HAVE_SIN6_LEN
sin6->sin6_len = sizeof(*sin6);
@@ -2748,7 +2748,7 @@ sctp_findassociation_ep_asconf(struct mbuf *m, int offset,
__FUNCTION__);
return (NULL);
}
- sin = (struct sockaddr_in *)&remote_store;
+ sin = &remote_store.sin;
sin->sin_family = AF_INET;
#ifdef HAVE_SIN_LEN
sin->sin_len = sizeof(*sin);
@@ -2773,7 +2773,7 @@ sctp_findassociation_ep_asconf(struct mbuf *m, int offset,
}
} else {
stcb = sctp_findassociation_ep_addr(inp_p,
- (struct sockaddr *)&remote_store, netp,
+ &remote_store.sa, netp,
dst, NULL);
}
return (stcb);
@@ -2841,7 +2841,13 @@ sctp_inpcb_alloc(struct socket *so, uint32_t vrf_id)
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);
- inp->sctp_ecn_enable = SCTP_BASE_SYSCTL(sctp_ecn_enable);
+ inp->ecn_supported = (uint8_t)SCTP_BASE_SYSCTL(sctp_ecn_enable);
+ inp->prsctp_supported = (uint8_t)SCTP_BASE_SYSCTL(sctp_pr_enable);
+ inp->auth_supported = (uint8_t)SCTP_BASE_SYSCTL(sctp_auth_enable);
+ inp->asconf_supported = (uint8_t)SCTP_BASE_SYSCTL(sctp_asconf_enable);
+ inp->reconfig_supported = (uint8_t)SCTP_BASE_SYSCTL(sctp_reconfig_enable);
+ inp->nrsack_supported = (uint8_t)SCTP_BASE_SYSCTL(sctp_nrsack_enable);
+ inp->pktdrop_supported = (uint8_t)SCTP_BASE_SYSCTL(sctp_pktdrop_enable);
#if defined(__Userspace__)
inp->ulp_info = NULL;
inp->recv_callback = NULL;
@@ -3090,12 +3096,15 @@ sctp_inpcb_alloc(struct socket *so, uint32_t vrf_id)
*/
m->local_hmacs = sctp_default_supported_hmaclist();
m->local_auth_chunks = sctp_alloc_chunklist();
+ if (inp->asconf_supported) {
+ sctp_auth_add_chunk(SCTP_ASCONF, m->local_auth_chunks);
+ sctp_auth_add_chunk(SCTP_ASCONF_ACK, m->local_auth_chunks);
+ }
m->default_dscp = 0;
#ifdef INET6
m->default_flowlabel = 0;
#endif
m->port = 0; /* encapsulation disabled by default */
- sctp_auth_set_default_chunks(m->local_auth_chunks);
LIST_INIT(&m->shared_keys);
/* add default NULL key as key id 0 */
null_key = sctp_alloc_sharedkey();
@@ -3583,8 +3592,8 @@ sctp_inpcb_bind(struct socket *so, struct sockaddr *addr,
last = MODULE_GLOBAL(ipport_lowlastauto);
} else {
#endif
- first = MODULE_GLOBAL(ipport_firstauto);
- last = MODULE_GLOBAL(ipport_lastauto);
+ first = MODULE_GLOBAL(ipport_firstauto);
+ last = MODULE_GLOBAL(ipport_lastauto);
#if defined(__FreeBSD__) || defined(__APPLE__)
}
#endif
@@ -3692,42 +3701,27 @@ sctp_inpcb_bind(struct socket *so, struct sockaddr *addr,
* too (before adding).
*/
struct sctp_ifa *ifa;
- struct sockaddr_storage store_sa;
+ union sctp_sockstore store;
- memset(&store_sa, 0, sizeof(store_sa));
+ memset(&store, 0, sizeof(store));
switch (addr->sa_family) {
#ifdef INET
case AF_INET:
- {
- struct sockaddr_in *sin;
-
- sin = (struct sockaddr_in *)&store_sa;
- memcpy(sin, addr, sizeof(struct sockaddr_in));
- sin->sin_port = 0;
+ memcpy(&store.sin, addr, sizeof(struct sockaddr_in));
+ store.sin.sin_port = 0;
break;
- }
#endif
#ifdef INET6
case AF_INET6:
- {
- struct sockaddr_in6 *sin6;
-
- sin6 = (struct sockaddr_in6 *)&store_sa;
- memcpy(sin6, addr, sizeof(struct sockaddr_in6));
- sin6->sin6_port = 0;
+ memcpy(&store.sin6, addr, sizeof(struct sockaddr_in6));
+ store.sin6.sin6_port = 0;
break;
- }
#endif
#if defined(__Userspace__)
case AF_CONN:
- {
- struct sockaddr_conn *sconn;
-
- sconn = (struct sockaddr_conn *)&store_sa;
- memcpy(sconn, addr, sizeof(struct sockaddr_conn));
- sconn->sconn_port = 0;
+ memcpy(&store.sconn, addr, sizeof(struct sockaddr_conn));
+ store.sconn.sconn_port = 0;
break;
- }
#endif
default:
break;
@@ -3744,7 +3738,7 @@ sctp_inpcb_bind(struct socket *so, struct sockaddr *addr,
* O/S's will pass things in via the
* sctp_ifap argument (Panda).
*/
- ifa = sctp_find_ifa_by_addr((struct sockaddr *)&store_sa,
+ ifa = sctp_find_ifa_by_addr(&store.sa,
vrf_id, SCTP_ADDR_NOT_LOCKED);
}
if (ifa == NULL) {
@@ -4615,7 +4609,7 @@ sctp_add_remote_addr(struct sctp_tcb *stcb, struct sockaddr *newaddr,
* this means its an initial value
*/
net->rto_needed = 1;
- net->RTO = 0;
+ net->RTO = 0;
net->RTO_measured = 0;
stcb->asoc.numnets++;
net->ref_count = 1;
@@ -4668,7 +4662,9 @@ sctp_add_remote_addr(struct sctp_tcb *stcb, struct sockaddr *newaddr,
#endif
SCTP_RTALLOC((sctp_route_t *)&net->ro, stcb->asoc.vrf_id);
-#if !defined(__Userspace__)
+#if defined(__Userspace__)
+ net->src_addr_selected = 0;
+#else
if (SCTP_ROUTE_HAS_VALID_IFN(&net->ro)) {
/* Get source address */
net->ro._s_addr = sctp_source_address_selection(stcb->sctp_ep,
@@ -4677,9 +4673,14 @@ sctp_add_remote_addr(struct sctp_tcb *stcb, struct sockaddr *newaddr,
net,
0,
stcb->asoc.vrf_id);
- /* Now get the interface MTU */
- if (net->ro._s_addr && net->ro._s_addr->ifn_p) {
- net->mtu = SCTP_GATHER_MTU_FROM_INTFC(net->ro._s_addr->ifn_p);
+ if (net->ro._s_addr != NULL) {
+ net->src_addr_selected = 1;
+ /* Now get the interface MTU */
+ if (net->ro._s_addr->ifn_p != NULL) {
+ net->mtu = SCTP_GATHER_MTU_FROM_INTFC(net->ro._s_addr->ifn_p);
+ }
+ } else {
+ net->src_addr_selected = 0;
}
if (net->mtu > 0) {
uint32_t rmtu;
@@ -4694,9 +4695,11 @@ sctp_add_remote_addr(struct sctp_tcb *stcb, struct sockaddr *newaddr,
* the route may be leading out the loopback, or
* a different interface.
*/
- net->mtu = rmtu;
+ net->mtu = rmtu;
}
- }
+ }
+ } else {
+ net->src_addr_selected = 0;
}
#endif
if (net->mtu == 0) {
@@ -4720,7 +4723,7 @@ sctp_add_remote_addr(struct sctp_tcb *stcb, struct sockaddr *newaddr,
break;
}
}
-#if defined INET || defined INET6
+#if defined(INET) || defined(INET6)
if (net->port) {
net->mtu -= (uint32_t)sizeof(struct udphdr);
}
@@ -4756,7 +4759,6 @@ sctp_add_remote_addr(struct sctp_tcb *stcb, struct sockaddr *newaddr,
*/
net->find_pseudo_cumack = 1;
net->find_rtx_pseudo_cumack = 1;
- net->src_addr_selected = 0;
#if defined(__FreeBSD__)
/* Choose an initial flowid. */
net->flowid = stcb->asoc.my_vtag ^
@@ -5191,9 +5193,9 @@ sctp_remove_net(struct sctp_tcb *stcb, struct sctp_nets *net)
(by micchie)
*/
if (sctp_is_mobility_feature_on(stcb->sctp_ep,
- SCTP_MOBILITY_BASE) ||
+ SCTP_MOBILITY_BASE) ||
sctp_is_mobility_feature_on(stcb->sctp_ep,
- SCTP_MOBILITY_FASTHANDOFF)) {
+ SCTP_MOBILITY_FASTHANDOFF)) {
SCTPDBG(SCTP_DEBUG_ASCONF1, "remove_net: primary dst is deleting\n");
if (asoc->deleted_primary != NULL) {
SCTPDBG(SCTP_DEBUG_ASCONF1, "remove_net: deleted primary may be already stored\n");
@@ -6947,13 +6949,16 @@ sctp_pcb_finish(void)
#endif
#if !defined(__FreeBSD__)
SCTP_IPI_ITERATOR_WQ_DESTROY();
- SCTP_ITERATOR_LOCK_DESTROY();
+ SCTP_ITERATOR_LOCK_DESTROY();
#endif
SCTP_OS_TIMER_STOP(&SCTP_BASE_INFO(addr_wq_timer.timer));
SCTP_WQ_ADDR_LOCK();
LIST_FOREACH_SAFE(wi, &SCTP_BASE_INFO(addr_wq), sctp_nxt_addr, nwi) {
LIST_REMOVE(wi, sctp_nxt_addr);
SCTP_DECR_LADDR_COUNT();
+ if (wi->action == SCTP_DEL_IP_ADDRESS) {
+ SCTP_FREE(wi->ifa, SCTP_M_IFA);
+ }
SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_laddr), wi);
}
SCTP_WQ_ADDR_UNLOCK();
@@ -7098,7 +7103,14 @@ sctp_load_addresses_from_init(struct sctp_tcb *stcb, struct mbuf *m,
sctp_key_t *new_key;
uint32_t keylen;
int got_random = 0, got_hmacs = 0, got_chklist = 0;
- uint8_t ecn_allowed;
+ uint8_t peer_supports_ecn;
+ uint8_t peer_supports_prsctp;
+ uint8_t peer_supports_auth;
+ uint8_t peer_supports_asconf;
+ uint8_t peer_supports_asconf_ack;
+ uint8_t peer_supports_reconfig;
+ uint8_t peer_supports_nrsack;
+ uint8_t peer_supports_pktdrop;
#ifdef INET
struct sockaddr_in sin;
#endif
@@ -7128,8 +7140,13 @@ sctp_load_addresses_from_init(struct sctp_tcb *stcb, struct mbuf *m,
} else {
sa = src;
}
- /* Turn off ECN until we get through all params */
- ecn_allowed = 0;
+ peer_supports_ecn = 0;
+ peer_supports_prsctp = 0;
+ peer_supports_auth = 0;
+ peer_supports_asconf = 0;
+ peer_supports_reconfig = 0;
+ peer_supports_nrsack = 0;
+ peer_supports_pktdrop = 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;
@@ -7188,12 +7205,6 @@ sctp_load_addresses_from_init(struct sctp_tcb *stcb, struct mbuf *m,
/* the assoc was freed? */
return (-4);
}
- /*
- * peer must explicitly turn this on. This may have been initialized
- * to be "on" in order to allow local addr changes while INIT's are
- * in flight.
- */
- stcb->asoc.peer_supports_asconf = 0;
/* now we must go through each of the params. */
phdr = sctp_get_next_param(m, offset, &parm_buf, sizeof(parm_buf));
while (phdr) {
@@ -7379,7 +7390,7 @@ sctp_load_addresses_from_init(struct sctp_tcb *stcb, struct mbuf *m,
} else
#endif
if (ptype == SCTP_ECN_CAPABLE) {
- ecn_allowed = 1;
+ peer_supports_ecn = 1;
} else if (ptype == SCTP_ULP_ADAPTATION) {
if (stcb->asoc.state != SCTP_STATE_OPEN) {
struct sctp_adaptation_layer_indication ai, *aip;
@@ -7400,7 +7411,9 @@ sctp_load_addresses_from_init(struct sctp_tcb *stcb, struct mbuf *m,
struct sctp_asconf_addrv4_param *fii;
#endif
- stcb->asoc.peer_supports_asconf = 1;
+ if (stcb->asoc.asconf_supported == 0) {
+ return (-100);
+ }
if (plen > sizeof(lstore)) {
return (-23);
}
@@ -7452,7 +7465,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;
+ peer_supports_prsctp = 1;
} else if (ptype == SCTP_SUPPORTED_CHUNK_EXT) {
/* A supported extension chunk */
struct sctp_supported_chunk_types_param *pr_supported;
@@ -7464,34 +7477,29 @@ sctp_load_addresses_from_init(struct sctp_tcb *stcb, struct mbuf *m,
if (phdr == NULL) {
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;
- stcb->asoc.peer_supports_auth = 0;
pr_supported = (struct sctp_supported_chunk_types_param *)phdr;
num_ent = plen - sizeof(struct sctp_paramhdr);
for (i = 0; i < num_ent; i++) {
switch (pr_supported->chunk_types[i]) {
case SCTP_ASCONF:
+ peer_supports_asconf = 1;
case SCTP_ASCONF_ACK:
- stcb->asoc.peer_supports_asconf = 1;
+ peer_supports_asconf_ack = 1;
break;
case SCTP_FORWARD_CUM_TSN:
- stcb->asoc.peer_supports_prsctp = 1;
+ peer_supports_prsctp = 1;
break;
case SCTP_PACKET_DROPPED:
- stcb->asoc.peer_supports_pktdrop = 1;
+ peer_supports_pktdrop = 1;
break;
case SCTP_NR_SELECTIVE_ACK:
- stcb->asoc.peer_supports_nr_sack = 1;
+ peer_supports_nrsack = 1;
break;
case SCTP_STREAM_RESET:
- stcb->asoc.peer_supports_strreset = 1;
+ peer_supports_reconfig = 1;
break;
case SCTP_AUTHENTICATION:
- stcb->asoc.peer_supports_auth = 1;
+ peer_supports_auth = 1;
break;
default:
/* one I have not learned yet */
@@ -7628,24 +7636,47 @@ sctp_load_addresses_from_init(struct sctp_tcb *stcb, struct mbuf *m,
}
}
}
- if (ecn_allowed == 0) {
- stcb->asoc.ecn_allowed = 0;
+ if ((stcb->asoc.ecn_supported == 1) &&
+ (peer_supports_ecn == 0)) {
+ stcb->asoc.ecn_supported = 0;
}
- /* validate authentication required parameters */
- if (got_random && got_hmacs) {
- stcb->asoc.peer_supports_auth = 1;
- } else {
- stcb->asoc.peer_supports_auth = 0;
+ if ((stcb->asoc.prsctp_supported == 1) &&
+ (peer_supports_prsctp == 0)) {
+ stcb->asoc.prsctp_supported = 0;
+ }
+ if ((stcb->asoc.auth_supported == 1) &&
+ ((peer_supports_auth == 0) ||
+ (got_random == 0) || (got_hmacs == 0))) {
+ stcb->asoc.auth_supported = 0;
+ }
+ if ((stcb->asoc.asconf_supported == 1) &&
+ ((peer_supports_asconf == 0) || (peer_supports_asconf_ack == 0) ||
+ (stcb->asoc.auth_supported == 0) ||
+ (saw_asconf == 0) || (saw_asconf_ack == 0))) {
+ stcb->asoc.asconf_supported = 0;
}
- if (!stcb->asoc.peer_supports_auth && got_chklist) {
+ if ((stcb->asoc.reconfig_supported == 1) &&
+ (peer_supports_reconfig == 0)) {
+ stcb->asoc.reconfig_supported = 0;
+ }
+ if ((stcb->asoc.nrsack_supported == 1) &&
+ (peer_supports_nrsack == 0)) {
+ stcb->asoc.nrsack_supported = 0;
+ }
+ if ((stcb->asoc.pktdrop_supported == 1) &&
+ (peer_supports_pktdrop == 0)){
+ stcb->asoc.pktdrop_supported = 0;
+ }
+ /* validate authentication required parameters */
+ if ((peer_supports_auth == 0) && (got_chklist == 1)) {
/* peer does not support auth but sent a chunks list? */
return (-31);
}
- if (!SCTP_BASE_SYSCTL(sctp_asconf_auth_nochk) && stcb->asoc.peer_supports_asconf &&
- !stcb->asoc.peer_supports_auth) {
+ if ((peer_supports_asconf == 1) && (peer_supports_auth == 0)) {
/* peer supports asconf but not auth? */
return (-32);
- } else if ((stcb->asoc.peer_supports_asconf) && (stcb->asoc.peer_supports_auth) &&
+ } else if ((peer_supports_asconf == 1) &&
+ (peer_supports_auth == 1) &&
((saw_asconf == 0) || (saw_asconf_ack == 0))) {
return (-33);
}
diff --git a/netinet/sctp_pcb.h b/netinet/sctp_pcb.h
index bcd2864..d09bb59 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 254248 2013-08-12 13:52:15Z tuexen $");
+__FBSDID("$FreeBSD: head/sys/netinet/sctp_pcb.h 269858 2014-08-12 11:30:16Z tuexen $");
#endif
#ifndef _NETINET_SCTP_PCB_H_
@@ -110,7 +110,7 @@ struct sctp_ifa {
*/
union sctp_sockstore address;
uint32_t refcount; /* number of folks refering to this */
- uint32_t flags;
+ uint32_t flags;
uint32_t localifa_flags;
uint32_t vrf_id; /* vrf_id of this addr (for deleting) */
uint8_t src_is_loop;
@@ -480,7 +480,13 @@ struct sctp_inpcb {
uint32_t sctp_context;
uint8_t local_strreset_support;
uint32_t sctp_cmt_on_off;
- uint32_t sctp_ecn_enable;
+ uint8_t ecn_supported;
+ uint8_t prsctp_supported;
+ uint8_t auth_supported;
+ uint8_t asconf_supported;
+ uint8_t reconfig_supported;
+ uint8_t nrsack_supported;
+ uint8_t pktdrop_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 bba97f6..beb11fb 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 243565 2012-11-26 16:44:03Z tuexen $");
+__FBSDID("$FreeBSD: head/sys/netinet/sctp_peeloff.c 269858 2014-08-12 11:30:16Z tuexen $");
#endif
#include <netinet/sctp_os.h>
@@ -125,7 +125,13 @@ sctp_do_peeloff(struct socket *head, struct socket *so, sctp_assoc_t assoc_id)
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->sctp_ecn_enable = inp->sctp_ecn_enable;
+ n_inp->ecn_supported = inp->ecn_supported;
+ n_inp->prsctp_supported = inp->prsctp_supported;
+ n_inp->auth_supported = inp->auth_supported;
+ n_inp->asconf_supported = inp->asconf_supported;
+ n_inp->reconfig_supported = inp->reconfig_supported;
+ n_inp->nrsack_supported = inp->nrsack_supported;
+ n_inp->pktdrop_supported = inp->pktdrop_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;
@@ -234,7 +240,13 @@ sctp_get_peeloff(struct socket *head, sctp_assoc_t assoc_id, int *error)
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->sctp_ecn_enable = inp->sctp_ecn_enable;
+ n_inp->ecn_supported = inp->ecn_supported;
+ n_inp->prsctp_supported = inp->prsctp_supported;
+ n_inp->auth_supported = inp->auth_supported;
+ n_inp->asconf_supported = inp->asconf_supported;
+ n_inp->reconfig_supported = inp->reconfig_supported;
+ n_inp->nrsack_supported = inp->nrsack_supported;
+ n_inp->pktdrop_supported = inp->pktdrop_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 f333ec8..7214d8d 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 255190 2013-09-03 19:31:59Z tuexen $");
+__FBSDID("$FreeBSD: head/sys/netinet/sctp_structs.h 269945 2014-08-13 15:50:16Z tuexen $");
#endif
#ifndef _NETINET_SCTP_STRUCTS_H_
@@ -636,6 +636,14 @@ struct sctp_stream_out {
struct sctp_streamhead outqueue;
union scheduling_parameters ss_params;
uint32_t chunks_on_queues;
+#if defined(SCTP_DETAILED_STR_STATS)
+ uint32_t abandoned_unsent[SCTP_PR_SCTP_MAX + 1];
+ uint32_t abandoned_sent[SCTP_PR_SCTP_MAX + 1];
+#else
+ /* Only the aggregation */
+ uint32_t abandoned_unsent[1];
+ uint32_t abandoned_sent[1];
+#endif
uint16_t stream_no;
uint16_t next_sequence_send; /* next one I expect to send out */
uint8_t last_msg_incomplete;
@@ -714,8 +722,8 @@ struct sctp_nonpad_sndrcvinfo {
struct sctp_cc_functions {
void (*sctp_set_initial_cc_param)(struct sctp_tcb *stcb, struct sctp_nets *net);
void (*sctp_cwnd_update_after_sack)(struct sctp_tcb *stcb,
- struct sctp_association *asoc,
- int accum_moved ,int reneged_all, int will_exit);
+ struct sctp_association *asoc,
+ int accum_moved ,int reneged_all, int will_exit);
void (*sctp_cwnd_update_exit_pf)(struct sctp_tcb *stcb, struct sctp_nets *net);
void (*sctp_cwnd_update_after_fr)(struct sctp_tcb *stcb,
struct sctp_association *asoc);
@@ -1200,30 +1208,21 @@ struct sctp_association {
* sum is updated as well.
*/
- /* Flag to tell if ECN is allowed */
- uint8_t ecn_allowed;
+ /* Flags whether an extension is supported or not */
+ uint8_t ecn_supported;
+ uint8_t prsctp_supported;
+ uint8_t auth_supported;
+ uint8_t asconf_supported;
+ uint8_t reconfig_supported;
+ uint8_t nrsack_supported;
+ uint8_t pktdrop_supported;
/* Did the peer make the stream config (add out) request */
uint8_t peer_req_out;
- /* flag to indicate if peer can do asconf */
- 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 */
- uint8_t peer_supports_strreset;
uint8_t local_strreset_support;
- uint8_t peer_supports_nat;
- /*
- * packet drop's are supported by the peer, we don't really care
- * about this but we bookkeep it anyway.
- */
- uint8_t peer_supports_pktdrop;
+ uint8_t peer_supports_nat;
struct sctp_scoping scope;
/* flags to handle send alternate net tracking */
@@ -1248,8 +1247,6 @@ struct sctp_association {
uint8_t sctp_cmt_on_off;
uint8_t iam_blocking;
uint8_t cookie_how[8];
- /* EY 05/05/08 - NR_SACK variable*/
- uint8_t sctp_nr_sack_on_off;
/* JRS 5/21/07 - CMT PF variable */
uint8_t sctp_cmt_pf;
uint8_t use_precise_time;
@@ -1272,6 +1269,8 @@ struct sctp_association {
uint32_t timoshutdownack;
struct timeval start_time;
struct timeval discontinuity_time;
+ uint64_t abandoned_unsent[SCTP_PR_SCTP_MAX + 1];
+ uint64_t abandoned_sent[SCTP_PR_SCTP_MAX + 1];
};
#endif
diff --git a/netinet/sctp_sysctl.c b/netinet/sctp_sysctl.c
index 21329f0..5b2a483 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 267674 2014-06-20 13:26:49Z tuexen $");
+__FBSDID("$FreeBSD: head/sys/netinet/sctp_sysctl.c 271221 2014-09-07 09:06:26Z tuexen $");
#endif
#include <netinet/sctp_os.h>
@@ -44,11 +44,16 @@ __FBSDID("$FreeBSD: head/sys/netinet/sctp_sysctl.c 267674 2014-06-20 13:26:49Z t
#include <netinet/sctp_output.h>
#ifdef __FreeBSD__
#include <sys/smp.h>
+#include <sys/sysctl.h>
#endif
#if defined(__APPLE__)
#include <netinet/sctp_bsd_addr.h>
#endif
+#ifdef __FreeBSD__
+FEATURE(sctp, "Stream Control Transmission Protocol");
+#endif
+
/*
* sysctl tunable variables
*/
@@ -61,6 +66,12 @@ 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_auth_enable) = SCTPCTL_AUTH_ENABLE_DEFAULT;
+ SCTP_BASE_SYSCTL(sctp_asconf_enable) = SCTPCTL_ASCONF_ENABLE_DEFAULT;
+ SCTP_BASE_SYSCTL(sctp_reconfig_enable) = SCTPCTL_RECONFIG_ENABLE_DEFAULT;
+ SCTP_BASE_SYSCTL(sctp_nrsack_enable) = SCTPCTL_NRSACK_ENABLE_DEFAULT;
+ SCTP_BASE_SYSCTL(sctp_pktdrop_enable) = SCTPCTL_PKTDROP_ENABLE_DEFAULT;
SCTP_BASE_SYSCTL(sctp_strict_sacks) = SCTPCTL_STRICT_SACKS_DEFAULT;
#if !(defined(__FreeBSD__) && __FreeBSD_version >= 800000)
#if !defined(SCTP_WITH_NO_CSUM)
@@ -96,12 +107,8 @@ sctp_init_sysctls()
SCTP_BASE_SYSCTL(sctp_nr_incoming_streams_default) = SCTPCTL_INCOMING_STREAMS_DEFAULT;
SCTP_BASE_SYSCTL(sctp_nr_outgoing_streams_default) = SCTPCTL_OUTGOING_STREAMS_DEFAULT;
SCTP_BASE_SYSCTL(sctp_cmt_on_off) = SCTPCTL_CMT_ON_OFF_DEFAULT;
- /* EY */
- SCTP_BASE_SYSCTL(sctp_nr_sack_on_off) = SCTPCTL_NR_SACK_ON_OFF_DEFAULT;
SCTP_BASE_SYSCTL(sctp_cmt_use_dac) = SCTPCTL_CMT_USE_DAC_DEFAULT;
SCTP_BASE_SYSCTL(sctp_use_cwnd_based_maxburst) = SCTPCTL_CWND_MAXBURST_DEFAULT;
- SCTP_BASE_SYSCTL(sctp_asconf_auth_nochk) = SCTPCTL_ASCONF_AUTH_NOCHK_DEFAULT;
- SCTP_BASE_SYSCTL(sctp_auth_disable) = SCTPCTL_AUTH_DISABLE_DEFAULT;
SCTP_BASE_SYSCTL(sctp_nat_friendly) = SCTPCTL_NAT_FRIENDLY_DEFAULT;
SCTP_BASE_SYSCTL(sctp_L2_abc_variable) = SCTPCTL_ABC_L_VAR_DEFAULT;
SCTP_BASE_SYSCTL(sctp_mbuf_threshold_count) = SCTPCTL_MAX_CHAINED_MBUFS_DEFAULT;
@@ -112,9 +119,7 @@ sctp_init_sysctls()
SCTP_BASE_SYSCTL(sctp_min_residual) = SCTPCTL_MIN_RESIDUAL_DEFAULT;
SCTP_BASE_SYSCTL(sctp_max_retran_chunk) = SCTPCTL_MAX_RETRAN_CHUNK_DEFAULT;
SCTP_BASE_SYSCTL(sctp_logging_level) = SCTPCTL_LOGGING_LEVEL_DEFAULT;
- /* JRS - Variable for default congestion control module */
SCTP_BASE_SYSCTL(sctp_default_cc_module) = SCTPCTL_DEFAULT_CC_MODULE_DEFAULT;
- /* RS - Variable for default stream scheduling module */
SCTP_BASE_SYSCTL(sctp_default_ss_module) = SCTPCTL_DEFAULT_SS_MODULE_DEFAULT;
SCTP_BASE_SYSCTL(sctp_default_frag_interleave) = SCTPCTL_DEFAULT_FRAG_INTERLEAVE_DEFAULT;
SCTP_BASE_SYSCTL(sctp_mobility_base) = SCTPCTL_MOBILITY_BASE_DEFAULT;
@@ -170,7 +175,7 @@ sctp_finish_sysctls()
#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__Windows__)
/* It returns an upper limit. No filtering is done here */
static unsigned int
-number_of_addresses(struct sctp_inpcb *inp)
+sctp_sysctl_number_of_addresses(struct sctp_inpcb *inp)
{
unsigned int cnt;
struct sctp_vrf *vrf;
@@ -220,7 +225,7 @@ number_of_addresses(struct sctp_inpcb *inp)
}
static int
-copy_out_local_addresses(struct sctp_inpcb *inp, struct sctp_tcb *stcb, struct sysctl_req *req)
+sctp_sysctl_copy_out_local_addresses(struct sctp_inpcb *inp, struct sctp_tcb *stcb, struct sysctl_req *req)
{
struct sctp_ifn *sctp_ifn;
struct sctp_ifa *sctp_ifa;
@@ -304,7 +309,7 @@ copy_out_local_addresses(struct sctp_inpcb *inp, struct sctp_tcb *stcb, struct s
if (ipv4_addr_legal) {
struct sockaddr_in *sin;
- sin = (struct sockaddr_in *)&sctp_ifa->address.sa;
+ sin = &sctp_ifa->address.sin;
if (sin->sin_addr.s_addr == 0)
continue;
#if defined(__FreeBSD__)
@@ -328,7 +333,7 @@ copy_out_local_addresses(struct sctp_inpcb *inp, struct sctp_tcb *stcb, struct s
#if defined(SCTP_EMBEDDED_V6_SCOPE) && !defined(SCTP_KAME)
struct sockaddr_in6 lsa6;
#endif
- sin6 = (struct sockaddr_in6 *)&sctp_ifa->address.sa;
+ sin6 = &sctp_ifa->address.sin6;
if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr))
continue;
#if defined(__FreeBSD__)
@@ -426,12 +431,12 @@ copy_out_local_addresses(struct sctp_inpcb *inp, struct sctp_tcb *stcb, struct s
*/
#if defined(__APPLE__)
static int
-sctp_assoclist SYSCTL_HANDLER_ARGS
+sctp_sysctl_handle_assoclist SYSCTL_HANDLER_ARGS
{
#pragma unused(oidp, arg1, arg2)
#else
static int
-sctp_assoclist(SYSCTL_HANDLER_ARGS)
+sctp_sysctl_handle_assoclist(SYSCTL_HANDLER_ARGS)
{
#endif
unsigned int number_of_endpoints;
@@ -454,18 +459,18 @@ sctp_assoclist(SYSCTL_HANDLER_ARGS)
number_of_remote_addresses = 0;
SCTP_INP_INFO_RLOCK();
-#if !defined(__Windows__)
+#if defined(__APPLE__)
if (req->oldptr == USER_ADDR_NULL) {
#else
- if (req->data == NULL) {
+ if (req->oldptr == NULL) {
#endif
LIST_FOREACH(inp, &SCTP_BASE_INFO(listhead), sctp_list) {
SCTP_INP_RLOCK(inp);
number_of_endpoints++;
- number_of_local_addresses += number_of_addresses(inp);
+ number_of_local_addresses += sctp_sysctl_number_of_addresses(inp);
LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) {
number_of_associations++;
- number_of_local_addresses += number_of_addresses(inp);
+ number_of_local_addresses += sctp_sysctl_number_of_addresses(inp);
TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
number_of_remote_addresses++;
}
@@ -486,10 +491,10 @@ sctp_assoclist(SYSCTL_HANDLER_ARGS)
#endif
return (0);
}
-#if !defined(__Windows__)
+#if defined(__APPLE__)
if (req->newptr != USER_ADDR_NULL) {
#else
- if (req->new_data != NULL) {
+ if (req->newptr != NULL) {
#endif
SCTP_INP_INFO_RUNLOCK();
SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTP_SYSCTL, EPERM);
@@ -532,7 +537,7 @@ sctp_assoclist(SYSCTL_HANDLER_ARGS)
}
SCTP_INP_INFO_RLOCK();
SCTP_INP_RLOCK(inp);
- error = copy_out_local_addresses(inp, NULL, req);
+ error = sctp_sysctl_copy_out_local_addresses(inp, NULL, req);
if (error) {
SCTP_INP_DECR_REF(inp);
return (error);
@@ -589,7 +594,7 @@ sctp_assoclist(SYSCTL_HANDLER_ARGS)
}
SCTP_INP_INFO_RLOCK();
SCTP_INP_RLOCK(inp);
- error = copy_out_local_addresses(inp, stcb, req);
+ error = sctp_sysctl_copy_out_local_addresses(inp, stcb, req);
if (error) {
SCTP_INP_DECR_REF(inp);
atomic_subtract_int(&stcb->asoc.refcnt, 1);
@@ -664,57 +669,59 @@ skip:
return (error);
}
-
-#if !defined(__Windows__)
-#define RANGECHK(var, min, max) \
- if ((var) < (min)) { (var) = (min); } \
- else if ((var) > (max)) { (var) = (max); }
-#else
-#define RANGECHK(var, min, max) \
- if ((var) <= (min)) { (var) = (min); } \
- else if ((var) >= (max)) { (var) = (max); }
-#endif
-
#if defined(__APPLE__)
static int
-sysctl_sctp_udp_tunneling_check SYSCTL_HANDLER_ARGS
+sctp_sysctl_handle_udp_tunneling SYSCTL_HANDLER_ARGS
{
#pragma unused(arg1, arg2)
#else
static int
-sysctl_sctp_udp_tunneling_check(SYSCTL_HANDLER_ARGS)
+sctp_sysctl_handle_udp_tunneling(SYSCTL_HANDLER_ARGS)
{
#endif
int error;
- uint32_t old_sctp_udp_tunneling_port;
+ uint32_t old, new;
SCTP_INP_INFO_RLOCK();
- old_sctp_udp_tunneling_port = SCTP_BASE_SYSCTL(sctp_udp_tunneling_port);
+ old = SCTP_BASE_SYSCTL(sctp_udp_tunneling_port);
SCTP_INP_INFO_RUNLOCK();
- error = sysctl_handle_int(oidp, oidp->oid_arg1, oidp->oid_arg2, req);
- if (error == 0) {
- RANGECHK(SCTP_BASE_SYSCTL(sctp_udp_tunneling_port), SCTPCTL_UDP_TUNNELING_PORT_MIN, SCTPCTL_UDP_TUNNELING_PORT_MAX);
-#if !defined(__Windows__)
- if (old_sctp_udp_tunneling_port == SCTP_BASE_SYSCTL(sctp_udp_tunneling_port)) {
- error = 0;
- goto out;
- }
- SCTP_INP_INFO_WLOCK();
- if (old_sctp_udp_tunneling_port) {
- sctp_over_udp_stop();
- }
- if (SCTP_BASE_SYSCTL(sctp_udp_tunneling_port)) {
- if (sctp_over_udp_start()) {
- SCTP_BASE_SYSCTL(sctp_udp_tunneling_port) = 0;
- }
- }
+ new = old;
+#if defined(__FreeBSD__) && __FreeBSD_version >= 800056 && __FreeBSD_version < 1000100
+#ifdef VIMAGE
+ error = vnet_sysctl_handle_int(oidp, &new, 0, req);
+#else
+ error = sysctl_handle_int(oidp, &new, 0, req);
+#endif
+#else
+ error = sysctl_handle_int(oidp, &new, 0, req);
+#endif
+ if ((error == 0) &&
+#if defined (__APPLE__)
+ (req->newptr != USER_ADDR_NULL)) {
#else
+ (req->newptr != NULL)) {
+#endif
+#if defined(__Windows__)
SCTP_INP_INFO_WLOCK();
sctp_over_udp_restart();
-#endif
SCTP_INP_INFO_WUNLOCK();
+#else
+ if ((new < SCTPCTL_UDP_TUNNELING_PORT_MIN) ||
+ (new > SCTPCTL_UDP_TUNNELING_PORT_MAX)) {
+ error = EINVAL;
+ } else {
+ SCTP_INP_INFO_WLOCK();
+ SCTP_BASE_SYSCTL(sctp_udp_tunneling_port) = new;
+ if (old != 0) {
+ sctp_over_udp_stop();
+ }
+ if (new != 0) {
+ error = sctp_over_udp_start();
+ }
+ SCTP_INP_INFO_WUNLOCK();
+ }
+#endif
}
-out:
return (error);
}
@@ -722,21 +729,29 @@ out:
int sctp_is_vmware_interface(struct ifnet *);
static int
-sysctl_sctp_vmware_interfaces_check SYSCTL_HANDLER_ARGS
+sctp_sysctl_handle_vmware_interfaces SYSCTL_HANDLER_ARGS
{
#pragma unused(arg1, arg2)
int error;
- uint32_t old_sctp_ignore_vmware_interfaces;
-
- old_sctp_ignore_vmware_interfaces = SCTP_BASE_SYSCTL(sctp_ignore_vmware_interfaces);
- error = sysctl_handle_int(oidp, oidp->oid_arg1, oidp->oid_arg2, req);
- if (error == 0) {
- RANGECHK(SCTP_BASE_SYSCTL(sctp_ignore_vmware_interfaces), SCTPCTL_IGNORE_VMWARE_INTERFACES_MIN, SCTPCTL_IGNORE_VMWARE_INTERFACES_MAX);
- if (old_sctp_ignore_vmware_interfaces && !SCTP_BASE_SYSCTL(sctp_ignore_vmware_interfaces)) {
- sctp_add_or_del_interfaces(sctp_is_vmware_interface, 1);
- }
- if (!old_sctp_ignore_vmware_interfaces && SCTP_BASE_SYSCTL(sctp_ignore_vmware_interfaces)) {
- sctp_add_or_del_interfaces(sctp_is_vmware_interface, 0);
+ uint32_t old, new;
+
+ old = SCTP_BASE_SYSCTL(sctp_ignore_vmware_interfaces);
+ new = old;
+ error = sysctl_handle_int(oidp, &new, 0, req);
+ if ((error == 0) && (req->newptr != USER_ADDR_NULL)) {
+ if ((new < SCTPCTL_IGNORE_VMWARE_INTERFACES_MIN) ||
+ (new > SCTPCTL_IGNORE_VMWARE_INTERFACES_MAX)) {
+ error = EINVAL;
+ } else {
+ if ((old == 1) && (new == 0)) {
+ sctp_add_or_del_interfaces(sctp_is_vmware_interface, 1);
+ }
+ if ((old == 0) && (new == 1)) {
+ sctp_add_or_del_interfaces(sctp_is_vmware_interface, 0);
+ }
+ if (old != new) {
+ SCTP_BASE_SYSCTL(sctp_ignore_vmware_interfaces) = new;
+ }
}
}
return (error);
@@ -745,143 +760,113 @@ sysctl_sctp_vmware_interfaces_check SYSCTL_HANDLER_ARGS
#if defined(__APPLE__)
static int
-sysctl_sctp_check SYSCTL_HANDLER_ARGS
+sctp_sysctl_handle_auth SYSCTL_HANDLER_ARGS
{
#pragma unused(arg1, arg2)
#else
static int
-sysctl_sctp_check(SYSCTL_HANDLER_ARGS)
+sctp_sysctl_handle_auth(SYSCTL_HANDLER_ARGS)
{
#endif
int error;
+ uint32_t new;
+ new = SCTP_BASE_SYSCTL(sctp_auth_enable);
#if defined(__FreeBSD__) && __FreeBSD_version >= 800056 && __FreeBSD_version < 1000100
#ifdef VIMAGE
- error = vnet_sysctl_handle_int(oidp, oidp->oid_arg1, oidp->oid_arg2, req);
+ error = vnet_sysctl_handle_int(oidp, &new, 0, req);
#else
- error = sysctl_handle_int(oidp, oidp->oid_arg1, oidp->oid_arg2, req);
+ error = sysctl_handle_int(oidp, &new, 0, req);
#endif
#else
- error = sysctl_handle_int(oidp, oidp->oid_arg1, oidp->oid_arg2, req);
-#endif
- if (error == 0) {
- RANGECHK(SCTP_BASE_SYSCTL(sctp_sendspace), SCTPCTL_MAXDGRAM_MIN, SCTPCTL_MAXDGRAM_MAX);
- RANGECHK(SCTP_BASE_SYSCTL(sctp_recvspace), SCTPCTL_RECVSPACE_MIN, SCTPCTL_RECVSPACE_MAX);
-#if defined(__FreeBSD__)
- RANGECHK(SCTP_BASE_SYSCTL(sctp_auto_asconf), SCTPCTL_AUTOASCONF_MIN, SCTPCTL_AUTOASCONF_MAX);
-#elif defined(SCTP_APPLE_AUTO_ASCONF)
- 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_strict_sacks), SCTPCTL_STRICT_SACKS_MIN, SCTPCTL_STRICT_SACKS_MAX);
-#if !(defined(__FreeBSD__) && __FreeBSD_version >= 800000)
-#if !defined(SCTP_WITH_NO_CSUM)
- RANGECHK(SCTP_BASE_SYSCTL(sctp_no_csum_on_loopback), SCTPCTL_LOOPBACK_NOCSUM_MIN, SCTPCTL_LOOPBACK_NOCSUM_MAX);
-#endif
+ error = sysctl_handle_int(oidp, &new, 0, req);
#endif
- RANGECHK(SCTP_BASE_SYSCTL(sctp_peer_chunk_oh), SCTPCTL_PEER_CHKOH_MIN, SCTPCTL_PEER_CHKOH_MAX);
- RANGECHK(SCTP_BASE_SYSCTL(sctp_max_burst_default), SCTPCTL_MAXBURST_MIN, SCTPCTL_MAXBURST_MAX);
- RANGECHK(SCTP_BASE_SYSCTL(sctp_fr_max_burst_default), SCTPCTL_FRMAXBURST_MIN, SCTPCTL_FRMAXBURST_MAX);
- RANGECHK(SCTP_BASE_SYSCTL(sctp_max_chunks_on_queue), SCTPCTL_MAXCHUNKS_MIN, SCTPCTL_MAXCHUNKS_MAX);
- RANGECHK(SCTP_BASE_SYSCTL(sctp_hashtblsize), SCTPCTL_TCBHASHSIZE_MIN, SCTPCTL_TCBHASHSIZE_MAX);
- RANGECHK(SCTP_BASE_SYSCTL(sctp_pcbtblsize), SCTPCTL_PCBHASHSIZE_MIN, SCTPCTL_PCBHASHSIZE_MAX);
- RANGECHK(SCTP_BASE_SYSCTL(sctp_min_split_point), SCTPCTL_MIN_SPLIT_POINT_MIN, SCTPCTL_MIN_SPLIT_POINT_MAX);
- RANGECHK(SCTP_BASE_SYSCTL(sctp_chunkscale), SCTPCTL_CHUNKSCALE_MIN, SCTPCTL_CHUNKSCALE_MAX);
- RANGECHK(SCTP_BASE_SYSCTL(sctp_delayed_sack_time_default), SCTPCTL_DELAYED_SACK_TIME_MIN, SCTPCTL_DELAYED_SACK_TIME_MAX);
- RANGECHK(SCTP_BASE_SYSCTL(sctp_sack_freq_default), SCTPCTL_SACK_FREQ_MIN, SCTPCTL_SACK_FREQ_MAX);
- RANGECHK(SCTP_BASE_SYSCTL(sctp_system_free_resc_limit), SCTPCTL_SYS_RESOURCE_MIN, SCTPCTL_SYS_RESOURCE_MAX);
- RANGECHK(SCTP_BASE_SYSCTL(sctp_asoc_free_resc_limit), SCTPCTL_ASOC_RESOURCE_MIN, SCTPCTL_ASOC_RESOURCE_MAX);
- RANGECHK(SCTP_BASE_SYSCTL(sctp_heartbeat_interval_default), SCTPCTL_HEARTBEAT_INTERVAL_MIN, SCTPCTL_HEARTBEAT_INTERVAL_MAX);
- RANGECHK(SCTP_BASE_SYSCTL(sctp_pmtu_raise_time_default), SCTPCTL_PMTU_RAISE_TIME_MIN, SCTPCTL_PMTU_RAISE_TIME_MAX);
- RANGECHK(SCTP_BASE_SYSCTL(sctp_shutdown_guard_time_default), SCTPCTL_SHUTDOWN_GUARD_TIME_MIN, SCTPCTL_SHUTDOWN_GUARD_TIME_MAX);
- RANGECHK(SCTP_BASE_SYSCTL(sctp_secret_lifetime_default), SCTPCTL_SECRET_LIFETIME_MIN, SCTPCTL_SECRET_LIFETIME_MAX);
- RANGECHK(SCTP_BASE_SYSCTL(sctp_rto_max_default), SCTPCTL_RTO_MAX_MIN, SCTPCTL_RTO_MAX_MAX);
- RANGECHK(SCTP_BASE_SYSCTL(sctp_rto_min_default), SCTPCTL_RTO_MIN_MIN, SCTPCTL_RTO_MIN_MAX);
- RANGECHK(SCTP_BASE_SYSCTL(sctp_rto_initial_default), SCTPCTL_RTO_INITIAL_MIN, SCTPCTL_RTO_INITIAL_MAX);
- RANGECHK(SCTP_BASE_SYSCTL(sctp_init_rto_max_default), SCTPCTL_INIT_RTO_MAX_MIN, SCTPCTL_INIT_RTO_MAX_MAX);
- RANGECHK(SCTP_BASE_SYSCTL(sctp_valid_cookie_life_default), SCTPCTL_VALID_COOKIE_LIFE_MIN, SCTPCTL_VALID_COOKIE_LIFE_MAX);
- RANGECHK(SCTP_BASE_SYSCTL(sctp_init_rtx_max_default), SCTPCTL_INIT_RTX_MAX_MIN, SCTPCTL_INIT_RTX_MAX_MAX);
- RANGECHK(SCTP_BASE_SYSCTL(sctp_assoc_rtx_max_default), SCTPCTL_ASSOC_RTX_MAX_MIN, SCTPCTL_ASSOC_RTX_MAX_MAX);
- RANGECHK(SCTP_BASE_SYSCTL(sctp_path_rtx_max_default), SCTPCTL_PATH_RTX_MAX_MIN, SCTPCTL_PATH_RTX_MAX_MAX);
- RANGECHK(SCTP_BASE_SYSCTL(sctp_path_pf_threshold), SCTPCTL_PATH_PF_THRESHOLD_MIN, SCTPCTL_PATH_PF_THRESHOLD_MAX);
- RANGECHK(SCTP_BASE_SYSCTL(sctp_add_more_threshold), SCTPCTL_ADD_MORE_ON_OUTPUT_MIN, SCTPCTL_ADD_MORE_ON_OUTPUT_MAX);
- RANGECHK(SCTP_BASE_SYSCTL(sctp_nr_incoming_streams_default), SCTPCTL_INCOMING_STREAMS_MIN, SCTPCTL_INCOMING_STREAMS_MAX);
- RANGECHK(SCTP_BASE_SYSCTL(sctp_nr_outgoing_streams_default), SCTPCTL_OUTGOING_STREAMS_MIN, SCTPCTL_OUTGOING_STREAMS_MAX);
- RANGECHK(SCTP_BASE_SYSCTL(sctp_cmt_on_off), SCTPCTL_CMT_ON_OFF_MIN, SCTPCTL_CMT_ON_OFF_MAX);
- /* EY */
- RANGECHK(SCTP_BASE_SYSCTL(sctp_nr_sack_on_off), SCTPCTL_NR_SACK_ON_OFF_MIN, SCTPCTL_NR_SACK_ON_OFF_MAX);
- RANGECHK(SCTP_BASE_SYSCTL(sctp_cmt_use_dac), SCTPCTL_CMT_USE_DAC_MIN, SCTPCTL_CMT_USE_DAC_MAX);
- RANGECHK(SCTP_BASE_SYSCTL(sctp_use_cwnd_based_maxburst), SCTPCTL_CWND_MAXBURST_MIN, SCTPCTL_CWND_MAXBURST_MAX);
- RANGECHK(SCTP_BASE_SYSCTL(sctp_asconf_auth_nochk), SCTPCTL_ASCONF_AUTH_NOCHK_MIN, SCTPCTL_ASCONF_AUTH_NOCHK_MAX);
- RANGECHK(SCTP_BASE_SYSCTL(sctp_auth_disable), SCTPCTL_AUTH_DISABLE_MIN, SCTPCTL_AUTH_DISABLE_MAX);
- RANGECHK(SCTP_BASE_SYSCTL(sctp_nat_friendly), SCTPCTL_NAT_FRIENDLY_MIN, SCTPCTL_NAT_FRIENDLY_MAX);
- RANGECHK(SCTP_BASE_SYSCTL(sctp_L2_abc_variable), SCTPCTL_ABC_L_VAR_MIN, SCTPCTL_ABC_L_VAR_MAX);
- RANGECHK(SCTP_BASE_SYSCTL(sctp_mbuf_threshold_count), SCTPCTL_MAX_CHAINED_MBUFS_MIN, SCTPCTL_MAX_CHAINED_MBUFS_MAX);
- RANGECHK(SCTP_BASE_SYSCTL(sctp_do_drain), SCTPCTL_DO_SCTP_DRAIN_MIN, SCTPCTL_DO_SCTP_DRAIN_MAX);
- RANGECHK(SCTP_BASE_SYSCTL(sctp_hb_maxburst), SCTPCTL_HB_MAX_BURST_MIN, SCTPCTL_HB_MAX_BURST_MAX);
- RANGECHK(SCTP_BASE_SYSCTL(sctp_abort_if_one_2_one_hits_limit), SCTPCTL_ABORT_AT_LIMIT_MIN, SCTPCTL_ABORT_AT_LIMIT_MAX);
- RANGECHK(SCTP_BASE_SYSCTL(sctp_strict_data_order), SCTPCTL_STRICT_DATA_ORDER_MIN, SCTPCTL_STRICT_DATA_ORDER_MAX);
- RANGECHK(SCTP_BASE_SYSCTL(sctp_min_residual), SCTPCTL_MIN_RESIDUAL_MIN, SCTPCTL_MIN_RESIDUAL_MAX);
- RANGECHK(SCTP_BASE_SYSCTL(sctp_max_retran_chunk), SCTPCTL_MAX_RETRAN_CHUNK_MIN, SCTPCTL_MAX_RETRAN_CHUNK_MAX);
- RANGECHK(SCTP_BASE_SYSCTL(sctp_logging_level), SCTPCTL_LOGGING_LEVEL_MIN, SCTPCTL_LOGGING_LEVEL_MAX);
- RANGECHK(SCTP_BASE_SYSCTL(sctp_default_cc_module), SCTPCTL_DEFAULT_CC_MODULE_MIN, SCTPCTL_DEFAULT_CC_MODULE_MAX);
- RANGECHK(SCTP_BASE_SYSCTL(sctp_default_ss_module), SCTPCTL_DEFAULT_SS_MODULE_MIN, SCTPCTL_DEFAULT_SS_MODULE_MAX);
- RANGECHK(SCTP_BASE_SYSCTL(sctp_default_frag_interleave), SCTPCTL_DEFAULT_FRAG_INTERLEAVE_MIN, SCTPCTL_DEFAULT_FRAG_INTERLEAVE_MAX);
- RANGECHK(SCTP_BASE_SYSCTL(sctp_vtag_time_wait), SCTPCTL_TIME_WAIT_MIN, SCTPCTL_TIME_WAIT_MAX);
- RANGECHK(SCTP_BASE_SYSCTL(sctp_buffer_splitting), SCTPCTL_BUFFER_SPLITTING_MIN, SCTPCTL_BUFFER_SPLITTING_MAX);
- RANGECHK(SCTP_BASE_SYSCTL(sctp_initial_cwnd), SCTPCTL_INITIAL_CWND_MIN, SCTPCTL_INITIAL_CWND_MAX);
- RANGECHK(SCTP_BASE_SYSCTL(sctp_rttvar_bw), SCTPCTL_RTTVAR_BW_MIN, SCTPCTL_RTTVAR_BW_MAX);
- RANGECHK(SCTP_BASE_SYSCTL(sctp_rttvar_rtt), SCTPCTL_RTTVAR_RTT_MIN, SCTPCTL_RTTVAR_RTT_MAX);
- RANGECHK(SCTP_BASE_SYSCTL(sctp_rttvar_eqret), SCTPCTL_RTTVAR_EQRET_MIN, SCTPCTL_RTTVAR_EQRET_MAX);
- RANGECHK(SCTP_BASE_SYSCTL(sctp_steady_step), SCTPCTL_RTTVAR_STEADYS_MIN, SCTPCTL_RTTVAR_STEADYS_MAX);
- RANGECHK(SCTP_BASE_SYSCTL(sctp_use_dccc_ecn), SCTPCTL_RTTVAR_DCCCECN_MIN, SCTPCTL_RTTVAR_DCCCECN_MAX);
-#if defined(__FreeBSD__)
- RANGECHK(SCTP_BASE_SYSCTL(sctp_mobility_base), SCTPCTL_MOBILITY_BASE_MIN, SCTPCTL_MOBILITY_BASE_MAX);
-#elif defined(SCTP_APPLE_MOBILITY_BASE)
- RANGECHK(SCTP_BASE_SYSCTL(sctp_mobility_base), SCTPCTL_MOBILITY_BASE_MIN, SCTPCTL_MOBILITY_BASE_MAX);
+ if ((error == 0) &&
+#if defined (__APPLE__)
+ (req->newptr != USER_ADDR_NULL)) {
+#else
+ (req->newptr != NULL)) {
#endif
-#if defined(__FreeBSD__)
- RANGECHK(SCTP_BASE_SYSCTL(sctp_mobility_fasthandoff), SCTPCTL_MOBILITY_FASTHANDOFF_MIN, SCTPCTL_MOBILITY_FASTHANDOFF_MAX);
-#elif defined(__FreeBSD__) || defined(SCTP_APPLE_MOBILITY_FASTHANDOFF)
- RANGECHK(SCTP_BASE_SYSCTL(sctp_mobility_fasthandoff), SCTPCTL_MOBILITY_FASTHANDOFF_MIN, SCTPCTL_MOBILITY_FASTHANDOFF_MAX);
+ if ((new < SCTPCTL_AUTH_ENABLE_MIN) ||
+ (new > SCTPCTL_AUTH_ENABLE_MAX) ||
+ ((new == 0) && (SCTP_BASE_SYSCTL(sctp_asconf_enable) == 1))) {
+ error = EINVAL;
+ } else {
+ SCTP_BASE_SYSCTL(sctp_auth_enable) = new;
+ }
+ }
+ return (error);
+}
+
+#if defined(__APPLE__)
+static int
+sctp_sysctl_handle_asconf SYSCTL_HANDLER_ARGS
+{
+#pragma unused(arg1, arg2)
+#else
+static int
+sctp_sysctl_handle_asconf(SYSCTL_HANDLER_ARGS)
+{
#endif
- RANGECHK(SCTP_BASE_SYSCTL(sctp_enable_sack_immediately), SCTPCTL_SACK_IMMEDIATELY_ENABLE_MIN, SCTPCTL_SACK_IMMEDIATELY_ENABLE_MAX);
- RANGECHK(SCTP_BASE_SYSCTL(sctp_inits_include_nat_friendly), SCTPCTL_NAT_FRIENDLY_INITS_MIN, SCTPCTL_NAT_FRIENDLY_INITS_MAX);
- RANGECHK(SCTP_BASE_SYSCTL(sctp_blackhole), SCTPCTL_BLACKHOLE_MIN, SCTPCTL_BLACKHOLE_MAX);
- RANGECHK(SCTP_BASE_SYSCTL(sctp_diag_info_code), SCTPCTL_DIAG_INFO_CODE_MIN, SCTPCTL_DIAG_INFO_CODE_MAX);
+ int error;
+ uint32_t new;
-#ifdef SCTP_DEBUG
- RANGECHK(SCTP_BASE_SYSCTL(sctp_debug_on), SCTPCTL_DEBUG_MIN, SCTPCTL_DEBUG_MAX);
+ new = SCTP_BASE_SYSCTL(sctp_asconf_enable);
+#if defined(__FreeBSD__) && __FreeBSD_version >= 800056 && __FreeBSD_version < 1000100
+#ifdef VIMAGE
+ error = vnet_sysctl_handle_int(oidp, &new, 0, req);
+#else
+ error = sysctl_handle_int(oidp, &new, 0, req);
#endif
-#if defined(__APPLE__)
- RANGECHK(SCTP_BASE_SYSCTL(sctp_main_timer), SCTPCTL_MAIN_TIMER_MIN, SCTPCTL_MAIN_TIMER_MAX);
- RANGECHK(SCTP_BASE_SYSCTL(sctp_addr_watchdog_limit), SCTPCTL_ADDR_WATCHDOG_LIMIT_MIN, SCTPCTL_ADDR_WATCHDOG_LIMIT_MAX);
- RANGECHK(SCTP_BASE_SYSCTL(sctp_vtag_watchdog_limit), SCTPCTL_VTAG_WATCHDOG_LIMIT_MIN, SCTPCTL_VTAG_WATCHDOG_LIMIT_MAX);
+#else
+ error = sysctl_handle_int(oidp, &new, 0, req);
#endif
-#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
- RANGECHK(SCTP_BASE_SYSCTL(sctp_output_unlocked), SCTPCTL_OUTPUT_UNLOCKED_MIN, SCTPCTL_OUTPUT_UNLOCKED_MAX);
+ if ((error == 0) &&
+#if defined (__APPLE__)
+ (req->newptr != USER_ADDR_NULL)) {
+#else
+ (req->newptr != NULL)) {
#endif
+ if ((new < SCTPCTL_ASCONF_ENABLE_MIN) ||
+ (new > SCTPCTL_ASCONF_ENABLE_MAX) ||
+ ((new == 1) && (SCTP_BASE_SYSCTL(sctp_auth_enable) == 0))) {
+ error = EINVAL;
+ } else {
+ SCTP_BASE_SYSCTL(sctp_asconf_enable) = new;
+ }
}
return (error);
}
-#if defined(__FreeBSD__) && defined(SMP) && defined(SCTP_USE_PERCPU_STAT)
+#if defined(__APPLE__)
+static int
+sctp_sysctl_handle_stats SYSCTL_HANDLER_ARGS
+{
+#pragma unused(oidp, arg1, arg2)
+#else
static int
-sysctl_stat_get(SYSCTL_HANDLER_ARGS)
+sctp_sysctl_handle_stats(SYSCTL_HANDLER_ARGS)
{
- int cpu, error;
- struct sctpstat sb, *sarry, *cpin = NULL;
-
- if ((req->newptr) && (req->newlen == sizeof(struct sctpstat))) {
- /* User wants us to clear or at least
- * reset the counters to the specified values.
- */
- cpin = (struct sctpstat *)req->newptr;
- } else if (req->newptr) {
- /* Must be a stat structure */
+#endif
+ int error;
+#if defined(__FreeBSD__)
+#if defined(SMP) && defined(SCTP_USE_PERCPU_STAT)
+ int cpu;
+ struct sctpstat sb, *sarry;
+#endif
+#endif
+
+#if defined (__APPLE__)
+ if ((req->newptr != USER_ADDR_NULL) &&
+#else
+ if ((req->newptr != NULL) &&
+#endif
+ (req->newlen != sizeof(struct sctpstat))) {
return (EINVAL);
}
- memset(&sb, 0, sizeof(sb));
+#if defined(__FreeBSD__)
+#if defined(SMP) && defined(SCTP_USE_PERCPU_STAT)
+ memset(&sb, 0, sizeof(struct sctpstat));
for (cpu = 0; cpu < mp_maxid; cpu++) {
sarry = &SCTP_BASE_STATS[cpu];
if (sarry->sctps_discontinuitytime.tv_sec > sb.sctps_discontinuitytime.tv_sec) {
@@ -1009,24 +994,49 @@ sysctl_stat_get(SYSCTL_HANDLER_ARGS)
sb.sctps_send_burst_avoid += sarry->sctps_send_burst_avoid;
sb.sctps_send_cwnd_avoid += sarry->sctps_send_cwnd_avoid;
sb.sctps_fwdtsn_map_over += sarry->sctps_fwdtsn_map_over;
- if (cpin) {
- memcpy(sarry, cpin, sizeof(struct sctpstat));
+ if (req->newptr != NULL) {
+ memcpy(sarry, req->newptr, sizeof(struct sctpstat));
}
}
- error = SYSCTL_OUT(req, &sb, sizeof(sb));
+ error = SYSCTL_OUT(req, &sb, sizeof(struct sctpstat));
+#else
+ error = SYSCTL_OUT(req, &SCTP_BASE_STATS, sizeof(struct sctpstat));
+#endif
+#else
+ error = SYSCTL_OUT(req, &SCTP_BASE_STATS, sizeof(struct sctpstat));
+#endif
return (error);
}
-#endif
#if defined(SCTP_LOCAL_TRACE_BUF)
#if defined(__APPLE__)
static int
-sysctl_sctp_cleartrace SYSCTL_HANDLER_ARGS
+sctp_sysctl_handle_trace_log SYSCTL_HANDLER_ARGS
+{
+#pragma unused(arg1, arg2, oidp)
+#else
+static int
+sctp_sysctl_handle_trace_log(SYSCTL_HANDLER_ARGS)
+{
+#endif
+ int error;
+
+#if defined(__Windows__)
+ error = SYSCTL_OUT(req, SCTP_BASE_SYSCTL(sctp_log), sizeof(struct sctp_log));
+#else
+ error = SYSCTL_OUT(req, &SCTP_BASE_SYSCTL(sctp_log), sizeof(struct sctp_log));
+#endif
+ return (error);
+}
+
+#if defined(__APPLE__)
+static int
+sctp_sysctl_handle_trace_log_clear SYSCTL_HANDLER_ARGS
{
#pragma unused(arg1, arg2, req, oidp)
#else
static int
-sysctl_sctp_cleartrace(SYSCTL_HANDLER_ARGS)
+sctp_sysctl_handle_trace_log_clear(SYSCTL_HANDLER_ARGS)
{
#endif
int error = 0;
@@ -1048,591 +1058,542 @@ sysctl_sctp_cleartrace(SYSCTL_HANDLER_ARGS)
}
#endif
-
#if defined(__APPLE__) || defined(__FreeBSD__)
-#if defined(__APPLE__)
+#if defined(__FreeBSD__)
+#if __FreeBSD_version >= 800056 && __FreeBSD_version < 1000100
+#ifdef VIMAGE
+#define SCTP_UINT_SYSCTL(name, var_name, prefix) \
+ static int \
+ sctp_sysctl_handle_##mib_name(SYSCTL_HANDLER_ARGS) \
+ { \
+ int error; \
+ uint32_t new; \
+ \
+ new = SCTP_BASE_SYSCTL(var_name); \
+ error = vnet_sysctl_handle_int(oidp, &new, 0, req); \
+ if ((error == 0) && (req->newptr != NULL)) { \
+ if ((new < prefix##_MIN) || \
+ (new > prefix##_MAX)) { \
+ error = EINVAL; \
+ } else { \
+ SCTP_BASE_SYSCTL(var_name) = new; \
+ } \
+ } \
+ return (error); \
+ } \
+ SYSCTL_PROC(_net_inet_sctp, OID_AUTO, mib_name, \
+ CTLTYPE_UINT|CTLFLAG_RW, NULL, 0, \
+ sctp_sysctl_handle_##mib_name, "UI", prefix##_DESC);
+#else
+#define SCTP_UINT_SYSCTL(mib_name, var_name, prefix) \
+ static int \
+ sctp_sysctl_handle_##mib_name(SYSCTL_HANDLER_ARGS) \
+ { \
+ int error; \
+ uint32_t new; \
+ \
+ new = SCTP_BASE_SYSCTL(var_name); \
+ error = sysctl_handle_int(oidp, &new, 0, req); \
+ if ((error == 0) && (req->newptr != NULL)) { \
+ if ((new < prefix##_MIN) || \
+ (new > prefix##_MAX)) { \
+ error = EINVAL; \
+ } else { \
+ SCTP_BASE_SYSCTL(var_name) = new; \
+ } \
+ } \
+ return (error); \
+ } \
+ SYSCTL_PROC(_net_inet_sctp, OID_AUTO, mib_name, \
+ CTLFLAG_VNET|CTLTYPE_UINT|CTLFLAG_RW, NULL, 0, \
+ sctp_sysctl_handle_##mib_name, "UI", prefix##_DESC);
+#endif
+#else
+#define SCTP_UINT_SYSCTL(mib_name, var_name, prefix) \
+ static int \
+ sctp_sysctl_handle_##mib_name(SYSCTL_HANDLER_ARGS) \
+ { \
+ int error; \
+ uint32_t new; \
+ \
+ new = SCTP_BASE_SYSCTL(var_name); \
+ error = sysctl_handle_int(oidp, &new, 0, req); \
+ if ((error == 0) && (req->newptr != NULL)) { \
+ if ((new < prefix##_MIN) || \
+ (new > prefix##_MAX)) { \
+ error = EINVAL; \
+ } else { \
+ SCTP_BASE_SYSCTL(var_name) = new; \
+ } \
+ } \
+ return (error); \
+ } \
+ SYSCTL_PROC(_net_inet_sctp, OID_AUTO, mib_name, \
+ CTLFLAG_VNET|CTLTYPE_UINT|CTLFLAG_RW, NULL, 0, \
+ sctp_sysctl_handle_##mib_name, "UI", prefix##_DESC);
+#endif
+#else
+#define SCTP_UINT_SYSCTL(mib_name, var_name, prefix) \
+ static int \
+ sctp_sysctl_handle_##mib_name(struct sysctl_oid *oidp, \
+ void *arg1 __attribute__((unused)), \
+ int arg2 __attribute__((unused)), \
+ struct sysctl_req *req) \
+ { \
+ int error; \
+ uint32_t new; \
+ \
+ new = SCTP_BASE_SYSCTL(var_name); \
+ error = sysctl_handle_int(oidp, &new, 0, req); \
+ if ((error == 0) && (req->newptr != USER_ADDR_NULL)) { \
+ if ((new < prefix##_MIN) || \
+ (new > prefix##_MAX)) { \
+ error = EINVAL; \
+ } else { \
+ SCTP_BASE_SYSCTL(var_name) = new; \
+ } \
+ } \
+ return (error); \
+ } \
+ SYSCTL_PROC(_net_inet_sctp, OID_AUTO, mib_name, \
+ CTLTYPE_INT | CTLFLAG_RW, NULL, 0, \
+ sctp_sysctl_handle_##mib_name, "I", prefix##_DESC);
#define CTLTYPE_UINT CTLTYPE_INT
-#define SYSCTL_VNET_PROC(parent, nbr, name, access, ptr, arg, handler, fmt, descr) \
- SYSCTL_PROC(parent, nbr, name, access, ptr, arg, handler, fmt, descr)
-#define SYSCTL_VNET_STRUCT(parent, nbr, name, access, ptr, type, descr) \
- SYSCTL_STRUCT(parent, nbr, name, access, ptr, type, descr)
+#define CTLFLAG_VNET 0
#endif
+
/*
* sysctl definitions
*/
-SYSCTL_VNET_PROC(_net_inet_sctp, OID_AUTO, sendspace, CTLTYPE_UINT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_sendspace), 0, sysctl_sctp_check, "IU",
- SCTPCTL_MAXDGRAM_DESC);
-
-SYSCTL_VNET_PROC(_net_inet_sctp, OID_AUTO, recvspace, CTLTYPE_UINT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_recvspace), 0, sysctl_sctp_check, "IU",
- SCTPCTL_RECVSPACE_DESC);
-
-#if defined(__FreeBSD__)
-SYSCTL_VNET_PROC(_net_inet_sctp, OID_AUTO, auto_asconf, CTLTYPE_UINT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_auto_asconf), 0, sysctl_sctp_check, "IU",
- SCTPCTL_AUTOASCONF_DESC);
-#elif defined(SCTP_APPLE_AUTO_ASCONF)
-SYSCTL_PROC(_net_inet_sctp, OID_AUTO, auto_asconf, CTLTYPE_UINT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_auto_asconf), 0, sysctl_sctp_check, "IU",
- SCTPCTL_AUTOASCONF_DESC);
-#endif
-
-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, strict_sacks, CTLTYPE_UINT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_strict_sacks), 0, sysctl_sctp_check, "IU",
- SCTPCTL_STRICT_SACKS_DESC);
-
-#if !(defined(__FreeBSD__) && __FreeBSD_version >= 800000)
+SCTP_UINT_SYSCTL(sendspace, sctp_sendspace, SCTPCTL_MAXDGRAM)
+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,
+ 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)
+SCTP_UINT_SYSCTL(strict_sacks, sctp_strict_sacks, SCTPCTL_STRICT_SACKS)
+#if defined(__APPLE__)
#if !defined(SCTP_WITH_NO_CSUM)
-SYSCTL_VNET_PROC(_net_inet_sctp, OID_AUTO, loopback_nocsum, CTLTYPE_UINT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_no_csum_on_loopback), 0, sysctl_sctp_check, "IU",
- SCTPCTL_LOOPBACK_NOCSUM_DESC);
-#endif
-#endif
-
-SYSCTL_VNET_PROC(_net_inet_sctp, OID_AUTO, peer_chkoh, CTLTYPE_UINT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_peer_chunk_oh), 0, sysctl_sctp_check, "IU",
- SCTPCTL_PEER_CHKOH_DESC);
-
-SYSCTL_VNET_PROC(_net_inet_sctp, OID_AUTO, maxburst, CTLTYPE_UINT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_max_burst_default), 0, sysctl_sctp_check, "IU",
- SCTPCTL_MAXBURST_DESC);
-
-SYSCTL_VNET_PROC(_net_inet_sctp, OID_AUTO, fr_maxburst, CTLTYPE_UINT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_fr_max_burst_default), 0, sysctl_sctp_check, "IU",
- SCTPCTL_FRMAXBURST_DESC);
-
-SYSCTL_VNET_PROC(_net_inet_sctp, OID_AUTO, maxchunks, CTLTYPE_UINT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_max_chunks_on_queue), 0, sysctl_sctp_check, "IU",
- SCTPCTL_MAXCHUNKS_DESC);
-
-SYSCTL_VNET_PROC(_net_inet_sctp, OID_AUTO, tcbhashsize, CTLTYPE_UINT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_hashtblsize), 0, sysctl_sctp_check, "IU",
- SCTPCTL_TCBHASHSIZE_DESC);
-
-SYSCTL_VNET_PROC(_net_inet_sctp, OID_AUTO, pcbhashsize, CTLTYPE_UINT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_pcbtblsize), 0, sysctl_sctp_check, "IU",
- SCTPCTL_PCBHASHSIZE_DESC);
-
-SYSCTL_VNET_PROC(_net_inet_sctp, OID_AUTO, min_split_point, CTLTYPE_UINT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_min_split_point), 0, sysctl_sctp_check, "IU",
- SCTPCTL_MIN_SPLIT_POINT_DESC);
-
-SYSCTL_VNET_PROC(_net_inet_sctp, OID_AUTO, chunkscale, CTLTYPE_UINT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_chunkscale), 0, sysctl_sctp_check, "IU",
- SCTPCTL_CHUNKSCALE_DESC);
-
-SYSCTL_VNET_PROC(_net_inet_sctp, OID_AUTO, delayed_sack_time, CTLTYPE_UINT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_delayed_sack_time_default), 0, sysctl_sctp_check, "IU",
- SCTPCTL_DELAYED_SACK_TIME_DESC);
-
-SYSCTL_VNET_PROC(_net_inet_sctp, OID_AUTO, sack_freq, CTLTYPE_UINT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_sack_freq_default), 0, sysctl_sctp_check, "IU",
- SCTPCTL_SACK_FREQ_DESC);
-
-SYSCTL_VNET_PROC(_net_inet_sctp, OID_AUTO, sys_resource, CTLTYPE_UINT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_system_free_resc_limit), 0, sysctl_sctp_check, "IU",
- SCTPCTL_SYS_RESOURCE_DESC);
-
-SYSCTL_VNET_PROC(_net_inet_sctp, OID_AUTO, asoc_resource, CTLTYPE_UINT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_asoc_free_resc_limit), 0, sysctl_sctp_check, "IU",
- SCTPCTL_ASOC_RESOURCE_DESC);
-
-SYSCTL_VNET_PROC(_net_inet_sctp, OID_AUTO, heartbeat_interval, CTLTYPE_UINT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_heartbeat_interval_default), 0, sysctl_sctp_check, "IU",
- SCTPCTL_HEARTBEAT_INTERVAL_DESC);
-
-SYSCTL_VNET_PROC(_net_inet_sctp, OID_AUTO, pmtu_raise_time, CTLTYPE_UINT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_pmtu_raise_time_default), 0, sysctl_sctp_check, "IU",
- SCTPCTL_PMTU_RAISE_TIME_DESC);
-
-SYSCTL_VNET_PROC(_net_inet_sctp, OID_AUTO, shutdown_guard_time, CTLTYPE_UINT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_shutdown_guard_time_default), 0, sysctl_sctp_check, "IU",
- SCTPCTL_SHUTDOWN_GUARD_TIME_DESC);
-
-SYSCTL_VNET_PROC(_net_inet_sctp, OID_AUTO, secret_lifetime, CTLTYPE_UINT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_secret_lifetime_default), 0, sysctl_sctp_check, "IU",
- SCTPCTL_SECRET_LIFETIME_DESC);
-
-SYSCTL_VNET_PROC(_net_inet_sctp, OID_AUTO, rto_max, CTLTYPE_UINT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_rto_max_default), 0, sysctl_sctp_check, "IU",
- SCTPCTL_RTO_MAX_DESC);
-
-SYSCTL_VNET_PROC(_net_inet_sctp, OID_AUTO, rto_min, CTLTYPE_UINT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_rto_min_default), 0, sysctl_sctp_check, "IU",
- SCTPCTL_RTO_MIN_DESC);
-
-SYSCTL_VNET_PROC(_net_inet_sctp, OID_AUTO, rto_initial, CTLTYPE_UINT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_rto_initial_default), 0, sysctl_sctp_check, "IU",
- SCTPCTL_RTO_INITIAL_DESC);
-
-SYSCTL_VNET_PROC(_net_inet_sctp, OID_AUTO, init_rto_max, CTLTYPE_UINT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_init_rto_max_default), 0, sysctl_sctp_check, "IU",
- SCTPCTL_INIT_RTO_MAX_DESC);
-
-SYSCTL_VNET_PROC(_net_inet_sctp, OID_AUTO, valid_cookie_life, CTLTYPE_UINT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_valid_cookie_life_default), 0, sysctl_sctp_check, "IU",
- SCTPCTL_VALID_COOKIE_LIFE_DESC);
-
-SYSCTL_VNET_PROC(_net_inet_sctp, OID_AUTO, init_rtx_max, CTLTYPE_UINT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_init_rtx_max_default), 0, sysctl_sctp_check, "IU",
- SCTPCTL_INIT_RTX_MAX_DESC);
-
-SYSCTL_VNET_PROC(_net_inet_sctp, OID_AUTO, assoc_rtx_max, CTLTYPE_UINT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_assoc_rtx_max_default), 0, sysctl_sctp_check, "IU",
- SCTPCTL_ASSOC_RTX_MAX_DESC);
-
-SYSCTL_VNET_PROC(_net_inet_sctp, OID_AUTO, path_rtx_max, CTLTYPE_UINT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_path_rtx_max_default), 0, sysctl_sctp_check, "IU",
- SCTPCTL_PATH_RTX_MAX_DESC);
-
-SYSCTL_VNET_PROC(_net_inet_sctp, OID_AUTO, path_pf_threshold, CTLTYPE_UINT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_path_pf_threshold), 0, sysctl_sctp_check, "IU",
- SCTPCTL_PATH_PF_THRESHOLD_DESC);
-
-SYSCTL_VNET_PROC(_net_inet_sctp, OID_AUTO, add_more_on_output, CTLTYPE_UINT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_add_more_threshold), 0, sysctl_sctp_check, "IU",
- SCTPCTL_ADD_MORE_ON_OUTPUT_DESC);
-
-SYSCTL_VNET_PROC(_net_inet_sctp, OID_AUTO, incoming_streams, CTLTYPE_UINT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_nr_incoming_streams_default), 0, sysctl_sctp_check, "IU",
- SCTPCTL_INCOMING_STREAMS_DESC);
-
-SYSCTL_VNET_PROC(_net_inet_sctp, OID_AUTO, outgoing_streams, CTLTYPE_UINT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_nr_outgoing_streams_default), 0, sysctl_sctp_check, "IU",
- SCTPCTL_OUTGOING_STREAMS_DESC);
-
-SYSCTL_VNET_PROC(_net_inet_sctp, OID_AUTO, cmt_on_off, CTLTYPE_UINT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_cmt_on_off), 0, sysctl_sctp_check, "IU",
- SCTPCTL_CMT_ON_OFF_DESC);
-
-SYSCTL_VNET_PROC(_net_inet_sctp, OID_AUTO, nr_sack_on_off, CTLTYPE_UINT | CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_nr_sack_on_off), 0, sysctl_sctp_check, "IU",
- SCTPCTL_NR_SACK_ON_OFF_DESC);
-
-SYSCTL_VNET_PROC(_net_inet_sctp, OID_AUTO, cmt_use_dac, CTLTYPE_UINT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_cmt_use_dac), 0, sysctl_sctp_check, "IU",
- SCTPCTL_CMT_USE_DAC_DESC);
-
-SYSCTL_VNET_PROC(_net_inet_sctp, OID_AUTO, cwnd_maxburst, CTLTYPE_UINT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_use_cwnd_based_maxburst), 0, sysctl_sctp_check, "IU",
- SCTPCTL_CWND_MAXBURST_DESC);
-
-SYSCTL_VNET_PROC(_net_inet_sctp, OID_AUTO, asconf_auth_nochk, CTLTYPE_UINT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_asconf_auth_nochk), 0, sysctl_sctp_check, "IU",
- SCTPCTL_ASCONF_AUTH_NOCHK_DESC);
-
-SYSCTL_VNET_PROC(_net_inet_sctp, OID_AUTO, auth_disable, CTLTYPE_UINT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_auth_disable), 0, sysctl_sctp_check, "IU",
- SCTPCTL_AUTH_DISABLE_DESC);
-
-SYSCTL_VNET_PROC(_net_inet_sctp, OID_AUTO, nat_friendly, CTLTYPE_UINT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_nat_friendly), 0, sysctl_sctp_check, "IU",
- SCTPCTL_NAT_FRIENDLY_DESC);
-
-SYSCTL_VNET_PROC(_net_inet_sctp, OID_AUTO, abc_l_var, CTLTYPE_UINT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_L2_abc_variable), 0, sysctl_sctp_check, "IU",
- SCTPCTL_ABC_L_VAR_DESC);
-
-SYSCTL_VNET_PROC(_net_inet_sctp, OID_AUTO, max_chained_mbufs, CTLTYPE_UINT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_mbuf_threshold_count), 0, sysctl_sctp_check, "IU",
- SCTPCTL_MAX_CHAINED_MBUFS_DESC);
-
-SYSCTL_VNET_PROC(_net_inet_sctp, OID_AUTO, do_sctp_drain, CTLTYPE_UINT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_do_drain), 0, sysctl_sctp_check, "IU",
- SCTPCTL_DO_SCTP_DRAIN_DESC);
-
-SYSCTL_VNET_PROC(_net_inet_sctp, OID_AUTO, hb_max_burst, CTLTYPE_UINT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_hb_maxburst), 0, sysctl_sctp_check, "IU",
- SCTPCTL_HB_MAX_BURST_DESC);
-
-SYSCTL_VNET_PROC(_net_inet_sctp, OID_AUTO, abort_at_limit, CTLTYPE_UINT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_abort_if_one_2_one_hits_limit), 0, sysctl_sctp_check, "IU",
- SCTPCTL_ABORT_AT_LIMIT_DESC);
-
-SYSCTL_VNET_PROC(_net_inet_sctp, OID_AUTO, strict_data_order, CTLTYPE_UINT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_strict_data_order), 0, sysctl_sctp_check, "IU",
- SCTPCTL_STRICT_DATA_ORDER_DESC);
-
-SYSCTL_VNET_PROC(_net_inet_sctp, OID_AUTO, min_residual, CTLTYPE_UINT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_min_residual), 0, sysctl_sctp_check, "IU",
- SCTPCTL_MIN_RESIDUAL_DESC);
-
-SYSCTL_VNET_PROC(_net_inet_sctp, OID_AUTO, max_retran_chunk, CTLTYPE_UINT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_max_retran_chunk), 0, sysctl_sctp_check, "IU",
- SCTPCTL_MAX_RETRAN_CHUNK_DESC);
-
-SYSCTL_VNET_PROC(_net_inet_sctp, OID_AUTO, log_level, CTLTYPE_UINT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_logging_level), 0, sysctl_sctp_check, "IU",
- SCTPCTL_LOGGING_LEVEL_DESC);
-
-SYSCTL_VNET_PROC(_net_inet_sctp, OID_AUTO, default_cc_module, CTLTYPE_UINT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_default_cc_module), 0, sysctl_sctp_check, "IU",
- SCTPCTL_DEFAULT_CC_MODULE_DESC);
-
-SYSCTL_VNET_PROC(_net_inet_sctp, OID_AUTO, default_ss_module, CTLTYPE_UINT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_default_ss_module), 0, sysctl_sctp_check, "IU",
- SCTPCTL_DEFAULT_SS_MODULE_DESC);
-
-SYSCTL_VNET_PROC(_net_inet_sctp, OID_AUTO, default_frag_interleave, CTLTYPE_UINT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_default_frag_interleave), 0, sysctl_sctp_check, "IU",
- SCTPCTL_DEFAULT_FRAG_INTERLEAVE_DESC);
-
-#if defined(__FreeBSD__)
-SYSCTL_VNET_PROC(_net_inet_sctp, OID_AUTO, mobility_base, CTLTYPE_UINT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_mobility_base), 0, sysctl_sctp_check, "IU",
- SCTPCTL_MOBILITY_BASE_DESC);
-#elif defined(SCTP_APPLE_MOBILITY_BASE)
-SYSCTL_PROC(_net_inet_sctp, OID_AUTO, mobility_base, CTLTYPE_UINT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_mobility_base), 0, sysctl_sctp_check, "IU",
- SCTPCTL_MOBILITY_BASE_DESC);
-#endif
-
-#if defined(__FreeBSD__)
-SYSCTL_VNET_PROC(_net_inet_sctp, OID_AUTO, mobility_fasthandoff, CTLTYPE_UINT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_mobility_fasthandoff), 0, sysctl_sctp_check, "IU",
- SCTPCTL_MOBILITY_FASTHANDOFF_DESC);
-#elif defined(SCTP_APPLE_MOBILITY_FASTHANDOFF)
-SYSCTL_PROC(_net_inet_sctp, OID_AUTO, mobility_fasthandoff, CTLTYPE_UINT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_mobility_fasthandoff), 0, sysctl_sctp_check, "IU",
- SCTPCTL_MOBILITY_FASTHANDOFF_DESC);
-#endif
-
+SCTP_UINT_SYSCTL(loopback_nocsum, sctp_no_csum_on_loopback, SCTPCTL_LOOPBACK_NOCSUM)
+#endif
+#endif
+SCTP_UINT_SYSCTL(peer_chkoh, sctp_peer_chunk_oh, SCTPCTL_PEER_CHKOH)
+SCTP_UINT_SYSCTL(maxburst, sctp_max_burst_default, SCTPCTL_MAXBURST)
+SCTP_UINT_SYSCTL(fr_maxburst, sctp_fr_max_burst_default, SCTPCTL_FRMAXBURST)
+SCTP_UINT_SYSCTL(maxchunks, sctp_max_chunks_on_queue, SCTPCTL_MAXCHUNKS)
+SCTP_UINT_SYSCTL(tcbhashsize, sctp_hashtblsize, SCTPCTL_TCBHASHSIZE)
+SCTP_UINT_SYSCTL(pcbhashsize, sctp_pcbtblsize, SCTPCTL_PCBHASHSIZE)
+SCTP_UINT_SYSCTL(min_split_point, sctp_min_split_point, SCTPCTL_MIN_SPLIT_POINT)
+SCTP_UINT_SYSCTL(chunkscale, sctp_chunkscale, SCTPCTL_CHUNKSCALE)
+SCTP_UINT_SYSCTL(delayed_sack_time, sctp_delayed_sack_time_default, SCTPCTL_DELAYED_SACK_TIME)
+SCTP_UINT_SYSCTL(sack_freq, sctp_sack_freq_default, SCTPCTL_SACK_FREQ)
+SCTP_UINT_SYSCTL(sys_resource, sctp_system_free_resc_limit, SCTPCTL_SYS_RESOURCE)
+SCTP_UINT_SYSCTL(asoc_resource, sctp_asoc_free_resc_limit, SCTPCTL_ASOC_RESOURCE)
+SCTP_UINT_SYSCTL(heartbeat_interval, sctp_heartbeat_interval_default, SCTPCTL_HEARTBEAT_INTERVAL)
+SCTP_UINT_SYSCTL(pmtu_raise_time, sctp_pmtu_raise_time_default, SCTPCTL_PMTU_RAISE_TIME)
+SCTP_UINT_SYSCTL(shutdown_guard_time, sctp_shutdown_guard_time_default, SCTPCTL_SHUTDOWN_GUARD_TIME)
+SCTP_UINT_SYSCTL(secret_lifetime, sctp_secret_lifetime_default, SCTPCTL_SECRET_LIFETIME)
+SCTP_UINT_SYSCTL(rto_max, sctp_rto_max_default, SCTPCTL_RTO_MAX)
+SCTP_UINT_SYSCTL(rto_min, sctp_rto_min_default, SCTPCTL_RTO_MIN)
+SCTP_UINT_SYSCTL(rto_initial, sctp_rto_initial_default, SCTPCTL_RTO_INITIAL)
+SCTP_UINT_SYSCTL(init_rto_max, sctp_init_rto_max_default, SCTPCTL_INIT_RTO_MAX)
+SCTP_UINT_SYSCTL(valid_cookie_life, sctp_valid_cookie_life_default, SCTPCTL_VALID_COOKIE_LIFE)
+SCTP_UINT_SYSCTL(init_rtx_max, sctp_init_rtx_max_default, SCTPCTL_INIT_RTX_MAX)
+SCTP_UINT_SYSCTL(assoc_rtx_max, sctp_assoc_rtx_max_default, SCTPCTL_ASSOC_RTX_MAX)
+SCTP_UINT_SYSCTL(path_rtx_max, sctp_path_rtx_max_default, SCTPCTL_PATH_RTX_MAX)
+SCTP_UINT_SYSCTL(path_pf_threshold, sctp_path_pf_threshold, SCTPCTL_PATH_PF_THRESHOLD)
+SCTP_UINT_SYSCTL(add_more_on_output, sctp_add_more_threshold, SCTPCTL_ADD_MORE_ON_OUTPUT)
+SCTP_UINT_SYSCTL(incoming_streams, sctp_nr_incoming_streams_default, SCTPCTL_INCOMING_STREAMS)
+SCTP_UINT_SYSCTL(outgoing_streams, sctp_nr_outgoing_streams_default, SCTPCTL_OUTGOING_STREAMS)
+SCTP_UINT_SYSCTL(cmt_on_off, sctp_cmt_on_off, SCTPCTL_CMT_ON_OFF)
+SCTP_UINT_SYSCTL(cmt_use_dac, sctp_cmt_use_dac, SCTPCTL_CMT_USE_DAC)
+SCTP_UINT_SYSCTL(cwnd_maxburst, sctp_use_cwnd_based_maxburst, SCTPCTL_CWND_MAXBURST)
+SCTP_UINT_SYSCTL(nat_friendly, sctp_nat_friendly, SCTPCTL_NAT_FRIENDLY)
+SCTP_UINT_SYSCTL(abc_l_var, sctp_L2_abc_variable, SCTPCTL_ABC_L_VAR)
+SCTP_UINT_SYSCTL(max_chained_mbufs, sctp_mbuf_threshold_count, SCTPCTL_MAX_CHAINED_MBUFS)
+SCTP_UINT_SYSCTL(do_sctp_drain, sctp_do_drain, SCTPCTL_DO_SCTP_DRAIN)
+SCTP_UINT_SYSCTL(hb_max_burst, sctp_hb_maxburst, SCTPCTL_HB_MAX_BURST)
+SCTP_UINT_SYSCTL(abort_at_limit, sctp_abort_if_one_2_one_hits_limit, SCTPCTL_ABORT_AT_LIMIT)
+SCTP_UINT_SYSCTL(strict_data_order, sctp_strict_data_order, SCTPCTL_STRICT_DATA_ORDER)
+SCTP_UINT_SYSCTL(min_residual, sctp_min_residual, SCTPCTL_MIN_RESIDUAL)
+SCTP_UINT_SYSCTL(max_retran_chunk, sctp_max_retran_chunk, SCTPCTL_MAX_RETRAN_CHUNK)
+SCTP_UINT_SYSCTL(log_level, sctp_logging_level, SCTPCTL_LOGGING_LEVEL)
+SCTP_UINT_SYSCTL(default_cc_module, sctp_default_cc_module, SCTPCTL_DEFAULT_CC_MODULE)
+SCTP_UINT_SYSCTL(default_ss_module, sctp_default_ss_module, SCTPCTL_DEFAULT_SS_MODULE)
+SCTP_UINT_SYSCTL(default_frag_interleave, sctp_default_frag_interleave, SCTPCTL_DEFAULT_FRAG_INTERLEAVE)
+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_VNET_STRUCT(_net_inet_sctp, OID_AUTO, log, CTLFLAG_RD,
- &SCTP_BASE_SYSCTL(sctp_log), sctp_log,
- "SCTP logging (struct sctp_log)");
-
-SYSCTL_VNET_PROC(_net_inet_sctp, OID_AUTO, clear_trace, CTLTYPE_UINT | CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_log), 0, sysctl_sctp_cleartrace, "IU",
- "Clear SCTP Logging buffer");
-#endif
-
-SYSCTL_VNET_PROC(_net_inet_sctp, OID_AUTO, udp_tunneling_port, CTLTYPE_UINT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_udp_tunneling_port), 0, sysctl_sctp_udp_tunneling_check, "IU",
- SCTPCTL_UDP_TUNNELING_PORT_DESC);
-
-SYSCTL_VNET_PROC(_net_inet_sctp, OID_AUTO, enable_sack_immediately, CTLTYPE_UINT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_enable_sack_immediately), 0, sysctl_sctp_check, "IU",
- SCTPCTL_SACK_IMMEDIATELY_ENABLE_DESC);
-
-SYSCTL_VNET_PROC(_net_inet_sctp, OID_AUTO, nat_friendly_init, CTLTYPE_UINT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_inits_include_nat_friendly), 0, sysctl_sctp_check, "IU",
- SCTPCTL_NAT_FRIENDLY_INITS_DESC);
-
-SYSCTL_VNET_PROC(_net_inet_sctp, OID_AUTO, vtag_time_wait, CTLTYPE_UINT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_vtag_time_wait), 0, sysctl_sctp_check, "IU",
- SCTPCTL_TIME_WAIT_DESC);
-
-SYSCTL_VNET_PROC(_net_inet_sctp, OID_AUTO, buffer_splitting, CTLTYPE_UINT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_buffer_splitting), 0, sysctl_sctp_check, "IU",
- SCTPCTL_BUFFER_SPLITTING_DESC);
-
-SYSCTL_VNET_PROC(_net_inet_sctp, OID_AUTO, initial_cwnd, CTLTYPE_UINT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_initial_cwnd), 0, sysctl_sctp_check, "IU",
- SCTPCTL_INITIAL_CWND_DESC);
-
-SYSCTL_VNET_PROC(_net_inet_sctp, OID_AUTO, rttvar_bw, CTLTYPE_UINT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_rttvar_bw), 0, sysctl_sctp_check, "IU",
- SCTPCTL_RTTVAR_BW_DESC);
-
-SYSCTL_VNET_PROC(_net_inet_sctp, OID_AUTO, rttvar_rtt, CTLTYPE_UINT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_rttvar_rtt), 0, sysctl_sctp_check, "IU",
- SCTPCTL_RTTVAR_RTT_DESC);
-
-SYSCTL_VNET_PROC(_net_inet_sctp, OID_AUTO, rttvar_eqret, CTLTYPE_UINT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_rttvar_eqret), 0, sysctl_sctp_check, "IU",
- SCTPCTL_RTTVAR_EQRET_DESC);
-
-SYSCTL_VNET_PROC(_net_inet_sctp, OID_AUTO, rttvar_steady_step, CTLTYPE_UINT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_steady_step), 0, sysctl_sctp_check, "IU",
- SCTPCTL_RTTVAR_STEADYS_DESC);
-
-SYSCTL_VNET_PROC(_net_inet_sctp, OID_AUTO, use_dcccecn, CTLTYPE_UINT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_use_dccc_ecn), 0, sysctl_sctp_check, "IU",
- SCTPCTL_RTTVAR_DCCCECN_DESC);
-
-SYSCTL_VNET_PROC(_net_inet_sctp, OID_AUTO, blackhole, CTLTYPE_UINT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_blackhole), 0, sysctl_sctp_check, "IU",
- SCTPCTL_BLACKHOLE_DESC);
-
-SYSCTL_VNET_PROC(_net_inet_sctp, OID_AUTO, diag_info_code, CTLTYPE_UINT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_diag_info_code), 0, sysctl_sctp_check, "IU",
- SCTPCTL_DIAG_INFO_CODE_DESC);
-
+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,
+ 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)
+SCTP_UINT_SYSCTL(buffer_splitting, sctp_buffer_splitting, SCTPCTL_BUFFER_SPLITTING)
+SCTP_UINT_SYSCTL(initial_cwnd, sctp_initial_cwnd, SCTPCTL_INITIAL_CWND)
+SCTP_UINT_SYSCTL(rttvar_bw, sctp_rttvar_bw, SCTPCTL_RTTVAR_BW)
+SCTP_UINT_SYSCTL(rttvar_rtt, sctp_rttvar_rtt, SCTPCTL_RTTVAR_RTT)
+SCTP_UINT_SYSCTL(rttvar_eqret, sctp_rttvar_eqret, SCTPCTL_RTTVAR_EQRET)
+SCTP_UINT_SYSCTL(rttvar_steady_step, sctp_steady_step, SCTPCTL_RTTVAR_STEADYS)
+SCTP_UINT_SYSCTL(use_dcccecn, sctp_use_dccc_ecn, SCTPCTL_RTTVAR_DCCCECN)
+SCTP_UINT_SYSCTL(blackhole, sctp_blackhole, SCTPCTL_BLACKHOLE)
+SCTP_UINT_SYSCTL(diag_info_code, sctp_diag_info_code, SCTPCTL_DIAG_INFO_CODE)
#ifdef SCTP_DEBUG
-SYSCTL_VNET_PROC(_net_inet_sctp, OID_AUTO, debug, CTLTYPE_UINT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_debug_on), 0, sysctl_sctp_check, "IU",
- SCTPCTL_DEBUG_DESC);
+SCTP_UINT_SYSCTL(debug, sctp_debug_on, SCTPCTL_DEBUG)
#endif
-
#if defined(__APPLE__)
-SYSCTL_INT(_net_inet_sctp, OID_AUTO, main_timer, CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_main_timer), 0, "Main timer interval in ms");
-
+SCTP_UINT_SYSCTL(main_timer, sctp_main_timer, SCTPCTL_MAIN_TIMER)
SYSCTL_PROC(_net_inet_sctp, OID_AUTO, ignore_vmware_interfaces, CTLTYPE_UINT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_ignore_vmware_interfaces), 0, sysctl_sctp_vmware_interfaces_check, "IU",
- SCTPCTL_IGNORE_VMWARE_INTERFACES_DESC);
-
-SYSCTL_INT(_net_inet_sctp, OID_AUTO, addr_watchdog_limit, CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_addr_watchdog_limit), 0, "Addr watchdog intervall");
-
-SYSCTL_INT(_net_inet_sctp, OID_AUTO, vtag_watchdog_limit, CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_vtag_watchdog_limit), 0, "Vtag watchdog intervall");
+ NULL, 0, sctp_sysctl_handle_vmware_interfaces, "IU", SCTPCTL_IGNORE_VMWARE_INTERFACES_DESC);
+SCTP_UINT_SYSCTL(addr_watchdog_limit, sctp_addr_watchdog_limit, SCTPCTL_ADDR_WATCHDOG_LIMIT)
+SCTP_UINT_SYSCTL(vtag_watchdog_limit, sctp_vtag_watchdog_limit, SCTPCTL_VTAG_WATCHDOG_LIMIT)
#endif
-
#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
-SYSCTL_VNET_PROC(_net_inet_sctp, OID_AUTO, output_unlocked, CTLTYPE_UINT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_output_unlocked), 0, sysctl_sctp_check, "IU",
- SCTPCTL_OUTPUT_UNLOCKED_DESC);
+SCTP_UINT_SYSCTL(output_unlocked, sctp_output_unlocked, SCTPCTL_OUTPUT_UNLOCKED)
#endif
+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");
-#if defined(__FreeBSD__) && defined(SMP) && defined(SCTP_USE_PERCPU_STAT)
-SYSCTL_VNET_PROC(_net_inet_sctp, OID_AUTO, stats,
- CTLTYPE_STRUCT|CTLFLAG_RW,
- 0, 0, sysctl_stat_get, "S,sctpstat",
- "SCTP statistics (struct sctp_stat)");
-#else
-SYSCTL_VNET_STRUCT(_net_inet_sctp, OID_AUTO, stats, CTLFLAG_RW,
- &SCTP_BASE_STATS_SYSCTL, sctpstat,
- "SCTP statistics (struct sctp_stat)");
-#endif
+#elif defined(__Windows__)
+
+#define RANGECHK(var, min, max) \
+ if ((var) < (min)) { (var) = (min); } \
+ else if ((var) > (max)) { (var) = (max); }
-SYSCTL_VNET_PROC(_net_inet_sctp, OID_AUTO, assoclist, CTLTYPE_OPAQUE | CTLFLAG_RD,
- 0, 0, sctp_assoclist,
- "S,xassoc", "List of active SCTP associations");
+static int
+sctp_sysctl_handle_int(SYSCTL_HANDLER_ARGS)
+{
+ int error;
-#elif defined(__Windows__)
-void sysctl_setup_sctp(void)
+ error = sysctl_handle_int(oidp, oidp->oid_arg1, oidp->oid_arg2, req);
+ if (error == 0) {
+ RANGECHK(SCTP_BASE_SYSCTL(sctp_sendspace), SCTPCTL_MAXDGRAM_MIN, SCTPCTL_MAXDGRAM_MAX);
+ RANGECHK(SCTP_BASE_SYSCTL(sctp_recvspace), SCTPCTL_RECVSPACE_MIN, SCTPCTL_RECVSPACE_MAX);
+ RANGECHK(SCTP_BASE_SYSCTL(sctp_auto_asconf), SCTPCTL_AUTOASCONF_MIN, SCTPCTL_AUTOASCONF_MAX);
+ RANGECHK(SCTP_BASE_SYSCTL(sctp_auto_asconf), SCTPCTL_AUTOASCONF_MIN, SCTPCTL_AUTOASCONF_MAX);
+ 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_reconfig_enable), SCTPCTL_RECONFIG_ENABLE_MIN, SCTPCTL_RECONFIG_ENABLE_MAX);
+ RANGECHK(SCTP_BASE_SYSCTL(sctp_nrsack_enable), SCTPCTL_NRSACK_ENABLE_MIN, SCTPCTL_NRSACK_ENABLE_MAX);
+ RANGECHK(SCTP_BASE_SYSCTL(sctp_pktdrop_enable), SCTPCTL_PKTDROP_ENABLE_MIN, SCTPCTL_PKTDROP_ENABLE_MAX);
+ RANGECHK(SCTP_BASE_SYSCTL(sctp_strict_sacks), SCTPCTL_STRICT_SACKS_MIN, SCTPCTL_STRICT_SACKS_MAX);
+#if !defined(SCTP_WITH_NO_CSUM)
+ RANGECHK(SCTP_BASE_SYSCTL(sctp_no_csum_on_loopback), SCTPCTL_LOOPBACK_NOCSUM_MIN, SCTPCTL_LOOPBACK_NOCSUM_MAX);
+#endif
+ RANGECHK(SCTP_BASE_SYSCTL(sctp_peer_chunk_oh), SCTPCTL_PEER_CHKOH_MIN, SCTPCTL_PEER_CHKOH_MAX);
+ RANGECHK(SCTP_BASE_SYSCTL(sctp_max_burst_default), SCTPCTL_MAXBURST_MIN, SCTPCTL_MAXBURST_MAX);
+ RANGECHK(SCTP_BASE_SYSCTL(sctp_fr_max_burst_default), SCTPCTL_FRMAXBURST_MIN, SCTPCTL_FRMAXBURST_MAX);
+ RANGECHK(SCTP_BASE_SYSCTL(sctp_max_chunks_on_queue), SCTPCTL_MAXCHUNKS_MIN, SCTPCTL_MAXCHUNKS_MAX);
+ RANGECHK(SCTP_BASE_SYSCTL(sctp_hashtblsize), SCTPCTL_TCBHASHSIZE_MIN, SCTPCTL_TCBHASHSIZE_MAX);
+ RANGECHK(SCTP_BASE_SYSCTL(sctp_pcbtblsize), SCTPCTL_PCBHASHSIZE_MIN, SCTPCTL_PCBHASHSIZE_MAX);
+ RANGECHK(SCTP_BASE_SYSCTL(sctp_min_split_point), SCTPCTL_MIN_SPLIT_POINT_MIN, SCTPCTL_MIN_SPLIT_POINT_MAX);
+ RANGECHK(SCTP_BASE_SYSCTL(sctp_chunkscale), SCTPCTL_CHUNKSCALE_MIN, SCTPCTL_CHUNKSCALE_MAX);
+ RANGECHK(SCTP_BASE_SYSCTL(sctp_delayed_sack_time_default), SCTPCTL_DELAYED_SACK_TIME_MIN, SCTPCTL_DELAYED_SACK_TIME_MAX);
+ RANGECHK(SCTP_BASE_SYSCTL(sctp_sack_freq_default), SCTPCTL_SACK_FREQ_MIN, SCTPCTL_SACK_FREQ_MAX);
+ RANGECHK(SCTP_BASE_SYSCTL(sctp_system_free_resc_limit), SCTPCTL_SYS_RESOURCE_MIN, SCTPCTL_SYS_RESOURCE_MAX);
+ RANGECHK(SCTP_BASE_SYSCTL(sctp_asoc_free_resc_limit), SCTPCTL_ASOC_RESOURCE_MIN, SCTPCTL_ASOC_RESOURCE_MAX);
+ RANGECHK(SCTP_BASE_SYSCTL(sctp_heartbeat_interval_default), SCTPCTL_HEARTBEAT_INTERVAL_MIN, SCTPCTL_HEARTBEAT_INTERVAL_MAX);
+ RANGECHK(SCTP_BASE_SYSCTL(sctp_pmtu_raise_time_default), SCTPCTL_PMTU_RAISE_TIME_MIN, SCTPCTL_PMTU_RAISE_TIME_MAX);
+ RANGECHK(SCTP_BASE_SYSCTL(sctp_shutdown_guard_time_default), SCTPCTL_SHUTDOWN_GUARD_TIME_MIN, SCTPCTL_SHUTDOWN_GUARD_TIME_MAX);
+ RANGECHK(SCTP_BASE_SYSCTL(sctp_secret_lifetime_default), SCTPCTL_SECRET_LIFETIME_MIN, SCTPCTL_SECRET_LIFETIME_MAX);
+ RANGECHK(SCTP_BASE_SYSCTL(sctp_rto_max_default), SCTPCTL_RTO_MAX_MIN, SCTPCTL_RTO_MAX_MAX);
+ RANGECHK(SCTP_BASE_SYSCTL(sctp_rto_min_default), SCTPCTL_RTO_MIN_MIN, SCTPCTL_RTO_MIN_MAX);
+ RANGECHK(SCTP_BASE_SYSCTL(sctp_rto_initial_default), SCTPCTL_RTO_INITIAL_MIN, SCTPCTL_RTO_INITIAL_MAX);
+ RANGECHK(SCTP_BASE_SYSCTL(sctp_init_rto_max_default), SCTPCTL_INIT_RTO_MAX_MIN, SCTPCTL_INIT_RTO_MAX_MAX);
+ RANGECHK(SCTP_BASE_SYSCTL(sctp_valid_cookie_life_default), SCTPCTL_VALID_COOKIE_LIFE_MIN, SCTPCTL_VALID_COOKIE_LIFE_MAX);
+ RANGECHK(SCTP_BASE_SYSCTL(sctp_init_rtx_max_default), SCTPCTL_INIT_RTX_MAX_MIN, SCTPCTL_INIT_RTX_MAX_MAX);
+ RANGECHK(SCTP_BASE_SYSCTL(sctp_assoc_rtx_max_default), SCTPCTL_ASSOC_RTX_MAX_MIN, SCTPCTL_ASSOC_RTX_MAX_MAX);
+ RANGECHK(SCTP_BASE_SYSCTL(sctp_path_rtx_max_default), SCTPCTL_PATH_RTX_MAX_MIN, SCTPCTL_PATH_RTX_MAX_MAX);
+ RANGECHK(SCTP_BASE_SYSCTL(sctp_path_pf_threshold), SCTPCTL_PATH_PF_THRESHOLD_MIN, SCTPCTL_PATH_PF_THRESHOLD_MAX);
+ RANGECHK(SCTP_BASE_SYSCTL(sctp_add_more_threshold), SCTPCTL_ADD_MORE_ON_OUTPUT_MIN, SCTPCTL_ADD_MORE_ON_OUTPUT_MAX);
+ RANGECHK(SCTP_BASE_SYSCTL(sctp_nr_incoming_streams_default), SCTPCTL_INCOMING_STREAMS_MIN, SCTPCTL_INCOMING_STREAMS_MAX);
+ RANGECHK(SCTP_BASE_SYSCTL(sctp_nr_outgoing_streams_default), SCTPCTL_OUTGOING_STREAMS_MIN, SCTPCTL_OUTGOING_STREAMS_MAX);
+ RANGECHK(SCTP_BASE_SYSCTL(sctp_cmt_on_off), SCTPCTL_CMT_ON_OFF_MIN, SCTPCTL_CMT_ON_OFF_MAX);
+ RANGECHK(SCTP_BASE_SYSCTL(sctp_cmt_use_dac), SCTPCTL_CMT_USE_DAC_MIN, SCTPCTL_CMT_USE_DAC_MAX);
+ RANGECHK(SCTP_BASE_SYSCTL(sctp_use_cwnd_based_maxburst), SCTPCTL_CWND_MAXBURST_MIN, SCTPCTL_CWND_MAXBURST_MAX);
+ RANGECHK(SCTP_BASE_SYSCTL(sctp_nat_friendly), SCTPCTL_NAT_FRIENDLY_MIN, SCTPCTL_NAT_FRIENDLY_MAX);
+ RANGECHK(SCTP_BASE_SYSCTL(sctp_L2_abc_variable), SCTPCTL_ABC_L_VAR_MIN, SCTPCTL_ABC_L_VAR_MAX);
+ RANGECHK(SCTP_BASE_SYSCTL(sctp_mbuf_threshold_count), SCTPCTL_MAX_CHAINED_MBUFS_MIN, SCTPCTL_MAX_CHAINED_MBUFS_MAX);
+ RANGECHK(SCTP_BASE_SYSCTL(sctp_do_drain), SCTPCTL_DO_SCTP_DRAIN_MIN, SCTPCTL_DO_SCTP_DRAIN_MAX);
+ RANGECHK(SCTP_BASE_SYSCTL(sctp_hb_maxburst), SCTPCTL_HB_MAX_BURST_MIN, SCTPCTL_HB_MAX_BURST_MAX);
+ RANGECHK(SCTP_BASE_SYSCTL(sctp_abort_if_one_2_one_hits_limit), SCTPCTL_ABORT_AT_LIMIT_MIN, SCTPCTL_ABORT_AT_LIMIT_MAX);
+ RANGECHK(SCTP_BASE_SYSCTL(sctp_strict_data_order), SCTPCTL_STRICT_DATA_ORDER_MIN, SCTPCTL_STRICT_DATA_ORDER_MAX);
+ RANGECHK(SCTP_BASE_SYSCTL(sctp_min_residual), SCTPCTL_MIN_RESIDUAL_MIN, SCTPCTL_MIN_RESIDUAL_MAX);
+ RANGECHK(SCTP_BASE_SYSCTL(sctp_max_retran_chunk), SCTPCTL_MAX_RETRAN_CHUNK_MIN, SCTPCTL_MAX_RETRAN_CHUNK_MAX);
+ RANGECHK(SCTP_BASE_SYSCTL(sctp_logging_level), SCTPCTL_LOGGING_LEVEL_MIN, SCTPCTL_LOGGING_LEVEL_MAX);
+ RANGECHK(SCTP_BASE_SYSCTL(sctp_default_cc_module), SCTPCTL_DEFAULT_CC_MODULE_MIN, SCTPCTL_DEFAULT_CC_MODULE_MAX);
+ RANGECHK(SCTP_BASE_SYSCTL(sctp_default_ss_module), SCTPCTL_DEFAULT_SS_MODULE_MIN, SCTPCTL_DEFAULT_SS_MODULE_MAX);
+ RANGECHK(SCTP_BASE_SYSCTL(sctp_default_frag_interleave), SCTPCTL_DEFAULT_FRAG_INTERLEAVE_MIN, SCTPCTL_DEFAULT_FRAG_INTERLEAVE_MAX);
+ RANGECHK(SCTP_BASE_SYSCTL(sctp_vtag_time_wait), SCTPCTL_TIME_WAIT_MIN, SCTPCTL_TIME_WAIT_MAX);
+ RANGECHK(SCTP_BASE_SYSCTL(sctp_buffer_splitting), SCTPCTL_BUFFER_SPLITTING_MIN, SCTPCTL_BUFFER_SPLITTING_MAX);
+ RANGECHK(SCTP_BASE_SYSCTL(sctp_initial_cwnd), SCTPCTL_INITIAL_CWND_MIN, SCTPCTL_INITIAL_CWND_MAX);
+ RANGECHK(SCTP_BASE_SYSCTL(sctp_rttvar_bw), SCTPCTL_RTTVAR_BW_MIN, SCTPCTL_RTTVAR_BW_MAX);
+ RANGECHK(SCTP_BASE_SYSCTL(sctp_rttvar_rtt), SCTPCTL_RTTVAR_RTT_MIN, SCTPCTL_RTTVAR_RTT_MAX);
+ RANGECHK(SCTP_BASE_SYSCTL(sctp_rttvar_eqret), SCTPCTL_RTTVAR_EQRET_MIN, SCTPCTL_RTTVAR_EQRET_MAX);
+ RANGECHK(SCTP_BASE_SYSCTL(sctp_steady_step), SCTPCTL_RTTVAR_STEADYS_MIN, SCTPCTL_RTTVAR_STEADYS_MAX);
+ RANGECHK(SCTP_BASE_SYSCTL(sctp_use_dccc_ecn), SCTPCTL_RTTVAR_DCCCECN_MIN, SCTPCTL_RTTVAR_DCCCECN_MAX);
+ RANGECHK(SCTP_BASE_SYSCTL(sctp_mobility_base), SCTPCTL_MOBILITY_BASE_MIN, SCTPCTL_MOBILITY_BASE_MAX);
+ RANGECHK(SCTP_BASE_SYSCTL(sctp_mobility_fasthandoff), SCTPCTL_MOBILITY_FASTHANDOFF_MIN, SCTPCTL_MOBILITY_FASTHANDOFF_MAX);
+ RANGECHK(SCTP_BASE_SYSCTL(sctp_enable_sack_immediately), SCTPCTL_SACK_IMMEDIATELY_ENABLE_MIN, SCTPCTL_SACK_IMMEDIATELY_ENABLE_MAX);
+ RANGECHK(SCTP_BASE_SYSCTL(sctp_inits_include_nat_friendly), SCTPCTL_NAT_FRIENDLY_INITS_MIN, SCTPCTL_NAT_FRIENDLY_INITS_MAX);
+ RANGECHK(SCTP_BASE_SYSCTL(sctp_blackhole), SCTPCTL_BLACKHOLE_MIN, SCTPCTL_BLACKHOLE_MAX);
+ RANGECHK(SCTP_BASE_SYSCTL(sctp_diag_info_code), SCTPCTL_DIAG_INFO_CODE_MIN, SCTPCTL_DIAG_INFO_CODE_MAX);
+#ifdef SCTP_DEBUG
+ RANGECHK(SCTP_BASE_SYSCTL(sctp_debug_on), SCTPCTL_DEBUG_MIN, SCTPCTL_DEBUG_MAX);
+#endif
+ }
+ return (error);
+}
+
+void
+sysctl_setup_sctp(void)
{
sysctl_add_oid(&sysctl_oid_top, "sendspace", CTLTYPE_INT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_sendspace), 0, sysctl_sctp_check,
+ &SCTP_BASE_SYSCTL(sctp_sendspace), 0, sctp_sysctl_handle_int,
SCTPCTL_MAXDGRAM_DESC);
sysctl_add_oid(&sysctl_oid_top, "recvspace", CTLTYPE_INT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_recvspace), 0, sysctl_sctp_check,
+ &SCTP_BASE_SYSCTL(sctp_recvspace), 0, sctp_sysctl_handle_int,
SCTPCTL_RECVSPACE_DESC);
sysctl_add_oid(&sysctl_oid_top, "auto_asconf", CTLTYPE_INT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_auto_asconf), 0, sysctl_sctp_check,
+ &SCTP_BASE_SYSCTL(sctp_auto_asconf), 0, sctp_sysctl_handle_int,
SCTPCTL_AUTOASCONF_DESC);
sysctl_add_oid(&sysctl_oid_top, "ecn_enable", CTLTYPE_INT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_ecn_enable), 0, sysctl_sctp_check,
+ &SCTP_BASE_SYSCTL(sctp_ecn_enable), 0, sctp_sysctl_handle_int,
SCTPCTL_ECN_ENABLE_DESC);
+ sysctl_add_oid(&sysctl_oid_top, "pr_enable", CTLTYPE_INT|CTLFLAG_RW,
+ &SCTP_BASE_SYSCTL(sctp_pr_enable), 0, sctp_sysctl_handle_int,
+ SCTPCTL_PR_ENABLE_DESC);
+
+ sysctl_add_oid(&sysctl_oid_top, "auth_enable", CTLTYPE_INT|CTLFLAG_RW,
+ &SCTP_BASE_SYSCTL(sctp_auth_enable), 0, sctp_sysctl_handle_auth,
+ SCTPCTL_AUTH_ENABLE_DESC);
+
+ sysctl_add_oid(&sysctl_oid_top, "asconf_enable", CTLTYPE_INT|CTLFLAG_RW,
+ &SCTP_BASE_SYSCTL(sctp_asconf_enable), 0, sctp_sysctl_handle_asconf,
+ SCTPCTL_ASCONF_ENABLE_DESC);
+
+ sysctl_add_oid(&sysctl_oid_top, "reconfig_enable", CTLTYPE_INT|CTLFLAG_RW,
+ &SCTP_BASE_SYSCTL(sctp_reconfig_enable), 0, sctp_sysctl_handle_int,
+ SCTPCTL_RECONFIG_ENABLE_DESC);
+
+ sysctl_add_oid(&sysctl_oid_top, "nrsack_enable", CTLTYPE_INT|CTLFLAG_RW,
+ &SCTP_BASE_SYSCTL(sctp_nrsack_enable), 0, sctp_sysctl_handle_int,
+ SCTPCTL_NRSACK_ENABLE_DESC);
+
+ sysctl_add_oid(&sysctl_oid_top, "pktdrop_enable", CTLTYPE_INT|CTLFLAG_RW,
+ &SCTP_BASE_SYSCTL(sctp_pktdrop_enable), 0, sctp_sysctl_handle_int,
+ SCTPCTL_PKTDROP_ENABLE_DESC);
+
sysctl_add_oid(&sysctl_oid_top, "strict_sacks", CTLTYPE_INT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_strict_sacks), 0, sysctl_sctp_check,
+ &SCTP_BASE_SYSCTL(sctp_strict_sacks), 0, sctp_sysctl_handle_int,
SCTPCTL_STRICT_SACKS_DESC);
-#if !(defined(__FreeBSD__) && __FreeBSD_version >= 800000)
#if !defined(SCTP_WITH_NO_CSUM)
sysctl_add_oid(&sysctl_oid_top, "loopback_nocsum", CTLTYPE_INT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_no_csum_on_loopback), 0, sysctl_sctp_check,
+ &SCTP_BASE_SYSCTL(sctp_no_csum_on_loopback), 0, sctp_sysctl_handle_int,
SCTPCTL_LOOPBACK_NOCSUM_DESC);
#endif
-#endif
sysctl_add_oid(&sysctl_oid_top, "peer_chkoh", CTLTYPE_INT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_peer_chunk_oh), 0, sysctl_sctp_check,
+ &SCTP_BASE_SYSCTL(sctp_peer_chunk_oh), 0, sctp_sysctl_handle_int,
SCTPCTL_PEER_CHKOH_DESC);
sysctl_add_oid(&sysctl_oid_top, "maxburst", CTLTYPE_INT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_max_burst_default), 0, sysctl_sctp_check,
+ &SCTP_BASE_SYSCTL(sctp_max_burst_default), 0, sctp_sysctl_handle_int,
SCTPCTL_MAXBURST_DESC);
sysctl_add_oid(&sysctl_oid_top, "fr_maxburst", CTLTYPE_INT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_fr_max_burst_default), 0, sysctl_sctp_check,
+ &SCTP_BASE_SYSCTL(sctp_fr_max_burst_default), 0, sctp_sysctl_handle_int,
SCTPCTL_FRMAXBURST_DESC);
sysctl_add_oid(&sysctl_oid_top, "maxchunks", CTLTYPE_INT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_max_chunks_on_queue), 0, sysctl_sctp_check,
+ &SCTP_BASE_SYSCTL(sctp_max_chunks_on_queue), 0, sctp_sysctl_handle_int,
SCTPCTL_MAXCHUNKS_DESC);
sysctl_add_oid(&sysctl_oid_top, "tcbhashsize", CTLTYPE_INT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_hashtblsize), 0, sysctl_sctp_check,
+ &SCTP_BASE_SYSCTL(sctp_hashtblsize), 0, sctp_sysctl_handle_int,
SCTPCTL_TCBHASHSIZE_DESC);
sysctl_add_oid(&sysctl_oid_top, "pcbhashsize", CTLTYPE_INT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_pcbtblsize), 0, sysctl_sctp_check,
+ &SCTP_BASE_SYSCTL(sctp_pcbtblsize), 0, sctp_sysctl_handle_int,
SCTPCTL_PCBHASHSIZE_DESC);
sysctl_add_oid(&sysctl_oid_top, "min_split_point", CTLTYPE_INT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_min_split_point), 0, sysctl_sctp_check,
+ &SCTP_BASE_SYSCTL(sctp_min_split_point), 0, sctp_sysctl_handle_int,
SCTPCTL_MIN_SPLIT_POINT_DESC);
sysctl_add_oid(&sysctl_oid_top, "chunkscale", CTLTYPE_INT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_chunkscale), 0, sysctl_sctp_check,
+ &SCTP_BASE_SYSCTL(sctp_chunkscale), 0, sctp_sysctl_handle_int,
SCTPCTL_CHUNKSCALE_DESC);
sysctl_add_oid(&sysctl_oid_top, "delayed_sack_time", CTLTYPE_INT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_delayed_sack_time_default), 0, sysctl_sctp_check,
+ &SCTP_BASE_SYSCTL(sctp_delayed_sack_time_default), 0, sctp_sysctl_handle_int,
SCTPCTL_DELAYED_SACK_TIME_DESC);
sysctl_add_oid(&sysctl_oid_top, "sack_freq", CTLTYPE_INT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_sack_freq_default), 0, sysctl_sctp_check,
+ &SCTP_BASE_SYSCTL(sctp_sack_freq_default), 0, sctp_sysctl_handle_int,
SCTPCTL_SACK_FREQ_DESC);
sysctl_add_oid(&sysctl_oid_top, "sys_resource", CTLTYPE_INT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_system_free_resc_limit), 0, sysctl_sctp_check,
+ &SCTP_BASE_SYSCTL(sctp_system_free_resc_limit), 0, sctp_sysctl_handle_int,
SCTPCTL_SYS_RESOURCE_DESC);
sysctl_add_oid(&sysctl_oid_top, "asoc_resource", CTLTYPE_INT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_asoc_free_resc_limit), 0, sysctl_sctp_check,
+ &SCTP_BASE_SYSCTL(sctp_asoc_free_resc_limit), 0, sctp_sysctl_handle_int,
SCTPCTL_ASOC_RESOURCE_DESC);
sysctl_add_oid(&sysctl_oid_top, "heartbeat_interval", CTLTYPE_INT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_heartbeat_interval_default), 0, sysctl_sctp_check,
+ &SCTP_BASE_SYSCTL(sctp_heartbeat_interval_default), 0, sctp_sysctl_handle_int,
SCTPCTL_HEARTBEAT_INTERVAL_DESC);
sysctl_add_oid(&sysctl_oid_top, "pmtu_raise_time", CTLTYPE_INT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_pmtu_raise_time_default), 0, sysctl_sctp_check,
+ &SCTP_BASE_SYSCTL(sctp_pmtu_raise_time_default), 0, sctp_sysctl_handle_int,
SCTPCTL_PMTU_RAISE_TIME_DESC);
sysctl_add_oid(&sysctl_oid_top, "shutdown_guard_time", CTLTYPE_INT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_shutdown_guard_time_default), 0, sysctl_sctp_check,
+ &SCTP_BASE_SYSCTL(sctp_shutdown_guard_time_default), 0, sctp_sysctl_handle_int,
SCTPCTL_SHUTDOWN_GUARD_TIME_DESC);
sysctl_add_oid(&sysctl_oid_top, "secret_lifetime", CTLTYPE_INT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_secret_lifetime_default), 0, sysctl_sctp_check,
+ &SCTP_BASE_SYSCTL(sctp_secret_lifetime_default), 0, sctp_sysctl_handle_int,
SCTPCTL_SECRET_LIFETIME_DESC);
sysctl_add_oid(&sysctl_oid_top, "rto_max", CTLTYPE_INT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_rto_max_default), 0, sysctl_sctp_check,
+ &SCTP_BASE_SYSCTL(sctp_rto_max_default), 0, sctp_sysctl_handle_int,
SCTPCTL_RTO_MAX_DESC);
sysctl_add_oid(&sysctl_oid_top, "rto_min", CTLTYPE_INT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_rto_min_default), 0, sysctl_sctp_check,
+ &SCTP_BASE_SYSCTL(sctp_rto_min_default), 0, sctp_sysctl_handle_int,
SCTPCTL_RTO_MIN_DESC);
sysctl_add_oid(&sysctl_oid_top, "rto_initial", CTLTYPE_INT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_rto_initial_default), 0, sysctl_sctp_check,
+ &SCTP_BASE_SYSCTL(sctp_rto_initial_default), 0, sctp_sysctl_handle_int,
SCTPCTL_RTO_INITIAL_DESC);
sysctl_add_oid(&sysctl_oid_top, "init_rto_max", CTLTYPE_INT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_init_rto_max_default), 0, sysctl_sctp_check,
+ &SCTP_BASE_SYSCTL(sctp_init_rto_max_default), 0, sctp_sysctl_handle_int,
SCTPCTL_INIT_RTO_MAX_DESC);
sysctl_add_oid(&sysctl_oid_top, "valid_cookie_life", CTLTYPE_INT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_valid_cookie_life_default), 0, sysctl_sctp_check,
+ &SCTP_BASE_SYSCTL(sctp_valid_cookie_life_default), 0, sctp_sysctl_handle_int,
SCTPCTL_VALID_COOKIE_LIFE_DESC);
sysctl_add_oid(&sysctl_oid_top, "init_rtx_max", CTLTYPE_INT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_init_rtx_max_default), 0, sysctl_sctp_check,
+ &SCTP_BASE_SYSCTL(sctp_init_rtx_max_default), 0, sctp_sysctl_handle_int,
SCTPCTL_INIT_RTX_MAX_DESC);
sysctl_add_oid(&sysctl_oid_top, "assoc_rtx_max", CTLTYPE_INT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_assoc_rtx_max_default), 0, sysctl_sctp_check,
+ &SCTP_BASE_SYSCTL(sctp_assoc_rtx_max_default), 0, sctp_sysctl_handle_int,
SCTPCTL_ASSOC_RTX_MAX_DESC);
sysctl_add_oid(&sysctl_oid_top, "path_rtx_max", CTLTYPE_INT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_path_rtx_max_default), 0, sysctl_sctp_check,
+ &SCTP_BASE_SYSCTL(sctp_path_rtx_max_default), 0, sctp_sysctl_handle_int,
SCTPCTL_PATH_RTX_MAX_DESC);
sysctl_add_oid(&sysctl_oid_top, "path_pf_threshold", CTLTYPE_INT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_path_pf_threshold), 0, sysctl_sctp_check,
+ &SCTP_BASE_SYSCTL(sctp_path_pf_threshold), 0, sctp_sysctl_handle_int,
SCTPCTL_PATH_PF_THRESHOLD_DESC);
sysctl_add_oid(&sysctl_oid_top, "add_more_on_output", CTLTYPE_INT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_add_more_threshold), 0, sysctl_sctp_check,
+ &SCTP_BASE_SYSCTL(sctp_add_more_threshold), 0, sctp_sysctl_handle_int,
SCTPCTL_ADD_MORE_ON_OUTPUT_DESC);
sysctl_add_oid(&sysctl_oid_top, "incoming_streams", CTLTYPE_INT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_nr_incoming_streams_default), 0, sysctl_sctp_check,
+ &SCTP_BASE_SYSCTL(sctp_nr_incoming_streams_default), 0, sctp_sysctl_handle_int,
SCTPCTL_INCOMING_STREAMS_DESC);
sysctl_add_oid(&sysctl_oid_top, "outgoing_streams", CTLTYPE_INT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_nr_outgoing_streams_default), 0, sysctl_sctp_check,
+ &SCTP_BASE_SYSCTL(sctp_nr_outgoing_streams_default), 0, sctp_sysctl_handle_int,
SCTPCTL_OUTGOING_STREAMS_DESC);
sysctl_add_oid(&sysctl_oid_top, "cmt_on_off", CTLTYPE_INT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_cmt_on_off), 0, sysctl_sctp_check,
+ &SCTP_BASE_SYSCTL(sctp_cmt_on_off), 0, sctp_sysctl_handle_int,
SCTPCTL_CMT_ON_OFF_DESC);
- /* EY */
- sysctl_add_oid(&sysctl_oid_top, "nr_sack_on_off", CTLTYPE_INT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_nr_sack_on_off), 0, sysctl_sctp_check,
- SCTPCTL_NR_SACK_ON_OFF_DESC);
-
sysctl_add_oid(&sysctl_oid_top, "cmt_use_dac", CTLTYPE_INT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_cmt_use_dac), 0, sysctl_sctp_check,
+ &SCTP_BASE_SYSCTL(sctp_cmt_use_dac), 0, sctp_sysctl_handle_int,
SCTPCTL_CMT_USE_DAC_DESC);
sysctl_add_oid(&sysctl_oid_top, "cwnd_maxburst", CTLTYPE_INT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_use_cwnd_based_maxburst), 0, sysctl_sctp_check,
+ &SCTP_BASE_SYSCTL(sctp_use_cwnd_based_maxburst), 0, sctp_sysctl_handle_int,
SCTPCTL_CWND_MAXBURST_DESC);
- sysctl_add_oid(&sysctl_oid_top, "asconf_auth_nochk", CTLTYPE_INT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_asconf_auth_nochk), 0, sysctl_sctp_check,
- SCTPCTL_ASCONF_AUTH_NOCHK_DESC);
-
- sysctl_add_oid(&sysctl_oid_top, "auth_disable", CTLTYPE_INT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_auth_disable), 0, sysctl_sctp_check,
- SCTPCTL_AUTH_DISABLE_DESC);
-
sysctl_add_oid(&sysctl_oid_top, "nat_friendly", CTLTYPE_INT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_nat_friendly), 0, sysctl_sctp_check,
+ &SCTP_BASE_SYSCTL(sctp_nat_friendly), 0, sctp_sysctl_handle_int,
SCTPCTL_NAT_FRIENDLY_DESC);
sysctl_add_oid(&sysctl_oid_top, "abc_l_var", CTLTYPE_INT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_L2_abc_variable), 0, sysctl_sctp_check,
+ &SCTP_BASE_SYSCTL(sctp_L2_abc_variable), 0, sctp_sysctl_handle_int,
SCTPCTL_ABC_L_VAR_DESC);
sysctl_add_oid(&sysctl_oid_top, "max_chained_mbufs", CTLTYPE_INT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_mbuf_threshold_count), 0, sysctl_sctp_check,
+ &SCTP_BASE_SYSCTL(sctp_mbuf_threshold_count), 0, sctp_sysctl_handle_int,
SCTPCTL_MAX_CHAINED_MBUFS_DESC);
sysctl_add_oid(&sysctl_oid_top, "do_sctp_drain", CTLTYPE_INT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_do_drain), 0, sysctl_sctp_check,
+ &SCTP_BASE_SYSCTL(sctp_do_drain), 0, sctp_sysctl_handle_int,
SCTPCTL_DO_SCTP_DRAIN_DESC);
sysctl_add_oid(&sysctl_oid_top, "hb_max_burst", CTLTYPE_INT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_hb_maxburst), 0, sysctl_sctp_check,
+ &SCTP_BASE_SYSCTL(sctp_hb_maxburst), 0, sctp_sysctl_handle_int,
SCTPCTL_HB_MAX_BURST_DESC);
sysctl_add_oid(&sysctl_oid_top, "abort_at_limit", CTLTYPE_INT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_abort_if_one_2_one_hits_limit), 0, sysctl_sctp_check,
+ &SCTP_BASE_SYSCTL(sctp_abort_if_one_2_one_hits_limit), 0, sctp_sysctl_handle_int,
SCTPCTL_ABORT_AT_LIMIT_DESC);
sysctl_add_oid(&sysctl_oid_top, "strict_data_order", CTLTYPE_INT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_strict_data_order), 0, sysctl_sctp_check,
+ &SCTP_BASE_SYSCTL(sctp_strict_data_order), 0, sctp_sysctl_handle_int,
SCTPCTL_STRICT_DATA_ORDER_DESC);
sysctl_add_oid(&sysctl_oid_top, "min_residual", CTLTYPE_INT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_min_residual), 0, sysctl_sctp_check,
+ &SCTP_BASE_SYSCTL(sctp_min_residual), 0, sctp_sysctl_handle_int,
SCTPCTL_MIN_RESIDUAL_DESC);
sysctl_add_oid(&sysctl_oid_top, "max_retran_chunk", CTLTYPE_INT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_max_retran_chunk), 0, sysctl_sctp_check,
+ &SCTP_BASE_SYSCTL(sctp_max_retran_chunk), 0, sctp_sysctl_handle_int,
SCTPCTL_MAX_RETRAN_CHUNK_DESC);
sysctl_add_oid(&sysctl_oid_top, "log_level", CTLTYPE_INT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_logging_level), 0, sysctl_sctp_check,
+ &SCTP_BASE_SYSCTL(sctp_logging_level), 0, sctp_sysctl_handle_int,
SCTPCTL_LOGGING_LEVEL_DESC);
sysctl_add_oid(&sysctl_oid_top, "default_cc_module", CTLTYPE_INT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_default_cc_module), 0, sysctl_sctp_check,
+ &SCTP_BASE_SYSCTL(sctp_default_cc_module), 0, sctp_sysctl_handle_int,
SCTPCTL_DEFAULT_CC_MODULE_DESC);
sysctl_add_oid(&sysctl_oid_top, "default_ss_module", CTLTYPE_INT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_default_ss_module), 0, sysctl_sctp_check,
+ &SCTP_BASE_SYSCTL(sctp_default_ss_module), 0, sctp_sysctl_handle_int,
SCTPCTL_DEFAULT_SS_MODULE_DESC);
sysctl_add_oid(&sysctl_oid_top, "default_frag_interleave", CTLTYPE_INT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_default_frag_interleave), 0, sysctl_sctp_check,
+ &SCTP_BASE_SYSCTL(sctp_default_frag_interleave), 0, sctp_sysctl_handle_int,
SCTPCTL_DEFAULT_FRAG_INTERLEAVE_DESC);
sysctl_add_oid(&sysctl_oid_top, "mobility_base", CTLTYPE_INT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_mobility_base), 0, sysctl_sctp_check,
+ &SCTP_BASE_SYSCTL(sctp_mobility_base), 0, sctp_sysctl_handle_int,
SCTPCTL_MOBILITY_BASE_DESC);
sysctl_add_oid(&sysctl_oid_top, "mobility_fasthandoff", CTLTYPE_INT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_mobility_fasthandoff), 0, sysctl_sctp_check,
+ &SCTP_BASE_SYSCTL(sctp_mobility_fasthandoff), 0, sctp_sysctl_handle_int,
SCTPCTL_MOBILITY_FASTHANDOFF_DESC);
#if defined(SCTP_LOCAL_TRACE_BUF)
@@ -1641,67 +1602,67 @@ void sysctl_setup_sctp(void)
"SCTP logging (struct sctp_log)");
sysctl_add_oid(&sysctl_oid_top, "clear_trace", CTLTYPE_INT|CTLFLAG_WR,
- NULL, 0, sysctl_sctp_cleartrace,
+ NULL, 0, sctp_sysctl_handle_trace_log_clear,
"Clear SCTP Logging buffer");
#endif
sysctl_add_oid(&sysctl_oid_top, "udp_tunneling_port", CTLTYPE_INT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_udp_tunneling_port), 0, sysctl_sctp_udp_tunneling_check,
+ &SCTP_BASE_SYSCTL(sctp_udp_tunneling_port), 0, sctp_sysctl_handle_udp_tunneling,
SCTPCTL_UDP_TUNNELING_PORT_DESC);
sysctl_add_oid(&sysctl_oid_top, "enable_sack_immediately", CTLTYPE_INT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_enable_sack_immediately), 0, sysctl_sctp_check,
+ &SCTP_BASE_SYSCTL(sctp_enable_sack_immediately), 0, sctp_sysctl_handle_int,
SCTPCTL_SACK_IMMEDIATELY_ENABLE_DESC);
sysctl_add_oid(&sysctl_oid_top, "nat_friendly_init", CTLTYPE_INT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_inits_include_nat_friendly), 0, sysctl_sctp_check,
+ &SCTP_BASE_SYSCTL(sctp_inits_include_nat_friendly), 0, sctp_sysctl_handle_int,
SCTPCTL_NAT_FRIENDLY_DESC);
sysctl_add_oid(&sysctl_oid_top, "vtag_time_wait", CTLTYPE_INT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_vtag_time_wait), 0, sysctl_sctp_check,
+ &SCTP_BASE_SYSCTL(sctp_vtag_time_wait), 0, sctp_sysctl_handle_int,
SCTPCTL_TIME_WAIT_DESC);
sysctl_add_oid(&sysctl_oid_top, "buffer_splitting", CTLTYPE_INT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_buffer_splitting), 0, sysctl_sctp_check,
+ &SCTP_BASE_SYSCTL(sctp_buffer_splitting), 0, sctp_sysctl_handle_int,
SCTPCTL_BUFFER_SPLITTING_DESC);
sysctl_add_oid(&sysctl_oid_top, "initial_cwnd", CTLTYPE_INT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_initial_cwnd), 0, sysctl_sctp_check,
+ &SCTP_BASE_SYSCTL(sctp_initial_cwnd), 0, sctp_sysctl_handle_int,
SCTPCTL_INITIAL_CWND_DESC);
sysctl_add_oid(&sysctl_oid_top, "rttvar_bw", CTLTYPE_INT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_rttvar_bw), 0, sysctl_sctp_check,
+ &SCTP_BASE_SYSCTL(sctp_rttvar_bw), 0, sctp_sysctl_handle_int,
SCTPCTL_RTTVAR_BW_DESC);
sysctl_add_oid(&sysctl_oid_top, "rttvar_rtt", CTLTYPE_INT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_rttvar_rtt), 0, sysctl_sctp_check,
+ &SCTP_BASE_SYSCTL(sctp_rttvar_rtt), 0, sctp_sysctl_handle_int,
SCTPCTL_RTTVAR_RTT_DESC);
sysctl_add_oid(&sysctl_oid_top, "rttvar_eqret", CTLTYPE_INT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_rttvar_eqret), 0, sysctl_sctp_check,
+ &SCTP_BASE_SYSCTL(sctp_rttvar_eqret), 0, sctp_sysctl_handle_int,
SCTPCTL_RTTVAR_EQRET_DESC);
sysctl_add_oid(&sysctl_oid_top, "rttvar_steady_step", CTLTYPE_INT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_steady_step), 0, sysctl_sctp_check,
+ &SCTP_BASE_SYSCTL(sctp_steady_step), 0, sctp_sysctl_handle_int,
SCTPCTL_RTTVAR_STEADYS_DESC);
sysctl_add_oid(&sysctl_oid_top, "use_dcccecn", CTLTYPE_INT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_use_dccc_ecn), 0, sysctl_sctp_check,
+ &SCTP_BASE_SYSCTL(sctp_use_dccc_ecn), 0, sctp_sysctl_handle_int,
SCTPCTL_RTTVAR_DCCCECN_DESC);
sysctl_add_oid(&sysctl_oid_top, "blackhole", CTLTYPE_INT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_blackhole), 0, sysctl_sctp_check,
- SCTPCTL_BLACKHOLE_DESC);
+ &SCTP_BASE_SYSCTL(sctp_blackhole), 0, sctp_sysctl_handle_int,
+ SCTPCTL_BLACKHOLE_DESC);
sysctl_add_oid(&sysctl_oid_top, "diag_info_code", CTLTYPE_INT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_diag_info_code), 0, sysctl_sctp_check,
- SCTPCTL_DIAG_INFO_CODE_DESC);
+ &SCTP_BASE_SYSCTL(sctp_diag_info_code), 0, sctp_sysctl_handle_int,
+ SCTPCTL_DIAG_INFO_CODE_DESC);
#ifdef SCTP_DEBUG
sysctl_add_oid(&sysctl_oid_top, "debug", CTLTYPE_INT|CTLFLAG_RW,
- &SCTP_BASE_SYSCTL(sctp_debug_on), sizeof(SCTP_BASE_SYSCTL(sctp_debug_on)), NULL,
+ &SCTP_BASE_SYSCTL(sctp_debug_on), 0, sctp_sysctl_handle_int,
SCTPCTL_DEBUG_DESC);
-#endif /* SCTP_DEBUG */
+#endif
sysctl_add_oid(&sysctl_oid_top, "stats", CTLTYPE_STRUCT|CTLFLAG_RW,
&SCTP_BASE_STATS, sizeof(SCTP_BASE_STATS), NULL,
diff --git a/netinet/sctp_sysctl.h b/netinet/sctp_sysctl.h
index 0b6cb16..3a33b71 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 263921 2014-03-29 20:21:36Z tuexen $");
+__FBSDID("$FreeBSD: head/sys/netinet/sctp_sysctl.h 271204 2014-09-06 19:12:14Z tuexen $");
#endif
#ifndef _NETINET_SCTP_SYSCTL_H_
@@ -47,6 +47,12 @@ 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_auth_enable;
+ uint32_t sctp_asconf_enable;
+ uint32_t sctp_reconfig_enable;
+ uint32_t sctp_nrsack_enable;
+ uint32_t sctp_pktdrop_enable;
uint32_t sctp_fr_max_burst_default;
uint32_t sctp_strict_sacks;
#if !(defined(__FreeBSD__) && __FreeBSD_version >= 800000)
@@ -83,11 +89,7 @@ struct sctp_sysctl {
uint32_t sctp_nr_outgoing_streams_default;
uint32_t sctp_cmt_on_off;
uint32_t sctp_cmt_use_dac;
- /* EY 5/5/08 - nr_sack flag variable */
- uint32_t sctp_nr_sack_on_off;
uint32_t sctp_use_cwnd_based_maxburst;
- uint32_t sctp_asconf_auth_nochk;
- uint32_t sctp_auth_disable;
uint32_t sctp_nat_friendly;
uint32_t sctp_L2_abc_variable;
uint32_t sctp_mbuf_threshold_count;
@@ -158,7 +160,7 @@ struct sctp_sysctl {
#define SCTPCTL_AUTOASCONF_DESC "Enable SCTP Auto-ASCONF"
#define SCTPCTL_AUTOASCONF_MIN 0
#define SCTPCTL_AUTOASCONF_MAX 1
-#define SCTPCTL_AUTOASCONF_DEFAULT SCTP_DEFAULT_AUTO_ASCONF
+#define SCTPCTL_AUTOASCONF_DEFAULT 1
/* autoasconf: Enable SCTP Auto-ASCONF */
#define SCTPCTL_MULTIPLEASCONFS_DESC "Enable SCTP Muliple-ASCONFs"
@@ -172,6 +174,42 @@ 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
+
+/* auth_enable: Enable SCTP AUTH function */
+#define SCTPCTL_AUTH_ENABLE_DESC "Enable SCTP AUTH function"
+#define SCTPCTL_AUTH_ENABLE_MIN 0
+#define SCTPCTL_AUTH_ENABLE_MAX 1
+#define SCTPCTL_AUTH_ENABLE_DEFAULT 1
+
+/* asconf_enable: Enable SCTP ASCONF */
+#define SCTPCTL_ASCONF_ENABLE_DESC "Enable SCTP ASCONF"
+#define SCTPCTL_ASCONF_ENABLE_MIN 0
+#define SCTPCTL_ASCONF_ENABLE_MAX 1
+#define SCTPCTL_ASCONF_ENABLE_DEFAULT 1
+
+/* reconfig_enable: Enable SCTP RE-CONFIG */
+#define SCTPCTL_RECONFIG_ENABLE_DESC "Enable SCTP RE-CONFIG"
+#define SCTPCTL_RECONFIG_ENABLE_MIN 0
+#define SCTPCTL_RECONFIG_ENABLE_MAX 1
+#define SCTPCTL_RECONFIG_ENABLE_DEFAULT 1
+
+/* nrsack_enable: Enable NR_SACK */
+#define SCTPCTL_NRSACK_ENABLE_DESC "Enable SCTP NR-SACK"
+#define SCTPCTL_NRSACK_ENABLE_MIN 0
+#define SCTPCTL_NRSACK_ENABLE_MAX 1
+#define SCTPCTL_NRSACK_ENABLE_DEFAULT 0
+
+/* pktdrop_enable: Enable SCTP Packet Drop Reports */
+#define SCTPCTL_PKTDROP_ENABLE_DESC "Enable SCTP PKTDROP"
+#define SCTPCTL_PKTDROP_ENABLE_MIN 0
+#define SCTPCTL_PKTDROP_ENABLE_MAX 1
+#define SCTPCTL_PKTDROP_ENABLE_DEFAULT 0
+
/* strict_sacks: Enable SCTP Strict SACK checking */
#define SCTPCTL_STRICT_SACKS_DESC "Enable SCTP Strict SACK checking"
#define SCTPCTL_STRICT_SACKS_MIN 0
@@ -359,12 +397,6 @@ struct sctp_sysctl {
#define SCTPCTL_CMT_ON_OFF_MAX SCTP_CMT_MAX
#define SCTPCTL_CMT_ON_OFF_DEFAULT SCTP_CMT_OFF
-/* EY - nr_sack_on_off: NR_SACK on/off flag */
-#define SCTPCTL_NR_SACK_ON_OFF_DESC "NR_SACK on/off flag"
-#define SCTPCTL_NR_SACK_ON_OFF_MIN 0
-#define SCTPCTL_NR_SACK_ON_OFF_MAX 1
-#define SCTPCTL_NR_SACK_ON_OFF_DEFAULT 0
-
/* cmt_use_dac: CMT DAC on/off flag */
#define SCTPCTL_CMT_USE_DAC_DESC "CMT DAC on/off flag"
#define SCTPCTL_CMT_USE_DAC_MIN 0
@@ -377,18 +409,6 @@ struct sctp_sysctl {
#define SCTPCTL_CWND_MAXBURST_MAX 1
#define SCTPCTL_CWND_MAXBURST_DEFAULT 1
-/* asconf_auth_nochk: Disable SCTP ASCONF AUTH requirement */
-#define SCTPCTL_ASCONF_AUTH_NOCHK_DESC "Disable SCTP ASCONF AUTH requirement"
-#define SCTPCTL_ASCONF_AUTH_NOCHK_MIN 0
-#define SCTPCTL_ASCONF_AUTH_NOCHK_MAX 1
-#define SCTPCTL_ASCONF_AUTH_NOCHK_DEFAULT 0
-
-/* auth_disable: Disable SCTP AUTH function */
-#define SCTPCTL_AUTH_DISABLE_DESC "Disable SCTP AUTH function"
-#define SCTPCTL_AUTH_DISABLE_MIN 0
-#define SCTPCTL_AUTH_DISABLE_MAX 1
-#define SCTPCTL_AUTH_DISABLE_DEFAULT 0
-
/* nat_friendly: SCTP NAT friendly operation */
#define SCTPCTL_NAT_FRIENDLY_DESC "SCTP NAT friendly operation"
#define SCTPCTL_NAT_FRIENDLY_MIN 0
@@ -471,13 +491,13 @@ struct sctp_sysctl {
#define SCTPCTL_MOBILITY_BASE_DESC "Enable SCTP base mobility"
#define SCTPCTL_MOBILITY_BASE_MIN 0
#define SCTPCTL_MOBILITY_BASE_MAX 1
-#define SCTPCTL_MOBILITY_BASE_DEFAULT SCTP_DEFAULT_MOBILITY_BASE
+#define SCTPCTL_MOBILITY_BASE_DEFAULT 0
/* mobility_fasthandoff: Enable SCTP fast handoff support */
#define SCTPCTL_MOBILITY_FASTHANDOFF_DESC "Enable SCTP fast handoff"
#define SCTPCTL_MOBILITY_FASTHANDOFF_MIN 0
#define SCTPCTL_MOBILITY_FASTHANDOFF_MAX 1
-#define SCTPCTL_MOBILITY_FASTHANDOFF_DEFAULT SCTP_DEFAULT_MOBILITY_FASTHANDOFF
+#define SCTPCTL_MOBILITY_FASTHANDOFF_DEFAULT 0
/* Enable SCTP/UDP tunneling port */
#define SCTPCTL_UDP_TUNNELING_PORT_DESC "Set the SCTP/UDP tunneling port"
@@ -584,12 +604,14 @@ struct sctp_sysctl {
#endif
#if defined(__APPLE__)
-#define SCTPCTL_ADDR_WATCHDOG_LIMIT_MIN 0
-#define SCTPCTL_ADDR_WATCHDOG_LIMIT_MAX 0xFFFFFFFF
+#define SCTPCTL_ADDR_WATCHDOG_LIMIT_DESC "Address watchdog limit"
+#define SCTPCTL_ADDR_WATCHDOG_LIMIT_MIN 0
+#define SCTPCTL_ADDR_WATCHDOG_LIMIT_MAX 0xFFFFFFFF
#define SCTPCTL_ADDR_WATCHDOG_LIMIT_DEFAULT SCTPCTL_ADDR_WATCHDOG_LIMIT_MIN
-#define SCTPCTL_VTAG_WATCHDOG_LIMIT_MIN 0
-#define SCTPCTL_VTAG_WATCHDOG_LIMIT_MAX 0xFFFFFFFF
+#define SCTPCTL_VTAG_WATCHDOG_LIMIT_DESC "VTag watchdog limit"
+#define SCTPCTL_VTAG_WATCHDOG_LIMIT_MIN 0
+#define SCTPCTL_VTAG_WATCHDOG_LIMIT_MAX 0xFFFFFFFF
#define SCTPCTL_VTAG_WATCHDOG_LIMIT_DEFAULT SCTPCTL_VTAG_WATCHDOG_LIMIT_MIN
#endif
diff --git a/netinet/sctp_timer.c b/netinet/sctp_timer.c
index 9627dc5..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 263237 2014-03-16 12:32:16Z tuexen $");
+__FBSDID("$FreeBSD: head/sys/netinet/sctp_timer.c 269448 2014-08-02 21:36:40Z tuexen $");
#endif
#define _IP_VHL
@@ -54,7 +54,7 @@ __FBSDID("$FreeBSD: head/sys/netinet/sctp_timer.c 263237 2014-03-16 12:32:16Z tu
#include <netinet/sctp_input.h>
#include <netinet/sctp.h>
#include <netinet/sctp_uio.h>
-#if defined INET || defined INET6
+#if defined(INET) || defined(INET6)
#if !defined(__Userspace_os_Windows)
#include <netinet/udp.h>
#endif
@@ -218,7 +218,7 @@ sctp_find_alternate_net(struct sctp_tcb *stcb,
* t3 handler.
*/
if (mnet == net) {
- if (min_errors == -1) {
+ if (min_errors == -1) {
min_errors = mnet->error_count + 1;
min_errors_net = mnet;
} else if (mnet->error_count + 1 < min_errors) {
@@ -231,7 +231,7 @@ sctp_find_alternate_net(struct sctp_tcb *stcb,
}
continue;
} else {
- if (min_errors == -1) {
+ if (min_errors == -1) {
min_errors = mnet->error_count;
min_errors_net = mnet;
} else if (mnet->error_count < min_errors) {
@@ -335,7 +335,7 @@ sctp_find_alternate_net(struct sctp_tcb *stcb,
do {
alt = TAILQ_NEXT(mnet, sctp_next);
if (alt == NULL)
- {
+ {
once++;
if (once > 1) {
break;
@@ -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) {
@@ -926,9 +926,9 @@ sctp_t3rxt_timer(struct sctp_inpcb *inp,
*/
if (net->ro._s_addr) {
sctp_free_ifa(net->ro._s_addr);
- net->ro._s_addr = NULL;
+ net->ro._s_addr = NULL;
}
- net->src_addr_selected = 0;
+ net->src_addr_selected = 0;
/* Force a route allocation too */
if (net->ro.ro_rt) {
@@ -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);
@@ -1479,7 +1479,7 @@ sctp_pathmtu_timer(struct sctp_inpcb *inp,
#elif defined(SCTP_KAME)
(void)sa6_embedscope(sin6, MODULE_GLOBAL(ip6_use_defzone));
#else
- (void)in6_embedscope(&sin6->sin6_addr, sin6);
+ (void)in6_embedscope(&sin6->sin6_addr, sin6);
#endif
}
#endif
@@ -1504,7 +1504,7 @@ sctp_pathmtu_timer(struct sctp_inpcb *inp,
}
if (net->ro._s_addr) {
mtu = SCTP_GATHER_MTU_FROM_ROUTE(net->ro._s_addr, &net->ro._s_addr.sa, net->ro.ro_rt);
-#if defined INET || defined INET6
+#if defined(INET) || defined(INET6)
if (net->port) {
mtu -= sizeof(struct udphdr);
}
diff --git a/netinet/sctp_uio.h b/netinet/sctp_uio.h
index 7d84313..7cf02ed 100755
--- a/netinet/sctp_uio.h
+++ b/netinet/sctp_uio.h
@@ -32,7 +32,7 @@
#ifdef __FreeBSD__
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/netinet/sctp_uio.h 255160 2013-09-02 22:48:41Z tuexen $");
+__FBSDID("$FreeBSD: head/sys/netinet/sctp_uio.h 269945 2014-08-13 15:50:16Z tuexen $");
#endif
#ifndef _NETINET_SCTP_UIO_H_
@@ -279,18 +279,23 @@ struct sctp_snd_all_completes {
SCTP_SACK_IMMEDIATELY)) != 0)
/* for the endpoint */
-/* The lower byte is an enumeration of PR-SCTP policies */
+/* The lower four bits is an enumeration of PR-SCTP policies */
#define SCTP_PR_SCTP_NONE 0x0000 /* Reliable transfer */
#define SCTP_PR_SCTP_TTL 0x0001 /* Time based PR-SCTP */
#define SCTP_PR_SCTP_BUF 0x0002 /* Buffer based PR-SCTP */
#define SCTP_PR_SCTP_RTX 0x0003 /* Number of retransmissions based PR-SCTP */
+#define SCTP_PR_SCTP_MAX SCTP_PR_SCTP_RTX
+#define SCTP_PR_SCTP_ALL 0x000f /* Used for aggregated stats */
#define PR_SCTP_POLICY(x) ((x) & 0x0f)
-#define PR_SCTP_ENABLED(x) (PR_SCTP_POLICY(x) != SCTP_PR_SCTP_NONE)
+#define PR_SCTP_ENABLED(x) ((PR_SCTP_POLICY(x) != SCTP_PR_SCTP_NONE) && \
+ (PR_SCTP_POLICY(x) != SCTP_PR_SCTP_ALL))
#define PR_SCTP_TTL_ENABLED(x) (PR_SCTP_POLICY(x) == SCTP_PR_SCTP_TTL)
#define PR_SCTP_BUF_ENABLED(x) (PR_SCTP_POLICY(x) == SCTP_PR_SCTP_BUF)
#define PR_SCTP_RTX_ENABLED(x) (PR_SCTP_POLICY(x) == SCTP_PR_SCTP_RTX)
-#define PR_SCTP_INVALID_POLICY(x) (PR_SCTP_POLICY(x) > SCTP_PR_SCTP_RTX)
+#define PR_SCTP_INVALID_POLICY(x) (PR_SCTP_POLICY(x) > SCTP_PR_SCTP_MAX)
+#define PR_SCTP_VALID_POLICY(x) (PR_SCTP_POLICY(x) <= SCTP_PR_SCTP_MAX)
+
/* Stat's */
struct sctp_pcbinfo {
uint32_t ep_count;
@@ -353,7 +358,6 @@ struct sctp_paddr_change {
uint32_t spc_state;
uint32_t spc_error;
sctp_assoc_t spc_assoc_id;
- uint8_t spc_padding[4];
};
/* paddr state values */
@@ -376,7 +380,7 @@ struct sctp_remote_error {
uint32_t sre_length;
uint16_t sre_error;
sctp_assoc_t sre_assoc_id;
- uint8_t sre_data[4];
+ uint8_t sre_data[];
};
/* data send failure event (deprecated) */
@@ -749,6 +753,14 @@ struct sctp_udpencaps {
uint16_t sue_port;
};
+struct sctp_prstatus {
+ sctp_assoc_t sprstat_assoc_id;
+ uint16_t sprstat_sid;
+ uint16_t sprstat_policy;
+ uint64_t sprstat_abandoned_unsent;
+ uint64_t sprstat_abandoned_sent;
+};
+
struct sctp_cwnd_args {
struct sctp_nets *net; /* network to */ /* FIXME: LP64 issue */
uint32_t cwnd_new_value;/* cwnd in k */
diff --git a/netinet/sctp_usrreq.c b/netinet/sctp_usrreq.c
index 796fd16..296b9f3 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 267688 2014-06-20 20:17:39Z tuexen $");
+__FBSDID("$FreeBSD: head/sys/netinet/sctp_usrreq.c 271221 2014-09-07 09:06:26Z tuexen $");
#endif
#include <netinet/sctp_os.h>
@@ -1676,7 +1676,7 @@ sctp_fill_up_addresses_vrf(struct sctp_inpcb *inp,
if (ipv4_addr_legal) {
struct sockaddr_in *sin;
- sin = (struct sockaddr_in *)&sctp_ifa->address.sa;
+ sin = &sctp_ifa->address.sin;
if (sin->sin_addr.s_addr == 0) {
/*
* we skip unspecifed
@@ -1725,7 +1725,7 @@ sctp_fill_up_addresses_vrf(struct sctp_inpcb *inp,
#if defined(SCTP_EMBEDDED_V6_SCOPE) && !defined(SCTP_KAME)
struct sockaddr_in6 lsa6;
#endif
- sin6 = (struct sockaddr_in6 *)&sctp_ifa->address.sa;
+ sin6 = &sctp_ifa->address.sin6;
if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
/*
* we skip unspecifed
@@ -4002,6 +4002,195 @@ sctp_getopt(struct socket *so, int optname, void *optval, size_t *optsize,
}
break;
}
+ case SCTP_ECN_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.ecn_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->ecn_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_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_AUTH_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.auth_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->auth_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_ASCONF_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.asconf_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->asconf_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_RECONFIG_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.reconfig_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->reconfig_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_NRSACK_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.nrsack_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->nrsack_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_PKTDROP_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.pktdrop_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->pktdrop_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;
@@ -4029,6 +4218,72 @@ sctp_getopt(struct socket *so, int optname, void *optval, size_t *optsize,
}
break;
}
+ case SCTP_PR_STREAM_STATUS:
+ {
+ struct sctp_prstatus *sprstat;
+ uint16_t sid;
+ uint16_t policy;
+
+ SCTP_CHECK_AND_CAST(sprstat, optval, struct sctp_prstatus, *optsize);
+ SCTP_FIND_STCB(inp, stcb, sprstat->sprstat_assoc_id);
+
+ sid = sprstat->sprstat_sid;
+ policy = sprstat->sprstat_policy;
+#if defined(SCTP_DETAILED_STR_STATS)
+ if ((stcb != NULL) &&
+ (policy != SCTP_PR_SCTP_NONE) &&
+ (sid < stcb->asoc.streamoutcnt) &&
+ ((policy == SCTP_PR_SCTP_ALL) ||
+ (PR_SCTP_VALID_POLICY(policy)))) {
+#else
+ if ((stcb != NULL) &&
+ (policy != SCTP_PR_SCTP_NONE) &&
+ (sid < stcb->asoc.streamoutcnt) &&
+ (policy == SCTP_PR_SCTP_ALL)) {
+#endif
+ if (policy == SCTP_PR_SCTP_ALL) {
+ sprstat->sprstat_abandoned_unsent = stcb->asoc.strmout[sid].abandoned_unsent[0];
+ sprstat->sprstat_abandoned_sent = stcb->asoc.strmout[sid].abandoned_sent[0];
+ } else {
+ sprstat->sprstat_abandoned_unsent = stcb->asoc.strmout[sid].abandoned_unsent[policy];
+ sprstat->sprstat_abandoned_sent = stcb->asoc.strmout[sid].abandoned_sent[policy];
+ }
+ SCTP_TCB_UNLOCK(stcb);
+ *optsize = sizeof(struct sctp_prstatus);
+ } else {
+ SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
+ error = EINVAL;
+ }
+ break;
+ }
+ case SCTP_PR_ASSOC_STATUS:
+ {
+ struct sctp_prstatus *sprstat;
+ uint16_t policy;
+
+ SCTP_CHECK_AND_CAST(sprstat, optval, struct sctp_prstatus, *optsize);
+ SCTP_FIND_STCB(inp, stcb, sprstat->sprstat_assoc_id);
+
+ policy = sprstat->sprstat_policy;
+ if ((stcb != NULL) &&
+ (policy != SCTP_PR_SCTP_NONE) &&
+ ((policy == SCTP_PR_SCTP_ALL) ||
+ (PR_SCTP_VALID_POLICY(policy)))) {
+ if (policy == SCTP_PR_SCTP_ALL) {
+ sprstat->sprstat_abandoned_unsent = stcb->asoc.abandoned_unsent[0];
+ sprstat->sprstat_abandoned_sent = stcb->asoc.abandoned_sent[0];
+ } else {
+ sprstat->sprstat_abandoned_unsent = stcb->asoc.abandoned_unsent[policy];
+ sprstat->sprstat_abandoned_sent = stcb->asoc.abandoned_sent[policy];
+ }
+ SCTP_TCB_UNLOCK(stcb);
+ *optsize = sizeof(struct sctp_prstatus);
+ } else {
+ SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
+ error = EINVAL;
+ }
+ break;
+ }
default:
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOPROTOOPT);
error = ENOPROTOOPT;
@@ -4452,7 +4707,7 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
/* The VRF must be in the VRF list */
if (*default_vrfid == inp->m_vrf_ids[i]) {
SCTP_INP_WLOCK(inp);
- inp->def_vrf_id = *default_vrfid;
+ inp->def_vrf_id = *default_vrfid;
SCTP_INP_WUNLOCK(inp);
goto sctp_done;
}
@@ -4571,7 +4826,7 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EOPNOTSUPP);
error = EOPNOTSUPP;
#endif
- break;
+ break;
}
case SCTP_DELAYED_SACK:
{
@@ -4987,7 +5242,7 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
error = ENOENT;
break;
}
- if (stcb->asoc.peer_supports_strreset == 0) {
+ if (stcb->asoc.reconfig_supported == 0) {
/*
* Peer does not support the chunk type.
*/
@@ -5054,7 +5309,7 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
error = ENOENT;
break;
}
- if (stcb->asoc.peer_supports_strreset == 0) {
+ if (stcb->asoc.reconfig_supported == 0) {
/*
* Peer does not support the chunk type.
*/
@@ -5120,7 +5375,7 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
error = ENOENT;
break;
}
- if (stcb->asoc.peer_supports_strreset == 0) {
+ if (stcb->asoc.reconfig_supported == 0) {
/*
* Peer does not support the chunk type.
*/
@@ -5662,7 +5917,7 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
}
if (net->dest_state & SCTP_ADDR_REACHABLE) {
if (net->error_count > paddrp->spp_pathmaxrxt) {
- net->dest_state &= ~SCTP_ADDR_REACHABLE;
+ net->dest_state &= ~SCTP_ADDR_REACHABLE;
sctp_ulp_notify(SCTP_NOTIFY_INTERFACE_DOWN, stcb, 0, net, SCTP_SO_LOCKED);
}
} else {
@@ -5705,7 +5960,7 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
}
if (net->dest_state & SCTP_ADDR_REACHABLE) {
if (net->error_count > paddrp->spp_pathmaxrxt) {
- net->dest_state &= ~SCTP_ADDR_REACHABLE;
+ net->dest_state &= ~SCTP_ADDR_REACHABLE;
sctp_ulp_notify(SCTP_NOTIFY_INTERFACE_DOWN, stcb, 0, net, SCTP_SO_LOCKED);
}
} else {
@@ -6204,7 +6459,7 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
#endif
{
error = EAFNOSUPPORT;
- break;
+ break;
}
sctp_bindx_add_address(so, inp, addrs->addr,
addrs->sget_assoc_id, vrf_id,
@@ -6602,7 +6857,7 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
} else {
if ((net->failure_threshold > thlds->spt_pathpfthld) &&
(net->failure_threshold <= thlds->spt_pathmaxrxt)) {
- net->dest_state |= SCTP_ADDR_PF;
+ net->dest_state |= SCTP_ADDR_PF;
sctp_send_hb(stcb, net, SCTP_SO_LOCKED);
sctp_timer_stop(SCTP_TIMER_TYPE_HEARTBEAT, stcb->sctp_ep, stcb, net, SCTP_FROM_SCTP_TIMER + SCTP_LOC_3);
sctp_timer_start(SCTP_TIMER_TYPE_HEARTBEAT, stcb->sctp_ep, stcb, net);
@@ -6631,7 +6886,7 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
} else {
if ((net->failure_threshold > thlds->spt_pathpfthld) &&
(net->failure_threshold <= thlds->spt_pathmaxrxt)) {
- net->dest_state |= SCTP_ADDR_PF;
+ net->dest_state |= SCTP_ADDR_PF;
sctp_send_hb(stcb, net, SCTP_SO_LOCKED);
sctp_timer_stop(SCTP_TIMER_TYPE_HEARTBEAT, stcb->sctp_ep, stcb, net, SCTP_FROM_SCTP_TIMER + SCTP_LOC_3);
sctp_timer_start(SCTP_TIMER_TYPE_HEARTBEAT, stcb->sctp_ep, stcb, net);
@@ -6762,6 +7017,231 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
}
break;
}
+ case SCTP_ECN_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->ecn_supported = 0;
+ } else {
+ 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 {
+ SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
+ error = EINVAL;
+ }
+ }
+ break;
+ }
+ case SCTP_AUTH_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)) {
+ if ((av->assoc_value == 0) &&
+ (inp->asconf_supported == 1)) {
+ /* AUTH is required for ASCONF */
+ SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
+ error = EINVAL;
+ } else {
+ SCTP_INP_WLOCK(inp);
+ if (av->assoc_value == 0) {
+ inp->auth_supported = 0;
+ } else {
+ inp->auth_supported = 1;
+ }
+ SCTP_INP_WUNLOCK(inp);
+ }
+ } else {
+ SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
+ error = EINVAL;
+ }
+ }
+ break;
+ }
+ case SCTP_ASCONF_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)) {
+ if ((av->assoc_value != 0) &&
+ (inp->auth_supported == 0)) {
+ /* AUTH is required for ASCONF */
+ SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
+ error = EINVAL;
+ } else {
+ SCTP_INP_WLOCK(inp);
+ if (av->assoc_value == 0) {
+ inp->asconf_supported = 0;
+ sctp_auth_delete_chunk(SCTP_ASCONF,
+ inp->sctp_ep.local_auth_chunks);
+ sctp_auth_delete_chunk(SCTP_ASCONF_ACK,
+ inp->sctp_ep.local_auth_chunks);
+ } else {
+ inp->asconf_supported = 1;
+ sctp_auth_add_chunk(SCTP_ASCONF,
+ inp->sctp_ep.local_auth_chunks);
+ sctp_auth_add_chunk(SCTP_ASCONF_ACK,
+ inp->sctp_ep.local_auth_chunks);
+ }
+ SCTP_INP_WUNLOCK(inp);
+ }
+ } else {
+ SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
+ error = EINVAL;
+ }
+ }
+ break;
+ }
+ case SCTP_RECONFIG_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->reconfig_supported = 0;
+ } else {
+ inp->reconfig_supported = 1;
+ }
+ SCTP_INP_WUNLOCK(inp);
+ } else {
+ SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
+ error = EINVAL;
+ }
+ }
+ break;
+ }
+ case SCTP_NRSACK_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->nrsack_supported = 0;
+ } else {
+ inp->nrsack_supported = 1;
+ }
+ SCTP_INP_WUNLOCK(inp);
+ } else {
+ SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
+ error = EINVAL;
+ }
+ }
+ break;
+ }
+ case SCTP_PKTDROP_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->pktdrop_supported = 0;
+ } else {
+ inp->pktdrop_supported = 1;
+ }
+ SCTP_INP_WUNLOCK(inp);
+ } else {
+ SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
+ error = EINVAL;
+ }
+ }
+ break;
+ }
default:
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOPROTOOPT);
error = ENOPROTOOPT;
@@ -6928,7 +7408,7 @@ sctp_connect(struct socket *so, struct mbuf *nam, struct proc *p)
#endif
default:
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EAFNOSUPPORT);
- return (EAFNOSUPPORT);
+ return (EAFNOSUPPORT);
}
#endif
SCTP_INP_INCR_REF(inp);
@@ -7103,7 +7583,7 @@ sctpconn_connect(struct socket *so, struct sockaddr *addr)
break;
default:
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EAFNOSUPPORT);
- return (EAFNOSUPPORT);
+ return (EAFNOSUPPORT);
}
SCTP_INP_INCR_REF(inp);
SCTP_ASOC_CREATE_LOCK(inp);
@@ -7735,7 +8215,7 @@ sctp_ingetaddr(struct socket *so, struct mbuf *nam)
if (laddr->ifa->address.sa.sa_family == AF_INET) {
struct sockaddr_in *sin_a;
- sin_a = (struct sockaddr_in *)&laddr->ifa->address.sa;
+ sin_a = &laddr->ifa->address.sin;
sin->sin_addr = sin_a->sin_addr;
fnd = 1;
break;
diff --git a/netinet/sctp_var.h b/netinet/sctp_var.h
index f2a0316..be2f2b9 100755
--- a/netinet/sctp_var.h
+++ b/netinet/sctp_var.h
@@ -32,7 +32,7 @@
#ifdef __FreeBSD__
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/netinet/sctp_var.h 242327 2012-10-29 20:47:32Z tuexen $");
+__FBSDID("$FreeBSD: head/sys/netinet/sctp_var.h 269699 2014-08-08 01:57:15Z kevlo $");
#endif
#ifndef _NETINET_SCTP_VAR_H_
@@ -76,7 +76,7 @@ extern struct pr_usrreqs sctp_usrreqs;
((stcb->asoc.sctp_features & feature) == 0)) || \
((stcb == NULL) && (inp != NULL) && \
((inp->sctp_features & feature) == 0)) || \
- ((stcb == NULL) && (inp == NULL)))
+ ((stcb == NULL) && (inp == NULL)))
/* managing mobility_feature in inpcb (by micchie) */
#define sctp_mobility_feature_on(inp, feature) (inp->sctp_mobility_features |= feature)
@@ -110,7 +110,7 @@ extern struct pr_usrreqs sctp_usrreqs;
#define sctp_alloc_a_readq(_stcb, _readq) { \
(_readq) = SCTP_ZONE_GET(SCTP_BASE_INFO(ipi_zone_readq), struct sctp_queued_to_read); \
if ((_readq)) { \
- SCTP_INCR_READQ_COUNT(); \
+ SCTP_INCR_READQ_COUNT(); \
} \
}
@@ -125,11 +125,11 @@ extern struct pr_usrreqs sctp_usrreqs;
#define sctp_alloc_a_strmoq(_stcb, _strmoq) { \
(_strmoq) = SCTP_ZONE_GET(SCTP_BASE_INFO(ipi_zone_strmoq), struct sctp_stream_queue_pending); \
- if ((_strmoq)) { \
+ if ((_strmoq)) { \
memset(_strmoq, 0, sizeof(struct sctp_stream_queue_pending)); \
SCTP_INCR_STRMOQ_COUNT(); \
(_strmoq)->holds_key_ref = 0; \
- } \
+ } \
}
#define sctp_free_a_chunk(_stcb, _chk, _so_locked) { \
@@ -137,22 +137,22 @@ extern struct pr_usrreqs sctp_usrreqs;
sctp_auth_key_release((_stcb), (_chk)->auth_keyid, _so_locked); \
(_chk)->holds_key_ref = 0; \
} \
- if (_stcb) { \
- SCTP_TCB_LOCK_ASSERT((_stcb)); \
- if ((_chk)->whoTo) { \
- sctp_free_remote_addr((_chk)->whoTo); \
- (_chk)->whoTo = NULL; \
- } \
- if (((_stcb)->asoc.free_chunk_cnt > SCTP_BASE_SYSCTL(sctp_asoc_free_resc_limit)) || \
- (SCTP_BASE_INFO(ipi_free_chunks) > SCTP_BASE_SYSCTL(sctp_system_free_resc_limit))) { \
- SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_chunk), (_chk)); \
- SCTP_DECR_CHK_COUNT(); \
- } else { \
- TAILQ_INSERT_TAIL(&(_stcb)->asoc.free_chunks, (_chk), sctp_next); \
- (_stcb)->asoc.free_chunk_cnt++; \
- atomic_add_int(&SCTP_BASE_INFO(ipi_free_chunks), 1); \
- } \
- } else { \
+ if (_stcb) { \
+ SCTP_TCB_LOCK_ASSERT((_stcb)); \
+ if ((_chk)->whoTo) { \
+ sctp_free_remote_addr((_chk)->whoTo); \
+ (_chk)->whoTo = NULL; \
+ } \
+ if (((_stcb)->asoc.free_chunk_cnt > SCTP_BASE_SYSCTL(sctp_asoc_free_resc_limit)) || \
+ (SCTP_BASE_INFO(ipi_free_chunks) > SCTP_BASE_SYSCTL(sctp_system_free_resc_limit))) { \
+ SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_chunk), (_chk)); \
+ SCTP_DECR_CHK_COUNT(); \
+ } else { \
+ TAILQ_INSERT_TAIL(&(_stcb)->asoc.free_chunks, (_chk), sctp_next); \
+ (_stcb)->asoc.free_chunk_cnt++; \
+ atomic_add_int(&SCTP_BASE_INFO(ipi_free_chunks), 1); \
+ } \
+ } else { \
SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_chunk), (_chk)); \
SCTP_DECR_CHK_COUNT(); \
} \
@@ -163,7 +163,7 @@ extern struct pr_usrreqs sctp_usrreqs;
(_chk) = SCTP_ZONE_GET(SCTP_BASE_INFO(ipi_zone_chunk), struct sctp_tmit_chunk); \
if ((_chk)) { \
SCTP_INCR_CHK_COUNT(); \
- (_chk)->whoTo = NULL; \
+ (_chk)->whoTo = NULL; \
(_chk)->holds_key_ref = 0; \
} \
} else { \
@@ -171,7 +171,7 @@ extern struct pr_usrreqs sctp_usrreqs;
TAILQ_REMOVE(&(_stcb)->asoc.free_chunks, (_chk), sctp_next); \
atomic_subtract_int(&SCTP_BASE_INFO(ipi_free_chunks), 1); \
(_chk)->holds_key_ref = 0; \
- SCTP_STAT_INCR(sctps_cached_chk); \
+ SCTP_STAT_INCR(sctps_cached_chk); \
(_stcb)->asoc.free_chunk_cnt--; \
} \
}
@@ -183,15 +183,15 @@ extern struct pr_usrreqs sctp_usrreqs;
if (SCTP_DECREMENT_AND_CHECK_REFCOUNT(&(__net)->ref_count)) { \
(void)SCTP_OS_TIMER_STOP(&(__net)->rxt_timer.timer); \
(void)SCTP_OS_TIMER_STOP(&(__net)->pmtu_timer.timer); \
- if ((__net)->ro.ro_rt) { \
+ if ((__net)->ro.ro_rt) { \
RTFREE((__net)->ro.ro_rt); \
(__net)->ro.ro_rt = NULL; \
- } \
+ } \
if ((__net)->src_addr_selected) { \
sctp_free_ifa((__net)->ro._s_addr); \
(__net)->ro._s_addr = NULL; \
} \
- (__net)->src_addr_selected = 0; \
+ (__net)->src_addr_selected = 0; \
(__net)->dest_state &= ~SCTP_ADDR_REACHABLE; \
SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_net), (__net)); \
SCTP_DECR_RADDR_COUNT(); \
@@ -231,15 +231,15 @@ extern struct pr_usrreqs sctp_usrreqs;
(void)SCTP_OS_TIMER_STOP(&(__net)->rxt_timer.timer); \
(void)SCTP_OS_TIMER_STOP(&(__net)->pmtu_timer.timer); \
(void)SCTP_OS_TIMER_STOP(&(__net)->hb_timer.timer); \
- if ((__net)->ro.ro_rt) { \
+ if ((__net)->ro.ro_rt) { \
RTFREE((__net)->ro.ro_rt); \
(__net)->ro.ro_rt = NULL; \
- } \
+ } \
if ((__net)->src_addr_selected) { \
sctp_free_ifa((__net)->ro._s_addr); \
(__net)->ro._s_addr = NULL; \
} \
- (__net)->src_addr_selected = 0; \
+ (__net)->src_addr_selected = 0; \
(__net)->dest_state &=~SCTP_ADDR_REACHABLE; \
SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_net), (__net)); \
SCTP_DECR_RADDR_COUNT(); \
@@ -323,12 +323,12 @@ extern struct pr_usrreqs sctp_usrreqs;
} while (0)
#define sctp_flight_size_increase(tp1) do { \
- (tp1)->whoTo->flight_size += (tp1)->book_size; \
+ (tp1)->whoTo->flight_size += (tp1)->book_size; \
} while (0)
#ifdef SCTP_FS_SPEC_LOG
#define sctp_total_flight_decrease(stcb, tp1) do { \
- if (stcb->asoc.fs_index > SCTP_FS_SPEC_LOG_SIZE) \
+ if (stcb->asoc.fs_index > SCTP_FS_SPEC_LOG_SIZE) \
stcb->asoc.fs_index = 0;\
stcb->asoc.fslog[stcb->asoc.fs_index].total_flight = stcb->asoc.total_flight; \
stcb->asoc.fslog[stcb->asoc.fs_index].tsn = tp1->rec.data.TSN_seq; \
@@ -337,7 +337,7 @@ extern struct pr_usrreqs sctp_usrreqs;
stcb->asoc.fslog[stcb->asoc.fs_index].incr = 0; \
stcb->asoc.fslog[stcb->asoc.fs_index].decr = 1; \
stcb->asoc.fs_index++; \
- tp1->window_probe = 0; \
+ tp1->window_probe = 0; \
if (stcb->asoc.total_flight >= tp1->book_size) { \
stcb->asoc.total_flight -= tp1->book_size; \
if (stcb->asoc.total_flight_count > 0) \
@@ -349,7 +349,7 @@ extern struct pr_usrreqs sctp_usrreqs;
} while (0)
#define sctp_total_flight_increase(stcb, tp1) do { \
- if (stcb->asoc.fs_index > SCTP_FS_SPEC_LOG_SIZE) \
+ if (stcb->asoc.fs_index > SCTP_FS_SPEC_LOG_SIZE) \
stcb->asoc.fs_index = 0;\
stcb->asoc.fslog[stcb->asoc.fs_index].total_flight = stcb->asoc.total_flight; \
stcb->asoc.fslog[stcb->asoc.fs_index].tsn = tp1->rec.data.TSN_seq; \
@@ -358,14 +358,14 @@ extern struct pr_usrreqs sctp_usrreqs;
stcb->asoc.fslog[stcb->asoc.fs_index].incr = 1; \
stcb->asoc.fslog[stcb->asoc.fs_index].decr = 0; \
stcb->asoc.fs_index++; \
- (stcb)->asoc.total_flight_count++; \
- (stcb)->asoc.total_flight += (tp1)->book_size; \
+ (stcb)->asoc.total_flight_count++; \
+ (stcb)->asoc.total_flight += (tp1)->book_size; \
} while (0)
#else
#define sctp_total_flight_decrease(stcb, tp1) do { \
- tp1->window_probe = 0; \
+ tp1->window_probe = 0; \
if (stcb->asoc.total_flight >= tp1->book_size) { \
stcb->asoc.total_flight -= tp1->book_size; \
if (stcb->asoc.total_flight_count > 0) \
@@ -377,8 +377,8 @@ extern struct pr_usrreqs sctp_usrreqs;
} while (0)
#define sctp_total_flight_increase(stcb, tp1) do { \
- (stcb)->asoc.total_flight_count++; \
- (stcb)->asoc.total_flight += (tp1)->book_size; \
+ (stcb)->asoc.total_flight_count++; \
+ (stcb)->asoc.total_flight += (tp1)->book_size; \
} while (0)
#endif
@@ -412,8 +412,12 @@ void sctp_ctlinput(int, struct sockaddr *, void *);
int sctp_ctloutput(struct socket *, struct sockopt *);
#ifdef INET
void sctp_input_with_port(struct mbuf *, int, uint16_t);
+#if defined(__FreeBSD__) && __FreeBSD_version >= 1100020
+int sctp_input(struct mbuf **, int *, int);
+#else
void sctp_input(struct mbuf *, int);
#endif
+#endif
void sctp_pathmtu_adjustment(struct sctp_tcb *, uint16_t);
#endif
#else
diff --git a/netinet/sctputil.c b/netinet/sctputil.c
index 73cf3ab..87e770d 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 267674 2014-06-20 13:26:49Z tuexen $");
+__FBSDID("$FreeBSD: head/sys/netinet/sctputil.c 271221 2014-09-07 09:06:26Z tuexen $");
#endif
#include <netinet/sctp_os.h>
@@ -963,6 +963,9 @@ sctp_init_asoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
* caller in the sctp_aloc_assoc() function.
*/
int i;
+#if defined(SCTP_DETAILED_STR_STATS)
+ int j;
+#endif
asoc = &stcb->asoc;
/* init all variables to a known value. */
@@ -972,8 +975,13 @@ sctp_init_asoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
asoc->heart_beat_delay = TICKS_TO_MSEC(inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_HEARTBEAT]);
asoc->cookie_life = inp->sctp_ep.def_cookie_life;
asoc->sctp_cmt_on_off = inp->sctp_cmt_on_off;
- asoc->ecn_allowed = inp->sctp_ecn_enable;
- asoc->sctp_nr_sack_on_off = (uint8_t)SCTP_BASE_SYSCTL(sctp_nr_sack_on_off);
+ asoc->ecn_supported = inp->ecn_supported;
+ asoc->prsctp_supported = inp->prsctp_supported;
+ asoc->auth_supported = inp->auth_supported;
+ asoc->asconf_supported = inp->asconf_supported;
+ asoc->reconfig_supported = inp->reconfig_supported;
+ asoc->nrsack_supported = inp->nrsack_supported;
+ asoc->pktdrop_supported = inp->pktdrop_supported;
asoc->sctp_cmt_pf = (uint8_t)0;
asoc->sctp_frag_point = inp->sctp_frag_point;
asoc->sctp_features = inp->sctp_features;
@@ -1004,7 +1012,7 @@ sctp_init_asoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
#ifdef SCTP_ASOCLOG_OF_TSNS
asoc->tsn_in_at = 0;
- asoc->tsn_out_at = 0;
+ asoc->tsn_out_at = 0;
asoc->tsn_in_wrapped = 0;
asoc->tsn_out_wrapped = 0;
asoc->cumack_log_at = 0;
@@ -1019,7 +1027,6 @@ sctp_init_asoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
sctp_select_initial_TSN(&inp->sctp_ep);
asoc->asconf_seq_out_acked = asoc->asconf_seq_out - 1;
/* we are optimisitic here */
- asoc->peer_supports_pktdrop = 1;
asoc->peer_supports_nat = 0;
asoc->sent_queue_retran_cnt = 0;
@@ -1133,6 +1140,15 @@ sctp_init_asoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
asoc->strmout[i].next_sequence_send = 0x0;
TAILQ_INIT(&asoc->strmout[i].outqueue);
asoc->strmout[i].chunks_on_queues = 0;
+#if defined(SCTP_DETAILED_STR_STATS)
+ for (j = 0; j < SCTP_PR_SCTP_MAX + 1; j++) {
+ asoc->strmout[i].abandoned_sent[j] = 0;
+ asoc->strmout[i].abandoned_unsent[j] = 0;
+ }
+#else
+ asoc->strmout[i].abandoned_sent[0] = 0;
+ asoc->strmout[i].abandoned_unsent[0] = 0;
+#endif
asoc->strmout[i].stream_no = i;
asoc->strmout[i].last_msg_incomplete = 0;
asoc->ss_functions.sctp_ss_init_stream(&asoc->strmout[i], NULL);
@@ -1188,6 +1204,10 @@ sctp_init_asoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
asoc->timoshutdownack = 0;
(void)SCTP_GETTIME_TIMEVAL(&asoc->start_time);
asoc->discontinuity_time = asoc->start_time;
+ for (i = 0; i < SCTP_PR_SCTP_MAX + 1; i++) {
+ asoc->abandoned_unsent[i] = 0;
+ asoc->abandoned_sent[i] = 0;
+ }
/* sa_ignore MEMLEAK {memory is put in the assoc mapping array and freed later when
* the association is freed.
*/
@@ -1273,7 +1293,7 @@ sctp_iterator_work(struct sctp_iterator *it)
SCTP_INP_INFO_RLOCK();
SCTP_ITERATOR_LOCK();
- if (it->inp) {
+ if (it->inp) {
SCTP_INP_RLOCK(it->inp);
SCTP_INP_DECR_REF(it->inp);
}
@@ -1816,7 +1836,7 @@ sctp_timeout_handler(void *t)
goto out_decr;
}
SCTP_STAT_INCR(sctps_timoshutdownack);
- stcb->asoc.timoshutdownack++;
+ stcb->asoc.timoshutdownack++;
#ifdef SCTP_AUDITING_ENABLED
sctp_auditing(4, inp, stcb, net);
#endif
@@ -2566,15 +2586,15 @@ sctp_calculate_rto(struct sctp_tcb *stcb,
stcb->asoc.sat_network = 0;
stcb->asoc.sat_network_lockout = 1;
}
- /* bound it, per C6/C7 in Section 5.3.1 */
- if (new_rto < stcb->asoc.minrto) {
+ /* bound it, per C6/C7 in Section 5.3.1 */
+ if (new_rto < stcb->asoc.minrto) {
new_rto = stcb->asoc.minrto;
}
if (new_rto > stcb->asoc.maxrto) {
new_rto = stcb->asoc.maxrto;
}
/* we are now returning the RTO */
- return (new_rto);
+ return (new_rto);
}
/*
@@ -2637,58 +2657,44 @@ sctp_get_next_param(struct mbuf *m,
}
-int
+struct mbuf *
sctp_add_pad_tombuf(struct mbuf *m, int padlen)
{
- /*
- * add padlen bytes of 0 filled padding to the end of the mbuf. If
- * padlen is > 3 this routine will fail.
- */
- uint8_t *dp;
- int i;
+ struct mbuf *m_last;
+ caddr_t dp;
if (padlen > 3) {
- SCTP_LTRACE_ERR_RET_PKT(m, NULL, NULL, NULL, SCTP_FROM_SCTPUTIL, ENOBUFS);
- return (ENOBUFS);
+ return (NULL);
}
if (padlen <= M_TRAILINGSPACE(m)) {
/*
* The easy way. We hope the majority of the time we hit
* here :)
*/
- dp = (uint8_t *) (mtod(m, caddr_t) + SCTP_BUF_LEN(m));
- SCTP_BUF_LEN(m) += padlen;
+ m_last = m;
} else {
- /* Hard way we must grow the mbuf */
- struct mbuf *tmp;
-
- tmp = sctp_get_mbuf_for_msg(padlen, 0, M_NOWAIT, 1, MT_DATA);
- if (tmp == NULL) {
- /* Out of space GAK! we are in big trouble. */
- SCTP_LTRACE_ERR_RET_PKT(m, NULL, NULL, NULL, SCTP_FROM_SCTPUTIL, ENOBUFS);
- return (ENOBUFS);
- }
- /* setup and insert in middle */
- SCTP_BUF_LEN(tmp) = padlen;
- SCTP_BUF_NEXT(tmp) = NULL;
- SCTP_BUF_NEXT(m) = tmp;
- dp = mtod(tmp, uint8_t *);
- }
- /* zero out the pad */
- for (i = 0; i < padlen; i++) {
- *dp = 0;
- dp++;
+ /* Hard way we must grow the mbuf chain */
+ m_last = sctp_get_mbuf_for_msg(padlen, 0, M_NOWAIT, 1, MT_DATA);
+ if (m_last == NULL) {
+ return (NULL);
+ }
+ SCTP_BUF_LEN(m_last) = 0;
+ SCTP_BUF_NEXT(m_last) = NULL;
+ SCTP_BUF_NEXT(m) = m_last;
}
- return (0);
+ dp = mtod(m_last, caddr_t) + SCTP_BUF_LEN(m_last);
+ SCTP_BUF_LEN(m_last) += padlen;
+ memset(dp, 0, padlen);
+ return (m_last);
}
-int
+struct mbuf *
sctp_pad_lastmbuf(struct mbuf *m, int padval, struct mbuf *last_mbuf)
{
/* find the last mbuf in chain and pad it */
struct mbuf *m_at;
- if (last_mbuf) {
+ if (last_mbuf != NULL) {
return (sctp_add_pad_tombuf(last_mbuf, padval));
} else {
for (m_at = m; m_at; m_at = SCTP_BUF_NEXT(m_at)) {
@@ -2697,8 +2703,7 @@ sctp_pad_lastmbuf(struct mbuf *m, int padval, struct mbuf *last_mbuf)
}
}
}
- SCTP_LTRACE_ERR_RET_PKT(m, NULL, NULL, NULL, SCTP_FROM_SCTPUTIL, EFAULT);
- return (EFAULT);
+ return (NULL);
}
static void
@@ -2741,6 +2746,7 @@ sctp_notify_assoc_change(uint16_t state, struct sctp_tcb *stcb,
}
SCTP_BUF_NEXT(m_notify) = NULL;
sac = mtod(m_notify, struct sctp_assoc_change *);
+ memset(sac, 0, notif_len);
sac->sac_type = SCTP_ASSOC_CHANGE;
sac->sac_flags = 0;
sac->sac_length = sizeof(struct sctp_assoc_change);
@@ -2753,17 +2759,17 @@ 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 == 1) {
sac->sac_info[i++] = SCTP_ASSOC_SUPPORTS_PR;
}
- if (stcb->asoc.peer_supports_auth) {
+ if (stcb->asoc.auth_supported == 1) {
sac->sac_info[i++] = SCTP_ASSOC_SUPPORTS_AUTH;
}
- if (stcb->asoc.peer_supports_asconf) {
+ if (stcb->asoc.asconf_supported == 1) {
sac->sac_info[i++] = SCTP_ASSOC_SUPPORTS_ASCONF;
}
sac->sac_info[i++] = SCTP_ASSOC_SUPPORTS_MULTIBUF;
- if (stcb->asoc.peer_supports_strreset) {
+ if (stcb->asoc.reconfig_supported == 1) {
sac->sac_info[i++] = SCTP_ASSOC_SUPPORTS_RE_CONFIG;
}
sac->sac_length += i;
@@ -2868,6 +2874,7 @@ sctp_notify_peer_addr_change(struct sctp_tcb *stcb, uint32_t state,
return;
SCTP_BUF_LEN(m_notify) = 0;
spc = mtod(m_notify, struct sctp_paddr_change *);
+ memset(spc, 0, sizeof(struct sctp_paddr_change));
spc->spc_type = SCTP_PEER_ADDR_CHANGE;
spc->spc_flags = 0;
spc->spc_length = sizeof(struct sctp_paddr_change);
@@ -2891,7 +2898,7 @@ sctp_notify_peer_addr_change(struct sctp_tcb *stcb, uint32_t state,
if (sin6->sin6_scope_id == 0) {
/* recover scope_id for user */
#ifdef SCTP_KAME
- (void)sa6_recoverscope(sin6);
+ (void)sa6_recoverscope(sin6);
#else
(void)in6_recoverscope(sin6, &sin6->sin6_addr,
NULL);
@@ -2972,21 +2979,21 @@ sctp_notify_send_failed(struct sctp_tcb *stcb, uint8_t sent, uint32_t error,
if (m_notify == NULL)
/* no space left */
return;
- length += chk->send_size;
- length -= sizeof(struct sctp_data_chunk);
SCTP_BUF_LEN(m_notify) = 0;
if (sctp_stcb_is_feature_on(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_RECVNSENDFAILEVNT)) {
ssfe = mtod(m_notify, struct sctp_send_failed_event *);
+ memset(ssfe, 0, length);
ssfe->ssfe_type = SCTP_SEND_FAILED_EVENT;
if (sent) {
ssfe->ssfe_flags = SCTP_DATA_SENT;
} else {
ssfe->ssfe_flags = SCTP_DATA_UNSENT;
}
+ length += chk->send_size;
+ length -= sizeof(struct sctp_data_chunk);
ssfe->ssfe_length = length;
ssfe->ssfe_error = error;
/* not exactly what the user sent in, but should be close :) */
- bzero(&ssfe->ssfe_info, sizeof(ssfe->ssfe_info));
ssfe->ssfe_info.snd_sid = chk->rec.data.stream_number;
ssfe->ssfe_info.snd_flags = chk->rec.data.rcv_flags;
ssfe->ssfe_info.snd_ppid = chk->rec.data.payloadtype;
@@ -2996,12 +3003,15 @@ sctp_notify_send_failed(struct sctp_tcb *stcb, uint8_t sent, uint32_t error,
SCTP_BUF_LEN(m_notify) = sizeof(struct sctp_send_failed_event);
} else {
ssf = mtod(m_notify, struct sctp_send_failed *);
+ memset(ssf, 0, length);
ssf->ssf_type = SCTP_SEND_FAILED;
if (sent) {
ssf->ssf_flags = SCTP_DATA_SENT;
} else {
ssf->ssf_flags = SCTP_DATA_UNSENT;
}
+ length += chk->send_size;
+ length -= sizeof(struct sctp_data_chunk);
ssf->ssf_length = length;
ssf->ssf_error = error;
/* not exactly what the user sent in, but should be close :) */
@@ -3086,16 +3096,16 @@ sctp_notify_send_failed2(struct sctp_tcb *stcb, uint32_t error,
/* no space left */
return;
}
- length += sp->length;
SCTP_BUF_LEN(m_notify) = 0;
if (sctp_stcb_is_feature_on(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_RECVNSENDFAILEVNT)) {
ssfe = mtod(m_notify, struct sctp_send_failed_event *);
+ memset(ssfe, 0, length);
ssfe->ssfe_type = SCTP_SEND_FAILED_EVENT;
ssfe->ssfe_flags = SCTP_DATA_UNSENT;
+ length += sp->length;
ssfe->ssfe_length = length;
ssfe->ssfe_error = error;
/* not exactly what the user sent in, but should be close :) */
- bzero(&ssfe->ssfe_info, sizeof(ssfe->ssfe_info));
ssfe->ssfe_info.snd_sid = sp->stream;
if (sp->some_taken) {
ssfe->ssfe_info.snd_flags = SCTP_DATA_LAST_FRAG;
@@ -3109,12 +3119,13 @@ sctp_notify_send_failed2(struct sctp_tcb *stcb, uint32_t error,
SCTP_BUF_LEN(m_notify) = sizeof(struct sctp_send_failed_event);
} else {
ssf = mtod(m_notify, struct sctp_send_failed *);
+ memset(ssf, 0, length);
ssf->ssf_type = SCTP_SEND_FAILED;
ssf->ssf_flags = SCTP_DATA_UNSENT;
+ length += sp->length;
ssf->ssf_length = length;
ssf->ssf_error = error;
/* not exactly what the user sent in, but should be close :) */
- bzero(&ssf->ssf_info, sizeof(ssf->ssf_info));
ssf->ssf_info.sinfo_stream = sp->stream;
ssf->ssf_info.sinfo_ssn = 0;
if (sp->some_taken) {
@@ -3177,6 +3188,7 @@ sctp_notify_adaptation_layer(struct sctp_tcb *stcb)
return;
SCTP_BUF_LEN(m_notify) = 0;
sai = mtod(m_notify, struct sctp_adaptation_event *);
+ memset(sai, 0, sizeof(struct sctp_adaptation_event));
sai->sai_type = SCTP_ADAPTATION_INDICATION;
sai->sai_flags = 0;
sai->sai_length = sizeof(struct sctp_adaptation_event);
@@ -3233,6 +3245,7 @@ sctp_notify_partial_delivery_indication(struct sctp_tcb *stcb, uint32_t error,
return;
SCTP_BUF_LEN(m_notify) = 0;
pdapi = mtod(m_notify, struct sctp_pdapi_event *);
+ memset(pdapi, 0, sizeof(struct sctp_pdapi_event));
pdapi->pdapi_type = SCTP_PARTIAL_DELIVERY_EVENT;
pdapi->pdapi_flags = 0;
pdapi->pdapi_length = sizeof(struct sctp_pdapi_event);
@@ -3343,6 +3356,7 @@ sctp_notify_shutdown_event(struct sctp_tcb *stcb)
/* no space left */
return;
sse = mtod(m_notify, struct sctp_shutdown_event *);
+ memset(sse, 0, sizeof(struct sctp_shutdown_event));
sse->sse_type = SCTP_SHUTDOWN_EVENT;
sse->sse_flags = 0;
sse->sse_length = sizeof(struct sctp_shutdown_event);
@@ -3394,6 +3408,7 @@ sctp_notify_sender_dry_event(struct sctp_tcb *stcb,
}
SCTP_BUF_LEN(m_notify) = 0;
event = mtod(m_notify, struct sctp_sender_dry_event *);
+ memset(event, 0, sizeof(struct sctp_sender_dry_event));
event->sender_dry_type = SCTP_SENDER_DRY_EVENT;
event->sender_dry_flags = 0;
event->sender_dry_length = sizeof(struct sctp_sender_dry_event);
@@ -3426,7 +3441,6 @@ sctp_notify_stream_reset_add(struct sctp_tcb *stcb, uint16_t numberin, uint16_t
struct mbuf *m_notify;
struct sctp_queued_to_read *control;
struct sctp_stream_change_event *stradd;
- int len;
if ((stcb == NULL) ||
(sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_STREAM_CHANGEEVNT))) {
@@ -3439,25 +3453,20 @@ sctp_notify_stream_reset_add(struct sctp_tcb *stcb, uint16_t numberin, uint16_t
return;
}
stcb->asoc.peer_req_out = 0;
- m_notify = sctp_get_mbuf_for_msg(MCLBYTES, 0, M_NOWAIT, 1, MT_DATA);
+ m_notify = sctp_get_mbuf_for_msg(sizeof(struct sctp_stream_change_event), 0, M_NOWAIT, 1, MT_DATA);
if (m_notify == NULL)
/* no space left */
return;
SCTP_BUF_LEN(m_notify) = 0;
- len = sizeof(struct sctp_stream_change_event);
- if (len > M_TRAILINGSPACE(m_notify)) {
- /* never enough room */
- sctp_m_freem(m_notify);
- return;
- }
stradd = mtod(m_notify, struct sctp_stream_change_event *);
+ memset(stradd, 0, sizeof(struct sctp_stream_change_event));
stradd->strchange_type = SCTP_STREAM_CHANGE_EVENT;
stradd->strchange_flags = flag;
- stradd->strchange_length = len;
+ stradd->strchange_length = sizeof(struct sctp_stream_change_event);
stradd->strchange_assoc_id = sctp_get_associd(stcb);
stradd->strchange_instrms = numberin;
stradd->strchange_outstrms = numberout;
- SCTP_BUF_LEN(m_notify) = len;
+ SCTP_BUF_LEN(m_notify) = sizeof(struct sctp_stream_change_event);
SCTP_BUF_NEXT(m_notify) = NULL;
if (sctp_sbspace(&stcb->asoc, &stcb->sctp_socket->so_rcv) < SCTP_BUF_LEN(m_notify)) {
/* no space */
@@ -3488,32 +3497,26 @@ sctp_notify_stream_reset_tsn(struct sctp_tcb *stcb, uint32_t sending_tsn, uint32
struct mbuf *m_notify;
struct sctp_queued_to_read *control;
struct sctp_assoc_reset_event *strasoc;
- int len;
if ((stcb == NULL) ||
(sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_ASSOC_RESETEVNT))) {
/* event not enabled */
return;
}
- m_notify = sctp_get_mbuf_for_msg(MCLBYTES, 0, M_NOWAIT, 1, MT_DATA);
+ m_notify = sctp_get_mbuf_for_msg(sizeof(struct sctp_assoc_reset_event), 0, M_NOWAIT, 1, MT_DATA);
if (m_notify == NULL)
/* no space left */
return;
SCTP_BUF_LEN(m_notify) = 0;
- len = sizeof(struct sctp_assoc_reset_event);
- if (len > M_TRAILINGSPACE(m_notify)) {
- /* never enough room */
- sctp_m_freem(m_notify);
- return;
- }
strasoc = mtod(m_notify, struct sctp_assoc_reset_event *);
+ memset(strasoc, 0, sizeof(struct sctp_assoc_reset_event));
strasoc->assocreset_type = SCTP_ASSOC_RESET_EVENT;
strasoc->assocreset_flags = flag;
- strasoc->assocreset_length = len;
+ strasoc->assocreset_length = sizeof(struct sctp_assoc_reset_event);
strasoc->assocreset_assoc_id= sctp_get_associd(stcb);
strasoc->assocreset_local_tsn = sending_tsn;
strasoc->assocreset_remote_tsn = recv_tsn;
- SCTP_BUF_LEN(m_notify) = len;
+ SCTP_BUF_LEN(m_notify) = sizeof(struct sctp_assoc_reset_event);
SCTP_BUF_NEXT(m_notify) = NULL;
if (sctp_sbspace(&stcb->asoc, &stcb->sctp_socket->so_rcv) < SCTP_BUF_LEN(m_notify)) {
/* no space */
@@ -3567,6 +3570,7 @@ sctp_notify_stream_reset(struct sctp_tcb *stcb,
return;
}
strreset = mtod(m_notify, struct sctp_stream_reset_event *);
+ memset(strreset, 0, len);
strreset->strreset_type = SCTP_STREAM_RESET_EVENT;
strreset->strreset_flags = flag;
strreset->strreset_length = len;
@@ -3633,6 +3637,7 @@ sctp_notify_remote_error(struct sctp_tcb *stcb, uint16_t error, struct sctp_erro
}
SCTP_BUF_NEXT(m_notify) = NULL;
sre = mtod(m_notify, struct sctp_remote_error *);
+ memset(sre, 0, notif_len);
sre->sre_type = SCTP_REMOTE_ERROR;
sre->sre_flags = 0;
sre->sre_length = sizeof(struct sctp_remote_error);
@@ -3708,7 +3713,7 @@ sctp_ulp_notify(uint32_t notification, struct sctp_tcb *stcb,
if (stcb->asoc.adaptation_needed && (stcb->asoc.adaptation_sent == 0)) {
sctp_notify_adaptation_layer(stcb);
}
- if (stcb->asoc.peer_supports_auth == 0) {
+ if (stcb->asoc.auth_supported == 0) {
sctp_ulp_notify(SCTP_NOTIFY_NO_PEER_AUTH, stcb, 0,
NULL, so_locked);
}
@@ -3797,7 +3802,7 @@ sctp_ulp_notify(uint32_t notification, struct sctp_tcb *stcb,
break;
case SCTP_NOTIFY_ASSOC_RESTART:
sctp_notify_assoc_change(SCTP_RESTART, stcb, error, NULL, 0, so_locked);
- if (stcb->asoc.peer_supports_auth == 0) {
+ if (stcb->asoc.auth_supported == 0) {
sctp_ulp_notify(SCTP_NOTIFY_NO_PEER_AUTH, stcb, 0,
NULL, so_locked);
}
@@ -5173,6 +5178,7 @@ sctp_release_pr_sctp_chunk(struct sctp_tcb *stcb, struct sctp_tmit_chunk *tp1,
int ret_sz = 0;
int notdone;
int do_wakeup_routine = 0;
+
#if defined(__APPLE__)
if (so_locked) {
sctp_lock_assert(SCTP_INP_SO(stcb->sctp_ep));
@@ -5182,6 +5188,21 @@ sctp_release_pr_sctp_chunk(struct sctp_tcb *stcb, struct sctp_tmit_chunk *tp1,
#endif
stream = tp1->rec.data.stream_number;
seq = tp1->rec.data.stream_seq;
+ if (sent || !(tp1->rec.data.rcv_flags & SCTP_DATA_FIRST_FRAG)) {
+ stcb->asoc.abandoned_sent[0]++;
+ stcb->asoc.abandoned_sent[PR_SCTP_POLICY(tp1->flags)]++;
+ stcb->asoc.strmout[stream].abandoned_sent[0]++;
+#if defined(SCTP_DETAILED_STR_STATS)
+ stcb->asoc.strmout[stream].abandoned_sent[PR_SCTP_POLICY(tp1->flags)]++;
+#endif
+ } else {
+ stcb->asoc.abandoned_unsent[0]++;
+ stcb->asoc.abandoned_unsent[PR_SCTP_POLICY(tp1->flags)]++;
+ stcb->asoc.strmout[stream].abandoned_unsent[0]++;
+#if defined(SCTP_DETAILED_STR_STATS)
+ stcb->asoc.strmout[stream].abandoned_unsent[PR_SCTP_POLICY(tp1->flags)]++;
+#endif
+ }
do {
ret_sz += tp1->book_size;
if (tp1->data != NULL) {
@@ -5232,7 +5253,7 @@ sctp_release_pr_sctp_chunk(struct sctp_tcb *stcb, struct sctp_tmit_chunk *tp1,
*/
TAILQ_FOREACH_SAFE(tp1, &stcb->asoc.send_queue, sctp_next, tp2) {
if ((tp1->rec.data.stream_number != stream) ||
- (tp1->rec.data.stream_seq != seq)) {
+ (tp1->rec.data.stream_seq != seq)) {
break;
}
/* save to chk in case we have some on stream out
@@ -6904,9 +6925,12 @@ sctp_soreceive( struct socket *so,
#if defined(__APPLE__)
SCTP_SOCKET_LOCK(so, 1);
#endif
+ if (filling_sinfo) {
+ memset(&sinfo, 0, sizeof(struct sctp_extrcvinfo));
+ }
error = sctp_sorecvmsg(so, uio, mp0, from, fromlen, flagsp,
(struct sctp_sndrcvinfo *)&sinfo, filling_sinfo);
- if ((controlp) && (filling_sinfo)) {
+ if (controlp != NULL) {
/* copy back the sinfo in a CMSG format */
if (filling_sinfo)
*controlp = sctp_build_ctl_nchunk(inp,
@@ -7561,7 +7585,7 @@ sctp_local_addr_count(struct sctp_tcb *stcb)
if (ipv4_addr_legal) {
struct sockaddr_in *sin;
- sin = (struct sockaddr_in *)&sctp_ifa->address.sa;
+ sin = &sctp_ifa->address.sin;
if (sin->sin_addr.s_addr == 0) {
/* skip unspecified addrs */
continue;
@@ -7591,7 +7615,7 @@ sctp_local_addr_count(struct sctp_tcb *stcb)
#if defined(SCTP_EMBEDDED_V6_SCOPE) && !defined(SCTP_KAME)
struct sockaddr_in6 lsa6;
#endif
- sin6 = (struct sockaddr_in6 *)&sctp_ifa->address.sa;
+ sin6 = &sctp_ifa->address.sin6;
if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
continue;
}
diff --git a/netinet/sctputil.h b/netinet/sctputil.h
index eec6c80..c807c66 100755
--- a/netinet/sctputil.h
+++ b/netinet/sctputil.h
@@ -32,7 +32,7 @@
#ifdef __FreeBSD__
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/netinet/sctputil.h 264679 2014-04-19 19:21:06Z tuexen $");
+__FBSDID("$FreeBSD: head/sys/netinet/sctputil.h 269376 2014-08-01 12:42:37Z tuexen $");
#endif
#ifndef _NETINET_SCTP_UTIL_H_
@@ -146,9 +146,11 @@ struct sctp_paramhdr *
sctp_get_next_param(struct mbuf *, int,
struct sctp_paramhdr *, int);
-int sctp_add_pad_tombuf(struct mbuf *, int);
+struct mbuf *
+sctp_add_pad_tombuf(struct mbuf *, int);
-int sctp_pad_lastmbuf(struct mbuf *, int, struct mbuf *);
+struct mbuf *
+sctp_pad_lastmbuf(struct mbuf *, int, struct mbuf *);
void sctp_ulp_notify(uint32_t, struct sctp_tcb *, uint32_t, void *, int
#if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING)
@@ -240,10 +242,10 @@ sctp_recover_scope(struct sockaddr_in6 *, struct sockaddr_in6 *);
} while (0)
#else
#define sctp_recover_scope_mac(addr, store) do { \
- if ((addr->sin6_family == AF_INET6) && \
- (IN6_IS_SCOPE_LINKLOCAL(&addr->sin6_addr))) { \
+ if ((addr->sin6_family == AF_INET6) && \
+ (IN6_IS_SCOPE_LINKLOCAL(&addr->sin6_addr))) { \
*store = *addr; \
- if (addr->sin6_scope_id == 0) { \
+ if (addr->sin6_scope_id == 0) { \
if (!in6_recoverscope(store, &store->sin6_addr, \
NULL)) { \
addr = store; \
@@ -252,7 +254,7 @@ sctp_recover_scope(struct sockaddr_in6 *, struct sockaddr_in6 *);
in6_clearscope(&addr->sin6_addr); \
addr = store; \
} \
- } \
+ } \
} while (0)
#endif
#endif
@@ -291,42 +293,42 @@ sctp_free_bufspace(struct sctp_tcb *, struct sctp_association *,
#define sctp_free_bufspace(stcb, asoc, tp1, chk_cnt) \
do { \
if (tp1->data != NULL) { \
- atomic_subtract_int(&((asoc)->chunks_on_out_queue), chk_cnt); \
+ atomic_subtract_int(&((asoc)->chunks_on_out_queue), chk_cnt); \
if ((asoc)->total_output_queue_size >= tp1->book_size) { \
atomic_subtract_int(&((asoc)->total_output_queue_size), tp1->book_size); \
} else { \
(asoc)->total_output_queue_size = 0; \
} \
- if (stcb->sctp_socket && ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || \
- (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL))) { \
+ if (stcb->sctp_socket && ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || \
+ (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL))) { \
if (stcb->sctp_socket->so_snd.sb_cc >= tp1->book_size) { \
atomic_subtract_int(&((stcb)->sctp_socket->so_snd.sb_cc), tp1->book_size); \
} else { \
stcb->sctp_socket->so_snd.sb_cc = 0; \
} \
} \
- } \
+ } \
} while (0)
#endif
#define sctp_free_spbufspace(stcb, asoc, sp) \
do { \
- if (sp->data != NULL) { \
+ if (sp->data != NULL) { \
if ((asoc)->total_output_queue_size >= sp->length) { \
atomic_subtract_int(&(asoc)->total_output_queue_size, sp->length); \
} else { \
(asoc)->total_output_queue_size = 0; \
} \
- if (stcb->sctp_socket && ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || \
- (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL))) { \
+ if (stcb->sctp_socket && ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || \
+ (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL))) { \
if (stcb->sctp_socket->so_snd.sb_cc >= sp->length) { \
atomic_subtract_int(&stcb->sctp_socket->so_snd.sb_cc,sp->length); \
} else { \
stcb->sctp_socket->so_snd.sb_cc = 0; \
} \
} \
- } \
+ } \
} while (0)
#define sctp_snd_sb_alloc(stcb, sz) \
diff --git a/netinet6/sctp6_usrreq.c b/netinet6/sctp6_usrreq.c
index 45a3196..3874794 100644
--- a/netinet6/sctp6_usrreq.c
+++ b/netinet6/sctp6_usrreq.c
@@ -32,7 +32,7 @@
#ifdef __FreeBSD__
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/netinet6/sctp6_usrreq.c 257555 2013-11-02 20:12:19Z tuexen $");
+__FBSDID("$FreeBSD: head/sys/netinet6/sctp6_usrreq.c 271221 2014-09-07 09:06:26Z tuexen $");
#endif
#include <netinet/sctp_os.h>
@@ -246,7 +246,7 @@ sctp6_input(struct mbuf **i_pak, int *offp, int proto)
#if defined(__APPLE__)
/* XXX: This code should also be used on Apple */
#endif
- if (in6_setscope(&src.sin6_addr, m->m_pkthdr.rcvif, NULL) != 0) {
+ if (in6_setscope(&src.sin6_addr, m->m_pkthdr.rcvif, NULL) != 0) {
goto out;
}
#endif
@@ -261,7 +261,7 @@ sctp6_input(struct mbuf **i_pak, int *offp, int proto)
#if defined(__APPLE__)
/* XXX: This code should also be used on Apple */
#endif
- if (in6_setscope(&dst.sin6_addr, m->m_pkthdr.rcvif, NULL) != 0) {
+ if (in6_setscope(&dst.sin6_addr, m->m_pkthdr.rcvif, NULL) != 0) {
goto out;
}
#endif
@@ -1184,7 +1184,7 @@ sctp6_connect(struct socket *so, struct mbuf *nam, struct proc *p)
#ifdef INET
struct in6pcb *inp6;
struct sockaddr_in6 *sin6;
- struct sockaddr_storage ss;
+ union sctp_sockstore store;
#endif
#ifdef INET
@@ -1273,8 +1273,8 @@ sctp6_connect(struct socket *so, struct mbuf *nam, struct proc *p)
}
if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
/* convert v4-mapped into v4 addr */
- in6_sin6_2_sin((struct sockaddr_in *)&ss, sin6);
- addr = (struct sockaddr *)&ss;
+ in6_sin6_2_sin(&store.sin, sin6);
+ addr = &store.sa;
}
#endif /* INET */
/* Now do we connect? */
@@ -1424,7 +1424,7 @@ sctp6_getaddr(struct socket *so, struct mbuf *nam)
if (laddr->ifa->address.sa.sa_family == AF_INET6) {
struct sockaddr_in6 *sin_a;
- sin_a = (struct sockaddr_in6 *)&laddr->ifa->address.sin6;
+ sin_a = &laddr->ifa->address.sin6;
sin6->sin6_addr = sin_a->sin6_addr;
fnd = 1;
break;
@@ -1729,7 +1729,7 @@ struct pr_usrreqs sctp6_usrreqs = {
.pru_sockaddr = sctp6_in6getaddr,
.pru_sosend = sctp_sosend,
.pru_soreceive = sctp_soreceive,
- .pru_sopoll = sopoll
+ .pru_sopoll = sopoll
#elif defined(__Windows__)
sctp6_abort,
sctp_accept,
diff --git a/user_socket.c b/user_socket.c
index 1b44f11..9a0e0c7 100755
--- a/user_socket.c
+++ b/user_socket.c
@@ -710,6 +710,7 @@ userspace_sctp_sendmsg(struct socket *so,
struct uio auio;
struct iovec iov[1];
+ memset(sinfo, 0, sizeof(struct sctp_sndrcvinfo));
sinfo->sinfo_ppid = ppid;
sinfo->sinfo_flags = flags;
sinfo->sinfo_stream = stream_no;
@@ -3247,6 +3248,12 @@ 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_auth_enable)
+USRSCTP_SYSCTL_SET_DEF(sctp_asconf_enable)
+USRSCTP_SYSCTL_SET_DEF(sctp_reconfig_enable)
+USRSCTP_SYSCTL_SET_DEF(sctp_nrsack_enable)
+USRSCTP_SYSCTL_SET_DEF(sctp_pktdrop_enable)
USRSCTP_SYSCTL_SET_DEF(sctp_strict_sacks)
#if !defined(SCTP_WITH_NO_CSUM)
USRSCTP_SYSCTL_SET_DEF(sctp_no_csum_on_loopback)
@@ -3278,10 +3285,7 @@ USRSCTP_SYSCTL_SET_DEF(sctp_add_more_threshold)
USRSCTP_SYSCTL_SET_DEF(sctp_nr_outgoing_streams_default)
USRSCTP_SYSCTL_SET_DEF(sctp_cmt_on_off)
USRSCTP_SYSCTL_SET_DEF(sctp_cmt_use_dac)
-USRSCTP_SYSCTL_SET_DEF(sctp_nr_sack_on_off)
USRSCTP_SYSCTL_SET_DEF(sctp_use_cwnd_based_maxburst)
-USRSCTP_SYSCTL_SET_DEF(sctp_asconf_auth_nochk)
-USRSCTP_SYSCTL_SET_DEF(sctp_auth_disable)
USRSCTP_SYSCTL_SET_DEF(sctp_nat_friendly)
USRSCTP_SYSCTL_SET_DEF(sctp_L2_abc_variable)
USRSCTP_SYSCTL_SET_DEF(sctp_mbuf_threshold_count)
@@ -3326,6 +3330,12 @@ 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_auth_enable)
+USRSCTP_SYSCTL_GET_DEF(sctp_asconf_enable)
+USRSCTP_SYSCTL_GET_DEF(sctp_reconfig_enable)
+USRSCTP_SYSCTL_GET_DEF(sctp_nrsack_enable)
+USRSCTP_SYSCTL_GET_DEF(sctp_pktdrop_enable)
USRSCTP_SYSCTL_GET_DEF(sctp_strict_sacks)
#if !defined(SCTP_WITH_NO_CSUM)
USRSCTP_SYSCTL_GET_DEF(sctp_no_csum_on_loopback)
@@ -3357,10 +3367,7 @@ USRSCTP_SYSCTL_GET_DEF(sctp_add_more_threshold)
USRSCTP_SYSCTL_GET_DEF(sctp_nr_outgoing_streams_default)
USRSCTP_SYSCTL_GET_DEF(sctp_cmt_on_off)
USRSCTP_SYSCTL_GET_DEF(sctp_cmt_use_dac)
-USRSCTP_SYSCTL_GET_DEF(sctp_nr_sack_on_off)
USRSCTP_SYSCTL_GET_DEF(sctp_use_cwnd_based_maxburst)
-USRSCTP_SYSCTL_GET_DEF(sctp_asconf_auth_nochk)
-USRSCTP_SYSCTL_GET_DEF(sctp_auth_disable)
USRSCTP_SYSCTL_GET_DEF(sctp_nat_friendly)
USRSCTP_SYSCTL_GET_DEF(sctp_L2_abc_variable)
USRSCTP_SYSCTL_GET_DEF(sctp_mbuf_threshold_count)
diff --git a/usrsctp.h b/usrsctp.h
index b72eeb6..0e922bf 100644
--- a/usrsctp.h
+++ b/usrsctp.h
@@ -983,7 +983,7 @@ usrsctp_dumppacket(void *, size_t, int);
void
usrsctp_freedumpbuffer(char *);
-#define USRSCTP_SYSCTL_DECL(__field) \
+#define USRSCTP_SYSCTL_DECL(__field) \
void usrsctp_sysctl_set_ ## __field(uint32_t value);\
uint32_t usrsctp_sysctl_get_ ## __field(void);
@@ -992,6 +992,12 @@ 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_auth_enable)
+USRSCTP_SYSCTL_DECL(sctp_asconf_enable)
+USRSCTP_SYSCTL_DECL(sctp_reconfig_enable)
+USRSCTP_SYSCTL_DECL(sctp_nrsack_enable)
+USRSCTP_SYSCTL_DECL(sctp_pktdrop_enable)
USRSCTP_SYSCTL_DECL(sctp_strict_sacks)
#if !defined(SCTP_WITH_NO_CSUM)
USRSCTP_SYSCTL_DECL(sctp_no_csum_on_loopback)
@@ -1024,10 +1030,7 @@ USRSCTP_SYSCTL_DECL(sctp_nr_incoming_streams_default)
USRSCTP_SYSCTL_DECL(sctp_nr_outgoing_streams_default)
USRSCTP_SYSCTL_DECL(sctp_cmt_on_off)
USRSCTP_SYSCTL_DECL(sctp_cmt_use_dac)
-USRSCTP_SYSCTL_DECL(sctp_nr_sack_on_off)
USRSCTP_SYSCTL_DECL(sctp_use_cwnd_based_maxburst)
-USRSCTP_SYSCTL_DECL(sctp_asconf_auth_nochk)
-USRSCTP_SYSCTL_DECL(sctp_auth_disable)
USRSCTP_SYSCTL_DECL(sctp_nat_friendly)
USRSCTP_SYSCTL_DECL(sctp_L2_abc_variable)
USRSCTP_SYSCTL_DECL(sctp_mbuf_threshold_count)