]>
git.proxmox.com Git - ovs.git/blob - tests/test-csum.c
2 * Copyright (c) 2009, 2010, 2011, 2014 Nicira, Inc.
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:
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
22 #include <netinet/in.h>
29 #include "unaligned.h"
34 size_t size
; /* Test requires a multiple of 4. */
38 #define TEST_CASE(DATA, CSUM) { DATA, (sizeof DATA) - 1, CSUM }
40 static const struct test_case test_cases
[] = {
41 /* RFC 1071 section 3. */
42 TEST_CASE("\x00\x01\xf2\x03"
44 0xffff - 0xddf2 /* ~0xddf2 */),
46 /* http://www.sbprojects.com/projects/tcpip/theory/theory14.htm */
47 TEST_CASE("\x45\x00\x00\x28"
54 /* http://mathforum.org/library/drmath/view/54379.html */
55 TEST_CASE("\x86\x5e\xac\x60"
68 /* This code is useful for generating new test cases for RFC 1624 section 4. */
70 generate_rfc1624_test_case(void)
74 for (i
= 0; i
< 10000000; i
++) {
78 for (j
= 0; j
< 8; j
++) {
79 data
[j
] = random_uint32();
81 data
[7] &= 0x0000ffff;
82 data
[7] |= 0x55550000;
83 if (ntohs(~csum(data
, sizeof data
- 2)) == 0xcd7a) {
84 ovs_hex_dump(stdout
, data
, sizeof data
, 0, false);
93 /* Make sure we get the calculation in RFC 1624 section 4 correct. */
97 /* "...an IP packet header in which a 16-bit field m = 0x5555..." */
99 0xfe, 0x8f, 0xc1, 0x14, 0x4b, 0x6f, 0x70, 0x2a,
100 0x80, 0x29, 0x78, 0xc0, 0x58, 0x81, 0x77, 0xaa,
101 0x66, 0x64, 0xfc, 0x96, 0x63, 0x97, 0x64, 0xee,
102 0x12, 0x53, 0x1d, 0xa9, 0x2d, 0xa9, 0x55, 0x55
105 /* "...the one's complement sum of all other header octets is 0xCD7A." */
106 assert(ntohs(csum(data
, sizeof data
- 2)) == 0xffff - 0xcd7a);
108 /* "...the header checksum would be:
110 HC = ~(0xCD7A + 0x5555)
114 assert(ntohs(csum(data
, sizeof data
)) == 0xdd2f);
116 /* "a 16-bit field m = 0x5555 changes to m' = 0x3285..." */
120 /* "The new checksum via recomputation is:
122 HC' = ~(0xCD7A + 0x3285)
126 assert(ntohs(csum(data
, sizeof data
)) == 0x0000);
128 /* "Applying [Eqn. 3] to the example above, we get the correct result:
130 HC' = ~(C + (-m) + m')
131 = ~(0x22D0 + ~0x5555 + 0x3285)
134 assert(recalc_csum16(htons(0xdd2f), htons(0x5555), htons(0x3285))
140 /* CRC32C checksum tests, based on Intel IPPs, Chapter 13,
141 * ippsCRC32C_8u() example, found at the following location:
142 * http://software.intel.com/sites/products/documentation/hpc/ipp/ipps/ */
148 0x01, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
149 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
150 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00,
151 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x18,
152 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
153 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
157 assert(ntohl(crc32c(data
, 48)) == 0x563a96d9L
);
159 /* 32 bytes of all zeroes */
160 for (i
= 0; i
< 32; i
++) data
[i
] = 0x00;
161 assert(ntohl(crc32c(data
, 32)) == 0xaa36918aL
);
163 /* 32 bytes of all ones */
164 for (i
= 0; i
< 32; i
++) data
[i
] = 0xff;
165 assert(ntohl(crc32c(data
, 32)) == 0x43aba862L
);
167 /* 32 bytes of incrementing 00..1f */
168 for (i
= 0; i
< 32; i
++) data
[i
] = i
;
169 assert(ntohl(crc32c(data
, 32)) == 0x4e79dd46L
);
171 /* 32 bytes of decrementing 1f..00 */
172 for (i
= 0; i
< 32; i
++) data
[i
] = 31 - i
;
173 assert(ntohl(crc32c(data
, 32)) == 0x5cdb3f11L
);
180 test_csum_main(int argc OVS_UNUSED
, char *argv
[] OVS_UNUSED
)
182 const struct test_case
*tc
;
185 for (tc
= test_cases
; tc
< &test_cases
[ARRAY_SIZE(test_cases
)]; tc
++) {
186 const void *data
= tc
->data
;
187 const ovs_be16
*data16
= (OVS_FORCE
const ovs_be16
*) data
;
188 const ovs_be32
*data32
= (OVS_FORCE
const ovs_be32
*) data
;
192 assert(ntohs(csum(tc
->data
, tc
->size
)) == tc
->csum
);
195 /* Test csum_add16(). */
197 for (i
= 0; i
< tc
->size
/ 2; i
++) {
198 partial
= csum_add16(partial
, get_unaligned_be16(&data16
[i
]));
200 assert(ntohs(csum_finish(partial
)) == tc
->csum
);
203 /* Test csum_add32(). */
205 for (i
= 0; i
< tc
->size
/ 4; i
++) {
206 partial
= csum_add32(partial
, get_unaligned_be32(&data32
[i
]));
208 assert(ntohs(csum_finish(partial
)) == tc
->csum
);
211 /* Test alternating csum_add16() and csum_add32(). */
213 for (i
= 0; i
< tc
->size
/ 4; i
++) {
215 partial
= csum_add32(partial
, get_unaligned_be32(&data32
[i
]));
217 ovs_be16 u0
= get_unaligned_be16(&data16
[i
* 2]);
218 ovs_be16 u1
= get_unaligned_be16(&data16
[i
* 2 + 1]);
219 partial
= csum_add16(partial
, u0
);
220 partial
= csum_add16(partial
, u1
);
223 assert(ntohs(csum_finish(partial
)) == tc
->csum
);
226 /* Test csum_continue(). */
228 for (i
= 0; i
< tc
->size
/ 4; i
++) {
230 partial
= csum_continue(partial
, &data32
[i
], 4);
232 partial
= csum_continue(partial
, &data16
[i
* 2], 2);
233 partial
= csum_continue(partial
, &data16
[i
* 2 + 1], 2);
236 assert(ntohs(csum_finish(partial
)) == tc
->csum
);
243 /* Test recalc_csum16(). */
244 for (i
= 0; i
< 32; i
++) {
245 ovs_be16 old_u16
, new_u16
;
250 for (j
= 0; j
< ARRAY_SIZE(data
); j
++) {
251 data
[j
] = (OVS_FORCE ovs_be16
) random_uint32();
253 old_csum
= csum(data
, sizeof data
);
254 index
= random_range(ARRAY_SIZE(data
));
255 old_u16
= data
[index
];
256 new_u16
= data
[index
] = (OVS_FORCE ovs_be16
) random_uint32();
257 assert(csum(data
, sizeof data
)
258 == recalc_csum16(old_csum
, old_u16
, new_u16
));
263 /* Test recalc_csum32(). */
264 for (i
= 0; i
< 32; i
++) {
265 ovs_be32 old_u32
, new_u32
;
270 for (j
= 0; j
< ARRAY_SIZE(data
); j
++) {
271 data
[j
] = (OVS_FORCE ovs_be32
) random_uint32();
273 old_csum
= csum(data
, sizeof data
);
274 index
= random_range(ARRAY_SIZE(data
));
275 old_u32
= data
[index
];
276 new_u32
= data
[index
] = (OVS_FORCE ovs_be32
) random_uint32();
277 assert(csum(data
, sizeof data
)
278 == recalc_csum32(old_csum
, old_u32
, new_u32
));
286 OVSTEST_REGISTER("test-csum", test_csum_main
);