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
,