diff options
author | rrs <rrs@FreeBSD.org> | 2009-02-03 11:04:03 +0000 |
---|---|---|
committer | rrs <rrs@FreeBSD.org> | 2009-02-03 11:04:03 +0000 |
commit | 520c389cb4f290b2acdcff4ed123d33cca39e0d8 (patch) | |
tree | ad3c3bea4fec4c5a81ac06bbcfcfc640edc88661 /sys/netinet/sctp_input.c | |
parent | 2688c691800f6933c6b9eeeb46cf522db6f1af5c (diff) | |
download | FreeBSD-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.c | 46 |
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... |