diff options
author | rrs <rrs@FreeBSD.org> | 2009-02-14 11:34:57 +0000 |
---|---|---|
committer | rrs <rrs@FreeBSD.org> | 2009-02-14 11:34:57 +0000 |
commit | d22f1350d2b99a2c94df984d76b37089bc7d610a (patch) | |
tree | b713f25db67c27ccf45455a371f2dd7e0322ff44 /sys/netinet/libalias/alias_sctp.c | |
parent | 5537532d1b2a9b8013d0af30efa778a7bb45f788 (diff) | |
download | FreeBSD-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/alias_sctp.c')
-rw-r--r-- | sys/netinet/libalias/alias_sctp.c | 41 |
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); |