4 * Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
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
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.
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.
38 #include <sys/queue.h>
39 #include <netinet/in.h>
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>
50 #include "pipeline_common_fe.h"
51 #include "pipeline_firewall.h"
54 struct app_pipeline_firewall_rule {
55 struct pipeline_firewall_key key;
60 TAILQ_ENTRY(app_pipeline_firewall_rule) node;
63 struct app_pipeline_firewall {
69 TAILQ_HEAD(, app_pipeline_firewall_rule) rules;
71 uint32_t default_rule_present;
72 uint32_t default_rule_port_id;
73 void *default_rule_entry_ptr;
77 print_firewall_ipv4_rule(struct app_pipeline_firewall_rule *rule)
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",
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,
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,
102 rule->key.key.ipv4_5tuple.src_port_from,
103 rule->key.key.ipv4_5tuple.src_port_to,
105 rule->key.key.ipv4_5tuple.dst_port_from,
106 rule->key.key.ipv4_5tuple.dst_port_to,
108 rule->key.key.ipv4_5tuple.proto,
109 rule->key.key.ipv4_5tuple.proto_mask,
115 static struct app_pipeline_firewall_rule *
116 app_pipeline_firewall_rule_find(struct app_pipeline_firewall *p,
117 struct pipeline_firewall_key *key)
119 struct app_pipeline_firewall_rule *r;
121 TAILQ_FOREACH(r, &p->rules, node)
124 sizeof(struct pipeline_firewall_key)) == 0)
131 app_pipeline_firewall_ls(
132 struct app_params *app,
133 uint32_t pipeline_id)
135 struct app_pipeline_firewall *p;
136 struct app_pipeline_firewall_rule *rule;
140 /* Check input arguments */
144 p = app_pipeline_data_fe(app, pipeline_id, &pipeline_firewall);
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);
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);
161 printf("Default rule: DROP\n");
169 app_pipeline_firewall_init(struct pipeline_params *params,
170 __rte_unused void *arg)
172 struct app_pipeline_firewall *p;
175 /* Check input arguments */
176 if ((params == NULL) ||
177 (params->n_ports_in == 0) ||
178 (params->n_ports_out == 0))
181 /* Memory allocation */
182 size = RTE_CACHE_LINE_ROUNDUP(sizeof(struct app_pipeline_firewall));
183 p = rte_zmalloc(NULL, size, RTE_CACHE_LINE_SIZE);
188 p->n_ports_in = params->n_ports_in;
189 p->n_ports_out = params->n_ports_out;
191 TAILQ_INIT(&p->rules);
193 p->default_rule_present = 0;
194 p->default_rule_port_id = 0;
195 p->default_rule_entry_ptr = NULL;
201 app_pipeline_firewall_free(void *pipeline)
203 struct app_pipeline_firewall *p = pipeline;
205 /* Check input arguments */
210 while (!TAILQ_EMPTY(&p->rules)) {
211 struct app_pipeline_firewall_rule *rule;
213 rule = TAILQ_FIRST(&p->rules);
214 TAILQ_REMOVE(&p->rules, rule, node);
223 app_pipeline_firewall_key_check_and_normalize(struct pipeline_firewall_key *key)
226 case PIPELINE_FIREWALL_IPV4_5TUPLE:
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;
235 uint32_t src_ip_netmask = 0;
236 uint32_t dst_ip_netmask = 0;
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))
245 src_ip_netmask = (~0U) << (32 - src_ip_depth);
248 dst_ip_netmask = ((~0U) << (32 - dst_ip_depth));
250 key->key.ipv4_5tuple.src_ip &= src_ip_netmask;
251 key->key.ipv4_5tuple.dst_ip &= dst_ip_netmask;
262 app_pipeline_firewall_load_file(char *filename,
263 struct pipeline_firewall_key *keys,
264 uint32_t *priorities,
273 /* Check input arguments */
274 if ((filename == NULL) ||
276 (priorities == NULL) ||
277 (port_ids == NULL) ||
286 /* Open input file */
287 f = fopen(filename, "r");
294 for (i = 0, l = 1; i < *n_keys; l++) {
296 uint32_t n_tokens = RTE_DIM(tokens);
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;
308 uint8_t protomask = 0;
309 uint32_t port_id = 0;
313 if (fgets(file_buf, sizeof(file_buf), f) == NULL)
316 status = parse_tokenize_string(file_buf, tokens, &n_tokens);
320 if ((n_tokens == 0) || (tokens[0][0] == '#'))
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]))
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;
355 port_ids[i] = port_id;
356 priorities[i] = priority;
358 if (app_pipeline_firewall_key_check_and_normalize(&keys[i]))
376 app_pipeline_firewall_add_rule(struct app_params *app,
377 uint32_t pipeline_id,
378 struct pipeline_firewall_key *key,
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;
388 /* Check input arguments */
391 (key->type != PIPELINE_FIREWALL_IPV4_5TUPLE))
394 p = app_pipeline_data_fe(app, pipeline_id, &pipeline_firewall);
398 if (port_id >= p->n_ports_out)
401 if (app_pipeline_firewall_key_check_and_normalize(key) != 0)
404 /* Find existing rule or allocate new rule */
405 rule = app_pipeline_firewall_rule_find(p, key);
406 new_rule = (rule == NULL);
408 rule = rte_malloc(NULL, sizeof(*rule), RTE_CACHE_LINE_SIZE);
414 /* Allocate and write request */
415 req = app_msg_alloc(app);
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;
428 /* Send request and wait for response */
429 rsp = app_msg_send_recv(app, pipeline_id, req, MSG_TIMEOUT_DEFAULT);
436 /* Read response and write rule */
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);
447 memcpy(&rule->key, key, sizeof(*key));
448 rule->priority = priority;
449 rule->port_id = port_id;
450 rule->entry_ptr = rsp->entry_ptr;
454 TAILQ_INSERT_TAIL(&p->rules, rule, node);
458 print_firewall_ipv4_rule(rule);
461 app_msg_free(app, rsp);
467 app_pipeline_firewall_delete_rule(struct app_params *app,
468 uint32_t pipeline_id,
469 struct pipeline_firewall_key *key)
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;
476 /* Check input arguments */
479 (key->type != PIPELINE_FIREWALL_IPV4_5TUPLE))
482 p = app_pipeline_data_fe(app, pipeline_id, &pipeline_firewall);
486 if (app_pipeline_firewall_key_check_and_normalize(key) != 0)
490 rule = app_pipeline_firewall_rule_find(p, key);
494 /* Allocate and write request */
495 req = app_msg_alloc(app);
499 req->type = PIPELINE_MSG_REQ_CUSTOM;
500 req->subtype = PIPELINE_FIREWALL_MSG_REQ_DEL;
501 memcpy(&req->key, key, sizeof(*key));
503 /* Send request and wait for response */
504 rsp = app_msg_send_recv(app, pipeline_id, req, MSG_TIMEOUT_DEFAULT);
509 if (rsp->status || !rsp->key_found) {
510 app_msg_free(app, rsp);
515 TAILQ_REMOVE(&p->rules, rule, node);
520 app_msg_free(app, rsp);
526 app_pipeline_firewall_add_bulk(struct app_params *app,
527 uint32_t pipeline_id,
528 struct pipeline_firewall_key *keys,
530 uint32_t *priorities,
533 struct app_pipeline_firewall *p;
534 struct pipeline_firewall_add_bulk_msg_req *req;
535 struct pipeline_firewall_add_bulk_msg_rsp *rsp;
537 struct app_pipeline_firewall_rule **rules;
546 /* Check input arguments */
550 p = app_pipeline_data_fe(app, pipeline_id, &pipeline_firewall);
554 rules = rte_malloc(NULL,
555 n_keys * sizeof(struct app_pipeline_firewall_rule *),
556 RTE_CACHE_LINE_SIZE);
560 new_rules = rte_malloc(NULL,
561 n_keys * sizeof(int),
562 RTE_CACHE_LINE_SIZE);
563 if (new_rules == NULL) {
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) {
576 if (app_pipeline_firewall_key_check_and_normalize(&keys[i]) != 0) {
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,
587 RTE_CACHE_LINE_SIZE);
589 if (rules[i] == NULL) {
592 for (j = 0; j <= i; j++)
603 keys_found = rte_malloc(NULL,
604 n_keys * sizeof(int),
605 RTE_CACHE_LINE_SIZE);
606 if (keys_found == NULL) {
609 for (j = 0; j < n_keys; j++)
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) {
624 for (j = 0; j < n_keys; j++)
630 rte_free(keys_found);
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);
638 if (entries_ptr[i] == NULL) {
641 for (j = 0; j < n_keys; j++)
645 for (j = 0; j <= i; j++)
646 rte_free(entries_ptr[j]);
650 rte_free(keys_found);
651 rte_free(entries_ptr);
656 /* Allocate and write request */
657 req = app_msg_alloc(app);
661 for (j = 0; j < n_keys; j++)
665 for (j = 0; j < n_keys; j++)
666 rte_free(entries_ptr[j]);
670 rte_free(keys_found);
671 rte_free(entries_ptr);
675 req->type = PIPELINE_MSG_REQ_CUSTOM;
676 req->subtype = PIPELINE_FIREWALL_MSG_REQ_ADD_BULK;
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;
685 /* Send request and wait for response */
686 rsp = app_msg_send_recv(app, pipeline_id, req, MSG_TIMEOUT_DEFAULT);
690 for (j = 0; j < n_keys; j++)
694 for (j = 0; j < n_keys; j++)
695 rte_free(entries_ptr[j]);
699 rte_free(keys_found);
700 rte_free(entries_ptr);
705 for (i = 0; i < n_keys; i++)
709 for (i = 0; i < n_keys; i++)
710 rte_free(entries_ptr[i]);
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++)
724 for (i = 0; i < n_keys; i++)
725 rte_free(entries_ptr[i]);
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];
740 TAILQ_INSERT_TAIL(&p->rules, rules[i], node);
744 print_firewall_ipv4_rule(rules[i]);
748 app_msg_free(app, rsp);
751 rte_free(keys_found);
752 rte_free(entries_ptr);
758 app_pipeline_firewall_delete_bulk(struct app_params *app,
759 uint32_t pipeline_id,
760 struct pipeline_firewall_key *keys,
763 struct app_pipeline_firewall *p;
764 struct pipeline_firewall_del_bulk_msg_req *req;
765 struct pipeline_firewall_del_bulk_msg_rsp *rsp;
767 struct app_pipeline_firewall_rule **rules;
773 /* Check input arguments */
777 p = app_pipeline_data_fe(app, pipeline_id, &pipeline_firewall);
781 rules = rte_malloc(NULL,
782 n_keys * sizeof(struct app_pipeline_firewall_rule *),
783 RTE_CACHE_LINE_SIZE);
787 for (i = 0; i < n_keys; i++) {
788 if (app_pipeline_firewall_key_check_and_normalize(&keys[i]) != 0) {
792 rules[i] = app_pipeline_firewall_rule_find(p, &keys[i]);
795 keys_found = rte_malloc(NULL,
796 n_keys * sizeof(int),
797 RTE_CACHE_LINE_SIZE);
798 if (keys_found == NULL) {
803 /* Allocate and write request */
804 req = app_msg_alloc(app);
807 rte_free(keys_found);
811 req->type = PIPELINE_MSG_REQ_CUSTOM;
812 req->subtype = PIPELINE_FIREWALL_MSG_REQ_DEL_BULK;
815 req->n_keys = n_keys;
816 req->keys_found = keys_found;
818 /* Send request and wait for response */
819 rsp = app_msg_send_recv(app, pipeline_id, req, MSG_TIMEOUT_DEFAULT);
822 rte_free(keys_found);
831 for (i = 0; i < n_keys; i++) {
832 if (keys_found[i] == 0) {
838 for (i = 0; i < n_keys; i++) {
839 TAILQ_REMOVE(&p->rules, rules[i], node);
845 app_msg_free(app, rsp);
847 rte_free(keys_found);
853 app_pipeline_firewall_add_default_rule(struct app_params *app,
854 uint32_t pipeline_id,
857 struct app_pipeline_firewall *p;
858 struct pipeline_firewall_add_default_msg_req *req;
859 struct pipeline_firewall_add_default_msg_rsp *rsp;
861 /* Check input arguments */
865 p = app_pipeline_data_fe(app, pipeline_id, &pipeline_firewall);
869 if (port_id >= p->n_ports_out)
872 /* Allocate and write request */
873 req = app_msg_alloc(app);
877 req->type = PIPELINE_MSG_REQ_CUSTOM;
878 req->subtype = PIPELINE_FIREWALL_MSG_REQ_ADD_DEFAULT;
879 req->port_id = port_id;
881 /* Send request and wait for response */
882 rsp = app_msg_send_recv(app, pipeline_id, req, MSG_TIMEOUT_DEFAULT);
886 /* Read response and write rule */
887 if (rsp->status || (rsp->entry_ptr == NULL)) {
888 app_msg_free(app, rsp);
892 p->default_rule_port_id = port_id;
893 p->default_rule_entry_ptr = rsp->entry_ptr;
896 p->default_rule_present = 1;
899 app_msg_free(app, rsp);
905 app_pipeline_firewall_delete_default_rule(struct app_params *app,
906 uint32_t pipeline_id)
908 struct app_pipeline_firewall *p;
909 struct pipeline_firewall_del_default_msg_req *req;
910 struct pipeline_firewall_del_default_msg_rsp *rsp;
912 /* Check input arguments */
916 p = app_pipeline_data_fe(app, pipeline_id, &pipeline_firewall);
920 /* Allocate and write request */
921 req = app_msg_alloc(app);
925 req->type = PIPELINE_MSG_REQ_CUSTOM;
926 req->subtype = PIPELINE_FIREWALL_MSG_REQ_DEL_DEFAULT;
928 /* Send request and wait for response */
929 rsp = app_msg_send_recv(app, pipeline_id, req, MSG_TIMEOUT_DEFAULT);
933 /* Read response and write rule */
935 app_msg_free(app, rsp);
940 p->default_rule_present = 0;
943 app_msg_free(app, rsp);
952 * p <pipelineid> firewall add priority <priority>
953 * ipv4 <sipaddr> <sipdepth> <dipaddr> <dipdepth>
954 * <sport0> <sport1> <dport0> <dport1> <proto> <protomask>
956 * Note: <protomask> is a hex value
958 * p <pipelineid> firewall add bulk <file>
960 * firewall add default:
961 * p <pipelineid> firewall add default <port ID>
964 * p <pipelineid> firewall del
965 * ipv4 <sipaddr> <sipdepth> <dipaddr> <dipdepth>
966 * <sport0> <sport1> <dport0> <dport1> <proto> <protomask>
968 * p <pipelineid> firewall del bulk <file>
970 * firewall del default:
971 * p <pipelineid> firewall del default
974 * p <pipelineid> firewall ls
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;
984 static void cmd_firewall_parsed(void *parsed_result,
985 __attribute__((unused)) struct cmdline *cl,
988 struct cmd_firewall_result *params = parsed_result;
989 struct app_params *app = data;
993 uint32_t n_tokens = RTE_DIM(tokens);
995 status = parse_tokenize_string(params->multi_string, tokens, &n_tokens);
997 printf(CMD_MSG_TOO_MANY_ARGS, "firewall");
1002 if ((n_tokens >= 2) &&
1003 (strcmp(tokens[0], "add") == 0) &&
1004 (strcmp(tokens[1], "priority") == 0)) {
1005 struct pipeline_firewall_key key;
1007 struct in_addr sipaddr;
1009 struct in_addr dipaddr;
1019 memset(&key, 0, sizeof(key));
1021 if (n_tokens != 16) {
1022 printf(CMD_MSG_MISMATCH_ARGS, "firewall add");
1026 if (parser_read_uint32(&priority, tokens[2])) {
1027 printf(CMD_MSG_INVALID_ARG, "priority");
1031 if (strcmp(tokens[3], "ipv4")) {
1032 printf(CMD_MSG_ARG_NOT_FOUND, "ipv4");
1036 if (parse_ipv4_addr(tokens[4], &sipaddr)) {
1037 printf(CMD_MSG_INVALID_ARG, "sipaddr");
1041 if (parser_read_uint32(&sipdepth, tokens[5])) {
1042 printf(CMD_MSG_INVALID_ARG, "sipdepth");
1046 if (parse_ipv4_addr(tokens[6], &dipaddr)) {
1047 printf(CMD_MSG_INVALID_ARG, "dipaddr");
1051 if (parser_read_uint32(&dipdepth, tokens[7])) {
1052 printf(CMD_MSG_INVALID_ARG, "dipdepth");
1056 if (parser_read_uint16(&sport0, tokens[8])) {
1057 printf(CMD_MSG_INVALID_ARG, "sport0");
1061 if (parser_read_uint16(&sport1, tokens[9])) {
1062 printf(CMD_MSG_INVALID_ARG, "sport1");
1066 if (parser_read_uint16(&dport0, tokens[10])) {
1067 printf(CMD_MSG_INVALID_ARG, "dport0");
1071 if (parser_read_uint16(&dport1, tokens[11])) {
1072 printf(CMD_MSG_INVALID_ARG, "dport1");
1076 if (parser_read_uint8(&proto, tokens[12])) {
1077 printf(CMD_MSG_INVALID_ARG, "proto");
1081 if (parser_read_uint8_hex(&protomask, tokens[13])) {
1082 printf(CMD_MSG_INVALID_ARG, "protomask");
1086 if (strcmp(tokens[14], "port")) {
1087 printf(CMD_MSG_ARG_NOT_FOUND, "port");
1091 if (parser_read_uint32(&port_id, tokens[15])) {
1092 printf(CMD_MSG_INVALID_ARG, "portid");
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;
1108 status = app_pipeline_firewall_add_rule(app,
1109 params->pipeline_id,
1114 printf(CMD_MSG_FAIL, "firewall add");
1117 } /* firewall add */
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;
1127 if (n_tokens != 3) {
1128 printf(CMD_MSG_MISMATCH_ARGS, "firewall add bulk");
1132 filename = tokens[2];
1134 n_keys = APP_PIPELINE_FIREWALL_MAX_RULES_IN_FILE;
1135 keys = malloc(n_keys * sizeof(struct pipeline_firewall_key));
1137 printf(CMD_MSG_OUT_OF_MEMORY);
1140 memset(keys, 0, n_keys * sizeof(struct pipeline_firewall_key));
1142 priorities = malloc(n_keys * sizeof(uint32_t));
1143 if (priorities == NULL) {
1144 printf(CMD_MSG_OUT_OF_MEMORY);
1149 port_ids = malloc(n_keys * sizeof(uint32_t));
1150 if (port_ids == NULL) {
1151 printf(CMD_MSG_OUT_OF_MEMORY);
1157 status = app_pipeline_firewall_load_file(filename,
1164 printf(CMD_MSG_FILE_ERR, filename, line);
1171 status = app_pipeline_firewall_add_bulk(app,
1172 params->pipeline_id,
1178 printf(CMD_MSG_FAIL, "firewall add bulk");
1184 } /* firewall add bulk */
1186 /* firewall add default */
1187 if ((n_tokens >= 2) &&
1188 (strcmp(tokens[0], "add") == 0) &&
1189 (strcmp(tokens[1], "default") == 0)) {
1192 if (n_tokens != 3) {
1193 printf(CMD_MSG_MISMATCH_ARGS, "firewall add default");
1197 if (parser_read_uint32(&port_id, tokens[2])) {
1198 printf(CMD_MSG_INVALID_ARG, "portid");
1202 status = app_pipeline_firewall_add_default_rule(app,
1203 params->pipeline_id,
1206 printf(CMD_MSG_FAIL, "firewall add default");
1209 } /* firewall add default */
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;
1218 struct in_addr dipaddr;
1227 memset(&key, 0, sizeof(key));
1229 if (n_tokens != 12) {
1230 printf(CMD_MSG_MISMATCH_ARGS, "firewall del");
1234 if (parse_ipv4_addr(tokens[2], &sipaddr)) {
1235 printf(CMD_MSG_INVALID_ARG, "sipaddr");
1239 if (parser_read_uint32(&sipdepth, tokens[3])) {
1240 printf(CMD_MSG_INVALID_ARG, "sipdepth");
1244 if (parse_ipv4_addr(tokens[4], &dipaddr)) {
1245 printf(CMD_MSG_INVALID_ARG, "dipaddr");
1249 if (parser_read_uint32(&dipdepth, tokens[5])) {
1250 printf(CMD_MSG_INVALID_ARG, "dipdepth");
1254 if (parser_read_uint16(&sport0, tokens[6])) {
1255 printf(CMD_MSG_INVALID_ARG, "sport0");
1259 if (parser_read_uint16(&sport1, tokens[7])) {
1260 printf(CMD_MSG_INVALID_ARG, "sport1");
1264 if (parser_read_uint16(&dport0, tokens[8])) {
1265 printf(CMD_MSG_INVALID_ARG, "dport0");
1269 if (parser_read_uint16(&dport1, tokens[9])) {
1270 printf(CMD_MSG_INVALID_ARG, "dport1");
1274 if (parser_read_uint8(&proto, tokens[10])) {
1275 printf(CMD_MSG_INVALID_ARG, "proto");
1279 if (parser_read_uint8_hex(&protomask, tokens[11])) {
1280 printf(CMD_MSG_INVALID_ARG, "protomask");
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;
1296 status = app_pipeline_firewall_delete_rule(app,
1297 params->pipeline_id,
1300 printf(CMD_MSG_FAIL, "firewall del");
1303 } /* firewall del */
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;
1313 if (n_tokens != 3) {
1314 printf(CMD_MSG_MISMATCH_ARGS, "firewall del bulk");
1318 filename = tokens[2];
1320 n_keys = APP_PIPELINE_FIREWALL_MAX_RULES_IN_FILE;
1321 keys = malloc(n_keys * sizeof(struct pipeline_firewall_key));
1323 printf(CMD_MSG_OUT_OF_MEMORY);
1326 memset(keys, 0, n_keys * sizeof(struct pipeline_firewall_key));
1328 priorities = malloc(n_keys * sizeof(uint32_t));
1329 if (priorities == NULL) {
1330 printf(CMD_MSG_OUT_OF_MEMORY);
1335 port_ids = malloc(n_keys * sizeof(uint32_t));
1336 if (port_ids == NULL) {
1337 printf(CMD_MSG_OUT_OF_MEMORY);
1343 status = app_pipeline_firewall_load_file(filename,
1350 printf(CMD_MSG_FILE_ERR, filename, line);
1357 status = app_pipeline_firewall_delete_bulk(app,
1358 params->pipeline_id,
1362 printf(CMD_MSG_FAIL, "firewall del bulk");
1368 } /* firewall del bulk */
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");
1379 status = app_pipeline_firewall_delete_default_rule(app,
1380 params->pipeline_id);
1382 printf(CMD_MSG_FAIL, "firewall del default");
1386 } /* firewall del default */
1389 if ((n_tokens >= 1) && (strcmp(tokens[0], "ls") == 0)) {
1390 if (n_tokens != 1) {
1391 printf(CMD_MSG_MISMATCH_ARGS, "firewall ls");
1395 status = app_pipeline_firewall_ls(app, params->pipeline_id);
1397 printf(CMD_MSG_FAIL, "firewall ls");
1402 printf(CMD_MSG_MISMATCH_ARGS, "firewall");
1405 static cmdline_parse_token_string_t cmd_firewall_p_string =
1406 TOKEN_STRING_INITIALIZER(struct cmd_firewall_result, p_string, "p");
1408 static cmdline_parse_token_num_t cmd_firewall_pipeline_id =
1409 TOKEN_NUM_INITIALIZER(struct cmd_firewall_result, pipeline_id, UINT32);
1411 static cmdline_parse_token_string_t cmd_firewall_firewall_string =
1412 TOKEN_STRING_INITIALIZER(struct cmd_firewall_result, firewall_string,
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);
1419 static cmdline_parse_inst_t cmd_firewall = {
1420 .f = cmd_firewall_parsed,
1422 .help_str = "firewall add / add bulk / add default / del / del bulk"
1423 " / del default / ls",
1425 (void *) &cmd_firewall_p_string,
1426 (void *) &cmd_firewall_pipeline_id,
1427 (void *) &cmd_firewall_firewall_string,
1428 (void *) &cmd_firewall_multi_string,
1433 static cmdline_parse_ctx_t pipeline_cmds[] = {
1434 (cmdline_parse_inst_t *) &cmd_firewall,
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,
1446 struct pipeline_type pipeline_firewall = {
1448 .be_ops = &pipeline_firewall_be_ops,
1449 .fe_ops = &pipeline_firewall_fe_ops,