Imported Upstream version 16.04
[deb_dpdk.git] / examples / ip_pipeline / pipeline / pipeline_firewall.c
1 /*-
2  *   BSD LICENSE
3  *
4  *   Copyright(c) 2010-2015 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 <stdio.h>
35 #include <string.h>
36 #include <sys/queue.h>
37 #include <netinet/in.h>
38
39 #include <rte_common.h>
40 #include <rte_hexdump.h>
41 #include <rte_malloc.h>
42 #include <cmdline_rdline.h>
43 #include <cmdline_parse.h>
44 #include <cmdline_parse_num.h>
45 #include <cmdline_parse_string.h>
46 #include <cmdline_parse_ipaddr.h>
47 #include <cmdline_parse_etheraddr.h>
48 #include <cmdline_socket.h>
49
50 #include "app.h"
51 #include "pipeline_common_fe.h"
52 #include "pipeline_firewall.h"
53
54 #define BUF_SIZE                1024
55
56 struct app_pipeline_firewall_rule {
57         struct pipeline_firewall_key key;
58         int32_t priority;
59         uint32_t port_id;
60         void *entry_ptr;
61
62         TAILQ_ENTRY(app_pipeline_firewall_rule) node;
63 };
64
65 struct app_pipeline_firewall {
66         /* parameters */
67         uint32_t n_ports_in;
68         uint32_t n_ports_out;
69
70         /* rules */
71         TAILQ_HEAD(, app_pipeline_firewall_rule) rules;
72         uint32_t n_rules;
73         uint32_t default_rule_present;
74         uint32_t default_rule_port_id;
75         void *default_rule_entry_ptr;
76 };
77
78 struct app_pipeline_add_bulk_params {
79         struct pipeline_firewall_key *keys;
80         uint32_t n_keys;
81         uint32_t *priorities;
82         uint32_t *port_ids;
83 };
84
85 struct app_pipeline_del_bulk_params {
86         struct pipeline_firewall_key *keys;
87         uint32_t n_keys;
88 };
89
90 static void
91 print_firewall_ipv4_rule(struct app_pipeline_firewall_rule *rule)
92 {
93         printf("Prio = %" PRId32 " (SA = %" PRIu32 ".%" PRIu32
94                 ".%" PRIu32 ".%" PRIu32 "/%" PRIu32 ", "
95                 "DA = %" PRIu32 ".%" PRIu32
96                 ".%"PRIu32 ".%" PRIu32 "/%" PRIu32 ", "
97                 "SP = %" PRIu32 "-%" PRIu32 ", "
98                 "DP = %" PRIu32 "-%" PRIu32 ", "
99                 "Proto = %" PRIu32 " / 0x%" PRIx32 ") => "
100                 "Port = %" PRIu32 " (entry ptr = %p)\n",
101
102                 rule->priority,
103
104                 (rule->key.key.ipv4_5tuple.src_ip >> 24) & 0xFF,
105                 (rule->key.key.ipv4_5tuple.src_ip >> 16) & 0xFF,
106                 (rule->key.key.ipv4_5tuple.src_ip >> 8) & 0xFF,
107                 rule->key.key.ipv4_5tuple.src_ip & 0xFF,
108                 rule->key.key.ipv4_5tuple.src_ip_mask,
109
110                 (rule->key.key.ipv4_5tuple.dst_ip >> 24) & 0xFF,
111                 (rule->key.key.ipv4_5tuple.dst_ip >> 16) & 0xFF,
112                 (rule->key.key.ipv4_5tuple.dst_ip >> 8) & 0xFF,
113                 rule->key.key.ipv4_5tuple.dst_ip & 0xFF,
114                 rule->key.key.ipv4_5tuple.dst_ip_mask,
115
116                 rule->key.key.ipv4_5tuple.src_port_from,
117                 rule->key.key.ipv4_5tuple.src_port_to,
118
119                 rule->key.key.ipv4_5tuple.dst_port_from,
120                 rule->key.key.ipv4_5tuple.dst_port_to,
121
122                 rule->key.key.ipv4_5tuple.proto,
123                 rule->key.key.ipv4_5tuple.proto_mask,
124
125                 rule->port_id,
126                 rule->entry_ptr);
127 }
128
129 static struct app_pipeline_firewall_rule *
130 app_pipeline_firewall_rule_find(struct app_pipeline_firewall *p,
131         struct pipeline_firewall_key *key)
132 {
133         struct app_pipeline_firewall_rule *r;
134
135         TAILQ_FOREACH(r, &p->rules, node)
136                 if (memcmp(key,
137                         &r->key,
138                         sizeof(struct pipeline_firewall_key)) == 0)
139                         return r;
140
141         return NULL;
142 }
143
144 static int
145 app_pipeline_firewall_ls(
146         struct app_params *app,
147         uint32_t pipeline_id)
148 {
149         struct app_pipeline_firewall *p;
150         struct app_pipeline_firewall_rule *rule;
151         uint32_t n_rules;
152         int priority;
153
154         /* Check input arguments */
155         if (app == NULL)
156                 return -1;
157
158         p = app_pipeline_data_fe(app, pipeline_id, &pipeline_firewall);
159         if (p == NULL)
160                 return -1;
161
162         n_rules = p->n_rules;
163         for (priority = 0; n_rules; priority++)
164                 TAILQ_FOREACH(rule, &p->rules, node)
165                         if (rule->priority == priority) {
166                                 print_firewall_ipv4_rule(rule);
167                                 n_rules--;
168                         }
169
170         if (p->default_rule_present)
171                 printf("Default rule: port %" PRIu32 " (entry ptr = %p)\n",
172                         p->default_rule_port_id,
173                         p->default_rule_entry_ptr);
174         else
175                 printf("Default rule: DROP\n");
176
177         printf("\n");
178
179         return 0;
180 }
181
182 static void*
183 app_pipeline_firewall_init(struct pipeline_params *params,
184         __rte_unused void *arg)
185 {
186         struct app_pipeline_firewall *p;
187         uint32_t size;
188
189         /* Check input arguments */
190         if ((params == NULL) ||
191                 (params->n_ports_in == 0) ||
192                 (params->n_ports_out == 0))
193                 return NULL;
194
195         /* Memory allocation */
196         size = RTE_CACHE_LINE_ROUNDUP(sizeof(struct app_pipeline_firewall));
197         p = rte_zmalloc(NULL, size, RTE_CACHE_LINE_SIZE);
198         if (p == NULL)
199                 return NULL;
200
201         /* Initialization */
202         p->n_ports_in = params->n_ports_in;
203         p->n_ports_out = params->n_ports_out;
204
205         TAILQ_INIT(&p->rules);
206         p->n_rules = 0;
207         p->default_rule_present = 0;
208         p->default_rule_port_id = 0;
209         p->default_rule_entry_ptr = NULL;
210
211         return (void *) p;
212 }
213
214 static int
215 app_pipeline_firewall_free(void *pipeline)
216 {
217         struct app_pipeline_firewall *p = pipeline;
218
219         /* Check input arguments */
220         if (p == NULL)
221                 return -1;
222
223         /* Free resources */
224         while (!TAILQ_EMPTY(&p->rules)) {
225                 struct app_pipeline_firewall_rule *rule;
226
227                 rule = TAILQ_FIRST(&p->rules);
228                 TAILQ_REMOVE(&p->rules, rule, node);
229                 rte_free(rule);
230         }
231
232         rte_free(p);
233         return 0;
234 }
235
236 static int
237 app_pipeline_firewall_key_check_and_normalize(struct pipeline_firewall_key *key)
238 {
239         switch (key->type) {
240         case PIPELINE_FIREWALL_IPV4_5TUPLE:
241         {
242                 uint32_t src_ip_depth = key->key.ipv4_5tuple.src_ip_mask;
243                 uint32_t dst_ip_depth = key->key.ipv4_5tuple.dst_ip_mask;
244                 uint16_t src_port_from = key->key.ipv4_5tuple.src_port_from;
245                 uint16_t src_port_to = key->key.ipv4_5tuple.src_port_to;
246                 uint16_t dst_port_from = key->key.ipv4_5tuple.dst_port_from;
247                 uint16_t dst_port_to = key->key.ipv4_5tuple.dst_port_to;
248
249                 uint32_t src_ip_netmask = 0;
250                 uint32_t dst_ip_netmask = 0;
251
252                 if ((src_ip_depth > 32) ||
253                         (dst_ip_depth > 32) ||
254                         (src_port_from > src_port_to) ||
255                         (dst_port_from > dst_port_to))
256                         return -1;
257
258                 if (src_ip_depth)
259                         src_ip_netmask = (~0U) << (32 - src_ip_depth);
260
261                 if (dst_ip_depth)
262                         dst_ip_netmask = ((~0U) << (32 - dst_ip_depth));
263
264                 key->key.ipv4_5tuple.src_ip &= src_ip_netmask;
265                 key->key.ipv4_5tuple.dst_ip &= dst_ip_netmask;
266
267                 return 0;
268         }
269
270         default:
271                 return -1;
272         }
273 }
274
275 static int
276 app_pipeline_add_bulk_parse_file(char *filename,
277                 struct app_pipeline_add_bulk_params *params)
278 {
279         FILE *f;
280         char file_buf[BUF_SIZE];
281         uint32_t i;
282         int status = 0;
283
284         f = fopen(filename, "r");
285         if (f == NULL)
286                 return -1;
287
288         params->n_keys = 0;
289         while (fgets(file_buf, BUF_SIZE, f) != NULL)
290                 params->n_keys++;
291         rewind(f);
292
293         if (params->n_keys == 0) {
294                 status = -1;
295                 goto end;
296         }
297
298         params->keys = rte_malloc(NULL,
299                         params->n_keys * sizeof(struct pipeline_firewall_key),
300                         RTE_CACHE_LINE_SIZE);
301         if (params->keys == NULL) {
302                 status = -1;
303                 goto end;
304         }
305
306         params->priorities = rte_malloc(NULL,
307                         params->n_keys * sizeof(uint32_t),
308                         RTE_CACHE_LINE_SIZE);
309         if (params->priorities == NULL) {
310                 status = -1;
311                 goto end;
312         }
313
314         params->port_ids = rte_malloc(NULL,
315                         params->n_keys * sizeof(uint32_t),
316                         RTE_CACHE_LINE_SIZE);
317         if (params->port_ids == NULL) {
318                 status = -1;
319                 goto end;
320         }
321
322         i = 0;
323         while (fgets(file_buf, BUF_SIZE, f) != NULL) {
324                 char *str;
325
326                 str = strtok(file_buf, " ");
327                 if (str == NULL) {
328                         status = -1;
329                         goto end;
330                 }
331                 params->priorities[i] = atoi(str);
332
333                 str = strtok(NULL, " .");
334                 if (str == NULL) {
335                         status = -1;
336                         goto end;
337                 }
338                 params->keys[i].key.ipv4_5tuple.src_ip = atoi(str)<<24;
339
340                 str = strtok(NULL, " .");
341                 if (str == NULL) {
342                         status = -1;
343                         goto end;
344                 }
345                 params->keys[i].key.ipv4_5tuple.src_ip |= atoi(str)<<16;
346
347                 str = strtok(NULL, " .");
348                 if (str == NULL) {
349                         status = -1;
350                         goto end;
351                 }
352                 params->keys[i].key.ipv4_5tuple.src_ip |= atoi(str)<<8;
353
354                 str = strtok(NULL, " .");
355                 if (str == NULL) {
356                         status = -1;
357                         goto end;
358                 }
359                 params->keys[i].key.ipv4_5tuple.src_ip |= atoi(str);
360
361                 str = strtok(NULL, " ");
362                 if (str == NULL) {
363                         status = -1;
364                         goto end;
365                 }
366                 params->keys[i].key.ipv4_5tuple.src_ip_mask = atoi(str);
367
368                 str = strtok(NULL, " .");
369                 if (str == NULL) {
370                         status = -1;
371                         goto end;
372                 }
373                 params->keys[i].key.ipv4_5tuple.dst_ip = atoi(str)<<24;
374
375                 str = strtok(NULL, " .");
376                 if (str == NULL) {
377                         status = -1;
378                         goto end;
379                 }
380                 params->keys[i].key.ipv4_5tuple.dst_ip |= atoi(str)<<16;
381
382                 str = strtok(NULL, " .");
383                 if (str == NULL) {
384                         status = -1;
385                         goto end;
386                 }
387                 params->keys[i].key.ipv4_5tuple.dst_ip |= atoi(str)<<8;
388
389                 str = strtok(NULL, " .");
390                 if (str == NULL) {
391                         status = -1;
392                         goto end;
393                 }
394                 params->keys[i].key.ipv4_5tuple.dst_ip |= atoi(str);
395
396                 str = strtok(NULL, " ");
397                 if (str == NULL) {
398                         status = -1;
399                         goto end;
400                 }
401                 params->keys[i].key.ipv4_5tuple.dst_ip_mask = atoi(str);
402
403                 str = strtok(NULL, " ");
404                 if (str == NULL) {
405                         status = -1;
406                         goto end;
407                 }
408                 params->keys[i].key.ipv4_5tuple.src_port_from = atoi(str);
409
410                 str = strtok(NULL, " ");
411                 if (str == NULL) {
412                         status = -1;
413                         goto end;
414                 }
415                 params->keys[i].key.ipv4_5tuple.src_port_to = atoi(str);
416
417                 str = strtok(NULL, " ");
418                 if (str == NULL) {
419                         status = -1;
420                         goto end;
421                 }
422                 params->keys[i].key.ipv4_5tuple.dst_port_from = atoi(str);
423
424                 str = strtok(NULL, " ");
425                 if (str == NULL) {
426                         status = -1;
427                         goto end;
428                 }
429                 params->keys[i].key.ipv4_5tuple.dst_port_to = atoi(str);
430
431                 str = strtok(NULL, " ");
432                 if (str == NULL) {
433                         status = -1;
434                         goto end;
435                 }
436                 params->keys[i].key.ipv4_5tuple.proto = atoi(str);
437
438                 str = strtok(NULL, " ");
439                 if (str == NULL) {
440                         status = -1;
441                         goto end;
442                 }
443                 /* Need to add 2 to str to skip leading 0x */
444                 params->keys[i].key.ipv4_5tuple.proto_mask = strtol(str+2, NULL, 16);
445
446                 str = strtok(NULL, " ");
447                 if (str == NULL) {
448                         status = -1;
449                         goto end;
450                 }
451                 params->port_ids[i] = atoi(str);
452                 params->keys[i].type = PIPELINE_FIREWALL_IPV4_5TUPLE;
453
454                 i++;
455         }
456
457 end:
458         fclose(f);
459         return status;
460 }
461
462 static int
463 app_pipeline_del_bulk_parse_file(char *filename,
464                 struct app_pipeline_del_bulk_params *params)
465 {
466         FILE *f;
467         char file_buf[BUF_SIZE];
468         uint32_t i;
469         int status = 0;
470
471         f = fopen(filename, "r");
472         if (f == NULL)
473                 return -1;
474
475         params->n_keys = 0;
476         while (fgets(file_buf, BUF_SIZE, f) != NULL)
477                 params->n_keys++;
478         rewind(f);
479
480         if (params->n_keys == 0) {
481                 status = -1;
482                 goto end;
483         }
484
485         params->keys = rte_malloc(NULL,
486                         params->n_keys * sizeof(struct pipeline_firewall_key),
487                         RTE_CACHE_LINE_SIZE);
488         if (params->keys == NULL) {
489                 status = -1;
490                 goto end;
491         }
492
493         i = 0;
494         while (fgets(file_buf, BUF_SIZE, f) != NULL) {
495                 char *str;
496
497                 str = strtok(file_buf, " .");
498                 if (str == NULL) {
499                         status = -1;
500                         goto end;
501                 }
502                 params->keys[i].key.ipv4_5tuple.src_ip = atoi(str)<<24;
503
504                 str = strtok(NULL, " .");
505                 if (str == NULL) {
506                         status = -1;
507                         goto end;
508                 }
509                 params->keys[i].key.ipv4_5tuple.src_ip |= atoi(str)<<16;
510
511                 str = strtok(NULL, " .");
512                 if (str == NULL) {
513                         status = -1;
514                         goto end;
515                 }
516                 params->keys[i].key.ipv4_5tuple.src_ip |= atoi(str)<<8;
517
518                 str = strtok(NULL, " .");
519                 if (str == NULL) {
520                         status = -1;
521                         goto end;
522                 }
523                 params->keys[i].key.ipv4_5tuple.src_ip |= atoi(str);
524
525                 str = strtok(NULL, " ");
526                 if (str == NULL) {
527                         status = -1;
528                         goto end;
529                 }
530                 params->keys[i].key.ipv4_5tuple.src_ip_mask = atoi(str);
531
532                 str = strtok(NULL, " .");
533                 if (str == NULL) {
534                         status = -1;
535                         goto end;
536                 }
537                 params->keys[i].key.ipv4_5tuple.dst_ip = atoi(str)<<24;
538
539                 str = strtok(NULL, " .");
540                 if (str == NULL) {
541                         status = -1;
542                         goto end;
543                 }
544                 params->keys[i].key.ipv4_5tuple.dst_ip |= atoi(str)<<16;
545
546                 str = strtok(NULL, " .");
547                 if (str == NULL) {
548                         status = -1;
549                         goto end;
550                 }
551                 params->keys[i].key.ipv4_5tuple.dst_ip |= atoi(str)<<8;
552
553                 str = strtok(NULL, " .");
554                 if (str == NULL) {
555                         status = -1;
556                         goto end;
557                 }
558                 params->keys[i].key.ipv4_5tuple.dst_ip |= atoi(str);
559
560                 str = strtok(NULL, " ");
561                 if (str == NULL) {
562                         status = -1;
563                         goto end;
564                 }
565                 params->keys[i].key.ipv4_5tuple.dst_ip_mask = atoi(str);
566
567                 str = strtok(NULL, " ");
568                 if (str == NULL) {
569                         status = -1;
570                         goto end;
571                 }
572                 params->keys[i].key.ipv4_5tuple.src_port_from = atoi(str);
573
574                 str = strtok(NULL, " ");
575                 if (str == NULL) {
576                         status = -1;
577                         goto end;
578                 }
579                 params->keys[i].key.ipv4_5tuple.src_port_to = atoi(str);
580
581                 str = strtok(NULL, " ");
582                 if (str == NULL) {
583                         status = -1;
584                         goto end;
585                 }
586                 params->keys[i].key.ipv4_5tuple.dst_port_from = atoi(str);
587
588                 str = strtok(NULL, " ");
589                 if (str == NULL) {
590                         status = -1;
591                         goto end;
592                 }
593                 params->keys[i].key.ipv4_5tuple.dst_port_to = atoi(str);
594
595                 str = strtok(NULL, " ");
596                 if (str == NULL) {
597                         status = -1;
598                         goto end;
599                 }
600                 params->keys[i].key.ipv4_5tuple.proto = atoi(str);
601
602                 str = strtok(NULL, " ");
603                 if (str == NULL) {
604                         status = -1;
605                         goto end;
606                 }
607                 /* Need to add 2 to str to skip leading 0x */
608                 params->keys[i].key.ipv4_5tuple.proto_mask = strtol(str+2, NULL, 16);
609
610                 params->keys[i].type = PIPELINE_FIREWALL_IPV4_5TUPLE;
611
612                 i++;
613         }
614
615         for (i = 0; i < params->n_keys; i++) {
616                 if (app_pipeline_firewall_key_check_and_normalize(&params->keys[i]) != 0) {
617                         status = -1;
618                         goto end;
619                 }
620         }
621
622 end:
623         fclose(f);
624         return status;
625 }
626
627 int
628 app_pipeline_firewall_add_rule(struct app_params *app,
629         uint32_t pipeline_id,
630         struct pipeline_firewall_key *key,
631         uint32_t priority,
632         uint32_t port_id)
633 {
634         struct app_pipeline_firewall *p;
635         struct app_pipeline_firewall_rule *rule;
636         struct pipeline_firewall_add_msg_req *req;
637         struct pipeline_firewall_add_msg_rsp *rsp;
638         int new_rule;
639
640         /* Check input arguments */
641         if ((app == NULL) ||
642                 (key == NULL) ||
643                 (key->type != PIPELINE_FIREWALL_IPV4_5TUPLE))
644                 return -1;
645
646         p = app_pipeline_data_fe(app, pipeline_id, &pipeline_firewall);
647         if (p == NULL)
648                 return -1;
649
650         if (port_id >= p->n_ports_out)
651                 return -1;
652
653         if (app_pipeline_firewall_key_check_and_normalize(key) != 0)
654                 return -1;
655
656         /* Find existing rule or allocate new rule */
657         rule = app_pipeline_firewall_rule_find(p, key);
658         new_rule = (rule == NULL);
659         if (rule == NULL) {
660                 rule = rte_malloc(NULL, sizeof(*rule), RTE_CACHE_LINE_SIZE);
661
662                 if (rule == NULL)
663                         return -1;
664         }
665
666         /* Allocate and write request */
667         req = app_msg_alloc(app);
668         if (req == NULL) {
669                 if (new_rule)
670                         rte_free(rule);
671                 return -1;
672         }
673
674         req->type = PIPELINE_MSG_REQ_CUSTOM;
675         req->subtype = PIPELINE_FIREWALL_MSG_REQ_ADD;
676         memcpy(&req->key, key, sizeof(*key));
677         req->priority = priority;
678         req->port_id = port_id;
679
680         /* Send request and wait for response */
681         rsp = app_msg_send_recv(app, pipeline_id, req, MSG_TIMEOUT_DEFAULT);
682         if (rsp == NULL) {
683                 if (new_rule)
684                         rte_free(rule);
685                 return -1;
686         }
687
688         /* Read response and write rule */
689         if (rsp->status ||
690                 (rsp->entry_ptr == NULL) ||
691                 ((new_rule == 0) && (rsp->key_found == 0)) ||
692                 ((new_rule == 1) && (rsp->key_found == 1))) {
693                 app_msg_free(app, rsp);
694                 if (new_rule)
695                         rte_free(rule);
696                 return -1;
697         }
698
699         memcpy(&rule->key, key, sizeof(*key));
700         rule->priority = priority;
701         rule->port_id = port_id;
702         rule->entry_ptr = rsp->entry_ptr;
703
704         /* Commit rule */
705         if (new_rule) {
706                 TAILQ_INSERT_TAIL(&p->rules, rule, node);
707                 p->n_rules++;
708         }
709
710         print_firewall_ipv4_rule(rule);
711
712         /* Free response */
713         app_msg_free(app, rsp);
714
715         return 0;
716 }
717
718 int
719 app_pipeline_firewall_delete_rule(struct app_params *app,
720         uint32_t pipeline_id,
721         struct pipeline_firewall_key *key)
722 {
723         struct app_pipeline_firewall *p;
724         struct app_pipeline_firewall_rule *rule;
725         struct pipeline_firewall_del_msg_req *req;
726         struct pipeline_firewall_del_msg_rsp *rsp;
727
728         /* Check input arguments */
729         if ((app == NULL) ||
730                 (key == NULL) ||
731                 (key->type != PIPELINE_FIREWALL_IPV4_5TUPLE))
732                 return -1;
733
734         p = app_pipeline_data_fe(app, pipeline_id, &pipeline_firewall);
735         if (p == NULL)
736                 return -1;
737
738         if (app_pipeline_firewall_key_check_and_normalize(key) != 0)
739                 return -1;
740
741         /* Find rule */
742         rule = app_pipeline_firewall_rule_find(p, key);
743         if (rule == NULL)
744                 return 0;
745
746         /* Allocate and write request */
747         req = app_msg_alloc(app);
748         if (req == NULL)
749                 return -1;
750
751         req->type = PIPELINE_MSG_REQ_CUSTOM;
752         req->subtype = PIPELINE_FIREWALL_MSG_REQ_DEL;
753         memcpy(&req->key, key, sizeof(*key));
754
755         /* Send request and wait for response */
756         rsp = app_msg_send_recv(app, pipeline_id, req, MSG_TIMEOUT_DEFAULT);
757         if (rsp == NULL)
758                 return -1;
759
760         /* Read response */
761         if (rsp->status || !rsp->key_found) {
762                 app_msg_free(app, rsp);
763                 return -1;
764         }
765
766         /* Remove rule */
767         TAILQ_REMOVE(&p->rules, rule, node);
768         p->n_rules--;
769         rte_free(rule);
770
771         /* Free response */
772         app_msg_free(app, rsp);
773
774         return 0;
775 }
776
777 int
778 app_pipeline_firewall_add_bulk(struct app_params *app,
779                 uint32_t pipeline_id,
780                 struct pipeline_firewall_key *keys,
781                 uint32_t n_keys,
782                 uint32_t *priorities,
783                 uint32_t *port_ids)
784 {
785         struct app_pipeline_firewall *p;
786         struct pipeline_firewall_add_bulk_msg_req *req;
787         struct pipeline_firewall_add_bulk_msg_rsp *rsp;
788
789         struct app_pipeline_firewall_rule **rules;
790         int *new_rules;
791
792         int *keys_found;
793         void **entries_ptr;
794
795         uint32_t i;
796         int status = 0;
797
798         /* Check input arguments */
799         if (app == NULL)
800                 return -1;
801
802         p = app_pipeline_data_fe(app, pipeline_id, &pipeline_firewall);
803         if (p == NULL)
804                 return -1;
805
806         rules = rte_malloc(NULL,
807                         n_keys * sizeof(struct app_pipeline_firewall_rule *),
808                         RTE_CACHE_LINE_SIZE);
809         if (rules == NULL)
810                 return -1;
811
812         new_rules = rte_malloc(NULL,
813                         n_keys * sizeof(int),
814                         RTE_CACHE_LINE_SIZE);
815         if (new_rules == NULL) {
816                 rte_free(rules);
817                 return -1;
818         }
819
820         /* check data integrity and add to rule list */
821         for (i = 0; i < n_keys; i++) {
822                 if (port_ids[i]  >= p->n_ports_out) {
823                         rte_free(rules);
824                         rte_free(new_rules);
825                         return -1;
826                 }
827
828                 if (app_pipeline_firewall_key_check_and_normalize(&keys[i]) != 0) {
829                         rte_free(rules);
830                         rte_free(new_rules);
831                         return -1;
832                 }
833
834                 rules[i] = app_pipeline_firewall_rule_find(p, &keys[i]);
835                 new_rules[i] = (rules[i] == NULL);
836                 if (rules[i] == NULL) {
837                         rules[i] = rte_malloc(NULL, sizeof(*rules[i]),
838                                         RTE_CACHE_LINE_SIZE);
839
840                         if (rules[i] == NULL) {
841                                 uint32_t j;
842
843                                 for (j = 0; j <= i; j++)
844                                         if (new_rules[j])
845                                                 rte_free(rules[j]);
846
847                                 rte_free(rules);
848                                 rte_free(new_rules);
849                                 return -1;
850                         }
851                 }
852         }
853
854         keys_found = rte_malloc(NULL,
855                         n_keys * sizeof(int),
856                         RTE_CACHE_LINE_SIZE);
857         if (keys_found == NULL) {
858                 uint32_t j;
859
860                 for (j = 0; j < n_keys; j++)
861                         if (new_rules[j])
862                                 rte_free(rules[j]);
863
864                 rte_free(rules);
865                 rte_free(new_rules);
866                 return -1;
867         }
868
869         entries_ptr = rte_malloc(NULL,
870                         n_keys * sizeof(struct rte_pipeline_table_entry *),
871                         RTE_CACHE_LINE_SIZE);
872         if (entries_ptr == NULL) {
873                 uint32_t j;
874
875                 for (j = 0; j < n_keys; j++)
876                         if (new_rules[j])
877                                 rte_free(rules[j]);
878
879                 rte_free(rules);
880                 rte_free(new_rules);
881                 rte_free(keys_found);
882                 return -1;
883         }
884         for (i = 0; i < n_keys; i++) {
885                 entries_ptr[i] = rte_malloc(NULL,
886                                 sizeof(struct rte_pipeline_table_entry),
887                                 RTE_CACHE_LINE_SIZE);
888
889                 if (entries_ptr[i] == NULL) {
890                         uint32_t j;
891
892                         for (j = 0; j < n_keys; j++)
893                                 if (new_rules[j])
894                                         rte_free(rules[j]);
895
896                         for (j = 0; j <= i; j++)
897                                 rte_free(entries_ptr[j]);
898
899                         rte_free(rules);
900                         rte_free(new_rules);
901                         rte_free(keys_found);
902                         rte_free(entries_ptr);
903                         return -1;
904                 }
905         }
906
907         /* Allocate and write request */
908         req = app_msg_alloc(app);
909         if (req == NULL) {
910                 uint32_t j;
911
912                 for (j = 0; j < n_keys; j++)
913                         if (new_rules[j])
914                                 rte_free(rules[j]);
915
916                 for (j = 0; j < n_keys; j++)
917                         rte_free(entries_ptr[j]);
918
919                 rte_free(rules);
920                 rte_free(new_rules);
921                 rte_free(keys_found);
922                 rte_free(entries_ptr);
923                 return -1;
924         }
925
926         req->type = PIPELINE_MSG_REQ_CUSTOM;
927         req->subtype = PIPELINE_FIREWALL_MSG_REQ_ADD_BULK;
928
929         req->keys = keys;
930         req->n_keys = n_keys;
931         req->port_ids = port_ids;
932         req->priorities = priorities;
933         req->keys_found = keys_found;
934         req->entries_ptr = entries_ptr;
935
936         /* Send request and wait for response */
937         rsp = app_msg_send_recv(app, pipeline_id, req, MSG_TIMEOUT_DEFAULT);
938         if (rsp == NULL) {
939                 uint32_t j;
940
941                 for (j = 0; j < n_keys; j++)
942                         if (new_rules[j])
943                                 rte_free(rules[j]);
944
945                 for (j = 0; j < n_keys; j++)
946                         rte_free(entries_ptr[j]);
947
948                 rte_free(rules);
949                 rte_free(new_rules);
950                 rte_free(keys_found);
951                 rte_free(entries_ptr);
952                 return -1;
953         }
954
955         if (rsp->status) {
956                 for (i = 0; i < n_keys; i++)
957                         if (new_rules[i])
958                                 rte_free(rules[i]);
959
960                 for (i = 0; i < n_keys; i++)
961                         rte_free(entries_ptr[i]);
962
963                 status = -1;
964                 goto cleanup;
965         }
966
967         for (i = 0; i < n_keys; i++) {
968                 if (entries_ptr[i] == NULL ||
969                         ((new_rules[i] == 0) && (keys_found[i] == 0)) ||
970                         ((new_rules[i] == 1) && (keys_found[i] == 1))) {
971                         for (i = 0; i < n_keys; i++)
972                                 if (new_rules[i])
973                                         rte_free(rules[i]);
974
975                         for (i = 0; i < n_keys; i++)
976                                 rte_free(entries_ptr[i]);
977
978                         status = -1;
979                         goto cleanup;
980                 }
981         }
982
983         for (i = 0; i < n_keys; i++) {
984                 memcpy(&rules[i]->key, &keys[i], sizeof(keys[i]));
985                 rules[i]->priority = priorities[i];
986                 rules[i]->port_id = port_ids[i];
987                 rules[i]->entry_ptr = entries_ptr[i];
988
989                 /* Commit rule */
990                 if (new_rules[i]) {
991                         TAILQ_INSERT_TAIL(&p->rules, rules[i], node);
992                         p->n_rules++;
993                 }
994
995                 print_firewall_ipv4_rule(rules[i]);
996         }
997
998 cleanup:
999         app_msg_free(app, rsp);
1000         rte_free(rules);
1001         rte_free(new_rules);
1002         rte_free(keys_found);
1003         rte_free(entries_ptr);
1004
1005         return status;
1006 }
1007
1008 int
1009 app_pipeline_firewall_delete_bulk(struct app_params *app,
1010         uint32_t pipeline_id,
1011         struct pipeline_firewall_key *keys,
1012         uint32_t n_keys)
1013 {
1014         struct app_pipeline_firewall *p;
1015         struct pipeline_firewall_del_bulk_msg_req *req;
1016         struct pipeline_firewall_del_bulk_msg_rsp *rsp;
1017
1018         struct app_pipeline_firewall_rule **rules;
1019         int *keys_found;
1020
1021         uint32_t i;
1022         int status = 0;
1023
1024         /* Check input arguments */
1025         if (app == NULL)
1026                 return -1;
1027
1028         p = app_pipeline_data_fe(app, pipeline_id, &pipeline_firewall);
1029         if (p == NULL)
1030                 return -1;
1031
1032         rules = rte_malloc(NULL,
1033                         n_keys * sizeof(struct app_pipeline_firewall_rule *),
1034                         RTE_CACHE_LINE_SIZE);
1035         if (rules == NULL)
1036                 return -1;
1037
1038         for (i = 0; i < n_keys; i++) {
1039                 if (app_pipeline_firewall_key_check_and_normalize(&keys[i]) != 0) {
1040                         return -1;
1041                 }
1042
1043                 rules[i] = app_pipeline_firewall_rule_find(p, &keys[i]);
1044         }
1045
1046         keys_found = rte_malloc(NULL,
1047                         n_keys * sizeof(int),
1048                         RTE_CACHE_LINE_SIZE);
1049         if (keys_found == NULL) {
1050                 rte_free(rules);
1051                 return -1;
1052         }
1053
1054         /* Allocate and write request */
1055         req = app_msg_alloc(app);
1056         if (req == NULL) {
1057                 rte_free(rules);
1058                 rte_free(keys_found);
1059                 return -1;
1060         }
1061
1062         req->type = PIPELINE_MSG_REQ_CUSTOM;
1063         req->subtype = PIPELINE_FIREWALL_MSG_REQ_DEL_BULK;
1064
1065         req->keys = keys;
1066         req->n_keys = n_keys;
1067         req->keys_found = keys_found;
1068
1069         /* Send request and wait for response */
1070         rsp = app_msg_send_recv(app, pipeline_id, req, MSG_TIMEOUT_DEFAULT);
1071         if (rsp == NULL) {
1072                 rte_free(rules);
1073                 rte_free(keys_found);
1074                 return -1;
1075         }
1076
1077         if (rsp->status) {
1078                 status = -1;
1079                 goto cleanup;
1080         }
1081
1082         for (i = 0; i < n_keys; i++) {
1083                 if (keys_found[i] == 0) {
1084                         status = -1;
1085                         goto cleanup;
1086                 }
1087         }
1088
1089         for (i = 0; i < n_keys; i++) {
1090                 TAILQ_REMOVE(&p->rules, rules[i], node);
1091                 p->n_rules--;
1092                 rte_free(rules[i]);
1093         }
1094
1095 cleanup:
1096         app_msg_free(app, rsp);
1097         rte_free(rules);
1098         rte_free(keys_found);
1099
1100         return status;
1101 }
1102
1103 int
1104 app_pipeline_firewall_add_default_rule(struct app_params *app,
1105         uint32_t pipeline_id,
1106         uint32_t port_id)
1107 {
1108         struct app_pipeline_firewall *p;
1109         struct pipeline_firewall_add_default_msg_req *req;
1110         struct pipeline_firewall_add_default_msg_rsp *rsp;
1111
1112         /* Check input arguments */
1113         if (app == NULL)
1114                 return -1;
1115
1116         p = app_pipeline_data_fe(app, pipeline_id, &pipeline_firewall);
1117         if (p == NULL)
1118                 return -1;
1119
1120         if (port_id >= p->n_ports_out)
1121                 return -1;
1122
1123         /* Allocate and write request */
1124         req = app_msg_alloc(app);
1125         if (req == NULL)
1126                 return -1;
1127
1128         req->type = PIPELINE_MSG_REQ_CUSTOM;
1129         req->subtype = PIPELINE_FIREWALL_MSG_REQ_ADD_DEFAULT;
1130         req->port_id = port_id;
1131
1132         /* Send request and wait for response */
1133         rsp = app_msg_send_recv(app, pipeline_id, req, MSG_TIMEOUT_DEFAULT);
1134         if (rsp == NULL)
1135                 return -1;
1136
1137         /* Read response and write rule */
1138         if (rsp->status || (rsp->entry_ptr == NULL)) {
1139                 app_msg_free(app, rsp);
1140                 return -1;
1141         }
1142
1143         p->default_rule_port_id = port_id;
1144         p->default_rule_entry_ptr = rsp->entry_ptr;
1145
1146         /* Commit rule */
1147         p->default_rule_present = 1;
1148
1149         /* Free response */
1150         app_msg_free(app, rsp);
1151
1152         return 0;
1153 }
1154
1155 int
1156 app_pipeline_firewall_delete_default_rule(struct app_params *app,
1157         uint32_t pipeline_id)
1158 {
1159         struct app_pipeline_firewall *p;
1160         struct pipeline_firewall_del_default_msg_req *req;
1161         struct pipeline_firewall_del_default_msg_rsp *rsp;
1162
1163         /* Check input arguments */
1164         if (app == NULL)
1165                 return -1;
1166
1167         p = app_pipeline_data_fe(app, pipeline_id, &pipeline_firewall);
1168         if (p == NULL)
1169                 return -1;
1170
1171         /* Allocate and write request */
1172         req = app_msg_alloc(app);
1173         if (req == NULL)
1174                 return -1;
1175
1176         req->type = PIPELINE_MSG_REQ_CUSTOM;
1177         req->subtype = PIPELINE_FIREWALL_MSG_REQ_DEL_DEFAULT;
1178
1179         /* Send request and wait for response */
1180         rsp = app_msg_send_recv(app, pipeline_id, req, MSG_TIMEOUT_DEFAULT);
1181         if (rsp == NULL)
1182                 return -1;
1183
1184         /* Read response and write rule */
1185         if (rsp->status) {
1186                 app_msg_free(app, rsp);
1187                 return -1;
1188         }
1189
1190         /* Commit rule */
1191         p->default_rule_present = 0;
1192
1193         /* Free response */
1194         app_msg_free(app, rsp);
1195
1196         return 0;
1197 }
1198
1199 /*
1200  * p firewall add ipv4
1201  */
1202
1203 struct cmd_firewall_add_ipv4_result {
1204         cmdline_fixed_string_t p_string;
1205         uint32_t pipeline_id;
1206         cmdline_fixed_string_t firewall_string;
1207         cmdline_fixed_string_t add_string;
1208         cmdline_fixed_string_t ipv4_string;
1209         int32_t priority;
1210         cmdline_ipaddr_t src_ip;
1211         uint32_t src_ip_mask;
1212         cmdline_ipaddr_t dst_ip;
1213         uint32_t dst_ip_mask;
1214         uint16_t src_port_from;
1215         uint16_t src_port_to;
1216         uint16_t dst_port_from;
1217         uint16_t dst_port_to;
1218         uint8_t proto;
1219         uint8_t proto_mask;
1220         uint8_t port_id;
1221 };
1222
1223 static void
1224 cmd_firewall_add_ipv4_parsed(
1225         void *parsed_result,
1226         __attribute__((unused)) struct cmdline *cl,
1227         void *data)
1228 {
1229         struct cmd_firewall_add_ipv4_result *params = parsed_result;
1230         struct app_params *app = data;
1231         struct pipeline_firewall_key key;
1232         int status;
1233
1234         key.type = PIPELINE_FIREWALL_IPV4_5TUPLE;
1235         key.key.ipv4_5tuple.src_ip = rte_bswap32(
1236                 (uint32_t) params->src_ip.addr.ipv4.s_addr);
1237         key.key.ipv4_5tuple.src_ip_mask = params->src_ip_mask;
1238         key.key.ipv4_5tuple.dst_ip = rte_bswap32(
1239                 (uint32_t) params->dst_ip.addr.ipv4.s_addr);
1240         key.key.ipv4_5tuple.dst_ip_mask = params->dst_ip_mask;
1241         key.key.ipv4_5tuple.src_port_from = params->src_port_from;
1242         key.key.ipv4_5tuple.src_port_to = params->src_port_to;
1243         key.key.ipv4_5tuple.dst_port_from = params->dst_port_from;
1244         key.key.ipv4_5tuple.dst_port_to = params->dst_port_to;
1245         key.key.ipv4_5tuple.proto = params->proto;
1246         key.key.ipv4_5tuple.proto_mask = params->proto_mask;
1247
1248         status = app_pipeline_firewall_add_rule(app,
1249                 params->pipeline_id,
1250                 &key,
1251                 params->priority,
1252                 params->port_id);
1253
1254         if (status != 0) {
1255                 printf("Command failed\n");
1256                 return;
1257         }
1258 }
1259
1260 cmdline_parse_token_string_t cmd_firewall_add_ipv4_p_string =
1261         TOKEN_STRING_INITIALIZER(struct cmd_firewall_add_ipv4_result, p_string,
1262                 "p");
1263
1264 cmdline_parse_token_num_t cmd_firewall_add_ipv4_pipeline_id =
1265         TOKEN_NUM_INITIALIZER(struct cmd_firewall_add_ipv4_result, pipeline_id,
1266                 UINT32);
1267
1268 cmdline_parse_token_string_t cmd_firewall_add_ipv4_firewall_string =
1269         TOKEN_STRING_INITIALIZER(struct cmd_firewall_add_ipv4_result,
1270                 firewall_string, "firewall");
1271
1272 cmdline_parse_token_string_t cmd_firewall_add_ipv4_add_string =
1273         TOKEN_STRING_INITIALIZER(struct cmd_firewall_add_ipv4_result,
1274                 add_string, "add");
1275
1276 cmdline_parse_token_string_t cmd_firewall_add_ipv4_ipv4_string =
1277         TOKEN_STRING_INITIALIZER(struct cmd_firewall_add_ipv4_result,
1278                 ipv4_string, "ipv4");
1279
1280 cmdline_parse_token_num_t cmd_firewall_add_ipv4_priority =
1281         TOKEN_NUM_INITIALIZER(struct cmd_firewall_add_ipv4_result, priority,
1282                 INT32);
1283
1284 cmdline_parse_token_ipaddr_t cmd_firewall_add_ipv4_src_ip =
1285         TOKEN_IPV4_INITIALIZER(struct cmd_firewall_add_ipv4_result, src_ip);
1286
1287 cmdline_parse_token_num_t cmd_firewall_add_ipv4_src_ip_mask =
1288         TOKEN_NUM_INITIALIZER(struct cmd_firewall_add_ipv4_result, src_ip_mask,
1289                 UINT32);
1290
1291 cmdline_parse_token_ipaddr_t cmd_firewall_add_ipv4_dst_ip =
1292         TOKEN_IPV4_INITIALIZER(struct cmd_firewall_add_ipv4_result, dst_ip);
1293
1294 cmdline_parse_token_num_t cmd_firewall_add_ipv4_dst_ip_mask =
1295         TOKEN_NUM_INITIALIZER(struct cmd_firewall_add_ipv4_result, dst_ip_mask,
1296                 UINT32);
1297
1298 cmdline_parse_token_num_t cmd_firewall_add_ipv4_src_port_from =
1299         TOKEN_NUM_INITIALIZER(struct cmd_firewall_add_ipv4_result,
1300                 src_port_from, UINT16);
1301
1302 cmdline_parse_token_num_t cmd_firewall_add_ipv4_src_port_to =
1303         TOKEN_NUM_INITIALIZER(struct cmd_firewall_add_ipv4_result,
1304                 src_port_to, UINT16);
1305
1306 cmdline_parse_token_num_t cmd_firewall_add_ipv4_dst_port_from =
1307         TOKEN_NUM_INITIALIZER(struct cmd_firewall_add_ipv4_result,
1308                 dst_port_from, UINT16);
1309
1310 cmdline_parse_token_num_t cmd_firewall_add_ipv4_dst_port_to =
1311         TOKEN_NUM_INITIALIZER(struct cmd_firewall_add_ipv4_result,
1312                 dst_port_to, UINT16);
1313
1314 cmdline_parse_token_num_t cmd_firewall_add_ipv4_proto =
1315         TOKEN_NUM_INITIALIZER(struct cmd_firewall_add_ipv4_result,
1316                 proto, UINT8);
1317
1318 cmdline_parse_token_num_t cmd_firewall_add_ipv4_proto_mask =
1319         TOKEN_NUM_INITIALIZER(struct cmd_firewall_add_ipv4_result,
1320                 proto_mask, UINT8);
1321
1322 cmdline_parse_token_num_t cmd_firewall_add_ipv4_port_id =
1323         TOKEN_NUM_INITIALIZER(struct cmd_firewall_add_ipv4_result,
1324                 port_id, UINT8);
1325
1326 cmdline_parse_inst_t cmd_firewall_add_ipv4 = {
1327         .f = cmd_firewall_add_ipv4_parsed,
1328         .data = NULL,
1329         .help_str = "Firewall rule add",
1330         .tokens = {
1331                 (void *) &cmd_firewall_add_ipv4_p_string,
1332                 (void *) &cmd_firewall_add_ipv4_pipeline_id,
1333                 (void *) &cmd_firewall_add_ipv4_firewall_string,
1334                 (void *) &cmd_firewall_add_ipv4_add_string,
1335                 (void *) &cmd_firewall_add_ipv4_ipv4_string,
1336                 (void *) &cmd_firewall_add_ipv4_priority,
1337                 (void *) &cmd_firewall_add_ipv4_src_ip,
1338                 (void *) &cmd_firewall_add_ipv4_src_ip_mask,
1339                 (void *) &cmd_firewall_add_ipv4_dst_ip,
1340                 (void *) &cmd_firewall_add_ipv4_dst_ip_mask,
1341                 (void *) &cmd_firewall_add_ipv4_src_port_from,
1342                 (void *) &cmd_firewall_add_ipv4_src_port_to,
1343                 (void *) &cmd_firewall_add_ipv4_dst_port_from,
1344                 (void *) &cmd_firewall_add_ipv4_dst_port_to,
1345                 (void *) &cmd_firewall_add_ipv4_proto,
1346                 (void *) &cmd_firewall_add_ipv4_proto_mask,
1347                 (void *) &cmd_firewall_add_ipv4_port_id,
1348                 NULL,
1349         },
1350 };
1351
1352 /*
1353  * p firewall del ipv4
1354  */
1355
1356 struct cmd_firewall_del_ipv4_result {
1357         cmdline_fixed_string_t p_string;
1358         uint32_t pipeline_id;
1359         cmdline_fixed_string_t firewall_string;
1360         cmdline_fixed_string_t del_string;
1361         cmdline_fixed_string_t ipv4_string;
1362         cmdline_ipaddr_t src_ip;
1363         uint32_t src_ip_mask;
1364         cmdline_ipaddr_t dst_ip;
1365         uint32_t dst_ip_mask;
1366         uint16_t src_port_from;
1367         uint16_t src_port_to;
1368         uint16_t dst_port_from;
1369         uint16_t dst_port_to;
1370         uint8_t proto;
1371         uint8_t proto_mask;
1372 };
1373
1374 static void
1375 cmd_firewall_del_ipv4_parsed(
1376         void *parsed_result,
1377         __attribute__((unused)) struct cmdline *cl,
1378         void *data)
1379 {
1380         struct cmd_firewall_del_ipv4_result *params = parsed_result;
1381         struct app_params *app = data;
1382         struct pipeline_firewall_key key;
1383         int status;
1384
1385         key.type = PIPELINE_FIREWALL_IPV4_5TUPLE;
1386         key.key.ipv4_5tuple.src_ip = rte_bswap32(
1387                 (uint32_t) params->src_ip.addr.ipv4.s_addr);
1388         key.key.ipv4_5tuple.src_ip_mask = params->src_ip_mask;
1389         key.key.ipv4_5tuple.dst_ip = rte_bswap32(
1390                 (uint32_t) params->dst_ip.addr.ipv4.s_addr);
1391         key.key.ipv4_5tuple.dst_ip_mask = params->dst_ip_mask;
1392         key.key.ipv4_5tuple.src_port_from = params->src_port_from;
1393         key.key.ipv4_5tuple.src_port_to = params->src_port_to;
1394         key.key.ipv4_5tuple.dst_port_from = params->dst_port_from;
1395         key.key.ipv4_5tuple.dst_port_to = params->dst_port_to;
1396         key.key.ipv4_5tuple.proto = params->proto;
1397         key.key.ipv4_5tuple.proto_mask = params->proto_mask;
1398
1399         status = app_pipeline_firewall_delete_rule(app,
1400                 params->pipeline_id,
1401                 &key);
1402
1403         if (status != 0) {
1404                 printf("Command failed\n");
1405                 return;
1406         }
1407 }
1408
1409 cmdline_parse_token_string_t cmd_firewall_del_ipv4_p_string =
1410         TOKEN_STRING_INITIALIZER(struct cmd_firewall_del_ipv4_result, p_string,
1411                 "p");
1412
1413 cmdline_parse_token_num_t cmd_firewall_del_ipv4_pipeline_id =
1414         TOKEN_NUM_INITIALIZER(struct cmd_firewall_del_ipv4_result, pipeline_id,
1415                 UINT32);
1416
1417 cmdline_parse_token_string_t cmd_firewall_del_ipv4_firewall_string =
1418         TOKEN_STRING_INITIALIZER(struct cmd_firewall_del_ipv4_result,
1419                 firewall_string, "firewall");
1420
1421 cmdline_parse_token_string_t cmd_firewall_del_ipv4_del_string =
1422         TOKEN_STRING_INITIALIZER(struct cmd_firewall_del_ipv4_result,
1423                 del_string, "del");
1424
1425 cmdline_parse_token_string_t cmd_firewall_del_ipv4_ipv4_string =
1426         TOKEN_STRING_INITIALIZER(struct cmd_firewall_del_ipv4_result,
1427                 ipv4_string, "ipv4");
1428
1429 cmdline_parse_token_ipaddr_t cmd_firewall_del_ipv4_src_ip =
1430         TOKEN_IPV4_INITIALIZER(struct cmd_firewall_del_ipv4_result, src_ip);
1431
1432 cmdline_parse_token_num_t cmd_firewall_del_ipv4_src_ip_mask =
1433         TOKEN_NUM_INITIALIZER(struct cmd_firewall_del_ipv4_result, src_ip_mask,
1434                 UINT32);
1435
1436 cmdline_parse_token_ipaddr_t cmd_firewall_del_ipv4_dst_ip =
1437         TOKEN_IPV4_INITIALIZER(struct cmd_firewall_del_ipv4_result, dst_ip);
1438
1439 cmdline_parse_token_num_t cmd_firewall_del_ipv4_dst_ip_mask =
1440         TOKEN_NUM_INITIALIZER(struct cmd_firewall_del_ipv4_result, dst_ip_mask,
1441                 UINT32);
1442
1443 cmdline_parse_token_num_t cmd_firewall_del_ipv4_src_port_from =
1444         TOKEN_NUM_INITIALIZER(struct cmd_firewall_del_ipv4_result,
1445                 src_port_from, UINT16);
1446
1447 cmdline_parse_token_num_t cmd_firewall_del_ipv4_src_port_to =
1448         TOKEN_NUM_INITIALIZER(struct cmd_firewall_del_ipv4_result, src_port_to,
1449                 UINT16);
1450
1451 cmdline_parse_token_num_t cmd_firewall_del_ipv4_dst_port_from =
1452         TOKEN_NUM_INITIALIZER(struct cmd_firewall_del_ipv4_result,
1453                 dst_port_from, UINT16);
1454
1455 cmdline_parse_token_num_t cmd_firewall_del_ipv4_dst_port_to =
1456         TOKEN_NUM_INITIALIZER(struct cmd_firewall_del_ipv4_result,
1457                 dst_port_to, UINT16);
1458
1459 cmdline_parse_token_num_t cmd_firewall_del_ipv4_proto =
1460         TOKEN_NUM_INITIALIZER(struct cmd_firewall_del_ipv4_result,
1461                 proto, UINT8);
1462
1463 cmdline_parse_token_num_t cmd_firewall_del_ipv4_proto_mask =
1464         TOKEN_NUM_INITIALIZER(struct cmd_firewall_del_ipv4_result, proto_mask,
1465                 UINT8);
1466
1467 cmdline_parse_inst_t cmd_firewall_del_ipv4 = {
1468         .f = cmd_firewall_del_ipv4_parsed,
1469         .data = NULL,
1470         .help_str = "Firewall rule delete",
1471         .tokens = {
1472                 (void *) &cmd_firewall_del_ipv4_p_string,
1473                 (void *) &cmd_firewall_del_ipv4_pipeline_id,
1474                 (void *) &cmd_firewall_del_ipv4_firewall_string,
1475                 (void *) &cmd_firewall_del_ipv4_del_string,
1476                 (void *) &cmd_firewall_del_ipv4_ipv4_string,
1477                 (void *) &cmd_firewall_del_ipv4_src_ip,
1478                 (void *) &cmd_firewall_del_ipv4_src_ip_mask,
1479                 (void *) &cmd_firewall_del_ipv4_dst_ip,
1480                 (void *) &cmd_firewall_del_ipv4_dst_ip_mask,
1481                 (void *) &cmd_firewall_del_ipv4_src_port_from,
1482                 (void *) &cmd_firewall_del_ipv4_src_port_to,
1483                 (void *) &cmd_firewall_del_ipv4_dst_port_from,
1484                 (void *) &cmd_firewall_del_ipv4_dst_port_to,
1485                 (void *) &cmd_firewall_del_ipv4_proto,
1486                 (void *) &cmd_firewall_del_ipv4_proto_mask,
1487                 NULL,
1488         },
1489 };
1490
1491 /*
1492  * p firewall add bulk
1493  */
1494
1495 struct cmd_firewall_add_bulk_result {
1496         cmdline_fixed_string_t p_string;
1497         uint32_t pipeline_id;
1498         cmdline_fixed_string_t firewall_string;
1499         cmdline_fixed_string_t add_string;
1500         cmdline_fixed_string_t bulk_string;
1501         cmdline_fixed_string_t file_path;
1502 };
1503
1504 static void
1505 cmd_firewall_add_bulk_parsed(
1506         void *parsed_result,
1507         __attribute__((unused)) struct cmdline *cl,
1508         void *data)
1509 {
1510         struct cmd_firewall_add_bulk_result *params = parsed_result;
1511         struct app_params *app = data;
1512         int status;
1513
1514         struct app_pipeline_add_bulk_params add_bulk_params;
1515
1516         status = app_pipeline_add_bulk_parse_file(params->file_path, &add_bulk_params);
1517         if (status != 0) {
1518                 printf("Command failed\n");
1519                 goto end;
1520         }
1521
1522         status = app_pipeline_firewall_add_bulk(app, params->pipeline_id, add_bulk_params.keys,
1523                         add_bulk_params.n_keys, add_bulk_params.priorities, add_bulk_params.port_ids);
1524         if (status != 0) {
1525                 printf("Command failed\n");
1526                 goto end;
1527         }
1528
1529 end:
1530         rte_free(add_bulk_params.keys);
1531         rte_free(add_bulk_params.priorities);
1532         rte_free(add_bulk_params.port_ids);
1533 }
1534
1535 cmdline_parse_token_string_t cmd_firewall_add_bulk_p_string =
1536         TOKEN_STRING_INITIALIZER(struct cmd_firewall_add_bulk_result, p_string,
1537                 "p");
1538
1539 cmdline_parse_token_num_t cmd_firewall_add_bulk_pipeline_id =
1540         TOKEN_NUM_INITIALIZER(struct cmd_firewall_add_bulk_result, pipeline_id,
1541                 UINT32);
1542
1543 cmdline_parse_token_string_t cmd_firewall_add_bulk_firewall_string =
1544         TOKEN_STRING_INITIALIZER(struct cmd_firewall_add_bulk_result,
1545                 firewall_string, "firewall");
1546
1547 cmdline_parse_token_string_t cmd_firewall_add_bulk_add_string =
1548         TOKEN_STRING_INITIALIZER(struct cmd_firewall_add_bulk_result,
1549                 add_string, "add");
1550
1551 cmdline_parse_token_string_t cmd_firewall_add_bulk_bulk_string =
1552         TOKEN_STRING_INITIALIZER(struct cmd_firewall_add_bulk_result,
1553                 bulk_string, "bulk");
1554
1555 cmdline_parse_token_string_t cmd_firewall_add_bulk_file_path_string =
1556         TOKEN_STRING_INITIALIZER(struct cmd_firewall_add_bulk_result,
1557                 file_path, NULL);
1558
1559 cmdline_parse_inst_t cmd_firewall_add_bulk = {
1560         .f = cmd_firewall_add_bulk_parsed,
1561         .data = NULL,
1562         .help_str = "Firewall rule add bulk",
1563         .tokens = {
1564                 (void *) &cmd_firewall_add_bulk_p_string,
1565                 (void *) &cmd_firewall_add_bulk_pipeline_id,
1566                 (void *) &cmd_firewall_add_bulk_firewall_string,
1567                 (void *) &cmd_firewall_add_bulk_add_string,
1568                 (void *) &cmd_firewall_add_bulk_bulk_string,
1569                 (void *) &cmd_firewall_add_bulk_file_path_string,
1570                 NULL,
1571         },
1572 };
1573
1574 /*
1575  * p firewall del bulk
1576  */
1577
1578 struct cmd_firewall_del_bulk_result {
1579         cmdline_fixed_string_t p_string;
1580         uint32_t pipeline_id;
1581         cmdline_fixed_string_t firewall_string;
1582         cmdline_fixed_string_t del_string;
1583         cmdline_fixed_string_t bulk_string;
1584         cmdline_fixed_string_t file_path;
1585 };
1586
1587 static void
1588 cmd_firewall_del_bulk_parsed(
1589         void *parsed_result,
1590         __attribute__((unused)) struct cmdline *cl,
1591         void *data)
1592 {
1593         struct cmd_firewall_del_bulk_result *params = parsed_result;
1594         struct app_params *app = data;
1595         int status;
1596
1597         struct app_pipeline_del_bulk_params del_bulk_params;
1598
1599         status = app_pipeline_del_bulk_parse_file(params->file_path, &del_bulk_params);
1600         if (status != 0) {
1601                 printf("Command failed\n");
1602                 goto end;
1603         }
1604
1605         status = app_pipeline_firewall_delete_bulk(app, params->pipeline_id,
1606                         del_bulk_params.keys, del_bulk_params.n_keys);
1607         if (status != 0) {
1608                 printf("Command failed\n");
1609                 goto end;
1610         }
1611
1612 end:
1613         rte_free(del_bulk_params.keys);
1614 }
1615
1616 cmdline_parse_token_string_t cmd_firewall_del_bulk_p_string =
1617         TOKEN_STRING_INITIALIZER(struct cmd_firewall_del_bulk_result, p_string,
1618                 "p");
1619
1620 cmdline_parse_token_num_t cmd_firewall_del_bulk_pipeline_id =
1621         TOKEN_NUM_INITIALIZER(struct cmd_firewall_del_bulk_result, pipeline_id,
1622                 UINT32);
1623
1624 cmdline_parse_token_string_t cmd_firewall_del_bulk_firewall_string =
1625         TOKEN_STRING_INITIALIZER(struct cmd_firewall_del_bulk_result,
1626                 firewall_string, "firewall");
1627
1628 cmdline_parse_token_string_t cmd_firewall_del_bulk_add_string =
1629         TOKEN_STRING_INITIALIZER(struct cmd_firewall_del_bulk_result,
1630                 del_string, "del");
1631
1632 cmdline_parse_token_string_t cmd_firewall_del_bulk_bulk_string =
1633         TOKEN_STRING_INITIALIZER(struct cmd_firewall_del_bulk_result,
1634                 bulk_string, "bulk");
1635
1636 cmdline_parse_token_string_t cmd_firewall_del_bulk_file_path_string =
1637         TOKEN_STRING_INITIALIZER(struct cmd_firewall_del_bulk_result,
1638                 file_path, NULL);
1639
1640 cmdline_parse_inst_t cmd_firewall_del_bulk = {
1641         .f = cmd_firewall_del_bulk_parsed,
1642         .data = NULL,
1643         .help_str = "Firewall rule del bulk",
1644         .tokens = {
1645                 (void *) &cmd_firewall_del_bulk_p_string,
1646                 (void *) &cmd_firewall_del_bulk_pipeline_id,
1647                 (void *) &cmd_firewall_del_bulk_firewall_string,
1648                 (void *) &cmd_firewall_del_bulk_add_string,
1649                 (void *) &cmd_firewall_del_bulk_bulk_string,
1650                 (void *) &cmd_firewall_del_bulk_file_path_string,
1651                 NULL,
1652         },
1653 };
1654
1655 /*
1656  * p firewall add default
1657  */
1658 struct cmd_firewall_add_default_result {
1659         cmdline_fixed_string_t p_string;
1660         uint32_t pipeline_id;
1661         cmdline_fixed_string_t firewall_string;
1662         cmdline_fixed_string_t add_string;
1663         cmdline_fixed_string_t default_string;
1664         uint8_t port_id;
1665 };
1666
1667 static void
1668 cmd_firewall_add_default_parsed(
1669         void *parsed_result,
1670         __attribute__((unused)) struct cmdline *cl,
1671         void *data)
1672 {
1673         struct cmd_firewall_add_default_result *params = parsed_result;
1674         struct app_params *app = data;
1675         int status;
1676
1677         status = app_pipeline_firewall_add_default_rule(app,
1678                 params->pipeline_id,
1679                 params->port_id);
1680
1681         if (status != 0) {
1682                 printf("Command failed\n");
1683                 return;
1684         }
1685 }
1686
1687 cmdline_parse_token_string_t cmd_firewall_add_default_p_string =
1688         TOKEN_STRING_INITIALIZER(struct cmd_firewall_add_default_result,
1689                 p_string, "p");
1690
1691 cmdline_parse_token_num_t cmd_firewall_add_default_pipeline_id =
1692         TOKEN_NUM_INITIALIZER(struct cmd_firewall_add_default_result,
1693                 pipeline_id, UINT32);
1694
1695 cmdline_parse_token_string_t cmd_firewall_add_default_firewall_string =
1696         TOKEN_STRING_INITIALIZER(struct cmd_firewall_add_default_result,
1697         firewall_string, "firewall");
1698
1699 cmdline_parse_token_string_t cmd_firewall_add_default_add_string =
1700         TOKEN_STRING_INITIALIZER(struct cmd_firewall_add_default_result,
1701         add_string, "add");
1702
1703 cmdline_parse_token_string_t cmd_firewall_add_default_default_string =
1704         TOKEN_STRING_INITIALIZER(struct cmd_firewall_add_default_result,
1705                 default_string, "default");
1706
1707 cmdline_parse_token_num_t cmd_firewall_add_default_port_id =
1708         TOKEN_NUM_INITIALIZER(struct cmd_firewall_add_default_result, port_id,
1709                 UINT8);
1710
1711 cmdline_parse_inst_t cmd_firewall_add_default = {
1712         .f = cmd_firewall_add_default_parsed,
1713         .data = NULL,
1714         .help_str = "Firewall default rule add",
1715         .tokens = {
1716                 (void *) &cmd_firewall_add_default_p_string,
1717                 (void *) &cmd_firewall_add_default_pipeline_id,
1718                 (void *) &cmd_firewall_add_default_firewall_string,
1719                 (void *) &cmd_firewall_add_default_add_string,
1720                 (void *) &cmd_firewall_add_default_default_string,
1721                 (void *) &cmd_firewall_add_default_port_id,
1722                 NULL,
1723         },
1724 };
1725
1726 /*
1727  * p firewall del default
1728  */
1729 struct cmd_firewall_del_default_result {
1730         cmdline_fixed_string_t p_string;
1731         uint32_t pipeline_id;
1732         cmdline_fixed_string_t firewall_string;
1733         cmdline_fixed_string_t del_string;
1734         cmdline_fixed_string_t default_string;
1735 };
1736
1737 static void
1738 cmd_firewall_del_default_parsed(
1739         void *parsed_result,
1740         __attribute__((unused)) struct cmdline *cl,
1741         void *data)
1742 {
1743         struct cmd_firewall_del_default_result *params = parsed_result;
1744         struct app_params *app = data;
1745         int status;
1746
1747         status = app_pipeline_firewall_delete_default_rule(app,
1748                 params->pipeline_id);
1749
1750         if (status != 0) {
1751                 printf("Command failed\n");
1752                 return;
1753         }
1754 }
1755
1756 cmdline_parse_token_string_t cmd_firewall_del_default_p_string =
1757         TOKEN_STRING_INITIALIZER(struct cmd_firewall_del_default_result,
1758                 p_string, "p");
1759
1760 cmdline_parse_token_num_t cmd_firewall_del_default_pipeline_id =
1761         TOKEN_NUM_INITIALIZER(struct cmd_firewall_del_default_result,
1762                 pipeline_id, UINT32);
1763
1764 cmdline_parse_token_string_t cmd_firewall_del_default_firewall_string =
1765         TOKEN_STRING_INITIALIZER(struct cmd_firewall_del_default_result,
1766         firewall_string, "firewall");
1767
1768 cmdline_parse_token_string_t cmd_firewall_del_default_del_string =
1769         TOKEN_STRING_INITIALIZER(struct cmd_firewall_del_default_result,
1770                 del_string, "del");
1771
1772 cmdline_parse_token_string_t cmd_firewall_del_default_default_string =
1773         TOKEN_STRING_INITIALIZER(struct cmd_firewall_del_default_result,
1774                 default_string, "default");
1775
1776 cmdline_parse_inst_t cmd_firewall_del_default = {
1777         .f = cmd_firewall_del_default_parsed,
1778         .data = NULL,
1779         .help_str = "Firewall default rule delete",
1780         .tokens = {
1781                 (void *) &cmd_firewall_del_default_p_string,
1782                 (void *) &cmd_firewall_del_default_pipeline_id,
1783                 (void *) &cmd_firewall_del_default_firewall_string,
1784                 (void *) &cmd_firewall_del_default_del_string,
1785                 (void *) &cmd_firewall_del_default_default_string,
1786                 NULL,
1787         },
1788 };
1789
1790 /*
1791  * p firewall ls
1792  */
1793
1794 struct cmd_firewall_ls_result {
1795         cmdline_fixed_string_t p_string;
1796         uint32_t pipeline_id;
1797         cmdline_fixed_string_t firewall_string;
1798         cmdline_fixed_string_t ls_string;
1799 };
1800
1801 static void
1802 cmd_firewall_ls_parsed(
1803         void *parsed_result,
1804         __attribute__((unused)) struct cmdline *cl,
1805         void *data)
1806 {
1807         struct cmd_firewall_ls_result *params = parsed_result;
1808         struct app_params *app = data;
1809         int status;
1810
1811         status = app_pipeline_firewall_ls(app, params->pipeline_id);
1812
1813         if (status != 0) {
1814                 printf("Command failed\n");
1815                 return;
1816         }
1817 }
1818
1819 cmdline_parse_token_string_t cmd_firewall_ls_p_string =
1820         TOKEN_STRING_INITIALIZER(struct cmd_firewall_ls_result, p_string,
1821                 "p");
1822
1823 cmdline_parse_token_num_t cmd_firewall_ls_pipeline_id =
1824         TOKEN_NUM_INITIALIZER(struct cmd_firewall_ls_result, pipeline_id,
1825                 UINT32);
1826
1827 cmdline_parse_token_string_t cmd_firewall_ls_firewall_string =
1828         TOKEN_STRING_INITIALIZER(struct cmd_firewall_ls_result,
1829         firewall_string, "firewall");
1830
1831 cmdline_parse_token_string_t cmd_firewall_ls_ls_string =
1832         TOKEN_STRING_INITIALIZER(struct cmd_firewall_ls_result, ls_string,
1833         "ls");
1834
1835 cmdline_parse_inst_t cmd_firewall_ls = {
1836         .f = cmd_firewall_ls_parsed,
1837         .data = NULL,
1838         .help_str = "Firewall rule list",
1839         .tokens = {
1840                 (void *) &cmd_firewall_ls_p_string,
1841                 (void *) &cmd_firewall_ls_pipeline_id,
1842                 (void *) &cmd_firewall_ls_firewall_string,
1843                 (void *) &cmd_firewall_ls_ls_string,
1844                 NULL,
1845         },
1846 };
1847
1848 static cmdline_parse_ctx_t pipeline_cmds[] = {
1849         (cmdline_parse_inst_t *) &cmd_firewall_add_ipv4,
1850         (cmdline_parse_inst_t *) &cmd_firewall_del_ipv4,
1851         (cmdline_parse_inst_t *) &cmd_firewall_add_bulk,
1852         (cmdline_parse_inst_t *) &cmd_firewall_del_bulk,
1853         (cmdline_parse_inst_t *) &cmd_firewall_add_default,
1854         (cmdline_parse_inst_t *) &cmd_firewall_del_default,
1855         (cmdline_parse_inst_t *) &cmd_firewall_ls,
1856         NULL,
1857 };
1858
1859 static struct pipeline_fe_ops pipeline_firewall_fe_ops = {
1860         .f_init = app_pipeline_firewall_init,
1861         .f_free = app_pipeline_firewall_free,
1862         .cmds = pipeline_cmds,
1863 };
1864
1865 struct pipeline_type pipeline_firewall = {
1866         .name = "FIREWALL",
1867         .be_ops = &pipeline_firewall_be_ops,
1868         .fe_ops = &pipeline_firewall_fe_ops,
1869 };