2 // Copyright (c) 2017 Intel Corporation
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
8 // http://www.apache.org/licenses/LICENSE-2.0
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
21 #include <rte_cycles.h>
22 #include <rte_ethdev.h>
23 #include <rte_ether.h>
26 #include <rte_malloc.h>
27 #include <rte_version.h>
31 #include "pipeline_common_fe.h"
32 #include "pipeline_master.h"
33 #include "thread_fe.h"
34 #include "pipeline_cgnapt.h"
35 #include "pipeline_loadb.h"
36 #include "pipeline_timer.h"
37 #include "pipeline_txrx.h"
38 #include "pipeline_arpicmp.h"
39 #include "interface.h"
40 #include "l3fwd_common.h"
41 #include "l3fwd_lpm4.h"
42 #include "l3fwd_lpm6.h"
45 #define APP_NAME_SIZE 32
46 port_config_t *port_config;
49 app_init_core_map(struct app_params *app)
51 APP_LOG(app, HIGH, "Initializing CPU core map ...");
52 app->core_map = cpu_core_map_init(4, 32, 4, 0);
54 if (app->core_map == NULL)
55 rte_panic("Cannot create CPU core map\n");
57 if (app->log_level >= APP_LOG_LEVEL_LOW)
58 cpu_core_map_print(app->core_map);
61 /* Core Mask String in Hex Representation */
62 #define APP_CORE_MASK_STRING_SIZE ((64 * APP_CORE_MASK_SIZE) / 8 * 2 + 1)
65 app_init_core_mask(struct app_params *app)
67 char core_mask_str[APP_CORE_MASK_STRING_SIZE];
70 for (i = 0; i < app->n_pipelines; i++) {
71 struct app_pipeline_params *p = &app->pipeline_params[i];
74 lcore_id = cpu_core_map_get_lcore_id(app->core_map,
80 rte_panic("Cannot create CPU core mask\n");
82 app_core_enable_in_core_mask(app, lcore_id);
85 app_core_build_core_mask_string(app, core_mask_str);
86 APP_LOG(app, HIGH, "CPU core mask = 0x%s", core_mask_str);
91 app_init_eal(struct app_params *app)
94 char core_mask_str[APP_CORE_MASK_STRING_SIZE];
95 struct app_eal_params *p = &app->eal_params;
100 app->eal_argv[n_args++] = strdup(app->app_name);
102 app_core_build_core_mask_string(app, core_mask_str);
103 snprintf(buffer, sizeof(buffer), "-c%s", core_mask_str);
104 app->eal_argv[n_args++] = strdup(buffer);
107 snprintf(buffer, sizeof(buffer), "--lcores=%s", p->coremap);
108 app->eal_argv[n_args++] = strdup(buffer);
111 if (p->master_lcore_present) {
114 "--master-lcore=%" PRIu32,
116 app->eal_argv[n_args++] = strdup(buffer);
119 snprintf(buffer, sizeof(buffer), "-n%" PRIu32, p->channels);
120 app->eal_argv[n_args++] = strdup(buffer);
122 if (p->memory_present) {
123 snprintf(buffer, sizeof(buffer), "-m%" PRIu32, p->memory);
124 app->eal_argv[n_args++] = strdup(buffer);
127 if (p->ranks_present) {
128 snprintf(buffer, sizeof(buffer), "-r%" PRIu32, p->ranks);
129 app->eal_argv[n_args++] = strdup(buffer);
132 for (i = 0; i < APP_MAX_LINKS; i++) {
133 if (p->pci_blacklist[i] == NULL)
138 "--pci-blacklist=%s",
139 p->pci_blacklist[i]);
140 app->eal_argv[n_args++] = strdup(buffer);
143 if (app->port_mask != 0)
144 for (i = 0; i < APP_MAX_LINKS; i++) {
145 if (p->pci_whitelist[i] == NULL)
150 "--pci-whitelist=%s",
151 p->pci_whitelist[i]);
153 app->eal_argv[n_args++] = strdup(buffer);
156 for (i = 0; i < app->n_links; i++) {
157 char *pci_bdf = app->link_params[i].pci_bdf;
161 "--pci-whitelist=%s",
163 app->eal_argv[n_args++] = strdup(buffer);
166 for (i = 0; i < APP_MAX_LINKS; i++) {
167 if (p->vdev[i] == NULL)
174 app->eal_argv[n_args++] = strdup(buffer);
177 if ((p->vmware_tsc_map_present) && p->vmware_tsc_map) {
178 snprintf(buffer, sizeof(buffer), "--vmware-tsc-map");
179 app->eal_argv[n_args++] = strdup(buffer);
187 app->eal_argv[n_args++] = strdup(buffer);
191 snprintf(buffer, sizeof(buffer), "--syslog=%s", p->syslog);
192 app->eal_argv[n_args++] = strdup(buffer);
195 if (p->log_level_present) {
198 "--log-level=%" PRIu32,
200 app->eal_argv[n_args++] = strdup(buffer);
203 if ((p->version_present) && p->version) {
204 snprintf(buffer, sizeof(buffer), "-v");
205 app->eal_argv[n_args++] = strdup(buffer);
208 if ((p->help_present) && p->help) {
209 snprintf(buffer, sizeof(buffer), "--help");
210 app->eal_argv[n_args++] = strdup(buffer);
213 if ((p->no_huge_present) && p->no_huge) {
214 snprintf(buffer, sizeof(buffer), "--no-huge");
215 app->eal_argv[n_args++] = strdup(buffer);
218 if ((p->no_pci_present) && p->no_pci) {
219 snprintf(buffer, sizeof(buffer), "--no-pci");
220 app->eal_argv[n_args++] = strdup(buffer);
223 if ((p->no_hpet_present) && p->no_hpet) {
224 snprintf(buffer, sizeof(buffer), "--no-hpet");
225 app->eal_argv[n_args++] = strdup(buffer);
228 if ((p->no_shconf_present) && p->no_shconf) {
229 snprintf(buffer, sizeof(buffer), "--no-shconf");
230 app->eal_argv[n_args++] = strdup(buffer);
234 snprintf(buffer, sizeof(buffer), "-d=%s", p->add_driver);
235 app->eal_argv[n_args++] = strdup(buffer);
243 app->eal_argv[n_args++] = strdup(buffer);
247 snprintf(buffer, sizeof(buffer), "--huge-dir=%s", p->huge_dir);
248 app->eal_argv[n_args++] = strdup(buffer);
251 if (p->file_prefix) {
256 app->eal_argv[n_args++] = strdup(buffer);
259 if (p->base_virtaddr) {
262 "--base-virtaddr=%s",
264 app->eal_argv[n_args++] = strdup(buffer);
267 if ((p->create_uio_dev_present) && p->create_uio_dev) {
268 snprintf(buffer, sizeof(buffer), "--create-uio-dev");
269 app->eal_argv[n_args++] = strdup(buffer);
277 app->eal_argv[n_args++] = strdup(buffer);
280 if ((p->xen_dom0_present) && (p->xen_dom0)) {
281 snprintf(buffer, sizeof(buffer), "--xen-dom0");
282 app->eal_argv[n_args++] = strdup(buffer);
285 snprintf(buffer, sizeof(buffer), "--");
286 app->eal_argv[n_args++] = strdup(buffer);
288 app->eal_argc = n_args;
290 APP_LOG(app, HIGH, "Initializing EAL ...");
291 if (app->log_level >= APP_LOG_LEVEL_LOW) {
294 fprintf(stdout, "[APP] EAL arguments: \"");
295 for (i = 1; i < app->eal_argc; i++)
296 fprintf(stdout, "%s ", app->eal_argv[i]);
297 fprintf(stdout, "\"\n");
300 status = rte_eal_init(app->eal_argc, app->eal_argv);
302 rte_panic("EAL init error\n");
306 app_init_mempool(struct app_params *app)
310 for (i = 0; i < app->n_mempools; i++) {
311 struct app_mempool_params *p = &app->mempool_params[i];
313 APP_LOG(app, HIGH, "Initializing %s ...", p->name);
314 app->mempool[i] = rte_mempool_create(
319 sizeof(struct rte_pktmbuf_pool_private),
320 rte_pktmbuf_pool_init, NULL,
321 rte_pktmbuf_init, NULL,
325 if (app->mempool[i] == NULL)
326 rte_panic("%s init error\n", p->name);
331 app_link_filter_arp_add(struct app_link_params *link)
333 struct rte_eth_ethertype_filter filter = {
334 .ether_type = ETHER_TYPE_ARP,
336 .queue = link->arp_q,
339 return rte_eth_dev_filter_ctrl(link->pmd_id,
340 RTE_ETH_FILTER_ETHERTYPE,
346 app_link_filter_tcp_syn_add(struct app_link_params *link)
348 struct rte_eth_syn_filter filter = {
350 .queue = link->tcp_syn_q,
353 return rte_eth_dev_filter_ctrl(link->pmd_id,
360 app_link_filter_ip_add(struct app_link_params *l1, struct app_link_params *l2)
362 struct rte_eth_ntuple_filter filter = {
363 .flags = RTE_5TUPLE_FLAGS,
364 .dst_ip = rte_bswap32(l2->ip),
365 .dst_ip_mask = UINT32_MAX, /* Enable */
367 .src_ip_mask = 0, /* Disable */
369 .dst_port_mask = 0, /* Disable */
371 .src_port_mask = 0, /* Disable */
373 .proto_mask = 0, /* Disable */
375 .priority = 1, /* Lowest */
376 .queue = l1->ip_local_q,
379 return rte_eth_dev_filter_ctrl(l1->pmd_id,
380 RTE_ETH_FILTER_NTUPLE,
386 app_link_filter_ip_del(struct app_link_params *l1, struct app_link_params *l2)
388 struct rte_eth_ntuple_filter filter = {
389 .flags = RTE_5TUPLE_FLAGS,
390 .dst_ip = rte_bswap32(l2->ip),
391 .dst_ip_mask = UINT32_MAX, /* Enable */
393 .src_ip_mask = 0, /* Disable */
395 .dst_port_mask = 0, /* Disable */
397 .src_port_mask = 0, /* Disable */
399 .proto_mask = 0, /* Disable */
401 .priority = 1, /* Lowest */
402 .queue = l1->ip_local_q,
405 return rte_eth_dev_filter_ctrl(l1->pmd_id,
406 RTE_ETH_FILTER_NTUPLE,
407 RTE_ETH_FILTER_DELETE,
412 app_link_filter_tcp_add(struct app_link_params *l1, struct app_link_params *l2)
414 struct rte_eth_ntuple_filter filter = {
415 .flags = RTE_5TUPLE_FLAGS,
416 .dst_ip = rte_bswap32(l2->ip),
417 .dst_ip_mask = UINT32_MAX, /* Enable */
419 .src_ip_mask = 0, /* Disable */
421 .dst_port_mask = 0, /* Disable */
423 .src_port_mask = 0, /* Disable */
424 .proto = IPPROTO_TCP,
425 .proto_mask = UINT8_MAX, /* Enable */
427 .priority = 2, /* Higher priority than IP */
428 .queue = l1->tcp_local_q,
431 return rte_eth_dev_filter_ctrl(l1->pmd_id,
432 RTE_ETH_FILTER_NTUPLE,
438 app_link_filter_tcp_del(struct app_link_params *l1, struct app_link_params *l2)
440 struct rte_eth_ntuple_filter filter = {
441 .flags = RTE_5TUPLE_FLAGS,
442 .dst_ip = rte_bswap32(l2->ip),
443 .dst_ip_mask = UINT32_MAX, /* Enable */
445 .src_ip_mask = 0, /* Disable */
447 .dst_port_mask = 0, /* Disable */
449 .src_port_mask = 0, /* Disable */
450 .proto = IPPROTO_TCP,
451 .proto_mask = UINT8_MAX, /* Enable */
453 .priority = 2, /* Higher priority than IP */
454 .queue = l1->tcp_local_q,
457 return rte_eth_dev_filter_ctrl(l1->pmd_id,
458 RTE_ETH_FILTER_NTUPLE,
459 RTE_ETH_FILTER_DELETE,
464 app_link_filter_udp_add(struct app_link_params *l1, struct app_link_params *l2)
466 struct rte_eth_ntuple_filter filter = {
467 .flags = RTE_5TUPLE_FLAGS,
468 .dst_ip = rte_bswap32(l2->ip),
469 .dst_ip_mask = UINT32_MAX, /* Enable */
471 .src_ip_mask = 0, /* Disable */
473 .dst_port_mask = 0, /* Disable */
475 .src_port_mask = 0, /* Disable */
476 .proto = IPPROTO_UDP,
477 .proto_mask = UINT8_MAX, /* Enable */
479 .priority = 2, /* Higher priority than IP */
480 .queue = l1->udp_local_q,
483 return rte_eth_dev_filter_ctrl(l1->pmd_id,
484 RTE_ETH_FILTER_NTUPLE,
490 app_link_filter_udp_del(struct app_link_params *l1, struct app_link_params *l2)
492 struct rte_eth_ntuple_filter filter = {
493 .flags = RTE_5TUPLE_FLAGS,
494 .dst_ip = rte_bswap32(l2->ip),
495 .dst_ip_mask = UINT32_MAX, /* Enable */
497 .src_ip_mask = 0, /* Disable */
499 .dst_port_mask = 0, /* Disable */
501 .src_port_mask = 0, /* Disable */
502 .proto = IPPROTO_UDP,
503 .proto_mask = UINT8_MAX, /* Enable */
505 .priority = 2, /* Higher priority than IP */
506 .queue = l1->udp_local_q,
509 return rte_eth_dev_filter_ctrl(l1->pmd_id,
510 RTE_ETH_FILTER_NTUPLE,
511 RTE_ETH_FILTER_DELETE,
516 app_link_filter_sctp_add(struct app_link_params *l1, struct app_link_params *l2)
518 struct rte_eth_ntuple_filter filter = {
519 .flags = RTE_5TUPLE_FLAGS,
520 .dst_ip = rte_bswap32(l2->ip),
521 .dst_ip_mask = UINT32_MAX, /* Enable */
523 .src_ip_mask = 0, /* Disable */
525 .dst_port_mask = 0, /* Disable */
527 .src_port_mask = 0, /* Disable */
528 .proto = IPPROTO_SCTP,
529 .proto_mask = UINT8_MAX, /* Enable */
531 .priority = 2, /* Higher priority than IP */
532 .queue = l1->sctp_local_q,
535 return rte_eth_dev_filter_ctrl(l1->pmd_id,
536 RTE_ETH_FILTER_NTUPLE,
542 app_link_filter_sctp_del(struct app_link_params *l1, struct app_link_params *l2)
544 struct rte_eth_ntuple_filter filter = {
545 .flags = RTE_5TUPLE_FLAGS,
546 .dst_ip = rte_bswap32(l2->ip),
547 .dst_ip_mask = UINT32_MAX, /* Enable */
549 .src_ip_mask = 0, /* Disable */
551 .dst_port_mask = 0, /* Disable */
553 .src_port_mask = 0, /* Disable */
554 .proto = IPPROTO_SCTP,
555 .proto_mask = UINT8_MAX, /* Enable */
557 .priority = 2, /* Higher priority than IP */
558 .queue = l1->sctp_local_q,
561 return rte_eth_dev_filter_ctrl(l1->pmd_id,
562 RTE_ETH_FILTER_NTUPLE,
563 RTE_ETH_FILTER_DELETE,
568 app_link_set_arp_filter(struct app_params *app, struct app_link_params *cp)
570 if (cp->arp_q != 0) {
571 int status = app_link_filter_arp_add(cp);
573 APP_LOG(app, LOW, "%s (%" PRIu32 "): "
574 "Adding ARP filter (queue = %" PRIu32 ")",
575 cp->name, cp->pmd_id, cp->arp_q);
578 rte_panic("%s (%" PRIu32 "): "
579 "Error adding ARP filter "
580 "(queue = %" PRIu32 ") (%" PRId32 ")\n",
581 cp->name, cp->pmd_id, cp->arp_q, status);
586 app_link_set_tcp_syn_filter(struct app_params *app, struct app_link_params *cp)
588 if (cp->tcp_syn_q != 0) {
589 int status = app_link_filter_tcp_syn_add(cp);
591 APP_LOG(app, LOW, "%s (%" PRIu32 "): "
592 "Adding TCP SYN filter (queue = %" PRIu32 ")",
593 cp->name, cp->pmd_id, cp->tcp_syn_q);
596 rte_panic("%s (%" PRIu32 "): "
597 "Error adding TCP SYN filter "
598 "(queue = %" PRIu32 ") (%" PRId32 ")\n",
599 cp->name, cp->pmd_id, cp->tcp_syn_q,
604 /* rte_eth_dev is removed in DPDK version 16.11 and onwards */
605 #if RTE_VERSION < 0x100b0000
607 app_link_is_virtual(__rte_unused struct app_link_params *p)
609 uint32_t pmd_id = p->pmd_id;
610 struct rte_eth_dev *dev = &rte_eth_devices[pmd_id];
611 if (dev->dev_type == RTE_ETH_DEV_VIRTUAL)
620 app_link_up_internal(__rte_unused struct app_params *app, struct app_link_params *cp)
625 struct rte_eth_link link;
627 #if RTE_VERSION < 0x100b0000
628 if (app_link_is_virtual(cp)) {
634 /* For each link, add filters for IP of current link */
636 for (i = 0; i < app->n_links; i++) {
637 struct app_link_params *p = &app->link_params[i];
640 if (p->ip_local_q != 0) {
641 int status = app_link_filter_ip_add(p, cp);
643 APP_LOG(app, LOW, "%s (%" PRIu32 "): "
644 "Adding IP filter (queue= %" PRIu32
645 ", IP = 0x%08" PRIx32 ")",
646 p->name, p->pmd_id, p->ip_local_q,
650 rte_panic("%s (%" PRIu32 "): "
652 "filter (queue= %" PRIu32 ", "
656 p->ip_local_q, cp->ip, status);
660 if (p->tcp_local_q != 0) {
661 int status = app_link_filter_tcp_add(p, cp);
663 APP_LOG(app, LOW, "%s (%" PRIu32 "): "
666 ", IP = 0x%08" PRIx32 ")",
667 p->name, p->pmd_id, p->tcp_local_q,
671 rte_panic("%s (%" PRIu32 "): "
673 "filter (queue = %" PRIu32 ", "
677 p->tcp_local_q, cp->ip, status);
681 if (p->udp_local_q != 0) {
682 int status = app_link_filter_udp_add(p, cp);
684 APP_LOG(app, LOW, "%s (%" PRIu32 "): "
687 ", IP = 0x%08" PRIx32 ")",
688 p->name, p->pmd_id, p->udp_local_q,
692 rte_panic("%s (%" PRIu32 "): "
694 "filter (queue = %" PRIu32 ", "
698 p->udp_local_q, cp->ip, status);
702 if (p->sctp_local_q != 0) {
703 int status = app_link_filter_sctp_add(p, cp);
705 APP_LOG(app, LOW, "%s (%" PRIu32
706 "): Adding SCTP filter "
708 ", IP = 0x%08" PRIx32 ")",
709 p->name, p->pmd_id, p->sctp_local_q,
713 rte_panic("%s (%" PRIu32 "): "
715 "filter (queue = %" PRIu32 ", "
719 p->sctp_local_q, cp->ip,
725 rte_eth_link_get(cp->pmd_id, &link);
726 if (!link.link_status) {
728 status = rte_eth_dev_set_link_up(cp->pmd_id);
730 rte_panic("%s (%" PRIu32 "): PMD set link up error %"
731 PRId32 "\n", cp->name, cp->pmd_id, status);
734 ifm_update_linkstatus(cp->pmd_id, IFM_ETH_LINK_UP);
736 /* Mark link as UP */
741 app_link_down_internal(__rte_unused struct app_params *app, struct app_link_params *cp)
746 struct rte_eth_link link;
748 #if RTE_VERSION < 0x100b0000
749 if (app_link_is_virtual(cp)) {
755 rte_eth_link_get(cp->pmd_id, &link);
756 if (link.link_status) {
758 status = rte_eth_dev_set_link_down(cp->pmd_id);
760 rte_panic("%s (%" PRIu32 "): PMD set link down error %"
761 PRId32 "\n", cp->name, cp->pmd_id, status);
764 ifm_update_linkstatus(cp->pmd_id, IFM_ETH_LINK_DOWN);
765 /* Mark link as DOWN */
768 /* Return if current link IP is not valid */
772 /* For each link, remove filters for IP of current link */
773 for (i = 0; i < app->n_links; i++) {
774 struct app_link_params *p = &app->link_params[i];
777 if (p->ip_local_q != 0) {
778 int status = app_link_filter_ip_del(p, cp);
780 APP_LOG(app, LOW, "%s (%" PRIu32
781 "): Deleting IP filter "
782 "(queue = %" PRIu32 ", IP = 0x%" PRIx32 ")",
783 p->name, p->pmd_id, p->ip_local_q, cp->ip);
786 rte_panic("%s (%" PRIu32
787 "): Error deleting IP filter "
791 p->name, p->pmd_id, p->ip_local_q,
796 if (p->tcp_local_q != 0) {
797 int status = app_link_filter_tcp_del(p, cp);
799 APP_LOG(app, LOW, "%s (%" PRIu32
800 "): Deleting TCP filter "
802 ", IP = 0x%" PRIx32 ")",
803 p->name, p->pmd_id, p->tcp_local_q, cp->ip);
806 rte_panic("%s (%" PRIu32
807 "): Error deleting TCP filter "
811 p->name, p->pmd_id, p->tcp_local_q,
816 if (p->udp_local_q != 0) {
817 int status = app_link_filter_udp_del(p, cp);
819 APP_LOG(app, LOW, "%s (%" PRIu32
820 "): Deleting UDP filter "
821 "(queue = %" PRIu32 ", IP = 0x%" PRIx32 ")",
822 p->name, p->pmd_id, p->udp_local_q, cp->ip);
825 rte_panic("%s (%" PRIu32
826 "): Error deleting UDP filter "
830 p->name, p->pmd_id, p->udp_local_q,
835 if (p->sctp_local_q != 0) {
836 int status = app_link_filter_sctp_del(p, cp);
838 APP_LOG(app, LOW, "%s (%" PRIu32
839 "): Deleting SCTP filter "
841 ", IP = 0x%" PRIx32 ")",
842 p->name, p->pmd_id, p->sctp_local_q, cp->ip);
845 rte_panic("%s (%" PRIu32
846 "): Error deleting SCTP filter "
850 p->name, p->pmd_id, p->sctp_local_q,
858 app_check_link(struct app_params *app)
860 uint32_t all_links_up, i;
864 for (i = 0; i < app->n_links; i++) {
865 struct app_link_params *p = &app->link_params[i];
866 struct rte_eth_link link_params;
868 memset(&link_params, 0, sizeof(link_params));
869 rte_eth_link_get(p->pmd_id, &link_params);
871 APP_LOG(app, HIGH, "%s (%" PRIu32 ") (%" PRIu32 " Gbps) %s",
874 link_params.link_speed / 1000,
875 link_params.link_status ? "UP" : "DOWN");
877 if (link_params.link_status == ETH_LINK_DOWN)
881 if (all_links_up == 0)
882 rte_panic("Some links are DOWN\n");
886 is_any_swq_frag_or_ras(struct app_params *app)
890 for (i = 0; i < app->n_pktq_swq; i++) {
891 struct app_pktq_swq_params *p = &app->swq_params[i];
893 if ((p->ipv4_frag == 1) || (p->ipv6_frag == 1) ||
894 (p->ipv4_ras == 1) || (p->ipv6_ras == 1))
902 app_init_link_frag_ras(struct app_params *app)
906 if (is_any_swq_frag_or_ras(app)) {
907 for (i = 0; i < app->n_pktq_hwq_out; i++) {
908 struct app_pktq_hwq_out_params *p_txq =
909 &app->hwq_out_params[i];
911 p_txq->conf.txq_flags &= ~ETH_TXQ_FLAGS_NOMULTSEGS;
917 app_get_cpu_socket_id(uint32_t pmd_id)
919 int status = rte_eth_dev_socket_id(pmd_id);
921 return (status != SOCKET_ID_ANY) ? status : 0;
924 struct rte_eth_rxmode rx_mode = {
925 .max_rx_pkt_len = ETHER_MAX_LEN, /**< Default maximum frame length. */
927 .header_split = 0, /**< Header Split disabled. */
928 .hw_ip_checksum = 0, /**< IP checksum offload disabled. */
929 .hw_vlan_filter = 1, /**< VLAN filtering enabled. */
930 .hw_vlan_strip = 1, /**< VLAN strip enabled. */
931 .hw_vlan_extend = 0, /**< Extended VLAN disabled. */
932 .jumbo_frame = 0, /**< Jumbo Frame Support disabled. */
933 .hw_strip_crc = 0, /**< CRC stripping by hardware disabled. */
935 struct rte_fdir_conf fdir_conf = {
936 .mode = RTE_FDIR_MODE_NONE,
937 .pballoc = RTE_FDIR_PBALLOC_64K,
938 .status = RTE_FDIR_REPORT_STATUS,
940 .vlan_tci_mask = 0x0,
942 .src_ip = 0xFFFFFFFF,
943 .dst_ip = 0xFFFFFFFF,
946 .src_ip = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
947 .dst_ip = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
949 .src_port_mask = 0xFFFF,
950 .dst_port_mask = 0xFFFF,
951 .mac_addr_byte_mask = 0xFF,
952 .tunnel_type_mask = 1,
953 .tunnel_id_mask = 0xFFFFFFFF,
959 app_init_link(struct app_params *app)
963 app_init_link_frag_ras(app);
966 *Configuring port_config_t structure for interface manager initialization
968 size = RTE_CACHE_LINE_ROUNDUP(sizeof(port_config_t));
969 port_config = rte_zmalloc(NULL, (app->n_links * size), RTE_CACHE_LINE_SIZE);
970 if (port_config == NULL)
971 rte_panic("port_config is NULL: Memory Allocation failure\n");
973 for (i = 0; i < app->n_links; i++) {
974 struct app_link_params *p_link = &app->link_params[i];
975 uint32_t link_id, n_hwq_in, n_hwq_out;
978 status = sscanf(p_link->name, "LINK%" PRIu32, &link_id);
980 rte_panic("%s (%" PRId32 "): "
981 "init error (%" PRId32 ")\n",
982 p_link->name, link_id, status);
984 n_hwq_in = app_link_get_n_rxq(app, p_link);
985 n_hwq_out = app_link_get_n_txq(app, p_link);
987 printf("\n\nn_hwq_in %d\n", n_hwq_in);
988 struct rte_eth_conf *My_local_conf = &p_link->conf;
991 My_local_conf->rxmode = rx_mode;
992 My_local_conf->fdir_conf = fdir_conf;
993 My_local_conf->rxmode.mq_mode = ETH_MQ_RX_RSS;
994 My_local_conf->rx_adv_conf.rss_conf.rss_key = NULL;
995 My_local_conf->rx_adv_conf.rss_conf.rss_hf = ETH_RSS_IP | ETH_RSS_UDP | ETH_RSS_TCP;
996 /* pkt-filter-mode is perfect */
997 My_local_conf->fdir_conf.mode = RTE_FDIR_MODE_PERFECT;
1000 My_local_conf->rx_adv_conf.rss_conf.rss_hf = 0;
1003 /* Set the hardware CRC stripping to avoid double stripping of FCS in VM */
1004 p_link->conf.rxmode.hw_strip_crc=1;
1006 APP_LOG(app, HIGH, "Initializing %s (%" PRIu32") "
1007 "(%" PRIu32 " RXQ, %" PRIu32 " TXQ) ...",
1013 port_config[i].port_id = p_link->pmd_id;
1014 port_config[i].nrx_queue = n_hwq_in;
1015 port_config[i].ntx_queue = n_hwq_out;
1016 port_config[i].state = 1;
1017 port_config[i].promisc = p_link->promisc;
1018 port_config[i].mempool.pool_size = app->mempool_params[0].pool_size;
1019 port_config[i].mempool.buffer_size = app->mempool_params[0].buffer_size;
1020 port_config[i].mempool.cache_size = app->mempool_params[0].cache_size;
1021 port_config[i].mempool.cpu_socket_id = app->mempool_params[0].cpu_socket_id;
1022 memcpy (&port_config[i].port_conf, &p_link->conf, sizeof(struct rte_eth_conf));
1023 memcpy (&port_config[i].rx_conf, &app->hwq_in_params[0].conf, sizeof(struct rte_eth_rxconf));
1024 memcpy (&port_config[i].tx_conf, &app->hwq_out_params[0].conf, sizeof(struct rte_eth_txconf));
1026 if(app->header_csum_req) {
1027 /* Enable TCP and UDP HW Checksum */
1028 port_config[i].tx_conf.txq_flags &=
1029 ~(ETH_TXQ_FLAGS_NOXSUMTCP|ETH_TXQ_FLAGS_NOXSUMUDP);
1032 if (ifm_port_setup (p_link->pmd_id, &port_config[i])) {
1033 printf("Failed to configure port %s - %"PRIu32
1034 ".\n", p_link->name, p_link->pmd_id);
1035 printf("Try again with offload disabled....\n");
1036 port_config[i].tx_conf.txq_flags |= ETH_TXQ_FLAGS_NOOFFLOADS;
1037 if (ifm_port_setup (p_link->pmd_id, &port_config[i]))
1038 rte_panic ("Port Setup Failed: %s - %"PRIu32"\n", p_link->name, p_link->pmd_id);
1043 status = rte_eth_dev_configure(
1049 rte_panic("%s (%" PRId32 "): "
1050 "init error (%" PRId32 ")\n",
1051 p_link->name, p_link->pmd_id, status);
1053 rte_eth_macaddr_get(p_link->pmd_id,
1054 (struct ether_addr *) &p_link->mac_addr);
1056 if (p_link->promisc)
1057 rte_eth_promiscuous_enable(p_link->pmd_id);
1060 for (j = 0; j < app->n_pktq_hwq_in; j++) {
1061 struct app_pktq_hwq_in_params *p_rxq =
1062 &app->hwq_in_params[j];
1063 uint32_t rxq_link_id, rxq_queue_id;
1066 sscanf(p_rxq->name, "RXQ%" PRIu32 ".%" PRIu32,
1067 &rxq_link_id, &rxq_queue_id);
1069 rte_panic("%s (%" PRId32 "): "
1070 "init error (%" PRId32 ")\n",
1071 p_rxq->name, rxq_queue_id, status);
1073 if (rxq_link_id != link_id)
1076 status = rte_eth_rx_queue_setup(
1080 app_get_cpu_socket_id(p_link->pmd_id),
1082 app->mempool[p_rxq->mempool_id]);
1084 rte_panic("%s (%" PRIu32 "): "
1085 "%s init error (%" PRId32 ")\n",
1093 for (j = 0; j < app->n_pktq_hwq_out; j++) {
1094 struct app_pktq_hwq_out_params *p_txq =
1095 &app->hwq_out_params[j];
1096 uint32_t txq_link_id, txq_queue_id;
1099 sscanf(p_txq->name, "TXQ%" PRIu32 ".%" PRIu32,
1100 &txq_link_id, &txq_queue_id);
1103 rte_panic("%s (%" PRId32 "): "
1104 "init error (%" PRId32 ")\n",
1105 p_txq->name, txq_link_id, status);
1107 if (txq_link_id != link_id)
1110 if (app->header_csum_req) {
1111 /* Enable TCP and UDP HW Checksum */
1112 p_txq->conf.txq_flags &=
1113 ~(ETH_TXQ_FLAGS_NOXSUMTCP|
1114 ETH_TXQ_FLAGS_NOXSUMUDP);
1117 status = rte_eth_tx_queue_setup(
1121 app_get_cpu_socket_id(p_link->pmd_id),
1125 rte_panic("%s (%" PRIu32 "): "
1126 "%s init error (%" PRId32 ")\n",
1134 status = rte_eth_dev_start(p_link->pmd_id);
1136 rte_panic("Cannot start %s (error %" PRId32 ")\n",
1137 p_link->name, status);
1140 app_link_set_arp_filter(app, p_link);
1141 app_link_set_tcp_syn_filter(app, p_link);
1143 app_link_up_internal(app, p_link);
1146 app_check_link(app);
1150 app_init_swq(struct app_params *app)
1154 for (i = 0; i < app->n_pktq_swq; i++) {
1155 struct app_pktq_swq_params *p = &app->swq_params[i];
1156 unsigned int flags = 0;
1158 if (app_swq_get_readers(app, p) == 1)
1159 flags |= RING_F_SC_DEQ;
1160 if (app_swq_get_writers(app, p) == 1)
1161 flags |= RING_F_SP_ENQ;
1163 APP_LOG(app, HIGH, "Initializing %s...", p->name);
1164 app->swq[i] = rte_ring_create(
1170 if (app->swq[i] == NULL)
1171 rte_panic("%s init error\n", p->name);
1176 app_init_tm(struct app_params *app)
1180 for (i = 0; i < app->n_pktq_tm; i++) {
1181 struct app_pktq_tm_params *p_tm = &app->tm_params[i];
1182 struct app_link_params *p_link;
1183 struct rte_eth_link link_eth_params;
1184 struct rte_sched_port *sched;
1185 uint32_t n_subports, subport_id;
1188 p_link = app_get_link_for_tm(app, p_tm);
1190 rte_eth_link_get(p_link->pmd_id, &link_eth_params);
1193 p_tm->sched_port_params.name = p_tm->name;
1194 p_tm->sched_port_params.socket =
1195 app_get_cpu_socket_id(p_link->pmd_id);
1196 p_tm->sched_port_params.rate =
1197 (uint64_t) link_eth_params.link_speed * 1000 * 1000 / 8;
1199 APP_LOG(app, HIGH, "Initializing %s ...", p_tm->name);
1200 sched = rte_sched_port_config(&p_tm->sched_port_params);
1202 rte_panic("%s init error\n", p_tm->name);
1206 n_subports = p_tm->sched_port_params.n_subports_per_port;
1207 for (subport_id = 0; subport_id < n_subports; subport_id++) {
1208 uint32_t n_pipes_per_subport, pipe_id;
1210 status = rte_sched_subport_config(sched,
1212 &p_tm->sched_subport_params[subport_id]);
1214 rte_panic("%s subport %" PRIu32
1215 " init error (%" PRId32 ")\n",
1216 p_tm->name, subport_id, status);
1219 n_pipes_per_subport =
1220 p_tm->sched_port_params.n_pipes_per_subport;
1222 pipe_id < n_pipes_per_subport;
1224 int profile_id = p_tm->sched_pipe_to_profile[
1225 subport_id * APP_MAX_SCHED_PIPES +
1228 if (profile_id == -1)
1231 status = rte_sched_pipe_config(sched,
1236 rte_panic("%s subport %" PRIu32
1238 " (profile %" PRId32 ") "
1239 "init error (% " PRId32 ")\n",
1240 p_tm->name, subport_id, pipe_id,
1241 profile_id, status);
1248 app_init_msgq(struct app_params *app)
1252 for (i = 0; i < app->n_msgq; i++) {
1253 struct app_msgq_params *p = &app->msgq_params[i];
1255 APP_LOG(app, HIGH, "Initializing %s ...", p->name);
1256 app->msgq[i] = rte_ring_create(
1260 RING_F_SP_ENQ | RING_F_SC_DEQ);
1262 if (app->msgq[i] == NULL)
1263 rte_panic("%s init error\n", p->name);
1267 static void app_pipeline_params_get(struct app_params *app,
1268 struct app_pipeline_params *p_in,
1269 struct pipeline_params *p_out)
1272 uint32_t mempool_id;
1274 snprintf(p_out->name, PIPELINE_NAME_SIZE, "%s", p_in->name);
1276 p_out->socket_id = (int) p_in->socket_id;
1278 p_out->log_level = app->log_level;
1281 p_out->n_ports_in = p_in->n_pktq_in;
1282 for (i = 0; i < p_in->n_pktq_in; i++) {
1283 struct app_pktq_in_params *in = &p_in->pktq_in[i];
1284 struct pipeline_port_in_params *out = &p_out->port_in[i];
1287 case APP_PKTQ_IN_HWQ:
1289 struct app_pktq_hwq_in_params *p_hwq_in =
1290 &app->hwq_in_params[in->id];
1291 struct app_link_params *p_link =
1292 app_get_link_for_rxq(app, p_hwq_in);
1293 uint32_t rxq_link_id, rxq_queue_id;
1296 sscanf(p_hwq_in->name, "RXQ%" SCNu32 ".%" SCNu32,
1300 rte_panic("%s (%" PRId32 "): "
1301 "init error (%" PRId32 ")\n",
1302 p_hwq_in->name, rxq_link_id, status);
1304 out->type = PIPELINE_PORT_IN_ETHDEV_READER;
1305 out->params.ethdev.port_id = p_link->pmd_id;
1306 out->params.ethdev.queue_id = rxq_queue_id;
1307 out->burst_size = p_hwq_in->burst;
1310 case APP_PKTQ_IN_SWQ:
1312 struct app_pktq_swq_params *swq_params =
1313 &app->swq_params[in->id];
1315 if ((swq_params->ipv4_frag == 0) &&
1316 (swq_params->ipv6_frag == 0)) {
1317 if (app_swq_get_readers(app,
1320 PIPELINE_PORT_IN_RING_READER;
1321 out->params.ring.ring =
1324 app->swq_params[in->id].
1327 out->type = PIPELINE_PORT_IN_RING_MULTI_READER;
1328 out->params.ring_multi.ring = app->swq[in->id];
1329 out->burst_size = swq_params->burst_read;
1332 if (swq_params->ipv4_frag == 1) {
1333 struct rte_port_ring_reader_ipv4_frag_params
1335 &out->params.ring_ipv4_frag;
1338 PIPELINE_PORT_IN_RING_READER_IPV4_FRAG;
1339 params->ring = app->swq[in->id];
1340 params->mtu = swq_params->mtu;
1341 params->metadata_size =
1342 swq_params->metadata_size;
1343 params->pool_direct =
1345 [swq_params->mempool_direct_id];
1346 params->pool_indirect =
1348 [swq_params->mempool_indirect_id];
1349 out->burst_size = swq_params->burst_read;
1351 struct rte_port_ring_reader_ipv6_frag_params
1353 &out->params.ring_ipv6_frag;
1356 PIPELINE_PORT_IN_RING_READER_IPV6_FRAG;
1357 params->ring = app->swq[in->id];
1358 params->mtu = swq_params->mtu;
1359 params->metadata_size =
1360 swq_params->metadata_size;
1361 params->pool_direct =
1363 [swq_params->mempool_direct_id];
1364 params->pool_indirect =
1366 [swq_params->mempool_indirect_id];
1367 out->burst_size = swq_params->burst_read;
1372 case APP_PKTQ_IN_TM:
1373 out->type = PIPELINE_PORT_IN_SCHED_READER;
1374 out->params.sched.sched = app->tm[in->id];
1375 out->burst_size = app->tm_params[in->id].burst_read;
1377 case APP_PKTQ_IN_SOURCE:
1378 mempool_id = app->source_params[in->id].mempool_id;
1379 out->type = PIPELINE_PORT_IN_SOURCE;
1380 out->params.source.mempool = app->mempool[mempool_id];
1381 out->burst_size = app->source_params[in->id].burst;
1384 if (app->source_params[in->id].file_name
1386 out->params.source.file_name = strdup(
1387 app->source_params[in->id].
1389 if (out->params.source.file_name == NULL) {
1391 n_bytes_per_pkt = 0;
1394 out->params.source.n_bytes_per_pkt =
1395 app->source_params[in->id].
1407 p_out->n_ports_out = p_in->n_pktq_out;
1408 for (i = 0; i < p_in->n_pktq_out; i++) {
1409 struct app_pktq_out_params *in = &p_in->pktq_out[i];
1410 struct pipeline_port_out_params *out = &p_out->port_out[i];
1413 case APP_PKTQ_OUT_HWQ:
1415 struct app_pktq_hwq_out_params *p_hwq_out =
1416 &app->hwq_out_params[in->id];
1417 struct app_link_params *p_link =
1418 app_get_link_for_txq(app, p_hwq_out);
1419 uint32_t txq_link_id, txq_queue_id;
1422 sscanf(p_hwq_out->name,
1423 "TXQ%" SCNu32 ".%" SCNu32,
1427 rte_panic("%s (%" PRId32 "): "
1428 "init error (%" PRId32 ")\n",
1429 p_hwq_out->name, txq_link_id, status);
1431 if (p_hwq_out->dropless == 0) {
1432 struct rte_port_ethdev_writer_params *params =
1433 &out->params.ethdev;
1435 out->type = PIPELINE_PORT_OUT_ETHDEV_WRITER;
1436 params->port_id = p_link->pmd_id;
1437 params->queue_id = txq_queue_id;
1438 params->tx_burst_sz =
1439 app->hwq_out_params[in->id].burst;
1441 struct rte_port_ethdev_writer_nodrop_params
1442 *params = &out->params.ethdev_nodrop;
1445 PIPELINE_PORT_OUT_ETHDEV_WRITER_NODROP;
1446 params->port_id = p_link->pmd_id;
1447 params->queue_id = txq_queue_id;
1448 params->tx_burst_sz = p_hwq_out->burst;
1449 params->n_retries = p_hwq_out->n_retries;
1453 case APP_PKTQ_OUT_SWQ:
1455 struct app_pktq_swq_params *swq_params =
1456 &app->swq_params[in->id];
1458 if ((swq_params->ipv4_ras == 0) &&
1459 (swq_params->ipv6_ras == 0)) {
1460 if (app_swq_get_writers(app, swq_params) == 1) {
1461 if (app->swq_params[in->id].dropless == 0) {
1462 struct rte_port_ring_writer_params *params =
1465 out->type = PIPELINE_PORT_OUT_RING_WRITER;
1466 params->ring = app->swq[in->id];
1467 params->tx_burst_sz =
1468 app->swq_params[in->id].burst_write;
1470 struct rte_port_ring_writer_nodrop_params
1471 *params = &out->params.ring_nodrop;
1474 PIPELINE_PORT_OUT_RING_WRITER_NODROP;
1475 params->ring = app->swq[in->id];
1476 params->tx_burst_sz =
1477 app->swq_params[in->id].burst_write;
1479 app->swq_params[in->id].n_retries;
1482 if (swq_params->dropless == 0) {
1483 struct rte_port_ring_multi_writer_params
1485 &out->params.ring_multi;
1488 PIPELINE_PORT_OUT_RING_MULTI_WRITER;
1489 params->ring = app->swq[in->id];
1490 params->tx_burst_sz = swq_params->burst_write;
1492 struct rte_port_ring_multi_writer_nodrop_params
1494 &out->params.ring_multi_nodrop;
1497 PIPELINE_PORT_OUT_RING_MULTI_WRITER_NODROP;
1499 params->ring = app->swq[in->id];
1500 params->tx_burst_sz = swq_params->burst_write;
1501 params->n_retries = swq_params->n_retries;
1505 if (swq_params->ipv4_ras == 1) {
1506 struct rte_port_ring_writer_ipv4_ras_params
1508 &out->params.ring_ipv4_ras;
1511 PIPELINE_PORT_OUT_RING_WRITER_IPV4_RAS;
1512 params->ring = app->swq[in->id];
1513 params->tx_burst_sz = swq_params->burst_write;
1515 struct rte_port_ring_writer_ipv6_ras_params
1517 &out->params.ring_ipv6_ras;
1520 PIPELINE_PORT_OUT_RING_WRITER_IPV6_RAS;
1521 params->ring = app->swq[in->id];
1522 params->tx_burst_sz = swq_params->burst_write;
1527 case APP_PKTQ_OUT_TM: {
1528 struct rte_port_sched_writer_params *params =
1531 out->type = PIPELINE_PORT_OUT_SCHED_WRITER;
1532 params->sched = app->tm[in->id];
1533 params->tx_burst_sz =
1534 app->tm_params[in->id].burst_write;
1537 case APP_PKTQ_OUT_SINK:
1538 out->type = PIPELINE_PORT_OUT_SINK;
1539 if (app->sink_params[in->id].file_name != NULL) {
1540 out->params.sink.file_name = strdup(
1541 app->sink_params[in->id].
1543 if (out->params.sink.file_name == NULL) {
1544 out->params.sink.max_n_pkts = 0;
1547 out->params.sink.max_n_pkts =
1548 app->sink_params[in->id].
1551 out->params.sink.file_name = NULL;
1552 out->params.sink.max_n_pkts = 0;
1561 p_out->n_msgq = p_in->n_msgq_in;
1563 for (i = 0; i < p_in->n_msgq_in; i++)
1564 p_out->msgq_in[i] = app->msgq[p_in->msgq_in[i]];
1566 for (i = 0; i < p_in->n_msgq_out; i++)
1567 p_out->msgq_out[i] = app->msgq[p_in->msgq_out[i]];
1570 p_out->n_args = p_in->n_args;
1571 for (i = 0; i < p_in->n_args; i++) {
1572 p_out->args_name[i] = p_in->args_name[i];
1573 p_out->args_value[i] = p_in->args_value[i];
1578 app_init_pipelines(struct app_params *app)
1582 for (p_id = 0; p_id < app->n_pipelines; p_id++) {
1583 struct app_pipeline_params *params =
1584 &app->pipeline_params[p_id];
1585 struct app_pipeline_data *data = &app->pipeline_data[p_id];
1586 struct pipeline_type *ptype;
1587 struct pipeline_params pp;
1589 APP_LOG(app, HIGH, "Initializing %s ...", params->name);
1591 ptype = app_pipeline_type_find(app, params->type);
1593 rte_panic("Init error: Unknown pipeline type \"%s\"\n",
1596 app_pipeline_params_get(app, params, &pp);
1600 if (ptype->be_ops->f_init) {
1601 data->be = ptype->be_ops->f_init(&pp, (void *) app);
1603 if (data->be == NULL)
1604 rte_panic("Pipeline instance \"%s\" back-end "
1605 "init error\n", params->name);
1610 if (ptype->fe_ops->f_init) {
1611 data->fe = ptype->fe_ops->f_init(&pp, (void *) app);
1613 if (data->fe == NULL)
1614 rte_panic("Pipeline instance \"%s\" front-end "
1615 "init error\n", params->name);
1618 data->ptype = ptype;
1620 data->timer_period = (rte_get_tsc_hz() *
1621 params->timer_period) / 100;
1626 app_init_threads(struct app_params *app)
1628 uint64_t time = rte_get_tsc_cycles();
1631 for (p_id = 0; p_id < app->n_pipelines; p_id++) {
1632 struct app_pipeline_params *params =
1633 &app->pipeline_params[p_id];
1634 struct app_pipeline_data *data = &app->pipeline_data[p_id];
1635 struct pipeline_type *ptype;
1636 struct app_thread_data *t;
1637 struct app_thread_pipeline_data *p;
1640 lcore_id = cpu_core_map_get_lcore_id(app->core_map,
1643 params->hyper_th_id);
1646 rte_panic("Invalid core s%" PRIu32 "c%" PRIu32 "%s\n",
1649 (params->hyper_th_id) ? "h" : "");
1651 t = &app->thread_data[lcore_id];
1653 t->timer_period = (rte_get_tsc_hz() *
1654 APP_THREAD_TIMER_PERIOD) / 1000;
1655 t->thread_req_deadline = time + t->timer_period;
1657 t->headroom_cycles = 0;
1658 t->headroom_time = rte_get_tsc_cycles();
1659 t->headroom_ratio = 0.0;
1661 t->msgq_in = app_thread_msgq_in_get(app,
1664 params->hyper_th_id);
1665 if (t->msgq_in == NULL)
1666 rte_panic("Init error: Cannot find MSGQ_IN "
1667 "for thread %" PRId32, lcore_id);
1669 t->msgq_out = app_thread_msgq_out_get(app,
1672 params->hyper_th_id);
1673 if (t->msgq_out == NULL)
1674 rte_panic("Init error: Cannot find MSGQ_OUT "
1675 "for thread %" PRId32, lcore_id);
1677 ptype = app_pipeline_type_find(app, params->type);
1679 rte_panic("Init error: Unknown pipeline "
1680 "type \"%s\"\n", params->type);
1682 p = (ptype->be_ops->f_run == NULL) ?
1683 &t->regular[t->n_regular] :
1684 &t->custom[t->n_custom];
1686 p->pipeline_id = p_id;
1688 p->f_run = ptype->be_ops->f_run;
1689 p->f_timer = ptype->be_ops->f_timer;
1690 p->timer_period = data->timer_period;
1691 p->deadline = time + data->timer_period;
1695 if (ptype->be_ops->f_run == NULL)
1702 int app_init(struct app_params *app)
1704 app_init_core_map(app);
1705 app_init_core_mask(app);
1709 //app_init_mempool(app);
1715 app_pipeline_common_cmd_push(app);
1716 app_pipeline_thread_cmd_push(app);
1717 app_pipeline_type_register(app, &pipeline_master);
1718 app_pipeline_type_register(app, &pipeline_cgnapt);
1719 app_pipeline_type_register(app, &pipeline_loadb);
1720 app_pipeline_type_register(app, &pipeline_timer);
1721 app_pipeline_type_register(app, &pipeline_txrx);
1722 app_pipeline_type_register(app, &pipeline_arpicmp);
1724 app_init_pipelines(app);
1725 app_init_threads(app);
1727 #ifdef L3_STACK_SUPPORT
1731 populate_lpm_routes();
1732 print_interface_details();
1739 app_pipeline_type_cmd_push(struct app_params *app,
1740 struct pipeline_type *ptype)
1742 cmdline_parse_ctx_t *cmds;
1745 /* Check input arguments */
1746 if ((app == NULL) ||
1750 n_cmds = pipeline_type_cmds_count(ptype);
1754 cmds = ptype->fe_ops->cmds;
1756 /* Check for available slots in the application commands array */
1757 if (n_cmds > APP_MAX_CMDS - app->n_cmds)
1760 /* Push pipeline commands into the application */
1761 memcpy(&app->cmds[app->n_cmds],
1763 n_cmds * sizeof(cmdline_parse_ctx_t));
1765 for (i = 0; i < n_cmds; i++)
1766 app->cmds[app->n_cmds + i]->data = app;
1768 app->n_cmds += n_cmds;
1769 app->cmds[app->n_cmds] = NULL;
1775 app_pipeline_type_register(struct app_params *app, struct pipeline_type *ptype)
1779 /* Check input arguments */
1780 if ((app == NULL) ||
1782 (ptype->name == NULL) ||
1783 (strlen(ptype->name) == 0) ||
1784 (ptype->be_ops->f_init == NULL) ||
1785 (ptype->be_ops->f_timer == NULL))
1788 /* Check for duplicate entry */
1789 for (i = 0; i < app->n_pipeline_types; i++)
1790 if (strcmp(app->pipeline_type[i].name, ptype->name) == 0)
1793 /* Check for resource availability */
1794 n_cmds = pipeline_type_cmds_count(ptype);
1795 if ((app->n_pipeline_types == APP_MAX_PIPELINE_TYPES) ||
1796 (n_cmds > APP_MAX_CMDS - app->n_cmds))
1799 /* Copy pipeline type */
1800 memcpy(&app->pipeline_type[app->n_pipeline_types++],
1802 sizeof(struct pipeline_type));
1804 /* Copy CLI commands */
1806 app_pipeline_type_cmd_push(app, ptype);
1812 pipeline_type *app_pipeline_type_find(struct app_params *app, char *name)
1816 for (i = 0; i < app->n_pipeline_types; i++)
1817 if (strcmp(app->pipeline_type[i].name, name) == 0)
1818 return &app->pipeline_type[i];