Пример #1
0
void
vl_msg_api_send_shmem_nolock (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]);

  (void) svm_queue_add_nolock (q, elem);
}
Пример #2
0
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);
}
Пример #3
0
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 */ );
}
Пример #4
0
/* 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 */ );
}