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