summaryrefslogtreecommitdiffstats
path: root/sys/netinet/sctp_input.c
diff options
context:
space:
mode:
authorrrs <rrs@FreeBSD.org>2009-02-03 11:04:03 +0000
committerrrs <rrs@FreeBSD.org>2009-02-03 11:04:03 +0000
commit520c389cb4f290b2acdcff4ed123d33cca39e0d8 (patch)
treead3c3bea4fec4c5a81ac06bbcfcfc640edc88661 /sys/netinet/sctp_input.c
parent2688c691800f6933c6b9eeeb46cf522db6f1af5c (diff)
downloadFreeBSD-src-520c389cb4f290b2acdcff4ed123d33cca39e0d8.zip
FreeBSD-src-520c389cb4f290b2acdcff4ed123d33cca39e0d8.tar.gz
- Cleanup checksum code.
- Prepare for CRC offloading, add MIB counters (RS/MT). - Bugfix: Disable CRC computation for IPv6 addresses with local scope (MT). - Bugfix: Handle close() with SO_LINGER correctly when notifications are generated during the close() call(MT). - Bugfix: Generate DRY event when sender is dry during subscription. Only for 1-to-1 style sockets (RS/MT) - Bugfix: Put vtags for the correct amount of time into time-wait (MT). - Bugfix: Clear vtag entries correctly on expiration (MT). - Bugfix: shutdown() indicates ENOTCONN when called for unconnected 1-to-1 style sockets (MT). - Bugfix: In sctp Auth code (PL). - Add support for devices that support SCTP csum offload (igb). - Add missing sctp_associd to mib sysctl xsctp_tcb structure (RS) Obtained from: With help from Peter Lei and Michael Tuexen
Diffstat (limited to 'sys/netinet/sctp_input.c')
-rw-r--r--sys/netinet/sctp_input.c46
1 files changed, 20 insertions, 26 deletions
diff --git a/sys/netinet/sctp_input.c b/sys/netinet/sctp_input.c
index c686fac..2d8a1f2 100644
--- a/sys/netinet/sctp_input.c
+++ b/sys/netinet/sctp_input.c
@@ -46,6 +46,7 @@ __FBSDID("$FreeBSD$");
#include <netinet/sctp_asconf.h>
#include <netinet/sctp_bsd_addr.h>
#include <netinet/sctp_timer.h>
+#include <netinet/sctp_crc32.h>
#include <netinet/udp.h>
@@ -1384,14 +1385,6 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset,
/* FOOBAR */
return (NULL);
}
- /* pre-reserve some space */
-#ifdef INET6
- SCTP_BUF_RESV_UF(op_err, sizeof(struct ip6_hdr));
-#else
- SCTP_BUF_RESV_UF(op_err, sizeof(struct ip));
-#endif
- SCTP_BUF_RESV_UF(op_err, sizeof(struct sctphdr));
- SCTP_BUF_RESV_UF(op_err, sizeof(struct sctp_chunkhdr));
/* Set the len */
SCTP_BUF_LEN(op_err) = sizeof(struct sctp_paramhdr);
ph = mtod(op_err, struct sctp_paramhdr *);
@@ -2504,15 +2497,6 @@ sctp_handle_cookie_echo(struct mbuf *m, int iphlen, int offset,
/* FOOBAR */
return (NULL);
}
- /* pre-reserve some space */
-#ifdef INET6
- SCTP_BUF_RESV_UF(op_err, sizeof(struct ip6_hdr));
-#else
- SCTP_BUF_RESV_UF(op_err, sizeof(struct ip));
-#endif
- SCTP_BUF_RESV_UF(op_err, sizeof(struct sctphdr));
- SCTP_BUF_RESV_UF(op_err, sizeof(struct sctp_chunkhdr));
-
/* Set the len */
SCTP_BUF_LEN(op_err) = sizeof(struct sctp_stale_cookie_msg);
scm = mtod(op_err, struct sctp_stale_cookie_msg *);
@@ -2598,9 +2582,9 @@ sctp_handle_cookie_echo(struct mbuf *m, int iphlen, int offset,
}
}
}
- if (to == NULL)
+ if (to == NULL) {
return (NULL);
-
+ }
cookie_len -= SCTP_SIGNATURE_SIZE;
if (*stcb == NULL) {
/* this is the "normal" case... get a new TCB */
@@ -5594,7 +5578,6 @@ sctp_input_with_port(i_pak, off, port)
int refcount_up = 0;
int length, mlen, offset;
-
if (SCTP_GET_PKT_VRFID(i_pak, vrf_id)) {
SCTP_RELEASE_PKT(i_pak);
return;
@@ -5642,6 +5625,11 @@ sctp_input_with_port(i_pak, off, port)
}
ip = mtod(m, struct ip *);
}
+ /* validate mbuf chain length with IP payload length */
+ if (mlen < (SCTP_GET_IPV4_LENGTH(ip) - iphlen)) {
+ 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,
@@ -5659,15 +5647,26 @@ sctp_input_with_port(i_pak, off, port)
goto bad;
}
/* validate SCTP checksum */
+ SCTPDBG(SCTP_DEBUG_CRCOFFLOAD,
+ "sctp_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);
+ if (m->m_pkthdr.csum_flags & CSUM_SCTP_VALID) {
+ SCTP_STAT_INCR(sctps_recvhwcrc);
+ goto sctp_skip_csum_4;
+ }
check = sh->checksum; /* save incoming checksum */
if ((check == 0) && (SCTP_BASE_SYSCTL(sctp_no_csum_on_loopback)) &&
((ip->ip_src.s_addr == ip->ip_dst.s_addr) ||
(SCTP_IS_IT_LOOPBACK(m)))
) {
+ SCTP_STAT_INCR(sctps_recvnocrc);
goto sctp_skip_csum_4;
}
sh->checksum = 0; /* prepare for calc */
- calc_check = sctp_calculate_sum(m, &mlen, iphlen);
+ calc_check = sctp_calculate_cksum(m, iphlen);
+ 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);
@@ -5699,11 +5698,6 @@ sctp_skip_csum_4:
SCTP_STAT_INCR(sctps_hdrops);
goto bad;
}
- /* validate mbuf chain length with IP payload length */
- if (mlen < (SCTP_GET_IPV4_LENGTH(ip) - iphlen)) {
- SCTP_STAT_INCR(sctps_hdrops);
- goto bad;
- }
/*
* Locate pcb and tcb for datagram sctp_findassociation_addr() wants
* IP/SCTP/first chunk header...
OpenPOWER on IntegriCloud