]> git.proxmox.com Git - ceph.git/blob - ceph/src/seastar/dpdk/examples/ip_pipeline/pipeline/pipeline_firewall.c
update sources to ceph Nautilus 14.2.1
[ceph.git] / ceph / src / seastar / dpdk / 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 #include <errno.h>
34 #include <stdio.h>
35 #include <string.h>
36 #include <stdlib.h>
37 #include <unistd.h>
38 #include <sys/queue.h>
39 #include <netinet/in.h>
40
41 #include <rte_common.h>
42 #include <rte_hexdump.h>
43 #include <rte_malloc.h>
44 #include <cmdline_rdline.h>
45 #include <cmdline_parse.h>
46 #include <cmdline_parse_num.h>
47 #include <cmdline_parse_string.h>
48
49 #include "app.h"
50 #include "pipeline_common_fe.h"
51 #include "pipeline_firewall.h"
52 #include "parser.h"
53
54 struct app_pipeline_firewall_rule {
55 struct pipeline_firewall_key key;
56 int32_t priority;
57 uint32_t port_id;
58 void *entry_ptr;
59
60 TAILQ_ENTRY(app_pipeline_firewall_rule) node;
61 };
62
63 struct app_pipeline_firewall {
64 /* parameters */
65 uint32_t n_ports_in;
66 uint32_t n_ports_out;
67
68 /* rules */
69 TAILQ_HEAD(, app_pipeline_firewall_rule) rules;
70 uint32_t n_rules;
71 uint32_t default_rule_present;
72 uint32_t default_rule_port_id;
73 void *default_rule_entry_ptr;
74 };
75
76 static void
77 print_firewall_ipv4_rule(struct app_pipeline_firewall_rule *rule)
78 {
79 printf("Prio = %" PRId32 " (SA = %" PRIu32 ".%" PRIu32
80 ".%" PRIu32 ".%" PRIu32 "/%" PRIu32 ", "
81 "DA = %" PRIu32 ".%" PRIu32
82 ".%"PRIu32 ".%" PRIu32 "/%" PRIu32 ", "
83 "SP = %" PRIu32 "-%" PRIu32 ", "
84 "DP = %" PRIu32 "-%" PRIu32 ", "
85 "Proto = %" PRIu32 " / 0x%" PRIx32 ") => "
86 "Port = %" PRIu32 " (entry ptr = %p)\n",
87
88 rule->priority,
89
90 (rule->key.key.ipv4_5tuple.src_ip >> 24) & 0xFF,
91 (rule->key.key.ipv4_5tuple.src_ip >> 16) & 0xFF,
92 (rule->key.key.ipv4_5tuple.src_ip >> 8) & 0xFF,
93 rule->key.key.ipv4_5tuple.src_ip & 0xFF,
94 rule->key.key.ipv4_5tuple.src_ip_mask,
95
96 (rule->key.key.ipv4_5tuple.dst_ip >> 24) & 0xFF,
97 (rule->key.key.ipv4_5tuple.dst_ip >> 16) & 0xFF,
98 (rule->key.key.ipv4_5tuple.dst_ip >> 8) & 0xFF,
99 rule->key.key.ipv4_5tuple.dst_ip & 0xFF,
100 rule->key.key.ipv4_5tuple.dst_ip_mask,
101
102 rule->key.key.ipv4_5tuple.src_port_from,
103 rule->key.key.ipv4_5tuple.src_port_to,
104
105 rule->key.key.ipv4_5tuple.dst_port_from,
106 rule->key.key.ipv4_5tuple.dst_port_to,
107
108 rule->key.key.ipv4_5tuple.proto,
109 rule->key.key.ipv4_5tuple.proto_mask,
110
111 rule->port_id,
112 rule->entry_ptr);
113 }
114
115 static struct app_pipeline_firewall_rule *
116 app_pipeline_firewall_rule_find(struct app_pipeline_firewall *p,
117 struct pipeline_firewall_key *key)
118 {
119 struct app_pipeline_firewall_rule *r;
120
121 TAILQ_FOREACH(r, &p->rules, node)
122 if (memcmp(key,
123 &r->key,
124 sizeof(struct pipeline_firewall_key)) == 0)
125 return r;
126
127 return NULL;
128 }
129
130 static int
131 app_pipeline_firewall_ls(
132 struct app_params *app,
133 uint32_t pipeline_id)
134 {
135 struct app_pipeline_firewall *p;
136 struct app_pipeline_firewall_rule *rule;
137 uint32_t n_rules;
138 int priority;
139
140 /* Check input arguments */
141 if (app == NULL)
142 return -1;
143
144 p = app_pipeline_data_fe(app, pipeline_id, &pipeline_firewall);
145 if (p == NULL)
146 return -1;
147
148 n_rules = p->n_rules;
149 for (priority = 0; n_rules; priority++)
150 TAILQ_FOREACH(rule, &p->rules, node)
151 if (rule->priority == priority) {
152 print_firewall_ipv4_rule(rule);
153 n_rules--;
154 }
155
156 if (p->default_rule_present)
157 printf("Default rule: port %" PRIu32 " (entry ptr = %p)\n",
158 p->default_rule_port_id,
159 p->default_rule_entry_ptr);
160 else
161 printf("Default rule: DROP\n");
162
163 printf("\n");
164
165 return 0;
166 }
167
168 static void*
169 app_pipeline_firewall_init(struct pipeline_params *params,
170 __rte_unused void *arg)
171 {
172 struct app_pipeline_firewall *p;
173 uint32_t size;
174
175 /* Check input arguments */
176 if ((params == NULL) ||
177 (params->n_ports_in == 0) ||
178 (params->n_ports_out == 0))
179 return NULL;
180
181 /* Memory allocation */
182 size = RTE_CACHE_LINE_ROUNDUP(sizeof(struct app_pipeline_firewall));
183 p = rte_zmalloc(NULL, size, RTE_CACHE_LINE_SIZE);
184 if (p == NULL)
185 return NULL;
186
187 /* Initialization */
188 p->n_ports_in = params->n_ports_in;
189 p->n_ports_out = params->n_ports_out;
190
191 TAILQ_INIT(&p->rules);
192 p->n_rules = 0;
193 p->default_rule_present = 0;
194 p->default_rule_port_id = 0;
195 p->default_rule_entry_ptr = NULL;
196
197 return (void *) p;
198 }
199
200 static int
201 app_pipeline_firewall_free(void *pipeline)
202 {
203 struct app_pipeline_firewall *p = pipeline;
204
205 /* Check input arguments */
206 if (p == NULL)
207 return -1;
208
209 /* Free resources */
210 while (!TAILQ_EMPTY(&p->rules)) {
211 struct app_pipeline_firewall_rule *rule;
212
213 rule = TAILQ_FIRST(&p->rules);
214 TAILQ_REMOVE(&p->rules, rule, node);
215 rte_free(rule);
216 }
217
218 rte_free(p);
219 return 0;
220 }
221
222 static int
223 app_pipeline_firewall_key_check_and_normalize(struct pipeline_firewall_key *key)
224 {
225 switch (key->type) {
226 case PIPELINE_FIREWALL_IPV4_5TUPLE:
227 {
228 uint32_t src_ip_depth = key->key.ipv4_5tuple.src_ip_mask;
229 uint32_t dst_ip_depth = key->key.ipv4_5tuple.dst_ip_mask;
230 uint16_t src_port_from = key->key.ipv4_5tuple.src_port_from;
231 uint16_t src_port_to = key->key.ipv4_5tuple.src_port_to;
232 uint16_t dst_port_from = key->key.ipv4_5tuple.dst_port_from;
233 uint16_t dst_port_to = key->key.ipv4_5tuple.dst_port_to;
234
235 uint32_t src_ip_netmask = 0;
236 uint32_t dst_ip_netmask = 0;
237
238 if ((src_ip_depth > 32) ||
239 (dst_ip_depth > 32) ||
240 (src_port_from > src_port_to) ||
241 (dst_port_from > dst_port_to))
242 return -1;
243
244 if (src_ip_depth)
245 src_ip_netmask = (~0U) << (32 - src_ip_depth);
246
247 if (dst_ip_depth)
248 dst_ip_netmask = ((~0U) << (32 - dst_ip_depth));
249
250 key->key.ipv4_5tuple.src_ip &= src_ip_netmask;
251 key->key.ipv4_5tuple.dst_ip &= dst_ip_netmask;
252
253 return 0;
254 }
255
256 default:
257 return -1;
258 }
259 }
260
261 int
262 app_pipeline_firewall_load_file(char *filename,
263 struct pipeline_firewall_key *keys,
264 uint32_t *priorities,
265 uint32_t *port_ids,
266 uint32_t *n_keys,
267 uint32_t *line)
268 {
269 FILE *f = NULL;
270 char file_buf[1024];
271 uint32_t i, l;
272
273 /* Check input arguments */
274 if ((filename == NULL) ||
275 (keys == NULL) ||
276 (priorities == NULL) ||
277 (port_ids == NULL) ||
278 (n_keys == NULL) ||
279 (*n_keys == 0) ||
280 (line == NULL)) {
281 if (line)
282 *line = 0;
283 return -1;
284 }
285
286 /* Open input file */
287 f = fopen(filename, "r");
288 if (f == NULL) {
289 *line = 0;
290 return -1;
291 }
292
293 /* Read file */
294 for (i = 0, l = 1; i < *n_keys; l++) {
295 char *tokens[32];
296 uint32_t n_tokens = RTE_DIM(tokens);
297
298 uint32_t priority = 0;
299 struct in_addr sipaddr;
300 uint32_t sipdepth = 0;
301 struct in_addr dipaddr;
302 uint32_t dipdepth = 0;
303 uint16_t sport0 = 0;
304 uint16_t sport1 = 0;
305 uint16_t dport0 = 0;
306 uint16_t dport1 = 0;
307 uint8_t proto = 0;
308 uint8_t protomask = 0;
309 uint32_t port_id = 0;
310
311 int status;
312
313 if (fgets(file_buf, sizeof(file_buf), f) == NULL)
314 break;
315
316 status = parse_tokenize_string(file_buf, tokens, &n_tokens);
317 if (status)
318 goto error1;
319
320 if ((n_tokens == 0) || (tokens[0][0] == '#'))
321 continue;
322
323 if ((n_tokens != 15) ||
324 strcmp(tokens[0], "priority") ||
325 parser_read_uint32(&priority, tokens[1]) ||
326 strcmp(tokens[2], "ipv4") ||
327 parse_ipv4_addr(tokens[3], &sipaddr) ||
328 parser_read_uint32(&sipdepth, tokens[4]) ||
329 parse_ipv4_addr(tokens[5], &dipaddr) ||
330 parser_read_uint32(&dipdepth, tokens[6]) ||
331 parser_read_uint16(&sport0, tokens[7]) ||
332 parser_read_uint16(&sport1, tokens[8]) ||
333 parser_read_uint16(&dport0, tokens[9]) ||
334 parser_read_uint16(&dport1, tokens[10]) ||
335 parser_read_uint8(&proto, tokens[11]) ||
336 parser_read_uint8_hex(&protomask, tokens[12]) ||
337 strcmp(tokens[13], "port") ||
338 parser_read_uint32(&port_id, tokens[14]))
339 goto error1;
340
341 keys[i].type = PIPELINE_FIREWALL_IPV4_5TUPLE;
342 keys[i].key.ipv4_5tuple.src_ip =
343 rte_be_to_cpu_32(sipaddr.s_addr);
344 keys[i].key.ipv4_5tuple.src_ip_mask = sipdepth;
345 keys[i].key.ipv4_5tuple.dst_ip =
346 rte_be_to_cpu_32(dipaddr.s_addr);
347 keys[i].key.ipv4_5tuple.dst_ip_mask = dipdepth;
348 keys[i].key.ipv4_5tuple.src_port_from = sport0;
349 keys[i].key.ipv4_5tuple.src_port_to = sport1;
350 keys[i].key.ipv4_5tuple.dst_port_from = dport0;
351 keys[i].key.ipv4_5tuple.dst_port_to = dport1;
352 keys[i].key.ipv4_5tuple.proto = proto;
353 keys[i].key.ipv4_5tuple.proto_mask = protomask;
354
355 port_ids[i] = port_id;
356 priorities[i] = priority;
357
358 if (app_pipeline_firewall_key_check_and_normalize(&keys[i]))
359 goto error1;
360
361 i++;
362 }
363
364 /* Close file */
365 *n_keys = i;
366 fclose(f);
367 return 0;
368
369 error1:
370 *line = l;
371 fclose(f);
372 return -1;
373 }
374
375 int
376 app_pipeline_firewall_add_rule(struct app_params *app,
377 uint32_t pipeline_id,
378 struct pipeline_firewall_key *key,
379 uint32_t priority,
380 uint32_t port_id)
381 {
382 struct app_pipeline_firewall *p;
383 struct app_pipeline_firewall_rule *rule;
384 struct pipeline_firewall_add_msg_req *req;
385 struct pipeline_firewall_add_msg_rsp *rsp;
386 int new_rule;
387
388 /* Check input arguments */
389 if ((app == NULL) ||
390 (key == NULL) ||
391 (key->type != PIPELINE_FIREWALL_IPV4_5TUPLE))
392 return -1;
393
394 p = app_pipeline_data_fe(app, pipeline_id, &pipeline_firewall);
395 if (p == NULL)
396 return -1;
397
398 if (port_id >= p->n_ports_out)
399 return -1;
400
401 if (app_pipeline_firewall_key_check_and_normalize(key) != 0)
402 return -1;
403
404 /* Find existing rule or allocate new rule */
405 rule = app_pipeline_firewall_rule_find(p, key);
406 new_rule = (rule == NULL);
407 if (rule == NULL) {
408 rule = rte_malloc(NULL, sizeof(*rule), RTE_CACHE_LINE_SIZE);
409
410 if (rule == NULL)
411 return -1;
412 }
413
414 /* Allocate and write request */
415 req = app_msg_alloc(app);
416 if (req == NULL) {
417 if (new_rule)
418 rte_free(rule);
419 return -1;
420 }
421
422 req->type = PIPELINE_MSG_REQ_CUSTOM;
423 req->subtype = PIPELINE_FIREWALL_MSG_REQ_ADD;
424 memcpy(&req->key, key, sizeof(*key));
425 req->priority = priority;
426 req->port_id = port_id;
427
428 /* Send request and wait for response */
429 rsp = app_msg_send_recv(app, pipeline_id, req, MSG_TIMEOUT_DEFAULT);
430 if (rsp == NULL) {
431 if (new_rule)
432 rte_free(rule);
433 return -1;
434 }
435
436 /* Read response and write rule */
437 if (rsp->status ||
438 (rsp->entry_ptr == NULL) ||
439 ((new_rule == 0) && (rsp->key_found == 0)) ||
440 ((new_rule == 1) && (rsp->key_found == 1))) {
441 app_msg_free(app, rsp);
442 if (new_rule)
443 rte_free(rule);
444 return -1;
445 }
446
447 memcpy(&rule->key, key, sizeof(*key));
448 rule->priority = priority;
449 rule->port_id = port_id;
450 rule->entry_ptr = rsp->entry_ptr;
451
452 /* Commit rule */
453 if (new_rule) {
454 TAILQ_INSERT_TAIL(&p->rules, rule, node);
455 p->n_rules++;
456 }
457
458 print_firewall_ipv4_rule(rule);
459
460 /* Free response */
461 app_msg_free(app, rsp);
462
463 return 0;
464 }
465
466 int
467 app_pipeline_firewall_delete_rule(struct app_params *app,
468 uint32_t pipeline_id,
469 struct pipeline_firewall_key *key)
470 {
471 struct app_pipeline_firewall *p;
472 struct app_pipeline_firewall_rule *rule;
473 struct pipeline_firewall_del_msg_req *req;
474 struct pipeline_firewall_del_msg_rsp *rsp;
475
476 /* Check input arguments */
477 if ((app == NULL) ||
478 (key == NULL) ||
479 (key->type != PIPELINE_FIREWALL_IPV4_5TUPLE))
480 return -1;
481
482 p = app_pipeline_data_fe(app, pipeline_id, &pipeline_firewall);
483 if (p == NULL)
484 return -1;
485
486 if (app_pipeline_firewall_key_check_and_normalize(key) != 0)
487 return -1;
488
489 /* Find rule */
490 rule = app_pipeline_firewall_rule_find(p, key);
491 if (rule == NULL)
492 return 0;
493
494 /* Allocate and write request */
495 req = app_msg_alloc(app);
496 if (req == NULL)
497 return -1;
498
499 req->type = PIPELINE_MSG_REQ_CUSTOM;
500 req->subtype = PIPELINE_FIREWALL_MSG_REQ_DEL;
501 memcpy(&req->key, key, sizeof(*key));
502
503 /* Send request and wait for response */
504 rsp = app_msg_send_recv(app, pipeline_id, req, MSG_TIMEOUT_DEFAULT);
505 if (rsp == NULL)
506 return -1;
507
508 /* Read response */
509 if (rsp->status || !rsp->key_found) {
510 app_msg_free(app, rsp);
511 return -1;
512 }
513
514 /* Remove rule */
515 TAILQ_REMOVE(&p->rules, rule, node);
516 p->n_rules--;
517 rte_free(rule);
518
519 /* Free response */
520 app_msg_free(app, rsp);
521
522 return 0;
523 }
524
525 int
526 app_pipeline_firewall_add_bulk(struct app_params *app,
527 uint32_t pipeline_id,
528 struct pipeline_firewall_key *keys,
529 uint32_t n_keys,
530 uint32_t *priorities,
531 uint32_t *port_ids)
532 {
533 struct app_pipeline_firewall *p;
534 struct pipeline_firewall_add_bulk_msg_req *req;
535 struct pipeline_firewall_add_bulk_msg_rsp *rsp;
536
537 struct app_pipeline_firewall_rule **rules;
538 int *new_rules;
539
540 int *keys_found;
541 void **entries_ptr;
542
543 uint32_t i;
544 int status = 0;
545
546 /* Check input arguments */
547 if (app == NULL)
548 return -1;
549
550 p = app_pipeline_data_fe(app, pipeline_id, &pipeline_firewall);
551 if (p == NULL)
552 return -1;
553
554 rules = rte_malloc(NULL,
555 n_keys * sizeof(struct app_pipeline_firewall_rule *),
556 RTE_CACHE_LINE_SIZE);
557 if (rules == NULL)
558 return -1;
559
560 new_rules = rte_malloc(NULL,
561 n_keys * sizeof(int),
562 RTE_CACHE_LINE_SIZE);
563 if (new_rules == NULL) {
564 rte_free(rules);
565 return -1;
566 }
567
568 /* check data integrity and add to rule list */
569 for (i = 0; i < n_keys; i++) {
570 if (port_ids[i] >= p->n_ports_out) {
571 rte_free(rules);
572 rte_free(new_rules);
573 return -1;
574 }
575
576 if (app_pipeline_firewall_key_check_and_normalize(&keys[i]) != 0) {
577 rte_free(rules);
578 rte_free(new_rules);
579 return -1;
580 }
581
582 rules[i] = app_pipeline_firewall_rule_find(p, &keys[i]);
583 new_rules[i] = (rules[i] == NULL);
584 if (rules[i] == NULL) {
585 rules[i] = rte_malloc(NULL,
586 sizeof(*rules[i]),
587 RTE_CACHE_LINE_SIZE);
588
589 if (rules[i] == NULL) {
590 uint32_t j;
591
592 for (j = 0; j <= i; j++)
593 if (new_rules[j])
594 rte_free(rules[j]);
595
596 rte_free(rules);
597 rte_free(new_rules);
598 return -1;
599 }
600 }
601 }
602
603 keys_found = rte_malloc(NULL,
604 n_keys * sizeof(int),
605 RTE_CACHE_LINE_SIZE);
606 if (keys_found == NULL) {
607 uint32_t j;
608
609 for (j = 0; j < n_keys; j++)
610 if (new_rules[j])
611 rte_free(rules[j]);
612
613 rte_free(rules);
614 rte_free(new_rules);
615 return -1;
616 }
617
618 entries_ptr = rte_malloc(NULL,
619 n_keys * sizeof(struct rte_pipeline_table_entry *),
620 RTE_CACHE_LINE_SIZE);
621 if (entries_ptr == NULL) {
622 uint32_t j;
623
624 for (j = 0; j < n_keys; j++)
625 if (new_rules[j])
626 rte_free(rules[j]);
627
628 rte_free(rules);
629 rte_free(new_rules);
630 rte_free(keys_found);
631 return -1;
632 }
633 for (i = 0; i < n_keys; i++) {
634 entries_ptr[i] = rte_malloc(NULL,
635 sizeof(struct rte_pipeline_table_entry),
636 RTE_CACHE_LINE_SIZE);
637
638 if (entries_ptr[i] == NULL) {
639 uint32_t j;
640
641 for (j = 0; j < n_keys; j++)
642 if (new_rules[j])
643 rte_free(rules[j]);
644
645 for (j = 0; j <= i; j++)
646 rte_free(entries_ptr[j]);
647
648 rte_free(rules);
649 rte_free(new_rules);
650 rte_free(keys_found);
651 rte_free(entries_ptr);
652 return -1;
653 }
654 }
655
656 /* Allocate and write request */
657 req = app_msg_alloc(app);
658 if (req == NULL) {
659 uint32_t j;
660
661 for (j = 0; j < n_keys; j++)
662 if (new_rules[j])
663 rte_free(rules[j]);
664
665 for (j = 0; j < n_keys; j++)
666 rte_free(entries_ptr[j]);
667
668 rte_free(rules);
669 rte_free(new_rules);
670 rte_free(keys_found);
671 rte_free(entries_ptr);
672 return -1;
673 }
674
675 req->type = PIPELINE_MSG_REQ_CUSTOM;
676 req->subtype = PIPELINE_FIREWALL_MSG_REQ_ADD_BULK;
677
678 req->keys = keys;
679 req->n_keys = n_keys;
680 req->port_ids = port_ids;
681 req->priorities = priorities;
682 req->keys_found = keys_found;
683 req->entries_ptr = entries_ptr;
684
685 /* Send request and wait for response */
686 rsp = app_msg_send_recv(app, pipeline_id, req, MSG_TIMEOUT_DEFAULT);
687 if (rsp == NULL) {
688 uint32_t j;
689
690 for (j = 0; j < n_keys; j++)
691 if (new_rules[j])
692 rte_free(rules[j]);
693
694 for (j = 0; j < n_keys; j++)
695 rte_free(entries_ptr[j]);
696
697 rte_free(rules);
698 rte_free(new_rules);
699 rte_free(keys_found);
700 rte_free(entries_ptr);
701 return -1;
702 }
703
704 if (rsp->status) {
705 for (i = 0; i < n_keys; i++)
706 if (new_rules[i])
707 rte_free(rules[i]);
708
709 for (i = 0; i < n_keys; i++)
710 rte_free(entries_ptr[i]);
711
712 status = -1;
713 goto cleanup;
714 }
715
716 for (i = 0; i < n_keys; i++) {
717 if (entries_ptr[i] == NULL ||
718 ((new_rules[i] == 0) && (keys_found[i] == 0)) ||
719 ((new_rules[i] == 1) && (keys_found[i] == 1))) {
720 for (i = 0; i < n_keys; i++)
721 if (new_rules[i])
722 rte_free(rules[i]);
723
724 for (i = 0; i < n_keys; i++)
725 rte_free(entries_ptr[i]);
726
727 status = -1;
728 goto cleanup;
729 }
730 }
731
732 for (i = 0; i < n_keys; i++) {
733 memcpy(&rules[i]->key, &keys[i], sizeof(keys[i]));
734 rules[i]->priority = priorities[i];
735 rules[i]->port_id = port_ids[i];
736 rules[i]->entry_ptr = entries_ptr[i];
737
738 /* Commit rule */
739 if (new_rules[i]) {
740 TAILQ_INSERT_TAIL(&p->rules, rules[i], node);
741 p->n_rules++;
742 }
743
744 print_firewall_ipv4_rule(rules[i]);
745 }
746
747 cleanup:
748 app_msg_free(app, rsp);
749 rte_free(rules);
750 rte_free(new_rules);
751 rte_free(keys_found);
752 rte_free(entries_ptr);
753
754 return status;
755 }
756
757 int
758 app_pipeline_firewall_delete_bulk(struct app_params *app,
759 uint32_t pipeline_id,
760 struct pipeline_firewall_key *keys,
761 uint32_t n_keys)
762 {
763 struct app_pipeline_firewall *p;
764 struct pipeline_firewall_del_bulk_msg_req *req;
765 struct pipeline_firewall_del_bulk_msg_rsp *rsp;
766
767 struct app_pipeline_firewall_rule **rules;
768 int *keys_found;
769
770 uint32_t i;
771 int status = 0;
772
773 /* Check input arguments */
774 if (app == NULL)
775 return -1;
776
777 p = app_pipeline_data_fe(app, pipeline_id, &pipeline_firewall);
778 if (p == NULL)
779 return -1;
780
781 rules = rte_malloc(NULL,
782 n_keys * sizeof(struct app_pipeline_firewall_rule *),
783 RTE_CACHE_LINE_SIZE);
784 if (rules == NULL)
785 return -1;
786
787 for (i = 0; i < n_keys; i++) {
788 if (app_pipeline_firewall_key_check_and_normalize(&keys[i]) != 0) {
789 return -1;
790 }
791
792 rules[i] = app_pipeline_firewall_rule_find(p, &keys[i]);
793 }
794
795 keys_found = rte_malloc(NULL,
796 n_keys * sizeof(int),
797 RTE_CACHE_LINE_SIZE);
798 if (keys_found == NULL) {
799 rte_free(rules);
800 return -1;
801 }
802
803 /* Allocate and write request */
804 req = app_msg_alloc(app);
805 if (req == NULL) {
806 rte_free(rules);
807 rte_free(keys_found);
808 return -1;
809 }
810
811 req->type = PIPELINE_MSG_REQ_CUSTOM;
812 req->subtype = PIPELINE_FIREWALL_MSG_REQ_DEL_BULK;
813
814 req->keys = keys;
815 req->n_keys = n_keys;
816 req->keys_found = keys_found;
817
818 /* Send request and wait for response */
819 rsp = app_msg_send_recv(app, pipeline_id, req, MSG_TIMEOUT_DEFAULT);
820 if (rsp == NULL) {
821 rte_free(rules);
822 rte_free(keys_found);
823 return -1;
824 }
825
826 if (rsp->status) {
827 status = -1;
828 goto cleanup;
829 }
830
831 for (i = 0; i < n_keys; i++) {
832 if (keys_found[i] == 0) {
833 status = -1;
834 goto cleanup;
835 }
836 }
837
838 for (i = 0; i < n_keys; i++) {
839 TAILQ_REMOVE(&p->rules, rules[i], node);
840 p->n_rules--;
841 rte_free(rules[i]);
842 }
843
844 cleanup:
845 app_msg_free(app, rsp);
846 rte_free(rules);
847 rte_free(keys_found);
848
849 return status;
850 }
851
852 int
853 app_pipeline_firewall_add_default_rule(struct app_params *app,
854 uint32_t pipeline_id,
855 uint32_t port_id)
856 {
857 struct app_pipeline_firewall *p;
858 struct pipeline_firewall_add_default_msg_req *req;
859 struct pipeline_firewall_add_default_msg_rsp *rsp;
860
861 /* Check input arguments */
862 if (app == NULL)
863 return -1;
864
865 p = app_pipeline_data_fe(app, pipeline_id, &pipeline_firewall);
866 if (p == NULL)
867 return -1;
868
869 if (port_id >= p->n_ports_out)
870 return -1;
871
872 /* Allocate and write request */
873 req = app_msg_alloc(app);
874 if (req == NULL)
875 return -1;
876
877 req->type = PIPELINE_MSG_REQ_CUSTOM;
878 req->subtype = PIPELINE_FIREWALL_MSG_REQ_ADD_DEFAULT;
879 req->port_id = port_id;
880
881 /* Send request and wait for response */
882 rsp = app_msg_send_recv(app, pipeline_id, req, MSG_TIMEOUT_DEFAULT);
883 if (rsp == NULL)
884 return -1;
885
886 /* Read response and write rule */
887 if (rsp->status || (rsp->entry_ptr == NULL)) {
888 app_msg_free(app, rsp);
889 return -1;
890 }
891
892 p->default_rule_port_id = port_id;
893 p->default_rule_entry_ptr = rsp->entry_ptr;
894
895 /* Commit rule */
896 p->default_rule_present = 1;
897
898 /* Free response */
899 app_msg_free(app, rsp);
900
901 return 0;
902 }
903
904 int
905 app_pipeline_firewall_delete_default_rule(struct app_params *app,
906 uint32_t pipeline_id)
907 {
908 struct app_pipeline_firewall *p;
909 struct pipeline_firewall_del_default_msg_req *req;
910 struct pipeline_firewall_del_default_msg_rsp *rsp;
911
912 /* Check input arguments */
913 if (app == NULL)
914 return -1;
915
916 p = app_pipeline_data_fe(app, pipeline_id, &pipeline_firewall);
917 if (p == NULL)
918 return -1;
919
920 /* Allocate and write request */
921 req = app_msg_alloc(app);
922 if (req == NULL)
923 return -1;
924
925 req->type = PIPELINE_MSG_REQ_CUSTOM;
926 req->subtype = PIPELINE_FIREWALL_MSG_REQ_DEL_DEFAULT;
927
928 /* Send request and wait for response */
929 rsp = app_msg_send_recv(app, pipeline_id, req, MSG_TIMEOUT_DEFAULT);
930 if (rsp == NULL)
931 return -1;
932
933 /* Read response and write rule */
934 if (rsp->status) {
935 app_msg_free(app, rsp);
936 return -1;
937 }
938
939 /* Commit rule */
940 p->default_rule_present = 0;
941
942 /* Free response */
943 app_msg_free(app, rsp);
944
945 return 0;
946 }
947
948 /*
949 * firewall
950 *
951 * firewall add:
952 * p <pipelineid> firewall add priority <priority>
953 * ipv4 <sipaddr> <sipdepth> <dipaddr> <dipdepth>
954 * <sport0> <sport1> <dport0> <dport1> <proto> <protomask>
955 * port <portid>
956 * Note: <protomask> is a hex value
957 *
958 * p <pipelineid> firewall add bulk <file>
959 *
960 * firewall add default:
961 * p <pipelineid> firewall add default <port ID>
962 *
963 * firewall del:
964 * p <pipelineid> firewall del
965 * ipv4 <sipaddr> <sipdepth> <dipaddr> <dipdepth>
966 * <sport0> <sport1> <dport0> <dport1> <proto> <protomask>
967 *
968 * p <pipelineid> firewall del bulk <file>
969 *
970 * firewall del default:
971 * p <pipelineid> firewall del default
972 *
973 * firewall ls:
974 * p <pipelineid> firewall ls
975 */
976
977 struct cmd_firewall_result {
978 cmdline_fixed_string_t p_string;
979 uint32_t pipeline_id;
980 cmdline_fixed_string_t firewall_string;
981 cmdline_multi_string_t multi_string;
982 };
983
984 static void cmd_firewall_parsed(void *parsed_result,
985 __attribute__((unused)) struct cmdline *cl,
986 void *data)
987 {
988 struct cmd_firewall_result *params = parsed_result;
989 struct app_params *app = data;
990 int status;
991
992 char *tokens[17];
993 uint32_t n_tokens = RTE_DIM(tokens);
994
995 status = parse_tokenize_string(params->multi_string, tokens, &n_tokens);
996 if (status) {
997 printf(CMD_MSG_TOO_MANY_ARGS, "firewall");
998 return;
999 }
1000
1001 /* firewall add */
1002 if ((n_tokens >= 2) &&
1003 (strcmp(tokens[0], "add") == 0) &&
1004 (strcmp(tokens[1], "priority") == 0)) {
1005 struct pipeline_firewall_key key;
1006 uint32_t priority;
1007 struct in_addr sipaddr;
1008 uint32_t sipdepth;
1009 struct in_addr dipaddr;
1010 uint32_t dipdepth;
1011 uint16_t sport0;
1012 uint16_t sport1;
1013 uint16_t dport0;
1014 uint16_t dport1;
1015 uint8_t proto;
1016 uint8_t protomask;
1017 uint32_t port_id;
1018
1019 memset(&key, 0, sizeof(key));
1020
1021 if (n_tokens != 16) {
1022 printf(CMD_MSG_MISMATCH_ARGS, "firewall add");
1023 return;
1024 }
1025
1026 if (parser_read_uint32(&priority, tokens[2])) {
1027 printf(CMD_MSG_INVALID_ARG, "priority");
1028 return;
1029 }
1030
1031 if (strcmp(tokens[3], "ipv4")) {
1032 printf(CMD_MSG_ARG_NOT_FOUND, "ipv4");
1033 return;
1034 }
1035
1036 if (parse_ipv4_addr(tokens[4], &sipaddr)) {
1037 printf(CMD_MSG_INVALID_ARG, "sipaddr");
1038 return;
1039 }
1040
1041 if (parser_read_uint32(&sipdepth, tokens[5])) {
1042 printf(CMD_MSG_INVALID_ARG, "sipdepth");
1043 return;
1044 }
1045
1046 if (parse_ipv4_addr(tokens[6], &dipaddr)) {
1047 printf(CMD_MSG_INVALID_ARG, "dipaddr");
1048 return;
1049 }
1050
1051 if (parser_read_uint32(&dipdepth, tokens[7])) {
1052 printf(CMD_MSG_INVALID_ARG, "dipdepth");
1053 return;
1054 }
1055
1056 if (parser_read_uint16(&sport0, tokens[8])) {
1057 printf(CMD_MSG_INVALID_ARG, "sport0");
1058 return;
1059 }
1060
1061 if (parser_read_uint16(&sport1, tokens[9])) {
1062 printf(CMD_MSG_INVALID_ARG, "sport1");
1063 return;
1064 }
1065
1066 if (parser_read_uint16(&dport0, tokens[10])) {
1067 printf(CMD_MSG_INVALID_ARG, "dport0");
1068 return;
1069 }
1070
1071 if (parser_read_uint16(&dport1, tokens[11])) {
1072 printf(CMD_MSG_INVALID_ARG, "dport1");
1073 return;
1074 }
1075
1076 if (parser_read_uint8(&proto, tokens[12])) {
1077 printf(CMD_MSG_INVALID_ARG, "proto");
1078 return;
1079 }
1080
1081 if (parser_read_uint8_hex(&protomask, tokens[13])) {
1082 printf(CMD_MSG_INVALID_ARG, "protomask");
1083 return;
1084 }
1085
1086 if (strcmp(tokens[14], "port")) {
1087 printf(CMD_MSG_ARG_NOT_FOUND, "port");
1088 return;
1089 }
1090
1091 if (parser_read_uint32(&port_id, tokens[15])) {
1092 printf(CMD_MSG_INVALID_ARG, "portid");
1093 return;
1094 }
1095
1096 key.type = PIPELINE_FIREWALL_IPV4_5TUPLE;
1097 key.key.ipv4_5tuple.src_ip = rte_be_to_cpu_32(sipaddr.s_addr);
1098 key.key.ipv4_5tuple.src_ip_mask = sipdepth;
1099 key.key.ipv4_5tuple.dst_ip = rte_be_to_cpu_32(dipaddr.s_addr);
1100 key.key.ipv4_5tuple.dst_ip_mask = dipdepth;
1101 key.key.ipv4_5tuple.src_port_from = sport0;
1102 key.key.ipv4_5tuple.src_port_to = sport1;
1103 key.key.ipv4_5tuple.dst_port_from = dport0;
1104 key.key.ipv4_5tuple.dst_port_to = dport1;
1105 key.key.ipv4_5tuple.proto = proto;
1106 key.key.ipv4_5tuple.proto_mask = protomask;
1107
1108 status = app_pipeline_firewall_add_rule(app,
1109 params->pipeline_id,
1110 &key,
1111 priority,
1112 port_id);
1113 if (status)
1114 printf(CMD_MSG_FAIL, "firewall add");
1115
1116 return;
1117 } /* firewall add */
1118
1119 /* firewall add bulk */
1120 if ((n_tokens >= 2) &&
1121 (strcmp(tokens[0], "add") == 0) &&
1122 (strcmp(tokens[1], "bulk") == 0)) {
1123 struct pipeline_firewall_key *keys;
1124 uint32_t *priorities, *port_ids, n_keys, line;
1125 char *filename;
1126
1127 if (n_tokens != 3) {
1128 printf(CMD_MSG_MISMATCH_ARGS, "firewall add bulk");
1129 return;
1130 }
1131
1132 filename = tokens[2];
1133
1134 n_keys = APP_PIPELINE_FIREWALL_MAX_RULES_IN_FILE;
1135 keys = malloc(n_keys * sizeof(struct pipeline_firewall_key));
1136 if (keys == NULL) {
1137 printf(CMD_MSG_OUT_OF_MEMORY);
1138 return;
1139 }
1140 memset(keys, 0, n_keys * sizeof(struct pipeline_firewall_key));
1141
1142 priorities = malloc(n_keys * sizeof(uint32_t));
1143 if (priorities == NULL) {
1144 printf(CMD_MSG_OUT_OF_MEMORY);
1145 free(keys);
1146 return;
1147 }
1148
1149 port_ids = malloc(n_keys * sizeof(uint32_t));
1150 if (port_ids == NULL) {
1151 printf(CMD_MSG_OUT_OF_MEMORY);
1152 free(priorities);
1153 free(keys);
1154 return;
1155 }
1156
1157 status = app_pipeline_firewall_load_file(filename,
1158 keys,
1159 priorities,
1160 port_ids,
1161 &n_keys,
1162 &line);
1163 if (status != 0) {
1164 printf(CMD_MSG_FILE_ERR, filename, line);
1165 free(port_ids);
1166 free(priorities);
1167 free(keys);
1168 return;
1169 }
1170
1171 status = app_pipeline_firewall_add_bulk(app,
1172 params->pipeline_id,
1173 keys,
1174 n_keys,
1175 priorities,
1176 port_ids);
1177 if (status)
1178 printf(CMD_MSG_FAIL, "firewall add bulk");
1179
1180 free(keys);
1181 free(priorities);
1182 free(port_ids);
1183 return;
1184 } /* firewall add bulk */
1185
1186 /* firewall add default */
1187 if ((n_tokens >= 2) &&
1188 (strcmp(tokens[0], "add") == 0) &&
1189 (strcmp(tokens[1], "default") == 0)) {
1190 uint32_t port_id;
1191
1192 if (n_tokens != 3) {
1193 printf(CMD_MSG_MISMATCH_ARGS, "firewall add default");
1194 return;
1195 }
1196
1197 if (parser_read_uint32(&port_id, tokens[2])) {
1198 printf(CMD_MSG_INVALID_ARG, "portid");
1199 return;
1200 }
1201
1202 status = app_pipeline_firewall_add_default_rule(app,
1203 params->pipeline_id,
1204 port_id);
1205 if (status)
1206 printf(CMD_MSG_FAIL, "firewall add default");
1207
1208 return;
1209 } /* firewall add default */
1210
1211 /* firewall del */
1212 if ((n_tokens >= 2) &&
1213 (strcmp(tokens[0], "del") == 0) &&
1214 (strcmp(tokens[1], "ipv4") == 0)) {
1215 struct pipeline_firewall_key key;
1216 struct in_addr sipaddr;
1217 uint32_t sipdepth;
1218 struct in_addr dipaddr;
1219 uint32_t dipdepth;
1220 uint16_t sport0;
1221 uint16_t sport1;
1222 uint16_t dport0;
1223 uint16_t dport1;
1224 uint8_t proto;
1225 uint8_t protomask;
1226
1227 memset(&key, 0, sizeof(key));
1228
1229 if (n_tokens != 12) {
1230 printf(CMD_MSG_MISMATCH_ARGS, "firewall del");
1231 return;
1232 }
1233
1234 if (parse_ipv4_addr(tokens[2], &sipaddr)) {
1235 printf(CMD_MSG_INVALID_ARG, "sipaddr");
1236 return;
1237 }
1238
1239 if (parser_read_uint32(&sipdepth, tokens[3])) {
1240 printf(CMD_MSG_INVALID_ARG, "sipdepth");
1241 return;
1242 }
1243
1244 if (parse_ipv4_addr(tokens[4], &dipaddr)) {
1245 printf(CMD_MSG_INVALID_ARG, "dipaddr");
1246 return;
1247 }
1248
1249 if (parser_read_uint32(&dipdepth, tokens[5])) {
1250 printf(CMD_MSG_INVALID_ARG, "dipdepth");
1251 return;
1252 }
1253
1254 if (parser_read_uint16(&sport0, tokens[6])) {
1255 printf(CMD_MSG_INVALID_ARG, "sport0");
1256 return;
1257 }
1258
1259 if (parser_read_uint16(&sport1, tokens[7])) {
1260 printf(CMD_MSG_INVALID_ARG, "sport1");
1261 return;
1262 }
1263
1264 if (parser_read_uint16(&dport0, tokens[8])) {
1265 printf(CMD_MSG_INVALID_ARG, "dport0");
1266 return;
1267 }
1268
1269 if (parser_read_uint16(&dport1, tokens[9])) {
1270 printf(CMD_MSG_INVALID_ARG, "dport1");
1271 return;
1272 }
1273
1274 if (parser_read_uint8(&proto, tokens[10])) {
1275 printf(CMD_MSG_INVALID_ARG, "proto");
1276 return;
1277 }
1278
1279 if (parser_read_uint8_hex(&protomask, tokens[11])) {
1280 printf(CMD_MSG_INVALID_ARG, "protomask");
1281 return;
1282 }
1283
1284 key.type = PIPELINE_FIREWALL_IPV4_5TUPLE;
1285 key.key.ipv4_5tuple.src_ip = rte_be_to_cpu_32(sipaddr.s_addr);
1286 key.key.ipv4_5tuple.src_ip_mask = sipdepth;
1287 key.key.ipv4_5tuple.dst_ip = rte_be_to_cpu_32(dipaddr.s_addr);
1288 key.key.ipv4_5tuple.dst_ip_mask = dipdepth;
1289 key.key.ipv4_5tuple.src_port_from = sport0;
1290 key.key.ipv4_5tuple.src_port_to = sport1;
1291 key.key.ipv4_5tuple.dst_port_from = dport0;
1292 key.key.ipv4_5tuple.dst_port_to = dport1;
1293 key.key.ipv4_5tuple.proto = proto;
1294 key.key.ipv4_5tuple.proto_mask = protomask;
1295
1296 status = app_pipeline_firewall_delete_rule(app,
1297 params->pipeline_id,
1298 &key);
1299 if (status)
1300 printf(CMD_MSG_FAIL, "firewall del");
1301
1302 return;
1303 } /* firewall del */
1304
1305 /* firewall del bulk */
1306 if ((n_tokens >= 2) &&
1307 (strcmp(tokens[0], "del") == 0) &&
1308 (strcmp(tokens[1], "bulk") == 0)) {
1309 struct pipeline_firewall_key *keys;
1310 uint32_t *priorities, *port_ids, n_keys, line;
1311 char *filename;
1312
1313 if (n_tokens != 3) {
1314 printf(CMD_MSG_MISMATCH_ARGS, "firewall del bulk");
1315 return;
1316 }
1317
1318 filename = tokens[2];
1319
1320 n_keys = APP_PIPELINE_FIREWALL_MAX_RULES_IN_FILE;
1321 keys = malloc(n_keys * sizeof(struct pipeline_firewall_key));
1322 if (keys == NULL) {
1323 printf(CMD_MSG_OUT_OF_MEMORY);
1324 return;
1325 }
1326 memset(keys, 0, n_keys * sizeof(struct pipeline_firewall_key));
1327
1328 priorities = malloc(n_keys * sizeof(uint32_t));
1329 if (priorities == NULL) {
1330 printf(CMD_MSG_OUT_OF_MEMORY);
1331 free(keys);
1332 return;
1333 }
1334
1335 port_ids = malloc(n_keys * sizeof(uint32_t));
1336 if (port_ids == NULL) {
1337 printf(CMD_MSG_OUT_OF_MEMORY);
1338 free(priorities);
1339 free(keys);
1340 return;
1341 }
1342
1343 status = app_pipeline_firewall_load_file(filename,
1344 keys,
1345 priorities,
1346 port_ids,
1347 &n_keys,
1348 &line);
1349 if (status != 0) {
1350 printf(CMD_MSG_FILE_ERR, filename, line);
1351 free(port_ids);
1352 free(priorities);
1353 free(keys);
1354 return;
1355 }
1356
1357 status = app_pipeline_firewall_delete_bulk(app,
1358 params->pipeline_id,
1359 keys,
1360 n_keys);
1361 if (status)
1362 printf(CMD_MSG_FAIL, "firewall del bulk");
1363
1364 free(port_ids);
1365 free(priorities);
1366 free(keys);
1367 return;
1368 } /* firewall del bulk */
1369
1370 /* firewall del default */
1371 if ((n_tokens >= 2) &&
1372 (strcmp(tokens[0], "del") == 0) &&
1373 (strcmp(tokens[1], "default") == 0)) {
1374 if (n_tokens != 2) {
1375 printf(CMD_MSG_MISMATCH_ARGS, "firewall del default");
1376 return;
1377 }
1378
1379 status = app_pipeline_firewall_delete_default_rule(app,
1380 params->pipeline_id);
1381 if (status)
1382 printf(CMD_MSG_FAIL, "firewall del default");
1383
1384 return;
1385
1386 } /* firewall del default */
1387
1388 /* firewall ls */
1389 if ((n_tokens >= 1) && (strcmp(tokens[0], "ls") == 0)) {
1390 if (n_tokens != 1) {
1391 printf(CMD_MSG_MISMATCH_ARGS, "firewall ls");
1392 return;
1393 }
1394
1395 status = app_pipeline_firewall_ls(app, params->pipeline_id);
1396 if (status)
1397 printf(CMD_MSG_FAIL, "firewall ls");
1398
1399 return;
1400 } /* firewall ls */
1401
1402 printf(CMD_MSG_MISMATCH_ARGS, "firewall");
1403 }
1404
1405 static cmdline_parse_token_string_t cmd_firewall_p_string =
1406 TOKEN_STRING_INITIALIZER(struct cmd_firewall_result, p_string, "p");
1407
1408 static cmdline_parse_token_num_t cmd_firewall_pipeline_id =
1409 TOKEN_NUM_INITIALIZER(struct cmd_firewall_result, pipeline_id, UINT32);
1410
1411 static cmdline_parse_token_string_t cmd_firewall_firewall_string =
1412 TOKEN_STRING_INITIALIZER(struct cmd_firewall_result, firewall_string,
1413 "firewall");
1414
1415 static cmdline_parse_token_string_t cmd_firewall_multi_string =
1416 TOKEN_STRING_INITIALIZER(struct cmd_firewall_result, multi_string,
1417 TOKEN_STRING_MULTI);
1418
1419 static cmdline_parse_inst_t cmd_firewall = {
1420 .f = cmd_firewall_parsed,
1421 .data = NULL,
1422 .help_str = "firewall add / add bulk / add default / del / del bulk"
1423 " / del default / ls",
1424 .tokens = {
1425 (void *) &cmd_firewall_p_string,
1426 (void *) &cmd_firewall_pipeline_id,
1427 (void *) &cmd_firewall_firewall_string,
1428 (void *) &cmd_firewall_multi_string,
1429 NULL,
1430 },
1431 };
1432
1433 static cmdline_parse_ctx_t pipeline_cmds[] = {
1434 (cmdline_parse_inst_t *) &cmd_firewall,
1435 NULL,
1436 };
1437
1438 static struct pipeline_fe_ops pipeline_firewall_fe_ops = {
1439 .f_init = app_pipeline_firewall_init,
1440 .f_post_init = NULL,
1441 .f_free = app_pipeline_firewall_free,
1442 .f_track = app_pipeline_track_default,
1443 .cmds = pipeline_cmds,
1444 };
1445
1446 struct pipeline_type pipeline_firewall = {
1447 .name = "FIREWALL",
1448 .be_ops = &pipeline_firewall_be_ops,
1449 .fe_ops = &pipeline_firewall_fe_ops,
1450 };