feature: Add packet trace API
[vpp.git] / src / plugins / tracedump / graph_cli.c
1 /* Hey Emacs use -*- mode: C -*- */
2 /*
3  * Copyright 2020 Rubicon Communications, LLC.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at:
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17
18 #include <sys/socket.h>
19 #include <linux/if.h>
20
21 #include <vnet/vnet.h>
22 #include <vnet/plugin/plugin.h>
23
24 #include <vlibapi/api.h>
25 #include <vlibmemory/api.h>
26 #include <vpp/app/version.h>
27 #include <vnet/format_fns.h>
28
29 #include <tracedump/graph.h>
30 #include <tracedump/graph.api_enum.h>
31 #include <tracedump/graph.api_types.h>
32
33 static void graph_node_print (vlib_main_t *vm, vlib_node_t *n, bool want_arcs)
34 {
35   vlib_cli_output (vm, "Node (%4d): %v, Flags: 0x%x\n",
36                    n->index, n->name, n->flags);
37   if (!want_arcs)
38     return;
39
40   int i;
41   int n_arcs = vec_len (n->next_nodes);
42   for (i = 0; i < n_arcs; ++i)
43     {
44       vlib_cli_output (vm, "    next: %d\n", n->next_nodes[i]);
45     }
46 }
47
48
49 static int
50 node_cmp (void *a1, void *a2)
51 {
52   vlib_node_t **n1 = a1;
53   vlib_node_t **n2 = a2;
54
55   return vec_cmp (n1[0]->name, n2[0]->name);
56 }
57
58 static clib_error_t *
59 graph_node_show_cmd (vlib_main_t * vm,
60                      unformat_input_t * input, vlib_cli_command_t * cmd)
61 {
62   vlib_node_main_t *nm = &vm->node_main;
63   vlib_node_t *n;
64   u32 index;
65   u8 *name;
66   u32 flags;
67   bool want_arcs;
68
69   index = ~0;
70   name = 0;
71   flags = 0;
72   want_arcs = false;
73   n = 0;
74
75   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
76     {
77       if (unformat (input, "node %d", &index))
78           n = vlib_get_node (vm, index);
79       else if (unformat (input, "node %v", &name))
80           n = vlib_get_node_by_name (vm, name);
81
82       else if (unformat (input, "want_arcs"))
83         want_arcs = true;
84
85       else if (unformat (input, "trace_supported"))
86         flags |= NODE_FLAG_TRACE_SUPPORTED;
87       else if (unformat (input, "input"))
88         flags |= NODE_FLAG_TRACE_SUPPORTED;
89       else if (unformat (input, "drop"))
90         flags |= NODE_FLAG_IS_DROP;
91       else if (unformat (input, "output"))
92         flags |= NODE_FLAG_IS_OUTPUT;
93       else if (unformat (input, "punt"))
94         flags |= NODE_FLAG_IS_PUNT;
95       else if (unformat (input, "handoff"))
96         flags |= NODE_FLAG_IS_HANDOFF;
97       else if (unformat (input, "no_free"))
98         flags |= NODE_FLAG_FRAME_NO_FREE_AFTER_DISPATCH;
99       else if (unformat (input, "polling"))
100         flags |= NODE_FLAG_SWITCH_FROM_INTERRUPT_TO_POLLING_MODE;
101       else if (unformat (input, "interrupt"))
102         flags |= NODE_FLAG_SWITCH_FROM_POLLING_TO_INTERRUPT_MODE;
103
104       else
105         return clib_error_return (0, "unknown input '%U'",
106                                   format_unformat_error, input);
107     }
108
109   /*
110    * Just one node requested?  Ignore flags.
111    */
112   if (n) {
113     graph_node_print (vm, n, want_arcs);
114     return 0;
115   }
116
117   vlib_node_t **nodes = vec_dup (nm->nodes);
118   uword i;
119
120   vec_sort_with_function (nodes, node_cmp);
121
122   for (i = 0; i < vec_len (nodes); ++i)
123     {
124       if (flags == 0 || (flags & nodes[i]->flags))
125         {
126           graph_node_print (vm, nodes[i], want_arcs);
127         }
128     }
129
130   vec_free (nodes);
131
132   return 0;
133 }
134
135 /* *INDENT-OFF* */
136 VLIB_CLI_COMMAND (graph_node_show_command, static) = {
137   .path = "show graph",
138   .short_help = "show graph [node <index>|<name>] [want_arcs] [input|trace_supported] [drop] [output] [punt] [handoff] [no_free] [polling] [interrupt]",
139   .function = graph_node_show_cmd,
140 };
141 /* *INDENT-ON* */
142
143
144 /*
145  * Local Variables:
146  * eval: (c-set-style "gnu")
147  * End:
148  */