54143773cc2b8d3f9fab072ee197f1591ec53271
[samplevnf.git] / VNFs / vFW / init.c
1 /*
2 // Copyright (c) 2017 Intel Corporation
3 //
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
7 //
8 //      http://www.apache.org/licenses/LICENSE-2.0
9 //
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.
15 */
16
17 #include <inttypes.h>
18 #include <stdio.h>
19 #include <string.h>
20
21 #include <rte_cycles.h>
22 #include <rte_ethdev.h>
23 #include <rte_ether.h>
24 #include <rte_ip.h>
25 #include <rte_eal.h>
26 #include <rte_malloc.h>
27
28 #include "app.h"
29 #include "pipeline.h"
30 #include "pipeline_common_fe.h"
31 #include "pipeline_master.h"
32 #include "pipeline_passthrough.h"
33 #include "thread_fe.h"
34 #include "pipeline_vfw.h"
35 #include "pipeline_loadb.h"
36 #include "pipeline_txrx.h"
37 #include "pipeline_arpicmp.h"
38 #include "interface.h"
39 #include "l3fwd_common.h"
40 #include "l3fwd_lpm4.h"
41 #include "l3fwd_lpm6.h"
42 #include "lib_arp.h"
43 #include "vnf_define.h"
44 #define APP_NAME_SIZE   32
45 port_config_t *port_config;
46
47 static void
48 app_init_core_map(struct app_params *app)
49 {
50         APP_LOG(app, HIGH, "Initializing CPU core map ...");
51         app->core_map = cpu_core_map_init(4, 32, 4, 0);
52
53         if (app->core_map == NULL)
54                 rte_panic("Cannot create CPU core map\n");
55
56         if (app->log_level >= APP_LOG_LEVEL_LOW)
57                 cpu_core_map_print(app->core_map);
58 }
59
60 /* Core Mask String in Hex Representation */
61 #define APP_CORE_MASK_STRING_SIZE ((64 * APP_CORE_MASK_SIZE) / 8 * 2 + 1)
62
63 static void
64 app_init_core_mask(struct app_params *app)
65 {
66         char core_mask_str[APP_CORE_MASK_STRING_SIZE];
67         uint32_t i;
68
69         for (i = 0; i < app->n_pipelines; i++) {
70                 struct app_pipeline_params *p = &app->pipeline_params[i];
71                 int lcore_id;
72
73                 lcore_id = cpu_core_map_get_lcore_id(app->core_map,
74                         p->socket_id,
75                         p->core_id,
76                         p->hyper_th_id);
77
78                 if (lcore_id < 0)
79                         rte_panic("Cannot create CPU core mask\n");
80
81                 app_core_enable_in_core_mask(app, lcore_id);
82         }
83
84        app_core_build_core_mask_string(app, core_mask_str);
85        APP_LOG(app, HIGH, "CPU core mask = 0x%s", core_mask_str);
86
87 }
88
89 static void
90 app_init_eal(struct app_params *app)
91 {
92         char buffer[256];
93         char core_mask_str[APP_CORE_MASK_STRING_SIZE];
94         struct app_eal_params *p = &app->eal_params;
95         uint8_t n_args = 0;
96         uint32_t i;
97         int status;
98
99         app->eal_argv[n_args++] = strdup(app->app_name);
100
101         app_core_build_core_mask_string(app, core_mask_str);
102         snprintf(buffer, sizeof(buffer), "-c%s", core_mask_str);
103         app->eal_argv[n_args++] = strdup(buffer);
104
105         if (p->coremap) {
106                 snprintf(buffer, sizeof(buffer), "--lcores=%s", p->coremap);
107                 app->eal_argv[n_args++] = strdup(buffer);
108         }
109
110         if (p->master_lcore_present) {
111                 snprintf(buffer,
112                         sizeof(buffer),
113                         "--master-lcore=%" PRIu32,
114                         p->master_lcore);
115                 app->eal_argv[n_args++] = strdup(buffer);
116         }
117
118         snprintf(buffer, sizeof(buffer), "-n%" PRIu32, p->channels);
119         app->eal_argv[n_args++] = strdup(buffer);
120
121         if (p->memory_present) {
122                 snprintf(buffer, sizeof(buffer), "-m%" PRIu32, p->memory);
123                 app->eal_argv[n_args++] = strdup(buffer);
124         }
125
126         if (p->ranks_present) {
127                 snprintf(buffer, sizeof(buffer), "-r%" PRIu32, p->ranks);
128                 app->eal_argv[n_args++] = strdup(buffer);
129         }
130
131         for (i = 0; i < APP_MAX_LINKS; i++) {
132                 if (p->pci_blacklist[i] == NULL)
133                         break;
134
135                 snprintf(buffer,
136                         sizeof(buffer),
137                         "--pci-blacklist=%s",
138                         p->pci_blacklist[i]);
139                 app->eal_argv[n_args++] = strdup(buffer);
140         }
141
142         if (app->port_mask != 0)
143                 for (i = 0; i < APP_MAX_LINKS; i++) {
144                         if (p->pci_whitelist[i] == NULL)
145                                 break;
146
147                         snprintf(buffer,
148                                 sizeof(buffer),
149                                 "--pci-whitelist=%s",
150                                 p->pci_whitelist[i]);
151                         app->eal_argv[n_args++] = strdup(buffer);
152                 }
153         else
154                 for (i = 0; i < app->n_links; i++) {
155                         char *pci_bdf = app->link_params[i].pci_bdf;
156
157                         snprintf(buffer,
158                                 sizeof(buffer),
159                                 "--pci-whitelist=%s",
160                                 pci_bdf);
161                         app->eal_argv[n_args++] = strdup(buffer);
162                 }
163
164         for (i = 0; i < APP_MAX_LINKS; i++) {
165                 if (p->vdev[i] == NULL)
166                         break;
167
168                 snprintf(buffer,
169                         sizeof(buffer),
170                         "--vdev=%s",
171                         p->vdev[i]);
172                 app->eal_argv[n_args++] = strdup(buffer);
173         }
174
175         if ((p->vmware_tsc_map_present) && p->vmware_tsc_map) {
176                 snprintf(buffer, sizeof(buffer), "--vmware-tsc-map");
177                 app->eal_argv[n_args++] = strdup(buffer);
178         }
179
180         if (p->proc_type) {
181                 snprintf(buffer,
182                         sizeof(buffer),
183                         "--proc-type=%s",
184                         p->proc_type);
185                 app->eal_argv[n_args++] = strdup(buffer);
186         }
187
188         if (p->syslog) {
189                 snprintf(buffer, sizeof(buffer), "--syslog=%s", p->syslog);
190                 app->eal_argv[n_args++] = strdup(buffer);
191         }
192
193         if (p->log_level_present) {
194                 snprintf(buffer,
195                         sizeof(buffer),
196                         "--log-level=%" PRIu32,
197                         p->log_level);
198                 app->eal_argv[n_args++] = strdup(buffer);
199         }
200
201         if ((p->version_present) && p->version) {
202                 snprintf(buffer, sizeof(buffer), "-v");
203                 app->eal_argv[n_args++] = strdup(buffer);
204         }
205
206         if ((p->help_present) && p->help) {
207                 snprintf(buffer, sizeof(buffer), "--help");
208                 app->eal_argv[n_args++] = strdup(buffer);
209         }
210
211         if ((p->no_huge_present) && p->no_huge) {
212                 snprintf(buffer, sizeof(buffer), "--no-huge");
213                 app->eal_argv[n_args++] = strdup(buffer);
214         }
215
216         if ((p->no_pci_present) && p->no_pci) {
217                 snprintf(buffer, sizeof(buffer), "--no-pci");
218                 app->eal_argv[n_args++] = strdup(buffer);
219         }
220
221         if ((p->no_hpet_present) && p->no_hpet) {
222                 snprintf(buffer, sizeof(buffer), "--no-hpet");
223                 app->eal_argv[n_args++] = strdup(buffer);
224         }
225
226         if ((p->no_shconf_present) && p->no_shconf) {
227                 snprintf(buffer, sizeof(buffer), "--no-shconf");
228                 app->eal_argv[n_args++] = strdup(buffer);
229         }
230
231         if (p->add_driver) {
232                 snprintf(buffer, sizeof(buffer), "-d=%s", p->add_driver);
233                 app->eal_argv[n_args++] = strdup(buffer);
234         }
235
236         if (p->socket_mem) {
237                 snprintf(buffer,
238                         sizeof(buffer),
239                         "--socket-mem=%s",
240                         p->socket_mem);
241                 app->eal_argv[n_args++] = strdup(buffer);
242         }
243
244         if (p->huge_dir) {
245                 snprintf(buffer, sizeof(buffer), "--huge-dir=%s", p->huge_dir);
246                 app->eal_argv[n_args++] = strdup(buffer);
247         }
248
249         if (p->file_prefix) {
250                 snprintf(buffer,
251                         sizeof(buffer),
252                         "--file-prefix=%s",
253                         p->file_prefix);
254                 app->eal_argv[n_args++] = strdup(buffer);
255         }
256
257         if (p->base_virtaddr) {
258                 snprintf(buffer,
259                         sizeof(buffer),
260                         "--base-virtaddr=%s",
261                         p->base_virtaddr);
262                 app->eal_argv[n_args++] = strdup(buffer);
263         }
264
265         if ((p->create_uio_dev_present) && p->create_uio_dev) {
266                 snprintf(buffer, sizeof(buffer), "--create-uio-dev");
267                 app->eal_argv[n_args++] = strdup(buffer);
268         }
269
270         if (p->vfio_intr) {
271                 snprintf(buffer,
272                         sizeof(buffer),
273                         "--vfio-intr=%s",
274                         p->vfio_intr);
275                 app->eal_argv[n_args++] = strdup(buffer);
276         }
277
278         if ((p->xen_dom0_present) && (p->xen_dom0)) {
279                 snprintf(buffer, sizeof(buffer), "--xen-dom0");
280                 app->eal_argv[n_args++] = strdup(buffer);
281         }
282
283         snprintf(buffer, sizeof(buffer), "--");
284         app->eal_argv[n_args++] = strdup(buffer);
285
286         app->eal_argc = n_args;
287
288         APP_LOG(app, HIGH, "Initializing EAL ...");
289         if (app->log_level >= APP_LOG_LEVEL_LOW) {
290                 int i;
291
292                 fprintf(stdout, "[APP] EAL arguments: \"");
293                 for (i = 1; i < app->eal_argc; i++)
294                         fprintf(stdout, "%s ", app->eal_argv[i]);
295                 fprintf(stdout, "\"\n");
296         }
297
298         status = rte_eal_init(app->eal_argc, app->eal_argv);
299         if (status < 0)
300                 rte_panic("EAL init error\n");
301 }
302 static inline int
303 app_link_filter_arp_add(struct app_link_params *link)
304 {
305         struct rte_eth_ethertype_filter filter = {
306                 .ether_type = ETHER_TYPE_ARP,
307                 .flags = 0,
308                 .queue = link->arp_q,
309         };
310
311         return rte_eth_dev_filter_ctrl(link->pmd_id,
312                 RTE_ETH_FILTER_ETHERTYPE,
313                 RTE_ETH_FILTER_ADD,
314                 &filter);
315 }
316
317 static inline int
318 app_link_filter_tcp_syn_add(struct app_link_params *link)
319 {
320         struct rte_eth_syn_filter filter = {
321                 .hig_pri = 1,
322                 .queue = link->tcp_syn_q,
323         };
324
325         return rte_eth_dev_filter_ctrl(link->pmd_id,
326                 RTE_ETH_FILTER_SYN,
327                 RTE_ETH_FILTER_ADD,
328                 &filter);
329 }
330
331 static inline int
332 app_link_filter_ip_add(struct app_link_params *l1, struct app_link_params *l2)
333 {
334         struct rte_eth_ntuple_filter filter = {
335                 .flags = RTE_5TUPLE_FLAGS,
336                 .dst_ip = rte_bswap32(l2->ip),
337                 .dst_ip_mask = UINT32_MAX, /* Enable */
338                 .src_ip = 0,
339                 .src_ip_mask = 0, /* Disable */
340                 .dst_port = 0,
341                 .dst_port_mask = 0, /* Disable */
342                 .src_port = 0,
343                 .src_port_mask = 0, /* Disable */
344                 .proto = 0,
345                 .proto_mask = 0, /* Disable */
346                 .tcp_flags = 0,
347                 .priority = 1, /* Lowest */
348                 .queue = l1->ip_local_q,
349         };
350
351         return rte_eth_dev_filter_ctrl(l1->pmd_id,
352                 RTE_ETH_FILTER_NTUPLE,
353                 RTE_ETH_FILTER_ADD,
354                 &filter);
355 }
356
357 static inline int
358 app_link_filter_ip_del(struct app_link_params *l1, struct app_link_params *l2)
359 {
360         struct rte_eth_ntuple_filter filter = {
361                 .flags = RTE_5TUPLE_FLAGS,
362                 .dst_ip = rte_bswap32(l2->ip),
363                 .dst_ip_mask = UINT32_MAX, /* Enable */
364                 .src_ip = 0,
365                 .src_ip_mask = 0, /* Disable */
366                 .dst_port = 0,
367                 .dst_port_mask = 0, /* Disable */
368                 .src_port = 0,
369                 .src_port_mask = 0, /* Disable */
370                 .proto = 0,
371                 .proto_mask = 0, /* Disable */
372                 .tcp_flags = 0,
373                 .priority = 1, /* Lowest */
374                 .queue = l1->ip_local_q,
375         };
376
377         return rte_eth_dev_filter_ctrl(l1->pmd_id,
378                 RTE_ETH_FILTER_NTUPLE,
379                 RTE_ETH_FILTER_DELETE,
380                 &filter);
381 }
382
383 static inline int
384 app_link_filter_tcp_add(struct app_link_params *l1, struct app_link_params *l2)
385 {
386         struct rte_eth_ntuple_filter filter = {
387                 .flags = RTE_5TUPLE_FLAGS,
388                 .dst_ip = rte_bswap32(l2->ip),
389                 .dst_ip_mask = UINT32_MAX, /* Enable */
390                 .src_ip = 0,
391                 .src_ip_mask = 0, /* Disable */
392                 .dst_port = 0,
393                 .dst_port_mask = 0, /* Disable */
394                 .src_port = 0,
395                 .src_port_mask = 0, /* Disable */
396                 .proto = IPPROTO_TCP,
397                 .proto_mask = UINT8_MAX, /* Enable */
398                 .tcp_flags = 0,
399                 .priority = 2, /* Higher priority than IP */
400                 .queue = l1->tcp_local_q,
401         };
402
403         return rte_eth_dev_filter_ctrl(l1->pmd_id,
404                 RTE_ETH_FILTER_NTUPLE,
405                 RTE_ETH_FILTER_ADD,
406                 &filter);
407 }
408
409 static inline int
410 app_link_filter_tcp_del(struct app_link_params *l1, struct app_link_params *l2)
411 {
412         struct rte_eth_ntuple_filter filter = {
413                 .flags = RTE_5TUPLE_FLAGS,
414                 .dst_ip = rte_bswap32(l2->ip),
415                 .dst_ip_mask = UINT32_MAX, /* Enable */
416                 .src_ip = 0,
417                 .src_ip_mask = 0, /* Disable */
418                 .dst_port = 0,
419                 .dst_port_mask = 0, /* Disable */
420                 .src_port = 0,
421                 .src_port_mask = 0, /* Disable */
422                 .proto = IPPROTO_TCP,
423                 .proto_mask = UINT8_MAX, /* Enable */
424                 .tcp_flags = 0,
425                 .priority = 2, /* Higher priority than IP */
426                 .queue = l1->tcp_local_q,
427         };
428
429         return rte_eth_dev_filter_ctrl(l1->pmd_id,
430                 RTE_ETH_FILTER_NTUPLE,
431                 RTE_ETH_FILTER_DELETE,
432                 &filter);
433 }
434
435 static inline int
436 app_link_filter_udp_add(struct app_link_params *l1, struct app_link_params *l2)
437 {
438         struct rte_eth_ntuple_filter filter = {
439                 .flags = RTE_5TUPLE_FLAGS,
440                 .dst_ip = rte_bswap32(l2->ip),
441                 .dst_ip_mask = UINT32_MAX, /* Enable */
442                 .src_ip = 0,
443                 .src_ip_mask = 0, /* Disable */
444                 .dst_port = 0,
445                 .dst_port_mask = 0, /* Disable */
446                 .src_port = 0,
447                 .src_port_mask = 0, /* Disable */
448                 .proto = IPPROTO_UDP,
449                 .proto_mask = UINT8_MAX, /* Enable */
450                 .tcp_flags = 0,
451                 .priority = 2, /* Higher priority than IP */
452                 .queue = l1->udp_local_q,
453         };
454
455         return rte_eth_dev_filter_ctrl(l1->pmd_id,
456                 RTE_ETH_FILTER_NTUPLE,
457                 RTE_ETH_FILTER_ADD,
458                 &filter);
459 }
460
461 static inline int
462 app_link_filter_udp_del(struct app_link_params *l1, struct app_link_params *l2)
463 {
464         struct rte_eth_ntuple_filter filter = {
465                 .flags = RTE_5TUPLE_FLAGS,
466                 .dst_ip = rte_bswap32(l2->ip),
467                 .dst_ip_mask = UINT32_MAX, /* Enable */
468                 .src_ip = 0,
469                 .src_ip_mask = 0, /* Disable */
470                 .dst_port = 0,
471                 .dst_port_mask = 0, /* Disable */
472                 .src_port = 0,
473                 .src_port_mask = 0, /* Disable */
474                 .proto = IPPROTO_UDP,
475                 .proto_mask = UINT8_MAX, /* Enable */
476                 .tcp_flags = 0,
477                 .priority = 2, /* Higher priority than IP */
478                 .queue = l1->udp_local_q,
479         };
480
481         return rte_eth_dev_filter_ctrl(l1->pmd_id,
482                 RTE_ETH_FILTER_NTUPLE,
483                 RTE_ETH_FILTER_DELETE,
484                 &filter);
485 }
486
487 static inline int
488 app_link_filter_sctp_add(struct app_link_params *l1, struct app_link_params *l2)
489 {
490         struct rte_eth_ntuple_filter filter = {
491                 .flags = RTE_5TUPLE_FLAGS,
492                 .dst_ip = rte_bswap32(l2->ip),
493                 .dst_ip_mask = UINT32_MAX, /* Enable */
494                 .src_ip = 0,
495                 .src_ip_mask = 0, /* Disable */
496                 .dst_port = 0,
497                 .dst_port_mask = 0, /* Disable */
498                 .src_port = 0,
499                 .src_port_mask = 0, /* Disable */
500                 .proto = IPPROTO_SCTP,
501                 .proto_mask = UINT8_MAX, /* Enable */
502                 .tcp_flags = 0,
503                 .priority = 2, /* Higher priority than IP */
504                 .queue = l1->sctp_local_q,
505         };
506
507         return rte_eth_dev_filter_ctrl(l1->pmd_id,
508                 RTE_ETH_FILTER_NTUPLE,
509                 RTE_ETH_FILTER_ADD,
510                 &filter);
511 }
512
513 static inline int
514 app_link_filter_sctp_del(struct app_link_params *l1, struct app_link_params *l2)
515 {
516         struct rte_eth_ntuple_filter filter = {
517                 .flags = RTE_5TUPLE_FLAGS,
518                 .dst_ip = rte_bswap32(l2->ip),
519                 .dst_ip_mask = UINT32_MAX, /* Enable */
520                 .src_ip = 0,
521                 .src_ip_mask = 0, /* Disable */
522                 .dst_port = 0,
523                 .dst_port_mask = 0, /* Disable */
524                 .src_port = 0,
525                 .src_port_mask = 0, /* Disable */
526                 .proto = IPPROTO_SCTP,
527                 .proto_mask = UINT8_MAX, /* Enable */
528                 .tcp_flags = 0,
529                 .priority = 2, /* Higher priority than IP */
530                 .queue = l1->sctp_local_q,
531         };
532
533         return rte_eth_dev_filter_ctrl(l1->pmd_id,
534                 RTE_ETH_FILTER_NTUPLE,
535                 RTE_ETH_FILTER_DELETE,
536                 &filter);
537 }
538
539 static int
540 app_link_is_virtual(struct app_link_params *p)
541 {
542         uint32_t pmd_id = p->pmd_id;
543         struct rte_eth_dev *dev = &rte_eth_devices[pmd_id];
544
545         if (dev->dev_type == RTE_ETH_DEV_VIRTUAL)
546                 return 1;
547
548         return 0;
549 }
550
551
552 void
553 app_link_up_internal(__rte_unused struct app_params *app,
554                 struct app_link_params *cp)
555 {
556         if(app == NULL || cp == NULL)
557                 printf("NULL Pointers");
558
559         if (app_link_is_virtual(cp)) {
560                 cp->state = 1;
561                 return;
562         }
563
564         ifm_update_linkstatus(cp->pmd_id, IFM_ETH_LINK_UP);
565
566         /* Mark link as UP */
567         cp->state = 1;
568 }
569
570 void
571 app_link_down_internal(__rte_unused struct app_params *app,
572                 struct app_link_params *cp)
573 {
574         if(app == NULL || cp == NULL)
575                 printf("NULL Pointers");
576
577         if (app_link_is_virtual(cp)) {
578                 cp->state = 0;
579                 return;
580         }
581
582         ifm_update_linkstatus(cp->pmd_id, IFM_ETH_LINK_DOWN);
583         /* Mark link as DOWN */
584         cp->state = 0;
585
586 }
587
588 static void
589 app_check_link(struct app_params *app)
590 {
591         uint32_t all_links_up, i;
592
593         all_links_up = 1;
594
595         for (i = 0; i < app->n_links; i++) {
596                 struct app_link_params *p = &app->link_params[i];
597                 struct rte_eth_link link_params;
598
599                 memset(&link_params, 0, sizeof(link_params));
600                 rte_eth_link_get(p->pmd_id, &link_params);
601
602                 APP_LOG(app, HIGH, "%s (%" PRIu32 ") (%" PRIu32 " Gbps) %s",
603                         p->name,
604                         p->pmd_id,
605                         link_params.link_speed / 1000,
606                         link_params.link_status ? "UP" : "DOWN");
607
608                 if (link_params.link_status == ETH_LINK_DOWN)
609                         all_links_up = 0;
610         }
611
612         if (all_links_up == 0)
613                 rte_panic("Some links are DOWN\n");
614 }
615
616 static uint32_t
617 is_any_swq_frag_or_ras(struct app_params *app)
618 {
619         uint32_t i;
620
621         for (i = 0; i < app->n_pktq_swq; i++) {
622                 struct app_pktq_swq_params *p = &app->swq_params[i];
623
624                 if ((p->ipv4_frag == 1) || (p->ipv6_frag == 1) ||
625                         (p->ipv4_ras == 1) || (p->ipv6_ras == 1))
626                         return 1;
627         }
628
629         return 0;
630 }
631
632 static void
633 app_init_link_frag_ras(struct app_params *app)
634 {
635         uint32_t i;
636
637         if (is_any_swq_frag_or_ras(app)) {
638                 for (i = 0; i < app->n_pktq_hwq_out; i++) {
639                         struct app_pktq_hwq_out_params *p_txq =
640                                 &app->hwq_out_params[i];
641
642                         p_txq->conf.txq_flags &= ~ETH_TXQ_FLAGS_NOMULTSEGS;
643                 }
644         }
645 }
646
647 static inline int
648 app_get_cpu_socket_id(uint32_t pmd_id)
649 {
650         int status = rte_eth_dev_socket_id(pmd_id);
651
652         return (status != SOCKET_ID_ANY) ? status : 0;
653 }
654
655 struct rte_eth_rxmode rx_mode = {
656         .max_rx_pkt_len = ETHER_MAX_LEN, /**< Default maximum frame length. */
657         .split_hdr_size = 0,
658         .header_split   = 0, /**< Header Split disabled. */
659         .hw_ip_checksum = 0, /**< IP checksum offload disabled. */
660         .hw_vlan_filter = 1, /**< VLAN filtering enabled. */
661         .hw_vlan_strip  = 1, /**< VLAN strip enabled. */
662         .hw_vlan_extend = 0, /**< Extended VLAN disabled. */
663         .jumbo_frame    = 0, /**< Jumbo Frame Support disabled. */
664         .hw_strip_crc   = 0, /**< CRC stripping by hardware disabled. */
665 };
666 struct rte_fdir_conf fdir_conf = {
667         .mode = RTE_FDIR_MODE_NONE,
668         .pballoc = RTE_FDIR_PBALLOC_64K,
669         .status = RTE_FDIR_REPORT_STATUS,
670         .mask = {
671                 .vlan_tci_mask = 0x0,
672                 .ipv4_mask     = {
673                         .src_ip = 0xFFFFFFFF,
674                         .dst_ip = 0xFFFFFFFF,
675                 },
676                 .ipv6_mask     = {
677                 .src_ip = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
678                 .dst_ip = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
679                 },
680                 .src_port_mask = 0xFFFF,
681                 .dst_port_mask = 0xFFFF,
682                 .mac_addr_byte_mask = 0xFF,
683                 .tunnel_type_mask = 1,
684                 .tunnel_id_mask = 0xFFFFFFFF,
685         },
686         .drop_queue = 127,
687 };
688
689         static void
690 app_init_link(struct app_params *app)
691 {
692         uint32_t i, size;
693
694         app_init_link_frag_ras(app);
695
696         /* Configuring port_config_t structure for interface
697          * manager initialization
698          */
699         size = RTE_CACHE_LINE_ROUNDUP(sizeof(port_config_t));
700         port_config = rte_zmalloc(NULL, (app->n_links * size),
701                         RTE_CACHE_LINE_SIZE);
702         if (port_config == NULL)
703                 rte_panic("port_config is NULL: Memory Allocation failure\n");
704
705         for (i = 0; i < app->n_links; i++) {
706                 struct app_link_params *p_link = &app->link_params[i];
707                 uint32_t link_id, n_hwq_in, n_hwq_out;
708                 int status;
709
710                 status = sscanf(p_link->name, "LINK%" PRIu32, &link_id);
711                 if (status < 0)
712                         rte_panic("%s (%" PRId32 "): "
713                                         "init error (%" PRId32 ")\n",
714                                         p_link->name, link_id, status);
715
716                 n_hwq_in = app_link_get_n_rxq(app, p_link);
717                 n_hwq_out = app_link_get_n_txq(app, p_link);
718
719                 printf("\n\nn_hwq_in %d\n", n_hwq_in);
720                 struct rte_eth_conf *My_local_conf = &p_link->conf;
721                 if (enable_hwlb) {
722                         My_local_conf->rxmode = rx_mode;
723                         My_local_conf->fdir_conf = fdir_conf;
724                         My_local_conf->rxmode.mq_mode = ETH_MQ_RX_RSS;
725                         My_local_conf->rx_adv_conf.rss_conf.rss_key = NULL;
726                         My_local_conf->rx_adv_conf.rss_conf.rss_hf = ETH_RSS_IP
727                                 | ETH_RSS_UDP | ETH_RSS_TCP;
728                 } else {/* disable-rss */
729                         My_local_conf->rx_adv_conf.rss_conf.rss_hf = 0;
730                         /* pkt-filter-mode is perfect */
731                         My_local_conf->fdir_conf.mode = RTE_FDIR_MODE_PERFECT;
732                 }
733
734                 /* Set the hardware CRC stripping to avoid double stripping
735                  * of FCS in VM */
736                 p_link->conf.rxmode.hw_strip_crc = 1;
737
738                 APP_LOG(app, HIGH, "Initializing %s (%" PRIu32") "
739                                 "(%" PRIu32 " RXQ, %" PRIu32 " TXQ) ...",
740                                 p_link->name,
741                                 p_link->pmd_id,
742                                 n_hwq_in,
743                                 n_hwq_out);
744
745                 port_config[i].port_id = p_link->pmd_id;
746                 port_config[i].nrx_queue = n_hwq_in;
747                 port_config[i].ntx_queue = n_hwq_out;
748                 port_config[i].state = 1;
749                 port_config[i].promisc = p_link->promisc;
750                 port_config[i].mempool.pool_size =
751                         app->mempool_params[0].pool_size;
752                 port_config[i].mempool.buffer_size =
753                         app->mempool_params[0].buffer_size;
754                 port_config[i].mempool.cache_size =
755                         app->mempool_params[0].cache_size;
756                 port_config[i].mempool.cpu_socket_id =
757                         app->mempool_params[0].cpu_socket_id;
758                 memcpy(&port_config[i].port_conf, &p_link->conf,
759                                 sizeof(struct rte_eth_conf));
760                 memcpy(&port_config[i].rx_conf, &app->hwq_in_params[0].conf,
761                                 sizeof(struct rte_eth_rxconf));
762                 memcpy(&port_config[i].tx_conf, &app->hwq_out_params[0].conf,
763                                 sizeof(struct rte_eth_txconf));
764
765                 if (app->header_csum_req) {
766                         /* Enable TCP and UDP HW Checksum */
767                         port_config[i].tx_conf.txq_flags &=
768                                 ~(ETH_TXQ_FLAGS_NOXSUMTCP |
769                                                 ETH_TXQ_FLAGS_NOXSUMUDP);
770                 }
771
772                 if (ifm_port_setup(p_link->pmd_id, &port_config[i])) {
773                         printf("Failed to configure port %s - %"PRIu32
774                                ".\n", p_link->name, p_link->pmd_id);
775                         printf("Try again with offload disabled....\n");
776                         port_config[i].tx_conf.txq_flags |= ETH_TXQ_FLAGS_NOOFFLOADS;
777                         if (ifm_port_setup (p_link->pmd_id, &port_config[i]))
778                             rte_panic("Port Setup Failed: %s - %" PRIu32
779                                         "\n", p_link->name, p_link->pmd_id);
780                 }
781
782                 app_link_up_internal(app, p_link);
783         }
784
785         app_check_link(app);
786 }
787
788 static void
789 app_init_swq(struct app_params *app)
790 {
791         uint32_t i;
792
793         for (i = 0; i < app->n_pktq_swq; i++) {
794                 struct app_pktq_swq_params *p = &app->swq_params[i];
795                 unsigned int flags = 0;
796
797                 if (app_swq_get_readers(app, p) == 1)
798                         flags |= RING_F_SC_DEQ;
799                 if (app_swq_get_writers(app, p) == 1)
800                         flags |= RING_F_SP_ENQ;
801
802                 APP_LOG(app, HIGH, "Initializing %s...", p->name);
803                 app->swq[i] = rte_ring_create(
804                                 p->name,
805                                 p->size,
806                                 p->cpu_socket_id,
807                                 flags);
808
809                 if (app->swq[i] == NULL)
810                         rte_panic("%s init error\n", p->name);
811         }
812 }
813
814 static void
815 app_init_tm(struct app_params *app)
816 {
817         uint32_t i;
818
819         for (i = 0; i < app->n_pktq_tm; i++) {
820                 struct app_pktq_tm_params *p_tm = &app->tm_params[i];
821                 struct app_link_params *p_link;
822                 struct rte_eth_link link_eth_params;
823                 struct rte_sched_port *sched;
824                 uint32_t n_subports, subport_id;
825                 int status;
826
827                 p_link = app_get_link_for_tm(app, p_tm);
828                 /* LINK */
829                 rte_eth_link_get(p_link->pmd_id, &link_eth_params);
830
831                 /* TM */
832                 p_tm->sched_port_params.name = p_tm->name;
833                 p_tm->sched_port_params.socket =
834                         app_get_cpu_socket_id(p_link->pmd_id);
835                 p_tm->sched_port_params.rate =
836                         (uint64_t) link_eth_params.link_speed * 1000 * 1000 / 8;
837
838                 APP_LOG(app, HIGH, "Initializing %s ...", p_tm->name);
839                 sched = rte_sched_port_config(&p_tm->sched_port_params);
840                 if (sched == NULL)
841                         rte_panic("%s init error\n", p_tm->name);
842                 app->tm[i] = sched;
843
844                 /* Subport */
845                 n_subports = p_tm->sched_port_params.n_subports_per_port;
846                 for (subport_id = 0; subport_id < n_subports; subport_id++) {
847                         uint32_t n_pipes_per_subport, pipe_id;
848
849                         status = rte_sched_subport_config(sched,
850                                 subport_id,
851                                 &p_tm->sched_subport_params[subport_id]);
852                         if (status)
853                                 rte_panic("%s subport %" PRIu32
854                                         " init error (%" PRId32 ")\n",
855                                         p_tm->name, subport_id, status);
856
857                         /* Pipe */
858                         n_pipes_per_subport =
859                                 p_tm->sched_port_params.n_pipes_per_subport;
860                         for (pipe_id = 0;
861                                 pipe_id < n_pipes_per_subport;
862                                 pipe_id++) {
863                                 int profile_id = p_tm->sched_pipe_to_profile[
864                                         subport_id * APP_MAX_SCHED_PIPES +
865                                         pipe_id];
866
867                                 if (profile_id == -1)
868                                         continue;
869
870                                 status = rte_sched_pipe_config(sched,
871                                         subport_id,
872                                         pipe_id,
873                                         profile_id);
874                                 if (status)
875                                         rte_panic("%s subport %" PRIu32
876                                                 " pipe %" PRIu32
877                                                 " (profile %" PRId32 ") "
878                                                 "init error (% " PRId32 ")\n",
879                                                 p_tm->name, subport_id, pipe_id,
880                                                 profile_id, status);
881                         }
882                 }
883         }
884 }
885
886 static void
887 app_init_msgq(struct app_params *app)
888 {
889         uint32_t i;
890
891         for (i = 0; i < app->n_msgq; i++) {
892                 struct app_msgq_params *p = &app->msgq_params[i];
893
894                 APP_LOG(app, HIGH, "Initializing %s ...", p->name);
895                 app->msgq[i] = rte_ring_create(
896                                 p->name,
897                                 p->size,
898                                 p->cpu_socket_id,
899                                 RING_F_SP_ENQ | RING_F_SC_DEQ);
900
901                 if (app->msgq[i] == NULL)
902                         rte_panic("%s init error\n", p->name);
903         }
904 }
905
906 static void app_pipeline_params_get(struct app_params *app,
907         struct app_pipeline_params *p_in,
908         struct pipeline_params *p_out)
909 {
910         uint32_t i;
911         uint32_t mempool_id;
912
913         snprintf(p_out->name, PIPELINE_NAME_SIZE, "%s", p_in->name);
914
915         p_out->socket_id = (int) p_in->socket_id;
916
917         p_out->log_level = app->log_level;
918
919         /* pktq_in */
920         p_out->n_ports_in = p_in->n_pktq_in;
921         for (i = 0; i < p_in->n_pktq_in; i++) {
922                 struct app_pktq_in_params *in = &p_in->pktq_in[i];
923                 struct pipeline_port_in_params *out = &p_out->port_in[i];
924
925                 switch (in->type) {
926                 case APP_PKTQ_IN_HWQ:
927                 {
928                         struct app_pktq_hwq_in_params *p_hwq_in =
929                                 &app->hwq_in_params[in->id];
930                         struct app_link_params *p_link =
931                                 app_get_link_for_rxq(app, p_hwq_in);
932                         uint32_t rxq_link_id, rxq_queue_id;
933
934                         int status =
935                         sscanf(p_hwq_in->name, "RXQ%" SCNu32 ".%" SCNu32,
936                                 &rxq_link_id,
937                                 &rxq_queue_id);
938                         if (status < 0)
939                                 rte_panic("%s (%" PRId32 "): "
940                                 "init error (%" PRId32 ")\n",
941                                 p_hwq_in->name, rxq_link_id, status);
942
943                         out->type = PIPELINE_PORT_IN_ETHDEV_READER;
944                         out->params.ethdev.port_id = p_link->pmd_id;
945                         out->params.ethdev.queue_id = rxq_queue_id;
946                         out->burst_size = p_hwq_in->burst;
947                         break;
948                 }
949                 case APP_PKTQ_IN_SWQ:
950                 {
951                         struct app_pktq_swq_params *swq_params =
952                                 &app->swq_params[in->id];
953
954                         if ((swq_params->ipv4_frag == 0) &&
955                                 (swq_params->ipv6_frag == 0)) {
956                                 if (app_swq_get_readers(app,
957                                         swq_params) == 1) {
958                                         out->type =
959                                                 PIPELINE_PORT_IN_RING_READER;
960                                         out->params.ring.ring =
961                                                 app->swq[in->id];
962                                         out->burst_size =
963                                                 app->swq_params[in->id].
964                                                         burst_read;
965                                 } else {
966                                 out->type = PIPELINE_PORT_IN_RING_MULTI_READER;
967                                 out->params.ring_multi.ring = app->swq[in->id];
968                                 out->burst_size = swq_params->burst_read;
969                                 }
970                         } else {
971                                 if (swq_params->ipv4_frag == 1) {
972                                 struct rte_port_ring_reader_ipv4_frag_params
973                                         *params =
974                                                 &out->params.ring_ipv4_frag;
975
976                                 out->type =
977                                         PIPELINE_PORT_IN_RING_READER_IPV4_FRAG;
978                                 params->ring = app->swq[in->id];
979                                 params->mtu = swq_params->mtu;
980                                 params->metadata_size =
981                                         swq_params->metadata_size;
982                                 params->pool_direct =
983                                         app->mempool
984                                         [swq_params->mempool_direct_id];
985                                 params->pool_indirect =
986                                         app->mempool
987                                         [swq_params->mempool_indirect_id];
988                                 out->burst_size = swq_params->burst_read;
989                                 } else {
990                                 struct rte_port_ring_reader_ipv6_frag_params
991                                         *params =
992                                                 &out->params.ring_ipv6_frag;
993
994                                 out->type =
995                                         PIPELINE_PORT_IN_RING_READER_IPV6_FRAG;
996                                 params->ring = app->swq[in->id];
997                                 params->mtu = swq_params->mtu;
998                                 params->metadata_size =
999                                         swq_params->metadata_size;
1000                                 params->pool_direct =
1001                                         app->mempool
1002                                         [swq_params->mempool_direct_id];
1003                                 params->pool_indirect =
1004                                         app->mempool
1005                                         [swq_params->mempool_indirect_id];
1006                                 out->burst_size = swq_params->burst_read;
1007                                 }
1008                         }
1009                         break;
1010                 }
1011                 case APP_PKTQ_IN_TM:
1012                         out->type = PIPELINE_PORT_IN_SCHED_READER;
1013                         out->params.sched.sched = app->tm[in->id];
1014                         out->burst_size = app->tm_params[in->id].burst_read;
1015                         break;
1016                 case APP_PKTQ_IN_SOURCE:
1017                         mempool_id = app->source_params[in->id].mempool_id;
1018                         out->type = PIPELINE_PORT_IN_SOURCE;
1019                         out->params.source.mempool = app->mempool[mempool_id];
1020                         out->burst_size = app->source_params[in->id].burst;
1021
1022 #ifdef RTE_NEXT_ABI
1023                         if (app->source_params[in->id].file_name
1024                                 != NULL) {
1025                                 out->params.source.file_name = strdup(
1026                                         app->source_params[in->id].
1027                                         file_name);
1028                                 if (out->params.source.file_name == NULL) {
1029                                         out->params.source.
1030                                                 n_bytes_per_pkt = 0;
1031                                         break;
1032                                 }
1033                                 out->params.source.n_bytes_per_pkt =
1034                                         app->source_params[in->id].
1035                                         n_bytes_per_pkt;
1036                         }
1037 #endif
1038
1039                         break;
1040                 default:
1041                         break;
1042                 }
1043         }
1044
1045         /* pktq_out */
1046         p_out->n_ports_out = p_in->n_pktq_out;
1047         for (i = 0; i < p_in->n_pktq_out; i++) {
1048                 struct app_pktq_out_params *in = &p_in->pktq_out[i];
1049                 struct pipeline_port_out_params *out = &p_out->port_out[i];
1050
1051                 switch (in->type) {
1052                 case APP_PKTQ_OUT_HWQ:
1053                 {
1054                         struct app_pktq_hwq_out_params *p_hwq_out =
1055                                 &app->hwq_out_params[in->id];
1056                         struct app_link_params *p_link =
1057                                 app_get_link_for_txq(app, p_hwq_out);
1058                         uint32_t txq_link_id, txq_queue_id;
1059
1060                         int status =
1061                         sscanf(p_hwq_out->name,
1062                                 "TXQ%" SCNu32 ".%" SCNu32,
1063                                 &txq_link_id,
1064                                 &txq_queue_id);
1065                         if (status < 0)
1066                                 rte_panic("%s (%" PRId32 "): "
1067                                 "init error (%" PRId32 ")\n",
1068                                 p_hwq_out->name, txq_link_id, status);
1069
1070                         if (p_hwq_out->dropless == 0) {
1071                                 struct rte_port_ethdev_writer_params *params =
1072                                         &out->params.ethdev;
1073
1074                                 out->type = PIPELINE_PORT_OUT_ETHDEV_WRITER;
1075                                 params->port_id = p_link->pmd_id;
1076                                 params->queue_id = txq_queue_id;
1077                                 params->tx_burst_sz =
1078                                         app->hwq_out_params[in->id].burst;
1079                         } else {
1080                                 struct rte_port_ethdev_writer_nodrop_params
1081                                         *params = &out->params.ethdev_nodrop;
1082
1083                                 out->type =
1084                                         PIPELINE_PORT_OUT_ETHDEV_WRITER_NODROP;
1085                                 params->port_id = p_link->pmd_id;
1086                                 params->queue_id = txq_queue_id;
1087                                 params->tx_burst_sz = p_hwq_out->burst;
1088                                 params->n_retries = p_hwq_out->n_retries;
1089                         }
1090                         break;
1091                 }
1092                 case APP_PKTQ_OUT_SWQ:
1093                 {
1094                 struct app_pktq_swq_params *swq_params =
1095                         &app->swq_params[in->id];
1096
1097                 if ((swq_params->ipv4_ras == 0) &&
1098                         (swq_params->ipv6_ras == 0)) {
1099                         if (app_swq_get_writers(app, swq_params) == 1) {
1100                                 if (app->swq_params[in->id].dropless == 0) {
1101                                         struct rte_port_ring_writer_params
1102                                                 *params = &out->params.ring;
1103
1104                                 out->type = PIPELINE_PORT_OUT_RING_WRITER;
1105                                 params->ring = app->swq[in->id];
1106                                 params->tx_burst_sz =
1107                                         app->swq_params[in->id].burst_write;
1108                                 } else {
1109                                 struct rte_port_ring_writer_nodrop_params
1110                                         *params = &out->params.ring_nodrop;
1111
1112                                 out->type =
1113                                         PIPELINE_PORT_OUT_RING_WRITER_NODROP;
1114                                 params->ring = app->swq[in->id];
1115                                 params->tx_burst_sz =
1116                                         app->swq_params[in->id].burst_write;
1117                                 params->n_retries =
1118                                 app->swq_params[in->id].n_retries;
1119                                 }
1120                         } else {
1121                                 if (swq_params->dropless == 0) {
1122                                         struct rte_port_ring_multi_writer_params
1123                                                 *params =
1124                                                 &out->params.ring_multi;
1125
1126                                 out->type =
1127                                         PIPELINE_PORT_OUT_RING_MULTI_WRITER;
1128                                 params->ring = app->swq[in->id];
1129                                 params->tx_burst_sz = swq_params->burst_write;
1130                                 } else {
1131                                 struct rte_port_ring_multi_writer_nodrop_params
1132                                         *params =
1133                                                 &out->params.ring_multi_nodrop;
1134
1135                                 out->type =
1136                                 PIPELINE_PORT_OUT_RING_MULTI_WRITER_NODROP;
1137
1138                                 params->ring = app->swq[in->id];
1139                                 params->tx_burst_sz = swq_params->burst_write;
1140                                 params->n_retries = swq_params->n_retries;
1141                                 }
1142                                 }
1143                         } else {
1144                         if (swq_params->ipv4_ras == 1) {
1145                                 struct rte_port_ring_writer_ipv4_ras_params
1146                                         *params =
1147                                                 &out->params.ring_ipv4_ras;
1148
1149                                 out->type =
1150                                         PIPELINE_PORT_OUT_RING_WRITER_IPV4_RAS;
1151                                 params->ring = app->swq[in->id];
1152                                 params->tx_burst_sz = swq_params->burst_write;
1153                         } else {
1154                                 struct rte_port_ring_writer_ipv6_ras_params
1155                                         *params =
1156                                                 &out->params.ring_ipv6_ras;
1157
1158                                 out->type =
1159                                         PIPELINE_PORT_OUT_RING_WRITER_IPV6_RAS;
1160                                 params->ring = app->swq[in->id];
1161                                 params->tx_burst_sz = swq_params->burst_write;
1162                         }
1163                         }
1164                         break;
1165                 }
1166                 case APP_PKTQ_OUT_TM: {
1167                         struct rte_port_sched_writer_params *params =
1168                                 &out->params.sched;
1169
1170                         out->type = PIPELINE_PORT_OUT_SCHED_WRITER;
1171                         params->sched = app->tm[in->id];
1172                         params->tx_burst_sz =
1173                                 app->tm_params[in->id].burst_write;
1174                         break;
1175                 }
1176                 case APP_PKTQ_OUT_SINK:
1177                         out->type = PIPELINE_PORT_OUT_SINK;
1178                         if (app->sink_params[in->id].file_name != NULL) {
1179                                 out->params.sink.file_name = strdup(
1180                                         app->sink_params[in->id].
1181                                         file_name);
1182                                 if (out->params.sink.file_name == NULL) {
1183                                         out->params.sink.max_n_pkts = 0;
1184                                         break;
1185                                 }
1186                                 out->params.sink.max_n_pkts =
1187                                         app->sink_params[in->id].
1188                                         n_pkts_to_dump;
1189                         } else {
1190                                 out->params.sink.file_name = NULL;
1191                                 out->params.sink.max_n_pkts = 0;
1192                         }
1193                         break;
1194                 default:
1195                         break;
1196                 }
1197         }
1198
1199         /* msgq */
1200         p_out->n_msgq = p_in->n_msgq_in;
1201
1202         for (i = 0; i < p_in->n_msgq_in; i++)
1203                 p_out->msgq_in[i] = app->msgq[p_in->msgq_in[i]];
1204
1205         for (i = 0; i < p_in->n_msgq_out; i++)
1206                 p_out->msgq_out[i] = app->msgq[p_in->msgq_out[i]];
1207
1208         /* args */
1209         p_out->n_args = p_in->n_args;
1210         for (i = 0; i < p_in->n_args; i++) {
1211                 p_out->args_name[i] = p_in->args_name[i];
1212                 p_out->args_value[i] = p_in->args_value[i];
1213         }
1214 }
1215
1216 static void
1217 app_init_pipelines(struct app_params *app)
1218 {
1219         uint32_t p_id;
1220
1221         for (p_id = 0; p_id < app->n_pipelines; p_id++) {
1222                 struct app_pipeline_params *params =
1223                         &app->pipeline_params[p_id];
1224                 struct app_pipeline_data *data = &app->pipeline_data[p_id];
1225                 struct pipeline_type *ptype;
1226                 struct pipeline_params pp;
1227
1228                 APP_LOG(app, HIGH, "Initializing %s ...", params->name);
1229
1230                 ptype = app_pipeline_type_find(app, params->type);
1231                 if (ptype == NULL)
1232                         rte_panic("Init error: Unknown pipeline type \"%s\"\n",
1233                                 params->type);
1234
1235                 app_pipeline_params_get(app, params, &pp);
1236
1237                 /* Back-end */
1238                 data->be = NULL;
1239                 if (ptype->be_ops->f_init) {
1240                         data->be = ptype->be_ops->f_init(&pp, (void *) app);
1241
1242                         if (data->be == NULL)
1243                                 rte_panic("Pipeline instance \"%s\" back-end "
1244                                         "init error\n", params->name);
1245                 }
1246
1247                 /* Front-end */
1248                 data->fe = NULL;
1249                 if (ptype->fe_ops->f_init) {
1250                         data->fe = ptype->fe_ops->f_init(&pp, (void *) app);
1251
1252                         if (data->fe == NULL)
1253                                 rte_panic("Pipeline instance \"%s\" front-end "
1254                                 "init error\n", params->name);
1255                 }
1256
1257                 data->ptype = ptype;
1258
1259                 data->timer_period = (rte_get_tsc_hz() *
1260                         params->timer_period) / 100;
1261         }
1262 }
1263
1264 static void
1265 app_init_threads(struct app_params *app)
1266 {
1267         uint64_t time = rte_get_tsc_cycles();
1268         uint32_t p_id;
1269
1270         for (p_id = 0; p_id < app->n_pipelines; p_id++) {
1271                 struct app_pipeline_params *params =
1272                         &app->pipeline_params[p_id];
1273                 struct app_pipeline_data *data = &app->pipeline_data[p_id];
1274                 struct pipeline_type *ptype;
1275                 struct app_thread_data *t;
1276                 struct app_thread_pipeline_data *p;
1277                 int lcore_id;
1278
1279                 lcore_id = cpu_core_map_get_lcore_id(app->core_map,
1280                         params->socket_id,
1281                         params->core_id,
1282                         params->hyper_th_id);
1283
1284                 if (lcore_id < 0)
1285                         rte_panic("Invalid core s%" PRIu32 "c%" PRIu32 "%s\n",
1286                                 params->socket_id,
1287                                 params->core_id,
1288                                 (params->hyper_th_id) ? "h" : "");
1289
1290                 t = &app->thread_data[lcore_id];
1291
1292                 t->timer_period = (rte_get_tsc_hz() *
1293                         APP_THREAD_TIMER_PERIOD) / DIV_CONV_HZ_SEC;
1294                 t->thread_req_deadline = time + t->timer_period;
1295
1296                 t->headroom_cycles = 0;
1297                 t->headroom_time = rte_get_tsc_cycles();
1298                 t->headroom_ratio = 0.0;
1299
1300                 t->msgq_in = app_thread_msgq_in_get(app,
1301                                 params->socket_id,
1302                                 params->core_id,
1303                                 params->hyper_th_id);
1304                 if (t->msgq_in == NULL)
1305                         rte_panic("Init error: Cannot find MSGQ_IN "
1306                                 "for thread %" PRId32, lcore_id);
1307
1308                 t->msgq_out = app_thread_msgq_out_get(app,
1309                                 params->socket_id,
1310                                 params->core_id,
1311                                 params->hyper_th_id);
1312                 if (t->msgq_out == NULL)
1313                         rte_panic("Init error: Cannot find MSGQ_OUT "
1314                                 "for thread %" PRId32, lcore_id);
1315
1316                 ptype = app_pipeline_type_find(app, params->type);
1317                 if (ptype == NULL)
1318                         rte_panic("Init error: Unknown pipeline "
1319                                 "type \"%s\"\n", params->type);
1320
1321                 p = (ptype->be_ops->f_run == NULL) ?
1322                         &t->regular[t->n_regular] :
1323                         &t->custom[t->n_custom];
1324
1325                 p->pipeline_id = p_id;
1326                 p->be = data->be;
1327                 p->f_run = ptype->be_ops->f_run;
1328                 p->f_timer = ptype->be_ops->f_timer;
1329                 p->timer_period = data->timer_period;
1330                 p->deadline = time + data->timer_period;
1331
1332                 data->enabled = 1;
1333
1334                 if (ptype->be_ops->f_run == NULL)
1335                         t->n_regular++;
1336                 else
1337                         t->n_custom++;
1338         }
1339 }
1340
1341 int app_init(struct app_params *app)
1342 {
1343         app_init_core_map(app);
1344         app_init_core_mask(app);
1345
1346         app_init_eal(app);
1347         ifm_init();
1348         /*app_init_mempool(app);*/
1349         app_init_link(app);
1350         app_init_swq(app);
1351         app_init_tm(app);
1352         app_init_msgq(app);
1353
1354         app_pipeline_common_cmd_push(app);
1355         app_pipeline_thread_cmd_push(app);
1356         app_pipeline_type_register(app, &pipeline_master);
1357         app_pipeline_type_register(app, &pipeline_passthrough);
1358         app_pipeline_type_register(app, &pipeline_vfw);
1359         app_pipeline_type_register(app, &pipeline_loadb);
1360         app_pipeline_type_register(app, &pipeline_txrx);
1361         app_pipeline_type_register(app, &pipeline_arpicmp);
1362
1363         app_init_pipelines(app);
1364         app_init_threads(app);
1365
1366         l3fwd_init();
1367         create_arp_table();
1368         create_nd_table();
1369         populate_lpm_routes();
1370         print_interface_details();
1371
1372         return 0;
1373 }
1374
1375 static int
1376 app_pipeline_type_cmd_push(struct app_params *app,
1377         struct pipeline_type *ptype)
1378 {
1379         cmdline_parse_ctx_t *cmds;
1380         uint32_t n_cmds, i;
1381
1382         /* Check input arguments */
1383         if ((app == NULL) ||
1384                 (ptype == NULL))
1385                 return -EINVAL;
1386
1387         n_cmds = pipeline_type_cmds_count(ptype);
1388         if (n_cmds == 0)
1389                 return 0;
1390
1391         cmds = ptype->fe_ops->cmds;
1392
1393         /* Check for available slots in the application commands array */
1394         if (n_cmds > APP_MAX_CMDS - app->n_cmds)
1395                 return -ENOMEM;
1396
1397         /* Push pipeline commands into the application */
1398         memcpy(&app->cmds[app->n_cmds],
1399                 cmds,
1400                 n_cmds * sizeof(cmdline_parse_ctx_t));
1401
1402         for (i = 0; i < n_cmds; i++)
1403                 app->cmds[app->n_cmds + i]->data = app;
1404
1405         app->n_cmds += n_cmds;
1406         app->cmds[app->n_cmds] = NULL;
1407
1408         return 0;
1409 }
1410
1411 int
1412 app_pipeline_type_register(struct app_params *app, struct pipeline_type *ptype)
1413 {
1414         uint32_t n_cmds, i;
1415
1416         /* Check input arguments */
1417         if ((app == NULL) ||
1418                 (ptype == NULL) ||
1419                 (ptype->name == NULL) ||
1420                 (strlen(ptype->name) == 0) ||
1421                 (ptype->be_ops->f_init == NULL) ||
1422                 (ptype->be_ops->f_timer == NULL))
1423                 return -EINVAL;
1424
1425         /* Check for duplicate entry */
1426         for (i = 0; i < app->n_pipeline_types; i++)
1427                 if (strcmp(app->pipeline_type[i].name, ptype->name) == 0)
1428                         return -EEXIST;
1429
1430         /* Check for resource availability */
1431         n_cmds = pipeline_type_cmds_count(ptype);
1432         if ((app->n_pipeline_types == APP_MAX_PIPELINE_TYPES) ||
1433                 (n_cmds > APP_MAX_CMDS - app->n_cmds))
1434                 return -ENOMEM;
1435
1436         /* Copy pipeline type */
1437         memcpy(&app->pipeline_type[app->n_pipeline_types++],
1438                 ptype,
1439                 sizeof(struct pipeline_type));
1440
1441         /* Copy CLI commands */
1442         if (n_cmds)
1443                 app_pipeline_type_cmd_push(app, ptype);
1444
1445         return 0;
1446 }
1447
1448 struct
1449 pipeline_type *app_pipeline_type_find(struct app_params *app, char *name)
1450 {
1451         uint32_t i;
1452
1453         for (i = 0; i < app->n_pipeline_types; i++)
1454                 if (strcmp(app->pipeline_type[i].name, name) == 0)
1455                         return &app->pipeline_type[i];
1456
1457         return NULL;
1458 }