xref: /mOS-networking-stack/core/src/config.c (revision 7245de1b)
176404edcSAsim Jamshed #include <stdlib.h>
276404edcSAsim Jamshed #include <assert.h>
376404edcSAsim Jamshed #include <sys/socket.h>
476404edcSAsim Jamshed #include <sys/ioctl.h>
576404edcSAsim Jamshed #include <sys/stat.h>
676404edcSAsim Jamshed #include <net/if.h>
776404edcSAsim Jamshed #include <arpa/inet.h>
876404edcSAsim Jamshed #include <netinet/in.h>
976404edcSAsim Jamshed #include <netdb.h>
1076404edcSAsim Jamshed #include <stdio.h>
1176404edcSAsim Jamshed #include <unistd.h>
1276404edcSAsim Jamshed #include <ctype.h>
1376404edcSAsim Jamshed #include <string.h>
1476404edcSAsim Jamshed 
1576404edcSAsim Jamshed #include "mtcp.h"
1676404edcSAsim Jamshed #include "config.h"
1776404edcSAsim Jamshed #include "tcp_in.h"
1876404edcSAsim Jamshed #include "arp.h"
1976404edcSAsim Jamshed #include "debug.h"
2076404edcSAsim Jamshed #include "mtcp_util.h"
2176404edcSAsim Jamshed /* for setting up io modules */
2276404edcSAsim Jamshed #include "io_module.h"
2376404edcSAsim Jamshed /* for if_nametoindex */
2476404edcSAsim Jamshed #include <net/if.h>
2576404edcSAsim Jamshed 
2676404edcSAsim Jamshed #define MAX_PROCLINE_LEN 1024
2776404edcSAsim Jamshed 
2876404edcSAsim Jamshed #ifdef DARWIN
2976404edcSAsim Jamshed #pragma GCC diagnostic ignored "-Wformat"
3076404edcSAsim Jamshed #pragma GCC diagnostic ignored "-Wempty-body"
3176404edcSAsim Jamshed #endif
3276404edcSAsim Jamshed 
3376404edcSAsim Jamshed /*----------------------------------------------------------------------------*/
3476404edcSAsim Jamshed int8_t end_app_exists = 0;
3576404edcSAsim Jamshed int8_t mon_app_exists = 0;
36a5e1a556SAsim Jamshed addr_pool_t ap[ETH_NUM] = {NULL};
378a941c7eSAsim Jamshed char *file = NULL;
3876404edcSAsim Jamshed /*----------------------------------------------------------------------------*/
3976404edcSAsim Jamshed /* return 0 on failure */
4076404edcSAsim Jamshed #define MATCH_ITEM(name, item) \
4176404edcSAsim Jamshed 	((strncmp(#name, item, strlen(#name)) == 0) \
4276404edcSAsim Jamshed 	 && (!isalnum(item[strlen(#name)])))
4376404edcSAsim Jamshed 
4476404edcSAsim Jamshed #define TRY_ASSIGN_NUM(name, base, item, value) \
4576404edcSAsim Jamshed 	((strncmp(#name, item, strlen(#name)) == 0) \
4676404edcSAsim Jamshed 	 && (!isalnum(item[strlen(#name)])) \
4776404edcSAsim Jamshed 	 && (sscanf(value, \
4876404edcSAsim Jamshed 			(sizeof((base)->name) == sizeof(char)) ? "%hhi" : \
4976404edcSAsim Jamshed 			(sizeof((base)->name) == sizeof(short)) ? "%hi" : \
5076404edcSAsim Jamshed 			(sizeof((base)->name) == sizeof(int)) ? "%i" : \
5176404edcSAsim Jamshed 			(sizeof((base)->name) == sizeof(long)) ? "%li" : \
5276404edcSAsim Jamshed 			(sizeof((base)->name) == sizeof(long long)) ? "%lli" : "ERROR", \
5376404edcSAsim Jamshed 			    &(base)->name) > 0))
5476404edcSAsim Jamshed 
5576404edcSAsim Jamshed #define TRY_ASSIGN_STR(name, base, item, value) \
5676404edcSAsim Jamshed 	(((strncmp(#name, item, strlen(#name)) == 0) \
5776404edcSAsim Jamshed 	  && (!isalnum(item[strlen(#name)])) \
5876404edcSAsim Jamshed 	  && (strlen(value) < sizeof((base)->name))) ? \
5976404edcSAsim Jamshed 	 (strcpy((base)->name, value), 1) : 0)
6076404edcSAsim Jamshed 
6176404edcSAsim Jamshed #define LINE_FOREACH(line, llen, buf, blen) \
6276404edcSAsim Jamshed 	for(line = buf, \
6376404edcSAsim Jamshed 		llen = ((strchr(line, '\n') == NULL) ? (buf + blen - line) \
6476404edcSAsim Jamshed 											 : strchr(line, '\n') - line); \
6576404edcSAsim Jamshed 		line + llen < buf + blen; \
6676404edcSAsim Jamshed 		line += llen + 1, \
6776404edcSAsim Jamshed 		llen = ((strchr(line, '\n') == NULL) ? (buf + blen - line) \
6876404edcSAsim Jamshed 											 : strchr(line, '\n') - line)) \
6976404edcSAsim Jamshed /*----------------------------------------------------------------------------*/
7076404edcSAsim Jamshed static int
SetMultiProcessSupport(char * multiprocess_details)7176404edcSAsim Jamshed SetMultiProcessSupport(char *multiprocess_details)
7276404edcSAsim Jamshed {
7376404edcSAsim Jamshed 	char *token = " =";
7476404edcSAsim Jamshed 	char *sample;
7576404edcSAsim Jamshed 	char *saveptr;
7676404edcSAsim Jamshed 
7776404edcSAsim Jamshed 	TRACE_CONFIG("Loading multi-process configuration\n");
7876404edcSAsim Jamshed 
7976404edcSAsim Jamshed 	sample = strtok_r(multiprocess_details, token, &saveptr);
8076404edcSAsim Jamshed 	if (sample == NULL) {
8176404edcSAsim Jamshed 		TRACE_CONFIG("No option for multi-process support given!\n");
8276404edcSAsim Jamshed 		return -1;
8376404edcSAsim Jamshed 	}
84c6a5549bSAsim Jamshed 	g_config.mos->multiprocess_curr_core = mystrtol(sample, 10);
8576404edcSAsim Jamshed 
8676404edcSAsim Jamshed 	sample = strtok_r(NULL, token, &saveptr);
8776404edcSAsim Jamshed 	if (sample != NULL && !strcmp(sample, "master"))
8876404edcSAsim Jamshed 		g_config.mos->multiprocess_is_master = 1;
8976404edcSAsim Jamshed 
9076404edcSAsim Jamshed 	return 0;
9176404edcSAsim Jamshed }
9276404edcSAsim Jamshed /*----------------------------------------------------------------------------*/
9376404edcSAsim Jamshed static int
DetectWord(char * buf,int len,char ** word,int * wlen)9476404edcSAsim Jamshed DetectWord(char *buf, int len, char **word, int *wlen)
9576404edcSAsim Jamshed {
9676404edcSAsim Jamshed 	int i;
9776404edcSAsim Jamshed 	for (i = 0; i < len; i++) {
9876404edcSAsim Jamshed 		if (isspace(buf[i]))
9976404edcSAsim Jamshed 			continue;
10076404edcSAsim Jamshed 
10176404edcSAsim Jamshed 		if (isalpha(buf[i])) {
10276404edcSAsim Jamshed 			*word = &buf[i];
10376404edcSAsim Jamshed 			break;
10476404edcSAsim Jamshed 		} else
10576404edcSAsim Jamshed 			/* not word */
10676404edcSAsim Jamshed 			return -1;
10776404edcSAsim Jamshed 	}
10876404edcSAsim Jamshed 
10976404edcSAsim Jamshed 	if (i == len)
11076404edcSAsim Jamshed 		return -1;
11176404edcSAsim Jamshed 
11276404edcSAsim Jamshed 	for (*wlen = 0; *wlen < len; (*wlen)++) {
11376404edcSAsim Jamshed 		if (isalnum((*word)[*wlen]) || (*word)[*wlen] == '_')
11476404edcSAsim Jamshed 			continue;
11576404edcSAsim Jamshed 
11676404edcSAsim Jamshed 		assert(*wlen != 0);
11776404edcSAsim Jamshed 		break;
11876404edcSAsim Jamshed 	}
11976404edcSAsim Jamshed 
12076404edcSAsim Jamshed 	assert(*word >= buf && *word + *wlen <= buf + len);
12176404edcSAsim Jamshed 
12276404edcSAsim Jamshed 	return 0;
12376404edcSAsim Jamshed }
12476404edcSAsim Jamshed /*----------------------------------------------------------------------------*/
12576404edcSAsim Jamshed static int
ReadItemValue(char * line,int llen,char * item,int ilen,char * value,int vlen)12676404edcSAsim Jamshed ReadItemValue(char *line, int llen, char *item, int ilen, char *value, int vlen)
12776404edcSAsim Jamshed {
12876404edcSAsim Jamshed 	const char *end = &line[llen];
129df5d5f77SAsim Jamshed 	char *word = NULL;
130df5d5f77SAsim Jamshed 	int wlen = 0;
13176404edcSAsim Jamshed 
13276404edcSAsim Jamshed 	if (DetectWord(line, llen, &word, &wlen) < 0 || wlen > ilen)
13376404edcSAsim Jamshed 		return -1;
13476404edcSAsim Jamshed 
13576404edcSAsim Jamshed 	line = word + wlen;
13676404edcSAsim Jamshed 
13776404edcSAsim Jamshed 	/* skip space */
13876404edcSAsim Jamshed 	while (line < end && isspace(*line))
13976404edcSAsim Jamshed 		line++;
14076404edcSAsim Jamshed 
14176404edcSAsim Jamshed 	if (*(line++) != '=')
14276404edcSAsim Jamshed 		return -1;
14376404edcSAsim Jamshed 
14476404edcSAsim Jamshed 	while (line < end && isspace(*line))
14576404edcSAsim Jamshed 		line++;
14676404edcSAsim Jamshed 
14776404edcSAsim Jamshed 	if (end - line > vlen)
14876404edcSAsim Jamshed 		return -1;
14976404edcSAsim Jamshed 
15076404edcSAsim Jamshed 	while (isspace(*(end - 1)))
15176404edcSAsim Jamshed 		end--;
15276404edcSAsim Jamshed 
15376404edcSAsim Jamshed 	if (end <= line)
15476404edcSAsim Jamshed 		return -1;
15576404edcSAsim Jamshed 
15676404edcSAsim Jamshed 	strncpy(item, word, wlen);
15776404edcSAsim Jamshed 
15876404edcSAsim Jamshed 	strncpy(value, line, (size_t)(end - line));
15976404edcSAsim Jamshed 
16076404edcSAsim Jamshed 	return 0;
16176404edcSAsim Jamshed }
16276404edcSAsim Jamshed /*----------------------------------------------------------------------------*/
16376404edcSAsim Jamshed static void
FeedAppConfLine(struct conf_block * blk,char * line,int len)16476404edcSAsim Jamshed FeedAppConfLine(struct conf_block *blk, char *line, int len)
16576404edcSAsim Jamshed {
16676404edcSAsim Jamshed 	struct app_conf * const conf = (struct app_conf *)blk->conf;
16776404edcSAsim Jamshed 
16876404edcSAsim Jamshed 	char item[WORD_LEN + 1] = {0};
16976404edcSAsim Jamshed 	char value[STR_LEN + 1] = {0};
17076404edcSAsim Jamshed 
17176404edcSAsim Jamshed 	if (ReadItemValue(line, len, item, WORD_LEN, value, STR_LEN) < 0)
17276404edcSAsim Jamshed 		return;
17376404edcSAsim Jamshed 
17476404edcSAsim Jamshed 	if      (TRY_ASSIGN_STR(type,       conf, item, value));
17576404edcSAsim Jamshed 	else if (TRY_ASSIGN_STR(run,        conf, item, value)) {
17676404edcSAsim Jamshed 		StrToArgs(conf->run, &conf->app_argc, conf->app_argv, MOS_APP_ARGC);
17776404edcSAsim Jamshed #if 0
17876404edcSAsim Jamshed 		conf->app_argv[conf->app_argc++] = strtok(conf->run, " \t\n\r");
17976404edcSAsim Jamshed 		while (conf->app_argc < MOS_APP_ARGC &&
18076404edcSAsim Jamshed 				(conf->app_argv[conf->app_argc] = strtok(NULL, " \t\n\r")))
18176404edcSAsim Jamshed 			conf->app_argc++;
18276404edcSAsim Jamshed #endif
18376404edcSAsim Jamshed 	} else if (TRY_ASSIGN_NUM(cpu_mask,   conf, item, value));
18476404edcSAsim Jamshed 	else if (TRY_ASSIGN_NUM(ip_forward, conf, item, value));
18576404edcSAsim Jamshed }
18676404edcSAsim Jamshed /*----------------------------------------------------------------------------*/
18776404edcSAsim Jamshed static void
FeedMosConfLine(struct conf_block * blk,char * line,int len)18876404edcSAsim Jamshed FeedMosConfLine(struct conf_block *blk, char *line, int len)
18976404edcSAsim Jamshed {
19076404edcSAsim Jamshed 	struct mos_conf * const conf = (struct mos_conf *)blk->conf;
19176404edcSAsim Jamshed 
19276404edcSAsim Jamshed 	char item[WORD_LEN + 1] = {0};
19376404edcSAsim Jamshed 	char value[STR_LEN + 1] = {0};
19476404edcSAsim Jamshed 
19576404edcSAsim Jamshed 	if (ReadItemValue(line, len, item, WORD_LEN, value, STR_LEN) < 0)
19676404edcSAsim Jamshed 		return;
19776404edcSAsim Jamshed 
19876404edcSAsim Jamshed 	if (TRY_ASSIGN_NUM(nb_mem_channels, conf, item, value));
19976404edcSAsim Jamshed 	else if (TRY_ASSIGN_NUM(forward,         conf, item, value));
20076404edcSAsim Jamshed 	else if (TRY_ASSIGN_NUM(max_concurrency, conf, item, value));
20176404edcSAsim Jamshed 	else if (TRY_ASSIGN_NUM(rmem_size,       conf, item, value));
20276404edcSAsim Jamshed 	else if (TRY_ASSIGN_NUM(wmem_size,       conf, item, value));
20376404edcSAsim Jamshed 	else if (TRY_ASSIGN_NUM(tcp_tw_interval, conf, item, value))
20476404edcSAsim Jamshed 		g_config.mos->tcp_tw_interval =
20576404edcSAsim Jamshed 			SEC_TO_USEC(g_config.mos->tcp_tw_interval) / TIME_TICK;
20676404edcSAsim Jamshed 	else if (TRY_ASSIGN_NUM(tcp_timeout,     conf, item, value))
20776404edcSAsim Jamshed 		g_config.mos->tcp_timeout =
20876404edcSAsim Jamshed 			SEC_TO_USEC(g_config.mos->tcp_timeout) / TIME_TICK;
20976404edcSAsim Jamshed 	else if (TRY_ASSIGN_NUM(no_ring_buffers, conf, item, value));
21076404edcSAsim Jamshed 	else if (TRY_ASSIGN_STR(mos_log,         conf, item, value));
21176404edcSAsim Jamshed 	else if (TRY_ASSIGN_STR(stat_print,      conf, item, value));
21276404edcSAsim Jamshed 	else if (TRY_ASSIGN_STR(port,            conf, item, value));
21376404edcSAsim Jamshed 	else if (strcmp(item, "multiprocess") == 0) {
21476404edcSAsim Jamshed 		conf->multiprocess = 1;
21576404edcSAsim Jamshed 		SetMultiProcessSupport(value);
21676404edcSAsim Jamshed 	}
21776404edcSAsim Jamshed }
21876404edcSAsim Jamshed /*----------------------------------------------------------------------------*/
21976404edcSAsim Jamshed static void
FeedNetdevConfLine(struct conf_block * blk,char * line,int len)22076404edcSAsim Jamshed FeedNetdevConfLine(struct conf_block *blk, char *line, int len)
22176404edcSAsim Jamshed {
22276404edcSAsim Jamshed 	struct netdev_conf * const conf = (struct netdev_conf *)blk->conf;
22376404edcSAsim Jamshed 
22476404edcSAsim Jamshed #ifndef DARWIN
22576404edcSAsim Jamshed 	int i;
22676404edcSAsim Jamshed #endif
22776404edcSAsim Jamshed 	uint64_t cpu_mask;
228a14d6bd4SAsim Jamshed 	char *word = NULL;
22976404edcSAsim Jamshed 	int wlen;
23076404edcSAsim Jamshed 
23176404edcSAsim Jamshed 	if (DetectWord(line, len, &word, &wlen) < 0 || wlen > WORD_LEN || wlen <= 0)
23276404edcSAsim Jamshed 		return;
23376404edcSAsim Jamshed 
23476404edcSAsim Jamshed 	line = word + wlen;
23576404edcSAsim Jamshed 
23676404edcSAsim Jamshed 	if (sscanf(line, "%li", &cpu_mask) <= 0)
23776404edcSAsim Jamshed 		return;
23876404edcSAsim Jamshed 
23976404edcSAsim Jamshed 	struct netdev_entry *ent = calloc(1, sizeof(struct netdev_entry));
24076404edcSAsim Jamshed 	if (!ent) {
24176404edcSAsim Jamshed 		TRACE_ERROR("Could not allocate memory for netdev_entry!\n");
24276404edcSAsim Jamshed 		exit(EXIT_FAILURE);
24376404edcSAsim Jamshed 	}
24476404edcSAsim Jamshed 
24576404edcSAsim Jamshed 	strncpy(ent->dev_name, word, wlen);
24676404edcSAsim Jamshed 	ent->cpu_mask = cpu_mask;
24776404edcSAsim Jamshed 	g_config.mos->cpu_mask |= cpu_mask;
24876404edcSAsim Jamshed 
249c6a5549bSAsim Jamshed 	strncpy(ent->ifr.ifr_name, ent->dev_name, IFNAMSIZ-1);
250ec2936c9SAsim Jamshed 	ent->ifr.ifr_name[IFNAMSIZ-1] = '\0';
25176404edcSAsim Jamshed 
25276404edcSAsim Jamshed 	/* Create socket */
25376404edcSAsim Jamshed 	int sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
25476404edcSAsim Jamshed 	if (sock == -1) {
25576404edcSAsim Jamshed 		perror("socket");
2561879243cSAsim Jamshed 		exit(EXIT_FAILURE);
25776404edcSAsim Jamshed 	}
25876404edcSAsim Jamshed 
25976404edcSAsim Jamshed 	/* getting address */
26076404edcSAsim Jamshed 	if (ioctl(sock, SIOCGIFADDR, &ent->ifr) == 0 ) {
26176404edcSAsim Jamshed 		struct in_addr sin = ((struct sockaddr_in *)&ent->ifr.ifr_addr)->sin_addr;
26276404edcSAsim Jamshed 		ent->ip_addr = *(uint32_t *)&sin;
26376404edcSAsim Jamshed 	}
26476404edcSAsim Jamshed 
26576404edcSAsim Jamshed 	/* Net MASK */
26676404edcSAsim Jamshed 	if (ioctl(sock, SIOCGIFNETMASK, &ent->ifr) == 0) {
26776404edcSAsim Jamshed 		struct in_addr sin = ((struct sockaddr_in *)&ent->ifr.ifr_addr)->sin_addr;
26876404edcSAsim Jamshed 		ent->netmask = *(uint32_t *)&sin;
26976404edcSAsim Jamshed 	}
27076404edcSAsim Jamshed 
27176404edcSAsim Jamshed #ifdef DARWIN
27276404edcSAsim Jamshed 	/* FIXME: How can I retrieve a mac address in MAC OS? */
27376404edcSAsim Jamshed #else
27476404edcSAsim Jamshed 	if (ioctl(sock, SIOCGIFHWADDR, &ent->ifr) == 0 ) {
27576404edcSAsim Jamshed 		for (i = 0; i < 6; i ++) {
27676404edcSAsim Jamshed 			ent->haddr[i] = ent->ifr.ifr_addr.sa_data[i];
27776404edcSAsim Jamshed 		}
27876404edcSAsim Jamshed 	}
27976404edcSAsim Jamshed #endif
28076404edcSAsim Jamshed 
28176404edcSAsim Jamshed 	close(sock);
28276404edcSAsim Jamshed 
28376404edcSAsim Jamshed 	ent->ifindex = -1;
28476404edcSAsim Jamshed 
28576404edcSAsim Jamshed 	TAILQ_INSERT_TAIL(&conf->list, ent, link);
28676404edcSAsim Jamshed 	conf->ent[conf->num] = ent;
28776404edcSAsim Jamshed 	conf->num++;
28876404edcSAsim Jamshed }
28976404edcSAsim Jamshed /*----------------------------------------------------------------------------*/
29076404edcSAsim Jamshed static void
FeedArpConfLine(struct conf_block * blk,char * line,int len)29176404edcSAsim Jamshed FeedArpConfLine(struct conf_block *blk, char *line, int len)
29276404edcSAsim Jamshed {
29376404edcSAsim Jamshed 	struct arp_conf * const conf = (struct arp_conf *)blk->conf;
29476404edcSAsim Jamshed 
29576404edcSAsim Jamshed 	char address[WORD_LEN];
29676404edcSAsim Jamshed 	int prefix;
29776404edcSAsim Jamshed 	uint8_t haddr[ETH_ALEN] = {0};
29876404edcSAsim Jamshed 
29976404edcSAsim Jamshed 	/* skip first space */
30076404edcSAsim Jamshed 	while (isspace(*line))
30176404edcSAsim Jamshed 		line++, len--;
30276404edcSAsim Jamshed 
30376404edcSAsim Jamshed 	if (sscanf(line, "%[0-9.]/%d %hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
30476404edcSAsim Jamshed 				address, &prefix, &haddr[0], &haddr[1], &haddr[2],
30576404edcSAsim Jamshed 				&haddr[3], &haddr[4], &haddr[5]) != 8)
30676404edcSAsim Jamshed 		return;
30776404edcSAsim Jamshed 
30876404edcSAsim Jamshed 	struct _arp_entry *ent = calloc(1, sizeof(struct _arp_entry));
30976404edcSAsim Jamshed 	if (!ent) {
31076404edcSAsim Jamshed 		TRACE_ERROR("Could not allocate memory for arp_entry!\n");
31176404edcSAsim Jamshed 		exit(EXIT_FAILURE);
31276404edcSAsim Jamshed 	}
31376404edcSAsim Jamshed 
31476404edcSAsim Jamshed 	ent->ip = inet_addr(address);
31576404edcSAsim Jamshed 	ent->prefix = prefix;
31676404edcSAsim Jamshed 	ent->mask = htonl((prefix == 0) ? 0 : ((-1) << (32 - prefix)));
31776404edcSAsim Jamshed 	ent->masked_ip = ent->mask & ent->ip;
31876404edcSAsim Jamshed 	memcpy(ent->haddr, haddr, ETH_ALEN);
31976404edcSAsim Jamshed 	TAILQ_INSERT_TAIL(&conf->list, ent, link);
32076404edcSAsim Jamshed 	conf->ent[conf->num] = ent;
32176404edcSAsim Jamshed 	conf->num++;
32276404edcSAsim Jamshed }
32376404edcSAsim Jamshed /*----------------------------------------------------------------------------*/
32476404edcSAsim Jamshed static void
FeedRouteConfLine(struct conf_block * blk,char * line,int len)32576404edcSAsim Jamshed FeedRouteConfLine(struct conf_block *blk, char *line, int len)
32676404edcSAsim Jamshed {
32776404edcSAsim Jamshed 	struct route_conf * const conf = (struct route_conf *)blk->conf;
32876404edcSAsim Jamshed 
32976404edcSAsim Jamshed 	char address[WORD_LEN], dev_name[WORD_LEN];
33076404edcSAsim Jamshed 	int prefix;
33176404edcSAsim Jamshed 
33276404edcSAsim Jamshed 	/* skip first space */
33376404edcSAsim Jamshed 	while (isspace(*line))
33476404edcSAsim Jamshed 		line++, len--;
33576404edcSAsim Jamshed 
33676404edcSAsim Jamshed 	if (sscanf(line, "%[0-9.]/%d %[^ ^\n^\t]", address, &prefix, dev_name) != 3)
33776404edcSAsim Jamshed 		return;
33876404edcSAsim Jamshed 
33976404edcSAsim Jamshed 	struct route_entry *ent = calloc(1, sizeof(struct route_entry));
34076404edcSAsim Jamshed 	if (!ent) {
34176404edcSAsim Jamshed 		TRACE_ERROR("Could not allocate memory for route_entry!\n");
34276404edcSAsim Jamshed 		exit(EXIT_FAILURE);
34376404edcSAsim Jamshed 	}
34476404edcSAsim Jamshed 
34576404edcSAsim Jamshed 	ent->ip = inet_addr(address);
34676404edcSAsim Jamshed 	ent->mask = htonl((prefix == 0) ? 0 : ((-1) << (32 - prefix)));
34776404edcSAsim Jamshed 	ent->masked_ip = ent->mask & ent->ip;
34876404edcSAsim Jamshed 	ent->prefix = prefix;
34976404edcSAsim Jamshed 	ent->nif = -1;
35076404edcSAsim Jamshed 	strcpy(ent->dev_name, dev_name);
35176404edcSAsim Jamshed 
35276404edcSAsim Jamshed 	TAILQ_INSERT_TAIL(&conf->list, ent, link);
35376404edcSAsim Jamshed 	conf->ent[conf->num] = ent;
35476404edcSAsim Jamshed 	conf->num++;
35576404edcSAsim Jamshed }
35676404edcSAsim Jamshed /*----------------------------------------------------------------------------*/
35776404edcSAsim Jamshed static void
FeedNICFwdConfLine(struct conf_block * blk,char * line,int len)35876404edcSAsim Jamshed FeedNICFwdConfLine(struct conf_block *blk, char *line, int len)
35976404edcSAsim Jamshed {
36076404edcSAsim Jamshed 	struct nic_forward_conf * const conf = (struct nic_forward_conf *)blk->conf;
36176404edcSAsim Jamshed 	char dev_name_in[WORD_LEN];
36276404edcSAsim Jamshed 	char dev_name_out[WORD_LEN];
36376404edcSAsim Jamshed 
36476404edcSAsim Jamshed 	/* skip first space */
36576404edcSAsim Jamshed 	while (isspace(*line))
36676404edcSAsim Jamshed 		line++, len--;
36776404edcSAsim Jamshed 
36876404edcSAsim Jamshed 	if (sscanf(line, "%[^ ^\n^\t] %[^ ^\n^\t]", dev_name_in, dev_name_out) != 2)
36976404edcSAsim Jamshed 		return;
37076404edcSAsim Jamshed 
37176404edcSAsim Jamshed 	struct nic_forward_entry *ent = calloc(1, sizeof(struct nic_forward_entry));
37276404edcSAsim Jamshed 	if (!ent) {
37376404edcSAsim Jamshed 		TRACE_ERROR("Could not allocate memory for nic forward entry!\n");
37476404edcSAsim Jamshed 		exit(EXIT_FAILURE);
37576404edcSAsim Jamshed 	}
37676404edcSAsim Jamshed 
37776404edcSAsim Jamshed 	strcpy(ent->nif_in, dev_name_in);
37876404edcSAsim Jamshed 	strcpy(ent->nif_out, dev_name_out);
37976404edcSAsim Jamshed 	TAILQ_INSERT_TAIL(&conf->list, ent, link);
38076404edcSAsim Jamshed 	conf->ent[conf->num] = ent;
38176404edcSAsim Jamshed 	conf->num++;
38276404edcSAsim Jamshed }
38376404edcSAsim Jamshed /*----------------------------------------------------------------------------*/
38476404edcSAsim Jamshed static void
MosConfAddChild(struct conf_block * blk,struct conf_block * child)38576404edcSAsim Jamshed MosConfAddChild(struct conf_block *blk, struct conf_block *child)
38676404edcSAsim Jamshed {
38776404edcSAsim Jamshed 	struct mos_conf * const conf = (struct mos_conf *)blk->conf;
38876404edcSAsim Jamshed 
38976404edcSAsim Jamshed 	if (strcmp(child->name, NETDEV_BLOCK_NAME) == 0) {
39076404edcSAsim Jamshed 		conf->netdev = child;
39176404edcSAsim Jamshed 		conf->netdev_table = (struct netdev_conf *)child->conf;
39276404edcSAsim Jamshed 	} else if (strcmp(child->name, ARP_BLOCK_NAME) == 0) {
39376404edcSAsim Jamshed 		conf->arp = child;
39476404edcSAsim Jamshed 		conf->arp_table = (struct arp_conf *)child->conf;
39576404edcSAsim Jamshed 	} else if (strcmp(child->name, ROUTE_BLOCK_NAME) == 0) {
39676404edcSAsim Jamshed 		conf->route = child;
39776404edcSAsim Jamshed 		conf->route_table = (struct route_conf *)child->conf;
39876404edcSAsim Jamshed 	} else if (strcmp(child->name, FORWARD_BLOCK_NAME) == 0) {
39976404edcSAsim Jamshed 		conf->nic_forward = child;
40076404edcSAsim Jamshed 		conf->nic_forward_table = (struct nic_forward_conf *)child->conf;
40176404edcSAsim Jamshed 	} else
40276404edcSAsim Jamshed 		return;
40376404edcSAsim Jamshed }
40476404edcSAsim Jamshed /*----------------------------------------------------------------------------*/
40576404edcSAsim Jamshed static int
AppConfIsValid(struct conf_block * blk)40676404edcSAsim Jamshed AppConfIsValid(struct conf_block *blk)
40776404edcSAsim Jamshed {
40876404edcSAsim Jamshed 	struct app_conf * const conf = (struct app_conf *)blk->conf;
40976404edcSAsim Jamshed 
41076404edcSAsim Jamshed 	if (conf->app_argc <= 0)
41176404edcSAsim Jamshed 		return 0;
41276404edcSAsim Jamshed 
41376404edcSAsim Jamshed 	return 1;
41476404edcSAsim Jamshed }
41576404edcSAsim Jamshed /*----------------------------------------------------------------------------*/
41676404edcSAsim Jamshed static int
MosConfIsValid(struct conf_block * blk)41776404edcSAsim Jamshed MosConfIsValid(struct conf_block *blk)
41876404edcSAsim Jamshed {
41976404edcSAsim Jamshed 	return 1;
42076404edcSAsim Jamshed }
42176404edcSAsim Jamshed /*----------------------------------------------------------------------------*/
42276404edcSAsim Jamshed static int
NetdevConfIsValid(struct conf_block * blk)42376404edcSAsim Jamshed NetdevConfIsValid(struct conf_block *blk)
42476404edcSAsim Jamshed {
42576404edcSAsim Jamshed 	return 1;
42676404edcSAsim Jamshed }
42776404edcSAsim Jamshed /*----------------------------------------------------------------------------*/
42876404edcSAsim Jamshed static int
ArpConfIsValid(struct conf_block * blk)42976404edcSAsim Jamshed ArpConfIsValid(struct conf_block *blk)
43076404edcSAsim Jamshed {
43176404edcSAsim Jamshed 	return 1;
43276404edcSAsim Jamshed }
43376404edcSAsim Jamshed /*----------------------------------------------------------------------------*/
43476404edcSAsim Jamshed static int
RouteConfIsValid(struct conf_block * blk)43576404edcSAsim Jamshed RouteConfIsValid(struct conf_block *blk)
43676404edcSAsim Jamshed {
43776404edcSAsim Jamshed 	return 1;
43876404edcSAsim Jamshed }
43976404edcSAsim Jamshed /*----------------------------------------------------------------------------*/
44076404edcSAsim Jamshed static int
NICFwdConfIsValid(struct conf_block * blk)44176404edcSAsim Jamshed NICFwdConfIsValid(struct conf_block *blk)
44276404edcSAsim Jamshed {
44376404edcSAsim Jamshed 	return 1;
44476404edcSAsim Jamshed }
44576404edcSAsim Jamshed /*----------------------------------------------------------------------------*/
44676404edcSAsim Jamshed static void
NetdevConfPrint(struct conf_block * blk)44776404edcSAsim Jamshed NetdevConfPrint(struct conf_block *blk)
44876404edcSAsim Jamshed {
44976404edcSAsim Jamshed 	struct netdev_conf * const conf = (struct netdev_conf *)blk->conf;
45076404edcSAsim Jamshed 
45176404edcSAsim Jamshed 	printf(" +===== Netdev configuration (%d entries) =====\n",
45276404edcSAsim Jamshed 			conf->num);
45376404edcSAsim Jamshed 
45476404edcSAsim Jamshed 	struct netdev_entry *walk;
45576404edcSAsim Jamshed 	TAILQ_FOREACH(walk, &conf->list, link) {
45676404edcSAsim Jamshed 		printf(" | %s(idx: %d, HADDR: %02hhX:%02hhX:%02hhX:%02hhX:%02hhX:%02hhX) maps to CPU 0x%016lX\n",
45776404edcSAsim Jamshed 				walk->dev_name, walk->ifindex,
45876404edcSAsim Jamshed 				walk->haddr[0], walk->haddr[1], walk->haddr[2],
45976404edcSAsim Jamshed 				walk->haddr[3], walk->haddr[4], walk->haddr[5],
46076404edcSAsim Jamshed 				walk->cpu_mask);
46176404edcSAsim Jamshed 	}
46276404edcSAsim Jamshed 	printf(" |\n");
46376404edcSAsim Jamshed }
46476404edcSAsim Jamshed /*----------------------------------------------------------------------------*/
46576404edcSAsim Jamshed static void
ArpConfPrint(struct conf_block * blk)46676404edcSAsim Jamshed ArpConfPrint(struct conf_block *blk)
46776404edcSAsim Jamshed {
46876404edcSAsim Jamshed 	struct arp_conf * const conf = (struct arp_conf *)blk->conf;
46976404edcSAsim Jamshed 
47076404edcSAsim Jamshed 	printf(" +===== Static ARP table configuration (%d entries) =====\n",
47176404edcSAsim Jamshed 			conf->num);
47276404edcSAsim Jamshed 
47376404edcSAsim Jamshed 	struct _arp_entry *walk;
47476404edcSAsim Jamshed 	TAILQ_FOREACH(walk, &conf->list, link) {
47576404edcSAsim Jamshed 		printf(" | IP: 0x%08X, NETMASK: 0x%08X, "
47676404edcSAsim Jamshed 			   "HADDR: %02hhX:%02hhX:%02hhX:%02hhX:%02hhX:%02hhX\n",
47776404edcSAsim Jamshed 			   ntohl(walk->ip), ntohl(walk->mask),
47876404edcSAsim Jamshed 			   walk->haddr[0], walk->haddr[1], walk->haddr[2],
47976404edcSAsim Jamshed 			   walk->haddr[3], walk->haddr[4], walk->haddr[5]);
48076404edcSAsim Jamshed 	}
48176404edcSAsim Jamshed 	printf(" |\n");
48276404edcSAsim Jamshed }
48376404edcSAsim Jamshed /*----------------------------------------------------------------------------*/
48476404edcSAsim Jamshed static void
RouteConfPrint(struct conf_block * blk)48576404edcSAsim Jamshed RouteConfPrint(struct conf_block *blk)
48676404edcSAsim Jamshed {
48776404edcSAsim Jamshed 	struct route_conf * const conf = (struct route_conf *)blk->conf;
48876404edcSAsim Jamshed 
48976404edcSAsim Jamshed 	printf(" +===== Routing table configuration (%d entries) =====\n",
49076404edcSAsim Jamshed 			conf->num);
49176404edcSAsim Jamshed 
49276404edcSAsim Jamshed 	struct route_entry *walk;
49376404edcSAsim Jamshed 	TAILQ_FOREACH(walk, &conf->list, link) {
49476404edcSAsim Jamshed 		printf(" | IP: 0x%08X, NETMASK: 0x%08X, INTERFACE: %s(idx: %d)\n",
49576404edcSAsim Jamshed 			   ntohl(walk->ip), ntohl(walk->mask), walk->dev_name, walk->nif);
49676404edcSAsim Jamshed 	}
49776404edcSAsim Jamshed 	printf(" |\n");
49876404edcSAsim Jamshed }
49976404edcSAsim Jamshed /*----------------------------------------------------------------------------*/
50076404edcSAsim Jamshed static void
NICFwdConfPrint(struct conf_block * blk)50176404edcSAsim Jamshed NICFwdConfPrint(struct conf_block *blk)
50276404edcSAsim Jamshed {
50376404edcSAsim Jamshed 	int i;
50476404edcSAsim Jamshed 	struct nic_forward_conf * const conf = (struct nic_forward_conf *)blk->conf;
50576404edcSAsim Jamshed 
50676404edcSAsim Jamshed 	printf(" +===== NIC Forwarding table configuration (%d entries) =====\n",
50776404edcSAsim Jamshed 			conf->num);
50876404edcSAsim Jamshed 
50976404edcSAsim Jamshed 	struct nic_forward_entry *walk;
51076404edcSAsim Jamshed 	TAILQ_FOREACH(walk, &conf->list, link) {
51176404edcSAsim Jamshed 		printf(" | NIC Forwarding Entry: %s <---> %s",
51276404edcSAsim Jamshed 		       walk->nif_in, walk->nif_out);
51376404edcSAsim Jamshed 	}
51476404edcSAsim Jamshed 	printf(" |\n");
51576404edcSAsim Jamshed 
51676404edcSAsim Jamshed 	printf(" | NIC Forwarding Index Table: |\n");
51776404edcSAsim Jamshed 
51876404edcSAsim Jamshed 	for (i = 0; i < MAX_FORWARD_ENTRY; i++)
51976404edcSAsim Jamshed 		printf( " | %d --> %d | \n", i, conf->nic_fwd_table[i]);
52076404edcSAsim Jamshed }
52176404edcSAsim Jamshed /*----------------------------------------------------------------------------*/
52276404edcSAsim Jamshed static void
AppConfPrint(struct conf_block * blk)52376404edcSAsim Jamshed AppConfPrint(struct conf_block *blk)
52476404edcSAsim Jamshed {
52576404edcSAsim Jamshed 	struct app_conf * const conf = (struct app_conf *)blk->conf;
52676404edcSAsim Jamshed 
52776404edcSAsim Jamshed 	printf("===== Application configuration =====\n");
52876404edcSAsim Jamshed 	printf("| type:       %s\n", conf->type);
52976404edcSAsim Jamshed 	printf("| run:        %s\n", conf->run);
53076404edcSAsim Jamshed 	printf("| cpu_mask:   0x%016lX\n", conf->cpu_mask);
53176404edcSAsim Jamshed 	printf("| ip_forward: %s\n", conf->ip_forward ? "forward" : "drop");
53276404edcSAsim Jamshed 	printf("\n");
53376404edcSAsim Jamshed }
53476404edcSAsim Jamshed /*----------------------------------------------------------------------------*/
53576404edcSAsim Jamshed static void
MosConfPrint(struct conf_block * blk)53676404edcSAsim Jamshed MosConfPrint(struct conf_block *blk)
53776404edcSAsim Jamshed {
53876404edcSAsim Jamshed 	struct mos_conf * const conf = (struct mos_conf *)blk->conf;
53976404edcSAsim Jamshed 
54076404edcSAsim Jamshed 	printf("===== MOS configuration =====\n");
54176404edcSAsim Jamshed 	printf("| num_cores:       %d\n", conf->num_cores);
54276404edcSAsim Jamshed 	printf("| nb_mem_channels: %d\n", conf->nb_mem_channels);
54376404edcSAsim Jamshed 	printf("| max_concurrency: %d\n", conf->max_concurrency);
54476404edcSAsim Jamshed 	printf("| rmem_size:       %d\n", conf->rmem_size);
54576404edcSAsim Jamshed 	printf("| wmem_size:       %d\n", conf->wmem_size);
54676404edcSAsim Jamshed 	printf("| tcp_tw_interval: %d\n", conf->tcp_tw_interval);
54776404edcSAsim Jamshed 	printf("| tcp_timeout:     %d\n", conf->tcp_timeout);
54876404edcSAsim Jamshed 	printf("| multiprocess:    %s\n", conf->multiprocess ? "true" : "false");
54976404edcSAsim Jamshed 	printf("| mos_log:         %s\n", conf->mos_log);
55076404edcSAsim Jamshed 	printf("| stat_print:      %s\n", conf->stat_print);
55176404edcSAsim Jamshed 	printf("| forward:         %s\n", conf->forward ? "forward" : "drop");
55276404edcSAsim Jamshed 	printf("|\n");
55376404edcSAsim Jamshed 	if (conf->netdev)
55476404edcSAsim Jamshed 		conf->netdev->print(conf->netdev);
55576404edcSAsim Jamshed 	if (conf->arp)
55676404edcSAsim Jamshed 		conf->arp->print(conf->arp);
55776404edcSAsim Jamshed 	if (conf->route)
55876404edcSAsim Jamshed 		conf->route->print(conf->route);
55976404edcSAsim Jamshed 	if (conf->nic_forward)
56076404edcSAsim Jamshed 		conf->nic_forward->print(conf->nic_forward);
56176404edcSAsim Jamshed 	printf("\n");
56276404edcSAsim Jamshed }
56376404edcSAsim Jamshed /*----------------------------------------------------------------------------*/
56476404edcSAsim Jamshed static void
InitAppBlock(struct config * config,struct conf_block * blk)56576404edcSAsim Jamshed InitAppBlock(struct config *config, struct conf_block *blk)
56676404edcSAsim Jamshed {
56776404edcSAsim Jamshed 	assert(blk);
56876404edcSAsim Jamshed 
56976404edcSAsim Jamshed 	blk->name = APP_BLOCK_NAME;
57076404edcSAsim Jamshed 
57176404edcSAsim Jamshed 	blk->feed = FeedAppConfLine;
57276404edcSAsim Jamshed 	blk->addchild = NULL;
57376404edcSAsim Jamshed 	blk->isvalid = AppConfIsValid;
57476404edcSAsim Jamshed 	blk->print = AppConfPrint;
57576404edcSAsim Jamshed 
57676404edcSAsim Jamshed 	struct app_conf *conf = calloc(1, sizeof(struct app_conf));
57776404edcSAsim Jamshed 	if (conf == NULL) {
57876404edcSAsim Jamshed 		TRACE_ERROR("Could not allocate memory for app_conf!\n");
57976404edcSAsim Jamshed 		exit(EXIT_FAILURE);
58076404edcSAsim Jamshed 	}
58176404edcSAsim Jamshed 	/* set default values */
58276404edcSAsim Jamshed 	conf->cpu_mask = -1;
58376404edcSAsim Jamshed 	conf->ip_forward = 1;
58476404edcSAsim Jamshed 	conf->app_argc = 0;
58576404edcSAsim Jamshed 	blk->conf = conf;
58676404edcSAsim Jamshed 
58776404edcSAsim Jamshed 	blk->list = (typeof(blk->list))&config->app_blkh;
58876404edcSAsim Jamshed }
58976404edcSAsim Jamshed /*----------------------------------------------------------------------------*/
59076404edcSAsim Jamshed static void
InitMosBlock(struct config * config,struct conf_block * blk)59176404edcSAsim Jamshed InitMosBlock(struct config *config, struct conf_block *blk)
59276404edcSAsim Jamshed {
59376404edcSAsim Jamshed 	assert(blk);
59476404edcSAsim Jamshed 
59576404edcSAsim Jamshed 	blk->name = MOS_BLOCK_NAME;
59676404edcSAsim Jamshed 
59776404edcSAsim Jamshed 	blk->feed = FeedMosConfLine;
59876404edcSAsim Jamshed 	blk->addchild = MosConfAddChild;
59976404edcSAsim Jamshed 	blk->isvalid = MosConfIsValid;
60076404edcSAsim Jamshed 	blk->print = MosConfPrint;
60176404edcSAsim Jamshed 
60276404edcSAsim Jamshed 	struct mos_conf *conf = calloc(1, sizeof(struct mos_conf));
60376404edcSAsim Jamshed 	if (conf == NULL) {
60476404edcSAsim Jamshed 		TRACE_ERROR("Could not allocate memory for mos_conf!\n");
60576404edcSAsim Jamshed 		exit(EXIT_FAILURE);
60676404edcSAsim Jamshed 	}
60776404edcSAsim Jamshed 	/* set default values */
60876404edcSAsim Jamshed 	conf->forward = 1;
60976404edcSAsim Jamshed 	conf->nb_mem_channels = 0;
61076404edcSAsim Jamshed 	conf->max_concurrency = 100000;
61176404edcSAsim Jamshed 	conf->no_ring_buffers = 0;
61276404edcSAsim Jamshed 	conf->rmem_size = 8192;
61376404edcSAsim Jamshed 	conf->wmem_size = 8192;
61476404edcSAsim Jamshed 	conf->tcp_tw_interval = SEC_TO_USEC(TCP_TIMEWAIT) / TIME_TICK;
61576404edcSAsim Jamshed 	conf->tcp_timeout = SEC_TO_USEC(TCP_TIMEOUT) / TIME_TICK;
61676404edcSAsim Jamshed 	conf->cpu_mask = 0;
61776404edcSAsim Jamshed 	blk->conf = conf;
61876404edcSAsim Jamshed 
61976404edcSAsim Jamshed 	blk->list = (typeof(blk->list))&config->mos_blkh;
62076404edcSAsim Jamshed 	config->mos = conf;
62176404edcSAsim Jamshed }
62276404edcSAsim Jamshed /*----------------------------------------------------------------------------*/
62376404edcSAsim Jamshed static void
InitNetdevBlock(struct config * config,struct conf_block * blk)62476404edcSAsim Jamshed InitNetdevBlock(struct config *config, struct conf_block *blk)
62576404edcSAsim Jamshed {
62676404edcSAsim Jamshed 	assert(blk);
62776404edcSAsim Jamshed 
62876404edcSAsim Jamshed 	blk->name = NETDEV_BLOCK_NAME;
62976404edcSAsim Jamshed 
63076404edcSAsim Jamshed 	blk->feed = FeedNetdevConfLine;
63176404edcSAsim Jamshed 	blk->addchild = NULL;
63276404edcSAsim Jamshed 	blk->isvalid = NetdevConfIsValid;
63376404edcSAsim Jamshed 	blk->print = NetdevConfPrint;
63476404edcSAsim Jamshed 
63576404edcSAsim Jamshed 	struct netdev_conf *conf = calloc(1, sizeof(struct netdev_conf));
63676404edcSAsim Jamshed 	if (conf == NULL) {
63776404edcSAsim Jamshed 		TRACE_ERROR("Could not allocate memory for netdev_conf!\n");
63876404edcSAsim Jamshed 		exit(EXIT_FAILURE);
63976404edcSAsim Jamshed 	}
64076404edcSAsim Jamshed 	TAILQ_INIT(&conf->list);
64176404edcSAsim Jamshed 	blk->conf = conf;
64276404edcSAsim Jamshed 
64376404edcSAsim Jamshed 	blk->list = NULL;
64476404edcSAsim Jamshed }
64576404edcSAsim Jamshed /*----------------------------------------------------------------------------*/
64676404edcSAsim Jamshed static void
FetchARPKernelEntries(struct arp_conf * const config)64776404edcSAsim Jamshed FetchARPKernelEntries(struct arp_conf * const config)
64876404edcSAsim Jamshed {
64976404edcSAsim Jamshed #define	_PATH_PROCNET_ARP		"/proc/net/arp"
65076404edcSAsim Jamshed #define	DPDK_PREFIX			"dpdk"
65176404edcSAsim Jamshed #define DPDK_PREFIX_LEN			4
65276404edcSAsim Jamshed #define LINE_LEN			200
65376404edcSAsim Jamshed #define ENTRY_LEN			25
65476404edcSAsim Jamshed 
65576404edcSAsim Jamshed 	FILE *fp;
65676404edcSAsim Jamshed 	char ip[ENTRY_LEN];
65776404edcSAsim Jamshed 	char hwa[ENTRY_LEN];
65876404edcSAsim Jamshed 	char mask[ENTRY_LEN];
659a14d6bd4SAsim Jamshed 	char dev[WORD_LEN];
66076404edcSAsim Jamshed 	char line[LINE_LEN];
66176404edcSAsim Jamshed 	int type, flags, num;
66276404edcSAsim Jamshed 
66376404edcSAsim Jamshed 	if ((fp = fopen(_PATH_PROCNET_ARP, "r")) == NULL) {
66476404edcSAsim Jamshed 		perror(_PATH_PROCNET_ARP);
66576404edcSAsim Jamshed 		exit(EXIT_FAILURE);
66676404edcSAsim Jamshed 	}
66776404edcSAsim Jamshed 
66876404edcSAsim Jamshed 	/* Bypass header -- read until newline */
66976404edcSAsim Jamshed 	if (fgets(line, sizeof(line), fp) != (char *) NULL) {
67076404edcSAsim Jamshed 		strcpy(mask, "-");
67176404edcSAsim Jamshed 		strcpy(dev, "-");
67276404edcSAsim Jamshed 		/* Read the ARP cache entries. */
67376404edcSAsim Jamshed 		for (; fgets(line, sizeof(line), fp);) {
67476404edcSAsim Jamshed 
67576404edcSAsim Jamshed 			num = sscanf(line, "%s 0x%x 0x%x %100s %100s %100s\n",
67676404edcSAsim Jamshed 				     ip, &type, &flags, hwa, mask, dev);
67776404edcSAsim Jamshed 			if (num < 6)
67876404edcSAsim Jamshed 				break;
67976404edcSAsim Jamshed 
68076404edcSAsim Jamshed 			/* if the user specified device differs, skip it */
68176404edcSAsim Jamshed 			if (strncmp(dev, DPDK_PREFIX, DPDK_PREFIX_LEN))
68276404edcSAsim Jamshed 				continue;
68376404edcSAsim Jamshed 
68476404edcSAsim Jamshed 			/* if the entry has not expired/tagged for removal then... */
68576404edcSAsim Jamshed 			if (flags != 0x00) {
68676404edcSAsim Jamshed 				/* add the new arp entry in MOS database */
68776404edcSAsim Jamshed 				struct _arp_entry *ent = calloc(1, sizeof(struct _arp_entry));
68876404edcSAsim Jamshed 				if (!ent) {
68976404edcSAsim Jamshed 					TRACE_ERROR("Can't allocate memory for arp_entry\n");
69076404edcSAsim Jamshed 					exit(EXIT_FAILURE);
69176404edcSAsim Jamshed 				}
69276404edcSAsim Jamshed 				uint8_t haddr[ETH_ALEN] = {0};
69376404edcSAsim Jamshed 				if (sscanf(hwa, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
69476404edcSAsim Jamshed 					   &haddr[0], &haddr[1], &haddr[2],
69576404edcSAsim Jamshed 					   &haddr[3], &haddr[4], &haddr[5]) != 6) {
69676404edcSAsim Jamshed 					TRACE_ERROR("Error reading the ARP entry\n");
69776404edcSAsim Jamshed 					exit(EXIT_FAILURE);
69876404edcSAsim Jamshed 				}
69976404edcSAsim Jamshed 				ent->ip = inet_addr(ip);
70076404edcSAsim Jamshed 				ent->prefix = 32;
70176404edcSAsim Jamshed 				ent->mask = htonl((ent->prefix == 0) ? 0 : ((-1) << (32 - ent->prefix)));
70276404edcSAsim Jamshed 				ent->masked_ip = ent->mask & ent->ip;
70376404edcSAsim Jamshed 				memcpy(ent->haddr, haddr, ETH_ALEN);
70476404edcSAsim Jamshed 				TAILQ_INSERT_TAIL(&config->list, ent, link);
70576404edcSAsim Jamshed 				config->ent[config->num] = ent;
70676404edcSAsim Jamshed 				config->num++;
70776404edcSAsim Jamshed 			}
70876404edcSAsim Jamshed 		}
70976404edcSAsim Jamshed 	}
71076404edcSAsim Jamshed 
71176404edcSAsim Jamshed 	fclose(fp);
71276404edcSAsim Jamshed }
71376404edcSAsim Jamshed /*----------------------------------------------------------------------------*/
71476404edcSAsim Jamshed static void
FetchRouteKernelEntries(struct route_conf * const config)71576404edcSAsim Jamshed FetchRouteKernelEntries(struct route_conf * const config)
71676404edcSAsim Jamshed {
71776404edcSAsim Jamshed #define	_PATH_PROCNET_ROUTE		"/proc/net/route"
71876404edcSAsim Jamshed #define	DPDK_PREFIX			"dpdk"
71976404edcSAsim Jamshed #define DPDK_PREFIX_LEN			4
72076404edcSAsim Jamshed 
72176404edcSAsim Jamshed 	FILE *fp;
72276404edcSAsim Jamshed 	uint32_t gate;
72376404edcSAsim Jamshed 	uint32_t dest;
72476404edcSAsim Jamshed 	uint32_t mask;
725a14d6bd4SAsim Jamshed 	char dev[WORD_LEN];
72676404edcSAsim Jamshed 	char line[LINE_LEN];
72776404edcSAsim Jamshed 	char mtu[ENTRY_LEN];
72876404edcSAsim Jamshed 	char win[ENTRY_LEN];
72976404edcSAsim Jamshed 	char irtt[ENTRY_LEN];
73076404edcSAsim Jamshed 	int flags, num, cnt, use, metric;
73176404edcSAsim Jamshed 
73276404edcSAsim Jamshed 	if ((fp = fopen(_PATH_PROCNET_ROUTE, "r")) == NULL) {
73376404edcSAsim Jamshed 		perror(_PATH_PROCNET_ARP);
73476404edcSAsim Jamshed 		exit(EXIT_FAILURE);
73576404edcSAsim Jamshed 	}
73676404edcSAsim Jamshed 
73776404edcSAsim Jamshed 	/* Bypass header -- read until newline */
73876404edcSAsim Jamshed 	if (fgets(line, sizeof(line), fp) != (char *) NULL) {
73976404edcSAsim Jamshed 		/* Read the route table entries. */
74076404edcSAsim Jamshed 		for (; fgets(line, sizeof(line), fp);) {
74176404edcSAsim Jamshed 
74276404edcSAsim Jamshed 			num = sscanf(line, "%s %08X %08X %d %d %d %d %08X %s %s %s\n",
74376404edcSAsim Jamshed 				     dev,
74476404edcSAsim Jamshed 				     &dest,
74576404edcSAsim Jamshed 				     &gate,
74676404edcSAsim Jamshed 				     &flags, &cnt, &use, &metric,
74776404edcSAsim Jamshed 				     &mask,
74876404edcSAsim Jamshed 				     mtu, win, irtt);
74976404edcSAsim Jamshed 
75076404edcSAsim Jamshed 			if (num < 11)
75176404edcSAsim Jamshed 				break;
75276404edcSAsim Jamshed #if 0
75376404edcSAsim Jamshed 			/* if the user specified device differs, skip it */
75476404edcSAsim Jamshed 			if (strncmp(dev, DPDK_PREFIX, DPDK_PREFIX_LEN))
75576404edcSAsim Jamshed 				continue;
75676404edcSAsim Jamshed #endif
75776404edcSAsim Jamshed 			struct route_entry *ent = calloc(1, sizeof(struct route_entry));
75876404edcSAsim Jamshed 			if (!ent) {
75976404edcSAsim Jamshed 				TRACE_ERROR("Could not allocate memory for route_entry!\n");
76076404edcSAsim Jamshed 				exit(EXIT_FAILURE);
76176404edcSAsim Jamshed 			}
76276404edcSAsim Jamshed 
76376404edcSAsim Jamshed 			ent->ip = dest;
7649982c7d0SAsim Jamshed 
7659982c7d0SAsim Jamshed 			/* __builtin_clz() returns undefined output with zero */
7669982c7d0SAsim Jamshed 			if (mask == 0)
76730fbb30bSAsim Jamshed 				ent->prefix = 0;
7689982c7d0SAsim Jamshed 			else
76976404edcSAsim Jamshed 				ent->prefix = 32 - __builtin_clz(mask);
77076404edcSAsim Jamshed 			ent->mask = mask;
77176404edcSAsim Jamshed 			ent->masked_ip = ent->mask & ent->ip;
77276404edcSAsim Jamshed 			strcpy(ent->dev_name, dev);
77376404edcSAsim Jamshed 			TAILQ_INSERT_TAIL(&config->list, ent, link);
77476404edcSAsim Jamshed 			config->ent[config->num] = ent;
77576404edcSAsim Jamshed 			config->num++;
77676404edcSAsim Jamshed 		}
77776404edcSAsim Jamshed 	}
77876404edcSAsim Jamshed 
77976404edcSAsim Jamshed 	fclose(fp);
78076404edcSAsim Jamshed }
78176404edcSAsim Jamshed /*----------------------------------------------------------------------------*/
78276404edcSAsim Jamshed static void
InitArpBlock(struct config * config,struct conf_block * blk)78376404edcSAsim Jamshed InitArpBlock(struct config *config, struct conf_block *blk)
78476404edcSAsim Jamshed {
78576404edcSAsim Jamshed 	assert(blk);
78676404edcSAsim Jamshed 
78776404edcSAsim Jamshed 	blk->name = ARP_BLOCK_NAME;
78876404edcSAsim Jamshed 
78976404edcSAsim Jamshed 	blk->feed = FeedArpConfLine;
79076404edcSAsim Jamshed 	blk->addchild = NULL;
79176404edcSAsim Jamshed 	blk->isvalid = ArpConfIsValid;
79276404edcSAsim Jamshed 	blk->print = ArpConfPrint;
79376404edcSAsim Jamshed 
79476404edcSAsim Jamshed 	struct arp_conf *conf = calloc(1, sizeof(struct arp_conf));
79576404edcSAsim Jamshed 	if (conf == NULL) {
79676404edcSAsim Jamshed 		TRACE_ERROR("Could not allocate memory for arp_conf!\n");
79776404edcSAsim Jamshed 		exit(EXIT_FAILURE);
79876404edcSAsim Jamshed 	}
79976404edcSAsim Jamshed 	TAILQ_INIT(&conf->list);
80076404edcSAsim Jamshed 	blk->conf = conf;
80176404edcSAsim Jamshed 
80276404edcSAsim Jamshed 	blk->list = NULL;
80376404edcSAsim Jamshed 	config->mos->arp = blk;
80476404edcSAsim Jamshed 
80576404edcSAsim Jamshed 	/* fetch relevant ARP entries for dpdk? from kernel tables */
80676404edcSAsim Jamshed 	FetchARPKernelEntries(conf);
80776404edcSAsim Jamshed }
80876404edcSAsim Jamshed /*----------------------------------------------------------------------------*/
80976404edcSAsim Jamshed static void
InitRouteBlock(struct config * config,struct conf_block * blk)81076404edcSAsim Jamshed InitRouteBlock(struct config *config, struct conf_block *blk)
81176404edcSAsim Jamshed {
81276404edcSAsim Jamshed 	assert(blk);
81376404edcSAsim Jamshed 
81476404edcSAsim Jamshed 	blk->name = ROUTE_BLOCK_NAME;
81576404edcSAsim Jamshed 
81676404edcSAsim Jamshed 	blk->feed = FeedRouteConfLine;
81776404edcSAsim Jamshed 	blk->addchild = NULL;
81876404edcSAsim Jamshed 	blk->isvalid = RouteConfIsValid;
81976404edcSAsim Jamshed 	blk->print = RouteConfPrint;
82076404edcSAsim Jamshed 
82176404edcSAsim Jamshed 	struct route_conf *conf = calloc(1, sizeof(struct route_conf));
82276404edcSAsim Jamshed 	if (conf == NULL) {
82376404edcSAsim Jamshed 		TRACE_ERROR("Could not allocate memory for route_conf!\n");
82476404edcSAsim Jamshed 		exit(EXIT_FAILURE);
82576404edcSAsim Jamshed 	}
82676404edcSAsim Jamshed 	TAILQ_INIT(&conf->list);
82776404edcSAsim Jamshed 	blk->conf = conf;
82876404edcSAsim Jamshed 
82976404edcSAsim Jamshed 	blk->list = NULL;
83076404edcSAsim Jamshed 	config->mos->route = blk;
83176404edcSAsim Jamshed 
83276404edcSAsim Jamshed 	/* fetch relevant route entries for dpdk? from kernel tables */
83376404edcSAsim Jamshed 	FetchRouteKernelEntries(conf);
83476404edcSAsim Jamshed }
83576404edcSAsim Jamshed /*----------------------------------------------------------------------------*/
83676404edcSAsim Jamshed static void
InitNICForwardBlock(struct config * config,struct conf_block * blk)83776404edcSAsim Jamshed InitNICForwardBlock(struct config *config, struct conf_block *blk)
83876404edcSAsim Jamshed {
83976404edcSAsim Jamshed 	int i;
84076404edcSAsim Jamshed 	assert(blk);
84176404edcSAsim Jamshed 	blk->name = FORWARD_BLOCK_NAME;
84276404edcSAsim Jamshed 
84376404edcSAsim Jamshed 	blk->feed = FeedNICFwdConfLine;
84476404edcSAsim Jamshed 	blk->addchild = NULL;
84576404edcSAsim Jamshed 	blk->isvalid = NICFwdConfIsValid;
84676404edcSAsim Jamshed 	blk->print = NICFwdConfPrint;
84776404edcSAsim Jamshed 
84876404edcSAsim Jamshed 	struct nic_forward_conf *conf = calloc(1, sizeof(struct nic_forward_conf));
84976404edcSAsim Jamshed 	if (conf == NULL) {
85076404edcSAsim Jamshed 		TRACE_ERROR("Could not allocate memory for nic_forward_conf!\n");
85176404edcSAsim Jamshed 		exit(EXIT_FAILURE);
85276404edcSAsim Jamshed 	}
85376404edcSAsim Jamshed 	for (i = 0; i < MAX_FORWARD_ENTRY; i++)
85476404edcSAsim Jamshed 		conf->nic_fwd_table[i] = -1;
85576404edcSAsim Jamshed 
85676404edcSAsim Jamshed 	TAILQ_INIT(&conf->list);
85776404edcSAsim Jamshed 	blk->conf = conf;
85876404edcSAsim Jamshed 
85976404edcSAsim Jamshed 	blk->list = NULL;
86076404edcSAsim Jamshed 	config->mos->nic_forward = blk;
86176404edcSAsim Jamshed }
86276404edcSAsim Jamshed /*----------------------------------------------------------------------------*/
86376404edcSAsim Jamshed void
PrintConf(struct config * conf)86476404edcSAsim Jamshed PrintConf(struct config *conf)
86576404edcSAsim Jamshed {
86676404edcSAsim Jamshed 	struct conf_block *walk;
86776404edcSAsim Jamshed 	TAILQ_FOREACH(walk, &conf->app_blkh, link) {
86876404edcSAsim Jamshed 		if (walk->print)
86976404edcSAsim Jamshed 			walk->print(walk);
87076404edcSAsim Jamshed 	}
87176404edcSAsim Jamshed 
87276404edcSAsim Jamshed 	TAILQ_FOREACH(walk, &conf->mos_blkh, link) {
87376404edcSAsim Jamshed 		if (walk->print)
87476404edcSAsim Jamshed 			walk->print(walk);
87576404edcSAsim Jamshed 	}
87676404edcSAsim Jamshed }
87776404edcSAsim Jamshed /*----------------------------------------------------------------------------*/
87876404edcSAsim Jamshed static void
CheckConfValidity(struct config * conf)87976404edcSAsim Jamshed CheckConfValidity(struct config *conf)
88076404edcSAsim Jamshed {
88176404edcSAsim Jamshed 	struct conf_block *walk;
88276404edcSAsim Jamshed 	TAILQ_FOREACH(walk, &conf->app_blkh, link) {
88376404edcSAsim Jamshed 		if (!walk->isvalid || !walk->isvalid(walk))
88476404edcSAsim Jamshed 			goto __error;
88576404edcSAsim Jamshed 	}
88676404edcSAsim Jamshed 
88776404edcSAsim Jamshed 	TAILQ_FOREACH(walk, &conf->mos_blkh, link) {
88876404edcSAsim Jamshed 		struct conf_block *child;
88976404edcSAsim Jamshed 
89076404edcSAsim Jamshed 		if (!walk->isvalid || !walk->isvalid(walk))
89176404edcSAsim Jamshed 			goto __error;
89276404edcSAsim Jamshed 
89376404edcSAsim Jamshed 		child = ((struct mos_conf *)walk->conf)->netdev;
89476404edcSAsim Jamshed 		if (!child->isvalid || !child->isvalid(child))
89576404edcSAsim Jamshed 			goto __error;
89676404edcSAsim Jamshed 
89776404edcSAsim Jamshed 		child = ((struct mos_conf *)walk->conf)->arp;
89876404edcSAsim Jamshed 		if (!child->isvalid || !child->isvalid(child))
89976404edcSAsim Jamshed 			goto __error;
90076404edcSAsim Jamshed 
90176404edcSAsim Jamshed 		child = ((struct mos_conf *)walk->conf)->route;
90276404edcSAsim Jamshed 		if (!child->isvalid || !child->isvalid(child))
90376404edcSAsim Jamshed 			goto __error;
90476404edcSAsim Jamshed 	}
90576404edcSAsim Jamshed 
90676404edcSAsim Jamshed 	return;
90776404edcSAsim Jamshed 
90876404edcSAsim Jamshed __error:
90976404edcSAsim Jamshed 	printf("!!!!! Configuration validity check failure !!!!!\n");
91076404edcSAsim Jamshed 	if (walk && walk->print)
91176404edcSAsim Jamshed 		walk->print(walk);
91276404edcSAsim Jamshed 	exit(0);
91376404edcSAsim Jamshed }
91476404edcSAsim Jamshed /*----------------------------------------------------------------------------*/
91576404edcSAsim Jamshed static char *
ReadConf(const char * fname)91676404edcSAsim Jamshed ReadConf(const char *fname)
91776404edcSAsim Jamshed {
918dcdbbb98SAsim Jamshed 	ssize_t hav_read = 0, rc;
91976404edcSAsim Jamshed 	FILE *fp = fopen(fname, "r");
92076404edcSAsim Jamshed 	if (fp == NULL) {
92176404edcSAsim Jamshed 		TRACE_ERROR("Cannot open the config file %s\n", fname);
92276404edcSAsim Jamshed 		exit(-1);
92376404edcSAsim Jamshed 	}
92476404edcSAsim Jamshed 
92576404edcSAsim Jamshed 	/* find out the size of file */
92676404edcSAsim Jamshed 	fseek(fp, 0L, SEEK_END);
92776404edcSAsim Jamshed 	int size = ftell(fp);
92876404edcSAsim Jamshed 	fseek(fp, 0L, SEEK_SET);
92976404edcSAsim Jamshed 
9308a941c7eSAsim Jamshed 	file = calloc(1, size + 1);
93176404edcSAsim Jamshed 	if (file == NULL) {
93276404edcSAsim Jamshed 		TRACE_ERROR("Can't allocate memory for file!\n");
9338a941c7eSAsim Jamshed 		exit(EXIT_FAILURE);
93476404edcSAsim Jamshed 	}
93576404edcSAsim Jamshed 
93676404edcSAsim Jamshed 	file[size] = '\0';
93776404edcSAsim Jamshed 
9381879243cSAsim Jamshed 	while (hav_read < size) {
9391879243cSAsim Jamshed 		rc = fread(file, 1, size, fp);
9401879243cSAsim Jamshed 		/* sanity check */
9411879243cSAsim Jamshed 		if (rc <= 0) break;
9421879243cSAsim Jamshed 		hav_read += rc;
9431879243cSAsim Jamshed 	}
94476404edcSAsim Jamshed 
94576404edcSAsim Jamshed 	fclose(fp);
94676404edcSAsim Jamshed 
94776404edcSAsim Jamshed 	return file;
94876404edcSAsim Jamshed }
94976404edcSAsim Jamshed /*----------------------------------------------------------------------------*/
95076404edcSAsim Jamshed static char *
PreprocessConf(char * raw)95176404edcSAsim Jamshed PreprocessConf(char *raw)
95276404edcSAsim Jamshed {
95376404edcSAsim Jamshed 	char *line;
95476404edcSAsim Jamshed 	int llen;
95576404edcSAsim Jamshed 
95676404edcSAsim Jamshed 	int len = strlen(raw);
95776404edcSAsim Jamshed 
95876404edcSAsim Jamshed 	LINE_FOREACH(line, llen, raw, len) {
95976404edcSAsim Jamshed 		int i, iscomment = 0;
96076404edcSAsim Jamshed 		for (i = 0; i < llen; i++) {
96176404edcSAsim Jamshed 			if (!iscomment && line[i] == '#')
96276404edcSAsim Jamshed 				iscomment = 1;
96376404edcSAsim Jamshed 			if (iscomment)
96476404edcSAsim Jamshed 				line[i] = ' ';
96576404edcSAsim Jamshed 		}
96676404edcSAsim Jamshed 	}
96776404edcSAsim Jamshed 	return raw;
96876404edcSAsim Jamshed }
96976404edcSAsim Jamshed /*----------------------------------------------------------------------------*/
97076404edcSAsim Jamshed static void
InitConfig(struct config * config)97176404edcSAsim Jamshed InitConfig(struct config *config)
97276404edcSAsim Jamshed {
97376404edcSAsim Jamshed 	int i;
97476404edcSAsim Jamshed 	struct conf_block *blk;
97576404edcSAsim Jamshed 
97676404edcSAsim Jamshed 	TAILQ_INIT(&g_free_blkh);
97776404edcSAsim Jamshed 	TAILQ_INIT(&config->app_blkh);
97876404edcSAsim Jamshed 	TAILQ_INIT(&config->mos_blkh);
97976404edcSAsim Jamshed 
98076404edcSAsim Jamshed 	for (i = 0; i < MAX_APP_BLOCK; i++) {
98176404edcSAsim Jamshed 		/* Allocate app conf_block */
98276404edcSAsim Jamshed 		blk = calloc(1, sizeof(struct conf_block));
98376404edcSAsim Jamshed 		if (blk == NULL) goto init_config_err;
98476404edcSAsim Jamshed 		InitAppBlock(config, blk);
98576404edcSAsim Jamshed 		TAILQ_INSERT_TAIL(&g_free_blkh, blk, link);
98676404edcSAsim Jamshed 
98776404edcSAsim Jamshed 		/* Allocate netdev conf_block */
98876404edcSAsim Jamshed 		blk = calloc(1, sizeof(struct conf_block));
98976404edcSAsim Jamshed 		if (blk == NULL) goto init_config_err;
99076404edcSAsim Jamshed 		InitNetdevBlock(config, blk);
99176404edcSAsim Jamshed 		TAILQ_INSERT_TAIL(&g_free_blkh, blk, link);
99276404edcSAsim Jamshed 	}
99376404edcSAsim Jamshed 
99476404edcSAsim Jamshed 	for (i = 0; i < MAX_MOS_BLOCK; i++) {
99576404edcSAsim Jamshed 		/* Allocate mos conf_block */
99676404edcSAsim Jamshed 		blk = calloc(1, sizeof(struct conf_block));
99776404edcSAsim Jamshed 		if (blk == NULL) goto init_config_err;
99876404edcSAsim Jamshed 		InitMosBlock(config, blk);
99976404edcSAsim Jamshed 		TAILQ_INSERT_TAIL(&g_free_blkh, blk, link);
100076404edcSAsim Jamshed 
100176404edcSAsim Jamshed 		/* Allocate arp conf_block */
100276404edcSAsim Jamshed 		blk = calloc(1, sizeof(struct conf_block));
100376404edcSAsim Jamshed 		if (blk == NULL) goto init_config_err;
100476404edcSAsim Jamshed 		InitArpBlock(config, blk);
100576404edcSAsim Jamshed 		TAILQ_INSERT_TAIL(&g_free_blkh, blk, link);
100676404edcSAsim Jamshed 
100776404edcSAsim Jamshed 		/* Allocate route conf_block */
100876404edcSAsim Jamshed 		blk = calloc(1, sizeof(struct conf_block));
100976404edcSAsim Jamshed 		if (blk == NULL) goto init_config_err;
101076404edcSAsim Jamshed 		InitRouteBlock(config, blk);
101176404edcSAsim Jamshed 		TAILQ_INSERT_TAIL(&g_free_blkh, blk, link);
101276404edcSAsim Jamshed 
101376404edcSAsim Jamshed 		/* Allocate nic_forward conf_block */
101476404edcSAsim Jamshed 		blk = calloc (1, sizeof(struct conf_block));
101576404edcSAsim Jamshed 		if (blk == NULL) goto init_config_err;
101676404edcSAsim Jamshed 		InitNICForwardBlock(config, blk);
101776404edcSAsim Jamshed 		TAILQ_INSERT_TAIL(&g_free_blkh, blk, link);
101876404edcSAsim Jamshed 	}
101976404edcSAsim Jamshed 	return;
102076404edcSAsim Jamshed  init_config_err:
102176404edcSAsim Jamshed 	TRACE_ERROR("Can't allocate memory for blk_entry!\n");
102276404edcSAsim Jamshed 	exit(EXIT_FAILURE);
102376404edcSAsim Jamshed }
102476404edcSAsim Jamshed /*----------------------------------------------------------------------------*/
102576404edcSAsim Jamshed static struct conf_block *
AllocateBlock(char * name,int len)102676404edcSAsim Jamshed AllocateBlock(char *name, int len)
102776404edcSAsim Jamshed {
102876404edcSAsim Jamshed 	struct conf_block *walk, *tmp;
102976404edcSAsim Jamshed 
103076404edcSAsim Jamshed 	for (walk = TAILQ_FIRST(&g_free_blkh); walk != NULL; walk = tmp) {
103176404edcSAsim Jamshed 		tmp = TAILQ_NEXT(walk, link);
103276404edcSAsim Jamshed 		if (len == strlen(walk->name) && strncmp(walk->name, name, len) == 0) {
103376404edcSAsim Jamshed 			TAILQ_REMOVE(&g_free_blkh, walk, link);
103476404edcSAsim Jamshed 			if (walk->list)
103576404edcSAsim Jamshed 				TAILQ_INSERT_TAIL(walk->list, walk, link);
103676404edcSAsim Jamshed 			return walk;
103776404edcSAsim Jamshed 		}
103876404edcSAsim Jamshed 	}
103976404edcSAsim Jamshed 
104076404edcSAsim Jamshed 	return NULL;
104176404edcSAsim Jamshed }
104276404edcSAsim Jamshed /*----------------------------------------------------------------------------*/
104376404edcSAsim Jamshed struct conf_block *
DetectBlock(struct conf_block * blk,char * buf,int len)104476404edcSAsim Jamshed DetectBlock(struct conf_block *blk, char *buf, int len)
104576404edcSAsim Jamshed {
104676404edcSAsim Jamshed 	int depth = 0;
1047a14d6bd4SAsim Jamshed 	char *blkname = NULL, *end = &buf[len];
104876404edcSAsim Jamshed 	int blknamelen;
104976404edcSAsim Jamshed 	struct conf_block *nblk;
105076404edcSAsim Jamshed 
105176404edcSAsim Jamshed 	/* skip first space */
105276404edcSAsim Jamshed 	while (buf < end && isspace(*buf))
105376404edcSAsim Jamshed 		buf++;
105476404edcSAsim Jamshed 
105576404edcSAsim Jamshed 	if (DetectWord(buf, len, &blkname, &blknamelen) < 0
105676404edcSAsim Jamshed 			|| blkname != buf)
105776404edcSAsim Jamshed 		/* Failed to detect conf_block name */
105876404edcSAsim Jamshed 		return NULL;
105976404edcSAsim Jamshed 
106076404edcSAsim Jamshed 	/* fast forward buffer */
106176404edcSAsim Jamshed 	buf += blknamelen;
106276404edcSAsim Jamshed 
106376404edcSAsim Jamshed 	/* skip space */
106476404edcSAsim Jamshed 	while (buf < end && isspace(*buf))
106576404edcSAsim Jamshed 		buf++;
106676404edcSAsim Jamshed 
106776404edcSAsim Jamshed 	/* buf must be '{' */
106876404edcSAsim Jamshed 	if (buf >= end || *buf != '{')
106976404edcSAsim Jamshed 		return NULL;
107076404edcSAsim Jamshed 
107176404edcSAsim Jamshed 	buf++;   /* skip '{' */
107276404edcSAsim Jamshed 	while (buf < end && isspace(*buf))
107376404edcSAsim Jamshed 		buf++; /* skip space */
107476404edcSAsim Jamshed 	depth++; /* Now in first parenthesis */
107576404edcSAsim Jamshed 
107676404edcSAsim Jamshed 	/* Now, the `buf` points the first byte inside conf_block */
107776404edcSAsim Jamshed 
107876404edcSAsim Jamshed 	for (len = 0; &buf[len] < end; len++) {
107976404edcSAsim Jamshed 		if (buf[len] == '{')
108076404edcSAsim Jamshed 			depth++;
108176404edcSAsim Jamshed 		else if (buf[len] == '}' && --depth == 0)
108276404edcSAsim Jamshed 				break;
108376404edcSAsim Jamshed 	}
108476404edcSAsim Jamshed 
108576404edcSAsim Jamshed 	if (depth != 0)
108676404edcSAsim Jamshed 		/* Failed to find the end of parenthesis */
108776404edcSAsim Jamshed 		return NULL;
108876404edcSAsim Jamshed 
108976404edcSAsim Jamshed 	if (!(nblk = AllocateBlock(blkname, blknamelen)))
109076404edcSAsim Jamshed 		return NULL;
109176404edcSAsim Jamshed 
109276404edcSAsim Jamshed 	if (blk) {
109376404edcSAsim Jamshed 		assert(blk->addchild);
109476404edcSAsim Jamshed 		blk->addchild(blk, nblk);
109576404edcSAsim Jamshed 	}
109676404edcSAsim Jamshed 
109776404edcSAsim Jamshed 	nblk->buf = buf;
109876404edcSAsim Jamshed 	nblk->len = len;
109976404edcSAsim Jamshed 
110076404edcSAsim Jamshed 	return nblk;
110176404edcSAsim Jamshed }
110276404edcSAsim Jamshed /*----------------------------------------------------------------------------*/
110376404edcSAsim Jamshed static void
ParseBlock(struct conf_block * blk)110476404edcSAsim Jamshed ParseBlock(struct conf_block *blk)
110576404edcSAsim Jamshed {
110676404edcSAsim Jamshed 	char *line;
110776404edcSAsim Jamshed 	int llen;
110876404edcSAsim Jamshed 
110976404edcSAsim Jamshed 	LINE_FOREACH(line, llen, blk->buf, blk->len) {
111076404edcSAsim Jamshed 		struct conf_block *nblk;
111176404edcSAsim Jamshed 
111276404edcSAsim Jamshed 		if ((nblk = DetectBlock(blk, line, blk->len - (line - blk->buf)))) {
111376404edcSAsim Jamshed 			ParseBlock(nblk);
111476404edcSAsim Jamshed 			/* skip nested conf_block by fast forwarding line */
111576404edcSAsim Jamshed 			line = &nblk->buf[nblk->len] + 1;
111676404edcSAsim Jamshed 			llen = 0;
111776404edcSAsim Jamshed 		} else
111876404edcSAsim Jamshed 			blk->feed(blk, line, llen);
111976404edcSAsim Jamshed 	}
112076404edcSAsim Jamshed }
112176404edcSAsim Jamshed /*----------------------------------------------------------------------------*/
112276404edcSAsim Jamshed void
PatchCONFIG(struct config * config)112376404edcSAsim Jamshed PatchCONFIG(struct config *config)
112476404edcSAsim Jamshed {
1125*7245de1bSYoungGyoun 	int i, count;
112676404edcSAsim Jamshed 	char *word, *str, *end;
112776404edcSAsim Jamshed 	int wlen;
1128*7245de1bSYoungGyoun 	uint64_t value;
112976404edcSAsim Jamshed 
1130*7245de1bSYoungGyoun 	value = g_config.mos->cpu_mask;
1131*7245de1bSYoungGyoun 	for (count = 0; value != 0; count++, value &= value-1);
1132*7245de1bSYoungGyoun 	if (count > num_cpus) {
1133*7245de1bSYoungGyoun 		TRACE_ERROR("CPU mask (%016lX) exceeds the number of CPU cores (%d)\n",
1134*7245de1bSYoungGyoun 					g_config.mos->cpu_mask, num_cpus);
1135*7245de1bSYoungGyoun 		exit(-1);
1136*7245de1bSYoungGyoun 	}
1137*7245de1bSYoungGyoun 	if (count > MAX_CPUS) {
1138*7245de1bSYoungGyoun 		TRACE_ERROR("mOS does not support more than %d CPU cores for now\n",
1139*7245de1bSYoungGyoun 					MAX_CPUS);
1140*7245de1bSYoungGyoun 		exit(-1);
1141*7245de1bSYoungGyoun 	}
1142*7245de1bSYoungGyoun 	g_config.mos->num_cores = count;
1143*7245de1bSYoungGyoun 
114476404edcSAsim Jamshed 	word = NULL;
114576404edcSAsim Jamshed 
114676404edcSAsim Jamshed 	i = 0;
114776404edcSAsim Jamshed 	struct conf_block *bwalk;
114876404edcSAsim Jamshed 	TAILQ_FOREACH(bwalk, &g_config.app_blkh, link) {
114976404edcSAsim Jamshed 		struct app_conf *app_conf = (struct app_conf *)bwalk->conf;
115076404edcSAsim Jamshed 		g_config.mos->forward = g_config.mos->forward && app_conf->ip_forward;
115176404edcSAsim Jamshed 		if (end_app_exists == 0 && !strcmp(app_conf->type, "end"))
115276404edcSAsim Jamshed 			end_app_exists = 1;
115376404edcSAsim Jamshed 		if (mon_app_exists == 0 && !strcmp(app_conf->type, "monitor"))
115476404edcSAsim Jamshed 			mon_app_exists = 1;
115576404edcSAsim Jamshed 		i++;
115676404edcSAsim Jamshed 	}
115776404edcSAsim Jamshed 	/* turn on monitor mode if end app is not set */
115876404edcSAsim Jamshed 	if (!end_app_exists && !mon_app_exists) mon_app_exists = 1;
115976404edcSAsim Jamshed 
116076404edcSAsim Jamshed 	/* stat print */
116176404edcSAsim Jamshed 	str = g_config.mos->stat_print;
116276404edcSAsim Jamshed 	end = str + strlen(str);
116376404edcSAsim Jamshed 	while (DetectWord(str, end - str, &word, &wlen) == 0) {
116476404edcSAsim Jamshed 		for (i = 0; i < g_config.mos->netdev_table->num; i++) {
116576404edcSAsim Jamshed 			if (strncmp(g_config.mos->netdev_table->ent[i]->dev_name, word, wlen) == 0) {
116676404edcSAsim Jamshed 				g_config.mos->netdev_table->ent[i]->stat_print = TRUE;
116776404edcSAsim Jamshed 			}
116876404edcSAsim Jamshed 		}
116976404edcSAsim Jamshed 		str = word + wlen;
117076404edcSAsim Jamshed 	}
117176404edcSAsim Jamshed 
117276404edcSAsim Jamshed }
117376404edcSAsim Jamshed /*----------------------------------------------------------------------------*/
117476404edcSAsim Jamshed int
LoadConfigurationUpperHalf(const char * fname)117576404edcSAsim Jamshed LoadConfigurationUpperHalf(const char *fname)
117676404edcSAsim Jamshed {
117776404edcSAsim Jamshed 	char *line;
117876404edcSAsim Jamshed 	int llen;
117976404edcSAsim Jamshed 
118076404edcSAsim Jamshed 	char *raw = ReadConf(fname);
118176404edcSAsim Jamshed 	char *preprocessed = PreprocessConf(raw);
118276404edcSAsim Jamshed 	int len = strlen(preprocessed);
118376404edcSAsim Jamshed 
118476404edcSAsim Jamshed 	InitConfig(&g_config);
118576404edcSAsim Jamshed 
118676404edcSAsim Jamshed 	LINE_FOREACH(line, llen, preprocessed, len) {
118776404edcSAsim Jamshed 		struct conf_block *nblk;
118876404edcSAsim Jamshed 
118976404edcSAsim Jamshed 		if ((nblk = DetectBlock(NULL, line, len - (line - preprocessed)))) {
119076404edcSAsim Jamshed 			ParseBlock(nblk);
119176404edcSAsim Jamshed 			/* skip parsed conf_block by fast forwarding line */
119276404edcSAsim Jamshed 			line = &nblk->buf[nblk->len] + 1;
119376404edcSAsim Jamshed 			llen = 0;
119476404edcSAsim Jamshed 		}
119576404edcSAsim Jamshed 	}
119676404edcSAsim Jamshed 
119776404edcSAsim Jamshed 	CheckConfValidity(&g_config);
119876404edcSAsim Jamshed 
119976404edcSAsim Jamshed 	PatchCONFIG(&g_config);
120076404edcSAsim Jamshed 
120176404edcSAsim Jamshed 	//PrintConf(&g_config);
120276404edcSAsim Jamshed 
120376404edcSAsim Jamshed 	return 0;
120476404edcSAsim Jamshed }
120576404edcSAsim Jamshed /*----------------------------------------------------------------------------*/
120676404edcSAsim Jamshed void
LoadConfigurationLowerHalf(void)120776404edcSAsim Jamshed LoadConfigurationLowerHalf(void)
120876404edcSAsim Jamshed {
120976404edcSAsim Jamshed 	struct route_conf *route_conf = g_config.mos->route_table;
121076404edcSAsim Jamshed 	struct netdev_conf *netdev_conf = g_config.mos->netdev_table;
121176404edcSAsim Jamshed 	struct nic_forward_conf *nicfwd_conf = g_config.mos->nic_forward_table;
121276404edcSAsim Jamshed 	struct route_entry *rwalk;
121376404edcSAsim Jamshed 	struct netdev_entry *nwalk;
121476404edcSAsim Jamshed 	struct nic_forward_entry *fwalk;
121576404edcSAsim Jamshed 	int nif_in = -1;
121676404edcSAsim Jamshed 	int nif_out = -1;
121776404edcSAsim Jamshed 
121876404edcSAsim Jamshed 	TAILQ_FOREACH(rwalk, &route_conf->list, link) {
121976404edcSAsim Jamshed 		TAILQ_FOREACH(nwalk, &netdev_conf->list, link) {
122076404edcSAsim Jamshed 			if (!strcmp(nwalk->dev_name, rwalk->dev_name))
122176404edcSAsim Jamshed 				break;
122276404edcSAsim Jamshed 		}
122376404edcSAsim Jamshed 		if (!nwalk)
122476404edcSAsim Jamshed 			continue;
122576404edcSAsim Jamshed 		if (nwalk->ifindex < 0 &&
122676404edcSAsim Jamshed 			(nwalk->ifindex = current_iomodule_func->get_nif(&nwalk->ifr)) < 0) {
122776404edcSAsim Jamshed 			TRACE_ERROR("Interface '%s' not found\n", nwalk->dev_name);
122876404edcSAsim Jamshed 			exit(EXIT_FAILURE);
122976404edcSAsim Jamshed 		}
123076404edcSAsim Jamshed 
123176404edcSAsim Jamshed 		rwalk->nif = nwalk->ifindex;
123276404edcSAsim Jamshed 	}
123376404edcSAsim Jamshed 
123476404edcSAsim Jamshed 	if (nicfwd_conf != NULL) {
123576404edcSAsim Jamshed 		TAILQ_FOREACH(fwalk, &nicfwd_conf->list, link) {
123676404edcSAsim Jamshed 			TAILQ_FOREACH(nwalk, &netdev_conf->list, link) {
123776404edcSAsim Jamshed 				if (!strcmp(nwalk->dev_name, fwalk->nif_in))
123857ae271fSAsim Jamshed 					nif_in = nwalk->ifindex = current_iomodule_func->get_nif(&nwalk->ifr);
123976404edcSAsim Jamshed 				if (!strcmp(nwalk->dev_name, fwalk->nif_out))
124057ae271fSAsim Jamshed 					nif_out = nwalk->ifindex = current_iomodule_func->get_nif(&nwalk->ifr);
124176404edcSAsim Jamshed 			}
124276404edcSAsim Jamshed 
124376404edcSAsim Jamshed 			if (nif_in != -1)
124476404edcSAsim Jamshed 				nicfwd_conf->nic_fwd_table[nif_in] = nif_out;
124576404edcSAsim Jamshed 			if (nif_out != -1)
124676404edcSAsim Jamshed 				nicfwd_conf->nic_fwd_table[nif_out] = nif_in;
124776404edcSAsim Jamshed 			nif_in = nif_out = -1;
124876404edcSAsim Jamshed 		}
124976404edcSAsim Jamshed 	}
125076404edcSAsim Jamshed }
125176404edcSAsim Jamshed /*----------------------------------------------------------------------------*/
12528a941c7eSAsim Jamshed void
FreeConfigResources()12538a941c7eSAsim Jamshed FreeConfigResources()
12548a941c7eSAsim Jamshed {
12558a941c7eSAsim Jamshed 	if (file) {
12568a941c7eSAsim Jamshed 		free(file);
12578a941c7eSAsim Jamshed 		file = NULL;
12588a941c7eSAsim Jamshed 	}
12598a941c7eSAsim Jamshed }
12608a941c7eSAsim Jamshed /*----------------------------------------------------------------------------*/
1261b88bd7d2SAsim Jamshed int
FetchEndianType()1262b88bd7d2SAsim Jamshed FetchEndianType()
1263b88bd7d2SAsim Jamshed {
126402e590b6SAsim Jamshed #ifdef ENABLE_DPDK
1265b88bd7d2SAsim Jamshed 	char *argv;
1266b88bd7d2SAsim Jamshed 	char **argp = &argv;
126702e590b6SAsim Jamshed 
1268b88bd7d2SAsim Jamshed 	if (current_iomodule_func == &dpdk_module_func) {
1269b88bd7d2SAsim Jamshed 		/* dpdk_module_func logic down below */
1270b88bd7d2SAsim Jamshed 		dpdk_module_func.dev_ioctl(NULL, 0, DRV_NAME, (void *)argp);
1271b88bd7d2SAsim Jamshed 		if (!strcmp(*argp, "net_i40e"))
1272b88bd7d2SAsim Jamshed 			return 1;
1273b88bd7d2SAsim Jamshed 
1274b88bd7d2SAsim Jamshed 		return 0;
1275b88bd7d2SAsim Jamshed 	}
127602e590b6SAsim Jamshed #endif
1277b88bd7d2SAsim Jamshed 	return 1;
1278b88bd7d2SAsim Jamshed }
1279b88bd7d2SAsim Jamshed /*----------------------------------------------------------------------------*/
1280