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>
48 #define APP_NAME_SIZE 32
51 app_init_core_map(struct app_params *app)
53 APP_LOG(app, HIGH, "Initializing CPU core map ...");
54 app->core_map = cpu_core_map_init(4, 32, 4, 0);
56 if (app->core_map == NULL)
57 rte_panic("Cannot create CPU core map\n");
59 if (app->log_level >= APP_LOG_LEVEL_LOW)
60 cpu_core_map_print(app->core_map);
64 app_init_core_mask(struct app_params *app)
69 for (i = 0; i < app->n_pipelines; i++) {
70 struct app_pipeline_params *p = &app->pipeline_params[i];
73 lcore_id = cpu_core_map_get_lcore_id(app->core_map,
79 rte_panic("Cannot create CPU core mask\n");
81 mask |= 1LLU << lcore_id;
84 app->core_mask = mask;
85 APP_LOG(app, HIGH, "CPU core mask = 0x%016" PRIx64, app->core_mask);
89 app_init_eal(struct app_params *app)
92 struct app_eal_params *p = &app->eal_params;
96 app->eal_argv[n_args++] = strdup(app->app_name);
98 snprintf(buffer, sizeof(buffer), "-c%" PRIx64, app->core_mask);
99 app->eal_argv[n_args++] = strdup(buffer);
102 snprintf(buffer, sizeof(buffer), "--lcores=%s", p->coremap);
103 app->eal_argv[n_args++] = strdup(buffer);
106 if (p->master_lcore_present) {
109 "--master-lcore=%" PRIu32,
111 app->eal_argv[n_args++] = strdup(buffer);
114 snprintf(buffer, sizeof(buffer), "-n%" PRIu32, p->channels);
115 app->eal_argv[n_args++] = strdup(buffer);
117 if (p->memory_present) {
118 snprintf(buffer, sizeof(buffer), "-m%" PRIu32, p->memory);
119 app->eal_argv[n_args++] = strdup(buffer);
122 if (p->ranks_present) {
123 snprintf(buffer, sizeof(buffer), "-r%" PRIu32, p->ranks);
124 app->eal_argv[n_args++] = strdup(buffer);
127 if (p->pci_blacklist) {
130 "--pci-blacklist=%s",
132 app->eal_argv[n_args++] = strdup(buffer);
135 if (p->pci_whitelist) {
138 "--pci-whitelist=%s",
140 app->eal_argv[n_args++] = strdup(buffer);
144 snprintf(buffer, sizeof(buffer), "--vdev=%s", p->vdev);
145 app->eal_argv[n_args++] = strdup(buffer);
148 if ((p->vmware_tsc_map_present) && p->vmware_tsc_map) {
149 snprintf(buffer, sizeof(buffer), "--vmware-tsc-map");
150 app->eal_argv[n_args++] = strdup(buffer);
158 app->eal_argv[n_args++] = strdup(buffer);
162 snprintf(buffer, sizeof(buffer), "--syslog=%s", p->syslog);
163 app->eal_argv[n_args++] = strdup(buffer);
166 if (p->log_level_present) {
169 "--log-level=%" PRIu32,
171 app->eal_argv[n_args++] = strdup(buffer);
174 if ((p->version_present) && p->version) {
175 snprintf(buffer, sizeof(buffer), "-v");
176 app->eal_argv[n_args++] = strdup(buffer);
179 if ((p->help_present) && p->help) {
180 snprintf(buffer, sizeof(buffer), "--help");
181 app->eal_argv[n_args++] = strdup(buffer);
184 if ((p->no_huge_present) && p->no_huge) {
185 snprintf(buffer, sizeof(buffer), "--no-huge");
186 app->eal_argv[n_args++] = strdup(buffer);
189 if ((p->no_pci_present) && p->no_pci) {
190 snprintf(buffer, sizeof(buffer), "--no-pci");
191 app->eal_argv[n_args++] = strdup(buffer);
194 if ((p->no_hpet_present) && p->no_hpet) {
195 snprintf(buffer, sizeof(buffer), "--no-hpet");
196 app->eal_argv[n_args++] = strdup(buffer);
199 if ((p->no_shconf_present) && p->no_shconf) {
200 snprintf(buffer, sizeof(buffer), "--no-shconf");
201 app->eal_argv[n_args++] = strdup(buffer);
205 snprintf(buffer, sizeof(buffer), "-d=%s", p->add_driver);
206 app->eal_argv[n_args++] = strdup(buffer);
214 app->eal_argv[n_args++] = strdup(buffer);
218 snprintf(buffer, sizeof(buffer), "--huge-dir=%s", p->huge_dir);
219 app->eal_argv[n_args++] = strdup(buffer);
222 if (p->file_prefix) {
227 app->eal_argv[n_args++] = strdup(buffer);
230 if (p->base_virtaddr) {
233 "--base-virtaddr=%s",
235 app->eal_argv[n_args++] = strdup(buffer);
238 if ((p->create_uio_dev_present) && p->create_uio_dev) {
239 snprintf(buffer, sizeof(buffer), "--create-uio-dev");
240 app->eal_argv[n_args++] = strdup(buffer);
248 app->eal_argv[n_args++] = strdup(buffer);
251 if ((p->xen_dom0_present) && (p->xen_dom0)) {
252 snprintf(buffer, sizeof(buffer), "--xen-dom0");
253 app->eal_argv[n_args++] = strdup(buffer);
256 snprintf(buffer, sizeof(buffer), "--");
257 app->eal_argv[n_args++] = strdup(buffer);
259 app->eal_argc = n_args;
261 APP_LOG(app, HIGH, "Initializing EAL ...");
262 status = rte_eal_init(app->eal_argc, app->eal_argv);
264 rte_panic("EAL init error\n");
268 app_init_mempool(struct app_params *app)
272 for (i = 0; i < app->n_mempools; i++) {
273 struct app_mempool_params *p = &app->mempool_params[i];
275 APP_LOG(app, HIGH, "Initializing %s ...", p->name);
276 app->mempool[i] = rte_mempool_create(
281 sizeof(struct rte_pktmbuf_pool_private),
282 rte_pktmbuf_pool_init, NULL,
283 rte_pktmbuf_init, NULL,
287 if (app->mempool[i] == NULL)
288 rte_panic("%s init error\n", p->name);
293 app_link_filter_arp_add(struct app_link_params *link)
295 struct rte_eth_ethertype_filter filter = {
296 .ether_type = ETHER_TYPE_ARP,
298 .queue = link->arp_q,
301 return rte_eth_dev_filter_ctrl(link->pmd_id,
302 RTE_ETH_FILTER_ETHERTYPE,
308 app_link_filter_tcp_syn_add(struct app_link_params *link)
310 struct rte_eth_syn_filter filter = {
312 .queue = link->tcp_syn_local_q,
315 return rte_eth_dev_filter_ctrl(link->pmd_id,
322 app_link_filter_ip_add(struct app_link_params *l1, struct app_link_params *l2)
324 struct rte_eth_ntuple_filter filter = {
325 .flags = RTE_5TUPLE_FLAGS,
326 .dst_ip = rte_bswap32(l2->ip),
327 .dst_ip_mask = UINT32_MAX, /* Enable */
329 .src_ip_mask = 0, /* Disable */
331 .dst_port_mask = 0, /* Disable */
333 .src_port_mask = 0, /* Disable */
335 .proto_mask = 0, /* Disable */
337 .priority = 1, /* Lowest */
338 .queue = l1->ip_local_q,
341 return rte_eth_dev_filter_ctrl(l1->pmd_id,
342 RTE_ETH_FILTER_NTUPLE,
348 app_link_filter_ip_del(struct app_link_params *l1, struct app_link_params *l2)
350 struct rte_eth_ntuple_filter filter = {
351 .flags = RTE_5TUPLE_FLAGS,
352 .dst_ip = rte_bswap32(l2->ip),
353 .dst_ip_mask = UINT32_MAX, /* Enable */
355 .src_ip_mask = 0, /* Disable */
357 .dst_port_mask = 0, /* Disable */
359 .src_port_mask = 0, /* Disable */
361 .proto_mask = 0, /* Disable */
363 .priority = 1, /* Lowest */
364 .queue = l1->ip_local_q,
367 return rte_eth_dev_filter_ctrl(l1->pmd_id,
368 RTE_ETH_FILTER_NTUPLE,
369 RTE_ETH_FILTER_DELETE,
374 app_link_filter_tcp_add(struct app_link_params *l1, struct app_link_params *l2)
376 struct rte_eth_ntuple_filter filter = {
377 .flags = RTE_5TUPLE_FLAGS,
378 .dst_ip = rte_bswap32(l2->ip),
379 .dst_ip_mask = UINT32_MAX, /* Enable */
381 .src_ip_mask = 0, /* Disable */
383 .dst_port_mask = 0, /* Disable */
385 .src_port_mask = 0, /* Disable */
386 .proto = IPPROTO_TCP,
387 .proto_mask = UINT8_MAX, /* Enable */
389 .priority = 2, /* Higher priority than IP */
390 .queue = l1->tcp_local_q,
393 return rte_eth_dev_filter_ctrl(l1->pmd_id,
394 RTE_ETH_FILTER_NTUPLE,
400 app_link_filter_tcp_del(struct app_link_params *l1, struct app_link_params *l2)
402 struct rte_eth_ntuple_filter filter = {
403 .flags = RTE_5TUPLE_FLAGS,
404 .dst_ip = rte_bswap32(l2->ip),
405 .dst_ip_mask = UINT32_MAX, /* Enable */
407 .src_ip_mask = 0, /* Disable */
409 .dst_port_mask = 0, /* Disable */
411 .src_port_mask = 0, /* Disable */
412 .proto = IPPROTO_TCP,
413 .proto_mask = UINT8_MAX, /* Enable */
415 .priority = 2, /* Higher priority than IP */
416 .queue = l1->tcp_local_q,
419 return rte_eth_dev_filter_ctrl(l1->pmd_id,
420 RTE_ETH_FILTER_NTUPLE,
421 RTE_ETH_FILTER_DELETE,
426 app_link_filter_udp_add(struct app_link_params *l1, struct app_link_params *l2)
428 struct rte_eth_ntuple_filter filter = {
429 .flags = RTE_5TUPLE_FLAGS,
430 .dst_ip = rte_bswap32(l2->ip),
431 .dst_ip_mask = UINT32_MAX, /* Enable */
433 .src_ip_mask = 0, /* Disable */
435 .dst_port_mask = 0, /* Disable */
437 .src_port_mask = 0, /* Disable */
438 .proto = IPPROTO_UDP,
439 .proto_mask = UINT8_MAX, /* Enable */
441 .priority = 2, /* Higher priority than IP */
442 .queue = l1->udp_local_q,
445 return rte_eth_dev_filter_ctrl(l1->pmd_id,
446 RTE_ETH_FILTER_NTUPLE,
452 app_link_filter_udp_del(struct app_link_params *l1, struct app_link_params *l2)
454 struct rte_eth_ntuple_filter filter = {
455 .flags = RTE_5TUPLE_FLAGS,
456 .dst_ip = rte_bswap32(l2->ip),
457 .dst_ip_mask = UINT32_MAX, /* Enable */
459 .src_ip_mask = 0, /* Disable */
461 .dst_port_mask = 0, /* Disable */
463 .src_port_mask = 0, /* Disable */
464 .proto = IPPROTO_UDP,
465 .proto_mask = UINT8_MAX, /* Enable */
467 .priority = 2, /* Higher priority than IP */
468 .queue = l1->udp_local_q,
471 return rte_eth_dev_filter_ctrl(l1->pmd_id,
472 RTE_ETH_FILTER_NTUPLE,
473 RTE_ETH_FILTER_DELETE,
478 app_link_filter_sctp_add(struct app_link_params *l1, struct app_link_params *l2)
480 struct rte_eth_ntuple_filter filter = {
481 .flags = RTE_5TUPLE_FLAGS,
482 .dst_ip = rte_bswap32(l2->ip),
483 .dst_ip_mask = UINT32_MAX, /* Enable */
485 .src_ip_mask = 0, /* Disable */
487 .dst_port_mask = 0, /* Disable */
489 .src_port_mask = 0, /* Disable */
490 .proto = IPPROTO_SCTP,
491 .proto_mask = UINT8_MAX, /* Enable */
493 .priority = 2, /* Higher priority than IP */
494 .queue = l1->sctp_local_q,
497 return rte_eth_dev_filter_ctrl(l1->pmd_id,
498 RTE_ETH_FILTER_NTUPLE,
504 app_link_filter_sctp_del(struct app_link_params *l1, struct app_link_params *l2)
506 struct rte_eth_ntuple_filter filter = {
507 .flags = RTE_5TUPLE_FLAGS,
508 .dst_ip = rte_bswap32(l2->ip),
509 .dst_ip_mask = UINT32_MAX, /* Enable */
511 .src_ip_mask = 0, /* Disable */
513 .dst_port_mask = 0, /* Disable */
515 .src_port_mask = 0, /* Disable */
516 .proto = IPPROTO_SCTP,
517 .proto_mask = UINT8_MAX, /* Enable */
519 .priority = 2, /* Higher priority than IP */
520 .queue = l1->sctp_local_q,
523 return rte_eth_dev_filter_ctrl(l1->pmd_id,
524 RTE_ETH_FILTER_NTUPLE,
525 RTE_ETH_FILTER_DELETE,
530 app_link_set_arp_filter(struct app_params *app, struct app_link_params *cp)
532 if (cp->arp_q != 0) {
533 int status = app_link_filter_arp_add(cp);
535 APP_LOG(app, LOW, "%s (%" PRIu32 "): "
536 "Adding ARP filter (queue = %" PRIu32 ")",
537 cp->name, cp->pmd_id, cp->arp_q);
540 rte_panic("%s (%" PRIu32 "): "
541 "Error adding ARP filter "
542 "(queue = %" PRIu32 ") (%" PRId32 ")\n",
543 cp->name, cp->pmd_id, cp->arp_q, status);
548 app_link_set_tcp_syn_filter(struct app_params *app, struct app_link_params *cp)
550 if (cp->tcp_syn_local_q != 0) {
551 int status = app_link_filter_tcp_syn_add(cp);
553 APP_LOG(app, LOW, "%s (%" PRIu32 "): "
554 "Adding TCP SYN filter (queue = %" PRIu32 ")",
555 cp->name, cp->pmd_id, cp->tcp_syn_local_q);
558 rte_panic("%s (%" PRIu32 "): "
559 "Error adding TCP SYN filter "
560 "(queue = %" PRIu32 ") (%" PRId32 ")\n",
561 cp->name, cp->pmd_id, cp->tcp_syn_local_q,
567 app_link_up_internal(struct app_params *app, struct app_link_params *cp)
572 /* For each link, add filters for IP of current link */
574 for (i = 0; i < app->n_links; i++) {
575 struct app_link_params *p = &app->link_params[i];
578 if (p->ip_local_q != 0) {
579 int status = app_link_filter_ip_add(p, cp);
581 APP_LOG(app, LOW, "%s (%" PRIu32 "): "
582 "Adding IP filter (queue= %" PRIu32
583 ", IP = 0x%08" PRIx32 ")",
584 p->name, p->pmd_id, p->ip_local_q,
588 rte_panic("%s (%" PRIu32 "): "
590 "filter (queue= %" PRIu32 ", "
594 p->ip_local_q, cp->ip, status);
598 if (p->tcp_local_q != 0) {
599 int status = app_link_filter_tcp_add(p, cp);
601 APP_LOG(app, LOW, "%s (%" PRIu32 "): "
604 ", IP = 0x%08" PRIx32 ")",
605 p->name, p->pmd_id, p->tcp_local_q,
609 rte_panic("%s (%" PRIu32 "): "
611 "filter (queue = %" PRIu32 ", "
615 p->tcp_local_q, cp->ip, status);
619 if (p->udp_local_q != 0) {
620 int status = app_link_filter_udp_add(p, cp);
622 APP_LOG(app, LOW, "%s (%" PRIu32 "): "
625 ", IP = 0x%08" PRIx32 ")",
626 p->name, p->pmd_id, p->udp_local_q,
630 rte_panic("%s (%" PRIu32 "): "
632 "filter (queue = %" PRIu32 ", "
636 p->udp_local_q, cp->ip, status);
640 if (p->sctp_local_q != 0) {
641 int status = app_link_filter_sctp_add(p, cp);
643 APP_LOG(app, LOW, "%s (%" PRIu32
644 "): Adding SCTP filter "
646 ", IP = 0x%08" PRIx32 ")",
647 p->name, p->pmd_id, p->sctp_local_q,
651 rte_panic("%s (%" PRIu32 "): "
653 "filter (queue = %" PRIu32 ", "
657 p->sctp_local_q, cp->ip,
664 status = rte_eth_dev_set_link_up(cp->pmd_id);
666 rte_panic("%s (%" PRIu32 "): PMD set up error %" PRId32 "\n",
667 cp->name, cp->pmd_id, status);
669 /* Mark link as UP */
674 app_link_down_internal(struct app_params *app, struct app_link_params *cp)
679 rte_eth_dev_set_link_down(cp->pmd_id);
681 /* Mark link as DOWN */
684 /* Return if current link IP is not valid */
688 /* For each link, remove filters for IP of current link */
689 for (i = 0; i < app->n_links; i++) {
690 struct app_link_params *p = &app->link_params[i];
693 if (p->ip_local_q != 0) {
694 int status = app_link_filter_ip_del(p, cp);
696 APP_LOG(app, LOW, "%s (%" PRIu32
697 "): Deleting IP filter "
698 "(queue = %" PRIu32 ", IP = 0x%" PRIx32 ")",
699 p->name, p->pmd_id, p->ip_local_q, cp->ip);
702 rte_panic("%s (%" PRIu32
703 "): Error deleting IP filter "
707 p->name, p->pmd_id, p->ip_local_q,
712 if (p->tcp_local_q != 0) {
713 int status = app_link_filter_tcp_del(p, cp);
715 APP_LOG(app, LOW, "%s (%" PRIu32
716 "): Deleting TCP filter "
718 ", IP = 0x%" PRIx32 ")",
719 p->name, p->pmd_id, p->tcp_local_q, cp->ip);
722 rte_panic("%s (%" PRIu32
723 "): Error deleting TCP filter "
727 p->name, p->pmd_id, p->tcp_local_q,
732 if (p->udp_local_q != 0) {
733 int status = app_link_filter_udp_del(p, cp);
735 APP_LOG(app, LOW, "%s (%" PRIu32
736 "): Deleting UDP filter "
737 "(queue = %" PRIu32 ", IP = 0x%" PRIx32 ")",
738 p->name, p->pmd_id, p->udp_local_q, cp->ip);
741 rte_panic("%s (%" PRIu32
742 "): Error deleting UDP filter "
746 p->name, p->pmd_id, p->udp_local_q,
751 if (p->sctp_local_q != 0) {
752 int status = app_link_filter_sctp_del(p, cp);
754 APP_LOG(app, LOW, "%s (%" PRIu32
755 "): Deleting SCTP filter "
757 ", IP = 0x%" PRIx32 ")",
758 p->name, p->pmd_id, p->sctp_local_q, cp->ip);
761 rte_panic("%s (%" PRIu32
762 "): Error deleting SCTP filter "
766 p->name, p->pmd_id, p->sctp_local_q,
773 app_check_link(struct app_params *app)
775 uint32_t all_links_up, i;
779 for (i = 0; i < app->n_links; i++) {
780 struct app_link_params *p = &app->link_params[i];
781 struct rte_eth_link link_params;
783 memset(&link_params, 0, sizeof(link_params));
784 rte_eth_link_get(p->pmd_id, &link_params);
786 APP_LOG(app, HIGH, "%s (%" PRIu32 ") (%" PRIu32 " Gbps) %s",
789 link_params.link_speed / 1000,
790 link_params.link_status ? "UP" : "DOWN");
792 if (link_params.link_status == 0)
796 if (all_links_up == 0)
797 rte_panic("Some links are DOWN\n");
801 app_init_link(struct app_params *app)
805 for (i = 0; i < app->n_links; i++) {
806 struct app_link_params *p_link = &app->link_params[i];
807 uint32_t link_id, n_hwq_in, n_hwq_out, j;
810 sscanf(p_link->name, "LINK%" PRIu32, &link_id);
811 n_hwq_in = app_link_get_n_rxq(app, p_link);
812 n_hwq_out = app_link_get_n_txq(app, p_link);
814 APP_LOG(app, HIGH, "Initializing %s (%" PRIu32") "
815 "(%" PRIu32 " RXQ, %" PRIu32 " TXQ) ...",
822 status = rte_eth_dev_configure(
828 rte_panic("%s (%" PRId32 "): "
829 "init error (%" PRId32 ")\n",
830 p_link->name, p_link->pmd_id, status);
832 rte_eth_macaddr_get(p_link->pmd_id,
833 (struct ether_addr *) &p_link->mac_addr);
836 rte_eth_promiscuous_enable(p_link->pmd_id);
839 for (j = 0; j < app->n_pktq_hwq_in; j++) {
840 struct app_pktq_hwq_in_params *p_rxq =
841 &app->hwq_in_params[j];
842 uint32_t rxq_link_id, rxq_queue_id;
844 sscanf(p_rxq->name, "RXQ%" PRIu32 ".%" PRIu32,
845 &rxq_link_id, &rxq_queue_id);
846 if (rxq_link_id != link_id)
849 status = rte_eth_rx_queue_setup(
853 rte_eth_dev_socket_id(p_link->pmd_id),
855 app->mempool[p_rxq->mempool_id]);
857 rte_panic("%s (%" PRIu32 "): "
858 "%s init error (%" PRId32 ")\n",
866 for (j = 0; j < app->n_pktq_hwq_out; j++) {
867 struct app_pktq_hwq_out_params *p_txq =
868 &app->hwq_out_params[j];
869 uint32_t txq_link_id, txq_queue_id;
871 sscanf(p_txq->name, "TXQ%" PRIu32 ".%" PRIu32,
872 &txq_link_id, &txq_queue_id);
873 if (txq_link_id != link_id)
876 status = rte_eth_tx_queue_setup(
880 rte_eth_dev_socket_id(p_link->pmd_id),
883 rte_panic("%s (%" PRIu32 "): "
884 "%s init error (%" PRId32 ")\n",
892 status = rte_eth_dev_start(p_link->pmd_id);
894 rte_panic("Cannot start %s (error %" PRId32 ")\n",
895 p_link->name, status);
898 app_link_set_arp_filter(app, p_link);
899 app_link_set_tcp_syn_filter(app, p_link);
900 app_link_up_internal(app, p_link);
907 app_init_swq(struct app_params *app)
911 for (i = 0; i < app->n_pktq_swq; i++) {
912 struct app_pktq_swq_params *p = &app->swq_params[i];
914 APP_LOG(app, HIGH, "Initializing %s...", p->name);
915 app->swq[i] = rte_ring_create(
919 RING_F_SP_ENQ | RING_F_SC_DEQ);
921 if (app->swq[i] == NULL)
922 rte_panic("%s init error\n", p->name);
927 app_init_tm(struct app_params *app)
931 for (i = 0; i < app->n_pktq_tm; i++) {
932 struct app_pktq_tm_params *p_tm = &app->tm_params[i];
933 struct app_link_params *p_link;
934 struct rte_eth_link link_eth_params;
935 struct rte_sched_port *sched;
936 uint32_t n_subports, subport_id;
939 p_link = app_get_link_for_tm(app, p_tm);
941 rte_eth_link_get(p_link->pmd_id, &link_eth_params);
944 p_tm->sched_port_params.name = p_tm->name;
945 p_tm->sched_port_params.socket =
946 rte_eth_dev_socket_id(p_link->pmd_id);
947 p_tm->sched_port_params.rate =
948 (uint64_t) link_eth_params.link_speed * 1000 * 1000 / 8;
950 APP_LOG(app, HIGH, "Initializing %s ...", p_tm->name);
951 sched = rte_sched_port_config(&p_tm->sched_port_params);
953 rte_panic("%s init error\n", p_tm->name);
957 n_subports = p_tm->sched_port_params.n_subports_per_port;
958 for (subport_id = 0; subport_id < n_subports; subport_id++) {
959 uint32_t n_pipes_per_subport, pipe_id;
961 status = rte_sched_subport_config(sched,
963 &p_tm->sched_subport_params[subport_id]);
965 rte_panic("%s subport %" PRIu32
966 " init error (%" PRId32 ")\n",
967 p_tm->name, subport_id, status);
970 n_pipes_per_subport =
971 p_tm->sched_port_params.n_pipes_per_subport;
973 pipe_id < n_pipes_per_subport;
975 int profile_id = p_tm->sched_pipe_to_profile[
976 subport_id * APP_MAX_SCHED_PIPES +
979 if (profile_id == -1)
982 status = rte_sched_pipe_config(sched,
987 rte_panic("%s subport %" PRIu32
989 " (profile %" PRId32 ") "
990 "init error (% " PRId32 ")\n",
991 p_tm->name, subport_id, pipe_id,
999 app_init_msgq(struct app_params *app)
1003 for (i = 0; i < app->n_msgq; i++) {
1004 struct app_msgq_params *p = &app->msgq_params[i];
1006 APP_LOG(app, HIGH, "Initializing %s ...", p->name);
1007 app->msgq[i] = rte_ring_create(
1011 RING_F_SP_ENQ | RING_F_SC_DEQ);
1013 if (app->msgq[i] == NULL)
1014 rte_panic("%s init error\n", p->name);
1018 static void app_pipeline_params_get(struct app_params *app,
1019 struct app_pipeline_params *p_in,
1020 struct pipeline_params *p_out)
1024 strcpy(p_out->name, p_in->name);
1026 p_out->socket_id = (int) p_in->socket_id;
1028 p_out->log_level = app->log_level;
1031 p_out->n_ports_in = p_in->n_pktq_in;
1032 for (i = 0; i < p_in->n_pktq_in; i++) {
1033 struct app_pktq_in_params *in = &p_in->pktq_in[i];
1034 struct pipeline_port_in_params *out = &p_out->port_in[i];
1037 case APP_PKTQ_IN_HWQ:
1039 struct app_pktq_hwq_in_params *p_hwq_in =
1040 &app->hwq_in_params[in->id];
1041 struct app_link_params *p_link =
1042 app_get_link_for_rxq(app, p_hwq_in);
1043 uint32_t rxq_link_id, rxq_queue_id;
1045 sscanf(p_hwq_in->name, "RXQ%" SCNu32 ".%" SCNu32,
1049 out->type = PIPELINE_PORT_IN_ETHDEV_READER;
1050 out->params.ethdev.port_id = p_link->pmd_id;
1051 out->params.ethdev.queue_id = rxq_queue_id;
1052 out->burst_size = p_hwq_in->burst;
1055 case APP_PKTQ_IN_SWQ:
1056 out->type = PIPELINE_PORT_IN_RING_READER;
1057 out->params.ring.ring = app->swq[in->id];
1058 out->burst_size = app->swq_params[in->id].burst_read;
1059 /* What about frag and ras ports? */
1061 case APP_PKTQ_IN_TM:
1062 out->type = PIPELINE_PORT_IN_SCHED_READER;
1063 out->params.sched.sched = app->tm[in->id];
1064 out->burst_size = app->tm_params[in->id].burst_read;
1066 case APP_PKTQ_IN_SOURCE:
1067 out->type = PIPELINE_PORT_IN_SOURCE;
1068 out->params.source.mempool = app->mempool[in->id];
1069 out->burst_size = app->source_params[in->id].burst;
1077 p_out->n_ports_out = p_in->n_pktq_out;
1078 for (i = 0; i < p_in->n_pktq_out; i++) {
1079 struct app_pktq_out_params *in = &p_in->pktq_out[i];
1080 struct pipeline_port_out_params *out = &p_out->port_out[i];
1083 case APP_PKTQ_OUT_HWQ:
1085 struct app_pktq_hwq_out_params *p_hwq_out =
1086 &app->hwq_out_params[in->id];
1087 struct app_link_params *p_link =
1088 app_get_link_for_txq(app, p_hwq_out);
1089 uint32_t txq_link_id, txq_queue_id;
1091 sscanf(p_hwq_out->name,
1092 "TXQ%" SCNu32 ".%" SCNu32,
1096 if (p_hwq_out->dropless == 0) {
1097 struct rte_port_ethdev_writer_params *params =
1098 &out->params.ethdev;
1100 out->type = PIPELINE_PORT_OUT_ETHDEV_WRITER;
1101 params->port_id = p_link->pmd_id;
1102 params->queue_id = txq_queue_id;
1103 params->tx_burst_sz =
1104 app->hwq_out_params[in->id].burst;
1106 struct rte_port_ethdev_writer_nodrop_params
1107 *params = &out->params.ethdev_nodrop;
1110 PIPELINE_PORT_OUT_ETHDEV_WRITER_NODROP;
1111 params->port_id = p_link->pmd_id;
1112 params->queue_id = txq_queue_id;
1113 params->tx_burst_sz = p_hwq_out->burst;
1114 params->n_retries = p_hwq_out->n_retries;
1118 case APP_PKTQ_OUT_SWQ:
1119 if (app->swq_params[in->id].dropless == 0) {
1120 struct rte_port_ring_writer_params *params =
1123 out->type = PIPELINE_PORT_OUT_RING_WRITER;
1124 params->ring = app->swq[in->id];
1125 params->tx_burst_sz =
1126 app->swq_params[in->id].burst_write;
1128 struct rte_port_ring_writer_nodrop_params
1129 *params = &out->params.ring_nodrop;
1132 PIPELINE_PORT_OUT_RING_WRITER_NODROP;
1133 params->ring = app->swq[in->id];
1134 params->tx_burst_sz =
1135 app->swq_params[in->id].burst_write;
1137 app->swq_params[in->id].n_retries;
1139 /* What about frag and ras ports? */
1141 case APP_PKTQ_OUT_TM: {
1142 struct rte_port_sched_writer_params *params =
1145 out->type = PIPELINE_PORT_OUT_SCHED_WRITER;
1146 params->sched = app->tm[in->id];
1147 params->tx_burst_sz =
1148 app->tm_params[in->id].burst_write;
1151 case APP_PKTQ_OUT_SINK:
1152 out->type = PIPELINE_PORT_OUT_SINK;
1160 p_out->n_msgq = p_in->n_msgq_in;
1162 for (i = 0; i < p_in->n_msgq_in; i++)
1163 p_out->msgq_in[i] = app->msgq[p_in->msgq_in[i]];
1165 for (i = 0; i < p_in->n_msgq_out; i++)
1166 p_out->msgq_out[i] = app->msgq[p_in->msgq_out[i]];
1169 p_out->n_args = p_in->n_args;
1170 for (i = 0; i < p_in->n_args; i++) {
1171 p_out->args_name[i] = p_in->args_name[i];
1172 p_out->args_value[i] = p_in->args_value[i];
1177 app_init_pipelines(struct app_params *app)
1181 for (p_id = 0; p_id < app->n_pipelines; p_id++) {
1182 struct app_pipeline_params *params =
1183 &app->pipeline_params[p_id];
1184 struct app_pipeline_data *data = &app->pipeline_data[p_id];
1185 struct pipeline_type *ptype;
1186 struct pipeline_params pp;
1188 APP_LOG(app, HIGH, "Initializing %s ...", params->name);
1190 ptype = app_pipeline_type_find(app, params->type);
1192 rte_panic("Init error: Unknown pipeline type \"%s\"\n",
1195 app_pipeline_params_get(app, params, &pp);
1199 if (ptype->be_ops->f_init) {
1200 data->be = ptype->be_ops->f_init(&pp, (void *) app);
1202 if (data->be == NULL)
1203 rte_panic("Pipeline instance \"%s\" back-end "
1204 "init error\n", params->name);
1209 if (ptype->fe_ops->f_init) {
1210 data->fe = ptype->fe_ops->f_init(&pp, (void *) app);
1212 if (data->fe == NULL)
1213 rte_panic("Pipeline instance \"%s\" front-end "
1214 "init error\n", params->name);
1217 data->timer_period = (rte_get_tsc_hz() * params->timer_period)
1223 app_init_threads(struct app_params *app)
1225 uint64_t time = rte_get_tsc_cycles();
1228 for (p_id = 0; p_id < app->n_pipelines; p_id++) {
1229 struct app_pipeline_params *params =
1230 &app->pipeline_params[p_id];
1231 struct app_pipeline_data *data = &app->pipeline_data[p_id];
1232 struct pipeline_type *ptype;
1233 struct app_thread_data *t;
1234 struct app_thread_pipeline_data *p;
1237 lcore_id = cpu_core_map_get_lcore_id(app->core_map,
1240 params->hyper_th_id);
1243 rte_panic("Invalid core s%" PRIu32 "c%" PRIu32 "%s\n",
1246 (params->hyper_th_id) ? "h" : "");
1248 t = &app->thread_data[lcore_id];
1250 ptype = app_pipeline_type_find(app, params->type);
1252 rte_panic("Init error: Unknown pipeline "
1253 "type \"%s\"\n", params->type);
1255 p = (ptype->be_ops->f_run == NULL) ?
1256 &t->regular[t->n_regular] :
1257 &t->custom[t->n_custom];
1260 p->f_run = ptype->be_ops->f_run;
1261 p->f_timer = ptype->be_ops->f_timer;
1262 p->timer_period = data->timer_period;
1263 p->deadline = time + data->timer_period;
1265 if (ptype->be_ops->f_run == NULL)
1272 int app_init(struct app_params *app)
1274 app_init_core_map(app);
1275 app_init_core_mask(app);
1278 app_init_mempool(app);
1284 app_init_pipelines(app);
1285 app_init_threads(app);
1291 app_pipeline_type_cmd_push(struct app_params *app,
1292 struct pipeline_type *ptype)
1294 cmdline_parse_ctx_t *cmds;
1297 /* Check input arguments */
1298 if ((app == NULL) ||
1302 n_cmds = pipeline_type_cmds_count(ptype);
1306 cmds = ptype->fe_ops->cmds;
1308 /* Check for available slots in the application commands array */
1309 if (n_cmds > APP_MAX_CMDS - app->n_cmds)
1312 /* Push pipeline commands into the application */
1313 memcpy(&app->cmds[app->n_cmds],
1315 n_cmds * sizeof(cmdline_parse_ctx_t *));
1317 for (i = 0; i < n_cmds; i++)
1318 app->cmds[app->n_cmds + i]->data = app;
1320 app->n_cmds += n_cmds;
1321 app->cmds[app->n_cmds] = NULL;
1327 app_pipeline_type_register(struct app_params *app, struct pipeline_type *ptype)
1331 /* Check input arguments */
1332 if ((app == NULL) ||
1334 (ptype->name == NULL) ||
1335 (strlen(ptype->name) == 0) ||
1336 (ptype->be_ops->f_init == NULL) ||
1337 (ptype->be_ops->f_timer == NULL))
1340 /* Check for duplicate entry */
1341 for (i = 0; i < app->n_pipeline_types; i++)
1342 if (strcmp(app->pipeline_type[i].name, ptype->name) == 0)
1345 /* Check for resource availability */
1346 n_cmds = pipeline_type_cmds_count(ptype);
1347 if ((app->n_pipeline_types == APP_MAX_PIPELINE_TYPES) ||
1348 (n_cmds > APP_MAX_CMDS - app->n_cmds))
1351 /* Copy pipeline type */
1352 memcpy(&app->pipeline_type[app->n_pipeline_types++],
1354 sizeof(struct pipeline_type));
1356 /* Copy CLI commands */
1358 app_pipeline_type_cmd_push(app, ptype);
1364 pipeline_type *app_pipeline_type_find(struct app_params *app, char *name)
1368 for (i = 0; i < app->n_pipeline_types; i++)
1369 if (strcmp(app->pipeline_type[i].name, name) == 0)
1370 return &app->pipeline_type[i];