blob: 2440295a1a78c318fe42fcb178e0cf1f3b002e37 [file] [log] [blame]
/* Hey Emacs use -*- mode: C -*- */
/*
* Copyright 2020 Rubicon Communications, LLC.
*
* 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 <sys/socket.h>
#include <linux/if.h>
#include <vnet/vnet.h>
#include <vnet/plugin/plugin.h>
#include <vlibapi/api.h>
#include <vlibmemory/api.h>
#include <vpp/app/version.h>
#include <vnet/format_fns.h>
#include <tracedump/graph.h>
#include <tracedump/graph.api_enum.h>
#include <tracedump/graph.api_types.h>
static void graph_node_print (vlib_main_t *vm, vlib_node_t *n, bool want_arcs)
{
vlib_cli_output (vm, "Node (%4d): %v, Flags: 0x%x\n",
n->index, n->name, n->flags);
if (!want_arcs)
return;
int i;
int n_arcs = vec_len (n->next_nodes);
for (i = 0; i < n_arcs; ++i)
{
vlib_cli_output (vm, " next: %d\n", n->next_nodes[i]);
}
}
static int
node_cmp (void *a1, void *a2)
{
vlib_node_t **n1 = a1;
vlib_node_t **n2 = a2;
return vec_cmp (n1[0]->name, n2[0]->name);
}
static clib_error_t *
graph_node_show_cmd (vlib_main_t * vm,
unformat_input_t * input, vlib_cli_command_t * cmd)
{
vlib_node_main_t *nm = &vm->node_main;
vlib_node_t *n;
u32 index;
u8 *name;
u32 flags;
bool want_arcs;
index = ~0;
name = 0;
flags = 0;
want_arcs = false;
n = 0;
while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
{
if (unformat (input, "node %d", &index))
n = vlib_get_node (vm, index);
else if (unformat (input, "node %v", &name))
n = vlib_get_node_by_name (vm, name);
else if (unformat (input, "want_arcs"))
want_arcs = true;
else if (unformat (input, "trace_supported"))
flags |= NODE_FLAG_TRACE_SUPPORTED;
else if (unformat (input, "input"))
flags |= NODE_FLAG_TRACE_SUPPORTED;
else if (unformat (input, "drop"))
flags |= NODE_FLAG_IS_DROP;
else if (unformat (input, "output"))
flags |= NODE_FLAG_IS_OUTPUT;
else if (unformat (input, "punt"))
flags |= NODE_FLAG_IS_PUNT;
else if (unformat (input, "handoff"))
flags |= NODE_FLAG_IS_HANDOFF;
else if (unformat (input, "no_free"))
flags |= NODE_FLAG_FRAME_NO_FREE_AFTER_DISPATCH;
else if (unformat (input, "polling"))
flags |= NODE_FLAG_SWITCH_FROM_INTERRUPT_TO_POLLING_MODE;
else if (unformat (input, "interrupt"))
flags |= NODE_FLAG_SWITCH_FROM_POLLING_TO_INTERRUPT_MODE;
else
return clib_error_return (0, "unknown input '%U'",
format_unformat_error, input);
}
/*
* Just one node requested? Ignore flags.
*/
if (n) {
graph_node_print (vm, n, want_arcs);
return 0;
}
vlib_node_t **nodes = vec_dup (nm->nodes);
uword i;
vec_sort_with_function (nodes, node_cmp);
for (i = 0; i < vec_len (nodes); ++i)
{
if (flags == 0 || (flags & nodes[i]->flags))
{
graph_node_print (vm, nodes[i], want_arcs);
}
}
vec_free (nodes);
return 0;
}
/* *INDENT-OFF* */
VLIB_CLI_COMMAND (graph_node_show_command, static) = {
.path = "show graph",
.short_help = "show graph [node <index>|<name>] [want_arcs] [input|trace_supported] [drop] [output] [punt] [handoff] [no_free] [polling] [interrupt]",
.function = graph_node_show_cmd,
};
/* *INDENT-ON* */
/*
* Local Variables:
* eval: (c-set-style "gnu")
* End:
*/