4 * Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
17 * * Neither the name of Intel Corporation nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38 #include <rte_cycles.h>
39 #include <rte_ethdev.h>
40 #include <rte_ether.h>
43 #include <rte_malloc.h>
47 #include "pipeline_common_fe.h"
48 #include "pipeline_master.h"
49 #include "pipeline_passthrough.h"
51 #define APP_NAME_SIZE 32
54 app_init_core_map(struct app_params *app)
56 APP_LOG(app, HIGH, "Initializing CPU core map ...");
57 app->core_map = cpu_core_map_init(4, 32, 4, 0);
59 if (app->core_map == NULL)
60 rte_panic("Cannot create CPU core map\n");
62 if (app->log_level >= APP_LOG_LEVEL_LOW)
63 cpu_core_map_print(app->core_map);
67 app_init_core_mask(struct app_params *app)
72 for (i = 0; i < app->n_pipelines; i++) {
73 struct app_pipeline_params *p = &app->pipeline_params[i];
76 lcore_id = cpu_core_map_get_lcore_id(app->core_map,
82 rte_panic("Cannot create CPU core mask\n");
84 mask |= 1LLU << lcore_id;
87 app->core_mask = mask;
88 APP_LOG(app, HIGH, "CPU core mask = 0x%016" PRIx64, app->core_mask);
92 app_init_eal(struct app_params *app)
95 struct app_eal_params *p = &app->eal_params;
99 app->eal_argv[n_args++] = strdup(app->app_name);
101 snprintf(buffer, sizeof(buffer), "-c%" PRIx64, app->core_mask);
102 app->eal_argv[n_args++] = strdup(buffer);
105 snprintf(buffer, sizeof(buffer), "--lcores=%s", p->coremap);
106 app->eal_argv[n_args++] = strdup(buffer);
109 if (p->master_lcore_present) {
112 "--master-lcore=%" PRIu32,
114 app->eal_argv[n_args++] = strdup(buffer);
117 snprintf(buffer, sizeof(buffer), "-n%" PRIu32, p->channels);
118 app->eal_argv[n_args++] = strdup(buffer);
120 if (p->memory_present) {
121 snprintf(buffer, sizeof(buffer), "-m%" PRIu32, p->memory);
122 app->eal_argv[n_args++] = strdup(buffer);
125 if (p->ranks_present) {
126 snprintf(buffer, sizeof(buffer), "-r%" PRIu32, p->ranks);
127 app->eal_argv[n_args++] = strdup(buffer);
130 if (p->pci_blacklist) {
133 "--pci-blacklist=%s",
135 app->eal_argv[n_args++] = strdup(buffer);
138 if (p->pci_whitelist) {
141 "--pci-whitelist=%s",
143 app->eal_argv[n_args++] = strdup(buffer);
147 snprintf(buffer, sizeof(buffer), "--vdev=%s", p->vdev);
148 app->eal_argv[n_args++] = strdup(buffer);
151 if ((p->vmware_tsc_map_present) && p->vmware_tsc_map) {
152 snprintf(buffer, sizeof(buffer), "--vmware-tsc-map");
153 app->eal_argv[n_args++] = strdup(buffer);
161 app->eal_argv[n_args++] = strdup(buffer);
165 snprintf(buffer, sizeof(buffer), "--syslog=%s", p->syslog);
166 app->eal_argv[n_args++] = strdup(buffer);
169 if (p->log_level_present) {
172 "--log-level=%" PRIu32,
174 app->eal_argv[n_args++] = strdup(buffer);
177 if ((p->version_present) && p->version) {
178 snprintf(buffer, sizeof(buffer), "-v");
179 app->eal_argv[n_args++] = strdup(buffer);
182 if ((p->help_present) && p->help) {
183 snprintf(buffer, sizeof(buffer), "--help");
184 app->eal_argv[n_args++] = strdup(buffer);
187 if ((p->no_huge_present) && p->no_huge) {
188 snprintf(buffer, sizeof(buffer), "--no-huge");
189 app->eal_argv[n_args++] = strdup(buffer);
192 if ((p->no_pci_present) && p->no_pci) {
193 snprintf(buffer, sizeof(buffer), "--no-pci");
194 app->eal_argv[n_args++] = strdup(buffer);
197 if ((p->no_hpet_present) && p->no_hpet) {
198 snprintf(buffer, sizeof(buffer), "--no-hpet");
199 app->eal_argv[n_args++] = strdup(buffer);
202 if ((p->no_shconf_present) && p->no_shconf) {
203 snprintf(buffer, sizeof(buffer), "--no-shconf");
204 app->eal_argv[n_args++] = strdup(buffer);
208 snprintf(buffer, sizeof(buffer), "-d=%s", p->add_driver);
209 app->eal_argv[n_args++] = strdup(buffer);
217 app->eal_argv[n_args++] = strdup(buffer);
221 snprintf(buffer, sizeof(buffer), "--huge-dir=%s", p->huge_dir);
222 app->eal_argv[n_args++] = strdup(buffer);
225 if (p->file_prefix) {
230 app->eal_argv[n_args++] = strdup(buffer);
233 if (p->base_virtaddr) {
236 "--base-virtaddr=%s",
238 app->eal_argv[n_args++] = strdup(buffer);
241 if ((p->create_uio_dev_present) && p->create_uio_dev) {
242 snprintf(buffer, sizeof(buffer), "--create-uio-dev");
243 app->eal_argv[n_args++] = strdup(buffer);
251 app->eal_argv[n_args++] = strdup(buffer);
254 if ((p->xen_dom0_present) && (p->xen_dom0)) {
255 snprintf(buffer, sizeof(buffer), "--xen-dom0");
256 app->eal_argv[n_args++] = strdup(buffer);
259 snprintf(buffer, sizeof(buffer), "--");
260 app->eal_argv[n_args++] = strdup(buffer);
262 app->eal_argc = n_args;
264 APP_LOG(app, HIGH, "Initializing EAL ...");
265 status = rte_eal_init(app->eal_argc, app->eal_argv);
267 rte_panic("EAL init error\n");
271 app_init_mempool(struct app_params *app)
275 for (i = 0; i < app->n_mempools; i++) {
276 struct app_mempool_params *p = &app->mempool_params[i];
278 APP_LOG(app, HIGH, "Initializing %s ...", p->name);
279 app->mempool[i] = rte_mempool_create(
284 sizeof(struct rte_pktmbuf_pool_private),
285 rte_pktmbuf_pool_init, NULL,
286 rte_pktmbuf_init, NULL,
290 if (app->mempool[i] == NULL)
291 rte_panic("%s init error\n", p->name);
296 app_link_filter_arp_add(struct app_link_params *link)
298 struct rte_eth_ethertype_filter filter = {
299 .ether_type = ETHER_TYPE_ARP,
301 .queue = link->arp_q,
304 return rte_eth_dev_filter_ctrl(link->pmd_id,
305 RTE_ETH_FILTER_ETHERTYPE,
311 app_link_filter_tcp_syn_add(struct app_link_params *link)
313 struct rte_eth_syn_filter filter = {
315 .queue = link->tcp_syn_local_q,
318 return rte_eth_dev_filter_ctrl(link->pmd_id,
325 app_link_filter_ip_add(struct app_link_params *l1, struct app_link_params *l2)
327 struct rte_eth_ntuple_filter filter = {
328 .flags = RTE_5TUPLE_FLAGS,
329 .dst_ip = rte_bswap32(l2->ip),
330 .dst_ip_mask = UINT32_MAX, /* Enable */
332 .src_ip_mask = 0, /* Disable */
334 .dst_port_mask = 0, /* Disable */
336 .src_port_mask = 0, /* Disable */
338 .proto_mask = 0, /* Disable */
340 .priority = 1, /* Lowest */
341 .queue = l1->ip_local_q,
344 return rte_eth_dev_filter_ctrl(l1->pmd_id,
345 RTE_ETH_FILTER_NTUPLE,
351 app_link_filter_ip_del(struct app_link_params *l1, struct app_link_params *l2)
353 struct rte_eth_ntuple_filter filter = {
354 .flags = RTE_5TUPLE_FLAGS,
355 .dst_ip = rte_bswap32(l2->ip),
356 .dst_ip_mask = UINT32_MAX, /* Enable */
358 .src_ip_mask = 0, /* Disable */
360 .dst_port_mask = 0, /* Disable */
362 .src_port_mask = 0, /* Disable */
364 .proto_mask = 0, /* Disable */
366 .priority = 1, /* Lowest */
367 .queue = l1->ip_local_q,
370 return rte_eth_dev_filter_ctrl(l1->pmd_id,
371 RTE_ETH_FILTER_NTUPLE,
372 RTE_ETH_FILTER_DELETE,
377 app_link_filter_tcp_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 */
389 .proto = IPPROTO_TCP,
390 .proto_mask = UINT8_MAX, /* Enable */
392 .priority = 2, /* Higher priority than IP */
393 .queue = l1->tcp_local_q,
396 return rte_eth_dev_filter_ctrl(l1->pmd_id,
397 RTE_ETH_FILTER_NTUPLE,
403 app_link_filter_tcp_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 */
415 .proto = IPPROTO_TCP,
416 .proto_mask = UINT8_MAX, /* Enable */
418 .priority = 2, /* Higher priority than IP */
419 .queue = l1->tcp_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_udp_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_UDP,
442 .proto_mask = UINT8_MAX, /* Enable */
444 .priority = 2, /* Higher priority than IP */
445 .queue = l1->udp_local_q,
448 return rte_eth_dev_filter_ctrl(l1->pmd_id,
449 RTE_ETH_FILTER_NTUPLE,
455 app_link_filter_udp_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_UDP,
468 .proto_mask = UINT8_MAX, /* Enable */
470 .priority = 2, /* Higher priority than IP */
471 .queue = l1->udp_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_sctp_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_SCTP,
494 .proto_mask = UINT8_MAX, /* Enable */
496 .priority = 2, /* Higher priority than IP */
497 .queue = l1->sctp_local_q,
500 return rte_eth_dev_filter_ctrl(l1->pmd_id,
501 RTE_ETH_FILTER_NTUPLE,
507 app_link_filter_sctp_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_SCTP,
520 .proto_mask = UINT8_MAX, /* Enable */
522 .priority = 2, /* Higher priority than IP */
523 .queue = l1->sctp_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_set_arp_filter(struct app_params *app, struct app_link_params *cp)
535 if (cp->arp_q != 0) {
536 int status = app_link_filter_arp_add(cp);
538 APP_LOG(app, LOW, "%s (%" PRIu32 "): "
539 "Adding ARP filter (queue = %" PRIu32 ")",
540 cp->name, cp->pmd_id, cp->arp_q);
543 rte_panic("%s (%" PRIu32 "): "
544 "Error adding ARP filter "
545 "(queue = %" PRIu32 ") (%" PRId32 ")\n",
546 cp->name, cp->pmd_id, cp->arp_q, status);
551 app_link_set_tcp_syn_filter(struct app_params *app, struct app_link_params *cp)
553 if (cp->tcp_syn_local_q != 0) {
554 int status = app_link_filter_tcp_syn_add(cp);
556 APP_LOG(app, LOW, "%s (%" PRIu32 "): "
557 "Adding TCP SYN filter (queue = %" PRIu32 ")",
558 cp->name, cp->pmd_id, cp->tcp_syn_local_q);
561 rte_panic("%s (%" PRIu32 "): "
562 "Error adding TCP SYN filter "
563 "(queue = %" PRIu32 ") (%" PRId32 ")\n",
564 cp->name, cp->pmd_id, cp->tcp_syn_local_q,
570 app_link_up_internal(struct app_params *app, struct app_link_params *cp)
575 /* For each link, add filters for IP of current link */
577 for (i = 0; i < app->n_links; i++) {
578 struct app_link_params *p = &app->link_params[i];
581 if (p->ip_local_q != 0) {
582 int status = app_link_filter_ip_add(p, cp);
584 APP_LOG(app, LOW, "%s (%" PRIu32 "): "
585 "Adding IP filter (queue= %" PRIu32
586 ", IP = 0x%08" PRIx32 ")",
587 p->name, p->pmd_id, p->ip_local_q,
591 rte_panic("%s (%" PRIu32 "): "
593 "filter (queue= %" PRIu32 ", "
597 p->ip_local_q, cp->ip, status);
601 if (p->tcp_local_q != 0) {
602 int status = app_link_filter_tcp_add(p, cp);
604 APP_LOG(app, LOW, "%s (%" PRIu32 "): "
607 ", IP = 0x%08" PRIx32 ")",
608 p->name, p->pmd_id, p->tcp_local_q,
612 rte_panic("%s (%" PRIu32 "): "
614 "filter (queue = %" PRIu32 ", "
618 p->tcp_local_q, cp->ip, status);
622 if (p->udp_local_q != 0) {
623 int status = app_link_filter_udp_add(p, cp);
625 APP_LOG(app, LOW, "%s (%" PRIu32 "): "
628 ", IP = 0x%08" PRIx32 ")",
629 p->name, p->pmd_id, p->udp_local_q,
633 rte_panic("%s (%" PRIu32 "): "
635 "filter (queue = %" PRIu32 ", "
639 p->udp_local_q, cp->ip, status);
643 if (p->sctp_local_q != 0) {
644 int status = app_link_filter_sctp_add(p, cp);
646 APP_LOG(app, LOW, "%s (%" PRIu32
647 "): Adding SCTP filter "
649 ", IP = 0x%08" PRIx32 ")",
650 p->name, p->pmd_id, p->sctp_local_q,
654 rte_panic("%s (%" PRIu32 "): "
656 "filter (queue = %" PRIu32 ", "
660 p->sctp_local_q, cp->ip,
667 status = rte_eth_dev_set_link_up(cp->pmd_id);
669 rte_panic("%s (%" PRIu32 "): PMD set up error %" PRId32 "\n",
670 cp->name, cp->pmd_id, status);
672 /* Mark link as UP */
677 app_link_down_internal(struct app_params *app, struct app_link_params *cp)
682 rte_eth_dev_set_link_down(cp->pmd_id);
684 /* Mark link as DOWN */
687 /* Return if current link IP is not valid */
691 /* For each link, remove filters for IP of current link */
692 for (i = 0; i < app->n_links; i++) {
693 struct app_link_params *p = &app->link_params[i];
696 if (p->ip_local_q != 0) {
697 int status = app_link_filter_ip_del(p, cp);
699 APP_LOG(app, LOW, "%s (%" PRIu32
700 "): Deleting IP filter "
701 "(queue = %" PRIu32 ", IP = 0x%" PRIx32 ")",
702 p->name, p->pmd_id, p->ip_local_q, cp->ip);
705 rte_panic("%s (%" PRIu32
706 "): Error deleting IP filter "
710 p->name, p->pmd_id, p->ip_local_q,
715 if (p->tcp_local_q != 0) {
716 int status = app_link_filter_tcp_del(p, cp);
718 APP_LOG(app, LOW, "%s (%" PRIu32
719 "): Deleting TCP filter "
721 ", IP = 0x%" PRIx32 ")",
722 p->name, p->pmd_id, p->tcp_local_q, cp->ip);
725 rte_panic("%s (%" PRIu32
726 "): Error deleting TCP filter "
730 p->name, p->pmd_id, p->tcp_local_q,
735 if (p->udp_local_q != 0) {
736 int status = app_link_filter_udp_del(p, cp);
738 APP_LOG(app, LOW, "%s (%" PRIu32
739 "): Deleting UDP filter "
740 "(queue = %" PRIu32 ", IP = 0x%" PRIx32 ")",
741 p->name, p->pmd_id, p->udp_local_q, cp->ip);
744 rte_panic("%s (%" PRIu32
745 "): Error deleting UDP filter "
749 p->name, p->pmd_id, p->udp_local_q,
754 if (p->sctp_local_q != 0) {
755 int status = app_link_filter_sctp_del(p, cp);
757 APP_LOG(app, LOW, "%s (%" PRIu32
758 "): Deleting SCTP filter "
760 ", IP = 0x%" PRIx32 ")",
761 p->name, p->pmd_id, p->sctp_local_q, cp->ip);
764 rte_panic("%s (%" PRIu32
765 "): Error deleting SCTP filter "
769 p->name, p->pmd_id, p->sctp_local_q,
776 app_check_link(struct app_params *app)
778 uint32_t all_links_up, i;
782 for (i = 0; i < app->n_links; i++) {
783 struct app_link_params *p = &app->link_params[i];
784 struct rte_eth_link link_params;
786 memset(&link_params, 0, sizeof(link_params));
787 rte_eth_link_get(p->pmd_id, &link_params);
789 APP_LOG(app, HIGH, "%s (%" PRIu32 ") (%" PRIu32 " Gbps) %s",
792 link_params.link_speed / 1000,
793 link_params.link_status ? "UP" : "DOWN");
795 if (link_params.link_status == 0)
799 if (all_links_up == 0)
800 rte_panic("Some links are DOWN\n");
804 app_init_link(struct app_params *app)
808 for (i = 0; i < app->n_links; i++) {
809 struct app_link_params *p_link = &app->link_params[i];
810 uint32_t link_id, n_hwq_in, n_hwq_out, j;
813 sscanf(p_link->name, "LINK%" PRIu32, &link_id);
814 n_hwq_in = app_link_get_n_rxq(app, p_link);
815 n_hwq_out = app_link_get_n_txq(app, p_link);
817 APP_LOG(app, HIGH, "Initializing %s (%" PRIu32") "
818 "(%" PRIu32 " RXQ, %" PRIu32 " TXQ) ...",
825 status = rte_eth_dev_configure(
831 rte_panic("%s (%" PRId32 "): "
832 "init error (%" PRId32 ")\n",
833 p_link->name, p_link->pmd_id, status);
835 rte_eth_macaddr_get(p_link->pmd_id,
836 (struct ether_addr *) &p_link->mac_addr);
839 rte_eth_promiscuous_enable(p_link->pmd_id);
842 for (j = 0; j < app->n_pktq_hwq_in; j++) {
843 struct app_pktq_hwq_in_params *p_rxq =
844 &app->hwq_in_params[j];
845 uint32_t rxq_link_id, rxq_queue_id;
847 sscanf(p_rxq->name, "RXQ%" PRIu32 ".%" PRIu32,
848 &rxq_link_id, &rxq_queue_id);
849 if (rxq_link_id != link_id)
852 status = rte_eth_rx_queue_setup(
856 rte_eth_dev_socket_id(p_link->pmd_id),
858 app->mempool[p_rxq->mempool_id]);
860 rte_panic("%s (%" PRIu32 "): "
861 "%s init error (%" PRId32 ")\n",
869 for (j = 0; j < app->n_pktq_hwq_out; j++) {
870 struct app_pktq_hwq_out_params *p_txq =
871 &app->hwq_out_params[j];
872 uint32_t txq_link_id, txq_queue_id;
874 sscanf(p_txq->name, "TXQ%" PRIu32 ".%" PRIu32,
875 &txq_link_id, &txq_queue_id);
876 if (txq_link_id != link_id)
879 status = rte_eth_tx_queue_setup(
883 rte_eth_dev_socket_id(p_link->pmd_id),
886 rte_panic("%s (%" PRIu32 "): "
887 "%s init error (%" PRId32 ")\n",
895 status = rte_eth_dev_start(p_link->pmd_id);
897 rte_panic("Cannot start %s (error %" PRId32 ")\n",
898 p_link->name, status);
901 app_link_set_arp_filter(app, p_link);
902 app_link_set_tcp_syn_filter(app, p_link);
903 app_link_up_internal(app, p_link);
910 app_init_swq(struct app_params *app)
914 for (i = 0; i < app->n_pktq_swq; i++) {
915 struct app_pktq_swq_params *p = &app->swq_params[i];
917 APP_LOG(app, HIGH, "Initializing %s...", p->name);
918 app->swq[i] = rte_ring_create(
922 RING_F_SP_ENQ | RING_F_SC_DEQ);
924 if (app->swq[i] == NULL)
925 rte_panic("%s init error\n", p->name);
930 app_init_tm(struct app_params *app)
934 for (i = 0; i < app->n_pktq_tm; i++) {
935 struct app_pktq_tm_params *p_tm = &app->tm_params[i];
936 struct app_link_params *p_link;
937 struct rte_eth_link link_eth_params;
938 struct rte_sched_port *sched;
939 uint32_t n_subports, subport_id;
942 p_link = app_get_link_for_tm(app, p_tm);
944 rte_eth_link_get(p_link->pmd_id, &link_eth_params);
947 p_tm->sched_port_params.name = p_tm->name;
948 p_tm->sched_port_params.socket =
949 rte_eth_dev_socket_id(p_link->pmd_id);
950 p_tm->sched_port_params.rate =
951 (uint64_t) link_eth_params.link_speed * 1000 * 1000 / 8;
953 APP_LOG(app, HIGH, "Initializing %s ...", p_tm->name);
954 sched = rte_sched_port_config(&p_tm->sched_port_params);
956 rte_panic("%s init error\n", p_tm->name);
960 n_subports = p_tm->sched_port_params.n_subports_per_port;
961 for (subport_id = 0; subport_id < n_subports; subport_id++) {
962 uint32_t n_pipes_per_subport, pipe_id;
964 status = rte_sched_subport_config(sched,
966 &p_tm->sched_subport_params[subport_id]);
968 rte_panic("%s subport %" PRIu32
969 " init error (%" PRId32 ")\n",
970 p_tm->name, subport_id, status);
973 n_pipes_per_subport =
974 p_tm->sched_port_params.n_pipes_per_subport;
976 pipe_id < n_pipes_per_subport;
978 int profile_id = p_tm->sched_pipe_to_profile[
979 subport_id * APP_MAX_SCHED_PIPES +
982 if (profile_id == -1)
985 status = rte_sched_pipe_config(sched,
990 rte_panic("%s subport %" PRIu32
992 " (profile %" PRId32 ") "
993 "init error (% " PRId32 ")\n",
994 p_tm->name, subport_id, pipe_id,
1002 app_init_msgq(struct app_params *app)
1006 for (i = 0; i < app->n_msgq; i++) {
1007 struct app_msgq_params *p = &app->msgq_params[i];
1009 APP_LOG(app, HIGH, "Initializing %s ...", p->name);
1010 app->msgq[i] = rte_ring_create(
1014 RING_F_SP_ENQ | RING_F_SC_DEQ);
1016 if (app->msgq[i] == NULL)
1017 rte_panic("%s init error\n", p->name);
1021 static void app_pipeline_params_get(struct app_params *app,
1022 struct app_pipeline_params *p_in,
1023 struct pipeline_params *p_out)
1027 strcpy(p_out->name, p_in->name);
1029 p_out->socket_id = (int) p_in->socket_id;
1031 p_out->log_level = app->log_level;
1034 p_out->n_ports_in = p_in->n_pktq_in;
1035 for (i = 0; i < p_in->n_pktq_in; i++) {
1036 struct app_pktq_in_params *in = &p_in->pktq_in[i];
1037 struct pipeline_port_in_params *out = &p_out->port_in[i];
1040 case APP_PKTQ_IN_HWQ:
1042 struct app_pktq_hwq_in_params *p_hwq_in =
1043 &app->hwq_in_params[in->id];
1044 struct app_link_params *p_link =
1045 app_get_link_for_rxq(app, p_hwq_in);
1046 uint32_t rxq_link_id, rxq_queue_id;
1048 sscanf(p_hwq_in->name, "RXQ%" SCNu32 ".%" SCNu32,
1052 out->type = PIPELINE_PORT_IN_ETHDEV_READER;
1053 out->params.ethdev.port_id = p_link->pmd_id;
1054 out->params.ethdev.queue_id = rxq_queue_id;
1055 out->burst_size = p_hwq_in->burst;
1058 case APP_PKTQ_IN_SWQ:
1059 out->type = PIPELINE_PORT_IN_RING_READER;
1060 out->params.ring.ring = app->swq[in->id];
1061 out->burst_size = app->swq_params[in->id].burst_read;
1062 /* What about frag and ras ports? */
1064 case APP_PKTQ_IN_TM:
1065 out->type = PIPELINE_PORT_IN_SCHED_READER;
1066 out->params.sched.sched = app->tm[in->id];
1067 out->burst_size = app->tm_params[in->id].burst_read;
1069 case APP_PKTQ_IN_SOURCE:
1070 out->type = PIPELINE_PORT_IN_SOURCE;
1071 out->params.source.mempool = app->mempool[in->id];
1072 out->burst_size = app->source_params[in->id].burst;
1080 p_out->n_ports_out = p_in->n_pktq_out;
1081 for (i = 0; i < p_in->n_pktq_out; i++) {
1082 struct app_pktq_out_params *in = &p_in->pktq_out[i];
1083 struct pipeline_port_out_params *out = &p_out->port_out[i];
1086 case APP_PKTQ_OUT_HWQ:
1088 struct app_pktq_hwq_out_params *p_hwq_out =
1089 &app->hwq_out_params[in->id];
1090 struct app_link_params *p_link =
1091 app_get_link_for_txq(app, p_hwq_out);
1092 uint32_t txq_link_id, txq_queue_id;
1094 sscanf(p_hwq_out->name,
1095 "TXQ%" SCNu32 ".%" SCNu32,
1099 if (p_hwq_out->dropless == 0) {
1100 struct rte_port_ethdev_writer_params *params =
1101 &out->params.ethdev;
1103 out->type = PIPELINE_PORT_OUT_ETHDEV_WRITER;
1104 params->port_id = p_link->pmd_id;
1105 params->queue_id = txq_queue_id;
1106 params->tx_burst_sz =
1107 app->hwq_out_params[in->id].burst;
1109 struct rte_port_ethdev_writer_nodrop_params
1110 *params = &out->params.ethdev_nodrop;
1113 PIPELINE_PORT_OUT_ETHDEV_WRITER_NODROP;
1114 params->port_id = p_link->pmd_id;
1115 params->queue_id = txq_queue_id;
1116 params->tx_burst_sz = p_hwq_out->burst;
1117 params->n_retries = p_hwq_out->n_retries;
1121 case APP_PKTQ_OUT_SWQ:
1122 if (app->swq_params[in->id].dropless == 0) {
1123 struct rte_port_ring_writer_params *params =
1126 out->type = PIPELINE_PORT_OUT_RING_WRITER;
1127 params->ring = app->swq[in->id];
1128 params->tx_burst_sz =
1129 app->swq_params[in->id].burst_write;
1131 struct rte_port_ring_writer_nodrop_params
1132 *params = &out->params.ring_nodrop;
1135 PIPELINE_PORT_OUT_RING_WRITER_NODROP;
1136 params->ring = app->swq[in->id];
1137 params->tx_burst_sz =
1138 app->swq_params[in->id].burst_write;
1140 app->swq_params[in->id].n_retries;
1142 /* What about frag and ras ports? */
1144 case APP_PKTQ_OUT_TM: {
1145 struct rte_port_sched_writer_params *params =
1148 out->type = PIPELINE_PORT_OUT_SCHED_WRITER;
1149 params->sched = app->tm[in->id];
1150 params->tx_burst_sz =
1151 app->tm_params[in->id].burst_write;
1154 case APP_PKTQ_OUT_SINK:
1155 out->type = PIPELINE_PORT_OUT_SINK;
1163 p_out->n_msgq = p_in->n_msgq_in;
1165 for (i = 0; i < p_in->n_msgq_in; i++)
1166 p_out->msgq_in[i] = app->msgq[p_in->msgq_in[i]];
1168 for (i = 0; i < p_in->n_msgq_out; i++)
1169 p_out->msgq_out[i] = app->msgq[p_in->msgq_out[i]];
1172 p_out->n_args = p_in->n_args;
1173 for (i = 0; i < p_in->n_args; i++) {
1174 p_out->args_name[i] = p_in->args_name[i];
1175 p_out->args_value[i] = p_in->args_value[i];
1180 app_init_pipelines(struct app_params *app)
1184 for (p_id = 0; p_id < app->n_pipelines; p_id++) {
1185 struct app_pipeline_params *params =
1186 &app->pipeline_params[p_id];
1187 struct app_pipeline_data *data = &app->pipeline_data[p_id];
1188 struct pipeline_type *ptype;
1189 struct pipeline_params pp;
1191 APP_LOG(app, HIGH, "Initializing %s ...", params->name);
1193 ptype = app_pipeline_type_find(app, params->type);
1195 rte_panic("Init error: Unknown pipeline type \"%s\"\n",
1198 app_pipeline_params_get(app, params, &pp);
1202 if (ptype->be_ops->f_init) {
1203 data->be = ptype->be_ops->f_init(&pp, (void *) app);
1205 if (data->be == NULL)
1206 rte_panic("Pipeline instance \"%s\" back-end "
1207 "init error\n", params->name);
1212 if (ptype->fe_ops->f_init) {
1213 data->fe = ptype->fe_ops->f_init(&pp, (void *) app);
1215 if (data->fe == NULL)
1216 rte_panic("Pipeline instance \"%s\" front-end "
1217 "init error\n", params->name);
1220 data->timer_period = (rte_get_tsc_hz() * params->timer_period)
1226 app_init_threads(struct app_params *app)
1228 uint64_t time = rte_get_tsc_cycles();
1231 for (p_id = 0; p_id < app->n_pipelines; p_id++) {
1232 struct app_pipeline_params *params =
1233 &app->pipeline_params[p_id];
1234 struct app_pipeline_data *data = &app->pipeline_data[p_id];
1235 struct pipeline_type *ptype;
1236 struct app_thread_data *t;
1237 struct app_thread_pipeline_data *p;
1240 lcore_id = cpu_core_map_get_lcore_id(app->core_map,
1243 params->hyper_th_id);
1246 rte_panic("Invalid core s%" PRIu32 "c%" PRIu32 "%s\n",
1249 (params->hyper_th_id) ? "h" : "");
1251 t = &app->thread_data[lcore_id];
1253 ptype = app_pipeline_type_find(app, params->type);
1255 rte_panic("Init error: Unknown pipeline "
1256 "type \"%s\"\n", params->type);
1258 p = (ptype->be_ops->f_run == NULL) ?
1259 &t->regular[t->n_regular] :
1260 &t->custom[t->n_custom];
1263 p->f_run = ptype->be_ops->f_run;
1264 p->f_timer = ptype->be_ops->f_timer;
1265 p->timer_period = data->timer_period;
1266 p->deadline = time + data->timer_period;
1268 if (ptype->be_ops->f_run == NULL)
1275 int app_init(struct app_params *app)
1277 app_init_core_map(app);
1278 app_init_core_mask(app);
1281 app_init_mempool(app);
1287 app_pipeline_common_cmd_push(app);
1288 app_pipeline_type_register(app, &pipeline_master);
1289 app_pipeline_type_register(app, &pipeline_passthrough);
1291 app_init_pipelines(app);
1292 app_init_threads(app);
1298 app_pipeline_type_cmd_push(struct app_params *app,
1299 struct pipeline_type *ptype)
1301 cmdline_parse_ctx_t *cmds;
1304 /* Check input arguments */
1305 if ((app == NULL) ||
1309 n_cmds = pipeline_type_cmds_count(ptype);
1313 cmds = ptype->fe_ops->cmds;
1315 /* Check for available slots in the application commands array */
1316 if (n_cmds > APP_MAX_CMDS - app->n_cmds)
1319 /* Push pipeline commands into the application */
1320 memcpy(&app->cmds[app->n_cmds],
1322 n_cmds * sizeof(cmdline_parse_ctx_t *));
1324 for (i = 0; i < n_cmds; i++)
1325 app->cmds[app->n_cmds + i]->data = app;
1327 app->n_cmds += n_cmds;
1328 app->cmds[app->n_cmds] = NULL;
1334 app_pipeline_type_register(struct app_params *app, struct pipeline_type *ptype)
1338 /* Check input arguments */
1339 if ((app == NULL) ||
1341 (ptype->name == NULL) ||
1342 (strlen(ptype->name) == 0) ||
1343 (ptype->be_ops->f_init == NULL) ||
1344 (ptype->be_ops->f_timer == NULL))
1347 /* Check for duplicate entry */
1348 for (i = 0; i < app->n_pipeline_types; i++)
1349 if (strcmp(app->pipeline_type[i].name, ptype->name) == 0)
1352 /* Check for resource availability */
1353 n_cmds = pipeline_type_cmds_count(ptype);
1354 if ((app->n_pipeline_types == APP_MAX_PIPELINE_TYPES) ||
1355 (n_cmds > APP_MAX_CMDS - app->n_cmds))
1358 /* Copy pipeline type */
1359 memcpy(&app->pipeline_type[app->n_pipeline_types++],
1361 sizeof(struct pipeline_type));
1363 /* Copy CLI commands */
1365 app_pipeline_type_cmd_push(app, ptype);
1371 pipeline_type *app_pipeline_type_find(struct app_params *app, char *name)
1375 for (i = 0; i < app->n_pipeline_types; i++)
1376 if (strcmp(app->pipeline_type[i].name, name) == 0)
1377 return &app->pipeline_type[i];