- Fixes so we won't try to start a timer when we
hold a wq lock for the iterator. Panda uses a silly recursive lock they hold through the timer. - Add poor mans wireshark compile option.. - Allocate and start using SCTP_M_XXX for all SCTP_MALLOC() calls. - sysctl now will get back the refcnt for viewing by onlookers. Reviewed by: gnn
This commit is contained in:
parent
20a990117d
commit
207304d4b7
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=170091
@ -158,6 +158,7 @@ struct sctp_paramhdr {
|
||||
#define SCTP_PCB_STATUS 0x00001104
|
||||
#define SCTP_GET_NONCE_VALUES 0x00001105
|
||||
|
||||
|
||||
/* Special hook for dynamically setting primary for all assoc's,
|
||||
* this is a write only option that requires root privledge.
|
||||
*/
|
||||
@ -196,6 +197,17 @@ struct sctp_paramhdr {
|
||||
#define SCTP_GET_VRF_IDS 0x00003003
|
||||
#define SCTP_GET_ASOC_VRF 0x00003004
|
||||
#define SCTP_DEL_VRF_ID 0x00003005
|
||||
|
||||
/*
|
||||
* If you enable packet logging you can get
|
||||
* a poor mans ethereal output in binary
|
||||
* form. Note this is a compile option to
|
||||
* the kernel, SCTP_PACKET_LOGGING, and
|
||||
* without it in your kernel you
|
||||
* will get a ENOSUPPORT.
|
||||
*/
|
||||
#define SCTP_GET_PACKET_LOG 0x00004001
|
||||
|
||||
/*
|
||||
* hidden implementation specific options these are NOT user visible (should
|
||||
* move out of sctp.h)
|
||||
@ -453,4 +465,7 @@ struct sctp_error_unrecognized_chunk {
|
||||
|
||||
#include <netinet/sctp_uio.h>
|
||||
|
||||
#define SCTP_PACKET_LOG_SIZE 65536
|
||||
|
||||
|
||||
#endif /* !_NETINET_SCTP_H_ */
|
||||
|
@ -942,13 +942,13 @@ sctp_asconf_queue_add(struct sctp_tcb *stcb, struct sctp_ifa *ifa, uint16_t type
|
||||
sctp_asconf_addr_mgmt_ack(stcb, aa->ifa, type, 1);
|
||||
/* free the entry */
|
||||
sctp_free_ifa(aa->ifa);
|
||||
SCTP_FREE(aa);
|
||||
SCTP_FREE(aa, SCTP_M_ASC_ADDR);
|
||||
return (-1);
|
||||
}
|
||||
} /* for each aa */
|
||||
|
||||
/* adding new request to the queue */
|
||||
SCTP_MALLOC(aa, struct sctp_asconf_addr *, sizeof(*aa), "AsconfAddr");
|
||||
SCTP_MALLOC(aa, struct sctp_asconf_addr *, sizeof(*aa), SCTP_M_ASC_ADDR);
|
||||
if (aa == NULL) {
|
||||
/* didn't get memory */
|
||||
SCTPDBG(SCTP_DEBUG_ASCONF1,
|
||||
@ -988,7 +988,7 @@ sctp_asconf_queue_add(struct sctp_tcb *stcb, struct sctp_ifa *ifa, uint16_t type
|
||||
sizeof(struct in_addr));
|
||||
} else {
|
||||
/* invalid family! */
|
||||
SCTP_FREE(aa);
|
||||
SCTP_FREE(aa, SCTP_M_ASC_ADDR);
|
||||
return (-1);
|
||||
}
|
||||
aa->sent = 0; /* clear sent flag */
|
||||
@ -1067,7 +1067,7 @@ sctp_asconf_queue_add_sa(struct sctp_tcb *stcb, struct sockaddr *sa,
|
||||
TAILQ_REMOVE(&stcb->asoc.asconf_queue, aa, next);
|
||||
/* free the entry */
|
||||
sctp_free_ifa(aa->ifa);
|
||||
SCTP_FREE(aa);
|
||||
SCTP_FREE(aa, SCTP_M_ASC_ADDR);
|
||||
return (-1);
|
||||
} else if (type == SCTP_DEL_IP_ADDRESS &&
|
||||
aa->ap.aph.ph.param_type == SCTP_ADD_IP_ADDRESS) {
|
||||
@ -1079,7 +1079,7 @@ sctp_asconf_queue_add_sa(struct sctp_tcb *stcb, struct sockaddr *sa,
|
||||
sctp_asconf_addr_mgmt_ack(stcb, aa->ifa, type, 1);
|
||||
/* free the entry */
|
||||
sctp_free_ifa(aa->ifa);
|
||||
SCTP_FREE(aa);
|
||||
SCTP_FREE(aa, SCTP_M_ASC_ADDR);
|
||||
return (-1);
|
||||
}
|
||||
} /* for each aa */
|
||||
@ -1095,7 +1095,7 @@ sctp_asconf_queue_add_sa(struct sctp_tcb *stcb, struct sockaddr *sa,
|
||||
return (-1);
|
||||
}
|
||||
/* adding new request to the queue */
|
||||
SCTP_MALLOC(aa, struct sctp_asconf_addr *, sizeof(*aa), "AsconfAddr");
|
||||
SCTP_MALLOC(aa, struct sctp_asconf_addr *, sizeof(*aa), SCTP_M_ASC_ADDR);
|
||||
if (aa == NULL) {
|
||||
/* didn't get memory */
|
||||
SCTPDBG(SCTP_DEBUG_ASCONF1,
|
||||
@ -1129,7 +1129,7 @@ sctp_asconf_queue_add_sa(struct sctp_tcb *stcb, struct sockaddr *sa,
|
||||
sizeof(struct in_addr));
|
||||
} else {
|
||||
/* invalid family! */
|
||||
SCTP_FREE(aa);
|
||||
SCTP_FREE(aa, SCTP_M_ASC_ADDR);
|
||||
return (-1);
|
||||
}
|
||||
aa->sent = 0; /* clear sent flag */
|
||||
@ -1258,7 +1258,7 @@ sctp_asconf_process_param_ack(struct sctp_tcb *stcb,
|
||||
/* remove the param and free it */
|
||||
TAILQ_REMOVE(&stcb->asoc.asconf_queue, aparam, next);
|
||||
sctp_free_ifa(aparam->ifa);
|
||||
SCTP_FREE(aparam);
|
||||
SCTP_FREE(aparam, SCTP_M_ASC_ADDR);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1864,7 +1864,7 @@ sctp_iterator_end(void *ptr, uint32_t val)
|
||||
SCTP_DECR_LADDR_COUNT();
|
||||
l = l_next;
|
||||
}
|
||||
SCTP_FREE(asc);
|
||||
SCTP_FREE(asc, SCTP_M_ASC_IT);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2566,14 +2566,14 @@ sctp_addr_mgmt_ep_sa(struct sctp_inpcb *inp, struct sockaddr *sa,
|
||||
|
||||
SCTP_MALLOC(asc, struct sctp_asconf_iterator *,
|
||||
sizeof(struct sctp_asconf_iterator),
|
||||
"SCTP_ASCONF_ITERATOR");
|
||||
SCTP_M_ASC_IT);
|
||||
if (asc == NULL) {
|
||||
return (ENOMEM);
|
||||
}
|
||||
wi = SCTP_ZONE_GET(sctppcbinfo.ipi_zone_laddr,
|
||||
struct sctp_laddr);
|
||||
if (wi == NULL) {
|
||||
SCTP_FREE(asc);
|
||||
SCTP_FREE(asc, SCTP_M_ASC_IT);
|
||||
return (ENOMEM);
|
||||
}
|
||||
if (type == SCTP_ADD_IP_ADDRESS) {
|
||||
|
@ -61,7 +61,7 @@ sctp_alloc_chunklist(void)
|
||||
sctp_auth_chklist_t *chklist;
|
||||
|
||||
SCTP_MALLOC(chklist, sctp_auth_chklist_t *, sizeof(*chklist),
|
||||
"AUTH chklist");
|
||||
SCTP_M_AUTH_CL);
|
||||
if (chklist == NULL) {
|
||||
SCTPDBG(SCTP_DEBUG_AUTH1, "sctp_alloc_chunklist: failed to get memory!\n");
|
||||
} else {
|
||||
@ -74,7 +74,7 @@ void
|
||||
sctp_free_chunklist(sctp_auth_chklist_t * list)
|
||||
{
|
||||
if (list != NULL)
|
||||
SCTP_FREE(list);
|
||||
SCTP_FREE(list, SCTP_M_AUTH_CL);
|
||||
}
|
||||
|
||||
sctp_auth_chklist_t *
|
||||
@ -260,7 +260,7 @@ sctp_alloc_key(uint32_t keylen)
|
||||
sctp_key_t *new_key;
|
||||
|
||||
SCTP_MALLOC(new_key, sctp_key_t *, sizeof(*new_key) + keylen,
|
||||
"AUTH key");
|
||||
SCTP_M_AUTH_KY);
|
||||
if (new_key == NULL) {
|
||||
/* out of memory */
|
||||
return (NULL);
|
||||
@ -273,7 +273,7 @@ void
|
||||
sctp_free_key(sctp_key_t * key)
|
||||
{
|
||||
if (key != NULL)
|
||||
SCTP_FREE(key);
|
||||
SCTP_FREE(key, SCTP_M_AUTH_KY);
|
||||
}
|
||||
|
||||
void
|
||||
@ -492,7 +492,7 @@ sctp_alloc_sharedkey(void)
|
||||
sctp_sharedkey_t *new_key;
|
||||
|
||||
SCTP_MALLOC(new_key, sctp_sharedkey_t *, sizeof(*new_key),
|
||||
"AUTH skey");
|
||||
SCTP_M_AUTH_KY);
|
||||
if (new_key == NULL) {
|
||||
/* out of memory */
|
||||
return (NULL);
|
||||
@ -508,7 +508,7 @@ sctp_free_sharedkey(sctp_sharedkey_t * skey)
|
||||
if (skey != NULL) {
|
||||
if (skey->key != NULL)
|
||||
sctp_free_key(skey->key);
|
||||
SCTP_FREE(skey);
|
||||
SCTP_FREE(skey, SCTP_M_AUTH_KY);
|
||||
}
|
||||
}
|
||||
|
||||
@ -607,7 +607,7 @@ sctp_alloc_hmaclist(uint8_t num_hmacs)
|
||||
|
||||
alloc_size = sizeof(*new_list) + num_hmacs * sizeof(new_list->hmac[0]);
|
||||
SCTP_MALLOC(new_list, sctp_hmaclist_t *, alloc_size,
|
||||
"AUTH HMAC list");
|
||||
SCTP_M_AUTH_HL);
|
||||
if (new_list == NULL) {
|
||||
/* out of memory */
|
||||
return (NULL);
|
||||
@ -621,7 +621,7 @@ void
|
||||
sctp_free_hmaclist(sctp_hmaclist_t * list)
|
||||
{
|
||||
if (list != NULL) {
|
||||
SCTP_FREE(list);
|
||||
SCTP_FREE(list, SCTP_M_AUTH_HL);
|
||||
list = NULL;
|
||||
}
|
||||
}
|
||||
@ -774,7 +774,8 @@ sctp_alloc_authinfo(void)
|
||||
sctp_authinfo_t *new_authinfo;
|
||||
|
||||
SCTP_MALLOC(new_authinfo, sctp_authinfo_t *, sizeof(*new_authinfo),
|
||||
"AUTH info");
|
||||
SCTP_M_AUTH_IF);
|
||||
|
||||
if (new_authinfo == NULL) {
|
||||
/* out of memory */
|
||||
return (NULL);
|
||||
@ -799,7 +800,7 @@ sctp_free_authinfo(sctp_authinfo_t * authinfo)
|
||||
sctp_free_key(authinfo->recv_key);
|
||||
|
||||
/* We are NOT dynamically allocating authinfo's right now... */
|
||||
/* SCTP_FREE(authinfo); */
|
||||
/* SCTP_FREE(authinfo, SCTP_M_AUTH_??); */
|
||||
}
|
||||
|
||||
|
||||
|
@ -49,6 +49,38 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/unistd.h>
|
||||
|
||||
|
||||
/* Declare all of our malloc named types */
|
||||
|
||||
/* Not to Michael/Peter for mac-os,
|
||||
* I think mac has this to since I
|
||||
* do see the M_PCB type, so I
|
||||
* will also put in the mac file the
|
||||
* MALLOC_DELCARE. If this does not
|
||||
* work for mac uncomment the defines for
|
||||
* the strings that we use in Panda, I put
|
||||
* them in comments in the mac-os file.
|
||||
*/
|
||||
MALLOC_DEFINE(SCTP_M_MAP, "sctp_map", "sctp asoc map descriptor");
|
||||
MALLOC_DEFINE(SCTP_M_STRMI, "sctp_stri", "sctp stream in array");
|
||||
MALLOC_DEFINE(SCTP_M_STRMO, "sctp_stro", "sctp stream out array");
|
||||
MALLOC_DEFINE(SCTP_M_ASC_ADDR, "sctp_aadr", "sctp asconf address");
|
||||
MALLOC_DEFINE(SCTP_M_ASC_IT, "sctp_a_it", "sctp asconf iterator");
|
||||
MALLOC_DEFINE(SCTP_M_AUTH_CL, "sctp_atcl", "sctp auth chunklist");
|
||||
MALLOC_DEFINE(SCTP_M_AUTH_KY, "sctp_atky", "sctp auth key");
|
||||
MALLOC_DEFINE(SCTP_M_AUTH_HL, "sctp_athm", "sctp auth hmac list");
|
||||
MALLOC_DEFINE(SCTP_M_AUTH_IF, "sctp_athi", "sctp auth info");
|
||||
MALLOC_DEFINE(SCTP_M_STRESET, "sctp_stre", "sctp stream reset");
|
||||
MALLOC_DEFINE(SCTP_M_CMSG, "sctp_cmsg", "sctp CMSG buffer");
|
||||
MALLOC_DEFINE(SCTP_M_COPYAL, "sctp_cpal", "sctp copy all");
|
||||
MALLOC_DEFINE(SCTP_M_VRF, "sctp_vrf", "sctp vrf struct");
|
||||
MALLOC_DEFINE(SCTP_M_IFA, "sctp_ifa", "sctp ifa struct");
|
||||
MALLOC_DEFINE(SCTP_M_IFN, "sctp_ifn", "sctp ifn struct");
|
||||
MALLOC_DEFINE(SCTP_M_TIMW, "sctp_timw", "sctp time block");
|
||||
MALLOC_DEFINE(SCTP_M_MVRF, "sctp_mvrf", "sctp mvrf pcb list");
|
||||
MALLOC_DEFINE(SCTP_M_ITER, "sctp_iter", "sctp iterator control");
|
||||
MALLOC_DEFINE(SCTP_M_SOCKOPT, "sctp_socko", "sctp socket option");
|
||||
|
||||
|
||||
#if defined(SCTP_USE_THREAD_BASED_ITERATOR)
|
||||
void
|
||||
sctp_wakeup_iterator(void)
|
||||
@ -338,3 +370,164 @@ sctp_get_mbuf_for_msg(unsigned int space_needed, int want_header,
|
||||
#endif
|
||||
return (m);
|
||||
}
|
||||
|
||||
|
||||
#ifdef SCTP_PACKET_LOGGING
|
||||
|
||||
int packet_log_start = 0;
|
||||
int packet_log_end = 0;
|
||||
int packet_log_old_end = SCTP_PACKET_LOG_SIZE;
|
||||
int packet_log_wrapped = 0;
|
||||
uint8_t packet_log_buffer[SCTP_PACKET_LOG_SIZE];
|
||||
|
||||
|
||||
void
|
||||
sctp_packet_log(struct mbuf *m, int length)
|
||||
{
|
||||
int *lenat, needed, thisone;
|
||||
void *copyto;
|
||||
uint32_t *tick_tock;
|
||||
int total_len, spare;
|
||||
|
||||
total_len = SCTP_SIZE32((length + (2 * sizeof(int))));
|
||||
/* Log a packet to the buffer. */
|
||||
if (total_len > SCTP_PACKET_LOG_SIZE) {
|
||||
/* Can't log this packet I have not a buffer big enough */
|
||||
return;
|
||||
}
|
||||
if (length < (SCTP_MIN_V4_OVERHEAD + sizeof(struct sctp_cookie_ack_chunk))) {
|
||||
printf("Huh, length is %d to small for sctp min:%d\n",
|
||||
length,
|
||||
(SCTP_MIN_V4_OVERHEAD + sizeof(struct sctp_cookie_ack_chunk)));
|
||||
return;
|
||||
}
|
||||
SCTP_IP_PKTLOG_LOCK();
|
||||
if ((SCTP_PACKET_LOG_SIZE - packet_log_end) <= total_len) {
|
||||
/*
|
||||
* it won't fit on the end. We must go back to the
|
||||
* beginning. To do this we go back and cahnge
|
||||
* packet_log_start.
|
||||
*/
|
||||
int orig_end;
|
||||
|
||||
lenat = (int *)packet_log_buffer;
|
||||
orig_end = packet_log_end;
|
||||
packet_log_old_end = packet_log_end;
|
||||
packet_log_end = 0;
|
||||
if (packet_log_start > packet_log_old_end) {
|
||||
/* calculate the head room */
|
||||
spare = packet_log_start - packet_log_old_end;
|
||||
} else {
|
||||
spare = 0;
|
||||
}
|
||||
needed = total_len - spare;
|
||||
packet_log_wrapped = 1;
|
||||
/* Now update the start */
|
||||
while (needed > 0) {
|
||||
thisone = (*(int *)(&packet_log_buffer[packet_log_start]));
|
||||
needed -= thisone;
|
||||
if (thisone == 0) {
|
||||
int *foo;
|
||||
|
||||
foo = (int *)(&packet_log_buffer[packet_log_start]);
|
||||
goto insane;
|
||||
}
|
||||
/* move to next one */
|
||||
packet_log_start += thisone;
|
||||
}
|
||||
} else {
|
||||
lenat = (int *)&packet_log_buffer[packet_log_end];
|
||||
if (packet_log_start > packet_log_end) {
|
||||
if ((packet_log_end + total_len) > packet_log_start) {
|
||||
/* Now need to update killing some packets */
|
||||
needed = total_len - ((packet_log_start - packet_log_end));
|
||||
while (needed > 0) {
|
||||
thisone = (*(int *)(&packet_log_buffer[packet_log_start]));
|
||||
needed -= thisone;
|
||||
if (thisone == 0) {
|
||||
goto insane;
|
||||
}
|
||||
/* move to next one */
|
||||
packet_log_start += thisone;
|
||||
if (((packet_log_start + sizeof(struct ip)) > SCTP_PACKET_LOG_SIZE) ||
|
||||
(packet_log_wrapped && (packet_log_start >= packet_log_old_end))) {
|
||||
packet_log_start = 0;
|
||||
packet_log_old_end = 0;
|
||||
packet_log_wrapped = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (((packet_log_end + total_len) >= SCTP_PACKET_LOG_SIZE) ||
|
||||
((void *)((caddr_t)lenat) < (void *)packet_log_buffer) ||
|
||||
((void *)((caddr_t)lenat + total_len) > (void *)&packet_log_buffer[SCTP_PACKET_LOG_SIZE])) {
|
||||
/* Madness protection */
|
||||
insane:
|
||||
printf("Went mad, end:%d start:%d len:%d wrapped:%d oe:%d - zapping\n",
|
||||
packet_log_end, packet_log_start, total_len, packet_log_wrapped, packet_log_old_end);
|
||||
packet_log_start = packet_log_end = packet_log_old_end = packet_log_wrapped = 0;
|
||||
lenat = (int *)&packet_log_buffer[0];
|
||||
}
|
||||
*lenat = total_len;
|
||||
lenat++;
|
||||
tick_tock = (uint32_t *) lenat;
|
||||
lenat++;
|
||||
*tick_tock = sctp_get_tick_count();
|
||||
copyto = (void *)lenat;
|
||||
packet_log_end = (((caddr_t)copyto + length) - (caddr_t)packet_log_buffer);
|
||||
SCTP_IP_PKTLOG_UNLOCK();
|
||||
m_copydata(m, 0, length, (caddr_t)copyto);
|
||||
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
sctp_copy_out_packet_log(uint8_t * target, int length)
|
||||
{
|
||||
/*
|
||||
* We wind through the packet log starting at start copying up to
|
||||
* length bytes out. We return the number of bytes copied.
|
||||
*/
|
||||
int tocopy, this_copy, copied = 0;
|
||||
void *at;
|
||||
|
||||
tocopy = length;
|
||||
if (packet_log_start == packet_log_end) {
|
||||
/* no data */
|
||||
return (0);
|
||||
}
|
||||
if (packet_log_wrapped) {
|
||||
/*
|
||||
* we have a wrapped buffer, we must copy from start to the
|
||||
* old end. Then copy from the top of the buffer to the end.
|
||||
*/
|
||||
SCTP_IP_PKTLOG_LOCK();
|
||||
at = (void *)&packet_log_buffer[packet_log_start];
|
||||
this_copy = min(tocopy, (packet_log_old_end - packet_log_start));
|
||||
memcpy(target, at, this_copy);
|
||||
tocopy -= this_copy;
|
||||
copied += this_copy;
|
||||
if (tocopy == 0) {
|
||||
SCTP_IP_PKTLOG_UNLOCK();
|
||||
return (copied);
|
||||
}
|
||||
this_copy = min(tocopy, packet_log_end);
|
||||
at = (void *)&packet_log_buffer;
|
||||
memcpy(&target[copied], at, this_copy);
|
||||
copied += this_copy;
|
||||
SCTP_IP_PKTLOG_UNLOCK();
|
||||
return (copied);
|
||||
} else {
|
||||
/* we have one contiguous buffer */
|
||||
SCTP_IP_PKTLOG_LOCK();
|
||||
at = (void *)&packet_log_buffer;
|
||||
this_copy = min(length, packet_log_end);
|
||||
memcpy(target, at, this_copy);
|
||||
SCTP_IP_PKTLOG_UNLOCK();
|
||||
return (this_copy);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -46,6 +46,13 @@ void sctp_startup_iterator(void);
|
||||
|
||||
void sctp_gather_internal_ifa_flags(struct sctp_ifa *ifa);
|
||||
|
||||
#ifdef SCTP_PACKET_LOGGING
|
||||
|
||||
void sctp_packet_log(struct mbuf *m, int length);
|
||||
int sctp_copy_out_packet_log(uint8_t * target, int length);
|
||||
|
||||
#endif
|
||||
|
||||
void sctp_addr_change(struct ifaddr *ifa, int cmd);
|
||||
|
||||
#endif
|
||||
|
@ -327,7 +327,7 @@ sctp_build_ctl_cchunk(struct sctp_inpcb *inp,
|
||||
} else {
|
||||
len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo));
|
||||
}
|
||||
SCTP_MALLOC(buf, char *, len, "SCTP_CMSG");
|
||||
SCTP_MALLOC(buf, char *, len, SCTP_M_CMSG);
|
||||
if (buf == NULL) {
|
||||
/* No space */
|
||||
return (buf);
|
||||
@ -1481,6 +1481,7 @@ sctp_process_a_data_chunk(struct sctp_tcb *stcb, struct sctp_association *asoc,
|
||||
return (0);
|
||||
}
|
||||
if (gap >= (uint32_t) (asoc->mapping_array_size << 3)) {
|
||||
SCTP_TCB_LOCK_ASSERT(stcb);
|
||||
if (sctp_expand_mapping_array(asoc)) {
|
||||
/* Can't expand, drop it */
|
||||
return (0);
|
||||
@ -1587,6 +1588,7 @@ sctp_process_a_data_chunk(struct sctp_tcb *stcb, struct sctp_association *asoc,
|
||||
sctp_queue_op_err(stcb, mb);
|
||||
}
|
||||
SCTP_STAT_INCR(sctps_badsid);
|
||||
SCTP_TCB_LOCK_ASSERT(stcb);
|
||||
SCTP_SET_TSN_PRESENT(asoc->mapping_array, gap);
|
||||
if (compare_with_wrap(tsn, asoc->highest_tsn_inside_map, MAX_TSN)) {
|
||||
/* we have a new high score */
|
||||
@ -2089,6 +2091,7 @@ sctp_process_a_data_chunk(struct sctp_tcb *stcb, struct sctp_association *asoc,
|
||||
sctp_log_map(asoc->mapping_array_base_tsn, asoc->cumulative_tsn,
|
||||
asoc->highest_tsn_inside_map, SCTP_MAP_PREPARE_SLIDE);
|
||||
#endif
|
||||
SCTP_TCB_LOCK_ASSERT(stcb);
|
||||
SCTP_SET_TSN_PRESENT(asoc->mapping_array, gap);
|
||||
/* check the special flag for stream resets */
|
||||
if (((liste = TAILQ_FIRST(&asoc->resetHead)) != NULL) &&
|
||||
@ -2105,7 +2108,7 @@ sctp_process_a_data_chunk(struct sctp_tcb *stcb, struct sctp_association *asoc,
|
||||
|
||||
sctp_reset_in_stream(stcb, liste->number_entries, liste->req.list_of_streams);
|
||||
TAILQ_REMOVE(&asoc->resetHead, liste, next_resp);
|
||||
SCTP_FREE(liste);
|
||||
SCTP_FREE(liste, SCTP_M_STRESET);
|
||||
/* sa_ignore FREED_MEMORY */
|
||||
liste = TAILQ_FIRST(&asoc->resetHead);
|
||||
ctl = TAILQ_FIRST(&asoc->pending_reply_queue);
|
||||
@ -5742,8 +5745,10 @@ sctp_handle_forward_tsn(struct sctp_tcb *stcb,
|
||||
gap = asoc->highest_tsn_inside_map +
|
||||
(MAX_TSN - asoc->mapping_array_base_tsn) + 1;
|
||||
}
|
||||
SCTP_STAT_INCR(sctps_fwdtsn_map_over);
|
||||
cumack_set_flag = 1;
|
||||
}
|
||||
SCTP_TCB_LOCK_ASSERT(stcb);
|
||||
for (i = 0; i <= gap; i++) {
|
||||
SCTP_SET_TSN_PRESENT(asoc->mapping_array, i);
|
||||
}
|
||||
|
@ -44,7 +44,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <netinet/sctp_auth.h>
|
||||
#include <netinet/sctp_indata.h>
|
||||
#include <netinet/sctp_asconf.h>
|
||||
|
||||
#include <netinet/sctp_bsd_addr.h>
|
||||
|
||||
|
||||
|
||||
@ -247,6 +247,7 @@ sctp_process_init(struct sctp_init_chunk *cp, struct sctp_tcb *stcb,
|
||||
asoc->last_echo_tsn = asoc->asconf_seq_in;
|
||||
asoc->advanced_peer_ack_point = asoc->last_acked_seq;
|
||||
/* open the requested streams */
|
||||
|
||||
if (asoc->strmin != NULL) {
|
||||
/* Free the old ones */
|
||||
struct sctp_queued_to_read *ctl;
|
||||
@ -262,14 +263,14 @@ sctp_process_init(struct sctp_init_chunk *cp, struct sctp_tcb *stcb,
|
||||
ctl = TAILQ_FIRST(&asoc->strmin[i].inqueue);
|
||||
}
|
||||
}
|
||||
SCTP_FREE(asoc->strmin);
|
||||
SCTP_FREE(asoc->strmin, SCTP_M_STRMI);
|
||||
}
|
||||
asoc->streamincnt = ntohs(init->num_outbound_streams);
|
||||
if (asoc->streamincnt > MAX_SCTP_STREAMS) {
|
||||
asoc->streamincnt = MAX_SCTP_STREAMS;
|
||||
}
|
||||
SCTP_MALLOC(asoc->strmin, struct sctp_stream_in *, asoc->streamincnt *
|
||||
sizeof(struct sctp_stream_in), "StreamsIn");
|
||||
sizeof(struct sctp_stream_in), SCTP_M_STRMI);
|
||||
if (asoc->strmin == NULL) {
|
||||
/* we didn't get memory for the streams! */
|
||||
SCTPDBG(SCTP_DEBUG_INPUT2, "process_init: couldn't get memory for the streams!\n");
|
||||
@ -3012,7 +3013,7 @@ sctp_handle_str_reset_request_out(struct sctp_tcb *stcb,
|
||||
|
||||
siz = sizeof(struct sctp_stream_reset_list) + (number_entries * sizeof(uint16_t));
|
||||
SCTP_MALLOC(liste, struct sctp_stream_reset_list *,
|
||||
siz, "StrRstList");
|
||||
siz, SCTP_M_STRESET);
|
||||
if (liste == NULL) {
|
||||
/* gak out of memory */
|
||||
sctp_add_stream_reset_result(chk, seq, SCTP_STREAM_RESET_DENIED);
|
||||
@ -3465,6 +3466,9 @@ sctp_process_control(struct mbuf *m, int iphlen, int *offset, int length,
|
||||
if (ntohs(ch->chunk_length) < sizeof(*ch)) {
|
||||
SCTPDBG(SCTP_DEBUG_INPUT1, "Invalid header length %d\n",
|
||||
ntohs(ch->chunk_length));
|
||||
if (locked_tcb) {
|
||||
SCTP_TCB_UNLOCK(locked_tcb);
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
/*
|
||||
@ -3504,6 +3508,9 @@ sctp_process_control(struct mbuf *m, int iphlen, int *offset, int length,
|
||||
if (*offset >= length) {
|
||||
/* no more data left in the mbuf chain */
|
||||
*offset = length;
|
||||
if (locked_tcb) {
|
||||
SCTP_TCB_UNLOCK(locked_tcb);
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
ch = (struct sctp_chunkhdr *)sctp_m_getptr(m, *offset,
|
||||
@ -3512,6 +3519,9 @@ sctp_process_control(struct mbuf *m, int iphlen, int *offset, int length,
|
||||
if (ch == NULL) {
|
||||
/* Help */
|
||||
*offset = length;
|
||||
if (locked_tcb) {
|
||||
SCTP_TCB_UNLOCK(locked_tcb);
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
if (ch->chunk_type == SCTP_COOKIE_ECHO) {
|
||||
@ -3547,6 +3557,9 @@ sctp_process_control(struct mbuf *m, int iphlen, int *offset, int length,
|
||||
auth_offset)) {
|
||||
/* auth HMAC failed so dump it */
|
||||
*offset = length;
|
||||
if (locked_tcb) {
|
||||
SCTP_TCB_UNLOCK(locked_tcb);
|
||||
}
|
||||
return (NULL);
|
||||
} else {
|
||||
/* remaining chunks are HMAC checked */
|
||||
@ -3926,7 +3939,8 @@ sctp_process_control(struct mbuf *m, int iphlen, int *offset, int length,
|
||||
stcb, *netp);
|
||||
break;
|
||||
case SCTP_ABORT_ASSOCIATION:
|
||||
SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_ABORT\n");
|
||||
SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_ABORT, stcb %p\n",
|
||||
stcb);
|
||||
if ((stcb) && netp && *netp)
|
||||
sctp_handle_abort((struct sctp_abort_chunk *)ch,
|
||||
stcb, *netp);
|
||||
@ -3934,7 +3948,8 @@ sctp_process_control(struct mbuf *m, int iphlen, int *offset, int length,
|
||||
return (NULL);
|
||||
break;
|
||||
case SCTP_SHUTDOWN:
|
||||
SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_SHUTDOWN\n");
|
||||
SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_SHUTDOWN, stcb %p\n",
|
||||
stcb);
|
||||
if ((stcb == NULL) || (chk_length != sizeof(struct sctp_shutdown_chunk))) {
|
||||
*offset = length;
|
||||
if (locked_tcb) {
|
||||
@ -3955,7 +3970,7 @@ sctp_process_control(struct mbuf *m, int iphlen, int *offset, int length,
|
||||
}
|
||||
break;
|
||||
case SCTP_SHUTDOWN_ACK:
|
||||
SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_SHUTDOWN-ACK\n");
|
||||
SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_SHUTDOWN-ACK, stcb %p\n", stcb);
|
||||
if ((stcb) && (netp) && (*netp))
|
||||
sctp_handle_shutdown_ack((struct sctp_shutdown_ack_chunk *)ch, stcb, *netp);
|
||||
*offset = length;
|
||||
@ -3972,7 +3987,7 @@ sctp_process_control(struct mbuf *m, int iphlen, int *offset, int length,
|
||||
break;
|
||||
case SCTP_COOKIE_ECHO:
|
||||
SCTPDBG(SCTP_DEBUG_INPUT3,
|
||||
"SCTP_COOKIE-ECHO stcb is %p\n", stcb);
|
||||
"SCTP_COOKIE-ECHO, stcb %p\n", stcb);
|
||||
if ((stcb) && (stcb->asoc.total_output_queue_size)) {
|
||||
;
|
||||
} else {
|
||||
@ -4097,7 +4112,7 @@ sctp_process_control(struct mbuf *m, int iphlen, int *offset, int length,
|
||||
}
|
||||
break;
|
||||
case SCTP_COOKIE_ACK:
|
||||
SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_COOKIE-ACK\n");
|
||||
SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_COOKIE-ACK, stcb %p\n", stcb);
|
||||
if ((stcb == NULL) || chk_length != sizeof(struct sctp_cookie_ack_chunk)) {
|
||||
if (locked_tcb) {
|
||||
SCTP_TCB_UNLOCK(locked_tcb);
|
||||
@ -4154,7 +4169,7 @@ sctp_process_control(struct mbuf *m, int iphlen, int *offset, int length,
|
||||
}
|
||||
break;
|
||||
case SCTP_SHUTDOWN_COMPLETE:
|
||||
SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_SHUTDOWN-COMPLETE\n");
|
||||
SCTPDBG(SCTP_DEBUG_INPUT3, "SCTP_SHUTDOWN-COMPLETE, stcb %p\n", stcb);
|
||||
/* must be first and only chunk */
|
||||
if ((num_chunks > 1) ||
|
||||
(length - *offset > SCTP_SIZE32(chk_length))) {
|
||||
@ -4707,6 +4722,7 @@ sctp_input(i_pak, off)
|
||||
SCTP_STAT_INCR(sctps_recvpackets);
|
||||
SCTP_STAT_INCR_COUNTER64(sctps_inpackets);
|
||||
|
||||
|
||||
#ifdef SCTP_MBUF_LOGGING
|
||||
/* Log in any input mbufs */
|
||||
mat = m;
|
||||
@ -4717,6 +4733,14 @@ sctp_input(i_pak, off)
|
||||
mat = SCTP_BUF_NEXT(mat);
|
||||
}
|
||||
#endif
|
||||
#ifdef SCTP_PACKET_LOGGING
|
||||
sctp_packet_log(m, mlen);
|
||||
#endif
|
||||
/*
|
||||
* Must take out the iphlen, since mlen expects this (only effect lb
|
||||
* case)
|
||||
*/
|
||||
mlen -= iphlen;
|
||||
|
||||
/*
|
||||
* Get IP, SCTP, and first chunk header together in first mbuf.
|
||||
|
@ -133,6 +133,19 @@ extern int sctp_logoff_stuff;
|
||||
#define SCTP_IPI_ITERATOR_WQ_UNLOCK() mtx_unlock(&sctppcbinfo.ipi_iterator_wq_mtx)
|
||||
|
||||
|
||||
#define SCTP_IP_PKTLOG_INIT() \
|
||||
mtx_init(&sctppcbinfo.ipi_pktlog_mtx, "sctp-pktlog", "packetlog", MTX_DEF)
|
||||
|
||||
|
||||
#define SCTP_IP_PKTLOG_LOCK() do { \
|
||||
mtx_lock(&sctppcbinfo.ipi_pktlog_mtx); \
|
||||
} while (0)
|
||||
|
||||
#define SCTP_IP_PKTLOG_UNLOCK() mtx_unlock(&sctppcbinfo.ipi_pktlog_mtx)
|
||||
|
||||
#define SCTP_IP_PKTLOG_DESTROY() \
|
||||
mtx_destroy(&sctppcbinfo.ipi_pktlog_mtx)
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -98,8 +98,26 @@ __FBSDID("$FreeBSD$");
|
||||
#ifndef in6pcb
|
||||
#define in6pcb inpcb
|
||||
#endif
|
||||
|
||||
|
||||
/* Declare all the malloc names for all the various mallocs */
|
||||
MALLOC_DECLARE(SCTP_M_MAP);
|
||||
MALLOC_DECLARE(SCTP_M_STRMI);
|
||||
MALLOC_DECLARE(SCTP_M_STRMO);
|
||||
MALLOC_DECLARE(SCTP_M_ASC_ADDR);
|
||||
MALLOC_DECLARE(SCTP_M_ASC_IT);
|
||||
MALLOC_DECLARE(SCTP_M_AUTH_CL);
|
||||
MALLOC_DECLARE(SCTP_M_AUTH_KY);
|
||||
MALLOC_DECLARE(SCTP_M_AUTH_HL);
|
||||
MALLOC_DECLARE(SCTP_M_AUTH_IF);
|
||||
MALLOC_DECLARE(SCTP_M_STRESET);
|
||||
MALLOC_DECLARE(SCTP_M_CMSG);
|
||||
MALLOC_DECLARE(SCTP_M_COPYAL);
|
||||
MALLOC_DECLARE(SCTP_M_VRF);
|
||||
MALLOC_DECLARE(SCTP_M_IFA);
|
||||
MALLOC_DECLARE(SCTP_M_IFN);
|
||||
MALLOC_DECLARE(SCTP_M_TIMW);
|
||||
MALLOC_DECLARE(SCTP_M_MVRF);
|
||||
MALLOC_DECLARE(SCTP_M_ITER);
|
||||
MALLOC_DECLARE(SCTP_M_SOCKOPT);
|
||||
|
||||
/*
|
||||
*
|
||||
@ -166,10 +184,10 @@ __FBSDID("$FreeBSD$");
|
||||
*/
|
||||
#define SCTP_MALLOC(var, type, size, name) \
|
||||
do { \
|
||||
MALLOC(var, type, size, M_PCB, M_NOWAIT); \
|
||||
MALLOC(var, type, size, name, M_NOWAIT); \
|
||||
} while (0)
|
||||
|
||||
#define SCTP_FREE(var) FREE(var, M_PCB)
|
||||
#define SCTP_FREE(var, type) FREE(var, type)
|
||||
|
||||
#define SCTP_MALLOC_SONAME(var, type, size) \
|
||||
do { \
|
||||
@ -220,6 +238,8 @@ typedef struct callout sctp_os_timer_t;
|
||||
#define SCTP_OS_TIMER_ACTIVE callout_active
|
||||
#define SCTP_OS_TIMER_DEACTIVATE callout_deactivate
|
||||
|
||||
#define sctp_get_tick_count() (ticks)
|
||||
|
||||
/*
|
||||
* Functions
|
||||
*/
|
||||
@ -299,8 +319,8 @@ SCTP_GET_PKT_TABLEID(void *m, uint32_t table_id)
|
||||
} 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))
|
||||
#define SCTP_IS_IT_BROADCAST(dst, m) ((m->m_flags & M_PKTHDR) ? in_broadcast(dst, m->m_pkthdr.rcvif) : 0)
|
||||
#define SCTP_IS_IT_LOOPBACK(m) ((m->m_flags & M_PKTHDR) && ((m->m_pkthdr.rcvif == NULL) || (m->m_pkthdr.rcvif->if_type == IFT_LOOP)))
|
||||
|
||||
|
||||
/* This converts any input packet header
|
||||
|
@ -3463,6 +3463,9 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp,
|
||||
sctp_m_freem(m);
|
||||
return (ENOMEM);
|
||||
}
|
||||
#ifdef SCTP_PACKET_LOGGING
|
||||
sctp_packet_log(m, packet_length);
|
||||
#endif
|
||||
SCTP_ATTACH_CHAIN(o_pak, m, packet_length);
|
||||
|
||||
/* send it out. table id is taken from stcb */
|
||||
@ -3676,6 +3679,9 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp,
|
||||
sctp_m_freem(m);
|
||||
return (ENOMEM);
|
||||
}
|
||||
#ifdef SCTP_PACKET_LOGGING
|
||||
sctp_packet_log(m, packet_length);
|
||||
#endif
|
||||
SCTP_ATTACH_CHAIN(o_pak, m, packet_length);
|
||||
|
||||
/* send it out. table id is taken from stcb */
|
||||
@ -5773,7 +5779,7 @@ sctp_sendall_completes(void *ptr, uint32_t val)
|
||||
|
||||
/* now free everything */
|
||||
sctp_m_freem(ca->m);
|
||||
SCTP_FREE(ca);
|
||||
SCTP_FREE(ca, SCTP_M_COPYAL);
|
||||
}
|
||||
|
||||
|
||||
@ -5833,7 +5839,7 @@ sctp_sendall(struct sctp_inpcb *inp, struct uio *uio, struct mbuf *m,
|
||||
struct sctp_copy_all *ca;
|
||||
|
||||
SCTP_MALLOC(ca, struct sctp_copy_all *, sizeof(struct sctp_copy_all),
|
||||
"CopyAll");
|
||||
SCTP_M_COPYAL);
|
||||
if (ca == NULL) {
|
||||
sctp_m_freem(m);
|
||||
return (ENOMEM);
|
||||
@ -5852,7 +5858,7 @@ 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) {
|
||||
SCTP_FREE(ca);
|
||||
SCTP_FREE(ca, SCTP_M_COPYAL);
|
||||
return (ENOMEM);
|
||||
}
|
||||
} else {
|
||||
@ -5874,7 +5880,7 @@ sctp_sendall(struct sctp_inpcb *inp, struct uio *uio, struct mbuf *m,
|
||||
sctp_sendall_completes, inp, 1);
|
||||
if (ret) {
|
||||
SCTP_PRINTF("Failed to initiate iterator for sendall\n");
|
||||
SCTP_FREE(ca);
|
||||
SCTP_FREE(ca, SCTP_M_COPYAL);
|
||||
return (EFAULT);
|
||||
}
|
||||
return (0);
|
||||
@ -9344,6 +9350,9 @@ sctp_send_shutdown_complete2(struct mbuf *m, int iphlen, struct sctphdr *sh,
|
||||
bzero(&ro, sizeof ro);
|
||||
/* set IPv4 length */
|
||||
iph_out->ip_len = mlen;
|
||||
#ifdef SCTP_PACKET_LOGGING
|
||||
sctp_packet_log(mout, mlen);
|
||||
#endif
|
||||
SCTP_ATTACH_CHAIN(o_pak, mout, mlen);
|
||||
|
||||
/* out it goes */
|
||||
@ -9360,6 +9369,9 @@ sctp_send_shutdown_complete2(struct mbuf *m, int iphlen, struct sctphdr *sh,
|
||||
|
||||
bzero(&ro, sizeof(ro));
|
||||
mlen = SCTP_BUF_LEN(mout);
|
||||
#ifdef SCTP_PACKET_LOGGING
|
||||
sctp_packet_log(mout, mlen);
|
||||
#endif
|
||||
SCTP_ATTACH_CHAIN(o_pak, mout, mlen);
|
||||
SCTP_IP6_OUTPUT(ret, o_pak, &ro, &ifp, stcb, vrf_id, table_id);
|
||||
|
||||
@ -10209,6 +10221,9 @@ sctp_send_abort(struct mbuf *m, int iphlen, struct sctphdr *sh, uint32_t vtag,
|
||||
/* set IPv4 length */
|
||||
iph_out->ip_len = len;
|
||||
/* out it goes */
|
||||
#ifdef SCTP_PACKET_LOGGING
|
||||
sctp_packet_log(mout, len);
|
||||
#endif
|
||||
SCTP_ATTACH_CHAIN(o_pak, mout, len);
|
||||
SCTP_IP_OUTPUT(ret, o_pak, &ro, stcb, vrf_id, table_id);
|
||||
|
||||
@ -10226,6 +10241,9 @@ sctp_send_abort(struct mbuf *m, int iphlen, struct sctphdr *sh, uint32_t vtag,
|
||||
SCTPDBG(SCTP_DEBUG_OUTPUT2, "sctp_send_abort calling ip6_output:\n");
|
||||
SCTPDBG_PKT(SCTP_DEBUG_OUTPUT2, (struct ip *)ip6_out, &abm->sh);
|
||||
ip6_out->ip6_plen = len - sizeof(*ip6_out);
|
||||
#ifdef SCTP_PACKET_LOGGING
|
||||
sctp_packet_log(mout, len);
|
||||
#endif
|
||||
SCTP_ATTACH_CHAIN(o_pak, mout, len);
|
||||
SCTP_IP6_OUTPUT(ret, o_pak, &ro, &ifp, stcb, vrf_id, table_id);
|
||||
|
||||
@ -10327,6 +10345,9 @@ sctp_send_operr_to(struct mbuf *m, int iphlen, struct mbuf *scm, uint32_t vtag,
|
||||
out->ip_src = iph->ip_dst;
|
||||
out->ip_dst = iph->ip_src;
|
||||
out->ip_len = len;
|
||||
#ifdef SCTP_PACKET_LOGGING
|
||||
sctp_packet_log(mout, len);
|
||||
#endif
|
||||
SCTP_ATTACH_CHAIN(o_pak, mout, len);
|
||||
|
||||
SCTP_IP_OUTPUT(retcode, o_pak, &ro, stcb, vrf_id, table_id);
|
||||
@ -10372,6 +10393,9 @@ sctp_send_operr_to(struct mbuf *m, int iphlen, struct mbuf *scm, uint32_t vtag,
|
||||
SCTPDBG(SCTP_DEBUG_OUTPUT2, "dst ");
|
||||
SCTPDBG_ADDR(SCTP_DEBUG_OUTPUT2, (struct sockaddr *)&fsa6);
|
||||
|
||||
#ifdef SCTP_PACKET_LOGGING
|
||||
sctp_packet_log(mout, len);
|
||||
#endif
|
||||
SCTP_ATTACH_CHAIN(o_pak, mout, len);
|
||||
SCTP_IP6_OUTPUT(ret, o_pak, &ro, &ifp, stcb, vrf_id, table_id);
|
||||
|
||||
@ -10867,12 +10891,12 @@ sctp_lower_sosend(struct socket *so,
|
||||
struct sctp_stream_out *,
|
||||
(asoc->pre_open_streams *
|
||||
sizeof(struct sctp_stream_out)),
|
||||
"StreamsOut");
|
||||
SCTP_M_STRMO);
|
||||
if (had_lock) {
|
||||
SCTP_TCB_LOCK(stcb);
|
||||
}
|
||||
if (tmp_str != NULL) {
|
||||
SCTP_FREE(asoc->strmout);
|
||||
SCTP_FREE(asoc->strmout, SCTP_M_STRMO);
|
||||
asoc->strmout = tmp_str;
|
||||
asoc->streamoutcnt = asoc->pre_open_streams;
|
||||
} else {
|
||||
@ -10943,6 +10967,8 @@ sctp_lower_sosend(struct socket *so,
|
||||
}
|
||||
}
|
||||
/* Keep the stcb from being freed under our feet */
|
||||
if (free_cnt_applied)
|
||||
panic("refcnt already incremented");
|
||||
atomic_add_int(&stcb->asoc.refcnt, 1);
|
||||
free_cnt_applied = 1;
|
||||
|
||||
|
@ -142,7 +142,7 @@ sctp_allocate_vrf(int vrf_id)
|
||||
return (vrf);
|
||||
}
|
||||
SCTP_MALLOC(vrf, struct sctp_vrf *, sizeof(struct sctp_vrf),
|
||||
"SCTP_VRF");
|
||||
SCTP_M_VRF);
|
||||
if (vrf == NULL) {
|
||||
/* No memory */
|
||||
#ifdef INVARIANTS
|
||||
@ -163,7 +163,7 @@ sctp_allocate_vrf(int vrf_id)
|
||||
#ifdef INVARIANTS
|
||||
panic("No memory for VRF:%d", vrf_id);
|
||||
#endif
|
||||
SCTP_FREE(vrf);
|
||||
SCTP_FREE(vrf, SCTP_M_VRF);
|
||||
return (NULL);
|
||||
}
|
||||
vrf->vrf_ifn_hash = SCTP_HASH_INIT(SCTP_VRF_IFN_HASH_SIZE,
|
||||
@ -174,7 +174,7 @@ sctp_allocate_vrf(int vrf_id)
|
||||
panic("No memory for VRF:%d", vrf_id);
|
||||
#endif
|
||||
SCTP_HASH_FREE(vrf->vrf_addr_hash, vrf->vrf_addr_hashmark);
|
||||
SCTP_FREE(vrf);
|
||||
SCTP_FREE(vrf, SCTP_M_VRF);
|
||||
return (NULL);
|
||||
}
|
||||
/* Add it to the hash table */
|
||||
@ -233,7 +233,7 @@ sctp_free_ifn(struct sctp_ifn *sctp_ifnp)
|
||||
ret = atomic_fetchadd_int(&sctp_ifnp->refcount, -1);
|
||||
if (ret == 1) {
|
||||
/* We zero'd the count */
|
||||
SCTP_FREE(sctp_ifnp);
|
||||
SCTP_FREE(sctp_ifnp, SCTP_M_IFN);
|
||||
atomic_subtract_int(&sctppcbinfo.ipi_count_ifns, 1);
|
||||
}
|
||||
}
|
||||
@ -262,7 +262,7 @@ sctp_free_ifa(struct sctp_ifa *sctp_ifap)
|
||||
ret = atomic_fetchadd_int(&sctp_ifap->refcount, -1);
|
||||
if (ret == 1) {
|
||||
/* We zero'd the count */
|
||||
SCTP_FREE(sctp_ifap);
|
||||
SCTP_FREE(sctp_ifap, SCTP_M_IFA);
|
||||
atomic_subtract_int(&sctppcbinfo.ipi_count_ifas, 1);
|
||||
}
|
||||
}
|
||||
@ -318,7 +318,7 @@ sctp_add_addr_to_vrf(uint32_t vrf_id, void *ifn, uint32_t ifn_index,
|
||||
* done though.
|
||||
*/
|
||||
SCTP_IPI_ADDR_UNLOCK();
|
||||
SCTP_MALLOC(sctp_ifnp, struct sctp_ifn *, sizeof(struct sctp_ifn), "SCTP_IFN");
|
||||
SCTP_MALLOC(sctp_ifnp, struct sctp_ifn *, sizeof(struct sctp_ifn), SCTP_M_IFN);
|
||||
if (sctp_ifnp == NULL) {
|
||||
#ifdef INVARIANTS
|
||||
panic("No memory for IFN:%u", sctp_ifnp->ifn_index);
|
||||
@ -376,7 +376,7 @@ sctp_add_addr_to_vrf(uint32_t vrf_id, void *ifn, uint32_t ifn_index,
|
||||
}
|
||||
}
|
||||
SCTP_IPI_ADDR_UNLOCK();
|
||||
SCTP_MALLOC(sctp_ifap, struct sctp_ifa *, sizeof(struct sctp_ifa), "SCTP_IFA");
|
||||
SCTP_MALLOC(sctp_ifap, struct sctp_ifa *, sizeof(struct sctp_ifa), SCTP_M_IFA);
|
||||
if (sctp_ifap == NULL) {
|
||||
#ifdef INVARIANTS
|
||||
panic("No memory for IFA");
|
||||
@ -461,11 +461,11 @@ sctp_add_addr_to_vrf(uint32_t vrf_id, void *ifn, uint32_t ifn_index,
|
||||
* the newest first :-0
|
||||
*/
|
||||
LIST_INSERT_HEAD(&sctppcbinfo.addr_wq, wi, sctp_nxt_addr);
|
||||
SCTP_IPI_ITERATOR_WQ_UNLOCK();
|
||||
sctp_timer_start(SCTP_TIMER_TYPE_ADDR_WQ,
|
||||
(struct sctp_inpcb *)NULL,
|
||||
(struct sctp_tcb *)NULL,
|
||||
(struct sctp_nets *)NULL);
|
||||
SCTP_IPI_ITERATOR_WQ_UNLOCK();
|
||||
} else {
|
||||
/* it's ready for use */
|
||||
sctp_ifap->localifa_flags &= ~SCTP_ADDR_DEFER_USE;
|
||||
@ -539,11 +539,12 @@ sctp_del_addr_from_vrf(uint32_t vrf_id, struct sockaddr *addr,
|
||||
* the newest first :-0
|
||||
*/
|
||||
LIST_INSERT_HEAD(&sctppcbinfo.addr_wq, wi, sctp_nxt_addr);
|
||||
SCTP_IPI_ITERATOR_WQ_UNLOCK();
|
||||
|
||||
sctp_timer_start(SCTP_TIMER_TYPE_ADDR_WQ,
|
||||
(struct sctp_inpcb *)NULL,
|
||||
(struct sctp_tcb *)NULL,
|
||||
(struct sctp_nets *)NULL);
|
||||
SCTP_IPI_ITERATOR_WQ_UNLOCK();
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -2165,7 +2166,7 @@ sctp_inpcb_bind(struct socket *so, struct sockaddr *addr, struct thread *p)
|
||||
SCTP_INP_DECR_REF(inp);
|
||||
/* unlock info */
|
||||
SCTP_INP_INFO_WUNLOCK();
|
||||
return (EADDRNOTAVAIL);
|
||||
return (EADDRINUSE);
|
||||
}
|
||||
} else {
|
||||
inp_tmp = sctp_pcb_findep(addr, 0, 1, vrf_id);
|
||||
@ -2181,7 +2182,7 @@ sctp_inpcb_bind(struct socket *so, struct sockaddr *addr, struct thread *p)
|
||||
SCTP_INP_DECR_REF(inp);
|
||||
/* unlock info */
|
||||
SCTP_INP_INFO_WUNLOCK();
|
||||
return (EADDRNOTAVAIL);
|
||||
return (EADDRINUSE);
|
||||
}
|
||||
}
|
||||
SCTP_INP_WLOCK(inp);
|
||||
@ -2192,7 +2193,7 @@ sctp_inpcb_bind(struct socket *so, struct sockaddr *addr, struct thread *p)
|
||||
SCTP_INP_DECR_REF(inp);
|
||||
SCTP_INP_WUNLOCK(inp);
|
||||
SCTP_INP_INFO_WUNLOCK();
|
||||
return (EADDRNOTAVAIL);
|
||||
return (EADDRINUSE);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -2241,7 +2242,7 @@ sctp_inpcb_bind(struct socket *so, struct sockaddr *addr, struct thread *p)
|
||||
SCTP_INP_DECR_REF(inp);
|
||||
SCTP_INP_WUNLOCK(inp);
|
||||
SCTP_INP_INFO_WUNLOCK();
|
||||
return (EADDRNOTAVAIL);
|
||||
return (EADDRINUSE);
|
||||
}
|
||||
if (candiate == last)
|
||||
candiate = first;
|
||||
@ -2449,7 +2450,7 @@ sctp_inpcb_free(struct sctp_inpcb *inp, int immediate, int from)
|
||||
so = inp->sctp_socket;
|
||||
if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) {
|
||||
/* been here before.. eeks.. get out of here */
|
||||
SCTP_PRINTF("This conflict in free SHOULD not be happening!\n");
|
||||
SCTP_PRINTF("This conflict in free SHOULD not be happening! from %d, imm %d\n", from, immediate);
|
||||
SCTP_ITERATOR_UNLOCK();
|
||||
#ifdef SCTP_LOG_CLOSING
|
||||
sctp_log_closing(inp, NULL, 1);
|
||||
@ -3375,11 +3376,14 @@ sctp_aloc_assoc(struct sctp_inpcb *inp, struct sockaddr *firstaddr,
|
||||
|
||||
if ((err = sctp_add_remote_addr(stcb, firstaddr, SCTP_DO_SETSCOPE, SCTP_ALLOC_ASOC))) {
|
||||
/* failure.. memory error? */
|
||||
if (asoc->strmout)
|
||||
SCTP_FREE(asoc->strmout);
|
||||
if (asoc->mapping_array)
|
||||
SCTP_FREE(asoc->mapping_array);
|
||||
|
||||
if (asoc->strmout) {
|
||||
SCTP_FREE(asoc->strmout, SCTP_M_STRMO);
|
||||
asoc->strmout = NULL;
|
||||
}
|
||||
if (asoc->mapping_array) {
|
||||
SCTP_FREE(asoc->mapping_array, SCTP_M_MAP);
|
||||
asoc->mapping_array = NULL;
|
||||
}
|
||||
SCTP_ZONE_FREE(sctppcbinfo.ipi_zone_asoc, stcb);
|
||||
SCTP_DECR_ASOC_COUNT();
|
||||
SCTP_TCB_LOCK_DESTROY(stcb);
|
||||
@ -3526,7 +3530,7 @@ sctp_add_vtag_to_timewait(struct sctp_inpcb *inp, uint32_t tag, uint32_t time)
|
||||
/* Need to add a new block to chain */
|
||||
if (!set) {
|
||||
SCTP_MALLOC(twait_block, struct sctp_tagblock *,
|
||||
sizeof(struct sctp_tagblock), "TimeWait");
|
||||
sizeof(struct sctp_tagblock), SCTP_M_TIMW);
|
||||
if (twait_block == NULL) {
|
||||
return;
|
||||
}
|
||||
@ -3877,7 +3881,7 @@ sctp_free_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int from_inpcbfre
|
||||
/* sa_ignore FREED_MEMORY */
|
||||
while ((liste = TAILQ_FIRST(&asoc->resetHead)) != NULL) {
|
||||
TAILQ_REMOVE(&asoc->resetHead, liste, next_resp);
|
||||
SCTP_FREE(liste);
|
||||
SCTP_FREE(liste, SCTP_M_STRESET);
|
||||
}
|
||||
|
||||
sq = TAILQ_FIRST(&asoc->pending_reply_queue);
|
||||
@ -4004,12 +4008,12 @@ sctp_free_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int from_inpcbfre
|
||||
}
|
||||
*/
|
||||
if (asoc->mapping_array) {
|
||||
SCTP_FREE(asoc->mapping_array);
|
||||
SCTP_FREE(asoc->mapping_array, SCTP_M_MAP);
|
||||
asoc->mapping_array = NULL;
|
||||
}
|
||||
/* the stream outs */
|
||||
if (asoc->strmout) {
|
||||
SCTP_FREE(asoc->strmout);
|
||||
SCTP_FREE(asoc->strmout, SCTP_M_STRMO);
|
||||
asoc->strmout = NULL;
|
||||
}
|
||||
asoc->streamoutcnt = 0;
|
||||
@ -4039,7 +4043,7 @@ sctp_free_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int from_inpcbfre
|
||||
}
|
||||
}
|
||||
}
|
||||
SCTP_FREE(asoc->strmin);
|
||||
SCTP_FREE(asoc->strmin, SCTP_M_STRMI);
|
||||
asoc->strmin = NULL;
|
||||
}
|
||||
asoc->streamincnt = 0;
|
||||
@ -4069,7 +4073,7 @@ sctp_free_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int from_inpcbfre
|
||||
/* sa_ignore FREED_MEMORY */
|
||||
aparam = TAILQ_FIRST(&asoc->asconf_queue);
|
||||
TAILQ_REMOVE(&asoc->asconf_queue, aparam, next);
|
||||
SCTP_FREE(aparam);
|
||||
SCTP_FREE(aparam, SCTP_M_ASC_ADDR);
|
||||
}
|
||||
if (asoc->last_asconf_ack_sent != NULL) {
|
||||
sctp_m_freem(asoc->last_asconf_ack_sent);
|
||||
@ -4589,7 +4593,9 @@ sctp_pcb_init()
|
||||
SCTP_IPI_COUNT_INIT();
|
||||
SCTP_IPI_ADDR_INIT();
|
||||
SCTP_IPI_ITERATOR_WQ_INIT();
|
||||
|
||||
#ifdef SCTP_PACKET_LOGGING
|
||||
SCTP_IP_PKTLOG_INIT();
|
||||
#endif
|
||||
LIST_INIT(&sctppcbinfo.addr_wq);
|
||||
|
||||
/* not sure if we need all the counts */
|
||||
@ -5559,7 +5565,7 @@ sctp_initiate_iterator(inp_func inpf,
|
||||
return (-1);
|
||||
}
|
||||
SCTP_MALLOC(it, struct sctp_iterator *, sizeof(struct sctp_iterator),
|
||||
"Iterator");
|
||||
SCTP_M_ITER);
|
||||
if (it == NULL) {
|
||||
return (ENOMEM);
|
||||
}
|
||||
|
@ -182,6 +182,7 @@ struct sctp_epinfo {
|
||||
struct mtx it_mtx;
|
||||
struct mtx ipi_iterator_wq_mtx;
|
||||
struct mtx ipi_addr_mtx;
|
||||
struct mtx ipi_pktlog_mtx;
|
||||
uint32_t ipi_count_ep;
|
||||
|
||||
/* assoc/tcb zone info */
|
||||
|
@ -391,6 +391,7 @@ sctp_assoclist(SYSCTL_HANDLER_ARGS)
|
||||
xstcb.cumulative_tsn = stcb->asoc.last_acked_seq;
|
||||
xstcb.cumulative_tsn_ack = stcb->asoc.cumulative_tsn;
|
||||
xstcb.mtu = stcb->asoc.smallest_mtu;
|
||||
xstcb.refcnt = stcb->asoc.refcnt;
|
||||
SCTP_INP_RUNLOCK(inp);
|
||||
SCTP_INP_INFO_RUNLOCK();
|
||||
error = SYSCTL_OUT(req, &xstcb, sizeof(struct xsctp_tcb));
|
||||
|
@ -1640,7 +1640,7 @@ sctp_iterator_timer(struct sctp_iterator *it)
|
||||
if (it->function_atend != NULL) {
|
||||
(*it->function_atend) (it->pointer, it->val);
|
||||
}
|
||||
SCTP_FREE(it);
|
||||
SCTP_FREE(it, SCTP_M_ITER);
|
||||
return;
|
||||
}
|
||||
select_a_new_ep:
|
||||
|
@ -897,6 +897,8 @@ struct sctpstat {
|
||||
* burst inflight to net */
|
||||
u_long sctps_send_cwnd_avoid; /* Send cwnd full avoidance, already
|
||||
* max burst inflight to net */
|
||||
u_long sctps_fwdtsn_map_over; /* number of map array over-runs via
|
||||
* fwd-tsn's */
|
||||
};
|
||||
|
||||
#define SCTP_STAT_INCR(_x) SCTP_STAT_INCR_BY(_x,1)
|
||||
@ -960,6 +962,7 @@ struct xsctp_tcb {
|
||||
uint32_t cumulative_tsn;
|
||||
uint32_t cumulative_tsn_ack;
|
||||
uint32_t mtu;
|
||||
uint32_t refcnt;
|
||||
/* add more association specific data here */
|
||||
};
|
||||
|
||||
|
@ -48,6 +48,8 @@ __FBSDID("$FreeBSD$");
|
||||
#include <netinet/sctp_indata.h>
|
||||
#include <netinet/sctp_timer.h>
|
||||
#include <netinet/sctp_auth.h>
|
||||
#include <netinet/sctp_bsd_addr.h>
|
||||
|
||||
|
||||
|
||||
|
||||
@ -1478,7 +1480,20 @@ sctp_getopt(struct socket *so, int optname, void *optval, size_t *optsize,
|
||||
*optsize = sizeof(val);
|
||||
}
|
||||
break;
|
||||
case SCTP_GET_PACKET_LOG:
|
||||
{
|
||||
#ifdef SCTP_PACKET_LOGGING
|
||||
uint8_t *target;
|
||||
int ret;
|
||||
|
||||
SCTP_CHECK_AND_CAST(target, optval, uint8_t, *optsize);
|
||||
ret = sctp_copy_out_packet_log(target, (int)*optsize);
|
||||
*optsize = ret;
|
||||
#else
|
||||
error = EOPNOTSUPP;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
case SCTP_PARTIAL_DELIVERY_POINT:
|
||||
{
|
||||
uint32_t *value;
|
||||
@ -3560,7 +3575,7 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
|
||||
error = sctp_addr_mgmt_ep_sa(inp, addr_touse,
|
||||
SCTP_ADD_IP_ADDRESS, vrf_id);
|
||||
} else {
|
||||
error = EADDRNOTAVAIL;
|
||||
error = EADDRINUSE;
|
||||
}
|
||||
if (error)
|
||||
break;
|
||||
@ -3659,13 +3674,13 @@ sctp_ctloutput(struct socket *so, struct sockopt *sopt)
|
||||
}
|
||||
optsize = sopt->sopt_valsize;
|
||||
if (optsize) {
|
||||
SCTP_MALLOC(optval, void *, optsize, "SCTPSockOpt");
|
||||
SCTP_MALLOC(optval, void *, optsize, SCTP_M_SOCKOPT);
|
||||
if (optval == NULL) {
|
||||
return (ENOBUFS);
|
||||
}
|
||||
error = sooptcopyin(sopt, optval, optsize, optsize);
|
||||
if (error) {
|
||||
SCTP_FREE(optval);
|
||||
SCTP_FREE(optval, SCTP_M_SOCKOPT);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
@ -3679,9 +3694,9 @@ sctp_ctloutput(struct socket *so, struct sockopt *sopt)
|
||||
}
|
||||
if ((error == 0) && (optval != NULL)) {
|
||||
error = sooptcopyout(sopt, optval, optsize);
|
||||
SCTP_FREE(optval);
|
||||
SCTP_FREE(optval, SCTP_M_SOCKOPT);
|
||||
} else if (optval != NULL) {
|
||||
SCTP_FREE(optval);
|
||||
SCTP_FREE(optval, SCTP_M_SOCKOPT);
|
||||
}
|
||||
out:
|
||||
return (error);
|
||||
|
@ -1061,7 +1061,7 @@ sctp_init_asoc(struct sctp_inpcb *m, struct sctp_association *asoc,
|
||||
m->sctp_ep.pre_open_stream_count;
|
||||
SCTP_MALLOC(asoc->strmout, struct sctp_stream_out *,
|
||||
asoc->streamoutcnt * sizeof(struct sctp_stream_out),
|
||||
"StreamsOut");
|
||||
SCTP_M_STRMO);
|
||||
if (asoc->strmout == NULL) {
|
||||
/* big trouble no memory */
|
||||
return (ENOMEM);
|
||||
@ -1085,9 +1085,9 @@ sctp_init_asoc(struct sctp_inpcb *m, struct sctp_association *asoc,
|
||||
/* Now the mapping array */
|
||||
asoc->mapping_array_size = SCTP_INITIAL_MAPPING_ARRAY;
|
||||
SCTP_MALLOC(asoc->mapping_array, uint8_t *, asoc->mapping_array_size,
|
||||
"MappingArray");
|
||||
SCTP_M_MAP);
|
||||
if (asoc->mapping_array == NULL) {
|
||||
SCTP_FREE(asoc->strmout);
|
||||
SCTP_FREE(asoc->strmout, SCTP_M_STRMO);
|
||||
return (ENOMEM);
|
||||
}
|
||||
memset(asoc->mapping_array, 0, asoc->mapping_array_size);
|
||||
@ -1129,7 +1129,7 @@ sctp_expand_mapping_array(struct sctp_association *asoc)
|
||||
uint16_t new_size;
|
||||
|
||||
new_size = asoc->mapping_array_size + SCTP_MAPPING_ARRAY_INCR;
|
||||
SCTP_MALLOC(new_array, uint8_t *, new_size, "MappingArray");
|
||||
SCTP_MALLOC(new_array, uint8_t *, new_size, SCTP_M_MAP);
|
||||
if (new_array == NULL) {
|
||||
/* can't get more, forget it */
|
||||
SCTP_PRINTF("No memory for expansion of SCTP mapping array %d\n",
|
||||
@ -1138,7 +1138,7 @@ sctp_expand_mapping_array(struct sctp_association *asoc)
|
||||
}
|
||||
memset(new_array, 0, new_size);
|
||||
memcpy(new_array, asoc->mapping_array, asoc->mapping_array_size);
|
||||
SCTP_FREE(asoc->mapping_array);
|
||||
SCTP_FREE(asoc->mapping_array, SCTP_M_MAP);
|
||||
asoc->mapping_array = new_array;
|
||||
asoc->mapping_array_size = new_size;
|
||||
return (0);
|
||||
@ -1162,7 +1162,7 @@ sctp_iterator_work(struct sctp_iterator *it)
|
||||
if (it->function_atend != NULL) {
|
||||
(*it->function_atend) (it->pointer, it->val);
|
||||
}
|
||||
SCTP_FREE(it);
|
||||
SCTP_FREE(it, SCTP_M_ITER);
|
||||
return;
|
||||
}
|
||||
select_a_new_ep:
|
||||
@ -1314,7 +1314,7 @@ sctp_handle_addr_wq(void)
|
||||
struct sctp_asconf_iterator *asc;
|
||||
|
||||
SCTP_MALLOC(asc, struct sctp_asconf_iterator *,
|
||||
sizeof(struct sctp_asconf_iterator), "SCTP_ASCONF_ITERATOR");
|
||||
sizeof(struct sctp_asconf_iterator), SCTP_M_ASC_IT);
|
||||
if (asc == NULL) {
|
||||
/* Try later, no memory */
|
||||
sctp_timer_start(SCTP_TIMER_TYPE_ADDR_WQ,
|
||||
@ -1335,7 +1335,7 @@ sctp_handle_addr_wq(void)
|
||||
}
|
||||
SCTP_IPI_ITERATOR_WQ_UNLOCK();
|
||||
if (asc->cnt == 0) {
|
||||
SCTP_FREE(asc);
|
||||
SCTP_FREE(asc, SCTP_M_ASC_IT);
|
||||
} else {
|
||||
(void)sctp_initiate_iterator(sctp_iterator_ep,
|
||||
sctp_iterator_stcb,
|
||||
@ -1426,6 +1426,9 @@ sctp_timeout_handler(void *t)
|
||||
if (inp) {
|
||||
SCTP_INP_DECR_REF(inp);
|
||||
}
|
||||
if (stcb) {
|
||||
atomic_add_int(&stcb->asoc.refcnt, -1);
|
||||
}
|
||||
return;
|
||||
}
|
||||
tmr->stopped_from = 0xa006;
|
||||
@ -4945,6 +4948,8 @@ sctp_sorecvmsg(struct socket *so,
|
||||
* to increment, we need to use the atomic add to
|
||||
* the refcnt
|
||||
*/
|
||||
if (freecnt_applied)
|
||||
panic("refcnt already incremented");
|
||||
atomic_add_int(&stcb->asoc.refcnt, 1);
|
||||
freecnt_applied = 1;
|
||||
/*
|
||||
|
@ -50,6 +50,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <netinet/sctp_auth.h>
|
||||
#include <netinet/sctp_input.h>
|
||||
#include <netinet/sctp_output.h>
|
||||
#include <netinet/sctp_bsd_addr.h>
|
||||
|
||||
|
||||
extern struct protosw inetsw[];
|
||||
@ -91,6 +92,9 @@ sctp6_input(i_pak, offp, proto)
|
||||
m = SCTP_HEADER_TO_CHAIN(*i_pak);
|
||||
pkt_len = SCTP_HEADER_LEN((*i_pak));
|
||||
|
||||
#ifdef SCTP_PACKET_LOGGING
|
||||
sctp_packet_log(m, pkt_len);
|
||||
#endif
|
||||
ip6 = mtod(m, struct ip6_hdr *);
|
||||
/* Ensure that (sctphdr + sctp_chunkhdr) in a row. */
|
||||
IP6_EXTHDR_GET(sh, struct sctphdr *, m, off,
|
||||
|
Loading…
Reference in New Issue
Block a user