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