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