aboutsummaryrefslogtreecommitdiffstats
path: root/src/vnet/pg/input.c
AgeCommit message (Collapse)AuthorFilesLines
2018-07-19Cleanup of handoff codeDamjan Marion1-3/+0
- removed handoff-dispatch node - removed some unused buffer metadata fields - enqueue to thread logic moved to inline function Change-Id: I7361e1d88f8cce74cd4fcec90d172eade1855cbd Signed-off-by: Damjan Marion <damarion@cisco.com>
2018-05-17Packet generator: preserve pcap file timestampsDave Barach1-0/+1
Set vnet_buffer2(b0)->pg_replay_timestamp, for use when desired. Fix a memory leak in pg_stream_free(...), which wasn't freeing the replay packet templates. Change-Id: I01822a9e91a52de4774d2b95cf0c2ee254a915e9 Signed-off-by: Dave Barach <dave@barachs.net>
2018-04-27A bit of buffer metadata reshuffling to accommodate flow_idDamjan Marion1-1/+1
Change-Id: I2794384557c6272fe217269b14a9db09eda19220 Signed-off-by: Damjan Marion <damarion@cisco.com>
2018-03-07packet-generator: use default free listDamjan Marion1-46/+6
Change-Id: I2a34546f9b32edc9bfb86b5492dde34aaef49ccc Signed-off-by: Damjan Marion <damarion@cisco.com>
2017-11-21dpdk: add l2_hdr_offset and l3_hdr_offset in vlib_buffer_tDamjan Marion1-2/+2
Change-Id: I0a6d1257e391c3b6f7da6498bd5f7d4c545d17e9 Signed-off-by: Damjan Marion <damarion@cisco.com>
2017-10-04[aarch64] Fixes CLI crashes on dpaa2 platform.Christophe Fontaine1-1/+1
- always use 'va_args' as pointer in all format_* functions - u32 for all 'indent' params as it's declaration was inconsistent Change-Id: Ic5799309a6b104c9b50fec309cba789c8da99e79 Signed-off-by: Christophe Fontaine <christophe.fontaine@enea.com>
2017-07-10vlib: store buffer memory information in the buffer_mainDamjan Marion1-3/+3
Currently, buffer index is calculated as a offset to the physmem region shifted by log2_cacheline size. When DPDK is used we "hack" physmem data with information taken from dpdk mempool. This makes physmem code not usable with DPDK. This change makes buffer memory start and size independent of physmem basically allowing physmem to be used when DPDK plugin is loaded. Change-Id: Ieb399d398f147583b9baab467152a352d58c9c31 Signed-off-by: Damjan Marion <damarion@cisco.com>
2017-04-06Use thread local storage for thread indexDamjan Marion1-2/+2
This patch deprecates stack-based thread identification, Also removes requirement that thread stacks are adjacent. Finally, possibly annoying for some folks, it renames all occurences of cpu_index and cpu_number with thread index. Using word "cpu" is misleading here as thread can be migrated ti different CPU, and also it is not related to linux cpu index. Change-Id: I68cdaf661e701d2336fc953dcb9978d10a70f7c1 Signed-off-by: Damjan Marion <damarion@cisco.com>
2017-03-07DHCP Multiple Servers (VPP-602, VPP-605)Neale Ranns1-0/+6
Multiple DHCP (4 and/or 6) servers can be added and removed through multiple calls to the 'set dhcp server' API. All 4/6/ discover/solicit messages will then be replicated to all servers in the list. The expectation is that the servers/system is configured in such a way that this is viable. If VSS information is providied for the clinet VRF which also has multiple servers configured, then the same VSS information is sent to each server. Likewise the source address of packets sent to from VPP to each server is the same. Change-Id: I3287cb084c84b3f612b78bc69cfcb5b9c1f8934d Signed-off-by: Neale Ranns <nranns@cisco.com>
2017-03-01dpdk: be a pluginDamjan Marion1-5/+6
Change-Id: I238258cdeb77035adc5e88903d824593d0a1da90 Signed-off-by: Damjan Marion <damarion@cisco.com>
2016-12-28Reorganize source tree to use single autotools instanceDamjan Marion1-0/+1667
Change-Id: I7b51f88292e057c6443b12224486f2d0c9f8ae23 Signed-off-by: Damjan Marion <damarion@cisco.com>
Generic.Emph */ .highlight .gi { color: #a6e22e } /* Generic.Inserted */ .highlight .gs { font-weight: bold } /* Generic.Strong */ .highlight .gu { color: #75715e } /* Generic.Subheading */ .highlight .kc { color: #66d9ef } /* Keyword.Constant */ .highlight .kd { color: #66d9ef } /* Keyword.Declaration */ .highlight .kn { color: #f92672 } /* Keyword.Namespace */ .highlight .kp { color: #66d9ef } /* Keyword.Pseudo */ .highlight .kr { color: #66d9ef } /* Keyword.Reserved */ .highlight .kt { color: #66d9ef } /* Keyword.Type */ .highlight .ld { color: #e6db74 } /* Literal.Date */ .highlight .m { color: #ae81ff } /* Literal.Number */ .highlight .s { color: #e6db74 } /* Literal.String */ .highlight .na { color: #a6e22e } /* Name.Attribute */ .highlight .nb { color: #f8f8f2 } /* Name.Builtin */ .highlight .nc { color: #a6e22e } /* Name.Class */ .highlight .no { color: #66d9ef } /* Name.Constant */ .highlight .nd { color: #a6e22e } /* Name.Decorator */ .highlight .ni { color: #f8f8f2 } /* Name.Entity */ .highlight .ne { color: #a6e22e } /* Name.Exception */ .highlight .nf { color: #a6e22e } /* Name.Function */ .highlight .nl { color: #f8f8f2 } /* Name.Label */ .highlight .nn { color: #f8f8f2 } /* Name.Namespace */ .highlight .nx { color: #a6e22e } /* Name.Other */ .highlight .py { color: #f8f8f2 } /* Name.Property */ .highlight .nt { color: #f92672 } /* Name.Tag */ .highlight .nv { color: #f8f8f2 } /* Name.Variable */ .highlight .ow { color: #f92672 } /* Operator.Word */ .highlight .w { color: #f8f8f2 } /* Text.Whitespace */ .highlight .mb { color: #ae81ff } /* Literal.Number.Bin */ .highlight .mf { color: #ae81ff } /* Literal.Number.Float */ .highlight .mh { color: #ae81ff } /* Literal.Number.Hex */ .highlight .mi { color: #ae81ff } /* Literal.Number.Integer */ .highlight .mo { color: #ae81ff } /* Literal.Number.Oct */ .highlight .sa { color: #e6db74 } /* Literal.String.Affix */ .highlight .sb { color: #e6db74 } /* Literal.String.Backtick */ .highlight .sc { color: #e6db74 } /* Literal.String.Char */ .highlight .dl { color: #e6db74 } /* Literal.String.Delimiter */ .highlight .sd { color: #e6db74 } /* Literal.String.Doc */ .highlight .s2 { color: #e6db74 } /* Literal.String.Double */ .highlight .se { color: #ae81ff } /* Literal.String.Escape */ .highlight .sh { color: #e6db74 } /* Literal.String.Heredoc */ .highlight .si { color: #e6db74 } /* Literal.String.Interpol */ .highlight .sx { color: #e6db74 } /* Literal.String.Other */ .highlight .sr { color: #e6db74 } /* Literal.String.Regex */ .highlight .s1 { color: #e6db74 } /* Literal.String.Single */ .highlight .ss { color: #e6db74 } /* Literal.String.Symbol */ .highlight .bp { color: #f8f8f2 } /* Name.Builtin.Pseudo */ .highlight .fm { color: #a6e22e } /* Name.Function.Magic */ .highlight .vc { color: #f8f8f2 } /* Name.Variable.Class */ .highlight .vg { color: #f8f8f2 } /* Name.Variable.Global */ .highlight .vi { color: #f8f8f2 } /* Name.Variable.Instance */ .highlight .vm { color: #f8f8f2 } /* Name.Variable.Magic */ .highlight .il { color: #ae81ff } /* Literal.Number.Integer.Long */ } @media (prefers-color-scheme: light) { .highlight .hll { background-color: #ffffcc } .highlight .c { color: #888888 } /* Comment */ .highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */ .highlight .k { color: #008800; font-weight: bold } /* Keyword */ .highlight .ch { color: #888888 } /* Comment.Hashbang */ .highlight .cm { color: #888888 } /* Comment.Multiline */ .highlight .cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */ .highlight .cpf { color: #888888 } /* Comment.PreprocFile */ .highlight .c1 { color: #888888 } /* Comment.Single */ .highlight .cs { color: #cc0000; font-weight: bold; background-color: #fff0f0 } /* Comment.Special */ .highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */ .highlight .ge { font-style: italic } /* Generic.Emph */ .highlight .gr { color: #aa0000 } /* Generic.Error */ .highlight .gh { color: #333333 } /* Generic.Heading */ .highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */ .highlight .go { color: #888888 } /* Generic.Output */ .highlight .gp { color: #555555 } /* Generic.Prompt */ .highlight .gs { font-weight: bold } /* Generic.Strong */ .highlight .gu { color: #666666 } /* Generic.Subheading */ .highlight .gt { color: #aa0000 } /* Generic.Traceback */ .highlight .kc { color: #008800; font-weight: bold } /* Keyword.Constant */ .highlight .kd { color: #008800; font-weight: bold } /* Keyword.Declaration */ .highlight .kn { color: #008800; font-weight: bold } /* Keyword.Namespace */ .highlight .kp { color: #008800 } /* Keyword.Pseudo */ .highlight .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */ .highlight .kt { color: #888888; font-weight: bold } /* Keyword.Type */ .highlight .m { color: #0000DD; font-weight: bold } /* Literal.Number */ .highlight .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */ .highlight .na { color: #336699 } /* Name.Attribute */ .highlight .nb { color: #003388 } /* Name.Builtin */ .highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */ .highlight .no { color: #003366; font-weight: bold } /* Name.Constant */ .highlight .nd { color: #555555 } /* Name.Decorator */ .highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */ .highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */ .highlight .nl { color: #336699; font-style: italic } /* Name.Label */ .highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */ .highlight .py { color: #336699; font-weight: bold } /* Name.Property */ .highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */ .highlight .nv { color: #336699 } /* Name.Variable */ .highlight .ow { color: #008800 } /* Operator.Word */ .highlight .w { color: #bbbbbb } /* Text.Whitespace */ .highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */ .highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */ .highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */ .highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */ .highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */ .highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */ .highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */ .highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */ .highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */ .highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */ .highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */ .highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */ .highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */ .highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */ .highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */ .highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */ .highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */ .highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */ .highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */ .highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */ .highlight .vc { color: #336699 } /* Name.Variable.Class */ .highlight .vg { color: #dd7700 } /* Name.Variable.Global */ .highlight .vi { color: #3333bb } /* Name.Variable.Instance */ .highlight .vm { color: #336699 } /* Name.Variable.Magic */ .highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */ }
/*
 * Copyright (c) 2016 Cisco and/or its affiliates.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at:
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#include <vlib/vlib.h>

#include <vppinfra/serialize.h>

/* serialized representation of state strings */

#define foreach_state_string_code               \
_(STATE_DONE, "done")                           \
_(STATE_DISABLED, "disabled")                   \
_(STATE_TIME_WAIT, "time wait")                 \
_(STATE_EVENT_WAIT, "event wait")               \
_(STATE_ANY_WAIT, "any wait")                   \
_(STATE_POLLING, "polling")                     \
_(STATE_INTERRUPT_WAIT, "interrupt wait")       \
_(STATE_INTERNAL, "internal")

typedef enum
{
#define _(a,b) a,
  foreach_state_string_code
#undef _
} state_string_enum_t;

static char *state_strings[] = {
#define _(a,b) b,
  foreach_state_string_code
#undef _
};

/*
 * Serialize a vlib_node_main_t. Appends the result to vector.
 * Pass 0 to create a new vector, use vec_reset_length(vector)
 * to recycle a vector / avoid memory allocation, etc.
 * Switch heaps before/after to serialize into API client shared memory.
 */
u8 *
vlib_node_serialize (vlib_main_t * vm, vlib_node_t *** node_dups, u8 * vector,
		     int include_nexts, int include_stats)
{
  serialize_main_t _sm, *sm = &_sm;
  vlib_node_t *n;
  vlib_node_t **nodes;
  u8 *namep;
  u32 name_bytes;
  uword i, j, k;
  u64 l, v, c, d;
  state_string_enum_t state_code;

  serialize_open_vector (sm, vector);
  serialize_likely_small_unsigned_integer (sm, vec_len (node_dups));

  for (j = 0; j < vec_len (node_dups); j++)
    {
      nodes = node_dups[j];

      serialize_likely_small_unsigned_integer (sm, vec_len (nodes));

      for (i = 0; i < vec_len (nodes); i++)
	{
	  n = nodes[i];

	  l = n->stats_total.clocks - n->stats_last_clear.clocks;
	  v = n->stats_total.vectors - n->stats_last_clear.vectors;
	  c = n->stats_total.calls - n->stats_last_clear.calls;
	  d = n->stats_total.suspends - n->stats_last_clear.suspends;

	  state_code = STATE_INTERNAL;

	  if (n->type == VLIB_NODE_TYPE_PROCESS)
	    {
	      vlib_process_t *p = vlib_get_process_from_node (vm, n);

	      switch (p->flags
		      & (VLIB_PROCESS_IS_SUSPENDED_WAITING_FOR_CLOCK
			 | VLIB_PROCESS_IS_SUSPENDED_WAITING_FOR_EVENT))
		{
		default:
		  if (!(p->flags & VLIB_PROCESS_IS_RUNNING))
		    state_code = STATE_DONE;
		  break;

		case VLIB_PROCESS_IS_SUSPENDED_WAITING_FOR_CLOCK:
		  state_code = STATE_TIME_WAIT;
		  break;

		case VLIB_PROCESS_IS_SUSPENDED_WAITING_FOR_EVENT:
		  state_code = STATE_EVENT_WAIT;
		  break;

		case (VLIB_PROCESS_IS_SUSPENDED_WAITING_FOR_EVENT | VLIB_PROCESS_IS_SUSPENDED_WAITING_FOR_CLOCK):
		  state_code =
		    STATE_ANY_WAIT;
		  break;
		}
	    }
	  else if (n->type != VLIB_NODE_TYPE_INTERNAL)
	    {
	      state_code = STATE_POLLING;
	      if (n->state == VLIB_NODE_STATE_DISABLED)
		state_code = STATE_DISABLED;
	      else if (n->state == VLIB_NODE_STATE_INTERRUPT)
		state_code = STATE_INTERRUPT_WAIT;
	    }

	  /* See unserialize_cstring */
	  name_bytes = vec_len (n->name);
	  serialize_likely_small_unsigned_integer (sm, name_bytes);
	  namep = serialize_get (sm, name_bytes);
	  memcpy (namep, n->name, name_bytes);

	  serialize_likely_small_unsigned_integer (sm, (u64) state_code);
	  serialize_likely_small_unsigned_integer (sm, n->type);

	  if (include_nexts)
	    {
	      serialize_likely_small_unsigned_integer
		(sm, vec_len (n->next_nodes));
	      for (k = 0; k < vec_len (n->next_nodes); k++)
		serialize_likely_small_unsigned_integer (sm,
							 n->next_nodes[k]);
	    }
	  else
	    serialize_likely_small_unsigned_integer (sm, 0);

	  if (include_stats)
	    {
	      /* stats present */
	      serialize_likely_small_unsigned_integer (sm, 1);
	      /* total clocks */
	      serialize_integer (sm, l, 8);
	      /* Total calls */
	      serialize_integer (sm, c, 8);
	      /* Total vectors */
	      serialize_integer (sm, v, 8);
	      /* Total suspends */
	      serialize_integer (sm, d, 8);
	    }
	  else			/* no stats */
	    serialize_likely_small_unsigned_integer (sm, 0);
	}
      vec_free (nodes);
    }
  return (serialize_close_vector (sm));
}

vlib_node_t ***
vlib_node_unserialize (u8 * vector)
{
  serialize_main_t _sm, *sm = &_sm;
  u32 nnodes, nnexts;
  u32 nstat_vms;
  vlib_node_t *node;
  vlib_node_t **nodes;
  vlib_node_t ***nodes_by_thread = 0;
  int i, j, k;
  u64 l, v, c, d;
  state_string_enum_t state_code;
  int stats_present;

  serialize_open_vector (sm, vector);

  nstat_vms = unserialize_likely_small_unsigned_integer (sm);

  vec_validate (nodes_by_thread, nstat_vms - 1);
  _vec_len (nodes_by_thread) = 0;

  for (i = 0; i < nstat_vms; i++)
    {
      nnodes = unserialize_likely_small_unsigned_integer (sm);

      nodes = 0;
      vec_validate (nodes, nnodes - 1);
      vec_add1 (nodes_by_thread, nodes);

      for (j = 0; j < nnodes; j++)
	{
	  node = 0;
	  vec_validate (node, 0);
	  nodes[j] = node;

	  unserialize_cstring (sm, (char **) &(node->name));
	  state_code = unserialize_likely_small_unsigned_integer (sm);
	  node->state_string = (u8 *) state_strings[state_code];

	  node->type = unserialize_likely_small_unsigned_integer (sm);
	  nnexts = unserialize_likely_small_unsigned_integer (sm);
	  if (nnexts > 0)
	    vec_validate (node->next_nodes, nnexts - 1);
	  for (k = 0; k < nnexts; k++)
	    node->next_nodes[k] =
	      unserialize_likely_small_unsigned_integer (sm);

	  stats_present = unserialize_likely_small_unsigned_integer (sm);

	  if (stats_present)
	    {
	      /* total clocks */
	      unserialize_integer (sm, &l, 8);
	      node->stats_total.clocks = l;
	      node->stats_last_clear.clocks = 0;

	      /* Total calls */
	      unserialize_integer (sm, &c, 8);
	      node->stats_total.calls = c;

	      /* Total vectors */
	      unserialize_integer (sm, &v, 8);
	      node->stats_total.vectors = v;

	      /* Total suspends */
	      unserialize_integer (sm, &d, 8);
	      node->stats_total.suspends = d;
	    }
	}
    }
  return nodes_by_thread;
}

#if TEST_CODE

static clib_error_t *
test_node_serialize_command_fn (vlib_main_t * vm,
				unformat_input_t * input,
				vlib_cli_command_t * cmd)
{
  vlib_node_main_t *nm = &vm->node_main;
  u8 *vector = 0;
  vlib_node_t ***nodes_by_thread;
  vlib_node_t **nodes;
  vlib_node_t *node;
  vlib_node_t *next_node;
  int i, j, k;
  u32 max_threads = (u32) ~ 0;
  int include_nexts = 0;
  int include_stats = 0;

  while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
    {
      if (unformat (input, "max-threads %d", &max_threads))
	;
      else if (unformat (input, "stats"))
	include_stats = 1;
      else if (unformat (input, "nexts"))
	include_nexts = 1;
      else
	break;
    }

  /*
   * Keep the number of memcpy ops to a minimum (e.g. 1).
   * The current size of the serialized vector is
   * slightly under 4K.
   */
  vec_validate (vector, 16383);
  vec_reset_length (vector);

  vector = vlib_node_serialize (nm, vector, max_threads,
				include_nexts, include_stats);

  vlib_cli_output (vm, "result vector %d bytes", vec_len (vector));

  nodes_by_thread = vlib_node_unserialize (vector);

  vec_free (vector);

  for (i = 0; i < vec_len (nodes_by_thread); i++)
    {
      nodes = nodes_by_thread[i];

      vlib_cli_output (vm, "thread %d", i);

      for (j = 0; j < vec_len (nodes); j++)
	{
	  node = nodes[j];

	  vlib_cli_output (vm, "[%d] %s state %s", j, node->name,
			   node->state_string);

	  vlib_cli_output
	    (vm, "    clocks %lld calls %lld suspends"
	     " %lld vectors %lld",
	     node->stats_total.clocks,
	     node->stats_total.calls,
	     node->stats_total.suspends, node->stats_total.vectors);

	  for (k = 0; k < vec_len (node->next_nodes); k++)
	    {
	      if (node->next_nodes[k] != ~0)
		{
		  next_node = nodes[node->next_nodes[k]];
		  vlib_cli_output (vm, "  [%d] %s", k, next_node->name);
		}
	    }
	}
    }

  for (j = 0; j < vec_len (nodes_by_thread); j++)
    {
      nodes = nodes_by_thread[j];

      for (i = 0; i < vec_len (nodes); i++)
	{
	  vec_free (nodes[i]->name);
	  vec_free (nodes[i]->next_nodes);
	  vec_free (nodes[i]);
	}
      vec_free (nodes);
    }
  vec_free (nodes_by_thread);

  return 0;
}

/* *INDENT-OFF* */
VLIB_CLI_COMMAND (test_node_serialize_node, static) = {
    .path = "test node serialize",
    .short_help = "test node serialize [max-threads NN] nexts stats",
    .function = test_node_serialize_command_fn,
};
/* *INDENT-ON* */
#endif

/*
 * fd.io coding-style-patch-verification: ON
 *
 * Local Variables:
 * eval: (c-set-style "gnu")
 * End:
 */