int fire_init_ioengine() { int i, ifindex = -1; int num_devices_attached = 0; int devices_attached[PS_MAX_DEVICES]; struct ps_device devices[PS_MAX_DEVICES]; int num_devices = ps_list_devices(devices); if (num_devices == -1) { perror("ps_list_devices"); exit(1); } /* client side interface */ for (i = 0; i < num_devices; i ++) { if (strcmp(config->client_interface, devices[i].name) != 0) continue; ifindex = devices[i].ifindex; memcpy(&(config->client_device), &(devices[i]), sizeof(struct ps_device)); break; } assert (ifindex != -1); for (i = 0; i < num_devices_attached; i ++) { assert(devices_attached[i] != ifindex); } devices_attached[num_devices_attached] = ifindex; config->client_ifindex = ifindex; num_devices_attached ++; /* server side interface */ for (i = 0; i < num_devices; i ++) { if (strcmp(config->server_interface, devices[i].name) != 0) continue; ifindex = devices[i].ifindex; memcpy(&(config->server_device), &(devices[i]), sizeof(struct ps_device)); break; } assert (ifindex != -1); for (i = 0; i < num_devices_attached; i ++) { //assert(devices_attached[i] != ifindex); } devices_attached[num_devices_attached] = ifindex; config->server_ifindex = ifindex; //config->client_ifindex = ifindex; num_devices_attached ++; /* There are the same number of queues and workers */ config->worker_num = devices[0].num_rx_queues; return 0; }
/* Init config->ifindex_0, and config->ifindex_1 */ int upro_init_ioengine() { int i, ifindex = -1; int num_devices_attached = 0; int devices_attached[PS_MAX_DEVICES]; struct ps_device devices[PS_MAX_DEVICES]; int num_devices = ps_list_devices(devices); if (num_devices == -1) { perror("ps_list_devices"); exit(1); } /* client side interface */ for (i = 0; i < num_devices; i ++) { if (strcmp(config->interface_0, devices[i].name) != 0) continue; ifindex = devices[i].ifindex; break; } assert(ifindex != -1); for (i = 0; i < num_devices_attached; i ++) { assert(devices_attached[i] != ifindex); } devices_attached[num_devices_attached] = ifindex; config->ifindex_0 = ifindex; num_devices_attached ++; /* server side interface */ for (i = 0; i < num_devices; i ++) { if (strcmp(config->interface_1, devices[i].name) != 0) continue; ifindex = devices[i].ifindex; break; } assert(ifindex != -1); for (i = 0; i < num_devices_attached; i ++) { assert(devices_attached[i] != ifindex); } devices_attached[num_devices_attached] = ifindex; config->ifindex_1 = ifindex; num_devices_attached ++; return 0; }
int main(int argc, char **argv) { num_devices = ps_list_devices(devices); if (num_devices == -1) { perror("ps_list_devices"); exit(1); } signal(SIGINT, handle_signal); parse_opt(argc, argv); attach(); dump(); return 0; }
int main(int argc, char **argv) { int num_cpus; int i ; num_cpus = get_num_cpus(); assert(num_cpus >= 1); num_devices = ps_list_devices(devices); if (num_devices == -1) { perror("ps_list_devices"); exit(1); } parse_opt(argc, argv); for (i = 0; i < num_cpus; i++) { int ret = fork(); assert(ret >= 0); my_cpu = i; if (ret == 0) { bind_cpu(i); signal(SIGINT, handle_signal); echo(); return 0; } } signal(SIGINT, SIG_IGN); while (1) { int ret = wait(NULL); if (ret == -1 && errno == ECHILD) break; } return 0; }
int main(int argc, char **argv) { num_devices = ps_list_devices(devices); if (num_devices == -1) { perror("ps_list_devices"); exit(1); } parse_opt(argc, argv); num_cpus = get_num_cpus(); assert(num_cpus >= 1); for (my_cpu = 0; my_cpu < num_cpus; my_cpu++) { int ret = fork(); assert(ret >= 0); if (ret == 0) { bind_cpu(my_cpu); signal(SIGINT, stat_signal); attach(); dump(); return 0; } } signal(SIGINT, SIG_IGN); while(1) { int ret = wait(NULL); if(-1 == ret && ECHILD == errno) break; } return 0; }
/*----------------------------------------------------------------------------*/ int SetInterfaceInfo(char* dev_name_list) { struct ifreq ifr; 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) exit(EXIT_FAILURE); if (current_iomodule_func == &ps_module_func) { /* 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) { perror("socket"); } /* 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"); return -1; } if (num_queues > num_cpus) { TRACE_CONFIG("Too many NIC queues available.\n"); return -1; } } else if (current_iomodule_func == &dpdk_module_func) { #ifndef DISABLE_DPDK int cpu = CONFIG.num_cores; uint32_t cpumask = 0; char cpumaskbuf[10]; char mem_channels[5]; int ret; static struct ether_addr ports_eth_addr[RTE_MAX_ETHPORTS]; /* get the cpu mask */ for (ret = 0; ret < cpu; ret++) cpumask = (cpumask | (1 << ret)); sprintf(cpumaskbuf, "%X", 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); /* initialize the rte env first, what a waste of implementation effort! */ char *argv[] = {"", "-c", cpumaskbuf, "-n", mem_channels, "--proc-type=auto", "" }; const int argc = 6; /* * 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 = rte_eal_init(argc, argv); if (ret < 0) rte_exit(EXIT_FAILURE, "Invalid EAL args!\n"); /* give me the count of 'detected' ethernet ports */ num_devices = rte_eth_dev_count(); if (num_devices == 0) { rte_exit(EXIT_FAILURE, "No Ethernet port!\n"); } /* 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->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; } 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); #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->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; } 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;//if_nametoindex(ifr.ifr_name); 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);//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 /* !DISABLE_NETMAP */ } return 0; }
int main(int argc, char **argv) { int num_packets = 0; int chunk_size = 64; int packet_size = 60; int num_flows = 0; int i; ip_version = 4; struct timeval begin, end; num_cpus = get_num_cpus(); assert(num_cpus >= 1); num_devices = ps_list_devices(devices); assert(num_devices != -1); assert(num_devices > 0); for (i = 1; i < argc; i += 2) { if (i == argc - 1) print_usage(argv[0]); if (!strcmp(argv[i], "-n")) { num_packets = atoi(argv[i + 1]); assert(num_packets >= 0); } else if (!strcmp(argv[i], "-s")) { chunk_size = atoi(argv[i + 1]); assert(chunk_size >= 1 && chunk_size <= MAX_CHUNK_SIZE); } else if (!strcmp(argv[i], "-p")) { packet_size = atoi(argv[i + 1]); assert(packet_size >= 60 && packet_size <= 1514); } else if (!strcmp(argv[i], "-f")) { num_flows = atoi(argv[i + 1]); assert(num_flows >= 0 && num_flows <= MAX_FLOWS); } else if (!strcmp(argv[i], "-v")) { ip_version = atoi(argv[i + 1]); assert(ip_version == 4 || ip_version == 6); } else if (!strcmp(argv[i], "-i")) { int ifindex = -1; int j; if (!strcmp(argv[i + 1], "all")) { for (j = 0; j < num_devices; j++) devices_registered[j] = j; num_devices_registered = num_devices; continue; } for (j = 0; j < num_devices; j++) if (!strcmp(argv[i + 1], devices[j].name)) ifindex = j; if (ifindex == -1) { fprintf(stderr, "device %s does not exist!\n", argv[i + 1]); exit(1); } for (j = 0; j < num_devices_registered; j++) if (devices_registered[j] == ifindex) { fprintf(stderr, "device %s is registered more than once!\n", argv[i + 1]); exit(1); } devices_registered[num_devices_registered] = ifindex; num_devices_registered++; } else if (!strcmp(argv[i], "-t")) { time_limit = atoi(argv[i + 1]); assert(time_limit >= 0); } else print_usage(argv[0]); } if (num_devices_registered == 0) print_usage(argv[0]); printf("# of CPUs = %d\n", num_cpus); printf("# of packets to transmit = %d\n", num_packets); printf("chunk size = %d\n", chunk_size); printf("packet size = %d bytes\n", packet_size); printf("# of flows = %d\n", num_flows); printf("ip version = %d\n", ip_version); printf("time limit = %d seconds\n", time_limit); printf("interfaces: "); for (i = 0; i < num_devices_registered; i++) { if (i > 0) printf(", "); printf("%s", devices[devices_registered[i]].name); } printf("\n"); printf("----------\n"); if (num_flows > 0) srand(time(NULL)); assert(gettimeofday(&begin, NULL) == 0); for (my_cpu = 0; my_cpu < num_cpus; my_cpu++) { int ret = fork(); assert(ret >= 0); if (ret == 0) { bind_cpu(my_cpu); signal(SIGINT, handle_signal); send_packets(num_packets ? : LONG_MAX, chunk_size, packet_size, num_flows); return 0; } }
/*----------------------------------------------------------------------------*/ 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; }
/*----------------------------------------------------------------------------*/ int SetInterfaceInfo(char* dev_name_list) { struct ifreq ifr; 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) exit(EXIT_FAILURE); if (current_iomodule_func == &ps_module_func) { /* 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) { perror("socket"); } /* 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 < 6; 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"); } } // end for: till num_devices num_queues = GetNumQueues(); if (num_queues <= 0) { TRACE_CONFIG("Failed to find NIC queues!\n"); return -1; } if (num_queues > num_cpus) { TRACE_CONFIG("Too many NIC queues available.\n"); return -1; } } else if (current_iomodule_func == &dpdk_module_func) { #ifndef DISABLE_DPDK int cpu = CONFIG.num_cores; uint32_t cpumask = 0; char cpumaskbuf[10]; char mem_channels[5]; int ret; static struct ether_addr ports_eth_addr[RTE_MAX_ETHPORTS]; /* get the cpu mask */ for (ret = 0; ret < cpu; ret++) cpumask = (cpumask | (1 << ret)); sprintf(cpumaskbuf, "%X", 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); /* initialize the rte env first, what a waste of implementation effort! */ char *argv[] = {"", "-c", cpumaskbuf, "-n", mem_channels, "--proc-type=auto", "" }; const int argc = 6; /* * 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 = rte_eal_init(argc, argv); if (ret < 0) rte_exit(EXIT_FAILURE, "Invalid EAL args!\n"); /* give me the count of 'detected' ethernet ports */ num_devices = rte_eth_dev_count(); if (num_devices == 0) { rte_exit(EXIT_FAILURE, "No Ethernet port!\n"); } /* 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->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; } if (ioctl(sock, SIOCGIFHWADDR, &ifr) == 0 ) { for (j = 0; j < 6; 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); #endif /* !DISABLE_DPDK */ } else if (current_iomodule_func == &tuntap_module_func) { printf("Trying to configure tuntap device\n"); #ifndef DISABLE_TUNTAP /* Let the great duplication of the code begin!!! */ // FIXME: Do I need this? num_queues = MIN(CONFIG.num_cores, MAX_CPUS); // FIXME: Currently tuntap will have only one queue assert(num_queues == 1); // Initializing the tuntap device as we want to read // their IP addresses and other settings // FIXME: Do this once per device in the list devices init_tap_network("tap0", "192.168.123.100", "255.255.255.0"); struct ifaddrs *ifap; struct ifaddrs *iter_if; char *seek; if (getifaddrs(&ifap) != 0) { perror("getifaddrs: "); exit(EXIT_FAILURE); } int if_count = 0; int if_count_used = 0; iter_if = ifap; do { if (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++; CONFIG.eths[eidx].ifindex = if_count_used; ++if_count_used; 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; in_addr_t addr = inet_addr("192.168.123.1"); //CONFIG.eths[eidx].ip_addr = *(uint32_t *)&sin; CONFIG.eths[eidx].ip_addr = addr; printf("IP addr: %"PRIx32" \n", CONFIG.eths[eidx].ip_addr); } if (ioctl(sock, SIOCGIFHWADDR, &ifr) == 0 ) { for (j = 0; j < 6; j ++) { CONFIG.eths[eidx].haddr[j] = ifr.ifr_addr.sa_data[j]; } // FIXME: Ugly hack to get a different MAC address by subtracting // one from the gateway's MAC address CONFIG.eths[eidx].haddr[5] = CONFIG.eths[eidx].haddr[5] - 1; } /* 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; printf("netmask: %"PRIx32" \n", CONFIG.eths[eidx].netmask); } close(sock); /* 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); } // end if: Valid device found else { fprintf(stderr, "INFO: Ignoring Interface name: %s\n", iter_if->ifa_name); } // end else: iter_if = iter_if->ifa_next; ++if_count; } while (iter_if != NULL); // for each interface in local system freeifaddrs(ifap); fprintf(stderr, "Total number of attached devices: %d\n", num_devices_attached); #endif // DISABLE_TUNTAP } else { printf("ERROR: This IO Module is not yet supported by %s:%s\n", __FILE__, __FUNCTION__); exit(EXIT_FAILURE); } return 0; } // end function: SetInterfaceInfo