コード例 #1
0
ファイル: vmxnet3_test.c プロジェクト: chrisy/vpp
/* vmxnet3 delete API */
static int
api_vmxnet3_delete (vat_main_t * vam)
{
  unformat_input_t *i = vam->input;
  vl_api_vmxnet3_delete_t *mp;
  u32 sw_if_index = 0;
  u8 index_defined = 0;
  int ret;

  while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
    {
      if (unformat (i, "sw_if_index %u", &sw_if_index))
	index_defined = 1;
      else
	{
	  clib_warning ("unknown input '%U'", format_unformat_error, i);
	  return -99;
	}
    }

  if (!index_defined)
    {
      errmsg ("missing sw_if_index\n");
      return -99;
    }

  M (VMXNET3_DELETE, mp);

  mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);

  S (mp);
  W (ret);

  return ret;
}
コード例 #2
0
ファイル: vmxnet3_test.c プロジェクト: chrisy/vpp
static int
api_vmxnet3_dump (vat_main_t * vam)
{
  vmxnet3_test_main_t *vxm = &vmxnet3_test_main;
  vl_api_vmxnet3_dump_t *mp;
  vl_api_control_ping_t *mp_ping;
  int ret;

  if (vam->json_output)
    {
      clib_warning ("JSON output not supported for vmxnet3_dump");
      return -99;
    }

  M (VMXNET3_DUMP, mp);
  S (mp);

  /* Use a control ping for synchronization */
  mp_ping = vl_msg_api_alloc_as_if_client (sizeof (*mp_ping));
  mp_ping->_vl_msg_id = htons (vxm->ping_id);
  mp_ping->client_index = vam->my_client_index;

  fformat (vam->ofp, "Sending ping id=%d\n", vxm->ping_id);

  vam->result_ready = 0;
  S (mp_ping);

  W (ret);
  return ret;
}
コード例 #3
0
ファイル: cdp_node.c プロジェクト: JehandadKhan/vpp
/*
 * cdp periodic function 
 */
