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