Example #1
0
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();
}
Example #2
0
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;
}