api: API trace improvements
[vpp.git] / src / plugins / tracedump / tracedump_test.c
1 /*
2  * tracedump.c - tracedump vpp-api-test plug-in
3  *
4  * Copyright (c) <current-year> <your-organization>
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 #include <vat/vat.h>
18 #include <vlibapi/api.h>
19 #include <vlibmemory/api.h>
20 #include <vppinfra/error.h>
21 #include <vnet/api_errno.h>
22 #include <stdbool.h>
23
24 #define __plugin_msg_base tracedump_test_main.msg_id_base
25 #include <vlibapi/vat_helper_macros.h>
26
27 /* Declare message IDs */
28 #include <tracedump/tracedump.api_enum.h>
29 #include <tracedump/tracedump.api_types.h>
30
31 typedef struct
32 {
33   /* API message ID base */
34   u16 msg_id_base;
35   vat_main_t *vat_main;
36 } tracedump_test_main_t;
37
38 tracedump_test_main_t tracedump_test_main;
39
40
41 int
42 api_trace_set_filters (vat_main_t * vam)
43 {
44   unformat_input_t *i = vam->input;
45   vl_api_trace_set_filters_t *mp;
46   u32 flag;
47   u32 count;
48   u32 node_index;
49   u32 classifier;
50
51   flag = TRACE_FF_NONE;
52   count = 50;
53   node_index = ~0;
54   classifier = ~0;
55
56   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
57     {
58       if (unformat (i, "none"))
59         flag = TRACE_FF_NONE;
60       else if (unformat (i, "include_node %u", &node_index))
61         flag = TRACE_FF_INCLUDE_NODE;
62       else if (unformat (i, "exclude_node %u", &node_index))
63         flag = TRACE_FF_EXCLUDE_NODE;
64       else if (unformat (i, "include_classifier %u", &classifier))
65         flag = TRACE_FF_INCLUDE_CLASSIFIER;
66       else if (unformat (i, "exclude_classifier %u", &classifier))
67         flag = TRACE_FF_EXCLUDE_CLASSIFIER;
68       else if (unformat (i, "count %u", &count))
69         ;
70       else
71         {
72           clib_warning ("Unknown input: %U\n", format_unformat_error, i);
73           return -99;
74         }
75     }
76
77   M (TRACE_SET_FILTERS, mp);
78   mp->flag = htonl (flag);
79   mp->node_index = htonl (node_index);
80   mp->count = htonl (count);
81   mp->classifier_table_index = htonl (classifier);
82
83   int ret = 0;
84   S (mp);
85   W (ret);
86
87   return ret;
88 }
89
90
91 int
92 api_trace_capture_packets (vat_main_t * vam)
93 {
94   unformat_input_t *i = vam->input;
95   vl_api_trace_capture_packets_t *mp;
96   u32 node_index;
97   u32 max;
98   bool pre_capture_clear;
99   bool use_filter;
100   bool verbose;
101
102   node_index = ~0;
103   max = 50;
104   pre_capture_clear = use_filter = verbose = false;
105
106   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
107     {
108       if (unformat (i, "node_index %u", &node_index))
109         ;
110       else if (unformat (i, "max %u", &max))
111         ;
112       else if (unformat (i, "pre_capture_clear"))
113         pre_capture_clear = false;
114       else if (unformat (i, "use_filter"))
115         use_filter = false;
116       else if (unformat (i, "verbose"))
117         verbose = false;
118       else
119         {
120           clib_warning ("Unknown input: %U\n", format_unformat_error, i);
121           return -99;
122         }
123     }
124
125   M (TRACE_CAPTURE_PACKETS, mp);
126   mp->node_index = htonl (node_index);
127   mp->max_packets = htonl (max);
128   mp->use_filter = use_filter;
129   mp->verbose = verbose;
130   mp->pre_capture_clear = pre_capture_clear;
131
132   int ret = 0;
133   S (mp);
134   W (ret);
135
136   return ret;
137 }
138
139
140 static void
141 vl_api_trace_details_t_handler (vl_api_trace_details_t * dmp)
142 {
143   u32 packet_number;
144   u32 thread_id, position;
145
146   thread_id = clib_net_to_host_u32 (dmp->thread_id);
147   position = clib_net_to_host_u32 (dmp->position);
148   packet_number = clib_net_to_host_u32 (dmp->packet_number);
149   fformat
150     (stdout,
151      "thread %d position %d more_this_thread %d more_threads %d done %d\n",
152      thread_id, position, (u32) dmp->more_this_thread,
153      (u32) dmp->more_threads, (u32) dmp->done);
154   fformat (stdout, "Packet %d\n%U\n\n",
155            packet_number, vl_api_format_string, (&dmp->trace_data));
156 }
157
158
159 static void
160 vl_api_trace_dump_reply_t_handler (vl_api_trace_dump_reply_t * rmp)
161 {
162   tracedump_test_main_t *ttm = &tracedump_test_main;
163   vat_main_t *vam = ttm->vat_main;
164   vl_api_trace_dump_t *mp;
165   i32 retval = (i32) clib_net_to_host_u32 (rmp->retval);
166   u32 thread_id, position;
167
168   if (retval != 0 || rmp->done)
169     {
170       vam->result_ready = 1;
171       vam->retval = retval;
172
173       /* Clear the cache */
174       if (retval == 0 && rmp->flush_only == 0)
175         {
176           M (TRACE_DUMP, mp);
177           mp->clear_cache = 1;
178           mp->thread_id = 0xFFFFFFFF;
179           mp->position = 0xFFFFFFFF;
180           S (mp);
181         }
182       return;
183     }
184
185   /* Figure out where the next batch starts */
186   thread_id = clib_host_to_net_u32 (rmp->last_thread_id);
187   position = clib_host_to_net_u32 (rmp->last_position);
188
189   if (rmp->more_threads)
190     {
191       position = 0;
192       thread_id++;
193     }
194   else
195     position++;
196
197   M (TRACE_DUMP, mp);
198   mp->clear_cache = 0;
199   mp->thread_id = clib_host_to_net_u32 (thread_id);
200   mp->position = clib_host_to_net_u32 (position);
201   mp->max_records = clib_host_to_net_u32 (10);
202   S (mp);
203 }
204
205 static int
206 api_trace_dump (vat_main_t * vam)
207 {
208   vl_api_trace_dump_t *mp;
209   int ret;
210
211   M (TRACE_DUMP, mp);
212   mp->clear_cache = 1;
213   mp->thread_id = 0;
214   mp->position = 0;
215   mp->max_records = clib_host_to_net_u32 (10);
216
217   S (mp);
218
219   W (ret);
220   return ret;
221 }
222
223 int
224 api_trace_clear_capture (vat_main_t * vam)
225 {
226   vl_api_trace_clear_capture_t *mp;
227   int ret;
228
229   M (TRACE_CLEAR_CAPTURE, mp);
230   S (mp);
231   W (ret);
232   return ret;
233 }
234
235
236
237
238 #define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
239 #define vl_endianfun
240 #include <tracedump/tracedump.api.h>
241 #undef vl_endianfun
242 #define vl_printfun
243 #include <tracedump/tracedump.api.h>
244 #undef vl_printfun
245
246 void
247 manual_setup_message_id_table (vat_main_t * vam)
248 {
249   vl_msg_api_set_handlers (
250     VL_API_TRACE_DETAILS + tracedump_test_main.msg_id_base, "trace_details",
251     vl_api_trace_details_t_handler, vl_noop_handler,
252     vl_api_trace_details_t_endian, vl_api_trace_details_t_print,
253     sizeof (vl_api_trace_details_t), 1, vl_api_trace_details_t_print_json,
254     vl_api_trace_details_t_tojson, vl_api_trace_details_t_fromjson);
255 }
256
257 #define VL_API_LOCAL_SETUP_MESSAGE_ID_TABLE manual_setup_message_id_table
258 #define VL_API_TRACE_DUMP_REPLY_T_HANDLER
259
260 #include <tracedump/tracedump.api_test.c>
261
262 /*
263  * fd.io coding-style-patch-verification: ON
264  *
265  * Local Variables:
266  * eval: (c-set-style "gnu")
267  * End:
268  */