4 * Copyright(c) 2010-2016 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.
37 #include <netinet/in.h>
38 #ifdef RTE_EXEC_ENV_LINUXAPP
40 #include <linux/if_tun.h>
43 #include <sys/ioctl.h>
46 #include <rte_cycles.h>
47 #include <rte_ethdev.h>
48 #include <rte_ether.h>
51 #include <rte_malloc.h>
55 #include "pipeline_common_fe.h"
56 #include "pipeline_master.h"
57 #include "pipeline_passthrough.h"
58 #include "pipeline_firewall.h"
59 #include "pipeline_flow_classification.h"
60 #include "pipeline_flow_actions.h"
61 #include "pipeline_routing.h"
62 #include "thread_fe.h"
64 #define APP_NAME_SIZE 32
66 #define APP_RETA_SIZE_MAX (ETH_RSS_RETA_SIZE_512 / RTE_RETA_GROUP_SIZE)
69 app_init_core_map(struct app_params
*app
)
71 APP_LOG(app
, HIGH
, "Initializing CPU core map ...");
72 app
->core_map
= cpu_core_map_init(RTE_MAX_NUMA_NODES
, RTE_MAX_LCORE
,
75 if (app
->core_map
== NULL
)
76 rte_panic("Cannot create CPU core map\n");
78 if (app
->log_level
>= APP_LOG_LEVEL_LOW
)
79 cpu_core_map_print(app
->core_map
);
82 /* Core Mask String in Hex Representation */
83 #define APP_CORE_MASK_STRING_SIZE ((64 * APP_CORE_MASK_SIZE) / 8 * 2 + 1)
86 app_init_core_mask(struct app_params
*app
)
89 char core_mask_str
[APP_CORE_MASK_STRING_SIZE
];
91 for (i
= 0; i
< app
->n_pipelines
; i
++) {
92 struct app_pipeline_params
*p
= &app
->pipeline_params
[i
];
95 lcore_id
= cpu_core_map_get_lcore_id(app
->core_map
,
101 rte_panic("Cannot create CPU core mask\n");
103 app_core_enable_in_core_mask(app
, lcore_id
);
106 app_core_build_core_mask_string(app
, core_mask_str
);
107 APP_LOG(app
, HIGH
, "CPU core mask = 0x%s", core_mask_str
);
111 app_init_eal(struct app_params
*app
)
114 char core_mask_str
[APP_CORE_MASK_STRING_SIZE
];
115 struct app_eal_params
*p
= &app
->eal_params
;
120 app
->eal_argv
[n_args
++] = strdup(app
->app_name
);
122 app_core_build_core_mask_string(app
, core_mask_str
);
123 snprintf(buffer
, sizeof(buffer
), "-c%s", core_mask_str
);
124 app
->eal_argv
[n_args
++] = strdup(buffer
);
127 snprintf(buffer
, sizeof(buffer
), "--lcores=%s", p
->coremap
);
128 app
->eal_argv
[n_args
++] = strdup(buffer
);
131 if (p
->master_lcore_present
) {
134 "--master-lcore=%" PRIu32
,
136 app
->eal_argv
[n_args
++] = strdup(buffer
);
139 snprintf(buffer
, sizeof(buffer
), "-n%" PRIu32
, p
->channels
);
140 app
->eal_argv
[n_args
++] = strdup(buffer
);
142 if (p
->memory_present
) {
143 snprintf(buffer
, sizeof(buffer
), "-m%" PRIu32
, p
->memory
);
144 app
->eal_argv
[n_args
++] = strdup(buffer
);
147 if (p
->ranks_present
) {
148 snprintf(buffer
, sizeof(buffer
), "-r%" PRIu32
, p
->ranks
);
149 app
->eal_argv
[n_args
++] = strdup(buffer
);
152 for (i
= 0; i
< APP_MAX_LINKS
; i
++) {
153 if (p
->pci_blacklist
[i
] == NULL
)
158 "--pci-blacklist=%s",
159 p
->pci_blacklist
[i
]);
160 app
->eal_argv
[n_args
++] = strdup(buffer
);
163 if (app
->port_mask
!= 0)
164 for (i
= 0; i
< APP_MAX_LINKS
; i
++) {
165 if (p
->pci_whitelist
[i
] == NULL
)
170 "--pci-whitelist=%s",
171 p
->pci_whitelist
[i
]);
172 app
->eal_argv
[n_args
++] = strdup(buffer
);
175 for (i
= 0; i
< app
->n_links
; i
++) {
176 char *pci_bdf
= app
->link_params
[i
].pci_bdf
;
180 "--pci-whitelist=%s",
182 app
->eal_argv
[n_args
++] = strdup(buffer
);
185 for (i
= 0; i
< APP_MAX_LINKS
; i
++) {
186 if (p
->vdev
[i
] == NULL
)
193 app
->eal_argv
[n_args
++] = strdup(buffer
);
196 if ((p
->vmware_tsc_map_present
) && p
->vmware_tsc_map
) {
197 snprintf(buffer
, sizeof(buffer
), "--vmware-tsc-map");
198 app
->eal_argv
[n_args
++] = strdup(buffer
);
206 app
->eal_argv
[n_args
++] = strdup(buffer
);
210 snprintf(buffer
, sizeof(buffer
), "--syslog=%s", p
->syslog
);
211 app
->eal_argv
[n_args
++] = strdup(buffer
);
214 if (p
->log_level_present
) {
217 "--log-level=%" PRIu32
,
219 app
->eal_argv
[n_args
++] = strdup(buffer
);
222 if ((p
->version_present
) && p
->version
) {
223 snprintf(buffer
, sizeof(buffer
), "-v");
224 app
->eal_argv
[n_args
++] = strdup(buffer
);
227 if ((p
->help_present
) && p
->help
) {
228 snprintf(buffer
, sizeof(buffer
), "--help");
229 app
->eal_argv
[n_args
++] = strdup(buffer
);
232 if ((p
->no_huge_present
) && p
->no_huge
) {
233 snprintf(buffer
, sizeof(buffer
), "--no-huge");
234 app
->eal_argv
[n_args
++] = strdup(buffer
);
237 if ((p
->no_pci_present
) && p
->no_pci
) {
238 snprintf(buffer
, sizeof(buffer
), "--no-pci");
239 app
->eal_argv
[n_args
++] = strdup(buffer
);
242 if ((p
->no_hpet_present
) && p
->no_hpet
) {
243 snprintf(buffer
, sizeof(buffer
), "--no-hpet");
244 app
->eal_argv
[n_args
++] = strdup(buffer
);
247 if ((p
->no_shconf_present
) && p
->no_shconf
) {
248 snprintf(buffer
, sizeof(buffer
), "--no-shconf");
249 app
->eal_argv
[n_args
++] = strdup(buffer
);
253 snprintf(buffer
, sizeof(buffer
), "-d%s", p
->add_driver
);
254 app
->eal_argv
[n_args
++] = strdup(buffer
);
262 app
->eal_argv
[n_args
++] = strdup(buffer
);
266 snprintf(buffer
, sizeof(buffer
), "--huge-dir=%s", p
->huge_dir
);
267 app
->eal_argv
[n_args
++] = strdup(buffer
);
270 if (p
->file_prefix
) {
275 app
->eal_argv
[n_args
++] = strdup(buffer
);
278 if (p
->base_virtaddr
) {
281 "--base-virtaddr=%s",
283 app
->eal_argv
[n_args
++] = strdup(buffer
);
286 if ((p
->create_uio_dev_present
) && p
->create_uio_dev
) {
287 snprintf(buffer
, sizeof(buffer
), "--create-uio-dev");
288 app
->eal_argv
[n_args
++] = strdup(buffer
);
296 app
->eal_argv
[n_args
++] = strdup(buffer
);
299 if ((p
->xen_dom0_present
) && (p
->xen_dom0
)) {
300 snprintf(buffer
, sizeof(buffer
), "--xen-dom0");
301 app
->eal_argv
[n_args
++] = strdup(buffer
);
304 snprintf(buffer
, sizeof(buffer
), "--");
305 app
->eal_argv
[n_args
++] = strdup(buffer
);
307 app
->eal_argc
= n_args
;
309 APP_LOG(app
, HIGH
, "Initializing EAL ...");
310 if (app
->log_level
>= APP_LOG_LEVEL_LOW
) {
313 fprintf(stdout
, "[APP] EAL arguments: \"");
314 for (i
= 1; i
< app
->eal_argc
; i
++)
315 fprintf(stdout
, "%s ", app
->eal_argv
[i
]);
316 fprintf(stdout
, "\"\n");
319 status
= rte_eal_init(app
->eal_argc
, app
->eal_argv
);
321 rte_panic("EAL init error\n");
325 app_init_mempool(struct app_params
*app
)
329 for (i
= 0; i
< app
->n_mempools
; i
++) {
330 struct app_mempool_params
*p
= &app
->mempool_params
[i
];
332 APP_LOG(app
, HIGH
, "Initializing %s ...", p
->name
);
333 app
->mempool
[i
] = rte_pktmbuf_pool_create(
339 sizeof(struct rte_mbuf
), /* mbuf data size */
342 if (app
->mempool
[i
] == NULL
)
343 rte_panic("%s init error\n", p
->name
);
348 app_link_filter_arp_add(struct app_link_params
*link
)
350 struct rte_eth_ethertype_filter filter
= {
351 .ether_type
= ETHER_TYPE_ARP
,
353 .queue
= link
->arp_q
,
356 return rte_eth_dev_filter_ctrl(link
->pmd_id
,
357 RTE_ETH_FILTER_ETHERTYPE
,
363 app_link_filter_tcp_syn_add(struct app_link_params
*link
)
365 struct rte_eth_syn_filter filter
= {
367 .queue
= link
->tcp_syn_q
,
370 return rte_eth_dev_filter_ctrl(link
->pmd_id
,
377 app_link_filter_ip_add(struct app_link_params
*l1
, struct app_link_params
*l2
)
379 struct rte_eth_ntuple_filter filter
= {
380 .flags
= RTE_5TUPLE_FLAGS
,
381 .dst_ip
= rte_bswap32(l2
->ip
),
382 .dst_ip_mask
= UINT32_MAX
, /* Enable */
384 .src_ip_mask
= 0, /* Disable */
386 .dst_port_mask
= 0, /* Disable */
388 .src_port_mask
= 0, /* Disable */
390 .proto_mask
= 0, /* Disable */
392 .priority
= 1, /* Lowest */
393 .queue
= l1
->ip_local_q
,
396 return rte_eth_dev_filter_ctrl(l1
->pmd_id
,
397 RTE_ETH_FILTER_NTUPLE
,
403 app_link_filter_ip_del(struct app_link_params
*l1
, struct app_link_params
*l2
)
405 struct rte_eth_ntuple_filter filter
= {
406 .flags
= RTE_5TUPLE_FLAGS
,
407 .dst_ip
= rte_bswap32(l2
->ip
),
408 .dst_ip_mask
= UINT32_MAX
, /* Enable */
410 .src_ip_mask
= 0, /* Disable */
412 .dst_port_mask
= 0, /* Disable */
414 .src_port_mask
= 0, /* Disable */
416 .proto_mask
= 0, /* Disable */
418 .priority
= 1, /* Lowest */
419 .queue
= l1
->ip_local_q
,
422 return rte_eth_dev_filter_ctrl(l1
->pmd_id
,
423 RTE_ETH_FILTER_NTUPLE
,
424 RTE_ETH_FILTER_DELETE
,
429 app_link_filter_tcp_add(struct app_link_params
*l1
, struct app_link_params
*l2
)
431 struct rte_eth_ntuple_filter filter
= {
432 .flags
= RTE_5TUPLE_FLAGS
,
433 .dst_ip
= rte_bswap32(l2
->ip
),
434 .dst_ip_mask
= UINT32_MAX
, /* Enable */
436 .src_ip_mask
= 0, /* Disable */
438 .dst_port_mask
= 0, /* Disable */
440 .src_port_mask
= 0, /* Disable */
441 .proto
= IPPROTO_TCP
,
442 .proto_mask
= UINT8_MAX
, /* Enable */
444 .priority
= 2, /* Higher priority than IP */
445 .queue
= l1
->tcp_local_q
,
448 return rte_eth_dev_filter_ctrl(l1
->pmd_id
,
449 RTE_ETH_FILTER_NTUPLE
,
455 app_link_filter_tcp_del(struct app_link_params
*l1
, struct app_link_params
*l2
)
457 struct rte_eth_ntuple_filter filter
= {
458 .flags
= RTE_5TUPLE_FLAGS
,
459 .dst_ip
= rte_bswap32(l2
->ip
),
460 .dst_ip_mask
= UINT32_MAX
, /* Enable */
462 .src_ip_mask
= 0, /* Disable */
464 .dst_port_mask
= 0, /* Disable */
466 .src_port_mask
= 0, /* Disable */
467 .proto
= IPPROTO_TCP
,
468 .proto_mask
= UINT8_MAX
, /* Enable */
470 .priority
= 2, /* Higher priority than IP */
471 .queue
= l1
->tcp_local_q
,
474 return rte_eth_dev_filter_ctrl(l1
->pmd_id
,
475 RTE_ETH_FILTER_NTUPLE
,
476 RTE_ETH_FILTER_DELETE
,
481 app_link_filter_udp_add(struct app_link_params
*l1
, struct app_link_params
*l2
)
483 struct rte_eth_ntuple_filter filter
= {
484 .flags
= RTE_5TUPLE_FLAGS
,
485 .dst_ip
= rte_bswap32(l2
->ip
),
486 .dst_ip_mask
= UINT32_MAX
, /* Enable */
488 .src_ip_mask
= 0, /* Disable */
490 .dst_port_mask
= 0, /* Disable */
492 .src_port_mask
= 0, /* Disable */
493 .proto
= IPPROTO_UDP
,
494 .proto_mask
= UINT8_MAX
, /* Enable */
496 .priority
= 2, /* Higher priority than IP */
497 .queue
= l1
->udp_local_q
,
500 return rte_eth_dev_filter_ctrl(l1
->pmd_id
,
501 RTE_ETH_FILTER_NTUPLE
,
507 app_link_filter_udp_del(struct app_link_params
*l1
, struct app_link_params
*l2
)
509 struct rte_eth_ntuple_filter filter
= {
510 .flags
= RTE_5TUPLE_FLAGS
,
511 .dst_ip
= rte_bswap32(l2
->ip
),
512 .dst_ip_mask
= UINT32_MAX
, /* Enable */
514 .src_ip_mask
= 0, /* Disable */
516 .dst_port_mask
= 0, /* Disable */
518 .src_port_mask
= 0, /* Disable */
519 .proto
= IPPROTO_UDP
,
520 .proto_mask
= UINT8_MAX
, /* Enable */
522 .priority
= 2, /* Higher priority than IP */
523 .queue
= l1
->udp_local_q
,
526 return rte_eth_dev_filter_ctrl(l1
->pmd_id
,
527 RTE_ETH_FILTER_NTUPLE
,
528 RTE_ETH_FILTER_DELETE
,
533 app_link_filter_sctp_add(struct app_link_params
*l1
, struct app_link_params
*l2
)
535 struct rte_eth_ntuple_filter filter
= {
536 .flags
= RTE_5TUPLE_FLAGS
,
537 .dst_ip
= rte_bswap32(l2
->ip
),
538 .dst_ip_mask
= UINT32_MAX
, /* Enable */
540 .src_ip_mask
= 0, /* Disable */
542 .dst_port_mask
= 0, /* Disable */
544 .src_port_mask
= 0, /* Disable */
545 .proto
= IPPROTO_SCTP
,
546 .proto_mask
= UINT8_MAX
, /* Enable */
548 .priority
= 2, /* Higher priority than IP */
549 .queue
= l1
->sctp_local_q
,
552 return rte_eth_dev_filter_ctrl(l1
->pmd_id
,
553 RTE_ETH_FILTER_NTUPLE
,
559 app_link_filter_sctp_del(struct app_link_params
*l1
, struct app_link_params
*l2
)
561 struct rte_eth_ntuple_filter filter
= {
562 .flags
= RTE_5TUPLE_FLAGS
,
563 .dst_ip
= rte_bswap32(l2
->ip
),
564 .dst_ip_mask
= UINT32_MAX
, /* Enable */
566 .src_ip_mask
= 0, /* Disable */
568 .dst_port_mask
= 0, /* Disable */
570 .src_port_mask
= 0, /* Disable */
571 .proto
= IPPROTO_SCTP
,
572 .proto_mask
= UINT8_MAX
, /* Enable */
574 .priority
= 2, /* Higher priority than IP */
575 .queue
= l1
->sctp_local_q
,
578 return rte_eth_dev_filter_ctrl(l1
->pmd_id
,
579 RTE_ETH_FILTER_NTUPLE
,
580 RTE_ETH_FILTER_DELETE
,
585 app_link_set_arp_filter(struct app_params
*app
, struct app_link_params
*cp
)
587 if (cp
->arp_q
!= 0) {
588 int status
= app_link_filter_arp_add(cp
);
590 APP_LOG(app
, LOW
, "%s (%" PRIu32
"): "
591 "Adding ARP filter (queue = %" PRIu32
")",
592 cp
->name
, cp
->pmd_id
, cp
->arp_q
);
595 rte_panic("%s (%" PRIu32
"): "
596 "Error adding ARP filter "
597 "(queue = %" PRIu32
") (%" PRId32
")\n",
598 cp
->name
, cp
->pmd_id
, cp
->arp_q
, status
);
603 app_link_set_tcp_syn_filter(struct app_params
*app
, struct app_link_params
*cp
)
605 if (cp
->tcp_syn_q
!= 0) {
606 int status
= app_link_filter_tcp_syn_add(cp
);
608 APP_LOG(app
, LOW
, "%s (%" PRIu32
"): "
609 "Adding TCP SYN filter (queue = %" PRIu32
")",
610 cp
->name
, cp
->pmd_id
, cp
->tcp_syn_q
);
613 rte_panic("%s (%" PRIu32
"): "
614 "Error adding TCP SYN filter "
615 "(queue = %" PRIu32
") (%" PRId32
")\n",
616 cp
->name
, cp
->pmd_id
, cp
->tcp_syn_q
,
622 app_link_up_internal(struct app_params
*app
, struct app_link_params
*cp
)
627 /* For each link, add filters for IP of current link */
629 for (i
= 0; i
< app
->n_links
; i
++) {
630 struct app_link_params
*p
= &app
->link_params
[i
];
633 if (p
->ip_local_q
!= 0) {
634 int status
= app_link_filter_ip_add(p
, cp
);
636 APP_LOG(app
, LOW
, "%s (%" PRIu32
"): "
637 "Adding IP filter (queue= %" PRIu32
638 ", IP = 0x%08" PRIx32
")",
639 p
->name
, p
->pmd_id
, p
->ip_local_q
,
643 rte_panic("%s (%" PRIu32
"): "
645 "filter (queue= %" PRIu32
", "
649 p
->ip_local_q
, cp
->ip
, status
);
653 if (p
->tcp_local_q
!= 0) {
654 int status
= app_link_filter_tcp_add(p
, cp
);
656 APP_LOG(app
, LOW
, "%s (%" PRIu32
"): "
659 ", IP = 0x%08" PRIx32
")",
660 p
->name
, p
->pmd_id
, p
->tcp_local_q
,
664 rte_panic("%s (%" PRIu32
"): "
666 "filter (queue = %" PRIu32
", "
670 p
->tcp_local_q
, cp
->ip
, status
);
674 if (p
->udp_local_q
!= 0) {
675 int status
= app_link_filter_udp_add(p
, cp
);
677 APP_LOG(app
, LOW
, "%s (%" PRIu32
"): "
680 ", IP = 0x%08" PRIx32
")",
681 p
->name
, p
->pmd_id
, p
->udp_local_q
,
685 rte_panic("%s (%" PRIu32
"): "
687 "filter (queue = %" PRIu32
", "
691 p
->udp_local_q
, cp
->ip
, status
);
695 if (p
->sctp_local_q
!= 0) {
696 int status
= app_link_filter_sctp_add(p
, cp
);
698 APP_LOG(app
, LOW
, "%s (%" PRIu32
699 "): Adding SCTP filter "
701 ", IP = 0x%08" PRIx32
")",
702 p
->name
, p
->pmd_id
, p
->sctp_local_q
,
706 rte_panic("%s (%" PRIu32
"): "
708 "filter (queue = %" PRIu32
", "
712 p
->sctp_local_q
, cp
->ip
,
719 status
= rte_eth_dev_set_link_up(cp
->pmd_id
);
720 /* Do not panic if PMD does not provide link up functionality */
721 if (status
< 0 && status
!= -ENOTSUP
)
722 rte_panic("%s (%" PRIu32
"): PMD set link up error %"
723 PRId32
"\n", cp
->name
, cp
->pmd_id
, status
);
725 /* Mark link as UP */
730 app_link_down_internal(struct app_params
*app
, struct app_link_params
*cp
)
736 status
= rte_eth_dev_set_link_down(cp
->pmd_id
);
737 /* Do not panic if PMD does not provide link down functionality */
738 if (status
< 0 && status
!= -ENOTSUP
)
739 rte_panic("%s (%" PRIu32
"): PMD set link down error %"
740 PRId32
"\n", cp
->name
, cp
->pmd_id
, status
);
742 /* Mark link as DOWN */
745 /* Return if current link IP is not valid */
749 /* For each link, remove filters for IP of current link */
750 for (i
= 0; i
< app
->n_links
; i
++) {
751 struct app_link_params
*p
= &app
->link_params
[i
];
754 if (p
->ip_local_q
!= 0) {
755 int status
= app_link_filter_ip_del(p
, cp
);
757 APP_LOG(app
, LOW
, "%s (%" PRIu32
758 "): Deleting IP filter "
759 "(queue = %" PRIu32
", IP = 0x%" PRIx32
")",
760 p
->name
, p
->pmd_id
, p
->ip_local_q
, cp
->ip
);
763 rte_panic("%s (%" PRIu32
764 "): Error deleting IP filter "
768 p
->name
, p
->pmd_id
, p
->ip_local_q
,
773 if (p
->tcp_local_q
!= 0) {
774 int status
= app_link_filter_tcp_del(p
, cp
);
776 APP_LOG(app
, LOW
, "%s (%" PRIu32
777 "): Deleting TCP filter "
779 ", IP = 0x%" PRIx32
")",
780 p
->name
, p
->pmd_id
, p
->tcp_local_q
, cp
->ip
);
783 rte_panic("%s (%" PRIu32
784 "): Error deleting TCP filter "
788 p
->name
, p
->pmd_id
, p
->tcp_local_q
,
793 if (p
->udp_local_q
!= 0) {
794 int status
= app_link_filter_udp_del(p
, cp
);
796 APP_LOG(app
, LOW
, "%s (%" PRIu32
797 "): Deleting UDP filter "
798 "(queue = %" PRIu32
", IP = 0x%" PRIx32
")",
799 p
->name
, p
->pmd_id
, p
->udp_local_q
, cp
->ip
);
802 rte_panic("%s (%" PRIu32
803 "): Error deleting UDP filter "
807 p
->name
, p
->pmd_id
, p
->udp_local_q
,
812 if (p
->sctp_local_q
!= 0) {
813 int status
= app_link_filter_sctp_del(p
, cp
);
815 APP_LOG(app
, LOW
, "%s (%" PRIu32
816 "): Deleting SCTP filter "
818 ", IP = 0x%" PRIx32
")",
819 p
->name
, p
->pmd_id
, p
->sctp_local_q
, cp
->ip
);
822 rte_panic("%s (%" PRIu32
823 "): Error deleting SCTP filter "
827 p
->name
, p
->pmd_id
, p
->sctp_local_q
,
834 app_check_link(struct app_params
*app
)
836 uint32_t all_links_up
, i
;
840 for (i
= 0; i
< app
->n_links
; i
++) {
841 struct app_link_params
*p
= &app
->link_params
[i
];
842 struct rte_eth_link link_params
;
844 memset(&link_params
, 0, sizeof(link_params
));
845 rte_eth_link_get(p
->pmd_id
, &link_params
);
847 APP_LOG(app
, HIGH
, "%s (%" PRIu32
") (%" PRIu32
" Gbps) %s",
850 link_params
.link_speed
/ 1000,
851 link_params
.link_status
? "UP" : "DOWN");
853 if (link_params
.link_status
== ETH_LINK_DOWN
)
857 if (all_links_up
== 0)
858 rte_panic("Some links are DOWN\n");
862 is_any_swq_frag_or_ras(struct app_params
*app
)
866 for (i
= 0; i
< app
->n_pktq_swq
; i
++) {
867 struct app_pktq_swq_params
*p
= &app
->swq_params
[i
];
869 if ((p
->ipv4_frag
== 1) || (p
->ipv6_frag
== 1) ||
870 (p
->ipv4_ras
== 1) || (p
->ipv6_ras
== 1))
878 app_init_link_frag_ras(struct app_params
*app
)
882 if (is_any_swq_frag_or_ras(app
)) {
883 for (i
= 0; i
< app
->n_pktq_hwq_out
; i
++) {
884 struct app_pktq_hwq_out_params
*p_txq
= &app
->hwq_out_params
[i
];
886 p_txq
->conf
.txq_flags
&= ~ETH_TXQ_FLAGS_NOMULTSEGS
;
892 app_get_cpu_socket_id(uint32_t pmd_id
)
894 int status
= rte_eth_dev_socket_id(pmd_id
);
896 return (status
!= SOCKET_ID_ANY
) ? status
: 0;
900 app_link_rss_enabled(struct app_link_params
*cp
)
902 return (cp
->n_rss_qs
) ? 1 : 0;
906 app_link_rss_setup(struct app_link_params
*cp
)
908 struct rte_eth_dev_info dev_info
;
909 struct rte_eth_rss_reta_entry64 reta_conf
[APP_RETA_SIZE_MAX
];
914 memset(&dev_info
, 0, sizeof(dev_info
));
915 rte_eth_dev_info_get(cp
->pmd_id
, &dev_info
);
917 if (dev_info
.reta_size
== 0)
918 rte_panic("%s (%u): RSS setup error (null RETA size)\n",
919 cp
->name
, cp
->pmd_id
);
921 if (dev_info
.reta_size
> ETH_RSS_RETA_SIZE_512
)
922 rte_panic("%s (%u): RSS setup error (RETA size too big)\n",
923 cp
->name
, cp
->pmd_id
);
925 /* Setup RETA contents */
926 memset(reta_conf
, 0, sizeof(reta_conf
));
928 for (i
= 0; i
< dev_info
.reta_size
; i
++)
929 reta_conf
[i
/ RTE_RETA_GROUP_SIZE
].mask
= UINT64_MAX
;
931 for (i
= 0; i
< dev_info
.reta_size
; i
++) {
932 uint32_t reta_id
= i
/ RTE_RETA_GROUP_SIZE
;
933 uint32_t reta_pos
= i
% RTE_RETA_GROUP_SIZE
;
934 uint32_t rss_qs_pos
= i
% cp
->n_rss_qs
;
936 reta_conf
[reta_id
].reta
[reta_pos
] =
937 (uint16_t) cp
->rss_qs
[rss_qs_pos
];
941 status
= rte_eth_dev_rss_reta_update(cp
->pmd_id
,
945 rte_panic("%s (%u): RSS setup error (RETA update failed)\n",
946 cp
->name
, cp
->pmd_id
);
950 app_init_link_set_config(struct app_link_params
*p
)
953 p
->conf
.rxmode
.mq_mode
= ETH_MQ_RX_RSS
;
954 p
->conf
.rx_adv_conf
.rss_conf
.rss_hf
= p
->rss_proto_ipv4
|
961 app_init_link(struct app_params
*app
)
965 app_init_link_frag_ras(app
);
967 for (i
= 0; i
< app
->n_links
; i
++) {
968 struct app_link_params
*p_link
= &app
->link_params
[i
];
969 uint32_t link_id
, n_hwq_in
, n_hwq_out
, j
;
972 sscanf(p_link
->name
, "LINK%" PRIu32
, &link_id
);
973 n_hwq_in
= app_link_get_n_rxq(app
, p_link
);
974 n_hwq_out
= app_link_get_n_txq(app
, p_link
);
975 app_init_link_set_config(p_link
);
977 APP_LOG(app
, HIGH
, "Initializing %s (%" PRIu32
") "
978 "(%" PRIu32
" RXQ, %" PRIu32
" TXQ) ...",
985 status
= rte_eth_dev_configure(
991 rte_panic("%s (%" PRId32
"): "
992 "init error (%" PRId32
")\n",
993 p_link
->name
, p_link
->pmd_id
, status
);
995 rte_eth_macaddr_get(p_link
->pmd_id
,
996 (struct ether_addr
*) &p_link
->mac_addr
);
999 rte_eth_promiscuous_enable(p_link
->pmd_id
);
1002 for (j
= 0; j
< app
->n_pktq_hwq_in
; j
++) {
1003 struct app_pktq_hwq_in_params
*p_rxq
=
1004 &app
->hwq_in_params
[j
];
1005 uint32_t rxq_link_id
, rxq_queue_id
;
1007 sscanf(p_rxq
->name
, "RXQ%" PRIu32
".%" PRIu32
,
1008 &rxq_link_id
, &rxq_queue_id
);
1009 if (rxq_link_id
!= link_id
)
1012 status
= rte_eth_rx_queue_setup(
1016 app_get_cpu_socket_id(p_link
->pmd_id
),
1018 app
->mempool
[p_rxq
->mempool_id
]);
1020 rte_panic("%s (%" PRIu32
"): "
1021 "%s init error (%" PRId32
")\n",
1029 for (j
= 0; j
< app
->n_pktq_hwq_out
; j
++) {
1030 struct app_pktq_hwq_out_params
*p_txq
=
1031 &app
->hwq_out_params
[j
];
1032 uint32_t txq_link_id
, txq_queue_id
;
1034 sscanf(p_txq
->name
, "TXQ%" PRIu32
".%" PRIu32
,
1035 &txq_link_id
, &txq_queue_id
);
1036 if (txq_link_id
!= link_id
)
1039 status
= rte_eth_tx_queue_setup(
1043 app_get_cpu_socket_id(p_link
->pmd_id
),
1046 rte_panic("%s (%" PRIu32
"): "
1047 "%s init error (%" PRId32
")\n",
1055 status
= rte_eth_dev_start(p_link
->pmd_id
);
1057 rte_panic("Cannot start %s (error %" PRId32
")\n",
1058 p_link
->name
, status
);
1061 app_link_set_arp_filter(app
, p_link
);
1062 app_link_set_tcp_syn_filter(app
, p_link
);
1063 if (app_link_rss_enabled(p_link
))
1064 app_link_rss_setup(p_link
);
1067 app_link_up_internal(app
, p_link
);
1070 app_check_link(app
);
1074 app_init_swq(struct app_params
*app
)
1078 for (i
= 0; i
< app
->n_pktq_swq
; i
++) {
1079 struct app_pktq_swq_params
*p
= &app
->swq_params
[i
];
1082 if (app_swq_get_readers(app
, p
) == 1)
1083 flags
|= RING_F_SC_DEQ
;
1084 if (app_swq_get_writers(app
, p
) == 1)
1085 flags
|= RING_F_SP_ENQ
;
1087 APP_LOG(app
, HIGH
, "Initializing %s...", p
->name
);
1088 app
->swq
[i
] = rte_ring_create(
1094 if (app
->swq
[i
] == NULL
)
1095 rte_panic("%s init error\n", p
->name
);
1100 app_init_tm(struct app_params
*app
)
1104 for (i
= 0; i
< app
->n_pktq_tm
; i
++) {
1105 struct app_pktq_tm_params
*p_tm
= &app
->tm_params
[i
];
1106 struct app_link_params
*p_link
;
1107 struct rte_eth_link link_eth_params
;
1108 struct rte_sched_port
*sched
;
1109 uint32_t n_subports
, subport_id
;
1112 p_link
= app_get_link_for_tm(app
, p_tm
);
1114 rte_eth_link_get(p_link
->pmd_id
, &link_eth_params
);
1117 p_tm
->sched_port_params
.name
= p_tm
->name
;
1118 p_tm
->sched_port_params
.socket
=
1119 app_get_cpu_socket_id(p_link
->pmd_id
);
1120 p_tm
->sched_port_params
.rate
=
1121 (uint64_t) link_eth_params
.link_speed
* 1000 * 1000 / 8;
1123 APP_LOG(app
, HIGH
, "Initializing %s ...", p_tm
->name
);
1124 sched
= rte_sched_port_config(&p_tm
->sched_port_params
);
1126 rte_panic("%s init error\n", p_tm
->name
);
1130 n_subports
= p_tm
->sched_port_params
.n_subports_per_port
;
1131 for (subport_id
= 0; subport_id
< n_subports
; subport_id
++) {
1132 uint32_t n_pipes_per_subport
, pipe_id
;
1134 status
= rte_sched_subport_config(sched
,
1136 &p_tm
->sched_subport_params
[subport_id
]);
1138 rte_panic("%s subport %" PRIu32
1139 " init error (%" PRId32
")\n",
1140 p_tm
->name
, subport_id
, status
);
1143 n_pipes_per_subport
=
1144 p_tm
->sched_port_params
.n_pipes_per_subport
;
1146 pipe_id
< n_pipes_per_subport
;
1148 int profile_id
= p_tm
->sched_pipe_to_profile
[
1149 subport_id
* APP_MAX_SCHED_PIPES
+
1152 if (profile_id
== -1)
1155 status
= rte_sched_pipe_config(sched
,
1160 rte_panic("%s subport %" PRIu32
1162 " (profile %" PRId32
") "
1163 "init error (% " PRId32
")\n",
1164 p_tm
->name
, subport_id
, pipe_id
,
1165 profile_id
, status
);
1171 #ifndef RTE_EXEC_ENV_LINUXAPP
1173 app_init_tap(struct app_params
*app
) {
1174 if (app
->n_pktq_tap
== 0)
1177 rte_panic("TAP device not supported.\n");
1181 app_init_tap(struct app_params
*app
)
1185 for (i
= 0; i
< app
->n_pktq_tap
; i
++) {
1186 struct app_pktq_tap_params
*p_tap
= &app
->tap_params
[i
];
1190 APP_LOG(app
, HIGH
, "Initializing %s ...", p_tap
->name
);
1192 fd
= open("/dev/net/tun", O_RDWR
| O_NONBLOCK
);
1194 rte_panic("Cannot open file /dev/net/tun\n");
1196 memset(&ifr
, 0, sizeof(ifr
));
1197 ifr
.ifr_flags
= IFF_TAP
| IFF_NO_PI
; /* No packet information */
1198 snprintf(ifr
.ifr_name
, IFNAMSIZ
, "%s", p_tap
->name
);
1200 status
= ioctl(fd
, TUNSETIFF
, (void *) &ifr
);
1202 rte_panic("TAP setup error\n");
1209 #ifdef RTE_LIBRTE_KNI
1211 kni_config_network_interface(uint8_t port_id
, uint8_t if_up
) {
1214 if (port_id
>= rte_eth_dev_count())
1218 rte_eth_dev_set_link_up(port_id
) :
1219 rte_eth_dev_set_link_down(port_id
);
1225 kni_change_mtu(uint8_t port_id
, unsigned new_mtu
) {
1228 if (port_id
>= rte_eth_dev_count())
1231 if (new_mtu
> ETHER_MAX_LEN
)
1235 ret
= rte_eth_dev_set_mtu(port_id
, new_mtu
);
1241 #endif /* RTE_LIBRTE_KNI */
1243 #ifndef RTE_LIBRTE_KNI
1245 app_init_kni(struct app_params
*app
) {
1246 if (app
->n_pktq_kni
== 0)
1249 rte_panic("Can not init KNI without librte_kni support.\n");
1253 app_init_kni(struct app_params
*app
) {
1256 if (app
->n_pktq_kni
== 0)
1259 rte_kni_init(app
->n_pktq_kni
);
1261 for (i
= 0; i
< app
->n_pktq_kni
; i
++) {
1262 struct app_pktq_kni_params
*p_kni
= &app
->kni_params
[i
];
1263 struct app_link_params
*p_link
;
1264 struct rte_eth_dev_info dev_info
;
1265 struct app_mempool_params
*mempool_params
;
1266 struct rte_mempool
*mempool
;
1267 struct rte_kni_conf conf
;
1268 struct rte_kni_ops ops
;
1271 p_link
= app_get_link_for_kni(app
, p_kni
);
1272 memset(&dev_info
, 0, sizeof(dev_info
));
1273 rte_eth_dev_info_get(p_link
->pmd_id
, &dev_info
);
1276 mempool_params
= &app
->mempool_params
[p_kni
->mempool_id
];
1277 mempool
= app
->mempool
[p_kni
->mempool_id
];
1280 memset(&conf
, 0, sizeof(conf
));
1281 snprintf(conf
.name
, RTE_KNI_NAMESIZE
, "%s", p_kni
->name
);
1282 conf
.force_bind
= p_kni
->force_bind
;
1283 if (conf
.force_bind
) {
1286 lcore_id
= cpu_core_map_get_lcore_id(app
->core_map
,
1289 p_kni
->hyper_th_id
);
1292 rte_panic("%s invalid CPU core\n", p_kni
->name
);
1294 conf
.core_id
= (uint32_t) lcore_id
;
1296 conf
.group_id
= p_link
->pmd_id
;
1297 conf
.mbuf_size
= mempool_params
->buffer_size
;
1298 conf
.addr
= dev_info
.pci_dev
->addr
;
1299 conf
.id
= dev_info
.pci_dev
->id
;
1301 memset(&ops
, 0, sizeof(ops
));
1302 ops
.port_id
= (uint8_t) p_link
->pmd_id
;
1303 ops
.change_mtu
= kni_change_mtu
;
1304 ops
.config_network_if
= kni_config_network_interface
;
1306 APP_LOG(app
, HIGH
, "Initializing %s ...", p_kni
->name
);
1307 app
->kni
[i
] = rte_kni_alloc(mempool
, &conf
, &ops
);
1309 rte_panic("%s init error\n", p_kni
->name
);
1312 #endif /* RTE_LIBRTE_KNI */
1315 app_init_msgq(struct app_params
*app
)
1319 for (i
= 0; i
< app
->n_msgq
; i
++) {
1320 struct app_msgq_params
*p
= &app
->msgq_params
[i
];
1322 APP_LOG(app
, HIGH
, "Initializing %s ...", p
->name
);
1323 app
->msgq
[i
] = rte_ring_create(
1327 RING_F_SP_ENQ
| RING_F_SC_DEQ
);
1329 if (app
->msgq
[i
] == NULL
)
1330 rte_panic("%s init error\n", p
->name
);
1334 void app_pipeline_params_get(struct app_params
*app
,
1335 struct app_pipeline_params
*p_in
,
1336 struct pipeline_params
*p_out
)
1340 snprintf(p_out
->name
, PIPELINE_NAME_SIZE
, "%s", p_in
->name
);
1342 snprintf(p_out
->type
, PIPELINE_TYPE_SIZE
, "%s", p_in
->type
);
1344 p_out
->socket_id
= (int) p_in
->socket_id
;
1346 p_out
->log_level
= app
->log_level
;
1349 p_out
->n_ports_in
= p_in
->n_pktq_in
;
1350 for (i
= 0; i
< p_in
->n_pktq_in
; i
++) {
1351 struct app_pktq_in_params
*in
= &p_in
->pktq_in
[i
];
1352 struct pipeline_port_in_params
*out
= &p_out
->port_in
[i
];
1355 case APP_PKTQ_IN_HWQ
:
1357 struct app_pktq_hwq_in_params
*p_hwq_in
=
1358 &app
->hwq_in_params
[in
->id
];
1359 struct app_link_params
*p_link
=
1360 app_get_link_for_rxq(app
, p_hwq_in
);
1361 uint32_t rxq_link_id
, rxq_queue_id
;
1363 sscanf(p_hwq_in
->name
, "RXQ%" SCNu32
".%" SCNu32
,
1367 out
->type
= PIPELINE_PORT_IN_ETHDEV_READER
;
1368 out
->params
.ethdev
.port_id
= p_link
->pmd_id
;
1369 out
->params
.ethdev
.queue_id
= rxq_queue_id
;
1370 out
->burst_size
= p_hwq_in
->burst
;
1373 case APP_PKTQ_IN_SWQ
:
1375 struct app_pktq_swq_params
*swq_params
= &app
->swq_params
[in
->id
];
1377 if ((swq_params
->ipv4_frag
== 0) && (swq_params
->ipv6_frag
== 0)) {
1378 if (app_swq_get_readers(app
, swq_params
) == 1) {
1379 out
->type
= PIPELINE_PORT_IN_RING_READER
;
1380 out
->params
.ring
.ring
= app
->swq
[in
->id
];
1381 out
->burst_size
= app
->swq_params
[in
->id
].burst_read
;
1383 out
->type
= PIPELINE_PORT_IN_RING_MULTI_READER
;
1384 out
->params
.ring_multi
.ring
= app
->swq
[in
->id
];
1385 out
->burst_size
= swq_params
->burst_read
;
1388 if (swq_params
->ipv4_frag
== 1) {
1389 struct rte_port_ring_reader_ipv4_frag_params
*params
=
1390 &out
->params
.ring_ipv4_frag
;
1392 out
->type
= PIPELINE_PORT_IN_RING_READER_IPV4_FRAG
;
1393 params
->ring
= app
->swq
[in
->id
];
1394 params
->mtu
= swq_params
->mtu
;
1395 params
->metadata_size
= swq_params
->metadata_size
;
1396 params
->pool_direct
=
1397 app
->mempool
[swq_params
->mempool_direct_id
];
1398 params
->pool_indirect
=
1399 app
->mempool
[swq_params
->mempool_indirect_id
];
1400 out
->burst_size
= swq_params
->burst_read
;
1402 struct rte_port_ring_reader_ipv6_frag_params
*params
=
1403 &out
->params
.ring_ipv6_frag
;
1405 out
->type
= PIPELINE_PORT_IN_RING_READER_IPV6_FRAG
;
1406 params
->ring
= app
->swq
[in
->id
];
1407 params
->mtu
= swq_params
->mtu
;
1408 params
->metadata_size
= swq_params
->metadata_size
;
1409 params
->pool_direct
=
1410 app
->mempool
[swq_params
->mempool_direct_id
];
1411 params
->pool_indirect
=
1412 app
->mempool
[swq_params
->mempool_indirect_id
];
1413 out
->burst_size
= swq_params
->burst_read
;
1418 case APP_PKTQ_IN_TM
:
1420 out
->type
= PIPELINE_PORT_IN_SCHED_READER
;
1421 out
->params
.sched
.sched
= app
->tm
[in
->id
];
1422 out
->burst_size
= app
->tm_params
[in
->id
].burst_read
;
1425 #ifdef RTE_EXEC_ENV_LINUXAPP
1426 case APP_PKTQ_IN_TAP
:
1428 struct app_pktq_tap_params
*tap_params
=
1429 &app
->tap_params
[in
->id
];
1430 struct app_mempool_params
*mempool_params
=
1431 &app
->mempool_params
[tap_params
->mempool_id
];
1432 struct rte_mempool
*mempool
=
1433 app
->mempool
[tap_params
->mempool_id
];
1435 out
->type
= PIPELINE_PORT_IN_FD_READER
;
1436 out
->params
.fd
.fd
= app
->tap
[in
->id
];
1437 out
->params
.fd
.mtu
= mempool_params
->buffer_size
;
1438 out
->params
.fd
.mempool
= mempool
;
1439 out
->burst_size
= app
->tap_params
[in
->id
].burst_read
;
1443 #ifdef RTE_LIBRTE_KNI
1444 case APP_PKTQ_IN_KNI
:
1446 out
->type
= PIPELINE_PORT_IN_KNI_READER
;
1447 out
->params
.kni
.kni
= app
->kni
[in
->id
];
1448 out
->burst_size
= app
->kni_params
[in
->id
].burst_read
;
1451 #endif /* RTE_LIBRTE_KNI */
1452 case APP_PKTQ_IN_SOURCE
:
1454 uint32_t mempool_id
=
1455 app
->source_params
[in
->id
].mempool_id
;
1457 out
->type
= PIPELINE_PORT_IN_SOURCE
;
1458 out
->params
.source
.mempool
= app
->mempool
[mempool_id
];
1459 out
->burst_size
= app
->source_params
[in
->id
].burst
;
1460 out
->params
.source
.file_name
=
1461 app
->source_params
[in
->id
].file_name
;
1462 out
->params
.source
.n_bytes_per_pkt
=
1463 app
->source_params
[in
->id
].n_bytes_per_pkt
;
1472 p_out
->n_ports_out
= p_in
->n_pktq_out
;
1473 for (i
= 0; i
< p_in
->n_pktq_out
; i
++) {
1474 struct app_pktq_out_params
*in
= &p_in
->pktq_out
[i
];
1475 struct pipeline_port_out_params
*out
= &p_out
->port_out
[i
];
1478 case APP_PKTQ_OUT_HWQ
:
1480 struct app_pktq_hwq_out_params
*p_hwq_out
=
1481 &app
->hwq_out_params
[in
->id
];
1482 struct app_link_params
*p_link
=
1483 app_get_link_for_txq(app
, p_hwq_out
);
1484 uint32_t txq_link_id
, txq_queue_id
;
1486 sscanf(p_hwq_out
->name
,
1487 "TXQ%" SCNu32
".%" SCNu32
,
1491 if (p_hwq_out
->dropless
== 0) {
1492 struct rte_port_ethdev_writer_params
*params
=
1493 &out
->params
.ethdev
;
1495 out
->type
= PIPELINE_PORT_OUT_ETHDEV_WRITER
;
1496 params
->port_id
= p_link
->pmd_id
;
1497 params
->queue_id
= txq_queue_id
;
1498 params
->tx_burst_sz
=
1499 app
->hwq_out_params
[in
->id
].burst
;
1501 struct rte_port_ethdev_writer_nodrop_params
1502 *params
= &out
->params
.ethdev_nodrop
;
1505 PIPELINE_PORT_OUT_ETHDEV_WRITER_NODROP
;
1506 params
->port_id
= p_link
->pmd_id
;
1507 params
->queue_id
= txq_queue_id
;
1508 params
->tx_burst_sz
= p_hwq_out
->burst
;
1509 params
->n_retries
= p_hwq_out
->n_retries
;
1513 case APP_PKTQ_OUT_SWQ
:
1515 struct app_pktq_swq_params
*swq_params
= &app
->swq_params
[in
->id
];
1517 if ((swq_params
->ipv4_ras
== 0) && (swq_params
->ipv6_ras
== 0)) {
1518 if (app_swq_get_writers(app
, swq_params
) == 1) {
1519 if (app
->swq_params
[in
->id
].dropless
== 0) {
1520 struct rte_port_ring_writer_params
*params
=
1523 out
->type
= PIPELINE_PORT_OUT_RING_WRITER
;
1524 params
->ring
= app
->swq
[in
->id
];
1525 params
->tx_burst_sz
=
1526 app
->swq_params
[in
->id
].burst_write
;
1528 struct rte_port_ring_writer_nodrop_params
1529 *params
= &out
->params
.ring_nodrop
;
1532 PIPELINE_PORT_OUT_RING_WRITER_NODROP
;
1533 params
->ring
= app
->swq
[in
->id
];
1534 params
->tx_burst_sz
=
1535 app
->swq_params
[in
->id
].burst_write
;
1537 app
->swq_params
[in
->id
].n_retries
;
1540 if (swq_params
->dropless
== 0) {
1541 struct rte_port_ring_multi_writer_params
*params
=
1542 &out
->params
.ring_multi
;
1544 out
->type
= PIPELINE_PORT_OUT_RING_MULTI_WRITER
;
1545 params
->ring
= app
->swq
[in
->id
];
1546 params
->tx_burst_sz
= swq_params
->burst_write
;
1548 struct rte_port_ring_multi_writer_nodrop_params
1549 *params
= &out
->params
.ring_multi_nodrop
;
1551 out
->type
= PIPELINE_PORT_OUT_RING_MULTI_WRITER_NODROP
;
1552 params
->ring
= app
->swq
[in
->id
];
1553 params
->tx_burst_sz
= swq_params
->burst_write
;
1554 params
->n_retries
= swq_params
->n_retries
;
1558 if (swq_params
->ipv4_ras
== 1) {
1559 struct rte_port_ring_writer_ipv4_ras_params
*params
=
1560 &out
->params
.ring_ipv4_ras
;
1562 out
->type
= PIPELINE_PORT_OUT_RING_WRITER_IPV4_RAS
;
1563 params
->ring
= app
->swq
[in
->id
];
1564 params
->tx_burst_sz
= swq_params
->burst_write
;
1566 struct rte_port_ring_writer_ipv6_ras_params
*params
=
1567 &out
->params
.ring_ipv6_ras
;
1569 out
->type
= PIPELINE_PORT_OUT_RING_WRITER_IPV6_RAS
;
1570 params
->ring
= app
->swq
[in
->id
];
1571 params
->tx_burst_sz
= swq_params
->burst_write
;
1576 case APP_PKTQ_OUT_TM
:
1578 struct rte_port_sched_writer_params
*params
=
1581 out
->type
= PIPELINE_PORT_OUT_SCHED_WRITER
;
1582 params
->sched
= app
->tm
[in
->id
];
1583 params
->tx_burst_sz
=
1584 app
->tm_params
[in
->id
].burst_write
;
1587 #ifdef RTE_EXEC_ENV_LINUXAPP
1588 case APP_PKTQ_OUT_TAP
:
1590 struct rte_port_fd_writer_params
*params
=
1593 out
->type
= PIPELINE_PORT_OUT_FD_WRITER
;
1594 params
->fd
= app
->tap
[in
->id
];
1595 params
->tx_burst_sz
=
1596 app
->tap_params
[in
->id
].burst_write
;
1600 #ifdef RTE_LIBRTE_KNI
1601 case APP_PKTQ_OUT_KNI
:
1603 struct app_pktq_kni_params
*p_kni
=
1604 &app
->kni_params
[in
->id
];
1606 if (p_kni
->dropless
== 0) {
1607 struct rte_port_kni_writer_params
*params
=
1610 out
->type
= PIPELINE_PORT_OUT_KNI_WRITER
;
1611 params
->kni
= app
->kni
[in
->id
];
1612 params
->tx_burst_sz
=
1613 app
->kni_params
[in
->id
].burst_write
;
1615 struct rte_port_kni_writer_nodrop_params
1616 *params
= &out
->params
.kni_nodrop
;
1618 out
->type
= PIPELINE_PORT_OUT_KNI_WRITER_NODROP
;
1619 params
->kni
= app
->kni
[in
->id
];
1620 params
->tx_burst_sz
=
1621 app
->kni_params
[in
->id
].burst_write
;
1623 app
->kni_params
[in
->id
].n_retries
;
1627 #endif /* RTE_LIBRTE_KNI */
1628 case APP_PKTQ_OUT_SINK
:
1630 out
->type
= PIPELINE_PORT_OUT_SINK
;
1631 out
->params
.sink
.file_name
=
1632 app
->sink_params
[in
->id
].file_name
;
1633 out
->params
.sink
.max_n_pkts
=
1634 app
->sink_params
[in
->id
].
1645 p_out
->n_msgq
= p_in
->n_msgq_in
;
1647 for (i
= 0; i
< p_in
->n_msgq_in
; i
++)
1648 p_out
->msgq_in
[i
] = app
->msgq
[p_in
->msgq_in
[i
]];
1650 for (i
= 0; i
< p_in
->n_msgq_out
; i
++)
1651 p_out
->msgq_out
[i
] = app
->msgq
[p_in
->msgq_out
[i
]];
1654 p_out
->n_args
= p_in
->n_args
;
1655 for (i
= 0; i
< p_in
->n_args
; i
++) {
1656 p_out
->args_name
[i
] = p_in
->args_name
[i
];
1657 p_out
->args_value
[i
] = p_in
->args_value
[i
];
1662 app_init_pipelines(struct app_params
*app
)
1666 for (p_id
= 0; p_id
< app
->n_pipelines
; p_id
++) {
1667 struct app_pipeline_params
*params
=
1668 &app
->pipeline_params
[p_id
];
1669 struct app_pipeline_data
*data
= &app
->pipeline_data
[p_id
];
1670 struct pipeline_type
*ptype
;
1671 struct pipeline_params pp
;
1673 APP_LOG(app
, HIGH
, "Initializing %s ...", params
->name
);
1675 ptype
= app_pipeline_type_find(app
, params
->type
);
1677 rte_panic("Init error: Unknown pipeline type \"%s\"\n",
1680 app_pipeline_params_get(app
, params
, &pp
);
1684 if (ptype
->be_ops
->f_init
) {
1685 data
->be
= ptype
->be_ops
->f_init(&pp
, (void *) app
);
1687 if (data
->be
== NULL
)
1688 rte_panic("Pipeline instance \"%s\" back-end "
1689 "init error\n", params
->name
);
1694 if (ptype
->fe_ops
->f_init
) {
1695 data
->fe
= ptype
->fe_ops
->f_init(&pp
, (void *) app
);
1697 if (data
->fe
== NULL
)
1698 rte_panic("Pipeline instance \"%s\" front-end "
1699 "init error\n", params
->name
);
1702 data
->ptype
= ptype
;
1704 data
->timer_period
= (rte_get_tsc_hz() *
1705 params
->timer_period
) / 100;
1710 app_post_init_pipelines(struct app_params
*app
)
1714 for (p_id
= 0; p_id
< app
->n_pipelines
; p_id
++) {
1715 struct app_pipeline_params
*params
=
1716 &app
->pipeline_params
[p_id
];
1717 struct app_pipeline_data
*data
= &app
->pipeline_data
[p_id
];
1720 if (data
->ptype
->fe_ops
->f_post_init
== NULL
)
1723 status
= data
->ptype
->fe_ops
->f_post_init(data
->fe
);
1725 rte_panic("Pipeline instance \"%s\" front-end "
1726 "post-init error\n", params
->name
);
1731 app_init_threads(struct app_params
*app
)
1733 uint64_t time
= rte_get_tsc_cycles();
1736 for (p_id
= 0; p_id
< app
->n_pipelines
; p_id
++) {
1737 struct app_pipeline_params
*params
=
1738 &app
->pipeline_params
[p_id
];
1739 struct app_pipeline_data
*data
= &app
->pipeline_data
[p_id
];
1740 struct pipeline_type
*ptype
;
1741 struct app_thread_data
*t
;
1742 struct app_thread_pipeline_data
*p
;
1745 lcore_id
= cpu_core_map_get_lcore_id(app
->core_map
,
1748 params
->hyper_th_id
);
1751 rte_panic("Invalid core s%" PRIu32
"c%" PRIu32
"%s\n",
1754 (params
->hyper_th_id
) ? "h" : "");
1756 t
= &app
->thread_data
[lcore_id
];
1758 t
->timer_period
= (rte_get_tsc_hz() * APP_THREAD_TIMER_PERIOD
) / 1000;
1759 t
->thread_req_deadline
= time
+ t
->timer_period
;
1761 t
->headroom_cycles
= 0;
1762 t
->headroom_time
= rte_get_tsc_cycles();
1763 t
->headroom_ratio
= 0.0;
1765 t
->msgq_in
= app_thread_msgq_in_get(app
,
1768 params
->hyper_th_id
);
1769 if (t
->msgq_in
== NULL
)
1770 rte_panic("Init error: Cannot find MSGQ_IN for thread %" PRId32
,
1773 t
->msgq_out
= app_thread_msgq_out_get(app
,
1776 params
->hyper_th_id
);
1777 if (t
->msgq_out
== NULL
)
1778 rte_panic("Init error: Cannot find MSGQ_OUT for thread %" PRId32
,
1781 ptype
= app_pipeline_type_find(app
, params
->type
);
1783 rte_panic("Init error: Unknown pipeline "
1784 "type \"%s\"\n", params
->type
);
1786 p
= (ptype
->be_ops
->f_run
== NULL
) ?
1787 &t
->regular
[t
->n_regular
] :
1788 &t
->custom
[t
->n_custom
];
1790 p
->pipeline_id
= p_id
;
1792 p
->f_run
= ptype
->be_ops
->f_run
;
1793 p
->f_timer
= ptype
->be_ops
->f_timer
;
1794 p
->timer_period
= data
->timer_period
;
1795 p
->deadline
= time
+ data
->timer_period
;
1799 if (ptype
->be_ops
->f_run
== NULL
)
1806 int app_init(struct app_params
*app
)
1808 app_init_core_map(app
);
1809 app_init_core_mask(app
);
1812 app_init_mempool(app
);
1820 app_pipeline_common_cmd_push(app
);
1821 app_pipeline_thread_cmd_push(app
);
1822 app_pipeline_type_register(app
, &pipeline_master
);
1823 app_pipeline_type_register(app
, &pipeline_passthrough
);
1824 app_pipeline_type_register(app
, &pipeline_flow_classification
);
1825 app_pipeline_type_register(app
, &pipeline_flow_actions
);
1826 app_pipeline_type_register(app
, &pipeline_firewall
);
1827 app_pipeline_type_register(app
, &pipeline_routing
);
1829 app_init_pipelines(app
);
1830 app_init_threads(app
);
1835 int app_post_init(struct app_params
*app
)
1837 app_post_init_pipelines(app
);
1843 app_pipeline_type_cmd_push(struct app_params
*app
,
1844 struct pipeline_type
*ptype
)
1846 cmdline_parse_ctx_t
*cmds
;
1849 /* Check input arguments */
1850 if ((app
== NULL
) ||
1854 n_cmds
= pipeline_type_cmds_count(ptype
);
1858 cmds
= ptype
->fe_ops
->cmds
;
1860 /* Check for available slots in the application commands array */
1861 if (n_cmds
> APP_MAX_CMDS
- app
->n_cmds
)
1864 /* Push pipeline commands into the application */
1865 memcpy(&app
->cmds
[app
->n_cmds
],
1867 n_cmds
* sizeof(cmdline_parse_ctx_t
));
1869 for (i
= 0; i
< n_cmds
; i
++)
1870 app
->cmds
[app
->n_cmds
+ i
]->data
= app
;
1872 app
->n_cmds
+= n_cmds
;
1873 app
->cmds
[app
->n_cmds
] = NULL
;
1879 app_pipeline_type_register(struct app_params
*app
, struct pipeline_type
*ptype
)
1883 /* Check input arguments */
1884 if ((app
== NULL
) ||
1886 (ptype
->name
== NULL
) ||
1887 (strlen(ptype
->name
) == 0) ||
1888 (ptype
->be_ops
->f_init
== NULL
) ||
1889 (ptype
->be_ops
->f_timer
== NULL
))
1892 /* Check for duplicate entry */
1893 for (i
= 0; i
< app
->n_pipeline_types
; i
++)
1894 if (strcmp(app
->pipeline_type
[i
].name
, ptype
->name
) == 0)
1897 /* Check for resource availability */
1898 n_cmds
= pipeline_type_cmds_count(ptype
);
1899 if ((app
->n_pipeline_types
== APP_MAX_PIPELINE_TYPES
) ||
1900 (n_cmds
> APP_MAX_CMDS
- app
->n_cmds
))
1903 /* Copy pipeline type */
1904 memcpy(&app
->pipeline_type
[app
->n_pipeline_types
++],
1906 sizeof(struct pipeline_type
));
1908 /* Copy CLI commands */
1910 app_pipeline_type_cmd_push(app
, ptype
);
1916 pipeline_type
*app_pipeline_type_find(struct app_params
*app
, char *name
)
1920 for (i
= 0; i
< app
->n_pipeline_types
; i
++)
1921 if (strcmp(app
->pipeline_type
[i
].name
, name
) == 0)
1922 return &app
->pipeline_type
[i
];