コード例 #1
0
ファイル: eal_common_options.c プロジェクト: zzl133/fastpath
int
eal_adjust_config(struct internal_config *internal_cfg)
{
	int i;
	struct rte_config *cfg = rte_eal_get_configuration();

	if (internal_config.process_type == RTE_PROC_AUTO)
		internal_config.process_type = eal_proc_type_detect();

	/* default master lcore is the first one */
	if (!master_lcore_parsed)
		cfg->master_lcore = rte_get_next_lcore(-1, 0, 0);

	/* if no memory amounts were requested, this will result in 0 and
	 * will be overridden later, right after eal_hugepage_info_init() */
	for (i = 0; i < RTE_MAX_NUMA_NODES; i++)
		internal_cfg->memory += internal_cfg->socket_mem[i];

	return 0;
}
コード例 #2
0
ファイル: eal.c プロジェクト: AMildner/MoonGen
/* Sets up rte_config structure with the pointer to shared memory config.*/
static void
rte_config_init(void)
{
	rte_config.process_type = (internal_config.process_type == RTE_PROC_AUTO) ?
			eal_proc_type_detect() : /* for auto, detect the type */
			internal_config.process_type; /* otherwise use what's already set */

	switch (rte_config.process_type){
	case RTE_PROC_PRIMARY:
		rte_eal_config_create();
		break;
	case RTE_PROC_SECONDARY:
		rte_eal_config_attach();
		rte_eal_mcfg_wait_complete(rte_config.mem_config);
		rte_eal_config_reattach();
		break;
	case RTE_PROC_AUTO:
	case RTE_PROC_INVALID:
		rte_panic("Invalid process type\n");
	}
}
コード例 #3
0
ファイル: eal.c プロジェクト: AMildner/MoonGen
/* Parse the argument given in the command line of the application */
static int
eal_parse_args(int argc, char **argv)
{
	int opt, ret, i;
	char **argvopt;
	int option_index;
	int coremask_ok = 0;
	char *prgname = argv[0];
	static struct option lgopts[] = {
		{OPT_NO_HUGE, 0, 0, 0},
		{OPT_NO_PCI, 0, 0, 0},
		{OPT_NO_HPET, 0, 0, 0},
		{OPT_VMWARE_TSC_MAP, 0, 0, 0},
		{OPT_HUGE_DIR, 1, 0, 0},
		{OPT_NO_SHCONF, 0, 0, 0},
		{OPT_PROC_TYPE, 1, 0, 0},
		{OPT_FILE_PREFIX, 1, 0, 0},
		{OPT_SOCKET_MEM, 1, 0, 0},
		{OPT_PCI_WHITELIST, 1, 0, 0},
		{OPT_PCI_BLACKLIST, 1, 0, 0},
		{OPT_VDEV, 1, 0, 0},
		{OPT_SYSLOG, 1, NULL, 0},
		{OPT_VFIO_INTR, 1, NULL, 0},
		{OPT_BASE_VIRTADDR, 1, 0, 0},
		{OPT_XEN_DOM0, 0, 0, 0},
		{OPT_CREATE_UIO_DEV, 1, NULL, 0},
		{0, 0, 0, 0}
	};
	struct shared_driver *solib;

	argvopt = argv;

	internal_config.memory = 0;
	internal_config.force_nrank = 0;
	internal_config.force_nchannel = 0;
	internal_config.hugefile_prefix = HUGEFILE_PREFIX_DEFAULT;
	internal_config.hugepage_dir = NULL;
	internal_config.force_sockets = 0;
	internal_config.syslog_facility = LOG_DAEMON;
	internal_config.xen_dom0_support = 0;
	/* if set to NONE, interrupt mode is determined automatically */
	internal_config.vfio_intr_mode = RTE_INTR_MODE_NONE;
#ifdef RTE_LIBEAL_USE_HPET
	internal_config.no_hpet = 0;
#else
	internal_config.no_hpet = 1;
#endif
	/* zero out the NUMA config */
	for (i = 0; i < RTE_MAX_NUMA_NODES; i++)
		internal_config.socket_mem[i] = 0;

	/* zero out hugedir descriptors */
	for (i = 0; i < MAX_HUGEPAGE_SIZES; i++)
		internal_config.hugepage_info[i].lock_descriptor = -1;

	internal_config.vmware_tsc_map = 0;
	internal_config.base_virtaddr = 0;

	while ((opt = getopt_long(argc, argvopt, "b:w:c:d:m:n:r:v",
				  lgopts, &option_index)) != EOF) {

		switch (opt) {
		/* blacklist */
		case 'b':
			if (rte_eal_devargs_add(RTE_DEVTYPE_BLACKLISTED_PCI,
					optarg) < 0) {
				eal_usage(prgname);
				return (-1);
			}
			break;
		/* whitelist */
		case 'w':
			if (rte_eal_devargs_add(RTE_DEVTYPE_WHITELISTED_PCI,
					optarg) < 0) {
				eal_usage(prgname);
				return -1;
			}
			break;
		/* coremask */
		case 'c':
			if (eal_parse_coremask(optarg) < 0) {
				RTE_LOG(ERR, EAL, "invalid coremask\n");
				eal_usage(prgname);
				return -1;
			}
			coremask_ok = 1;
			break;
		/* force loading of external driver */
		case 'd':
			solib = malloc(sizeof(*solib));
			if (solib == NULL) {
				RTE_LOG(ERR, EAL, "malloc(solib) failed\n");
				return -1;
			}
			memset(solib, 0, sizeof(*solib));
			strncpy(solib->name, optarg, PATH_MAX-1);
			solib->name[PATH_MAX-1] = 0;
			TAILQ_INSERT_TAIL(&solib_list, solib, next);
			break;
		/* size of memory */
		case 'm':
			internal_config.memory = atoi(optarg);
			internal_config.memory *= 1024ULL;
			internal_config.memory *= 1024ULL;
			break;
		/* force number of channels */
		case 'n':
			internal_config.force_nchannel = atoi(optarg);
			if (internal_config.force_nchannel == 0 ||
			    internal_config.force_nchannel > 4) {
				RTE_LOG(ERR, EAL, "invalid channel number\n");
				eal_usage(prgname);
				return -1;
			}
			break;
		/* force number of ranks */
		case 'r':
			internal_config.force_nrank = atoi(optarg);
			if (internal_config.force_nrank == 0 ||
			    internal_config.force_nrank > 16) {
				RTE_LOG(ERR, EAL, "invalid rank number\n");
				eal_usage(prgname);
				return -1;
			}
			break;
		case 'v':
			/* since message is explicitly requested by user, we
			 * write message at highest log level so it can always be seen
			 * even if info or warning messages are disabled */
			RTE_LOG(CRIT, EAL, "RTE Version: '%s'\n", rte_version());
			break;

		/* long options */
		case 0:
			if (!strcmp(lgopts[option_index].name, OPT_NO_HUGE)) {
				internal_config.no_hugetlbfs = 1;
			}
			if (!strcmp(lgopts[option_index].name, OPT_XEN_DOM0)) {
		#ifdef RTE_LIBRTE_XEN_DOM0
				internal_config.xen_dom0_support = 1;
		#else
				RTE_LOG(ERR, EAL, "Can't support DPDK app "
					"running on Dom0, please configure"
					" RTE_LIBRTE_XEN_DOM0=y\n");
				return -1;
		#endif
			}
			else if (!strcmp(lgopts[option_index].name, OPT_NO_PCI)) {
				internal_config.no_pci = 1;
			}
			else if (!strcmp(lgopts[option_index].name, OPT_NO_HPET)) {
				internal_config.no_hpet = 1;
			}
			else if (!strcmp(lgopts[option_index].name, OPT_VMWARE_TSC_MAP)) {
				internal_config.vmware_tsc_map = 1;
			}
			else if (!strcmp(lgopts[option_index].name, OPT_NO_SHCONF)) {
				internal_config.no_shconf = 1;
			}
			else if (!strcmp(lgopts[option_index].name, OPT_HUGE_DIR)) {
				internal_config.hugepage_dir = optarg;
			}
			else if (!strcmp(lgopts[option_index].name, OPT_PROC_TYPE)) {
				internal_config.process_type = eal_parse_proc_type(optarg);
			}
			else if (!strcmp(lgopts[option_index].name, OPT_FILE_PREFIX)) {
				internal_config.hugefile_prefix = optarg;
			}
			else if (!strcmp(lgopts[option_index].name, OPT_SOCKET_MEM)) {
				if (eal_parse_socket_mem(optarg) < 0) {
					RTE_LOG(ERR, EAL, "invalid parameters for --"
							OPT_SOCKET_MEM "\n");
					eal_usage(prgname);
					return -1;
				}
			}
			else if (!strcmp(lgopts[option_index].name, OPT_USE_DEVICE)) {
				printf("The --use-device option is deprecated, please use\n"
					"--whitelist or --vdev instead.\n");
				eal_usage(prgname);
				return -1;
			}
			else if (!strcmp(lgopts[option_index].name, OPT_PCI_BLACKLIST)) {
				if (rte_eal_devargs_add(RTE_DEVTYPE_BLACKLISTED_PCI,
						optarg) < 0) {
					eal_usage(prgname);
					return -1;
				}
			}
			else if (!strcmp(lgopts[option_index].name, OPT_PCI_WHITELIST)) {
				if (rte_eal_devargs_add(RTE_DEVTYPE_WHITELISTED_PCI,
						optarg) < 0) {
					eal_usage(prgname);
					return -1;
				}
			}
			else if (!strcmp(lgopts[option_index].name, OPT_VDEV)) {
				if (rte_eal_devargs_add(RTE_DEVTYPE_VIRTUAL,
						optarg) < 0) {
					eal_usage(prgname);
					return -1;
				}
			}
			else if (!strcmp(lgopts[option_index].name, OPT_SYSLOG)) {
				if (eal_parse_syslog(optarg) < 0) {
					RTE_LOG(ERR, EAL, "invalid parameters for --"
							OPT_SYSLOG "\n");
					eal_usage(prgname);
					return -1;
				}
			}
			else if (!strcmp(lgopts[option_index].name, OPT_BASE_VIRTADDR)) {
				if (eal_parse_base_virtaddr(optarg) < 0) {
					RTE_LOG(ERR, EAL, "invalid parameter for --"
							OPT_BASE_VIRTADDR "\n");
					eal_usage(prgname);
					return -1;
				}
			}
			else if (!strcmp(lgopts[option_index].name, OPT_VFIO_INTR)) {
				if (eal_parse_vfio_intr(optarg) < 0) {
					RTE_LOG(ERR, EAL, "invalid parameters for --"
							OPT_VFIO_INTR "\n");
					eal_usage(prgname);
					return -1;
				}
			}
			else if (!strcmp(lgopts[option_index].name, OPT_CREATE_UIO_DEV)) {
				internal_config.create_uio_dev = 1;
			}
			break;

		default:
			eal_usage(prgname);
			return -1;
		}
	}

	/* sanity checks */
	if (!coremask_ok) {
		RTE_LOG(ERR, EAL, "coremask not specified\n");
		eal_usage(prgname);
		return -1;
	}
	if (internal_config.process_type == RTE_PROC_AUTO){
		internal_config.process_type = eal_proc_type_detect();
	}
	if (internal_config.process_type == RTE_PROC_INVALID){
		RTE_LOG(ERR, EAL, "Invalid process type specified\n");
		eal_usage(prgname);
		return -1;
	}
	if (internal_config.process_type == RTE_PROC_PRIMARY &&
			internal_config.force_nchannel == 0) {
		RTE_LOG(ERR, EAL, "Number of memory channels (-n) not specified\n");
		eal_usage(prgname);
		return -1;
	}
	if (index(internal_config.hugefile_prefix,'%') != NULL){
		RTE_LOG(ERR, EAL, "Invalid char, '%%', in '"OPT_FILE_PREFIX"' option\n");
		eal_usage(prgname);
		return -1;
	}
	if (internal_config.memory > 0 && internal_config.force_sockets == 1) {
		RTE_LOG(ERR, EAL, "Options -m and --socket-mem cannot be specified "
				"at the same time\n");
		eal_usage(prgname);
		return -1;
	}
	/* --no-huge doesn't make sense with either -m or --socket-mem */
	if (internal_config.no_hugetlbfs &&
			(internal_config.memory > 0 ||
					internal_config.force_sockets == 1)) {
		RTE_LOG(ERR, EAL, "Options -m or --socket-mem cannot be specified "
				"together with --no-huge!\n");
		eal_usage(prgname);
		return -1;
	}
	/* --xen-dom0 doesn't make sense with --socket-mem */
	if (internal_config.xen_dom0_support && internal_config.force_sockets == 1) {
		RTE_LOG(ERR, EAL, "Options --socket-mem cannot be specified "
					"together with --xen_dom0!\n");
		eal_usage(prgname);
		return -1;
	}

	if (rte_eal_devargs_type_count(RTE_DEVTYPE_WHITELISTED_PCI) != 0 &&
		rte_eal_devargs_type_count(RTE_DEVTYPE_BLACKLISTED_PCI) != 0) {
		RTE_LOG(ERR, EAL, "Error: blacklist [-b] and whitelist "
			"[-w] options cannot be used at the same time\n");
		eal_usage(prgname);
		return -1;
	}

	if (optind >= 0)
		argv[optind-1] = prgname;

	/* if no memory amounts were requested, this will result in 0 and
	 * will be overriden later, right after eal_hugepage_info_init() */
	for (i = 0; i < RTE_MAX_NUMA_NODES; i++)
		internal_config.memory += internal_config.socket_mem[i];

	ret = optind-1;
	optind = 0; /* reset getopt lib */
	return ret;
}
コード例 #4
0
ファイル: io_module.c プロジェクト: eunyoung14/mtcp
/*----------------------------------------------------------------------------*/
int
SetNetEnv(char *dev_name_list, char *port_stat_list)
{
	int eidx = 0;
	int i, j;

	int set_all_inf = (strncmp(dev_name_list, ALL_STRING, sizeof(ALL_STRING))==0);

	TRACE_CONFIG("Loading interface setting\n");

	CONFIG.eths = (struct eth_table *)
			calloc(MAX_DEVICES, sizeof(struct eth_table));
	if (!CONFIG.eths) {
		TRACE_ERROR("Can't allocate space for CONFIG.eths\n");
		exit(EXIT_FAILURE);
	}

	if (current_iomodule_func == &ps_module_func) {
#ifndef DISABLE_PSIO
		struct ifreq ifr;		
		/* calculate num_devices now! */
		num_devices = ps_list_devices(devices);
		if (num_devices == -1) {
			perror("ps_list_devices");
			exit(EXIT_FAILURE);
		}

		/* Create socket */
		int sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
		if (sock == -1) {
			TRACE_ERROR("socket");
			exit(EXIT_FAILURE);
		}

		/* To Do: Parse dev_name_list rather than use strstr */
		for (i = 0; i < num_devices; i++) {
			strcpy(ifr.ifr_name, devices[i].name);

			/* getting interface information */
			if (ioctl(sock, SIOCGIFFLAGS, &ifr) == 0) {

				if (!set_all_inf && strstr(dev_name_list, ifr.ifr_name) == NULL)
					continue;

				/* Setting informations */
				eidx = CONFIG.eths_num++;
				strcpy(CONFIG.eths[eidx].dev_name, ifr.ifr_name);
				CONFIG.eths[eidx].ifindex = devices[i].ifindex;

				/* getting address */
				if (ioctl(sock, SIOCGIFADDR, &ifr) == 0 ) {
					struct in_addr sin = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr;
					CONFIG.eths[eidx].ip_addr = *(uint32_t *)&sin;
				}

				if (ioctl(sock, SIOCGIFHWADDR, &ifr) == 0 ) {
					for (j = 0; j < ETH_ALEN; j ++) {
						CONFIG.eths[eidx].haddr[j] = ifr.ifr_addr.sa_data[j];
					}
				}

				/* Net MASK */
				if (ioctl(sock, SIOCGIFNETMASK, &ifr) == 0) {
					struct in_addr sin = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr;
					CONFIG.eths[eidx].netmask = *(uint32_t *)&sin;
				}

				/* add to attached devices */
				for (j = 0; j < num_devices_attached; j++) {
					if (devices_attached[j] == devices[i].ifindex) {
						break;
					}
				}
				devices_attached[num_devices_attached] = devices[i].ifindex;
				num_devices_attached++;

			} else {
				perror("SIOCGIFFLAGS");
			}
		}
		num_queues = GetNumQueues();
		if (num_queues <= 0) {
			TRACE_CONFIG("Failed to find NIC queues!\n");
			close(sock);
			return -1;
		}
		if (num_queues > num_cpus) {
			TRACE_CONFIG("Too many NIC queues available.\n");
			close(sock);
			return -1;
		}
		close(sock);
#endif /* !PSIO_MODULE */
	} else if (current_iomodule_func == &dpdk_module_func) {
#ifndef DISABLE_DPDK
		int cpu = CONFIG.num_cores;
		mpz_t _cpumask;
		char cpumaskbuf[32] = "";
		char mem_channels[8] = "";
		char socket_mem_str[32] = "";
		// int i;
		int ret, socket_mem;
		static struct ether_addr ports_eth_addr[RTE_MAX_ETHPORTS];

		/* STEP 1: first determine CPU mask */
		mpz_init(_cpumask);

		if (!mpz_cmp(_cpumask, CONFIG._cpumask)) {
			/* get the cpu mask */
			for (ret = 0; ret < cpu; ret++)
				mpz_setbit(_cpumask, ret);
			
			gmp_sprintf(cpumaskbuf, "%ZX", _cpumask);
		} else
			gmp_sprintf(cpumaskbuf, "%ZX", CONFIG._cpumask);
		
		mpz_clear(_cpumask);

		/* STEP 2: determine memory channels per socket */
		/* get the mem channels per socket */
		if (CONFIG.num_mem_ch == 0) {
			TRACE_ERROR("DPDK module requires # of memory channels "
				    "per socket parameter!\n");
			exit(EXIT_FAILURE);
		}
		sprintf(mem_channels, "%d", CONFIG.num_mem_ch);

		/* STEP 3: determine socket memory */
		/* get socket memory threshold (in MB) */
		socket_mem = 
			RTE_ALIGN_CEIL((unsigned long)ceil((CONFIG.num_cores *
							    (CONFIG.rcvbuf_size +
							     CONFIG.sndbuf_size +
							     sizeof(struct tcp_stream) +
							     sizeof(struct tcp_recv_vars) +
							     sizeof(struct tcp_send_vars) +
							     sizeof(struct fragment_ctx)) *
							    CONFIG.max_concurrency)/RTE_SOCKET_MEM_SHIFT),
				       RTE_CACHE_LINE_SIZE);
		
		/* initialize the rte env, what a waste of implementation effort! */
		int argc = 6;//8;
		char *argv[RTE_ARGC_MAX] = {"",
					    "-c",
					    cpumaskbuf,
					    "-n",
					    mem_channels,
#if 0
					    "--socket-mem",
					    socket_mem_str,
#endif
					    "--proc-type=auto"
		};
		ret = probe_all_rte_devices(argv, &argc, dev_name_list);


		/* STEP 4: build up socket mem parameter */
		sprintf(socket_mem_str, "%d", socket_mem);
#if 0
		char *smsptr = socket_mem_str + strlen(socket_mem_str);
		for (i = 1; i < ret + 1; i++) {
			sprintf(smsptr, ",%d", socket_mem);
			smsptr += strlen(smsptr);
		}
		TRACE_DBG("socket_mem: %s\n", socket_mem_str);
#endif
		/*
		 * re-set getopt extern variable optind.
		 * this issue was a bitch to debug
		 * rte_eal_init() internally uses getopt() syscall
		 * mtcp applications that also use an `external' getopt
		 * will cause a violent crash if optind is not reset to zero
		 * prior to calling the func below...
		 * see man getopt(3) for more details
		 */
		optind = 0;

#ifdef DEBUG
		/* print argv's */
		for (i = 0; i < argc; i++)
			TRACE_INFO("argv[%d]: %s\n", i, argv[i]);
#endif
		/* initialize the dpdk eal env */
		ret = rte_eal_init(argc, argv);
		if (ret < 0) {
			TRACE_ERROR("Invalid EAL args!\n");
			exit(EXIT_FAILURE);
		}
		/* give me the count of 'detected' ethernet ports */
#if RTE_VERSION < RTE_VERSION_NUM(18, 5, 0, 0)
		num_devices = rte_eth_dev_count();
#else
		num_devices = rte_eth_dev_count_avail();
#endif
		if (num_devices == 0) {
			TRACE_ERROR("No Ethernet port!\n");
			exit(EXIT_FAILURE);
		}

		/* get mac addr entries of 'detected' dpdk ports */
		for (ret = 0; ret < num_devices; ret++)
			rte_eth_macaddr_get(ret, &ports_eth_addr[ret]);

		num_queues = MIN(CONFIG.num_cores, MAX_CPUS);

		struct ifaddrs *ifap;
		struct ifaddrs *iter_if;
		char *seek;

		if (getifaddrs(&ifap) != 0) {
			perror("getifaddrs: ");
			exit(EXIT_FAILURE);
		}

		iter_if = ifap;
		do {
			if (iter_if->ifa_addr && iter_if->ifa_addr->sa_family == AF_INET &&
			    !set_all_inf &&
			    (seek=strstr(dev_name_list, iter_if->ifa_name)) != NULL &&
			    /* check if the interface was not aliased */
			    *(seek + strlen(iter_if->ifa_name)) != ':') {
				struct ifreq ifr;

				/* Setting informations */
				eidx = CONFIG.eths_num++;
				strcpy(CONFIG.eths[eidx].dev_name, iter_if->ifa_name);
				strcpy(ifr.ifr_name, iter_if->ifa_name);

				/* Create socket */
				int sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
				if (sock == -1) {
					perror("socket");
					exit(EXIT_FAILURE);
				}

				/* getting address */
				if (ioctl(sock, SIOCGIFADDR, &ifr) == 0 ) {
					struct in_addr sin = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr;
					CONFIG.eths[eidx].ip_addr = *(uint32_t *)&sin;
				}

				if (ioctl(sock, SIOCGIFHWADDR, &ifr) == 0 ) {
					for (j = 0; j < ETH_ALEN; j ++) {
						CONFIG.eths[eidx].haddr[j] = ifr.ifr_addr.sa_data[j];
					}
				}

				/* Net MASK */
				if (ioctl(sock, SIOCGIFNETMASK, &ifr) == 0) {
					struct in_addr sin = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr;
					CONFIG.eths[eidx].netmask = *(uint32_t *)&sin;
				}
				close(sock);

				for (j = 0; j < num_devices; j++) {
					if (!memcmp(&CONFIG.eths[eidx].haddr[0], &ports_eth_addr[j],
						    ETH_ALEN))
						CONFIG.eths[eidx].ifindex = j;
				}

				/* add to attached devices */
				for (j = 0; j < num_devices_attached; j++) {
					if (devices_attached[j] == CONFIG.eths[eidx].ifindex) {
						break;
					}
				}
				devices_attached[num_devices_attached] = CONFIG.eths[eidx].ifindex;
				num_devices_attached++;
				fprintf(stderr, "Total number of attached devices: %d\n",
					num_devices_attached);
				fprintf(stderr, "Interface name: %s\n",
					iter_if->ifa_name);
			}
			iter_if = iter_if->ifa_next;
		} while (iter_if != NULL);

		freeifaddrs(ifap);
#if 0
		/*
		 * XXX: It seems that there is a bug in the RTE SDK.
		 * The dynamically allocated rte_argv params are left 
		 * as dangling pointers. Freeing them causes program
		 * to crash.
		 */
		
		/* free up all resources */
		for (; rte_argc >= 9; rte_argc--) {
			if (rte_argv[rte_argc] != NULL) {
				fprintf(stderr, "Cleaning up rte_argv[%d]: %s (%p)\n",
					rte_argc, rte_argv[rte_argc], rte_argv[rte_argc]);
				free(rte_argv[rte_argc]);
				rte_argv[rte_argc] = NULL;
			}
		}
#endif
		/* check if process is primary or secondary */
		CONFIG.multi_process_is_master = (eal_proc_type_detect() == RTE_PROC_PRIMARY) ?
			1 : 0;
		
#endif /* !DISABLE_DPDK */
	} else if (current_iomodule_func == &netmap_module_func) {
#ifndef DISABLE_NETMAP
		struct ifaddrs *ifap;
		struct ifaddrs *iter_if;
		char *seek;

		num_queues = MIN(CONFIG.num_cores, MAX_CPUS);

		if (getifaddrs(&ifap) != 0) {
			perror("getifaddrs: ");
			exit(EXIT_FAILURE);
		}

		iter_if = ifap;
		do {
			if (iter_if->ifa_addr && iter_if->ifa_addr->sa_family == AF_INET &&
			    !set_all_inf &&
			    (seek=strstr(dev_name_list, iter_if->ifa_name)) != NULL &&
			    /* check if the interface was not aliased */
			    *(seek + strlen(iter_if->ifa_name)) != ':') {
				struct ifreq ifr;

				/* Setting informations */
				eidx = CONFIG.eths_num++;
				strcpy(CONFIG.eths[eidx].dev_name, iter_if->ifa_name);
				strcpy(ifr.ifr_name, iter_if->ifa_name);

				/* Create socket */
				int sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
				if (sock == -1) {
					perror("socket");
					exit(EXIT_FAILURE);
				}

				/* getting address */
				if (ioctl(sock, SIOCGIFADDR, &ifr) == 0 ) {
					struct in_addr sin = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr;
					CONFIG.eths[eidx].ip_addr = *(uint32_t *)&sin;
				}

				if (ioctl(sock, SIOCGIFHWADDR, &ifr) == 0 ) {
					for (j = 0; j < ETH_ALEN; j ++) {
						CONFIG.eths[eidx].haddr[j] = ifr.ifr_addr.sa_data[j];
					}
				}

				/* Net MASK */
				if (ioctl(sock, SIOCGIFNETMASK, &ifr) == 0) {
					struct in_addr sin = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr;
					CONFIG.eths[eidx].netmask = *(uint32_t *)&sin;
				}
				close(sock);
#if 0
				for (j = 0; j < num_devices; j++) {
					if (!memcmp(&CONFIG.eths[eidx].haddr[0], &ports_eth_addr[j],
						    ETH_ALEN))
						CONFIG.eths[eidx].ifindex = ifr.ifr_ifindex;
#endif
				CONFIG.eths[eidx].ifindex = eidx;
				TRACE_INFO("Ifindex of interface %s is: %d\n",
					   ifr.ifr_name, CONFIG.eths[eidx].ifindex);
#if 0
				}
#endif

				/* add to attached devices */
				for (j = 0; j < num_devices_attached; j++) {
					if (devices_attached[j] == CONFIG.eths[eidx].ifindex) {
						break;
					}
				}
				devices_attached[num_devices_attached] = if_nametoindex(ifr.ifr_name);
				num_devices_attached++;
				fprintf(stderr, "Total number of attached devices: %d\n",
					num_devices_attached);
				fprintf(stderr, "Interface name: %s\n",
					iter_if->ifa_name);
			}
			iter_if = iter_if->ifa_next;
		} while (iter_if != NULL);

		freeifaddrs(ifap);
#endif /* !DISABLE_NETMAP */
	} else if (current_iomodule_func == &onvm_module_func) {
#ifdef ENABLE_ONVM
		int cpu = CONFIG.num_cores;
		mpz_t cpumask;
		char cpumaskbuf[32];
		char mem_channels[8];
		char service[6];
		char instance[6];
		int ret;

		mpz_init(cpumask);
		
		/* get the cpu mask */
		for (ret = 0; ret < cpu; ret++)
			mpz_setbit(cpumask, ret);
		gmp_sprintf(cpumaskbuf, "%ZX", cpumask);

		mpz_clear(cpumask);
				
		/* get the mem channels per socket */
		if (CONFIG.num_mem_ch == 0) {
			TRACE_ERROR("DPDK module requires # of memory channels "
				    "per socket parameter!\n");
			exit(EXIT_FAILURE);
		}
		sprintf(mem_channels, "%d", CONFIG.num_mem_ch);
		sprintf(service, "%d", CONFIG.onvm_serv);
		sprintf(instance, "%d", CONFIG.onvm_inst);

		/* initialize the rte env first, what a waste of implementation effort!  */
		char *argv[] = {"", 
				"-c", 
				cpumaskbuf,
				"-n", 
				mem_channels,
				"--proc-type=secondary",
				"--",
				"-r",
				service,
				instance,
				""
		};
		
		const int argc = 10; 

		/* 
		 * re-set getopt extern variable optind.
		 * this issue was a bitch to debug
		 * rte_eal_init() internally uses getopt() syscall
		 * mtcp applications that also use an `external' getopt
		 * will cause a violent crash if optind is not reset to zero
		 * prior to calling the func below...
		 * see man getopt(3) for more details
		 */
		optind = 0;

		/* initialize the dpdk eal env */
		ret = onvm_nflib_init(argc, argv, "mtcp_nf", &CONFIG.nf_info);
		if (ret < 0) {
			TRACE_ERROR("Invalid EAL args!\n");
			exit(EXIT_FAILURE);
		}
		/* give me the count of 'detected' ethernet ports */
		num_devices = ports->num_ports;
		if (num_devices == 0) {
			TRACE_ERROR("No Ethernet port!\n");
			exit(EXIT_FAILURE);
		}

		num_queues = MIN(CONFIG.num_cores, MAX_CPUS);
		
		struct ifaddrs *ifap;
		struct ifaddrs *iter_if;
		char *seek;

		if (getifaddrs(&ifap) != 0) {
			perror("getifaddrs: ");
			exit(EXIT_FAILURE);
		}
		
		iter_if = ifap;
		do {
			if (iter_if->ifa_addr && iter_if->ifa_addr->sa_family == AF_INET &&
			    !set_all_inf && 
			    (seek=strstr(dev_name_list, iter_if->ifa_name)) != NULL &&
			    /* check if the interface was not aliased */
			    *(seek + strlen(iter_if->ifa_name)) != ':') {
				struct ifreq ifr;
				
				/* Setting informations */
				eidx = CONFIG.eths_num++;
				strcpy(CONFIG.eths[eidx].dev_name, iter_if->ifa_name);
				strcpy(ifr.ifr_name, iter_if->ifa_name);

				/* Create socket */
				int sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
				if (sock == -1) {
					perror("socket");
				}			
				
				/* getting address */
				if (ioctl(sock, SIOCGIFADDR, &ifr) == 0 ) {
					struct in_addr sin = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr;
					CONFIG.eths[eidx].ip_addr = *(uint32_t *)&sin;
				}

				for (j = 0; j < ETH_ALEN; j ++) {
					CONFIG.eths[eidx].haddr[j] = ports->mac[eidx].addr_bytes[j];
					};

				/* Net MASK */
				if (ioctl(sock, SIOCGIFNETMASK, &ifr) == 0) {
					struct in_addr sin = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr;
					CONFIG.eths[eidx].netmask = *(uint32_t *)&sin;
				}
				close(sock);
				
				CONFIG.eths[eidx].ifindex = ports->id[eidx];		
				devices_attached[num_devices_attached] = CONFIG.eths[eidx].ifindex;
				num_devices_attached++;
				fprintf(stderr, "Total number of attached devices: %d\n",
					num_devices_attached);
				fprintf(stderr, "Interface name: %s\n", 
					iter_if->ifa_name);
			}
			iter_if = iter_if->ifa_next;
		} while (iter_if != NULL);

		freeifaddrs(ifap);
#endif /* ENABLE_ONVM */
	}

	CONFIG.nif_to_eidx = (int*)calloc(MAX_DEVICES, sizeof(int));

	if (!CONFIG.nif_to_eidx) {
	        exit(EXIT_FAILURE);
	}

	for (i = 0; i < MAX_DEVICES; ++i) {
	        CONFIG.nif_to_eidx[i] = -1;
	}

	for (i = 0; i < CONFIG.eths_num; ++i) {

		j = CONFIG.eths[i].ifindex;
		if (j >= MAX_DEVICES) {
		        TRACE_ERROR("ifindex of eths_%d exceed the limit: %d\n", i, j);
		        exit(EXIT_FAILURE);
		}

		/* the physic port index of the i-th port listed in the config file is j*/
		CONFIG.nif_to_eidx[j] = i;

		/* finally set the port stats option `on' */
		if (strcmp(CONFIG.eths[i].dev_name, port_stat_list) == 0)
			CONFIG.eths[i].stat_print = TRUE;
	}

	return 0;
}
コード例 #5
0
ファイル: eal.c プロジェクト: alegacy/Pktgen-DPDK
/* Parse the argument given in the command line of the application */
static int
eal_parse_args(int argc, char **argv)
{
	int opt, ret, i;
	char **argvopt;
	int option_index;
	int coremask_ok = 0;
	ssize_t blacklist_index = 0;;
	char *prgname = argv[0];
	static struct option lgopts[] = {
		{OPT_NO_HUGE, 0, 0, 0},
		{OPT_NO_PCI, 0, 0, 0},
		{OPT_NO_HPET, 0, 0, 0},
		{OPT_HUGE_DIR, 1, 0, 0},
		{OPT_NO_SHCONF, 0, 0, 0},
		{OPT_PROC_TYPE, 1, 0, 0},
		{OPT_FILE_PREFIX, 1, 0, 0},
		{OPT_SOCKET_MEM, 1, 0, 0},
		{0, 0, 0, 0}
	};

	argvopt = argv;

	internal_config.memory = 0;
	internal_config.force_nrank = 0;
	internal_config.force_nchannel = 0;
	internal_config.hugefile_prefix = HUGEFILE_PREFIX_DEFAULT;
	internal_config.hugepage_dir = NULL;
	internal_config.force_sockets = 0;
#ifdef RTE_LIBEAL_USE_HPET
	internal_config.no_hpet = 0;
#else
	internal_config.no_hpet = 1;
#endif
	/* zero out the NUMA config */
	for (i = 0; i < RTE_MAX_NUMA_NODES; i++)
		internal_config.socket_mem[i] = 0;

	/* zero out hugedir descriptors */
	for (i = 0; i < MAX_HUGEPAGE_SIZES; i++)
		internal_config.hugepage_info[i].lock_descriptor = 0;

	while ((opt = getopt_long(argc, argvopt, "b:c:m:n:r:v",
				  lgopts, &option_index)) != EOF) {

		switch (opt) {
		/* blacklist */
		case 'b':
			if ((blacklist_index = eal_parse_blacklist_opt(optarg,
			    blacklist_index)) < 0) {
				eal_usage(prgname);
				return (-1);
			}
			break;
		/* coremask */
		case 'c':
			if (eal_parse_coremask(optarg) < 0) {
				RTE_LOG(ERR, EAL, "invalid coremask\n");
				eal_usage(prgname);
				return -1;
			}
			coremask_ok = 1;
			break;
		/* size of memory */
		case 'm':
			internal_config.memory = atoi(optarg);
			internal_config.memory *= 1024ULL;
			internal_config.memory *= 1024ULL;
			break;
		/* force number of channels */
		case 'n':
			internal_config.force_nchannel = atoi(optarg);
			if (internal_config.force_nchannel == 0 ||
			    internal_config.force_nchannel > 4) {
				RTE_LOG(ERR, EAL, "invalid channel number\n");
				eal_usage(prgname);
				return -1;
			}
			break;
		/* force number of ranks */
		case 'r':
			internal_config.force_nrank = atoi(optarg);
			if (internal_config.force_nrank == 0 ||
			    internal_config.force_nrank > 16) {
				RTE_LOG(ERR, EAL, "invalid rank number\n");
				eal_usage(prgname);
				return -1;
			}
			break;
		case 'v':
			/* since message is explicitly requested by user, we
			 * write message at highest log level so it can always be seen
			 * even if info or warning messages are disabled */
			RTE_LOG(CRIT, EAL, "RTE Version: '%s'\n", rte_version());
			break;

		/* long options */
		case 0:
			if (!strcmp(lgopts[option_index].name, OPT_NO_HUGE)) {
				internal_config.no_hugetlbfs = 1;
			}
			else if (!strcmp(lgopts[option_index].name, OPT_NO_PCI)) {
				internal_config.no_pci = 1;
			}
			else if (!strcmp(lgopts[option_index].name, OPT_NO_HPET)) {
				internal_config.no_hpet = 1;
			}
			else if (!strcmp(lgopts[option_index].name, OPT_NO_SHCONF)) {
				internal_config.no_shconf = 1;
			}
			else if (!strcmp(lgopts[option_index].name, OPT_HUGE_DIR)) {
				internal_config.hugepage_dir = optarg;
			}
			else if (!strcmp(lgopts[option_index].name, OPT_PROC_TYPE)) {
				internal_config.process_type = eal_parse_proc_type(optarg);
			}
			else if (!strcmp(lgopts[option_index].name, OPT_FILE_PREFIX)) {
				internal_config.hugefile_prefix = optarg;
			}
			else if (!strcmp(lgopts[option_index].name, OPT_SOCKET_MEM)) {
				if (eal_parse_socket_mem(optarg) < 0) {
					RTE_LOG(ERR, EAL, "invalid parameters for --"
							OPT_SOCKET_MEM "\n");
					eal_usage(prgname);
					return -1;
				}
			}
			break;

		default:
			eal_usage(prgname);
			return -1;
		}
	}

	/* sanity checks */
	if (!coremask_ok) {
		RTE_LOG(ERR, EAL, "coremask not specified\n");
		eal_usage(prgname);
		return -1;
	}
	if (internal_config.process_type == RTE_PROC_AUTO){
		internal_config.process_type = eal_proc_type_detect();
	}
	if (internal_config.process_type == RTE_PROC_INVALID){
		RTE_LOG(ERR, EAL, "Invalid process type specified\n");
		eal_usage(prgname);
		return -1;
	}
	if (internal_config.process_type == RTE_PROC_PRIMARY &&
			internal_config.force_nchannel == 0) {
		RTE_LOG(ERR, EAL, "Number of memory channels (-n) not specified\n");
		eal_usage(prgname);
		return -1;
	}
	if (index(internal_config.hugefile_prefix,'%') != NULL){
		RTE_LOG(ERR, EAL, "Invalid char, '%%', in '"OPT_FILE_PREFIX"' option\n");
		eal_usage(prgname);
		return -1;
	}
	if (internal_config.memory > 0 && internal_config.force_sockets == 1) {
		RTE_LOG(ERR, EAL, "Options -m and --socket-mem cannot be specified "
				"at the same time\n");
		eal_usage(prgname);
		return -1;
	}
	/* --no-huge doesn't make sense with either -m or --socket-mem */
	if (internal_config.no_hugetlbfs &&
			(internal_config.memory > 0 ||
					internal_config.force_sockets == 1)) {
		RTE_LOG(ERR, EAL, "Options -m or --socket-mem cannot be specified "
				"together with --no-huge!\n");
		eal_usage(prgname);
		return -1;
	}

	if (blacklist_index > 0)
		rte_eal_pci_set_blacklist(eal_dev_blacklist, blacklist_index);

	if (optind >= 0)
		argv[optind-1] = prgname;

	/* if no memory amounts were requested, this will result in 0 and
	 * will be overriden later, right after eal_hugepage_info_init() */
	for (i = 0; i < RTE_MAX_NUMA_NODES; i++)
		internal_config.memory += internal_config.socket_mem[i];

	ret = optind-1;
	optind = 0; /* reset getopt lib */
	return ret;
}