static uword
cdp_process (vlib_main_t * vm,
                    vlib_node_runtime_t * rt,
                    vlib_frame_t * f)
{
    cdp_main_t * cm = &cdp_main;
    f64 poll_time_remaining;
    uword event_type, * event_data = 0;

    /* So we can send events to the cdp process */
    cm->cdp_process_node_index = cdp_process_node.index;

    /* Dynamically register the cdp input node with the snap classifier */
    snap_register_input_protocol (vm, "cdp-input", 
                                  0xC /* ieee_oui, Cisco */,
                                  0x2000 /* protocol CDP */,
                                  cdp_input_node.index);

    snap_register_input_protocol (vm, "cdp-input", 
                                  0xC /* ieee_oui, Cisco */,
                                  0x2004 /* protocol CDP */,
                                  cdp_input_node.index);

#if 0 /* retain for reference */
    /* with the hdlc classifier */
    hdlc_register_input_protocol (vm, HDLC_PROTOCOL_cdp,
                                  cdp_input_node.index);
#endif

    /* with ethernet input (for SRP) */
    ethernet_register_input_type (vm, ETHERNET_TYPE_CDP /* CDP */,
				  cdp_input_node.index);

    poll_time_remaining = 10.0 /* seconds */;
    while (1) {
        /* sleep until next poll time, or msg serialize event occurs */
        poll_time_remaining = 
            vlib_process_wait_for_event_or_clock (vm, poll_time_remaining);
        
        event_type = vlib_process_get_events (vm, &event_data);
        switch (event_type) {
        case ~0:                /* no events => timeout */
            break;

        default:
            clib_warning ("BUG: event type 0x%wx", event_type);
            break;
        }
        if (event_data)
            _vec_len (event_data) = 0;

        /* peer timeout scan, send announcements */
        if (vlib_process_suspend_time_is_zero (poll_time_remaining)) {
            cdp_periodic (vm);
            poll_time_remaining = 10.0;
        }
    }

    return 0;
}
コード例 #4
0
ファイル: time_range.c プロジェクト: chrisy/vpp
void
clib_timebase_init (clib_timebase_t * tb, i32 timezone_offset_in_hours,
		    clib_timebase_daylight_time_t daylight_type)
{
  clib_memset (tb, 0, sizeof (*tb));

  clib_time_init (&tb->clib_time);
  tb->time_zero = unix_time_now ();

  tb->timezone_offset = ((f64) (timezone_offset_in_hours)) * 3600.0;
  tb->daylight_time_type = daylight_type;
  switch (tb->daylight_time_type)
    {
    case CLIB_TIMEBASE_DAYLIGHT_NONE:
      tb->summer_offset = 0.0;
      break;
    case CLIB_TIMEBASE_DAYLIGHT_USA:
      tb->summer_offset = 3600.0;
      break;
    default:
      clib_warning ("unknown daylight type %d", tb->daylight_time_type);
      tb->daylight_time_type = CLIB_TIMEBASE_DAYLIGHT_NONE;
      tb->summer_offset = 0.0;
    }
}
コード例 #5
0
ファイル: memory_client.c プロジェクト: JehandadKhan/vpp
u16 vl_client_get_first_plugin_msg_id (char * plugin_name)
{
    vl_api_get_first_msg_id_t * mp;
    api_main_t * am = &api_main;
    memory_client_main_t * mm = &memory_client_main;
    f64 timeout;
    void * old_handler;
    clib_time_t clib_time;
    u16 rv = ~0;

    if (strlen(plugin_name) + 1 > sizeof (mp->name))
        return (rv);

    memset (&clib_time, 0, sizeof (clib_time));
    clib_time_init (&clib_time);

    /* Push this plugin's first_msg_id_reply handler */
    old_handler = am->msg_handlers[VL_API_GET_FIRST_MSG_ID_REPLY];
    am->msg_handlers[VL_API_GET_FIRST_MSG_ID_REPLY] = (void *)
        vl_api_get_first_msg_id_reply_t_handler;

    /* Ask the data-plane for the message-ID base of the indicated plugin */
    mm->first_msg_id_reply_ready = 0;

    mp = vl_msg_api_alloc (sizeof(*mp));
    memset (mp, 0, sizeof (*mp));
    mp->_vl_msg_id = ntohs(VL_API_GET_FIRST_MSG_ID);
    mp->client_index = am->my_client_index;
    strncpy ((char *) mp->name, plugin_name, sizeof (mp->name) - 1);

    vl_msg_api_send_shmem (am->shmem_hdr->vl_input_queue, (u8 *)&mp);

    /* Synchronously wait for the answer */
    do {                                          
        timeout = clib_time_now (&clib_time) + 1.0;       
        
        while (clib_time_now (&clib_time) < timeout) {    
            if (mm->first_msg_id_reply_ready == 1) {         
                rv = mm->first_msg_id_reply;
                goto result;
            }                                     
        }                                         
        /* Restore old handler */
        am->msg_handlers[VL_API_GET_FIRST_MSG_ID_REPLY] = old_handler;

        return rv;
    } while(0);

result:

    /* Restore the old handler */
    am->msg_handlers[VL_API_GET_FIRST_MSG_ID_REPLY] = old_handler;

    if (rv == (u16) ~0)
        clib_warning ("plugin '%s' not registered", plugin_name);

    return rv;
}
コード例 #6
0
static int
load_one_vat_plugin (plugin_main_t * pm, plugin_info_t * pi)
{
  void *handle, *register_handle;
  clib_error_t *(*fp) (vat_main_t *);
  clib_error_t *error;

  handle = dlopen ((char *) pi->filename, RTLD_LAZY);

  /*
   * Note: this can happen if the plugin has an undefined symbol reference,
   * so print a warning. Otherwise, the poor slob won't know what happened.
   * Ask me how I know that...
   */
  if (handle == 0)
    {
      clib_warning ("%s", dlerror ());
      return 0;
    }

  pi->handle = handle;

  register_handle = dlsym (pi->handle, "vat_plugin_register");
  if (register_handle == 0)
    {
      clib_warning ("%s: symbol vat_plugin_register not found", pi->name);
      dlclose (handle);
      return 0;
    }

  fp = register_handle;

  error = (*fp) (pm->vat_main);

  if (error)
    {
      clib_error_report (error);
      dlclose (handle);
      return 1;
    }

  clib_warning ("Loaded plugin: %s", pi->name);

  return 0;
}
コード例 #7
0
static inline int
session_send_evt_to_thread (void *data, void *args, u32 thread_index,
			    session_evt_type_t evt_type)
{
  session_event_t *evt;
  svm_msg_q_msg_t msg;
  svm_msg_q_t *mq;
  u32 tries = 0, max_tries;

  mq = session_main_get_vpp_event_queue (thread_index);
  while (svm_msg_q_try_lock (mq))
    {
      max_tries = vlib_get_current_process (vlib_get_main ())? 1e6 : 3;
      if (tries++ == max_tries)
	{
	  SESSION_DBG ("failed to enqueue evt");
	  return -1;
	}
    }
  if (PREDICT_FALSE (svm_msg_q_ring_is_full (mq, SESSION_MQ_IO_EVT_RING)))
    {
      svm_msg_q_unlock (mq);
      return -2;
    }
  msg = svm_msg_q_alloc_msg_w_ring (mq, SESSION_MQ_IO_EVT_RING);
  if (PREDICT_FALSE (svm_msg_q_msg_is_invalid (&msg)))
    {
      svm_msg_q_unlock (mq);
      return -2;
    }
  evt = (session_event_t *) svm_msg_q_msg_data (mq, &msg);
  evt->event_type = evt_type;
  switch (evt_type)
    {
    case SESSION_CTRL_EVT_RPC:
      evt->rpc_args.fp = data;
      evt->rpc_args.arg = args;
      break;
    case SESSION_IO_EVT_TX:
    case SESSION_IO_EVT_TX_FLUSH:
    case SESSION_IO_EVT_BUILTIN_RX:
      evt->session_index = *(u32 *) data;
      break;
    case SESSION_IO_EVT_BUILTIN_TX:
    case SESSION_CTRL_EVT_CLOSE:
      evt->session_handle = session_handle ((session_t *) data);
      break;
    default:
      clib_warning ("evt unhandled!");
      svm_msg_q_unlock (mq);
      return -1;
    }

  svm_msg_q_add_and_unlock (mq, &msg);
  return 0;
}
コード例 #8
0
/**
 * Cleans up session and lookup table.
 *
 * Transport connection must still be valid.
 */
