summaryrefslogtreecommitdiffstats
path: root/vlib-api/vlibapi
diff options
context:
space:
mode:
authorDave Barach <dave@barachs.net>2016-02-19 09:06:23 -0500
committerDave Barach <dave@barachs.net>2016-02-19 09:06:46 -0500
commitb44e9bc90b634b07d5f93a731a95028adc73bcbc (patch)
treeba6477830970b8cb663ad2c393cdca778418fb13 /vlib-api/vlibapi
parentc07bf5d5032e2b3ed4a651c8e6b8ff2131bc79c6 (diff)
Serialize and upload the data plane node graph
Include node names and graph arcs. Prep work for uploading node runtime data, so the latter can be reported in a comprehensible manner. Change-Id: I215b1f8cff244200c37c7e088f1f22229dc97eb6 Signed-off-by: Dave Barach <dave@barachs.net>
Diffstat (limited to 'vlib-api/vlibapi')
-rw-r--r--vlib-api/vlibapi/api.h4
-rw-r--r--vlib-api/vlibapi/node_serialize.c141
2 files changed, 145 insertions, 0 deletions
diff --git a/vlib-api/vlibapi/api.h b/vlib-api/vlibapi/api.h
index f620d950d8e..1f45a05738c 100644
--- a/vlib-api/vlibapi/api.h
+++ b/vlib-api/vlibapi/api.h
@@ -215,6 +215,10 @@ int vl_msg_api_pd_handler (void *mp, int rv);
void vl_msg_api_set_first_available_msg_id (u16 first_avail);
u16 vl_msg_api_get_msg_ids (char * name, int n);
+/* node_serialize.c prototypes */
+u8 * vlib_node_serialize (vlib_node_main_t *nm, u8 * vector);
+vlib_node_t ** vlib_node_unserialize (u8 * vector);
+
#define VLIB_API_INIT_FUNCTION(x) VLIB_DECLARE_INIT_FUNCTION(x,api_init)
#endif /* included_api_h */
diff --git a/vlib-api/vlibapi/node_serialize.c b/vlib-api/vlibapi/node_serialize.c
new file mode 100644
index 00000000000..d4fbd502398
--- /dev/null
+++ b/vlib-api/vlibapi/node_serialize.c
@@ -0,0 +1,141 @@
+/*
+ * 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>
+
+/*
+ * 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_node_main_t *nm, u8 * vector)
+{
+ serialize_main_t _sm, *sm=&_sm;
+ vlib_node_t * node;
+ int i, j;
+ u8 * cstemp = 0;
+
+ serialize_open_vector (sm, vector);
+
+ serialize_likely_small_unsigned_integer (sm, vec_len(nm->nodes));
+ for (i = 0; i < vec_len (nm->nodes); i++)
+ {
+ node = nm->nodes[i];
+ vec_reset_length (cstemp);
+ cstemp = vec_dup(node->name);
+ vec_add1(cstemp, 0);
+ serialize_cstring (sm, (char *)cstemp);
+ serialize_likely_small_unsigned_integer (sm, vec_len(node->next_nodes));
+ for (j = 0; j < vec_len (node->next_nodes); j++)
+ serialize_likely_small_unsigned_integer (sm, node->next_nodes[j]);
+ }
+ vec_free(cstemp);
+
+ return (serialize_close_vector (sm));
+}
+
+vlib_node_t ** vlib_node_unserialize (u8 * vector)
+{
+ serialize_main_t _sm, *sm=&_sm;
+ u32 nnodes, nnexts;
+ vlib_node_t * node;
+ vlib_node_t ** nodes = 0;
+ int i, j;
+
+ serialize_open_vector (sm, vector);
+
+ nnodes = unserialize_likely_small_unsigned_integer (sm);
+
+ vec_validate (nodes, nnodes-1);
+
+ for (i = 0; i < nnodes; i++)
+ {
+ node = 0;
+ vec_validate (node,0);
+ nodes[i] = node;
+ unserialize_cstring (sm, (char **)&node->name);
+
+ nnexts = unserialize_likely_small_unsigned_integer (sm);
+ if (nnexts > 0)
+ vec_validate (node->next_nodes, nnexts-1);
+ for (j = 0; j < vec_len (node->next_nodes); j++)
+ node->next_nodes[j] =
+ unserialize_likely_small_unsigned_integer (sm);
+ }
+ return nodes;
+}
+
+
+#if CLIB_DEBUG > 0
+
+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;
+ vlib_node_t * node;
+ vlib_node_t * next_node;
+ int i, j;
+
+ /*
+ * 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, 4095);
+ vec_reset_length (vector);
+
+ vector = vlib_node_serialize (nm, vector);
+
+ nodes = vlib_node_unserialize (vector);
+
+ vec_free (vector);
+
+ for (i = 0; i < vec_len(nodes); i++)
+ {
+ node = nodes[i];
+
+ vlib_cli_output (vm, "[%d] %s", i, node->name);
+ for (j = 0; j < vec_len (node->next_nodes); j++)
+ {
+ if (node->next_nodes[j] != ~0)
+ next_node = nodes[node->next_nodes[j]];
+ vlib_cli_output (vm, " [%d] %s", j, next_node->name);
+ }
+ }
+
+ 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);
+
+ return 0;
+}
+
+VLIB_CLI_COMMAND (test_node_serialize_node, static) = {
+ .path = "test node serialize",
+ .short_help = "test node serialize",
+ .function = test_node_serialize_command_fn,
+};
+#endif