xref: /f-stack/lib/ff_config.c (revision e6804bae)
1a9643ea8Slogwang /*
22317ada5Sfengbojiang  * Copyright (C) 2017-2021 THL A29 Limited, a Tencent company.
3a9643ea8Slogwang  * All rights reserved.
4a9643ea8Slogwang  *
5a9643ea8Slogwang  * Redistribution and use in source and binary forms, with or without
6a9643ea8Slogwang  * modification, are permitted provided that the following conditions are met:
7a9643ea8Slogwang  *
8a9643ea8Slogwang  * 1. Redistributions of source code must retain the above copyright notice, this
9a9643ea8Slogwang  *   list of conditions and the following disclaimer.
10a9643ea8Slogwang  * 2. Redistributions in binary form must reproduce the above copyright notice,
11a9643ea8Slogwang  *   this list of conditions and the following disclaimer in the documentation
12a9643ea8Slogwang  *   and/or other materials provided with the distribution.
13a9643ea8Slogwang  *
14a9643ea8Slogwang  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
15a9643ea8Slogwang  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16a9643ea8Slogwang  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17a9643ea8Slogwang  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
18a9643ea8Slogwang  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19a9643ea8Slogwang  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
20a9643ea8Slogwang  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21a9643ea8Slogwang  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22a9643ea8Slogwang  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
23a9643ea8Slogwang  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24a9643ea8Slogwang  *
25a9643ea8Slogwang  */
26a9643ea8Slogwang 
27a9643ea8Slogwang #include <string.h>
28a9643ea8Slogwang #include <stdio.h>
29a9643ea8Slogwang #include <stdlib.h>
30a9643ea8Slogwang #include <stdint.h>
31a9643ea8Slogwang #include <getopt.h>
32a02c88d6Slogwang #include <ctype.h>
33a02c88d6Slogwang #include <rte_config.h>
3480a6164cSYuYang #include <rte_string_fns.h>
35a02c88d6Slogwang 
36a9643ea8Slogwang #include "ff_config.h"
37a9643ea8Slogwang #include "ff_ini_parser.h"
38a9643ea8Slogwang 
39a02c88d6Slogwang #define DEFAULT_CONFIG_FILE   "config.ini"
40a02c88d6Slogwang 
41a02c88d6Slogwang #define BITS_PER_HEX 4
42a02c88d6Slogwang 
43a9643ea8Slogwang struct ff_config ff_global_cfg;
44a9643ea8Slogwang int dpdk_argc;
45a9643ea8Slogwang char *dpdk_argv[DPDK_CONFIG_NUM + 1];
46a9643ea8Slogwang 
47a02c88d6Slogwang char* const short_options = "c:t:p:";
48a9643ea8Slogwang struct option long_options[] = {
49a02c88d6Slogwang     { "conf", 1, NULL, 'c'},
50a02c88d6Slogwang     { "proc-type", 1, NULL, 't'},
51a02c88d6Slogwang     { "proc-id", 1, NULL, 'p'},
52a9643ea8Slogwang     { 0, 0, 0, 0},
53a9643ea8Slogwang };
54a9643ea8Slogwang 
55a9643ea8Slogwang static int
xdigit2val(unsigned char c)56a02c88d6Slogwang xdigit2val(unsigned char c)
57a02c88d6Slogwang {
58a02c88d6Slogwang     int val;
59a02c88d6Slogwang 
60a02c88d6Slogwang     if (isdigit(c))
61a02c88d6Slogwang         val = c - '0';
62a02c88d6Slogwang     else if (isupper(c))
63a02c88d6Slogwang         val = c - 'A' + 10;
64a02c88d6Slogwang     else
65a02c88d6Slogwang         val = c - 'a' + 10;
66a02c88d6Slogwang     return val;
67a02c88d6Slogwang }
68a02c88d6Slogwang 
69a02c88d6Slogwang static int
parse_lcore_mask(struct ff_config * cfg,const char * coremask)70a02c88d6Slogwang parse_lcore_mask(struct ff_config *cfg, const char *coremask)
71a02c88d6Slogwang {
72813e23e2Sbeard-627     int i, j, idx = 0, shift = 0, zero_num = 0;
73a02c88d6Slogwang     unsigned count = 0;
74a02c88d6Slogwang     char c;
75a02c88d6Slogwang     int val;
76a02c88d6Slogwang     uint16_t *proc_lcore;
77a02c88d6Slogwang     char buf[RTE_MAX_LCORE] = {0};
78813e23e2Sbeard-627     char zero[RTE_MAX_LCORE] = {0};
79a02c88d6Slogwang 
80a02c88d6Slogwang     if (coremask == NULL)
81a02c88d6Slogwang         return 0;
82a02c88d6Slogwang 
83a02c88d6Slogwang     cfg->dpdk.proc_lcore = (uint16_t *)calloc(RTE_MAX_LCORE, sizeof(uint16_t));
84a02c88d6Slogwang     if (cfg->dpdk.proc_lcore == NULL) {
85a02c88d6Slogwang         fprintf(stderr, "parse_lcore_mask malloc failed\n");
86a02c88d6Slogwang         return 0;
87a02c88d6Slogwang     }
88a02c88d6Slogwang     proc_lcore = cfg->dpdk.proc_lcore;
89a02c88d6Slogwang 
90a02c88d6Slogwang     /*
91a02c88d6Slogwang      * Remove all blank characters ahead and after.
92a02c88d6Slogwang      * Remove 0x/0X if exists.
93a02c88d6Slogwang      */
94a02c88d6Slogwang     while (isblank(*coremask))
95a02c88d6Slogwang         coremask++;
96a02c88d6Slogwang     if (coremask[0] == '0' && ((coremask[1] == 'x')
97a02c88d6Slogwang         || (coremask[1] == 'X')))
98a02c88d6Slogwang         coremask += 2;
99a02c88d6Slogwang 
100a02c88d6Slogwang     i = strlen(coremask);
101a02c88d6Slogwang     while ((i > 0) && isblank(coremask[i - 1]))
102a02c88d6Slogwang         i--;
103a02c88d6Slogwang 
104a02c88d6Slogwang     if (i == 0)
105a02c88d6Slogwang         return 0;
106a02c88d6Slogwang 
107a02c88d6Slogwang     for (i = i - 1; i >= 0 && idx < RTE_MAX_LCORE; i--) {
108a02c88d6Slogwang         c = coremask[i];
109a02c88d6Slogwang         if (isxdigit(c) == 0) {
110a02c88d6Slogwang             return 0;
111a02c88d6Slogwang         }
112a02c88d6Slogwang         val = xdigit2val(c);
113a02c88d6Slogwang         for (j = 0; j < BITS_PER_HEX && idx < RTE_MAX_LCORE; j++, idx++) {
114a02c88d6Slogwang             if ((1 << j) & val) {
115a02c88d6Slogwang                 proc_lcore[count] = idx;
116a02c88d6Slogwang                 if (cfg->dpdk.proc_id == count) {
117813e23e2Sbeard-627                     zero_num = idx >> 2;
118813e23e2Sbeard-627                     shift = idx & 0x3;
119813e23e2Sbeard-627                     memset(zero,'0',zero_num);
120b8b4b7b9Sfengbojiang(姜凤波)                     snprintf(buf, sizeof(buf) - 1, "%llx%s",
121b8b4b7b9Sfengbojiang(姜凤波)                         (unsigned long long)1<<shift, zero);
122a02c88d6Slogwang                     cfg->dpdk.proc_mask = strdup(buf);
123a02c88d6Slogwang 		}
124a02c88d6Slogwang                 count++;
125a02c88d6Slogwang             }
126a02c88d6Slogwang         }
127a02c88d6Slogwang     }
128a02c88d6Slogwang 
129a02c88d6Slogwang     for (; i >= 0; i--)
130a02c88d6Slogwang         if (coremask[i] != '0')
131a02c88d6Slogwang             return 0;
132a02c88d6Slogwang 
133a02c88d6Slogwang     if (cfg->dpdk.proc_id >= count)
134a02c88d6Slogwang         return 0;
135a02c88d6Slogwang 
136a02c88d6Slogwang     cfg->dpdk.nb_procs = count;
137a02c88d6Slogwang 
138a02c88d6Slogwang     return 1;
139a02c88d6Slogwang }
140a02c88d6Slogwang 
141a02c88d6Slogwang static int
is_integer(const char * s)142a9643ea8Slogwang is_integer(const char *s)
143a9643ea8Slogwang {
144a9643ea8Slogwang     if (*s == '-' || *s == '+')
145a9643ea8Slogwang         s++;
146a9643ea8Slogwang     if (*s < '0' || '9' < *s)
147a9643ea8Slogwang         return 0;
148a9643ea8Slogwang     s++;
149a9643ea8Slogwang     while ('0' <= *s && *s <= '9')
150a9643ea8Slogwang         s++;
151a9643ea8Slogwang     return (*s == '\0');
152a9643ea8Slogwang }
153a9643ea8Slogwang 
154a9643ea8Slogwang static int
freebsd_conf_handler(struct ff_config * cfg,const char * section,const char * name,const char * value)155a9643ea8Slogwang freebsd_conf_handler(struct ff_config *cfg, const char *section,
156a9643ea8Slogwang     const char *name, const char *value)
157a9643ea8Slogwang {
158a9643ea8Slogwang     struct ff_freebsd_cfg *newconf, **cur;
159a9643ea8Slogwang     newconf = (struct ff_freebsd_cfg *)malloc(sizeof(struct ff_freebsd_cfg));
160a9643ea8Slogwang     if (newconf == NULL) {
161a9643ea8Slogwang         fprintf(stderr, "freebsd conf malloc failed\n");
162a9643ea8Slogwang         return 0;
163a9643ea8Slogwang     }
164a9643ea8Slogwang 
165a9643ea8Slogwang     newconf->name = strdup(name);
166a9643ea8Slogwang     newconf->str = strdup(value);
167a9643ea8Slogwang 
168a9643ea8Slogwang     if (strcmp(section, "boot") == 0) {
169a9643ea8Slogwang         cur = &cfg->freebsd.boot;
170a9643ea8Slogwang 
171a9643ea8Slogwang         newconf->value = (void *)newconf->str;
172a9643ea8Slogwang         newconf->vlen = strlen(value);
173a9643ea8Slogwang     } else if (strcmp(section, "sysctl") == 0) {
174a9643ea8Slogwang         cur = &cfg->freebsd.sysctl;
175a9643ea8Slogwang 
176a9643ea8Slogwang         if (is_integer(value)) {
1778755b2deSlogwang             if (strcmp(name, "kern.ipc.maxsockbuf") == 0) {
1788755b2deSlogwang                 long *p = (long *)malloc(sizeof(long));
1798755b2deSlogwang                 *p = atol(value);
1808755b2deSlogwang                 newconf->value = (void *)p;
1818755b2deSlogwang                 newconf->vlen = sizeof(*p);
1828755b2deSlogwang             } else {
183a9643ea8Slogwang                  int *p = (int *)malloc(sizeof(int));
184a9643ea8Slogwang                  *p = atoi(value);
185a9643ea8Slogwang                  newconf->value = (void *)p;
186a9643ea8Slogwang                  newconf->vlen = sizeof(*p);
1878755b2deSlogwang             }
188a9643ea8Slogwang         } else {
189a9643ea8Slogwang             newconf->value = (void *)newconf->str;
190a9643ea8Slogwang             newconf->vlen = strlen(value);
191a9643ea8Slogwang         }
192a9643ea8Slogwang     } else {
193a9643ea8Slogwang         fprintf(stderr, "freebsd conf section[%s] error\n", section);
194*e6804baeSBjörn Svensson         free(newconf);
195a9643ea8Slogwang         return 0;
196a9643ea8Slogwang     }
197a9643ea8Slogwang 
198a9643ea8Slogwang     if (*cur == NULL) {
1998755b2deSlogwang         newconf->next = NULL;
200a9643ea8Slogwang         *cur = newconf;
201a9643ea8Slogwang     } else {
2028755b2deSlogwang         newconf->next = (*cur)->next;
203a9643ea8Slogwang         (*cur)->next = newconf;
204a9643ea8Slogwang     }
205a9643ea8Slogwang 
206a9643ea8Slogwang     return 1;
207a9643ea8Slogwang }
20880a6164cSYuYang // A recursive binary search function. It returns location of x in
20980a6164cSYuYang // given array arr[l..r] is present, otherwise -1
21080a6164cSYuYang static int
uint16_binary_search(uint16_t arr[],int l,int r,uint16_t x)21180a6164cSYuYang uint16_binary_search(uint16_t arr[], int l, int r, uint16_t x)
21280a6164cSYuYang {
21380a6164cSYuYang     if (r >= l) {
21480a6164cSYuYang         int mid = l + (r - l)/2;
21580a6164cSYuYang 
21680a6164cSYuYang         // If the element is present at the middle itself
21780a6164cSYuYang         if (arr[mid] == x)  return mid;
21880a6164cSYuYang 
21980a6164cSYuYang         // If element is smaller than mid, then it can only be present
22080a6164cSYuYang         // in left subarray
22180a6164cSYuYang         if (arr[mid] > x) return uint16_binary_search(arr, l, mid-1, x);
22280a6164cSYuYang 
22380a6164cSYuYang         // Else the element can only be present in right subarray
22480a6164cSYuYang         return uint16_binary_search(arr, mid+1, r, x);
22580a6164cSYuYang     }
22680a6164cSYuYang 
22780a6164cSYuYang     // We reach here when element is not present in array
22880a6164cSYuYang     return -1;
22980a6164cSYuYang }
23080a6164cSYuYang 
23180a6164cSYuYang static int
uint16_cmp(const void * a,const void * b)23280a6164cSYuYang uint16_cmp (const void * a, const void * b)
23380a6164cSYuYang {
23480a6164cSYuYang     return ( *(uint16_t*)a - *(uint16_t*)b );
23580a6164cSYuYang }
23680a6164cSYuYang 
23780a6164cSYuYang static inline void
sort_uint16_array(uint16_t arr[],int n)23880a6164cSYuYang sort_uint16_array(uint16_t arr[], int n)
23980a6164cSYuYang {
24080a6164cSYuYang     qsort(arr, n, sizeof(uint16_t), uint16_cmp);
24180a6164cSYuYang }
24280a6164cSYuYang 
24380a6164cSYuYang static inline char *
__strstrip(char * s)24480a6164cSYuYang __strstrip(char *s)
24580a6164cSYuYang {
24680a6164cSYuYang     char *end = s + strlen(s) - 1;
24780a6164cSYuYang     while(*s == ' ') s++;
24880a6164cSYuYang     for (; end >= s; --end) {
24980a6164cSYuYang         if (*end != ' ') break;
25080a6164cSYuYang     }
25180a6164cSYuYang     *(++end) = '\0';
25280a6164cSYuYang     return s;
25380a6164cSYuYang }
25480a6164cSYuYang 
25580a6164cSYuYang static int
__parse_config_list(uint16_t * arr,int * sz,const char * value)25680a6164cSYuYang __parse_config_list(uint16_t *arr, int *sz, const char *value) {
25780a6164cSYuYang     int i, j;
25880a6164cSYuYang     char input[4096];
25980a6164cSYuYang     char *tokens[128];
26080a6164cSYuYang     int nTokens = 0;
26180a6164cSYuYang     char *endptr;
26280a6164cSYuYang     int nr_ele = 0;
26380a6164cSYuYang     int max_ele = *sz;
26480a6164cSYuYang 
265b8b4b7b9Sfengbojiang(姜凤波)     strncpy(input, value, sizeof(input) - 1);
26680a6164cSYuYang     nTokens = rte_strsplit(input, sizeof(input), tokens, 128, ',');
26780a6164cSYuYang     for (i = 0; i < nTokens; i++) {
26880a6164cSYuYang         char *tok = tokens[i];
26980a6164cSYuYang         char *middle = strchr(tok, '-');
27080a6164cSYuYang         if (middle == NULL) {
27180a6164cSYuYang             tok = __strstrip(tok);
27280a6164cSYuYang             long v = strtol(tok, &endptr, 10);
27380a6164cSYuYang             if (*endptr != '\0') {
27480a6164cSYuYang                 fprintf(stderr, "%s is not a integer.", tok);
27580a6164cSYuYang                 return 0;
27680a6164cSYuYang             }
27780a6164cSYuYang             if (nr_ele > max_ele) {
27880a6164cSYuYang                 fprintf(stderr, "too many elements in list %s\n", value);
27980a6164cSYuYang                 return 0;
28080a6164cSYuYang             }
28180a6164cSYuYang             arr[nr_ele++] = (uint16_t)v;
28280a6164cSYuYang         } else {
28380a6164cSYuYang             *middle = '\0';
28480a6164cSYuYang             char *lbound = __strstrip(tok);
28580a6164cSYuYang             char *rbound = __strstrip(middle+1);
28680a6164cSYuYang             long lv = strtol(lbound, &endptr, 10);
28780a6164cSYuYang             if (*endptr != '\0') {
28880a6164cSYuYang                 fprintf(stderr, "%s is not a integer.", lbound);
28980a6164cSYuYang                 return 0;
29080a6164cSYuYang             }
29180a6164cSYuYang             long rv = strtol(rbound, &endptr, 10);
29280a6164cSYuYang             if (*endptr != '\0') {
29380a6164cSYuYang                 fprintf(stderr, "%s is not a integer.", rbound);
29480a6164cSYuYang                 return 0;
29580a6164cSYuYang             }
29680a6164cSYuYang             for (j = lv; j <= rv; ++j) {
29780a6164cSYuYang                 if (nr_ele > max_ele) {
29880a6164cSYuYang                     fprintf(stderr, "too many elements in list %s.\n", value);
29980a6164cSYuYang                     return 0;
30080a6164cSYuYang                 }
30180a6164cSYuYang                 arr[nr_ele++] = (uint16_t)j;
30280a6164cSYuYang             }
30380a6164cSYuYang         }
30480a6164cSYuYang     }
30580a6164cSYuYang     if (nr_ele <= 0) {
306c506e436Sfengbojiang         fprintf(stderr, "list %s is empty\n", value);
30780a6164cSYuYang         return 1;
30880a6164cSYuYang     }
30980a6164cSYuYang     sort_uint16_array(arr, nr_ele);
31080a6164cSYuYang     *sz = nr_ele;
31180a6164cSYuYang     return 1;
31280a6164cSYuYang }
31380a6164cSYuYang 
31480a6164cSYuYang static int
parse_port_lcore_list(struct ff_port_cfg * cfg,const char * v_str)31580a6164cSYuYang parse_port_lcore_list(struct ff_port_cfg *cfg, const char *v_str)
31680a6164cSYuYang {
31780a6164cSYuYang     cfg->nb_lcores = DPDK_MAX_LCORE;
31880a6164cSYuYang     uint16_t *cores = cfg->lcore_list;
31980a6164cSYuYang     return __parse_config_list(cores, &cfg->nb_lcores, v_str);
32080a6164cSYuYang }
32180a6164cSYuYang 
32280a6164cSYuYang static int
parse_port_list(struct ff_config * cfg,const char * v_str)32380a6164cSYuYang parse_port_list(struct ff_config *cfg, const char *v_str)
32480a6164cSYuYang {
32580a6164cSYuYang     int res;
32680a6164cSYuYang     uint16_t ports[RTE_MAX_ETHPORTS];
32780a6164cSYuYang     int sz = RTE_MAX_ETHPORTS;
32880a6164cSYuYang 
32980a6164cSYuYang     res = __parse_config_list(ports, &sz, v_str);
33080a6164cSYuYang     if (! res) return res;
33180a6164cSYuYang 
33280a6164cSYuYang     uint16_t *portid_list = malloc(sizeof(uint16_t)*sz);
33380a6164cSYuYang 
33480a6164cSYuYang     if (portid_list == NULL) {
33580a6164cSYuYang         fprintf(stderr, "parse_port_list malloc failed\n");
33680a6164cSYuYang         return 0;
33780a6164cSYuYang     }
33880a6164cSYuYang     memcpy(portid_list, ports, sz*sizeof(uint16_t));
33980a6164cSYuYang 
34080a6164cSYuYang     cfg->dpdk.portid_list = portid_list;
34180a6164cSYuYang     cfg->dpdk.nb_ports = sz;
34280a6164cSYuYang     cfg->dpdk.max_portid = portid_list[sz-1];
34380a6164cSYuYang     return res;
34480a6164cSYuYang }
345a9643ea8Slogwang 
346a9643ea8Slogwang static int
parse_port_slave_list(struct ff_port_cfg * cfg,const char * v_str)347c0f66684Sfengbojiang(姜凤波) parse_port_slave_list(struct ff_port_cfg *cfg, const char *v_str)
348c0f66684Sfengbojiang(姜凤波) {
349c0f66684Sfengbojiang(姜凤波)     int res;
350c0f66684Sfengbojiang(姜凤波)     uint16_t ports[RTE_MAX_ETHPORTS];
351c0f66684Sfengbojiang(姜凤波)     int sz = RTE_MAX_ETHPORTS;
352c0f66684Sfengbojiang(姜凤波) 
353c0f66684Sfengbojiang(姜凤波)     res = __parse_config_list(ports, &sz, v_str);
354c0f66684Sfengbojiang(姜凤波)     if (! res) return res;
355c0f66684Sfengbojiang(姜凤波) 
356c0f66684Sfengbojiang(姜凤波)     uint16_t *portid_list = malloc(sizeof(uint16_t)*sz);
357c0f66684Sfengbojiang(姜凤波) 
358c0f66684Sfengbojiang(姜凤波)     if (portid_list == NULL) {
359c0f66684Sfengbojiang(姜凤波)         fprintf(stderr, "parse_port_slave_list malloc failed\n");
360c0f66684Sfengbojiang(姜凤波)         return 0;
361c0f66684Sfengbojiang(姜凤波)     }
362c0f66684Sfengbojiang(姜凤波)     memcpy(portid_list, ports, sz*sizeof(uint16_t));
363c0f66684Sfengbojiang(姜凤波) 
364c0f66684Sfengbojiang(姜凤波)     cfg->slave_portid_list = portid_list;
365c0f66684Sfengbojiang(姜凤波)     cfg->nb_slaves = sz;
366c0f66684Sfengbojiang(姜凤波) 
367c0f66684Sfengbojiang(姜凤波)     return res;
368c0f66684Sfengbojiang(姜凤波) }
369c0f66684Sfengbojiang(姜凤波) 
370c0f66684Sfengbojiang(姜凤波) static int
vip_cfg_handler(struct ff_port_cfg * cur)371c37034d0SBjörn Svensson vip_cfg_handler(struct ff_port_cfg *cur)
372503a15e0Sfengbojiang {
373503a15e0Sfengbojiang     //vip cfg
374503a15e0Sfengbojiang     int ret;
375503a15e0Sfengbojiang     char *vip_addr_array[VIP_MAX_NUM];
376503a15e0Sfengbojiang 
377503a15e0Sfengbojiang     ret = rte_strsplit(cur->vip_addr_str, strlen(cur->vip_addr_str), &vip_addr_array[0], VIP_MAX_NUM, ';');
378503a15e0Sfengbojiang     if (ret <= 0) {
379c37034d0SBjörn Svensson         fprintf(stdout, "vip_cfg_handler nb_vip is 0, not set vip_addr or set invalid vip_addr %s\n",
380503a15e0Sfengbojiang             cur->vip_addr_str);
381503a15e0Sfengbojiang         return 1;
382503a15e0Sfengbojiang     }
383503a15e0Sfengbojiang 
384503a15e0Sfengbojiang     cur->nb_vip = ret;
385503a15e0Sfengbojiang 
386503a15e0Sfengbojiang     cur->vip_addr_array = (char **)calloc(cur->nb_vip, sizeof(char *));
387503a15e0Sfengbojiang     if (cur->vip_addr_array == NULL) {
388c37034d0SBjörn Svensson         fprintf(stderr, "vip_cfg_handler malloc failed\n");
389503a15e0Sfengbojiang         goto err;
390503a15e0Sfengbojiang     }
391503a15e0Sfengbojiang 
392503a15e0Sfengbojiang     memcpy(cur->vip_addr_array, vip_addr_array, cur->nb_vip * sizeof(char *));
393503a15e0Sfengbojiang 
394503a15e0Sfengbojiang     return 1;
395503a15e0Sfengbojiang 
396503a15e0Sfengbojiang err:
397503a15e0Sfengbojiang     cur->nb_vip = 0;
398503a15e0Sfengbojiang     if (cur->vip_addr_array) {
399503a15e0Sfengbojiang         free(cur->vip_addr_array);
400503a15e0Sfengbojiang         cur->vip_addr_array = NULL;
401503a15e0Sfengbojiang     }
402503a15e0Sfengbojiang 
403503a15e0Sfengbojiang     return 0;
404503a15e0Sfengbojiang }
405503a15e0Sfengbojiang 
406503a15e0Sfengbojiang #ifdef INET6
407503a15e0Sfengbojiang static int
vip6_cfg_handler(struct ff_port_cfg * cur)408c37034d0SBjörn Svensson vip6_cfg_handler(struct ff_port_cfg *cur)
409503a15e0Sfengbojiang {
410503a15e0Sfengbojiang     //vip6 cfg
411503a15e0Sfengbojiang     int ret;
412503a15e0Sfengbojiang     char *vip_addr6_array[VIP_MAX_NUM];
413503a15e0Sfengbojiang 
414503a15e0Sfengbojiang     ret = rte_strsplit(cur->vip_addr6_str, strlen(cur->vip_addr6_str),
415503a15e0Sfengbojiang                                     &vip_addr6_array[0], VIP_MAX_NUM, ';');
416503a15e0Sfengbojiang     if (ret == 0) {
417c37034d0SBjörn Svensson         fprintf(stdout, "vip6_cfg_handler nb_vip6 is 0, not set vip_addr6 or set invalid vip_addr6 %s\n",
418503a15e0Sfengbojiang             cur->vip_addr6_str);
419503a15e0Sfengbojiang         return 1;
420503a15e0Sfengbojiang     }
421503a15e0Sfengbojiang 
422503a15e0Sfengbojiang     cur->nb_vip6 = ret;
423503a15e0Sfengbojiang 
424503a15e0Sfengbojiang     cur->vip_addr6_array = (char **) calloc(cur->nb_vip6, sizeof(char *));
425503a15e0Sfengbojiang     if (cur->vip_addr6_array == NULL) {
426c37034d0SBjörn Svensson         fprintf(stderr, "vip6_cfg_handler malloc failed\n");
427503a15e0Sfengbojiang         goto fail;
428503a15e0Sfengbojiang     }
429503a15e0Sfengbojiang 
430503a15e0Sfengbojiang     memcpy(cur->vip_addr6_array, vip_addr6_array, cur->nb_vip6 * sizeof(char *));
431503a15e0Sfengbojiang 
432503a15e0Sfengbojiang     return 1;
433503a15e0Sfengbojiang 
434503a15e0Sfengbojiang fail:
435503a15e0Sfengbojiang     cur->nb_vip6 = 0;
436503a15e0Sfengbojiang     if (cur->vip_addr6_array) {
437503a15e0Sfengbojiang         free(cur->vip_addr6_array);
438503a15e0Sfengbojiang         cur->vip_addr6_array = NULL;
439503a15e0Sfengbojiang     }
440503a15e0Sfengbojiang 
441503a15e0Sfengbojiang     return 0;
442503a15e0Sfengbojiang }
443503a15e0Sfengbojiang #endif
444503a15e0Sfengbojiang 
445503a15e0Sfengbojiang static int
port_cfg_handler(struct ff_config * cfg,const char * section,const char * name,const char * value)446a9643ea8Slogwang port_cfg_handler(struct ff_config *cfg, const char *section,
447a9643ea8Slogwang     const char *name, const char *value) {
448a9643ea8Slogwang 
449a9643ea8Slogwang     if (cfg->dpdk.nb_ports == 0) {
45080a6164cSYuYang         fprintf(stderr, "port_cfg_handler: must config dpdk.port_list first\n");
451a9643ea8Slogwang         return 0;
452a9643ea8Slogwang     }
453a9643ea8Slogwang 
454a9643ea8Slogwang     if (cfg->dpdk.port_cfgs == NULL) {
45580a6164cSYuYang         struct ff_port_cfg *pc = calloc(RTE_MAX_ETHPORTS, sizeof(struct ff_port_cfg));
456a9643ea8Slogwang         if (pc == NULL) {
457a9643ea8Slogwang             fprintf(stderr, "port_cfg_handler malloc failed\n");
458a9643ea8Slogwang             return 0;
459a9643ea8Slogwang         }
46080a6164cSYuYang         // initialize lcore list and nb_lcores
46180a6164cSYuYang         int i;
46280a6164cSYuYang         for (i = 0; i < cfg->dpdk.nb_ports; ++i) {
46380a6164cSYuYang             uint16_t portid = cfg->dpdk.portid_list[i];
464a9643ea8Slogwang 
46580a6164cSYuYang             struct ff_port_cfg *pconf = &pc[portid];
46680a6164cSYuYang             pconf->port_id = portid;
46780a6164cSYuYang             pconf->nb_lcores = ff_global_cfg.dpdk.nb_procs;
46880a6164cSYuYang             memcpy(pconf->lcore_list, ff_global_cfg.dpdk.proc_lcore,
46980a6164cSYuYang                    pconf->nb_lcores*sizeof(uint16_t));
47080a6164cSYuYang         }
471a9643ea8Slogwang         cfg->dpdk.port_cfgs = pc;
472a9643ea8Slogwang     }
473a9643ea8Slogwang 
474a9643ea8Slogwang     int portid;
475a9643ea8Slogwang     int ret = sscanf(section, "port%d", &portid);
476a9643ea8Slogwang     if (ret != 1) {
477a9643ea8Slogwang         fprintf(stderr, "port_cfg_handler section[%s] error\n", section);
478a9643ea8Slogwang         return 0;
479a9643ea8Slogwang     }
480a9643ea8Slogwang 
481a9643ea8Slogwang     /* just return true if portid >= nb_ports because it has no effect */
48280a6164cSYuYang     if (portid > cfg->dpdk.max_portid) {
48380a6164cSYuYang         fprintf(stderr, "port_cfg_handler section[%s] bigger than max port id\n", section);
484a9643ea8Slogwang         return 1;
485a9643ea8Slogwang     }
486a9643ea8Slogwang 
487a9643ea8Slogwang     struct ff_port_cfg *cur = &cfg->dpdk.port_cfgs[portid];
488a9643ea8Slogwang     if (cur->name == NULL) {
489a9643ea8Slogwang         cur->name = strdup(section);
490a9643ea8Slogwang         cur->port_id = portid;
491a9643ea8Slogwang     }
492a9643ea8Slogwang 
4935c84990dSIbtisam Tariq     if (strcmp(name, "ifc_name") == 0) {
4945c84990dSIbtisam Tariq         cur->ifname = strdup(value);
4955c84990dSIbtisam Tariq     } else if (strcmp(name, "addr") == 0) {
496a9643ea8Slogwang         cur->addr = strdup(value);
497a9643ea8Slogwang     } else if (strcmp(name, "netmask") == 0) {
498a9643ea8Slogwang         cur->netmask = strdup(value);
499a9643ea8Slogwang     } else if (strcmp(name, "broadcast") == 0) {
500a9643ea8Slogwang         cur->broadcast = strdup(value);
501a9643ea8Slogwang     } else if (strcmp(name, "gateway") == 0) {
502a9643ea8Slogwang         cur->gateway = strdup(value);
50380a6164cSYuYang     } else if (strcmp(name, "lcore_list") == 0) {
50480a6164cSYuYang         return parse_port_lcore_list(cur, value);
505c0f66684Sfengbojiang(姜凤波)     } else if (strcmp(name, "slave_port_list") == 0) {
506c0f66684Sfengbojiang(姜凤波)         return parse_port_slave_list(cur, value);
507503a15e0Sfengbojiang     } else if (strcmp(name, "vip_addr") == 0) {
508503a15e0Sfengbojiang         cur->vip_addr_str = strdup(value);
509503a15e0Sfengbojiang         if (cur->vip_addr_str) {
510c37034d0SBjörn Svensson             return vip_cfg_handler(cur);
511503a15e0Sfengbojiang         }
512503a15e0Sfengbojiang     } else if (strcmp(name, "vip_ifname") == 0) {
513503a15e0Sfengbojiang         cur->vip_ifname = strdup(value);
514a9643ea8Slogwang     }
515a9643ea8Slogwang 
516a25f323cSzengyi1001 #ifdef INET6
517503a15e0Sfengbojiang     else if (0 == strcmp(name, "addr6")) {
518a25f323cSzengyi1001         cur->addr6_str = strdup(value);
519503a15e0Sfengbojiang     } else if (0 == strcmp(name, "prefix_len")) {
520a25f323cSzengyi1001         cur->prefix_len = atoi(value);
521503a15e0Sfengbojiang     } else if (0 == strcmp(name, "gateway6")) {
522a25f323cSzengyi1001         cur->gateway6_str = strdup(value);
523503a15e0Sfengbojiang     } else if (strcmp(name, "vip_addr6") == 0) {
524503a15e0Sfengbojiang         cur->vip_addr6_str = strdup(value);
525cb78dc58SBjörn Svensson         if (cur->vip_addr6_str) {
526cb78dc58SBjörn Svensson             return vip6_cfg_handler(cur);
527503a15e0Sfengbojiang         }
528503a15e0Sfengbojiang     } else if (0 == strcmp(name, "vip_prefix_len")) {
529503a15e0Sfengbojiang         cur->vip_prefix_len = atoi(value);
530a25f323cSzengyi1001     }
531a25f323cSzengyi1001 #endif
532a25f323cSzengyi1001 
533a9643ea8Slogwang     return 1;
534a9643ea8Slogwang }
535a9643ea8Slogwang 
536a9643ea8Slogwang static int
vdev_cfg_handler(struct ff_config * cfg,const char * section,const char * name,const char * value)537a3bbaff5Sfengbojiang vdev_cfg_handler(struct ff_config *cfg, const char *section,
538a3bbaff5Sfengbojiang     const char *name, const char *value) {
539a3bbaff5Sfengbojiang 
540a3bbaff5Sfengbojiang     if (cfg->dpdk.nb_vdev == 0) {
541a3bbaff5Sfengbojiang         fprintf(stderr, "vdev_cfg_handler: must config dpdk.nb_vdev first\n");
542a3bbaff5Sfengbojiang         return 0;
543a3bbaff5Sfengbojiang     }
544a3bbaff5Sfengbojiang 
545a3bbaff5Sfengbojiang     if (cfg->dpdk.vdev_cfgs == NULL) {
546a3bbaff5Sfengbojiang         struct ff_vdev_cfg *vc = calloc(RTE_MAX_ETHPORTS, sizeof(struct ff_vdev_cfg));
547a3bbaff5Sfengbojiang         if (vc == NULL) {
548a3bbaff5Sfengbojiang             fprintf(stderr, "vdev_cfg_handler malloc failed\n");
549a3bbaff5Sfengbojiang             return 0;
550a3bbaff5Sfengbojiang         }
551a3bbaff5Sfengbojiang         cfg->dpdk.vdev_cfgs = vc;
552a3bbaff5Sfengbojiang     }
553a3bbaff5Sfengbojiang 
554a3bbaff5Sfengbojiang     int vdevid;
555a3bbaff5Sfengbojiang     int ret = sscanf(section, "vdev%d", &vdevid);
556a3bbaff5Sfengbojiang     if (ret != 1) {
557a3bbaff5Sfengbojiang         fprintf(stderr, "vdev_cfg_handler section[%s] error\n", section);
558a3bbaff5Sfengbojiang         return 0;
559a3bbaff5Sfengbojiang     }
560a3bbaff5Sfengbojiang 
561a3bbaff5Sfengbojiang     /* just return true if vdevid >= nb_vdev because it has no effect */
562a3bbaff5Sfengbojiang     if (vdevid > cfg->dpdk.nb_vdev) {
563a3bbaff5Sfengbojiang         fprintf(stderr, "vdev_cfg_handler section[%s] bigger than max vdev id\n", section);
564a3bbaff5Sfengbojiang         return 1;
565a3bbaff5Sfengbojiang     }
566a3bbaff5Sfengbojiang 
567a3bbaff5Sfengbojiang     struct ff_vdev_cfg *cur = &cfg->dpdk.vdev_cfgs[vdevid];
568a3bbaff5Sfengbojiang     if (cur->name == NULL) {
569a3bbaff5Sfengbojiang         cur->name = strdup(section);
570a3bbaff5Sfengbojiang         cur->vdev_id = vdevid;
571a3bbaff5Sfengbojiang     }
572a3bbaff5Sfengbojiang 
573a3bbaff5Sfengbojiang     if (strcmp(name, "iface") == 0) {
574a3bbaff5Sfengbojiang         cur->iface = strdup(value);
575a3bbaff5Sfengbojiang     } else if (strcmp(name, "path") == 0) {
576a3bbaff5Sfengbojiang         cur->path = strdup(value);
577a3bbaff5Sfengbojiang     } else if (strcmp(name, "queues") == 0) {
578a3bbaff5Sfengbojiang         cur->nb_queues = atoi(value);
579a3bbaff5Sfengbojiang     } else if (strcmp(name, "queue_size") == 0) {
580a3bbaff5Sfengbojiang         cur->queue_size = atoi(value);
581a3bbaff5Sfengbojiang     } else if (strcmp(name, "mac") == 0) {
582a3bbaff5Sfengbojiang         cur->mac = strdup(value);
583a3bbaff5Sfengbojiang     } else if (strcmp(name, "cq") == 0) {
584a3bbaff5Sfengbojiang         cur->nb_cq = atoi(value);
585a3bbaff5Sfengbojiang     }
586a3bbaff5Sfengbojiang 
587a3bbaff5Sfengbojiang     return 1;
588a3bbaff5Sfengbojiang }
589a3bbaff5Sfengbojiang 
590c0f66684Sfengbojiang(姜凤波) static int
bond_cfg_handler(struct ff_config * cfg,const char * section,const char * name,const char * value)591c0f66684Sfengbojiang(姜凤波) bond_cfg_handler(struct ff_config *cfg, const char *section,
592c0f66684Sfengbojiang(姜凤波)     const char *name, const char *value) {
593c0f66684Sfengbojiang(姜凤波) 
594c0f66684Sfengbojiang(姜凤波)     if (cfg->dpdk.nb_bond == 0) {
595c0f66684Sfengbojiang(姜凤波)         fprintf(stderr, "bond_cfg_handler: must config dpdk.nb_bond first\n");
596c0f66684Sfengbojiang(姜凤波)         return 0;
597c0f66684Sfengbojiang(姜凤波)     }
598c0f66684Sfengbojiang(姜凤波) 
599c0f66684Sfengbojiang(姜凤波)     if (cfg->dpdk.bond_cfgs == NULL) {
600c0f66684Sfengbojiang(姜凤波)         struct ff_bond_cfg *vc = calloc(RTE_MAX_ETHPORTS, sizeof(struct ff_bond_cfg));
601c0f66684Sfengbojiang(姜凤波)         if (vc == NULL) {
602c0f66684Sfengbojiang(姜凤波)             fprintf(stderr, "ff_bond_cfg malloc failed\n");
603c0f66684Sfengbojiang(姜凤波)             return 0;
604c0f66684Sfengbojiang(姜凤波)         }
605c0f66684Sfengbojiang(姜凤波)         cfg->dpdk.bond_cfgs = vc;
606c0f66684Sfengbojiang(姜凤波)     }
607c0f66684Sfengbojiang(姜凤波) 
608c0f66684Sfengbojiang(姜凤波)     int bondid;
609c0f66684Sfengbojiang(姜凤波)     int ret = sscanf(section, "bond%d", &bondid);
610c0f66684Sfengbojiang(姜凤波)     if (ret != 1) {
611c0f66684Sfengbojiang(姜凤波)         fprintf(stderr, "bond_cfg_handler section[%s] error\n", section);
612c0f66684Sfengbojiang(姜凤波)         return 0;
613c0f66684Sfengbojiang(姜凤波)     }
614c0f66684Sfengbojiang(姜凤波) 
615c0f66684Sfengbojiang(姜凤波)     /* just return true if bondid >= nb_vdev because it has no effect */
616c0f66684Sfengbojiang(姜凤波)     if (bondid > cfg->dpdk.nb_bond) {
617c0f66684Sfengbojiang(姜凤波)         fprintf(stderr, "bond_cfg_handler section[%s] bigger than max bond id\n", section);
618c0f66684Sfengbojiang(姜凤波)         return 1;
619c0f66684Sfengbojiang(姜凤波)     }
620c0f66684Sfengbojiang(姜凤波) 
621c0f66684Sfengbojiang(姜凤波)     struct ff_bond_cfg *cur = &cfg->dpdk.bond_cfgs[bondid];
622c0f66684Sfengbojiang(姜凤波)     if (cur->name == NULL) {
623c0f66684Sfengbojiang(姜凤波)         cur->name = strdup(section);
624c0f66684Sfengbojiang(姜凤波)         cur->bond_id = bondid;
625c0f66684Sfengbojiang(姜凤波)     }
626c0f66684Sfengbojiang(姜凤波) 
627c0f66684Sfengbojiang(姜凤波)     if (strcmp(name, "mode") == 0) {
628c0f66684Sfengbojiang(姜凤波)         cur->mode = atoi(value);
629c0f66684Sfengbojiang(姜凤波)     } else if (strcmp(name, "slave") == 0) {
630c0f66684Sfengbojiang(姜凤波)         cur->slave = strdup(value);
631c0f66684Sfengbojiang(姜凤波)     } else if (strcmp(name, "primary") == 0) {
632c0f66684Sfengbojiang(姜凤波)         cur->primary = strdup(value);
633c0f66684Sfengbojiang(姜凤波)     } else if (strcmp(name, "socket_id") == 0) {
634c0f66684Sfengbojiang(姜凤波)         cur->socket_id = atoi(value);
635c0f66684Sfengbojiang(姜凤波)     } else if (strcmp(name, "mac") == 0) {
636c0f66684Sfengbojiang(姜凤波)         cur->bond_mac = strdup(value);
637c0f66684Sfengbojiang(姜凤波)     } else if (strcmp(name, "xmit_policy") == 0) {
638c0f66684Sfengbojiang(姜凤波)         cur->xmit_policy = strdup(value);
639c0f66684Sfengbojiang(姜凤波)     } else if (strcmp(name, "lsc_poll_period_ms") == 0) {
640c0f66684Sfengbojiang(姜凤波)         cur->lsc_poll_period_ms = atoi(value);
641c0f66684Sfengbojiang(姜凤波)     } else if (strcmp(name, "up_delay") == 0) {
642c0f66684Sfengbojiang(姜凤波)         cur->up_delay = atoi(value);
643c0f66684Sfengbojiang(姜凤波)     } else if (strcmp(name, "down_delay") == 0) {
644c0f66684Sfengbojiang(姜凤波)         cur->down_delay = atoi(value);
645c0f66684Sfengbojiang(姜凤波)     }
646c0f66684Sfengbojiang(姜凤波) 
647c0f66684Sfengbojiang(姜凤波)     return 1;
648c0f66684Sfengbojiang(姜凤波) }
649a3bbaff5Sfengbojiang 
650a3bbaff5Sfengbojiang static int
ini_parse_handler(void * user,const char * section,const char * name,const char * value)651a02c88d6Slogwang ini_parse_handler(void* user, const char* section, const char* name,
652a9643ea8Slogwang     const char* value)
653a9643ea8Slogwang {
654a9643ea8Slogwang     struct ff_config *pconfig = (struct ff_config*)user;
655a9643ea8Slogwang 
656a9643ea8Slogwang     printf("[%s]: %s=%s\n", section, name, value);
657a9643ea8Slogwang 
658a9643ea8Slogwang     #define MATCH(s, n) strcmp(section, s) == 0 && strcmp(name, n) == 0
659a9643ea8Slogwang     if (MATCH("dpdk", "channel")) {
660a9643ea8Slogwang         pconfig->dpdk.nb_channel = atoi(value);
661a9643ea8Slogwang     } else if (MATCH("dpdk", "memory")) {
662a9643ea8Slogwang         pconfig->dpdk.memory = atoi(value);
663a9643ea8Slogwang     } else if (MATCH("dpdk", "no_huge")) {
664a9643ea8Slogwang         pconfig->dpdk.no_huge = atoi(value);
665a9643ea8Slogwang     } else if (MATCH("dpdk", "lcore_mask")) {
666a9643ea8Slogwang         pconfig->dpdk.lcore_mask = strdup(value);
667a02c88d6Slogwang         return parse_lcore_mask(pconfig, pconfig->dpdk.lcore_mask);
66879f0ade3Sfengbojiang     } else if (MATCH("dpdk", "base_virtaddr")) {
66979f0ade3Sfengbojiang         pconfig->dpdk.base_virtaddr= strdup(value);
670838bd0faSzhangxiang10     } else if (MATCH("dpdk", "file_prefix")) {
671838bd0faSzhangxiang10         pconfig->dpdk.file_prefix = strdup(value);
672838bd0faSzhangxiang10     } else if (MATCH("dpdk", "pci_whitelist")) {
673838bd0faSzhangxiang10         pconfig->dpdk.pci_whitelist = strdup(value);
67480a6164cSYuYang     } else if (MATCH("dpdk", "port_list")) {
67580a6164cSYuYang         return parse_port_list(pconfig, value);
676a3bbaff5Sfengbojiang     } else if (MATCH("dpdk", "nb_vdev")) {
677a3bbaff5Sfengbojiang         pconfig->dpdk.nb_vdev = atoi(value);
678c0f66684Sfengbojiang(姜凤波)     } else if (MATCH("dpdk", "nb_bond")) {
679c0f66684Sfengbojiang(姜凤波)         pconfig->dpdk.nb_bond = atoi(value);
680a9643ea8Slogwang     } else if (MATCH("dpdk", "promiscuous")) {
681a9643ea8Slogwang         pconfig->dpdk.promiscuous = atoi(value);
682a9643ea8Slogwang     } else if (MATCH("dpdk", "numa_on")) {
683a9643ea8Slogwang         pconfig->dpdk.numa_on = atoi(value);
684213fa7b3Slogwang     } else if (MATCH("dpdk", "tso")) {
685213fa7b3Slogwang         pconfig->dpdk.tso = atoi(value);
6863a3642c7SJayath Sathyanarayana     } else if (MATCH("dpdk", "tx_csum_offoad_skip")) {
6873a3642c7SJayath Sathyanarayana         pconfig->dpdk.tx_csum_offoad_skip = atoi(value);
68864abcf71Slogwang     } else if (MATCH("dpdk", "vlan_strip")) {
68964abcf71Slogwang         pconfig->dpdk.vlan_strip = atoi(value);
690c506e436Sfengbojiang     } else if (MATCH("dpdk", "idle_sleep")) {
691c506e436Sfengbojiang         pconfig->dpdk.idle_sleep = atoi(value);
69259bb71f6Sfengbojiang(姜凤波)     } else if (MATCH("dpdk", "pkt_tx_delay")) {
69359bb71f6Sfengbojiang(姜凤波)         pconfig->dpdk.pkt_tx_delay = atoi(value);
694f41205e9Sfengbojiang     } else if (MATCH("dpdk", "symmetric_rss")) {
695f41205e9Sfengbojiang         pconfig->dpdk.symmetric_rss = atoi(value);
696a9643ea8Slogwang     } else if (MATCH("kni", "enable")) {
697a9643ea8Slogwang         pconfig->kni.enable= atoi(value);
69847507c15Spengtian     } else if (MATCH("kni", "kni_action")) {
69947507c15Spengtian         pconfig->kni.kni_action= strdup(value);
700a9643ea8Slogwang     } else if (MATCH("kni", "method")) {
701a9643ea8Slogwang         pconfig->kni.method= strdup(value);
702a9643ea8Slogwang     } else if (MATCH("kni", "tcp_port")) {
703a9643ea8Slogwang         pconfig->kni.tcp_port = strdup(value);
7049efa5f0aSlogwang     } else if (MATCH("kni", "udp_port")) {
705a9643ea8Slogwang         pconfig->kni.udp_port= strdup(value);
706a9643ea8Slogwang     } else if (strcmp(section, "freebsd.boot") == 0) {
707a9643ea8Slogwang         if (strcmp(name, "hz") == 0) {
708a9643ea8Slogwang             pconfig->freebsd.hz = atoi(value);
709a9643ea8Slogwang         } else if (strcmp(name, "physmem") == 0) {
710a9643ea8Slogwang             pconfig->freebsd.physmem = atol(value);
711615f2d3cSlogwang         } else if (strcmp(name, "fd_reserve") == 0) {
712615f2d3cSlogwang             pconfig->freebsd.fd_reserve = atoi(value);
713ef5ab859S10077240         } else if (strcmp(name, "memsz_MB") == 0) {
714ef5ab859S10077240             pconfig->freebsd.mem_size = atoi(value);
715a9643ea8Slogwang         } else {
716a9643ea8Slogwang             return freebsd_conf_handler(pconfig, "boot", name, value);
717a9643ea8Slogwang         }
718a9643ea8Slogwang     } else if (strcmp(section, "freebsd.sysctl") == 0) {
719a9643ea8Slogwang         return freebsd_conf_handler(pconfig, "sysctl", name, value);
720a9643ea8Slogwang     } else if (strncmp(section, "port", 4) == 0) {
721a9643ea8Slogwang         return port_cfg_handler(pconfig, section, name, value);
722a3bbaff5Sfengbojiang     } else if (strncmp(section, "vdev", 4) == 0) {
723a3bbaff5Sfengbojiang         return vdev_cfg_handler(pconfig, section, name, value);
724c0f66684Sfengbojiang(姜凤波)     } else if (strncmp(section, "bond", 4) == 0) {
725c0f66684Sfengbojiang(姜凤波)         return bond_cfg_handler(pconfig, section, name, value);
726819aafb6Sjinhao2     } else if (strcmp(section, "pcap") == 0) {
727819aafb6Sjinhao2         if (strcmp(name, "snaplen") == 0) {
728819aafb6Sjinhao2             pconfig->pcap.snap_len = (uint16_t)atoi(value);
729819aafb6Sjinhao2         } else if (strcmp(name, "savelen") == 0) {
730819aafb6Sjinhao2             pconfig->pcap.save_len = (uint32_t)atoi(value);
731819aafb6Sjinhao2         } else if (strcmp(name, "enable") == 0) {
732819aafb6Sjinhao2             pconfig->pcap.enable = (uint16_t)atoi(value);
733819aafb6Sjinhao2         } else if (strcmp(name, "savepath") == 0) {
734819aafb6Sjinhao2             pconfig->pcap.save_path = strdup(value);
735819aafb6Sjinhao2         }
736a9643ea8Slogwang     }
737a9643ea8Slogwang 
738a9643ea8Slogwang     return 1;
739a9643ea8Slogwang }
740a9643ea8Slogwang 
741a9643ea8Slogwang static int
dpdk_args_setup(struct ff_config * cfg)742a02c88d6Slogwang dpdk_args_setup(struct ff_config *cfg)
743a9643ea8Slogwang {
744a9643ea8Slogwang     int n = 0, i;
745a9643ea8Slogwang     dpdk_argv[n++] = strdup("f-stack");
746b8b4b7b9Sfengbojiang(姜凤波)     char temp[DPDK_CONFIG_MAXLEN] = {0}, temp2[DPDK_CONFIG_MAXLEN] = {0};
747a9643ea8Slogwang 
748a9643ea8Slogwang     if (cfg->dpdk.no_huge) {
749a9643ea8Slogwang         dpdk_argv[n++] = strdup("--no-huge");
750a9643ea8Slogwang     }
751a9643ea8Slogwang     if (cfg->dpdk.proc_mask) {
752a9643ea8Slogwang         sprintf(temp, "-c%s", cfg->dpdk.proc_mask);
753a9643ea8Slogwang         dpdk_argv[n++] = strdup(temp);
754a9643ea8Slogwang     }
755a9643ea8Slogwang     if (cfg->dpdk.nb_channel) {
756a9643ea8Slogwang         sprintf(temp, "-n%d", cfg->dpdk.nb_channel);
757a9643ea8Slogwang         dpdk_argv[n++] = strdup(temp);
758a9643ea8Slogwang     }
759a9643ea8Slogwang     if (cfg->dpdk.memory) {
760a9643ea8Slogwang         sprintf(temp, "-m%d", cfg->dpdk.memory);
761a9643ea8Slogwang         dpdk_argv[n++] = strdup(temp);
762a9643ea8Slogwang     }
763a02c88d6Slogwang     if (cfg->dpdk.proc_type) {
764a02c88d6Slogwang         sprintf(temp, "--proc-type=%s", cfg->dpdk.proc_type);
765a02c88d6Slogwang         dpdk_argv[n++] = strdup(temp);
766a9643ea8Slogwang     }
76779f0ade3Sfengbojiang     if (cfg->dpdk.base_virtaddr) {
76879f0ade3Sfengbojiang         sprintf(temp, "--base-virtaddr=%s", cfg->dpdk.base_virtaddr);
76979f0ade3Sfengbojiang         dpdk_argv[n++] = strdup(temp);
77079f0ade3Sfengbojiang     }
771838bd0faSzhangxiang10     if (cfg->dpdk.file_prefix) {
772199154d9Szhangxiang10         sprintf(temp, "--file-prefix=container-%s", cfg->dpdk.file_prefix);
773838bd0faSzhangxiang10         dpdk_argv[n++] = strdup(temp);
774838bd0faSzhangxiang10     }
775838bd0faSzhangxiang10     if (cfg->dpdk.pci_whitelist) {
776838bd0faSzhangxiang10         char* token;
777838bd0faSzhangxiang10         char* rest = cfg->dpdk.pci_whitelist;
778838bd0faSzhangxiang10 
779a9643ea8Slogwang         while ((token = strtok_r(rest, ",", &rest))){
780a3bbaff5Sfengbojiang             sprintf(temp, "--pci-whitelist=%s", token);
781a3bbaff5Sfengbojiang             dpdk_argv[n++] = strdup(temp);
782a3bbaff5Sfengbojiang         }
783a3bbaff5Sfengbojiang 
784a3bbaff5Sfengbojiang     }
785a3bbaff5Sfengbojiang 
786b8b4b7b9Sfengbojiang(姜凤波)     if (cfg->dpdk.nb_vdev) {
787b8b4b7b9Sfengbojiang(姜凤波)         for (i=0; i<cfg->dpdk.nb_vdev; i++) {
788b8b4b7b9Sfengbojiang(姜凤波)             sprintf(temp, "--vdev=virtio_user%d,path=%s",
789a3bbaff5Sfengbojiang                 cfg->dpdk.vdev_cfgs[i].vdev_id,
790a3bbaff5Sfengbojiang                 cfg->dpdk.vdev_cfgs[i].path);
791b8b4b7b9Sfengbojiang(姜凤波)             if (cfg->dpdk.vdev_cfgs[i].nb_queues) {
792b8b4b7b9Sfengbojiang(姜凤波)                 sprintf(temp2, ",queues=%u",
793b8b4b7b9Sfengbojiang(姜凤波)                     cfg->dpdk.vdev_cfgs[i].nb_queues);
794a3bbaff5Sfengbojiang                 strcat(temp, temp2);
795a3bbaff5Sfengbojiang             }
796b8b4b7b9Sfengbojiang(姜凤波)             if (cfg->dpdk.vdev_cfgs[i].nb_cq) {
797b8b4b7b9Sfengbojiang(姜凤波)                 sprintf(temp2, ",cq=%u",
798b8b4b7b9Sfengbojiang(姜凤波)                     cfg->dpdk.vdev_cfgs[i].nb_cq);
799a3bbaff5Sfengbojiang                 strcat(temp, temp2);
800a3bbaff5Sfengbojiang             }
801b8b4b7b9Sfengbojiang(姜凤波)             if (cfg->dpdk.vdev_cfgs[i].queue_size) {
802b8b4b7b9Sfengbojiang(姜凤波)                 sprintf(temp2, ",queue_size=%u",
803b8b4b7b9Sfengbojiang(姜凤波)                     cfg->dpdk.vdev_cfgs[i].queue_size);
804a3bbaff5Sfengbojiang                 strcat(temp, temp2);
805a3bbaff5Sfengbojiang             }
806a3bbaff5Sfengbojiang             if (cfg->dpdk.vdev_cfgs[i].mac) {
807a3bbaff5Sfengbojiang                 sprintf(temp2, ",mac=%s",
808a3bbaff5Sfengbojiang                     cfg->dpdk.vdev_cfgs[i].mac);
809838bd0faSzhangxiang10                 strcat(temp, temp2);
810a3bbaff5Sfengbojiang             }
811a3bbaff5Sfengbojiang             dpdk_argv[n++] = strdup(temp);
812a3bbaff5Sfengbojiang         }
813838bd0faSzhangxiang10         sprintf(temp, "--no-pci");
814a3bbaff5Sfengbojiang         dpdk_argv[n++] = strdup(temp);
815c0f66684Sfengbojiang(姜凤波)         if (!cfg->dpdk.file_prefix) {
816c0f66684Sfengbojiang(姜凤波)             sprintf(temp, "--file-prefix=container");
817c0f66684Sfengbojiang(姜凤波)             dpdk_argv[n++] = strdup(temp);
818c0f66684Sfengbojiang(姜凤波)         }
819c0f66684Sfengbojiang(姜凤波)     }
820c0f66684Sfengbojiang(姜凤波) 
821c0f66684Sfengbojiang(姜凤波)     if (cfg->dpdk.nb_bond) {
822c0f66684Sfengbojiang(姜凤波)         for (i=0; i<cfg->dpdk.nb_bond; i++) {
823c0f66684Sfengbojiang(姜凤波)             sprintf(temp, "--vdev");
824c0f66684Sfengbojiang(姜凤波)             dpdk_argv[n++] = strdup(temp);
825b8b4b7b9Sfengbojiang(姜凤波)             sprintf(temp, "net_bonding%d,mode=%d,slave=%s",
826b8b4b7b9Sfengbojiang(姜凤波)                 cfg->dpdk.bond_cfgs[i].bond_id,
827b8b4b7b9Sfengbojiang(姜凤波)                 cfg->dpdk.bond_cfgs[i].mode,
828c0f66684Sfengbojiang(姜凤波)                 cfg->dpdk.bond_cfgs[i].slave);
829c0f66684Sfengbojiang(姜凤波) 
830c0f66684Sfengbojiang(姜凤波)                 if (cfg->dpdk.bond_cfgs[i].primary) {
831b8b4b7b9Sfengbojiang(姜凤波)                     sprintf(temp2, ",primary=%s",
832b8b4b7b9Sfengbojiang(姜凤波)                         cfg->dpdk.bond_cfgs[i].primary);
833b8b4b7b9Sfengbojiang(姜凤波)                     strcat(temp, temp2);
834c0f66684Sfengbojiang(姜凤波)                 }
835c0f66684Sfengbojiang(姜凤波) 
836c0f66684Sfengbojiang(姜凤波)                 if (cfg->dpdk.bond_cfgs[i].socket_id) {
837b8b4b7b9Sfengbojiang(姜凤波)                     sprintf(temp2, ",socket_id=%d",
838b8b4b7b9Sfengbojiang(姜凤波)                         cfg->dpdk.bond_cfgs[i].socket_id);
839b8b4b7b9Sfengbojiang(姜凤波)                     strcat(temp, temp2);
840c0f66684Sfengbojiang(姜凤波)                 }
841c0f66684Sfengbojiang(姜凤波) 
842c0f66684Sfengbojiang(姜凤波)                 if (cfg->dpdk.bond_cfgs[i].bond_mac) {
843b8b4b7b9Sfengbojiang(姜凤波)                     sprintf(temp2, ",mac=%s",
844b8b4b7b9Sfengbojiang(姜凤波)                         cfg->dpdk.bond_cfgs[i].bond_mac);
845b8b4b7b9Sfengbojiang(姜凤波)                     strcat(temp, temp2);
846c0f66684Sfengbojiang(姜凤波)                 }
847c0f66684Sfengbojiang(姜凤波) 
848c0f66684Sfengbojiang(姜凤波)                 if (cfg->dpdk.bond_cfgs[i].xmit_policy) {
849b8b4b7b9Sfengbojiang(姜凤波)                     sprintf(temp2, ",xmit_policy=%s",
850b8b4b7b9Sfengbojiang(姜凤波)                         cfg->dpdk.bond_cfgs[i].xmit_policy);
851b8b4b7b9Sfengbojiang(姜凤波)                     strcat(temp, temp2);
852c0f66684Sfengbojiang(姜凤波)                 }
853c0f66684Sfengbojiang(姜凤波) 
854c0f66684Sfengbojiang(姜凤波)                 if (cfg->dpdk.bond_cfgs[i].lsc_poll_period_ms) {
855b8b4b7b9Sfengbojiang(姜凤波)                     sprintf(temp2, ",lsc_poll_period_ms=%d",
856b8b4b7b9Sfengbojiang(姜凤波)                         cfg->dpdk.bond_cfgs[i].lsc_poll_period_ms);
857b8b4b7b9Sfengbojiang(姜凤波)                     strcat(temp, temp2);
858c0f66684Sfengbojiang(姜凤波)                 }
859c0f66684Sfengbojiang(姜凤波) 
860c0f66684Sfengbojiang(姜凤波)                 if (cfg->dpdk.bond_cfgs[i].up_delay) {
861b8b4b7b9Sfengbojiang(姜凤波)                     sprintf(temp2, ",up_delay=%d",
862b8b4b7b9Sfengbojiang(姜凤波)                         cfg->dpdk.bond_cfgs[i].up_delay);
863b8b4b7b9Sfengbojiang(姜凤波)                     strcat(temp, temp2);
864c0f66684Sfengbojiang(姜凤波)                 }
865c0f66684Sfengbojiang(姜凤波) 
866c0f66684Sfengbojiang(姜凤波)                 if (cfg->dpdk.bond_cfgs[i].down_delay) {
867c0f66684Sfengbojiang(姜凤波)                     sprintf(temp2, ",down_delay=%d",
868c0f66684Sfengbojiang(姜凤波)                         cfg->dpdk.bond_cfgs[i].down_delay);
869a9643ea8Slogwang                     strcat(temp, temp2);
870a9643ea8Slogwang                 }
871a3bbaff5Sfengbojiang                 dpdk_argv[n++] = strdup(temp);
872a3bbaff5Sfengbojiang         }
873a3bbaff5Sfengbojiang     }
874a9643ea8Slogwang 
875a9643ea8Slogwang     dpdk_argc = n;
876a9643ea8Slogwang 
877a02c88d6Slogwang     for (i=0; i<n; i++)
878a02c88d6Slogwang         printf("%s ", dpdk_argv[i]);
879a9643ea8Slogwang 
880a9643ea8Slogwang     return n;
881a9643ea8Slogwang }
88240600211Slogwang 
883a9643ea8Slogwang static int
ff_parse_args(struct ff_config * cfg,int argc,char * const argv[])884a9643ea8Slogwang ff_parse_args(struct ff_config *cfg, int argc, char *const argv[])
885a9643ea8Slogwang {
886a02c88d6Slogwang     int c;
887a9643ea8Slogwang     int index = 0;
888a02c88d6Slogwang     optind = 1;
889a9643ea8Slogwang     while((c = getopt_long(argc, argv, short_options, long_options, &index)) != -1) {
890a02c88d6Slogwang         switch (c) {
891a02c88d6Slogwang             case 'c':
892a02c88d6Slogwang                 cfg->filename = strdup(optarg);
893a9643ea8Slogwang                 break;
894a9643ea8Slogwang             case 'p':
895a02c88d6Slogwang                 cfg->dpdk.proc_id = atoi(optarg);
896a9643ea8Slogwang                 break;
897a9643ea8Slogwang             case 't':
898a02c88d6Slogwang                 cfg->dpdk.proc_type = strdup(optarg);
899867abe45Swhl739                 break;
900867abe45Swhl739             default:
901867abe45Swhl739                 return -1;
902867abe45Swhl739         }
903867abe45Swhl739     }
904867abe45Swhl739 
905867abe45Swhl739     if (cfg->dpdk.proc_type == NULL) {
90679f0ade3Sfengbojiang         cfg->dpdk.proc_type = strdup("auto");
907a02c88d6Slogwang     }
908a02c88d6Slogwang 
909a02c88d6Slogwang     if (strcmp(cfg->dpdk.proc_type, "primary") &&
910a02c88d6Slogwang         strcmp(cfg->dpdk.proc_type, "secondary") &&
91186036c74Swhl739         strcmp(cfg->dpdk.proc_type, "auto")) {
91286036c74Swhl739         printf("invalid proc-type:%s\n", cfg->dpdk.proc_type);
913a02c88d6Slogwang         return -1;
914a02c88d6Slogwang     }
915a02c88d6Slogwang 
916a9643ea8Slogwang     if ((uint16_t)cfg->dpdk.proc_id > RTE_MAX_LCORE) {
917a9643ea8Slogwang         printf("invalid proc_id:%d, use default 0\n", cfg->dpdk.proc_id);
918a9643ea8Slogwang         cfg->dpdk.proc_id = 0;
919a9643ea8Slogwang     }
920a9643ea8Slogwang 
921a9643ea8Slogwang     return 0;
922a9643ea8Slogwang }
923a9643ea8Slogwang 
924a9643ea8Slogwang static int
ff_check_config(struct ff_config * cfg)925a9643ea8Slogwang ff_check_config(struct ff_config *cfg)
926a9643ea8Slogwang {
927a9643ea8Slogwang     if(cfg->kni.enable && !cfg->kni.method) {
928a9643ea8Slogwang         fprintf(stderr, "conf dpdk.method is necessary\n");
929a9643ea8Slogwang         return -1;
930a9643ea8Slogwang     }
931a9643ea8Slogwang 
932a9643ea8Slogwang     if(cfg->kni.method) {
933a9643ea8Slogwang         if(strcasecmp(cfg->kni.method,"accept") &&
934a9643ea8Slogwang             strcasecmp(cfg->kni.method,"reject")) {
93547507c15Spengtian             fprintf(stderr, "conf kni.method[accept|reject] is error(%s)\n",
93647507c15Spengtian                 cfg->kni.method);
93747507c15Spengtian             return -1;
93847507c15Spengtian         }
93947507c15Spengtian     }
94047507c15Spengtian 
94147507c15Spengtian     if(cfg->kni.kni_action) {
94247507c15Spengtian         if (strcasecmp(cfg->kni.kni_action,"alltokni") &&
94347507c15Spengtian             strcasecmp(cfg->kni.kni_action,"alltoff") &&
94447507c15Spengtian             strcasecmp(cfg->kni.kni_action,"default")){
945819aafb6Sjinhao2                 fprintf(stderr, "conf kni.kni_action[alltokni|alltoff|default] is error(%s)\n",
946819aafb6Sjinhao2                 cfg->kni.kni_action);
947819aafb6Sjinhao2                 return -1;
948819aafb6Sjinhao2         }
949819aafb6Sjinhao2     }
950819aafb6Sjinhao2 
951819aafb6Sjinhao2     if (cfg->pcap.save_len < PCAP_SAVE_MINLEN)
952a9643ea8Slogwang         cfg->pcap.save_len = PCAP_SAVE_MINLEN;
953a9643ea8Slogwang     if (cfg->pcap.snap_len < PCAP_SNAP_MINLEN)
954a9643ea8Slogwang         cfg->pcap.snap_len = PCAP_SNAP_MINLEN;
955a9643ea8Slogwang     if (cfg->pcap.save_path==NULL || strlen(cfg->pcap.save_path) ==0)
956a9643ea8Slogwang         cfg->pcap.save_path = strdup(".");
957a9643ea8Slogwang 
958a9643ea8Slogwang     #define CHECK_VALID(n) \
959a9643ea8Slogwang         do { \
960a9643ea8Slogwang             if (!pc->n) { \
961a9643ea8Slogwang                 fprintf(stderr, "port%d if config error: no %s\n", \
962a9643ea8Slogwang                     pc->port_id, #n); \
96380a6164cSYuYang                 return -1; \
96480a6164cSYuYang             } \
965a9643ea8Slogwang         } while (0)
966a9643ea8Slogwang 
967a9643ea8Slogwang     int i;
968a9643ea8Slogwang     for (i = 0; i < cfg->dpdk.nb_ports; i++) {
96980a6164cSYuYang         uint16_t portid = cfg->dpdk.portid_list[i];
97080a6164cSYuYang         struct ff_port_cfg *pc = &cfg->dpdk.port_cfgs[portid];
97180a6164cSYuYang         CHECK_VALID(addr);
97280a6164cSYuYang         CHECK_VALID(netmask);
97380a6164cSYuYang         CHECK_VALID(broadcast);
97480a6164cSYuYang         CHECK_VALID(gateway);
97580a6164cSYuYang         // check if the lcores in lcore_list are enabled.
97680a6164cSYuYang         int k;
97780a6164cSYuYang         for (k = 0; k < pc->nb_lcores; k++) {
97880a6164cSYuYang             uint16_t lcore_id = pc->lcore_list[k];
97980a6164cSYuYang             if (uint16_binary_search(cfg->dpdk.proc_lcore, 0,
98080a6164cSYuYang                                      cfg->dpdk.nb_procs-1, lcore_id) < 0) {
98180a6164cSYuYang                 fprintf(stderr, "lcore %d is not enabled.\n", lcore_id);
98280a6164cSYuYang                 return -1;
98380a6164cSYuYang             }
98480a6164cSYuYang         }
98580a6164cSYuYang         /*
98680a6164cSYuYang          * only primary process process KNI, so if KNI enabled,
98780a6164cSYuYang          * primary lcore must stay in every enabled ports' lcore_list
98880a6164cSYuYang          */
98980a6164cSYuYang         if (cfg->kni.enable &&
99080a6164cSYuYang             strcmp(cfg->dpdk.proc_type, "primary") == 0) {
99180a6164cSYuYang             int found = 0;
99280a6164cSYuYang             int j;
99380a6164cSYuYang             uint16_t lcore_id = cfg->dpdk.proc_lcore[cfg->dpdk.proc_id];
99480a6164cSYuYang             for (j = 0; j < pc->nb_lcores; j++) {
99580a6164cSYuYang                 if (pc->lcore_list[j] == lcore_id) {
99680a6164cSYuYang                     found = 1;
99780a6164cSYuYang                 }
99880a6164cSYuYang             }
99980a6164cSYuYang             if (! found) {
1000a9643ea8Slogwang                 fprintf(stderr,
1001a9643ea8Slogwang                          "primary lcore %d should stay in port %d's lcore_list.\n",
1002a9643ea8Slogwang                          lcore_id, pc->port_id);
1003a9643ea8Slogwang                 return -1;
1004a9643ea8Slogwang             }
1005a9643ea8Slogwang         }
1006a9643ea8Slogwang     }
1007a9643ea8Slogwang 
1008a9643ea8Slogwang     return 0;
1009a9643ea8Slogwang }
1010a02c88d6Slogwang 
1011a02c88d6Slogwang static void
ff_default_config(struct ff_config * cfg)1012a02c88d6Slogwang ff_default_config(struct ff_config *cfg)
1013a9643ea8Slogwang {
1014a9643ea8Slogwang     memset(cfg, 0, sizeof(struct ff_config));
101559bb71f6Sfengbojiang(姜凤波) 
1016a9643ea8Slogwang     cfg->filename = DEFAULT_CONFIG_FILE;
1017a9643ea8Slogwang 
1018a9643ea8Slogwang     cfg->dpdk.proc_id = -1;
1019a02c88d6Slogwang     cfg->dpdk.numa_on = 1;
1020ef5ab859S10077240     cfg->dpdk.promiscuous = 1;
1021a9643ea8Slogwang     cfg->dpdk.pkt_tx_delay = BURST_TX_DRAIN_US;
1022a9643ea8Slogwang 
1023a9643ea8Slogwang     cfg->freebsd.hz = 100;
1024a02c88d6Slogwang     cfg->freebsd.physmem = 1048576*256;
1025a9643ea8Slogwang     cfg->freebsd.fd_reserve = 0;
1026a9643ea8Slogwang     cfg->freebsd.mem_size = 256;
1027a9643ea8Slogwang }
1028a02c88d6Slogwang 
1029a02c88d6Slogwang int
ff_load_config(int argc,char * const argv[])1030a02c88d6Slogwang ff_load_config(int argc, char *const argv[])
1031a02c88d6Slogwang {
1032a02c88d6Slogwang     ff_default_config(&ff_global_cfg);
1033a02c88d6Slogwang 
1034a02c88d6Slogwang     int ret = ff_parse_args(&ff_global_cfg, argc, argv);
1035a9643ea8Slogwang     if (ret < 0) {
1036a02c88d6Slogwang         return ret;
1037a9643ea8Slogwang     }
1038a9643ea8Slogwang 
1039a9643ea8Slogwang     ret = ini_parse(ff_global_cfg.filename, ini_parse_handler,
1040a9643ea8Slogwang         &ff_global_cfg);
1041a9643ea8Slogwang     if (ret != 0) {
1042a9643ea8Slogwang         printf("parse %s failed on line %d\n", ff_global_cfg.filename, ret);
1043a9643ea8Slogwang         return -1;
1044a02c88d6Slogwang     }
1045a9643ea8Slogwang 
1046a9643ea8Slogwang     if (ff_check_config(&ff_global_cfg)) {
1047a9643ea8Slogwang         return -1;
1048a9643ea8Slogwang     }
1049a9643ea8Slogwang 
1050     if (dpdk_args_setup(&ff_global_cfg) <= 0) {
1051         return -1;
1052     }
1053 
1054     return 0;
1055 }
1056