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