]> git.proxmox.com Git - mirror_ovs.git/blame - tests/test-csum.c
tests: Log commands being executed for async message control test.
[mirror_ovs.git] / tests / test-csum.c
CommitLineData
21effc03 1/*
eadd1644 2 * Copyright (c) 2009, 2010, 2011, 2014 Nicira, Inc.
21effc03 3 *
a14bc59f
BP
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at:
21effc03 7 *
a14bc59f
BP
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
21effc03
BP
15 */
16
17#include <config.h>
3f636c7e 18#undef NDEBUG
21effc03 19#include "csum.h"
3f636c7e 20#include <assert.h>
21effc03 21#include <inttypes.h>
b2befd5b 22#include <sys/types.h>
21effc03 23#include <netinet/in.h>
0292a0c9 24#include <netinet/ip.h>
21effc03
BP
25#include <stdio.h>
26#include <stdlib.h>
27#include <string.h>
3f636c7e
JR
28#include "crc32c.h"
29#include "ovstest.h"
0292a0c9 30#include "packets.h"
21effc03 31#include "random.h"
80642190 32#include "unaligned.h"
21effc03 33#include "util.h"
21effc03
BP
34
35struct test_case {
36 char *data;
d932cf70 37 size_t size; /* Test requires a multiple of 4. */
21effc03
BP
38 uint16_t csum;
39};
40
41#define TEST_CASE(DATA, CSUM) { DATA, (sizeof DATA) - 1, CSUM }
42
43static const struct test_case test_cases[] = {
44 /* RFC 1071 section 3. */
d932cf70
BP
45 TEST_CASE("\x00\x01\xf2\x03"
46 "\xf4\xf5\xf6\xf7",
d84d4b88 47 0xffff - 0xddf2 /* ~0xddf2 */),
21effc03
BP
48
49 /* http://www.sbprojects.com/projects/tcpip/theory/theory14.htm */
d932cf70
BP
50 TEST_CASE("\x45\x00\x00\x28"
51 "\x1F\xFD\x40\x00"
52 "\x80\x06\x00\x00"
53 "\xC0\xA8\x3B\x0A"
54 "\xC0\xA8\x3B\x32",
21effc03
BP
55 0xe345),
56
57 /* http://mathforum.org/library/drmath/view/54379.html */
d932cf70
BP
58 TEST_CASE("\x86\x5e\xac\x60"
59 "\x71\x2a\x81\xb5",
60 0xda60),
21effc03
BP
61};
62
63static void
64mark(char c)
65{
66 putchar(c);
67 fflush(stdout);
68}
69
70#if 0
71/* This code is useful for generating new test cases for RFC 1624 section 4. */
72static void
73generate_rfc1624_test_case(void)
74{
75 int i;
76
77 for (i = 0; i < 10000000; i++) {
78 uint32_t data[8];
79 int j;
80
81 for (j = 0; j < 8; j++) {
82 data[j] = random_uint32();
83 }
84 data[7] &= 0x0000ffff;
85 data[7] |= 0x55550000;
86 if (ntohs(~csum(data, sizeof data - 2)) == 0xcd7a) {
87 ovs_hex_dump(stdout, data, sizeof data, 0, false);
88 exit(0);
89 }
90 }
91}
92#endif
93
94
95
96/* Make sure we get the calculation in RFC 1624 section 4 correct. */
97static void
98test_rfc1624(void)
99{
100 /* "...an IP packet header in which a 16-bit field m = 0x5555..." */
8d32c1d3
EJ
101 uint8_t data[32] = {
102 0xfe, 0x8f, 0xc1, 0x14, 0x4b, 0x6f, 0x70, 0x2a,
103 0x80, 0x29, 0x78, 0xc0, 0x58, 0x81, 0x77, 0xaa,
104 0x66, 0x64, 0xfc, 0x96, 0x63, 0x97, 0x64, 0xee,
105 0x12, 0x53, 0x1d, 0xa9, 0x2d, 0xa9, 0x55, 0x55
106 };
21effc03
BP
107
108 /* "...the one's complement sum of all other header octets is 0xCD7A." */
d84d4b88 109 assert(ntohs(csum(data, sizeof data - 2)) == 0xffff - 0xcd7a);
21effc03
BP
110
111 /* "...the header checksum would be:
112
113 HC = ~(0xCD7A + 0x5555)
114 = ~0x22D0
115 = 0xDD2F"
116 */
117 assert(ntohs(csum(data, sizeof data)) == 0xdd2f);
118
119 /* "a 16-bit field m = 0x5555 changes to m' = 0x3285..." */
120 data[30] = 0x32;
121 data[31] = 0x85;
122
123 /* "The new checksum via recomputation is:
124
125 HC' = ~(0xCD7A + 0x3285)
126 = ~0xFFFF
127 = 0x0000"
128 */
129 assert(ntohs(csum(data, sizeof data)) == 0x0000);
130
131 /* "Applying [Eqn. 3] to the example above, we get the correct result:
132
133 HC' = ~(C + (-m) + m')
134 = ~(0x22D0 + ~0x5555 + 0x3285)
135 = ~0xFFFF
136 = 0x0000" */
d84d4b88
BP
137 assert(recalc_csum16(htons(0xdd2f), htons(0x5555), htons(0x3285))
138 == htons(0x0000));
21effc03
BP
139
140 mark('#');
141}
142
97025b23
JS
143/* CRC32C checksum tests, based on Intel IPPs, Chapter 13,
144 * ippsCRC32C_8u() example, found at the following location:
145 * http://software.intel.com/sites/products/documentation/hpc/ipp/ipps/ */
146static void
147test_crc32c(void)
148{
149 int i;
150 uint8_t data[48] = {
151 0x01, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
152 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
153 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00,
154 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x18,
155 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
156 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
157 };
158
159 /* iSCSI Read PDU */
160 assert(ntohl(crc32c(data, 48)) == 0x563a96d9L);
161
162 /* 32 bytes of all zeroes */
163 for (i = 0; i < 32; i++) data[i] = 0x00;
164 assert(ntohl(crc32c(data, 32)) == 0xaa36918aL);
165
166 /* 32 bytes of all ones */
167 for (i = 0; i < 32; i++) data[i] = 0xff;
168 assert(ntohl(crc32c(data, 32)) == 0x43aba862L);
169
170 /* 32 bytes of incrementing 00..1f */
171 for (i = 0; i < 32; i++) data[i] = i;
172 assert(ntohl(crc32c(data, 32)) == 0x4e79dd46L);
173
174 /* 32 bytes of decrementing 1f..00 */
175 for (i = 0; i < 32; i++) data[i] = 31 - i;
176 assert(ntohl(crc32c(data, 32)) == 0x5cdb3f11L);
177
178 mark('#');
179}
180
0292a0c9
JG
181/* Check the IP pseudoheader calculation. */
182static void
183test_pseudo(void)
184{
2f86335b 185 ovs_be16 csum;
0292a0c9
JG
186 /* Try an IP header similar to one that the tunnel code
187 * might generate. */
188 struct ip_header ip = {
189 .ip_ihl_ver = IP_IHL_VER(5, 4),
190 .ip_tos = 0,
191 .ip_tot_len = htons(134),
192 .ip_id = 0,
193 .ip_frag_off = htons(IP_DF),
194 .ip_ttl = 64,
195 .ip_proto = IPPROTO_UDP,
196 .ip_csum = htons(0x1265),
197 .ip_src = { .hi = htons(0x1400), .lo = htons(0x0002) },
198 .ip_dst = { .hi = htons(0x1400), .lo = htons(0x0001) }
199 };
200
2f86335b
FL
201 csum = csum_finish(packet_csum_pseudoheader(&ip));
202 assert(csum == htons(0xd779));
0292a0c9
JG
203
204 /* And also test something totally different to check for
205 * corner cases. */
206 memset(&ip, 0xff, sizeof ip);
2f86335b
FL
207 csum = csum_finish(packet_csum_pseudoheader(&ip));
208 assert(csum == htons(0xff3c));
0292a0c9
JG
209
210 mark('#');
211}
eadd1644
AZ
212
213static void
214test_csum_main(int argc OVS_UNUSED, char *argv[] OVS_UNUSED)
21effc03
BP
215{
216 const struct test_case *tc;
217 int i;
218
219 for (tc = test_cases; tc < &test_cases[ARRAY_SIZE(test_cases)]; tc++) {
e7b3e606
BP
220 const void *data = tc->data;
221 const ovs_be16 *data16 = (OVS_FORCE const ovs_be16 *) data;
222 const ovs_be32 *data32 = (OVS_FORCE const ovs_be32 *) data;
21effc03 223 uint32_t partial;
21effc03
BP
224
225 /* Test csum(). */
226 assert(ntohs(csum(tc->data, tc->size)) == tc->csum);
227 mark('.');
228
229 /* Test csum_add16(). */
230 partial = 0;
231 for (i = 0; i < tc->size / 2; i++) {
d84d4b88 232 partial = csum_add16(partial, get_unaligned_be16(&data16[i]));
21effc03
BP
233 }
234 assert(ntohs(csum_finish(partial)) == tc->csum);
235 mark('.');
236
237 /* Test csum_add32(). */
238 partial = 0;
239 for (i = 0; i < tc->size / 4; i++) {
d84d4b88 240 partial = csum_add32(partial, get_unaligned_be32(&data32[i]));
21effc03
BP
241 }
242 assert(ntohs(csum_finish(partial)) == tc->csum);
243 mark('.');
244
245 /* Test alternating csum_add16() and csum_add32(). */
246 partial = 0;
247 for (i = 0; i < tc->size / 4; i++) {
248 if (i % 2) {
d84d4b88 249 partial = csum_add32(partial, get_unaligned_be32(&data32[i]));
21effc03 250 } else {
d84d4b88
BP
251 ovs_be16 u0 = get_unaligned_be16(&data16[i * 2]);
252 ovs_be16 u1 = get_unaligned_be16(&data16[i * 2 + 1]);
80642190
BP
253 partial = csum_add16(partial, u0);
254 partial = csum_add16(partial, u1);
21effc03
BP
255 }
256 }
257 assert(ntohs(csum_finish(partial)) == tc->csum);
258 mark('.');
259
260 /* Test csum_continue(). */
261 partial = 0;
262 for (i = 0; i < tc->size / 4; i++) {
263 if (i) {
264 partial = csum_continue(partial, &data32[i], 4);
265 } else {
266 partial = csum_continue(partial, &data16[i * 2], 2);
267 partial = csum_continue(partial, &data16[i * 2 + 1], 2);
268 }
269 }
270 assert(ntohs(csum_finish(partial)) == tc->csum);
271 mark('#');
272 }
273
274 test_rfc1624();
97025b23 275 test_crc32c();
0292a0c9 276 test_pseudo();
21effc03
BP
277
278 /* Test recalc_csum16(). */
279 for (i = 0; i < 32; i++) {
d84d4b88
BP
280 ovs_be16 old_u16, new_u16;
281 ovs_be16 old_csum;
282 ovs_be16 data[16];
21effc03
BP
283 int j, index;
284
285 for (j = 0; j < ARRAY_SIZE(data); j++) {
d84d4b88 286 data[j] = (OVS_FORCE ovs_be16) random_uint32();
21effc03
BP
287 }
288 old_csum = csum(data, sizeof data);
289 index = random_range(ARRAY_SIZE(data));
290 old_u16 = data[index];
d84d4b88 291 new_u16 = data[index] = (OVS_FORCE ovs_be16) random_uint32();
21effc03
BP
292 assert(csum(data, sizeof data)
293 == recalc_csum16(old_csum, old_u16, new_u16));
294 mark('.');
295 }
296 mark('#');
297
298 /* Test recalc_csum32(). */
299 for (i = 0; i < 32; i++) {
d84d4b88
BP
300 ovs_be32 old_u32, new_u32;
301 ovs_be16 old_csum;
302 ovs_be32 data[16];
21effc03
BP
303 int j, index;
304
305 for (j = 0; j < ARRAY_SIZE(data); j++) {
d84d4b88 306 data[j] = (OVS_FORCE ovs_be32) random_uint32();
21effc03
BP
307 }
308 old_csum = csum(data, sizeof data);
309 index = random_range(ARRAY_SIZE(data));
310 old_u32 = data[index];
d84d4b88 311 new_u32 = data[index] = (OVS_FORCE ovs_be32) random_uint32();
21effc03
BP
312 assert(csum(data, sizeof data)
313 == recalc_csum32(old_csum, old_u32, new_u32));
314 mark('.');
315 }
316 mark('#');
317
318 putchar('\n');
21effc03 319}
eadd1644
AZ
320
321OVSTEST_REGISTER("test-csum", test_csum_main);