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