blob: 18eb83b68b736757d55ab3ef4f367d70ded9ce1a [file] [log] [blame]
Dave Barach371e4e12016-07-08 09:38:52 -04001/*
Ed Warnickecb9cada2015-12-08 15:45:58 -07002 *------------------------------------------------------------------
3 * api_shared.c - API message handling, common code for both clients
4 * and the vlib process itself.
Dave Barach371e4e12016-07-08 09:38:52 -04005 *
Ed Warnickecb9cada2015-12-08 15:45:58 -07006 *
7 * Copyright (c) 2009 Cisco and/or its affiliates.
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at:
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 *------------------------------------------------------------------
20 */
21
22#include <stdio.h>
23#include <stdlib.h>
Dave Barach072f8de2016-12-02 13:31:25 -050024#include <stddef.h>
Ed Warnickecb9cada2015-12-08 15:45:58 -070025#include <string.h>
Ed Warnickecb9cada2015-12-08 15:45:58 -070026#include <vppinfra/format.h>
27#include <vppinfra/byte_order.h>
28#include <vppinfra/error.h>
29#include <vlib/vlib.h>
30#include <vlib/unix/unix.h>
31#include <vlibapi/api.h>
32#include <vppinfra/elog.h>
33
Dave Barach80f54e22017-03-08 19:08:56 -050034/* *INDENT-OFF* */
35api_main_t api_main =
36 {
37 .region_name = "/unset",
38 .api_uid = -1,
39 .api_gid = -1,
40 };
41/* *INDENT-ON* */
Dave Barach371e4e12016-07-08 09:38:52 -040042
43void
44vl_msg_api_increment_missing_client_counter (void)
45{
46 api_main_t *am = &api_main;
47 am->missing_clients++;
48}
49
Dave Barach371e4e12016-07-08 09:38:52 -040050int
51vl_msg_api_rx_trace_enabled (api_main_t * am)
Ed Warnickecb9cada2015-12-08 15:45:58 -070052{
Dave Barach371e4e12016-07-08 09:38:52 -040053 return (am->rx_trace && am->rx_trace->enabled);
Ed Warnickecb9cada2015-12-08 15:45:58 -070054}
55
Dave Barach371e4e12016-07-08 09:38:52 -040056int
57vl_msg_api_tx_trace_enabled (api_main_t * am)
Ed Warnickecb9cada2015-12-08 15:45:58 -070058{
Dave Barach371e4e12016-07-08 09:38:52 -040059 return (am->tx_trace && am->tx_trace->enabled);
Ed Warnickecb9cada2015-12-08 15:45:58 -070060}
61
62/*
63 * vl_msg_api_trace
64 */
Dave Barach371e4e12016-07-08 09:38:52 -040065void
66vl_msg_api_trace (api_main_t * am, vl_api_trace_t * tp, void *msg)
Ed Warnickecb9cada2015-12-08 15:45:58 -070067{
Dave Barach371e4e12016-07-08 09:38:52 -040068 u8 **this_trace;
69 u8 **old_trace;
70 u8 *msg_copy;
Dave Barach072f8de2016-12-02 13:31:25 -050071 u32 length;
Dave Barach371e4e12016-07-08 09:38:52 -040072 trace_cfg_t *cfgp;
Dave Barach9683c1e2019-07-01 09:42:41 -040073 u16 msg_id = clib_net_to_host_u16 (*((u16 *) msg));
Dave Barach072f8de2016-12-02 13:31:25 -050074 msgbuf_t *header = (msgbuf_t *) (((u8 *) msg) - offsetof (msgbuf_t, data));
Ed Warnickecb9cada2015-12-08 15:45:58 -070075
Dave Barach371e4e12016-07-08 09:38:52 -040076 cfgp = am->api_trace_cfg + msg_id;
Ed Warnickecb9cada2015-12-08 15:45:58 -070077
Dave Barach371e4e12016-07-08 09:38:52 -040078 if (!cfgp || !cfgp->trace_enable)
79 return;
Ed Warnickecb9cada2015-12-08 15:45:58 -070080
Dave Barach371e4e12016-07-08 09:38:52 -040081 msg_copy = 0;
Ed Warnickecb9cada2015-12-08 15:45:58 -070082
Dave Barach371e4e12016-07-08 09:38:52 -040083 if (tp->nitems == 0)
84 {
85 clib_warning ("tp->nitems is 0");
86 return;
Ed Warnickecb9cada2015-12-08 15:45:58 -070087 }
88
Dave Barach371e4e12016-07-08 09:38:52 -040089 if (vec_len (tp->traces) < tp->nitems)
90 {
91 vec_add1 (tp->traces, 0);
92 this_trace = tp->traces + vec_len (tp->traces) - 1;
93 }
94 else
95 {
96 tp->wrapped = 1;
97 old_trace = tp->traces + tp->curindex++;
98 if (tp->curindex == tp->nitems)
99 tp->curindex = 0;
Dave Barachf35a0722019-06-12 16:50:38 -0400100 /* Reuse the trace record, may save some memory allocator traffic */
101 msg_copy = *old_trace;
102 vec_reset_length (msg_copy);
Dave Barach371e4e12016-07-08 09:38:52 -0400103 this_trace = old_trace;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700104 }
105
Dave Barach072f8de2016-12-02 13:31:25 -0500106 length = clib_net_to_host_u32 (header->data_len);
107
108 vec_validate (msg_copy, length - 1);
Dave Barach178cf492018-11-13 16:34:13 -0500109 clib_memcpy_fast (msg_copy, msg, length);
Dave Barach371e4e12016-07-08 09:38:52 -0400110 *this_trace = msg_copy;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700111}
112
Dave Barach371e4e12016-07-08 09:38:52 -0400113int
114vl_msg_api_trace_onoff (api_main_t * am, vl_api_trace_which_t which,
115 int onoff)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700116{
Dave Barach371e4e12016-07-08 09:38:52 -0400117 vl_api_trace_t *tp;
118 int rv;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700119
Dave Barach371e4e12016-07-08 09:38:52 -0400120 switch (which)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700121 {
122 case VL_API_TRACE_TX:
Dave Barach371e4e12016-07-08 09:38:52 -0400123 tp = am->tx_trace;
124 if (tp == 0)
125 {
126 vl_msg_api_trace_configure (am, which, 1024);
127 tp = am->tx_trace;
128 }
129 break;
130
Ed Warnickecb9cada2015-12-08 15:45:58 -0700131 case VL_API_TRACE_RX:
Dave Barach371e4e12016-07-08 09:38:52 -0400132 tp = am->rx_trace;
133 if (tp == 0)
134 {
135 vl_msg_api_trace_configure (am, which, 1024);
136 tp = am->rx_trace;
137 }
138 break;
139
Ed Warnickecb9cada2015-12-08 15:45:58 -0700140 default:
Dave Barach371e4e12016-07-08 09:38:52 -0400141 /* duh? */
142 return -1;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700143 }
144
Dave Barach371e4e12016-07-08 09:38:52 -0400145 /* Configured? */
146 if (tp == 0 || tp->nitems == 0)
147 return -1;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700148
Dave Barach371e4e12016-07-08 09:38:52 -0400149 rv = tp->enabled;
150 tp->enabled = onoff;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700151
Dave Barach371e4e12016-07-08 09:38:52 -0400152 return rv;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700153}
154
Dave Barach371e4e12016-07-08 09:38:52 -0400155int
156vl_msg_api_trace_free (api_main_t * am, vl_api_trace_which_t which)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700157{
Dave Barach371e4e12016-07-08 09:38:52 -0400158 vl_api_trace_t *tp;
159 int i;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700160
Dave Barach371e4e12016-07-08 09:38:52 -0400161 switch (which)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700162 {
163 case VL_API_TRACE_TX:
Dave Barach371e4e12016-07-08 09:38:52 -0400164 tp = am->tx_trace;
165 break;
166
Ed Warnickecb9cada2015-12-08 15:45:58 -0700167 case VL_API_TRACE_RX:
Dave Barach371e4e12016-07-08 09:38:52 -0400168 tp = am->rx_trace;
169 break;
170
Ed Warnickecb9cada2015-12-08 15:45:58 -0700171 default:
Dave Barach371e4e12016-07-08 09:38:52 -0400172 /* duh? */
173 return -1;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700174 }
175
Dave Barach371e4e12016-07-08 09:38:52 -0400176 /* Configured? */
177 if (!tp || tp->nitems == 0)
178 return -1;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700179
Dave Barach371e4e12016-07-08 09:38:52 -0400180 tp->curindex = 0;
181 tp->wrapped = 0;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700182
Dave Barach371e4e12016-07-08 09:38:52 -0400183 for (i = 0; i < vec_len (tp->traces); i++)
184 {
185 vec_free (tp->traces[i]);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700186 }
Dave Barach371e4e12016-07-08 09:38:52 -0400187 vec_free (tp->traces);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700188
Dave Barach371e4e12016-07-08 09:38:52 -0400189 return 0;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700190}
191
Dave Barach371e4e12016-07-08 09:38:52 -0400192int
193vl_msg_api_trace_save (api_main_t * am, vl_api_trace_which_t which, FILE * fp)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700194{
Dave Barach371e4e12016-07-08 09:38:52 -0400195 vl_api_trace_t *tp;
196 vl_api_trace_file_header_t fh;
197 int i;
198 u8 *msg;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700199
Dave Barach371e4e12016-07-08 09:38:52 -0400200 switch (which)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700201 {
202 case VL_API_TRACE_TX:
Dave Barach371e4e12016-07-08 09:38:52 -0400203 tp = am->tx_trace;
204 break;
205
Ed Warnickecb9cada2015-12-08 15:45:58 -0700206 case VL_API_TRACE_RX:
Dave Barach371e4e12016-07-08 09:38:52 -0400207 tp = am->rx_trace;
208 break;
209
Ed Warnickecb9cada2015-12-08 15:45:58 -0700210 default:
Dave Barach371e4e12016-07-08 09:38:52 -0400211 /* duh? */
212 return -1;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700213 }
214
Dave Barach371e4e12016-07-08 09:38:52 -0400215 /* Configured, data present? */
216 if (tp == 0 || tp->nitems == 0 || vec_len (tp->traces) == 0)
217 return -1;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700218
Dave Barach371e4e12016-07-08 09:38:52 -0400219 /* "Dare to be stupid" check */
220 if (fp == 0)
221 {
222 return -2;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700223 }
224
Dave Barach371e4e12016-07-08 09:38:52 -0400225 /* Write the file header */
226 fh.nitems = vec_len (tp->traces);
227 fh.endian = tp->endian;
228 fh.wrapped = tp->wrapped;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700229
Dave Barach371e4e12016-07-08 09:38:52 -0400230 if (fwrite (&fh, sizeof (fh), 1, fp) != 1)
231 {
232 return (-10);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700233 }
234
Dave Barach371e4e12016-07-08 09:38:52 -0400235 /* No-wrap case */
236 if (tp->wrapped == 0)
237 {
238 /*
239 * Note: vec_len return 0 when fed a NULL pointer.
240 * Unfortunately, the static analysis tool doesn't
241 * figure it out, hence the suppressed warnings.
242 * What a great use of my time.
243 */
244 for (i = 0; i < vec_len (tp->traces); i++)
245 {
Dave Barach072f8de2016-12-02 13:31:25 -0500246 u32 msg_length;
Dave Barach371e4e12016-07-08 09:38:52 -0400247 /*sa_ignore NO_NULL_CHK */
248 msg = tp->traces[i];
249 /*
250 * This retarded check required to pass
251 * [sic] SA-checking.
252 */
253 if (!msg)
254 continue;
Dave Barach072f8de2016-12-02 13:31:25 -0500255
256 msg_length = clib_host_to_net_u32 (vec_len (msg));
257 if (fwrite (&msg_length, 1, sizeof (msg_length), fp)
258 != sizeof (msg_length))
259 {
260 return (-14);
261 }
Dave Barach371e4e12016-07-08 09:38:52 -0400262 if (fwrite (msg, 1, vec_len (msg), fp) != vec_len (msg))
263 {
264 return (-11);
265 }
266 }
Ed Warnickecb9cada2015-12-08 15:45:58 -0700267 }
Dave Barach371e4e12016-07-08 09:38:52 -0400268 else
269 {
270 /* Wrap case: write oldest -> end of buffer */
271 for (i = tp->curindex; i < vec_len (tp->traces); i++)
272 {
Dave Barach072f8de2016-12-02 13:31:25 -0500273 u32 msg_length;
Dave Barach371e4e12016-07-08 09:38:52 -0400274 msg = tp->traces[i];
275 /*
276 * This retarded check required to pass
277 * [sic] SA-checking
278 */
279 if (!msg)
280 continue;
281
Dave Barach072f8de2016-12-02 13:31:25 -0500282 msg_length = clib_host_to_net_u32 (vec_len (msg));
283 if (fwrite (&msg_length, 1, sizeof (msg_length), fp)
284 != sizeof (msg_length))
285 {
286 return (-14);
287 }
288
Dave Barach371e4e12016-07-08 09:38:52 -0400289 if (fwrite (msg, 1, vec_len (msg), fp) != vec_len (msg))
290 {
291 return (-12);
292 }
293 }
294 /* write beginning of buffer -> oldest-1 */
295 for (i = 0; i < tp->curindex; i++)
296 {
Dave Barach072f8de2016-12-02 13:31:25 -0500297 u32 msg_length;
Dave Barach371e4e12016-07-08 09:38:52 -0400298 /*sa_ignore NO_NULL_CHK */
299 msg = tp->traces[i];
300 /*
301 * This retarded check required to pass
302 * [sic] SA-checking
303 */
304 if (!msg)
305 continue;
306
Dave Barach072f8de2016-12-02 13:31:25 -0500307 msg_length = clib_host_to_net_u32 (vec_len (msg));
308 if (fwrite (&msg_length, 1, sizeof (msg_length), fp)
309 != sizeof (msg_length))
310 {
311 return (-14);
312 }
313
Dave Barach371e4e12016-07-08 09:38:52 -0400314 if (fwrite (msg, 1, vec_len (msg), fp) != vec_len (msg))
315 {
316 return (-13);
317 }
318 }
319 }
320 return 0;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700321}
322
Dave Barach371e4e12016-07-08 09:38:52 -0400323int
324vl_msg_api_trace_configure (api_main_t * am, vl_api_trace_which_t which,
325 u32 nitems)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700326{
Dave Barach371e4e12016-07-08 09:38:52 -0400327 vl_api_trace_t *tp;
328 int was_on = 0;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700329
Dave Barach371e4e12016-07-08 09:38:52 -0400330 switch (which)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700331 {
332 case VL_API_TRACE_TX:
Dave Barach371e4e12016-07-08 09:38:52 -0400333 tp = am->tx_trace;
334 if (tp == 0)
335 {
336 vec_validate (am->tx_trace, 0);
337 tp = am->tx_trace;
338 }
339 break;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700340
Dave Barach371e4e12016-07-08 09:38:52 -0400341 case VL_API_TRACE_RX:
342 tp = am->rx_trace;
343 if (tp == 0)
344 {
345 vec_validate (am->rx_trace, 0);
346 tp = am->rx_trace;
347 }
348
349 break;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700350
351 default:
Dave Barach371e4e12016-07-08 09:38:52 -0400352 return -1;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700353
354 }
355
Dave Barach371e4e12016-07-08 09:38:52 -0400356 if (tp->enabled)
357 {
358 was_on = vl_msg_api_trace_onoff (am, which, 0);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700359 }
Dave Barach371e4e12016-07-08 09:38:52 -0400360 if (tp->traces)
361 {
362 vl_msg_api_trace_free (am, which);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700363 }
364
Dave Barachb7b92992018-10-17 10:38:51 -0400365 clib_memset (tp, 0, sizeof (*tp));
Ed Warnickecb9cada2015-12-08 15:45:58 -0700366
Dave Barach371e4e12016-07-08 09:38:52 -0400367 if (clib_arch_is_big_endian)
368 {
369 tp->endian = VL_API_BIG_ENDIAN;
370 }
371 else
372 {
373 tp->endian = VL_API_LITTLE_ENDIAN;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700374 }
375
Dave Barach371e4e12016-07-08 09:38:52 -0400376 tp->nitems = nitems;
377 if (was_on)
378 {
379 (void) vl_msg_api_trace_onoff (am, which, was_on);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700380 }
Dave Barach371e4e12016-07-08 09:38:52 -0400381 return 0;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700382}
383
Dave Barach80f54e22017-03-08 19:08:56 -0500384void
385vl_msg_api_barrier_sync (void)
386{
387}
388
389void
390vl_msg_api_barrier_release (void)
391{
392}
393
Dave Barach371e4e12016-07-08 09:38:52 -0400394always_inline void
395msg_handler_internal (api_main_t * am,
396 void *the_msg, int trace_it, int do_it, int free_it)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700397{
Dave Barach9683c1e2019-07-01 09:42:41 -0400398 u16 id = clib_net_to_host_u16 (*((u16 *) the_msg));
Dave Barach371e4e12016-07-08 09:38:52 -0400399 u8 *(*print_fp) (void *, void *);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700400
Dave Barachb09f4d02019-07-15 16:00:03 -0400401 if (PREDICT_FALSE (am->elog_trace_api_messages))
402 {
403 /* *INDENT-OFF* */
404 ELOG_TYPE_DECLARE (e) =
405 {
406 .format = "api-msg: %s",
407 .format_args = "T4",
408 };
409 /* *INDENT-ON* */
410 struct
411 {
412 u32 c;
413 } *ed;
414 ed = ELOG_DATA (am->elog_main, e);
415 if (id < vec_len (am->msg_names))
416 ed->c = elog_string (am->elog_main, (char *) am->msg_names[id]);
417 else
418 ed->c = elog_string (am->elog_main, "BOGUS");
419 }
420
Dave Barach371e4e12016-07-08 09:38:52 -0400421 if (id < vec_len (am->msg_handlers) && am->msg_handlers[id])
422 {
423 if (trace_it)
424 vl_msg_api_trace (am, am->rx_trace, the_msg);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700425
Dave Barach371e4e12016-07-08 09:38:52 -0400426 if (am->msg_print_flag)
427 {
428 fformat (stdout, "[%d]: %s\n", id, am->msg_names[id]);
429 print_fp = (void *) am->msg_print_handlers[id];
430 if (print_fp == 0)
431 {
432 fformat (stdout, " [no registered print fn]\n");
433 }
434 else
435 {
436 (*print_fp) (the_msg, stdout);
437 }
438 }
439
440 if (do_it)
441 {
442 if (!am->is_mp_safe[id])
Colin Tregenza Dancereb1ac172017-09-06 20:23:24 +0100443 {
444 vl_msg_api_barrier_trace_context (am->msg_names[id]);
445 vl_msg_api_barrier_sync ();
446 }
Dave Barach371e4e12016-07-08 09:38:52 -0400447 (*am->msg_handlers[id]) (the_msg);
448 if (!am->is_mp_safe[id])
449 vl_msg_api_barrier_release ();
450 }
451 }
452 else
453 {
454 clib_warning ("no handler for msg id %d", id);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700455 }
456
Dave Barach371e4e12016-07-08 09:38:52 -0400457 if (free_it)
458 vl_msg_api_free (the_msg);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700459
Dave Barachb09f4d02019-07-15 16:00:03 -0400460 if (PREDICT_FALSE (am->elog_trace_api_messages))
461 {
462 /* *INDENT-OFF* */
463 ELOG_TYPE_DECLARE (e) =
464 {
465 .format = "api-msg-done(%s): %s",
466 .format_args = "t4T4",
467 .n_enum_strings = 2,
468 .enum_strings =
469 {
470 "barrier",
471 "mp-safe",
472 }
473 };
474 /* *INDENT-ON* */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700475
Dave Barachb09f4d02019-07-15 16:00:03 -0400476 struct
477 {
478 u32 barrier;
479 u32 c;
480 } *ed;
481 ed = ELOG_DATA (am->elog_main, e);
482 if (id < vec_len (am->msg_names))
483 ed->c = elog_string (am->elog_main, (char *) am->msg_names[id]);
484 else
485 ed->c = elog_string (am->elog_main, "BOGUS");
486 ed->barrier = !am->is_mp_safe[id];
487 }
Ed Warnickecb9cada2015-12-08 15:45:58 -0700488}
Ed Warnickecb9cada2015-12-08 15:45:58 -0700489
490/* This is only to be called from a vlib/vnet app */
Dave Barach371e4e12016-07-08 09:38:52 -0400491void
492vl_msg_api_handler_with_vm_node (api_main_t * am,
493 void *the_msg, vlib_main_t * vm,
494 vlib_node_runtime_t * node)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700495{
Dave Barach9683c1e2019-07-01 09:42:41 -0400496 u16 id = clib_net_to_host_u16 (*((u16 *) the_msg));
Dave Barach371e4e12016-07-08 09:38:52 -0400497 u8 *(*handler) (void *, void *, void *);
ezkexma75f9fb62019-03-21 07:38:19 -0400498 u8 *(*print_fp) (void *, void *);
Dave Barachc898a4f2019-06-14 17:29:55 -0400499 int is_mp_safe = 1;
Dave Barach371e4e12016-07-08 09:38:52 -0400500
Dave Barachb09f4d02019-07-15 16:00:03 -0400501 if (PREDICT_FALSE (am->elog_trace_api_messages))
Dave Barach371e4e12016-07-08 09:38:52 -0400502 {
Dave Barachc3a06552018-10-01 09:25:32 -0400503 /* *INDENT-OFF* */
504 ELOG_TYPE_DECLARE (e) =
505 {
506 .format = "api-msg: %s",
507 .format_args = "T4",
508 };
509 /* *INDENT-ON* */
510 struct
511 {
512 u32 c;
513 } *ed;
Dave Barachb09f4d02019-07-15 16:00:03 -0400514 ed = ELOG_DATA (am->elog_main, e);
Dave Barachc3a06552018-10-01 09:25:32 -0400515 if (id < vec_len (am->msg_names))
Dave Barachb09f4d02019-07-15 16:00:03 -0400516 ed->c = elog_string (am->elog_main, (char *) am->msg_names[id]);
Dave Barachc3a06552018-10-01 09:25:32 -0400517 else
Dave Barachb09f4d02019-07-15 16:00:03 -0400518 ed->c = elog_string (am->elog_main, "BOGUS");
Dave Barachc3a06552018-10-01 09:25:32 -0400519 }
Dave Barach371e4e12016-07-08 09:38:52 -0400520
521 if (id < vec_len (am->msg_handlers) && am->msg_handlers[id])
522 {
523 handler = (void *) am->msg_handlers[id];
524
ezkexma75f9fb62019-03-21 07:38:19 -0400525 if (PREDICT_FALSE (am->rx_trace && am->rx_trace->enabled))
Dave Barach371e4e12016-07-08 09:38:52 -0400526 vl_msg_api_trace (am, am->rx_trace, the_msg);
527
ezkexma75f9fb62019-03-21 07:38:19 -0400528 if (PREDICT_FALSE (am->msg_print_flag))
529 {
530 fformat (stdout, "[%d]: %s\n", id, am->msg_names[id]);
531 print_fp = (void *) am->msg_print_handlers[id];
532 if (print_fp == 0)
533 {
534 fformat (stdout, " [no registered print fn for msg %d]\n", id);
535 }
536 else
537 {
538 (*print_fp) (the_msg, vm);
539 }
540 }
Dave Barachc898a4f2019-06-14 17:29:55 -0400541 is_mp_safe = am->is_mp_safe[id];
ezkexma75f9fb62019-03-21 07:38:19 -0400542
Dave Barachc898a4f2019-06-14 17:29:55 -0400543 if (!is_mp_safe)
Colin Tregenza Dancereb1ac172017-09-06 20:23:24 +0100544 {
545 vl_msg_api_barrier_trace_context (am->msg_names[id]);
546 vl_msg_api_barrier_sync ();
547 }
Dave Barach371e4e12016-07-08 09:38:52 -0400548 (*handler) (the_msg, vm, node);
Dave Barachc898a4f2019-06-14 17:29:55 -0400549 if (!is_mp_safe)
Dave Barach371e4e12016-07-08 09:38:52 -0400550 vl_msg_api_barrier_release ();
551 }
552 else
553 {
Jon Loeligerf95b37e2017-02-13 15:21:12 -0600554 clib_warning ("no handler for msg id %d", id);
Dave Barach371e4e12016-07-08 09:38:52 -0400555 }
556
557 /*
Ed Warnickecb9cada2015-12-08 15:45:58 -0700558 * Special-case, so we can e.g. bounce messages off the vnet
559 * main thread without copying them...
560 */
561 if (!(am->message_bounce[id]))
Dave Barach371e4e12016-07-08 09:38:52 -0400562 vl_msg_api_free (the_msg);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700563
Dave Barachb09f4d02019-07-15 16:00:03 -0400564 if (PREDICT_FALSE (am->elog_trace_api_messages))
Ed Warnickecb9cada2015-12-08 15:45:58 -0700565 {
Dave Barachc3a06552018-10-01 09:25:32 -0400566 /* *INDENT-OFF* */
Dave Barachc898a4f2019-06-14 17:29:55 -0400567 ELOG_TYPE_DECLARE (e) =
568 {
569 .format = "api-msg-done(%s): %s",
570 .format_args = "t4T4",
571 .n_enum_strings = 2,
572 .enum_strings =
573 {
574 "barrier",
575 "mp-safe",
576 }
577 };
Dave Barachc3a06552018-10-01 09:25:32 -0400578 /* *INDENT-ON* */
579
580 struct
581 {
Dave Barachc898a4f2019-06-14 17:29:55 -0400582 u32 barrier;
Dave Barachc3a06552018-10-01 09:25:32 -0400583 u32 c;
584 } *ed;
Dave Barachb09f4d02019-07-15 16:00:03 -0400585 ed = ELOG_DATA (am->elog_main, e);
Dave Barachc3a06552018-10-01 09:25:32 -0400586 if (id < vec_len (am->msg_names))
Dave Barachb09f4d02019-07-15 16:00:03 -0400587 ed->c = elog_string (am->elog_main, (char *) am->msg_names[id]);
Dave Barachc3a06552018-10-01 09:25:32 -0400588 else
Dave Barachb09f4d02019-07-15 16:00:03 -0400589 ed->c = elog_string (am->elog_main, "BOGUS");
Dave Barachc898a4f2019-06-14 17:29:55 -0400590 ed->barrier = is_mp_safe;
Dave Barachc3a06552018-10-01 09:25:32 -0400591 }
Ed Warnickecb9cada2015-12-08 15:45:58 -0700592}
593
Dave Barach371e4e12016-07-08 09:38:52 -0400594void
595vl_msg_api_handler (void *the_msg)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700596{
Dave Barach371e4e12016-07-08 09:38:52 -0400597 api_main_t *am = &api_main;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700598
Dave Barach371e4e12016-07-08 09:38:52 -0400599 msg_handler_internal (am, the_msg,
600 (am->rx_trace
601 && am->rx_trace->enabled) /* trace_it */ ,
602 1 /* do_it */ , 1 /* free_it */ );
Ed Warnickecb9cada2015-12-08 15:45:58 -0700603}
604
Dave Barach371e4e12016-07-08 09:38:52 -0400605void
606vl_msg_api_handler_no_free (void *the_msg)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700607{
Dave Barach371e4e12016-07-08 09:38:52 -0400608 api_main_t *am = &api_main;
609 msg_handler_internal (am, the_msg,
610 (am->rx_trace
611 && am->rx_trace->enabled) /* trace_it */ ,
612 1 /* do_it */ , 0 /* free_it */ );
Ed Warnickecb9cada2015-12-08 15:45:58 -0700613}
614
Dave Barach371e4e12016-07-08 09:38:52 -0400615void
616vl_msg_api_handler_no_trace_no_free (void *the_msg)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700617{
Dave Barach371e4e12016-07-08 09:38:52 -0400618 api_main_t *am = &api_main;
619 msg_handler_internal (am, the_msg, 0 /* trace_it */ , 1 /* do_it */ ,
620 0 /* free_it */ );
Ed Warnickecb9cada2015-12-08 15:45:58 -0700621}
622
623/*
624 * Add a trace record to the API message trace buffer, if
625 * API message tracing is enabled. Handy for adding sufficient
626 * data to the trace to reproduce autonomous state, as opposed to
Dave Barach371e4e12016-07-08 09:38:52 -0400627 * state downloaded via control-plane API messages. Example: the NAT
Ed Warnickecb9cada2015-12-08 15:45:58 -0700628 * application creates database entries based on packet traffic, not
629 * control-plane messages.
630 *
631 */
Dave Barach371e4e12016-07-08 09:38:52 -0400632void
633vl_msg_api_trace_only (void *the_msg)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700634{
Dave Barach371e4e12016-07-08 09:38:52 -0400635 api_main_t *am = &api_main;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700636
Dave Barach371e4e12016-07-08 09:38:52 -0400637 msg_handler_internal (am, the_msg,
638 (am->rx_trace
639 && am->rx_trace->enabled) /* trace_it */ ,
640 0 /* do_it */ , 0 /* free_it */ );
Ed Warnickecb9cada2015-12-08 15:45:58 -0700641}
642
Dave Barach371e4e12016-07-08 09:38:52 -0400643void
644vl_msg_api_cleanup_handler (void *the_msg)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700645{
Dave Barach371e4e12016-07-08 09:38:52 -0400646 api_main_t *am = &api_main;
Dave Barach9683c1e2019-07-01 09:42:41 -0400647 u16 id = clib_net_to_host_u16 (*((u16 *) the_msg));
Ed Warnickecb9cada2015-12-08 15:45:58 -0700648
Dave Barach371e4e12016-07-08 09:38:52 -0400649 if (PREDICT_FALSE (id >= vec_len (am->msg_cleanup_handlers)))
650 {
651 clib_warning ("_vl_msg_id too large: %d\n", id);
652 return;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700653 }
Dave Barach371e4e12016-07-08 09:38:52 -0400654 if (am->msg_cleanup_handlers[id])
655 (*am->msg_cleanup_handlers[id]) (the_msg);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700656
Dave Barach371e4e12016-07-08 09:38:52 -0400657 vl_msg_api_free (the_msg);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700658}
659
660/*
661 * vl_msg_api_replay_handler
662 */
Dave Barach371e4e12016-07-08 09:38:52 -0400663void
664vl_msg_api_replay_handler (void *the_msg)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700665{
Dave Barach371e4e12016-07-08 09:38:52 -0400666 api_main_t *am = &api_main;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700667
Dave Barach9683c1e2019-07-01 09:42:41 -0400668 u16 id = clib_net_to_host_u16 (*((u16 *) the_msg));
Ed Warnickecb9cada2015-12-08 15:45:58 -0700669
Dave Barach371e4e12016-07-08 09:38:52 -0400670 if (PREDICT_FALSE (id >= vec_len (am->msg_handlers)))
671 {
672 clib_warning ("_vl_msg_id too large: %d\n", id);
673 return;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700674 }
Dave Barach371e4e12016-07-08 09:38:52 -0400675 /* do NOT trace the message... */
676 if (am->msg_handlers[id])
677 (*am->msg_handlers[id]) (the_msg);
678 /* do NOT free the message buffer... */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700679}
Dave Barach371e4e12016-07-08 09:38:52 -0400680
Dave Barachbfd92272017-05-12 11:59:25 -0400681u32
682vl_msg_api_get_msg_length (void *msg_arg)
683{
684 return vl_msg_api_get_msg_length_inline (msg_arg);
685}
686
Ed Warnickecb9cada2015-12-08 15:45:58 -0700687/*
688 * vl_msg_api_socket_handler
689 */
Dave Barach371e4e12016-07-08 09:38:52 -0400690void
691vl_msg_api_socket_handler (void *the_msg)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700692{
Dave Barach371e4e12016-07-08 09:38:52 -0400693 api_main_t *am = &api_main;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700694
Dave Barach371e4e12016-07-08 09:38:52 -0400695 msg_handler_internal (am, the_msg,
696 (am->rx_trace
697 && am->rx_trace->enabled) /* trace_it */ ,
698 1 /* do_it */ , 0 /* free_it */ );
Ed Warnickecb9cada2015-12-08 15:45:58 -0700699}
700
701#define foreach_msg_api_vector \
702_(msg_names) \
703_(msg_handlers) \
704_(msg_cleanup_handlers) \
705_(msg_endian_handlers) \
706_(msg_print_handlers) \
707_(api_trace_cfg) \
708_(message_bounce) \
709_(is_mp_safe)
710
Dave Barach371e4e12016-07-08 09:38:52 -0400711void
712vl_msg_api_config (vl_msg_api_msg_config_t * c)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700713{
Dave Barach371e4e12016-07-08 09:38:52 -0400714 api_main_t *am = &api_main;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700715
Dave Barach65457162017-10-10 17:53:14 -0400716 /*
717 * This happens during the java core tests if the message
718 * dictionary is missing newly added xxx_reply_t messages.
719 * Should never happen, but since I shot myself in the foot once
720 * this way, I thought I'd make it easy to debug if I ever do
721 * it again... (;-)...
722 */
723 if (c->id == 0)
724 {
725 if (c->name)
726 clib_warning ("Trying to register %s with a NULL msg id!", c->name);
727 else
728 clib_warning ("Trying to register a NULL msg with a NULL msg id!");
729 clib_warning ("Did you forget to call setup_message_id_table?");
730 return;
731 }
Ed Warnickecb9cada2015-12-08 15:45:58 -0700732
733#define _(a) vec_validate (am->a, c->id);
Dave Barach371e4e12016-07-08 09:38:52 -0400734 foreach_msg_api_vector;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700735#undef _
736
Dave Barach392206e2017-09-20 08:40:16 -0400737 if (am->msg_handlers[c->id] && am->msg_handlers[c->id] != c->handler)
738 clib_warning
739 ("BUG: re-registering 'vl_api_%s_t_handler'."
740 "Handler was %llx, replaced by %llx",
741 c->name, am->msg_handlers[c->id], c->handler);
Dave Baracha1a093d2017-03-02 13:13:23 -0500742
Dave Barach371e4e12016-07-08 09:38:52 -0400743 am->msg_names[c->id] = c->name;
744 am->msg_handlers[c->id] = c->handler;
745 am->msg_cleanup_handlers[c->id] = c->cleanup;
746 am->msg_endian_handlers[c->id] = c->endian;
747 am->msg_print_handlers[c->id] = c->print;
748 am->message_bounce[c->id] = c->message_bounce;
749 am->is_mp_safe[c->id] = c->is_mp_safe;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700750
Dave Barach371e4e12016-07-08 09:38:52 -0400751 am->api_trace_cfg[c->id].size = c->size;
752 am->api_trace_cfg[c->id].trace_enable = c->traced;
753 am->api_trace_cfg[c->id].replay_enable = c->replay;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700754}
755
Dave Barach371e4e12016-07-08 09:38:52 -0400756/*
Ed Warnickecb9cada2015-12-08 15:45:58 -0700757 * vl_msg_api_set_handlers
758 * preserve the old API for a while
759 */
Dave Barach371e4e12016-07-08 09:38:52 -0400760void
761vl_msg_api_set_handlers (int id, char *name, void *handler, void *cleanup,
762 void *endian, void *print, int size, int traced)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700763{
Dave Barach371e4e12016-07-08 09:38:52 -0400764 vl_msg_api_msg_config_t cfg;
765 vl_msg_api_msg_config_t *c = &cfg;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700766
Dave Barachb7b92992018-10-17 10:38:51 -0400767 clib_memset (c, 0, sizeof (*c));
Dave Barach0691d6e2017-01-05 10:08:52 -0500768
Dave Barach371e4e12016-07-08 09:38:52 -0400769 c->id = id;
770 c->name = name;
771 c->handler = handler;
772 c->cleanup = cleanup;
773 c->endian = endian;
774 c->print = print;
Dave Barach371e4e12016-07-08 09:38:52 -0400775 c->traced = traced;
776 c->replay = 1;
777 c->message_bounce = 0;
778 c->is_mp_safe = 0;
779 vl_msg_api_config (c);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700780}
781
Dave Barach371e4e12016-07-08 09:38:52 -0400782void
Matej Perina75a17ec2017-09-21 17:03:27 +0200783vl_msg_api_clean_handlers (int msg_id)
784{
785 vl_msg_api_msg_config_t cfg;
786 vl_msg_api_msg_config_t *c = &cfg;
787
Dave Barachb7b92992018-10-17 10:38:51 -0400788 clib_memset (c, 0, sizeof (*c));
Matej Perina75a17ec2017-09-21 17:03:27 +0200789
790 c->id = msg_id;
791 vl_msg_api_config (c);
792}
793
794void
Dave Barach371e4e12016-07-08 09:38:52 -0400795vl_msg_api_set_cleanup_handler (int msg_id, void *fp)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700796{
Dave Barach371e4e12016-07-08 09:38:52 -0400797 api_main_t *am = &api_main;
798 ASSERT (msg_id > 0);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700799
Dave Barach371e4e12016-07-08 09:38:52 -0400800 vec_validate (am->msg_cleanup_handlers, msg_id);
801 am->msg_cleanup_handlers[msg_id] = fp;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700802}
803
Dave Barach371e4e12016-07-08 09:38:52 -0400804void
Florin Corase86a8ed2018-01-05 03:20:25 -0800805vl_msg_api_queue_handler (svm_queue_t * q)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700806{
Dave Barach371e4e12016-07-08 09:38:52 -0400807 uword msg;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700808
Mohsin Kazmi3fca5672018-01-04 18:57:26 +0100809 while (!svm_queue_sub (q, (u8 *) & msg, SVM_Q_WAIT, 0))
Dave Barach371e4e12016-07-08 09:38:52 -0400810 vl_msg_api_handler ((void *) msg);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700811}
812
Dave Barach371e4e12016-07-08 09:38:52 -0400813vl_api_trace_t *
814vl_msg_api_trace_get (api_main_t * am, vl_api_trace_which_t which)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700815{
Dave Barach371e4e12016-07-08 09:38:52 -0400816 switch (which)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700817 {
818 case VL_API_TRACE_RX:
Dave Barach371e4e12016-07-08 09:38:52 -0400819 return am->rx_trace;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700820 case VL_API_TRACE_TX:
Dave Barach371e4e12016-07-08 09:38:52 -0400821 return am->tx_trace;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700822 default:
Dave Barach371e4e12016-07-08 09:38:52 -0400823 return 0;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700824 }
825}
826
Dave Barach371e4e12016-07-08 09:38:52 -0400827void
828vl_noop_handler (void *mp)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700829{
Ed Warnickecb9cada2015-12-08 15:45:58 -0700830}
831
Ed Warnickecb9cada2015-12-08 15:45:58 -0700832
833static u8 post_mortem_dump_enabled;
834
Dave Barach80f54e22017-03-08 19:08:56 -0500835void
836vl_msg_api_post_mortem_dump_enable_disable (int enable)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700837{
Dave Barach80f54e22017-03-08 19:08:56 -0500838 post_mortem_dump_enabled = enable;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700839}
840
Dave Barach371e4e12016-07-08 09:38:52 -0400841void
842vl_msg_api_post_mortem_dump (void)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700843{
Dave Barach371e4e12016-07-08 09:38:52 -0400844 api_main_t *am = &api_main;
845 FILE *fp;
846 char filename[64];
847 int rv;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700848
Dave Barach371e4e12016-07-08 09:38:52 -0400849 if (post_mortem_dump_enabled == 0)
850 return;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700851
Dave Barach371e4e12016-07-08 09:38:52 -0400852 snprintf (filename, sizeof (filename), "/tmp/api_post_mortem.%d",
853 getpid ());
Ed Warnickecb9cada2015-12-08 15:45:58 -0700854
Dave Barach371e4e12016-07-08 09:38:52 -0400855 fp = fopen (filename, "w");
856 if (fp == NULL)
857 {
858 rv = write (2, "Couldn't create ", 16);
859 rv = write (2, filename, strlen (filename));
860 rv = write (2, "\n", 1);
861 return;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700862 }
Dave Barach371e4e12016-07-08 09:38:52 -0400863 rv = vl_msg_api_trace_save (am, VL_API_TRACE_RX, fp);
864 fclose (fp);
865 if (rv < 0)
866 {
867 rv = write (2, "Failed to save post-mortem API trace to ", 40);
868 rv = write (2, filename, strlen (filename));
869 rv = write (2, "\n", 1);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700870 }
Dave Barach371e4e12016-07-08 09:38:52 -0400871
Ed Warnickecb9cada2015-12-08 15:45:58 -0700872}
873
874/* Layered message handling support */
875
Dave Barach371e4e12016-07-08 09:38:52 -0400876void
877vl_msg_api_register_pd_handler (void *fp, u16 msg_id_host_byte_order)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700878{
Dave Barach371e4e12016-07-08 09:38:52 -0400879 api_main_t *am = &api_main;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700880
Dave Barach371e4e12016-07-08 09:38:52 -0400881 /* Mild idiot proofing */
882 if (msg_id_host_byte_order > 10000)
883 clib_warning ("msg_id_host_byte_order endian issue? %d arg vs %d",
884 msg_id_host_byte_order,
885 clib_net_to_host_u16 (msg_id_host_byte_order));
886 vec_validate (am->pd_msg_handlers, msg_id_host_byte_order);
887 am->pd_msg_handlers[msg_id_host_byte_order] = fp;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700888}
889
Dave Barach371e4e12016-07-08 09:38:52 -0400890int
891vl_msg_api_pd_handler (void *mp, int rv)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700892{
Dave Barach371e4e12016-07-08 09:38:52 -0400893 api_main_t *am = &api_main;
894 int (*fp) (void *, int);
895 u16 msg_id;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700896
Dave Barach371e4e12016-07-08 09:38:52 -0400897 if (clib_arch_is_little_endian)
898 msg_id = clib_net_to_host_u16 (*((u16 *) mp));
899 else
900 msg_id = *((u16 *) mp);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700901
Dave Barach371e4e12016-07-08 09:38:52 -0400902 if (msg_id >= vec_len (am->pd_msg_handlers)
903 || am->pd_msg_handlers[msg_id] == 0)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700904 return rv;
Dave Barach371e4e12016-07-08 09:38:52 -0400905
906 fp = am->pd_msg_handlers[msg_id];
907 rv = (*fp) (mp, rv);
908 return rv;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700909}
910
Dave Barach371e4e12016-07-08 09:38:52 -0400911void
912vl_msg_api_set_first_available_msg_id (u16 first_avail)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700913{
Dave Barach371e4e12016-07-08 09:38:52 -0400914 api_main_t *am = &api_main;
915
916 am->first_available_msg_id = first_avail;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700917}
918
Dave Barach371e4e12016-07-08 09:38:52 -0400919u16
Neale Rannse72be392017-04-26 13:59:20 -0700920vl_msg_api_get_msg_ids (const char *name, int n)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700921{
Dave Barach371e4e12016-07-08 09:38:52 -0400922 api_main_t *am = &api_main;
923 u8 *name_copy;
924 vl_api_msg_range_t *rp;
925 uword *p;
926 u16 rv;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700927
Dave Barach371e4e12016-07-08 09:38:52 -0400928 if (am->msg_range_by_name == 0)
929 am->msg_range_by_name = hash_create_string (0, sizeof (uword));
Ed Warnickecb9cada2015-12-08 15:45:58 -0700930
Dave Barach371e4e12016-07-08 09:38:52 -0400931 name_copy = format (0, "%s%c", name, 0);
932
933 p = hash_get_mem (am->msg_range_by_name, name_copy);
934 if (p)
935 {
936 clib_warning ("WARNING: duplicate message range registration for '%s'",
937 name_copy);
938 vec_free (name_copy);
939 return ((u16) ~ 0);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700940 }
941
Dave Barach371e4e12016-07-08 09:38:52 -0400942 if (n < 0 || n > 1024)
943 {
944 clib_warning
945 ("WARNING: bad number of message-IDs (%d) requested by '%s'",
946 n, name_copy);
947 vec_free (name_copy);
948 return ((u16) ~ 0);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700949 }
950
Dave Barach371e4e12016-07-08 09:38:52 -0400951 vec_add2 (am->msg_ranges, rp, 1);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700952
Dave Barach371e4e12016-07-08 09:38:52 -0400953 rv = rp->first_msg_id = am->first_available_msg_id;
954 am->first_available_msg_id += n;
955 rp->last_msg_id = am->first_available_msg_id - 1;
956 rp->name = name_copy;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700957
Dave Barach371e4e12016-07-08 09:38:52 -0400958 hash_set_mem (am->msg_range_by_name, name_copy, rp - am->msg_ranges);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700959
Dave Barach371e4e12016-07-08 09:38:52 -0400960 return rv;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700961}
Dave Barach371e4e12016-07-08 09:38:52 -0400962
Dave Barach557d1282016-11-10 14:22:49 -0500963void
Neale Rannse72be392017-04-26 13:59:20 -0700964vl_msg_api_add_msg_name_crc (api_main_t * am, const char *string, u32 id)
Dave Barach557d1282016-11-10 14:22:49 -0500965{
966 uword *p;
967
968 if (am->msg_index_by_name_and_crc == 0)
969 am->msg_index_by_name_and_crc = hash_create_string (0, sizeof (uword));
970
971 p = hash_get_mem (am->msg_index_by_name_and_crc, string);
972 if (p)
973 {
974 clib_warning ("attempt to redefine '%s' ignored...", string);
975 return;
976 }
977
978 hash_set_mem (am->msg_index_by_name_and_crc, string, id);
979}
980
Dave Barach0d056e52017-09-28 15:11:16 -0400981void
982vl_msg_api_add_version (api_main_t * am, const char *string,
983 u32 major, u32 minor, u32 patch)
984{
985 api_version_t version = {.major = major,.minor = minor,.patch = patch };
986 ASSERT (strlen (string) < 64);
Ole Troan7504e992017-10-10 08:43:35 +0200987 strncpy (version.name, string, 64 - 1);
Dave Barach0d056e52017-09-28 15:11:16 -0400988 vec_add1 (am->api_version_list, version);
989}
Dave Barach557d1282016-11-10 14:22:49 -0500990
Florin Corase86a8ed2018-01-05 03:20:25 -0800991u32
992vl_msg_api_get_msg_index (u8 * name_and_crc)
993{
994 api_main_t *am = &api_main;
995 uword *p;
996
997 if (am->msg_index_by_name_and_crc)
998 {
999 p = hash_get_mem (am->msg_index_by_name_and_crc, name_and_crc);
1000 if (p)
1001 return p[0];
1002 }
1003 return ~0;
1004}
1005
Ole Troan73710c72018-06-04 22:27:49 +02001006void *
1007vl_msg_push_heap (void)
1008{
1009 api_main_t *am = &api_main;
1010 pthread_mutex_lock (&am->vlib_rp->mutex);
1011 return svm_push_data_heap (am->vlib_rp);
1012}
1013
1014void
1015vl_msg_pop_heap (void *oldheap)
1016{
1017 api_main_t *am = &api_main;
1018 svm_pop_heap (oldheap);
1019 pthread_mutex_unlock (&am->vlib_rp->mutex);
1020}
1021
Neale Ranns377860a2019-06-21 07:57:18 -07001022int
1023vl_api_to_api_string (u32 len, const char *buf, vl_api_string_t * str)
1024{
1025 clib_memcpy_fast (str->buf, buf, len);
1026 str->length = htonl (len);
1027 return len + sizeof (u32);
1028}
1029
1030int
1031vl_api_vec_to_api_string (const u8 * vec, vl_api_string_t * str)
1032{
1033 u32 len = vec_len (vec);
1034 clib_memcpy (str->buf, vec, len);
1035 str->length = htonl (len);
1036 return len + sizeof (u32);
1037}
1038
1039/* Return a pointer to the API string (not nul terminated */
1040u8 *
1041vl_api_from_api_string (vl_api_string_t * astr)
1042{
1043 return astr->buf;
1044}
1045
1046u32
1047vl_api_string_len (vl_api_string_t * astr)
1048{
Dave Barach9683c1e2019-07-01 09:42:41 -04001049 return clib_net_to_host_u32 (astr->length);
Neale Ranns377860a2019-06-21 07:57:18 -07001050}
1051
1052/*
1053 * Returns a new vector. Remember to free it after use.
1054 */
1055u8 *
1056vl_api_from_api_to_vec (vl_api_string_t * astr)
1057{
1058 u8 *v = 0;
Dave Barach9683c1e2019-07-01 09:42:41 -04001059 vec_add (v, astr->buf, clib_net_to_host_u32 (astr->length));
Neale Ranns377860a2019-06-21 07:57:18 -07001060 return v;
1061}
Ole Troan73710c72018-06-04 22:27:49 +02001062
Dave Barachb09f4d02019-07-15 16:00:03 -04001063void
1064vl_api_set_elog_main (elog_main_t * m)
1065{
1066 api_main_t *am = &api_main;
1067 am->elog_main = m;
1068}
1069
1070int
1071vl_api_set_elog_trace_api_messages (int enable)
1072{
1073 int rv;
1074 api_main_t *am = &api_main;
1075
1076 rv = am->elog_trace_api_messages;
1077 am->elog_trace_api_messages = enable;
1078 return rv;
1079}
1080
1081int
1082vl_api_get_elog_trace_api_messages (void)
1083{
1084 api_main_t *am = &api_main;
1085
1086 return am->elog_trace_api_messages;
1087}
1088
Dave Barach371e4e12016-07-08 09:38:52 -04001089/*
1090 * fd.io coding-style-patch-verification: ON
1091 *
1092 * Local Variables:
1093 * eval: (c-set-style "gnu")
1094 * End:
1095 */