summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/netinet/sctp_asconf.c47
-rw-r--r--sys/netinet/sctp_asconf.h7
-rw-r--r--sys/netinet/sctp_auth.c50
-rw-r--r--sys/netinet/sctp_bsd_addr.c17
-rw-r--r--sys/netinet/sctp_indata.c324
-rw-r--r--sys/netinet/sctp_input.c171
-rw-r--r--sys/netinet/sctp_os.h6
-rw-r--r--sys/netinet/sctp_os_bsd.h69
-rw-r--r--sys/netinet/sctp_output.c965
-rw-r--r--sys/netinet/sctp_pcb.c102
-rw-r--r--sys/netinet/sctp_pcb.h1
-rw-r--r--sys/netinet/sctp_structs.h8
-rw-r--r--sys/netinet/sctp_timer.c19
-rw-r--r--sys/netinet/sctp_usrreq.c247
-rw-r--r--sys/netinet/sctp_var.h80
-rw-r--r--sys/netinet/sctputil.c410
-rw-r--r--sys/netinet6/sctp6_usrreq.c40
17 files changed, 1222 insertions, 1341 deletions
diff --git a/sys/netinet/sctp_asconf.c b/sys/netinet/sctp_asconf.c
index de1bc86..0d2fe04 100644
--- a/sys/netinet/sctp_asconf.c
+++ b/sys/netinet/sctp_asconf.c
@@ -178,7 +178,7 @@ sctp_asconf_success_response(uint32_t id)
aph->correlation_id = id;
aph->ph.param_type = htons(SCTP_SUCCESS_REPORT);
aph->ph.param_length = sizeof(struct sctp_asconf_paramhdr);
- m_reply->m_len = aph->ph.param_length;
+ SCTP_BUF_LEN(m_reply) = aph->ph.param_length;
aph->ph.param_length = htons(aph->ph.param_length);
return m_reply;
@@ -229,7 +229,7 @@ sctp_asconf_error_response(uint32_t id, uint16_t cause, uint8_t * error_tlv,
tlv = (uint8_t *) (error + 1);
memcpy(tlv, error_tlv, tlv_length);
}
- m_reply->m_len = aph->ph.param_length;
+ SCTP_BUF_LEN(m_reply) = aph->ph.param_length;
error->length = htons(error->length);
aph->ph.param_length = htons(aph->ph.param_length);
@@ -327,7 +327,7 @@ sctp_process_asconf_add_ip(struct mbuf *m, struct sctp_asconf_paramhdr *aph,
} /* end switch */
/* if 0.0.0.0/::0, add the source address instead */
- if (zero_address) {
+ if (zero_address && sctp_nat_friendly) {
sa = (struct sockaddr *)&sa_source;
sctp_asconf_get_source_ip(m, sa);
#ifdef SCTP_DEBUG
@@ -500,7 +500,7 @@ sctp_process_asconf_delete_ip(struct mbuf *m, struct sctp_asconf_paramhdr *aph,
return m_reply;
}
/* if deleting 0.0.0.0/::0, delete all addresses except src addr */
- if (zero_address) {
+ if (zero_address && sctp_nat_friendly) {
result = sctp_asconf_del_remote_addrs_except(stcb,
(struct sockaddr *)&sa_source);
@@ -637,7 +637,7 @@ sctp_process_asconf_set_primary(struct mbuf *m,
}
/* if 0.0.0.0/::0, use the source address instead */
- if (zero_address) {
+ if (zero_address && sctp_nat_friendly) {
sa = (struct sockaddr *)&sa_source;
sctp_asconf_get_source_ip(m, sa);
#ifdef SCTP_DEBUG
@@ -744,7 +744,7 @@ sctp_handle_asconf(struct mbuf *m, unsigned int offset,
sctp_m_freem(asoc->last_asconf_ack_sent);
asoc->last_asconf_ack_sent = NULL;
}
- m_ack = sctp_get_mbuf_for_msg(sizeof(struct sctp_asconf_ack_chunk), 1,
+ m_ack = sctp_get_mbuf_for_msg(sizeof(struct sctp_asconf_ack_chunk), 0,
M_DONTWAIT, 1, MT_DATA);
if (m_ack == NULL) {
#ifdef SCTP_DEBUG
@@ -762,9 +762,8 @@ sctp_handle_asconf(struct mbuf *m, unsigned int offset,
ack_cp->ch.chunk_flags = 0;
ack_cp->serial_number = htonl(serial_num);
/* set initial lengths (eg. just an ASCONF-ACK), ntohx at the end! */
- m_ack->m_len = sizeof(struct sctp_asconf_ack_chunk);
+ SCTP_BUF_LEN(m_ack) = sizeof(struct sctp_asconf_ack_chunk);
ack_cp->ch.chunk_length = sizeof(struct sctp_asconf_ack_chunk);
- m_ack->m_pkthdr.len = sizeof(struct sctp_asconf_ack_chunk);
/* skip the lookup address parameter */
offset += sizeof(struct sctp_asconf_chunk);
@@ -881,12 +880,11 @@ sctp_handle_asconf(struct mbuf *m, unsigned int offset,
/* add any (error) result to the reply mbuf chain */
if (m_result != NULL) {
- m_tail->m_next = m_result;
+ SCTP_BUF_NEXT(m_tail) = m_result;
m_tail = m_result;
/* update lengths, make sure it's aligned too */
- m_result->m_len = SCTP_SIZE32(m_result->m_len);
- m_ack->m_pkthdr.len += m_result->m_len;
- ack_cp->ch.chunk_length += m_result->m_len;
+ SCTP_BUF_LEN(m_result) = SCTP_SIZE32(SCTP_BUF_LEN(m_result));
+ ack_cp->ch.chunk_length += SCTP_BUF_LEN(m_result);
/* set flag to force success reports */
error = 1;
}
@@ -2245,7 +2243,7 @@ sctp_find_valid_localaddr_ep(struct sctp_tcb *stcb)
* mbuf, no ASCONF params queued, etc)
*/
struct mbuf *
-sctp_compose_asconf(struct sctp_tcb *stcb)
+sctp_compose_asconf(struct sctp_tcb *stcb, int *retlen)
{
struct mbuf *m_asconf, *m_asconf_chk;
struct sctp_asconf_addr *aa;
@@ -2266,7 +2264,7 @@ sctp_compose_asconf(struct sctp_tcb *stcb)
* it's simpler to fill in the asconf chunk header lookup address on
* the fly
*/
- m_asconf_chk = sctp_get_mbuf_for_msg(sizeof(struct sctp_asconf_chunk), 1, M_DONTWAIT, 1, MT_DATA);
+ m_asconf_chk = sctp_get_mbuf_for_msg(sizeof(struct sctp_asconf_chunk), 0, M_DONTWAIT, 1, MT_DATA);
if (m_asconf_chk == NULL) {
/* no mbuf's */
#ifdef SCTP_DEBUG
@@ -2275,7 +2273,7 @@ sctp_compose_asconf(struct sctp_tcb *stcb)
#endif /* SCTP_DEBUG */
return (NULL);
}
- m_asconf = sctp_get_mbuf_for_msg(MCLBYTES, 1, M_DONTWAIT, 1, MT_DATA);
+ m_asconf = sctp_get_mbuf_for_msg(MCLBYTES, 0, M_DONTWAIT, 1, MT_DATA);
if (m_asconf == NULL) {
/* no mbuf's */
#ifdef SCTP_DEBUG
@@ -2285,8 +2283,8 @@ sctp_compose_asconf(struct sctp_tcb *stcb)
sctp_m_freem(m_asconf_chk);
return (NULL);
}
- m_asconf_chk->m_len = sizeof(struct sctp_asconf_chunk);
- m_asconf->m_len = 0;
+ SCTP_BUF_LEN(m_asconf_chk) = sizeof(struct sctp_asconf_chunk);
+ SCTP_BUF_LEN(m_asconf) = 0;
acp = mtod(m_asconf_chk, struct sctp_asconf_chunk *);
bzero(acp, sizeof(struct sctp_asconf_chunk));
/* save pointers to lookup address and asconf params */
@@ -2303,7 +2301,7 @@ sctp_compose_asconf(struct sctp_tcb *stcb)
/* get the parameter length */
p_length = SCTP_SIZE32(aa->ap.aph.ph.param_length);
/* will it fit in current chunk? */
- if (m_asconf->m_len + p_length > stcb->asoc.smallest_mtu) {
+ if (SCTP_BUF_LEN(m_asconf) + p_length > stcb->asoc.smallest_mtu) {
/* won't fit, so we're done with this chunk */
break;
}
@@ -2336,7 +2334,7 @@ sctp_compose_asconf(struct sctp_tcb *stcb)
}
lookup->ph.param_length = htons(SCTP_SIZE32(p_size));
memcpy(lookup->addr, &aa->ap.addrp.addr, addr_size);
- m_asconf_chk->m_len += SCTP_SIZE32(p_size);
+ SCTP_BUF_LEN(m_asconf_chk) += SCTP_SIZE32(p_size);
lookup_used = 1;
}
/* copy into current space */
@@ -2351,7 +2349,7 @@ sctp_compose_asconf(struct sctp_tcb *stcb)
aap->addrp.ph.param_type = htons(aap->addrp.ph.param_type);
aap->addrp.ph.param_length = htons(aap->addrp.ph.param_length);
- m_asconf->m_len += SCTP_SIZE32(p_length);
+ SCTP_BUF_LEN(m_asconf) += SCTP_SIZE32(p_length);
ptr += SCTP_SIZE32(p_length);
/*
@@ -2395,7 +2393,7 @@ sctp_compose_asconf(struct sctp_tcb *stcb)
}
lookup->ph.param_length = htons(SCTP_SIZE32(p_size));
memcpy(lookup->addr, addr_ptr, addr_size);
- m_asconf_chk->m_len += SCTP_SIZE32(p_size);
+ SCTP_BUF_LEN(m_asconf_chk) += SCTP_SIZE32(p_size);
lookup_used = 1;
} else {
/* uh oh... don't have any address?? */
@@ -2407,14 +2405,13 @@ sctp_compose_asconf(struct sctp_tcb *stcb)
lookup->ph.param_type = htons(SCTP_IPV4_ADDRESS);
lookup->ph.param_length = htons(SCTP_SIZE32(sizeof(struct sctp_ipv4addr_param)));
bzero(lookup->addr, sizeof(struct in_addr));
- m_asconf_chk->m_len += SCTP_SIZE32(sizeof(struct sctp_ipv4addr_param));
+ SCTP_BUF_LEN(m_asconf_chk) += SCTP_SIZE32(sizeof(struct sctp_ipv4addr_param));
lookup_used = 1;
}
}
/* chain it all together */
- m_asconf_chk->m_next = m_asconf;
- m_asconf_chk->m_pkthdr.len = m_asconf_chk->m_len + m_asconf->m_len;
- acp->ch.chunk_length = ntohs(m_asconf_chk->m_pkthdr.len);
+ SCTP_BUF_NEXT(m_asconf_chk) = m_asconf;
+ *retlen = acp->ch.chunk_length = ntohs(SCTP_BUF_LEN(m_asconf_chk) + SCTP_BUF_LEN(m_asconf));
/* update "sent" flag */
stcb->asoc.asconf_sent++;
diff --git a/sys/netinet/sctp_asconf.h b/sys/netinet/sctp_asconf.h
index e3e7df4..df9e465 100644
--- a/sys/netinet/sctp_asconf.h
+++ b/sys/netinet/sctp_asconf.h
@@ -36,16 +36,17 @@ __FBSDID("$FreeBSD$");
#ifndef _NETINET_SCTP_ASCONF_H_
#define _NETINET_SCTP_ASCONF_H_
-
#include <sys/malloc.h>
-
#if defined(_KERNEL)
+/*
+ * function prototypes
+ */
extern void sctp_asconf_cleanup(struct sctp_tcb *, struct sctp_nets *);
-extern struct mbuf *sctp_compose_asconf(struct sctp_tcb *);
+extern struct mbuf *sctp_compose_asconf(struct sctp_tcb *, int *);
extern void
sctp_handle_asconf(struct mbuf *, unsigned int, struct sctp_asconf_chunk *,
diff --git a/sys/netinet/sctp_auth.c b/sys/netinet/sctp_auth.c
index a87f47f..d5fe70a 100644
--- a/sys/netinet/sctp_auth.c
+++ b/sys/netinet/sctp_auth.c
@@ -372,7 +372,7 @@ sctp_generate_random_key(uint32_t keylen)
/* out of memory */
return (NULL);
}
- sctp_read_random(new_key->key, keylen);
+ SCTP_READ_RANDOM(new_key->key, keylen);
new_key->keylen = keylen;
return (new_key);
}
@@ -1110,17 +1110,18 @@ sctp_hmac_m(uint16_t hmac_algo, uint8_t * key, uint32_t keylen,
sctp_hmac_update(hmac_algo, &ctx, ipad, blocklen);
/* find the correct starting mbuf and offset (get start of text) */
m_tmp = m;
- while ((m_tmp != NULL) && (m_offset >= (uint32_t) m_tmp->m_len)) {
- m_offset -= m_tmp->m_len;
- m_tmp = m_tmp->m_next;
+ while ((m_tmp != NULL) && (m_offset >= (uint32_t) SCTP_BUF_LEN(m_tmp))) {
+ m_offset -= SCTP_BUF_LEN(m_tmp);
+ m_tmp = SCTP_BUF_NEXT(m_tmp);
}
/* now use the rest of the mbuf chain for the text */
while (m_tmp != NULL) {
sctp_hmac_update(hmac_algo, &ctx, mtod(m_tmp, uint8_t *) + m_offset,
- m_tmp->m_len - m_offset);
+ SCTP_BUF_LEN(m_tmp) - m_offset);
+
/* clear the offset since it's only for the first mbuf */
m_offset = 0;
- m_tmp = m_tmp->m_next;
+ m_tmp = SCTP_BUF_NEXT(m_tmp);
}
sctp_hmac_final(hmac_algo, &ctx, temp);
@@ -1618,23 +1619,23 @@ sctp_bzero_m(struct mbuf *m, uint32_t m_offset, uint32_t size)
/* find the correct starting mbuf and offset (get start position) */
m_tmp = m;
- while ((m_tmp != NULL) && (m_offset >= (uint32_t) m_tmp->m_len)) {
- m_offset -= m_tmp->m_len;
- m_tmp = m_tmp->m_next;
+ while ((m_tmp != NULL) && (m_offset >= (uint32_t) SCTP_BUF_LEN(m_tmp))) {
+ m_offset -= SCTP_BUF_LEN(m_tmp);
+ m_tmp = SCTP_BUF_NEXT(m_tmp);
}
/* now use the rest of the mbuf chain */
while ((m_tmp != NULL) && (size > 0)) {
data = mtod(m_tmp, uint8_t *) + m_offset;
- if (size > (uint32_t) m_tmp->m_len) {
- bzero(data, m_tmp->m_len);
- size -= m_tmp->m_len;
+ if (size > (uint32_t) SCTP_BUF_LEN(m_tmp)) {
+ bzero(data, SCTP_BUF_LEN(m_tmp));
+ size -= SCTP_BUF_LEN(m_tmp);
} else {
bzero(data, size);
size = 0;
}
/* clear the offset since it's only for the first mbuf */
m_offset = 0;
- m_tmp = m_tmp->m_next;
+ m_tmp = SCTP_BUF_NEXT(m_tmp);
}
}
@@ -1685,17 +1686,17 @@ sctp_handle_auth(struct sctp_tcb *stcb, struct sctp_auth_chunk *auth,
* report this in an Error Chunk: Unsupported HMAC
* Identifier
*/
- m_err = sctp_get_mbuf_for_msg(sizeof(*err), 1, M_DONTWAIT, 1, MT_HEADER);
+ m_err = sctp_get_mbuf_for_msg(sizeof(*err), 0, M_DONTWAIT, 1, MT_HEADER);
if (m_err != NULL) {
/* pre-reserve some space */
- m_err->m_data += sizeof(struct sctp_chunkhdr);
+ SCTP_BUF_RESV_UF(m_err, sizeof(struct sctp_chunkhdr));
/* fill in the error */
err = mtod(m_err, struct sctp_auth_invalid_hmac *);
bzero(err, sizeof(*err));
err->ph.param_type = htons(SCTP_CAUSE_UNSUPPORTED_HMACID);
err->ph.param_length = htons(sizeof(*err));
err->hmac_id = ntohs(hmac_id);
- m_err->m_pkthdr.len = m_err->m_len = sizeof(*err);
+ SCTP_BUF_LEN(m_err) = sizeof(*err);
/* queue it */
sctp_queue_op_err(stcb, m_err);
}
@@ -1787,11 +1788,12 @@ sctp_notify_authentication(struct sctp_tcb *stcb, uint32_t indication,
return;
m_notify = sctp_get_mbuf_for_msg(sizeof(struct sctp_authkey_event),
- 1, M_DONTWAIT, 1, MT_HEADER);
+ 0, M_DONTWAIT, 1, MT_HEADER);
if (m_notify == NULL)
/* no space left */
return;
- m_notify->m_len = 0;
+
+ SCTP_BUF_LEN(m_notify) = 0;
auth = mtod(m_notify, struct sctp_authkey_event *);
auth->auth_type = SCTP_AUTHENTICATION_EVENT;
auth->auth_flags = 0;
@@ -1801,11 +1803,8 @@ sctp_notify_authentication(struct sctp_tcb *stcb, uint32_t indication,
auth->auth_indication = indication;
auth->auth_assoc_id = sctp_get_associd(stcb);
- m_notify->m_flags |= M_EOR | M_NOTIFICATION;
- m_notify->m_pkthdr.len = sizeof(*auth);
- m_notify->m_pkthdr.rcvif = 0;
- m_notify->m_len = sizeof(*auth);
- m_notify->m_next = NULL;
+ SCTP_BUF_LEN(m_notify) = sizeof(*auth);
+ SCTP_BUF_NEXT(m_notify) = NULL;
/* append to socket */
control = sctp_build_readq_entry(stcb, stcb->asoc.primary_destination,
@@ -1815,7 +1814,8 @@ sctp_notify_authentication(struct sctp_tcb *stcb, uint32_t indication,
sctp_m_freem(m_notify);
return;
}
- control->length = m_notify->m_len;
+ control->spec_flags = M_NOTIFICATION;
+ control->length = SCTP_BUF_LEN(m_notify);
/* not that we need this */
control->tail_mbuf = m_notify;
sctp_add_to_readq(stcb->sctp_ep, stcb, control,
@@ -1969,7 +1969,7 @@ sctp_initialize_auth_params(struct sctp_inpcb *inp, struct sctp_tcb *stcb)
new_key = sctp_alloc_key(keylen);
if (new_key != NULL) {
/* generate and copy in the RANDOM */
- sctp_read_random(new_key->key, random_len);
+ SCTP_READ_RANDOM(new_key->key, random_len);
keylen = random_len;
/* append in the AUTH chunks */
if (stcb->asoc.local_auth_chunks) {
diff --git a/sys/netinet/sctp_bsd_addr.c b/sys/netinet/sctp_bsd_addr.c
index 7d1265c..6cdbc6c 100644
--- a/sys/netinet/sctp_bsd_addr.c
+++ b/sys/netinet/sctp_bsd_addr.c
@@ -1873,23 +1873,22 @@ sctp_add_addr_to_mbuf(struct mbuf *m, struct ifaddr *ifa)
/* unknown type */
return (m);
}
-
if (M_TRAILINGSPACE(m) >= len) {
/* easy side we just drop it on the end */
- parmh = (struct sctp_paramhdr *)(m->m_data + m->m_len);
+ parmh = (struct sctp_paramhdr *)(SCTP_BUF_AT(m, SCTP_BUF_LEN(m)));
mret = m;
} else {
/* Need more space */
mret = m;
- while (mret->m_next != NULL) {
- mret = mret->m_next;
+ while (SCTP_BUF_NEXT(mret) != NULL) {
+ mret = SCTP_BUF_NEXT(mret);
}
- mret->m_next = sctp_get_mbuf_for_msg(len, 0, M_DONTWAIT, 1, MT_DATA);
- if (mret->m_next == NULL) {
+ SCTP_BUF_NEXT(mret) = sctp_get_mbuf_for_msg(len, 0, M_DONTWAIT, 1, MT_DATA);
+ if (SCTP_BUF_NEXT(mret) == NULL) {
/* We are hosed, can't add more addresses */
return (m);
}
- mret = mret->m_next;
+ mret = SCTP_BUF_NEXT(mret);
parmh = mtod(mret, struct sctp_paramhdr *);
}
/* now add the parameter */
@@ -1902,7 +1901,7 @@ sctp_add_addr_to_mbuf(struct mbuf *m, struct ifaddr *ifa)
parmh->param_type = htons(SCTP_IPV4_ADDRESS);
parmh->param_length = htons(len);
ipv4p->addr = sin->sin_addr.s_addr;
- mret->m_len += len;
+ SCTP_BUF_LEN(mret) += len;
} else if (ifa->ifa_addr->sa_family == AF_INET6) {
struct sctp_ipv6addr_param *ipv6p;
struct sockaddr_in6 *sin6;
@@ -1915,7 +1914,7 @@ sctp_add_addr_to_mbuf(struct mbuf *m, struct ifaddr *ifa)
sizeof(ipv6p->addr));
/* clear embedded scope in the address */
in6_clearscope((struct in6_addr *)ipv6p->addr);
- mret->m_len += len;
+ SCTP_BUF_LEN(mret) += len;
} else {
return (m);
}
diff --git a/sys/netinet/sctp_indata.c b/sys/netinet/sctp_indata.c
index de25893..935ecf1 100644
--- a/sys/netinet/sctp_indata.c
+++ b/sys/netinet/sctp_indata.c
@@ -252,6 +252,7 @@ sctp_build_readq_entry(struct sctp_tcb *stcb,
read_queue_e->length = 0;
atomic_add_int(&net->ref_count, 1);
read_queue_e->data = dm;
+ read_queue_e->spec_flags = 0;
read_queue_e->tail_mbuf = NULL;
read_queue_e->stcb = stcb;
read_queue_e->port_from = stcb->rport;
@@ -292,6 +293,7 @@ sctp_build_readq_entry_chk(struct sctp_tcb *stcb,
read_queue_e->tail_mbuf = NULL;
read_queue_e->stcb = stcb;
read_queue_e->port_from = stcb->rport;
+ read_queue_e->spec_flags = 0;
read_queue_e->do_not_ref_stcb = 0;
read_queue_e->end_added = 0;
read_queue_e->pdapi_aborted = 0;
@@ -323,7 +325,7 @@ sctp_build_ctl_nchunk(struct sctp_inpcb *inp,
ret = sctp_get_mbuf_for_msg(len,
- 1, M_DONTWAIT, 1, MT_DATA);
+ 0, M_DONTWAIT, 1, MT_DATA);
if (ret == NULL) {
/* No space */
@@ -342,11 +344,11 @@ sctp_build_ctl_nchunk(struct sctp_inpcb *inp,
cmh->cmsg_len = len;
*outinfo = *sinfo;
}
- ret->m_len = cmh->cmsg_len;
- ret->m_pkthdr.len = ret->m_len;
+ SCTP_BUF_LEN(ret) = cmh->cmsg_len;
return (ret);
}
+
/*
* We are delivering currently from the reassembly queue. We must continue to
* deliver until we either: 1) run out of space. 2) run out of sequential
@@ -356,7 +358,6 @@ static void
sctp_service_reassembly(struct sctp_tcb *stcb, struct sctp_association *asoc)
{
struct sctp_tmit_chunk *chk;
- struct mbuf *m;
uint16_t nxt_todel;
uint16_t stream_no;
int end = 0;
@@ -410,34 +411,6 @@ sctp_service_reassembly(struct sctp_tcb *stcb, struct sctp_association *asoc)
*/
return;
}
- if ((chk->data->m_flags & M_PKTHDR) == 0) {
- m = sctp_get_mbuf_for_msg(1,
- 1, M_DONTWAIT, 1, MT_DATA);
- if (m == NULL) {
- /* no room! */
- return;
- }
- m->m_pkthdr.len = chk->send_size;
- m->m_len = 0;
- m->m_next = chk->data;
- chk->data = m;
- }
- if (chk->rec.data.rcv_flags & SCTP_DATA_LAST_FRAG) {
- if (chk->data->m_next == NULL) {
- /* hopefully we hit here most of the time */
- chk->data->m_flags |= M_EOR;
- } else {
- /*
- * Add the flag to the LAST mbuf in the
- * chain
- */
- m = chk->data;
- while (m->m_next != NULL) {
- m = m->m_next;
- }
- m->m_flags |= M_EOR;
- }
- }
if (chk->rec.data.rcv_flags & SCTP_DATA_FIRST_FRAG) {
control = sctp_build_readq_entry_chk(stcb, chk);
@@ -540,7 +513,7 @@ sctp_service_reassembly(struct sctp_tcb *stcb, struct sctp_association *asoc)
nxt_todel = strm->last_sequence_delivered + 1;
}
}
- return;
+ break;
}
chk = TAILQ_FIRST(&asoc->reasmqueue);
} while (chk);
@@ -611,17 +584,17 @@ sctp_queue_data_to_stream(struct sctp_tcb *stcb, struct sctp_association *asoc,
* association destruction
*/
TAILQ_INSERT_HEAD(&strm->inqueue, control, next);
- oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + sizeof(uint32_t)),
+ oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + 3 * sizeof(uint32_t)),
0, M_DONTWAIT, 1, MT_DATA);
if (oper) {
struct sctp_paramhdr *ph;
uint32_t *ippp;
- oper->m_len = sizeof(struct sctp_paramhdr) +
+ SCTP_BUF_LEN(oper) = sizeof(struct sctp_paramhdr) +
(sizeof(uint32_t) * 3);
ph = mtod(oper, struct sctp_paramhdr *);
ph->param_type = htons(SCTP_CAUSE_PROTOCOL_VIOLATION);
- ph->param_length = htons(oper->m_len);
+ ph->param_length = htons(SCTP_BUF_LEN(oper));
ippp = (uint32_t *) (ph + 1);
*ippp = htonl(SCTP_FROM_SCTP_INDATA + SCTP_LOC_1);
ippp++;
@@ -789,6 +762,7 @@ sctp_deliver_reasm_check(struct sctp_tcb *stcb, struct sctp_association *asoc)
uint16_t nxt_todel;
uint32_t tsize;
+doit_again:
chk = TAILQ_FIRST(&asoc->reasmqueue);
if (chk == NULL) {
/* Huh? */
@@ -826,7 +800,20 @@ sctp_deliver_reasm_check(struct sctp_tcb *stcb, struct sctp_association *asoc)
}
}
} else {
+ /*
+ * Service re-assembly will deliver stream data queued at
+ * the end of fragmented delivery.. but it wont know to go
+ * back and call itself again... we do that here with the
+ * got doit_again
+ */
sctp_service_reassembly(stcb, asoc);
+ if (asoc->fragmented_delivery_inprogress == 0) {
+ /*
+ * finished our Fragmented delivery, could be more
+ * waiting?
+ */
+ goto doit_again;
+ }
}
}
@@ -870,20 +857,20 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc,
printf("Gak, Evil plot, its not first, no fragmented delivery in progress\n");
}
#endif
- oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + sizeof(uint32_t)),
+ oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + 3 * sizeof(uint32_t)),
0, M_DONTWAIT, 1, MT_DATA);
if (oper) {
struct sctp_paramhdr *ph;
uint32_t *ippp;
- oper->m_len =
+ SCTP_BUF_LEN(oper) =
sizeof(struct sctp_paramhdr) +
(sizeof(uint32_t) * 3);
ph = mtod(oper, struct sctp_paramhdr *);
ph->param_type =
htons(SCTP_CAUSE_PROTOCOL_VIOLATION);
- ph->param_length = htons(oper->m_len);
+ ph->param_length = htons(SCTP_BUF_LEN(oper));
ippp = (uint32_t *) (ph + 1);
*ippp = htonl(SCTP_FROM_SCTP_INDATA + SCTP_LOC_2);
ippp++;
@@ -908,19 +895,19 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc,
printf("Gak, Evil plot, it IS a first and fragmented delivery in progress\n");
}
#endif
- oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + sizeof(uint32_t)),
+ oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + 3 * sizeof(uint32_t)),
0, M_DONTWAIT, 1, MT_DATA);
if (oper) {
struct sctp_paramhdr *ph;
uint32_t *ippp;
- oper->m_len =
+ SCTP_BUF_LEN(oper) =
sizeof(struct sctp_paramhdr) +
(3 * sizeof(uint32_t));
ph = mtod(oper, struct sctp_paramhdr *);
ph->param_type =
htons(SCTP_CAUSE_PROTOCOL_VIOLATION);
- ph->param_length = htons(oper->m_len);
+ ph->param_length = htons(SCTP_BUF_LEN(oper));
ippp = (uint32_t *) (ph + 1);
*ippp = htonl(SCTP_FROM_SCTP_INDATA + SCTP_LOC_3);
ippp++;
@@ -947,13 +934,13 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc,
asoc->str_of_pdapi);
}
#endif
- oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + sizeof(uint32_t)),
+ oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + 3 * sizeof(uint32_t)),
0, M_DONTWAIT, 1, MT_DATA);
if (oper) {
struct sctp_paramhdr *ph;
uint32_t *ippp;
- oper->m_len =
+ SCTP_BUF_LEN(oper) =
sizeof(struct sctp_paramhdr) +
(sizeof(uint32_t) * 3);
ph = mtod(oper,
@@ -961,7 +948,7 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc,
ph->param_type =
htons(SCTP_CAUSE_PROTOCOL_VIOLATION);
ph->param_length =
- htons(oper->m_len);
+ htons(SCTP_BUF_LEN(oper));
ippp = (uint32_t *) (ph + 1);
*ippp = htonl(SCTP_FROM_SCTP_INDATA + SCTP_LOC_4);
ippp++;
@@ -985,13 +972,13 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc,
asoc->ssn_of_pdapi);
}
#endif
- oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + sizeof(uint32_t)),
+ oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + 3 * sizeof(uint32_t)),
0, M_DONTWAIT, 1, MT_DATA);
if (oper) {
struct sctp_paramhdr *ph;
uint32_t *ippp;
- oper->m_len =
+ SCTP_BUF_LEN(oper) =
sizeof(struct sctp_paramhdr) +
(3 * sizeof(uint32_t));
ph = mtod(oper,
@@ -999,7 +986,7 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc,
ph->param_type =
htons(SCTP_CAUSE_PROTOCOL_VIOLATION);
ph->param_length =
- htons(oper->m_len);
+ htons(SCTP_BUF_LEN(oper));
ippp = (uint32_t *) (ph + 1);
*ippp = htonl(SCTP_FROM_SCTP_INDATA + SCTP_LOC_5);
ippp++;
@@ -1088,13 +1075,13 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc,
printf("Gak, Evil plot, it's a FIRST!\n");
}
#endif
- oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + sizeof(uint32_t)),
+ oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + 3 * sizeof(uint32_t)),
0, M_DONTWAIT, 1, MT_DATA);
if (oper) {
struct sctp_paramhdr *ph;
uint32_t *ippp;
- oper->m_len =
+ SCTP_BUF_LEN(oper) =
sizeof(struct sctp_paramhdr) +
(3 * sizeof(uint32_t));
ph = mtod(oper,
@@ -1102,7 +1089,7 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc,
ph->param_type =
htons(SCTP_CAUSE_PROTOCOL_VIOLATION);
ph->param_length =
- htons(oper->m_len);
+ htons(SCTP_BUF_LEN(oper));
ippp = (uint32_t *) (ph + 1);
*ippp = htonl(SCTP_FROM_SCTP_INDATA + SCTP_LOC_6);
ippp++;
@@ -1130,13 +1117,13 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc,
prev->rec.data.stream_number);
}
#endif
- oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + sizeof(uint32_t)),
+ oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + 3 * sizeof(uint32_t)),
0, M_DONTWAIT, 1, MT_DATA);
if (oper) {
struct sctp_paramhdr *ph;
uint32_t *ippp;
- oper->m_len =
+ SCTP_BUF_LEN(oper) =
sizeof(struct sctp_paramhdr) +
(3 * sizeof(uint32_t));
ph = mtod(oper,
@@ -1144,7 +1131,7 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc,
ph->param_type =
htons(SCTP_CAUSE_PROTOCOL_VIOLATION);
ph->param_length =
- htons(oper->m_len);
+ htons(SCTP_BUF_LEN(oper));
ippp = (uint32_t *) (ph + 1);
*ippp = htonl(SCTP_FROM_SCTP_INDATA + SCTP_LOC_7);
ippp++;
@@ -1173,13 +1160,13 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc,
prev->rec.data.stream_seq);
}
#endif
- oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + sizeof(uint32_t)),
+ oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + 3 * sizeof(uint32_t)),
0, M_DONTWAIT, 1, MT_DATA);
if (oper) {
struct sctp_paramhdr *ph;
uint32_t *ippp;
- oper->m_len =
+ SCTP_BUF_LEN(oper) =
sizeof(struct sctp_paramhdr) +
(3 * sizeof(uint32_t));
ph = mtod(oper,
@@ -1187,7 +1174,7 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc,
ph->param_type =
htons(SCTP_CAUSE_PROTOCOL_VIOLATION);
ph->param_length =
- htons(oper->m_len);
+ htons(SCTP_BUF_LEN(oper));
ippp = (uint32_t *) (ph + 1);
*ippp = htonl(SCTP_FROM_SCTP_INDATA + SCTP_LOC_8);
ippp++;
@@ -1212,13 +1199,13 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc,
printf("Prev check - Gak, evil plot, its not FIRST and it must be!\n");
}
#endif
- oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + sizeof(uint32_t)),
+ oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + 3 * sizeof(uint32_t)),
0, M_DONTWAIT, 1, MT_DATA);
if (oper) {
struct sctp_paramhdr *ph;
uint32_t *ippp;
- oper->m_len =
+ SCTP_BUF_LEN(oper) =
sizeof(struct sctp_paramhdr) +
(3 * sizeof(uint32_t));
ph = mtod(oper,
@@ -1226,7 +1213,7 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc,
ph->param_type =
htons(SCTP_CAUSE_PROTOCOL_VIOLATION);
ph->param_length =
- htons(oper->m_len);
+ htons(SCTP_BUF_LEN(oper));
ippp = (uint32_t *) (ph + 1);
*ippp = htonl(SCTP_FROM_SCTP_INDATA + SCTP_LOC_9);
ippp++;
@@ -1262,13 +1249,13 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc,
printf("Gak, Evil plot, its not a last!\n");
}
#endif
- oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + sizeof(uint32_t)),
+ oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + 3 * sizeof(uint32_t)),
0, M_DONTWAIT, 1, MT_DATA);
if (oper) {
struct sctp_paramhdr *ph;
uint32_t *ippp;
- oper->m_len =
+ SCTP_BUF_LEN(oper) =
sizeof(struct sctp_paramhdr) +
(3 * sizeof(uint32_t));
ph = mtod(oper,
@@ -1276,7 +1263,7 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc,
ph->param_type =
htons(SCTP_CAUSE_PROTOCOL_VIOLATION);
ph->param_length =
- htons(oper->m_len);
+ htons(SCTP_BUF_LEN(oper));
ippp = (uint32_t *) (ph + 1);
*ippp = htonl(SCTP_FROM_SCTP_INDATA + SCTP_LOC_10);
ippp++;
@@ -1307,13 +1294,13 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc,
printf("Gak, Evil plot, new prev chunk is a LAST\n");
}
#endif
- oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + sizeof(uint32_t)),
+ oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + 3 * sizeof(uint32_t)),
0, M_DONTWAIT, 1, MT_DATA);
if (oper) {
struct sctp_paramhdr *ph;
uint32_t *ippp;
- oper->m_len =
+ SCTP_BUF_LEN(oper) =
sizeof(struct sctp_paramhdr) +
(3 * sizeof(uint32_t));
ph = mtod(oper,
@@ -1321,7 +1308,7 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc,
ph->param_type =
htons(SCTP_CAUSE_PROTOCOL_VIOLATION);
ph->param_length =
- htons(oper->m_len);
+ htons(SCTP_BUF_LEN(oper));
ippp = (uint32_t *) (ph + 1);
*ippp = htonl(SCTP_FROM_SCTP_INDATA + SCTP_LOC_11);
ippp++;
@@ -1350,13 +1337,13 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc,
next->rec.data.stream_number);
}
#endif
- oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + sizeof(uint32_t)),
+ oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + 3 * sizeof(uint32_t)),
0, M_DONTWAIT, 1, MT_DATA);
if (oper) {
struct sctp_paramhdr *ph;
uint32_t *ippp;
- oper->m_len =
+ SCTP_BUF_LEN(oper) =
sizeof(struct sctp_paramhdr) +
(3 * sizeof(uint32_t));
ph = mtod(oper,
@@ -1364,7 +1351,7 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc,
ph->param_type =
htons(SCTP_CAUSE_PROTOCOL_VIOLATION);
ph->param_length =
- htons(oper->m_len);
+ htons(SCTP_BUF_LEN(oper));
ippp = (uint32_t *) (ph + 1);
*ippp = htonl(SCTP_FROM_SCTP_INDATA + SCTP_LOC_12);
ippp++;
@@ -1394,13 +1381,13 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc,
next->rec.data.stream_seq);
}
#endif
- oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + sizeof(uint32_t)),
+ oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + 3 * sizeof(uint32_t)),
0, M_DONTWAIT, 1, MT_DATA);
if (oper) {
struct sctp_paramhdr *ph;
uint32_t *ippp;
- oper->m_len =
+ SCTP_BUF_LEN(oper) =
sizeof(struct sctp_paramhdr) +
(3 * sizeof(uint32_t));
ph = mtod(oper,
@@ -1408,7 +1395,7 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc,
ph->param_type =
htons(SCTP_CAUSE_PROTOCOL_VIOLATION);
ph->param_length =
- htons(oper->m_len);
+ htons(SCTP_BUF_LEN(oper));
ippp = (uint32_t *) (ph + 1);
*ippp = htonl(SCTP_FROM_SCTP_INDATA + SCTP_LOC_13);
ippp++;
@@ -1506,6 +1493,7 @@ sctp_process_a_data_chunk(struct sctp_tcb *stcb, struct sctp_association *asoc,
uint32_t tsn, gap;
struct mbuf *dmbuf;
int indx, the_len;
+ int need_reasm_check = 0;
uint16_t strmno, strmseq;
struct mbuf *oper;
struct sctp_queued_to_read *control;
@@ -1553,7 +1541,7 @@ sctp_process_a_data_chunk(struct sctp_tcb *stcb, struct sctp_association *asoc,
asoc->dup_tsns[asoc->numduptsns] = tsn;
asoc->numduptsns++;
}
- if (!callout_pending(&asoc->dack_timer.timer)) {
+ if (!SCTP_OS_TIMER_PENDING(&asoc->dack_timer.timer)) {
/*
* By starting the timer we assure that we WILL sack
* at the end of the packet when sctp_sack_check
@@ -1634,18 +1622,17 @@ sctp_process_a_data_chunk(struct sctp_tcb *stcb, struct sctp_association *asoc,
struct mbuf *mb;
mb = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) * 2),
- 1, M_DONTWAIT, 1, MT_DATA);
+ 0, M_DONTWAIT, 1, MT_DATA);
if (mb != NULL) {
/* add some space up front so prepend will work well */
- mb->m_data += sizeof(struct sctp_chunkhdr);
+ SCTP_BUF_RESV_UF(mb, sizeof(struct sctp_chunkhdr));
phdr = mtod(mb, struct sctp_paramhdr *);
/*
* Error causes are just param's and this one has
* two back to back phdr, one with the error type
* and size, the other with the streamid and a rsvd
*/
- mb->m_pkthdr.len = mb->m_len =
- (sizeof(struct sctp_paramhdr) * 2);
+ SCTP_BUF_LEN(mb) = (sizeof(struct sctp_paramhdr) * 2);
phdr->param_type = htons(SCTP_CAUSE_INVALID_STREAM);
phdr->param_length =
htons(sizeof(struct sctp_paramhdr) * 2);
@@ -1684,17 +1671,17 @@ sctp_process_a_data_chunk(struct sctp_tcb *stcb, struct sctp_association *asoc,
* throw it in the stream so it gets cleaned up in
* association destruction
*/
- oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + sizeof(uint32_t)),
+ oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + 3 * sizeof(uint32_t)),
0, M_DONTWAIT, 1, MT_DATA);
if (oper) {
struct sctp_paramhdr *ph;
uint32_t *ippp;
- oper->m_len = sizeof(struct sctp_paramhdr) +
+ SCTP_BUF_LEN(oper) = sizeof(struct sctp_paramhdr) +
(3 * sizeof(uint32_t));
ph = mtod(oper, struct sctp_paramhdr *);
ph->param_type = htons(SCTP_CAUSE_PROTOCOL_VIOLATION);
- ph->param_length = htons(oper->m_len);
+ ph->param_length = htons(SCTP_BUF_LEN(oper));
ippp = (uint32_t *) (ph + 1);
*ippp = htonl(SCTP_FROM_SCTP_INDATA + SCTP_LOC_14);
ippp++;
@@ -1720,21 +1707,39 @@ sctp_process_a_data_chunk(struct sctp_tcb *stcb, struct sctp_association *asoc,
mat = dmbuf;
while (mat) {
- if (mat->m_flags & M_EXT) {
+ if (SCTP_BUF_IS_EXTENDED(mat)) {
sctp_log_mb(mat, SCTP_MBUF_ICOPY);
}
- mat = mat->m_next;
+ mat = SCTP_BUF_NEXT(mat);
}
}
#endif
} else {
/* We can steal the last chunk */
+ int l_len;
+
dmbuf = *m;
/* lop off the top part */
m_adj(dmbuf, (offset + sizeof(struct sctp_data_chunk)));
- if (dmbuf->m_pkthdr.len > the_len) {
+ if (SCTP_BUF_NEXT(dmbuf) == NULL) {
+ l_len = SCTP_BUF_LEN(dmbuf);
+ } else {
+ /*
+ * need to count up the size hopefully does not hit
+ * this to often :-0
+ */
+ struct mbuf *lat;
+
+ l_len = 0;
+ lat = dmbuf;
+ while (lat) {
+ l_len += SCTP_BUF_LEN(lat);
+ lat = SCTP_BUF_NEXT(lat);
+ }
+ }
+ if (l_len > the_len) {
/* Trim the end round bytes off too */
- m_adj(dmbuf, -(dmbuf->m_pkthdr.len - the_len));
+ m_adj(dmbuf, -(l_len - the_len));
}
}
if (dmbuf == NULL) {
@@ -1821,7 +1826,6 @@ failed_express_del:
asoc->last_flags_delivered = ch->ch.chunk_flags;
asoc->last_strm_seq_delivered = strmseq;
asoc->last_strm_no_delivered = strmno;
-
if (end) {
/* clean up the flags and such */
asoc->fragmented_delivery_inprogress = 0;
@@ -1829,6 +1833,13 @@ failed_express_del:
asoc->strmin[strmno].last_sequence_delivered++;
}
stcb->asoc.control_pdapi = NULL;
+ if (TAILQ_EMPTY(&asoc->reasmqueue) == 0) {
+ /*
+ * There could be another message
+ * ready
+ */
+ need_reasm_check = 1;
+ }
}
control = NULL;
goto finish_express_del;
@@ -1901,19 +1912,19 @@ failed_pdapi_express_del:
control->data = NULL;
sctp_free_remote_addr(control->whoFrom);
sctp_free_a_readq(stcb, control);
- oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + sizeof(uint32_t)),
+ oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + 3 * sizeof(uint32_t)),
0, M_DONTWAIT, 1, MT_DATA);
if (oper) {
struct sctp_paramhdr *ph;
uint32_t *ippp;
- oper->m_len =
+ SCTP_BUF_LEN(oper) =
sizeof(struct sctp_paramhdr) +
(3 * sizeof(uint32_t));
ph = mtod(oper, struct sctp_paramhdr *);
ph->param_type =
htons(SCTP_CAUSE_PROTOCOL_VIOLATION);
- ph->param_length = htons(oper->m_len);
+ ph->param_length = htons(SCTP_BUF_LEN(oper));
ippp = (uint32_t *) (ph + 1);
*ippp = htonl(SCTP_FROM_SCTP_INDATA + SCTP_LOC_15);
ippp++;
@@ -1934,13 +1945,13 @@ failed_pdapi_express_del:
sctp_free_remote_addr(control->whoFrom);
sctp_free_a_readq(stcb, control);
- oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + sizeof(uint32_t)),
+ oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + 3 * sizeof(uint32_t)),
0, M_DONTWAIT, 1, MT_DATA);
if (oper) {
struct sctp_paramhdr *ph;
uint32_t *ippp;
- oper->m_len =
+ SCTP_BUF_LEN(oper) =
sizeof(struct sctp_paramhdr) +
(3 * sizeof(uint32_t));
ph = mtod(oper,
@@ -1948,7 +1959,7 @@ failed_pdapi_express_del:
ph->param_type =
htons(SCTP_CAUSE_PROTOCOL_VIOLATION);
ph->param_length =
- htons(oper->m_len);
+ htons(SCTP_BUF_LEN(oper));
ippp = (uint32_t *) (ph + 1);
*ippp = htonl(SCTP_FROM_SCTP_INDATA + SCTP_LOC_16);
ippp++;
@@ -1978,13 +1989,13 @@ failed_pdapi_express_del:
control->data = NULL;
sctp_free_remote_addr(control->whoFrom);
sctp_free_a_readq(stcb, control);
- oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + sizeof(uint32_t)),
+ oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + 3 * sizeof(uint32_t)),
0, M_DONTWAIT, 1, MT_DATA);
if (oper) {
struct sctp_paramhdr *ph;
uint32_t *ippp;
- oper->m_len =
+ SCTP_BUF_LEN(oper) =
sizeof(struct sctp_paramhdr) +
(3 * sizeof(uint32_t));
ph = mtod(oper,
@@ -1992,7 +2003,7 @@ failed_pdapi_express_del:
ph->param_type =
htons(SCTP_CAUSE_PROTOCOL_VIOLATION);
ph->param_length =
- htons(oper->m_len);
+ htons(SCTP_BUF_LEN(oper));
ippp = (uint32_t *) (ph + 1);
*ippp = htonl(SCTP_FROM_SCTP_INDATA + SCTP_LOC_17);
ippp++;
@@ -2118,6 +2129,10 @@ finish_express_del:
asoc->highest_tsn_inside_map, SCTP_MAP_PREPARE_SLIDE);
#endif
SCTP_SET_TSN_PRESENT(asoc->mapping_array, gap);
+ if (need_reasm_check) {
+ /* Another one waits ? */
+ sctp_deliver_reasm_check(stcb, asoc);
+ }
return (1);
}
@@ -2367,7 +2382,7 @@ sctp_sack_check(struct sctp_tcb *stcb, int ok_to_sack, int was_a_gap, int *abort
* maker sure SACK timer is off and instead send a
* SHUTDOWN and a SACK
*/
- if (callout_pending(&stcb->asoc.dack_timer.timer)) {
+ if (SCTP_OS_TIMER_PENDING(&stcb->asoc.dack_timer.timer)) {
sctp_timer_stop(SCTP_TIMER_TYPE_RECV,
stcb->sctp_ep, stcb, NULL, SCTP_FROM_SCTP_INDATA + SCTP_LOC_18);
}
@@ -2393,15 +2408,15 @@ sctp_sack_check(struct sctp_tcb *stcb, int ok_to_sack, int was_a_gap, int *abort
(stcb->asoc.numduptsns) || /* we have dup's */
(is_a_gap) || /* is still a gap */
(stcb->asoc.delayed_ack == 0) ||
- (callout_pending(&stcb->asoc.dack_timer.timer)) /* timer was up . second
- * packet */
+ (SCTP_OS_TIMER_PENDING(&stcb->asoc.dack_timer.timer)) /* timer was up . second
+ * packet */
) {
if ((sctp_cmt_on_off) && (sctp_cmt_use_dac) &&
(stcb->asoc.first_ack_sent == 1) &&
(stcb->asoc.numduptsns == 0) &&
(stcb->asoc.delayed_ack) &&
- (!callout_pending(&stcb->asoc.dack_timer.timer))) {
+ (!SCTP_OS_TIMER_PENDING(&stcb->asoc.dack_timer.timer))) {
/*
* CMT DAC algorithm: With CMT,
@@ -2456,6 +2471,7 @@ sctp_service_queues(struct sctp_tcb *stcb, struct sctp_association *asoc)
* Now is there some other chunk I can deliver from the reassembly
* queue.
*/
+doit_again:
chk = TAILQ_FIRST(&asoc->reasmqueue);
if (chk == NULL) {
asoc->size_on_reasm_queue = 0;
@@ -2485,6 +2501,9 @@ sctp_service_queues(struct sctp_tcb *stcb, struct sctp_association *asoc)
asoc->pdapi_ppid = chk->rec.data.payloadtype;
asoc->fragment_flags = chk->rec.data.rcv_flags;
sctp_service_reassembly(stcb, asoc);
+ if (asoc->fragmented_delivery_inprogress == 0) {
+ goto doit_again;
+ }
}
}
}
@@ -2542,23 +2561,19 @@ sctp_process_data(struct mbuf **mm, int iphlen, int *offset, int length,
* to a smaller mbuf and free up the cluster mbuf. This will help
* with cluster starvation.
*/
- if (m->m_len < (long)MHLEN && m->m_next == NULL) {
+ if (SCTP_BUF_LEN(m) < (long)MHLEN && SCTP_BUF_NEXT(m) == NULL) {
/* we only handle mbufs that are singletons.. not chains */
- m = sctp_get_mbuf_for_msg(m->m_len, 1, M_DONTWAIT, 1, MT_DATA);
+ m = sctp_get_mbuf_for_msg(SCTP_BUF_LEN(m), 0, M_DONTWAIT, 1, MT_DATA);
if (m) {
/* ok lets see if we can copy the data up */
caddr_t *from, *to;
- if ((*mm)->m_flags & M_PKTHDR) {
- /* got to copy the header first */
- M_MOVE_PKTHDR(m, (*mm));
- }
/* get the pointers and copy */
to = mtod(m, caddr_t *);
from = mtod((*mm), caddr_t *);
- memcpy(to, from, (*mm)->m_len);
+ memcpy(to, from, SCTP_BUF_LEN((*mm)));
/* copy the length and free up the old */
- m->m_len = (*mm)->m_len;
+ SCTP_BUF_LEN(m) = SCTP_BUF_LEN((*mm));
sctp_m_freem(*mm);
/* sucess, back copy */
*mm = m;
@@ -2594,19 +2609,19 @@ sctp_process_data(struct mbuf **mm, int iphlen, int *offset, int length,
*/
struct mbuf *op_err;
- op_err = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + sizeof(uint32_t)),
+ op_err = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + 2 * sizeof(uint32_t)),
0, M_DONTWAIT, 1, MT_DATA);
if (op_err) {
struct sctp_paramhdr *ph;
uint32_t *ippp;
- op_err->m_len = sizeof(struct sctp_paramhdr) +
+ SCTP_BUF_LEN(op_err) = sizeof(struct sctp_paramhdr) +
(2 * sizeof(uint32_t));
ph = mtod(op_err, struct sctp_paramhdr *);
ph->param_type =
htons(SCTP_CAUSE_PROTOCOL_VIOLATION);
- ph->param_length = htons(op_err->m_len);
+ ph->param_length = htons(SCTP_BUF_LEN(op_err));
ippp = (uint32_t *) (ph + 1);
*ippp = htonl(SCTP_FROM_SCTP_INDATA + SCTP_LOC_19);
ippp++;
@@ -2689,7 +2704,7 @@ sctp_process_data(struct mbuf **mm, int iphlen, int *offset, int length,
struct mbuf *mm;
struct sctp_paramhdr *phd;
- mm = sctp_get_mbuf_for_msg(sizeof(*phd), 1, M_DONTWAIT, 1, MT_DATA);
+ mm = sctp_get_mbuf_for_msg(sizeof(*phd), 0, M_DONTWAIT, 1, MT_DATA);
if (mm) {
phd = mtod(mm, struct sctp_paramhdr *);
/*
@@ -2704,14 +2719,11 @@ sctp_process_data(struct mbuf **mm, int iphlen, int *offset, int length,
htons(SCTP_CAUSE_UNRECOG_CHUNK);
phd->param_length =
htons(chk_length + sizeof(*phd));
- mm->m_len = sizeof(*phd);
- mm->m_next = sctp_m_copym(m, *offset,
+ SCTP_BUF_LEN(mm) = sizeof(*phd);
+ SCTP_BUF_NEXT(mm) = sctp_m_copym(m, *offset,
SCTP_SIZE32(chk_length),
M_DONTWAIT);
- if (mm->m_next) {
- mm->m_pkthdr.len =
- SCTP_SIZE32(chk_length) +
- sizeof(*phd);
+ if (SCTP_BUF_NEXT(mm)) {
sctp_queue_op_err(stcb, mm);
} else {
sctp_m_freem(mm);
@@ -2776,9 +2788,9 @@ sctp_process_data(struct mbuf **mm, int iphlen, int *offset, int length,
/* need to do the slide */
sctp_sack_check(stcb, 1, was_a_gap, &abort_flag);
} else {
- if (callout_pending(&stcb->asoc.dack_timer.timer)) {
+ if (SCTP_OS_TIMER_PENDING(&stcb->asoc.dack_timer.timer)) {
stcb->asoc.first_ack_sent = 1;
- callout_stop(&stcb->asoc.dack_timer.timer);
+ SCTP_OS_TIMER_STOP(&stcb->asoc.dack_timer.timer);
sctp_send_sack(stcb);
} else {
sctp_timer_start(SCTP_TIMER_TYPE_RECV,
@@ -2797,7 +2809,8 @@ sctp_process_data(struct mbuf **mm, int iphlen, int *offset, int length,
static void
sctp_handle_segments(struct sctp_tcb *stcb, struct sctp_association *asoc,
struct sctp_sack_chunk *ch, uint32_t last_tsn, uint32_t * biggest_tsn_acked,
- uint32_t * biggest_newly_acked_tsn, uint32_t * this_sack_lowest_newack, int num_seg, int *ecn_seg_sums)
+ uint32_t * biggest_newly_acked_tsn, uint32_t * this_sack_lowest_newack,
+ int num_seg, int *ecn_seg_sums)
{
/************************************************/
/* process fragments and update sendqueue */
@@ -3898,7 +3911,7 @@ sctp_cwnd_update(struct sctp_tcb *stcb,
* to illicit a sack with gaps to force out
* the others.
*/
- if (callout_pending(&net->fr_timer.timer)) {
+ if (SCTP_OS_TIMER_PENDING(&net->fr_timer.timer)) {
SCTP_STAT_INCR(sctps_earlyfrstpidsck2);
sctp_timer_stop(SCTP_TIMER_TYPE_EARLYFR, stcb->sctp_ep, stcb, net,
SCTP_FROM_SCTP_INDATA + SCTP_LOC_20);
@@ -3907,7 +3920,7 @@ sctp_cwnd_update(struct sctp_tcb *stcb,
sctp_timer_start(SCTP_TIMER_TYPE_EARLYFR, stcb->sctp_ep, stcb, net);
} else {
/* No, stop it if its running */
- if (callout_pending(&net->fr_timer.timer)) {
+ if (SCTP_OS_TIMER_PENDING(&net->fr_timer.timer)) {
SCTP_STAT_INCR(sctps_earlyfrstpidsck3);
sctp_timer_stop(SCTP_TIMER_TYPE_EARLYFR, stcb->sctp_ep, stcb, net,
SCTP_FROM_SCTP_INDATA + SCTP_LOC_21);
@@ -4088,6 +4101,44 @@ sctp_express_handle_sack(struct sctp_tcb *stcb, uint32_t cumack,
net->net_ack = 0;
net->net_ack2 = 0;
}
+ if (sctp_strict_sacks) {
+ uint32_t send_s;
+
+ if (TAILQ_EMPTY(&asoc->send_queue)) {
+ send_s = asoc->sending_seq;
+ } else {
+ tp1 = TAILQ_FIRST(&asoc->send_queue);
+ send_s = tp1->rec.data.TSN_seq;
+ }
+ if ((cumack == send_s) ||
+ compare_with_wrap(cumack, send_s, MAX_TSN)) {
+#ifdef INVARIANTS /* for testing only */
+ panic("Impossible sack 1");
+#else
+ struct mbuf *oper;
+
+ *abort_now = 1;
+ /* XXX */
+ oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + sizeof(uint32_t)),
+ 0, M_DONTWAIT, 1, MT_DATA);
+ if (oper) {
+ struct sctp_paramhdr *ph;
+ uint32_t *ippp;
+
+ SCTP_BUF_LEN(oper) = sizeof(struct sctp_paramhdr) +
+ sizeof(uint32_t);
+ ph = mtod(oper, struct sctp_paramhdr *);
+ ph->param_type = htons(SCTP_CAUSE_PROTOCOL_VIOLATION);
+ ph->param_length = htons(SCTP_BUF_LEN(oper));
+ ippp = (uint32_t *) (ph + 1);
+ *ippp = htonl(SCTP_FROM_SCTP_INDATA + SCTP_LOC_25);
+ }
+ stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_25;
+ sctp_abort_an_association(stcb->sctp_ep, stcb, SCTP_PEER_FAULTY, oper);
+ return;
+#endif
+ }
+ }
asoc->this_sack_highest_gap = cumack;
stcb->asoc.overall_error_count = 0;
/* process the new consecutive TSN first */
@@ -4276,16 +4327,16 @@ again:
to_ticks = MSEC_TO_TICKS(net->RTO);
}
j++;
- callout_reset(&net->rxt_timer.timer, to_ticks,
+ SCTP_OS_TIMER_START(&net->rxt_timer.timer, to_ticks,
sctp_timeout_handler, &net->rxt_timer);
} else {
- if (callout_pending(&net->rxt_timer.timer)) {
+ if (SCTP_OS_TIMER_PENDING(&net->rxt_timer.timer)) {
sctp_timer_stop(SCTP_TIMER_TYPE_SEND, stcb->sctp_ep,
stcb, net,
SCTP_FROM_SCTP_INDATA + SCTP_LOC_22);
}
if (sctp_early_fr) {
- if (callout_pending(&net->fr_timer.timer)) {
+ if (SCTP_OS_TIMER_PENDING(&net->fr_timer.timer)) {
SCTP_STAT_INCR(sctps_earlyfrstpidsck4);
sctp_timer_stop(SCTP_TIMER_TYPE_EARLYFR, stcb->sctp_ep, stcb, net,
SCTP_FROM_SCTP_INDATA + SCTP_LOC_23);
@@ -4359,11 +4410,11 @@ again:
struct sctp_paramhdr *ph;
uint32_t *ippp;
- oper->m_len = sizeof(struct sctp_paramhdr) +
+ SCTP_BUF_LEN(oper) = sizeof(struct sctp_paramhdr) +
sizeof(uint32_t);
ph = mtod(oper, struct sctp_paramhdr *);
ph->param_type = htons(SCTP_CAUSE_USER_INITIATED_ABT);
- ph->param_length = htons(oper->m_len);
+ ph->param_length = htons(SCTP_BUF_LEN(oper));
ippp = (uint32_t *) (ph + 1);
*ippp = htonl(SCTP_FROM_SCTP_INDATA + SCTP_LOC_24);
}
@@ -4515,6 +4566,10 @@ sctp_handle_sack(struct sctp_sack_chunk *ch, struct sctp_tcb *stcb,
if (sctp_strict_sacks) {
if (cum_ack == send_s ||
compare_with_wrap(cum_ack, send_s, MAX_TSN)) {
+#ifdef INVARIANTS /* for testing only */
+ hopeless_peer:
+ panic("Impossible sack 1");
+#else
struct mbuf *oper;
/*
@@ -4530,17 +4585,18 @@ sctp_handle_sack(struct sctp_sack_chunk *ch, struct sctp_tcb *stcb,
struct sctp_paramhdr *ph;
uint32_t *ippp;
- oper->m_len = sizeof(struct sctp_paramhdr) +
+ SCTP_BUF_LEN(oper) = sizeof(struct sctp_paramhdr) +
sizeof(uint32_t);
ph = mtod(oper, struct sctp_paramhdr *);
ph->param_type = htons(SCTP_CAUSE_PROTOCOL_VIOLATION);
- ph->param_length = htons(oper->m_len);
+ ph->param_length = htons(SCTP_BUF_LEN(oper));
ippp = (uint32_t *) (ph + 1);
*ippp = htonl(SCTP_FROM_SCTP_INDATA + SCTP_LOC_25);
}
stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_25;
sctp_abort_an_association(stcb->sctp_ep, stcb, SCTP_PEER_FAULTY, oper);
return;
+#endif
}
}
/**********************/
@@ -4573,7 +4629,7 @@ sctp_handle_sack(struct sctp_sack_chunk *ch, struct sctp_tcb *stcb,
sctp_timer_stop(SCTP_TIMER_TYPE_SEND, stcb->sctp_ep,
stcb, net, SCTP_FROM_SCTP_INDATA + SCTP_LOC_26);
if (sctp_early_fr) {
- if (callout_pending(&net->fr_timer.timer)) {
+ if (SCTP_OS_TIMER_PENDING(&net->fr_timer.timer)) {
SCTP_STAT_INCR(sctps_earlyfrstpidsck1);
sctp_timer_stop(SCTP_TIMER_TYPE_EARLYFR, stcb->sctp_ep, stcb, net,
SCTP_FROM_SCTP_INDATA + SCTP_LOC_26);
@@ -4927,7 +4983,7 @@ done_with_it:
TAILQ_FOREACH(net, &asoc->nets, sctp_next) {
/* stop all timers */
if (sctp_early_fr) {
- if (callout_pending(&net->fr_timer.timer)) {
+ if (SCTP_OS_TIMER_PENDING(&net->fr_timer.timer)) {
SCTP_STAT_INCR(sctps_earlyfrstpidsck4);
sctp_timer_stop(SCTP_TIMER_TYPE_EARLYFR, stcb->sctp_ep, stcb, net,
SCTP_FROM_SCTP_INDATA + SCTP_LOC_29);
@@ -4991,11 +5047,11 @@ done_with_it:
struct sctp_paramhdr *ph;
uint32_t *ippp;
- oper->m_len = sizeof(struct sctp_paramhdr) +
+ SCTP_BUF_LEN(oper) = sizeof(struct sctp_paramhdr) +
sizeof(uint32_t);
ph = mtod(oper, struct sctp_paramhdr *);
ph->param_type = htons(SCTP_CAUSE_USER_INITIATED_ABT);
- ph->param_length = htons(oper->m_len);
+ ph->param_length = htons(SCTP_BUF_LEN(oper));
ippp = (uint32_t *) (ph + 1);
*ippp = htonl(SCTP_FROM_SCTP_INDATA + SCTP_LOC_31);
}
@@ -5653,4 +5709,8 @@ sctp_handle_forward_tsn(struct sctp_tcb *stcb,
sctp_kick_prsctp_reorder_queue(stcb, strm);
}
}
+ if (TAILQ_FIRST(&asoc->reasmqueue)) {
+ /* now lets kick out and check for more fragmented delivery */
+ sctp_deliver_reasm_check(stcb, &stcb->asoc);
+ }
}
diff --git a/sys/netinet/sctp_input.c b/sys/netinet/sctp_input.c
index adeb48b..8674713 100644
--- a/sys/netinet/sctp_input.c
+++ b/sys/netinet/sctp_input.c
@@ -455,7 +455,7 @@ sctp_process_init_ack(struct mbuf *m, int iphlen, int offset,
*/
struct sctp_inv_mandatory_param *mp;
- op_err->m_len =
+ SCTP_BUF_LEN(op_err) =
sizeof(struct sctp_inv_mandatory_param);
mp = mtod(op_err,
struct sctp_inv_mandatory_param *);
@@ -612,9 +612,6 @@ sctp_handle_shutdown(struct sctp_shutdown_chunk *cp,
SCTP_INP_READ_LOCK(stcb->sctp_ep);
asoc->control_pdapi->end_added = 1;
asoc->control_pdapi->pdapi_aborted = 1;
- if (asoc->control_pdapi->tail_mbuf) {
- asoc->control_pdapi->tail_mbuf->m_flags |= M_EOR;
- }
asoc->control_pdapi = NULL;
SCTP_INP_READ_UNLOCK(stcb->sctp_ep);
sctp_sorwakeup(stcb->sctp_ep, stcb->sctp_socket);
@@ -704,9 +701,6 @@ sctp_handle_shutdown_ack(struct sctp_shutdown_ack_chunk *cp,
SCTP_INP_READ_LOCK(stcb->sctp_ep);
asoc->control_pdapi->end_added = 1;
asoc->control_pdapi->pdapi_aborted = 1;
- if (asoc->control_pdapi->tail_mbuf) {
- asoc->control_pdapi->tail_mbuf->m_flags |= M_EOR;
- }
asoc->control_pdapi = NULL;
SCTP_INP_READ_UNLOCK(stcb->sctp_ep);
sctp_sorwakeup(stcb->sctp_ep, stcb->sctp_socket);
@@ -1119,17 +1113,17 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset,
sctp_send_shutdown_ack(stcb, stcb->asoc.primary_destination);
op_err = sctp_get_mbuf_for_msg(sizeof(struct sctp_paramhdr),
- 1, M_DONTWAIT, 1, MT_DATA);
+ 0, M_DONTWAIT, 1, MT_DATA);
if (op_err == NULL) {
/* FOOBAR */
return (NULL);
}
/* pre-reserve some space */
- op_err->m_data += sizeof(struct ip6_hdr);
- op_err->m_data += sizeof(struct sctphdr);
- op_err->m_data += sizeof(struct sctp_chunkhdr);
+ SCTP_BUF_RESV_UF(op_err, sizeof(struct ip6_hdr));
+ SCTP_BUF_RESV_UF(op_err, sizeof(struct sctphdr));
+ SCTP_BUF_RESV_UF(op_err, sizeof(struct sctp_chunkhdr));
/* Set the len */
- op_err->m_len = op_err->m_pkthdr.len = sizeof(struct sctp_paramhdr);
+ SCTP_BUF_LEN(op_err) = sizeof(struct sctp_paramhdr);
ph = mtod(op_err, struct sctp_paramhdr *);
ph->param_type = htons(SCTP_CAUSE_COOKIE_IN_SHUTDOWN);
ph->param_length = htons(sizeof(struct sctp_paramhdr));
@@ -1371,10 +1365,35 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset,
/* temp code */
sctp_timer_stop(SCTP_TIMER_TYPE_INIT, inp, stcb, net, SCTP_FROM_SCTP_INPUT + SCTP_LOC_14);
sctp_timer_stop(SCTP_TIMER_TYPE_HEARTBEAT, inp, stcb, net, SCTP_FROM_SCTP_INPUT + SCTP_LOC_15);
+
*sac_assoc_id = sctp_get_associd(stcb);
/* notify upper layer */
*notification = SCTP_NOTIFY_ASSOC_RESTART;
atomic_add_int(&stcb->asoc.refcnt, 1);
+ if (asoc->state & SCTP_STATE_SHUTDOWN_PENDING) {
+ asoc->state = SCTP_STATE_OPEN |
+ SCTP_STATE_SHUTDOWN_PENDING;
+ sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNGUARD,
+ stcb->sctp_ep, stcb, asoc->primary_destination);
+
+ } else if (!(asoc->state & SCTP_STATE_SHUTDOWN_SENT)) {
+ /* move to OPEN state, if not in SHUTDOWN_SENT */
+ asoc->state = SCTP_STATE_OPEN;
+ }
+ asoc->pre_open_streams =
+ ntohs(initack_cp->init.num_outbound_streams);
+ asoc->init_seq_number = ntohl(initack_cp->init.initial_tsn);
+ asoc->sending_seq = asoc->asconf_seq_out = asoc->str_reset_seq_out = asoc->init_seq_number;
+
+ asoc->last_cwr_tsn = asoc->init_seq_number - 1;
+ asoc->asconf_seq_in = asoc->last_acked_seq = asoc->init_seq_number - 1;
+
+ asoc->str_reset_seq_in = asoc->init_seq_number;
+
+ asoc->advanced_peer_ack_point = asoc->last_acked_seq;
+ if (asoc->mapping_array)
+ memset(asoc->mapping_array, 0,
+ asoc->mapping_array_size);
SCTP_TCB_UNLOCK(stcb);
SCTP_INP_INFO_WLOCK();
SCTP_INP_WLOCK(stcb->sctp_ep);
@@ -1412,20 +1431,6 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset,
LIST_INSERT_HEAD(head, stcb, sctp_tcbrestarhash);
stcb->asoc.in_restart_hash = 1;
}
- asoc->pre_open_streams =
- ntohs(initack_cp->init.num_outbound_streams);
- asoc->init_seq_number = ntohl(initack_cp->init.initial_tsn);
- asoc->sending_seq = asoc->asconf_seq_out = asoc->str_reset_seq_out = asoc->init_seq_number;
-
- asoc->last_cwr_tsn = asoc->init_seq_number - 1;
- asoc->asconf_seq_in = asoc->last_acked_seq = asoc->init_seq_number - 1;
-
- asoc->str_reset_seq_in = asoc->init_seq_number;
-
- asoc->advanced_peer_ack_point = asoc->last_acked_seq;
- if (asoc->mapping_array)
- memset(asoc->mapping_array, 0,
- asoc->mapping_array_size);
/* process the INIT info (peer's info) */
SCTP_TCB_SEND_UNLOCK(stcb);
SCTP_INP_WUNLOCK(stcb->sctp_ep);
@@ -1446,16 +1451,6 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset,
initack_offset, sh, init_src)) {
return (NULL);
}
- if (asoc->state & SCTP_STATE_SHUTDOWN_PENDING) {
- asoc->state = SCTP_STATE_OPEN |
- SCTP_STATE_SHUTDOWN_PENDING;
- sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNGUARD,
- stcb->sctp_ep, stcb, asoc->primary_destination);
-
- } else if (!(asoc->state & SCTP_STATE_SHUTDOWN_SENT)) {
- /* move to OPEN state, if not in SHUTDOWN_SENT */
- asoc->state = SCTP_STATE_OPEN;
- }
/* respond with a COOKIE-ACK */
sctp_stop_all_cookie_timers(stcb);
sctp_toss_old_cookies(stcb, asoc);
@@ -1799,6 +1794,8 @@ sctp_handle_cookie_echo(struct mbuf *m, int iphlen, int offset,
sin->sin_len = sizeof(*sin);
sin->sin_port = sh->dest_port;
sin->sin_addr.s_addr = iph->ip_dst.s_addr;
+ size_of_pkt = SCTP_GET_IPV4_LENGTH(iph);
+
} else if (iph->ip_v == (IPV6_VERSION >> 4)) {
/* its IPv6 */
struct ip6_hdr *ip6;
@@ -1811,6 +1808,7 @@ sctp_handle_cookie_echo(struct mbuf *m, int iphlen, int offset,
ip6 = mtod(m, struct ip6_hdr *);
sin6->sin6_port = sh->dest_port;
sin6->sin6_addr = ip6->ip6_dst;
+ size_of_pkt = SCTP_GET_IPV6_LENGTH(ip6);
} else {
return (NULL);
}
@@ -1831,20 +1829,6 @@ sctp_handle_cookie_echo(struct mbuf *m, int iphlen, int offset,
*/
return (NULL);
}
- /* compute size of packet */
- if (m->m_flags & M_PKTHDR) {
- size_of_pkt = m->m_pkthdr.len;
- } else {
- /* Should have a pkt hdr really */
- struct mbuf *mat;
-
- mat = m;
- size_of_pkt = 0;
- while (mat != NULL) {
- size_of_pkt += mat->m_len;
- mat = mat->m_next;
- }
- }
if (cookie_len > size_of_pkt ||
cookie_len < sizeof(struct sctp_cookie_echo_chunk) +
sizeof(struct sctp_init_chunk) +
@@ -1925,35 +1909,10 @@ sctp_handle_cookie_echo(struct mbuf *m, int iphlen, int offset,
struct mbuf *m_at;
m_at = m;
- while (m_at->m_next != NULL) {
- m_at = m_at->m_next;
- }
- m_at->m_next = m_sig;
- if (m->m_flags & M_PKTHDR) {
- /*
- * We should only do this if and only if the front
- * mbuf has a m_pkthdr... it should in theory.
- */
- if (m_sig->m_flags & M_PKTHDR) {
- /* Add back to the pkt hdr of main m chain */
- m->m_pkthdr.len += m_sig->m_pkthdr.len;
- } else {
- /*
- * Got a problem, no pkthdr in split chain.
- * TSNH but we will handle it just in case
- */
- int mmlen = 0;
- struct mbuf *lat;
-
- printf("Warning: Hitting m_split join TSNH code - fixed\n");
- lat = m_sig;
- while (lat) {
- mmlen += lat->m_len;
- lat = lat->m_next;
- }
- m->m_pkthdr.len += mmlen;
- }
+ while (SCTP_BUF_NEXT(m_at) != NULL) {
+ m_at = SCTP_BUF_NEXT(m_at);
}
+ SCTP_BUF_NEXT(m_at) = m_sig;
}
if (cookie_ok == 0) {
@@ -1980,18 +1939,18 @@ sctp_handle_cookie_echo(struct mbuf *m, int iphlen, int offset,
uint32_t tim;
op_err = sctp_get_mbuf_for_msg(sizeof(struct sctp_stale_cookie_msg),
- 1, M_DONTWAIT, 1, MT_DATA);
+ 0, M_DONTWAIT, 1, MT_DATA);
if (op_err == NULL) {
/* FOOBAR */
return (NULL);
}
/* pre-reserve some space */
- op_err->m_data += sizeof(struct ip6_hdr);
- op_err->m_data += sizeof(struct sctphdr);
- op_err->m_data += sizeof(struct sctp_chunkhdr);
+ SCTP_BUF_RESV_UF(op_err, sizeof(struct ip6_hdr));
+ SCTP_BUF_RESV_UF(op_err, sizeof(struct sctphdr));
+ SCTP_BUF_RESV_UF(op_err, sizeof(struct sctp_chunkhdr));
/* Set the len */
- op_err->m_len = op_err->m_pkthdr.len = sizeof(struct sctp_stale_cookie_msg);
+ SCTP_BUF_LEN(op_err) = sizeof(struct sctp_stale_cookie_msg);
scm = mtod(op_err, struct sctp_stale_cookie_msg *);
scm->ph.param_type = htons(SCTP_CAUSE_STALE_COOKIE);
scm->ph.param_length = htons((sizeof(struct sctp_paramhdr) +
@@ -3117,7 +3076,7 @@ sctp_handle_stream_reset(struct sctp_tcb *stcb, struct sctp_stream_reset_out_req
chk->asoc = &stcb->asoc;
chk->no_fr_allowed = 0;
chk->book_size = chk->send_size = sizeof(struct sctp_chunkhdr);
- chk->data = sctp_get_mbuf_for_msg(MCLBYTES, 1, M_DONTWAIT, 1, MT_DATA);
+ chk->data = sctp_get_mbuf_for_msg(MCLBYTES, 0, M_DONTWAIT, 1, MT_DATA);
if (chk->data == NULL) {
strres_nochunk:
if (chk->data) {
@@ -3127,7 +3086,7 @@ strres_nochunk:
sctp_free_a_chunk(stcb, chk);
return (ret_code);
}
- chk->data->m_data += SCTP_MIN_OVERHEAD;
+ SCTP_BUF_RESV_UF(chk->data, SCTP_MIN_OVERHEAD);
/* setup chunk parameters */
chk->sent = SCTP_DATAGRAM_UNSENT;
@@ -3139,7 +3098,7 @@ strres_nochunk:
ch->chunk_type = SCTP_STREAM_RESET;
ch->chunk_flags = 0;
ch->chunk_length = htons(chk->send_size);
- chk->data->m_pkthdr.len = chk->data->m_len = SCTP_SIZE32(chk->send_size);
+ SCTP_BUF_LEN(chk->data) = SCTP_SIZE32(chk->send_size);
ph = (struct sctp_paramhdr *)&sr_req->sr_req;
@@ -3706,12 +3665,11 @@ process_control_chunks:
oper = NULL;
oper = sctp_get_mbuf_for_msg(sizeof(struct sctp_paramhdr),
- 1, M_DONTWAIT, 1, MT_DATA);
+ 0, M_DONTWAIT, 1, MT_DATA);
if (oper) {
/* pre-reserve some space */
- oper->m_data += sizeof(struct sctp_chunkhdr);
- oper->m_len = sizeof(struct sctp_paramhdr);
- oper->m_pkthdr.len = oper->m_len;
+ SCTP_BUF_RESV_UF(oper, sizeof(struct sctp_chunkhdr));
+ SCTP_BUF_LEN(oper) = sizeof(struct sctp_paramhdr);
phdr = mtod(oper, struct sctp_paramhdr *);
phdr->param_type = htons(SCTP_CAUSE_OUT_OF_RESC);
phdr->param_length = htons(sizeof(struct sctp_paramhdr));
@@ -4016,10 +3974,9 @@ process_control_chunks:
if (sctp_abort_if_one_2_one_hits_limit) {
oper = NULL;
oper = sctp_get_mbuf_for_msg(sizeof(struct sctp_paramhdr),
- 1, M_DONTWAIT, 1, MT_DATA);
+ 0, M_DONTWAIT, 1, MT_DATA);
if (oper) {
- oper->m_len =
- oper->m_pkthdr.len =
+ SCTP_BUF_LEN(oper) =
sizeof(struct sctp_paramhdr);
phdr = mtod(oper,
struct sctp_paramhdr *);
@@ -4296,7 +4253,7 @@ process_control_chunks:
struct sctp_paramhdr *phd;
mm = sctp_get_mbuf_for_msg(sizeof(struct sctp_paramhdr),
- 1, M_DONTWAIT, 1, MT_DATA);
+ 0, M_DONTWAIT, 1, MT_DATA);
if (mm) {
phd = mtod(mm, struct sctp_paramhdr *);
/*
@@ -4308,11 +4265,10 @@ process_control_chunks:
*/
phd->param_type = htons(SCTP_CAUSE_UNRECOG_CHUNK);
phd->param_length = htons(chk_length + sizeof(*phd));
- mm->m_len = sizeof(*phd);
- mm->m_next = sctp_m_copym(m, *offset, SCTP_SIZE32(chk_length),
+ SCTP_BUF_LEN(mm) = sizeof(*phd);
+ SCTP_BUF_NEXT(mm) = sctp_m_copym(m, *offset, SCTP_SIZE32(chk_length),
M_DONTWAIT);
- if (mm->m_next) {
- mm->m_pkthdr.len = SCTP_SIZE32(chk_length) + sizeof(*phd);
+ if (SCTP_BUF_NEXT(mm)) {
sctp_queue_op_err(stcb, mm);
} else {
sctp_m_freem(mm);
@@ -4648,8 +4604,8 @@ uint8_t sctp_list_of_chunks[30000];
void
-sctp_input(m, off)
- struct mbuf *m;
+sctp_input(i_pak, off)
+ struct mbuf *i_pak;
int off;
{
@@ -4657,6 +4613,7 @@ sctp_input(m, off)
struct mbuf *mat;
#endif
+ struct mbuf *m;
int iphlen;
int s;
uint8_t ecn_bits;
@@ -4673,6 +4630,7 @@ sctp_input(m, off)
iphlen = off;
+ m = SCTP_HEADER_TO_CHAIN(i_pak);
net = NULL;
SCTP_STAT_INCR(sctps_recvpackets);
SCTP_STAT_INCR_COUNTER64(sctps_inpackets);
@@ -4684,10 +4642,10 @@ sctp_input(m, off)
/* Log in any input mbufs */
mat = m;
while (mat) {
- if (mat->m_flags & M_EXT) {
+ if (SCTP_BUF_IS_EXTENDED(mat)) {
sctp_log_mb(mat, SCTP_MBUF_INPUT);
}
- mat = mat->m_next;
+ mat = SCTP_BUF_NEXT(mat);
}
#endif
if ((size_t)iphlen > sizeof(struct ip)) {
@@ -4699,7 +4657,7 @@ sctp_input(m, off)
*/
ip = mtod(m, struct ip *);
offset = iphlen + sizeof(*sh) + sizeof(*ch);
- if (m->m_len < offset) {
+ if (SCTP_BUF_LEN(m) < offset) {
if ((m = m_pullup(m, offset)) == 0) {
SCTP_STAT_INCR(sctps_hdrops);
return;
@@ -4716,7 +4674,7 @@ sctp_input(m, off)
if (((ch->chunk_type == SCTP_INITIATION) ||
(ch->chunk_type == SCTP_INITIATION_ACK) ||
(ch->chunk_type == SCTP_COOKIE_ECHO)) &&
- (in_broadcast(ip->ip_dst, m->m_pkthdr.rcvif))) {
+ (SCTP_IS_IT_BROADCAST(ip->ip_dst, i_pak))) {
/*
* We only look at broadcast if its a front state, All
* others we will not have a tcb for anyway.
@@ -4730,8 +4688,7 @@ sctp_input(m, off)
}
/* validate SCTP checksum */
if ((sctp_no_csum_on_loopback == 0) ||
- (m->m_pkthdr.rcvif == NULL) ||
- (m->m_pkthdr.rcvif->if_type != IFT_LOOP)) {
+ SCTP_IS_IT_LOOPBACK(i_pak)) {
/*
* we do NOT validate things from the loopback if the sysctl
* is set to 1.
@@ -4772,7 +4729,7 @@ sctp_input(m, off)
sh->checksum = calc_check;
} else {
sctp_skip_csum_4:
- mlen = m->m_pkthdr.len;
+ mlen = SCTP_HEADER_LEN(i_pak);
}
/* validate mbuf chain length with IP payload length */
if (mlen < (ip->ip_len - iphlen)) {
diff --git a/sys/netinet/sctp_os.h b/sys/netinet/sctp_os.h
index 436eb37..a4545b3 100644
--- a/sys/netinet/sctp_os.h
+++ b/sys/netinet/sctp_os.h
@@ -55,13 +55,9 @@ __FBSDID("$FreeBSD$");
* SCTP_ZONE_DESTROY(zone)
*/
-/*
- * Functions:
- * sctp_read_random(void *buffer, uint32_t bytes)
- */
-
#include <netinet/sctp_os_bsd.h>
+
#endif
diff --git a/sys/netinet/sctp_os_bsd.h b/sys/netinet/sctp_os_bsd.h
index 9b557a2..d355324 100644
--- a/sys/netinet/sctp_os_bsd.h
+++ b/sys/netinet/sctp_os_bsd.h
@@ -37,7 +37,6 @@ __FBSDID("$FreeBSD$");
*/
#include <sys/random.h>
-
/*
*
*/
@@ -85,8 +84,74 @@ typedef struct uma_zone *sctp_zone_t;
uma_zfree(zone, element);
/*
+ * timers
+ */
+#include <sys/callout.h>
+typedef struct callout sctp_os_timer_t;
+
+#define SCTP_OS_TIMER_INIT(tmr) callout_init(tmr, 1)
+#define SCTP_OS_TIMER_START callout_reset
+#define SCTP_OS_TIMER_STOP callout_stop
+#define SCTP_OS_TIMER_PENDING callout_pending
+#define SCTP_OS_TIMER_ACTIVE callout_active
+#define SCTP_OS_TIMER_DEACTIVATE callout_deactivate
+
+/*
* Functions
*/
-#define sctp_read_random(buf, len) read_random(buf, len)
+#define SCTP_READ_RANDOM(buf, len) read_random(buf, len)
+
+/* Mbuf manipulation and access macros */
+#define SCTP_BUF_LEN(m) (m->m_len)
+#define SCTP_BUF_NEXT(m) (m->m_next)
+#define SCTP_BUF_NEXT_PKT(m) (m->m_nextpkt)
+#define SCTP_BUF_RESV_UF(m, size) m->m_data += size
+#define SCTP_BUF_AT(m, size) m->m_data + size
+#define SCTP_BUF_IS_EXTENDED(m) (m->m_flags & M_EXT)
+#define SCTP_BUF_EXTEND_SIZE(m) (m->m_ext.ext_size)
+#define SCTP_BUF_TYPE(m) (m->m_type)
+#define SCTP_BUF_RECVIF(m) (m->m_pkthdr.rcvif)
+#define SCTP_BUF_PREPEND M_PREPEND
+/*************************/
+/* These are for logging */
+/*************************/
+/* return the base ext data pointer */
+#define SCTP_BUF_EXTEND_BASE(m) (m->m_ext.ext_buf)
+ /* return the refcnt of the data pointer */
+#define SCTP_BUF_EXTEND_REFCNT(m) (*m->m_ext.ref_cnt)
+/* return any buffer related flags, this is
+ * used beyond logging for apple only.
+ */
+#define SCTP_BUF_GET_FLAGS(m) (m->m_flags)
+
+/* For BSD this just accesses the M_PKTHDR length
+ * so it operates on an mbuf with hdr flag. Other
+ * O/S's may have seperate packet header and mbuf
+ * chain pointers.. thus the macro.
+ */
+#define SCTP_HEADER_TO_CHAIN(m) (m)
+#define SCTP_HEADER_LEN(m) (m->m_pkthdr.len)
+#define SCTP_GET_HEADER_FOR_OUTPUT(len) sctp_get_mbuf_for_msg(len, 1, M_DONTWAIT, 1, MT_DATA)
+
+/* Attach the chain of data into the sendable packet. */
+#define SCTP_ATTACH_CHAIN(pak, m, packet_length) do { \
+ pak->m_next = m; \
+ pak->m_pkthdr.len = packet_length; \
+ } while(0)
+
+/* Other m_pkthdr type things */
+#define SCTP_IS_IT_BROADCAST(dst, m) in_broadcast(dst, m->m_pkthdr.rcvif)
+#define SCTP_IS_IT_LOOPBACK(m) ((m->m_pkthdr.rcvif == NULL) ||(m->m_pkthdr.rcvif->if_type == IFT_LOOP))
+
+
+/* This converts any input packet header
+ * into the chain of data holders, for BSD
+ * its a NOP.
+ */
+#define SCTP_PAK_TO_BUF(i_pak) (i_pak)
+
+/* Macro's for getting length from V6/V4 header */
+#define SCTP_GET_IPV4_LENGTH(iph) (iph->ip_len)
+#define SCTP_GET_IPV6_LENGTH(ip6) (ntohs(ip6->ip6_plen))
#endif
diff --git a/sys/netinet/sctp_output.c b/sys/netinet/sctp_output.c
index 74e1181..261b66e 100644
--- a/sys/netinet/sctp_output.c
+++ b/sys/netinet/sctp_output.c
@@ -1931,7 +1931,7 @@ sctp_find_cmsg(int c_type, void *data, struct mbuf *control, int cpsize)
struct cmsghdr cmh;
int tlen, at;
- tlen = control->m_len;
+ tlen = SCTP_BUF_LEN(control);
at = 0;
/*
* Independent of how many mbufs, find the c_type inside the control
@@ -2020,7 +2020,7 @@ try_again:
if (m == NULL) {
return (NULL);
}
- if ((m->m_flags & M_EXT) == 0) {
+ if (SCTP_BUF_IS_EXTENDED(m) == 0) {
if ((aloc_size != MCLBYTES) &&
(allonebuf == 0)) {
aloc_size -= 10;
@@ -2030,17 +2030,13 @@ try_again:
return (NULL);
}
}
- m->m_len = 0;
- m->m_next = m->m_nextpkt = NULL;
+ SCTP_BUF_LEN(m) = 0;
+ SCTP_BUF_NEXT(m) = SCTP_BUF_NEXT_PKT(m) = NULL;
#ifdef SCTP_MBUF_LOGGING
- if (m->m_flags & M_EXT) {
+ if (SCTP_BUF_IS_EXTENDED(m)) {
sctp_log_mb(m, SCTP_MBUF_IALLOC);
}
#endif
-
- if (want_header) {
- m->m_pkthdr.len = 0;
- }
return (m);
}
@@ -2079,7 +2075,7 @@ sctp_add_cookie(struct sctp_inpcb *inp, struct mbuf *init, int init_offset,
}
/* easy side we just drop it on the end */
ph = mtod(mret, struct sctp_paramhdr *);
- mret->m_len = sizeof(struct sctp_state_cookie) +
+ SCTP_BUF_LEN(mret) = sizeof(struct sctp_state_cookie) +
sizeof(struct sctp_paramhdr);
stc = (struct sctp_state_cookie *)((caddr_t)ph +
sizeof(struct sctp_paramhdr));
@@ -2091,25 +2087,25 @@ sctp_add_cookie(struct sctp_inpcb *inp, struct mbuf *init, int init_offset,
/* tack the INIT and then the INIT-ACK onto the chain */
cookie_sz = 0;
m_at = mret;
- for (m_at = mret; m_at; m_at = m_at->m_next) {
- cookie_sz += m_at->m_len;
- if (m_at->m_next == NULL) {
- m_at->m_next = copy_init;
+ for (m_at = mret; m_at; m_at = SCTP_BUF_NEXT(m_at)) {
+ cookie_sz += SCTP_BUF_LEN(m_at);
+ if (SCTP_BUF_NEXT(m_at) == NULL) {
+ SCTP_BUF_NEXT(m_at) = copy_init;
break;
}
}
- for (m_at = copy_init; m_at; m_at = m_at->m_next) {
- cookie_sz += m_at->m_len;
- if (m_at->m_next == NULL) {
- m_at->m_next = copy_initack;
+ for (m_at = copy_init; m_at; m_at = SCTP_BUF_NEXT(m_at)) {
+ cookie_sz += SCTP_BUF_LEN(m_at);
+ if (SCTP_BUF_NEXT(m_at) == NULL) {
+ SCTP_BUF_NEXT(m_at) = copy_initack;
break;
}
}
- for (m_at = copy_initack; m_at; m_at = m_at->m_next) {
- cookie_sz += m_at->m_len;
- if (m_at->m_next == NULL) {
+ for (m_at = copy_initack; m_at; m_at = SCTP_BUF_NEXT(m_at)) {
+ cookie_sz += SCTP_BUF_LEN(m_at);
+ if (SCTP_BUF_NEXT(m_at) == NULL) {
break;
}
}
@@ -2119,8 +2115,8 @@ sctp_add_cookie(struct sctp_inpcb *inp, struct mbuf *init, int init_offset,
sctp_m_freem(mret);
return (NULL);
}
- sig->m_len = 0;
- m_at->m_next = sig;
+ SCTP_BUF_LEN(sig) = 0;
+ SCTP_BUF_NEXT(m_at) = sig;
sig_offset = 0;
signature = (uint8_t *) (mtod(sig, caddr_t)+sig_offset);
/* Time to sign the cookie */
@@ -2128,7 +2124,7 @@ sctp_add_cookie(struct sctp_inpcb *inp, struct mbuf *init, int init_offset,
(uint8_t *) inp->sctp_ep.secret_key[(int)(inp->sctp_ep.current_secret_number)],
SCTP_SECRET_SIZE, mret, sizeof(struct sctp_paramhdr),
(uint8_t *) signature);
- sig->m_len += SCTP_SIGNATURE_SIZE;
+ SCTP_BUF_LEN(sig) += SCTP_SIGNATURE_SIZE;
cookie_sz += SCTP_SIGNATURE_SIZE;
ph->param_length = htons(cookie_sz);
@@ -2204,16 +2200,20 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp,
/* nofragment_flag to tell if IP_DF should be set (IPv4 only) */
{
/*
- * Given a mbuf chain (via m_next) that holds a packet header WITH a
- * SCTPHDR but no IP header, endpoint inp and sa structure. - fill
- * in the HMAC digest of any AUTH chunk in the packet - calculate
- * SCTP checksum and fill in - prepend a IP address header - if
- * boundall use INADDR_ANY - if boundspecific do source address
- * selection - set fragmentation option for ipV4 - On return from IP
- * output, check/adjust mtu size - of output interface and
- * smallest_mtu size as well.
+ * Given a mbuf chain (via SCTP_BUF_NEXT()) that holds a packet
+ * header WITH a SCTPHDR but no IP header, endpoint inp and sa
+ * structure. - fill in the HMAC digest of any AUTH chunk in the
+ * packet - calculate SCTP checksum and fill in - prepend a IP
+ * address header - if boundall use INADDR_ANY - if boundspecific do
+ * source address selection - set fragmentation option for ipV4 - On
+ * return from IP output, check/adjust mtu size - of output
+ * interface and smallest_mtu size as well.
*/
+ /* Will need ifdefs around this */
+ struct mbuf *o_pak;
+
struct sctphdr *sctphdr;
+ int packet_length;
int o_flgs;
uint32_t csum;
int ret;
@@ -2224,15 +2224,6 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp,
sctp_m_freem(m);
return (EFAULT);
}
- if ((m->m_flags & M_PKTHDR) == 0) {
-#ifdef SCTP_DEBUG
- if (sctp_debug_on & SCTP_DEBUG_OUTPUT1) {
- printf("Software error: sctp_lowlevel_chunk_output() called with non pkthdr!\n");
- }
-#endif
- sctp_m_freem(m);
- return (EFAULT);
- }
/* fill in the HMAC digest for any AUTH chunk in the packet */
if ((auth != NULL) && (stcb != NULL)) {
sctp_fill_hmac_digest_m(m, auth_offset, auth, stcb);
@@ -2249,23 +2240,28 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp,
* no more bad pktlen's coming in. But we will wait a while
* yet.
*/
- m->m_pkthdr.len = sctp_calculate_len(m);
+ packet_length = sctp_calculate_len(m);
} else {
sctphdr->checksum = 0;
- csum = sctp_calculate_sum(m, &m->m_pkthdr.len, 0);
+ csum = sctp_calculate_sum(m, &packet_length, 0);
sctphdr->checksum = csum;
}
+
if (to->sa_family == AF_INET) {
struct ip *ip;
struct route iproute;
uint8_t tos_value;
- M_PREPEND(m, sizeof(struct ip), M_DONTWAIT);
- if (m == NULL) {
+ o_pak = SCTP_GET_HEADER_FOR_OUTPUT(sizeof(struct ip));
+ if (o_pak == NULL) {
/* failed to prepend data, give up */
+ sctp_m_freem(m);
return (ENOMEM);
}
- ip = mtod(m, struct ip *);
+ SCTP_BUF_LEN(SCTP_HEADER_TO_CHAIN(o_pak)) = sizeof(struct ip);
+ packet_length += sizeof(struct ip);
+ SCTP_ATTACH_CHAIN(o_pak, m, packet_length);
+ ip = mtod(SCTP_HEADER_TO_CHAIN(o_pak), struct ip *);
ip->ip_v = IPVERSION;
ip->ip_hl = (sizeof(struct ip) >> 2);
if (net) {
@@ -2287,7 +2283,7 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp,
ip->ip_id = ip_newid();
ip->ip_ttl = inp->ip_inp.inp.inp_ip_ttl;
- ip->ip_len = m->m_pkthdr.len;
+ ip->ip_len = SCTP_HEADER_LEN(o_pak);
if (stcb) {
if ((stcb->asoc.ecn_allowed) && ecn_ok) {
/* Enable ECN */
@@ -2330,7 +2326,7 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp,
/*
* If source address selection fails and we find no route
- * then the ip_ouput should fail as well with a
+ * then the ip_output should fail as well with a
* NO_ROUTE_TO_HOST type error. We probably should catch
* that somewhere and abort the association right away
* (assuming this is an INIT being sent).
@@ -2372,7 +2368,7 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp,
}
}
}
- sctp_m_freem(m);
+ sctp_m_freem(o_pak);
return (EHOSTUNREACH);
} else {
have_mtu = ro->ro_rt->rt_ifp->if_mtu;
@@ -2397,7 +2393,7 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp,
if (ro != &iproute) {
memcpy(&iproute, ro, sizeof(*ro));
}
- ret = ip_output(m, inp->ip_inp.inp.inp_options,
+ ret = ip_output(o_pak, inp->ip_inp.inp.inp_options,
ro, o_flgs, inp->ip_inp.inp.inp_moptions
,(struct inpcb *)NULL
);
@@ -2454,13 +2450,16 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp,
} else {
flowlabel = ((struct in6pcb *)inp)->in6p_flowinfo;
}
- M_PREPEND(m, sizeof(struct ip6_hdr), M_DONTWAIT);
- if (m == NULL) {
+ o_pak = SCTP_GET_HEADER_FOR_OUTPUT(sizeof(struct ip6_hdr));
+ if (o_pak == NULL) {
/* failed to prepend data, give up */
+ sctp_m_freem(m);
return (ENOMEM);
}
- ip6h = mtod(m, struct ip6_hdr *);
-
+ SCTP_BUF_LEN(SCTP_HEADER_TO_CHAIN(o_pak)) = sizeof(struct ip6_hdr);
+ packet_length += sizeof(struct ip6_hdr);
+ SCTP_ATTACH_CHAIN(o_pak, m, packet_length);
+ ip6h = mtod(SCTP_HEADER_TO_CHAIN(o_pak), struct ip6_hdr *);
/*
* We assume here that inp_flow is in host byte order within
* the TCB!
@@ -2497,7 +2496,7 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp,
}
ip6h->ip6_flow = htonl(((tosTop << 24) | ((tosBottom | flowTop) << 16) | flowBottom));
ip6h->ip6_nxt = IPPROTO_SCTP;
- ip6h->ip6_plen = m->m_pkthdr.len;
+ ip6h->ip6_plen = (SCTP_HEADER_LEN(o_pak) - sizeof(struct ip6_hdr));
ip6h->ip6_dst = sin6->sin6_addr;
/*
@@ -2536,7 +2535,7 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp,
printf("low_level_output: dropped v6 pkt- no valid source addr\n");
}
#endif
- sctp_m_freem(m);
+ sctp_m_freem(o_pak);
if (net) {
if ((net->dest_state & SCTP_ADDR_REACHABLE) && stcb)
sctp_ulp_notify(SCTP_NOTIFY_INTERFACE_DOWN,
@@ -2572,7 +2571,7 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp,
lsa6_storage.sin6_family = AF_INET6;
lsa6_storage.sin6_len = sizeof(lsa6_storage);
if ((error = sa6_recoverscope(&lsa6_storage)) != 0) {
- sctp_m_freem(m);
+ sctp_m_freem(o_pak);
return (error);
}
/* XXX */
@@ -2610,7 +2609,7 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp,
prev_scope = sin6->sin6_scope_id;
prev_port = sin6->sin6_port;
}
- ret = ip6_output(m, ((struct in6pcb *)inp)->in6p_outputopts,
+ ret = ip6_output(o_pak, ((struct in6pcb *)inp)->in6p_outputopts,
(struct route_in6 *)ro,
o_flgs,
((struct in6pcb *)inp)->in6p_moptions,
@@ -2721,7 +2720,7 @@ sctp_send_initiate(struct sctp_inpcb *inp, struct sctp_tcb *stcb)
if (IN6_IS_ADDR_LINKLOCAL(&sin6l->sin6_addr))
cnt_inits_to = 1;
}
- if (callout_pending(&net->rxt_timer.timer)) {
+ if (SCTP_OS_TIMER_PENDING(&net->rxt_timer.timer)) {
/* This case should not happen */
return;
}
@@ -2735,9 +2734,7 @@ sctp_send_initiate(struct sctp_inpcb *inp, struct sctp_tcb *stcb)
/* No memory, INIT timer will re-attempt. */
return;
}
- m->m_pkthdr.len = 0;
- m->m_data += SCTP_MIN_OVERHEAD;
- m->m_len = sizeof(struct sctp_init_msg);
+ SCTP_BUF_LEN(m) = sizeof(struct sctp_init_msg);
/* Now lets put the SCTP header in place */
initm = mtod(m, struct sctp_init_msg *);
initm->sh.src_port = inp->sctp_lport;
@@ -2767,7 +2764,7 @@ sctp_send_initiate(struct sctp_inpcb *inp, struct sctp_tcb *stcb)
sizeof(uint16_t));
sup_addr->addr_type[0] = htons(SCTP_IPV4_ADDRESS);
sup_addr->addr_type[1] = htons(SCTP_IPV6_ADDRESS);
- m->m_len += sizeof(*sup_addr) + sizeof(uint16_t);
+ SCTP_BUF_LEN(m) += sizeof(*sup_addr) + sizeof(uint16_t);
if (inp->sctp_ep.adaptation_layer_indicator) {
struct sctp_adaptation_layer_indication *ali;
@@ -2777,7 +2774,7 @@ sctp_send_initiate(struct sctp_inpcb *inp, struct sctp_tcb *stcb)
ali->ph.param_type = htons(SCTP_ULP_ADAPTATION);
ali->ph.param_length = htons(sizeof(*ali));
ali->indication = ntohl(inp->sctp_ep.adaptation_layer_indicator);
- m->m_len += sizeof(*ali);
+ SCTP_BUF_LEN(m) += sizeof(*ali);
ecn = (struct sctp_ecn_supported_param *)((caddr_t)ali +
sizeof(*ali));
} else {
@@ -2794,7 +2791,7 @@ sctp_send_initiate(struct sctp_inpcb *inp, struct sctp_tcb *stcb)
cookie_preserve->ph.param_length = htons(
sizeof(*cookie_preserve));
cookie_preserve->time = htonl(stcb->asoc.cookie_preserve_req);
- m->m_len += sizeof(*cookie_preserve);
+ SCTP_BUF_LEN(m) += sizeof(*cookie_preserve);
ecn = (struct sctp_ecn_supported_param *)(
(caddr_t)cookie_preserve + sizeof(*cookie_preserve));
stcb->asoc.cookie_preserve_req = 0;
@@ -2803,7 +2800,7 @@ sctp_send_initiate(struct sctp_inpcb *inp, struct sctp_tcb *stcb)
if (sctp_ecn_enable == 1) {
ecn->ph.param_type = htons(SCTP_ECN_CAPABLE);
ecn->ph.param_length = htons(sizeof(*ecn));
- m->m_len += sizeof(*ecn);
+ SCTP_BUF_LEN(m) += sizeof(*ecn);
prsctp = (struct sctp_prsctp_supported_param *)((caddr_t)ecn +
sizeof(*ecn));
} else {
@@ -2812,7 +2809,7 @@ sctp_send_initiate(struct sctp_inpcb *inp, struct sctp_tcb *stcb)
/* And now tell the peer we do pr-sctp */
prsctp->ph.param_type = htons(SCTP_PRSCTP_SUPPORTED);
prsctp->ph.param_length = htons(sizeof(*prsctp));
- m->m_len += sizeof(*prsctp);
+ SCTP_BUF_LEN(m) += sizeof(*prsctp);
/* And now tell the peer we do all the extensions */
pr_supported = (struct sctp_supported_chunk_types_param *)
@@ -2829,7 +2826,7 @@ sctp_send_initiate(struct sctp_inpcb *inp, struct sctp_tcb *stcb)
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);
- m->m_len += SCTP_SIZE32(p_len);
+ SCTP_BUF_LEN(m) += SCTP_SIZE32(p_len);
/* ECN nonce: And now tell the peer we support ECN nonce */
if (sctp_ecn_nonce) {
@@ -2837,7 +2834,7 @@ sctp_send_initiate(struct sctp_inpcb *inp, struct sctp_tcb *stcb)
((caddr_t)pr_supported + SCTP_SIZE32(p_len));
ecn_nonce->ph.param_type = htons(SCTP_ECN_NONCE_SUPPORTED);
ecn_nonce->ph.param_length = htons(sizeof(*ecn_nonce));
- m->m_len += sizeof(*ecn_nonce);
+ SCTP_BUF_LEN(m) += sizeof(*ecn_nonce);
}
/* add authentication parameters */
if (!sctp_auth_disable) {
@@ -2847,7 +2844,7 @@ sctp_send_initiate(struct sctp_inpcb *inp, struct sctp_tcb *stcb)
/* attach RANDOM parameter, if available */
if (stcb->asoc.authinfo.random != NULL) {
- random = (struct sctp_auth_random *)(mtod(m, caddr_t)+m->m_len);
+ random = (struct sctp_auth_random *)(mtod(m, caddr_t)+SCTP_BUF_LEN(m));
random->ph.param_type = htons(SCTP_RANDOM);
p_len = sizeof(*random) + stcb->asoc.authinfo.random_len;
random->ph.param_length = htons(p_len);
@@ -2855,10 +2852,10 @@ sctp_send_initiate(struct sctp_inpcb *inp, struct sctp_tcb *stcb)
stcb->asoc.authinfo.random_len);
/* zero out any padding required */
bzero((caddr_t)random + p_len, SCTP_SIZE32(p_len) - p_len);
- m->m_len += SCTP_SIZE32(p_len);
+ SCTP_BUF_LEN(m) += SCTP_SIZE32(p_len);
}
/* add HMAC_ALGO parameter */
- hmacs = (struct sctp_auth_hmac_algo *)(mtod(m, caddr_t)+m->m_len);
+ hmacs = (struct sctp_auth_hmac_algo *)(mtod(m, caddr_t)+SCTP_BUF_LEN(m));
p_len = sctp_serialize_hmaclist(stcb->asoc.local_hmacs,
(uint8_t *) hmacs->hmac_ids);
if (p_len > 0) {
@@ -2867,10 +2864,10 @@ sctp_send_initiate(struct sctp_inpcb *inp, struct sctp_tcb *stcb)
hmacs->ph.param_length = htons(p_len);
/* zero out any padding required */
bzero((caddr_t)hmacs + p_len, SCTP_SIZE32(p_len) - p_len);
- m->m_len += SCTP_SIZE32(p_len);
+ SCTP_BUF_LEN(m) += SCTP_SIZE32(p_len);
}
/* add CHUNKS parameter */
- chunks = (struct sctp_auth_chunk_list *)(mtod(m, caddr_t)+m->m_len);
+ chunks = (struct sctp_auth_chunk_list *)(mtod(m, caddr_t)+SCTP_BUF_LEN(m));
p_len = sctp_serialize_auth_chunks(stcb->asoc.local_auth_chunks,
chunks->chunk_types);
if (p_len > 0) {
@@ -2879,7 +2876,7 @@ sctp_send_initiate(struct sctp_inpcb *inp, struct sctp_tcb *stcb)
chunks->ph.param_length = htons(p_len);
/* zero out any padding required */
bzero((caddr_t)chunks + p_len, SCTP_SIZE32(p_len) - p_len);
- m->m_len += SCTP_SIZE32(p_len);
+ SCTP_BUF_LEN(m) += SCTP_SIZE32(p_len);
}
}
m_at = m;
@@ -2906,21 +2903,20 @@ sctp_send_initiate(struct sctp_inpcb *inp, struct sctp_tcb *stcb)
/* calulate the size and update pkt header and chunk header */
- m->m_pkthdr.len = 0;
- for (m_at = m; m_at; m_at = m_at->m_next) {
- if (m_at->m_next == NULL)
+ p_len = 0;
+ for (m_at = m; m_at; m_at = SCTP_BUF_NEXT(m_at)) {
+ if (SCTP_BUF_NEXT(m_at) == NULL)
m_last = m_at;
- m->m_pkthdr.len += m_at->m_len;
+ p_len += SCTP_BUF_LEN(m_at);
}
- initm->msg.ch.chunk_length = htons((m->m_pkthdr.len -
- sizeof(struct sctphdr)));
+ initm->msg.ch.chunk_length = htons((p_len - sizeof(struct sctphdr)));
/*
* We pass 0 here to NOT set IP_DF if its IPv4, we ignore the return
* here since the timer will drive a retranmission.
*/
/* I don't expect this to execute but we will be safe here */
- padval = m->m_pkthdr.len % 4;
+ padval = p_len % 4;
if ((padval) && (m_last)) {
/*
* The compiler worries that m_last may not be set even
@@ -2935,7 +2931,7 @@ sctp_send_initiate(struct sctp_inpcb *inp, struct sctp_tcb *stcb)
sctp_m_freem(m);
return;
}
- m->m_pkthdr.len += padval;
+ p_len += padval;
}
ret = sctp_lowlevel_chunk_output(inp, stcb, net,
(struct sockaddr *)&net->ro._l_addr,
@@ -3038,17 +3034,16 @@ sctp_arethere_unrecognized_parameters(struct mbuf *in_initpkt,
l_len = sizeof(struct ip6_hdr) + sizeof(struct sctphdr) + sizeof(struct sctp_chunkhdr);
l_len += plen;
l_len += sizeof(struct sctp_paramhdr);
- op_err = sctp_get_mbuf_for_msg(l_len, 1, M_DONTWAIT, 1, MT_DATA);
+ op_err = sctp_get_mbuf_for_msg(l_len, 0, M_DONTWAIT, 1, MT_DATA);
if (op_err) {
- op_err->m_len = 0;
- op_err->m_pkthdr.len = 0;
+ SCTP_BUF_LEN(op_err) = 0;
/*
* pre-reserve space for ip and sctp
* header and chunk hdr
*/
- op_err->m_data += sizeof(struct ip6_hdr);
- op_err->m_data += sizeof(struct sctphdr);
- op_err->m_data += sizeof(struct sctp_chunkhdr);
+ SCTP_BUF_RESV_UF(op_err, sizeof(struct ip6_hdr));
+ SCTP_BUF_RESV_UF(op_err, sizeof(struct sctphdr));
+ SCTP_BUF_RESV_UF(op_err, sizeof(struct sctp_chunkhdr));
}
}
if (op_err) {
@@ -3095,13 +3090,12 @@ sctp_arethere_unrecognized_parameters(struct mbuf *in_initpkt,
l_len = sizeof(struct ip6_hdr) + sizeof(struct sctphdr) + sizeof(struct sctp_chunkhdr);
l_len += plen;
l_len += sizeof(struct sctp_paramhdr);
- op_err = sctp_get_mbuf_for_msg(l_len, 1, M_DONTWAIT, 1, MT_DATA);
+ op_err = sctp_get_mbuf_for_msg(l_len, 0, M_DONTWAIT, 1, MT_DATA);
if (op_err) {
- op_err->m_len = 0;
- op_err->m_pkthdr.len = 0;
- op_err->m_data += sizeof(struct ip6_hdr);
- op_err->m_data += sizeof(struct sctphdr);
- op_err->m_data += sizeof(struct sctp_chunkhdr);
+ SCTP_BUF_LEN(op_err) = 0;
+ SCTP_BUF_RESV_UF(op_err, sizeof(struct ip6_hdr));
+ SCTP_BUF_RESV_UF(op_err, sizeof(struct sctphdr));
+ SCTP_BUF_RESV_UF(op_err, sizeof(struct sctp_chunkhdr));
}
}
if (op_err) {
@@ -3354,16 +3348,14 @@ sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
sctp_send_abort(init_pkt, iphlen, sh, init_chk->init.initiate_tag, op_err);
return;
}
- m = sctp_get_mbuf_for_msg(MCLBYTES, 1, M_DONTWAIT, 1, MT_DATA);
+ m = sctp_get_mbuf_for_msg(MCLBYTES, 0, M_DONTWAIT, 1, MT_DATA);
if (m == NULL) {
/* No memory, INIT timer will re-attempt. */
if (op_err)
sctp_m_freem(op_err);
return;
}
- m->m_data += SCTP_MIN_OVERHEAD;
- m->m_pkthdr.rcvif = 0;
- m->m_len = sizeof(struct sctp_init_msg);
+ SCTP_BUF_LEN(m) = sizeof(struct sctp_init_msg);
/* the time I built cookie */
SCTP_GETTIME_TIMEVAL(&stc.time_entered);
@@ -3512,6 +3504,7 @@ sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
/* pull out the scope_id from incoming pkt */
/* FIX ME: does this have scope from rcvif? */
(void)sa6_recoverscope(sin6);
+
sa6_embedscope(sin6, ip6_use_defzone);
stc.scope_id = sin6->sin6_scope_id;
} else if (IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr)) {
@@ -3674,7 +3667,7 @@ sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
ali->ph.param_type = htons(SCTP_ULP_ADAPTATION);
ali->ph.param_length = htons(sizeof(*ali));
ali->indication = ntohl(inp->sctp_ep.adaptation_layer_indicator);
- m->m_len += sizeof(*ali);
+ SCTP_BUF_LEN(m) += sizeof(*ali);
ecn = (struct sctp_ecn_supported_param *)((caddr_t)ali +
sizeof(*ali));
} else {
@@ -3686,7 +3679,7 @@ sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
if (sctp_ecn_enable == 1) {
ecn->ph.param_type = htons(SCTP_ECN_CAPABLE);
ecn->ph.param_length = htons(sizeof(*ecn));
- m->m_len += sizeof(*ecn);
+ SCTP_BUF_LEN(m) += sizeof(*ecn);
prsctp = (struct sctp_prsctp_supported_param *)((caddr_t)ecn +
sizeof(*ecn));
@@ -3696,7 +3689,7 @@ sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
/* And now tell the peer we do pr-sctp */
prsctp->ph.param_type = htons(SCTP_PRSCTP_SUPPORTED);
prsctp->ph.param_length = htons(sizeof(*prsctp));
- m->m_len += sizeof(*prsctp);
+ SCTP_BUF_LEN(m) += sizeof(*prsctp);
/* And now tell the peer we do all the extensions */
pr_supported = (struct sctp_supported_chunk_types_param *)
@@ -3714,7 +3707,7 @@ sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
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);
- m->m_len += SCTP_SIZE32(p_len);
+ SCTP_BUF_LEN(m) += SCTP_SIZE32(p_len);
/* ECN nonce: And now tell the peer we support ECN nonce */
if (sctp_ecn_nonce) {
@@ -3722,7 +3715,7 @@ sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
((caddr_t)pr_supported + SCTP_SIZE32(p_len));
ecn_nonce->ph.param_type = htons(SCTP_ECN_NONCE_SUPPORTED);
ecn_nonce->ph.param_length = htons(sizeof(*ecn_nonce));
- m->m_len += sizeof(*ecn_nonce);
+ SCTP_BUF_LEN(m) += sizeof(*ecn_nonce);
}
/* add authentication parameters */
if (!sctp_auth_disable) {
@@ -3733,17 +3726,17 @@ sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
/* generate and add RANDOM parameter */
random_len = sctp_auth_random_len;
- random = (struct sctp_auth_random *)(mtod(m, caddr_t)+m->m_len);
+ random = (struct sctp_auth_random *)(mtod(m, caddr_t)+SCTP_BUF_LEN(m));
random->ph.param_type = htons(SCTP_RANDOM);
p_len = sizeof(*random) + random_len;
random->ph.param_length = htons(p_len);
- sctp_read_random(random->random_data, random_len);
+ SCTP_READ_RANDOM(random->random_data, random_len);
/* zero out any padding required */
bzero((caddr_t)random + p_len, SCTP_SIZE32(p_len) - p_len);
- m->m_len += SCTP_SIZE32(p_len);
+ SCTP_BUF_LEN(m) += SCTP_SIZE32(p_len);
/* add HMAC_ALGO parameter */
- hmacs = (struct sctp_auth_hmac_algo *)(mtod(m, caddr_t)+m->m_len);
+ 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) {
@@ -3752,10 +3745,10 @@ sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
hmacs->ph.param_length = htons(p_len);
/* zero out any padding required */
bzero((caddr_t)hmacs + p_len, SCTP_SIZE32(p_len) - p_len);
- m->m_len += SCTP_SIZE32(p_len);
+ SCTP_BUF_LEN(m) += SCTP_SIZE32(p_len);
}
/* add CHUNKS parameter */
- chunks = (struct sctp_auth_chunk_list *)(mtod(m, caddr_t)+m->m_len);
+ 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) {
@@ -3764,7 +3757,7 @@ sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
chunks->ph.param_length = htons(p_len);
/* zero out any padding required */
bzero((caddr_t)chunks + p_len, SCTP_SIZE32(p_len) - p_len);
- m->m_len += SCTP_SIZE32(p_len);
+ SCTP_BUF_LEN(m) += SCTP_SIZE32(p_len);
}
}
m_at = m;
@@ -3790,29 +3783,38 @@ sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
/* tack on the operational error if present */
if (op_err) {
- if (op_err->m_pkthdr.len % 4) {
+ 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 - (op_err->m_pkthdr.len % 4);
- m_copyback(op_err, op_err->m_pkthdr.len, padlen, (caddr_t)&cpthis);
+ padlen = 4 - (llen % 4);
+ m_copyback(op_err, llen, padlen, (caddr_t)&cpthis);
}
- while (m_at->m_next != NULL) {
- m_at = m_at->m_next;
+ while (SCTP_BUF_NEXT(m_at) != NULL) {
+ m_at = SCTP_BUF_NEXT(m_at);
}
- m_at->m_next = op_err;
- while (m_at->m_next != NULL) {
- m_at = m_at->m_next;
+ SCTP_BUF_NEXT(m_at) = op_err;
+ while (SCTP_BUF_NEXT(m_at) != NULL) {
+ m_at = SCTP_BUF_NEXT(m_at);
}
}
/* Get total size of init packet */
sz_of = SCTP_SIZE32(ntohs(init_chk->ch.chunk_length));
/* pre-calulate the size and update pkt header and chunk header */
- m->m_pkthdr.len = 0;
- for (m_tmp = m; m_tmp; m_tmp = m_tmp->m_next) {
- m->m_pkthdr.len += m_tmp->m_len;
- if (m_tmp->m_next == NULL) {
+ 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;
}
@@ -3829,10 +3831,10 @@ sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
*/
/* add once for the INIT-ACK */
- sz_of += (m->m_pkthdr.len - sizeof(struct sctphdr));
+ sz_of += (p_len - sizeof(struct sctphdr));
/* add a second time for the INIT-ACK in the cookie */
- sz_of += (m->m_pkthdr.len - sizeof(struct sctphdr));
+ sz_of += (p_len - sizeof(struct sctphdr));
/* Now add the cookie header and cookie message struct */
sz_of += sizeof(struct sctp_state_cookie_param);
@@ -3849,10 +3851,10 @@ 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 */
- m_tmp->m_next = m_cookie;
- for (; m_tmp; m_tmp = m_tmp->m_next) {
- m->m_pkthdr.len += m_tmp->m_len;
- if (m_tmp->m_next == NULL) {
+ SCTP_BUF_NEXT(m_tmp) = m_cookie;
+ for (; 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 */
m_last = m_tmp;
break;
@@ -3863,7 +3865,7 @@ sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
* We pass 0 here to NOT set IP_DF if its IPv4, we ignore the return
* here since the timer will drive a retranmission.
*/
- padval = m->m_pkthdr.len % 4;
+ padval = p_len % 4;
if ((padval) && (m_last)) {
/* see my previous comments on m_last */
int ret;
@@ -3874,7 +3876,7 @@ sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
sctp_m_freem(m);
return;
}
- m->m_pkthdr.len += padval;
+ p_len += padval;
}
sctp_lowlevel_chunk_output(inp, NULL, NULL, to, m, 0, NULL, 0, 0,
NULL, 0);
@@ -4187,23 +4189,16 @@ sctp_msg_append(struct sctp_tcb *stcb,
sp->length = 0;
at = m;
sctp_set_prsctp_policy(stcb, sp);
+ /*
+ * We could in theory (for sendall) pass the length in, but we would
+ * still have to hunt through the chain since we need to setup the
+ * tail_mbuf
+ */
while (at) {
- if (at->m_next == NULL)
+ if (SCTP_BUF_NEXT(at) == NULL)
sp->tail_mbuf = at;
- sp->length += at->m_len;
- at = at->m_next;
- }
- if (sp->data->m_flags & M_PKTHDR) {
- sp->data->m_pkthdr.len = sp->length;
- } else {
- /* Get an HDR in front please */
- at = sctp_get_mbuf_for_msg(1, 1, M_DONTWAIT, 1, MT_DATA);
- if (at) {
- at->m_pkthdr.len = sp->length;
- at->m_len = 0;
- at->m_next = sp->data;
- sp->data = at;
- }
+ sp->length += SCTP_BUF_LEN(at);
+ at = SCTP_BUF_NEXT(at);
}
SCTP_TCB_SEND_LOCK(stcb);
sctp_snd_sb_alloc(stcb, sp->length);
@@ -4258,14 +4253,14 @@ error_out:
if (outchain == NULL) {
/* This is the general case */
new_mbuf:
- outchain = sctp_get_mbuf_for_msg(MCLBYTES, 1, M_DONTWAIT, 1, MT_HEADER);
+ outchain = sctp_get_mbuf_for_msg(MCLBYTES, 0, M_DONTWAIT, 1, MT_HEADER);
if (outchain == NULL) {
goto error_out;
}
- outchain->m_len = 0;
+ SCTP_BUF_LEN(outchain) = 0;
*endofchain = outchain;
/* get the prepend space */
- outchain->m_data += (SCTP_FIRST_MBUF_RESV + 4);
+ SCTP_BUF_RESV_UF(outchain, (SCTP_FIRST_MBUF_RESV + 4));
} else {
/*
* We really should not get a NULL
@@ -4274,11 +4269,11 @@ error_out:
/* find end */
m = outchain;
while (m) {
- if (m->m_next == NULL) {
+ if (SCTP_BUF_NEXT(m) == NULL) {
*endofchain = m;
break;
}
- m = m->m_next;
+ m = SCTP_BUF_NEXT(m);
}
/* sanity */
if (*endofchain == NULL) {
@@ -4297,52 +4292,36 @@ error_out:
len = M_TRAILINGSPACE(*endofchain);
}
/* Find the end of the data, for appending */
- cp = (mtod((*endofchain), caddr_t)+(*endofchain)->m_len);
+ cp = (mtod((*endofchain), caddr_t)+SCTP_BUF_LEN((*endofchain)));
/* Now lets copy it out */
if (len >= sizeofcpy) {
/* It all fits, copy it in */
m_copydata(clonechain, 0, sizeofcpy, cp);
- (*endofchain)->m_len += sizeofcpy;
- if (outchain->m_flags & M_PKTHDR)
- outchain->m_pkthdr.len += sizeofcpy;
+ SCTP_BUF_LEN((*endofchain)) += sizeofcpy;
} else {
/* fill up the end of the chain */
if (len > 0) {
m_copydata(clonechain, 0, len, cp);
- (*endofchain)->m_len += len;
- if (outchain->m_flags & M_PKTHDR)
- outchain->m_pkthdr.len += len;
+ SCTP_BUF_LEN((*endofchain)) += len;
/* now we need another one */
sizeofcpy -= len;
}
- m = sctp_get_mbuf_for_msg(MCLBYTES, 1, M_DONTWAIT, 1, MT_HEADER);
+ m = sctp_get_mbuf_for_msg(MCLBYTES, 0, M_DONTWAIT, 1, MT_HEADER);
if (m == NULL) {
/* We failed */
goto error_out;
}
- (*endofchain)->m_next = m;
+ SCTP_BUF_NEXT((*endofchain)) = m;
*endofchain = m;
cp = mtod((*endofchain), caddr_t);
m_copydata(clonechain, len, sizeofcpy, cp);
- (*endofchain)->m_len += sizeofcpy;
- if (outchain->m_flags & M_PKTHDR) {
- outchain->m_pkthdr.len += sizeofcpy;
- }
+ SCTP_BUF_LEN((*endofchain)) += sizeofcpy;
}
return (outchain);
} else {
/* copy the old fashion way */
- /*
- * Supposedly m_copypacket is an optimization, use
- * it if we can
- */
- if (clonechain->m_flags & M_PKTHDR) {
- appendchain = m_copypacket(clonechain, M_DONTWAIT);
- } else {
- appendchain = m_copy(clonechain, 0, M_COPYALL);
- }
-
+ appendchain = m_copy(clonechain, 0, M_COPYALL);
}
}
if (appendchain == NULL) {
@@ -4351,79 +4330,41 @@ error_out:
sctp_m_freem(outchain);
return (NULL);
}
- /* if outchain is null, check our special reservation flag */
- if (outchain == NULL) {
- /*
- * need a lead mbuf in this one if we don't have space for:
- * - E-net header (12+2+2) - IP header (20/40) - SCTP Common
- * Header (12)
- */
- if (M_LEADINGSPACE(appendchain) < (SCTP_FIRST_MBUF_RESV)) {
- outchain = sctp_get_mbuf_for_msg(8, 1, M_DONTWAIT, 1, MT_HEADER);
- if (outchain) {
- /*
- * if we don't hit here we have a problem
- * anyway :o We reserve all the mbuf for
- * prepends.
- */
- outchain->m_pkthdr.len = 0;
- outchain->m_len = 0;
- outchain->m_next = NULL;
- MH_ALIGN(outchain, 4);
- *endofchain = outchain;
- }
- }
- }
if (outchain) {
/* tack on to the end */
if (*endofchain != NULL) {
- (*endofchain)->m_next = appendchain;
+ SCTP_BUF_NEXT(((*endofchain))) = appendchain;
} else {
m = outchain;
while (m) {
- if (m->m_next == NULL) {
- m->m_next = appendchain;
+ if (SCTP_BUF_NEXT(m) == NULL) {
+ SCTP_BUF_NEXT(m) = appendchain;
break;
}
- m = m->m_next;
+ m = SCTP_BUF_NEXT(m);
}
}
- if (outchain->m_flags & M_PKTHDR) {
- int append_tot;
-
- m = appendchain;
- append_tot = 0;
- while (m) {
- append_tot += m->m_len;
- if (m->m_next == NULL) {
- *endofchain = m;
- }
- m = m->m_next;
- }
- outchain->m_pkthdr.len += append_tot;
- } else {
- /*
- * save off the end and update the end-chain postion
- */
- m = appendchain;
- while (m) {
- if (m->m_next == NULL) {
- *endofchain = m;
- break;
- }
- m = m->m_next;
+ /*
+ * save off the end and update the end-chain postion
+ */
+ m = appendchain;
+ while (m) {
+ if (SCTP_BUF_NEXT(m) == NULL) {
+ *endofchain = m;
+ break;
}
+ m = SCTP_BUF_NEXT(m);
}
return (outchain);
} else {
/* save off the end and update the end-chain postion */
m = appendchain;
while (m) {
- if (m->m_next == NULL) {
+ if (SCTP_BUF_NEXT(m) == NULL) {
*endofchain = m;
break;
}
- m = m->m_next;
+ m = SCTP_BUF_NEXT(m);
}
return (appendchain);
}
@@ -4457,7 +4398,7 @@ sctp_sendall_iterator(struct sctp_inpcb *inp, struct sctp_tcb *stcb, void *ptr,
/* TSNH */
return;
}
- if ((ca->m) && (ca->m->m_pkthdr.len)) {
+ if ((ca->m) && ca->sndlen) {
m = m_copym(ca->m, 0, M_COPYALL, M_DONTWAIT);
if (m == NULL) {
/* can't copy so we are done */
@@ -4473,11 +4414,11 @@ sctp_sendall_iterator(struct sctp_inpcb *inp, struct sctp_tcb *stcb, void *ptr,
if (m) {
struct sctp_paramhdr *ph;
- M_PREPEND(m, sizeof(struct sctp_paramhdr), M_DONTWAIT);
+ SCTP_BUF_PREPEND(m, sizeof(struct sctp_paramhdr), M_DONTWAIT);
if (m) {
ph = mtod(m, struct sctp_paramhdr *);
ph->param_type = htons(SCTP_CAUSE_USER_INITIATED_ABT);
- ph->param_length = htons(m->m_pkthdr.len);
+ ph->param_length = htons(ca->sndlen);
}
/*
* We add one here to keep the assoc from
@@ -4635,7 +4576,7 @@ sctp_sendall_completes(void *ptr, uint32_t val)
#define MC_ALIGN(m, len) do { \
- (m)->m_data += (MCLBYTES - (len)) & ~(sizeof(long) - 1); \
+ SCTP_BUF_RESV_UF(m, ((MCLBYTES - (len)) & ~(sizeof(long) - 1)); \
} while (0)
@@ -4646,14 +4587,13 @@ sctp_copy_out_all(struct uio *uio, int len)
struct mbuf *ret, *at;
int left, willcpy, cancpy, error;
- ret = sctp_get_mbuf_for_msg(MCLBYTES, 1, M_WAIT, 1, MT_DATA);
+ ret = sctp_get_mbuf_for_msg(MCLBYTES, 0, M_WAIT, 1, MT_DATA);
if (ret == NULL) {
/* TSNH */
return (NULL);
}
left = len;
- ret->m_len = 0;
- ret->m_pkthdr.len = len;
+ SCTP_BUF_LEN(ret) = 0;
/* save space for the data chunk header */
cancpy = M_TRAILINGSPACE(ret);
willcpy = min(cancpy, left);
@@ -4666,16 +4606,16 @@ sctp_copy_out_all(struct uio *uio, int len)
sctp_m_freem(at);
return (NULL);
}
- at->m_len = willcpy;
- at->m_nextpkt = at->m_next = 0;
+ SCTP_BUF_LEN(at) = willcpy;
+ SCTP_BUF_NEXT_PKT(at) = SCTP_BUF_NEXT(at) = 0;
left -= willcpy;
if (left > 0) {
- at->m_next = sctp_get_mbuf_for_msg(left, 0, M_WAIT, 1, MT_DATA);
- if (at->m_next == NULL) {
+ SCTP_BUF_NEXT(at) = sctp_get_mbuf_for_msg(left, 0, M_WAIT, 1, MT_DATA);
+ if (SCTP_BUF_NEXT(at) == NULL) {
goto err_out_now;
}
- at = at->m_next;
- at->m_len = 0;
+ at = SCTP_BUF_NEXT(at);
+ SCTP_BUF_LEN(at) = 0;
cancpy = M_TRAILINGSPACE(at);
willcpy = min(cancpy, left);
}
@@ -4710,32 +4650,18 @@ sctp_sendall(struct sctp_inpcb *inp, struct uio *uio, struct mbuf *m,
ca->sndlen = uio->uio_resid;
ca->m = sctp_copy_out_all(uio, ca->sndlen);
if (ca->m == NULL) {
- out_no_mem:
SCTP_FREE(ca);
return (ENOMEM);
}
} else {
- if ((m->m_flags & M_PKTHDR) == 0) {
- struct mbuf *mat;
+ /* Gather the length of the send */
+ struct mbuf *mat;
- mat = m;
- ca->sndlen = 0;
- while (m) {
- ca->sndlen += m->m_len;
- m = m->m_next;
- }
- mat = sctp_get_mbuf_for_msg(1, 1, M_WAIT, 1, MT_DATA);
- if (mat) {
- sctp_m_freem(m);
- goto out_no_mem;
- }
- /* We MUST have a header on the front */
- mat->m_next = m;
- mat->m_len = 0;
- mat->m_pkthdr.len = ca->sndlen;
- ca->m = mat;
- } else {
- ca->sndlen = m->m_pkthdr.len;
+ mat = m;
+ ca->sndlen = 0;
+ while (m) {
+ ca->sndlen += SCTP_BUF_LEN(m);
+ m = SCTP_BUF_NEXT(m);
}
ca->m = m;
}
@@ -5089,7 +5015,7 @@ out_gu:
memset(chk, sizeof(*chk), 0);
chk->rec.data.rcv_flags = rcv_flags;
SCTP_TCB_SEND_LOCK(stcb);
- if (sp->data->m_flags & M_EXT) {
+ if (SCTP_BUF_IS_EXTENDED(sp->data)) {
chk->copy_by_ref = 1;
} else {
chk->copy_by_ref = 0;
@@ -5116,9 +5042,9 @@ out_gu:
m_adj(sp->data, to_move);
/* Now lets work our way down and compact it */
m = sp->data;
- while (m && (m->m_len == 0)) {
- sp->data = m->m_next;
- m->m_next = NULL;
+ while (m && (SCTP_BUF_LEN(m) == 0)) {
+ sp->data = SCTP_BUF_NEXT(m);
+ SCTP_BUF_NEXT(m) = NULL;
if (sp->tail_mbuf == m) {
/* freeing tail */
sp->tail_mbuf = sp->data;
@@ -5133,19 +5059,14 @@ out_gu:
sp->length -= to_move;
}
- /* Update the new length in */
- if (sp->data && (sp->data->m_flags & M_PKTHDR)) {
- /* update length */
- sp->data->m_pkthdr.len = sp->length;
- }
if (M_LEADINGSPACE(chk->data) < sizeof(struct sctp_data_chunk)) {
/* Not enough room for a chunk header, get some */
struct mbuf *m;
- m = sctp_get_mbuf_for_msg(1, 1, M_DONTWAIT, 0, MT_DATA);
+ m = sctp_get_mbuf_for_msg(1, 0, M_DONTWAIT, 0, MT_DATA);
if (m == NULL) {
/*
- * we're in trouble here. M_PREPEND below will free
+ * we're in trouble here. _PREPEND below will free
* all the data if there is no leading space, so we
* must put the data back and restore.
*/
@@ -5159,25 +5080,21 @@ out_gu:
/* reassemble the data */
m = sp->data;
sp->data = chk->data;
- sp->data->m_next = m;
+ SCTP_BUF_NEXT(sp->data) = m;
}
sp->some_taken = some_taken;
sp->length += to_move;
- if (sp->data && (sp->data->m_flags & M_PKTHDR)) {
- sp->data->m_pkthdr.len = sp->length;
- }
sctp_free_a_chunk(stcb, chk);
SCTP_TCB_SEND_UNLOCK(stcb);
goto out_gu;
} else {
- m->m_len = 0;
- m->m_next = chk->data;
+ SCTP_BUF_LEN(m) = 0;
+ SCTP_BUF_NEXT(m) = chk->data;
chk->data = m;
- chk->data->m_pkthdr.len = to_move;
- MH_ALIGN(chk->data, 4);
+ M_ALIGN(chk->data, 4);
}
}
- M_PREPEND(chk->data, sizeof(struct sctp_data_chunk), M_DONTWAIT);
+ SCTP_BUF_PREPEND(chk->data, sizeof(struct sctp_data_chunk), M_DONTWAIT);
if (chk->data == NULL) {
/* HELP */
sctp_free_a_chunk(stcb, chk);
@@ -5195,8 +5112,8 @@ out_gu:
*/
if (chk->last_mbuf == NULL) {
chk->last_mbuf = chk->data;
- while (chk->last_mbuf->m_next != NULL) {
- chk->last_mbuf = chk->last_mbuf->m_next;
+ while (SCTP_BUF_NEXT(chk->last_mbuf) != NULL) {
+ chk->last_mbuf = SCTP_BUF_NEXT(chk->last_mbuf);
}
}
chk->flags = 0;
@@ -5247,13 +5164,10 @@ out_gu:
if (sctp_pad_lastmbuf(chk->data, pads, chk->last_mbuf) == 0) {
chk->pad_inplace = 1;
}
- if ((lm = chk->last_mbuf->m_next) != NULL) {
+ if ((lm = SCTP_BUF_NEXT(chk->last_mbuf)) != NULL) {
/* pad added an mbuf */
chk->last_mbuf = lm;
}
- if (chk->data->m_flags & M_PKTHDR) {
- chk->data->m_pkthdr.len += pads;
- }
chk->send_size += pads;
}
/* We only re-set the policy if it is on */
@@ -5695,15 +5609,6 @@ again_one_more_time:
if (chk->data == NULL) {
continue;
}
- if ((chk->data->m_flags & M_PKTHDR) == 0) {
- /*
- * NOTE: the chk queue MUST have the PKTHDR
- * flag set on it with a total in the
- * m_pkthdr.len field!! else the chunk will
- * ALWAYS be skipped
- */
- continue;
- }
if (chk->sent != SCTP_DATAGRAM_UNSENT) {
/*
* It must be unsent. Cookies and ASCONF's
@@ -5727,7 +5632,7 @@ again_one_more_time:
} else
omtu = 0;
/* Here we do NOT factor the r_mtu */
- if ((chk->data->m_pkthdr.len < (int)(mtu - omtu)) ||
+ if ((chk->send_size < (int)(mtu - omtu)) ||
(chk->flags & CHUNK_FLAGS_FRAGMENT_OK)) {
/*
* We probably should glom the mbuf chain
@@ -5756,18 +5661,18 @@ again_one_more_time:
}
outchain = sctp_copy_mbufchain(chk->data, outchain, &endoutchain,
(int)chk->rec.chunk_id.can_take_data,
- chk->data->m_pkthdr.len, chk->copy_by_ref);
+ chk->send_size, chk->copy_by_ref);
if (outchain == NULL) {
*reason_code = 8;
return (ENOMEM);
}
SCTP_STAT_INCR_COUNTER64(sctps_outcontrolchunks);
/* update our MTU size */
- if (mtu > (chk->data->m_pkthdr.len + omtu))
- mtu -= (chk->data->m_pkthdr.len + omtu);
+ if (mtu > (chk->send_size + omtu))
+ mtu -= (chk->send_size + omtu);
else
mtu = 0;
- to_out += (chk->data->m_pkthdr.len + omtu);
+ to_out += (chk->send_size + omtu);
/* Do clear IP_DF ? */
if (chk->flags & CHUNK_FLAGS_FRAGMENT_OK) {
no_fragmentflg = 0;
@@ -5791,7 +5696,7 @@ again_one_more_time:
/* remove these chunks at the end */
if (chk->rec.chunk_id.id == SCTP_SELECTIVE_ACK) {
/* turn off the timer */
- if (callout_pending(&stcb->asoc.dack_timer.timer)) {
+ if (SCTP_OS_TIMER_PENDING(&stcb->asoc.dack_timer.timer)) {
sctp_timer_stop(SCTP_TIMER_TYPE_RECV,
inp, stcb, net, SCTP_FROM_SCTP_OUTPUT + SCTP_LOC_1);
}
@@ -5834,7 +5739,7 @@ again_one_more_time:
sctp_timer_start(SCTP_TIMER_TYPE_COOKIE, inp, stcb, net);
cookie = 0;
}
- M_PREPEND(outchain, sizeof(struct sctphdr), M_DONTWAIT);
+ SCTP_BUF_PREPEND(outchain, sizeof(struct sctphdr), M_DONTWAIT);
if (outchain == NULL) {
/* no memory */
error = ENOBUFS;
@@ -6006,7 +5911,7 @@ again_one_more_time:
printf("No memory?\n");
}
#endif
- if (!callout_pending(&net->rxt_timer.timer)) {
+ if (!SCTP_OS_TIMER_PENDING(&net->rxt_timer.timer)) {
sctp_timer_start(SCTP_TIMER_TYPE_SEND, inp, stcb, net);
}
*reason_code = 3;
@@ -6076,7 +5981,7 @@ again_one_more_time:
cookie = 0;
}
/* must start a send timer if data is being sent */
- if (bundle_at && (!callout_pending(&net->rxt_timer.timer))) {
+ if (bundle_at && (!SCTP_OS_TIMER_PENDING(&net->rxt_timer.timer))) {
/*
* no timer running on this destination
* restart it.
@@ -6084,7 +5989,7 @@ again_one_more_time:
sctp_timer_start(SCTP_TIMER_TYPE_SEND, inp, stcb, net);
}
/* Now send it, if there is anything to send :> */
- M_PREPEND(outchain, sizeof(struct sctphdr), M_DONTWAIT);
+ SCTP_BUF_PREPEND(outchain, sizeof(struct sctphdr), M_DONTWAIT);
if (outchain == NULL) {
/* out of mbufs */
error = ENOBUFS;
@@ -6173,7 +6078,7 @@ again_one_more_time:
if (sctp_early_fr) {
if (net->flight_size < net->cwnd) {
/* start or restart it */
- if (callout_pending(&net->fr_timer.timer)) {
+ if (SCTP_OS_TIMER_PENDING(&net->fr_timer.timer)) {
sctp_timer_stop(SCTP_TIMER_TYPE_EARLYFR, inp, stcb, net,
SCTP_FROM_SCTP_OUTPUT + SCTP_LOC_2);
}
@@ -6181,7 +6086,7 @@ again_one_more_time:
sctp_timer_start(SCTP_TIMER_TYPE_EARLYFR, inp, stcb, net);
} else {
/* stop it if its running */
- if (callout_pending(&net->fr_timer.timer)) {
+ if (SCTP_OS_TIMER_PENDING(&net->fr_timer.timer)) {
SCTP_STAT_INCR(sctps_earlyfrstpout);
sctp_timer_stop(SCTP_TIMER_TYPE_EARLYFR, inp, stcb, net,
SCTP_FROM_SCTP_OUTPUT + SCTP_LOC_3);
@@ -6237,7 +6142,7 @@ sctp_queue_op_err(struct sctp_tcb *stcb, struct mbuf *op_err)
return;
}
chk->copy_by_ref = 0;
- M_PREPEND(op_err, sizeof(struct sctp_chunkhdr), M_DONTWAIT);
+ SCTP_BUF_PREPEND(op_err, sizeof(struct sctp_chunkhdr), M_DONTWAIT);
if (op_err == NULL) {
sctp_free_a_chunk(stcb, chk);
return;
@@ -6245,8 +6150,8 @@ sctp_queue_op_err(struct sctp_tcb *stcb, struct mbuf *op_err)
chk->send_size = 0;
mat = op_err;
while (mat != NULL) {
- chk->send_size += mat->m_len;
- mat = mat->m_next;
+ chk->send_size += SCTP_BUF_LEN(mat);
+ mat = SCTP_BUF_NEXT(mat);
}
chk->rec.chunk_id.id = SCTP_OPERATION_ERROR;
chk->rec.chunk_id.can_take_data = 1;
@@ -6278,7 +6183,7 @@ sctp_send_cookie_echo(struct mbuf *m,
* queue.
*/
int at;
- struct mbuf *cookie, *mat;
+ struct mbuf *cookie;
struct sctp_paramhdr parm, *phdr;
struct sctp_chunkhdr *hdr;
struct sctp_tmit_chunk *chk;
@@ -6322,20 +6227,6 @@ sctp_send_cookie_echo(struct mbuf *m,
hdr = mtod(cookie, struct sctp_chunkhdr *);
hdr->chunk_type = SCTP_COOKIE_ECHO;
hdr->chunk_flags = 0;
- /* now we MUST have a PKTHDR on it */
- if ((cookie->m_flags & M_PKTHDR) != M_PKTHDR) {
- /* we hope this happens rarely */
- mat = sctp_get_mbuf_for_msg(8, 1, M_DONTWAIT, 1, MT_HEADER);
- if (mat == NULL) {
- sctp_m_freem(cookie);
- return (-4);
- }
- mat->m_len = 0;
- mat->m_pkthdr.rcvif = 0;
- mat->m_next = cookie;
- cookie = mat;
- }
- cookie->m_pkthdr.len = plen;
/* get the chunk stuff now and place it in the FRONT of the queue */
sctp_alloc_a_chunk(stcb, chk);
if (chk == NULL) {
@@ -6344,7 +6235,7 @@ sctp_send_cookie_echo(struct mbuf *m,
return (-5);
}
chk->copy_by_ref = 0;
- chk->send_size = cookie->m_pkthdr.len;
+ chk->send_size = plen;
chk->rec.chunk_id.id = SCTP_COOKIE_ECHO;
chk->rec.chunk_id.can_take_data = 0;
chk->sent = SCTP_DATAGRAM_UNSENT;
@@ -6386,28 +6277,13 @@ sctp_send_heartbeat_ack(struct sctp_tcb *stcb,
chdr = mtod(outchain, struct sctp_chunkhdr *);
chdr->chunk_type = SCTP_HEARTBEAT_ACK;
chdr->chunk_flags = 0;
- if ((outchain->m_flags & M_PKTHDR) != M_PKTHDR) {
- /* should not happen but we are cautious. */
- struct mbuf *tmp;
-
- tmp = sctp_get_mbuf_for_msg(1, 1, M_DONTWAIT, 1, MT_HEADER);
- if (tmp == NULL) {
- return;
- }
- tmp->m_len = 0;
- tmp->m_pkthdr.rcvif = 0;
- tmp->m_next = outchain;
- outchain = tmp;
- }
- outchain->m_pkthdr.len = chk_length;
if (chk_length % 4) {
/* need pad */
uint32_t cpthis = 0;
int padlen;
- padlen = 4 - (outchain->m_pkthdr.len % 4);
- m_copyback(outchain, outchain->m_pkthdr.len, padlen,
- (caddr_t)&cpthis);
+ padlen = 4 - (chk_length % 4);
+ m_copyback(outchain, chk_length, padlen, (caddr_t)&cpthis);
}
sctp_alloc_a_chunk(stcb, chk);
if (chk == NULL) {
@@ -6441,12 +6317,12 @@ sctp_send_cookie_ack(struct sctp_tcb *stcb)
cookie_ack = NULL;
SCTP_TCB_LOCK_ASSERT(stcb);
- cookie_ack = sctp_get_mbuf_for_msg(sizeof(struct sctp_chunkhdr), 1, M_DONTWAIT, 1, MT_HEADER);
+ cookie_ack = sctp_get_mbuf_for_msg(sizeof(struct sctp_chunkhdr), 0, M_DONTWAIT, 1, MT_HEADER);
if (cookie_ack == NULL) {
/* no mbuf's */
return (-1);
}
- cookie_ack->m_data += SCTP_MIN_OVERHEAD;
+ SCTP_BUF_RESV_UF(cookie_ack, SCTP_MIN_OVERHEAD);
sctp_alloc_a_chunk(stcb, chk);
if (chk == NULL) {
/* no memory */
@@ -6472,8 +6348,7 @@ sctp_send_cookie_ack(struct sctp_tcb *stcb)
hdr->chunk_type = SCTP_COOKIE_ACK;
hdr->chunk_flags = 0;
hdr->chunk_length = htons(chk->send_size);
- cookie_ack->m_pkthdr.len = cookie_ack->m_len = chk->send_size;
- cookie_ack->m_pkthdr.rcvif = 0;
+ SCTP_BUF_LEN(cookie_ack) = chk->send_size;
TAILQ_INSERT_TAIL(&chk->asoc->control_send_queue, chk, sctp_next);
chk->asoc->ctrl_queue_cnt++;
return (0);
@@ -6488,12 +6363,12 @@ sctp_send_shutdown_ack(struct sctp_tcb *stcb, struct sctp_nets *net)
struct sctp_shutdown_ack_chunk *ack_cp;
struct sctp_tmit_chunk *chk;
- m_shutdown_ack = sctp_get_mbuf_for_msg(sizeof(struct sctp_shutdown_ack_chunk), 1, M_DONTWAIT, 1, MT_HEADER);
+ m_shutdown_ack = sctp_get_mbuf_for_msg(sizeof(struct sctp_shutdown_ack_chunk), 0, M_DONTWAIT, 1, MT_HEADER);
if (m_shutdown_ack == NULL) {
/* no mbuf's */
return (-1);
}
- m_shutdown_ack->m_data += SCTP_MIN_OVERHEAD;
+ SCTP_BUF_RESV_UF(m_shutdown_ack, SCTP_MIN_OVERHEAD);
sctp_alloc_a_chunk(stcb, chk);
if (chk == NULL) {
/* no memory */
@@ -6517,8 +6392,7 @@ sctp_send_shutdown_ack(struct sctp_tcb *stcb, struct sctp_nets *net)
ack_cp->ch.chunk_type = SCTP_SHUTDOWN_ACK;
ack_cp->ch.chunk_flags = 0;
ack_cp->ch.chunk_length = htons(chk->send_size);
- m_shutdown_ack->m_pkthdr.len = m_shutdown_ack->m_len = chk->send_size;
- m_shutdown_ack->m_pkthdr.rcvif = 0;
+ SCTP_BUF_LEN(m_shutdown_ack) = chk->send_size;
TAILQ_INSERT_TAIL(&chk->asoc->control_send_queue, chk, sctp_next);
chk->asoc->ctrl_queue_cnt++;
return (0);
@@ -6532,12 +6406,12 @@ sctp_send_shutdown(struct sctp_tcb *stcb, struct sctp_nets *net)
struct sctp_shutdown_chunk *shutdown_cp;
struct sctp_tmit_chunk *chk;
- m_shutdown = sctp_get_mbuf_for_msg(sizeof(struct sctp_shutdown_chunk), 1, M_DONTWAIT, 1, MT_HEADER);
+ m_shutdown = sctp_get_mbuf_for_msg(sizeof(struct sctp_shutdown_chunk), 0, M_DONTWAIT, 1, MT_HEADER);
if (m_shutdown == NULL) {
/* no mbuf's */
return (-1);
}
- m_shutdown->m_data += SCTP_MIN_OVERHEAD;
+ SCTP_BUF_RESV_UF(m_shutdown, SCTP_MIN_OVERHEAD);
sctp_alloc_a_chunk(stcb, chk);
if (chk == NULL) {
/* no memory */
@@ -6561,8 +6435,7 @@ sctp_send_shutdown(struct sctp_tcb *stcb, struct sctp_nets *net)
shutdown_cp->ch.chunk_flags = 0;
shutdown_cp->ch.chunk_length = htons(chk->send_size);
shutdown_cp->cumulative_tsn_ack = htonl(stcb->asoc.cumulative_tsn);
- m_shutdown->m_pkthdr.len = m_shutdown->m_len = chk->send_size;
- m_shutdown->m_pkthdr.rcvif = 0;
+ SCTP_BUF_LEN(m_shutdown) = chk->send_size;
TAILQ_INSERT_TAIL(&chk->asoc->control_send_queue, chk, sctp_next);
chk->asoc->ctrl_queue_cnt++;
return (0);
@@ -6578,11 +6451,12 @@ sctp_send_asconf(struct sctp_tcb *stcb, struct sctp_nets *net)
struct sctp_tmit_chunk *chk;
struct mbuf *m_asconf;
struct sctp_asconf_chunk *acp;
+ int len;
SCTP_TCB_LOCK_ASSERT(stcb);
/* compose an ASCONF chunk, maximum length is PMTU */
- m_asconf = sctp_compose_asconf(stcb);
+ m_asconf = sctp_compose_asconf(stcb, &len);
if (m_asconf == NULL) {
return (-1);
}
@@ -6595,7 +6469,7 @@ sctp_send_asconf(struct sctp_tcb *stcb, struct sctp_nets *net)
}
chk->copy_by_ref = 0;
chk->data = m_asconf;
- chk->send_size = m_asconf->m_pkthdr.len;
+ chk->send_size = len;
chk->rec.chunk_id.id = SCTP_ASCONF;
chk->rec.chunk_id.can_take_data = 0;
chk->sent = SCTP_DATAGRAM_UNSENT;
@@ -6617,7 +6491,7 @@ sctp_send_asconf_ack(struct sctp_tcb *stcb, uint32_t retrans)
* must be stored in the tcb
*/
struct sctp_tmit_chunk *chk;
- struct mbuf *m_ack;
+ struct mbuf *m_ack, *m;
SCTP_TCB_LOCK_ASSERT(stcb);
/* is there a asconf-ack mbuf chain to send? */
@@ -6625,14 +6499,8 @@ sctp_send_asconf_ack(struct sctp_tcb *stcb, uint32_t retrans)
return (-1);
}
/* copy the asconf_ack */
- /*
- * Supposedly the m_copypacket is a optimzation, use it if we can.
- */
- if (stcb->asoc.last_asconf_ack_sent->m_flags & M_PKTHDR) {
- m_ack = m_copypacket(stcb->asoc.last_asconf_ack_sent, M_DONTWAIT);
- } else
- m_ack = m_copy(stcb->asoc.last_asconf_ack_sent, 0, M_COPYALL);
-
+ /* We no longer have pak headers here so m_copy is it */
+ m_ack = m_copy(stcb->asoc.last_asconf_ack_sent, 0, M_COPYALL);
if (m_ack == NULL) {
/* couldn't copy it */
@@ -6674,7 +6542,13 @@ sctp_send_asconf_ack(struct sctp_tcb *stcb, uint32_t retrans)
stcb->asoc.used_alt_asconfack = 0;
}
chk->data = m_ack;
- chk->send_size = m_ack->m_pkthdr.len;
+ chk->send_size = 0;
+ /* Get size */
+ m = m_ack;
+ while (m) {
+ chk->send_size += SCTP_BUF_LEN(m);
+ m = SCTP_BUF_NEXT(m);
+ }
chk->rec.chunk_id.id = SCTP_ASCONF_ACK;
chk->rec.chunk_id.can_take_data = 1;
chk->sent = SCTP_DATAGRAM_UNSENT;
@@ -6790,7 +6664,7 @@ sctp_chunk_retransmission(struct sctp_inpcb *inp,
} else if (chk->rec.chunk_id.id == SCTP_ASCONF)
sctp_timer_start(SCTP_TIMER_TYPE_ASCONF, inp, stcb, chk->whoTo);
- M_PREPEND(m, sizeof(struct sctphdr), M_DONTWAIT);
+ SCTP_BUF_PREPEND(m, sizeof(struct sctphdr), M_DONTWAIT);
if (m == NULL) {
return (ENOBUFS);
}
@@ -7003,7 +6877,7 @@ one_chunk_around:
* No matter if we fail/or suceed we should start a
* timer. A failure is like a lost IP packet :-)
*/
- if (!callout_pending(&net->rxt_timer.timer)) {
+ if (!SCTP_OS_TIMER_PENDING(&net->rxt_timer.timer)) {
/*
* no timer running on this destination
* restart it.
@@ -7011,7 +6885,7 @@ one_chunk_around:
sctp_timer_start(SCTP_TIMER_TYPE_SEND, inp, stcb, net);
tmr_started = 1;
}
- M_PREPEND(m, sizeof(struct sctphdr), M_DONTWAIT);
+ SCTP_BUF_PREPEND(m, sizeof(struct sctphdr), M_DONTWAIT);
if (m == NULL) {
return (ENOBUFS);
}
@@ -7159,7 +7033,7 @@ sctp_timer_validation(struct sctp_inpcb *inp,
/* Validate that a timer is running somewhere */
TAILQ_FOREACH(net, &asoc->nets, sctp_next) {
- if (callout_pending(&net->rxt_timer.timer)) {
+ if (SCTP_OS_TIMER_PENDING(&net->rxt_timer.timer)) {
/* Here is a timer */
return (ret);
}
@@ -7223,9 +7097,9 @@ 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 (callout_pending(&stcb->asoc.dack_timer.timer)) {
+ if (SCTP_OS_TIMER_PENDING(&stcb->asoc.dack_timer.timer)) {
sctp_send_sack(stcb);
- callout_stop(&stcb->asoc.dack_timer.timer);
+ SCTP_OS_TIMER_STOP(&stcb->asoc.dack_timer.timer);
}
while (asoc->sent_queue_retran_cnt) {
/*
@@ -7491,13 +7365,13 @@ send_forward_tsn(struct sctp_tcb *stcb,
chk->rec.chunk_id.id = SCTP_FORWARD_CUM_TSN;
chk->rec.chunk_id.can_take_data = 0;
chk->asoc = asoc;
- chk->data = sctp_get_mbuf_for_msg(MCLBYTES, 1, M_DONTWAIT, 1, MT_DATA);
+ chk->data = sctp_get_mbuf_for_msg(MCLBYTES, 0, M_DONTWAIT, 1, MT_DATA);
if (chk->data == NULL) {
atomic_subtract_int(&chk->whoTo->ref_count, 1);
sctp_free_a_chunk(stcb, chk);
return;
}
- chk->data->m_data += SCTP_MIN_OVERHEAD;
+ SCTP_BUF_RESV_UF(chk->data, SCTP_MIN_OVERHEAD);
chk->sent = SCTP_DATAGRAM_UNSENT;
chk->snd_count = 0;
chk->whoTo = asoc->primary_destination;
@@ -7509,7 +7383,7 @@ sctp_fill_in_rest:
* Here we go through and fill out the part that deals with
* stream/seq of the ones we skip.
*/
- chk->data->m_pkthdr.len = chk->data->m_len = 0;
+ SCTP_BUF_LEN(chk->data) = 0;
{
struct sctp_tmit_chunk *at, *tp1, *last;
struct sctp_strseq *strseq;
@@ -7576,7 +7450,7 @@ sctp_fill_in_rest:
fwdtsn->new_cumulative_tsn = htonl(asoc->advanced_peer_ack_point);
chk->send_size = (sizeof(struct sctp_forward_tsn_chunk) +
(cnt_of_skipped * sizeof(struct sctp_strseq)));
- chk->data->m_pkthdr.len = chk->data->m_len = chk->send_size;
+ SCTP_BUF_LEN(chk->data) = chk->send_size;
fwdtsn++;
/*
* Move pointer to after the fwdtsn and transfer to the
@@ -7722,7 +7596,7 @@ sctp_send_sack(struct sctp_tcb *stcb)
space_req = MCLBYTES;
}
/* Ok now lets formulate a MBUF with our sack */
- a_chk->data = sctp_get_mbuf_for_msg(space_req, 1, M_DONTWAIT, 1, MT_DATA);
+ a_chk->data = sctp_get_mbuf_for_msg(space_req, 0, M_DONTWAIT, 1, MT_DATA);
if ((a_chk->data == NULL) ||
(a_chk->whoTo == NULL)) {
/* rats, no mbuf memory */
@@ -7741,7 +7615,7 @@ sctp_send_sack(struct sctp_tcb *stcb)
return;
}
/* ok, lets go through and fill it in */
- a_chk->data->m_data += SCTP_MIN_OVERHEAD;
+ SCTP_BUF_RESV_UF(a_chk->data, SCTP_MIN_OVERHEAD);
space = M_TRAILINGSPACE(a_chk->data);
if (space > (a_chk->whoTo->mtu - SCTP_MIN_OVERHEAD)) {
space = (a_chk->whoTo->mtu - SCTP_MIN_OVERHEAD);
@@ -7860,7 +7734,7 @@ sctp_send_sack(struct sctp_tcb *stcb)
a_chk->send_size = (sizeof(struct sctp_sack_chunk) +
(num_gap_blocks * sizeof(struct sctp_gap_ack_block)) +
(num_dups * sizeof(int32_t)));
- a_chk->data->m_pkthdr.len = a_chk->data->m_len = a_chk->send_size;
+ SCTP_BUF_LEN(a_chk->data) = a_chk->send_size;
sack->sack.num_gap_ack_blks = htons(num_gap_blocks);
sack->sack.num_dup_tsns = htons(num_dups);
sack->ch.chunk_length = htons(a_chk->send_size);
@@ -7892,7 +7766,7 @@ sctp_send_abort_tcb(struct sctp_tcb *stcb, struct mbuf *operr)
stcb, SCTP_ABORT_ASSOCIATION);
}
SCTP_TCB_LOCK_ASSERT(stcb);
- m_abort = sctp_get_mbuf_for_msg(sizeof(struct sctp_abort_chunk), 1, M_DONTWAIT, 1, MT_HEADER);
+ m_abort = sctp_get_mbuf_for_msg(sizeof(struct sctp_abort_chunk), 0, M_DONTWAIT, 1, MT_HEADER);
if (m_abort == NULL) {
/* no mbuf's */
if (m_out)
@@ -7900,28 +7774,25 @@ sctp_send_abort_tcb(struct sctp_tcb *stcb, struct mbuf *operr)
return;
}
/* link in any error */
- m_abort->m_next = operr;
+ SCTP_BUF_NEXT(m_abort) = operr;
sz = 0;
if (operr) {
struct mbuf *n;
n = operr;
while (n) {
- sz += n->m_len;
- n = n->m_next;
+ sz += SCTP_BUF_LEN(n);
+ n = SCTP_BUF_NEXT(n);
}
}
- m_abort->m_len = sizeof(*abort);
- m_abort->m_pkthdr.len = m_abort->m_len + sz;
- m_abort->m_pkthdr.rcvif = 0;
+ SCTP_BUF_LEN(m_abort) = sizeof(*abort);
if (m_out == NULL) {
/* NO Auth chunk prepended, so reserve space in front */
- m_abort->m_data += SCTP_MIN_OVERHEAD;
+ SCTP_BUF_RESV_UF(m_abort, SCTP_MIN_OVERHEAD);
m_out = m_abort;
} else {
/* Put AUTH chunk at the front of the chain */
- m_out->m_pkthdr.len += m_abort->m_pkthdr.len;
- m_end->m_next = m_abort;
+ SCTP_BUF_NEXT(m_end) = m_abort;
}
/* fill in the ABORT chunk */
@@ -7931,7 +7802,7 @@ sctp_send_abort_tcb(struct sctp_tcb *stcb, struct mbuf *operr)
abort->ch.chunk_length = htons(sizeof(*abort) + sz);
/* prepend and fill in the SCTP header */
- M_PREPEND(m_out, sizeof(struct sctphdr), M_DONTWAIT);
+ SCTP_BUF_PREPEND(m_out, sizeof(struct sctphdr), M_DONTWAIT);
if (m_out == NULL) {
/* TSNH: no memory */
return;
@@ -7958,12 +7829,11 @@ sctp_send_shutdown_complete(struct sctp_tcb *stcb,
struct mbuf *m_shutdown_comp;
struct sctp_shutdown_complete_msg *comp_cp;
- m_shutdown_comp = sctp_get_mbuf_for_msg(sizeof(struct sctp_shutdown_complete_msg), 1, M_DONTWAIT, 1, MT_HEADER);
+ m_shutdown_comp = sctp_get_mbuf_for_msg(sizeof(struct sctp_shutdown_complete_msg), 0, M_DONTWAIT, 1, MT_HEADER);
if (m_shutdown_comp == NULL) {
/* no mbuf's */
return (-1);
}
- m_shutdown_comp->m_data += sizeof(struct ip6_hdr);
comp_cp = mtod(m_shutdown_comp, struct sctp_shutdown_complete_msg *);
comp_cp->shut_cmp.ch.chunk_type = SCTP_SHUTDOWN_COMPLETE;
comp_cp->shut_cmp.ch.chunk_flags = 0;
@@ -7973,8 +7843,7 @@ sctp_send_shutdown_complete(struct sctp_tcb *stcb,
comp_cp->sh.v_tag = htonl(stcb->asoc.peer_vtag);
comp_cp->sh.checksum = 0;
- m_shutdown_comp->m_pkthdr.len = m_shutdown_comp->m_len = sizeof(struct sctp_shutdown_complete_msg);
- m_shutdown_comp->m_pkthdr.rcvif = 0;
+ SCTP_BUF_LEN(m_shutdown_comp) = sizeof(struct sctp_shutdown_complete_msg);
sctp_lowlevel_chunk_output(stcb->sctp_ep, stcb, net,
(struct sockaddr *)&net->ro._l_addr,
m_shutdown_comp, 0, NULL, 1, 0, NULL, 0);
@@ -7986,25 +7855,30 @@ int
sctp_send_shutdown_complete2(struct mbuf *m, int iphlen, struct sctphdr *sh)
{
/* formulate and SEND a SHUTDOWN-COMPLETE */
+ struct mbuf *o_pak;
struct mbuf *mout;
struct ip *iph, *iph_out;
struct ip6_hdr *ip6, *ip6_out;
- int offset_out;
+ int offset_out, len;
struct sctp_shutdown_complete_msg *comp_cp;
- mout = sctp_get_mbuf_for_msg(sizeof(struct sctp_shutdown_complete_msg), 1, M_DONTWAIT, 1, MT_HEADER);
- if (mout == NULL) {
+ /* Get room for the largest message */
+ len = (sizeof(struct ip6_hdr) + sizeof(struct sctp_shutdown_complete_msg));
+
+ o_pak = SCTP_GET_HEADER_FOR_OUTPUT(len);
+ if (o_pak == NULL) {
/* no mbuf's */
return (-1);
}
+ mout = SCTP_HEADER_TO_CHAIN(o_pak);
iph = mtod(m, struct ip *);
iph_out = NULL;
ip6_out = NULL;
offset_out = 0;
if (iph->ip_v == IPVERSION) {
- mout->m_len = sizeof(struct ip) +
+ SCTP_BUF_LEN(mout) = sizeof(struct ip) +
sizeof(struct sctp_shutdown_complete_msg);
- mout->m_next = NULL;
+ SCTP_BUF_NEXT(mout) = NULL;
iph_out = mtod(mout, struct ip *);
/* Fill in the IP header for the ABORT */
@@ -8025,9 +7899,9 @@ sctp_send_shutdown_complete2(struct mbuf *m, int iphlen, struct sctphdr *sh)
(caddr_t)iph_out + offset_out);
} else if (iph->ip_v == (IPV6_VERSION >> 4)) {
ip6 = (struct ip6_hdr *)iph;
- mout->m_len = sizeof(struct ip6_hdr) +
+ SCTP_BUF_LEN(mout) = sizeof(struct ip6_hdr) +
sizeof(struct sctp_shutdown_complete_msg);
- mout->m_next = NULL;
+ SCTP_BUF_NEXT(mout) = NULL;
ip6_out = mtod(mout, struct ip6_hdr *);
/* Fill in the IPv6 header for the ABORT */
@@ -8036,7 +7910,11 @@ sctp_send_shutdown_complete2(struct mbuf *m, int iphlen, struct sctphdr *sh)
ip6_out->ip6_nxt = IPPROTO_SCTP;
ip6_out->ip6_src = ip6->ip6_dst;
ip6_out->ip6_dst = ip6->ip6_src;
- ip6_out->ip6_plen = mout->m_len;
+ /*
+ * ?? The old code had both the iph len + payload, I think
+ * this is wrong and would never have worked
+ */
+ ip6_out->ip6_plen = sizeof(struct sctp_shutdown_complete_msg);
offset_out += sizeof(*ip6_out);
comp_cp = (struct sctp_shutdown_complete_msg *)(
(caddr_t)ip6_out + offset_out);
@@ -8045,6 +7923,7 @@ sctp_send_shutdown_complete2(struct mbuf *m, int iphlen, struct sctphdr *sh)
return (-1);
}
+ SCTP_HEADER_LEN(o_pak) = SCTP_BUF_LEN(mout);
/* Now copy in and fill in the ABORT tags etc. */
comp_cp->sh.src_port = sh->dest_port;
comp_cp->sh.dest_port = sh->src_port;
@@ -8054,27 +7933,20 @@ sctp_send_shutdown_complete2(struct mbuf *m, int iphlen, struct sctphdr *sh)
comp_cp->shut_cmp.ch.chunk_type = SCTP_SHUTDOWN_COMPLETE;
comp_cp->shut_cmp.ch.chunk_length = htons(sizeof(struct sctp_shutdown_complete_chunk));
- mout->m_pkthdr.len = mout->m_len;
/* add checksum */
- if ((sctp_no_csum_on_loopback) &&
- (m->m_pkthdr.rcvif) &&
- (m->m_pkthdr.rcvif->if_type == IFT_LOOP)) {
+ if ((sctp_no_csum_on_loopback) && SCTP_IS_IT_LOOPBACK(o_pak)) {
comp_cp->sh.checksum = 0;
} else {
comp_cp->sh.checksum = sctp_calculate_sum(mout, NULL, offset_out);
}
-
- /* zap the rcvif, it should be null */
- mout->m_pkthdr.rcvif = 0;
- /* zap the stack pointer to the route */
if (iph_out != NULL) {
struct route ro;
bzero(&ro, sizeof ro);
/* set IPv4 length */
- iph_out->ip_len = mout->m_pkthdr.len;
+ iph_out->ip_len = SCTP_HEADER_LEN(o_pak);
/* out it goes */
- ip_output(mout, 0, &ro, IP_RAWOUTPUT, NULL
+ ip_output(o_pak, 0, &ro, IP_RAWOUTPUT, NULL
,NULL
);
/* Free the route if we got one back */
@@ -8085,7 +7957,7 @@ sctp_send_shutdown_complete2(struct mbuf *m, int iphlen, struct sctphdr *sh)
bzero(&ro, sizeof(ro));
- ip6_output(mout, NULL, &ro, 0, NULL, NULL
+ ip6_output(o_pak, NULL, &ro, 0, NULL, NULL
,NULL
);
/* Free the route if we got one back */
@@ -8233,13 +8105,13 @@ sctp_send_hb(struct sctp_tcb *stcb, int user_req, struct sctp_nets *u_net)
chk->asoc = &stcb->asoc;
chk->send_size = sizeof(struct sctp_heartbeat_chunk);
- chk->data = sctp_get_mbuf_for_msg(chk->send_size, 1, M_DONTWAIT, 1, MT_HEADER);
+ chk->data = sctp_get_mbuf_for_msg(chk->send_size, 0, M_DONTWAIT, 1, MT_HEADER);
if (chk->data == NULL) {
sctp_free_a_chunk(stcb, chk);
return (0);
}
- chk->data->m_data += SCTP_MIN_OVERHEAD;
- chk->data->m_pkthdr.len = chk->data->m_len = chk->send_size;
+ SCTP_BUF_RESV_UF(chk->data, SCTP_MIN_OVERHEAD);
+ SCTP_BUF_LEN(chk->data) = chk->send_size;
chk->sent = SCTP_DATAGRAM_UNSENT;
chk->snd_count = 0;
chk->whoTo = net;
@@ -8342,13 +8214,13 @@ sctp_send_ecn_echo(struct sctp_tcb *stcb, struct sctp_nets *net,
chk->rec.chunk_id.can_take_data = 0;
chk->asoc = &stcb->asoc;
chk->send_size = sizeof(struct sctp_ecne_chunk);
- chk->data = sctp_get_mbuf_for_msg(chk->send_size, 1, M_DONTWAIT, 1, MT_HEADER);
+ chk->data = sctp_get_mbuf_for_msg(chk->send_size, 0, M_DONTWAIT, 1, MT_HEADER);
if (chk->data == NULL) {
sctp_free_a_chunk(stcb, chk);
return;
}
- chk->data->m_data += SCTP_MIN_OVERHEAD;
- chk->data->m_pkthdr.len = chk->data->m_len = chk->send_size;
+ SCTP_BUF_RESV_UF(chk->data, SCTP_MIN_OVERHEAD);
+ SCTP_BUF_LEN(chk->data) = chk->send_size;
chk->sent = SCTP_DATAGRAM_UNSENT;
chk->snd_count = 0;
chk->whoTo = net;
@@ -8407,18 +8279,14 @@ sctp_send_packet_dropped(struct sctp_tcb *stcb, struct sctp_nets *net,
ip6h = mtod(m, struct ip6_hdr *);
len = chk->send_size = htons(ip6h->ip6_plen);
}
- if ((len + iphlen) > m->m_pkthdr.len) {
- /* huh */
- chk->send_size = len = m->m_pkthdr.len - iphlen;
- }
chk->asoc = &stcb->asoc;
- chk->data = sctp_get_mbuf_for_msg(MCLBYTES, 1, M_DONTWAIT, 1, MT_DATA);
+ chk->data = sctp_get_mbuf_for_msg(MCLBYTES, 0, M_DONTWAIT, 1, MT_DATA);
if (chk->data == NULL) {
jump_out:
sctp_free_a_chunk(stcb, chk);
return;
}
- chk->data->m_data += SCTP_MIN_OVERHEAD;
+ SCTP_BUF_RESV_UF(chk->data, SCTP_MIN_OVERHEAD);
drp = mtod(chk->data, struct sctp_pktdrop_chunk *);
if (drp == NULL) {
sctp_m_freem(chk->data);
@@ -8448,7 +8316,7 @@ jump_out:
drp->ch.chunk_flags |= SCTP_BADCRC;
}
chk->send_size += sizeof(struct sctp_pktdrop_chunk);
- chk->data->m_pkthdr.len = chk->data->m_len = chk->send_size;
+ SCTP_BUF_LEN(chk->data) = chk->send_size;
chk->sent = SCTP_DATAGRAM_UNSENT;
chk->snd_count = 0;
if (net) {
@@ -8516,13 +8384,13 @@ sctp_send_cwr(struct sctp_tcb *stcb, struct sctp_nets *net, uint32_t high_tsn)
chk->rec.chunk_id.can_take_data = 1;
chk->asoc = &stcb->asoc;
chk->send_size = sizeof(struct sctp_cwr_chunk);
- chk->data = sctp_get_mbuf_for_msg(chk->send_size, 1, M_DONTWAIT, 1, MT_HEADER);
+ chk->data = sctp_get_mbuf_for_msg(chk->send_size, 0, M_DONTWAIT, 1, MT_HEADER);
if (chk->data == NULL) {
sctp_free_a_chunk(stcb, chk);
return;
}
- chk->data->m_data += SCTP_MIN_OVERHEAD;
- chk->data->m_pkthdr.len = chk->data->m_len = chk->send_size;
+ SCTP_BUF_RESV_UF(chk->data, SCTP_MIN_OVERHEAD);
+ SCTP_BUF_LEN(chk->data) = chk->send_size;
chk->sent = SCTP_DATAGRAM_UNSENT;
chk->snd_count = 0;
chk->whoTo = net;
@@ -8574,9 +8442,9 @@ sctp_add_stream_reset_out(struct sctp_tmit_chunk *chk,
}
/* now fix the chunk length */
ch->chunk_length = htons(len + old_len);
- chk->send_size = len + old_len;
- chk->book_size = SCTP_SIZE32(chk->send_size);
- chk->data->m_pkthdr.len = chk->data->m_len = SCTP_SIZE32(chk->send_size);
+ chk->book_size = len + old_len;
+ chk->send_size = SCTP_SIZE32(chk->book_size);
+ SCTP_BUF_LEN(chk->data) = chk->send_size;
return;
}
@@ -8617,9 +8485,9 @@ sctp_add_stream_reset_in(struct sctp_tmit_chunk *chk,
}
/* now fix the chunk length */
ch->chunk_length = htons(len + old_len);
- chk->send_size = len + old_len;
- chk->book_size = SCTP_SIZE32(chk->send_size);
- chk->data->m_pkthdr.len = chk->data->m_len = SCTP_SIZE32(chk->send_size);
+ chk->book_size = len + old_len;
+ chk->send_size = SCTP_SIZE32(chk->book_size);
+ SCTP_BUF_LEN(chk->data) = chk->send_size;
return;
}
@@ -8649,7 +8517,7 @@ sctp_add_stream_reset_tsn(struct sctp_tmit_chunk *chk,
ch->chunk_length = htons(len + old_len);
chk->send_size = len + old_len;
chk->book_size = SCTP_SIZE32(chk->send_size);
- chk->data->m_pkthdr.len = chk->data->m_len = SCTP_SIZE32(chk->send_size);
+ SCTP_BUF_LEN(chk->data) = SCTP_SIZE32(chk->send_size);
return;
}
@@ -8677,9 +8545,9 @@ sctp_add_stream_reset_result(struct sctp_tmit_chunk *chk,
/* now fix the chunk length */
ch->chunk_length = htons(len + old_len);
- chk->send_size = len + old_len;
- chk->book_size = SCTP_SIZE32(chk->send_size);
- chk->data->m_pkthdr.len = chk->data->m_len = SCTP_SIZE32(chk->send_size);
+ chk->book_size = len + old_len;
+ chk->send_size = SCTP_SIZE32(chk->book_size);
+ SCTP_BUF_LEN(chk->data) = chk->send_size;
return;
}
@@ -8712,9 +8580,9 @@ sctp_add_stream_reset_result_tsn(struct sctp_tmit_chunk *chk,
/* now fix the chunk length */
ch->chunk_length = htons(len + old_len);
- chk->send_size = len + old_len;
- chk->book_size = SCTP_SIZE32(chk->send_size);
- chk->data->m_pkthdr.len = chk->data->m_len = SCTP_SIZE32(chk->send_size);
+ chk->book_size = len + old_len;
+ chk->send_size = SCTP_SIZE32(chk->book_size);
+ SCTP_BUF_LEN(chk->data) = chk->send_size;
return;
}
@@ -8755,14 +8623,15 @@ sctp_send_str_reset_req(struct sctp_tcb *stcb,
chk->rec.chunk_id.id = SCTP_STREAM_RESET;
chk->rec.chunk_id.can_take_data = 0;
chk->asoc = &stcb->asoc;
- chk->book_size = SCTP_SIZE32(chk->send_size = sizeof(struct sctp_chunkhdr));
+ chk->book_size = sizeof(struct sctp_chunkhdr);
+ chk->send_size = SCTP_SIZE32(chk->book_size);
- chk->data = sctp_get_mbuf_for_msg(MCLBYTES, 1, M_DONTWAIT, 1, MT_DATA);
+ chk->data = sctp_get_mbuf_for_msg(MCLBYTES, 0, M_DONTWAIT, 1, MT_DATA);
if (chk->data == NULL) {
sctp_free_a_chunk(stcb, chk);
return (ENOMEM);
}
- chk->data->m_data += SCTP_MIN_OVERHEAD;
+ SCTP_BUF_RESV_UF(chk->data, SCTP_MIN_OVERHEAD);
/* setup chunk parameters */
chk->sent = SCTP_DATAGRAM_UNSENT;
@@ -8773,8 +8642,8 @@ sctp_send_str_reset_req(struct sctp_tcb *stcb,
ch = mtod(chk->data, struct sctp_chunkhdr *);
ch->chunk_type = SCTP_STREAM_RESET;
ch->chunk_flags = 0;
- ch->chunk_length = htons(chk->send_size);
- chk->data->m_pkthdr.len = chk->data->m_len = SCTP_SIZE32(chk->send_size);
+ ch->chunk_length = htons(chk->book_size);
+ SCTP_BUF_LEN(chk->data) = chk->send_size;
seq = stcb->asoc.str_reset_seq_out;
if (send_out_req) {
@@ -8810,6 +8679,7 @@ sctp_send_abort(struct mbuf *m, int iphlen, struct sctphdr *sh, uint32_t vtag,
/*
* Formulate the abort message, and send it back down.
*/
+ struct mbuf *o_pak;
struct mbuf *mout;
struct sctp_abort_msg *abm;
struct ip *iph, *iph_out;
@@ -8822,20 +8692,20 @@ sctp_send_abort(struct mbuf *m, int iphlen, struct sctphdr *sh, uint32_t vtag,
sctp_m_freem(err_cause);
return;
}
- mout = sctp_get_mbuf_for_msg((sizeof(struct ip6_hdr) + sizeof(struct sctp_abort_msg)),
- 1, M_DONTWAIT, 1, MT_HEADER);
- if (mout == NULL) {
+ o_pak = SCTP_GET_HEADER_FOR_OUTPUT((sizeof(struct ip6_hdr) + sizeof(struct sctp_abort_msg)));
+ if (o_pak == NULL) {
if (err_cause)
sctp_m_freem(err_cause);
return;
}
+ mout = SCTP_HEADER_TO_CHAIN(o_pak);
iph = mtod(m, struct ip *);
iph_out = NULL;
ip6_out = NULL;
if (iph->ip_v == IPVERSION) {
iph_out = mtod(mout, struct ip *);
- mout->m_len = sizeof(*iph_out) + sizeof(*abm);
- mout->m_next = err_cause;
+ SCTP_BUF_LEN(mout) = sizeof(*iph_out) + sizeof(*abm);
+ SCTP_BUF_NEXT(mout) = err_cause;
/* Fill in the IP header for the ABORT */
iph_out->ip_v = IPVERSION;
@@ -8855,8 +8725,8 @@ sctp_send_abort(struct mbuf *m, int iphlen, struct sctphdr *sh, uint32_t vtag,
} else if (iph->ip_v == (IPV6_VERSION >> 4)) {
ip6 = (struct ip6_hdr *)iph;
ip6_out = mtod(mout, struct ip6_hdr *);
- mout->m_len = sizeof(*ip6_out) + sizeof(*abm);
- mout->m_next = err_cause;
+ SCTP_BUF_LEN(mout) = sizeof(*ip6_out) + sizeof(*abm);
+ SCTP_BUF_NEXT(mout) = err_cause;
/* Fill in the IP6 header for the ABORT */
ip6_out->ip6_flow = ip6->ip6_flow;
@@ -8890,35 +8760,31 @@ sctp_send_abort(struct mbuf *m, int iphlen, struct sctphdr *sh, uint32_t vtag,
/* get length of the err_cause chain */
while (m_tmp != NULL) {
- err_len += m_tmp->m_len;
- m_tmp = m_tmp->m_next;
+ err_len += SCTP_BUF_LEN(m_tmp);
+ m_tmp = SCTP_BUF_NEXT(m_tmp);
}
- mout->m_pkthdr.len = mout->m_len + err_len;
+ SCTP_HEADER_LEN(o_pak) = SCTP_BUF_LEN(mout) + err_len;
if (err_len % 4) {
/* need pad at end of chunk */
uint32_t cpthis = 0;
int padlen;
- padlen = 4 - (mout->m_pkthdr.len % 4);
- m_copyback(mout, mout->m_pkthdr.len, padlen, (caddr_t)&cpthis);
+ padlen = 4 - (SCTP_HEADER_LEN(o_pak) % 4);
+ m_copyback(mout, SCTP_HEADER_LEN(o_pak), padlen, (caddr_t)&cpthis);
+ SCTP_HEADER_LEN(o_pak) += padlen;
}
abm->msg.ch.chunk_length = htons(sizeof(abm->msg.ch) + err_len);
} else {
- mout->m_pkthdr.len = mout->m_len;
+ SCTP_HEADER_LEN(mout) = SCTP_BUF_LEN(mout);
abm->msg.ch.chunk_length = htons(sizeof(abm->msg.ch));
}
/* add checksum */
- if ((sctp_no_csum_on_loopback) &&
- (m->m_pkthdr.rcvif) &&
- (m->m_pkthdr.rcvif->if_type == IFT_LOOP)) {
+ if ((sctp_no_csum_on_loopback) && SCTP_IS_IT_LOOPBACK(m)) {
abm->sh.checksum = 0;
} else {
abm->sh.checksum = sctp_calculate_sum(mout, NULL, iphlen_out);
}
-
- /* zap the rcvif, it should be null */
- mout->m_pkthdr.rcvif = 0;
if (iph_out != NULL) {
struct route ro;
@@ -8931,9 +8797,9 @@ sctp_send_abort(struct mbuf *m, int iphlen, struct sctphdr *sh, uint32_t vtag,
}
#endif
/* set IPv4 length */
- iph_out->ip_len = mout->m_pkthdr.len;
+ iph_out->ip_len = SCTP_HEADER_LEN(o_pak);
/* out it goes */
- (void)ip_output(mout, 0, &ro, IP_RAWOUTPUT, NULL
+ (void)ip_output(o_pak, 0, &ro, IP_RAWOUTPUT, NULL
,NULL
);
/* Free the route if we got one back */
@@ -8951,7 +8817,8 @@ sctp_send_abort(struct mbuf *m, int iphlen, struct sctphdr *sh, uint32_t vtag,
sctp_print_address_pkt((struct ip *)ip6_out, &abm->sh);
}
#endif
- ip6_output(mout, NULL, &ro, 0, NULL, NULL
+ ip6_out->ip6_plen = SCTP_HEADER_LEN(o_pak) - sizeof(*ip6_out);
+ ip6_output(o_pak, NULL, &ro, 0, NULL, NULL
,NULL
);
/* Free the route if we got one back */
@@ -8967,6 +8834,7 @@ sctp_send_operr_to(struct mbuf *m, int iphlen,
struct mbuf *scm,
uint32_t vtag)
{
+ struct mbuf *o_pak;
struct sctphdr *ihdr;
int retcode;
struct sctphdr *ohdr;
@@ -8979,16 +8847,13 @@ sctp_send_operr_to(struct mbuf *m, int iphlen,
#endif
uint32_t val;
+ struct mbuf *at;
+ int len;
iph = mtod(m, struct ip *);
ihdr = (struct sctphdr *)((caddr_t)iph + iphlen);
- if (!(scm->m_flags & M_PKTHDR)) {
- /* must be a pkthdr */
- printf("Huh, not a packet header in send_operr\n");
- sctp_m_freem(scm);
- return;
- }
- M_PREPEND(scm, (sizeof(struct sctphdr) + sizeof(struct sctp_chunkhdr)), M_DONTWAIT);
+
+ SCTP_BUF_PREPEND(scm, (sizeof(struct sctphdr) + sizeof(struct sctp_chunkhdr)), M_DONTWAIT);
if (scm == NULL) {
/* can't send because we can't add a mbuf */
return;
@@ -9001,18 +8866,24 @@ sctp_send_operr_to(struct mbuf *m, int iphlen,
ophdr = (struct sctp_chunkhdr *)(ohdr + 1);
ophdr->chunk_type = SCTP_OPERATION_ERROR;
ophdr->chunk_flags = 0;
- ophdr->chunk_length = htons(scm->m_pkthdr.len - sizeof(struct sctphdr));
- if (scm->m_pkthdr.len % 4) {
+ len = 0;
+ at = scm;
+ while (at) {
+ len += SCTP_BUF_LEN(at);
+ at = SCTP_BUF_NEXT(at);
+ }
+
+ ophdr->chunk_length = htons(len - sizeof(struct sctphdr));
+ if (len % 4) {
/* need padding */
uint32_t cpthis = 0;
int padlen;
- padlen = 4 - (scm->m_pkthdr.len % 4);
- m_copyback(scm, scm->m_pkthdr.len, padlen, (caddr_t)&cpthis);
+ padlen = 4 - (len % 4);
+ m_copyback(scm, len, padlen, (caddr_t)&cpthis);
+ len += padlen;
}
- if ((sctp_no_csum_on_loopback) &&
- (m->m_pkthdr.rcvif) &&
- (m->m_pkthdr.rcvif->if_type == IFT_LOOP)) {
+ if ((sctp_no_csum_on_loopback) && SCTP_IS_IT_LOOPBACK(m)) {
val = 0;
} else {
val = sctp_calculate_sum(scm, NULL, 0);
@@ -9023,11 +8894,16 @@ sctp_send_operr_to(struct mbuf *m, int iphlen,
struct ip *out;
struct route ro;
- M_PREPEND(scm, sizeof(struct ip), M_DONTWAIT);
- if (scm == NULL)
+ o_pak = SCTP_GET_HEADER_FOR_OUTPUT(sizeof(struct ip));
+ if (o_pak == NULL) {
+ sctp_m_freem(scm);
return;
+ }
+ SCTP_BUF_LEN(SCTP_HEADER_TO_CHAIN(o_pak)) = sizeof(struct ip);
+ len += sizeof(struct ip);
+ SCTP_ATTACH_CHAIN(o_pak, scm, len);
bzero(&ro, sizeof ro);
- out = mtod(scm, struct ip *);
+ out = mtod(SCTP_HEADER_TO_CHAIN(o_pak), struct ip *);
out->ip_v = iph->ip_v;
out->ip_hl = (sizeof(struct ip) / 4);
out->ip_tos = iph->ip_tos;
@@ -9038,8 +8914,8 @@ sctp_send_operr_to(struct mbuf *m, int iphlen,
out->ip_sum = 0;
out->ip_src = iph->ip_dst;
out->ip_dst = iph->ip_src;
- out->ip_len = scm->m_pkthdr.len;
- retcode = ip_output(scm, 0, &ro, IP_RAWOUTPUT, NULL
+ out->ip_len = SCTP_HEADER_LEN(o_pak);
+ retcode = ip_output(o_pak, 0, &ro, IP_RAWOUTPUT, NULL
,NULL
);
SCTP_STAT_INCR(sctps_sendpackets);
@@ -9053,18 +8929,24 @@ sctp_send_operr_to(struct mbuf *m, int iphlen,
struct ip6_hdr *out6, *in6;
- M_PREPEND(scm, sizeof(struct ip6_hdr), M_DONTWAIT);
- if (scm == NULL)
+ o_pak = SCTP_GET_HEADER_FOR_OUTPUT(sizeof(struct ip6_hdr));
+ if (o_pak == NULL) {
+ sctp_m_freem(scm);
return;
+ }
+ SCTP_BUF_LEN(SCTP_HEADER_TO_CHAIN(o_pak)) = sizeof(struct ip6_hdr);
+ len += sizeof(struct ip6_hdr);
+ SCTP_ATTACH_CHAIN(o_pak, scm, len);
+
bzero(&ro, sizeof ro);
in6 = mtod(m, struct ip6_hdr *);
- out6 = mtod(scm, struct ip6_hdr *);
+ out6 = mtod(SCTP_HEADER_TO_CHAIN(o_pak), struct ip6_hdr *);
out6->ip6_flow = in6->ip6_flow;
out6->ip6_hlim = ip6_defhlim;
out6->ip6_nxt = IPPROTO_SCTP;
out6->ip6_src = in6->ip6_dst;
out6->ip6_dst = in6->ip6_src;
-
+ out6->ip6_plen = len - sizeof(struct ip6_hdr);
#ifdef SCTP_DEBUG
bzero(&lsa6, sizeof(lsa6));
lsa6.sin6_len = sizeof(lsa6);
@@ -9082,7 +8964,7 @@ sctp_send_operr_to(struct mbuf *m, int iphlen,
sctp_print_address((struct sockaddr *)&fsa6);
}
#endif /* SCTP_DEBUG */
- ip6_output(scm, NULL, &ro, 0, NULL, NULL
+ ip6_output(o_pak, NULL, &ro, 0, NULL, NULL
,NULL
);
SCTP_STAT_INCR(sctps_sendpackets);
@@ -9105,14 +8987,12 @@ sctp_copy_resume(struct sctp_stream_queue_pending *sp,
uint32_t * sndout,
struct mbuf **new_tail)
{
- int left, cancpy, willcpy, need_hdr = 0;
+ int left, cancpy, willcpy;
struct mbuf *m, *prev, *head;
left = min(uio->uio_resid, max_send_len);
/* Always get a header just in case */
- need_hdr = 1;
-
- head = sctp_get_mbuf_for_msg(left, need_hdr, M_WAIT, 0, MT_DATA);
+ head = sctp_get_mbuf_for_msg(left, 0, M_WAIT, 0, MT_DATA);
cancpy = M_TRAILINGSPACE(head);
willcpy = min(cancpy, left);
*error = uiomove(mtod(head, caddr_t), willcpy, uio);
@@ -9122,20 +9002,20 @@ sctp_copy_resume(struct sctp_stream_queue_pending *sp,
}
*sndout += willcpy;
left -= willcpy;
- head->m_len = willcpy;
+ SCTP_BUF_LEN(head) = willcpy;
m = head;
*new_tail = head;
while (left > 0) {
/* move in user data */
- m->m_next = sctp_get_mbuf_for_msg(left, 0, M_WAIT, 0, MT_DATA);
- if (m->m_next == NULL) {
+ SCTP_BUF_NEXT(m) = sctp_get_mbuf_for_msg(left, 0, M_WAIT, 0, MT_DATA);
+ if (SCTP_BUF_NEXT(m) == NULL) {
sctp_m_freem(head);
*new_tail = NULL;
*error = ENOMEM;
return (NULL);
}
prev = m;
- m = m->m_next;
+ m = SCTP_BUF_NEXT(m);
cancpy = M_TRAILINGSPACE(m);
willcpy = min(cancpy, left);
*error = uiomove(mtod(m, caddr_t), willcpy, uio);
@@ -9145,12 +9025,12 @@ sctp_copy_resume(struct sctp_stream_queue_pending *sp,
*error = EFAULT;
return (NULL);
}
- m->m_len = willcpy;
+ SCTP_BUF_LEN(m) = willcpy;
left -= willcpy;
*sndout += willcpy;
*new_tail = m;
if (left == 0) {
- m->m_next = NULL;
+ SCTP_BUF_NEXT(m) = NULL;
}
}
return (head);
@@ -9167,7 +9047,7 @@ sctp_copy_one(struct sctp_stream_queue_pending *sp,
/* First one gets a header */
left = sp->length;
- head = m = sctp_get_mbuf_for_msg((left + resv_upfront), 1, M_WAIT, 0, MT_DATA);
+ head = m = sctp_get_mbuf_for_msg((left + resv_upfront), 0, M_WAIT, 0, MT_DATA);
if (m == NULL) {
return (ENOMEM);
}
@@ -9175,7 +9055,7 @@ sctp_copy_one(struct sctp_stream_queue_pending *sp,
* Add this one for m in now, that way if the alloc fails we won't
* have a bad cnt.
*/
- m->m_data += resv_upfront;
+ SCTP_BUF_RESV_UF(m, resv_upfront);
cancpy = M_TRAILINGSPACE(m);
willcpy = min(cancpy, left);
while (left > 0) {
@@ -9185,12 +9065,12 @@ sctp_copy_one(struct sctp_stream_queue_pending *sp,
sctp_m_freem(head);
return (error);
}
- m->m_len = willcpy;
+ SCTP_BUF_LEN(m) = willcpy;
left -= willcpy;
cpsz += willcpy;
if (left > 0) {
- m->m_next = sctp_get_mbuf_for_msg(left, 0, M_WAIT, 0, MT_DATA);
- if (m->m_next == NULL) {
+ SCTP_BUF_NEXT(m) = sctp_get_mbuf_for_msg(left, 0, M_WAIT, 0, MT_DATA);
+ if (SCTP_BUF_NEXT(m) == NULL) {
/*
* the head goes back to caller, he can free
* the rest
@@ -9198,12 +9078,12 @@ sctp_copy_one(struct sctp_stream_queue_pending *sp,
sctp_m_freem(head);
return (ENOMEM);
}
- m = m->m_next;
+ m = SCTP_BUF_NEXT(m);
cancpy = M_TRAILINGSPACE(m);
willcpy = min(cancpy, left);
} else {
sp->tail_mbuf = m;
- m->m_next = NULL;
+ SCTP_BUF_NEXT(m) = NULL;
}
}
sp->data = head;
@@ -9296,7 +9176,6 @@ sctp_copy_it_in(struct sctp_tcb *stcb,
sp->addr_over = 0;
}
atomic_add_int(&sp->net->ref_count, 1);
- sp->data->m_pkthdr.len = sp->length;
sctp_set_prsctp_policy(stcb, sp);
}
out_now:
@@ -9341,7 +9220,7 @@ int
sctp_lower_sosend(struct socket *so,
struct sockaddr *addr,
struct uio *uio,
- struct mbuf *top,
+ struct mbuf *i_pak,
struct mbuf *control,
int flags,
int use_rcvinfo,
@@ -9351,6 +9230,7 @@ sctp_lower_sosend(struct socket *so,
{
unsigned int sndlen, max_len;
int error, len;
+ struct mbuf *top = NULL;
int s, queue_only = 0, queue_only_for_init = 0;
int free_cnt_applied = 0;
int un_sent = 0;
@@ -9382,8 +9262,10 @@ sctp_lower_sosend(struct socket *so,
atomic_add_int(&inp->total_sends, 1);
if (uio)
sndlen = uio->uio_resid;
- else
- sndlen = top->m_pkthdr.len;
+ else {
+ sndlen = SCTP_HEADER_LEN(i_pak);
+ top = SCTP_HEADER_TO_CHAIN(i_pak);
+ }
s = splnet();
hold_tcblock = 0;
@@ -9746,25 +9628,22 @@ sctp_lower_sosend(struct socket *so,
hold_tcblock = 0;
}
if (top) {
- mm = sctp_get_mbuf_for_msg(1, 1, M_WAIT, 1, MT_DATA);
- if (top->m_flags & M_PKTHDR)
- tot_out = top->m_pkthdr.len;
- else {
- struct mbuf *cntm;
+ struct mbuf *cntm;
- tot_out = 0;
- cntm = top;
- while (cntm) {
- tot_out += cntm->m_len;
- cntm = cntm->m_next;
- }
+ mm = sctp_get_mbuf_for_msg(1, 0, M_WAIT, 1, MT_DATA);
+
+ tot_out = 0;
+ cntm = top;
+ while (cntm) {
+ tot_out += SCTP_BUF_LEN(cntm);
+ cntm = SCTP_BUF_NEXT(cntm);
}
tot_demand = (tot_out + sizeof(struct sctp_paramhdr));
} else {
/* Must fit in a MTU */
tot_out = uio->uio_resid;
tot_demand = (tot_out + sizeof(struct sctp_paramhdr));
- mm = sctp_get_mbuf_for_msg(tot_demand, 1, M_WAIT, 1, MT_DATA);
+ mm = sctp_get_mbuf_for_msg(tot_demand, 0, M_WAIT, 1, MT_DATA);
}
if (mm == NULL) {
error = ENOMEM;
@@ -9783,8 +9662,7 @@ sctp_lower_sosend(struct socket *so,
ph->param_type = htons(SCTP_CAUSE_USER_INITIATED_ABT);
ph->param_length = htons((sizeof(struct sctp_paramhdr) + tot_out));
ph++;
- mm->m_pkthdr.len = tot_out + sizeof(struct sctp_paramhdr);
- mm->m_len = mm->m_pkthdr.len;
+ SCTP_BUF_LEN(mm) = tot_out + sizeof(struct sctp_paramhdr);
if (top == NULL) {
error = uiomove((caddr_t)ph, (int)tot_out, uio);
if (error) {
@@ -9797,7 +9675,7 @@ sctp_lower_sosend(struct socket *so,
mm = NULL;
}
} else {
- mm->m_next = top;
+ SCTP_BUF_NEXT(mm) = top;
}
}
if (hold_tcblock == 0) {
@@ -9997,7 +9875,7 @@ sctp_lower_sosend(struct socket *so,
}
if (sp->tail_mbuf) {
/* tack it to the end */
- sp->tail_mbuf->m_next = mm;
+ SCTP_BUF_NEXT(sp->tail_mbuf) = mm;
sp->tail_mbuf = new_tail;
} else {
/* A stolen mbuf */
@@ -10016,10 +9894,6 @@ sctp_lower_sosend(struct socket *so,
} else {
sp->msg_is_complete = 0;
}
- if (sp->data->m_flags & M_PKTHDR) {
- /* update length */
- sp->data->m_pkthdr.len = sp->length;
- }
SCTP_TCB_SEND_UNLOCK(stcb);
}
if (uio->uio_resid == 0) {
@@ -10467,14 +10341,14 @@ sctp_add_auth_chunk(struct mbuf *m, struct mbuf **m_end,
if (!sctp_auth_is_required_chunk(chunk, stcb->asoc.peer_auth_chunks)) {
return (m);
}
- m_auth = sctp_get_mbuf_for_msg(sizeof(*auth), 1, M_DONTWAIT, 1, MT_HEADER);
+ m_auth = sctp_get_mbuf_for_msg(sizeof(*auth), 0, M_DONTWAIT, 1, MT_HEADER);
if (m_auth == NULL) {
/* no mbuf's */
return (m);
}
/* reserve some space if this will be the first mbuf */
if (m == NULL)
- m_auth->m_data += SCTP_MIN_OVERHEAD;
+ SCTP_BUF_RESV_UF(m_auth, SCTP_MIN_OVERHEAD);
/* fill in the AUTH chunk details */
auth = mtod(m_auth, struct sctp_auth_chunk *);
bzero(auth, sizeof(*auth));
@@ -10487,13 +10361,20 @@ sctp_add_auth_chunk(struct mbuf *m, struct mbuf **m_end,
/* key id and hmac digest will be computed and filled in upon send */
/* save the offset where the auth was inserted into the chain */
- if (m != NULL)
- *offset = m->m_pkthdr.len;
- else
+ if (m != NULL) {
+ struct mbuf *cn;
+
+ *offset = 0;
+ cn = m;
+ while (cn) {
+ *offset += SCTP_BUF_LEN(cn);
+ cn = SCTP_BUF_NEXT(cn);
+ }
+ } else
*offset = 0;
/* update length and return pointer to the auth chunk */
- m_auth->m_pkthdr.len = m_auth->m_len = chunk_len;
+ SCTP_BUF_LEN(m_auth) = chunk_len;
m = sctp_copy_mbufchain(m_auth, m, m_end, 1, chunk_len, 0);
if (auth_ret != NULL)
*auth_ret = auth;
diff --git a/sys/netinet/sctp_pcb.c b/sys/netinet/sctp_pcb.c
index 89e649b..67b5189 100644
--- a/sys/netinet/sctp_pcb.c
+++ b/sys/netinet/sctp_pcb.c
@@ -52,8 +52,6 @@ __FBSDID("$FreeBSD$");
#include <sys/kernel.h>
#include <sys/sysctl.h>
-#include <sys/callout.h>
-
#include <sys/limits.h>
#include <machine/cpu.h>
@@ -1461,7 +1459,7 @@ sctp_inpcb_alloc(struct socket *so)
LIST_INIT(&inp->sctp_asoc_free_list);
#endif
/* Init the timer structure for signature change */
- callout_init(&inp->sctp_ep.signature_change.timer, 1);
+ SCTP_OS_TIMER_INIT(&inp->sctp_ep.signature_change.timer);
inp->sctp_ep.signature_change.type = SCTP_TIMER_TYPE_NEWCOOKIE;
/* now init the actual endpoint default data */
@@ -1498,7 +1496,7 @@ sctp_inpcb_alloc(struct socket *so)
/* seed random number generator */
m->random_counter = 1;
m->store_at = SCTP_SIGNATURE_SIZE;
- sctp_read_random(m->random_numbers, sizeof(m->random_numbers));
+ SCTP_READ_RANDOM(m->random_numbers, sizeof(m->random_numbers));
sctp_fill_random_store(m);
/* Minimum cookie size */
@@ -2162,13 +2160,13 @@ sctp_inpcb_free(struct sctp_inpcb *inp, int immediate, int from)
struct sctp_paramhdr *ph;
uint32_t *ippp;
- op_err->m_len =
+ SCTP_BUF_LEN(op_err) =
sizeof(struct sctp_paramhdr) + sizeof(uint32_t);
ph = mtod(op_err,
struct sctp_paramhdr *);
ph->param_type = htons(
SCTP_CAUSE_USER_INITIATED_ABT);
- ph->param_length = htons(op_err->m_len);
+ ph->param_length = htons(SCTP_BUF_LEN(op_err));
ippp = (uint32_t *) (ph + 1);
*ippp = htonl(SCTP_FROM_SCTP_PCB + SCTP_LOC_3);
}
@@ -2238,14 +2236,14 @@ sctp_inpcb_free(struct sctp_inpcb *inp, int immediate, int from)
struct sctp_paramhdr *ph;
uint32_t *ippp;
- op_err->m_len =
+ SCTP_BUF_LEN(op_err) =
(sizeof(struct sctp_paramhdr) +
sizeof(uint32_t));
ph = mtod(op_err,
struct sctp_paramhdr *);
ph->param_type = htons(
SCTP_CAUSE_USER_INITIATED_ABT);
- ph->param_length = htons(op_err->m_len);
+ ph->param_length = htons(SCTP_BUF_LEN(op_err));
ippp = (uint32_t *) (ph + 1);
*ippp = htonl(SCTP_FROM_SCTP_PCB + SCTP_LOC_5);
}
@@ -2312,12 +2310,12 @@ sctp_inpcb_free(struct sctp_inpcb *inp, int immediate, int from)
/* Fill in the user initiated abort */
struct sctp_paramhdr *ph;
- op_err->m_len = (sizeof(struct sctp_paramhdr) +
+ SCTP_BUF_LEN(op_err) = (sizeof(struct sctp_paramhdr) +
sizeof(uint32_t));
ph = mtod(op_err, struct sctp_paramhdr *);
ph->param_type = htons(
SCTP_CAUSE_USER_INITIATED_ABT);
- ph->param_length = htons(op_err->m_len);
+ ph->param_length = htons(SCTP_BUF_LEN(op_err));
ippp = (uint32_t *) (ph + 1);
*ippp = htonl(SCTP_FROM_SCTP_PCB + SCTP_LOC_7);
@@ -2338,7 +2336,7 @@ sctp_inpcb_free(struct sctp_inpcb *inp, int immediate, int from)
}
if (cnt) {
/* Ok we have someone out there that will kill us */
- callout_stop(&inp->sctp_ep.signature_change.timer);
+ SCTP_OS_TIMER_STOP(&inp->sctp_ep.signature_change.timer);
SCTP_INP_WUNLOCK(inp);
SCTP_ASOC_CREATE_UNLOCK(inp);
SCTP_INP_INFO_WUNLOCK();
@@ -2349,7 +2347,7 @@ sctp_inpcb_free(struct sctp_inpcb *inp, int immediate, int from)
return;
}
if ((inp->refcount) || (inp->sctp_flags & SCTP_PCB_FLAGS_CLOSE_IP)) {
- callout_stop(&inp->sctp_ep.signature_change.timer);
+ SCTP_OS_TIMER_STOP(&inp->sctp_ep.signature_change.timer);
sctp_timer_start(SCTP_TIMER_TYPE_INPKILL, inp, NULL, NULL);
SCTP_INP_WUNLOCK(inp);
SCTP_ASOC_CREATE_UNLOCK(inp);
@@ -2360,7 +2358,7 @@ sctp_inpcb_free(struct sctp_inpcb *inp, int immediate, int from)
#endif
return;
}
- callout_stop(&inp->sctp_ep.signature_change.timer);
+ SCTP_OS_TIMER_STOP(&inp->sctp_ep.signature_change.timer);
inp->sctp_ep.signature_change.type = 0;
inp->sctp_flags |= SCTP_PCB_FLAGS_SOCKET_ALLGONE;
@@ -2368,7 +2366,7 @@ sctp_inpcb_free(struct sctp_inpcb *inp, int immediate, int from)
sctp_log_closing(inp, NULL, 5);
#endif
- callout_stop(&inp->sctp_ep.signature_change.timer);
+ SCTP_OS_TIMER_STOP(&inp->sctp_ep.signature_change.timer);
inp->sctp_ep.signature_change.type = SCTP_TIMER_TYPE_NONE;
/* Clear the read queue */
while ((sq = TAILQ_FIRST(&inp->read_queue)) != NULL) {
@@ -2727,9 +2725,9 @@ sctp_add_remote_addr(struct sctp_tcb *stcb, struct sockaddr *newaddr,
net->tos_flowlabel = stcb->asoc.default_flowlabel;
#endif
/* Init the timer structure */
- callout_init(&net->rxt_timer.timer, 1);
- callout_init(&net->fr_timer.timer, 1);
- callout_init(&net->pmtu_timer.timer, 1);
+ SCTP_OS_TIMER_INIT(&net->rxt_timer.timer);
+ SCTP_OS_TIMER_INIT(&net->fr_timer.timer);
+ SCTP_OS_TIMER_INIT(&net->pmtu_timer.timer);
/* Now generate a route for this guy */
/* KAME hack: embed scopeid */
@@ -3019,13 +3017,14 @@ sctp_aloc_assoc(struct sctp_inpcb *inp, struct sockaddr *firstaddr,
return (NULL);
}
/* Init all the timers */
- callout_init(&asoc->hb_timer.timer, 1);
- callout_init(&asoc->dack_timer.timer, 1);
- callout_init(&asoc->asconf_timer.timer, 1);
- callout_init(&asoc->strreset_timer.timer, 1);
- callout_init(&asoc->shut_guard_timer.timer, 1);
- callout_init(&asoc->autoclose_timer.timer, 1);
- callout_init(&asoc->delayed_event_timer.timer, 1);
+ SCTP_OS_TIMER_INIT(&asoc->hb_timer.timer);
+ SCTP_OS_TIMER_INIT(&asoc->dack_timer.timer);
+ SCTP_OS_TIMER_INIT(&asoc->strreset_timer.timer);
+ SCTP_OS_TIMER_INIT(&asoc->asconf_timer.timer);
+ SCTP_OS_TIMER_INIT(&asoc->shut_guard_timer.timer);
+ SCTP_OS_TIMER_INIT(&asoc->autoclose_timer.timer);
+ SCTP_OS_TIMER_INIT(&asoc->delayed_event_timer.timer);
+
LIST_INSERT_HEAD(&inp->sctp_asoc_list, stcb, sctp_tcblist);
/* now file the port under the hash as well */
if (inp->sctp_tcbhash != NULL) {
@@ -3282,18 +3281,18 @@ sctp_free_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int from_inpcbfre
}
}
/* now clean up any other timers */
- callout_stop(&asoc->hb_timer.timer);
- callout_stop(&asoc->dack_timer.timer);
- callout_stop(&asoc->strreset_timer.timer);
- callout_stop(&asoc->asconf_timer.timer);
- callout_stop(&asoc->autoclose_timer.timer);
- callout_stop(&asoc->shut_guard_timer.timer);
- callout_stop(&asoc->delayed_event_timer.timer);
+ SCTP_OS_TIMER_STOP(&asoc->hb_timer.timer);
+ SCTP_OS_TIMER_STOP(&asoc->dack_timer.timer);
+ SCTP_OS_TIMER_STOP(&asoc->strreset_timer.timer);
+ SCTP_OS_TIMER_STOP(&asoc->asconf_timer.timer);
+ SCTP_OS_TIMER_STOP(&asoc->autoclose_timer.timer);
+ SCTP_OS_TIMER_STOP(&asoc->shut_guard_timer.timer);
+ SCTP_OS_TIMER_STOP(&asoc->delayed_event_timer.timer);
TAILQ_FOREACH(net, &asoc->nets, sctp_next) {
- callout_stop(&net->fr_timer.timer);
- callout_stop(&net->rxt_timer.timer);
- callout_stop(&net->pmtu_timer.timer);
+ SCTP_OS_TIMER_STOP(&net->fr_timer.timer);
+ SCTP_OS_TIMER_STOP(&net->rxt_timer.timer);
+ SCTP_OS_TIMER_STOP(&net->pmtu_timer.timer);
}
/* Now the read queue needs to be cleaned up (only once) */
cnt = 0;
@@ -3421,7 +3420,7 @@ sctp_free_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int from_inpcbfre
}
}
/* Stop any timer someone may have started */
- callout_stop(&asoc->strreset_timer.timer);
+ SCTP_OS_TIMER_STOP(&asoc->strreset_timer.timer);
/*
* Make it invalid too, that way if its about to run it will abort
* and return.
@@ -3433,18 +3432,18 @@ sctp_free_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int from_inpcbfre
atomic_add_int(&stcb->asoc.refcnt, -1);
}
/* now restop the timers to be sure - this is paranoia at is finest! */
- callout_stop(&asoc->hb_timer.timer);
- callout_stop(&asoc->dack_timer.timer);
- callout_stop(&asoc->strreset_timer.timer);
- callout_stop(&asoc->asconf_timer.timer);
- callout_stop(&asoc->shut_guard_timer.timer);
- callout_stop(&asoc->autoclose_timer.timer);
- callout_stop(&asoc->delayed_event_timer.timer);
+ SCTP_OS_TIMER_STOP(&asoc->hb_timer.timer);
+ SCTP_OS_TIMER_STOP(&asoc->dack_timer.timer);
+ SCTP_OS_TIMER_STOP(&asoc->strreset_timer.timer);
+ SCTP_OS_TIMER_STOP(&asoc->asconf_timer.timer);
+ SCTP_OS_TIMER_STOP(&asoc->shut_guard_timer.timer);
+ SCTP_OS_TIMER_STOP(&asoc->autoclose_timer.timer);
+ SCTP_OS_TIMER_STOP(&asoc->delayed_event_timer.timer);
TAILQ_FOREACH(net, &asoc->nets, sctp_next) {
- callout_stop(&net->fr_timer.timer);
- callout_stop(&net->rxt_timer.timer);
- callout_stop(&net->pmtu_timer.timer);
+ SCTP_OS_TIMER_STOP(&net->fr_timer.timer);
+ SCTP_OS_TIMER_STOP(&net->rxt_timer.timer);
+ SCTP_OS_TIMER_STOP(&net->pmtu_timer.timer);
}
asoc->state = 0;
if (inp->sctp_tcbhash) {
@@ -4198,7 +4197,6 @@ static char sctp_pcb_initialized = 0;
static int sctp_max_number_of_assoc = SCTP_MAX_NUM_OF_ASOC;
static int sctp_scale_up_for_address = SCTP_SCALE_FOR_ADDR;
-
void
sctp_pcb_init()
{
@@ -4308,8 +4306,7 @@ sctp_pcb_init()
sctppcbinfo.ipi_free_strmoq = 0;
sctppcbinfo.ipi_free_chunks = 0;
-
- callout_init(&sctppcbinfo.addr_wq_timer.timer, 1);
+ SCTP_OS_TIMER_INIT(&sctppcbinfo.addr_wq_timer.timer);
/* port stuff */
sctppcbinfo.lastlow = ipport_firstauto;
@@ -5213,7 +5210,7 @@ sctp_drain_mbufs(struct sctp_inpcb *inp, struct sctp_tcb *stcb)
asoc->highest_tsn_inside_map = asoc->cumulative_tsn;
}
asoc->last_revoke_count = cnt;
- callout_stop(&stcb->asoc.dack_timer.timer);
+ SCTP_OS_TIMER_STOP(&stcb->asoc.dack_timer.timer);
sctp_send_sack(stcb);
reneged_asoc_ids[reneged_at] = sctp_get_associd(stcb);
reneged_at++;
@@ -5300,7 +5297,7 @@ sctp_initiate_iterator(inp_func inpf, asoc_func af, uint32_t pcb_state,
}
/* Init the timer */
- callout_init(&it->tmr.timer, 1);
+ SCTP_OS_TIMER_INIT(&it->tmr.timer);
/* add to the list of all iterators */
SCTP_INP_INFO_WLOCK();
LIST_INSERT_HEAD(&sctppcbinfo.iteratorhead, it, sctp_nxt_itr);
@@ -5311,8 +5308,3 @@ sctp_initiate_iterator(inp_func inpf, asoc_func af, uint32_t pcb_state,
splx(s);
return (0);
}
-
-
-/*
- * Callout/Timer routines for OS that doesn't have them
- */
diff --git a/sys/netinet/sctp_pcb.h b/sys/netinet/sctp_pcb.h
index 82f7db2..d421c36 100644
--- a/sys/netinet/sctp_pcb.h
+++ b/sys/netinet/sctp_pcb.h
@@ -510,6 +510,5 @@ sctp_initiate_iterator(inp_func inpf, asoc_func af, uint32_t, uint32_t,
uint32_t, void *, uint32_t, end_func ef, struct sctp_inpcb *, uint8_t co_off);
-
#endif /* _KERNEL */
#endif /* !__sctp_pcb_h__ */
diff --git a/sys/netinet/sctp_structs.h b/sys/netinet/sctp_structs.h
index 9f4e9d0..35f7f7f 100644
--- a/sys/netinet/sctp_structs.h
+++ b/sys/netinet/sctp_structs.h
@@ -37,8 +37,6 @@ __FBSDID("$FreeBSD$");
#define __sctp_structs_h__
#include <sys/queue.h>
-
-#include <sys/callout.h>
#include <sys/socket.h>
#ifdef IPSEC
@@ -46,12 +44,14 @@ __FBSDID("$FreeBSD$");
#include <netkey/key.h>
#endif
+#include <netinet/sctp_os.h>
#include <netinet/sctp_header.h>
#include <netinet/sctp_uio.h>
#include <netinet/sctp_auth.h>
struct sctp_timer {
- struct callout timer;
+ sctp_os_timer_t timer;
+
int type;
/*
* Depending on the timer type these will be setup and cast with the
@@ -367,9 +367,11 @@ struct sctp_queued_to_read { /* sinfo structure Pluse more */
struct sctp_tcb *stcb; /* assoc, used for window update */
TAILQ_ENTRY(sctp_queued_to_read) next;
uint16_t port_from;
+ uint16_t spec_flags; /* Flags to hold the notification field */
uint8_t do_not_ref_stcb;
uint8_t end_added;
uint8_t pdapi_aborted;
+ uint8_t resv;
};
/* This data structure will be on the outbound
diff --git a/sys/netinet/sctp_timer.c b/sys/netinet/sctp_timer.c
index dc55ef6..dae2a81 100644
--- a/sys/netinet/sctp_timer.c
+++ b/sys/netinet/sctp_timer.c
@@ -318,11 +318,11 @@ sctp_threshold_management(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
struct sctp_paramhdr *ph;
uint32_t *ippp;
- oper->m_len = sizeof(struct sctp_paramhdr) +
+ SCTP_BUF_LEN(oper) = sizeof(struct sctp_paramhdr) +
sizeof(uint32_t);
ph = mtod(oper, struct sctp_paramhdr *);
ph->param_type = htons(SCTP_CAUSE_PROTOCOL_VIOLATION);
- ph->param_length = htons(oper->m_len);
+ ph->param_length = htons(SCTP_BUF_LEN(oper));
ippp = (uint32_t *) (ph + 1);
*ippp = htonl(SCTP_FROM_SCTP_TIMER + SCTP_LOC_1);
}
@@ -544,8 +544,8 @@ sctp_mark_all_for_resend(struct sctp_tcb *stcb,
window_probe,
SCTP_FR_T3_MARK_TIME);
sctp_log_fr(net->flight_size,
- callout_pending(&net->fr_timer.timer),
- callout_active(&net->fr_timer.timer),
+ SCTP_OS_TIMER_PENDING(&net->fr_timer.timer),
+ SCTP_OS_TIMER_ACTIVE(&net->fr_timer.timer),
SCTP_FR_CWND_REPORT);
sctp_log_fr(net->flight_size, net->cwnd, stcb->asoc.total_flight, SCTP_FR_CWND_REPORT);
#endif
@@ -1091,11 +1091,11 @@ sctp_cookie_timer(struct sctp_inpcb *inp,
struct sctp_paramhdr *ph;
uint32_t *ippp;
- oper->m_len = sizeof(struct sctp_paramhdr) +
+ SCTP_BUF_LEN(oper) = sizeof(struct sctp_paramhdr) +
sizeof(uint32_t);
ph = mtod(oper, struct sctp_paramhdr *);
ph->param_type = htons(SCTP_CAUSE_PROTOCOL_VIOLATION);
- ph->param_length = htons(oper->m_len);
+ ph->param_length = htons(SCTP_BUF_LEN(oper));
ippp = (uint32_t *) (ph + 1);
*ippp = htonl(SCTP_FROM_SCTP_TIMER + SCTP_LOC_2);
}
@@ -1472,7 +1472,7 @@ sctp_heartbeat_timer(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
int
sctp_is_hb_timer_running(struct sctp_tcb *stcb)
{
- if (callout_pending(&stcb->asoc.hb_timer.timer)) {
+ if (SCTP_OS_TIMER_PENDING(&stcb->asoc.hb_timer.timer)) {
/* its running */
return (1);
} else {
@@ -1484,7 +1484,7 @@ sctp_is_hb_timer_running(struct sctp_tcb *stcb)
int
sctp_is_sack_timer_running(struct sctp_tcb *stcb)
{
- if (callout_pending(&stcb->asoc.dack_timer.timer)) {
+ if (SCTP_OS_TIMER_PENDING(&stcb->asoc.dack_timer.timer)) {
/* its running */
return (1);
} else {
@@ -1493,7 +1493,6 @@ sctp_is_sack_timer_running(struct sctp_tcb *stcb)
}
}
-
#define SCTP_NUMBER_OF_MTU_SIZES 18
static uint32_t mtu_sizes[] = {
68,
@@ -1656,7 +1655,7 @@ done_with_iterator:
LIST_REMOVE(it, sctp_nxt_itr);
/* stopping the callout is not needed, in theory */
SCTP_INP_INFO_WUNLOCK();
- callout_stop(&it->tmr.timer);
+ SCTP_OS_TIMER_STOP(&it->tmr.timer);
if (it->function_atend != NULL) {
(*it->function_atend) (it->pointer, it->val);
}
diff --git a/sys/netinet/sctp_usrreq.c b/sys/netinet/sctp_usrreq.c
index c650e35..79a62a0 100644
--- a/sys/netinet/sctp_usrreq.c
+++ b/sys/netinet/sctp_usrreq.c
@@ -163,6 +163,7 @@ unsigned int sctp_early_fr_msec = SCTP_MINFR_MSEC_TIMER;
unsigned int sctp_use_rttvar_cc = 0;
int sctp_says_check_for_deadlock = 0;
unsigned int sctp_asconf_auth_nochk = 0;
+unsigned int sctp_nat_friendly = 1;
unsigned int sctp_auth_disable = 0;
unsigned int sctp_auth_random_len = SCTP_AUTH_RANDOM_SIZE_DEFAULT;
unsigned int sctp_auth_hmac_id_default = SCTP_AUTH_HMAC_ID_SHA1;
@@ -314,7 +315,7 @@ sctp_notify_mbuf(struct sctp_inpcb *inp,
nxtsz = find_next_best_mtu(totsz);
}
/* Stop any PMTU timer */
- if (callout_pending(&net->pmtu_timer.timer)) {
+ if (SCTP_OS_TIMER_PENDING(&net->pmtu_timer.timer)) {
tmr_stopped = 1;
sctp_timer_stop(SCTP_TIMER_TYPE_PATHMTURAISE, inp, stcb, net,
SCTP_FROM_SCTP_USRREQ + SCTP_LOC_1);
@@ -923,6 +924,10 @@ SYSCTL_PROC(_net_inet_sctp, OID_AUTO, assoclist, CTLFLAG_RD,
0, 0, sctp_assoclist,
"S,xassoc", "List of active SCTP associations");
+SYSCTL_UINT(_net_inet_sctp, OID_AUTO, nat_friendly, CTLFLAG_RW,
+ &sctp_nat_friendly, 0,
+ "SCTP NAT friendly operation");
+
#ifdef SCTP_DEBUG
SYSCTL_INT(_net_inet_sctp, OID_AUTO, debug, CTLFLAG_RW,
&sctp_debug_on, 0, "Configure debug output");
@@ -1179,21 +1184,9 @@ connected_type:
}
inp->control = control;
}
- /* add it in possibly */
- if ((inp->pkt) && (inp->pkt->m_flags & M_PKTHDR)) {
- struct mbuf *x;
- int c_len;
-
- c_len = 0;
- /* How big is it */
- for (x = m; x; x = x->m_next) {
- c_len += x->m_len;
- }
- inp->pkt->m_pkthdr.len += c_len;
- }
/* Place the data */
if (inp->pkt) {
- inp->pkt_last->m_next = m;
+ SCTP_BUF_NEXT(inp->pkt_last) = m;
inp->pkt_last = m;
} else {
inp->pkt_last = inp->pkt = m;
@@ -1275,9 +1268,9 @@ sctp_disconnect(struct socket *so)
struct sctp_paramhdr *ph;
ph = mtod(err, struct sctp_paramhdr *);
- err->m_len = sizeof(struct sctp_paramhdr);
+ SCTP_BUF_LEN(err) = sizeof(struct sctp_paramhdr);
ph->param_type = htons(SCTP_CAUSE_USER_INITIATED_ABT);
- ph->param_length = htons(err->m_len);
+ ph->param_length = htons(SCTP_BUF_LEN(err));
}
sctp_send_abort_tcb(stcb, err);
SCTP_STAT_INCR_COUNTER32(sctps_aborted);
@@ -1360,13 +1353,13 @@ sctp_disconnect(struct socket *so)
struct sctp_paramhdr *ph;
uint32_t *ippp;
- op_err->m_len =
+ SCTP_BUF_LEN(op_err) =
(sizeof(struct sctp_paramhdr) + sizeof(uint32_t));
ph = mtod(op_err,
struct sctp_paramhdr *);
ph->param_type = htons(
SCTP_CAUSE_USER_INITIATED_ABT);
- ph->param_length = htons(op_err->m_len);
+ ph->param_length = htons(SCTP_BUF_LEN(op_err));
ippp = (uint32_t *) (ph + 1);
*ippp = htonl(SCTP_FROM_SCTP_USRREQ + SCTP_LOC_4);
}
@@ -1499,13 +1492,13 @@ sctp_shutdown(struct socket *so)
struct sctp_paramhdr *ph;
uint32_t *ippp;
- op_err->m_len =
+ SCTP_BUF_LEN(op_err) =
sizeof(struct sctp_paramhdr) + sizeof(uint32_t);
ph = mtod(op_err,
struct sctp_paramhdr *);
ph->param_type = htons(
SCTP_CAUSE_USER_INITIATED_ABT);
- ph->param_length = htons(op_err->m_len);
+ ph->param_length = htons(SCTP_BUF_LEN(op_err));
ippp = (uint32_t *) (ph + 1);
*ippp = htonl(SCTP_FROM_SCTP_USRREQ + SCTP_LOC_6);
}
@@ -1869,7 +1862,7 @@ sctp_do_connect_x(struct socket *so,
error = EALREADY;
goto out_now;
}
- if ((at + incr) > m->m_len) {
+ if ((at + incr) > SCTP_BUF_LEN(m)) {
totaddr = i;
break;
}
@@ -2040,57 +2033,57 @@ sctp_optsget(struct socket *so,
/* make it an "on/off" value */
optval = (optval != 0);
}
- if ((size_t)m->m_len < sizeof(int)) {
+ if ((size_t)SCTP_BUF_LEN(m) < sizeof(int)) {
error = EINVAL;
}
SCTP_INP_RUNLOCK(inp);
if (error == 0) {
/* return the option value */
*mtod(m, int *)= optval;
- m->m_len = sizeof(optval);
+ SCTP_BUF_LEN(m) = sizeof(optval);
}
break;
case SCTP_PARTIAL_DELIVERY_POINT:
{
- if ((size_t)m->m_len < sizeof(unsigned int)) {
+ if ((size_t)SCTP_BUF_LEN(m) < sizeof(unsigned int)) {
error = EINVAL;
break;
}
*mtod(m, unsigned int *)= inp->partial_delivery_point;
- m->m_len = sizeof(unsigned int);
+ SCTP_BUF_LEN(m) = sizeof(unsigned int);
}
break;
case SCTP_FRAGMENT_INTERLEAVE:
{
- if ((size_t)m->m_len < sizeof(unsigned int)) {
+ if ((size_t)SCTP_BUF_LEN(m) < sizeof(unsigned int)) {
error = EINVAL;
break;
}
*mtod(m, unsigned int *)= sctp_is_feature_on(inp, SCTP_PCB_FLAGS_FRAG_INTERLEAVE);
- m->m_len = sizeof(unsigned int);
+ SCTP_BUF_LEN(m) = sizeof(unsigned int);
}
break;
case SCTP_CMT_ON_OFF:
{
- if ((size_t)m->m_len < sizeof(unsigned int)) {
+ if ((size_t)SCTP_BUF_LEN(m) < sizeof(unsigned int)) {
error = EINVAL;
break;
}
*mtod(m, unsigned int *)= sctp_cmt_sockopt_on_off;
- m->m_len = sizeof(unsigned int);
+ SCTP_BUF_LEN(m) = sizeof(unsigned int);
}
break;
case SCTP_CMT_USE_DAC:
{
*mtod(m, unsigned int *)= sctp_cmt_sockopt_use_dac;
- m->m_len = sizeof(unsigned int);
+ SCTP_BUF_LEN(m) = sizeof(unsigned int);
}
break;
case SCTP_GET_ADDR_LEN:
{
struct sctp_assoc_value *av;
- if ((size_t)m->m_len < sizeof(struct sctp_assoc_value)) {
+ if ((size_t)SCTP_BUF_LEN(m) < sizeof(struct sctp_assoc_value)) {
error = EINVAL;
break;
}
@@ -2116,7 +2109,7 @@ sctp_optsget(struct socket *so,
int cnt, at;
uint16_t orig;
- if ((size_t)m->m_len < sizeof(struct sctp_assoc_ids)) {
+ if ((size_t)SCTP_BUF_LEN(m) < sizeof(struct sctp_assoc_ids)) {
error = EINVAL;
break;
}
@@ -2164,7 +2157,7 @@ sctp_optsget(struct socket *so,
struct sctp_assoc_value *av;
- if ((size_t)m->m_len < sizeof(struct sctp_assoc_value)) {
+ if ((size_t)SCTP_BUF_LEN(m) < sizeof(struct sctp_assoc_value)) {
error = EINVAL;
break;
}
@@ -2186,7 +2179,7 @@ sctp_optsget(struct socket *so,
{
struct sctp_get_nonce_values *gnv;
- if ((size_t)m->m_len < sizeof(struct sctp_get_nonce_values)) {
+ if ((size_t)SCTP_BUF_LEN(m) < sizeof(struct sctp_get_nonce_values)) {
error = EINVAL;
break;
}
@@ -2206,7 +2199,7 @@ sctp_optsget(struct socket *so,
{
struct sctp_assoc_value *tm;
- if ((size_t)m->m_len < sizeof(struct sctp_assoc_value)) {
+ if ((size_t)SCTP_BUF_LEN(m) < sizeof(struct sctp_assoc_value)) {
error = EINVAL;
break;
}
@@ -2237,7 +2230,7 @@ sctp_optsget(struct socket *so,
break;
case SCTP_GET_SNDBUF_USE:
- if ((size_t)m->m_len < sizeof(struct sctp_sockstat)) {
+ if ((size_t)SCTP_BUF_LEN(m) < sizeof(struct sctp_sockstat)) {
error = EINVAL;
} else {
struct sctp_sockstat *ss;
@@ -2255,7 +2248,7 @@ sctp_optsget(struct socket *so,
asoc->size_on_all_streams);
SCTP_TCB_UNLOCK(stcb);
error = 0;
- m->m_len = sizeof(struct sctp_sockstat);
+ SCTP_BUF_LEN(m) = sizeof(struct sctp_sockstat);
}
}
break;
@@ -2267,7 +2260,7 @@ sctp_optsget(struct socket *so,
SCTP_INP_RLOCK(inp);
*burst = inp->sctp_ep.max_burst;
SCTP_INP_RUNLOCK(inp);
- m->m_len = sizeof(uint8_t);
+ SCTP_BUF_LEN(m) = sizeof(uint8_t);
}
break;
@@ -2277,17 +2270,17 @@ sctp_optsget(struct socket *so,
sctp_assoc_t *assoc_id;
int ovh;
- if ((size_t)m->m_len < sizeof(uint32_t)) {
+ if ((size_t)SCTP_BUF_LEN(m) < sizeof(uint32_t)) {
error = EINVAL;
break;
}
- if ((size_t)m->m_len < sizeof(sctp_assoc_t)) {
+ if ((size_t)SCTP_BUF_LEN(m) < sizeof(sctp_assoc_t)) {
error = EINVAL;
break;
}
assoc_id = mtod(m, sctp_assoc_t *);
segsize = mtod(m, uint32_t *);
- m->m_len = sizeof(uint32_t);
+ SCTP_BUF_LEN(m) = sizeof(uint32_t);
if (((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) &&
(inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED)) ||
@@ -2332,14 +2325,14 @@ sctp_optsget(struct socket *so,
{
uint32_t *level;
- if ((size_t)m->m_len < sizeof(uint32_t)) {
+ if ((size_t)SCTP_BUF_LEN(m) < sizeof(uint32_t)) {
error = EINVAL;
break;
}
level = mtod(m, uint32_t *);
error = 0;
*level = sctp_debug_on;
- m->m_len = sizeof(uint32_t);
+ SCTP_BUF_LEN(m) = sizeof(uint32_t);
printf("Returning DEBUG LEVEL %x is set\n",
(uint32_t) sctp_debug_on);
}
@@ -2358,7 +2351,7 @@ sctp_optsget(struct socket *so,
{
struct sctp_event_subscribe *events;
- if ((size_t)m->m_len < sizeof(struct sctp_event_subscribe)) {
+ if ((size_t)SCTP_BUF_LEN(m) < sizeof(struct sctp_event_subscribe)) {
error = EINVAL;
break;
}
@@ -2395,40 +2388,40 @@ sctp_optsget(struct socket *so,
if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_STREAM_RESETEVNT))
events->sctp_stream_reset_events = 1;
SCTP_INP_RUNLOCK(inp);
- m->m_len = sizeof(struct sctp_event_subscribe);
+ SCTP_BUF_LEN(m) = sizeof(struct sctp_event_subscribe);
}
break;
case SCTP_ADAPTATION_LAYER:
- if ((size_t)m->m_len < sizeof(int)) {
+ if ((size_t)SCTP_BUF_LEN(m) < sizeof(int)) {
error = EINVAL;
break;
}
SCTP_INP_RLOCK(inp);
*mtod(m, int *)= inp->sctp_ep.adaptation_layer_indicator;
SCTP_INP_RUNLOCK(inp);
- m->m_len = sizeof(int);
+ SCTP_BUF_LEN(m) = sizeof(int);
break;
case SCTP_SET_INITIAL_DBG_SEQ:
- if ((size_t)m->m_len < sizeof(int)) {
+ if ((size_t)SCTP_BUF_LEN(m) < sizeof(int)) {
error = EINVAL;
break;
}
SCTP_INP_RLOCK(inp);
*mtod(m, int *)= inp->sctp_ep.initial_sequence_debug;
SCTP_INP_RUNLOCK(inp);
- m->m_len = sizeof(int);
+ SCTP_BUF_LEN(m) = sizeof(int);
break;
case SCTP_GET_LOCAL_ADDR_SIZE:
- if ((size_t)m->m_len < sizeof(int)) {
+ if ((size_t)SCTP_BUF_LEN(m) < sizeof(int)) {
error = EINVAL;
break;
}
SCTP_INP_RLOCK(inp);
*mtod(m, int *)= sctp_count_max_addresses(inp);
SCTP_INP_RUNLOCK(inp);
- m->m_len = sizeof(int);
+ SCTP_BUF_LEN(m) = sizeof(int);
break;
case SCTP_GET_REMOTE_ADDR_SIZE:
{
@@ -2436,7 +2429,7 @@ sctp_optsget(struct socket *so,
uint32_t *val, sz;
struct sctp_nets *net;
- if ((size_t)m->m_len < sizeof(sctp_assoc_t)) {
+ if ((size_t)SCTP_BUF_LEN(m) < sizeof(sctp_assoc_t)) {
error = EINVAL;
break;
}
@@ -2473,7 +2466,7 @@ sctp_optsget(struct socket *so,
}
SCTP_TCB_UNLOCK(stcb);
*val = sz;
- m->m_len = sizeof(uint32_t);
+ SCTP_BUF_LEN(m) = sizeof(uint32_t);
}
break;
case SCTP_GET_PEER_ADDRESSES:
@@ -2487,11 +2480,11 @@ sctp_optsget(struct socket *so,
struct sctp_nets *net;
struct sctp_getaddresses *saddr;
- if ((size_t)m->m_len < sizeof(struct sctp_getaddresses)) {
+ if ((size_t)SCTP_BUF_LEN(m) < sizeof(struct sctp_getaddresses)) {
error = EINVAL;
break;
}
- left = m->m_len - sizeof(struct sctp_getaddresses);
+ left = SCTP_BUF_LEN(m) - sizeof(struct sctp_getaddresses);
saddr = mtod(m, struct sctp_getaddresses *);
if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) {
SCTP_INP_RLOCK(inp);
@@ -2506,7 +2499,7 @@ sctp_optsget(struct socket *so,
error = ENOENT;
break;
}
- m->m_len = sizeof(struct sctp_getaddresses);
+ SCTP_BUF_LEN(m) = sizeof(struct sctp_getaddresses);
sas = (struct sockaddr_storage *)&saddr->addr[0];
TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
@@ -2535,7 +2528,7 @@ sctp_optsget(struct socket *so,
sas = (struct sockaddr_storage *)((caddr_t)sas + cpsz);
left -= cpsz;
- m->m_len += cpsz;
+ SCTP_BUF_LEN(m) += cpsz;
}
SCTP_TCB_UNLOCK(stcb);
}
@@ -2546,7 +2539,7 @@ sctp_optsget(struct socket *so,
struct sockaddr_storage *sas;
struct sctp_getaddresses *saddr;
- if ((size_t)m->m_len < sizeof(struct sctp_getaddresses)) {
+ if ((size_t)SCTP_BUF_LEN(m) < sizeof(struct sctp_getaddresses)) {
error = EINVAL;
break;
}
@@ -2578,11 +2571,11 @@ sctp_optsget(struct socket *so,
SCTP_INP_RUNLOCK(inp);
}
sas = (struct sockaddr_storage *)&saddr->addr[0];
- limit = m->m_len - sizeof(sctp_assoc_t);
+ limit = SCTP_BUF_LEN(m) - sizeof(sctp_assoc_t);
actual = sctp_fill_up_addresses(inp, stcb, limit, sas);
if (stcb)
SCTP_TCB_UNLOCK(stcb);
- m->m_len = sizeof(struct sockaddr_storage) + actual;
+ SCTP_BUF_LEN(m) = sizeof(struct sockaddr_storage) + actual;
}
break;
case SCTP_PEER_ADDR_PARAMS:
@@ -2590,7 +2583,7 @@ sctp_optsget(struct socket *so,
struct sctp_paddrparams *paddrp;
struct sctp_nets *net;
- if ((size_t)m->m_len < sizeof(struct sctp_paddrparams)) {
+ if ((size_t)SCTP_BUF_LEN(m) < sizeof(struct sctp_paddrparams)) {
error = EINVAL;
break;
}
@@ -2653,7 +2646,7 @@ sctp_optsget(struct socket *so,
else
paddrp->spp_flags |= SPP_HB_ENABLE;
/* get flags for PMTU */
- if (callout_pending(&net->pmtu_timer.timer)) {
+ if (SCTP_OS_TIMER_PENDING(&net->pmtu_timer.timer)) {
paddrp->spp_flags |= SPP_PMTUD_ENABLE;
} else {
paddrp->spp_flags |= SPP_PMTUD_DISABLE;
@@ -2725,7 +2718,7 @@ sctp_optsget(struct socket *so,
SCTP_INP_RUNLOCK(inp);
}
- m->m_len = sizeof(struct sctp_paddrparams);
+ SCTP_BUF_LEN(m) = sizeof(struct sctp_paddrparams);
}
break;
case SCTP_GET_PEER_ADDR_INFO:
@@ -2733,7 +2726,7 @@ sctp_optsget(struct socket *so,
struct sctp_paddrinfo *paddri;
struct sctp_nets *net;
- if ((size_t)m->m_len < sizeof(struct sctp_paddrinfo)) {
+ if ((size_t)SCTP_BUF_LEN(m) < sizeof(struct sctp_paddrinfo)) {
error = EINVAL;
break;
}
@@ -2771,7 +2764,7 @@ sctp_optsget(struct socket *so,
error = ENOENT;
break;
}
- m->m_len = sizeof(struct sctp_paddrinfo);
+ SCTP_BUF_LEN(m) = sizeof(struct sctp_paddrinfo);
paddri->spinfo_state = net->dest_state & (SCTP_REACHABLE_MASK | SCTP_ADDR_NOHB);
paddri->spinfo_cwnd = net->cwnd;
paddri->spinfo_srtt = ((net->lastsa >> 2) + net->lastsv) >> 1;
@@ -2784,13 +2777,13 @@ sctp_optsget(struct socket *so,
{
struct sctp_pcbinfo *spcb;
- if ((size_t)m->m_len < sizeof(struct sctp_pcbinfo)) {
+ if ((size_t)SCTP_BUF_LEN(m) < sizeof(struct sctp_pcbinfo)) {
error = EINVAL;
break;
}
spcb = mtod(m, struct sctp_pcbinfo *);
sctp_fill_pcbinfo(spcb);
- m->m_len = sizeof(struct sctp_pcbinfo);
+ SCTP_BUF_LEN(m) = sizeof(struct sctp_pcbinfo);
}
break;
case SCTP_STATUS:
@@ -2798,7 +2791,7 @@ sctp_optsget(struct socket *so,
struct sctp_nets *net;
struct sctp_status *sstat;
- if ((size_t)m->m_len < sizeof(struct sctp_status)) {
+ if ((size_t)SCTP_BUF_LEN(m) < sizeof(struct sctp_status)) {
error = EINVAL;
break;
}
@@ -2852,14 +2845,14 @@ sctp_optsget(struct socket *so,
sstat->sstat_primary.spinfo_mtu = net->mtu;
sstat->sstat_primary.spinfo_assoc_id = sctp_get_associd(stcb);
SCTP_TCB_UNLOCK(stcb);
- m->m_len = sizeof(*sstat);
+ SCTP_BUF_LEN(m) = sizeof(*sstat);
}
break;
case SCTP_RTOINFO:
{
struct sctp_rtoinfo *srto;
- if ((size_t)m->m_len < sizeof(struct sctp_rtoinfo)) {
+ if ((size_t)SCTP_BUF_LEN(m) < sizeof(struct sctp_rtoinfo)) {
error = EINVAL;
break;
}
@@ -2890,14 +2883,14 @@ sctp_optsget(struct socket *so,
srto->srto_max = stcb->asoc.maxrto;
srto->srto_min = stcb->asoc.minrto;
SCTP_TCB_UNLOCK(stcb);
- m->m_len = sizeof(*srto);
+ SCTP_BUF_LEN(m) = sizeof(*srto);
}
break;
case SCTP_ASSOCINFO:
{
struct sctp_assocparams *sasoc;
- if ((size_t)m->m_len < sizeof(struct sctp_assocparams)) {
+ if ((size_t)SCTP_BUF_LEN(m) < sizeof(struct sctp_assocparams)) {
error = EINVAL;
break;
}
@@ -2938,14 +2931,14 @@ sctp_optsget(struct socket *so,
sasoc->sasoc_cookie_life = inp->sctp_ep.def_cookie_life;
SCTP_INP_RUNLOCK(inp);
}
- m->m_len = sizeof(*sasoc);
+ SCTP_BUF_LEN(m) = sizeof(*sasoc);
}
break;
case SCTP_DEFAULT_SEND_PARAM:
{
struct sctp_sndrcvinfo *s_info;
- if (m->m_len != sizeof(struct sctp_sndrcvinfo)) {
+ if (SCTP_BUF_LEN(m) != sizeof(struct sctp_sndrcvinfo)) {
error = EINVAL;
break;
}
@@ -2966,14 +2959,14 @@ sctp_optsget(struct socket *so,
/* Copy it out */
*s_info = stcb->asoc.def_send;
SCTP_TCB_UNLOCK(stcb);
- m->m_len = sizeof(*s_info);
+ SCTP_BUF_LEN(m) = sizeof(*s_info);
}
break;
case SCTP_INITMSG:
{
struct sctp_initmsg *sinit;
- if ((size_t)m->m_len < sizeof(struct sctp_initmsg)) {
+ if ((size_t)SCTP_BUF_LEN(m) < sizeof(struct sctp_initmsg)) {
error = EINVAL;
break;
}
@@ -2984,7 +2977,7 @@ sctp_optsget(struct socket *so,
sinit->sinit_max_attempts = inp->sctp_ep.max_init_times;
sinit->sinit_max_init_timeo = inp->sctp_ep.initial_init_rto_max;
SCTP_INP_RUNLOCK(inp);
- m->m_len = sizeof(*sinit);
+ SCTP_BUF_LEN(m) = sizeof(*sinit);
}
break;
case SCTP_PRIMARY_ADDR:
@@ -2992,7 +2985,7 @@ sctp_optsget(struct socket *so,
{
struct sctp_setprim *ssp;
- if ((size_t)m->m_len < sizeof(struct sctp_setprim)) {
+ if ((size_t)SCTP_BUF_LEN(m) < sizeof(struct sctp_setprim)) {
error = EINVAL;
break;
}
@@ -3030,7 +3023,7 @@ sctp_optsget(struct socket *so,
&stcb->asoc.primary_destination->ro._l_addr,
((struct sockaddr *)&stcb->asoc.primary_destination->ro._l_addr)->sa_len);
SCTP_TCB_UNLOCK(stcb);
- m->m_len = sizeof(*ssp);
+ SCTP_BUF_LEN(m) = sizeof(*ssp);
}
break;
@@ -3041,7 +3034,7 @@ sctp_optsget(struct socket *so,
uint32_t size;
int i;
- if ((size_t)(m->m_len) < sizeof(*shmac)) {
+ if ((size_t)(SCTP_BUF_LEN(m)) < sizeof(*shmac)) {
error = EINVAL;
break;
}
@@ -3050,13 +3043,13 @@ sctp_optsget(struct socket *so,
hmaclist = inp->sctp_ep.local_hmacs;
if (hmaclist == NULL) {
/* no HMACs to return */
- m->m_len = sizeof(*shmac);
+ SCTP_BUF_LEN(m) = sizeof(*shmac);
break;
}
/* is there room for all of the hmac ids? */
size = sizeof(*shmac) + (hmaclist->num_algo *
sizeof(shmac->shmac_idents[0]));
- if ((size_t)(m->m_len) < size) {
+ if ((size_t)(SCTP_BUF_LEN(m)) < size) {
error = EINVAL;
SCTP_INP_RUNLOCK(inp);
break;
@@ -3065,14 +3058,14 @@ sctp_optsget(struct socket *so,
for (i = 0; i < hmaclist->num_algo; i++)
shmac->shmac_idents[i] = hmaclist->hmac[i];
SCTP_INP_RUNLOCK(inp);
- m->m_len = size;
+ SCTP_BUF_LEN(m) = size;
break;
}
case SCTP_AUTH_ACTIVE_KEY:
{
struct sctp_authkeyid *scact;
- if ((size_t)(m->m_len) < sizeof(*scact)) {
+ if ((size_t)(SCTP_BUF_LEN(m)) < sizeof(*scact)) {
error = EINVAL;
break;
}
@@ -3104,7 +3097,7 @@ sctp_optsget(struct socket *so,
scact->scact_keynumber = inp->sctp_ep.default_keyid;
SCTP_INP_RUNLOCK(inp);
}
- m->m_len = sizeof(*scact);
+ SCTP_BUF_LEN(m) = sizeof(*scact);
break;
}
case SCTP_LOCAL_AUTH_CHUNKS:
@@ -3113,7 +3106,7 @@ sctp_optsget(struct socket *so,
sctp_auth_chklist_t *chklist = NULL;
int size = 0;
- if ((size_t)(m->m_len) < sizeof(*sac)) {
+ if ((size_t)(SCTP_BUF_LEN(m)) < sizeof(*sac)) {
error = EINVAL;
break;
}
@@ -3145,7 +3138,7 @@ sctp_optsget(struct socket *so,
}
/* is there enough space? */
size = sctp_auth_get_chklist_size(chklist);
- if ((size_t)m->m_len < (sizeof(struct sctp_authchunks) + size)) {
+ if ((size_t)SCTP_BUF_LEN(m) < (sizeof(struct sctp_authchunks) + size)) {
error = EINVAL;
SCTP_TCB_UNLOCK(stcb);
break;
@@ -3164,7 +3157,7 @@ sctp_optsget(struct socket *so,
}
/* is there enough space? */
size = sctp_auth_get_chklist_size(chklist);
- if ((size_t)m->m_len < (sizeof(struct sctp_authchunks) + size)) {
+ if ((size_t)SCTP_BUF_LEN(m) < (sizeof(struct sctp_authchunks) + size)) {
error = EINVAL;
SCTP_INP_RUNLOCK(inp);
break;
@@ -3173,7 +3166,7 @@ sctp_optsget(struct socket *so,
sctp_serialize_auth_chunks(chklist, sac->gauth_chunks);
SCTP_INP_RUNLOCK(inp);
}
- m->m_len = sizeof(struct sctp_authchunks) + size;
+ SCTP_BUF_LEN(m) = sizeof(struct sctp_authchunks) + size;
break;
}
case SCTP_PEER_AUTH_CHUNKS:
@@ -3182,7 +3175,7 @@ sctp_optsget(struct socket *so,
sctp_auth_chklist_t *chklist = NULL;
int size = 0;
- if ((size_t)(m->m_len) < sizeof(*sac)) {
+ if ((size_t)(SCTP_BUF_LEN(m)) < sizeof(*sac)) {
error = EINVAL;
break;
}
@@ -3213,7 +3206,7 @@ sctp_optsget(struct socket *so,
}
/* is there enough space? */
size = sctp_auth_get_chklist_size(chklist);
- if ((size_t)m->m_len < (sizeof(struct sctp_authchunks) + size)) {
+ if ((size_t)SCTP_BUF_LEN(m) < (sizeof(struct sctp_authchunks) + size)) {
error = EINVAL;
SCTP_TCB_UNLOCK(stcb);
break;
@@ -3221,14 +3214,14 @@ sctp_optsget(struct socket *so,
/* copy in the chunks */
sctp_serialize_auth_chunks(chklist, sac->gauth_chunks);
SCTP_TCB_UNLOCK(stcb);
- m->m_len = sizeof(struct sctp_authchunks) + size;
+ SCTP_BUF_LEN(m) = sizeof(struct sctp_authchunks) + size;
break;
}
default:
error = ENOPROTOOPT;
- m->m_len = 0;
+ SCTP_BUF_LEN(m) = 0;
break;
} /* end switch (sopt->sopt_name) */
return (error);
@@ -3268,7 +3261,7 @@ sctp_optsset(struct socket *so,
case SCTP_USE_EXT_RCVINFO:
case SCTP_I_WANT_MAPPED_V4_ADDR:
/* copy in the option value */
- if ((size_t)m->m_len < sizeof(int)) {
+ if ((size_t)SCTP_BUF_LEN(m) < sizeof(int)) {
error = EINVAL;
break;
}
@@ -3318,12 +3311,12 @@ sctp_optsset(struct socket *so,
break;
case SCTP_PARTIAL_DELIVERY_POINT:
{
- if ((size_t)m->m_len < sizeof(unsigned int)) {
+ if ((size_t)SCTP_BUF_LEN(m) < sizeof(unsigned int)) {
error = EINVAL;
break;
}
inp->partial_delivery_point = *mtod(m, unsigned int *);
- m->m_len = sizeof(unsigned int);
+ SCTP_BUF_LEN(m) = sizeof(unsigned int);
}
break;
case SCTP_FRAGMENT_INTERLEAVE:
@@ -3331,7 +3324,7 @@ sctp_optsset(struct socket *so,
{
int on_off;
- if ((size_t)m->m_len < sizeof(int)) {
+ if ((size_t)SCTP_BUF_LEN(m) < sizeof(int)) {
error = EINVAL;
break;
}
@@ -3347,7 +3340,7 @@ sctp_optsset(struct socket *so,
{
struct sctp_assoc_value *av;
- if ((size_t)m->m_len < sizeof(struct sctp_assoc_value)) {
+ if ((size_t)SCTP_BUF_LEN(m) < sizeof(struct sctp_assoc_value)) {
error = EINVAL;
break;
}
@@ -3371,7 +3364,7 @@ sctp_optsset(struct socket *so,
break;
case SCTP_CMT_USE_DAC:
{
- if ((size_t)m->m_len < sizeof(unsigned int)) {
+ if ((size_t)SCTP_BUF_LEN(m) < sizeof(unsigned int)) {
error = EINVAL;
break;
}
@@ -3392,7 +3385,7 @@ sctp_optsset(struct socket *so,
struct sctp_assoc_value *av;
- if ((size_t)m->m_len < sizeof(struct sctp_assoc_value)) {
+ if ((size_t)SCTP_BUF_LEN(m) < sizeof(struct sctp_assoc_value)) {
error = EINVAL;
break;
}
@@ -3414,7 +3407,7 @@ sctp_optsset(struct socket *so,
{
struct sctp_assoc_value *tm;
- if ((size_t)m->m_len < sizeof(struct sctp_assoc_value)) {
+ if ((size_t)SCTP_BUF_LEN(m) < sizeof(struct sctp_assoc_value)) {
error = EINVAL;
break;
}
@@ -3453,7 +3446,7 @@ sctp_optsset(struct socket *so,
{
struct sctp_authchunk *sauth;
- if ((size_t)m->m_len < sizeof(*sauth)) {
+ if ((size_t)SCTP_BUF_LEN(m) < sizeof(*sauth)) {
error = EINVAL;
break;
}
@@ -3471,7 +3464,7 @@ sctp_optsset(struct socket *so,
sctp_key_t *key = NULL;
int size;
- size = m->m_len - sizeof(*sca);
+ size = SCTP_BUF_LEN(m) - sizeof(*sca);
if (size < 0) {
error = EINVAL;
break;
@@ -3564,7 +3557,7 @@ sctp_optsset(struct socket *so,
uint32_t hmacid;
int size, i;
- size = m->m_len - sizeof(*shmac);
+ size = SCTP_BUF_LEN(m) - sizeof(*shmac);
if (size < 0) {
error = EINVAL;
break;
@@ -3598,7 +3591,7 @@ sctp_optsset(struct socket *so,
{
struct sctp_authkeyid *scact;
- if ((size_t)m->m_len < sizeof(*scact)) {
+ if ((size_t)SCTP_BUF_LEN(m) < sizeof(*scact)) {
error = EINVAL;
break;
}
@@ -3639,7 +3632,7 @@ sctp_optsset(struct socket *so,
{
struct sctp_authkeyid *scdel;
- if ((size_t)m->m_len < sizeof(*scdel)) {
+ if ((size_t)SCTP_BUF_LEN(m) < sizeof(*scdel)) {
error = EINVAL;
break;
}
@@ -3681,7 +3674,7 @@ sctp_optsset(struct socket *so,
uint8_t send_in = 0, send_tsn = 0, send_out = 0;
int i;
- if ((size_t)m->m_len < sizeof(struct sctp_stream_reset)) {
+ if ((size_t)SCTP_BUF_LEN(m) < sizeof(struct sctp_stream_reset)) {
error = EINVAL;
break;
}
@@ -3760,7 +3753,7 @@ sctp_optsset(struct socket *so,
}
break;
case SCTP_CONNECT_X:
- if ((size_t)m->m_len < (sizeof(int) + sizeof(struct sockaddr_in))) {
+ if ((size_t)SCTP_BUF_LEN(m) < (sizeof(int) + sizeof(struct sockaddr_in))) {
error = EINVAL;
break;
}
@@ -3768,7 +3761,7 @@ sctp_optsset(struct socket *so,
break;
case SCTP_CONNECT_X_DELAYED:
- if ((size_t)m->m_len < (sizeof(int) + sizeof(struct sockaddr_in))) {
+ if ((size_t)SCTP_BUF_LEN(m) < (sizeof(int) + sizeof(struct sockaddr_in))) {
error = EINVAL;
break;
}
@@ -3780,7 +3773,7 @@ sctp_optsset(struct socket *so,
struct sockaddr *sa;
struct sctp_nets *net;
- if ((size_t)m->m_len < sizeof(struct sockaddr_in)) {
+ if ((size_t)SCTP_BUF_LEN(m) < sizeof(struct sockaddr_in)) {
error = EINVAL;
break;
}
@@ -3863,7 +3856,7 @@ sctp_optsset(struct socket *so,
{
uint32_t *level;
- if ((size_t)m->m_len < sizeof(uint32_t)) {
+ if ((size_t)SCTP_BUF_LEN(m) < sizeof(uint32_t)) {
error = EINVAL;
break;
}
@@ -3883,7 +3876,7 @@ sctp_optsset(struct socket *so,
{
struct sctp_event_subscribe *events;
- if ((size_t)m->m_len < sizeof(struct sctp_event_subscribe)) {
+ if ((size_t)SCTP_BUF_LEN(m) < sizeof(struct sctp_event_subscribe)) {
error = EINVAL;
break;
}
@@ -3956,7 +3949,7 @@ sctp_optsset(struct socket *so,
{
struct sctp_setadaptation *adap_bits;
- if ((size_t)m->m_len < sizeof(struct sctp_setadaptation)) {
+ if ((size_t)SCTP_BUF_LEN(m) < sizeof(struct sctp_setadaptation)) {
error = EINVAL;
break;
}
@@ -3970,7 +3963,7 @@ sctp_optsset(struct socket *so,
{
uint32_t *vvv;
- if ((size_t)m->m_len < sizeof(uint32_t)) {
+ if ((size_t)SCTP_BUF_LEN(m) < sizeof(uint32_t)) {
error = EINVAL;
break;
}
@@ -3984,7 +3977,7 @@ sctp_optsset(struct socket *so,
{
struct sctp_sndrcvinfo *s_info;
- if (m->m_len != sizeof(struct sctp_sndrcvinfo)) {
+ if (SCTP_BUF_LEN(m) != sizeof(struct sctp_sndrcvinfo)) {
error = EINVAL;
break;
}
@@ -4027,7 +4020,7 @@ sctp_optsset(struct socket *so,
struct sctp_paddrparams *paddrp;
struct sctp_nets *net;
- if ((size_t)m->m_len < sizeof(struct sctp_paddrparams)) {
+ if ((size_t)SCTP_BUF_LEN(m) < sizeof(struct sctp_paddrparams)) {
error = EINVAL;
break;
}
@@ -4112,7 +4105,7 @@ sctp_optsset(struct socket *so,
net->dest_state &= ~SCTP_ADDR_NOHB;
}
if (paddrp->spp_flags & SPP_PMTUD_DISABLE) {
- if (callout_pending(&net->pmtu_timer.timer)) {
+ if (SCTP_OS_TIMER_PENDING(&net->pmtu_timer.timer)) {
sctp_timer_stop(SCTP_TIMER_TYPE_PATHMTURAISE, inp, stcb, net,
SCTP_FROM_SCTP_USRREQ + SCTP_LOC_10);
}
@@ -4123,7 +4116,7 @@ sctp_optsset(struct socket *so,
}
}
if (paddrp->spp_flags & SPP_PMTUD_ENABLE) {
- if (callout_pending(&net->pmtu_timer.timer)) {
+ if (SCTP_OS_TIMER_PENDING(&net->pmtu_timer.timer)) {
sctp_timer_start(SCTP_TIMER_TYPE_PATHMTURAISE, inp, stcb, net);
}
}
@@ -4220,7 +4213,7 @@ sctp_optsset(struct socket *so,
{
struct sctp_rtoinfo *srto;
- if ((size_t)m->m_len < sizeof(struct sctp_rtoinfo)) {
+ if ((size_t)SCTP_BUF_LEN(m) < sizeof(struct sctp_rtoinfo)) {
error = EINVAL;
break;
}
@@ -4266,7 +4259,7 @@ sctp_optsset(struct socket *so,
{
struct sctp_assocparams *sasoc;
- if ((size_t)m->m_len < sizeof(struct sctp_assocparams)) {
+ if ((size_t)SCTP_BUF_LEN(m) < sizeof(struct sctp_assocparams)) {
error = EINVAL;
break;
}
@@ -4314,7 +4307,7 @@ sctp_optsset(struct socket *so,
{
struct sctp_initmsg *sinit;
- if ((size_t)m->m_len < sizeof(struct sctp_initmsg)) {
+ if ((size_t)SCTP_BUF_LEN(m) < sizeof(struct sctp_initmsg)) {
error = EINVAL;
break;
}
@@ -4343,7 +4336,7 @@ sctp_optsset(struct socket *so,
struct sctp_setprim *spa;
struct sctp_nets *net, *lnet;
- if ((size_t)m->m_len < sizeof(struct sctp_setprim)) {
+ if ((size_t)SCTP_BUF_LEN(m) < sizeof(struct sctp_setprim)) {
error = EINVAL;
break;
}
@@ -4405,7 +4398,7 @@ sctp_optsset(struct socket *so,
{
struct sctp_setpeerprim *sspp;
- if ((size_t)m->m_len < sizeof(struct sctp_setpeerprim)) {
+ if ((size_t)SCTP_BUF_LEN(m) < sizeof(struct sctp_setpeerprim)) {
error = EINVAL;
break;
}
@@ -4441,7 +4434,7 @@ sctp_optsset(struct socket *so,
error = EINVAL;
break;
}
- if ((size_t)m->m_len < sizeof(struct sctp_getaddresses)) {
+ if ((size_t)SCTP_BUF_LEN(m) < sizeof(struct sctp_getaddresses)) {
error = EINVAL;
break;
}
@@ -4517,7 +4510,7 @@ sctp_optsset(struct socket *so,
error = EINVAL;
break;
}
- if ((size_t)m->m_len < sizeof(struct sctp_getaddresses)) {
+ if ((size_t)SCTP_BUF_LEN(m) < sizeof(struct sctp_getaddresses)) {
error = EINVAL;
break;
}
@@ -4606,7 +4599,7 @@ sctp_ctloutput(struct socket *so, struct sockopt *sopt)
(void)sctp_m_free(m);
goto out;
}
- m->m_len = sopt->sopt_valsize;
+ SCTP_BUF_LEN(m) = sopt->sopt_valsize;
}
if (sopt->sopt_dir == SOPT_SET) {
error = sctp_optsset(so, sopt->sopt_name, &m, sopt->sopt_td);
@@ -4616,7 +4609,7 @@ sctp_ctloutput(struct socket *so, struct sockopt *sopt)
error = EINVAL;
}
if ((error == 0) && (m != NULL)) {
- error = sooptcopyout(sopt, mtod(m, caddr_t), m->m_len);
+ error = sooptcopyout(sopt, mtod(m, caddr_t), SCTP_BUF_LEN(m));
sctp_m_freem(m);
} else if (m != NULL) {
sctp_m_freem(m);
diff --git a/sys/netinet/sctp_var.h b/sys/netinet/sctp_var.h
index 4461074..2293cb5 100644
--- a/sys/netinet/sctp_var.h
+++ b/sys/netinet/sctp_var.h
@@ -96,11 +96,12 @@ __FBSDID("$FreeBSD$");
#define SCTPCTL_ADD_MORE 47
#define SCTPCTL_SYS_RESC 48
#define SCTPCTL_ASOC_RESC 49
+#define SCTPCTL_NAT_FRIENDLY 50
#ifdef SCTP_DEBUG
-#define SCTPCTL_DEBUG 50
-#define SCTPCTL_MAXID 50
+#define SCTPCTL_DEBUG 51
+#define SCTPCTL_MAXID 51
#else
-#define SCTPCTL_MAXID 49
+#define SCTPCTL_MAXID 50
#endif
#ifdef SCTP_DEBUG
@@ -155,6 +156,7 @@ __FBSDID("$FreeBSD$");
{ "add_more_on_output", CTLTYPE_INT }, \
{ "sys_resource", CTLTYPE_INT }, \
{ "asoc_resource", CTLTYPE_INT }, \
+ { "nat_friendly", CTLTYPE_INT }, \
{ "debug", CTLTYPE_INT }, \
}
#else
@@ -209,12 +211,12 @@ __FBSDID("$FreeBSD$");
{ "add_more_on_output", CTLTYPE_INT }, \
{ "sys_resource", CTLTYPE_INT }, \
{ "asoc_resource", CTLTYPE_INT }, \
+ { "nat_friendly", CTLTYPE_INT }, \
}
#endif
-
#if defined(_KERNEL)
#ifdef SYSCTL_DECL
@@ -317,14 +319,12 @@ extern uint32_t sctp_system_free_resc_limit;
-
-
#define sctp_free_remote_addr(__net) { \
if ((__net)) { \
if (atomic_fetchadd_int(&(__net)->ref_count, -1) == 1) { \
- callout_stop(&(__net)->rxt_timer.timer); \
- callout_stop(&(__net)->pmtu_timer.timer); \
- callout_stop(&(__net)->fr_timer.timer); \
+ SCTP_OS_TIMER_STOP(&(__net)->rxt_timer.timer); \
+ SCTP_OS_TIMER_STOP(&(__net)->pmtu_timer.timer); \
+ SCTP_OS_TIMER_STOP(&(__net)->fr_timer.timer); \
(__net)->dest_state = SCTP_ADDR_NOT_REACHABLE; \
SCTP_ZONE_FREE(sctppcbinfo.ipi_zone_net, (__net)); \
SCTP_DECR_RADDR_COUNT(); \
@@ -332,59 +332,58 @@ extern uint32_t sctp_system_free_resc_limit;
} \
}
-
#define sctp_sbfree(ctl, stcb, sb, m) { \
uint32_t val; \
- val = atomic_fetchadd_int(&(sb)->sb_cc,-((m)->m_len)); \
- if(val < (m)->m_len) { \
+ val = atomic_fetchadd_int(&(sb)->sb_cc,-(SCTP_BUF_LEN((m)))); \
+ if(val < SCTP_BUF_LEN((m))) { \
panic("sb_cc goes negative"); \
} \
val = atomic_fetchadd_int(&(sb)->sb_mbcnt,-(MSIZE)); \
if(val < MSIZE) { \
panic("sb_mbcnt goes negative"); \
} \
- if ((m)->m_flags & M_EXT) { \
- val = atomic_fetchadd_int(&(sb)->sb_mbcnt,-((m)->m_ext.ext_size)); \
- if(val < (m)->m_ext.ext_size) { \
+ if (SCTP_BUF_IS_EXTENDED(m)) { \
+ val = atomic_fetchadd_int(&(sb)->sb_mbcnt,-(SCTP_BUF_EXTEND_SIZE(m))); \
+ if(val < SCTP_BUF_EXTEND_SIZE(m)) { \
panic("sb_mbcnt goes negative2"); \
} \
} \
if (((ctl)->do_not_ref_stcb == 0) && stcb) {\
- val = atomic_fetchadd_int(&(stcb)->asoc.sb_cc,-((m)->m_len)); \
- if(val < (m)->m_len) {\
+ val = atomic_fetchadd_int(&(stcb)->asoc.sb_cc,-(SCTP_BUF_LEN((m)))); \
+ if(val < SCTP_BUF_LEN((m))) {\
panic("stcb->sb_cc goes negative"); \
} \
val = atomic_fetchadd_int(&(stcb)->asoc.sb_mbcnt,-(MSIZE)); \
if(val < MSIZE) { \
panic("asoc->mbcnt goes negative"); \
} \
- if ((m)->m_flags & M_EXT) { \
- val = atomic_fetchadd_int(&(stcb)->asoc.sb_mbcnt,-((m)->m_ext.ext_size)); \
- if(val < (m)->m_ext.ext_size) { \
+ if (SCTP_BUF_IS_EXTENDED(m)) { \
+ val = atomic_fetchadd_int(&(stcb)->asoc.sb_mbcnt,-(SCTP_BUF_EXTEND_SIZE(m))); \
+ if(val < SCTP_BUF_EXTEND_SIZE(m)) { \
panic("assoc stcb->mbcnt would go negative"); \
} \
} \
} \
- if ((m)->m_type != MT_DATA && (m)->m_type != MT_HEADER && \
- (m)->m_type != MT_OOBDATA) \
- atomic_subtract_int(&(sb)->sb_ctl,(m)->m_len); \
+ if (SCTP_BUF_TYPE(m) != MT_DATA && SCTP_BUF_TYPE(m) != MT_HEADER && \
+ SCTP_BUF_TYPE(m) != MT_OOBDATA) \
+ atomic_subtract_int(&(sb)->sb_ctl,SCTP_BUF_LEN((m))); \
}
#define sctp_sballoc(stcb, sb, m) { \
- atomic_add_int(&(sb)->sb_cc,(m)->m_len); \
+ atomic_add_int(&(sb)->sb_cc,SCTP_BUF_LEN((m))); \
atomic_add_int(&(sb)->sb_mbcnt, MSIZE); \
- if ((m)->m_flags & M_EXT) \
- atomic_add_int(&(sb)->sb_mbcnt,(m)->m_ext.ext_size); \
+ if (SCTP_BUF_IS_EXTENDED(m)) \
+ atomic_add_int(&(sb)->sb_mbcnt,SCTP_BUF_EXTEND_SIZE(m)); \
if(stcb) { \
- atomic_add_int(&(stcb)->asoc.sb_cc,(m)->m_len); \
+ atomic_add_int(&(stcb)->asoc.sb_cc,SCTP_BUF_LEN((m))); \
atomic_add_int(&(stcb)->asoc.sb_mbcnt, MSIZE); \
- if ((m)->m_flags & M_EXT) \
- atomic_add_int(&(stcb)->asoc.sb_mbcnt,(m)->m_ext.ext_size); \
+ if (SCTP_BUF_IS_EXTENDED(m)) \
+ atomic_add_int(&(stcb)->asoc.sb_mbcnt,SCTP_BUF_EXTEND_SIZE(m)); \
} \
- if ((m)->m_type != MT_DATA && (m)->m_type != MT_HEADER && \
- (m)->m_type != MT_OOBDATA) \
- atomic_add_int(&(sb)->sb_ctl,(m)->m_len); \
+ if (SCTP_BUF_TYPE(m) != MT_DATA && SCTP_BUF_TYPE(m) != MT_HEADER && \
+ SCTP_BUF_TYPE(m) != MT_OOBDATA) \
+ atomic_add_int(&(sb)->sb_ctl,SCTP_BUF_LEN((m))); \
}
@@ -403,15 +402,18 @@ extern uint32_t sctp_system_free_resc_limit;
#define sctp_mbuf_crush(data) do { \
struct mbuf *_m; \
_m = (data); \
- while(_m && (_m->m_len == 0)) { \
- (data) = _m->m_next; \
- _m->m_next = NULL; \
+ while(_m && (SCTP_BUF_LEN(_m) == 0)) { \
+ (data) = SCTP_BUF_NEXT(_m); \
+ SCTP_BUF_NEXT(_m) = NULL; \
sctp_m_free(_m); \
_m = (data); \
} \
} while (0)
+/*
+ * some sysctls
+ */
extern int sctp_sendspace;
extern int sctp_recvspace;
extern int sctp_ecn_enable;
@@ -420,12 +422,13 @@ extern int sctp_use_cwnd_based_maxburst;
extern unsigned int sctp_cmt_on_off;
extern unsigned int sctp_cmt_use_dac;
extern unsigned int sctp_cmt_sockopt_on_off;
+extern uint32_t sctp_nat_friendly;
+
struct sctp_nets;
struct sctp_inpcb;
struct sctp_tcb;
struct sctphdr;
-
void sctp_ctlinput __P((int, struct sockaddr *, void *));
int sctp_ctloutput __P((struct socket *, struct sockopt *));
void sctp_input __P((struct mbuf *, int));
@@ -450,11 +453,9 @@ __P((struct sctp_inpcb *, int, struct sctphdr *,
/* can't use sctp_assoc_t here */
int sctp_peeloff(struct socket *, struct socket *, int, caddr_t, int *);
-
sctp_assoc_t sctp_getassocid(struct sockaddr *);
-
int sctp_ingetaddr(struct socket *,
struct sockaddr **
);
@@ -465,12 +466,9 @@ __P((struct sctp_inpcb *, int, struct sctphdr *,
int sctp_listen(struct socket *, int, struct thread *);
-
int sctp_accept(struct socket *, struct sockaddr **);
-
-
#endif /* _KERNEL */
#endif /* !_NETINET_SCTP_VAR_H_ */
diff --git a/sys/netinet/sctputil.c b/sys/netinet/sctputil.c
index 18fe59d..6882cee 100644
--- a/sys/netinet/sctputil.c
+++ b/sys/netinet/sctputil.c
@@ -63,8 +63,6 @@ __FBSDID("$FreeBSD$");
#include <sys/uio.h>
#include <sys/jail.h>
-#include <sys/callout.h>
-
#include <net/radix.h>
#include <net/route.h>
@@ -300,12 +298,12 @@ sctp_log_mb(struct mbuf *m, int from)
sctp_clog[sctp_cwnd_log_at].from = (uint8_t) from;
sctp_clog[sctp_cwnd_log_at].event_type = (uint8_t) SCTP_LOG_EVENT_MBUF;
sctp_clog[sctp_cwnd_log_at].x.mb.mp = m;
- sctp_clog[sctp_cwnd_log_at].x.mb.mbuf_flags = (uint8_t) (m->m_flags);
- sctp_clog[sctp_cwnd_log_at].x.mb.size = (uint16_t) (m->m_len);
- sctp_clog[sctp_cwnd_log_at].x.mb.data = m->m_data;
- if (m->m_flags & M_EXT) {
- sctp_clog[sctp_cwnd_log_at].x.mb.ext = m->m_ext.ext_buf;
- sctp_clog[sctp_cwnd_log_at].x.mb.refcnt = (uint8_t) (*m->m_ext.ref_cnt);
+ sctp_clog[sctp_cwnd_log_at].x.mb.mbuf_flags = (uint8_t) (SCTP_BUF_GET_FLAGS(m));
+ sctp_clog[sctp_cwnd_log_at].x.mb.size = (uint16_t) (SCTP_BUF_LEN(m));
+ sctp_clog[sctp_cwnd_log_at].x.mb.data = SCTP_BUF_AT(m, 0);
+ if (SCTP_BUF_IS_EXTENDED(m)) {
+ sctp_clog[sctp_cwnd_log_at].x.mb.ext = SCTP_BUF_EXTEND_BASE(m);
+ sctp_clog[sctp_cwnd_log_at].x.mb.refcnt = (uint8_t) (SCTP_BUF_EXTEND_REFCNT(m));
} else {
sctp_clog[sctp_cwnd_log_at].x.mb.ext = 0;
sctp_clog[sctp_cwnd_log_at].x.mb.refcnt = 0;
@@ -567,7 +565,7 @@ sctp_fill_stat_log(struct mbuf *m)
if (m == NULL)
return (EINVAL);
- size_limit = (m->m_len - sizeof(struct sctp_cwnd_log_req));
+ size_limit = (SCTP_BUF_LEN(m) - sizeof(struct sctp_cwnd_log_req));
if (size_limit < sizeof(struct sctp_cwnd_log)) {
return (EINVAL);
}
@@ -637,7 +635,7 @@ sctp_fill_stat_log(struct mbuf *m)
if (at >= SCTP_STAT_LOG_SIZE)
at = 0;
}
- m->m_len = (cnt_out * sizeof(struct sctp_cwnd_log)) + sizeof(struct sctp_cwnd_log_req);
+ SCTP_BUF_LEN(m) = (cnt_out * sizeof(struct sctp_cwnd_log)) + sizeof(struct sctp_cwnd_log_req);
return (0);
}
@@ -875,15 +873,15 @@ sctp_stop_timers_for_shutdown(struct sctp_tcb *stcb)
asoc = &stcb->asoc;
- callout_stop(&asoc->hb_timer.timer);
- callout_stop(&asoc->dack_timer.timer);
- callout_stop(&asoc->strreset_timer.timer);
- callout_stop(&asoc->asconf_timer.timer);
- callout_stop(&asoc->autoclose_timer.timer);
- callout_stop(&asoc->delayed_event_timer.timer);
+ SCTP_OS_TIMER_STOP(&asoc->hb_timer.timer);
+ SCTP_OS_TIMER_STOP(&asoc->dack_timer.timer);
+ SCTP_OS_TIMER_STOP(&asoc->strreset_timer.timer);
+ SCTP_OS_TIMER_STOP(&asoc->asconf_timer.timer);
+ SCTP_OS_TIMER_STOP(&asoc->autoclose_timer.timer);
+ SCTP_OS_TIMER_STOP(&asoc->delayed_event_timer.timer);
TAILQ_FOREACH(net, &asoc->nets, sctp_next) {
- callout_stop(&net->fr_timer.timer);
- callout_stop(&net->pmtu_timer.timer);
+ SCTP_OS_TIMER_STOP(&net->fr_timer.timer);
+ SCTP_OS_TIMER_STOP(&net->pmtu_timer.timer);
}
}
@@ -935,7 +933,7 @@ sctp_select_initial_TSN(struct sctp_pcb *m)
* the initial stream sequence number, using RFC1750 as a good
* guideline
*/
- u_long x, *xp;
+ uint32_t x, *xp;
uint8_t *p;
if (m->initial_sequence_debug != 0) {
@@ -950,9 +948,9 @@ sctp_select_initial_TSN(struct sctp_pcb *m)
sctp_fill_random_store(m);
}
p = &m->random_store[(int)m->store_at];
- xp = (u_long *)p;
+ xp = (uint32_t *) p;
x = *xp;
- m->store_at += sizeof(u_long);
+ m->store_at += sizeof(uint32_t);
return (x);
}
@@ -1015,6 +1013,7 @@ sctp_init_asoc(struct sctp_inpcb *m, struct sctp_association *asoc,
if (override_tag) {
struct timeval now;
+ SCTP_GETTIME_TIMEVAL(&now);
if (sctp_is_vtag_good(m, override_tag, &now)) {
asoc->my_vtag = override_tag;
} else {
@@ -1319,7 +1318,7 @@ sctp_timeout_handler(void *t)
printf("Timer type %d goes off\n", tmr->type);
}
#endif /* SCTP_DEBUG */
- if (!callout_active(&tmr->timer)) {
+ if (!SCTP_OS_TIMER_ACTIVE(&tmr->timer)) {
splx(s);
if (inp) {
SCTP_INP_DECR_REF(inp);
@@ -1336,7 +1335,7 @@ sctp_timeout_handler(void *t)
atomic_add_int(&stcb->asoc.refcnt, -1);
}
/* mark as being serviced now */
- callout_deactivate(&tmr->timer);
+ SCTP_OS_TIMER_DEACTIVATE(&tmr->timer);
/* call the handler for the appropriate timer type */
switch (tmr->type) {
@@ -1602,9 +1601,7 @@ sctp_timer_start(int t_type, struct sctp_inpcb *inp, struct sctp_tcb *stcb,
int to_ticks;
struct sctp_timer *tmr;
-
- if ((t_type != SCTP_TIMER_TYPE_ADDR_WQ) &&
- (inp == NULL))
+ if ((t_type != SCTP_TIMER_TYPE_ADDR_WQ) && (inp == NULL))
return (EFAULT);
to_ticks = 0;
@@ -1929,7 +1926,7 @@ sctp_timer_start(int t_type, struct sctp_inpcb *inp, struct sctp_tcb *stcb,
#endif /* SCTP_DEBUG */
return (EFAULT);
}
- if (callout_pending(&tmr->timer)) {
+ if (SCTP_OS_TIMER_PENDING(&tmr->timer)) {
/*
* we do NOT allow you to have it already running. if it is
* we leave the current one up unchanged
@@ -1947,7 +1944,7 @@ sctp_timer_start(int t_type, struct sctp_inpcb *inp, struct sctp_tcb *stcb,
tmr->net = (void *)net;
tmr->self = (void *)tmr;
tmr->ticks = ticks;
- callout_reset(&tmr->timer, to_ticks, sctp_timeout_handler, tmr);
+ SCTP_OS_TIMER_START(&tmr->timer, to_ticks, sctp_timeout_handler, tmr);
return (0);
}
@@ -2111,7 +2108,7 @@ sctp_timer_stop(int t_type, struct sctp_inpcb *inp, struct sctp_tcb *stcb,
}
tmr->self = NULL;
tmr->stopped_from = from;
- callout_stop(&tmr->timer);
+ SCTP_OS_TIMER_STOP(&tmr->timer);
return (0);
}
@@ -2165,8 +2162,8 @@ sctp_calculate_len(struct mbuf *m)
at = m;
while (at) {
- tlen += at->m_len;
- at = at->m_next;
+ tlen += SCTP_BUF_LEN(at);
+ at = SCTP_BUF_NEXT(at);
}
return (tlen);
}
@@ -2179,11 +2176,11 @@ sctp_calculate_sum(struct mbuf *m, int32_t * pktlen, uint32_t offset)
/*
* given a mbuf chain with a packetheader offset by 'offset'
* pointing at a sctphdr (with csum set to 0) go through the chain
- * of m_next's and calculate the SCTP checksum. This is currently
- * Adler32 but will change to CRC32x soon. Also has a side bonus
- * calculate the total length of the mbuf chain. Note: if offset is
- * greater than the total mbuf length, checksum=1, pktlen=0 is
- * returned (ie. no real error code)
+ * of SCTP_BUF_NEXT()'s and calculate the SCTP checksum. This is
+ * currently Adler32 but will change to CRC32x soon. Also has a side
+ * bonus calculate the total length of the mbuf chain. Note: if
+ * offset is greater than the total mbuf length, checksum=1,
+ * pktlen=0 is returned (ie. no real error code)
*/
if (pktlen == NULL)
return (0);
@@ -2201,11 +2198,11 @@ sctp_calculate_sum(struct mbuf *m, int32_t * pktlen, uint32_t offset)
/*
* given a mbuf chain with a packetheader offset by 'offset'
* pointing at a sctphdr (with csum set to 0) go through the chain
- * of m_next's and calculate the SCTP checksum. This is currently
- * Adler32 but will change to CRC32x soon. Also has a side bonus
- * calculate the total length of the mbuf chain. Note: if offset is
- * greater than the total mbuf length, checksum=1, pktlen=0 is
- * returned (ie. no real error code)
+ * of SCTP_BUF_NEXT()'s and calculate the SCTP checksum. This is
+ * currently Adler32 but will change to CRC32x soon. Also has a side
+ * bonus calculate the total length of the mbuf chain. Note: if
+ * offset is greater than the total mbuf length, checksum=1,
+ * pktlen=0 is returned (ie. no real error code)
*/
int32_t tlen = 0;
struct mbuf *at;
@@ -2213,8 +2210,8 @@ sctp_calculate_sum(struct mbuf *m, int32_t * pktlen, uint32_t offset)
at = m;
while (at) {
- tlen += at->m_len;
- at = at->m_next;
+ tlen += SCTP_BUF_LEN(at);
+ at = SCTP_BUF_NEXT(at);
}
the_sum = (uint32_t) (in_cksum_skip(m, tlen, offset));
if (pktlen != NULL)
@@ -2231,11 +2228,11 @@ sctp_calculate_sum(struct mbuf *m, int32_t * pktlen, uint32_t offset)
/*
* given a mbuf chain with a packetheader offset by 'offset'
* pointing at a sctphdr (with csum set to 0) go through the chain
- * of m_next's and calculate the SCTP checksum. This is currently
- * Adler32 but will change to CRC32x soon. Also has a side bonus
- * calculate the total length of the mbuf chain. Note: if offset is
- * greater than the total mbuf length, checksum=1, pktlen=0 is
- * returned (ie. no real error code)
+ * of SCTP_BUF_NEXT()'s and calculate the SCTP checksum. This is
+ * currently Adler32 but will change to CRC32x soon. Also has a side
+ * bonus calculate the total length of the mbuf chain. Note: if
+ * offset is greater than the total mbuf length, checksum=1,
+ * pktlen=0 is returned (ie. no real error code)
*/
int32_t tlen = 0;
@@ -2250,38 +2247,39 @@ sctp_calculate_sum(struct mbuf *m, int32_t * pktlen, uint32_t offset)
at = m;
/* find the correct mbuf and offset into mbuf */
- while ((at != NULL) && (offset > (uint32_t) at->m_len)) {
- offset -= at->m_len; /* update remaining offset left */
- at = at->m_next;
+ while ((at != NULL) && (offset > (uint32_t) SCTP_BUF_LEN(at))) {
+ offset -= SCTP_BUF_LEN(at); /* update remaining offset
+ * left */
+ at = SCTP_BUF_NEXT(at);
}
while (at != NULL) {
- if ((at->m_len - offset) > 0) {
+ if ((SCTP_BUF_LEN(at) - offset) > 0) {
#ifdef SCTP_USE_ADLER32
base = update_adler32(base,
- (unsigned char *)(at->m_data + offset),
- (unsigned int)(at->m_len - offset));
+ (unsigned char *)(SCTP_BUF_AT(at, offset)),
+ (unsigned int)(SCTP_BUF_LEN(at) - offset));
#else
- if ((at->m_len - offset) < 4) {
+ if ((SCTP_BUF_LEN(at) - offset) < 4) {
/* Use old method if less than 4 bytes */
base = old_update_crc32(base,
- (unsigned char *)(at->m_data + offset),
- (unsigned int)(at->m_len - offset));
+ (unsigned char *)(SCTP_BUF_AT(at, offset)),
+ (unsigned int)(SCTP_BUF_LEN(at) - offset));
} else {
base = update_crc32(base,
- (unsigned char *)(at->m_data + offset),
- (unsigned int)(at->m_len - offset));
+ (unsigned char *)(SCTP_BUF_AT(at, offset)),
+ (unsigned int)(SCTP_BUF_LEN(at) - offset));
}
#endif /* SCTP_USE_ADLER32 */
- tlen += at->m_len - offset;
+ tlen += SCTP_BUF_LEN(at) - offset;
/* we only offset once into the first mbuf */
}
if (offset) {
- if (offset < at->m_len)
+ if (offset < SCTP_BUF_LEN(at))
offset = 0;
else
- offset -= at->m_len;
+ offset -= SCTP_BUF_LEN(at);
}
- at = at->m_next;
+ at = SCTP_BUF_NEXT(at);
}
if (pktlen != NULL) {
*pktlen = tlen;
@@ -2471,26 +2469,26 @@ sctp_m_getptr(struct mbuf *m, int off, int len, uint8_t * in_ptr)
/* find the desired start location */
while ((m != NULL) && (off > 0)) {
- if (off < m->m_len)
+ if (off < SCTP_BUF_LEN(m))
break;
- off -= m->m_len;
- m = m->m_next;
+ off -= SCTP_BUF_LEN(m);
+ m = SCTP_BUF_NEXT(m);
}
if (m == NULL)
return (NULL);
/* is the current mbuf large enough (eg. contiguous)? */
- if ((m->m_len - off) >= len) {
+ if ((SCTP_BUF_LEN(m) - off) >= len) {
return (mtod(m, caddr_t)+off);
} else {
/* else, it spans more than one mbuf, so save a temp copy... */
while ((m != NULL) && (len > 0)) {
- count = min(m->m_len - off, len);
+ count = min(SCTP_BUF_LEN(m) - off, len);
bcopy(mtod(m, caddr_t)+off, ptr, count);
len -= count;
ptr += count;
off = 0;
- m = m->m_next;
+ m = SCTP_BUF_NEXT(m);
}
if ((m == NULL) && (len > 0))
return (NULL);
@@ -2530,8 +2528,8 @@ sctp_add_pad_tombuf(struct mbuf *m, int padlen)
* The easy way. We hope the majority of the time we hit
* here :)
*/
- dp = (uint8_t *) (mtod(m, caddr_t)+m->m_len);
- m->m_len += padlen;
+ dp = (uint8_t *) (mtod(m, caddr_t)+SCTP_BUF_LEN(m));
+ SCTP_BUF_LEN(m) += padlen;
} else {
/* Hard way we must grow the mbuf */
struct mbuf *tmp;
@@ -2542,9 +2540,9 @@ sctp_add_pad_tombuf(struct mbuf *m, int padlen)
return (ENOSPC);
}
/* setup and insert in middle */
- tmp->m_next = m->m_next;
- tmp->m_len = padlen;
- m->m_next = tmp;
+ SCTP_BUF_NEXT(tmp) = SCTP_BUF_NEXT(m);
+ SCTP_BUF_LEN(tmp) = padlen;
+ SCTP_BUF_NEXT(m) = tmp;
dp = mtod(tmp, uint8_t *);
}
/* zero out the pad */
@@ -2566,10 +2564,10 @@ sctp_pad_lastmbuf(struct mbuf *m, int padval, struct mbuf *last_mbuf)
return (sctp_add_pad_tombuf(last_mbuf, padval));
} else {
while (m_at) {
- if (m_at->m_next == NULL) {
+ if (SCTP_BUF_NEXT(m_at) == NULL) {
return (sctp_add_pad_tombuf(m_at, padval));
}
- m_at = m_at->m_next;
+ m_at = SCTP_BUF_NEXT(m_at);
}
}
return (EFAULT);
@@ -2616,11 +2614,11 @@ sctp_notify_assoc_change(uint32_t event, struct sctp_tcb *stcb,
/* event not enabled */
return;
}
- m_notify = sctp_get_mbuf_for_msg(sizeof(struct sctp_assoc_change), 1, M_DONTWAIT, 1, MT_DATA);
+ m_notify = sctp_get_mbuf_for_msg(sizeof(struct sctp_assoc_change), 0, M_DONTWAIT, 1, MT_DATA);
if (m_notify == NULL)
/* no space left */
return;
- m_notify->m_len = 0;
+ SCTP_BUF_LEN(m_notify) = 0;
sac = mtod(m_notify, struct sctp_assoc_change *);
sac->sac_type = SCTP_ASSOC_CHANGE;
@@ -2632,11 +2630,8 @@ sctp_notify_assoc_change(uint32_t event, struct sctp_tcb *stcb,
sac->sac_outbound_streams = stcb->asoc.streamoutcnt;
sac->sac_inbound_streams = stcb->asoc.streamincnt;
sac->sac_assoc_id = sctp_get_associd(stcb);
- m_notify->m_flags |= M_EOR | M_NOTIFICATION;
- m_notify->m_pkthdr.len = sizeof(struct sctp_assoc_change);
- m_notify->m_pkthdr.rcvif = 0;
- m_notify->m_len = sizeof(struct sctp_assoc_change);
- m_notify->m_next = NULL;
+ SCTP_BUF_LEN(m_notify) = sizeof(struct sctp_assoc_change);
+ SCTP_BUF_NEXT(m_notify) = NULL;
control = sctp_build_readq_entry(stcb, stcb->asoc.primary_destination,
0, 0, 0, 0, 0, 0,
m_notify);
@@ -2645,9 +2640,10 @@ sctp_notify_assoc_change(uint32_t event, struct sctp_tcb *stcb,
sctp_m_freem(m_notify);
return;
}
- control->length = m_notify->m_len;
+ control->length = SCTP_BUF_LEN(m_notify);
/* not that we need this */
control->tail_mbuf = m_notify;
+ control->spec_flags = M_NOTIFICATION;
sctp_add_to_readq(stcb->sctp_ep, stcb,
control,
&stcb->sctp_socket->so_rcv, 1);
@@ -2669,10 +2665,10 @@ sctp_notify_peer_addr_change(struct sctp_tcb *stcb, uint32_t state,
/* event not enabled */
return;
- m_notify = sctp_get_mbuf_for_msg(sizeof(struct sctp_paddr_change), 1, M_DONTWAIT, 1, MT_DATA);
+ m_notify = sctp_get_mbuf_for_msg(sizeof(struct sctp_paddr_change), 0, M_DONTWAIT, 1, MT_DATA);
if (m_notify == NULL)
return;
- m_notify->m_len = 0;
+ SCTP_BUF_LEN(m_notify) = 0;
spc = mtod(m_notify, struct sctp_paddr_change *);
spc->spc_type = SCTP_PEER_ADDR_CHANGE;
spc->spc_flags = 0;
@@ -2686,11 +2682,8 @@ sctp_notify_peer_addr_change(struct sctp_tcb *stcb, uint32_t state,
spc->spc_error = error;
spc->spc_assoc_id = sctp_get_associd(stcb);
- m_notify->m_flags |= M_EOR | M_NOTIFICATION;
- m_notify->m_pkthdr.len = sizeof(struct sctp_paddr_change);
- m_notify->m_pkthdr.rcvif = 0;
- m_notify->m_len = sizeof(struct sctp_paddr_change);
- m_notify->m_next = NULL;
+ SCTP_BUF_LEN(m_notify) = sizeof(struct sctp_paddr_change);
+ SCTP_BUF_NEXT(m_notify) = NULL;
/* append to socket */
control = sctp_build_readq_entry(stcb, stcb->asoc.primary_destination,
@@ -2701,7 +2694,8 @@ sctp_notify_peer_addr_change(struct sctp_tcb *stcb, uint32_t state,
sctp_m_freem(m_notify);
return;
}
- control->length = m_notify->m_len;
+ control->length = SCTP_BUF_LEN(m_notify);
+ control->spec_flags = M_NOTIFICATION;
/* not that we need this */
control->tail_mbuf = m_notify;
sctp_add_to_readq(stcb->sctp_ep, stcb,
@@ -2724,11 +2718,11 @@ sctp_notify_send_failed(struct sctp_tcb *stcb, uint32_t error,
return;
length = sizeof(struct sctp_send_failed) + chk->send_size;
- m_notify = sctp_get_mbuf_for_msg(sizeof(struct sctp_send_failed), 1, M_DONTWAIT, 1, MT_DATA);
+ m_notify = sctp_get_mbuf_for_msg(sizeof(struct sctp_send_failed), 0, M_DONTWAIT, 1, MT_DATA);
if (m_notify == NULL)
/* no space left */
return;
- m_notify->m_len = 0;
+ SCTP_BUF_LEN(m_notify) = 0;
ssf = mtod(m_notify, struct sctp_send_failed *);
ssf->ssf_type = SCTP_SEND_FAILED;
if (error == SCTP_NOTIFY_DATAGRAM_UNSENT)
@@ -2745,11 +2739,8 @@ sctp_notify_send_failed(struct sctp_tcb *stcb, uint32_t error,
ssf->ssf_info.sinfo_context = chk->rec.data.context;
ssf->ssf_info.sinfo_assoc_id = sctp_get_associd(stcb);
ssf->ssf_assoc_id = sctp_get_associd(stcb);
- m_notify->m_next = chk->data;
- m_notify->m_flags |= M_NOTIFICATION;
- m_notify->m_pkthdr.len = length;
- m_notify->m_pkthdr.rcvif = 0;
- m_notify->m_len = sizeof(struct sctp_send_failed);
+ SCTP_BUF_NEXT(m_notify) = chk->data;
+ SCTP_BUF_LEN(m_notify) = sizeof(struct sctp_send_failed);
/* Steal off the mbuf */
chk->data = NULL;
@@ -2758,7 +2749,7 @@ sctp_notify_send_failed(struct sctp_tcb *stcb, uint32_t error,
* is going away we don't want to overfill the socket buffer for a
* non-reader
*/
- if (sctp_sbspace_failedmsgs(&stcb->sctp_socket->so_rcv) < m_notify->m_len) {
+ if (sctp_sbspace_failedmsgs(&stcb->sctp_socket->so_rcv) < SCTP_BUF_LEN(m_notify)) {
sctp_m_freem(m_notify);
return;
}
@@ -2771,6 +2762,7 @@ sctp_notify_send_failed(struct sctp_tcb *stcb, uint32_t error,
sctp_m_freem(m_notify);
return;
}
+ control->spec_flags = M_NOTIFICATION;
sctp_add_to_readq(stcb->sctp_ep, stcb,
control,
&stcb->sctp_socket->so_rcv, 1);
@@ -2791,11 +2783,11 @@ sctp_notify_send_failed2(struct sctp_tcb *stcb, uint32_t error,
return;
length = sizeof(struct sctp_send_failed) + sp->length;
- m_notify = sctp_get_mbuf_for_msg(sizeof(struct sctp_adaption_event), 1, M_DONTWAIT, 1, MT_DATA);
+ m_notify = sctp_get_mbuf_for_msg(sizeof(struct sctp_adaption_event), 0, M_DONTWAIT, 1, MT_DATA);
if (m_notify == NULL)
/* no space left */
return;
- m_notify->m_len = 0;
+ SCTP_BUF_LEN(m_notify) = 0;
ssf = mtod(m_notify, struct sctp_send_failed *);
ssf->ssf_type = SCTP_SEND_FAILED;
if (error == SCTP_NOTIFY_DATAGRAM_UNSENT)
@@ -2812,11 +2804,8 @@ sctp_notify_send_failed2(struct sctp_tcb *stcb, uint32_t error,
ssf->ssf_info.sinfo_context = sp->context;
ssf->ssf_info.sinfo_assoc_id = sctp_get_associd(stcb);
ssf->ssf_assoc_id = sctp_get_associd(stcb);
- m_notify->m_next = sp->data;
- m_notify->m_flags |= M_NOTIFICATION;
- m_notify->m_pkthdr.len = length;
- m_notify->m_pkthdr.rcvif = 0;
- m_notify->m_len = sizeof(struct sctp_send_failed);
+ SCTP_BUF_NEXT(m_notify) = sp->data;
+ SCTP_BUF_LEN(m_notify) = sizeof(struct sctp_send_failed);
/* Steal off the mbuf */
sp->data = NULL;
@@ -2825,7 +2814,7 @@ sctp_notify_send_failed2(struct sctp_tcb *stcb, uint32_t error,
* is going away we don't want to overfill the socket buffer for a
* non-reader
*/
- if (sctp_sbspace_failedmsgs(&stcb->sctp_socket->so_rcv) < m_notify->m_len) {
+ if (sctp_sbspace_failedmsgs(&stcb->sctp_socket->so_rcv) < SCTP_BUF_LEN(m_notify)) {
sctp_m_freem(m_notify);
return;
}
@@ -2838,6 +2827,7 @@ sctp_notify_send_failed2(struct sctp_tcb *stcb, uint32_t error,
sctp_m_freem(m_notify);
return;
}
+ control->spec_flags = M_NOTIFICATION;
sctp_add_to_readq(stcb->sctp_ep, stcb,
control,
&stcb->sctp_socket->so_rcv, 1);
@@ -2857,11 +2847,11 @@ sctp_notify_adaptation_layer(struct sctp_tcb *stcb,
/* event not enabled */
return;
- m_notify = sctp_get_mbuf_for_msg(sizeof(struct sctp_adaption_event), 1, M_DONTWAIT, 1, MT_DATA);
+ m_notify = sctp_get_mbuf_for_msg(sizeof(struct sctp_adaption_event), 0, M_DONTWAIT, 1, MT_DATA);
if (m_notify == NULL)
/* no space left */
return;
- m_notify->m_len = 0;
+ SCTP_BUF_LEN(m_notify) = 0;
sai = mtod(m_notify, struct sctp_adaptation_event *);
sai->sai_type = SCTP_ADAPTATION_INDICATION;
sai->sai_flags = 0;
@@ -2869,11 +2859,8 @@ sctp_notify_adaptation_layer(struct sctp_tcb *stcb,
sai->sai_adaptation_ind = error;
sai->sai_assoc_id = sctp_get_associd(stcb);
- m_notify->m_flags |= M_EOR | M_NOTIFICATION;
- m_notify->m_pkthdr.len = sizeof(struct sctp_adaptation_event);
- m_notify->m_pkthdr.rcvif = 0;
- m_notify->m_len = sizeof(struct sctp_adaptation_event);
- m_notify->m_next = NULL;
+ SCTP_BUF_LEN(m_notify) = sizeof(struct sctp_adaptation_event);
+ SCTP_BUF_NEXT(m_notify) = NULL;
/* append to socket */
control = sctp_build_readq_entry(stcb, stcb->asoc.primary_destination,
@@ -2884,7 +2871,8 @@ sctp_notify_adaptation_layer(struct sctp_tcb *stcb,
sctp_m_freem(m_notify);
return;
}
- control->length = m_notify->m_len;
+ control->length = SCTP_BUF_LEN(m_notify);
+ control->spec_flags = M_NOTIFICATION;
/* not that we need this */
control->tail_mbuf = m_notify;
sctp_add_to_readq(stcb->sctp_ep, stcb,
@@ -2906,11 +2894,11 @@ sctp_notify_partial_delivery_indication(struct sctp_tcb *stcb,
/* event not enabled */
return;
- m_notify = sctp_get_mbuf_for_msg(sizeof(struct sctp_pdapi_event), 1, M_DONTWAIT, 1, MT_DATA);
+ m_notify = sctp_get_mbuf_for_msg(sizeof(struct sctp_pdapi_event), 0, M_DONTWAIT, 1, MT_DATA);
if (m_notify == NULL)
/* no space left */
return;
- m_notify->m_len = 0;
+ SCTP_BUF_LEN(m_notify) = 0;
pdapi = mtod(m_notify, struct sctp_pdapi_event *);
pdapi->pdapi_type = SCTP_PARTIAL_DELIVERY_EVENT;
pdapi->pdapi_flags = 0;
@@ -2918,11 +2906,8 @@ sctp_notify_partial_delivery_indication(struct sctp_tcb *stcb,
pdapi->pdapi_indication = error;
pdapi->pdapi_assoc_id = sctp_get_associd(stcb);
- m_notify->m_flags |= M_EOR | M_NOTIFICATION;
- m_notify->m_pkthdr.len = sizeof(struct sctp_pdapi_event);
- m_notify->m_pkthdr.rcvif = 0;
- m_notify->m_len = sizeof(struct sctp_pdapi_event);
- m_notify->m_next = NULL;
+ SCTP_BUF_LEN(m_notify) = sizeof(struct sctp_pdapi_event);
+ SCTP_BUF_NEXT(m_notify) = NULL;
control = sctp_build_readq_entry(stcb, stcb->asoc.primary_destination,
0, 0, 0, 0, 0, 0,
m_notify);
@@ -2931,7 +2916,8 @@ sctp_notify_partial_delivery_indication(struct sctp_tcb *stcb,
sctp_m_freem(m_notify);
return;
}
- control->length = m_notify->m_len;
+ control->spec_flags = M_NOTIFICATION;
+ control->length = SCTP_BUF_LEN(m_notify);
/* not that we need this */
control->tail_mbuf = m_notify;
control->held_length = 0;
@@ -2941,13 +2927,13 @@ sctp_notify_partial_delivery_indication(struct sctp_tcb *stcb,
}
sb = &stcb->sctp_socket->so_rcv;
#ifdef SCTP_SB_LOGGING
- sctp_sblog(sb, control->do_not_ref_stcb ? NULL : stcb, SCTP_LOG_SBALLOC, m_notify->m_len);
+ sctp_sblog(sb, control->do_not_ref_stcb ? NULL : stcb, SCTP_LOG_SBALLOC, SCTP_BUF_LEN(m_notify));
#endif
sctp_sballoc(stcb, sb, m_notify);
#ifdef SCTP_SB_LOGGING
sctp_sblog(sb, control->do_not_ref_stcb ? NULL : stcb, SCTP_LOG_SBRESULT, 0);
#endif
- atomic_add_int(&control->length, m_notify->m_len);
+ atomic_add_int(&control->length, SCTP_BUF_LEN(m_notify));
control->end_added = 1;
if (stcb->asoc.control_pdapi)
TAILQ_INSERT_AFTER(&stcb->sctp_ep->read_queue, stcb->asoc.control_pdapi, control, next);
@@ -2984,22 +2970,18 @@ sctp_notify_shutdown_event(struct sctp_tcb *stcb)
/* event not enabled */
return;
- m_notify = sctp_get_mbuf_for_msg(sizeof(struct sctp_shutdown_event), 1, M_DONTWAIT, 1, MT_DATA);
+ m_notify = sctp_get_mbuf_for_msg(sizeof(struct sctp_shutdown_event), 0, M_DONTWAIT, 1, MT_DATA);
if (m_notify == NULL)
/* no space left */
return;
- m_notify->m_len = 0;
sse = mtod(m_notify, struct sctp_shutdown_event *);
sse->sse_type = SCTP_SHUTDOWN_EVENT;
sse->sse_flags = 0;
sse->sse_length = sizeof(struct sctp_shutdown_event);
sse->sse_assoc_id = sctp_get_associd(stcb);
- m_notify->m_flags |= M_EOR | M_NOTIFICATION;
- m_notify->m_pkthdr.len = sizeof(struct sctp_shutdown_event);
- m_notify->m_pkthdr.rcvif = 0;
- m_notify->m_len = sizeof(struct sctp_shutdown_event);
- m_notify->m_next = NULL;
+ SCTP_BUF_LEN(m_notify) = sizeof(struct sctp_shutdown_event);
+ SCTP_BUF_NEXT(m_notify) = NULL;
/* append to socket */
control = sctp_build_readq_entry(stcb, stcb->asoc.primary_destination,
@@ -3010,7 +2992,8 @@ sctp_notify_shutdown_event(struct sctp_tcb *stcb)
sctp_m_freem(m_notify);
return;
}
- control->length = m_notify->m_len;
+ control->spec_flags = M_NOTIFICATION;
+ control->length = SCTP_BUF_LEN(m_notify);
/* not that we need this */
control->tail_mbuf = m_notify;
sctp_add_to_readq(stcb->sctp_ep, stcb,
@@ -3031,11 +3014,11 @@ sctp_notify_stream_reset(struct sctp_tcb *stcb,
/* event not enabled */
return;
- m_notify = sctp_get_mbuf_for_msg(MCLBYTES, 1, M_DONTWAIT, 1, MT_DATA);
+ m_notify = sctp_get_mbuf_for_msg(MCLBYTES, 0, M_DONTWAIT, 1, MT_DATA);
if (m_notify == NULL)
/* no space left */
return;
- m_notify->m_len = 0;
+ SCTP_BUF_LEN(m_notify) = 0;
len = sizeof(struct sctp_stream_reset_event) + (number_entries * sizeof(uint16_t));
if (len > M_TRAILINGSPACE(m_notify)) {
/* never enough room */
@@ -3058,12 +3041,9 @@ sctp_notify_stream_reset(struct sctp_tcb *stcb,
strreset->strreset_list[i] = ntohs(list[i]);
}
}
- m_notify->m_flags |= M_EOR | M_NOTIFICATION;
- m_notify->m_pkthdr.len = len;
- m_notify->m_pkthdr.rcvif = 0;
- m_notify->m_len = len;
- m_notify->m_next = NULL;
- if (sctp_sbspace(&stcb->asoc, &stcb->sctp_socket->so_rcv) < m_notify->m_len) {
+ SCTP_BUF_LEN(m_notify) = len;
+ SCTP_BUF_NEXT(m_notify) = NULL;
+ if (sctp_sbspace(&stcb->asoc, &stcb->sctp_socket->so_rcv) < SCTP_BUF_LEN(m_notify)) {
/* no space */
sctp_m_freem(m_notify);
return;
@@ -3077,7 +3057,8 @@ sctp_notify_stream_reset(struct sctp_tcb *stcb,
sctp_m_freem(m_notify);
return;
}
- control->length = m_notify->m_len;
+ control->spec_flags = M_NOTIFICATION;
+ control->length = SCTP_BUF_LEN(m_notify);
/* not that we need this */
control->tail_mbuf = m_notify;
sctp_add_to_readq(stcb->sctp_ep, stcb,
@@ -3669,7 +3650,7 @@ sctp_print_address_pkt(struct ip *iph, struct sctphdr *sh)
#define SCTP_SBLINKRECORD(sb, m0) do { \
if ((sb)->sb_lastrecord != NULL) \
- (sb)->sb_lastrecord->m_nextpkt = (m0); \
+ SCTP_BUF_NEXT_PKT((sb)->sb_lastrecord) = (m0); \
else \
(sb)->sb_mb = (m0); \
(sb)->sb_lastrecord = (m0); \
@@ -3725,13 +3706,13 @@ sctp_pull_off_control_to_new_inp(struct sctp_inpcb *old_inp,
m = control->data;
while (m) {
#ifdef SCTP_SB_LOGGING
- sctp_sblog(&old_so->so_rcv, control->do_not_ref_stcb ? NULL : stcb, SCTP_LOG_SBFREE, m->m_len);
+ sctp_sblog(&old_so->so_rcv, control->do_not_ref_stcb ? NULL : stcb, SCTP_LOG_SBFREE, SCTP_BUF_LEN(m));
#endif
sctp_sbfree(control, stcb, &old_so->so_rcv, m);
#ifdef SCTP_SB_LOGGING
sctp_sblog(&old_so->so_rcv, control->do_not_ref_stcb ? NULL : stcb, SCTP_LOG_SBRESULT, 0);
#endif
- m = m->m_next;
+ m = SCTP_BUF_NEXT(m);
}
}
control = nctl;
@@ -3753,13 +3734,13 @@ sctp_pull_off_control_to_new_inp(struct sctp_inpcb *old_inp,
m = control->data;
while (m) {
#ifdef SCTP_SB_LOGGING
- sctp_sblog(&new_so->so_rcv, control->do_not_ref_stcb ? NULL : stcb, SCTP_LOG_SBALLOC, m->m_len);
+ sctp_sblog(&new_so->so_rcv, control->do_not_ref_stcb ? NULL : stcb, SCTP_LOG_SBALLOC, SCTP_BUF_LEN(m));
#endif
sctp_sballoc(stcb, &new_so->so_rcv, m);
#ifdef SCTP_SB_LOGGING
sctp_sblog(&new_so->so_rcv, control->do_not_ref_stcb ? NULL : stcb, SCTP_LOG_SBRESULT, 0);
#endif
- m = m->m_next;
+ m = SCTP_BUF_NEXT(m);
}
control = nctl;
}
@@ -3795,15 +3776,15 @@ sctp_add_to_readq(struct sctp_inpcb *inp,
control->held_length = 0;
control->length = 0;
while (m) {
- if (m->m_len == 0) {
+ if (SCTP_BUF_LEN(m) == 0) {
/* Skip mbufs with NO length */
if (prev == NULL) {
/* First one */
control->data = sctp_m_free(m);
m = control->data;
} else {
- prev->m_next = sctp_m_free(m);
- m = prev->m_next;
+ SCTP_BUF_NEXT(prev) = sctp_m_free(m);
+ m = SCTP_BUF_NEXT(prev);
}
if (m == NULL) {
control->tail_mbuf = prev;;
@@ -3812,21 +3793,19 @@ sctp_add_to_readq(struct sctp_inpcb *inp,
}
prev = m;
#ifdef SCTP_SB_LOGGING
- sctp_sblog(sb, control->do_not_ref_stcb ? NULL : stcb, SCTP_LOG_SBALLOC, m->m_len);
+ sctp_sblog(sb, control->do_not_ref_stcb ? NULL : stcb, SCTP_LOG_SBALLOC, SCTP_BUF_LEN(m));
#endif
sctp_sballoc(stcb, sb, m);
#ifdef SCTP_SB_LOGGING
sctp_sblog(sb, control->do_not_ref_stcb ? NULL : stcb, SCTP_LOG_SBRESULT, 0);
#endif
- atomic_add_int(&control->length, m->m_len);
- m = m->m_next;
+ atomic_add_int(&control->length, SCTP_BUF_LEN(m));
+ m = SCTP_BUF_NEXT(m);
}
if (prev != NULL) {
control->tail_mbuf = prev;
- if (end) {
- prev->m_flags |= M_EOR;
- }
} else {
+ /* Everything got collapsed out?? */
return;
}
if (end) {
@@ -3871,8 +3850,7 @@ get_out:
}
return (-1);
}
- if ((control->tail_mbuf) &&
- (control->tail_mbuf->m_flags & M_EOR)) {
+ if (control->end_added) {
/* huh this one is complete? */
goto get_out;
}
@@ -3881,30 +3859,30 @@ get_out:
goto get_out;
}
while (mm) {
- if (mm->m_len == 0) {
+ if (SCTP_BUF_LEN(mm) == 0) {
/* Skip mbufs with NO lenght */
if (prev == NULL) {
/* First one */
m = sctp_m_free(mm);
mm = m;
} else {
- prev->m_next = sctp_m_free(mm);
- mm = prev->m_next;
+ SCTP_BUF_NEXT(prev) = sctp_m_free(mm);
+ mm = SCTP_BUF_NEXT(prev);
}
continue;
}
prev = mm;
- len += mm->m_len;
+ len += SCTP_BUF_LEN(mm);
if (sb) {
#ifdef SCTP_SB_LOGGING
- sctp_sblog(sb, control->do_not_ref_stcb ? NULL : stcb, SCTP_LOG_SBALLOC, mm->m_len);
+ sctp_sblog(sb, control->do_not_ref_stcb ? NULL : stcb, SCTP_LOG_SBALLOC, SCTP_BUF_LEN(mm));
#endif
sctp_sballoc(stcb, sb, mm);
#ifdef SCTP_SB_LOGGING
sctp_sblog(sb, control->do_not_ref_stcb ? NULL : stcb, SCTP_LOG_SBRESULT, 0);
#endif
}
- mm = mm->m_next;
+ mm = SCTP_BUF_NEXT(mm);
}
if (prev) {
tail = prev;
@@ -3922,7 +3900,6 @@ get_out:
}
if (end) {
/* message is complete */
- tail->m_flags |= M_EOR;
if (control == stcb->asoc.control_pdapi) {
stcb->asoc.control_pdapi = NULL;
}
@@ -3932,7 +3909,7 @@ get_out:
atomic_add_int(&control->length, len);
if (control->tail_mbuf) {
/* append */
- control->tail_mbuf->m_next = m;
+ SCTP_BUF_NEXT(control->tail_mbuf) = m;
control->tail_mbuf = tail;
} else {
/* nothing there */
@@ -3980,7 +3957,7 @@ sctp_generate_invmanparam(int err)
if (m) {
struct sctp_paramhdr *ph;
- m->m_len = sizeof(struct sctp_paramhdr);
+ SCTP_BUF_LEN(m) = sizeof(struct sctp_paramhdr);
ph = mtod(m, struct sctp_paramhdr *);
ph->param_length = htons(sizeof(struct sctp_paramhdr));
ph->param_type = htons(err);
@@ -4147,13 +4124,6 @@ sctp_find_ifa_by_addr(struct sockaddr *sa)
return (NULL);
}
-
-
-
-
-
-
-
static void
sctp_user_rcvd(struct sctp_tcb *stcb, int *freed_so_far, int hold_rlock,
uint32_t rwnd_req)
@@ -4463,13 +4433,12 @@ restart_nosblocks:
m = control->data;
while (m) {
- cnt += m->m_len;
- if (m->m_next == NULL) {
+ cnt += SCTP_BUF_LEN(m);
+ if (SCTP_BUF_NEXT(m) == NULL) {
control->tail_mbuf = m;
- m->m_flags |= M_EOR;
control->end_added = 1;
}
- m = m->m_next;
+ m = SCTP_BUF_NEXT(m);
}
control->length = cnt;
} else {
@@ -4572,7 +4541,7 @@ found_one:
s_extra->next_ppid = nxt->sinfo_ppid;
s_extra->next_stream = nxt->sinfo_stream;
if (nxt->tail_mbuf != NULL) {
- if (nxt->tail_mbuf->m_flags & M_EOR) {
+ if (nxt->end_added) {
s_extra->next_flags |= SCTP_NEXT_MSG_ISCOMPLETE;
}
}
@@ -4653,7 +4622,7 @@ get_more_data:
while (m) {
/* Move out all we can */
cp_len = (int)uio->uio_resid;
- my_len = (int)m->m_len;
+ my_len = (int)SCTP_BUF_LEN(m);
if (cp_len > my_len) {
/* not enough in this buf */
cp_len = my_len;
@@ -4685,8 +4654,8 @@ get_more_data:
/* error we are out of here */
goto release;
}
- if ((m->m_next == NULL) &&
- (cp_len >= m->m_len) &&
+ if ((SCTP_BUF_NEXT(m) == NULL) &&
+ (cp_len >= SCTP_BUF_LEN(m)) &&
((control->end_added == 0) ||
(control->end_added && (TAILQ_NEXT(control, next) == NULL)))
) {
@@ -4694,13 +4663,13 @@ get_more_data:
sctp_misc_ints(SCTP_SORCV_DOESLCK,
so->so_rcv.sb_cc,
cp_len,
- m->m_len,
+ SCTP_BUF_LEN(m),
control->length);
#endif
SCTP_INP_READ_LOCK(inp);
hold_rlock = 1;
}
- if (cp_len == m->m_len) {
+ if (cp_len == SCTP_BUF_LEN(m)) {
#ifdef SCTP_RECV_DETAIL_RWND_LOGGING
sctp_misc_ints(SCTP_SORCV_DOESADJ,
so->so_rcv.sb_cc,
@@ -4708,22 +4677,23 @@ get_more_data:
cp_len,
0);
#endif
- if (m->m_flags & M_EOR) {
+ if ((SCTP_BUF_NEXT(m) == NULL) &&
+ (control->end_added)) {
out_flags |= MSG_EOR;
}
- if (m->m_flags & M_NOTIFICATION) {
+ if (control->spec_flags & M_NOTIFICATION) {
out_flags |= MSG_NOTIFICATION;
}
/* we ate up the mbuf */
if (in_flags & MSG_PEEK) {
/* just looking */
- m = m->m_next;
+ m = SCTP_BUF_NEXT(m);
copied_so_far += cp_len;
} else {
/* dispose of the mbuf */
#ifdef SCTP_SB_LOGGING
sctp_sblog(&so->so_rcv,
- control->do_not_ref_stcb ? NULL : stcb, SCTP_LOG_SBFREE, m->m_len);
+ control->do_not_ref_stcb ? NULL : stcb, SCTP_LOG_SBFREE, SCTP_BUF_LEN(m));
#endif
sctp_sbfree(control, stcb, &so->so_rcv, m);
#ifdef SCTP_SB_LOGGING
@@ -4783,21 +4753,12 @@ get_more_data:
}
} else {
/* Do we need to trim the mbuf? */
- if (m->m_flags & M_NOTIFICATION) {
+ if (control->spec_flags & M_NOTIFICATION) {
out_flags |= MSG_NOTIFICATION;
}
if ((in_flags & MSG_PEEK) == 0) {
- if (out_flags & MSG_NOTIFICATION) {
- /*
- * remark this one with the
- * notify flag, they read
- * only part of the
- * notification.
- */
- m->m_flags |= M_NOTIFICATION;
- }
- m->m_data += cp_len;
- m->m_len -= cp_len;
+ SCTP_BUF_RESV_UF(m, cp_len);
+ SCTP_BUF_LEN(m) -= cp_len;
#ifdef SCTP_SB_LOGGING
sctp_sblog(&so->so_rcv, control->do_not_ref_stcb ? NULL : stcb, SCTP_LOG_SBFREE, cp_len);
#endif
@@ -5037,10 +4998,10 @@ get_more_data2:
hold_rlock = 1;
}
}
- if (control->tail_mbuf->m_flags & M_EOR) {
+ if (control->end_added) {
out_flags |= MSG_EOR;
}
- if (control->data->m_flags & M_NOTIFICATION) {
+ if (control->spec_flags & M_NOTIFICATION) {
out_flags |= MSG_NOTIFICATION;
}
if (uio)
@@ -5050,15 +5011,15 @@ get_more_data2:
while (m) {
#ifdef SCTP_SB_LOGGING
sctp_sblog(&so->so_rcv,
- control->do_not_ref_stcb ? NULL : stcb, SCTP_LOG_SBFREE, m->m_len);
+ control->do_not_ref_stcb ? NULL : stcb, SCTP_LOG_SBFREE, SCTP_BUF_LEN(m));
#endif
sctp_sbfree(control, stcb, &so->so_rcv, m);
- freed_so_far += m->m_len;
+ freed_so_far += SCTP_BUF_LEN(m);
#ifdef SCTP_SB_LOGGING
sctp_sblog(&so->so_rcv,
control->do_not_ref_stcb ? NULL : stcb, SCTP_LOG_SBRESULT, 0);
#endif
- m = m->m_next;
+ m = SCTP_BUF_NEXT(m);
}
control->data = control->tail_mbuf = NULL;
control->length = 0;
@@ -5126,29 +5087,29 @@ get_more_data2:
hold_rlock = 1;
}
}
- if (m->m_flags & M_NOTIFICATION) {
+ if (control->spec_flags & M_NOTIFICATION) {
out_flags |= MSG_NOTIFICATION;
}
while ((m) && (cp_len > 0)) {
- if (cp_len >= m->m_len) {
+ if (cp_len >= SCTP_BUF_LEN(m)) {
*mp = m;
- atomic_subtract_int(&control->length, m->m_len);
+ atomic_subtract_int(&control->length, SCTP_BUF_LEN(m));
if (uio)
- uio->uio_resid -= m->m_len;
- cp_len -= m->m_len;
- control->data = m->m_next;
- m->m_next = NULL;
+ uio->uio_resid -= SCTP_BUF_LEN(m);
+ cp_len -= SCTP_BUF_LEN(m);
+ control->data = SCTP_BUF_NEXT(m);
+ SCTP_BUF_NEXT(m) = NULL;
#ifdef SCTP_SB_LOGGING
sctp_sblog(&so->so_rcv,
- control->do_not_ref_stcb ? NULL : stcb, SCTP_LOG_SBFREE, m->m_len);
+ control->do_not_ref_stcb ? NULL : stcb, SCTP_LOG_SBFREE, SCTP_BUF_LEN(m));
#endif
sctp_sbfree(control, stcb, &so->so_rcv, m);
- freed_so_far += m->m_len;
+ freed_so_far += SCTP_BUF_LEN(m);
#ifdef SCTP_SB_LOGGING
sctp_sblog(&so->so_rcv,
control->do_not_ref_stcb ? NULL : stcb, SCTP_LOG_SBRESULT, 0);
#endif
- mp = &m->m_next;
+ mp = &SCTP_BUF_NEXT(m);
m = control->data;
} else {
/*
@@ -5156,8 +5117,8 @@ get_more_data2:
* this mbuf only.
*/
if (uio)
- uio->uio_resid -= m->m_len;
- cp_len -= m->m_len;
+ uio->uio_resid -= SCTP_BUF_LEN(m);
+ cp_len -= SCTP_BUF_LEN(m);
if (hold_rlock) {
SCTP_INP_READ_UNLOCK(inp);
hold_rlock = 0;
@@ -5185,8 +5146,8 @@ get_more_data2:
stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) {
no_rcv_needed = 1;
}
- m->m_data += cp_len;
- m->m_len -= cp_len;
+ SCTP_BUF_RESV_UF(m, cp_len);
+ SCTP_BUF_LEN(m) -= cp_len;
#ifdef SCTP_SB_LOGGING
sctp_sblog(&so->so_rcv, control->do_not_ref_stcb ? NULL : stcb, SCTP_LOG_SBFREE, cp_len);
#endif
@@ -5203,13 +5164,6 @@ get_more_data2:
sctp_sblog(&so->so_rcv, control->do_not_ref_stcb ? NULL : stcb,
SCTP_LOG_SBRESULT, 0);
#endif
- if (out_flags & MSG_NOTIFICATION) {
- /*
- * remark the first mbuf if
- * they took a partial read.
- */
- control->data->m_flags |= M_NOTIFICATION;
- }
goto release;
}
}
@@ -5290,7 +5244,7 @@ out:
struct mbuf *
sctp_m_free(struct mbuf *m)
{
- if (m->m_flags & M_EXT) {
+ if (SCTP_BUF_IS_EXTENDED(m)) {
sctp_log_mb(m, SCTP_MBUF_IFREE);
}
return (m_free(m));
diff --git a/sys/netinet6/sctp6_usrreq.c b/sys/netinet6/sctp6_usrreq.c
index 7bf4aaf..ab1141a 100644
--- a/sys/netinet6/sctp6_usrreq.c
+++ b/sys/netinet6/sctp6_usrreq.c
@@ -118,7 +118,7 @@ sctp6_input(mp, offp, proto)
int proto;
{
- struct mbuf *m = *mp;
+ struct mbuf *m;
struct ip6_hdr *ip6;
struct sctphdr *sh;
struct sctp_inpcb *in6p = NULL;
@@ -133,6 +133,8 @@ sctp6_input(mp, offp, proto)
int off = *offp;
int s;
+ m = SCTP_HEADER_TO_CHAIN(*mp);
+
ip6 = mtod(m, struct ip6_hdr *);
#ifndef PULLDOWN_TEST
/* If PULLDOWN_TEST off, must be in a single mbuf. */
@@ -163,7 +165,7 @@ sctp6_input(mp, offp, proto)
SCTP_STAT_INCR_COUNTER64(sctps_inpackets);
#ifdef SCTP_DEBUG
if (sctp_debug_on & SCTP_DEBUG_INPUT1) {
- printf("V6 input gets a packet iphlen:%d pktlen:%d\n", iphlen, m->m_pkthdr.len);
+ printf("V6 input gets a packet iphlen:%d pktlen:%d\n", iphlen, SCTP_HEADER_LEN((*mp)));
}
#endif
if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst)) {
@@ -174,8 +176,7 @@ sctp6_input(mp, offp, proto)
if (sh->dest_port == 0)
goto bad;
if ((sctp_no_csum_on_loopback == 0) ||
- (m->m_pkthdr.rcvif == NULL) ||
- (m->m_pkthdr.rcvif->if_type != IFT_LOOP)) {
+ (!SCTP_IS_IT_LOOPBACK(m))) {
/*
* we do NOT validate things from the loopback if the sysctl
* is set to 1.
@@ -214,10 +215,8 @@ sctp6_input(mp, offp, proto)
goto bad;
}
sh->checksum = calc_check;
- } else {
-sctp_skip_csum:
- mlen = m->m_pkthdr.len;
}
+sctp_skip_csum:
net = NULL;
/*
* Locate pcb and tcb for datagram sctp_findassociation_addr() wants
@@ -270,9 +269,12 @@ sctp_skip_csum:
/*
* CONTROL chunk processing
*/
- length = ntohs(ip6->ip6_plen) + iphlen;
offset -= sizeof(*ch);
ecn_bits = ((ntohl(ip6->ip6_flow) >> 20) & 0x000000ff);
+
+ /* Length now holds the total packet length payload + iphlen */
+ length = ntohs(ip6->ip6_plen) + iphlen;
+
s = splnet();
(void)sctp_common_input_processing(&m, iphlen, offset, length, sh, ch,
in6p, stcb, net, ecn_bits);
@@ -420,8 +422,7 @@ sctp6_ctlinput(cmd, pktdst, d)
struct sctp_nets *net = NULL;
struct sockaddr_in6 final;
- if (ip6cp->ip6c_m == NULL ||
- (size_t)ip6cp->ip6c_m->m_pkthdr.len < (ip6cp->ip6c_off + sizeof(sh)))
+ if (ip6cp->ip6c_m == NULL)
return;
bzero(&sh, sizeof(sh));
@@ -818,9 +819,9 @@ sctp6_disconnect(struct socket *so)
struct sctp_paramhdr *ph;
ph = mtod(err, struct sctp_paramhdr *);
- err->m_len = sizeof(struct sctp_paramhdr);
+ SCTP_BUF_LEN(err) = sizeof(struct sctp_paramhdr);
ph->param_type = htons(SCTP_CAUSE_USER_INITIATED_ABT);
- ph->param_length = htons(err->m_len);
+ ph->param_length = htons(SCTP_BUF_LEN(err));
}
sctp_send_abort_tcb(stcb, err);
SCTP_STAT_INCR_COUNTER32(sctps_aborted);
@@ -982,22 +983,9 @@ connected_type:
}
inp->control = control;
}
- /* add it in possibly */
- if ((inp->pkt) &&
- (inp->pkt->m_flags & M_PKTHDR)) {
- struct mbuf *x;
- int c_len;
-
- c_len = 0;
- /* How big is it */
- for (x = m; x; x = x->m_next) {
- c_len += x->m_len;
- }
- inp->pkt->m_pkthdr.len += c_len;
- }
/* Place the data */
if (inp->pkt) {
- inp->pkt_last->m_next = m;
+ SCTP_BUF_NEXT(inp->pkt_last) = m;
inp->pkt_last = m;
} else {
inp->pkt_last = inp->pkt = m;
OpenPOWER on IntegriCloud