Пример #1
0
int main(int argc, char* argv[]) {
  char *device = NULL, c;
  long i;
  int cluster_id = -1;
  char *bind_mask = NULL;
  pthread_t *threads;
  char *id;
  u_int numCPU = sysconf( _SC_NPROCESSORS_ONLN );

  startTime.tv_sec = 0;

  while((c = getopt(argc,argv,"ac:g:hi:f")) != '?') {
    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 'i':
      device = strdup(optarg);
      break;
    case 'g':
      bind_mask = strdup(optarg);
      break;
    case 'f':
      flush_packet = 1;
      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();

  threads = calloc(num_threads,     sizeof(pthread_t));
  buffers = calloc(num_threads,     sizeof(pfring_zc_pkt_buff *));
  zq =      calloc(num_threads - 1, sizeof(pfring_zc_queue *));

  zc = pfring_zc_create_cluster(
    cluster_id, 
    1536, 
#ifdef METADATA_TEST
    8,
#else
    0,
#endif
    MAX_CARD_SLOTS + (num_threads - 1) * QUEUE_LEN + num_threads, 
    numa_node_of_cpu(bind_core[0]),
    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;
  }

  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;
    }
  }

  zq[0] = pfring_zc_open_device(zc, device, rx_only, 0);

  if(zq[0] == NULL) {
    fprintf(stderr, "pfring_zc_open_device error [%s] Please check that %s is up and not already used\n",
	    strerror(errno), device);
    return -1;
  }

  for (i = 1; i < num_threads; i++) { 
    zq[i] = pfring_zc_create_queue(zc, QUEUE_LEN);

    if(zq[i] == NULL) {
      fprintf(stderr, "pfring_zc_create_queue error [%s]\n", strerror(errno));
      return -1;
    }
  }

  signal(SIGINT,  sigproc);
  signal(SIGTERM, sigproc);
  signal(SIGINT,  sigproc);
  signal(SIGALRM, my_sigalarm);
  alarm(ALARM_SLEEP);

  printf("Starting pipeline with %d stages..\n", num_threads);

  for (i = 0; i < num_threads; i++)
    pthread_create(&threads[i], NULL, pipeline_stage_thread, (void*) i);
  
  for (i = 0; i < num_threads; i++)
    pthread_join(threads[i], NULL);

  sleep(1);

  pfring_zc_destroy_cluster(zc);

  return 0;
}
Пример #2
0
int main(int argc, char* argv[]) {
  char *device = NULL, c;
  int i;

  startTime.tv_sec = 0;

  while((c = getopt(argc,argv,"ab:c:g:hi:n:p:l:z")) != '?') {
    if((c == 255) || (c == -1)) break;

    switch(c) {
    case 'h':
      printHelp();
      break;
    case 'a':
      active = 1;
      break;
    case 'b':
      num_ips = atoi(optarg);
      break;
    case 'c':
      cluster_id = atoi(optarg);
      break;
    case 'i':
      device = strdup(optarg);
      break;
    case 'l':
      packet_len = atoi(optarg);
      break;
    case 'n':
      num_to_send = atoi(optarg);
      break;
    case 'p':
      pps = atoi(optarg);
      break;
    case 'g':
      bind_core = atoi(optarg);
      break;
#ifdef BURST_API
    case 'z':
      use_pkt_burst_api = 1;
      break;
#endif
    }
  }

  if (cluster_id < 0) printHelp();
  
  if (device) {
    num_queue_buffers = MAX_CARD_SLOTS;
  } else {
    num_queue_buffers = QUEUE_LEN;
  }

  stdin_packet_len = read_packet_hex(stdin_packet, sizeof(stdin_packet));

  if (stdin_packet_len > 0)
    packet_len = stdin_packet_len;

  zc = pfring_zc_create_cluster(
    cluster_id, 
    1536, 
    0,
    num_queue_buffers + NBUFF, 
    numa_node_of_cpu(bind_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;
  }

  for (i = 0; i < NBUFF; i++) {
    buffers[i] = pfring_zc_get_packet_handle(zc);

    if (buffers[i] == NULL) {
      fprintf(stderr, "pfring_zc_get_packet_handle error\n");
      return -1;
    }
  }

  if (device) {
    zq = pfring_zc_open_device(zc, device, tx_only, 0);
  
    if(zq == NULL) {
      fprintf(stderr, "pfring_zc_open_device error [%s] Please check that %s is up and not already used\n",
	      strerror(errno), device);
      return -1;
    }

    fprintf(stderr, "Sending packets to %s\n", device);
  } else {
    zq = pfring_zc_create_queue(zc, num_queue_buffers);

    if(zq == NULL) {
      fprintf(stderr, "pfring_zc_create_queue error [%s]\n", strerror(errno));
      return -1;
    }
   
    zp = pfring_zc_create_buffer_pool(zc, POOL_SIZE);

    if (zp == NULL) {
      fprintf(stderr, "pfring_zc_create_buffer_pool error\n");
      return -1;
    }
 
    fprintf(stderr, "Sending packets to cluster %u queue %u\n", cluster_id, 0);
  }

  signal(SIGINT,  sigproc);
  signal(SIGTERM, sigproc);
  signal(SIGINT,  sigproc);
  signal(SIGALRM, my_sigalarm);
  alarm(ALARM_SLEEP);

  send_traffic();

  print_stats();

  pfring_zc_destroy_cluster(zc);

  return 0;
}
Пример #3
0
int main(int argc, char* argv[]) {
  char *device = NULL, c;
  pthread_t thread;
  pthread_t time_thread;
  char *vm_sock = NULL;
  int i, rc, ipc_q_attach = 0;

  startTime.tv_sec = 0;

  while((c = getopt(argc,argv,"ab:c:g:hi:n:p:l:zN:S:P:Q:")) != '?') {
    if((c == 255) || (c == -1)) break;

    switch(c) {
    case 'h':
      printHelp();
      break;
    case 'a':
      active = 1;
      break;
    case 'b':
      num_ips = atoi(optarg);
      break;
    case 'c':
      cluster_id = atoi(optarg);
      break;
    case 'i':
      device = strdup(optarg);
      break;
    case 'l':
      packet_len = atoi(optarg);
      break;
    case 'n':
      num_to_send = atoi(optarg);
      break;
    case 'p':
      pps = atoi(optarg);
      /* auto flush on wait flush_packet = 1; */
      break;
    case 'g':
      bind_core = atoi(optarg);
      break;
    case 'Q':
      enable_vm_support = 1;
      vm_sock = strdup(optarg);
      break;
#ifdef BURST_API
    case 'z':
      use_pkt_burst_api = 1;
      break;
#endif
    case 'N':
      n2disk_producer = 1;
      n2disk_threads = atoi(optarg);
      break;
    case 'S':
      append_timestamp = 1;
      bind_time_pulse_core = atoi(optarg);
      break;
    case 'P':
      use_pulse_time = 1;
      bind_time_pulse_core = atoi(optarg);
      break;
    }
  }

  if (n2disk_producer) 
    device = NULL;

  /* checking if the interface is a queue allocated by an external cluster (ipc) */
  if (device != NULL && is_a_queue(device, &cluster_id, &queue_id)) 
    ipc_q_attach = 1;

  if (cluster_id < 0) printHelp();

  stdin_packet_len = read_packet_hex(stdin_packet, sizeof(stdin_packet));

  if (stdin_packet_len > 0)
    packet_len = stdin_packet_len;

  if (n2disk_producer) {
    if (device != NULL || ipc_q_attach) printHelp();
    if (n2disk_threads < 1) printHelp();
    metadata_len = N2DISK_METADATA;
    num_consumer_buffers += (n2disk_threads * (N2DISK_CONSUMER_QUEUE_LEN + 1)) + N2DISK_PREFETCH_BUFFERS;
  }
 
  if (!ipc_q_attach) {

    if (device != NULL)
      num_queue_buffers = MAX_CARD_SLOTS;
    else
      num_queue_buffers = QUEUE_LEN;

    zc = pfring_zc_create_cluster(
      cluster_id, 
      max_packet_len(device),
      metadata_len, 
      num_queue_buffers + NBUFF + num_consumer_buffers, 
      numa_node_of_cpu(bind_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;
    }

    for (i = 0; i < NBUFF; i++) {
      buffers[i] = pfring_zc_get_packet_handle(zc);

      if (buffers[i] == NULL) {
        fprintf(stderr, "pfring_zc_get_packet_handle error\n");
        return -1;
      }
    }

    if (device) {
      zq = pfring_zc_open_device(zc, device, tx_only, 0);
  
      if(zq == NULL) {
        fprintf(stderr, "pfring_zc_open_device error [%s] Please check that %s is up and not already used\n",
	        strerror(errno), device);
        return -1;
      }

      fprintf(stderr, "Sending packets to %s\n", device);
    } else {
      zq = pfring_zc_create_queue(zc, num_queue_buffers);

      if(zq == NULL) {
        fprintf(stderr, "pfring_zc_create_queue error [%s]\n", strerror(errno));
        return -1;
      }

      if (pfring_zc_create_buffer_pool(zc, n2disk_producer ? (N2DISK_PREFETCH_BUFFERS + n2disk_threads) : 1) == NULL) {
        fprintf(stderr, "pfring_zc_create_buffer_pool error\n");
        return -1;
      }
   
      fprintf(stderr, "Sending packets to cluster %u queue %u\n", cluster_id, 0);

      if (n2disk_producer) {
        char queues_list[256];
        queues_list[0] = '\0';

        for (i = 0; i < n2disk_threads; i++) {
          if(pfring_zc_create_queue(zc, N2DISK_CONSUMER_QUEUE_LEN) == NULL) {
            fprintf(stderr, "pfring_zc_create_queue error [%s]\n", strerror(errno));
            return -1;
          }
          sprintf(&queues_list[strlen(queues_list)], "%d,", i+1);
        }
        queues_list[strlen(queues_list)-1] = '\0';

        fprintf(stderr, "Run n2disk with: --cluster-ipc-attach --cluster-id %d --cluster-ipc-queues %s --cluster-ipc-pool 0\n", cluster_id, queues_list);
      }

    }

    if (enable_vm_support) {
      rc = pfring_zc_vm_register(zc, vm_sock);

      if (rc < 0) {
        fprintf(stderr, "pfring_zc_vm_register(%s) error\n", vm_sock);
        return -1;
      }

      rc = pfring_zc_vm_backend_enable(zc);

      if (rc < 0) {
        fprintf(stderr, "pfring_zc_vm_backend_enable error\n");
        return -1;
      }
    }

  } else { /* IPC */

    fprintf(stderr, "Attaching to cluster %d queue %d (IPC)\n", cluster_id, queue_id);

    zq = pfring_zc_ipc_attach_queue(cluster_id, queue_id, tx_only);

    if(zq == NULL) {
      fprintf(stderr, "pfring_zc_ipc_attach_queue error [%s] Please check that cluster %d is running\n",
  	      strerror(errno), cluster_id);
      return -1;
    }

    zp = pfring_zc_ipc_attach_buffer_pool(cluster_id, queue_id);

    if(zp == NULL) {
      fprintf(stderr, "pfring_zc_ipc_attach_buffer_pool error [%s] Please check that cluster %d is running\n",
  	      strerror(errno), cluster_id);
      return -1;
    }

    for (i = 0; i < NBUFF; i++) {
      buffers[i] = pfring_zc_get_packet_handle_from_pool(zp);

      if (buffers[i] == NULL) {
        fprintf(stderr, "pfring_zc_get_packet_handle_from_pool error\n");
        return -1;
      }
    } 
  }

  signal(SIGINT,  sigproc);
  signal(SIGTERM, sigproc);
  signal(SIGINT,  sigproc);

  if (use_pulse_time)   pulse_timestamp_ns   = calloc(CACHE_LINE_LEN/sizeof(u_int64_t), sizeof(u_int64_t));
  if (append_timestamp) pulse_timestamp_ns_n = calloc(CACHE_LINE_LEN/sizeof(u_int64_t), sizeof(u_int64_t));
  if (append_timestamp || use_pulse_time) pthread_create(&time_thread, NULL, time_pulse_thread, NULL);
  if (use_pulse_time)   while (!*pulse_timestamp_ns   && !do_shutdown); /* wait for ts */
  if (append_timestamp) while (!*pulse_timestamp_ns_n && !do_shutdown); /* wait for ts */

  pthread_create(&thread, NULL, send_traffic, NULL);

  while (!do_shutdown) {
    sleep(ALARM_SLEEP);
    print_stats();
  }

  pthread_join(thread, NULL);

  print_stats();

  if (append_timestamp || use_pulse_time)
    pthread_join(time_thread, NULL);

  if (!ipc_q_attach) {
    pfring_zc_destroy_cluster(zc);
  } else {
    for (i = 0; i < NBUFF; i++)
      pfring_zc_release_packet_handle_to_pool(zp, buffers[i]);
    pfring_zc_ipc_detach_queue(zq);
    pfring_zc_ipc_detach_buffer_pool(zp);  
  }

  return 0;
}
Пример #4
0
int main(int argc, char* argv[]) {
  char *device = NULL, c;
  int i;

  startTime.tv_sec = 0;

  while((c = getopt(argc,argv,"ab:c:g:hi:n:p:l:zN:")) != '?') {
    if((c == 255) || (c == -1)) break;

    switch(c) {
    case 'h':
      printHelp();
      break;
    case 'a':
      active = 1;
      break;
    case 'b':
      num_ips = atoi(optarg);
      break;
    case 'c':
      cluster_id = atoi(optarg);
      break;
    case 'i':
      device = strdup(optarg);
      break;
    case 'l':
      packet_len = atoi(optarg);
      break;
    case 'n':
      num_to_send = atoi(optarg);
      break;
    case 'p':
      pps = atoi(optarg);
      break;
    case 'g':
      bind_core = atoi(optarg);
      break;
#ifdef BURST_API
    case 'z':
      use_pkt_burst_api = 1;
      break;
#endif
    case 'N':
      n2disk_producer = 1;
      n2disk_threads = atoi(optarg);
      break;
    }
  }

  if (cluster_id < 0) printHelp();

  if (n2disk_producer) {
    if (device != NULL) printHelp();
    if (n2disk_threads < 1) printHelp();
    metadata_len = N2DISK_METADATA;
    num_consumer_buffers += (n2disk_threads * (N2DISK_CONSUMER_QUEUE_LEN + 1)) + N2DISK_PREFETCH_BUFFERS;
  }
  
  if (device) {
    num_queue_buffers = MAX_CARD_SLOTS;
  } else {
    num_queue_buffers = QUEUE_LEN;
  }

  stdin_packet_len = read_packet_hex(stdin_packet, sizeof(stdin_packet));

  if (stdin_packet_len > 0)
    packet_len = stdin_packet_len;

  zc = pfring_zc_create_cluster(
    cluster_id, 
    max_packet_len(device),
    metadata_len, 
    num_queue_buffers + NBUFF + num_consumer_buffers, 
    numa_node_of_cpu(bind_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;
  }

  for (i = 0; i < NBUFF; i++) {
    buffers[i] = pfring_zc_get_packet_handle(zc);

    if (buffers[i] == NULL) {
      fprintf(stderr, "pfring_zc_get_packet_handle error\n");
      return -1;
    }
  }

  if (device) {
    zq = pfring_zc_open_device(zc, device, tx_only, 0);
  
    if(zq == NULL) {
      fprintf(stderr, "pfring_zc_open_device error [%s] Please check that %s is up and not already used\n",
	      strerror(errno), device);
      return -1;
    }

    fprintf(stderr, "Sending packets to %s\n", device);
  } else {
    zq = pfring_zc_create_queue(zc, num_queue_buffers);

    if(zq == NULL) {
      fprintf(stderr, "pfring_zc_create_queue error [%s]\n", strerror(errno));
      return -1;
    }
   
    fprintf(stderr, "Sending packets to cluster %u queue %u\n", cluster_id, 0);

    if (n2disk_producer) {
      char queues_list[256];
      queues_list[0] = '\0';

      for (i = 0; i < n2disk_threads; i++) {
        if(pfring_zc_create_queue(zc, N2DISK_CONSUMER_QUEUE_LEN) == NULL) {
          fprintf(stderr, "pfring_zc_create_queue error [%s]\n", strerror(errno));
          return -1;
        }
        sprintf(&queues_list[strlen(queues_list)], "%d,", i+1);
      }
      queues_list[strlen(queues_list)-1] = '\0';

      if (pfring_zc_create_buffer_pool(zc, N2DISK_PREFETCH_BUFFERS + n2disk_threads) == NULL) {
        fprintf(stderr, "pfring_zc_create_buffer_pool error\n");
        return -1;
      }

      fprintf(stderr, "Run n2disk with: --cluster-ipc-attach --cluster-id %d --cluster-ipc-queues %s --cluster-ipc-pool 0\n", cluster_id, queues_list);
    }

  }

  signal(SIGINT,  sigproc);
  signal(SIGTERM, sigproc);
  signal(SIGINT,  sigproc);
  signal(SIGALRM, my_sigalarm);
  alarm(ALARM_SLEEP);

  send_traffic();

  print_stats();

  pfring_zc_destroy_cluster(zc);

  return 0;
}
Пример #5
0
int main(int argc, char* argv[]) {
  char c;
  char *in_pair = NULL, *out_pair = NULL;
  char *vm_sockets = NULL, *vm_sock; 
  long i;
  int cluster_id = -1;
  int rc;

  start_time.tv_sec = 0;

  while((c = getopt(argc,argv,"ac:fhi:o:n:Q:r:t:")) != '?') {
    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 'f':
      flush_packet = 1;
      break;
    case 'n':
      num_ipc_queues = atoi(optarg);
      break;
    case 'i':
      in_pair = strdup(optarg);
      break;
    case 'o':
      out_pair = strdup(optarg);
      break;
    case 'r':
      forwarder[RX_FWDR].bind_core = atoi(optarg);
      break;
    case 't':
      forwarder[TX_FWDR].bind_core = atoi(optarg);
      break;
    case 'Q':
      enable_vm_support = 1;
      vm_sockets = strdup(optarg);
      break;
    }
  }
  
  if (cluster_id < 0) printHelp();
  if (num_ipc_queues < 1) printHelp();

  if (in_pair != NULL) {
    char *q_id = strchr(in_pair, ';');
    if (q_id == NULL) printHelp();
    q_id[0] = '\0'; q_id++;
    in_device = strdup(in_pair);
    in_queue_id = atoi(q_id);
    if (in_queue_id < 0 || in_queue_id >= num_ipc_queues) printHelp();
  }

  if (out_pair != NULL) {
    char *q_id = strchr(out_pair, ';');
    if (q_id == NULL) printHelp();
    q_id[0] = '\0'; q_id++;
    out_device = strdup(out_pair);
    out_queue_id = atoi(q_id);
    if (out_queue_id < 0 || out_queue_id >= num_ipc_queues) printHelp();
  }

  ipczqs = calloc(num_ipc_queues,  sizeof(pfring_zc_queue *));
  pools =  calloc(num_ipc_queues,  sizeof(pfring_zc_buffer_pool *));

  zc = pfring_zc_create_cluster(
    cluster_id, 
    in_device != NULL ? max_packet_len(in_device) : 1536, 
    0,
    (((in_device != NULL) + (out_device != NULL)) * (MAX_CARD_SLOTS + 1)) + (num_ipc_queues * (QUEUE_LEN + 1)), 
    numa_node_of_cpu(forwarder[RX_FWDR].bind_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;
  }

  for (i = 0; i < num_ipc_queues; i++) { 
    ipczqs[i] = pfring_zc_create_queue(zc, QUEUE_LEN);

    if(ipczqs[i] == NULL) {
      fprintf(stderr, "pfring_zc_create_queue error [%s]\n", strerror(errno));
      return -1;
    }
  }

  for (i = 0; i < num_ipc_queues; i++) { 
    pools[i] = pfring_zc_create_buffer_pool(zc, 1);

    if (pools[i] == NULL) {
      fprintf(stderr, "pfring_zc_create_buffer_pool error\n");
      return -1;
    }
  }

  if (in_device != NULL) {
    forwarder[RX_FWDR].inzq = pfring_zc_open_device(zc, in_device, rx_only, 0);
    forwarder[RX_FWDR].outzq = ipczqs[in_queue_id];

    if(forwarder[RX_FWDR].inzq == NULL) {
      fprintf(stderr, "pfring_zc_open_device error [%s] Please check that %s is up and not already used\n",
	      strerror(errno), in_device);
      return -1;
    }

    forwarder[RX_FWDR].buffer = pfring_zc_get_packet_handle(zc);

    if (forwarder[RX_FWDR].buffer == NULL) {
      fprintf(stderr, "pfring_zc_get_packet_handle error\n");
      return -1;
    }

    printf("Forwarding from %s to Q%u\n", in_device, in_queue_id);
  }

  if (out_device != NULL) {
    forwarder[TX_FWDR].inzq = ipczqs[out_queue_id];
    forwarder[TX_FWDR].outzq = pfring_zc_open_device(zc, out_device, tx_only, 0);

    if(forwarder[TX_FWDR].outzq == NULL) {
      fprintf(stderr, "pfring_zc_open_device error [%s] Please check that %s is up and not already used\n",
	      strerror(errno), out_device);
      return -1;
    }

    forwarder[TX_FWDR].buffer = pfring_zc_get_packet_handle(zc);

    if (forwarder[TX_FWDR].buffer == NULL) {
      fprintf(stderr, "pfring_zc_get_packet_handle error\n");
      return -1;
    }
    
    printf("Forwarding from Q%u to %s\n", out_queue_id, out_device);
  }

  if (enable_vm_support) {
    vm_sock = strtok(vm_sockets, ",");
    while(vm_sock != NULL) {

      rc = pfring_zc_vm_register(zc, vm_sock);

      if (rc < 0) {
        fprintf(stderr, "pfring_zc_vm_register error\n");
        return -1;
      }

      vm_sock = strtok(NULL, ",");
    }

    rc = pfring_zc_vm_backend_enable(zc);

    if (rc < 0) {
      fprintf(stderr, "pfring_zc_vm_backend_enable error\n");
      return -1;
    }
  }

  signal(SIGINT,  sigproc);
  signal(SIGTERM, sigproc);
  signal(SIGINT,  sigproc);

  printf("Starting master with %d queues..\n", num_ipc_queues);

  if (out_device != NULL) pthread_create(&forwarder[TX_FWDR].thread, NULL, forwarder_thread, &forwarder[TX_FWDR]);
  if (in_device  != NULL) pthread_create(&forwarder[RX_FWDR].thread, NULL, forwarder_thread, &forwarder[RX_FWDR]);

  while (!do_shutdown) {
    sleep(ALARM_SLEEP);
    print_stats();
  }
  
  if (out_device != NULL) pthread_join(forwarder[TX_FWDR].thread, NULL);
  if (in_device  != NULL) pthread_join(forwarder[RX_FWDR].thread, NULL);

  pfring_zc_destroy_cluster(zc);

  return 0;
}
Пример #6
0
static int pfring_zc_daq_initialize(const DAQ_Config_t *config,
                                    void **ctxt_ptr, char *errbuf, size_t len) {
    Pfring_Context_t *context;
    DAQ_Dict* entry;
    u_int numCPU = get_nprocs();
    int i, max_buffer_len = 0, card_buffers;
    int num_buffers;
    int ipc_cluster_id;

    context = calloc(1, sizeof(Pfring_Context_t));

    if (context == NULL) {
        snprintf(errbuf, len, "%s: Couldn't allocate memory for context!", __FUNCTION__);
        return DAQ_ERROR_NOMEM;
    }

    context->mode = config->mode;
    context->snaplen = config->snaplen;
    context->promisc_flag =(config->flags & DAQ_CFG_PROMISC);
    context->timeout = (config->timeout > 0) ? (int) config->timeout : -1;
    context->devices[DAQ_PF_RING_PASSIVE_DEV_IDX] = strdup(config->name);
    context->num_devices = 1;
    context->ids_bridge = 0;
    context->cluster_id = -1;
    context->max_buffer_len = 0;
    context->bindcpu = 0;
    context->ipc_attach = 0;

    if (!context->devices[DAQ_PF_RING_PASSIVE_DEV_IDX]) {
        snprintf(errbuf, len, "%s: Couldn't allocate memory for the device string!", __FUNCTION__);
        free(context);
        return DAQ_ERROR_NOMEM;
    }

    for (entry = config->values; entry; entry = entry->next) {
        if (!entry->value || !*entry->value) {
            snprintf(errbuf, len, "%s: variable needs value(%s)\n", __FUNCTION__, entry->key);
            return DAQ_ERROR;
        } else if (!strcmp(entry->key, "bindcpu")) {
            char *end = entry->value;
            context->bindcpu = (int) strtol(entry->value, &end, 0);
            if (*end
                    || (context->bindcpu >= numCPU)) {
                snprintf(errbuf, len, "%s: bad bindcpu(%s)\n", __FUNCTION__, entry->value);
                return DAQ_ERROR;
            } else {
                cpu_set_t mask;

                CPU_ZERO(&mask);
                CPU_SET((int)context->bindcpu, &mask);
                if (sched_setaffinity(0, sizeof(mask), &mask) < 0) {
                    snprintf(errbuf, len, "%s:failed to set bindcpu(%u) on pid %i\n", __FUNCTION__, context->bindcpu, getpid());
                    return DAQ_ERROR;
                }
            }
        } else if (!strcmp(entry->key, "timeout")) {
            char *end = entry->value;
            context->timeout = (int) strtol(entry->value, &end, 0);
            if (*end || (context->timeout < 0)) {
                snprintf(errbuf, len, "%s: bad timeout(%s)\n", __FUNCTION__, entry->value);
                return DAQ_ERROR;
            }
        } else if (!strcmp(entry->key, "idsbridge")) {
            if (context->mode == DAQ_MODE_PASSIVE) {
                char* end = entry->value;
                context->ids_bridge = (int) strtol(entry->value, &end, 0);
                if (*end || (context->ids_bridge < 0) || (context->ids_bridge > 2)) {
                    snprintf(errbuf, len, "%s: bad ids bridge mode(%s)\n", __FUNCTION__, entry->value);
                    return DAQ_ERROR;
                }
            } else {
                snprintf(errbuf, len, "%s: idsbridge is for passive mode only\n", __FUNCTION__);
                return DAQ_ERROR;
            }
        } else if (!strcmp(entry->key, "clusterid")) {
            char *end = entry->value;
            context->cluster_id = (int) strtol(entry->value, &end, 0);
            if (*end || (context->cluster_id < 0)) {
                snprintf(errbuf, len, "%s: bad clusterid(%s)\n", __FUNCTION__, entry->value);
                return DAQ_ERROR;
            }
        } else {
            snprintf(errbuf, len, "%s: unsupported variable(%s=%s)\n", __FUNCTION__, entry->key, entry->value);
            return DAQ_ERROR;
        }
    }

    if (context->mode == DAQ_MODE_READ_FILE) {
        snprintf(errbuf, len, "%s: function not supported on PF_RING", __FUNCTION__);
        free(context);
        return DAQ_ERROR;
    } else if (context->mode == DAQ_MODE_INLINE || (context->mode == DAQ_MODE_PASSIVE && context->ids_bridge)) {
        /* zc:ethX+zc:ethY,zc:ethZ+zc:ethJ */
        char *twins, *twins_pos = NULL;
        context->num_devices = 0;

        twins = strtok_r(context->devices[DAQ_PF_RING_PASSIVE_DEV_IDX], ",", &twins_pos);
        while (twins != NULL) {
            char *dev, *dev_pos = NULL, *tx_dev;
            int last_twin = 0;

            dev = strtok_r(twins, "+", &dev_pos);
            while (dev != NULL) {

                if (context->num_devices >= DAQ_PF_RING_MAX_NUM_DEVICES) {
                    snprintf(errbuf, len, "%s: Maximum num of devices reached (%d), you should increase "
                             "DAQ_PF_RING_MAX_NUM_DEVICES.\n", __FUNCTION__, DAQ_PF_RING_MAX_NUM_DEVICES);
                    free(context);
                    return DAQ_ERROR;
                }

                last_twin = context->num_devices;

                context->devices[context->num_devices] = dev;

                tx_dev = strchr(dev, '-');
                if (tx_dev != NULL) { /* use the specified device for tx */
                    tx_dev[0] = '\0';
                    tx_dev++;
                    context->tx_devices[context->num_devices] = tx_dev;
                } else {
                    context->tx_devices[context->num_devices] = dev;
                }

                context->num_devices++;

                dev = strtok_r(NULL, "+", &dev_pos);
            }

            if (context->num_devices & 0x1) {
                snprintf(errbuf, len, "%s: Wrong format: %s requires pairs of devices",
                         __FUNCTION__, context->mode == DAQ_MODE_INLINE ? "inline mode" : "ids bridge");
                free(context);
                return DAQ_ERROR;
            }

            if (last_twin > 0) /* new dev pair */
                printf("%s <-> %s\n", context->devices[last_twin - 1], context->devices[last_twin]);

            twins = strtok_r(NULL, ",", &twins_pos);
        }
    } else if (context->mode == DAQ_MODE_PASSIVE) {
        /* zc:ethX,zc:ethY */
        char *dev, *dev_pos = NULL;
        context->num_devices = 0;
        context->ipc_attach = 1; /* IPC queue attach supported in pure IDS only at the moment */

        dev = strtok_r(context->devices[DAQ_PF_RING_PASSIVE_DEV_IDX], ",", &dev_pos);
        while (dev != NULL) {

            /* checking for IPC Queue */
            if (!is_a_queue(dev, &ipc_cluster_id, &context->ipc_queues[context->num_devices])) {
                context->ipc_attach = 0;
            } else {
                if (context->cluster_id == -1)
                    context->cluster_id = ipc_cluster_id;
                else if (ipc_cluster_id != context->cluster_id)
                    context->ipc_attach = 0;
            }

            context->devices[context->num_devices++] = dev;
            dev = strtok_r(NULL, ",", &dev_pos);
        }
    }

#ifdef SIG_RELOAD
    /* catching the SIGRELOAD signal, replacing the default snort handler */
    if ((default_sig_reload_handler = signal(SIGHUP, pfring_zc_daq_sig_reload)) == SIG_ERR)
        default_sig_reload_handler = NULL;
#endif

    if (!context->ipc_attach) {

        num_buffers = 2 /* buffer, buffer_inject */;

#ifdef DAQ_PF_RING_BEST_EFFORT_BOOST
        if (context->mode == DAQ_MODE_PASSIVE && context->ids_bridge == 2)
            num_buffers += QUEUE_LEN;
#endif

        for (i = 0; i < context->num_devices; i++) {
            max_buffer_len = max_packet_len(context, context->devices[i], i, &card_buffers);
            if (max_buffer_len > context->max_buffer_len) context->max_buffer_len = max_buffer_len;
            if (strstr(context->devices[i], "zc:") != NULL) num_buffers += card_buffers;
            if (context->tx_devices[i] != NULL) {
                max_buffer_len = max_packet_len(context, context->tx_devices[i], i, &card_buffers);
                if (max_buffer_len > context->max_buffer_len) context->max_buffer_len = max_buffer_len;
                if (strstr(context->tx_devices[i], "zc:") != NULL) num_buffers += card_buffers;
            }
        }

        context->cluster = pfring_zc_create_cluster(context->cluster_id, context->max_buffer_len, 0, num_buffers,
                           context->bindcpu == 0 ? -1 : numa_node_of_cpu(context->bindcpu), NULL);

        if (context->cluster == NULL) {
            DPE(context->errbuf, "%s: Cluster failed: %s(%d)", __FUNCTION__, strerror(errno), errno);
            return DAQ_ERROR;
        }

        context->buffer = pfring_zc_get_packet_handle(context->cluster);

        if (context->buffer == NULL) {
            DPE(context->errbuf, "%s: Buffer allocation failed: %s(%d)", __FUNCTION__, strerror(errno), errno);
            return DAQ_ERROR;
        }

        context->buffer_inject = pfring_zc_get_packet_handle(context->cluster);

        if (context->buffer_inject == NULL) {
            DPE(context->errbuf, "%s: Buffer allocation failed: %s(%d)", __FUNCTION__, strerror(errno), errno);
            return DAQ_ERROR;
        }

    } else {

        context->ipc_pool = pfring_zc_ipc_attach_buffer_pool(context->cluster_id, context->ipc_queues[0]);

        if (context->ipc_pool == NULL) {
            snprintf(errbuf, len, "%s: pfring_zc_ipc_attach_buffer_pool error %s(%d), please check that cluster %d is running\n",
                     __FUNCTION__, strerror(errno), errno, context->cluster_id);
            return -1;
        }

        context->buffer = pfring_zc_get_packet_handle_from_pool(context->ipc_pool);

        if (context->buffer == NULL) {
            DPE(context->errbuf, "%s: Buffer allocation failed: %s(%d)", __FUNCTION__, strerror(errno), errno);
            return DAQ_ERROR;
        }

    }

    for (i = 0; i < context->num_devices; i++) {
        if (pfring_zc_daq_open(context, i) == -1)
            return DAQ_ERROR;
    }

    if (!context->ipc_attach) {
#ifdef DAQ_PF_RING_BEST_EFFORT_BOOST
        if (context->mode == DAQ_MODE_PASSIVE && context->ids_bridge == 2) {
            context->q = pfring_zc_create_queue(context->cluster, QUEUE_LEN);

            if (context->q == NULL) {
                snprintf(errbuf, len, "%s: Couldn't create queue: '%s'", __FUNCTION__, strerror(errno));
                return DAQ_ERROR_NOMEM;
            }

            context->mq_queues[context->num_devices] = context->q;
            context->mq = pfring_zc_create_multi_queue(context->mq_queues, context->num_devices + 1);
        }
#endif
    }

    context->state = DAQ_STATE_INITIALIZED;

    *ctxt_ptr = context;
    return DAQ_SUCCESS;
}
Пример #7
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;
}