summaryrefslogtreecommitdiffstats
path: root/sys/netinet/libalias
diff options
context:
space:
mode:
authorrrs <rrs@FreeBSD.org>2009-02-14 11:34:57 +0000
committerrrs <rrs@FreeBSD.org>2009-02-14 11:34:57 +0000
commitd22f1350d2b99a2c94df984d76b37089bc7d610a (patch)
treeb713f25db67c27ccf45455a371f2dd7e0322ff44 /sys/netinet/libalias
parent5537532d1b2a9b8013d0af30efa778a7bb45f788 (diff)
downloadFreeBSD-src-d22f1350d2b99a2c94df984d76b37089bc7d610a.zip
FreeBSD-src-d22f1350d2b99a2c94df984d76b37089bc7d610a.tar.gz
This commit fixes the issue with alias_sctp.c. No
longer do we require SCTP to be in the kernel for the lib to be able to handle SCTP. We do this by moving the CRC32c checksum into libkern/crc32.c and then adjusting all routines to use the common methods. Note that this will improve the performance of iSCSI since they were using the old single 256 bit table lookup versus the slicing 8 algorithm (which gives a 4x speed up in CRC32c calculation :-D) Reviewed by:rwatson, gnn, scottl, paolo MFC after: 4 week? (assuming we MFC the alias_sctp changes)
Diffstat (limited to 'sys/netinet/libalias')
-rw-r--r--sys/netinet/libalias/alias_sctp.c41
1 files changed, 39 insertions, 2 deletions
diff --git a/sys/netinet/libalias/alias_sctp.c b/sys/netinet/libalias/alias_sctp.c
index 89dc979..22cf5cd 100644
--- a/sys/netinet/libalias/alias_sctp.c
+++ b/sys/netinet/libalias/alias_sctp.c
@@ -91,8 +91,8 @@
#include <arpa/inet.h>
#include "alias.h"
#include "alias_local.h"
-#include <netinet/sctp_crc32.h>
#include <machine/in_cksum.h>
+#include <sys/libkern.h>
#endif //#ifdef _KERNEL
/* ----------------------------------------------------------------------
@@ -864,6 +864,43 @@ SctpAlias(struct libalias *la, struct ip *pip, int direction)
* @param sndrply SN_SEND_ABORT | SN_REPLY_ABORT | SN_REPLY_ERROR
* @param direction SN_TO_LOCAL | SN_TO_GLOBAL
*/
+static uint32_t
+local_sctp_finalize_crc32(uint32_t crc32c)
+{
+ /* This routine is duplicated from SCTP
+ * we need to do that since it MAY be that SCTP
+ * is NOT compiled into the kernel. The CRC32C routines
+ * however are always available in libkern.
+ */
+ 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...
+ */
+ byte0 = result & 0x000000ff;
+ byte1 = (result >> 8) & 0x000000ff;
+ byte2 = (result >> 16) & 0x000000ff;
+ byte3 = (result >> 24) & 0x000000ff;
+ 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.
+ */
+ crc32c = result;
+#endif
+ return (crc32c);
+}
+
static void
TxAbortErrorM(struct libalias *la, struct sctp_nat_msg *sm, struct sctp_nat_assoc *assoc, int sndrply, int direction)
{
@@ -943,7 +980,7 @@ TxAbortErrorM(struct libalias *la, struct sctp_nat_msg *sm, struct sctp_nat_asso
/* calculate SCTP header CRC32 */
sctp_hdr->checksum = 0;
- sctp_hdr->checksum = sctp_finalize_crc32(update_crc32(0xffffffff, (unsigned char *) sctp_hdr, sctp_size));
+ sctp_hdr->checksum = local_sctp_finalize_crc32(calculate_crc32c(0xffffffff, (unsigned char *) sctp_hdr, sctp_size));
memcpy(sm->ip_hdr, ip, ip_size);
OpenPOWER on IntegriCloud