hs-test: more debug output in http3 test
[vpp.git] / src / vnet / crypto / cli.c
1 /*
2  * Copyright (c) 2019 Cisco and/or its affiliates.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at:
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15
16 #include <stdbool.h>
17 #include <vlib/vlib.h>
18 #include <vnet/crypto/crypto.h>
19
20 static clib_error_t *
21 show_crypto_engines_command_fn (vlib_main_t * vm,
22                                 unformat_input_t * input,
23                                 vlib_cli_command_t * cmd)
24 {
25   unformat_input_t _line_input, *line_input = &_line_input;
26   vnet_crypto_main_t *cm = &crypto_main;
27   vnet_crypto_engine_t *p;
28
29   if (unformat_user (input, unformat_line_input, line_input))
30     unformat_free (line_input);
31
32   if (vec_len (cm->engines) == 0)
33     {
34       vlib_cli_output (vm, "No crypto engines registered");
35       return 0;
36     }
37
38   vlib_cli_output (vm, "%-20s%-8s%s", "Name", "Prio", "Description");
39   vec_foreach (p, cm->engines)
40     {
41       vlib_cli_output (vm, "%-20s%-8u%s", p->name, p->priority, p->desc);
42     }
43   return 0;
44 }
45
46 VLIB_CLI_COMMAND (show_crypto_engines_command, static) =
47 {
48   .path = "show crypto engines",
49   .short_help = "show crypto engines",
50   .function = show_crypto_engines_command_fn,
51 };
52
53 static u8 *
54 format_vnet_crypto_engine_candidates (u8 * s, va_list * args)
55 {
56   vnet_crypto_engine_t *e;
57   vnet_crypto_main_t *cm = &crypto_main;
58   u32 id = va_arg (*args, u32);
59   u32 ei = va_arg (*args, u32);
60   int is_chained = va_arg (*args, int);
61   int is_async = va_arg (*args, int);
62
63   if (is_async)
64     {
65       vec_foreach (e, cm->engines)
66         {
67           if (e->enqueue_handlers[id] && e->dequeue_handler)
68             {
69               s = format (s, "%U", format_vnet_crypto_engine, e - cm->engines);
70               if (ei == e - cm->engines)
71                 s = format (s, "%c ", '*');
72               else
73                 s = format (s, " ");
74             }
75         }
76
77       return s;
78     }
79   else
80     {
81       vec_foreach (e, cm->engines)
82         {
83           void * h = is_chained ? (void *) e->chained_ops_handlers[id]
84             : (void *) e->ops_handlers[id];
85
86           if (h)
87             {
88               s = format (s, "%U", format_vnet_crypto_engine, e - cm->engines);
89               if (ei == e - cm->engines)
90                 s = format (s, "%c ", '*');
91               else
92                 s = format (s, " ");
93             }
94         }
95       return s;
96     }
97 }
98
99 static u8 *
100 format_vnet_crypto_handlers (u8 * s, va_list * args)
101 {
102   vnet_crypto_alg_t alg = va_arg (*args, vnet_crypto_alg_t);
103   vnet_crypto_main_t *cm = &crypto_main;
104   vnet_crypto_alg_data_t *d = vec_elt_at_index (cm->algs, alg);
105   u32 indent = format_get_indent (s);
106   int i, first = 1;
107
108   for (i = 0; i < VNET_CRYPTO_OP_N_TYPES; i++)
109     {
110       vnet_crypto_op_data_t *od;
111       vnet_crypto_op_id_t id = d->op_by_type[i];
112
113       if (id == 0)
114         continue;
115
116       od = cm->opt_data + id;
117       if (first == 0)
118         s = format (s, "\n%U", format_white_space, indent);
119       s = format (s, "%-16U", format_vnet_crypto_op_type, od->type);
120
121       s = format (s, "%-28U", format_vnet_crypto_engine_candidates, id,
122           od->active_engine_index_simple, 0, 0);
123       s = format (s, "%U", format_vnet_crypto_engine_candidates, id,
124           od->active_engine_index_chained, 1, 0);
125       first = 0;
126     }
127   return s;
128 }
129
130
131 static clib_error_t *
132 show_crypto_handlers_command_fn (vlib_main_t * vm,
133                         unformat_input_t * input, vlib_cli_command_t * cmd)
134 {
135   unformat_input_t _line_input, *line_input = &_line_input;
136   int i;
137
138   if (unformat_user (input, unformat_line_input, line_input))
139     unformat_free (line_input);
140
141   vlib_cli_output (vm, "%-16s%-16s%-28s%s", "Algo", "Type", "Simple",
142       "Chained");
143
144   for (i = 0; i < VNET_CRYPTO_N_ALGS; i++)
145     vlib_cli_output (vm, "%-20U%U", format_vnet_crypto_alg, i,
146                      format_vnet_crypto_handlers, i);
147
148   return 0;
149 }
150
151 VLIB_CLI_COMMAND (show_crypto_handlers_command, static) =
152 {
153   .path = "show crypto handlers",
154   .short_help = "show crypto handlers",
155   .function = show_crypto_handlers_command_fn,
156 };
157
158 static clib_error_t *
159 set_crypto_handler_command_fn (vlib_main_t * vm,
160                                unformat_input_t * input,
161                                vlib_cli_command_t * cmd)
162 {
163   unformat_input_t _line_input, *line_input = &_line_input;
164   vnet_crypto_main_t *cm = &crypto_main;
165   int rc = 0;
166   char **args = 0, *s, **arg, *engine = 0;
167   int all = 0;
168   clib_error_t *error = 0;
169   crypto_op_class_type_t oct = CRYPTO_OP_BOTH;
170
171   if (!unformat_user (input, unformat_line_input, line_input))
172     return 0;
173
174   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
175     {
176       if (unformat (line_input, "all"))
177         all = 1;
178       else if (unformat (line_input, "simple"))
179         oct = CRYPTO_OP_SIMPLE;
180       else if (unformat (line_input, "chained"))
181         oct = CRYPTO_OP_CHAINED;
182       else if (unformat (line_input, "both"))
183         oct = CRYPTO_OP_BOTH;
184       else if (unformat (line_input, "%s", &s))
185         vec_add1 (args, s);
186       else
187         {
188           error = clib_error_return (0, "invalid params");
189           goto done;
190         }
191     }
192
193   if ((vec_len (args) < 2 && !all) || (vec_len (args) == 0 && all))
194     {
195       error = clib_error_return (0, "missing cipher or engine!");
196       goto done;
197     }
198
199   engine = vec_elt_at_index (args, vec_len (args) - 1)[0];
200   vec_del1 (args, vec_len (args) - 1);
201
202   if (all)
203     {
204       char *key;
205       u8 *value;
206
207       hash_foreach_mem (key, value, cm->alg_index_by_name,
208       ({
209         (void) value;
210         rc += vnet_crypto_set_handler2 (key, engine, oct);
211       }));
212
213       if (rc)
214         vlib_cli_output (vm, "failed to set crypto engine!");
215     }
216   else
217     {
218       vec_foreach (arg, args)
219       {
220         rc = vnet_crypto_set_handler2 (arg[0], engine, oct);
221         if (rc)
222           {
223             vlib_cli_output (vm, "failed to set engine %s for %s!",
224                              engine, arg[0]);
225           }
226       }
227     }
228
229 done:
230   vec_free (engine);
231   vec_foreach (arg, args) vec_free (arg[0]);
232   vec_free (args);
233   unformat_free (line_input);
234   return error;
235 }
236
237 VLIB_CLI_COMMAND (set_crypto_handler_command, static) =
238 {
239   .path = "set crypto handler",
240   .short_help = "set crypto handler cipher [cipher2 cipher3 ...] engine"
241     " [simple|chained]",
242   .function = set_crypto_handler_command_fn,
243 };
244
245 static u8 *
246 format_vnet_crypto_async_handlers (u8 * s, va_list * args)
247 {
248   vnet_crypto_async_alg_t alg = va_arg (*args, vnet_crypto_async_alg_t);
249   vnet_crypto_main_t *cm = &crypto_main;
250   vnet_crypto_async_alg_data_t *d = vec_elt_at_index (cm->async_algs, alg);
251   u32 indent = format_get_indent (s);
252   int i, first = 1;
253
254   for (i = 0; i < VNET_CRYPTO_ASYNC_OP_N_TYPES; i++)
255     {
256       vnet_crypto_async_op_data_t *od;
257       vnet_crypto_async_op_id_t id = d->op_by_type[i];
258
259       if (id == 0)
260         continue;
261
262       od = cm->async_opt_data + id;
263       if (first == 0)
264         s = format (s, "\n%U", format_white_space, indent);
265       s = format (s, "%-16U", format_vnet_crypto_async_op_type, od->type);
266
267       s = format (s, "%U", format_vnet_crypto_engine_candidates, id,
268                   od->active_engine_index_async, 0, 1);
269       first = 0;
270     }
271   return s;
272 }
273
274 static clib_error_t *
275 show_crypto_async_handlers_command_fn (vlib_main_t * vm,
276                                        unformat_input_t * input,
277                                        vlib_cli_command_t * cmd)
278 {
279   unformat_input_t _line_input, *line_input = &_line_input;
280   int i;
281
282   if (unformat_user (input, unformat_line_input, line_input))
283     unformat_free (line_input);
284
285   vlib_cli_output (vm, "%-28s%-16s%s", "Algo", "Type", "Handler");
286
287   for (i = 0; i < VNET_CRYPTO_N_ASYNC_ALGS; i++)
288     vlib_cli_output (vm, "%-28U%U", format_vnet_crypto_async_alg, i,
289                      format_vnet_crypto_async_handlers, i);
290
291   return 0;
292 }
293
294 VLIB_CLI_COMMAND (show_crypto_async_handlers_command, static) =
295 {
296   .path = "show crypto async handlers",
297   .short_help = "show crypto async handlers",
298   .function = show_crypto_async_handlers_command_fn,
299 };
300
301
302 static clib_error_t *
303 show_crypto_async_status_command_fn (vlib_main_t * vm,
304                                      unformat_input_t * input,
305                                      vlib_cli_command_t * cmd)
306 {
307   vnet_crypto_main_t *cm = &crypto_main;
308   vlib_thread_main_t *tm = vlib_get_thread_main ();
309   unformat_input_t _line_input, *line_input = &_line_input;
310   int i;
311
312   if (unformat_user (input, unformat_line_input, line_input))
313     unformat_free (line_input);
314
315   for (i = 0; i < tm->n_vlib_mains; i++)
316     {
317       vlib_node_state_t state = vlib_node_get_state (
318         vlib_get_main_by_index (i), cm->crypto_node_index);
319       if (state == VLIB_NODE_STATE_POLLING)
320         vlib_cli_output (vm, "threadId: %-6d POLLING", i);
321       if (state == VLIB_NODE_STATE_INTERRUPT)
322         vlib_cli_output (vm, "threadId: %-6d INTERRUPT", i);
323       if (state == VLIB_NODE_STATE_DISABLED)
324         vlib_cli_output (vm, "threadId: %-6d DISABLED", i);
325     }
326   return 0;
327 }
328
329 VLIB_CLI_COMMAND (show_crypto_async_status_command, static) =
330 {
331   .path = "show crypto async status",
332   .short_help = "show crypto async status",
333   .function = show_crypto_async_status_command_fn,
334 };
335
336 static clib_error_t *
337 set_crypto_async_handler_command_fn (vlib_main_t * vm,
338                                      unformat_input_t * input,
339                                      vlib_cli_command_t * cmd)
340 {
341   unformat_input_t _line_input, *line_input = &_line_input;
342   vnet_crypto_main_t *cm = &crypto_main;
343   int rc = 0;
344   char **args = 0, *s, **arg, *engine = 0;
345   int all = 0;
346   clib_error_t *error = 0;
347
348   if (!unformat_user (input, unformat_line_input, line_input))
349     return 0;
350
351   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
352     {
353       if (unformat (line_input, "all"))
354         all = 1;
355       else if (unformat (line_input, "%s", &s))
356         vec_add1 (args, s);
357       else
358         {
359           error = clib_error_return (0, "invalid params");
360           goto done;
361         }
362     }
363
364   if ((vec_len (args) < 2 && !all) || (vec_len (args) == 0 && all))
365     {
366       error = clib_error_return (0, "missing cipher or engine!");
367       goto done;
368     }
369
370   engine = vec_elt_at_index (args, vec_len (args) - 1)[0];
371   vec_del1 (args, vec_len (args) - 1);
372
373   if (all)
374     {
375       char *key;
376       u8 *value;
377
378       hash_foreach_mem (key, value, cm->async_alg_index_by_name,
379       ({
380         (void) value;
381         rc += vnet_crypto_set_async_handler2 (key, engine);
382       }));
383
384       if (rc)
385         vlib_cli_output (vm, "failed to set crypto engine!");
386     }
387   else
388     {
389       vec_foreach (arg, args)
390       {
391         rc = vnet_crypto_set_async_handler2 (arg[0], engine);
392         if (rc)
393           {
394             vlib_cli_output (vm, "failed to set engine %s for %s!",
395                              engine, arg[0]);
396           }
397       }
398     }
399
400 done:
401   vec_free (engine);
402   vec_foreach (arg, args) vec_free (arg[0]);
403   vec_free (args);
404   unformat_free (line_input);
405   return error;
406 }
407
408 VLIB_CLI_COMMAND (set_crypto_async_handler_command, static) =
409 {
410   .path = "set crypto async handler",
411   .short_help = "set crypto async handler type [type2 type3 ...] engine",
412   .function = set_crypto_async_handler_command_fn,
413 };
414
415 static clib_error_t *
416 set_crypto_async_dispatch_command_fn (vlib_main_t *vm, unformat_input_t *input,
417                                       vlib_cli_command_t *cmd)
418 {
419   unformat_input_t _line_input, *line_input = &_line_input;
420   clib_error_t *error = 0;
421   u8 adaptive = 0;
422   u8 mode = VLIB_NODE_STATE_INTERRUPT;
423
424   if (!unformat_user (input, unformat_line_input, line_input))
425     return 0;
426
427   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
428     {
429       if (unformat (line_input, "polling"))
430         mode = VLIB_NODE_STATE_POLLING;
431       else if (unformat (line_input, "interrupt"))
432         mode = VLIB_NODE_STATE_INTERRUPT;
433       else if (unformat (line_input, "adaptive"))
434         adaptive = 1;
435       else
436         {
437           error = clib_error_return (0, "invalid params");
438           goto done;
439         }
440     }
441
442   vnet_crypto_set_async_dispatch (mode, adaptive);
443 done:
444   unformat_free (line_input);
445   return error;
446 }
447
448 VLIB_CLI_COMMAND (set_crypto_async_dispatch_mode_command, static) = {
449   .path = "set crypto async dispatch mode",
450   .short_help = "set crypto async dispatch mode <polling|interrupt|adaptive>",
451   .function = set_crypto_async_dispatch_command_fn,
452 };
453
454 /*
455  * fd.io coding-style-patch-verification: ON
456  *
457  * Local Variables:
458  * eval: (c-set-style "gnu")
459  * End:
460  */