static void
session_delete (session_t * s)
{
  int rv;

  /* Delete from the main lookup table. */
  if ((rv = session_lookup_del_session (s)))
    clib_warning ("hash delete error, rv %d", rv);

  session_free_w_fifos (s);
}
コード例 #9
0
ファイル: vmxnet3_test.c プロジェクト: chrisy/vpp
/* vmxnet3 create API */
static int
api_vmxnet3_create (vat_main_t * vam)
{
  unformat_input_t *i = vam->input;
  vl_api_vmxnet3_create_t *mp;
  vmxnet3_create_if_args_t args;
  int ret;
  u32 x[4];

  clib_memset (&args, 0, sizeof (vmxnet3_create_if_args_t));

  while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
    {
      if (unformat (i, "%x:%x:%x.%x", &x[0], &x[1], &x[2], &x[3]))
	{
	  args.addr.domain = x[0];
	  args.addr.bus = x[1];
	  args.addr.slot = x[2];
	  args.addr.function = x[3];
	}
      else if (unformat (i, "elog"))
	args.enable_elog = 1;
      else if (unformat (i, "bind"))
	args.bind = 1;
      else if (unformat (i, "rx-queue-size %u", &args.rxq_size))
	;
      else if (unformat (i, "tx-queue-size %u", &args.txq_size))
	;
      else if (unformat (i, "num-tx-queues %u", &args.txq_num))
	;
      else if (unformat (i, "num-rx-queues %u", &args.rxq_num))
	;
      else
	{
	  clib_warning ("unknown input '%U'", format_unformat_error, i);
	  return -99;
	}
    }

  M (VMXNET3_CREATE, mp);

  mp->pci_addr = clib_host_to_net_u32 (args.addr.as_u32);
  mp->enable_elog = clib_host_to_net_u16 (args.enable_elog);
  mp->rxq_size = clib_host_to_net_u16 (args.rxq_size);
  mp->txq_size = clib_host_to_net_u16 (args.txq_size);
  mp->txq_num = clib_host_to_net_u16 (args.txq_num);
  mp->rxq_num = clib_host_to_net_u16 (args.rxq_num);
  mp->bind = args.bind;

  S (mp);
  W (ret);

  return ret;
}
コード例 #10
0
ファイル: memory_client.c プロジェクト: JehandadKhan/vpp
static int connect_to_vlib_internal (char *svm_name, char *client_name, 
                                     int rx_queue_size, int want_pthread)
{
    int rv=0;
    memory_client_main_t *mm = &memory_client_main;
    
    if ((rv = vl_client_api_map(svm_name))) {
        clib_warning ("vl_client_api map rv %d", rv);
        return rv;
    }
    
#define _(N,n)                                                  \
    vl_msg_api_set_handlers(VL_API_##N, #n,                     \
                            vl_api_##n##_t_handler,             \
                            noop_handler,                       \
                            vl_api_##n##_t_endian,              \
                            vl_api_##n##_t_print,               \
                            sizeof(vl_api_##n##_t), 1); 
    foreach_api_msg;
#undef _

    if (vl_client_connect(client_name, 0 /* punt quota */,
                          rx_queue_size /* input queue */) < 0) {
        vl_client_api_unmap();
        return -1;
    }

    /* Start the rx queue thread */
    
    if (want_pthread) {
        rv = pthread_create(&mm->rx_thread_handle, 
                            NULL /*attr*/, rx_thread_fn, 0);
        if (rv)
            clib_warning("pthread_create returned %d", rv);
    }
    
    mm->connected_to_vlib = 1;
    return 0;
}
コード例 #11
0
ファイル: api_shared.c プロジェクト: JehandadKhan/vpp
void vl_msg_api_cleanup_handler (void *the_msg)
{
    api_main_t *am = &api_main;
    u16 id = ntohs(*((u16 *)the_msg));

    if (PREDICT_FALSE(id >= vec_len(am->msg_cleanup_handlers))) {
        clib_warning ("_vl_msg_id too large: %d\n", id);
        return;
    }
    if (am->msg_cleanup_handlers[id])
        (*am->msg_cleanup_handlers[id])(the_msg);

    vl_msg_api_free(the_msg);
}
コード例 #12
0
ファイル: api_shared.c プロジェクト: JehandadKhan/vpp
/*
 * vl_msg_api_replay_handler
 */
void vl_msg_api_replay_handler(void *the_msg)
{
    api_main_t *am = &api_main;

    u16 id = ntohs(*((u16 *)the_msg));

    if (PREDICT_FALSE(id >= vec_len(am->msg_handlers))) {
        clib_warning ("_vl_msg_id too large: %d\n", id);
        return;
    }
    /* do NOT trace the message... */
    if (am->msg_handlers[id])
        (*am->msg_handlers[id])(the_msg);
    /* do NOT free the message buffer... */
}
コード例 #13
0
ファイル: device.c プロジェクト: JehandadKhan/vpp
static struct rte_mbuf * dpdk_replicate_packet_mb (vlib_buffer_t * b)
{
  vlib_main_t * vm = vlib_get_main();
  vlib_buffer_main_t * bm = vm->buffer_main;
  struct rte_mbuf * first_mb = 0, * new_mb, * pkt_mb, ** prev_mb_next = 0;
  u8 nb_segs, nb_segs_left;
  u32 copy_bytes;
  unsigned socket_id = rte_socket_id();

  ASSERT (bm->pktmbuf_pools[socket_id]);
  pkt_mb = ((struct rte_mbuf *)b)-1;
  nb_segs = pkt_mb->nb_segs;
  for (nb_segs_left = nb_segs; nb_segs_left; nb_segs_left--)
    {
      if (PREDICT_FALSE(pkt_mb == 0))
	{
	  clib_warning ("Missing %d mbuf chain segment(s):   "
			"(nb_segs = %d, nb_segs_left = %d)!",
			nb_segs - nb_segs_left, nb_segs, nb_segs_left);
	  if (first_mb)
	    rte_pktmbuf_free(first_mb);
	  return NULL;
	}
      new_mb = rte_pktmbuf_alloc (bm->pktmbuf_pools[socket_id]);
      if (PREDICT_FALSE(new_mb == 0))
	{
	  if (first_mb)
	    rte_pktmbuf_free(first_mb);
	  return NULL;
	}
      
      /*
       * Copy packet info into 1st segment.
       */
      if (first_mb == 0)
	{
	  first_mb = new_mb;
	  rte_pktmbuf_pkt_len (first_mb) = pkt_mb->pkt_len;
	  first_mb->nb_segs = pkt_mb->nb_segs;
	  first_mb->port = pkt_mb->port;
#ifdef DAW_FIXME // TX Offload support TBD
	  first_mb->vlan_macip = pkt_mb->vlan_macip;
	  first_mb->hash = pkt_mb->hash;
	  first_mb->ol_flags = pkt_mb->ol_flags
#endif
	}
      else
	{
コード例 #14
0
ファイル: api_shared.c プロジェクト: Venkattk/vpp
always_inline void
msg_handler_internal (api_main_t * am,
		      void *the_msg, int trace_it, int do_it, int free_it)
{
  u16 id = ntohs (*((u16 *) the_msg));
  u8 *(*print_fp) (void *, void *);

  if (id < vec_len (am->msg_handlers) && am->msg_handlers[id])
    {
      if (trace_it)
	vl_msg_api_trace (am, am->rx_trace, the_msg);

      if (am->msg_print_flag)
	{
	  fformat (stdout, "[%d]: %s\n", id, am->msg_names[id]);
	  print_fp = (void *) am->msg_print_handlers[id];
	  if (print_fp == 0)
	    {
	      fformat (stdout, "  [no registered print fn]\n");
	    }
	  else
	    {
	      (*print_fp) (the_msg, stdout);
	    }
	}

      if (do_it)
	{
	  if (!am->is_mp_safe[id])
	    vl_msg_api_barrier_sync ();
	  (*am->msg_handlers[id]) (the_msg);
	  if (!am->is_mp_safe[id])
	    vl_msg_api_barrier_release ();
	}
    }
  else
    {
      clib_warning ("no handler for msg id %d", id);
    }

  if (free_it)
    vl_msg_api_free (the_msg);
}
コード例 #15
0
ファイル: memory_shared.c プロジェクト: chrisy/vpp
void
vl_msg_api_send_shmem (svm_queue_t * q, u8 * elem)
{
  api_main_t *am = &api_main;
  uword *trace = (uword *) elem;

  if (am->tx_trace && am->tx_trace->enabled)
    vl_msg_api_trace (am, am->tx_trace, (void *) trace[0]);

  /*
   * Announce a probable binary API client bug:
   * some client's input queue is stuffed.
   * The situation may be recoverable, or not.
   */
  if (PREDICT_FALSE
      (am->vl_clients /* vpp side */  && (q->cursize == q->maxsize)))
    clib_warning ("WARNING: client input queue at %llx is stuffed...", q);
  (void) svm_queue_add (q, elem, 0 /* nowait */ );
}
コード例 #16
0
void
ssvm_delete_shm (ssvm_private_t * ssvm)
{
  u8 *fn;

  fn = format (0, "/dev/shm/%s%c", ssvm->name, 0);

  if (CLIB_DEBUG > 1)
    clib_warning ("[%d] unlinking ssvm (%s) backing file '%s'", getpid (),
		  ssvm->name, fn);

  /* Throw away the backing file */
  if (unlink ((char *) fn) < 0)
    clib_unix_warning ("unlink segment '%s'", ssvm->name);

  vec_free (fn);
  vec_free (ssvm->name);

  munmap ((void *) ssvm->requested_va, ssvm->ssvm_size);
}
コード例 #17
0
ファイル: perfmon_periodic.c プロジェクト: vpp-dev/vpp
static uword
perfmon_periodic_process (vlib_main_t * vm,
			  vlib_node_runtime_t * rt, vlib_frame_t * f)
{
  perfmon_main_t *pm = &perfmon_main;
  f64 now;
  uword *event_data = 0;
  uword event_type;
  int i;

  while (1)
    {
      if (pm->state == PERFMON_STATE_RUNNING)
	vlib_process_wait_for_event_or_clock (vm, pm->timeout_interval);
      else
	vlib_process_wait_for_event (vm);

      now = vlib_time_now (vm);

      event_type = vlib_process_get_events (vm, (uword **) & event_data);

      switch (event_type)
	{
	case PERFMON_START:
	  for (i = 0; i < vec_len (event_data); i++)
	    start_event (pm, now, event_data[i]);
	  break;

	  /* Handle timeout */
	case ~0:
	  handle_timeout (vm, pm, now);
	  break;

	default:
	  clib_warning ("Unexpected event %d", event_type);
	  break;
	}
      vec_reset_length (event_data);
    }
  return 0;			/* or not */
}
コード例 #18
0
ファイル: api_shared.c プロジェクト: Venkattk/vpp
/*
 * vl_msg_api_trace
 */
void
vl_msg_api_trace (api_main_t * am, vl_api_trace_t * tp, void *msg)
{
  u8 **this_trace;
  u8 **old_trace;
  u8 *msg_copy;
  trace_cfg_t *cfgp;
  u16 msg_id = ntohs (*((u16 *) msg));

  cfgp = am->api_trace_cfg + msg_id;

  if (!cfgp || !cfgp->trace_enable)
    return;

  msg_copy = 0;

  if (tp->nitems == 0)
    {
      clib_warning ("tp->nitems is 0");
      return;
    }

  if (vec_len (tp->traces) < tp->nitems)
    {
      vec_add1 (tp->traces, 0);
      this_trace = tp->traces + vec_len (tp->traces) - 1;
    }
  else
    {
      tp->wrapped = 1;
      old_trace = tp->traces + tp->curindex++;
      if (tp->curindex == tp->nitems)
	tp->curindex = 0;
      vec_free (*old_trace);
      this_trace = old_trace;
    }

  vec_validate (msg_copy, cfgp->size - 1);
  clib_memcpy (msg_copy, msg, cfgp->size);
  *this_trace = msg_copy;
}
コード例 #19
0
ファイル: svmdb.c プロジェクト: ajvoniq/vpp
static void
notify_value (svmdb_value_t * v, svmdb_action_t a)
{
  int i;
  int rv;
  union sigval sv;
  u32 value;
  u32 *dead_registrations = 0;

  svmdb_notify_t *np;

  for (i = 0; i < vec_len (v->notifications); i++)
    {
      np = vec_elt_at_index (v->notifications, i);
      if (np->action == a)
	{
	  value = (np->action << 28) | (np->opaque);
	  sv.sival_ptr = (void *) (uword) value;
	  do
	    {
	      rv = 0;
	      if (sigqueue (np->pid, np->signum, sv) == 0)
		break;
	      rv = errno;
	    }
	  while (rv == EAGAIN);
	  if (rv == 0)
	    continue;
	  vec_add1 (dead_registrations, i);
	}
    }

  for (i = 0; i < vec_len (dead_registrations); i++)
    {
      np = vec_elt_at_index (v->notifications, dead_registrations[i]);
      clib_warning ("dead reg pid %d sig %d action %d opaque %x",
		    np->pid, np->signum, np->action, np->opaque);
      vec_delete (v->notifications, 1, dead_registrations[i]);
    }
  vec_free (dead_registrations);
}
コード例 #20
0
ファイル: memory_shared.c プロジェクト: chrisy/vpp
void
vl_api_mem_config (vl_shmem_hdr_t * hdr, vl_api_shm_elem_config_t * config)
{
  vl_api_shm_elem_config_t *c;
  ring_alloc_t *rp;
  u32 size;

  if (!config)
    {
      vl_api_default_mem_config (hdr);
      return;
    }

  vec_foreach (c, config)
  {
    switch (c->type)
      {
      case VL_API_QUEUE:
	hdr->vl_input_queue = svm_queue_alloc_and_init (c->count, c->size,
							getpid ());
	continue;
      case VL_API_VLIB_RING:
	vec_add2 (hdr->vl_rings, rp, 1);
	break;
      case VL_API_CLIENT_RING:
	vec_add2 (hdr->client_rings, rp, 1);
	break;
      default:
	clib_warning ("unknown config type: %d", c->type);
	continue;
      }

    size = sizeof (ring_alloc_t) + c->size;
    rp->rp = svm_queue_alloc_and_init (c->count, size, 0);
    rp->size = size;
    rp->nitems = c->count;
    rp->hits = 0;
    rp->misses = 0;
  }
}
コード例 #21
0
ファイル: ssvm_eth.c プロジェクト: ayourtch/vpp-ssvm-eth-test
clib_error_t * ssvm_eth_init ()
{
  ssvm_eth_main_t * em = &ssvm_eth_main;

  if (((sizeof(ssvm_eth_queue_elt_t) / CLIB_CACHE_LINE_BYTES) 
       * CLIB_CACHE_LINE_BYTES) != sizeof(ssvm_eth_queue_elt_t))
    clib_warning ("ssvm_eth_queue_elt_t size %d not a multiple of %d",
                  sizeof(ssvm_eth_queue_elt_t), CLIB_CACHE_LINE_BYTES);


  /* default config param values... */

  em->next_base_va = 0x600000000ULL;
  /* 
   * Allocate 2 full superframes in each dir (256 x 2 x 2 x 2048 bytes),
   * 2mb; double that so we have plenty of space... 4mb
   */
  em->segment_size = 8<<20;
  em->nbuffers = 1024;
  em->queue_elts = 512;
  return 0;
}
コード例 #22
0
ファイル: flowprobe.c プロジェクト: chrisy/vpp
/**
 * @brief API message handler
 * @param mp vl_api_flowprobe_tx_interface_add_del_t * mp the api message
 */
void vl_api_flowprobe_tx_interface_add_del_t_handler
  (vl_api_flowprobe_tx_interface_add_del_t * mp)
{
  flowprobe_main_t *fm = &flowprobe_main;
  vl_api_flowprobe_tx_interface_add_del_reply_t *rmp;
  u32 sw_if_index = ntohl (mp->sw_if_index);
  int rv = 0;

  VALIDATE_SW_IF_INDEX (mp);

  if (mp->which != FLOW_VARIANT_IP4 && mp->which != FLOW_VARIANT_L2
      && mp->which != FLOW_VARIANT_IP6)
    {
      rv = VNET_API_ERROR_UNIMPLEMENTED;
      goto out;
    }

  if (fm->record == 0)
    {
      clib_warning ("Please specify flowprobe params record first...");
      rv = VNET_API_ERROR_CANNOT_ENABLE_DISABLE_FEATURE;
      goto out;
    }

  rv = validate_feature_on_interface (fm, sw_if_index, mp->which);
  if ((rv == 1 && mp->is_add == 1) || rv == 0)
    {
      rv = VNET_API_ERROR_CANNOT_ENABLE_DISABLE_FEATURE;
      goto out;
    }

  rv = flowprobe_tx_interface_add_del_feature
    (fm, sw_if_index, mp->which, mp->is_add);

out:
  BAD_SW_IF_INDEX_LABEL;

  REPLY_MACRO (VL_API_FLOWPROBE_TX_INTERFACE_ADD_DEL_REPLY);
}
コード例 #23
0
ファイル: lisp_gpe_adjacency.c プロジェクト: chrisy/vpp
static void
lisp_gpe_increment_stats_counters (lisp_cp_main_t * lcm, ip_adjacency_t * adj,
				   vlib_buffer_t * b)
{
  lisp_gpe_main_t *lgm = vnet_lisp_gpe_get_main ();
  lisp_gpe_adjacency_t *ladj;
  ip_address_t rloc;
  index_t lai;
  u32 si, di;
  gid_address_t src, dst;
  uword *feip;

  ip46_address_to_ip_address (&adj->sub_type.nbr.next_hop, &rloc);
  si = vnet_buffer (b)->sw_if_index[VLIB_TX];
  lai = lisp_adj_find (&rloc, si);
  ASSERT (INDEX_INVALID != lai);

  ladj = pool_elt_at_index (lisp_adj_pool, lai);

  u8 *lisp_data = (u8 *) vlib_buffer_get_current (b);

  /* skip IP header */
  if (is_v4_packet (lisp_data))
    lisp_data += sizeof (ip4_header_t);
  else
    lisp_data += sizeof (ip6_header_t);

  /* skip UDP header */
  lisp_data += sizeof (udp_header_t);
  // TODO: skip TCP?

  /* skip LISP GPE header */
  lisp_data += sizeof (lisp_gpe_header_t);

  i16 saved_current_data = b->current_data;
  b->current_data = lisp_data - b->data;

  lisp_afi_e afi = lisp_afi_from_vnet_link_type (adj->ia_link);
  get_src_and_dst_eids_from_buffer (lcm, b, &src, &dst, afi);
  b->current_data = saved_current_data;
  di = gid_dictionary_sd_lookup (&lcm->mapping_index_by_gid, &dst, &src);
  if (PREDICT_FALSE (~0 == di))
    {
      clib_warning ("dst mapping not found (%U, %U)", format_gid_address,
		    &src, format_gid_address, &dst);
      return;
    }

  feip = hash_get (lcm->fwd_entry_by_mapping_index, di);
  if (PREDICT_FALSE (!feip))
    return;

  lisp_stats_key_t key;
  clib_memset (&key, 0, sizeof (key));
  key.fwd_entry_index = feip[0];
  key.tunnel_index = ladj->tunnel_index;

  uword *p = hash_get_mem (lgm->lisp_stats_index_by_key, &key);
  ASSERT (p);

  /* compute payload length starting after GPE */
  u32 bytes = b->current_length - (lisp_data - b->data - b->current_data);
  vlib_increment_combined_counter (&lgm->counters, vlib_get_thread_index (),
				   p[0], 1, bytes);
}
コード例 #24
0
ファイル: counter.c プロジェクト: Venkattk/vpp
void
unserialize_vlib_combined_counter_main (serialize_main_t * m, va_list * va)
{
  clib_warning ("unimplemented");
}
コード例 #25
0
ファイル: counter.c プロジェクト: Venkattk/vpp
void
serialize_vlib_simple_counter_main (serialize_main_t * m, va_list * va)
{
  clib_warning ("unimplemented");
}
コード例 #26
0
ファイル: api_shared.c プロジェクト: Venkattk/vpp
/* This is only to be called from a vlib/vnet app */
void
vl_msg_api_handler_with_vm_node (api_main_t * am,
				 void *the_msg, vlib_main_t * vm,
				 vlib_node_runtime_t * node)
{
  u16 id = ntohs (*((u16 *) the_msg));
  u8 *(*handler) (void *, void *, void *);

#if ELOG_API_MESSAGE_HANDLERS > 0
  {
    /* *INDENT-OFF* */
    ELOG_TYPE_DECLARE (e) =
      {
        .format = "api-msg: %s",
        .format_args = "T4",
      };
    /* *INDENT-ON* */
    struct
    {
      u32 c;
    } *ed;
    ed = ELOG_DATA (&vm->elog_main, e);
    if (id < vec_len (am->msg_names))
      ed->c = elog_id_for_msg_name (vm, am->msg_names[id]);
    else
      ed->c = elog_id_for_msg_name (vm, "BOGUS");
  }
#endif

  if (id < vec_len (am->msg_handlers) && am->msg_handlers[id])
    {
      handler = (void *) am->msg_handlers[id];

      if (am->rx_trace && am->rx_trace->enabled)
	vl_msg_api_trace (am, am->rx_trace, the_msg);

      if (!am->is_mp_safe[id])
	vl_msg_api_barrier_sync ();
      (*handler) (the_msg, vm, node);
      if (!am->is_mp_safe[id])
	vl_msg_api_barrier_release ();
    }
  else
    {
      clib_warning ("no hander for msg id %d", id);
    }

  /*
   * Special-case, so we can e.g. bounce messages off the vnet
   * main thread without copying them...
   */
  if (!(am->message_bounce[id]))
    vl_msg_api_free (the_msg);

#if ELOG_API_MESSAGE_HANDLERS > 0
  {
  /* *INDENT-OFF* */
  ELOG_TYPE_DECLARE (e) = {
    .format = "api-msg-done: %s",
    .format_args = "T4",
  };
  /* *INDENT-ON* */

    struct
    {
      u32 c;
    } *ed;
    ed = ELOG_DATA (&vm->elog_main, e);
    if (id < vec_len (am->msg_names))
      ed->c = elog_id_for_msg_name (vm, am->msg_names[id]);
    else
      ed->c = elog_id_for_msg_name (vm, "BOGUS");
  }
#endif
}

void
vl_msg_api_handler (void *the_msg)
{
  api_main_t *am = &api_main;

  msg_handler_internal (am, the_msg,
			(am->rx_trace
			 && am->rx_trace->enabled) /* trace_it */ ,
			1 /* do_it */ , 1 /* free_it */ );
}

void
vl_msg_api_handler_no_free (void *the_msg)
{
  api_main_t *am = &api_main;
  msg_handler_internal (am, the_msg,
			(am->rx_trace
			 && am->rx_trace->enabled) /* trace_it */ ,
			1 /* do_it */ , 0 /* free_it */ );
}
コード例 #27
0
ファイル: test_random.c プロジェクト: Venkattk/vpp
int test_random_main (unformat_input_t * input)
{
  uword n_iterations;
  uword i, repeat_count;
  uword * bitmap = 0;
  uword print;
  u32 seed;
  u32 *seedp = &seed;

  /* first, check known sequence from Numerical Recipes in C, 2nd ed.
     page 284 */
  seed = known_random_sequence[0];
  for (i = 0; i < ARRAY_LEN(known_random_sequence)-1; i++) 
    {
      u32 rv;
      rv = random_u32 (seedp);
      if (rv != known_random_sequence[i+1])
        {
          fformat(stderr, "known sequence check FAILS at index %d", i+1);
          break;
        }
    }

  clib_warning ("known sequence check passes");

  n_iterations = 1000;
  seed = 0;
  print = 1 << 24;

  while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
    {
      if (0 == unformat (input, "iter %d", &n_iterations)
	  && 0 == unformat (input, "print %d", &print)
	  && 0 == unformat (input, "seed %d", &seed))
	clib_error ("unknown input `%U'", format_unformat_error, input);
    }

  if (! seed)
    seed = random_default_seed ();

  if (n_iterations == 0)
    n_iterations = random_u32_max ();

  clib_warning ("%d iterations, seed %d\n", n_iterations, seed);

  repeat_count = 0;
  for (i = 0; i < n_iterations; i++)
    {
      uword r = random_u32 (&seed);
      uword b, ri, rj;

      ri = r / BITS (bitmap[0]);
      rj = (uword) 1 << (r % BITS (bitmap[0]));

      vec_validate (bitmap, ri);
      b = bitmap[ri];

      if (b & rj)
	goto repeat;
      b |= rj;
      bitmap[ri] = b;

      if (0 == (i & (print - 1)))
	fformat (stderr, "0x%08x iterations %d repeats\n", i, repeat_count);
      continue;

    repeat:
      fformat (stderr, "repeat found at iteration  %d/%d\n", i, n_iterations);
      repeat_count++;
      continue;
    }

  return 0;
}
コード例 #28
0
static void
unix_signal_handler (int signum, siginfo_t * si, ucontext_t * uc)
{
  uword fatal = 0;

  /* These come in handy when looking at core files from optimized images */
  last_signum = signum;
  last_faulting_address = (uword) si->si_addr;

  syslog_msg = format (syslog_msg, "received signal %U, PC %U",
		       format_signal, signum, format_ucontext_pc, uc);

  if (signum == SIGSEGV)
    syslog_msg = format (syslog_msg, ", faulting address %p", si->si_addr);

  switch (signum)
    {
      /* these (caught) signals cause the application to exit */
    case SIGTERM:
      /*
       * Ignore SIGTERM if it's sent before we're ready.
       */
      if (unix_main.vlib_main && unix_main.vlib_main->main_loop_exit_set)
	{
	  syslog (LOG_ERR | LOG_DAEMON, "received SIGTERM, exiting...");
	  unix_main.vlib_main->main_loop_exit_now = 1;
	}
      else
	syslog (LOG_ERR | LOG_DAEMON, "IGNORE early SIGTERM...");
      break;
      /* fall through */
    case SIGQUIT:
    case SIGINT:
    case SIGILL:
    case SIGBUS:
    case SIGSEGV:
    case SIGHUP:
    case SIGFPE:
    case SIGABRT:
      fatal = 1;
      break;

      /* by default, print a message and continue */
    default:
      fatal = 0;
      break;
    }

#ifdef CLIB_GCOV
  /*
   * Test framework sends SIGTERM, so we need to flush the
   * code coverage stats here.
   */
  {
    void __gcov_flush (void);
    __gcov_flush ();
  }
#endif

  /* Null terminate. */
  vec_add1 (syslog_msg, 0);

  if (fatal)
    {
      syslog (LOG_ERR | LOG_DAEMON, "%s", syslog_msg);

      /* Address of callers: outer first, inner last. */
      uword callers[15];
      uword n_callers = clib_backtrace (callers, ARRAY_LEN (callers), 0);
      int i;
      for (i = 0; i < n_callers; i++)
	{
	  vec_reset_length (syslog_msg);

	  syslog_msg =
	    format (syslog_msg, "#%-2d 0x%016lx %U%c", i, callers[i],
		    format_clib_elf_symbol_with_address, callers[i], 0);

	  syslog (LOG_ERR | LOG_DAEMON, "%s", syslog_msg);
	}

      /* have to remove SIGABRT to avoid recusive - os_exit calling abort() */
      unsetup_signal_handlers (SIGABRT);

      os_exit (1);
    }
  else
    clib_warning ("%s", syslog_msg);

}
コード例 #29
0
static clib_error_t *
unix_config (vlib_main_t * vm, unformat_input_t * input)
{
  unix_main_t *um = &unix_main;
  clib_error_t *error = 0;
  gid_t gid;
  int pidfd = -1;

  /* Defaults */
  um->cli_pager_buffer_limit = UNIX_CLI_DEFAULT_PAGER_LIMIT;
  um->cli_history_limit = UNIX_CLI_DEFAULT_HISTORY;

  while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
    {
      char *cli_prompt;
      if (unformat (input, "interactive"))
	um->flags |= UNIX_FLAG_INTERACTIVE;
      else if (unformat (input, "nodaemon"))
	um->flags |= UNIX_FLAG_NODAEMON;
      else if (unformat (input, "cli-prompt %s", &cli_prompt))
	vlib_unix_cli_set_prompt (cli_prompt);
      else
	if (unformat (input, "cli-listen %s", &um->cli_listen_socket.config))
	;
      else if (unformat (input, "runtime-dir %s", &um->runtime_dir))
	;
      else if (unformat (input, "cli-line-mode"))
	um->cli_line_mode = 1;
      else if (unformat (input, "cli-no-banner"))
	um->cli_no_banner = 1;
      else if (unformat (input, "cli-no-pager"))
	um->cli_no_pager = 1;
      else if (unformat (input, "poll-sleep-usec %d", &um->poll_sleep_usec))
	;
      else if (unformat (input, "cli-pager-buffer-limit %d",
			 &um->cli_pager_buffer_limit))
	;
      else
	if (unformat (input, "cli-history-limit %d", &um->cli_history_limit))
	;
      else if (unformat (input, "coredump-size"))
	{
	  uword coredump_size = 0;
	  if (unformat (input, "unlimited"))
	    {
	      coredump_size = RLIM_INFINITY;
	    }
	  else
	    if (!unformat (input, "%U", unformat_memory_size, &coredump_size))
	    {
	      return clib_error_return (0,
					"invalid coredump-size parameter `%U'",
					format_unformat_error, input);
	    }
	  const struct rlimit new_limit = { coredump_size, coredump_size };
	  if (0 != setrlimit (RLIMIT_CORE, &new_limit))
	    {
	      clib_unix_warning ("prlimit() failed");
	    }
	}
      else if (unformat (input, "full-coredump"))
	{
	  int fd;

	  fd = open ("/proc/self/coredump_filter", O_WRONLY);
	  if (fd >= 0)
	    {
	      if (write (fd, "0x6f\n", 5) != 5)
		clib_unix_warning ("coredump filter write failed!");
	      close (fd);
	    }
	  else
	    clib_unix_warning ("couldn't open /proc/self/coredump_filter");
	}
      else if (unformat (input, "startup-config %s",
			 &um->startup_config_filename))
	;
      else if (unformat (input, "exec %s", &um->startup_config_filename))
	;
      else if (unformat (input, "log %s", &um->log_filename))
	{
	  um->log_fd = open ((char *) um->log_filename,
			     O_CREAT | O_WRONLY | O_APPEND, 0644);
	  if (um->log_fd < 0)
	    {
	      clib_warning ("couldn't open log '%s'\n", um->log_filename);
	      um->log_fd = 0;
	    }
	  else
	    {
	      u8 *lv = 0;
	      lv = format (0, "%U: ***** Start: PID %d *****\n",
			   format_timeval, 0 /* current bat-time */ ,
			   0 /* current bat-format */ ,
			   getpid ());
	      {
		int rv __attribute__ ((unused)) =
		  write (um->log_fd, lv, vec_len (lv));
	      }
	      vec_free (lv);
	    }
	}
      else if (unformat (input, "gid %U", unformat_unix_gid, &gid))
	{
	  if (setegid (gid) == -1)
	    return clib_error_return_unix (0, "setegid");
	}
      else if (unformat (input, "pidfile %s", &um->pidfile))
	;
      else
	return clib_error_return (0, "unknown input `%U'",
				  format_unformat_error, input);
    }

  if (um->runtime_dir == 0)
    {
      uid_t uid = geteuid ();
      if (uid == 00)
	um->runtime_dir = format (0, "/run/%s%c",
				  vlib_default_runtime_dir, 0);
      else
	um->runtime_dir = format (0, "/run/user/%u/%s%c", uid,
				  vlib_default_runtime_dir, 0);
    }

  error = setup_signal_handlers (um);
  if (error)
    return error;

  if (um->pidfile)
    {
      if ((error = vlib_unix_validate_runtime_file (um,
						    (char *) um->pidfile,
						    &um->pidfile)))
	return error;

      if (((pidfd = open ((char *) um->pidfile,
			  O_CREAT | O_WRONLY | O_TRUNC, 0644)) < 0))
	{
	  return clib_error_return_unix (0, "open");
	}
    }

  if (!(um->flags & UNIX_FLAG_INTERACTIVE))
    {
      openlog (vm->name, LOG_CONS | LOG_PERROR | LOG_PID, LOG_DAEMON);
      clib_error_register_handler (unix_error_handler, um);

      if (!(um->flags & UNIX_FLAG_NODAEMON) && daemon ( /* chdir to / */ 0,
						       /* stdin/stdout/stderr -> /dev/null */
						       0) < 0)
	clib_error_return (0, "daemon () fails");
    }

  if (pidfd >= 0)
    {
      u8 *lv = format (0, "%d", getpid ());
      if (write (pidfd, (char *) lv, vec_len (lv)) != vec_len (lv))
	{
	  vec_free (lv);
	  close (pidfd);
	  return clib_error_return_unix (0, "write");
	}
      vec_free (lv);
      close (pidfd);
    }

  um->unix_config_complete = 1;

  return 0;
}
コード例 #30
0
static uword
startup_config_process (vlib_main_t * vm,
			vlib_node_runtime_t * rt, vlib_frame_t * f)
{
  unix_main_t *um = &unix_main;
  u8 *buf = 0;
  uword l, n = 1;

  vlib_process_suspend (vm, 2.0);

  while (um->unix_config_complete == 0)
    vlib_process_suspend (vm, 0.1);

  if (um->startup_config_filename)
    {
      unformat_input_t sub_input;
      int fd;
      struct stat s;
      char *fn = (char *) um->startup_config_filename;

      fd = open (fn, O_RDONLY);
      if (fd < 0)
	{
	  clib_warning ("failed to open `%s'", fn);
	  return 0;
	}

      if (fstat (fd, &s) < 0)
	{
	  clib_warning ("failed to stat `%s'", fn);
	bail:
	  close (fd);
	  return 0;
	}

      if (!(S_ISREG (s.st_mode) || S_ISLNK (s.st_mode)))
	{
	  clib_warning ("not a regular file: `%s'", fn);
	  goto bail;
	}

      while (n > 0)
	{
	  l = vec_len (buf);
	  vec_resize (buf, 4096);
	  n = read (fd, buf + l, 4096);
	  if (n > 0)
	    {
	      _vec_len (buf) = l + n;
	      if (n < 4096)
		break;
	    }
	  else
	    break;
	}
      if (um->log_fd && vec_len (buf))
	{
	  u8 *lv = 0;
	  lv = format (lv, "%U: ***** Startup Config *****\n%v",
		       format_timeval, 0 /* current bat-time */ ,
		       0 /* current bat-format */ ,
		       buf);
	  {
	    int rv __attribute__ ((unused)) =
	      write (um->log_fd, lv, vec_len (lv));
	  }
	  vec_reset_length (lv);
	  lv = format (lv, "%U: ***** End Startup Config *****\n",
		       format_timeval, 0 /* current bat-time */ ,
		       0 /* current bat-format */ );
	  {
	    int rv __attribute__ ((unused)) =
	      write (um->log_fd, lv, vec_len (lv));
	  }
	  vec_free (lv);
	}

      if (vec_len (buf))
	{
	  unformat_init_vector (&sub_input, buf);
	  vlib_cli_input (vm, &sub_input, 0, 0);
	  /* frees buf for us */
	  unformat_free (&sub_input);
	}
      close (fd);
    }
  return 0;
}