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