app/test: convert all tests to register system
[dpdk.git] / app / test / test_acl.c
1 /*-
2  *   BSD LICENSE
3  *
4  *   Copyright(c) 2010-2014 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 #ifdef RTE_LIBRTE_ACL
40
41 #include <rte_string_fns.h>
42 #include <rte_mbuf.h>
43 #include <rte_byteorder.h>
44 #include <rte_ip.h>
45 #include <rte_acl.h>
46 #include <rte_common.h>
47
48 #include "test_acl.h"
49
50 #define LEN RTE_ACL_MAX_CATEGORIES
51
52 struct rte_acl_param acl_param = {
53         .name = "acl_ctx",
54         .socket_id = SOCKET_ID_ANY,
55         .rule_size = RTE_ACL_IPV4VLAN_RULE_SZ,
56         .max_rule_num = 0x30000,
57 };
58
59 struct rte_acl_ipv4vlan_rule acl_rule = {
60                 .data = { .priority = 1, .category_mask = 0xff },
61                 .src_port_low = 0,
62                 .src_port_high = UINT16_MAX,
63                 .dst_port_low = 0,
64                 .dst_port_high = UINT16_MAX,
65 };
66
67 /* byteswap to cpu or network order */
68 static void
69 bswap_test_data(struct ipv4_7tuple *data, int len, int to_be)
70 {
71         int i;
72
73         for (i = 0; i < len; i++) {
74
75                 if (to_be) {
76                         /* swap all bytes so that they are in network order */
77                         data[i].ip_dst = rte_cpu_to_be_32(data[i].ip_dst);
78                         data[i].ip_src = rte_cpu_to_be_32(data[i].ip_src);
79                         data[i].port_dst = rte_cpu_to_be_16(data[i].port_dst);
80                         data[i].port_src = rte_cpu_to_be_16(data[i].port_src);
81                         data[i].vlan = rte_cpu_to_be_16(data[i].vlan);
82                         data[i].domain = rte_cpu_to_be_16(data[i].domain);
83                 } else {
84                         data[i].ip_dst = rte_be_to_cpu_32(data[i].ip_dst);
85                         data[i].ip_src = rte_be_to_cpu_32(data[i].ip_src);
86                         data[i].port_dst = rte_be_to_cpu_16(data[i].port_dst);
87                         data[i].port_src = rte_be_to_cpu_16(data[i].port_src);
88                         data[i].vlan = rte_be_to_cpu_16(data[i].vlan);
89                         data[i].domain = rte_be_to_cpu_16(data[i].domain);
90                 }
91         }
92 }
93
94 /*
95  * Test scalar and SSE ACL lookup.
96  */
97 static int
98 test_classify_run(struct rte_acl_ctx *acx)
99 {
100         int ret, i;
101         uint32_t result, count;
102         uint32_t results[RTE_DIM(acl_test_data) * RTE_ACL_MAX_CATEGORIES];
103         const uint8_t *data[RTE_DIM(acl_test_data)];
104
105         /* swap all bytes in the data to network order */
106         bswap_test_data(acl_test_data, RTE_DIM(acl_test_data), 1);
107
108         /* store pointers to test data */
109         for (i = 0; i < (int) RTE_DIM(acl_test_data); i++)
110                 data[i] = (uint8_t *)&acl_test_data[i];
111
112         /**
113          * these will run quite a few times, it's necessary to test code paths
114          * from num=0 to num>8
115          */
116         for (count = 0; count < RTE_DIM(acl_test_data); count++) {
117                 ret = rte_acl_classify(acx, data, results,
118                                 count, RTE_ACL_MAX_CATEGORIES);
119                 if (ret != 0) {
120                         printf("Line %i: SSE classify failed!\n", __LINE__);
121                         goto err;
122                 }
123
124                 /* check if we allow everything we should allow */
125                 for (i = 0; i < (int) count; i++) {
126                         result =
127                                 results[i * RTE_ACL_MAX_CATEGORIES + ACL_ALLOW];
128                         if (result != acl_test_data[i].allow) {
129                                 printf("Line %i: Error in allow results at %i "
130                                         "(expected %"PRIu32" got %"PRIu32")!\n",
131                                         __LINE__, i, acl_test_data[i].allow,
132                                         result);
133                                 goto err;
134                         }
135                 }
136
137                 /* check if we deny everything we should deny */
138                 for (i = 0; i < (int) count; i++) {
139                         result = results[i * RTE_ACL_MAX_CATEGORIES + ACL_DENY];
140                         if (result != acl_test_data[i].deny) {
141                                 printf("Line %i: Error in deny results at %i "
142                                         "(expected %"PRIu32" got %"PRIu32")!\n",
143                                         __LINE__, i, acl_test_data[i].deny,
144                                         result);
145                                 goto err;
146                         }
147                 }
148         }
149
150         /* make a quick check for scalar */
151         ret = rte_acl_classify_scalar(acx, data, results,
152                         RTE_DIM(acl_test_data), RTE_ACL_MAX_CATEGORIES);
153         if (ret != 0) {
154                 printf("Line %i: SSE classify failed!\n", __LINE__);
155                 goto err;
156         }
157
158         /* check if we allow everything we should allow */
159         for (i = 0; i < (int) RTE_DIM(acl_test_data); i++) {
160                 result = results[i * RTE_ACL_MAX_CATEGORIES + ACL_ALLOW];
161                 if (result != acl_test_data[i].allow) {
162                         printf("Line %i: Error in allow results at %i "
163                                         "(expected %"PRIu32" got %"PRIu32")!\n",
164                                         __LINE__, i, acl_test_data[i].allow,
165                                         result);
166                         goto err;
167                 }
168         }
169
170         /* check if we deny everything we should deny */
171         for (i = 0; i < (int) RTE_DIM(acl_test_data); i++) {
172                 result = results[i * RTE_ACL_MAX_CATEGORIES + ACL_DENY];
173                 if (result != acl_test_data[i].deny) {
174                         printf("Line %i: Error in deny results at %i "
175                                         "(expected %"PRIu32" got %"PRIu32")!\n",
176                                         __LINE__, i, acl_test_data[i].deny,
177                                         result);
178                         goto err;
179                 }
180         }
181
182         ret = 0;
183
184 err:
185         /* swap data back to cpu order so that next time tests don't fail */
186         bswap_test_data(acl_test_data, RTE_DIM(acl_test_data), 0);
187         return ret;
188 }
189
190 static int
191 test_classify_buid(struct rte_acl_ctx *acx)
192 {
193         int ret;
194         const uint32_t layout[RTE_ACL_IPV4VLAN_NUM] = {
195                         offsetof(struct ipv4_7tuple, proto),
196                         offsetof(struct ipv4_7tuple, vlan),
197                         offsetof(struct ipv4_7tuple, ip_src),
198                         offsetof(struct ipv4_7tuple, ip_dst),
199                         offsetof(struct ipv4_7tuple, port_src),
200         };
201
202         /* add rules to the context */
203         ret = rte_acl_ipv4vlan_add_rules(acx, acl_test_rules,
204                         RTE_DIM(acl_test_rules));
205         if (ret != 0) {
206                 printf("Line %i: Adding rules to ACL context failed!\n",
207                         __LINE__);
208                 return ret;
209         }
210
211         /* try building the context */
212         ret = rte_acl_ipv4vlan_build(acx, layout, RTE_ACL_MAX_CATEGORIES);
213         if (ret != 0) {
214                 printf("Line %i: Building ACL context failed!\n", __LINE__);
215                 return ret;
216         }
217
218         return 0;
219 }
220
221 #define TEST_CLASSIFY_ITER      4
222
223 /*
224  * Test scalar and SSE ACL lookup.
225  */
226 static int
227 test_classify(void)
228 {
229         struct rte_acl_ctx *acx;
230         int i, ret;
231
232         acx = rte_acl_create(&acl_param);
233         if (acx == NULL) {
234                 printf("Line %i: Error creating ACL context!\n", __LINE__);
235                 return -1;
236         }
237
238         ret = 0;
239         for (i = 0; i != TEST_CLASSIFY_ITER; i++) {
240
241                 if ((i & 1) == 0)
242                         rte_acl_reset(acx);
243                 else
244                         rte_acl_reset_rules(acx);
245
246                 ret = test_classify_buid(acx);
247                 if (ret != 0) {
248                         printf("Line %i, iter: %d: "
249                                 "Adding rules to ACL context failed!\n",
250                                 __LINE__, i);
251                         break;
252                 }
253
254                 ret = test_classify_run(acx);
255                 if (ret != 0) {
256                         printf("Line %i, iter: %d: %s failed!\n",
257                                 __LINE__, i, __func__);
258                         break;
259                 }
260
261                 /* reset rules and make sure that classify still works ok. */
262                 rte_acl_reset_rules(acx);
263                 ret = test_classify_run(acx);
264                 if (ret != 0) {
265                         printf("Line %i, iter: %d: %s failed!\n",
266                                 __LINE__, i, __func__);
267                         break;
268                 }
269         }
270
271         rte_acl_free(acx);
272         return ret;
273 }
274
275 /*
276  * Test wrong layout behavior
277  * This test supplies the ACL context with invalid layout, which results in
278  * ACL matching the wrong stuff. However, it should match the wrong stuff
279  * the right way. We switch around source and destination addresses,
280  * source and destination ports, and protocol will point to first byte of
281  * destination port.
282  */
283 static int
284 test_invalid_layout(void)
285 {
286         struct rte_acl_ctx *acx;
287         int ret, i;
288
289         uint32_t results[RTE_DIM(invalid_layout_data)];
290         const uint8_t *data[RTE_DIM(invalid_layout_data)];
291
292         const uint32_t layout[RTE_ACL_IPV4VLAN_NUM] = {
293                         /* proto points to destination port's first byte */
294                         offsetof(struct ipv4_7tuple, port_dst),
295
296                         0, /* VLAN not used */
297
298                         /* src and dst addresses are swapped */
299                         offsetof(struct ipv4_7tuple, ip_dst),
300                         offsetof(struct ipv4_7tuple, ip_src),
301
302                         /*
303                          * we can't swap ports here, so we will swap
304                          * them in the data
305                          */
306                         offsetof(struct ipv4_7tuple, port_src),
307         };
308
309         acx = rte_acl_create(&acl_param);
310         if (acx == NULL) {
311                 printf("Line %i: Error creating ACL context!\n", __LINE__);
312                 return -1;
313         }
314
315         /* putting a lot of rules into the context results in greater
316          * coverage numbers. it doesn't matter if they are identical */
317         for (i = 0; i < 1000; i++) {
318                 /* add rules to the context */
319                 ret = rte_acl_ipv4vlan_add_rules(acx, invalid_layout_rules,
320                                 RTE_DIM(invalid_layout_rules));
321                 if (ret != 0) {
322                         printf("Line %i: Adding rules to ACL context failed!\n",
323                                 __LINE__);
324                         rte_acl_free(acx);
325                         return -1;
326                 }
327         }
328
329         /* try building the context */
330         ret = rte_acl_ipv4vlan_build(acx, layout, 1);
331         if (ret != 0) {
332                 printf("Line %i: Building ACL context failed!\n", __LINE__);
333                 rte_acl_free(acx);
334                 return -1;
335         }
336
337         /* swap all bytes in the data to network order */
338         bswap_test_data(invalid_layout_data, RTE_DIM(invalid_layout_data), 1);
339
340         /* prepare data */
341         for (i = 0; i < (int) RTE_DIM(invalid_layout_data); i++) {
342                 data[i] = (uint8_t *)&invalid_layout_data[i];
343         }
344
345         /* classify tuples */
346         ret = rte_acl_classify(acx, data, results,
347                         RTE_DIM(results), 1);
348         if (ret != 0) {
349                 printf("Line %i: SSE classify failed!\n", __LINE__);
350                 rte_acl_free(acx);
351                 return -1;
352         }
353
354         for (i = 0; i < (int) RTE_DIM(results); i++) {
355                 if (results[i] != invalid_layout_data[i].allow) {
356                         printf("Line %i: Wrong results at %i "
357                                 "(result=%u, should be %u)!\n",
358                                 __LINE__, i, results[i],
359                                 invalid_layout_data[i].allow);
360                         goto err;
361                 }
362         }
363
364         /* classify tuples (scalar) */
365         ret = rte_acl_classify_scalar(acx, data, results,
366                         RTE_DIM(results), 1);
367         if (ret != 0) {
368                 printf("Line %i: Scalar classify failed!\n", __LINE__);
369                 rte_acl_free(acx);
370                 return -1;
371         }
372
373         for (i = 0; i < (int) RTE_DIM(results); i++) {
374                 if (results[i] != invalid_layout_data[i].allow) {
375                         printf("Line %i: Wrong results at %i "
376                                 "(result=%u, should be %u)!\n",
377                                 __LINE__, i, results[i],
378                                 invalid_layout_data[i].allow);
379                         goto err;
380                 }
381         }
382
383         rte_acl_free(acx);
384
385         /* swap data back to cpu order so that next time tests don't fail */
386         bswap_test_data(invalid_layout_data, RTE_DIM(invalid_layout_data), 0);
387
388         return 0;
389 err:
390
391         /* swap data back to cpu order so that next time tests don't fail */
392         bswap_test_data(invalid_layout_data, RTE_DIM(invalid_layout_data), 0);
393
394         rte_acl_free(acx);
395
396         return -1;
397 }
398
399 /*
400  * Test creating and finding ACL contexts, and adding rules
401  */
402 static int
403 test_create_find_add(void)
404 {
405         struct rte_acl_param param;
406         struct rte_acl_ctx *acx, *acx2, *tmp;
407         struct rte_acl_ipv4vlan_rule rules[LEN];
408
409         const uint32_t layout[RTE_ACL_IPV4VLAN_NUM] = {0};
410
411         const char *acx_name = "acx";
412         const char *acx2_name = "acx2";
413         int i, ret;
414
415         /* create two contexts */
416         memcpy(&param, &acl_param, sizeof(param));
417         param.max_rule_num = 2;
418
419         param.name = acx_name;
420         acx = rte_acl_create(&param);
421         if (acx == NULL) {
422                 printf("Line %i: Error creating %s!\n", __LINE__, acx_name);
423                 return -1;
424         }
425
426         param.name = acx2_name;
427         acx2 = rte_acl_create(&param);
428         if (acx2 == NULL || acx2 == acx) {
429                 printf("Line %i: Error creating %s!\n", __LINE__, acx2_name);
430                 rte_acl_free(acx);
431                 return -1;
432         }
433
434         /* try to create third one, with an existing name */
435         param.name = acx_name;
436         tmp = rte_acl_create(&param);
437         if (tmp != acx) {
438                 printf("Line %i: Creating context with existing name "
439                         "test failed!\n",
440                         __LINE__);
441                 if (tmp)
442                         rte_acl_free(tmp);
443                 goto err;
444         }
445
446         param.name = acx2_name;
447         tmp = rte_acl_create(&param);
448         if (tmp != acx2) {
449                 printf("Line %i: Creating context with existing "
450                         "name test 2 failed!\n",
451                         __LINE__);
452                 if (tmp)
453                         rte_acl_free(tmp);
454                 goto err;
455         }
456
457         /* try to find existing ACL contexts */
458         tmp = rte_acl_find_existing(acx_name);
459         if (tmp != acx) {
460                 printf("Line %i: Finding %s failed!\n", __LINE__, acx_name);
461                 if (tmp)
462                         rte_acl_free(tmp);
463                 goto err;
464         }
465
466         tmp = rte_acl_find_existing(acx2_name);
467         if (tmp != acx2) {
468                 printf("Line %i: Finding %s failed!\n", __LINE__, acx2_name);
469                 if (tmp)
470                         rte_acl_free(tmp);
471                 goto err;
472         }
473
474         /* try to find non-existing context */
475         tmp = rte_acl_find_existing("invalid");
476         if (tmp != NULL) {
477                 printf("Line %i: Non-existent ACL context found!\n", __LINE__);
478                 goto err;
479         }
480
481         /* free context */
482         rte_acl_free(acx);
483
484
485         /* create valid (but severely limited) acx */
486         memcpy(&param, &acl_param, sizeof(param));
487         param.max_rule_num = LEN;
488
489         acx = rte_acl_create(&param);
490         if (acx == NULL) {
491                 printf("Line %i: Error creating %s!\n", __LINE__, param.name);
492                 goto err;
493         }
494
495         /* create dummy acl */
496         for (i = 0; i < LEN; i++) {
497                 memcpy(&rules[i], &acl_rule,
498                         sizeof(struct rte_acl_ipv4vlan_rule));
499                 /* skip zero */
500                 rules[i].data.userdata = i + 1;
501                 /* one rule per category */
502                 rules[i].data.category_mask = 1 << i;
503         }
504
505         /* try filling up the context */
506         ret = rte_acl_ipv4vlan_add_rules(acx, rules, LEN);
507         if (ret != 0) {
508                 printf("Line %i: Adding %i rules to ACL context failed!\n",
509                                 __LINE__, LEN);
510                 goto err;
511         }
512
513         /* try adding to a (supposedly) full context */
514         ret = rte_acl_ipv4vlan_add_rules(acx, rules, 1);
515         if (ret == 0) {
516                 printf("Line %i: Adding rules to full ACL context should"
517                                 "have failed!\n", __LINE__);
518                 goto err;
519         }
520
521         /* try building the context */
522         ret = rte_acl_ipv4vlan_build(acx, layout, RTE_ACL_MAX_CATEGORIES);
523         if (ret != 0) {
524                 printf("Line %i: Building ACL context failed!\n", __LINE__);
525                 goto err;
526         }
527
528         rte_acl_free(acx);
529         rte_acl_free(acx2);
530
531         return 0;
532 err:
533         rte_acl_free(acx);
534         rte_acl_free(acx2);
535         return -1;
536 }
537
538 /*
539  * test various invalid rules
540  */
541 static int
542 test_invalid_rules(void)
543 {
544         struct rte_acl_ctx *acx;
545         int ret;
546
547         struct rte_acl_ipv4vlan_rule rule;
548
549         acx = rte_acl_create(&acl_param);
550         if (acx == NULL) {
551                 printf("Line %i: Error creating ACL context!\n", __LINE__);
552                 return -1;
553         }
554
555         /* test inverted high/low source and destination ports.
556          * originally, there was a problem with memory consumption when using
557          * such rules.
558          */
559         /* create dummy acl */
560         memcpy(&rule, &acl_rule, sizeof(struct rte_acl_ipv4vlan_rule));
561         rule.data.userdata = 1;
562         rule.dst_port_low = 0xfff0;
563         rule.dst_port_high = 0x0010;
564
565         /* add rules to context and try to build it */
566         ret = rte_acl_ipv4vlan_add_rules(acx, &rule, 1);
567         if (ret == 0) {
568                 printf("Line %i: Adding rules to ACL context "
569                                 "should have failed!\n", __LINE__);
570                 goto err;
571         }
572
573         rule.dst_port_low = 0x0;
574         rule.dst_port_high = 0xffff;
575         rule.src_port_low = 0xfff0;
576         rule.src_port_high = 0x0010;
577
578         /* add rules to context and try to build it */
579         ret = rte_acl_ipv4vlan_add_rules(acx, &rule, 1);
580         if (ret == 0) {
581                 printf("Line %i: Adding rules to ACL context "
582                                 "should have failed!\n", __LINE__);
583                 goto err;
584         }
585
586         rule.dst_port_low = 0x0;
587         rule.dst_port_high = 0xffff;
588         rule.src_port_low = 0x0;
589         rule.src_port_high = 0xffff;
590
591         rule.dst_mask_len = 33;
592
593         /* add rules to context and try to build it */
594         ret = rte_acl_ipv4vlan_add_rules(acx, &rule, 1);
595         if (ret == 0) {
596                 printf("Line %i: Adding rules to ACL context "
597                                 "should have failed!\n", __LINE__);
598                 goto err;
599         }
600
601         rule.dst_mask_len = 0;
602         rule.src_mask_len = 33;
603
604         /* add rules to context and try to build it */
605         ret = rte_acl_ipv4vlan_add_rules(acx, &rule, 1);
606         if (ret == 0) {
607                 printf("Line %i: Adding rules to ACL context "
608                                 "should have failed!\n", __LINE__);
609                 goto err;
610         }
611
612         rule.dst_mask_len = 0;
613         rule.src_mask_len = 0;
614         rule.data.userdata = 0;
615
616         /* try adding this rule (it should fail because userdata is invalid) */
617         ret = rte_acl_ipv4vlan_add_rules(acx, &rule, 1);
618         if (ret == 0) {
619                 printf("Line %i: Adding a rule with invalid user data "
620                                 "should have failed!\n", __LINE__);
621                 rte_acl_free(acx);
622                 return -1;
623         }
624
625         rte_acl_free(acx);
626
627         return 0;
628
629 err:
630         rte_acl_free(acx);
631
632         return -1;
633 }
634
635 /*
636  * test functions by passing invalid or
637  * non-workable parameters.
638  *
639  * we do very limited testing of classify functions here
640  * because those are performance-critical and
641  * thus don't do much parameter checking.
642  */
643 static int
644 test_invalid_parameters(void)
645 {
646         struct rte_acl_param param;
647         struct rte_acl_ctx *acx;
648         struct rte_acl_ipv4vlan_rule rule;
649         int result;
650
651         uint32_t layout[RTE_ACL_IPV4VLAN_NUM] = {0};
652
653
654         /**
655          * rte_ac_create()
656          */
657
658         /* NULL param */
659         acx = rte_acl_create(NULL);
660         if (acx != NULL) {
661                 printf("Line %i: ACL context creation with NULL param "
662                                 "should have failed!\n", __LINE__);
663                 rte_acl_free(acx);
664                 return -1;
665         }
666
667         /* zero rule size */
668         memcpy(&param, &acl_param, sizeof(param));
669         param.rule_size = 0;
670
671         acx = rte_acl_create(&param);
672         if (acx == NULL) {
673                 printf("Line %i: ACL context creation with zero rule len "
674                                 "failed!\n", __LINE__);
675                 return -1;
676         } else
677                 rte_acl_free(acx);
678
679         /* zero max rule num */
680         memcpy(&param, &acl_param, sizeof(param));
681         param.max_rule_num = 0;
682
683         acx = rte_acl_create(&param);
684         if (acx == NULL) {
685                 printf("Line %i: ACL context creation with zero rule num "
686                                 "failed!\n", __LINE__);
687                 return -1;
688         } else
689                 rte_acl_free(acx);
690
691         /* invalid NUMA node */
692         memcpy(&param, &acl_param, sizeof(param));
693         param.socket_id = RTE_MAX_NUMA_NODES + 1;
694
695         acx = rte_acl_create(&param);
696         if (acx != NULL) {
697                 printf("Line %i: ACL context creation with invalid NUMA "
698                                 "should have failed!\n", __LINE__);
699                 rte_acl_free(acx);
700                 return -1;
701         }
702
703         /* NULL name */
704         memcpy(&param, &acl_param, sizeof(param));
705         param.name = NULL;
706
707         acx = rte_acl_create(&param);
708         if (acx != NULL) {
709                 printf("Line %i: ACL context creation with NULL name "
710                                 "should have failed!\n", __LINE__);
711                 rte_acl_free(acx);
712                 return -1;
713         }
714
715         /**
716          * rte_acl_find_existing
717          */
718
719         acx = rte_acl_find_existing(NULL);
720         if (acx != NULL) {
721                 printf("Line %i: NULL ACL context found!\n", __LINE__);
722                 rte_acl_free(acx);
723                 return -1;
724         }
725
726         /**
727          * rte_acl_ipv4vlan_add_rules
728          */
729
730         /* initialize everything */
731         memcpy(&param, &acl_param, sizeof(param));
732         acx = rte_acl_create(&param);
733         if (acx == NULL) {
734                 printf("Line %i: ACL context creation failed!\n", __LINE__);
735                 return -1;
736         }
737
738         memcpy(&rule, &acl_rule, sizeof(rule));
739
740         /* NULL context */
741         result = rte_acl_ipv4vlan_add_rules(NULL, &rule, 1);
742         if (result == 0) {
743                 printf("Line %i: Adding rules with NULL ACL context "
744                                 "should have failed!\n", __LINE__);
745                 rte_acl_free(acx);
746                 return -1;
747         }
748
749         /* NULL rule */
750         result = rte_acl_ipv4vlan_add_rules(acx, NULL, 1);
751         if (result == 0) {
752                 printf("Line %i: Adding NULL rule to ACL context "
753                                 "should have failed!\n", __LINE__);
754                 rte_acl_free(acx);
755                 return -1;
756         }
757
758         /* zero count (should succeed) */
759         result = rte_acl_ipv4vlan_add_rules(acx, &rule, 0);
760         if (result != 0) {
761                 printf("Line %i: Adding 0 rules to ACL context failed!\n",
762                         __LINE__);
763                 rte_acl_free(acx);
764                 return -1;
765         }
766
767         /* free ACL context */
768         rte_acl_free(acx);
769
770         /* set wrong rule_size so that adding any rules would fail */
771         param.rule_size = RTE_ACL_IPV4VLAN_RULE_SZ + 4;
772         acx = rte_acl_create(&param);
773         if (acx == NULL) {
774                 printf("Line %i: ACL context creation failed!\n", __LINE__);
775                 return -1;
776         }
777
778         /* try adding a rule with size different from context rule_size */
779         result = rte_acl_ipv4vlan_add_rules(acx, &rule, 1);
780         if (result == 0) {
781                 printf("Line %i: Adding an invalid sized rule "
782                                 "should have failed!\n", __LINE__);
783                 rte_acl_free(acx);
784                 return -1;
785         }
786
787         /* free ACL context */
788         rte_acl_free(acx);
789
790
791         /**
792          * rte_acl_ipv4vlan_build
793          */
794
795         /* reinitialize context */
796         memcpy(&param, &acl_param, sizeof(param));
797         acx = rte_acl_create(&param);
798         if (acx == NULL) {
799                 printf("Line %i: ACL context creation failed!\n", __LINE__);
800                 return -1;
801         }
802
803         /* NULL context */
804         result = rte_acl_ipv4vlan_build(NULL, layout, 1);
805         if (result == 0) {
806                 printf("Line %i: Building with NULL context "
807                                 "should have failed!\n", __LINE__);
808                 rte_acl_free(acx);
809                 return -1;
810         }
811
812         /* NULL layout */
813         result = rte_acl_ipv4vlan_build(acx, NULL, 1);
814         if (result == 0) {
815                 printf("Line %i: Building with NULL layout "
816                                 "should have failed!\n", __LINE__);
817                 rte_acl_free(acx);
818                 return -1;
819         }
820
821         /* zero categories (should not fail) */
822         result = rte_acl_ipv4vlan_build(acx, layout, 0);
823         if (result == 0) {
824                 printf("Line %i: Building with 0 categories should fail!\n",
825                         __LINE__);
826                 rte_acl_free(acx);
827                 return -1;
828         }
829
830         /* SSE classify test */
831
832         /* cover zero categories in classify (should not fail) */
833         result = rte_acl_classify(acx, NULL, NULL, 0, 0);
834         if (result != 0) {
835                 printf("Line %i: SSE classify with zero categories "
836                                 "failed!\n", __LINE__);
837                 rte_acl_free(acx);
838                 return -1;
839         }
840
841         /* cover invalid but positive categories in classify */
842         result = rte_acl_classify(acx, NULL, NULL, 0, 3);
843         if (result == 0) {
844                 printf("Line %i: SSE classify with 3 categories "
845                                 "should have failed!\n", __LINE__);
846                 rte_acl_free(acx);
847                 return -1;
848         }
849
850         /* scalar classify test */
851
852         /* cover zero categories in classify (should not fail) */
853         result = rte_acl_classify_scalar(acx, NULL, NULL, 0, 0);
854         if (result != 0) {
855                 printf("Line %i: Scalar classify with zero categories "
856                                 "failed!\n", __LINE__);
857                 rte_acl_free(acx);
858                 return -1;
859         }
860
861         /* cover invalid but positive categories in classify */
862         result = rte_acl_classify_scalar(acx, NULL, NULL, 0, 3);
863         if (result == 0) {
864                 printf("Line %i: Scalar classify with 3 categories "
865                                 "should have failed!\n", __LINE__);
866                 rte_acl_free(acx);
867                 return -1;
868         }
869
870         /* free ACL context */
871         rte_acl_free(acx);
872
873
874         /**
875          * make sure void functions don't crash with NULL parameters
876          */
877
878         rte_acl_free(NULL);
879
880         rte_acl_dump(NULL);
881
882         return 0;
883 }
884
885 /**
886  * Various tests that don't test much but improve coverage
887  */
888 static int
889 test_misc(void)
890 {
891         struct rte_acl_param param;
892         struct rte_acl_ctx *acx;
893
894         /* create context */
895         memcpy(&param, &acl_param, sizeof(param));
896
897         acx = rte_acl_create(&param);
898         if (acx == NULL) {
899                 printf("Line %i: Error creating ACL context!\n", __LINE__);
900                 return -1;
901         }
902
903         /* dump context with rules - useful for coverage */
904         rte_acl_list_dump();
905
906         rte_acl_dump(acx);
907
908         rte_acl_free(acx);
909
910         return 0;
911 }
912
913 static int
914 test_acl(void)
915 {
916         if (test_invalid_parameters() < 0)
917                 return -1;
918         if (test_invalid_rules() < 0)
919                 return -1;
920         if (test_create_find_add() < 0)
921                 return -1;
922         if (test_invalid_layout() < 0)
923                 return -1;
924         if (test_misc() < 0)
925                 return -1;
926         if (test_classify() < 0)
927                 return -1;
928
929         return 0;
930 }
931
932 static struct test_command acl_cmd = {
933         .command = "acl_autotest",
934         .callback = test_acl,
935 };
936 REGISTER_TEST_COMMAND(acl_cmd);
937 #endif /* RTE_LIBRTE_ACL */