Unify sctp_input() and sctp6_input().
MFC after: 3 days
This commit is contained in:
parent
f2618bb4d1
commit
6dc5aabcb7
@ -5885,12 +5885,12 @@ sctp_input_with_port(struct mbuf *i_pak, int off, uint16_t port)
|
||||
uint8_t ecn_bits;
|
||||
struct ip *ip;
|
||||
struct sctphdr *sh;
|
||||
struct sctp_inpcb *inp = NULL;
|
||||
struct sctp_nets *net;
|
||||
struct sctp_tcb *stcb = NULL;
|
||||
struct sctp_chunkhdr *ch;
|
||||
struct sctp_inpcb *inp = NULL;
|
||||
struct sctp_tcb *stcb = NULL;
|
||||
struct sctp_nets *net = NULL;
|
||||
int refcount_up = 0;
|
||||
int length, mlen, offset;
|
||||
int length, offset;
|
||||
uint32_t mflowid;
|
||||
uint8_t use_mflowid;
|
||||
|
||||
@ -5899,19 +5899,12 @@ sctp_input_with_port(struct mbuf *i_pak, int off, uint16_t port)
|
||||
|
||||
#endif
|
||||
|
||||
iphlen = off;
|
||||
if (SCTP_GET_PKT_VRFID(i_pak, vrf_id)) {
|
||||
SCTP_RELEASE_PKT(i_pak);
|
||||
return;
|
||||
}
|
||||
mlen = SCTP_HEADER_LEN(i_pak);
|
||||
iphlen = off;
|
||||
m = SCTP_HEADER_TO_CHAIN(i_pak);
|
||||
|
||||
net = NULL;
|
||||
SCTP_STAT_INCR(sctps_recvpackets);
|
||||
SCTP_STAT_INCR_COUNTER64(sctps_inpackets);
|
||||
|
||||
|
||||
#ifdef SCTP_MBUF_LOGGING
|
||||
/* Log in any input mbufs */
|
||||
if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_MBUF_LOGGING_ENABLE) {
|
||||
@ -5925,8 +5918,9 @@ sctp_input_with_port(struct mbuf *i_pak, int off, uint16_t port)
|
||||
}
|
||||
#endif
|
||||
#ifdef SCTP_PACKET_LOGGING
|
||||
if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LAST_PACKET_TRACING)
|
||||
if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LAST_PACKET_TRACING) {
|
||||
sctp_packet_log(m);
|
||||
}
|
||||
#endif
|
||||
if (m->m_flags & M_FLOWID) {
|
||||
mflowid = m->m_pkthdr.flowid;
|
||||
@ -5935,17 +5929,11 @@ sctp_input_with_port(struct mbuf *i_pak, int off, uint16_t port)
|
||||
mflowid = 0;
|
||||
use_mflowid = 0;
|
||||
}
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
SCTP_STAT_INCR(sctps_recvpackets);
|
||||
SCTP_STAT_INCR_COUNTER64(sctps_inpackets);
|
||||
/* Get IP, SCTP, and first chunk header together in the first mbuf. */
|
||||
ip = mtod(m, struct ip *);
|
||||
offset = iphlen + sizeof(*sh) + sizeof(*ch);
|
||||
offset = iphlen + sizeof(struct sctphdr) + sizeof(struct sctp_chunkhdr);
|
||||
if (SCTP_BUF_LEN(m) < offset) {
|
||||
if ((m = m_pullup(m, offset)) == 0) {
|
||||
SCTP_STAT_INCR(sctps_hdrops);
|
||||
@ -5953,28 +5941,26 @@ sctp_input_with_port(struct mbuf *i_pak, int off, uint16_t port)
|
||||
}
|
||||
ip = mtod(m, struct ip *);
|
||||
}
|
||||
/* validate mbuf chain length with IP payload length */
|
||||
if (mlen < (SCTP_GET_IPV4_LENGTH(ip) - iphlen)) {
|
||||
sh = (struct sctphdr *)((caddr_t)ip + iphlen);
|
||||
ch = (struct sctp_chunkhdr *)((caddr_t)sh + sizeof(struct sctphdr));
|
||||
offset -= sizeof(struct sctp_chunkhdr);
|
||||
length = ip->ip_len + iphlen;
|
||||
/* Validate mbuf chain length with IP payload length. */
|
||||
if (SCTP_HEADER_LEN(i_pak) != length) {
|
||||
SCTPDBG(SCTP_DEBUG_INPUT1,
|
||||
"sctp_input() length:%d reported length:%d\n", length, SCTP_HEADER_LEN(i_pak));
|
||||
SCTP_STAT_INCR(sctps_hdrops);
|
||||
goto bad;
|
||||
}
|
||||
sh = (struct sctphdr *)((caddr_t)ip + iphlen);
|
||||
ch = (struct sctp_chunkhdr *)((caddr_t)sh + sizeof(*sh));
|
||||
SCTPDBG(SCTP_DEBUG_INPUT1,
|
||||
"sctp_input() length:%d iphlen:%d\n", mlen, iphlen);
|
||||
|
||||
/* SCTP does not allow broadcasts or multicasts */
|
||||
if (IN_MULTICAST(ntohl(ip->ip_dst.s_addr))) {
|
||||
goto bad;
|
||||
}
|
||||
if (SCTP_IS_IT_BROADCAST(ip->ip_dst, m)) {
|
||||
/*
|
||||
* We only look at broadcast if its a front state, All
|
||||
* others we will not have a tcb for anyway.
|
||||
*/
|
||||
goto bad;
|
||||
}
|
||||
/* validate SCTP checksum */
|
||||
SCTPDBG(SCTP_DEBUG_INPUT1,
|
||||
"sctp_input() length:%d iphlen:%d\n", length, iphlen);
|
||||
SCTPDBG(SCTP_DEBUG_CRCOFFLOAD,
|
||||
"sctp_input(): Packet of length %d received on %s with csum_flags 0x%x.\n",
|
||||
m->m_pkthdr.len,
|
||||
@ -5985,21 +5971,18 @@ sctp_input_with_port(struct mbuf *i_pak, int off, uint16_t port)
|
||||
#else
|
||||
if (m->m_pkthdr.csum_flags & CSUM_SCTP_VALID) {
|
||||
SCTP_STAT_INCR(sctps_recvhwcrc);
|
||||
goto sctp_skip_csum_4;
|
||||
goto sctp_skip_csum;
|
||||
}
|
||||
check = sh->checksum; /* save incoming checksum */
|
||||
sh->checksum = 0; /* prepare for calc */
|
||||
check = sh->checksum;
|
||||
sh->checksum = 0;
|
||||
calc_check = sctp_calculate_cksum(m, iphlen);
|
||||
sh->checksum = check;
|
||||
SCTP_STAT_INCR(sctps_recvswcrc);
|
||||
if (calc_check != check) {
|
||||
SCTPDBG(SCTP_DEBUG_INPUT1, "Bad CSUM on SCTP packet calc_check:%x check:%x m:%p mlen:%d iphlen:%d\n",
|
||||
calc_check, check, m, mlen, iphlen);
|
||||
|
||||
stcb = sctp_findassociation_addr(m,
|
||||
offset - sizeof(*ch),
|
||||
sh, ch, &inp, &net,
|
||||
vrf_id);
|
||||
calc_check, check, m, length, iphlen);
|
||||
stcb = sctp_findassociation_addr(m, offset,
|
||||
sh, ch, &inp, &net, vrf_id);
|
||||
if ((net) && (port)) {
|
||||
if (net->port == 0) {
|
||||
sctp_pathmtu_adjustment(stcb, net->mtu - sizeof(struct udphdr));
|
||||
@ -6013,7 +5996,7 @@ sctp_input_with_port(struct mbuf *i_pak, int off, uint16_t port)
|
||||
#endif
|
||||
}
|
||||
if ((inp) && (stcb)) {
|
||||
sctp_send_packet_dropped(stcb, net, m, mlen + iphlen, iphlen, 1);
|
||||
sctp_send_packet_dropped(stcb, net, m, length, iphlen, 1);
|
||||
sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_INPUT_ERROR, SCTP_SO_NOT_LOCKED);
|
||||
} else if ((inp != NULL) && (stcb == NULL)) {
|
||||
refcount_up = 1;
|
||||
@ -6022,18 +6005,14 @@ sctp_input_with_port(struct mbuf *i_pak, int off, uint16_t port)
|
||||
SCTP_STAT_INCR_COUNTER32(sctps_checksumerrors);
|
||||
goto bad;
|
||||
}
|
||||
sctp_skip_csum_4:
|
||||
sctp_skip_csum:
|
||||
#endif
|
||||
/* destination port of 0 is illegal, based on RFC2960. */
|
||||
if (sh->dest_port == 0) {
|
||||
SCTP_STAT_INCR(sctps_hdrops);
|
||||
goto bad;
|
||||
}
|
||||
/*
|
||||
* Locate pcb and tcb for datagram sctp_findassociation_addr() wants
|
||||
* IP/SCTP/first chunk header...
|
||||
*/
|
||||
stcb = sctp_findassociation_addr(m, offset - sizeof(*ch),
|
||||
stcb = sctp_findassociation_addr(m, offset,
|
||||
sh, ch, &inp, &net, vrf_id);
|
||||
if ((net) && (port)) {
|
||||
if (net->port == 0) {
|
||||
@ -6047,27 +6026,10 @@ sctp_skip_csum_4:
|
||||
net->flowidset = 1;
|
||||
#endif
|
||||
}
|
||||
/* inp's ref-count increased && stcb locked */
|
||||
if (inp == NULL) {
|
||||
struct sctp_init_chunk *init_chk, chunk_buf;
|
||||
|
||||
SCTP_STAT_INCR(sctps_noport);
|
||||
if (badport_bandlim(BANDLIM_SCTP_OOTB) < 0)
|
||||
goto bad;
|
||||
SCTPDBG(SCTP_DEBUG_INPUT1,
|
||||
"Sending a ABORT from packet entry!\n");
|
||||
if (ch->chunk_type == SCTP_INITIATION) {
|
||||
/*
|
||||
* we do a trick here to get the INIT tag, dig in
|
||||
* and get the tag from the INIT and put it in the
|
||||
* common header.
|
||||
*/
|
||||
init_chk = (struct sctp_init_chunk *)sctp_m_getptr(m,
|
||||
iphlen + sizeof(*sh), sizeof(*init_chk),
|
||||
(uint8_t *) & chunk_buf);
|
||||
if (init_chk != NULL)
|
||||
sh->v_tag = init_chk->init.initiate_tag;
|
||||
}
|
||||
if (ch->chunk_type == SCTP_SHUTDOWN_ACK) {
|
||||
sctp_send_shutdown_complete2(m, sh,
|
||||
use_mflowid, mflowid,
|
||||
@ -6091,7 +6053,7 @@ sctp_skip_csum_4:
|
||||
refcount_up = 1;
|
||||
}
|
||||
#ifdef IPSEC
|
||||
/*
|
||||
/*-
|
||||
* I very much doubt any of the IPSEC stuff will work but I have no
|
||||
* idea, so I will leave it in place.
|
||||
*/
|
||||
@ -6100,28 +6062,22 @@ sctp_skip_csum_4:
|
||||
SCTP_STAT_INCR(sctps_hdrops);
|
||||
goto bad;
|
||||
}
|
||||
#endif /* IPSEC */
|
||||
|
||||
/*
|
||||
* common chunk processing
|
||||
*/
|
||||
length = ip->ip_len + iphlen;
|
||||
offset -= sizeof(struct sctp_chunkhdr);
|
||||
#endif
|
||||
|
||||
ecn_bits = ip->ip_tos;
|
||||
|
||||
/* sa_ignore NO_NULL_CHK */
|
||||
sctp_common_input_processing(&m, iphlen, offset, length, sh, ch,
|
||||
inp, stcb, net, ecn_bits,
|
||||
use_mflowid, mflowid,
|
||||
vrf_id, port);
|
||||
/* inp's ref-count reduced && stcb unlocked */
|
||||
if (m) {
|
||||
sctp_m_freem(m);
|
||||
}
|
||||
if ((inp) && (refcount_up)) {
|
||||
/* reduce ref-count */
|
||||
SCTP_INP_WLOCK(inp);
|
||||
SCTP_INP_DECR_REF(inp);
|
||||
SCTP_INP_WUNLOCK(inp);
|
||||
}
|
||||
return;
|
||||
bad:
|
||||
@ -6130,7 +6086,9 @@ bad:
|
||||
}
|
||||
if ((inp) && (refcount_up)) {
|
||||
/* reduce ref-count */
|
||||
SCTP_INP_WLOCK(inp);
|
||||
SCTP_INP_DECR_REF(inp);
|
||||
SCTP_INP_WUNLOCK(inp);
|
||||
}
|
||||
if (m) {
|
||||
sctp_m_freem(m);
|
||||
|
@ -68,22 +68,17 @@ int
|
||||
sctp6_input(struct mbuf **i_pak, int *offp, int proto)
|
||||
{
|
||||
struct mbuf *m;
|
||||
int iphlen;
|
||||
uint32_t vrf_id = 0;
|
||||
uint8_t ecn_bits;
|
||||
struct ip6_hdr *ip6;
|
||||
struct sctphdr *sh;
|
||||
struct sctp_inpcb *in6p = NULL;
|
||||
struct sctp_nets *net;
|
||||
int refcount_up = 0;
|
||||
uint32_t vrf_id = 0;
|
||||
|
||||
#ifdef IPSEC
|
||||
struct inpcb *in6p_ip;
|
||||
|
||||
#endif
|
||||
struct sctp_chunkhdr *ch;
|
||||
int length, offset, iphlen;
|
||||
uint8_t ecn_bits;
|
||||
struct sctp_inpcb *inp = NULL;
|
||||
struct sctp_tcb *stcb = NULL;
|
||||
int pkt_len = 0;
|
||||
struct sctp_nets *net = NULL;
|
||||
int refcount_up = 0;
|
||||
int length, offset;
|
||||
uint32_t mflowid;
|
||||
uint8_t use_mflowid;
|
||||
|
||||
@ -91,17 +86,26 @@ sctp6_input(struct mbuf **i_pak, int *offp, int proto)
|
||||
uint32_t check, calc_check;
|
||||
|
||||
#endif
|
||||
int off = *offp;
|
||||
uint16_t port = 0;
|
||||
|
||||
/* get the VRF and table id's */
|
||||
iphlen = *offp;
|
||||
if (SCTP_GET_PKT_VRFID(*i_pak, vrf_id)) {
|
||||
SCTP_RELEASE_PKT(*i_pak);
|
||||
return (-1);
|
||||
return (IPPROTO_DONE);
|
||||
}
|
||||
m = SCTP_HEADER_TO_CHAIN(*i_pak);
|
||||
pkt_len = SCTP_HEADER_LEN(*i_pak);
|
||||
#ifdef SCTP_MBUF_LOGGING
|
||||
/* Log in any input mbufs */
|
||||
if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_MBUF_LOGGING_ENABLE) {
|
||||
struct mbuf *mat;
|
||||
|
||||
for (mat = m; mat; mat = SCTP_BUF_NEXT(mat)) {
|
||||
if (SCTP_BUF_IS_EXTENDED(mat)) {
|
||||
sctp_log_mb(mat, SCTP_MBUF_INPUT);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifdef SCTP_PACKET_LOGGING
|
||||
if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LAST_PACKET_TRACING) {
|
||||
sctp_packet_log(m);
|
||||
@ -114,42 +118,38 @@ sctp6_input(struct mbuf **i_pak, int *offp, int proto)
|
||||
mflowid = 0;
|
||||
use_mflowid = 0;
|
||||
}
|
||||
SCTP_STAT_INCR(sctps_recvpackets);
|
||||
SCTP_STAT_INCR_COUNTER64(sctps_inpackets);
|
||||
/* Get IP, SCTP, and first chunk header together in the first mbuf. */
|
||||
ip6 = mtod(m, struct ip6_hdr *);
|
||||
/* Ensure that (sctphdr + sctp_chunkhdr) in a row. */
|
||||
IP6_EXTHDR_GET(sh, struct sctphdr *, m, off,
|
||||
(int)(sizeof(*sh) + sizeof(*ch)));
|
||||
offset = iphlen + sizeof(struct sctphdr) + sizeof(struct sctp_chunkhdr);
|
||||
IP6_EXTHDR_GET(sh, struct sctphdr *, m, iphlen,
|
||||
(int)(sizeof(struct sctphdr) + sizeof(struct sctp_chunkhdr)));
|
||||
if (sh == NULL) {
|
||||
SCTP_STAT_INCR(sctps_hdrops);
|
||||
return (IPPROTO_DONE);
|
||||
}
|
||||
ch = (struct sctp_chunkhdr *)((caddr_t)sh + sizeof(struct sctphdr));
|
||||
iphlen = off;
|
||||
offset = iphlen + sizeof(*sh) + sizeof(*ch);
|
||||
SCTPDBG(SCTP_DEBUG_INPUT1,
|
||||
"sctp6_input() length:%d iphlen:%d\n", pkt_len, iphlen);
|
||||
|
||||
|
||||
#if defined(NFAITH) && NFAITH > 0
|
||||
|
||||
offset -= sizeof(struct sctp_chunkhdr);
|
||||
if (faithprefix_p != NULL && (*faithprefix_p) (&ip6->ip6_dst)) {
|
||||
/* XXX send icmp6 host/port unreach? */
|
||||
goto bad;
|
||||
}
|
||||
#endif /* NFAITH defined and > 0 */
|
||||
SCTP_STAT_INCR(sctps_recvpackets);
|
||||
SCTP_STAT_INCR_COUNTER64(sctps_inpackets);
|
||||
SCTPDBG(SCTP_DEBUG_INPUT1, "V6 input gets a packet iphlen:%d pktlen:%d\n",
|
||||
iphlen, pkt_len);
|
||||
if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst)) {
|
||||
/* No multi-cast support in SCTP */
|
||||
length = ntohs(ip6->ip6_plen) + iphlen;
|
||||
/* Validate mbuf chain length with IP payload length. */
|
||||
if (SCTP_HEADER_LEN(*i_pak) != length) {
|
||||
SCTPDBG(SCTP_DEBUG_INPUT1,
|
||||
"sctp6_input() length:%d reported length:%d\n", length, SCTP_HEADER_LEN(*i_pak));
|
||||
SCTP_STAT_INCR(sctps_hdrops);
|
||||
goto bad;
|
||||
}
|
||||
/* destination port of 0 is illegal, based on RFC2960. */
|
||||
if (sh->dest_port == 0)
|
||||
if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst)) {
|
||||
goto bad;
|
||||
|
||||
}
|
||||
SCTPDBG(SCTP_DEBUG_INPUT1,
|
||||
"sctp6_input() length:%d iphlen:%d\n", length, iphlen);
|
||||
SCTPDBG(SCTP_DEBUG_CRCOFFLOAD,
|
||||
"sctp_input(): Packet of length %d received on %s with csum_flags 0x%x.\n",
|
||||
"sctp6_input(): Packet of length %d received on %s with csum_flags 0x%x.\n",
|
||||
m->m_pkthdr.len,
|
||||
if_name(m->m_pkthdr.rcvif),
|
||||
m->m_pkthdr.csum_flags);
|
||||
@ -160,15 +160,16 @@ sctp6_input(struct mbuf **i_pak, int *offp, int proto)
|
||||
SCTP_STAT_INCR(sctps_recvhwcrc);
|
||||
goto sctp_skip_csum;
|
||||
}
|
||||
check = sh->checksum; /* save incoming checksum */
|
||||
sh->checksum = 0; /* prepare for calc */
|
||||
check = sh->checksum;
|
||||
sh->checksum = 0;
|
||||
calc_check = sctp_calculate_cksum(m, iphlen);
|
||||
sh->checksum = check;
|
||||
SCTP_STAT_INCR(sctps_recvswcrc);
|
||||
if (calc_check != check) {
|
||||
SCTPDBG(SCTP_DEBUG_INPUT1, "Bad CSUM on SCTP packet calc_check:%x check:%x m:%p phlen:%d\n",
|
||||
calc_check, check, m, iphlen);
|
||||
stcb = sctp_findassociation_addr(m, offset - sizeof(*ch),
|
||||
sh, ch, &in6p, &net, vrf_id);
|
||||
SCTPDBG(SCTP_DEBUG_INPUT1, "Bad CSUM on SCTP packet calc_check:%x check:%x m:%p mlen:%d iphlen:%d\n",
|
||||
calc_check, check, m, length, iphlen);
|
||||
stcb = sctp_findassociation_addr(m, offset,
|
||||
sh, ch, &inp, &net, vrf_id);
|
||||
if ((net) && (port)) {
|
||||
if (net->port == 0) {
|
||||
sctp_pathmtu_adjustment(stcb, net->mtu - sizeof(struct udphdr));
|
||||
@ -181,28 +182,25 @@ sctp6_input(struct mbuf **i_pak, int *offp, int proto)
|
||||
net->flowidset = 1;
|
||||
#endif
|
||||
}
|
||||
/* in6p's ref-count increased && stcb locked */
|
||||
if ((in6p) && (stcb)) {
|
||||
sctp_send_packet_dropped(stcb, net, m, pkt_len, iphlen, 1);
|
||||
sctp_chunk_output((struct sctp_inpcb *)in6p, stcb, SCTP_OUTPUT_FROM_INPUT_ERROR, SCTP_SO_NOT_LOCKED);
|
||||
} else if ((in6p != NULL) && (stcb == NULL)) {
|
||||
if ((inp) && (stcb)) {
|
||||
sctp_send_packet_dropped(stcb, net, m, length, iphlen, 1);
|
||||
sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_INPUT_ERROR, SCTP_SO_NOT_LOCKED);
|
||||
} else if ((inp != NULL) && (stcb == NULL)) {
|
||||
refcount_up = 1;
|
||||
}
|
||||
SCTP_STAT_INCR(sctps_badsum);
|
||||
SCTP_STAT_INCR_COUNTER32(sctps_checksumerrors);
|
||||
goto bad;
|
||||
}
|
||||
sh->checksum = calc_check;
|
||||
|
||||
sctp_skip_csum:
|
||||
#endif
|
||||
net = NULL;
|
||||
/*
|
||||
* Locate pcb and tcb for datagram sctp_findassociation_addr() wants
|
||||
* IP/SCTP/first chunk header...
|
||||
*/
|
||||
stcb = sctp_findassociation_addr(m, offset - sizeof(*ch),
|
||||
sh, ch, &in6p, &net, vrf_id);
|
||||
/* destination port of 0 is illegal, based on RFC2960. */
|
||||
if (sh->dest_port == 0) {
|
||||
SCTP_STAT_INCR(sctps_hdrops);
|
||||
goto bad;
|
||||
}
|
||||
stcb = sctp_findassociation_addr(m, offset,
|
||||
sh, ch, &inp, &net, vrf_id);
|
||||
if ((net) && (port)) {
|
||||
if (net->port == 0) {
|
||||
sctp_pathmtu_adjustment(stcb, net->mtu - sizeof(struct udphdr));
|
||||
@ -215,25 +213,10 @@ sctp_skip_csum:
|
||||
net->flowidset = 1;
|
||||
#endif
|
||||
}
|
||||
/* in6p's ref-count increased */
|
||||
if (in6p == NULL) {
|
||||
struct sctp_init_chunk *init_chk, chunk_buf;
|
||||
|
||||
if (inp == NULL) {
|
||||
SCTP_STAT_INCR(sctps_noport);
|
||||
if (ch->chunk_type == SCTP_INITIATION) {
|
||||
/*
|
||||
* we do a trick here to get the INIT tag, dig in
|
||||
* and get the tag from the INIT and put it in the
|
||||
* common header.
|
||||
*/
|
||||
init_chk = (struct sctp_init_chunk *)sctp_m_getptr(m,
|
||||
iphlen + sizeof(*sh), sizeof(*init_chk),
|
||||
(uint8_t *) & chunk_buf);
|
||||
if (init_chk)
|
||||
sh->v_tag = init_chk->init.initiate_tag;
|
||||
else
|
||||
sh->v_tag = 0;
|
||||
}
|
||||
if (badport_bandlim(BANDLIM_SCTP_OOTB) < 0)
|
||||
goto bad;
|
||||
if (ch->chunk_type == SCTP_SHUTDOWN_ACK) {
|
||||
sctp_send_shutdown_complete2(m, sh,
|
||||
use_mflowid, mflowid,
|
||||
@ -257,55 +240,46 @@ sctp_skip_csum:
|
||||
refcount_up = 1;
|
||||
}
|
||||
#ifdef IPSEC
|
||||
/*
|
||||
* Check AH/ESP integrity.
|
||||
/*-
|
||||
* I very much doubt any of the IPSEC stuff will work but I have no
|
||||
* idea, so I will leave it in place.
|
||||
*/
|
||||
in6p_ip = (struct inpcb *)in6p;
|
||||
if (in6p_ip && (ipsec6_in_reject(m, in6p_ip))) {
|
||||
/* XXX */
|
||||
if (inp && ipsec6_in_reject(m, &inp->ip_inp.inp)) {
|
||||
MODULE_GLOBAL(ipsec6stat).in_polvio++;
|
||||
SCTP_STAT_INCR(sctps_hdrops);
|
||||
goto bad;
|
||||
}
|
||||
#endif /* IPSEC */
|
||||
#endif
|
||||
|
||||
/*
|
||||
* CONTROL chunk processing
|
||||
*/
|
||||
offset -= sizeof(*ch);
|
||||
ecn_bits = ((ntohl(ip6->ip6_flow) >> 20) & 0x000000ff);
|
||||
|
||||
/* Length now holds the total packet length payload + iphlen */
|
||||
length = ntohs(ip6->ip6_plen) + iphlen;
|
||||
|
||||
/* sa_ignore NO_NULL_CHK */
|
||||
sctp_common_input_processing(&m, iphlen, offset, length, sh, ch,
|
||||
in6p, stcb, net, ecn_bits,
|
||||
inp, stcb, net, ecn_bits,
|
||||
use_mflowid, mflowid,
|
||||
vrf_id, port);
|
||||
/* inp's ref-count reduced && stcb unlocked */
|
||||
/* XXX this stuff below gets moved to appropriate parts later... */
|
||||
if (m)
|
||||
if (m) {
|
||||
sctp_m_freem(m);
|
||||
if ((in6p) && refcount_up) {
|
||||
}
|
||||
if ((inp) && (refcount_up)) {
|
||||
/* reduce ref-count */
|
||||
SCTP_INP_WLOCK(in6p);
|
||||
SCTP_INP_DECR_REF(in6p);
|
||||
SCTP_INP_WUNLOCK(in6p);
|
||||
SCTP_INP_WLOCK(inp);
|
||||
SCTP_INP_DECR_REF(inp);
|
||||
SCTP_INP_WUNLOCK(inp);
|
||||
}
|
||||
return (IPPROTO_DONE);
|
||||
|
||||
bad:
|
||||
if (stcb) {
|
||||
SCTP_TCB_UNLOCK(stcb);
|
||||
}
|
||||
if ((in6p) && refcount_up) {
|
||||
if ((inp) && (refcount_up)) {
|
||||
/* reduce ref-count */
|
||||
SCTP_INP_WLOCK(in6p);
|
||||
SCTP_INP_DECR_REF(in6p);
|
||||
SCTP_INP_WUNLOCK(in6p);
|
||||
SCTP_INP_WLOCK(inp);
|
||||
SCTP_INP_DECR_REF(inp);
|
||||
SCTP_INP_WUNLOCK(inp);
|
||||
}
|
||||
if (m)
|
||||
if (m) {
|
||||
sctp_m_freem(m);
|
||||
}
|
||||
return (IPPROTO_DONE);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user