Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 26 Dec 2017 13:40:47 +0100
From:      Michael Tuexen <tuexen@freebsd.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   Re: svn commit: r327200 - in head/sys: conf netinet
Message-ID:  <9F922F21-3319-4146-B6BE-9BC99E446AE3@freebsd.org>
In-Reply-To: <201712261235.vBQCZ2Al076120@repo.freebsd.org>
References:  <201712261235.vBQCZ2Al076120@repo.freebsd.org>

next in thread | previous in thread | raw e-mail | index | archive | help
> On 26. Dec 2017, at 13:35, Michael Tuexen <tuexen@FreeBSD.org> wrote:
>=20
> Author: tuexen
> Date: Tue Dec 26 12:35:02 2017
> New Revision: 327200
> URL: https://svnweb.freebsd.org/changeset/base/327200
>=20
> 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.
>=20
>  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.
>=20
>  While there, do some cleanups and improve comments.
>=20
>  Thanks to Kevin Kevin Browling for reporting the issue and suggesting
>  a fix.
Thanks to Kevin Bowling. Sorry for the typo.

Best regards
Michael
>=20
> Modified:
>  head/sys/conf/files
>  head/sys/netinet/sctp_crc32.c
>  head/sys/netinet/sctp_crc32.h
>=20
> Modified: head/sys/conf/files
> =
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
> --- 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
>=20
> Modified: head/sys/netinet/sctp_crc32.c
> =
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
> --- 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$");
>=20
> +#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>
>=20
> +#include <netinet/sctp_crc32.h>
> +#endif
>=20
> -
> static uint32_t
> sctp_finalize_crc32c(uint32_t crc32c)
> {
> 	uint32_t result;
> -
> #if BYTE_ORDER =3D=3D BIG_ENDIAN
> 	uint8_t byte0, byte1, byte2, byte3;
> -
> #endif
> +
> 	/* Complement the result */
> 	result =3D ~crc32c;
> #if BYTE_ORDER =3D=3D 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 =3D result & 0x000000ff;
> 	byte1 =3D (result >> 8) & 0x000000ff;
> @@ -66,56 +73,54 @@ sctp_finalize_crc32c(uint32_t crc32c)
> 	crc32c =3D ((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 =3D result;
> #endif
> 	return (crc32c);
> }
>=20
> +/*
> + * 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=3D1, pktlen=3D0 is returned (ie. no real =
error code)
> -	 */
> 	uint32_t base =3D 0xffffffff;
> -	struct mbuf *at;
>=20
> -	at =3D m;
> -	/* find the correct mbuf and offset into mbuf */
> -	while ((at !=3D NULL) && (offset > (uint32_t)SCTP_BUF_LEN(at))) =
{
> -		offset -=3D SCTP_BUF_LEN(at);	/* update remaining =
offset
> -						 * left */
> -		at =3D SCTP_BUF_NEXT(at);
> -	}
> -	while (at !=3D NULL) {
> -		if ((SCTP_BUF_LEN(at) - offset) > 0) {
> -			base =3D calculate_crc32c(base,
> -			    (unsigned char *)(SCTP_BUF_AT(at, offset)),
> -			    (unsigned int)(SCTP_BUF_LEN(at) - offset));
> +	while (offset > 0) {
> +		KASSERT(m !=3D 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 =3D 0;
> -			else
> -				offset -=3D SCTP_BUF_LEN(at);
> -		}
> -		at =3D SCTP_BUF_NEXT(at);
> +		offset -=3D m->m_len;
> +		m =3D m->m_next;
> 	}
> +	if (offset > 0) {
> +		base =3D calculate_crc32c(base,
> +		    (unsigned char *)(m->m_data + offset),
> +		    (unsigned int)(m->m_len - offset));
> +		m =3D m->m_next;
> +	}
> +	while (m !=3D NULL) {
> +		base =3D calculate_crc32c(base,
> +		    (unsigned char *)m->m_data,
> +		    (unsigned int)m->m_len);
> +		m =3D m->m_next;
> +	}
> 	base =3D sctp_finalize_crc32c(base);
> 	return (base);
> }
>=20
> -
> +#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 +=3D offsetof(struct sctphdr, checksum);
>=20
> 	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) =3D checksum;
> }
> +#endif
>=20
> Modified: head/sys/netinet/sctp_crc32.h
> =
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
> --- 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$");
>=20
> #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__ */
>=20




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?9F922F21-3319-4146-B6BE-9BC99E446AE3>