xref: /mOS-networking-stack/core/src/config.c (revision 7245de1b)
1 #include <stdlib.h>
2 #include <assert.h>
3 #include <sys/socket.h>
4 #include <sys/ioctl.h>
5 #include <sys/stat.h>
6 #include <net/if.h>
7 #include <arpa/inet.h>
8 #include <netinet/in.h>
9 #include <netdb.h>
10 #include <stdio.h>
11 #include <unistd.h>
12 #include <ctype.h>
13 #include <string.h>
14 
15 #include "mtcp.h"
16 #include "config.h"
17 #include "tcp_in.h"
18 #include "arp.h"
19 #include "debug.h"
20 #include "mtcp_util.h"
21 /* for setting up io modules */
22 #include "io_module.h"
23 /* for if_nametoindex */
24 #include <net/if.h>
25 
26 #define MAX_PROCLINE_LEN 1024
27 
28 #ifdef DARWIN
29 #pragma GCC diagnostic ignored "-Wformat"
30 #pragma GCC diagnostic ignored "-Wempty-body"
31 #endif
32 
33 /*----------------------------------------------------------------------------*/
34 int8_t end_app_exists = 0;
35 int8_t mon_app_exists = 0;
36 addr_pool_t ap[ETH_NUM] = {NULL};
37 char *file = NULL;
38 /*----------------------------------------------------------------------------*/
39 /* return 0 on failure */
40 #define MATCH_ITEM(name, item) \
41 	((strncmp(#name, item, strlen(#name)) == 0) \
42 	 && (!isalnum(item[strlen(#name)])))
43 
44 #define TRY_ASSIGN_NUM(name, base, item, value) \
45 	((strncmp(#name, item, strlen(#name)) == 0) \
46 	 && (!isalnum(item[strlen(#name)])) \
47 	 && (sscanf(value, \
48 			(sizeof((base)->name) == sizeof(char)) ? "%hhi" : \
49 			(sizeof((base)->name) == sizeof(short)) ? "%hi" : \
50 			(sizeof((base)->name) == sizeof(int)) ? "%i" : \
51 			(sizeof((base)->name) == sizeof(long)) ? "%li" : \
52 			(sizeof((base)->name) == sizeof(long long)) ? "%lli" : "ERROR", \
53 			    &(base)->name) > 0))
54 
55 #define TRY_ASSIGN_STR(name, base, item, value) \
56 	(((strncmp(#name, item, strlen(#name)) == 0) \
57 	  && (!isalnum(item[strlen(#name)])) \
58 	  && (strlen(value) < sizeof((base)->name))) ? \
59 	 (strcpy((base)->name, value), 1) : 0)
60 
61 #define LINE_FOREACH(line, llen, buf, blen) \
62 	for(line = buf, \
63 		llen = ((strchr(line, '\n') == NULL) ? (buf + blen - line) \
64 											 : strchr(line, '\n') - line); \
65 		line + llen < buf + blen; \
66 		line += llen + 1, \
67 		llen = ((strchr(line, '\n') == NULL) ? (buf + blen - line) \
68 											 : strchr(line, '\n') - line)) \
69 /*----------------------------------------------------------------------------*/
70 static int
SetMultiProcessSupport(char * multiprocess_details)71 SetMultiProcessSupport(char *multiprocess_details)
72 {
73 	char *token = " =";
74 	char *sample;
75 	char *saveptr;
76 
77 	TRACE_CONFIG("Loading multi-process configuration\n");
78 
79 	sample = strtok_r(multiprocess_details, token, &saveptr);
80 	if (sample == NULL) {
81 		TRACE_CONFIG("No option for multi-process support given!\n");
82 		return -1;
83 	}
84 	g_config.mos->multiprocess_curr_core = mystrtol(sample, 10);
85 
86 	sample = strtok_r(NULL, token, &saveptr);
87 	if (sample != NULL && !strcmp(sample, "master"))
88 		g_config.mos->multiprocess_is_master = 1;
89 
90 	return 0;
91 }
92 /*----------------------------------------------------------------------------*/
93 static int
DetectWord(char * buf,int len,char ** word,int * wlen)94 DetectWord(char *buf, int len, char **word, int *wlen)
95 {
96 	int i;
97 	for (i = 0; i < len; i++) {
98 		if (isspace(buf[i]))
99 			continue;
100 
101 		if (isalpha(buf[i])) {
102 			*word = &buf[i];
103 			break;
104 		} else
105 			/* not word */
106 			return -1;
107 	}
108 
109 	if (i == len)
110 		return -1;
111 
112 	for (*wlen = 0; *wlen < len; (*wlen)++) {
113 		if (isalnum((*word)[*wlen]) || (*word)[*wlen] == '_')
114 			continue;
115 
116 		assert(*wlen != 0);
117 		break;
118 	}
119 
120 	assert(*word >= buf && *word + *wlen <= buf + len);
121 
122 	return 0;
123 }
124 /*----------------------------------------------------------------------------*/
125 static int
ReadItemValue(char * line,int llen,char * item,int ilen,char * value,int vlen)126 ReadItemValue(char *line, int llen, char *item, int ilen, char *value, int vlen)
127 {
128 	const char *end = &line[llen];
129 	char *word = NULL;
130 	int wlen = 0;
131 
132 	if (DetectWord(line, llen, &word, &wlen) < 0 || wlen > ilen)
133 		return -1;
134 
135 	line = word + wlen;
136 
137 	/* skip space */
138 	while (line < end && isspace(*line))
139 		line++;
140 
141 	if (*(line++) != '=')
142 		return -1;
143 
144 	while (line < end && isspace(*line))
145 		line++;
146 
147 	if (end - line > vlen)
148 		return -1;
149 
150 	while (isspace(*(end - 1)))
151 		end--;
152 
153 	if (end <= line)
154 		return -1;
155 
156 	strncpy(item, word, wlen);
157 
158 	strncpy(value, line, (size_t)(end - line));
159 
160 	return 0;
161 }
162 /*----------------------------------------------------------------------------*/
163 static void
FeedAppConfLine(struct conf_block * blk,char * line,int len)164 FeedAppConfLine(struct conf_block *blk, char *line, int len)
165 {
166 	struct app_conf * const conf = (struct app_conf *)blk->conf;
167 
168 	char item[WORD_LEN + 1] = {0};
169 	char value[STR_LEN + 1] = {0};
170 
171 	if (ReadItemValue(line, len, item, WORD_LEN, value, STR_LEN) < 0)
172 		return;
173 
174 	if      (TRY_ASSIGN_STR(type,       conf, item, value));
175 	else if (TRY_ASSIGN_STR(run,        conf, item, value)) {
176 		StrToArgs(conf->run, &conf->app_argc, conf->app_argv, MOS_APP_ARGC);
177 #if 0
178 		conf->app_argv[conf->app_argc++] = strtok(conf->run, " \t\n\r");
179 		while (conf->app_argc < MOS_APP_ARGC &&
180 				(conf->app_argv[conf->app_argc] = strtok(NULL, " \t\n\r")))
181 			conf->app_argc++;
182 #endif
183 	} else if (TRY_ASSIGN_NUM(cpu_mask,   conf, item, value));
184 	else if (TRY_ASSIGN_NUM(ip_forward, conf, item, value));
185 }
186 /*----------------------------------------------------------------------------*/
187 static void
FeedMosConfLine(struct conf_block * blk,char * line,int len)188 FeedMosConfLine(struct conf_block *blk, char *line, int len)
189 {
190 	struct mos_conf * const conf = (struct mos_conf *)blk->conf;
191 
192 	char item[WORD_LEN + 1] = {0};
193 	char value[STR_LEN + 1] = {0};
194 
195 	if (ReadItemValue(line, len, item, WORD_LEN, value, STR_LEN) < 0)
196 		return;
197 
198 	if (TRY_ASSIGN_NUM(nb_mem_channels, conf, item, value));
199 	else if (TRY_ASSIGN_NUM(forward,         conf, item, value));
200 	else if (TRY_ASSIGN_NUM(max_concurrency, conf, item, value));
201 	else if (TRY_ASSIGN_NUM(rmem_size,       conf, item, value));
202 	else if (TRY_ASSIGN_NUM(wmem_size,       conf, item, value));
203 	else if (TRY_ASSIGN_NUM(tcp_tw_interval, conf, item, value))
204 		g_config.mos->tcp_tw_interval =
205 			SEC_TO_USEC(g_config.mos->tcp_tw_interval) / TIME_TICK;
206 	else if (TRY_ASSIGN_NUM(tcp_timeout,     conf, item, value))
207 		g_config.mos->tcp_timeout =
208 			SEC_TO_USEC(g_config.mos->tcp_timeout) / TIME_TICK;
209 	else if (TRY_ASSIGN_NUM(no_ring_buffers, conf, item, value));
210 	else if (TRY_ASSIGN_STR(mos_log,         conf, item, value));
211 	else if (TRY_ASSIGN_STR(stat_print,      conf, item, value));
212 	else if (TRY_ASSIGN_STR(port,            conf, item, value));
213 	else if (strcmp(item, "multiprocess") == 0) {
214 		conf->multiprocess = 1;
215 		SetMultiProcessSupport(value);
216 	}
217 }
218 /*----------------------------------------------------------------------------*/
219 static void
FeedNetdevConfLine(struct conf_block * blk,char * line,int len)220 FeedNetdevConfLine(struct conf_block *blk, char *line, int len)
221 {
222 	struct netdev_conf * const conf = (struct netdev_conf *)blk->conf;
223 
224 #ifndef DARWIN
225 	int i;
226 #endif
227 	uint64_t cpu_mask;
228 	char *word = NULL;
229 	int wlen;
230 
231 	if (DetectWord(line, len, &word, &wlen) < 0 || wlen > WORD_LEN || wlen <= 0)
232 		return;
233 
234 	line = word + wlen;
235 
236 	if (sscanf(line, "%li", &cpu_mask) <= 0)
237 		return;
238 
239 	struct netdev_entry *ent = calloc(1, sizeof(struct netdev_entry));
240 	if (!ent) {
241 		TRACE_ERROR("Could not allocate memory for netdev_entry!\n");
242 		exit(EXIT_FAILURE);
243 	}
244 
245 	strncpy(ent->dev_name, word, wlen);
246 	ent->cpu_mask = cpu_mask;
247 	g_config.mos->cpu_mask |= cpu_mask;
248 
249 	strncpy(ent->ifr.ifr_name, ent->dev_name, IFNAMSIZ-1);
250 	ent->ifr.ifr_name[IFNAMSIZ-1] = '\0';
251 
252 	/* Create socket */
253 	int sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
254 	if (sock == -1) {
255 		perror("socket");
256 		exit(EXIT_FAILURE);
257 	}
258 
259 	/* getting address */
260 	if (ioctl(sock, SIOCGIFADDR, &ent->ifr) == 0 ) {
261 		struct in_addr sin = ((struct sockaddr_in *)&ent->ifr.ifr_addr)->sin_addr;
262 		ent->ip_addr = *(uint32_t *)&sin;
263 	}
264 
265 	/* Net MASK */
266 	if (ioctl(sock, SIOCGIFNETMASK, &ent->ifr) == 0) {
267 		struct in_addr sin = ((struct sockaddr_in *)&ent->ifr.ifr_addr)->sin_addr;
268 		ent->netmask = *(uint32_t *)&sin;
269 	}
270 
271 #ifdef DARWIN
272 	/* FIXME: How can I retrieve a mac address in MAC OS? */
273 #else
274 	if (ioctl(sock, SIOCGIFHWADDR, &ent->ifr) == 0 ) {
275 		for (i = 0; i < 6; i ++) {
276 			ent->haddr[i] = ent->ifr.ifr_addr.sa_data[i];
277 		}
278 	}
279 #endif
280 
281 	close(sock);
282 
283 	ent->ifindex = -1;
284 
285 	TAILQ_INSERT_TAIL(&conf->list, ent, link);
286 	conf->ent[conf->num] = ent;
287 	conf->num++;
288 }
289 /*----------------------------------------------------------------------------*/
290 static void
FeedArpConfLine(struct conf_block * blk,char * line,int len)291 FeedArpConfLine(struct conf_block *blk, char *line, int len)
292 {
293 	struct arp_conf * const conf = (struct arp_conf *)blk->conf;
294 
295 	char address[WORD_LEN];
296 	int prefix;
297 	uint8_t haddr[ETH_ALEN] = {0};
298 
299 	/* skip first space */
300 	while (isspace(*line))
301 		line++, len--;
302 
303 	if (sscanf(line, "%[0-9.]/%d %hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
304 				address, &prefix, &haddr[0], &haddr[1], &haddr[2],
305 				&haddr[3], &haddr[4], &haddr[5]) != 8)
306 		return;
307 
308 	struct _arp_entry *ent = calloc(1, sizeof(struct _arp_entry));
309 	if (!ent) {
310 		TRACE_ERROR("Could not allocate memory for arp_entry!\n");
311 		exit(EXIT_FAILURE);
312 	}
313 
314 	ent->ip = inet_addr(address);
315 	ent->prefix = prefix;
316 	ent->mask = htonl((prefix == 0) ? 0 : ((-1) << (32 - prefix)));
317 	ent->masked_ip = ent->mask & ent->ip;
318 	memcpy(ent->haddr, haddr, ETH_ALEN);
319 	TAILQ_INSERT_TAIL(&conf->list, ent, link);
320 	conf->ent[conf->num] = ent;
321 	conf->num++;
322 }
323 /*----------------------------------------------------------------------------*/
324 static void
FeedRouteConfLine(struct conf_block * blk,char * line,int len)325 FeedRouteConfLine(struct conf_block *blk, char *line, int len)
326 {
327 	struct route_conf * const conf = (struct route_conf *)blk->conf;
328 
329 	char address[WORD_LEN], dev_name[WORD_LEN];
330 	int prefix;
331 
332 	/* skip first space */
333 	while (isspace(*line))
334 		line++, len--;
335 
336 	if (sscanf(line, "%[0-9.]/%d %[^ ^\n^\t]", address, &prefix, dev_name) != 3)
337 		return;
338 
339 	struct route_entry *ent = calloc(1, sizeof(struct route_entry));
340 	if (!ent) {
341 		TRACE_ERROR("Could not allocate memory for route_entry!\n");
342 		exit(EXIT_FAILURE);
343 	}
344 
345 	ent->ip = inet_addr(address);
346 	ent->mask = htonl((prefix == 0) ? 0 : ((-1) << (32 - prefix)));
347 	ent->masked_ip = ent->mask & ent->ip;
348 	ent->prefix = prefix;
349 	ent->nif = -1;
350 	strcpy(ent->dev_name, dev_name);
351 
352 	TAILQ_INSERT_TAIL(&conf->list, ent, link);
353 	conf->ent[conf->num] = ent;
354 	conf->num++;
355 }
356 /*----------------------------------------------------------------------------*/
357 static void
FeedNICFwdConfLine(struct conf_block * blk,char * line,int len)358 FeedNICFwdConfLine(struct conf_block *blk, char *line, int len)
359 {
360 	struct nic_forward_conf * const conf = (struct nic_forward_conf *)blk->conf;
361 	char dev_name_in[WORD_LEN];
362 	char dev_name_out[WORD_LEN];
363 
364 	/* skip first space */
365 	while (isspace(*line))
366 		line++, len--;
367 
368 	if (sscanf(line, "%[^ ^\n^\t] %[^ ^\n^\t]", dev_name_in, dev_name_out) != 2)
369 		return;
370 
371 	struct nic_forward_entry *ent = calloc(1, sizeof(struct nic_forward_entry));
372 	if (!ent) {
373 		TRACE_ERROR("Could not allocate memory for nic forward entry!\n");
374 		exit(EXIT_FAILURE);
375 	}
376 
377 	strcpy(ent->nif_in, dev_name_in);
378 	strcpy(ent->nif_out, dev_name_out);
379 	TAILQ_INSERT_TAIL(&conf->list, ent, link);
380 	conf->ent[conf->num] = ent;
381 	conf->num++;
382 }
383 /*----------------------------------------------------------------------------*/
384 static void
MosConfAddChild(struct conf_block * blk,struct conf_block * child)385 MosConfAddChild(struct conf_block *blk, struct conf_block *child)
386 {
387 	struct mos_conf * const conf = (struct mos_conf *)blk->conf;
388 
389 	if (strcmp(child->name, NETDEV_BLOCK_NAME) == 0) {
390 		conf->netdev = child;
391 		conf->netdev_table = (struct netdev_conf *)child->conf;
392 	} else if (strcmp(child->name, ARP_BLOCK_NAME) == 0) {
393 		conf->arp = child;
394 		conf->arp_table = (struct arp_conf *)child->conf;
395 	} else if (strcmp(child->name, ROUTE_BLOCK_NAME) == 0) {
396 		conf->route = child;
397 		conf->route_table = (struct route_conf *)child->conf;
398 	} else if (strcmp(child->name, FORWARD_BLOCK_NAME) == 0) {
399 		conf->nic_forward = child;
400 		conf->nic_forward_table = (struct nic_forward_conf *)child->conf;
401 	} else
402 		return;
403 }
404 /*----------------------------------------------------------------------------*/
405 static int
AppConfIsValid(struct conf_block * blk)406 AppConfIsValid(struct conf_block *blk)
407 {
408 	struct app_conf * const conf = (struct app_conf *)blk->conf;
409 
410 	if (conf->app_argc <= 0)
411 		return 0;
412 
413 	return 1;
414 }
415 /*----------------------------------------------------------------------------*/
416 static int
MosConfIsValid(struct conf_block * blk)417 MosConfIsValid(struct conf_block *blk)
418 {
419 	return 1;
420 }
421 /*----------------------------------------------------------------------------*/
422 static int
NetdevConfIsValid(struct conf_block * blk)423 NetdevConfIsValid(struct conf_block *blk)
424 {
425 	return 1;
426 }
427 /*----------------------------------------------------------------------------*/
428 static int
ArpConfIsValid(struct conf_block * blk)429 ArpConfIsValid(struct conf_block *blk)
430 {
431 	return 1;
432 }
433 /*----------------------------------------------------------------------------*/
434 static int
RouteConfIsValid(struct conf_block * blk)435 RouteConfIsValid(struct conf_block *blk)
436 {
437 	return 1;
438 }
439 /*----------------------------------------------------------------------------*/
440 static int
NICFwdConfIsValid(struct conf_block * blk)441 NICFwdConfIsValid(struct conf_block *blk)
442 {
443 	return 1;
444 }
445 /*----------------------------------------------------------------------------*/
446 static void
NetdevConfPrint(struct conf_block * blk)447 NetdevConfPrint(struct conf_block *blk)
448 {
449 	struct netdev_conf * const conf = (struct netdev_conf *)blk->conf;
450 
451 	printf(" +===== Netdev configuration (%d entries) =====\n",
452 			conf->num);
453 
454 	struct netdev_entry *walk;
455 	TAILQ_FOREACH(walk, &conf->list, link) {
456 		printf(" | %s(idx: %d, HADDR: %02hhX:%02hhX:%02hhX:%02hhX:%02hhX:%02hhX) maps to CPU 0x%016lX\n",
457 				walk->dev_name, walk->ifindex,
458 				walk->haddr[0], walk->haddr[1], walk->haddr[2],
459 				walk->haddr[3], walk->haddr[4], walk->haddr[5],
460 				walk->cpu_mask);
461 	}
462 	printf(" |\n");
463 }
464 /*----------------------------------------------------------------------------*/
465 static void
ArpConfPrint(struct conf_block * blk)466 ArpConfPrint(struct conf_block *blk)
467 {
468 	struct arp_conf * const conf = (struct arp_conf *)blk->conf;
469 
470 	printf(" +===== Static ARP table configuration (%d entries) =====\n",
471 			conf->num);
472 
473 	struct _arp_entry *walk;
474 	TAILQ_FOREACH(walk, &conf->list, link) {
475 		printf(" | IP: 0x%08X, NETMASK: 0x%08X, "
476 			   "HADDR: %02hhX:%02hhX:%02hhX:%02hhX:%02hhX:%02hhX\n",
477 			   ntohl(walk->ip), ntohl(walk->mask),
478 			   walk->haddr[0], walk->haddr[1], walk->haddr[2],
479 			   walk->haddr[3], walk->haddr[4], walk->haddr[5]);
480 	}
481 	printf(" |\n");
482 }
483 /*----------------------------------------------------------------------------*/
484 static void
RouteConfPrint(struct conf_block * blk)485 RouteConfPrint(struct conf_block *blk)
486 {
487 	struct route_conf * const conf = (struct route_conf *)blk->conf;
488 
489 	printf(" +===== Routing table configuration (%d entries) =====\n",
490 			conf->num);
491 
492 	struct route_entry *walk;
493 	TAILQ_FOREACH(walk, &conf->list, link) {
494 		printf(" | IP: 0x%08X, NETMASK: 0x%08X, INTERFACE: %s(idx: %d)\n",
495 			   ntohl(walk->ip), ntohl(walk->mask), walk->dev_name, walk->nif);
496 	}
497 	printf(" |\n");
498 }
499 /*----------------------------------------------------------------------------*/
500 static void
NICFwdConfPrint(struct conf_block * blk)501 NICFwdConfPrint(struct conf_block *blk)
502 {
503 	int i;
504 	struct nic_forward_conf * const conf = (struct nic_forward_conf *)blk->conf;
505 
506 	printf(" +===== NIC Forwarding table configuration (%d entries) =====\n",
507 			conf->num);
508 
509 	struct nic_forward_entry *walk;
510 	TAILQ_FOREACH(walk, &conf->list, link) {
511 		printf(" | NIC Forwarding Entry: %s <---> %s",
512 		       walk->nif_in, walk->nif_out);
513 	}
514 	printf(" |\n");
515 
516 	printf(" | NIC Forwarding Index Table: |\n");
517 
518 	for (i = 0; i < MAX_FORWARD_ENTRY; i++)
519 		printf( " | %d --> %d | \n", i, conf->nic_fwd_table[i]);
520 }
521 /*----------------------------------------------------------------------------*/
522 static void
AppConfPrint(struct conf_block * blk)523 AppConfPrint(struct conf_block *blk)
524 {
525 	struct app_conf * const conf = (struct app_conf *)blk->conf;
526 
527 	printf("===== Application configuration =====\n");
528 	printf("| type:       %s\n", conf->type);
529 	printf("| run:        %s\n", conf->run);
530 	printf("| cpu_mask:   0x%016lX\n", conf->cpu_mask);
531 	printf("| ip_forward: %s\n", conf->ip_forward ? "forward" : "drop");
532 	printf("\n");
533 }
534 /*----------------------------------------------------------------------------*/
535 static void
MosConfPrint(struct conf_block * blk)536 MosConfPrint(struct conf_block *blk)
537 {
538 	struct mos_conf * const conf = (struct mos_conf *)blk->conf;
539 
540 	printf("===== MOS configuration =====\n");
541 	printf("| num_cores:       %d\n", conf->num_cores);
542 	printf("| nb_mem_channels: %d\n", conf->nb_mem_channels);
543 	printf("| max_concurrency: %d\n", conf->max_concurrency);
544 	printf("| rmem_size:       %d\n", conf->rmem_size);
545 	printf("| wmem_size:       %d\n", conf->wmem_size);
546 	printf("| tcp_tw_interval: %d\n", conf->tcp_tw_interval);
547 	printf("| tcp_timeout:     %d\n", conf->tcp_timeout);
548 	printf("| multiprocess:    %s\n", conf->multiprocess ? "true" : "false");
549 	printf("| mos_log:         %s\n", conf->mos_log);
550 	printf("| stat_print:      %s\n", conf->stat_print);
551 	printf("| forward:         %s\n", conf->forward ? "forward" : "drop");
552 	printf("|\n");
553 	if (conf->netdev)
554 		conf->netdev->print(conf->netdev);
555 	if (conf->arp)
556 		conf->arp->print(conf->arp);
557 	if (conf->route)
558 		conf->route->print(conf->route);
559 	if (conf->nic_forward)
560 		conf->nic_forward->print(conf->nic_forward);
561 	printf("\n");
562 }
563 /*----------------------------------------------------------------------------*/
564 static void
InitAppBlock(struct config * config,struct conf_block * blk)565 InitAppBlock(struct config *config, struct conf_block *blk)
566 {
567 	assert(blk);
568 
569 	blk->name = APP_BLOCK_NAME;
570 
571 	blk->feed = FeedAppConfLine;
572 	blk->addchild = NULL;
573 	blk->isvalid = AppConfIsValid;
574 	blk->print = AppConfPrint;
575 
576 	struct app_conf *conf = calloc(1, sizeof(struct app_conf));
577 	if (conf == NULL) {
578 		TRACE_ERROR("Could not allocate memory for app_conf!\n");
579 		exit(EXIT_FAILURE);
580 	}
581 	/* set default values */
582 	conf->cpu_mask = -1;
583 	conf->ip_forward = 1;
584 	conf->app_argc = 0;
585 	blk->conf = conf;
586 
587 	blk->list = (typeof(blk->list))&config->app_blkh;
588 }
589 /*----------------------------------------------------------------------------*/
590 static void
InitMosBlock(struct config * config,struct conf_block * blk)591 InitMosBlock(struct config *config, struct conf_block *blk)
592 {
593 	assert(blk);
594 
595 	blk->name = MOS_BLOCK_NAME;
596 
597 	blk->feed = FeedMosConfLine;
598 	blk->addchild = MosConfAddChild;
599 	blk->isvalid = MosConfIsValid;
600 	blk->print = MosConfPrint;
601 
602 	struct mos_conf *conf = calloc(1, sizeof(struct mos_conf));
603 	if (conf == NULL) {
604 		TRACE_ERROR("Could not allocate memory for mos_conf!\n");
605 		exit(EXIT_FAILURE);
606 	}
607 	/* set default values */
608 	conf->forward = 1;
609 	conf->nb_mem_channels = 0;
610 	conf->max_concurrency = 100000;
611 	conf->no_ring_buffers = 0;
612 	conf->rmem_size = 8192;
613 	conf->wmem_size = 8192;
614 	conf->tcp_tw_interval = SEC_TO_USEC(TCP_TIMEWAIT) / TIME_TICK;
615 	conf->tcp_timeout = SEC_TO_USEC(TCP_TIMEOUT) / TIME_TICK;
616 	conf->cpu_mask = 0;
617 	blk->conf = conf;
618 
619 	blk->list = (typeof(blk->list))&config->mos_blkh;
620 	config->mos = conf;
621 }
622 /*----------------------------------------------------------------------------*/
623 static void
InitNetdevBlock(struct config * config,struct conf_block * blk)624 InitNetdevBlock(struct config *config, struct conf_block *blk)
625 {
626 	assert(blk);
627 
628 	blk->name = NETDEV_BLOCK_NAME;
629 
630 	blk->feed = FeedNetdevConfLine;
631 	blk->addchild = NULL;
632 	blk->isvalid = NetdevConfIsValid;
633 	blk->print = NetdevConfPrint;
634 
635 	struct netdev_conf *conf = calloc(1, sizeof(struct netdev_conf));
636 	if (conf == NULL) {
637 		TRACE_ERROR("Could not allocate memory for netdev_conf!\n");
638 		exit(EXIT_FAILURE);
639 	}
640 	TAILQ_INIT(&conf->list);
641 	blk->conf = conf;
642 
643 	blk->list = NULL;
644 }
645 /*----------------------------------------------------------------------------*/
646 static void
FetchARPKernelEntries(struct arp_conf * const config)647 FetchARPKernelEntries(struct arp_conf * const config)
648 {
649 #define	_PATH_PROCNET_ARP		"/proc/net/arp"
650 #define	DPDK_PREFIX			"dpdk"
651 #define DPDK_PREFIX_LEN			4
652 #define LINE_LEN			200
653 #define ENTRY_LEN			25
654 
655 	FILE *fp;
656 	char ip[ENTRY_LEN];
657 	char hwa[ENTRY_LEN];
658 	char mask[ENTRY_LEN];
659 	char dev[WORD_LEN];
660 	char line[LINE_LEN];
661 	int type, flags, num;
662 
663 	if ((fp = fopen(_PATH_PROCNET_ARP, "r")) == NULL) {
664 		perror(_PATH_PROCNET_ARP);
665 		exit(EXIT_FAILURE);
666 	}
667 
668 	/* Bypass header -- read until newline */
669 	if (fgets(line, sizeof(line), fp) != (char *) NULL) {
670 		strcpy(mask, "-");
671 		strcpy(dev, "-");
672 		/* Read the ARP cache entries. */
673 		for (; fgets(line, sizeof(line), fp);) {
674 
675 			num = sscanf(line, "%s 0x%x 0x%x %100s %100s %100s\n",
676 				     ip, &type, &flags, hwa, mask, dev);
677 			if (num < 6)
678 				break;
679 
680 			/* if the user specified device differs, skip it */
681 			if (strncmp(dev, DPDK_PREFIX, DPDK_PREFIX_LEN))
682 				continue;
683 
684 			/* if the entry has not expired/tagged for removal then... */
685 			if (flags != 0x00) {
686 				/* add the new arp entry in MOS database */
687 				struct _arp_entry *ent = calloc(1, sizeof(struct _arp_entry));
688 				if (!ent) {
689 					TRACE_ERROR("Can't allocate memory for arp_entry\n");
690 					exit(EXIT_FAILURE);
691 				}
692 				uint8_t haddr[ETH_ALEN] = {0};
693 				if (sscanf(hwa, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
694 					   &haddr[0], &haddr[1], &haddr[2],
695 					   &haddr[3], &haddr[4], &haddr[5]) != 6) {
696 					TRACE_ERROR("Error reading the ARP entry\n");
697 					exit(EXIT_FAILURE);
698 				}
699 				ent->ip = inet_addr(ip);
700 				ent->prefix = 32;
701 				ent->mask = htonl((ent->prefix == 0) ? 0 : ((-1) << (32 - ent->prefix)));
702 				ent->masked_ip = ent->mask & ent->ip;
703 				memcpy(ent->haddr, haddr, ETH_ALEN);
704 				TAILQ_INSERT_TAIL(&config->list, ent, link);
705 				config->ent[config->num] = ent;
706 				config->num++;
707 			}
708 		}
709 	}
710 
711 	fclose(fp);
712 }
713 /*----------------------------------------------------------------------------*/
714 static void
FetchRouteKernelEntries(struct route_conf * const config)715 FetchRouteKernelEntries(struct route_conf * const config)
716 {
717 #define	_PATH_PROCNET_ROUTE		"/proc/net/route"
718 #define	DPDK_PREFIX			"dpdk"
719 #define DPDK_PREFIX_LEN			4
720 
721 	FILE *fp;
722 	uint32_t gate;
723 	uint32_t dest;
724 	uint32_t mask;
725 	char dev[WORD_LEN];
726 	char line[LINE_LEN];
727 	char mtu[ENTRY_LEN];
728 	char win[ENTRY_LEN];
729 	char irtt[ENTRY_LEN];
730 	int flags, num, cnt, use, metric;
731 
732 	if ((fp = fopen(_PATH_PROCNET_ROUTE, "r")) == NULL) {
733 		perror(_PATH_PROCNET_ARP);
734 		exit(EXIT_FAILURE);
735 	}
736 
737 	/* Bypass header -- read until newline */
738 	if (fgets(line, sizeof(line), fp) != (char *) NULL) {
739 		/* Read the route table entries. */
740 		for (; fgets(line, sizeof(line), fp);) {
741 
742 			num = sscanf(line, "%s %08X %08X %d %d %d %d %08X %s %s %s\n",
743 				     dev,
744 				     &dest,
745 				     &gate,
746 				     &flags, &cnt, &use, &metric,
747 				     &mask,
748 				     mtu, win, irtt);
749 
750 			if (num < 11)
751 				break;
752 #if 0
753 			/* if the user specified device differs, skip it */
754 			if (strncmp(dev, DPDK_PREFIX, DPDK_PREFIX_LEN))
755 				continue;
756 #endif
757 			struct route_entry *ent = calloc(1, sizeof(struct route_entry));
758 			if (!ent) {
759 				TRACE_ERROR("Could not allocate memory for route_entry!\n");
760 				exit(EXIT_FAILURE);
761 			}
762 
763 			ent->ip = dest;
764 
765 			/* __builtin_clz() returns undefined output with zero */
766 			if (mask == 0)
767 				ent->prefix = 0;
768 			else
769 				ent->prefix = 32 - __builtin_clz(mask);
770 			ent->mask = mask;
771 			ent->masked_ip = ent->mask & ent->ip;
772 			strcpy(ent->dev_name, dev);
773 			TAILQ_INSERT_TAIL(&config->list, ent, link);
774 			config->ent[config->num] = ent;
775 			config->num++;
776 		}
777 	}
778 
779 	fclose(fp);
780 }
781 /*----------------------------------------------------------------------------*/
782 static void
InitArpBlock(struct config * config,struct conf_block * blk)783 InitArpBlock(struct config *config, struct conf_block *blk)
784 {
785 	assert(blk);
786 
787 	blk->name = ARP_BLOCK_NAME;
788 
789 	blk->feed = FeedArpConfLine;
790 	blk->addchild = NULL;
791 	blk->isvalid = ArpConfIsValid;
792 	blk->print = ArpConfPrint;
793 
794 	struct arp_conf *conf = calloc(1, sizeof(struct arp_conf));
795 	if (conf == NULL) {
796 		TRACE_ERROR("Could not allocate memory for arp_conf!\n");
797 		exit(EXIT_FAILURE);
798 	}
799 	TAILQ_INIT(&conf->list);
800 	blk->conf = conf;
801 
802 	blk->list = NULL;
803 	config->mos->arp = blk;
804 
805 	/* fetch relevant ARP entries for dpdk? from kernel tables */
806 	FetchARPKernelEntries(conf);
807 }
808 /*----------------------------------------------------------------------------*/
809 static void
InitRouteBlock(struct config * config,struct conf_block * blk)810 InitRouteBlock(struct config *config, struct conf_block *blk)
811 {
812 	assert(blk);
813 
814 	blk->name = ROUTE_BLOCK_NAME;
815 
816 	blk->feed = FeedRouteConfLine;
817 	blk->addchild = NULL;
818 	blk->isvalid = RouteConfIsValid;
819 	blk->print = RouteConfPrint;
820 
821 	struct route_conf *conf = calloc(1, sizeof(struct route_conf));
822 	if (conf == NULL) {
823 		TRACE_ERROR("Could not allocate memory for route_conf!\n");
824 		exit(EXIT_FAILURE);
825 	}
826 	TAILQ_INIT(&conf->list);
827 	blk->conf = conf;
828 
829 	blk->list = NULL;
830 	config->mos->route = blk;
831 
832 	/* fetch relevant route entries for dpdk? from kernel tables */
833 	FetchRouteKernelEntries(conf);
834 }
835 /*----------------------------------------------------------------------------*/
836 static void
InitNICForwardBlock(struct config * config,struct conf_block * blk)837 InitNICForwardBlock(struct config *config, struct conf_block *blk)
838 {
839 	int i;
840 	assert(blk);
841 	blk->name = FORWARD_BLOCK_NAME;
842 
843 	blk->feed = FeedNICFwdConfLine;
844 	blk->addchild = NULL;
845 	blk->isvalid = NICFwdConfIsValid;
846 	blk->print = NICFwdConfPrint;
847 
848 	struct nic_forward_conf *conf = calloc(1, sizeof(struct nic_forward_conf));
849 	if (conf == NULL) {
850 		TRACE_ERROR("Could not allocate memory for nic_forward_conf!\n");
851 		exit(EXIT_FAILURE);
852 	}
853 	for (i = 0; i < MAX_FORWARD_ENTRY; i++)
854 		conf->nic_fwd_table[i] = -1;
855 
856 	TAILQ_INIT(&conf->list);
857 	blk->conf = conf;
858 
859 	blk->list = NULL;
860 	config->mos->nic_forward = blk;
861 }
862 /*----------------------------------------------------------------------------*/
863 void
PrintConf(struct config * conf)864 PrintConf(struct config *conf)
865 {
866 	struct conf_block *walk;
867 	TAILQ_FOREACH(walk, &conf->app_blkh, link) {
868 		if (walk->print)
869 			walk->print(walk);
870 	}
871 
872 	TAILQ_FOREACH(walk, &conf->mos_blkh, link) {
873 		if (walk->print)
874 			walk->print(walk);
875 	}
876 }
877 /*----------------------------------------------------------------------------*/
878 static void
CheckConfValidity(struct config * conf)879 CheckConfValidity(struct config *conf)
880 {
881 	struct conf_block *walk;
882 	TAILQ_FOREACH(walk, &conf->app_blkh, link) {
883 		if (!walk->isvalid || !walk->isvalid(walk))
884 			goto __error;
885 	}
886 
887 	TAILQ_FOREACH(walk, &conf->mos_blkh, link) {
888 		struct conf_block *child;
889 
890 		if (!walk->isvalid || !walk->isvalid(walk))
891 			goto __error;
892 
893 		child = ((struct mos_conf *)walk->conf)->netdev;
894 		if (!child->isvalid || !child->isvalid(child))
895 			goto __error;
896 
897 		child = ((struct mos_conf *)walk->conf)->arp;
898 		if (!child->isvalid || !child->isvalid(child))
899 			goto __error;
900 
901 		child = ((struct mos_conf *)walk->conf)->route;
902 		if (!child->isvalid || !child->isvalid(child))
903 			goto __error;
904 	}
905 
906 	return;
907 
908 __error:
909 	printf("!!!!! Configuration validity check failure !!!!!\n");
910 	if (walk && walk->print)
911 		walk->print(walk);
912 	exit(0);
913 }
914 /*----------------------------------------------------------------------------*/
915 static char *
ReadConf(const char * fname)916 ReadConf(const char *fname)
917 {
918 	ssize_t hav_read = 0, rc;
919 	FILE *fp = fopen(fname, "r");
920 	if (fp == NULL) {
921 		TRACE_ERROR("Cannot open the config file %s\n", fname);
922 		exit(-1);
923 	}
924 
925 	/* find out the size of file */
926 	fseek(fp, 0L, SEEK_END);
927 	int size = ftell(fp);
928 	fseek(fp, 0L, SEEK_SET);
929 
930 	file = calloc(1, size + 1);
931 	if (file == NULL) {
932 		TRACE_ERROR("Can't allocate memory for file!\n");
933 		exit(EXIT_FAILURE);
934 	}
935 
936 	file[size] = '\0';
937 
938 	while (hav_read < size) {
939 		rc = fread(file, 1, size, fp);
940 		/* sanity check */
941 		if (rc <= 0) break;
942 		hav_read += rc;
943 	}
944 
945 	fclose(fp);
946 
947 	return file;
948 }
949 /*----------------------------------------------------------------------------*/
950 static char *
PreprocessConf(char * raw)951 PreprocessConf(char *raw)
952 {
953 	char *line;
954 	int llen;
955 
956 	int len = strlen(raw);
957 
958 	LINE_FOREACH(line, llen, raw, len) {
959 		int i, iscomment = 0;
960 		for (i = 0; i < llen; i++) {
961 			if (!iscomment && line[i] == '#')
962 				iscomment = 1;
963 			if (iscomment)
964 				line[i] = ' ';
965 		}
966 	}
967 	return raw;
968 }
969 /*----------------------------------------------------------------------------*/
970 static void
InitConfig(struct config * config)971 InitConfig(struct config *config)
972 {
973 	int i;
974 	struct conf_block *blk;
975 
976 	TAILQ_INIT(&g_free_blkh);
977 	TAILQ_INIT(&config->app_blkh);
978 	TAILQ_INIT(&config->mos_blkh);
979 
980 	for (i = 0; i < MAX_APP_BLOCK; i++) {
981 		/* Allocate app conf_block */
982 		blk = calloc(1, sizeof(struct conf_block));
983 		if (blk == NULL) goto init_config_err;
984 		InitAppBlock(config, blk);
985 		TAILQ_INSERT_TAIL(&g_free_blkh, blk, link);
986 
987 		/* Allocate netdev conf_block */
988 		blk = calloc(1, sizeof(struct conf_block));
989 		if (blk == NULL) goto init_config_err;
990 		InitNetdevBlock(config, blk);
991 		TAILQ_INSERT_TAIL(&g_free_blkh, blk, link);
992 	}
993 
994 	for (i = 0; i < MAX_MOS_BLOCK; i++) {
995 		/* Allocate mos conf_block */
996 		blk = calloc(1, sizeof(struct conf_block));
997 		if (blk == NULL) goto init_config_err;
998 		InitMosBlock(config, blk);
999 		TAILQ_INSERT_TAIL(&g_free_blkh, blk, link);
1000 
1001 		/* Allocate arp conf_block */
1002 		blk = calloc(1, sizeof(struct conf_block));
1003 		if (blk == NULL) goto init_config_err;
1004 		InitArpBlock(config, blk);
1005 		TAILQ_INSERT_TAIL(&g_free_blkh, blk, link);
1006 
1007 		/* Allocate route conf_block */
1008 		blk = calloc(1, sizeof(struct conf_block));
1009 		if (blk == NULL) goto init_config_err;
1010 		InitRouteBlock(config, blk);
1011 		TAILQ_INSERT_TAIL(&g_free_blkh, blk, link);
1012 
1013 		/* Allocate nic_forward conf_block */
1014 		blk = calloc (1, sizeof(struct conf_block));
1015 		if (blk == NULL) goto init_config_err;
1016 		InitNICForwardBlock(config, blk);
1017 		TAILQ_INSERT_TAIL(&g_free_blkh, blk, link);
1018 	}
1019 	return;
1020  init_config_err:
1021 	TRACE_ERROR("Can't allocate memory for blk_entry!\n");
1022 	exit(EXIT_FAILURE);
1023 }
1024 /*----------------------------------------------------------------------------*/
1025 static struct conf_block *
AllocateBlock(char * name,int len)1026 AllocateBlock(char *name, int len)
1027 {
1028 	struct conf_block *walk, *tmp;
1029 
1030 	for (walk = TAILQ_FIRST(&g_free_blkh); walk != NULL; walk = tmp) {
1031 		tmp = TAILQ_NEXT(walk, link);
1032 		if (len == strlen(walk->name) && strncmp(walk->name, name, len) == 0) {
1033 			TAILQ_REMOVE(&g_free_blkh, walk, link);
1034 			if (walk->list)
1035 				TAILQ_INSERT_TAIL(walk->list, walk, link);
1036 			return walk;
1037 		}
1038 	}
1039 
1040 	return NULL;
1041 }
1042 /*----------------------------------------------------------------------------*/
1043 struct conf_block *
DetectBlock(struct conf_block * blk,char * buf,int len)1044 DetectBlock(struct conf_block *blk, char *buf, int len)
1045 {
1046 	int depth = 0;
1047 	char *blkname = NULL, *end = &buf[len];
1048 	int blknamelen;
1049 	struct conf_block *nblk;
1050 
1051 	/* skip first space */
1052 	while (buf < end && isspace(*buf))
1053 		buf++;
1054 
1055 	if (DetectWord(buf, len, &blkname, &blknamelen) < 0
1056 			|| blkname != buf)
1057 		/* Failed to detect conf_block name */
1058 		return NULL;
1059 
1060 	/* fast forward buffer */
1061 	buf += blknamelen;
1062 
1063 	/* skip space */
1064 	while (buf < end && isspace(*buf))
1065 		buf++;
1066 
1067 	/* buf must be '{' */
1068 	if (buf >= end || *buf != '{')
1069 		return NULL;
1070 
1071 	buf++;   /* skip '{' */
1072 	while (buf < end && isspace(*buf))
1073 		buf++; /* skip space */
1074 	depth++; /* Now in first parenthesis */
1075 
1076 	/* Now, the `buf` points the first byte inside conf_block */
1077 
1078 	for (len = 0; &buf[len] < end; len++) {
1079 		if (buf[len] == '{')
1080 			depth++;
1081 		else if (buf[len] == '}' && --depth == 0)
1082 				break;
1083 	}
1084 
1085 	if (depth != 0)
1086 		/* Failed to find the end of parenthesis */
1087 		return NULL;
1088 
1089 	if (!(nblk = AllocateBlock(blkname, blknamelen)))
1090 		return NULL;
1091 
1092 	if (blk) {
1093 		assert(blk->addchild);
1094 		blk->addchild(blk, nblk);
1095 	}
1096 
1097 	nblk->buf = buf;
1098 	nblk->len = len;
1099 
1100 	return nblk;
1101 }
1102 /*----------------------------------------------------------------------------*/
1103 static void
ParseBlock(struct conf_block * blk)1104 ParseBlock(struct conf_block *blk)
1105 {
1106 	char *line;
1107 	int llen;
1108 
1109 	LINE_FOREACH(line, llen, blk->buf, blk->len) {
1110 		struct conf_block *nblk;
1111 
1112 		if ((nblk = DetectBlock(blk, line, blk->len - (line - blk->buf)))) {
1113 			ParseBlock(nblk);
1114 			/* skip nested conf_block by fast forwarding line */
1115 			line = &nblk->buf[nblk->len] + 1;
1116 			llen = 0;
1117 		} else
1118 			blk->feed(blk, line, llen);
1119 	}
1120 }
1121 /*----------------------------------------------------------------------------*/
1122 void
PatchCONFIG(struct config * config)1123 PatchCONFIG(struct config *config)
1124 {
1125 	int i, count;
1126 	char *word, *str, *end;
1127 	int wlen;
1128 	uint64_t value;
1129 
1130 	value = g_config.mos->cpu_mask;
1131 	for (count = 0; value != 0; count++, value &= value-1);
1132 	if (count > num_cpus) {
1133 		TRACE_ERROR("CPU mask (%016lX) exceeds the number of CPU cores (%d)\n",
1134 					g_config.mos->cpu_mask, num_cpus);
1135 		exit(-1);
1136 	}
1137 	if (count > MAX_CPUS) {
1138 		TRACE_ERROR("mOS does not support more than %d CPU cores for now\n",
1139 					MAX_CPUS);
1140 		exit(-1);
1141 	}
1142 	g_config.mos->num_cores = count;
1143 
1144 	word = NULL;
1145 
1146 	i = 0;
1147 	struct conf_block *bwalk;
1148 	TAILQ_FOREACH(bwalk, &g_config.app_blkh, link) {
1149 		struct app_conf *app_conf = (struct app_conf *)bwalk->conf;
1150 		g_config.mos->forward = g_config.mos->forward && app_conf->ip_forward;
1151 		if (end_app_exists == 0 && !strcmp(app_conf->type, "end"))
1152 			end_app_exists = 1;
1153 		if (mon_app_exists == 0 && !strcmp(app_conf->type, "monitor"))
1154 			mon_app_exists = 1;
1155 		i++;
1156 	}
1157 	/* turn on monitor mode if end app is not set */
1158 	if (!end_app_exists && !mon_app_exists) mon_app_exists = 1;
1159 
1160 	/* stat print */
1161 	str = g_config.mos->stat_print;
1162 	end = str + strlen(str);
1163 	while (DetectWord(str, end - str, &word, &wlen) == 0) {
1164 		for (i = 0; i < g_config.mos->netdev_table->num; i++) {
1165 			if (strncmp(g_config.mos->netdev_table->ent[i]->dev_name, word, wlen) == 0) {
1166 				g_config.mos->netdev_table->ent[i]->stat_print = TRUE;
1167 			}
1168 		}
1169 		str = word + wlen;
1170 	}
1171 
1172 }
1173 /*----------------------------------------------------------------------------*/
1174 int
LoadConfigurationUpperHalf(const char * fname)1175 LoadConfigurationUpperHalf(const char *fname)
1176 {
1177 	char *line;
1178 	int llen;
1179 
1180 	char *raw = ReadConf(fname);
1181 	char *preprocessed = PreprocessConf(raw);
1182 	int len = strlen(preprocessed);
1183 
1184 	InitConfig(&g_config);
1185 
1186 	LINE_FOREACH(line, llen, preprocessed, len) {
1187 		struct conf_block *nblk;
1188 
1189 		if ((nblk = DetectBlock(NULL, line, len - (line - preprocessed)))) {
1190 			ParseBlock(nblk);
1191 			/* skip parsed conf_block by fast forwarding line */
1192 			line = &nblk->buf[nblk->len] + 1;
1193 			llen = 0;
1194 		}
1195 	}
1196 
1197 	CheckConfValidity(&g_config);
1198 
1199 	PatchCONFIG(&g_config);
1200 
1201 	//PrintConf(&g_config);
1202 
1203 	return 0;
1204 }
1205 /*----------------------------------------------------------------------------*/
1206 void
LoadConfigurationLowerHalf(void)1207 LoadConfigurationLowerHalf(void)
1208 {
1209 	struct route_conf *route_conf = g_config.mos->route_table;
1210 	struct netdev_conf *netdev_conf = g_config.mos->netdev_table;
1211 	struct nic_forward_conf *nicfwd_conf = g_config.mos->nic_forward_table;
1212 	struct route_entry *rwalk;
1213 	struct netdev_entry *nwalk;
1214 	struct nic_forward_entry *fwalk;
1215 	int nif_in = -1;
1216 	int nif_out = -1;
1217 
1218 	TAILQ_FOREACH(rwalk, &route_conf->list, link) {
1219 		TAILQ_FOREACH(nwalk, &netdev_conf->list, link) {
1220 			if (!strcmp(nwalk->dev_name, rwalk->dev_name))
1221 				break;
1222 		}
1223 		if (!nwalk)
1224 			continue;
1225 		if (nwalk->ifindex < 0 &&
1226 			(nwalk->ifindex = current_iomodule_func->get_nif(&nwalk->ifr)) < 0) {
1227 			TRACE_ERROR("Interface '%s' not found\n", nwalk->dev_name);
1228 			exit(EXIT_FAILURE);
1229 		}
1230 
1231 		rwalk->nif = nwalk->ifindex;
1232 	}
1233 
1234 	if (nicfwd_conf != NULL) {
1235 		TAILQ_FOREACH(fwalk, &nicfwd_conf->list, link) {
1236 			TAILQ_FOREACH(nwalk, &netdev_conf->list, link) {
1237 				if (!strcmp(nwalk->dev_name, fwalk->nif_in))
1238 					nif_in = nwalk->ifindex = current_iomodule_func->get_nif(&nwalk->ifr);
1239 				if (!strcmp(nwalk->dev_name, fwalk->nif_out))
1240 					nif_out = nwalk->ifindex = current_iomodule_func->get_nif(&nwalk->ifr);
1241 			}
1242 
1243 			if (nif_in != -1)
1244 				nicfwd_conf->nic_fwd_table[nif_in] = nif_out;
1245 			if (nif_out != -1)
1246 				nicfwd_conf->nic_fwd_table[nif_out] = nif_in;
1247 			nif_in = nif_out = -1;
1248 		}
1249 	}
1250 }
1251 /*----------------------------------------------------------------------------*/
1252 void
FreeConfigResources()1253 FreeConfigResources()
1254 {
1255 	if (file) {
1256 		free(file);
1257 		file = NULL;
1258 	}
1259 }
1260 /*----------------------------------------------------------------------------*/
1261 int
FetchEndianType()1262 FetchEndianType()
1263 {
1264 #ifdef ENABLE_DPDK
1265 	char *argv;
1266 	char **argp = &argv;
1267 
1268 	if (current_iomodule_func == &dpdk_module_func) {
1269 		/* dpdk_module_func logic down below */
1270 		dpdk_module_func.dev_ioctl(NULL, 0, DRV_NAME, (void *)argp);
1271 		if (!strcmp(*argp, "net_i40e"))
1272 			return 1;
1273 
1274 		return 0;
1275 	}
1276 #endif
1277 	return 1;
1278 }
1279 /*----------------------------------------------------------------------------*/
1280