summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorrrs <rrs@FreeBSD.org>2006-12-29 20:21:42 +0000
committerrrs <rrs@FreeBSD.org>2006-12-29 20:21:42 +0000
commitd392a291a28a8cbedf2cc9398d4a03c8467d8c3d (patch)
treeca49939e7d34d46ab49b2ec2d88653e27f3e43a1 /sys
parentc2bdc9dc5c518c1a3f29bb61d0d469bb1b6b68a9 (diff)
downloadFreeBSD-src-d392a291a28a8cbedf2cc9398d4a03c8467d8c3d.zip
FreeBSD-src-d392a291a28a8cbedf2cc9398d4a03c8467d8c3d.tar.gz
a) macro-ization of all mbuf and random number
access plus timers. This makes the code more portable and able to change out the mbuf or timer system used more easily ;-) b) removal of all use of pkt-hdr's until only the places we need them (before ip_output routines). c) remove a bunch of code not needed due to <b> aka worrying about pkthdr's :-) d) There was one last reorder problem it looks where if a restart occur's and we release and relock (at the point where we setup our alias vtag) we would end up possibly getting the wrong TSN in place. The code that fixed the TSN's just needed to be shifted around BEFORE the release of the lock.. also code that set the state (since this also could contribute). Approved by: gnn
Diffstat (limited to 'sys')
-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