doc: announce behaviour change to i40e RSS
[dpdk.git] / test / test / test_flow_classify.c
1 /*-
2  *   BSD LICENSE
3  *
4  *   Copyright(c) 2017 Intel Corporation. All rights reserved.
5  *   All rights reserved.
6  *
7  *   Redistribution and use in source and binary forms, with or without
8  *   modification, are permitted provided that the following conditions
9  *   are met:
10  *
11  *     * Redistributions of source code must retain the above copyright
12  *       notice, this list of conditions and the following disclaimer.
13  *     * Redistributions in binary form must reproduce the above copyright
14  *       notice, this list of conditions and the following disclaimer in
15  *       the documentation and/or other materials provided with the
16  *       distribution.
17  *     * Neither the name of Intel Corporation nor the names of its
18  *       contributors may be used to endorse or promote products derived
19  *       from this software without specific prior written permission.
20  *
21  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  */
33
34 #include <string.h>
35 #include <errno.h>
36
37 #include "test.h"
38
39 #include <rte_string_fns.h>
40 #include <rte_mbuf.h>
41 #include <rte_byteorder.h>
42 #include <rte_ip.h>
43 #include <rte_acl.h>
44 #include <rte_common.h>
45 #include <rte_table_acl.h>
46 #include <rte_flow.h>
47 #include <rte_flow_classify.h>
48
49 #include "packet_burst_generator.h"
50 #include "test_flow_classify.h"
51
52
53 #define FLOW_CLASSIFY_MAX_RULE_NUM 100
54 struct flow_classifier *cls;
55
56 struct flow_classifier {
57         struct rte_flow_classifier *cls;
58         uint32_t table_id[RTE_FLOW_CLASSIFY_TABLE_MAX];
59         uint32_t n_tables;
60 };
61
62 struct flow_classifier_acl {
63         struct flow_classifier cls;
64 } __rte_cache_aligned;
65
66 /*
67  * test functions by passing invalid or
68  * non-workable parameters.
69  */
70 static int
71 test_invalid_parameters(void)
72 {
73         struct rte_flow_classify_rule *rule;
74         int ret;
75
76         rule = rte_flow_classify_table_entry_add(NULL, 1, NULL, NULL, NULL,
77                         NULL, NULL);
78         if (rule) {
79                 printf("Line %i: flow_classifier_table_entry_add", __LINE__);
80                 printf(" with NULL param should have failed!\n");
81                 return -1;
82         }
83
84         ret = rte_flow_classify_table_entry_delete(NULL, 1, NULL);
85         if (!ret) {
86                 printf("Line %i: rte_flow_classify_table_entry_delete",
87                         __LINE__);
88                 printf(" with NULL param should have failed!\n");
89                 return -1;
90         }
91
92         ret = rte_flow_classifier_query(NULL, 1, NULL, 0, NULL, NULL);
93         if (!ret) {
94                 printf("Line %i: flow_classifier_query", __LINE__);
95                 printf(" with NULL param should have failed!\n");
96                 return -1;
97         }
98
99         rule = rte_flow_classify_table_entry_add(NULL, 1, NULL, NULL, NULL,
100                 NULL, &error);
101         if (rule) {
102                 printf("Line %i: flow_classify_table_entry_add ", __LINE__);
103                 printf("with NULL param should have failed!\n");
104                 return -1;
105         }
106
107         ret = rte_flow_classify_table_entry_delete(NULL, 1, NULL);
108         if (!ret) {
109                 printf("Line %i: rte_flow_classify_table_entry_delete",
110                         __LINE__);
111                 printf("with NULL param should have failed!\n");
112                 return -1;
113         }
114
115         ret = rte_flow_classifier_query(NULL, 1, NULL, 0, NULL, NULL);
116         if (!ret) {
117                 printf("Line %i: flow_classifier_query", __LINE__);
118                 printf(" with NULL param should have failed!\n");
119                 return -1;
120         }
121         return 0;
122 }
123
124 static int
125 test_valid_parameters(void)
126 {
127         struct rte_flow_classify_rule *rule;
128         int ret;
129         int key_found;
130
131         /*
132          * set up parameters for rte_flow_classify_table_entry_add and
133          * rte_flow_classify_table_entry_delete
134          */
135
136         attr.ingress = 1;
137         attr.priority = 1;
138         pattern[0] = eth_item;
139         pattern[1] = ipv4_udp_item_1;
140         pattern[2] = udp_item_1;
141         pattern[3] = end_item;
142         actions[0] = count_action;
143         actions[1] = end_action;
144
145         rule = rte_flow_classify_table_entry_add(cls->cls, 0, &key_found,
146                         &attr, pattern, actions, &error);
147         if (!rule) {
148                 printf("Line %i: flow_classify_table_entry_add", __LINE__);
149                 printf(" should not have failed!\n");
150                 return -1;
151         }
152
153         ret = rte_flow_classify_table_entry_delete(cls->cls, 0, rule);
154         if (ret) {
155                 printf("Line %i: rte_flow_classify_table_entry_delete",
156                         __LINE__);
157                 printf(" should not have failed!\n");
158                 return -1;
159         }
160         return 0;
161 }
162
163 static int
164 test_invalid_patterns(void)
165 {
166         struct rte_flow_classify_rule *rule;
167         int ret;
168         int key_found;
169
170         /*
171          * set up parameters for rte_flow_classify_table_entry_add and
172          * rte_flow_classify_table_entry_delete
173          */
174
175         attr.ingress = 1;
176         attr.priority = 1;
177         pattern[0] = eth_item_bad;
178         pattern[1] = ipv4_udp_item_1;
179         pattern[2] = udp_item_1;
180         pattern[3] = end_item;
181         actions[0] = count_action;
182         actions[1] = end_action;
183
184         pattern[0] = eth_item;
185         pattern[1] = ipv4_udp_item_bad;
186         rule = rte_flow_classify_table_entry_add(cls->cls, 0, &key_found,
187                         &attr, pattern, actions, &error);
188         if (rule) {
189                 printf("Line %i: flow_classify_table_entry_add", __LINE__);
190                 printf(" should have failed!\n");
191                 return -1;
192         }
193
194         ret = rte_flow_classify_table_entry_delete(cls->cls, 0, rule);
195         if (!ret) {
196                 printf("Line %i: rte_flow_classify_table_entry_delete",
197                         __LINE__);
198                 printf(" should have failed!\n");
199                 return -1;
200         }
201
202         pattern[1] = ipv4_udp_item_1;
203         pattern[2] = udp_item_bad;
204         pattern[3] = end_item_bad;
205         rule = rte_flow_classify_table_entry_add(cls->cls, 0, &key_found,
206                         &attr, pattern, actions, &error);
207         if (rule) {
208                 printf("Line %i: flow_classify_table_entry_add", __LINE__);
209                 printf(" should have failed!\n");
210                 return -1;
211         }
212
213         ret = rte_flow_classify_table_entry_delete(cls->cls, 0, rule);
214         if (!ret) {
215                 printf("Line %i: rte_flow_classify_table_entry_delete",
216                         __LINE__);
217                 printf(" should have failed!\n");
218                 return -1;
219         }
220         return 0;
221 }
222
223 static int
224 test_invalid_actions(void)
225 {
226         struct rte_flow_classify_rule *rule;
227         int ret;
228         int key_found;
229
230         /*
231          * set up parameters for rte_flow_classify_table_entry_add and
232          * rte_flow_classify_table_entry_delete
233          */
234
235         attr.ingress = 1;
236         attr.priority = 1;
237         pattern[0] = eth_item;
238         pattern[1] = ipv4_udp_item_1;
239         pattern[2] = udp_item_1;
240         pattern[3] = end_item;
241         actions[0] = count_action_bad;
242         actions[1] = end_action;
243
244         rule = rte_flow_classify_table_entry_add(cls->cls, 0, &key_found,
245                         &attr, pattern, actions, &error);
246         if (rule) {
247                 printf("Line %i: flow_classify_table_entry_add", __LINE__);
248                 printf(" should have failed!\n");
249                 return -1;
250         }
251
252         ret = rte_flow_classify_table_entry_delete(cls->cls, 0, rule);
253         if (!ret) {
254                 printf("Line %i: rte_flow_classify_table_entry_delete",
255                         __LINE__);
256                 printf(" should have failed!\n");
257                 return -1;
258         }
259
260         actions[0] = count_action;
261         actions[1] = end_action_bad;
262
263         rule = rte_flow_classify_table_entry_add(cls->cls, 0, &key_found,
264                         &attr, pattern, actions, &error);
265         if (rule) {
266                 printf("Line %i: flow_classify_table_entry_add", __LINE__);
267                 printf(" should have failed!\n");
268                 return -1;
269         }
270
271         ret = rte_flow_classify_table_entry_delete(cls->cls, 0, rule);
272         if (!ret) {
273                 printf("Line %i: rte_flow_classify_table_entry_delete",
274                         __LINE__);
275                 printf("should have failed!\n");
276                 return -1;
277         }
278         return 0;
279 }
280
281 static int
282 init_ipv4_udp_traffic(struct rte_mempool *mp,
283              struct rte_mbuf **pkts_burst, uint32_t burst_size)
284 {
285         struct ether_hdr pkt_eth_hdr;
286         struct ipv4_hdr pkt_ipv4_hdr;
287         struct udp_hdr pkt_udp_hdr;
288         uint32_t src_addr = IPV4_ADDR(2, 2, 2, 3);
289         uint32_t dst_addr = IPV4_ADDR(2, 2, 2, 7);
290         uint16_t src_port = 32;
291         uint16_t dst_port = 33;
292         uint16_t pktlen;
293
294         static uint8_t src_mac[] = { 0x00, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF };
295         static uint8_t dst_mac[] = { 0x00, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA };
296
297         printf("Set up IPv4 UDP traffic\n");
298         initialize_eth_header(&pkt_eth_hdr,
299                 (struct ether_addr *)src_mac,
300                 (struct ether_addr *)dst_mac, ETHER_TYPE_IPv4, 0, 0);
301         pktlen = (uint16_t)(sizeof(struct ether_hdr));
302         printf("ETH  pktlen %u\n", pktlen);
303
304         pktlen = initialize_ipv4_header(&pkt_ipv4_hdr, src_addr, dst_addr,
305                                         pktlen);
306         printf("ETH + IPv4 pktlen %u\n", pktlen);
307
308         pktlen = initialize_udp_header(&pkt_udp_hdr, src_port, dst_port,
309                                         pktlen);
310         printf("ETH + IPv4 + UDP pktlen %u\n\n", pktlen);
311
312         return generate_packet_burst(mp, pkts_burst, &pkt_eth_hdr,
313                                      0, &pkt_ipv4_hdr, 1,
314                                      &pkt_udp_hdr, burst_size,
315                                      PACKET_BURST_GEN_PKT_LEN, 1);
316 }
317
318 static int
319 init_ipv4_tcp_traffic(struct rte_mempool *mp,
320              struct rte_mbuf **pkts_burst, uint32_t burst_size)
321 {
322         struct ether_hdr pkt_eth_hdr;
323         struct ipv4_hdr pkt_ipv4_hdr;
324         struct tcp_hdr pkt_tcp_hdr;
325         uint32_t src_addr = IPV4_ADDR(1, 2, 3, 4);
326         uint32_t dst_addr = IPV4_ADDR(5, 6, 7, 8);
327         uint16_t src_port = 16;
328         uint16_t dst_port = 17;
329         uint16_t pktlen;
330
331         static uint8_t src_mac[] = { 0x00, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF };
332         static uint8_t dst_mac[] = { 0x00, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA };
333
334         printf("Set up IPv4 TCP traffic\n");
335         initialize_eth_header(&pkt_eth_hdr,
336                 (struct ether_addr *)src_mac,
337                 (struct ether_addr *)dst_mac, ETHER_TYPE_IPv4, 0, 0);
338         pktlen = (uint16_t)(sizeof(struct ether_hdr));
339         printf("ETH  pktlen %u\n", pktlen);
340
341         pktlen = initialize_ipv4_header_proto(&pkt_ipv4_hdr, src_addr,
342                                         dst_addr, pktlen, IPPROTO_TCP);
343         printf("ETH + IPv4 pktlen %u\n", pktlen);
344
345         pktlen = initialize_tcp_header(&pkt_tcp_hdr, src_port, dst_port,
346                                         pktlen);
347         printf("ETH + IPv4 + TCP pktlen %u\n\n", pktlen);
348
349         return generate_packet_burst_proto(mp, pkts_burst, &pkt_eth_hdr,
350                                         0, &pkt_ipv4_hdr, 1, IPPROTO_TCP,
351                                         &pkt_tcp_hdr, burst_size,
352                                         PACKET_BURST_GEN_PKT_LEN, 1);
353 }
354
355 static int
356 init_ipv4_sctp_traffic(struct rte_mempool *mp,
357              struct rte_mbuf **pkts_burst, uint32_t burst_size)
358 {
359         struct ether_hdr pkt_eth_hdr;
360         struct ipv4_hdr pkt_ipv4_hdr;
361         struct sctp_hdr pkt_sctp_hdr;
362         uint32_t src_addr = IPV4_ADDR(11, 12, 13, 14);
363         uint32_t dst_addr = IPV4_ADDR(15, 16, 17, 18);
364         uint16_t src_port = 10;
365         uint16_t dst_port = 11;
366         uint16_t pktlen;
367
368         static uint8_t src_mac[] = { 0x00, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF };
369         static uint8_t dst_mac[] = { 0x00, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA };
370
371         printf("Set up IPv4 SCTP traffic\n");
372         initialize_eth_header(&pkt_eth_hdr,
373                 (struct ether_addr *)src_mac,
374                 (struct ether_addr *)dst_mac, ETHER_TYPE_IPv4, 0, 0);
375         pktlen = (uint16_t)(sizeof(struct ether_hdr));
376         printf("ETH  pktlen %u\n", pktlen);
377
378         pktlen = initialize_ipv4_header_proto(&pkt_ipv4_hdr, src_addr,
379                                         dst_addr, pktlen, IPPROTO_SCTP);
380         printf("ETH + IPv4 pktlen %u\n", pktlen);
381
382         pktlen = initialize_sctp_header(&pkt_sctp_hdr, src_port, dst_port,
383                                         pktlen);
384         printf("ETH + IPv4 + SCTP pktlen %u\n\n", pktlen);
385
386         return generate_packet_burst_proto(mp, pkts_burst, &pkt_eth_hdr,
387                                         0, &pkt_ipv4_hdr, 1, IPPROTO_SCTP,
388                                         &pkt_sctp_hdr, burst_size,
389                                         PACKET_BURST_GEN_PKT_LEN, 1);
390 }
391
392 static int
393 init_mbufpool(void)
394 {
395         int socketid;
396         int ret = 0;
397         unsigned int lcore_id;
398         char s[64];
399
400         for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) {
401                 if (rte_lcore_is_enabled(lcore_id) == 0)
402                         continue;
403
404                 socketid = rte_lcore_to_socket_id(lcore_id);
405                 if (socketid >= NB_SOCKETS) {
406                         printf(
407                                 "Socket %d of lcore %u is out of range %d\n",
408                                 socketid, lcore_id, NB_SOCKETS);
409                         ret = -1;
410                         break;
411                 }
412                 if (mbufpool[socketid] == NULL) {
413                         snprintf(s, sizeof(s), "mbuf_pool_%d", socketid);
414                         mbufpool[socketid] =
415                                 rte_pktmbuf_pool_create(s, NB_MBUF,
416                                         MEMPOOL_CACHE_SIZE, 0, MBUF_SIZE,
417                                         socketid);
418                         if (mbufpool[socketid]) {
419                                 printf("Allocated mbuf pool on socket %d\n",
420                                         socketid);
421                         } else {
422                                 printf("Cannot init mbuf pool on socket %d\n",
423                                         socketid);
424                                 ret = -ENOMEM;
425                                 break;
426                         }
427                 }
428         }
429         return ret;
430 }
431
432 static int
433 test_query_udp(void)
434 {
435         struct rte_flow_error error;
436         struct rte_flow_classify_rule *rule;
437         int ret;
438         int i;
439         int key_found;
440
441         ret = init_ipv4_udp_traffic(mbufpool[0], bufs, MAX_PKT_BURST);
442         if (ret != MAX_PKT_BURST) {
443                 printf("Line %i: init_udp_ipv4_traffic has failed!\n",
444                                 __LINE__);
445                 return -1;
446         }
447
448         for (i = 0; i < MAX_PKT_BURST; i++)
449                 bufs[i]->packet_type = RTE_PTYPE_L3_IPV4;
450
451         /*
452          * set up parameters for rte_flow_classify_table_entry_add and
453          * rte_flow_classify_table_entry_delete
454          */
455
456         attr.ingress = 1;
457         attr.priority = 1;
458         pattern[0] = eth_item;
459         pattern[1] = ipv4_udp_item_1;
460         pattern[2] = udp_item_1;
461         pattern[3] = end_item;
462         actions[0] = count_action;
463         actions[1] = end_action;
464
465         rule = rte_flow_classify_table_entry_add(cls->cls, 0, &key_found,
466                         &attr, pattern, actions, &error);
467         if (!rule) {
468                 printf("Line %i: flow_classify_table_entry_add", __LINE__);
469                 printf(" should not have failed!\n");
470                 return -1;
471         }
472
473         ret = rte_flow_classifier_query(cls->cls, 0, bufs, MAX_PKT_BURST,
474                         rule, &udp_classify_stats);
475         if (ret) {
476                 printf("Line %i: flow_classifier_query", __LINE__);
477                 printf(" should not have failed!\n");
478                 return -1;
479         }
480
481         ret = rte_flow_classify_table_entry_delete(cls->cls, 0, rule);
482         if (ret) {
483                 printf("Line %i: rte_flow_classify_table_entry_delete",
484                         __LINE__);
485                 printf(" should not have failed!\n");
486                 return -1;
487         }
488         return 0;
489 }
490
491 static int
492 test_query_tcp(void)
493 {
494         struct rte_flow_classify_rule *rule;
495         int ret;
496         int i;
497         int key_found;
498
499         ret = init_ipv4_tcp_traffic(mbufpool[0], bufs, MAX_PKT_BURST);
500         if (ret != MAX_PKT_BURST) {
501                 printf("Line %i: init_ipv4_tcp_traffic has failed!\n",
502                                 __LINE__);
503                 return -1;
504         }
505
506         for (i = 0; i < MAX_PKT_BURST; i++)
507                 bufs[i]->packet_type = RTE_PTYPE_L3_IPV4;
508
509         /*
510          * set up parameters for rte_flow_classify_table_entry_add and
511          * rte_flow_classify_table_entry_delete
512          */
513
514         attr.ingress = 1;
515         attr.priority = 1;
516         pattern[0] = eth_item;
517         pattern[1] = ipv4_tcp_item_1;
518         pattern[2] = tcp_item_1;
519         pattern[3] = end_item;
520         actions[0] = count_action;
521         actions[1] = end_action;
522
523         rule = rte_flow_classify_table_entry_add(cls->cls, 0, &key_found,
524                         &attr, pattern, actions, &error);
525         if (!rule) {
526                 printf("Line %i: flow_classify_table_entry_add", __LINE__);
527                 printf(" should not have failed!\n");
528                 return -1;
529         }
530
531         ret = rte_flow_classifier_query(cls->cls, 0, bufs, MAX_PKT_BURST,
532                         rule, &tcp_classify_stats);
533         if (ret) {
534                 printf("Line %i: flow_classifier_query", __LINE__);
535                 printf(" should not have failed!\n");
536                 return -1;
537         }
538
539         ret = rte_flow_classify_table_entry_delete(cls->cls, 0, rule);
540         if (ret) {
541                 printf("Line %i: rte_flow_classify_table_entry_delete",
542                         __LINE__);
543                 printf(" should not have failed!\n");
544                 return -1;
545         }
546         return 0;
547 }
548
549 static int
550 test_query_sctp(void)
551 {
552         struct rte_flow_classify_rule *rule;
553         int ret;
554         int i;
555         int key_found;
556
557         ret = init_ipv4_sctp_traffic(mbufpool[0], bufs, MAX_PKT_BURST);
558         if (ret != MAX_PKT_BURST) {
559                 printf("Line %i: init_ipv4_tcp_traffic has failed!\n",
560                         __LINE__);
561                 return -1;
562         }
563
564         for (i = 0; i < MAX_PKT_BURST; i++)
565                 bufs[i]->packet_type = RTE_PTYPE_L3_IPV4;
566
567         /*
568          * set up parameters rte_flow_classify_table_entry_add and
569          * rte_flow_classify_table_entry_delete
570          */
571
572         attr.ingress = 1;
573         attr.priority = 1;
574         pattern[0] = eth_item;
575         pattern[1] = ipv4_sctp_item_1;
576         pattern[2] = sctp_item_1;
577         pattern[3] = end_item;
578         actions[0] = count_action;
579         actions[1] = end_action;
580
581         rule = rte_flow_classify_table_entry_add(cls->cls, 0, &key_found,
582                         &attr, pattern, actions, &error);
583         if (!rule) {
584                 printf("Line %i: flow_classify_table_entry_add", __LINE__);
585                 printf(" should not have failed!\n");
586                 return -1;
587         }
588
589         ret = rte_flow_classifier_query(cls->cls, 0, bufs, MAX_PKT_BURST,
590                         rule, &sctp_classify_stats);
591         if (ret) {
592                 printf("Line %i: flow_classifier_query", __LINE__);
593                 printf(" should not have failed!\n");
594                 return -1;
595         }
596
597         ret = rte_flow_classify_table_entry_delete(cls->cls, 0, rule);
598         if (ret) {
599                 printf("Line %i: rte_flow_classify_table_entry_delete",
600                         __LINE__);
601                 printf(" should not have failed!\n");
602                 return -1;
603         }
604         return 0;
605 }
606
607 static int
608 test_flow_classify(void)
609 {
610         struct rte_table_acl_params table_acl_params;
611         struct rte_flow_classify_table_params cls_table_params;
612         struct rte_flow_classifier_params cls_params;
613         int socket_id;
614         int ret;
615         uint32_t size;
616
617         socket_id = rte_eth_dev_socket_id(0);
618
619         /* Memory allocation */
620         size = RTE_CACHE_LINE_ROUNDUP(sizeof(struct flow_classifier_acl));
621         cls = rte_zmalloc(NULL, size, RTE_CACHE_LINE_SIZE);
622
623         cls_params.name = "flow_classifier";
624         cls_params.socket_id = socket_id;
625         cls_params.type = RTE_FLOW_CLASSIFY_TABLE_TYPE_ACL;
626         cls->cls = rte_flow_classifier_create(&cls_params);
627
628         /* initialise ACL table params */
629         table_acl_params.n_rule_fields = RTE_DIM(ipv4_defs);
630         table_acl_params.name = "table_acl_ipv4_5tuple";
631         table_acl_params.n_rules = FLOW_CLASSIFY_MAX_RULE_NUM;
632         memcpy(table_acl_params.field_format, ipv4_defs, sizeof(ipv4_defs));
633
634         /* initialise table create params */
635         cls_table_params.ops = &rte_table_acl_ops,
636         cls_table_params.arg_create = &table_acl_params,
637
638         ret = rte_flow_classify_table_create(cls->cls, &cls_table_params,
639                         &cls->table_id[0]);
640         if (ret) {
641                 printf("Line %i: f_create has failed!\n", __LINE__);
642                 rte_flow_classifier_free(cls->cls);
643                 rte_free(cls);
644                 return -1;
645         }
646         printf("Created table_acl for for IPv4 five tuple packets\n");
647
648         ret = init_mbufpool();
649         if (ret) {
650                 printf("Line %i: init_mbufpool has failed!\n", __LINE__);
651                 return -1;
652         }
653
654         if (test_invalid_parameters() < 0)
655                 return -1;
656         if (test_valid_parameters() < 0)
657                 return -1;
658         if (test_invalid_patterns() < 0)
659                 return -1;
660         if (test_invalid_actions() < 0)
661                 return -1;
662         if (test_query_udp() < 0)
663                 return -1;
664         if (test_query_tcp() < 0)
665                 return -1;
666         if (test_query_sctp() < 0)
667                 return -1;
668
669         return 0;
670 }
671
672 REGISTER_TEST_COMMAND(flow_classify_autotest, test_flow_classify);