svn commit: r327200 - in head/sys: conf netinet
Michael Tuexen
tuexen at freebsd.org
Tue Dec 26 12:41:04 UTC 2017
> On 26. Dec 2017, at 13:35, Michael Tuexen <tuexen at FreeBSD.org> wrote:
>
> Author: tuexen
> Date: Tue Dec 26 12:35:02 2017
> New Revision: 327200
> URL: https://svnweb.freebsd.org/changeset/base/327200
>
> Log:
> When adding support for sending SCTP packets containing an ABORT chunk
> to ipfw in https://svnweb.freebsd.org/changeset/base/326233,
> a dependency on the SCTP stack was added to ipfw by accident.
>
> This was noted by Kevel Bowling in https://reviews.freebsd.org/D13594
> where also a solution was suggested. This patch is based on Kevin's
> suggestion, but implements the required SCTP checksum computation
> without any dependency on other SCTP sources.
>
> While there, do some cleanups and improve comments.
>
> Thanks to Kevin Kevin Browling for reporting the issue and suggesting
> a fix.
Thanks to Kevin Bowling. Sorry for the typo.
Best regards
Michael
>
> Modified:
> head/sys/conf/files
> head/sys/netinet/sctp_crc32.c
> head/sys/netinet/sctp_crc32.h
>
> Modified: head/sys/conf/files
> ==============================================================================
> --- head/sys/conf/files Tue Dec 26 12:11:04 2017 (r327199)
> +++ head/sys/conf/files Tue Dec 26 12:35:02 2017 (r327200)
> @@ -4255,7 +4255,7 @@ netinet/sctp_asconf.c optional inet sctp | inet6 sctp
> netinet/sctp_auth.c optional inet sctp | inet6 sctp
> netinet/sctp_bsd_addr.c optional inet sctp | inet6 sctp
> netinet/sctp_cc_functions.c optional inet sctp | inet6 sctp
> -netinet/sctp_crc32.c optional inet sctp | inet6 sctp
> +netinet/sctp_crc32.c optional inet | inet6
> netinet/sctp_indata.c optional inet sctp | inet6 sctp
> netinet/sctp_input.c optional inet sctp | inet6 sctp
> netinet/sctp_output.c optional inet sctp | inet6 sctp
>
> Modified: head/sys/netinet/sctp_crc32.c
> ==============================================================================
> --- head/sys/netinet/sctp_crc32.c Tue Dec 26 12:11:04 2017 (r327199)
> +++ head/sys/netinet/sctp_crc32.c Tue Dec 26 12:35:02 2017 (r327200)
> @@ -35,29 +35,36 @@
> #include <sys/cdefs.h>
> __FBSDID("$FreeBSD$");
>
> +#include "opt_sctp.h"
> +
> +#ifdef SCTP
> #include <netinet/sctp_os.h>
> #include <netinet/sctp.h>
> #include <netinet/sctp_crc32.h>
> #include <netinet/sctp_pcb.h>
> +#else
> +#include <sys/param.h>
> +#include <sys/systm.h>
> +#include <sys/mbuf.h>
>
> +#include <netinet/sctp_crc32.h>
> +#endif
>
> -
> static uint32_t
> sctp_finalize_crc32c(uint32_t crc32c)
> {
> uint32_t result;
> -
> #if BYTE_ORDER == BIG_ENDIAN
> uint8_t byte0, byte1, byte2, byte3;
> -
> #endif
> +
> /* Complement the result */
> result = ~crc32c;
> #if BYTE_ORDER == BIG_ENDIAN
> /*
> - * For BIG-ENDIAN.. aka Motorola byte order the result is in
> - * little-endian form. So we must manually swap the bytes. Then we
> - * can call htonl() which does nothing...
> + * For BIG-ENDIAN platforms the result is in little-endian form. So
> + * we must swap the bytes to return the result in network byte
> + * order.
> */
> byte0 = result & 0x000000ff;
> byte1 = (result >> 8) & 0x000000ff;
> @@ -66,56 +73,54 @@ sctp_finalize_crc32c(uint32_t crc32c)
> crc32c = ((byte0 << 24) | (byte1 << 16) | (byte2 << 8) | byte3);
> #else
> /*
> - * For INTEL platforms the result comes out in network order. No
> - * htonl is required or the swap above. So we optimize out both the
> - * htonl and the manual swap above.
> + * For LITTLE ENDIAN platforms the result is in already in network
> + * byte order.
> */
> crc32c = result;
> #endif
> return (crc32c);
> }
>
> +/*
> + * Compute the SCTP checksum in network byte order for a given mbuf chain m
> + * which contains an SCTP packet starting at offset.
> + * Since this function is also called by ipfw, don't assume that
> + * it is compiled on a kernel with SCTP support.
> + */
> uint32_t
> sctp_calculate_cksum(struct mbuf *m, uint32_t offset)
> {
> - /*
> - * given a mbuf chain with a packetheader offset by 'offset'
> - * pointing at a sctphdr (with csum set to 0) go through the chain
> - * of SCTP_BUF_NEXT()'s and calculate the SCTP checksum. This also
> - * has a side bonus as it will calculate the total length of the
> - * mbuf chain. Note: if offset is greater than the total mbuf
> - * length, checksum=1, pktlen=0 is returned (ie. no real error code)
> - */
> uint32_t base = 0xffffffff;
> - struct mbuf *at;
>
> - at = m;
> - /* find the correct mbuf and offset into mbuf */
> - while ((at != NULL) && (offset > (uint32_t)SCTP_BUF_LEN(at))) {
> - offset -= SCTP_BUF_LEN(at); /* update remaining offset
> - * left */
> - at = SCTP_BUF_NEXT(at);
> - }
> - while (at != NULL) {
> - if ((SCTP_BUF_LEN(at) - offset) > 0) {
> - base = calculate_crc32c(base,
> - (unsigned char *)(SCTP_BUF_AT(at, offset)),
> - (unsigned int)(SCTP_BUF_LEN(at) - offset));
> + while (offset > 0) {
> + KASSERT(m != NULL, ("sctp_calculate_cksum, offset > length of mbuf chain"));
> + if (offset < (uint32_t)m->m_len) {
> + break;
> }
> - if (offset) {
> - /* we only offset once into the first mbuf */
> - if (offset < (uint32_t)SCTP_BUF_LEN(at))
> - offset = 0;
> - else
> - offset -= SCTP_BUF_LEN(at);
> - }
> - at = SCTP_BUF_NEXT(at);
> + offset -= m->m_len;
> + m = m->m_next;
> }
> + if (offset > 0) {
> + base = calculate_crc32c(base,
> + (unsigned char *)(m->m_data + offset),
> + (unsigned int)(m->m_len - offset));
> + m = m->m_next;
> + }
> + while (m != NULL) {
> + base = calculate_crc32c(base,
> + (unsigned char *)m->m_data,
> + (unsigned int)m->m_len);
> + m = m->m_next;
> + }
> base = sctp_finalize_crc32c(base);
> return (base);
> }
>
> -
> +#ifdef SCTP
> +/*
> + * Compute and insert the SCTP checksum in network byte order for a given
> + * mbuf chain m which contains an SCTP packet starting at offset.
> + */
> void
> sctp_delayed_cksum(struct mbuf *m, uint32_t offset)
> {
> @@ -127,14 +132,15 @@ sctp_delayed_cksum(struct mbuf *m, uint32_t offset)
> offset += offsetof(struct sctphdr, checksum);
>
> if (offset + sizeof(uint32_t) > (uint32_t)(m->m_len)) {
> - SCTP_PRINTF("sctp_delayed_cksum(): m->len: %d, off: %d.\n",
> - (uint32_t)m->m_len, offset);
> - /*
> - * XXX this shouldn't happen, but if it does, the correct
> - * behavior may be to insert the checksum in the appropriate
> - * next mbuf in the chain.
> - */
> +#ifdef INVARIANTS
> + panic("sctp_delayed_cksum(): m->m_len: %d, offset: %u.",
> + m->m_len, offset);
> +#else
> + SCTP_PRINTF("sctp_delayed_cksum(): m->m_len: %d, offset: %u.\n",
> + m->m_len, offset);
> +#endif
> return;
> }
> *(uint32_t *)(m->m_data + offset) = checksum;
> }
> +#endif
>
> Modified: head/sys/netinet/sctp_crc32.h
> ==============================================================================
> --- head/sys/netinet/sctp_crc32.h Tue Dec 26 12:11:04 2017 (r327199)
> +++ head/sys/netinet/sctp_crc32.h Tue Dec 26 12:35:02 2017 (r327200)
> @@ -40,6 +40,8 @@ __FBSDID("$FreeBSD$");
>
> #if defined(_KERNEL)
> uint32_t sctp_calculate_cksum(struct mbuf *, uint32_t);
> +#ifdef SCTP
> void sctp_delayed_cksum(struct mbuf *, uint32_t offset);
> +#endif
> #endif /* _KERNEL */
> #endif /* __crc32c_h__ */
>
More information about the svn-src-head
mailing list