summaryrefslogtreecommitdiffstats
path: root/sys/netinet/sctp_output.c
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/netinet/sctp_output.c
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/netinet/sctp_output.c')
-rw-r--r--sys/netinet/sctp_output.c965
1 files changed, 423 insertions, 542 deletions
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;
OpenPOWER on IntegriCloud