void sigproc(int sig) { static int called = 0; fprintf(stderr, "Leaving...\n"); if(called) return; else called = 1; do_shutdown = 1; pfring_zc_kill_worker(zw); print_stats(); }
int main(int argc, char* argv[]) { char *device = NULL, *dev, c; long i; int cluster_id = -1; char *bind_mask = NULL; pthread_t *threads; char *id; u_int numCPU = sysconf( _SC_NPROCESSORS_ONLN ); int hash_mode = 0; startTime.tv_sec = 0; while((c = getopt(argc,argv,"ac:g:hi:r:m:")) != '?') { if((c == 255) || (c == -1)) break; switch(c) { case 'h': printHelp(); break; case 'a': wait_for_packet = 0; break; case 'c': cluster_id = atoi(optarg); break; case 'm': hash_mode = atoi(optarg); break; case 'i': device = strdup(optarg); break; case 'g': bind_mask = strdup(optarg); break; case 'r': bind_worker_core = atoi(optarg); break; } } if (device == NULL) printHelp(); if (cluster_id < 0) printHelp(); if (bind_mask == NULL) printHelp(); id = strtok(bind_mask, ":"); while(id != NULL) { bind_core = realloc(bind_core, sizeof(int) * (num_threads+1)); bind_core[num_threads] = atoi(id) % numCPU; num_threads++; id = strtok(NULL, ":"); } if (num_threads < 1) printHelp(); dev = strtok(device, ","); while(dev != NULL) { devices = realloc(devices, sizeof(char *) * (num_devices+1)); devices[num_devices] = strdup(dev); num_devices++; dev = strtok(NULL, ","); } zc = pfring_zc_create_cluster( cluster_id, max_packet_len(devices[0]), 0, (num_devices * MAX_CARD_SLOTS) + (num_threads * QUEUE_LEN) + num_threads + PREFETCH_BUFFERS, numa_node_of_cpu(bind_worker_core), NULL /* auto hugetlb mountpoint */ ); if(zc == NULL) { fprintf(stderr, "pfring_zc_create_cluster error [%s] Please check your hugetlb configuration\n", strerror(errno)); return -1; } threads = calloc(num_threads, sizeof(pthread_t)); buffers = calloc(num_threads, sizeof(pfring_zc_pkt_buff *)); inzq = calloc(num_devices, sizeof(pfring_zc_queue *)); outzq = calloc(num_threads, sizeof(pfring_zc_queue *)); consumers_stats = calloc(num_threads, sizeof(struct stats)); for (i = 0; i < num_threads; i++) { buffers[i] = pfring_zc_get_packet_handle(zc); if (buffers[i] == NULL) { fprintf(stderr, "pfring_zc_get_packet_handle error\n"); return -1; } } for (i = 0; i < num_devices; i++) { inzq[i] = pfring_zc_open_device(zc, devices[i], rx_only, 0); if(inzq[i] == NULL) { fprintf(stderr, "pfring_zc_open_device error [%s] Please check that %s is up and not already used\n", strerror(errno), devices[i]); return -1; } //printf("Created device with ID=%u, INDEX=%u\n", pfring_zc_get_queue_id(inzq[i]), QUEUEID_TO_IFINDEX(pfring_zc_get_queue_id(inzq[i]))); } for (i = 0; i < num_threads; i++) { outzq[i] = pfring_zc_create_queue(zc, QUEUE_LEN); if(outzq[i] == NULL) { fprintf(stderr, "pfring_zc_create_queue error [%s]\n", strerror(errno)); return -1; } //printf("Created queue with ID=%u\n", pfring_zc_get_queue_id(outzq[i])); } wsp = pfring_zc_create_buffer_pool(zc, PREFETCH_BUFFERS); if (wsp == NULL) { fprintf(stderr, "pfring_zc_create_buffer_pool error\n"); return -1; } signal(SIGINT, sigproc); signal(SIGTERM, sigproc); signal(SIGINT, sigproc); printf("Starting balancer with %d consumer threads..\n", num_threads); if (hash_mode < 2) { /* balancer */ pfring_zc_distribution_func func; if(strcmp(device, "sysdig") == 0) func = (hash_mode == 0) ? rr_distribution_func : sysdig_distribution_func; else func = (hash_mode == 0) ? rr_distribution_func : NULL /* built-in IP-based */; zw = pfring_zc_run_balancer( inzq, outzq, num_devices, num_threads, wsp, round_robin_bursts_policy, NULL /* idle callback */, func, (void *) ((long) num_threads), !wait_for_packet, bind_worker_core ); } else { outzmq = pfring_zc_create_multi_queue(outzq, num_threads); if(outzmq == NULL) { fprintf(stderr, "pfring_zc_create_multi_queue error [%s]\n", strerror(errno)); return -1; } zw = pfring_zc_run_fanout( inzq, outzmq, num_devices, wsp, round_robin_bursts_policy, NULL /* idle callback */, NULL /* built-in send-to-all */, (void *) ((long) num_threads), !wait_for_packet, bind_worker_core ); } if(zw == NULL) { fprintf(stderr, "pfring_zc_run_balancer error [%s]\n", strerror(errno)); return -1; } for (i = 0; i < num_threads; i++) pthread_create(&threads[i], NULL, consumer_thread, (void*) i); while (!do_shutdown) { sleep(ALARM_SLEEP); print_stats(); } for (i = 0; i < num_threads; i++) pthread_join(threads[i], NULL); pfring_zc_kill_worker(zw); pfring_zc_destroy_cluster(zc); return 0; }