/*
- * Copyright (c) 2009, 2010, 2011 Nicira, Inc.
+ * Copyright (c) 2009, 2010, 2011, 2014 Nicira, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*/
#include <config.h>
+#undef NDEBUG
#include "csum.h"
+#include <assert.h>
#include <inttypes.h>
#include <netinet/in.h>
+#include <netinet/ip.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include "crc32c.h"
+#include "ovstest.h"
+#include "packets.h"
#include "random.h"
#include "unaligned.h"
#include "util.h"
-#undef NDEBUG
-#include <assert.h>
-
struct test_case {
char *data;
size_t size; /* Test requires a multiple of 4. */
mark('#');
}
-int
-main(void)
+/* CRC32C checksum tests, based on Intel IPPs, Chapter 13,
+ * ippsCRC32C_8u() example, found at the following location:
+ * http://software.intel.com/sites/products/documentation/hpc/ipp/ipps/ */
+static void
+test_crc32c(void)
+{
+ int i;
+ uint8_t data[48] = {
+ 0x01, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00,
+ 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x18,
+ 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ };
+
+ /* iSCSI Read PDU */
+ assert(ntohl(crc32c(data, 48)) == 0x563a96d9L);
+
+ /* 32 bytes of all zeroes */
+ for (i = 0; i < 32; i++) data[i] = 0x00;
+ assert(ntohl(crc32c(data, 32)) == 0xaa36918aL);
+
+ /* 32 bytes of all ones */
+ for (i = 0; i < 32; i++) data[i] = 0xff;
+ assert(ntohl(crc32c(data, 32)) == 0x43aba862L);
+
+ /* 32 bytes of incrementing 00..1f */
+ for (i = 0; i < 32; i++) data[i] = i;
+ assert(ntohl(crc32c(data, 32)) == 0x4e79dd46L);
+
+ /* 32 bytes of decrementing 1f..00 */
+ for (i = 0; i < 32; i++) data[i] = 31 - i;
+ assert(ntohl(crc32c(data, 32)) == 0x5cdb3f11L);
+
+ mark('#');
+}
+
+/* Check the IP pseudoheader calculation. */
+static void
+test_pseudo(void)
+{
+ ovs_be16 csum;
+ /* Try an IP header similar to one that the tunnel code
+ * might generate. */
+ struct ip_header ip = {
+ .ip_ihl_ver = IP_IHL_VER(5, 4),
+ .ip_tos = 0,
+ .ip_tot_len = htons(134),
+ .ip_id = 0,
+ .ip_frag_off = htons(IP_DF),
+ .ip_ttl = 64,
+ .ip_proto = IPPROTO_UDP,
+ .ip_csum = htons(0x1265),
+ .ip_src = { .hi = htons(0x1400), .lo = htons(0x0002) },
+ .ip_dst = { .hi = htons(0x1400), .lo = htons(0x0001) }
+ };
+
+ csum = csum_finish(packet_csum_pseudoheader(&ip));
+ assert(csum == htons(0xd779));
+
+ /* And also test something totally different to check for
+ * corner cases. */
+ memset(&ip, 0xff, sizeof ip);
+ csum = csum_finish(packet_csum_pseudoheader(&ip));
+ assert(csum == htons(0xff3c));
+
+ mark('#');
+}
+
+static void
+test_csum_main(int argc OVS_UNUSED, char *argv[] OVS_UNUSED)
{
const struct test_case *tc;
int i;
}
test_rfc1624();
+ test_crc32c();
+ test_pseudo();
/* Test recalc_csum16(). */
for (i = 0; i < 32; i++) {
mark('#');
putchar('\n');
-
- return 0;
}
+
+OVSTEST_REGISTER("test-csum", test_csum_main);