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