1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2010-2014 Intel Corporation 3 */ 4 5 #ifndef RTE_EXEC_ENV_WINDOWS 6 7 #include <rte_ip.h> 8 #include <rte_string_fns.h> 9 #include <rte_hexdump.h> 10 #include "test_table.h" 11 #include "test_table_acl.h" 12 13 /* 14 * Rule and trace formats definitions. 15 **/ 16 17 struct ipv4_5tuple { 18 uint8_t proto; 19 uint32_t ip_src; 20 uint32_t ip_dst; 21 uint16_t port_src; 22 uint16_t port_dst; 23 }; 24 25 enum { 26 PROTO_FIELD_IPV4, 27 SRC_FIELD_IPV4, 28 DST_FIELD_IPV4, 29 SRCP_FIELD_IPV4, 30 DSTP_FIELD_IPV4, 31 NUM_FIELDS_IPV4 32 }; 33 34 struct rte_acl_field_def ipv4_defs[NUM_FIELDS_IPV4] = { 35 { 36 .type = RTE_ACL_FIELD_TYPE_BITMASK, 37 .size = sizeof(uint8_t), 38 .field_index = PROTO_FIELD_IPV4, 39 .input_index = PROTO_FIELD_IPV4, 40 .offset = offsetof(struct ipv4_5tuple, proto), 41 }, 42 { 43 .type = RTE_ACL_FIELD_TYPE_MASK, 44 .size = sizeof(uint32_t), 45 .field_index = SRC_FIELD_IPV4, 46 .input_index = SRC_FIELD_IPV4, 47 .offset = offsetof(struct ipv4_5tuple, ip_src), 48 }, 49 { 50 .type = RTE_ACL_FIELD_TYPE_MASK, 51 .size = sizeof(uint32_t), 52 .field_index = DST_FIELD_IPV4, 53 .input_index = DST_FIELD_IPV4, 54 .offset = offsetof(struct ipv4_5tuple, ip_dst), 55 }, 56 { 57 .type = RTE_ACL_FIELD_TYPE_RANGE, 58 .size = sizeof(uint16_t), 59 .field_index = SRCP_FIELD_IPV4, 60 .input_index = SRCP_FIELD_IPV4, 61 .offset = offsetof(struct ipv4_5tuple, port_src), 62 }, 63 { 64 .type = RTE_ACL_FIELD_TYPE_RANGE, 65 .size = sizeof(uint16_t), 66 .field_index = DSTP_FIELD_IPV4, 67 .input_index = SRCP_FIELD_IPV4, 68 .offset = offsetof(struct ipv4_5tuple, port_dst), 69 }, 70 }; 71 72 struct rte_table_acl_rule_add_params table_acl_IPv4_rule; 73 74 typedef int (*parse_5tuple)(char *text, 75 struct rte_table_acl_rule_add_params *rule); 76 77 /* 78 * The order of the fields in the rule string after the initial '@' 79 */ 80 enum { 81 CB_FLD_SRC_ADDR, 82 CB_FLD_DST_ADDR, 83 CB_FLD_SRC_PORT_RANGE, 84 CB_FLD_DST_PORT_RANGE, 85 CB_FLD_PROTO, 86 CB_FLD_NUM, 87 }; 88 89 90 #define GET_CB_FIELD(in, fd, base, lim, dlm) \ 91 do { \ 92 unsigned long val; \ 93 char *end; \ 94 \ 95 errno = 0; \ 96 val = strtoul((in), &end, (base)); \ 97 if (errno != 0 || end[0] != (dlm) || val > (lim)) \ 98 return -EINVAL; \ 99 (fd) = (typeof(fd)) val; \ 100 (in) = end + 1; \ 101 } while (0) 102 103 104 105 106 static int 107 parse_ipv4_net(const char *in, uint32_t *addr, uint32_t *mask_len) 108 { 109 uint8_t a, b, c, d, m; 110 111 GET_CB_FIELD(in, a, 0, UINT8_MAX, '.'); 112 GET_CB_FIELD(in, b, 0, UINT8_MAX, '.'); 113 GET_CB_FIELD(in, c, 0, UINT8_MAX, '.'); 114 GET_CB_FIELD(in, d, 0, UINT8_MAX, '/'); 115 GET_CB_FIELD(in, m, 0, sizeof(uint32_t) * CHAR_BIT, 0); 116 117 addr[0] = RTE_IPV4(a, b, c, d); 118 mask_len[0] = m; 119 120 return 0; 121 } 122 123 static int 124 parse_port_range(const char *in, uint16_t *port_low, uint16_t *port_high) 125 { 126 uint16_t a, b; 127 128 GET_CB_FIELD(in, a, 0, UINT16_MAX, ':'); 129 GET_CB_FIELD(in, b, 0, UINT16_MAX, 0); 130 131 port_low[0] = a; 132 port_high[0] = b; 133 134 return 0; 135 } 136 137 static int 138 parse_cb_ipv4_rule(char *str, struct rte_table_acl_rule_add_params *v) 139 { 140 int i, rc; 141 char *s, *sp, *in[CB_FLD_NUM]; 142 static const char *dlm = " \t\n"; 143 144 /* 145 ** Skip leading '@' 146 */ 147 if (strchr(str, '@') != str) 148 return -EINVAL; 149 150 s = str + 1; 151 152 /* 153 * Populate the 'in' array with the location of each 154 * field in the string we're parsing 155 */ 156 for (i = 0; i != DIM(in); i++) { 157 in[i] = strtok_r(s, dlm, &sp); 158 if (in[i] == NULL) 159 return -EINVAL; 160 s = NULL; 161 } 162 163 /* Parse x.x.x.x/x */ 164 rc = parse_ipv4_net(in[CB_FLD_SRC_ADDR], 165 &v->field_value[SRC_FIELD_IPV4].value.u32, 166 &v->field_value[SRC_FIELD_IPV4].mask_range.u32); 167 if (rc != 0) { 168 fprintf(stderr, "failed to read src address/mask: %s\n", 169 in[CB_FLD_SRC_ADDR]); 170 return rc; 171 } 172 173 printf("V=%u, mask=%u\n", v->field_value[SRC_FIELD_IPV4].value.u32, 174 v->field_value[SRC_FIELD_IPV4].mask_range.u32); 175 176 /* Parse x.x.x.x/x */ 177 rc = parse_ipv4_net(in[CB_FLD_DST_ADDR], 178 &v->field_value[DST_FIELD_IPV4].value.u32, 179 &v->field_value[DST_FIELD_IPV4].mask_range.u32); 180 if (rc != 0) { 181 fprintf(stderr, "failed to read dest address/mask: %s\n", 182 in[CB_FLD_DST_ADDR]); 183 return rc; 184 } 185 186 printf("V=%u, mask=%u\n", v->field_value[DST_FIELD_IPV4].value.u32, 187 v->field_value[DST_FIELD_IPV4].mask_range.u32); 188 /* Parse n:n */ 189 rc = parse_port_range(in[CB_FLD_SRC_PORT_RANGE], 190 &v->field_value[SRCP_FIELD_IPV4].value.u16, 191 &v->field_value[SRCP_FIELD_IPV4].mask_range.u16); 192 if (rc != 0) { 193 fprintf(stderr, "failed to read source port range: %s\n", 194 in[CB_FLD_SRC_PORT_RANGE]); 195 return rc; 196 } 197 198 printf("V=%u, mask=%u\n", v->field_value[SRCP_FIELD_IPV4].value.u16, 199 v->field_value[SRCP_FIELD_IPV4].mask_range.u16); 200 /* Parse n:n */ 201 rc = parse_port_range(in[CB_FLD_DST_PORT_RANGE], 202 &v->field_value[DSTP_FIELD_IPV4].value.u16, 203 &v->field_value[DSTP_FIELD_IPV4].mask_range.u16); 204 if (rc != 0) { 205 fprintf(stderr, "failed to read dest port range: %s\n", 206 in[CB_FLD_DST_PORT_RANGE]); 207 return rc; 208 } 209 210 printf("V=%u, mask=%u\n", v->field_value[DSTP_FIELD_IPV4].value.u16, 211 v->field_value[DSTP_FIELD_IPV4].mask_range.u16); 212 /* parse 0/0xnn */ 213 GET_CB_FIELD(in[CB_FLD_PROTO], 214 v->field_value[PROTO_FIELD_IPV4].value.u8, 215 0, UINT8_MAX, '/'); 216 GET_CB_FIELD(in[CB_FLD_PROTO], 217 v->field_value[PROTO_FIELD_IPV4].mask_range.u8, 218 0, UINT8_MAX, 0); 219 220 printf("V=%u, mask=%u\n", 221 (unsigned int)v->field_value[PROTO_FIELD_IPV4].value.u8, 222 v->field_value[PROTO_FIELD_IPV4].mask_range.u8); 223 return 0; 224 } 225 226 static int 227 parse_cb_ipv4_rule_del(char *str, struct rte_table_acl_rule_delete_params *v) 228 { 229 int i, rc; 230 char *s, *sp, *in[CB_FLD_NUM]; 231 static const char *dlm = " \t\n"; 232 233 /* 234 ** Skip leading '@' 235 */ 236 if (strchr(str, '@') != str) 237 return -EINVAL; 238 239 s = str + 1; 240 241 /* 242 * Populate the 'in' array with the location of each 243 * field in the string we're parsing 244 */ 245 for (i = 0; i != DIM(in); i++) { 246 in[i] = strtok_r(s, dlm, &sp); 247 if (in[i] == NULL) 248 return -EINVAL; 249 s = NULL; 250 } 251 252 /* Parse x.x.x.x/x */ 253 rc = parse_ipv4_net(in[CB_FLD_SRC_ADDR], 254 &v->field_value[SRC_FIELD_IPV4].value.u32, 255 &v->field_value[SRC_FIELD_IPV4].mask_range.u32); 256 if (rc != 0) { 257 fprintf(stderr, "failed to read src address/mask: %s\n", 258 in[CB_FLD_SRC_ADDR]); 259 return rc; 260 } 261 262 printf("V=%u, mask=%u\n", v->field_value[SRC_FIELD_IPV4].value.u32, 263 v->field_value[SRC_FIELD_IPV4].mask_range.u32); 264 265 /* Parse x.x.x.x/x */ 266 rc = parse_ipv4_net(in[CB_FLD_DST_ADDR], 267 &v->field_value[DST_FIELD_IPV4].value.u32, 268 &v->field_value[DST_FIELD_IPV4].mask_range.u32); 269 if (rc != 0) { 270 fprintf(stderr, "failed to read dest address/mask: %s\n", 271 in[CB_FLD_DST_ADDR]); 272 return rc; 273 } 274 275 printf("V=%u, mask=%u\n", v->field_value[DST_FIELD_IPV4].value.u32, 276 v->field_value[DST_FIELD_IPV4].mask_range.u32); 277 /* Parse n:n */ 278 rc = parse_port_range(in[CB_FLD_SRC_PORT_RANGE], 279 &v->field_value[SRCP_FIELD_IPV4].value.u16, 280 &v->field_value[SRCP_FIELD_IPV4].mask_range.u16); 281 if (rc != 0) { 282 fprintf(stderr, "failed to read source port range: %s\n", 283 in[CB_FLD_SRC_PORT_RANGE]); 284 return rc; 285 } 286 287 printf("V=%u, mask=%u\n", v->field_value[SRCP_FIELD_IPV4].value.u16, 288 v->field_value[SRCP_FIELD_IPV4].mask_range.u16); 289 /* Parse n:n */ 290 rc = parse_port_range(in[CB_FLD_DST_PORT_RANGE], 291 &v->field_value[DSTP_FIELD_IPV4].value.u16, 292 &v->field_value[DSTP_FIELD_IPV4].mask_range.u16); 293 if (rc != 0) { 294 fprintf(stderr, "failed to read dest port range: %s\n", 295 in[CB_FLD_DST_PORT_RANGE]); 296 return rc; 297 } 298 299 printf("V=%u, mask=%u\n", v->field_value[DSTP_FIELD_IPV4].value.u16, 300 v->field_value[DSTP_FIELD_IPV4].mask_range.u16); 301 /* parse 0/0xnn */ 302 GET_CB_FIELD(in[CB_FLD_PROTO], 303 v->field_value[PROTO_FIELD_IPV4].value.u8, 304 0, UINT8_MAX, '/'); 305 GET_CB_FIELD(in[CB_FLD_PROTO], 306 v->field_value[PROTO_FIELD_IPV4].mask_range.u8, 307 0, UINT8_MAX, 0); 308 309 printf("V=%u, mask=%u\n", 310 (unsigned int)v->field_value[PROTO_FIELD_IPV4].value.u8, 311 v->field_value[PROTO_FIELD_IPV4].mask_range.u8); 312 return 0; 313 } 314 315 /* 316 * The format for these rules DO NOT need the port ranges to be 317 * separated by ' : ', just ':'. It's a lot more readable and 318 * cleaner, IMO. 319 */ 320 char lines[][128] = { 321 "@0.0.0.0/0 0.0.0.0/0 0:65535 0:65535 2/0xff", /* Protocol check */ 322 "@192.168.3.1/32 0.0.0.0/0 0:65535 0:65535 0/0", /* Src IP checl */ 323 "@0.0.0.0/0 10.4.4.1/32 0:65535 0:65535 0/0", /* dst IP check */ 324 "@0.0.0.0/0 0.0.0.0/0 105:105 0:65535 0/0", /* src port check */ 325 "@0.0.0.0/0 0.0.0.0/0 0:65535 206:206 0/0", /* dst port check */ 326 }; 327 328 char line[128]; 329 330 331 static int 332 setup_acl_pipeline(void) 333 { 334 int ret; 335 int i; 336 struct rte_pipeline_params pipeline_params = { 337 .name = "PIPELINE", 338 .socket_id = 0, 339 }; 340 uint32_t n; 341 struct rte_table_acl_rule_add_params rule_params; 342 struct rte_pipeline_table_acl_rule_delete_params *delete_params; 343 parse_5tuple parser; 344 char acl_name[64]; 345 346 /* Pipeline configuration */ 347 p = rte_pipeline_create(&pipeline_params); 348 if (p == NULL) { 349 fprintf(stderr, "%s: Failed to configure pipeline\n", 350 __func__); 351 goto fail; 352 } 353 354 /* Input port configuration */ 355 for (i = 0; i < N_PORTS; i++) { 356 struct rte_port_ring_reader_params port_ring_params = { 357 .ring = rings_rx[i], 358 }; 359 360 struct rte_pipeline_port_in_params port_params = { 361 .ops = &rte_port_ring_reader_ops, 362 .arg_create = (void *) &port_ring_params, 363 .f_action = NULL, 364 .burst_size = BURST_SIZE, 365 }; 366 367 /* Put in action for some ports */ 368 if (i) 369 port_params.f_action = port_in_action; 370 371 ret = rte_pipeline_port_in_create(p, &port_params, 372 &port_in_id[i]); 373 if (ret) { 374 rte_panic("Unable to configure input port %d, ret:%d\n", 375 i, ret); 376 goto fail; 377 } 378 } 379 380 /* output Port configuration */ 381 for (i = 0; i < N_PORTS; i++) { 382 struct rte_port_ring_writer_params port_ring_params = { 383 .ring = rings_tx[i], 384 .tx_burst_sz = BURST_SIZE, 385 }; 386 387 struct rte_pipeline_port_out_params port_params = { 388 .ops = &rte_port_ring_writer_ops, 389 .arg_create = (void *) &port_ring_params, 390 .f_action = NULL, 391 .arg_ah = NULL, 392 }; 393 394 395 if (rte_pipeline_port_out_create(p, &port_params, 396 &port_out_id[i])) { 397 rte_panic("Unable to configure output port %d\n", i); 398 goto fail; 399 } 400 } 401 402 /* Table configuration */ 403 for (i = 0; i < N_PORTS; i++) { 404 struct rte_pipeline_table_params table_params; 405 406 /* Set up defaults for stub */ 407 table_params.ops = &rte_table_stub_ops; 408 table_params.arg_create = NULL; 409 table_params.f_action_hit = action_handler_hit; 410 table_params.f_action_miss = NULL; 411 table_params.action_data_size = 0; 412 413 printf("miss_action=%x\n", 414 table_entry_miss_action); 415 416 printf("RTE_ACL_RULE_SZ(%zu) = %zu\n", DIM(ipv4_defs), 417 RTE_ACL_RULE_SZ(DIM(ipv4_defs))); 418 419 struct rte_table_acl_params acl_params; 420 421 acl_params.n_rules = 1 << 5; 422 acl_params.n_rule_fields = DIM(ipv4_defs); 423 snprintf(acl_name, sizeof(acl_name), "ACL%d", i); 424 acl_params.name = acl_name; 425 memcpy(acl_params.field_format, ipv4_defs, sizeof(ipv4_defs)); 426 427 table_params.ops = &rte_table_acl_ops; 428 table_params.arg_create = &acl_params; 429 430 if (rte_pipeline_table_create(p, &table_params, &table_id[i])) { 431 rte_panic("Unable to configure table %u\n", i); 432 goto fail; 433 } 434 435 if (connect_miss_action_to_table) { 436 if (rte_pipeline_table_create(p, &table_params, 437 &table_id[i+2])) { 438 rte_panic("Unable to configure table %u\n", i); 439 goto fail; 440 } 441 } 442 } 443 444 for (i = 0; i < N_PORTS; i++) { 445 if (rte_pipeline_port_in_connect_to_table(p, port_in_id[i], 446 table_id[i])) { 447 rte_panic("Unable to connect input port %u to " 448 "table %u\n", 449 port_in_id[i], table_id[i]); 450 goto fail; 451 } 452 } 453 454 /* Add bulk entries to tables */ 455 for (i = 0; i < N_PORTS; i++) { 456 struct rte_table_acl_rule_add_params keys[5]; 457 struct rte_pipeline_table_entry entries[5]; 458 struct rte_table_acl_rule_add_params *key_array[5]; 459 struct rte_pipeline_table_entry *table_entries[5]; 460 int key_found[5]; 461 struct rte_pipeline_table_entry *table_entries_ptr[5]; 462 struct rte_pipeline_table_entry entries_ptr[5]; 463 464 parser = parse_cb_ipv4_rule; 465 for (n = 0; n < 5; n++) { 466 memset(&keys[n], 0, sizeof(struct rte_table_acl_rule_add_params)); 467 key_array[n] = &keys[n]; 468 469 strlcpy(line, lines[n], sizeof(line)); 470 printf("PARSING [%s]\n", line); 471 472 ret = parser(line, &keys[n]); 473 if (ret != 0) { 474 fprintf(stderr, 475 "line %u: parse_cb_ipv4vlan_rule failed, error code: %d (%s)\n", 476 n, ret, strerror(-ret)); 477 return ret; 478 } 479 480 keys[n].priority = RTE_ACL_MAX_PRIORITY - n - 1; 481 482 entries[n].action = RTE_PIPELINE_ACTION_PORT; 483 entries[n].port_id = port_out_id[i^1]; 484 table_entries[n] = &entries[n]; 485 table_entries_ptr[n] = &entries_ptr[n]; 486 } 487 488 ret = rte_pipeline_table_entry_add_bulk(p, table_id[i], 489 (void **)key_array, table_entries, 5, key_found, table_entries_ptr); 490 if (ret < 0) { 491 rte_panic("Add entry bulk to table %u failed (%d)\n", 492 table_id[i], ret); 493 goto fail; 494 } 495 } 496 497 /* Delete bulk entries from tables */ 498 for (i = 0; i < N_PORTS; i++) { 499 struct rte_table_acl_rule_delete_params keys[5]; 500 struct rte_table_acl_rule_delete_params *key_array[5]; 501 struct rte_pipeline_table_entry *table_entries[5]; 502 int key_found[5]; 503 504 memset(table_entries, 0, sizeof(table_entries)); 505 506 for (n = 0; n < 5; n++) { 507 memset(&keys[n], 0, sizeof(struct rte_table_acl_rule_delete_params)); 508 key_array[n] = &keys[n]; 509 510 strlcpy(line, lines[n], sizeof(line)); 511 printf("PARSING [%s]\n", line); 512 513 ret = parse_cb_ipv4_rule_del(line, &keys[n]); 514 if (ret != 0) { 515 fprintf(stderr, 516 "line %u: parse_cb_ipv4vlan_rule failed, error code: %d (%s)\n", 517 n, ret, strerror(-ret)); 518 return ret; 519 } 520 } 521 522 ret = rte_pipeline_table_entry_delete_bulk(p, table_id[i], 523 (void **)key_array, 5, key_found, table_entries); 524 if (ret < 0) { 525 rte_panic("Delete bulk entries from table %u failed (%d)\n", 526 table_id[i], ret); 527 goto fail; 528 } else 529 printf("Bulk deleted rules.\n"); 530 } 531 532 /* Add entries to tables */ 533 for (i = 0; i < N_PORTS; i++) { 534 struct rte_pipeline_table_entry table_entry = { 535 .action = RTE_PIPELINE_ACTION_PORT, 536 {.port_id = port_out_id[i^1]}, 537 }; 538 int key_found; 539 struct rte_pipeline_table_entry *entry_ptr; 540 541 memset(&rule_params, 0, sizeof(rule_params)); 542 parser = parse_cb_ipv4_rule; 543 544 for (n = 1; n <= 5; n++) { 545 strlcpy(line, lines[n - 1], sizeof(line)); 546 printf("PARSING [%s]\n", line); 547 548 ret = parser(line, &rule_params); 549 if (ret != 0) { 550 fprintf(stderr, 551 "line %u: parse_cb_ipv4vlan_rule failed, error code: %d (%s)\n", 552 n, ret, strerror(-ret)); 553 return ret; 554 } 555 556 rule_params.priority = RTE_ACL_MAX_PRIORITY - n; 557 558 ret = rte_pipeline_table_entry_add(p, table_id[i], 559 &rule_params, 560 &table_entry, &key_found, &entry_ptr); 561 if (ret < 0) { 562 rte_panic("Add entry to table %u failed (%d)\n", 563 table_id[i], ret); 564 goto fail; 565 } 566 } 567 568 /* delete a few rules */ 569 for (n = 2; n <= 3; n++) { 570 strlcpy(line, lines[n - 1], sizeof(line)); 571 printf("PARSING [%s]\n", line); 572 573 ret = parser(line, &rule_params); 574 if (ret != 0) { 575 fprintf(stderr, 576 "line %u: parse rule failed, error code: %d (%s)\n", 577 n, ret, strerror(-ret)); 578 return ret; 579 } 580 581 delete_params = (struct 582 rte_pipeline_table_acl_rule_delete_params *) 583 &(rule_params.field_value[0]); 584 ret = rte_pipeline_table_entry_delete(p, table_id[i], 585 delete_params, &key_found, NULL); 586 if (ret < 0) { 587 rte_panic("Add entry to table %u failed (%d)\n", 588 table_id[i], ret); 589 goto fail; 590 } else 591 printf("Deleted Rule.\n"); 592 } 593 594 595 /* Try to add duplicates */ 596 for (n = 1; n <= 5; n++) { 597 strlcpy(line, lines[n - 1], sizeof(line)); 598 printf("PARSING [%s]\n", line); 599 600 ret = parser(line, &rule_params); 601 if (ret != 0) { 602 fprintf(stderr, 603 "line %u: parse rule failed, error code: %d (%s)\n", 604 n, ret, strerror(-ret)); 605 return ret; 606 } 607 608 rule_params.priority = RTE_ACL_MAX_PRIORITY - n; 609 610 ret = rte_pipeline_table_entry_add(p, table_id[i], 611 &rule_params, 612 &table_entry, &key_found, &entry_ptr); 613 if (ret < 0) { 614 rte_panic("Add entry to table %u failed (%d)\n", 615 table_id[i], ret); 616 goto fail; 617 } 618 } 619 } 620 621 /* Enable input ports */ 622 for (i = 0; i < N_PORTS ; i++) 623 if (rte_pipeline_port_in_enable(p, port_in_id[i])) 624 rte_panic("Unable to enable input port %u\n", 625 port_in_id[i]); 626 627 /* Check pipeline consistency */ 628 if (rte_pipeline_check(p) < 0) { 629 rte_panic("Pipeline consistency check failed\n"); 630 goto fail; 631 } 632 633 return 0; 634 fail: 635 636 return -1; 637 } 638 639 static int 640 test_pipeline_single_filter(int expected_count) 641 { 642 int i, j, ret, tx_count; 643 struct ipv4_5tuple five_tuple; 644 645 /* Allocate a few mbufs and manually insert into the rings. */ 646 for (i = 0; i < N_PORTS; i++) { 647 for (j = 0; j < 8; j++) { 648 struct rte_mbuf *mbuf; 649 650 mbuf = rte_pktmbuf_alloc(pool); 651 if (mbuf == NULL) 652 /* this will cause test failure after cleanup 653 * of already enqueued mbufs, as the mbuf 654 * counts won't match */ 655 break; 656 memset(rte_pktmbuf_mtod(mbuf, char *), 0x00, 657 sizeof(struct ipv4_5tuple)); 658 659 five_tuple.proto = j; 660 five_tuple.ip_src = rte_bswap32(RTE_IPV4(192, 168, j, 1)); 661 five_tuple.ip_dst = rte_bswap32(RTE_IPV4(10, 4, j, 1)); 662 five_tuple.port_src = rte_bswap16(100 + j); 663 five_tuple.port_dst = rte_bswap16(200 + j); 664 665 memcpy(rte_pktmbuf_mtod(mbuf, char *), &five_tuple, 666 sizeof(struct ipv4_5tuple)); 667 printf("%s: Enqueue onto ring %d\n", 668 __func__, i); 669 rte_ring_enqueue(rings_rx[i], mbuf); 670 } 671 } 672 673 /* Run pipeline once */ 674 for (i = 0; i< N_PORTS; i++) 675 rte_pipeline_run(p); 676 677 rte_pipeline_flush(p); 678 679 tx_count = 0; 680 681 for (i = 0; i < N_PORTS; i++) { 682 void *objs[RING_TX_SIZE]; 683 struct rte_mbuf *mbuf; 684 685 ret = rte_ring_sc_dequeue_burst(rings_tx[i], objs, 10, NULL); 686 if (ret <= 0) { 687 printf("Got no objects from ring %d - error code %d\n", 688 i, ret); 689 } else { 690 printf("Got %d object(s) from ring %d!\n", ret, i); 691 for (j = 0; j < ret; j++) { 692 mbuf = objs[j]; 693 rte_hexdump(stdout, "mbuf", 694 rte_pktmbuf_mtod(mbuf, char *), 64); 695 rte_pktmbuf_free(mbuf); 696 } 697 tx_count += ret; 698 } 699 } 700 701 if (tx_count != expected_count) { 702 fprintf(stderr, 703 "%s: Unexpected packets for ACL test, expected %d, got %d\n", 704 __func__, expected_count, tx_count); 705 goto fail; 706 } 707 708 rte_pipeline_free(p); 709 710 return 0; 711 fail: 712 return -1; 713 714 } 715 716 int 717 test_table_acl(void) 718 { 719 720 721 override_hit_mask = 0xFF; /* All packets are a hit */ 722 723 setup_acl_pipeline(); 724 if (test_pipeline_single_filter(10) < 0) 725 return -1; 726 727 return 0; 728 } 729 730 #endif /* !RTE_EXEC_ENV_WINDOWS */ 731