1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2015-2019 Vladimir Medvedkin <[email protected]> 3 */ 4 5 #include <rte_common.h> 6 #include <rte_eal.h> 7 #include <rte_ip.h> 8 #include <rte_random.h> 9 10 #include "test.h" 11 12 #include <rte_thash.h> 13 14 #define HASH_MSK(reta_sz) ((1 << reta_sz) - 1) 15 #define TUPLE_SZ (RTE_THASH_V4_L4_LEN * 4) 16 17 struct test_thash_v4 { 18 uint32_t dst_ip; 19 uint32_t src_ip; 20 uint16_t dst_port; 21 uint16_t src_port; 22 uint32_t hash_l3; 23 uint32_t hash_l3l4; 24 }; 25 26 struct test_thash_v6 { 27 uint8_t dst_ip[16]; 28 uint8_t src_ip[16]; 29 uint16_t dst_port; 30 uint16_t src_port; 31 uint32_t hash_l3; 32 uint32_t hash_l3l4; 33 }; 34 35 /*From 82599 Datasheet 7.1.2.8.3 RSS Verification Suite*/ 36 struct test_thash_v4 v4_tbl[] = { 37 {RTE_IPV4(161, 142, 100, 80), RTE_IPV4(66, 9, 149, 187), 38 1766, 2794, 0x323e8fc2, 0x51ccc178}, 39 {RTE_IPV4(65, 69, 140, 83), RTE_IPV4(199, 92, 111, 2), 40 4739, 14230, 0xd718262a, 0xc626b0ea}, 41 {RTE_IPV4(12, 22, 207, 184), RTE_IPV4(24, 19, 198, 95), 42 38024, 12898, 0xd2d0a5de, 0x5c2b394a}, 43 {RTE_IPV4(209, 142, 163, 6), RTE_IPV4(38, 27, 205, 30), 44 2217, 48228, 0x82989176, 0xafc7327f}, 45 {RTE_IPV4(202, 188, 127, 2), RTE_IPV4(153, 39, 163, 191), 46 1303, 44251, 0x5d1809c5, 0x10e828a2}, 47 }; 48 49 struct test_thash_v6 v6_tbl[] = { 50 /*3ffe:2501:200:3::1*/ 51 {{0x3f, 0xfe, 0x25, 0x01, 0x02, 0x00, 0x00, 0x03, 52 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,}, 53 /*3ffe:2501:200:1fff::7*/ 54 {0x3f, 0xfe, 0x25, 0x01, 0x02, 0x00, 0x1f, 0xff, 55 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07,}, 56 1766, 2794, 0x2cc18cd5, 0x40207d3d}, 57 /*ff02::1*/ 58 {{0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 59 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,}, 60 /*3ffe:501:8::260:97ff:fe40:efab*/ 61 {0x3f, 0xfe, 0x05, 0x01, 0x00, 0x08, 0x00, 0x00, 62 0x02, 0x60, 0x97, 0xff, 0xfe, 0x40, 0xef, 0xab,}, 63 4739, 14230, 0x0f0c461c, 0xdde51bbf}, 64 /*fe80::200:f8ff:fe21:67cf*/ 65 {{0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 66 0x02, 0x00, 0xf8, 0xff, 0xfe, 0x21, 0x67, 0xcf,}, 67 /*3ffe:1900:4545:3:200:f8ff:fe21:67cf*/ 68 {0x3f, 0xfe, 0x19, 0x00, 0x45, 0x45, 0x00, 0x03, 69 0x02, 0x00, 0xf8, 0xff, 0xfe, 0x21, 0x67, 0xcf,}, 70 38024, 44251, 0x4b61e985, 0x02d1feef}, 71 }; 72 73 uint8_t default_rss_key[] = { 74 0x6d, 0x5a, 0x56, 0xda, 0x25, 0x5b, 0x0e, 0xc2, 75 0x41, 0x67, 0x25, 0x3d, 0x43, 0xa3, 0x8f, 0xb0, 76 0xd0, 0xca, 0x2b, 0xcb, 0xae, 0x7b, 0x30, 0xb4, 77 0x77, 0xcb, 0x2d, 0xa3, 0x80, 0x30, 0xf2, 0x0c, 78 0x6a, 0x42, 0xb7, 0x3b, 0xbe, 0xac, 0x01, 0xfa, 79 }; 80 81 static int 82 test_toeplitz_hash_calc(void) 83 { 84 uint32_t i, j; 85 union rte_thash_tuple tuple; 86 uint32_t rss_l3, rss_l3l4; 87 uint8_t rss_key_be[RTE_DIM(default_rss_key)]; 88 struct rte_ipv6_hdr ipv6_hdr; 89 90 /* Convert RSS key*/ 91 rte_convert_rss_key((uint32_t *)&default_rss_key, 92 (uint32_t *)rss_key_be, RTE_DIM(default_rss_key)); 93 94 95 for (i = 0; i < RTE_DIM(v4_tbl); i++) { 96 tuple.v4.src_addr = v4_tbl[i].src_ip; 97 tuple.v4.dst_addr = v4_tbl[i].dst_ip; 98 tuple.v4.sport = v4_tbl[i].src_port; 99 tuple.v4.dport = v4_tbl[i].dst_port; 100 /*Calculate hash with original key*/ 101 rss_l3 = rte_softrss((uint32_t *)&tuple, 102 RTE_THASH_V4_L3_LEN, default_rss_key); 103 rss_l3l4 = rte_softrss((uint32_t *)&tuple, 104 RTE_THASH_V4_L4_LEN, default_rss_key); 105 if ((rss_l3 != v4_tbl[i].hash_l3) || 106 (rss_l3l4 != v4_tbl[i].hash_l3l4)) 107 return -TEST_FAILED; 108 /*Calculate hash with converted key*/ 109 rss_l3 = rte_softrss_be((uint32_t *)&tuple, 110 RTE_THASH_V4_L3_LEN, rss_key_be); 111 rss_l3l4 = rte_softrss_be((uint32_t *)&tuple, 112 RTE_THASH_V4_L4_LEN, rss_key_be); 113 if ((rss_l3 != v4_tbl[i].hash_l3) || 114 (rss_l3l4 != v4_tbl[i].hash_l3l4)) 115 return -TEST_FAILED; 116 } 117 for (i = 0; i < RTE_DIM(v6_tbl); i++) { 118 /*Fill ipv6 hdr*/ 119 for (j = 0; j < RTE_DIM(ipv6_hdr.src_addr); j++) 120 ipv6_hdr.src_addr[j] = v6_tbl[i].src_ip[j]; 121 for (j = 0; j < RTE_DIM(ipv6_hdr.dst_addr); j++) 122 ipv6_hdr.dst_addr[j] = v6_tbl[i].dst_ip[j]; 123 /*Load and convert ipv6 address into tuple*/ 124 rte_thash_load_v6_addrs(&ipv6_hdr, &tuple); 125 tuple.v6.sport = v6_tbl[i].src_port; 126 tuple.v6.dport = v6_tbl[i].dst_port; 127 /*Calculate hash with original key*/ 128 rss_l3 = rte_softrss((uint32_t *)&tuple, 129 RTE_THASH_V6_L3_LEN, default_rss_key); 130 rss_l3l4 = rte_softrss((uint32_t *)&tuple, 131 RTE_THASH_V6_L4_LEN, default_rss_key); 132 if ((rss_l3 != v6_tbl[i].hash_l3) || 133 (rss_l3l4 != v6_tbl[i].hash_l3l4)) 134 return -TEST_FAILED; 135 /*Calculate hash with converted key*/ 136 rss_l3 = rte_softrss_be((uint32_t *)&tuple, 137 RTE_THASH_V6_L3_LEN, rss_key_be); 138 rss_l3l4 = rte_softrss_be((uint32_t *)&tuple, 139 RTE_THASH_V6_L4_LEN, rss_key_be); 140 if ((rss_l3 != v6_tbl[i].hash_l3) || 141 (rss_l3l4 != v6_tbl[i].hash_l3l4)) 142 return -TEST_FAILED; 143 } 144 return TEST_SUCCESS; 145 } 146 147 static int 148 test_create_invalid(void) 149 { 150 struct rte_thash_ctx *ctx; 151 int key_len = 40; 152 int reta_sz = 7; 153 154 ctx = rte_thash_init_ctx(NULL, key_len, reta_sz, NULL, 0); 155 RTE_TEST_ASSERT(ctx == NULL, 156 "Call succeeded with invalid parameters\n"); 157 158 ctx = rte_thash_init_ctx("test", 0, reta_sz, NULL, 0); 159 RTE_TEST_ASSERT(ctx == NULL, 160 "Call succeeded with invalid parameters\n"); 161 162 ctx = rte_thash_init_ctx(NULL, key_len, 1, NULL, 0); 163 RTE_TEST_ASSERT(ctx == NULL, 164 "Call succeeded with invalid parameters\n"); 165 166 ctx = rte_thash_init_ctx(NULL, key_len, 17, NULL, 0); 167 RTE_TEST_ASSERT(ctx == NULL, 168 "Call succeeded with invalid parameters\n"); 169 170 return TEST_SUCCESS; 171 } 172 173 static int 174 test_multiple_create(void) 175 { 176 struct rte_thash_ctx *ctx; 177 int key_len = 40; 178 int reta_sz = 7; 179 int i; 180 181 for (i = 0; i < 100; i++) { 182 ctx = rte_thash_init_ctx("test", key_len, reta_sz, NULL, 0); 183 RTE_TEST_ASSERT(ctx != NULL, "Can not create CTX\n"); 184 185 rte_thash_free_ctx(ctx); 186 } 187 188 return TEST_SUCCESS; 189 } 190 191 static int 192 test_free_null(void) 193 { 194 struct rte_thash_ctx *ctx; 195 196 ctx = rte_thash_init_ctx("test", 40, 7, NULL, 0); 197 RTE_TEST_ASSERT(ctx != NULL, "Can not create CTX\n"); 198 199 rte_thash_free_ctx(ctx); 200 rte_thash_free_ctx(NULL); 201 202 return TEST_SUCCESS; 203 } 204 205 static int 206 test_add_invalid_helper(void) 207 { 208 struct rte_thash_ctx *ctx; 209 const int key_len = 40; 210 int reta_sz = 7; 211 int ret; 212 213 ctx = rte_thash_init_ctx("test", key_len, reta_sz, NULL, 0); 214 RTE_TEST_ASSERT(ctx != NULL, "can not create thash ctx\n"); 215 216 ret = rte_thash_add_helper(NULL, "test", reta_sz, 0); 217 RTE_TEST_ASSERT(ret == -EINVAL, 218 "Call succeeded with invalid parameters\n"); 219 220 ret = rte_thash_add_helper(ctx, NULL, reta_sz, 0); 221 RTE_TEST_ASSERT(ret == -EINVAL, 222 "Call succeeded with invalid parameters\n"); 223 224 ret = rte_thash_add_helper(ctx, "test", reta_sz - 1, 0); 225 RTE_TEST_ASSERT(ret == -EINVAL, 226 "Call succeeded with invalid parameters\n"); 227 228 ret = rte_thash_add_helper(ctx, "test", reta_sz, key_len * 8); 229 RTE_TEST_ASSERT(ret == -EINVAL, 230 "Call succeeded with invalid parameters\n"); 231 232 ret = rte_thash_add_helper(ctx, "first_range", reta_sz, 0); 233 RTE_TEST_ASSERT(ret == 0, "Can not create helper\n"); 234 235 ret = rte_thash_add_helper(ctx, "first_range", reta_sz, 0); 236 RTE_TEST_ASSERT(ret == -EEXIST, 237 "Call succeeded with duplicated name\n"); 238 239 /* 240 * Create second helper with offset 3 * reta_sz. 241 * Note first_range helper created range in key: 242 * [0, 32 + length{= reta_sz} - 1), i.e [0, 37). 243 * second range is [44, 81) 244 */ 245 ret = rte_thash_add_helper(ctx, "second_range", reta_sz, 246 32 + 2 * reta_sz); 247 RTE_TEST_ASSERT(ret == 0, "Can not create helper\n"); 248 249 /* 250 * Try to create overlapping with first_ and second_ ranges, 251 * i.e. [6, 49) 252 */ 253 ret = rte_thash_add_helper(ctx, "third_range", 2 * reta_sz, reta_sz); 254 RTE_TEST_ASSERT(ret == -EEXIST, 255 "Call succeeded with overlapping ranges\n"); 256 257 rte_thash_free_ctx(ctx); 258 259 return TEST_SUCCESS; 260 } 261 262 static int 263 test_find_existing(void) 264 { 265 struct rte_thash_ctx *ctx, *ret_ctx; 266 267 ctx = rte_thash_init_ctx("test", 40, 7, NULL, 0); 268 RTE_TEST_ASSERT(ctx != NULL, "can not create thash ctx\n"); 269 270 ret_ctx = rte_thash_find_existing("test"); 271 RTE_TEST_ASSERT(ret_ctx != NULL, "can not find existing ctx\n"); 272 273 rte_thash_free_ctx(ctx); 274 275 return TEST_SUCCESS; 276 } 277 278 static int 279 test_get_helper(void) 280 { 281 struct rte_thash_ctx *ctx; 282 struct rte_thash_subtuple_helper *h; 283 int ret; 284 285 ctx = rte_thash_init_ctx("test", 40, 7, NULL, 0); 286 RTE_TEST_ASSERT(ctx != NULL, "Can not create thash ctx\n"); 287 288 h = rte_thash_get_helper(NULL, "first_range"); 289 RTE_TEST_ASSERT(h == NULL, "Call succeeded with invalid parameters\n"); 290 291 h = rte_thash_get_helper(ctx, NULL); 292 RTE_TEST_ASSERT(h == NULL, "Call succeeded with invalid parameters\n"); 293 294 ret = rte_thash_add_helper(ctx, "first_range", 8, 0); 295 RTE_TEST_ASSERT(ret == 0, "Can not create helper\n"); 296 297 h = rte_thash_get_helper(ctx, "first_range"); 298 RTE_TEST_ASSERT(h != NULL, "Can not find helper\n"); 299 300 rte_thash_free_ctx(ctx); 301 302 return TEST_SUCCESS; 303 } 304 305 static int 306 test_period_overflow(void) 307 { 308 struct rte_thash_ctx *ctx; 309 int reta_sz = 7; /* reflects polynomial degree */ 310 int ret; 311 312 /* first create without RTE_THASH_IGNORE_PERIOD_OVERFLOW flag */ 313 ctx = rte_thash_init_ctx("test", 40, reta_sz, NULL, 0); 314 RTE_TEST_ASSERT(ctx != NULL, "Can not create thash ctx\n"); 315 316 /* requested range > (2^reta_sz) - 1 */ 317 ret = rte_thash_add_helper(ctx, "test", (1 << reta_sz), 0); 318 RTE_TEST_ASSERT(ret == -ENOSPC, 319 "Call succeeded with invalid parameters\n"); 320 321 /* requested range == len + 32 - 1, smaller than (2^reta_sz) - 1 */ 322 ret = rte_thash_add_helper(ctx, "test", (1 << reta_sz) - 32, 0); 323 RTE_TEST_ASSERT(ret == 0, "Can not create helper\n"); 324 325 rte_thash_free_ctx(ctx); 326 327 /* create with RTE_THASH_IGNORE_PERIOD_OVERFLOW flag */ 328 ctx = rte_thash_init_ctx("test", 40, reta_sz, NULL, 329 RTE_THASH_IGNORE_PERIOD_OVERFLOW); 330 RTE_TEST_ASSERT(ctx != NULL, "Can not create thash ctx\n"); 331 332 /* requested range > (2^reta_sz - 1) */ 333 ret = rte_thash_add_helper(ctx, "test", (1 << reta_sz) + 10, 0); 334 RTE_TEST_ASSERT(ret == 0, "Can not create helper\n"); 335 336 rte_thash_free_ctx(ctx); 337 338 return TEST_SUCCESS; 339 } 340 341 static int 342 test_predictable_rss_min_seq(void) 343 { 344 struct rte_thash_ctx *ctx; 345 struct rte_thash_subtuple_helper *h; 346 const int key_len = 40; 347 int reta_sz = 6; 348 uint8_t initial_key[key_len]; 349 const uint8_t *new_key; 350 int ret; 351 union rte_thash_tuple tuple; 352 uint32_t orig_hash, adj_hash, adj; 353 unsigned int desired_value = 27 & HASH_MSK(reta_sz); 354 uint16_t port_value = 22; 355 356 memset(initial_key, 0, key_len); 357 358 ctx = rte_thash_init_ctx("test", key_len, reta_sz, initial_key, 359 RTE_THASH_MINIMAL_SEQ); 360 RTE_TEST_ASSERT(ctx != NULL, "can not create thash ctx\n"); 361 362 ret = rte_thash_add_helper(ctx, "snat", sizeof(uint16_t) * 8, 363 offsetof(union rte_thash_tuple, v4.sport) * 8); 364 RTE_TEST_ASSERT(ret == 0, "can not add helper, ret %d\n", ret); 365 366 h = rte_thash_get_helper(ctx, "snat"); 367 RTE_TEST_ASSERT(h != NULL, "can not find helper\n"); 368 369 new_key = rte_thash_get_key(ctx); 370 tuple.v4.src_addr = RTE_IPV4(0, 0, 0, 0); 371 tuple.v4.dst_addr = RTE_IPV4(0, 0, 0, 0); 372 tuple.v4.sport = 0; 373 tuple.v4.sport = rte_cpu_to_be_16(port_value); 374 tuple.v4.dport = 0; 375 tuple.v4.sctp_tag = rte_be_to_cpu_32(tuple.v4.sctp_tag); 376 377 orig_hash = rte_softrss((uint32_t *)&tuple, 378 RTE_THASH_V4_L4_LEN, new_key); 379 adj = rte_thash_get_complement(h, orig_hash, desired_value); 380 381 tuple.v4.sctp_tag = rte_cpu_to_be_32(tuple.v4.sctp_tag); 382 tuple.v4.sport ^= rte_cpu_to_be_16(adj); 383 tuple.v4.sctp_tag = rte_be_to_cpu_32(tuple.v4.sctp_tag); 384 385 adj_hash = rte_softrss((uint32_t *)&tuple, 386 RTE_THASH_V4_L4_LEN, new_key); 387 RTE_TEST_ASSERT((adj_hash & HASH_MSK(reta_sz)) == 388 desired_value, "bad desired value\n"); 389 390 rte_thash_free_ctx(ctx); 391 392 return TEST_SUCCESS; 393 } 394 395 /* 396 * This test creates 7 subranges in the following order: 397 * range_one = [56, 95), len = 8, offset = 56 398 * range_two = [64, 103), len = 8, offset = 64 399 * range_three = [120, 159), len = 8, offset = 120 400 * range_four = [48, 87), len = 8, offset = 48 401 * range_five = [57, 95), len = 7, offset = 57 402 * range_six = [40, 111), len = 40, offset = 40 403 * range_seven = [0, 39), len = 8, offset = 0 404 */ 405 struct range { 406 const char *name; 407 int len; 408 int offset; 409 int byte_idx; 410 }; 411 412 struct range rng_arr[] = { 413 {"one", 8, 56, 7}, 414 {"two", 8, 64, 8}, 415 {"three", 8, 120, 15}, 416 {"four", 8, 48, 6}, 417 {"six", 40, 40, 9}, 418 {"five", 7, 57, 7}, 419 {"seven", 8, 0, 0} 420 }; 421 422 static int 423 test_predictable_rss_multirange(void) 424 { 425 struct rte_thash_ctx *ctx; 426 struct rte_thash_subtuple_helper *h[RTE_DIM(rng_arr)]; 427 const uint8_t *new_key; 428 const int key_len = 40; 429 int reta_sz = 7; 430 unsigned int i, j, k; 431 int ret; 432 uint32_t desired_value = rte_rand() & HASH_MSK(reta_sz); 433 uint8_t tuples[RTE_DIM(rng_arr)][16] = { {0} }; 434 uint32_t *ptr; 435 uint32_t hashes[RTE_DIM(rng_arr)]; 436 uint32_t adj_hashes[RTE_DIM(rng_arr)]; 437 uint32_t adj; 438 439 ctx = rte_thash_init_ctx("test", key_len, reta_sz, NULL, 0); 440 RTE_TEST_ASSERT(ctx != NULL, "can not create thash ctx\n"); 441 442 for (i = 0; i < RTE_DIM(rng_arr); i++) { 443 ret = rte_thash_add_helper(ctx, rng_arr[i].name, 444 rng_arr[i].len, rng_arr[i].offset); 445 RTE_TEST_ASSERT(ret == 0, "can not add helper\n"); 446 447 h[i] = rte_thash_get_helper(ctx, rng_arr[i].name); 448 RTE_TEST_ASSERT(h[i] != NULL, "can not find helper\n"); 449 } 450 new_key = rte_thash_get_key(ctx); 451 452 /* 453 * calculate hashes, complements, then adjust keys with 454 * complements and recalsulate hashes 455 */ 456 for (i = 0; i < RTE_DIM(rng_arr); i++) { 457 for (k = 0; k < 100; k++) { 458 /* init with random keys */ 459 ptr = (uint32_t *)&tuples[i][0]; 460 for (j = 0; j < 4; j++) 461 ptr[j] = rte_rand(); 462 /* convert keys from BE to CPU byte order */ 463 for (j = 0; j < 4; j++) 464 ptr[j] = rte_be_to_cpu_32(ptr[j]); 465 466 hashes[i] = rte_softrss(ptr, 4, new_key); 467 adj = rte_thash_get_complement(h[i], hashes[i], 468 desired_value); 469 /* convert back to BE to adjust the value */ 470 for (j = 0; j < 4; j++) 471 ptr[j] = rte_cpu_to_be_32(ptr[j]); 472 473 tuples[i][rng_arr[i].byte_idx] ^= adj; 474 475 for (j = 0; j < 4; j++) 476 ptr[j] = rte_be_to_cpu_32(ptr[j]); 477 478 adj_hashes[i] = rte_softrss(ptr, 4, new_key); 479 RTE_TEST_ASSERT((adj_hashes[i] & HASH_MSK(reta_sz)) == 480 desired_value, 481 "bad desired value for %d tuple\n", i); 482 } 483 } 484 485 rte_thash_free_ctx(ctx); 486 487 return TEST_SUCCESS; 488 } 489 490 static int 491 cmp_tuple_eq(void *userdata, uint8_t *tuple) 492 { 493 return memcmp(userdata, tuple, TUPLE_SZ); 494 } 495 496 static int 497 test_adjust_tuple(void) 498 { 499 struct rte_thash_ctx *ctx; 500 struct rte_thash_subtuple_helper *h; 501 const int key_len = 40; 502 const uint8_t *new_key; 503 uint8_t tuple[TUPLE_SZ]; 504 uint32_t tmp_tuple[TUPLE_SZ / sizeof(uint32_t)]; 505 uint32_t tuple_copy[TUPLE_SZ / sizeof(uint32_t)]; 506 uint32_t hash; 507 int reta_sz = CHAR_BIT; 508 int ret; 509 unsigned int i, desired_value = rte_rand() & HASH_MSK(reta_sz); 510 511 memset(tuple, 0xab, TUPLE_SZ); 512 513 ctx = rte_thash_init_ctx("test", key_len, reta_sz, NULL, 0); 514 RTE_TEST_ASSERT(ctx != NULL, "can not create thash ctx\n"); 515 516 /* 517 * set offset to be in the middle of a byte 518 * set size of the subtuple to be 2 * rets_sz 519 * to have the room for random bits 520 */ 521 ret = rte_thash_add_helper(ctx, "test", reta_sz * 2, 522 (5 * CHAR_BIT) + 4); 523 RTE_TEST_ASSERT(ret == 0, "can not add helper, ret %d\n", ret); 524 525 new_key = rte_thash_get_key(ctx); 526 527 h = rte_thash_get_helper(ctx, "test"); 528 RTE_TEST_ASSERT(h != NULL, "can not find helper\n"); 529 530 ret = rte_thash_adjust_tuple(ctx, h, tuple, TUPLE_SZ, desired_value, 531 1, NULL, NULL); 532 RTE_TEST_ASSERT(ret == 0, "can not adjust tuple, ret %d\n", ret); 533 534 for (i = 0; i < (TUPLE_SZ / 4); i++) 535 tmp_tuple[i] = 536 rte_be_to_cpu_32(*(uint32_t *)&tuple[i * 4]); 537 538 hash = rte_softrss(tmp_tuple, TUPLE_SZ / 4, new_key); 539 RTE_TEST_ASSERT((hash & HASH_MSK(reta_sz)) == 540 desired_value, "bad desired value\n"); 541 542 543 /* Pass previously calculated tuple to callback function */ 544 memcpy(tuple_copy, tuple, TUPLE_SZ); 545 546 memset(tuple, 0xab, TUPLE_SZ); 547 ret = rte_thash_adjust_tuple(ctx, h, tuple, TUPLE_SZ, desired_value, 548 1, cmp_tuple_eq, tuple_copy); 549 RTE_TEST_ASSERT(ret == -EEXIST, 550 "adjust tuple didn't indicate collision\n"); 551 552 /* 553 * Make the function to generate random bits into subtuple 554 * after first adjustment attempt. 555 */ 556 memset(tuple, 0xab, TUPLE_SZ); 557 ret = rte_thash_adjust_tuple(ctx, h, tuple, TUPLE_SZ, desired_value, 558 2, cmp_tuple_eq, tuple_copy); 559 RTE_TEST_ASSERT(ret == 0, "can not adjust tuple, ret %d\n", ret); 560 561 for (i = 0; i < (TUPLE_SZ / 4); i++) 562 tmp_tuple[i] = 563 rte_be_to_cpu_32(*(uint32_t *)&tuple[i * 4]); 564 565 hash = rte_softrss(tmp_tuple, TUPLE_SZ / 4, new_key); 566 RTE_TEST_ASSERT((hash & HASH_MSK(reta_sz)) == 567 desired_value, "bad desired value\n"); 568 569 rte_thash_free_ctx(ctx); 570 571 return TEST_SUCCESS; 572 } 573 574 static struct unit_test_suite thash_tests = { 575 .suite_name = "thash autotest", 576 .setup = NULL, 577 .teardown = NULL, 578 .unit_test_cases = { 579 TEST_CASE(test_toeplitz_hash_calc), 580 TEST_CASE(test_create_invalid), 581 TEST_CASE(test_multiple_create), 582 TEST_CASE(test_free_null), 583 TEST_CASE(test_add_invalid_helper), 584 TEST_CASE(test_find_existing), 585 TEST_CASE(test_get_helper), 586 TEST_CASE(test_period_overflow), 587 TEST_CASE(test_predictable_rss_min_seq), 588 TEST_CASE(test_predictable_rss_multirange), 589 TEST_CASE(test_adjust_tuple), 590 TEST_CASES_END() 591 } 592 }; 593 594 static int 595 test_thash(void) 596 { 597 return unit_test_suite_runner(&thash_tests); 598 } 599 600 REGISTER_TEST_COMMAND(thash_autotest, test_thash); 601