]> git.proxmox.com Git - ceph.git/blob - ceph/src/dpdk/examples/ip_pipeline/pipeline/pipeline_firewall_be.c
bump version to 12.2.12-pve1
[ceph.git] / ceph / src / dpdk / examples / ip_pipeline / pipeline / pipeline_firewall_be.c
1 /*-
2 * BSD LICENSE
3 *
4 * Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
16 * distribution.
17 * * Neither the name of Intel Corporation nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34 #include <string.h>
35
36 #include <rte_common.h>
37 #include <rte_malloc.h>
38 #include <rte_ether.h>
39 #include <rte_ip.h>
40 #include <rte_tcp.h>
41 #include <rte_byteorder.h>
42 #include <rte_table_acl.h>
43
44 #include "pipeline_firewall_be.h"
45 #include "parser.h"
46
47 struct pipeline_firewall {
48 struct pipeline p;
49 pipeline_msg_req_handler custom_handlers[PIPELINE_FIREWALL_MSG_REQS];
50
51 uint32_t n_rules;
52 uint32_t n_rule_fields;
53 struct rte_acl_field_def *field_format;
54 uint32_t field_format_size;
55 } __rte_cache_aligned;
56
57 static void *
58 pipeline_firewall_msg_req_custom_handler(struct pipeline *p, void *msg);
59
60 static pipeline_msg_req_handler handlers[] = {
61 [PIPELINE_MSG_REQ_PING] =
62 pipeline_msg_req_ping_handler,
63 [PIPELINE_MSG_REQ_STATS_PORT_IN] =
64 pipeline_msg_req_stats_port_in_handler,
65 [PIPELINE_MSG_REQ_STATS_PORT_OUT] =
66 pipeline_msg_req_stats_port_out_handler,
67 [PIPELINE_MSG_REQ_STATS_TABLE] =
68 pipeline_msg_req_stats_table_handler,
69 [PIPELINE_MSG_REQ_PORT_IN_ENABLE] =
70 pipeline_msg_req_port_in_enable_handler,
71 [PIPELINE_MSG_REQ_PORT_IN_DISABLE] =
72 pipeline_msg_req_port_in_disable_handler,
73 [PIPELINE_MSG_REQ_CUSTOM] =
74 pipeline_firewall_msg_req_custom_handler,
75 };
76
77 static void *
78 pipeline_firewall_msg_req_add_handler(struct pipeline *p, void *msg);
79
80 static void *
81 pipeline_firewall_msg_req_del_handler(struct pipeline *p, void *msg);
82
83 static void *
84 pipeline_firewall_msg_req_add_bulk_handler(struct pipeline *p, void *msg);
85
86 static void *
87 pipeline_firewall_msg_req_del_bulk_handler(struct pipeline *p, void *msg);
88
89 static void *
90 pipeline_firewall_msg_req_add_default_handler(struct pipeline *p, void *msg);
91
92 static void *
93 pipeline_firewall_msg_req_del_default_handler(struct pipeline *p, void *msg);
94
95 static pipeline_msg_req_handler custom_handlers[] = {
96 [PIPELINE_FIREWALL_MSG_REQ_ADD] =
97 pipeline_firewall_msg_req_add_handler,
98 [PIPELINE_FIREWALL_MSG_REQ_DEL] =
99 pipeline_firewall_msg_req_del_handler,
100 [PIPELINE_FIREWALL_MSG_REQ_ADD_BULK] =
101 pipeline_firewall_msg_req_add_bulk_handler,
102 [PIPELINE_FIREWALL_MSG_REQ_DEL_BULK] =
103 pipeline_firewall_msg_req_del_bulk_handler,
104 [PIPELINE_FIREWALL_MSG_REQ_ADD_DEFAULT] =
105 pipeline_firewall_msg_req_add_default_handler,
106 [PIPELINE_FIREWALL_MSG_REQ_DEL_DEFAULT] =
107 pipeline_firewall_msg_req_del_default_handler,
108 };
109
110 /*
111 * Firewall table
112 */
113 struct firewall_table_entry {
114 struct rte_pipeline_table_entry head;
115 };
116
117 static struct rte_acl_field_def field_format_ipv4[] = {
118 /* Protocol */
119 [0] = {
120 .type = RTE_ACL_FIELD_TYPE_BITMASK,
121 .size = sizeof(uint8_t),
122 .field_index = 0,
123 .input_index = 0,
124 .offset = sizeof(struct ether_hdr) +
125 offsetof(struct ipv4_hdr, next_proto_id),
126 },
127
128 /* Source IP address (IPv4) */
129 [1] = {
130 .type = RTE_ACL_FIELD_TYPE_MASK,
131 .size = sizeof(uint32_t),
132 .field_index = 1,
133 .input_index = 1,
134 .offset = sizeof(struct ether_hdr) +
135 offsetof(struct ipv4_hdr, src_addr),
136 },
137
138 /* Destination IP address (IPv4) */
139 [2] = {
140 .type = RTE_ACL_FIELD_TYPE_MASK,
141 .size = sizeof(uint32_t),
142 .field_index = 2,
143 .input_index = 2,
144 .offset = sizeof(struct ether_hdr) +
145 offsetof(struct ipv4_hdr, dst_addr),
146 },
147
148 /* Source Port */
149 [3] = {
150 .type = RTE_ACL_FIELD_TYPE_RANGE,
151 .size = sizeof(uint16_t),
152 .field_index = 3,
153 .input_index = 3,
154 .offset = sizeof(struct ether_hdr) +
155 sizeof(struct ipv4_hdr) +
156 offsetof(struct tcp_hdr, src_port),
157 },
158
159 /* Destination Port */
160 [4] = {
161 .type = RTE_ACL_FIELD_TYPE_RANGE,
162 .size = sizeof(uint16_t),
163 .field_index = 4,
164 .input_index = 4,
165 .offset = sizeof(struct ether_hdr) +
166 sizeof(struct ipv4_hdr) +
167 offsetof(struct tcp_hdr, dst_port),
168 },
169 };
170
171 #define SIZEOF_VLAN_HDR 4
172
173 static struct rte_acl_field_def field_format_vlan_ipv4[] = {
174 /* Protocol */
175 [0] = {
176 .type = RTE_ACL_FIELD_TYPE_BITMASK,
177 .size = sizeof(uint8_t),
178 .field_index = 0,
179 .input_index = 0,
180 .offset = sizeof(struct ether_hdr) +
181 SIZEOF_VLAN_HDR +
182 offsetof(struct ipv4_hdr, next_proto_id),
183 },
184
185 /* Source IP address (IPv4) */
186 [1] = {
187 .type = RTE_ACL_FIELD_TYPE_MASK,
188 .size = sizeof(uint32_t),
189 .field_index = 1,
190 .input_index = 1,
191 .offset = sizeof(struct ether_hdr) +
192 SIZEOF_VLAN_HDR +
193 offsetof(struct ipv4_hdr, src_addr),
194 },
195
196 /* Destination IP address (IPv4) */
197 [2] = {
198 .type = RTE_ACL_FIELD_TYPE_MASK,
199 .size = sizeof(uint32_t),
200 .field_index = 2,
201 .input_index = 2,
202 .offset = sizeof(struct ether_hdr) +
203 SIZEOF_VLAN_HDR +
204 offsetof(struct ipv4_hdr, dst_addr),
205 },
206
207 /* Source Port */
208 [3] = {
209 .type = RTE_ACL_FIELD_TYPE_RANGE,
210 .size = sizeof(uint16_t),
211 .field_index = 3,
212 .input_index = 3,
213 .offset = sizeof(struct ether_hdr) +
214 SIZEOF_VLAN_HDR +
215 sizeof(struct ipv4_hdr) +
216 offsetof(struct tcp_hdr, src_port),
217 },
218
219 /* Destination Port */
220 [4] = {
221 .type = RTE_ACL_FIELD_TYPE_RANGE,
222 .size = sizeof(uint16_t),
223 .field_index = 4,
224 .input_index = 4,
225 .offset = sizeof(struct ether_hdr) +
226 SIZEOF_VLAN_HDR +
227 sizeof(struct ipv4_hdr) +
228 offsetof(struct tcp_hdr, dst_port),
229 },
230 };
231
232 #define SIZEOF_QINQ_HEADER 8
233
234 static struct rte_acl_field_def field_format_qinq_ipv4[] = {
235 /* Protocol */
236 [0] = {
237 .type = RTE_ACL_FIELD_TYPE_BITMASK,
238 .size = sizeof(uint8_t),
239 .field_index = 0,
240 .input_index = 0,
241 .offset = sizeof(struct ether_hdr) +
242 SIZEOF_QINQ_HEADER +
243 offsetof(struct ipv4_hdr, next_proto_id),
244 },
245
246 /* Source IP address (IPv4) */
247 [1] = {
248 .type = RTE_ACL_FIELD_TYPE_MASK,
249 .size = sizeof(uint32_t),
250 .field_index = 1,
251 .input_index = 1,
252 .offset = sizeof(struct ether_hdr) +
253 SIZEOF_QINQ_HEADER +
254 offsetof(struct ipv4_hdr, src_addr),
255 },
256
257 /* Destination IP address (IPv4) */
258 [2] = {
259 .type = RTE_ACL_FIELD_TYPE_MASK,
260 .size = sizeof(uint32_t),
261 .field_index = 2,
262 .input_index = 2,
263 .offset = sizeof(struct ether_hdr) +
264 SIZEOF_QINQ_HEADER +
265 offsetof(struct ipv4_hdr, dst_addr),
266 },
267
268 /* Source Port */
269 [3] = {
270 .type = RTE_ACL_FIELD_TYPE_RANGE,
271 .size = sizeof(uint16_t),
272 .field_index = 3,
273 .input_index = 3,
274 .offset = sizeof(struct ether_hdr) +
275 SIZEOF_QINQ_HEADER +
276 sizeof(struct ipv4_hdr) +
277 offsetof(struct tcp_hdr, src_port),
278 },
279
280 /* Destination Port */
281 [4] = {
282 .type = RTE_ACL_FIELD_TYPE_RANGE,
283 .size = sizeof(uint16_t),
284 .field_index = 4,
285 .input_index = 4,
286 .offset = sizeof(struct ether_hdr) +
287 SIZEOF_QINQ_HEADER +
288 sizeof(struct ipv4_hdr) +
289 offsetof(struct tcp_hdr, dst_port),
290 },
291 };
292
293 static int
294 pipeline_firewall_parse_args(struct pipeline_firewall *p,
295 struct pipeline_params *params)
296 {
297 uint32_t n_rules_present = 0;
298 uint32_t pkt_type_present = 0;
299 uint32_t i;
300
301 /* defaults */
302 p->n_rules = 4 * 1024;
303 p->n_rule_fields = RTE_DIM(field_format_ipv4);
304 p->field_format = field_format_ipv4;
305 p->field_format_size = sizeof(field_format_ipv4);
306
307 for (i = 0; i < params->n_args; i++) {
308 char *arg_name = params->args_name[i];
309 char *arg_value = params->args_value[i];
310
311 if (strcmp(arg_name, "n_rules") == 0) {
312 int status;
313
314 PIPELINE_PARSE_ERR_DUPLICATE(
315 n_rules_present == 0, params->name,
316 arg_name);
317 n_rules_present = 1;
318
319 status = parser_read_uint32(&p->n_rules,
320 arg_value);
321 PIPELINE_PARSE_ERR_INV_VAL((status != -EINVAL),
322 params->name, arg_name, arg_value);
323 PIPELINE_PARSE_ERR_OUT_RNG((status != -ERANGE),
324 params->name, arg_name, arg_value);
325 continue;
326 }
327
328 if (strcmp(arg_name, "pkt_type") == 0) {
329 PIPELINE_PARSE_ERR_DUPLICATE(
330 pkt_type_present == 0, params->name,
331 arg_name);
332 pkt_type_present = 1;
333
334 /* ipv4 */
335 if (strcmp(arg_value, "ipv4") == 0) {
336 p->n_rule_fields = RTE_DIM(field_format_ipv4);
337 p->field_format = field_format_ipv4;
338 p->field_format_size =
339 sizeof(field_format_ipv4);
340 continue;
341 }
342
343 /* vlan_ipv4 */
344 if (strcmp(arg_value, "vlan_ipv4") == 0) {
345 p->n_rule_fields =
346 RTE_DIM(field_format_vlan_ipv4);
347 p->field_format = field_format_vlan_ipv4;
348 p->field_format_size =
349 sizeof(field_format_vlan_ipv4);
350 continue;
351 }
352
353 /* qinq_ipv4 */
354 if (strcmp(arg_value, "qinq_ipv4") == 0) {
355 p->n_rule_fields =
356 RTE_DIM(field_format_qinq_ipv4);
357 p->field_format = field_format_qinq_ipv4;
358 p->field_format_size =
359 sizeof(field_format_qinq_ipv4);
360 continue;
361 }
362
363 /* other */
364 PIPELINE_PARSE_ERR_INV_VAL(0, params->name,
365 arg_name, arg_value);
366 }
367
368 /* other */
369 PIPELINE_PARSE_ERR_INV_ENT(0, params->name, arg_name);
370 }
371
372 return 0;
373 }
374
375 static void *
376 pipeline_firewall_init(struct pipeline_params *params,
377 __rte_unused void *arg)
378 {
379 struct pipeline *p;
380 struct pipeline_firewall *p_fw;
381 uint32_t size, i;
382
383 /* Check input arguments */
384 if ((params == NULL) ||
385 (params->n_ports_in == 0) ||
386 (params->n_ports_out == 0))
387 return NULL;
388
389 /* Memory allocation */
390 size = RTE_CACHE_LINE_ROUNDUP(sizeof(struct pipeline_firewall));
391 p = rte_zmalloc(NULL, size, RTE_CACHE_LINE_SIZE);
392 p_fw = (struct pipeline_firewall *) p;
393 if (p == NULL)
394 return NULL;
395
396 strcpy(p->name, params->name);
397 p->log_level = params->log_level;
398
399 PLOG(p, HIGH, "Firewall");
400
401 /* Parse arguments */
402 if (pipeline_firewall_parse_args(p_fw, params))
403 return NULL;
404
405 /* Pipeline */
406 {
407 struct rte_pipeline_params pipeline_params = {
408 .name = params->name,
409 .socket_id = params->socket_id,
410 .offset_port_id = 0,
411 };
412
413 p->p = rte_pipeline_create(&pipeline_params);
414 if (p->p == NULL) {
415 rte_free(p);
416 return NULL;
417 }
418 }
419
420 /* Input ports */
421 p->n_ports_in = params->n_ports_in;
422 for (i = 0; i < p->n_ports_in; i++) {
423 struct rte_pipeline_port_in_params port_params = {
424 .ops = pipeline_port_in_params_get_ops(
425 &params->port_in[i]),
426 .arg_create = pipeline_port_in_params_convert(
427 &params->port_in[i]),
428 .f_action = NULL,
429 .arg_ah = NULL,
430 .burst_size = params->port_in[i].burst_size,
431 };
432
433 int status = rte_pipeline_port_in_create(p->p,
434 &port_params,
435 &p->port_in_id[i]);
436
437 if (status) {
438 rte_pipeline_free(p->p);
439 rte_free(p);
440 return NULL;
441 }
442 }
443
444 /* Output ports */
445 p->n_ports_out = params->n_ports_out;
446 for (i = 0; i < p->n_ports_out; i++) {
447 struct rte_pipeline_port_out_params port_params = {
448 .ops = pipeline_port_out_params_get_ops(
449 &params->port_out[i]),
450 .arg_create = pipeline_port_out_params_convert(
451 &params->port_out[i]),
452 .f_action = NULL,
453 .arg_ah = NULL,
454 };
455
456 int status = rte_pipeline_port_out_create(p->p,
457 &port_params,
458 &p->port_out_id[i]);
459
460 if (status) {
461 rte_pipeline_free(p->p);
462 rte_free(p);
463 return NULL;
464 }
465 }
466
467 /* Tables */
468 p->n_tables = 1;
469 {
470 struct rte_table_acl_params table_acl_params = {
471 .name = params->name,
472 .n_rules = p_fw->n_rules,
473 .n_rule_fields = p_fw->n_rule_fields,
474 };
475
476 struct rte_pipeline_table_params table_params = {
477 .ops = &rte_table_acl_ops,
478 .arg_create = &table_acl_params,
479 .f_action_hit = NULL,
480 .f_action_miss = NULL,
481 .arg_ah = NULL,
482 .action_data_size =
483 sizeof(struct firewall_table_entry) -
484 sizeof(struct rte_pipeline_table_entry),
485 };
486
487 int status;
488
489 memcpy(table_acl_params.field_format,
490 p_fw->field_format,
491 p_fw->field_format_size);
492
493 status = rte_pipeline_table_create(p->p,
494 &table_params,
495 &p->table_id[0]);
496
497 if (status) {
498 rte_pipeline_free(p->p);
499 rte_free(p);
500 return NULL;
501 }
502 }
503
504 /* Connecting input ports to tables */
505 for (i = 0; i < p->n_ports_in; i++) {
506 int status = rte_pipeline_port_in_connect_to_table(p->p,
507 p->port_in_id[i],
508 p->table_id[0]);
509
510 if (status) {
511 rte_pipeline_free(p->p);
512 rte_free(p);
513 return NULL;
514 }
515 }
516
517 /* Enable input ports */
518 for (i = 0; i < p->n_ports_in; i++) {
519 int status = rte_pipeline_port_in_enable(p->p,
520 p->port_in_id[i]);
521
522 if (status) {
523 rte_pipeline_free(p->p);
524 rte_free(p);
525 return NULL;
526 }
527 }
528
529 /* Check pipeline consistency */
530 if (rte_pipeline_check(p->p) < 0) {
531 rte_pipeline_free(p->p);
532 rte_free(p);
533 return NULL;
534 }
535
536 /* Message queues */
537 p->n_msgq = params->n_msgq;
538 for (i = 0; i < p->n_msgq; i++)
539 p->msgq_in[i] = params->msgq_in[i];
540 for (i = 0; i < p->n_msgq; i++)
541 p->msgq_out[i] = params->msgq_out[i];
542
543 /* Message handlers */
544 memcpy(p->handlers, handlers, sizeof(p->handlers));
545 memcpy(p_fw->custom_handlers,
546 custom_handlers,
547 sizeof(p_fw->custom_handlers));
548
549 return p;
550 }
551
552 static int
553 pipeline_firewall_free(void *pipeline)
554 {
555 struct pipeline *p = (struct pipeline *) pipeline;
556
557 /* Check input arguments */
558 if (p == NULL)
559 return -1;
560
561 /* Free resources */
562 rte_pipeline_free(p->p);
563 rte_free(p);
564 return 0;
565 }
566
567 static int
568 pipeline_firewall_timer(void *pipeline)
569 {
570 struct pipeline *p = (struct pipeline *) pipeline;
571
572 pipeline_msg_req_handle(p);
573 rte_pipeline_flush(p->p);
574
575 return 0;
576 }
577
578 void *
579 pipeline_firewall_msg_req_custom_handler(struct pipeline *p,
580 void *msg)
581 {
582 struct pipeline_firewall *p_fw = (struct pipeline_firewall *) p;
583 struct pipeline_custom_msg_req *req = msg;
584 pipeline_msg_req_handler f_handle;
585
586 f_handle = (req->subtype < PIPELINE_FIREWALL_MSG_REQS) ?
587 p_fw->custom_handlers[req->subtype] :
588 pipeline_msg_req_invalid_handler;
589
590 if (f_handle == NULL)
591 f_handle = pipeline_msg_req_invalid_handler;
592
593 return f_handle(p, req);
594 }
595
596 void *
597 pipeline_firewall_msg_req_add_handler(struct pipeline *p, void *msg)
598 {
599 struct pipeline_firewall_add_msg_req *req = msg;
600 struct pipeline_firewall_add_msg_rsp *rsp = msg;
601
602 struct rte_table_acl_rule_add_params params;
603 struct firewall_table_entry entry = {
604 .head = {
605 .action = RTE_PIPELINE_ACTION_PORT,
606 {.port_id = p->port_out_id[req->port_id]},
607 },
608 };
609
610 memset(&params, 0, sizeof(params));
611
612 switch (req->key.type) {
613 case PIPELINE_FIREWALL_IPV4_5TUPLE:
614 params.priority = req->priority;
615 params.field_value[0].value.u8 =
616 req->key.key.ipv4_5tuple.proto;
617 params.field_value[0].mask_range.u8 =
618 req->key.key.ipv4_5tuple.proto_mask;
619 params.field_value[1].value.u32 =
620 req->key.key.ipv4_5tuple.src_ip;
621 params.field_value[1].mask_range.u32 =
622 req->key.key.ipv4_5tuple.src_ip_mask;
623 params.field_value[2].value.u32 =
624 req->key.key.ipv4_5tuple.dst_ip;
625 params.field_value[2].mask_range.u32 =
626 req->key.key.ipv4_5tuple.dst_ip_mask;
627 params.field_value[3].value.u16 =
628 req->key.key.ipv4_5tuple.src_port_from;
629 params.field_value[3].mask_range.u16 =
630 req->key.key.ipv4_5tuple.src_port_to;
631 params.field_value[4].value.u16 =
632 req->key.key.ipv4_5tuple.dst_port_from;
633 params.field_value[4].mask_range.u16 =
634 req->key.key.ipv4_5tuple.dst_port_to;
635 break;
636
637 default:
638 rsp->status = -1; /* Error */
639 return rsp;
640 }
641
642 rsp->status = rte_pipeline_table_entry_add(p->p,
643 p->table_id[0],
644 &params,
645 (struct rte_pipeline_table_entry *) &entry,
646 &rsp->key_found,
647 (struct rte_pipeline_table_entry **) &rsp->entry_ptr);
648
649 return rsp;
650 }
651
652 void *
653 pipeline_firewall_msg_req_del_handler(struct pipeline *p, void *msg)
654 {
655 struct pipeline_firewall_del_msg_req *req = msg;
656 struct pipeline_firewall_del_msg_rsp *rsp = msg;
657
658 struct rte_table_acl_rule_delete_params params;
659
660 memset(&params, 0, sizeof(params));
661
662 switch (req->key.type) {
663 case PIPELINE_FIREWALL_IPV4_5TUPLE:
664 params.field_value[0].value.u8 =
665 req->key.key.ipv4_5tuple.proto;
666 params.field_value[0].mask_range.u8 =
667 req->key.key.ipv4_5tuple.proto_mask;
668 params.field_value[1].value.u32 =
669 req->key.key.ipv4_5tuple.src_ip;
670 params.field_value[1].mask_range.u32 =
671 req->key.key.ipv4_5tuple.src_ip_mask;
672 params.field_value[2].value.u32 =
673 req->key.key.ipv4_5tuple.dst_ip;
674 params.field_value[2].mask_range.u32 =
675 req->key.key.ipv4_5tuple.dst_ip_mask;
676 params.field_value[3].value.u16 =
677 req->key.key.ipv4_5tuple.src_port_from;
678 params.field_value[3].mask_range.u16 =
679 req->key.key.ipv4_5tuple.src_port_to;
680 params.field_value[4].value.u16 =
681 req->key.key.ipv4_5tuple.dst_port_from;
682 params.field_value[4].mask_range.u16 =
683 req->key.key.ipv4_5tuple.dst_port_to;
684 break;
685
686 default:
687 rsp->status = -1; /* Error */
688 return rsp;
689 }
690
691 rsp->status = rte_pipeline_table_entry_delete(p->p,
692 p->table_id[0],
693 &params,
694 &rsp->key_found,
695 NULL);
696
697 return rsp;
698 }
699
700 static void *
701 pipeline_firewall_msg_req_add_bulk_handler(struct pipeline *p, void *msg)
702 {
703 struct pipeline_firewall_add_bulk_msg_req *req = msg;
704 struct pipeline_firewall_add_bulk_msg_rsp *rsp = msg;
705
706 struct rte_table_acl_rule_add_params *params[req->n_keys];
707 struct firewall_table_entry *entries[req->n_keys];
708
709 uint32_t i, n_keys;
710
711 n_keys = req->n_keys;
712
713 for (i = 0; i < n_keys; i++) {
714 entries[i] = rte_zmalloc(NULL,
715 sizeof(struct firewall_table_entry),
716 RTE_CACHE_LINE_SIZE);
717 if (entries[i] == NULL) {
718 rsp->status = -1;
719 return rsp;
720 }
721
722 params[i] = rte_zmalloc(NULL,
723 sizeof(struct rte_table_acl_rule_add_params),
724 RTE_CACHE_LINE_SIZE);
725 if (params[i] == NULL) {
726 rsp->status = -1;
727 return rsp;
728 }
729
730 entries[i]->head.action = RTE_PIPELINE_ACTION_PORT;
731 entries[i]->head.port_id = p->port_out_id[req->port_ids[i]];
732
733 switch (req->keys[i].type) {
734 case PIPELINE_FIREWALL_IPV4_5TUPLE:
735 params[i]->priority = req->priorities[i];
736 params[i]->field_value[0].value.u8 =
737 req->keys[i].key.ipv4_5tuple.proto;
738 params[i]->field_value[0].mask_range.u8 =
739 req->keys[i].key.ipv4_5tuple.proto_mask;
740 params[i]->field_value[1].value.u32 =
741 req->keys[i].key.ipv4_5tuple.src_ip;
742 params[i]->field_value[1].mask_range.u32 =
743 req->keys[i].key.ipv4_5tuple.src_ip_mask;
744 params[i]->field_value[2].value.u32 =
745 req->keys[i].key.ipv4_5tuple.dst_ip;
746 params[i]->field_value[2].mask_range.u32 =
747 req->keys[i].key.ipv4_5tuple.dst_ip_mask;
748 params[i]->field_value[3].value.u16 =
749 req->keys[i].key.ipv4_5tuple.src_port_from;
750 params[i]->field_value[3].mask_range.u16 =
751 req->keys[i].key.ipv4_5tuple.src_port_to;
752 params[i]->field_value[4].value.u16 =
753 req->keys[i].key.ipv4_5tuple.dst_port_from;
754 params[i]->field_value[4].mask_range.u16 =
755 req->keys[i].key.ipv4_5tuple.dst_port_to;
756 break;
757
758 default:
759 rsp->status = -1; /* Error */
760
761 for (i = 0; i < n_keys; i++) {
762 rte_free(entries[i]);
763 rte_free(params[i]);
764 }
765
766 return rsp;
767 }
768 }
769
770 rsp->status = rte_pipeline_table_entry_add_bulk(p->p, p->table_id[0],
771 (void *)params, (struct rte_pipeline_table_entry **)entries,
772 n_keys, req->keys_found,
773 (struct rte_pipeline_table_entry **)req->entries_ptr);
774
775 for (i = 0; i < n_keys; i++) {
776 rte_free(entries[i]);
777 rte_free(params[i]);
778 }
779
780 return rsp;
781 }
782
783 static void *
784 pipeline_firewall_msg_req_del_bulk_handler(struct pipeline *p, void *msg)
785 {
786 struct pipeline_firewall_del_bulk_msg_req *req = msg;
787 struct pipeline_firewall_del_bulk_msg_rsp *rsp = msg;
788
789 struct rte_table_acl_rule_delete_params *params[req->n_keys];
790
791 uint32_t i, n_keys;
792
793 n_keys = req->n_keys;
794
795 for (i = 0; i < n_keys; i++) {
796 params[i] = rte_zmalloc(NULL,
797 sizeof(struct rte_table_acl_rule_delete_params),
798 RTE_CACHE_LINE_SIZE);
799 if (params[i] == NULL) {
800 rsp->status = -1;
801 return rsp;
802 }
803
804 switch (req->keys[i].type) {
805 case PIPELINE_FIREWALL_IPV4_5TUPLE:
806 params[i]->field_value[0].value.u8 =
807 req->keys[i].key.ipv4_5tuple.proto;
808 params[i]->field_value[0].mask_range.u8 =
809 req->keys[i].key.ipv4_5tuple.proto_mask;
810 params[i]->field_value[1].value.u32 =
811 req->keys[i].key.ipv4_5tuple.src_ip;
812 params[i]->field_value[1].mask_range.u32 =
813 req->keys[i].key.ipv4_5tuple.src_ip_mask;
814 params[i]->field_value[2].value.u32 =
815 req->keys[i].key.ipv4_5tuple.dst_ip;
816 params[i]->field_value[2].mask_range.u32 =
817 req->keys[i].key.ipv4_5tuple.dst_ip_mask;
818 params[i]->field_value[3].value.u16 =
819 req->keys[i].key.ipv4_5tuple.src_port_from;
820 params[i]->field_value[3].mask_range.u16 =
821 req->keys[i].key.ipv4_5tuple.src_port_to;
822 params[i]->field_value[4].value.u16 =
823 req->keys[i].key.ipv4_5tuple.dst_port_from;
824 params[i]->field_value[4].mask_range.u16 =
825 req->keys[i].key.ipv4_5tuple.dst_port_to;
826 break;
827
828 default:
829 rsp->status = -1; /* Error */
830
831 for (i = 0; i < n_keys; i++)
832 rte_free(params[i]);
833
834 return rsp;
835 }
836 }
837
838 rsp->status = rte_pipeline_table_entry_delete_bulk(p->p, p->table_id[0],
839 (void **)&params, n_keys, req->keys_found, NULL);
840
841 for (i = 0; i < n_keys; i++)
842 rte_free(params[i]);
843
844 return rsp;
845 }
846
847 void *
848 pipeline_firewall_msg_req_add_default_handler(struct pipeline *p, void *msg)
849 {
850 struct pipeline_firewall_add_default_msg_req *req = msg;
851 struct pipeline_firewall_add_default_msg_rsp *rsp = msg;
852
853 struct firewall_table_entry default_entry = {
854 .head = {
855 .action = RTE_PIPELINE_ACTION_PORT,
856 {.port_id = p->port_out_id[req->port_id]},
857 },
858 };
859
860 rsp->status = rte_pipeline_table_default_entry_add(p->p,
861 p->table_id[0],
862 (struct rte_pipeline_table_entry *) &default_entry,
863 (struct rte_pipeline_table_entry **) &rsp->entry_ptr);
864
865 return rsp;
866 }
867
868 void *
869 pipeline_firewall_msg_req_del_default_handler(struct pipeline *p, void *msg)
870 {
871 struct pipeline_firewall_del_default_msg_rsp *rsp = msg;
872
873 rsp->status = rte_pipeline_table_default_entry_delete(p->p,
874 p->table_id[0],
875 NULL);
876
877 return rsp;
878 }
879
880 struct pipeline_be_ops pipeline_firewall_be_ops = {
881 .f_init = pipeline_firewall_init,
882 .f_free = pipeline_firewall_free,
883 .f_run = NULL,
884 .f_timer = pipeline_firewall_timer,
885 };