blob: 355be35c67738f432318fac5a6d00b4c16aabed3 [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))
Dave Barach67947872019-07-19 09:31:29 -0400483 {
484 ed->c = elog_string (am->elog_main, (char *) am->msg_names[id]);
485 ed->barrier = !am->is_mp_safe[id];
486 }
Dave Barachb09f4d02019-07-15 16:00:03 -0400487 else
Dave Barach67947872019-07-19 09:31:29 -0400488 {
489 ed->c = elog_string (am->elog_main, "BOGUS");
490 ed->barrier = 0;
491 }
Dave Barachb09f4d02019-07-15 16:00:03 -0400492 }
Ed Warnickecb9cada2015-12-08 15:45:58 -0700493}
Ed Warnickecb9cada2015-12-08 15:45:58 -0700494
495/* This is only to be called from a vlib/vnet app */
Dave Barach371e4e12016-07-08 09:38:52 -0400496void
497vl_msg_api_handler_with_vm_node (api_main_t * am,
498 void *the_msg, vlib_main_t * vm,
499 vlib_node_runtime_t * node)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700500{
Dave Barach9683c1e2019-07-01 09:42:41 -0400501 u16 id = clib_net_to_host_u16 (*((u16 *) the_msg));
Dave Barach371e4e12016-07-08 09:38:52 -0400502 u8 *(*handler) (void *, void *, void *);
ezkexma75f9fb62019-03-21 07:38:19 -0400503 u8 *(*print_fp) (void *, void *);
Dave Barachc898a4f2019-06-14 17:29:55 -0400504 int is_mp_safe = 1;
Dave Barach371e4e12016-07-08 09:38:52 -0400505
Dave Barachb09f4d02019-07-15 16:00:03 -0400506 if (PREDICT_FALSE (am->elog_trace_api_messages))
Dave Barach371e4e12016-07-08 09:38:52 -0400507 {
Dave Barachc3a06552018-10-01 09:25:32 -0400508 /* *INDENT-OFF* */
509 ELOG_TYPE_DECLARE (e) =
510 {
511 .format = "api-msg: %s",
512 .format_args = "T4",
513 };
514 /* *INDENT-ON* */
515 struct
516 {
517 u32 c;
518 } *ed;
Dave Barachb09f4d02019-07-15 16:00:03 -0400519 ed = ELOG_DATA (am->elog_main, e);
Dave Barachc3a06552018-10-01 09:25:32 -0400520 if (id < vec_len (am->msg_names))
Dave Barachb09f4d02019-07-15 16:00:03 -0400521 ed->c = elog_string (am->elog_main, (char *) am->msg_names[id]);
Dave Barachc3a06552018-10-01 09:25:32 -0400522 else
Dave Barachb09f4d02019-07-15 16:00:03 -0400523 ed->c = elog_string (am->elog_main, "BOGUS");
Dave Barachc3a06552018-10-01 09:25:32 -0400524 }
Dave Barach371e4e12016-07-08 09:38:52 -0400525
526 if (id < vec_len (am->msg_handlers) && am->msg_handlers[id])
527 {
528 handler = (void *) am->msg_handlers[id];
529
ezkexma75f9fb62019-03-21 07:38:19 -0400530 if (PREDICT_FALSE (am->rx_trace && am->rx_trace->enabled))
Dave Barach371e4e12016-07-08 09:38:52 -0400531 vl_msg_api_trace (am, am->rx_trace, the_msg);
532
ezkexma75f9fb62019-03-21 07:38:19 -0400533 if (PREDICT_FALSE (am->msg_print_flag))
534 {
535 fformat (stdout, "[%d]: %s\n", id, am->msg_names[id]);
536 print_fp = (void *) am->msg_print_handlers[id];
537 if (print_fp == 0)
538 {
539 fformat (stdout, " [no registered print fn for msg %d]\n", id);
540 }
541 else
542 {
543 (*print_fp) (the_msg, vm);
544 }
545 }
Dave Barachc898a4f2019-06-14 17:29:55 -0400546 is_mp_safe = am->is_mp_safe[id];
ezkexma75f9fb62019-03-21 07:38:19 -0400547
Dave Barachc898a4f2019-06-14 17:29:55 -0400548 if (!is_mp_safe)
Colin Tregenza Dancereb1ac172017-09-06 20:23:24 +0100549 {
550 vl_msg_api_barrier_trace_context (am->msg_names[id]);
551 vl_msg_api_barrier_sync ();
552 }
Dave Barach371e4e12016-07-08 09:38:52 -0400553 (*handler) (the_msg, vm, node);
Dave Barachc898a4f2019-06-14 17:29:55 -0400554 if (!is_mp_safe)
Dave Barach371e4e12016-07-08 09:38:52 -0400555 vl_msg_api_barrier_release ();
556 }
557 else
558 {
Jon Loeligerf95b37e2017-02-13 15:21:12 -0600559 clib_warning ("no handler for msg id %d", id);
Dave Barach371e4e12016-07-08 09:38:52 -0400560 }
561
562 /*
Ed Warnickecb9cada2015-12-08 15:45:58 -0700563 * Special-case, so we can e.g. bounce messages off the vnet
564 * main thread without copying them...
565 */
566 if (!(am->message_bounce[id]))
Dave Barach371e4e12016-07-08 09:38:52 -0400567 vl_msg_api_free (the_msg);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700568
Dave Barachb09f4d02019-07-15 16:00:03 -0400569 if (PREDICT_FALSE (am->elog_trace_api_messages))
Ed Warnickecb9cada2015-12-08 15:45:58 -0700570 {
Dave Barachc3a06552018-10-01 09:25:32 -0400571 /* *INDENT-OFF* */
Dave Barachc898a4f2019-06-14 17:29:55 -0400572 ELOG_TYPE_DECLARE (e) =
573 {
574 .format = "api-msg-done(%s): %s",
575 .format_args = "t4T4",
576 .n_enum_strings = 2,
577 .enum_strings =
578 {
579 "barrier",
580 "mp-safe",
581 }
582 };
Dave Barachc3a06552018-10-01 09:25:32 -0400583 /* *INDENT-ON* */
584
585 struct
586 {
Dave Barachc898a4f2019-06-14 17:29:55 -0400587 u32 barrier;
Dave Barachc3a06552018-10-01 09:25:32 -0400588 u32 c;
589 } *ed;
Dave Barachb09f4d02019-07-15 16:00:03 -0400590 ed = ELOG_DATA (am->elog_main, e);
Dave Barachc3a06552018-10-01 09:25:32 -0400591 if (id < vec_len (am->msg_names))
Dave Barachb09f4d02019-07-15 16:00:03 -0400592 ed->c = elog_string (am->elog_main, (char *) am->msg_names[id]);
Dave Barachc3a06552018-10-01 09:25:32 -0400593 else
Dave Barachb09f4d02019-07-15 16:00:03 -0400594 ed->c = elog_string (am->elog_main, "BOGUS");
Dave Barachc898a4f2019-06-14 17:29:55 -0400595 ed->barrier = is_mp_safe;
Dave Barachc3a06552018-10-01 09:25:32 -0400596 }
Ed Warnickecb9cada2015-12-08 15:45:58 -0700597}
598
Dave Barach371e4e12016-07-08 09:38:52 -0400599void
600vl_msg_api_handler (void *the_msg)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700601{
Dave Barach371e4e12016-07-08 09:38:52 -0400602 api_main_t *am = &api_main;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700603
Dave Barach371e4e12016-07-08 09:38:52 -0400604 msg_handler_internal (am, the_msg,
605 (am->rx_trace
606 && am->rx_trace->enabled) /* trace_it */ ,
607 1 /* do_it */ , 1 /* free_it */ );
Ed Warnickecb9cada2015-12-08 15:45:58 -0700608}
609
Dave Barach371e4e12016-07-08 09:38:52 -0400610void
611vl_msg_api_handler_no_free (void *the_msg)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700612{
Dave Barach371e4e12016-07-08 09:38:52 -0400613 api_main_t *am = &api_main;
614 msg_handler_internal (am, the_msg,
615 (am->rx_trace
616 && am->rx_trace->enabled) /* trace_it */ ,
617 1 /* do_it */ , 0 /* free_it */ );
Ed Warnickecb9cada2015-12-08 15:45:58 -0700618}
619
Dave Barach371e4e12016-07-08 09:38:52 -0400620void
621vl_msg_api_handler_no_trace_no_free (void *the_msg)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700622{
Dave Barach371e4e12016-07-08 09:38:52 -0400623 api_main_t *am = &api_main;
624 msg_handler_internal (am, the_msg, 0 /* trace_it */ , 1 /* do_it */ ,
625 0 /* free_it */ );
Ed Warnickecb9cada2015-12-08 15:45:58 -0700626}
627
628/*
629 * Add a trace record to the API message trace buffer, if
630 * API message tracing is enabled. Handy for adding sufficient
631 * data to the trace to reproduce autonomous state, as opposed to
Dave Barach371e4e12016-07-08 09:38:52 -0400632 * state downloaded via control-plane API messages. Example: the NAT
Ed Warnickecb9cada2015-12-08 15:45:58 -0700633 * application creates database entries based on packet traffic, not
634 * control-plane messages.
635 *
636 */
Dave Barach371e4e12016-07-08 09:38:52 -0400637void
638vl_msg_api_trace_only (void *the_msg)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700639{
Dave Barach371e4e12016-07-08 09:38:52 -0400640 api_main_t *am = &api_main;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700641
Dave Barach371e4e12016-07-08 09:38:52 -0400642 msg_handler_internal (am, the_msg,
643 (am->rx_trace
644 && am->rx_trace->enabled) /* trace_it */ ,
645 0 /* do_it */ , 0 /* free_it */ );
Ed Warnickecb9cada2015-12-08 15:45:58 -0700646}
647
Dave Barach371e4e12016-07-08 09:38:52 -0400648void
649vl_msg_api_cleanup_handler (void *the_msg)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700650{
Dave Barach371e4e12016-07-08 09:38:52 -0400651 api_main_t *am = &api_main;
Dave Barach9683c1e2019-07-01 09:42:41 -0400652 u16 id = clib_net_to_host_u16 (*((u16 *) the_msg));
Ed Warnickecb9cada2015-12-08 15:45:58 -0700653
Dave Barach371e4e12016-07-08 09:38:52 -0400654 if (PREDICT_FALSE (id >= vec_len (am->msg_cleanup_handlers)))
655 {
656 clib_warning ("_vl_msg_id too large: %d\n", id);
657 return;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700658 }
Dave Barach371e4e12016-07-08 09:38:52 -0400659 if (am->msg_cleanup_handlers[id])
660 (*am->msg_cleanup_handlers[id]) (the_msg);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700661
Dave Barach371e4e12016-07-08 09:38:52 -0400662 vl_msg_api_free (the_msg);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700663}
664
665/*
666 * vl_msg_api_replay_handler
667 */
Dave Barach371e4e12016-07-08 09:38:52 -0400668void
669vl_msg_api_replay_handler (void *the_msg)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700670{
Dave Barach371e4e12016-07-08 09:38:52 -0400671 api_main_t *am = &api_main;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700672
Dave Barach9683c1e2019-07-01 09:42:41 -0400673 u16 id = clib_net_to_host_u16 (*((u16 *) the_msg));
Ed Warnickecb9cada2015-12-08 15:45:58 -0700674
Dave Barach371e4e12016-07-08 09:38:52 -0400675 if (PREDICT_FALSE (id >= vec_len (am->msg_handlers)))
676 {
677 clib_warning ("_vl_msg_id too large: %d\n", id);
678 return;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700679 }
Dave Barach371e4e12016-07-08 09:38:52 -0400680 /* do NOT trace the message... */
681 if (am->msg_handlers[id])
682 (*am->msg_handlers[id]) (the_msg);
683 /* do NOT free the message buffer... */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700684}
Dave Barach371e4e12016-07-08 09:38:52 -0400685
Dave Barachbfd92272017-05-12 11:59:25 -0400686u32
687vl_msg_api_get_msg_length (void *msg_arg)
688{
689 return vl_msg_api_get_msg_length_inline (msg_arg);
690}
691
Ed Warnickecb9cada2015-12-08 15:45:58 -0700692/*
693 * vl_msg_api_socket_handler
694 */
Dave Barach371e4e12016-07-08 09:38:52 -0400695void
696vl_msg_api_socket_handler (void *the_msg)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700697{
Dave Barach371e4e12016-07-08 09:38:52 -0400698 api_main_t *am = &api_main;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700699
Dave Barach371e4e12016-07-08 09:38:52 -0400700 msg_handler_internal (am, the_msg,
701 (am->rx_trace
702 && am->rx_trace->enabled) /* trace_it */ ,
703 1 /* do_it */ , 0 /* free_it */ );
Ed Warnickecb9cada2015-12-08 15:45:58 -0700704}
705
706#define foreach_msg_api_vector \
707_(msg_names) \
708_(msg_handlers) \
709_(msg_cleanup_handlers) \
710_(msg_endian_handlers) \
711_(msg_print_handlers) \
712_(api_trace_cfg) \
713_(message_bounce) \
714_(is_mp_safe)
715
Dave Barach371e4e12016-07-08 09:38:52 -0400716void
717vl_msg_api_config (vl_msg_api_msg_config_t * c)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700718{
Dave Barach371e4e12016-07-08 09:38:52 -0400719 api_main_t *am = &api_main;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700720
Dave Barach65457162017-10-10 17:53:14 -0400721 /*
722 * This happens during the java core tests if the message
723 * dictionary is missing newly added xxx_reply_t messages.
724 * Should never happen, but since I shot myself in the foot once
725 * this way, I thought I'd make it easy to debug if I ever do
726 * it again... (;-)...
727 */
728 if (c->id == 0)
729 {
730 if (c->name)
731 clib_warning ("Trying to register %s with a NULL msg id!", c->name);
732 else
733 clib_warning ("Trying to register a NULL msg with a NULL msg id!");
734 clib_warning ("Did you forget to call setup_message_id_table?");
735 return;
736 }
Ed Warnickecb9cada2015-12-08 15:45:58 -0700737
738#define _(a) vec_validate (am->a, c->id);
Dave Barach371e4e12016-07-08 09:38:52 -0400739 foreach_msg_api_vector;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700740#undef _
741
Dave Barach392206e2017-09-20 08:40:16 -0400742 if (am->msg_handlers[c->id] && am->msg_handlers[c->id] != c->handler)
743 clib_warning
744 ("BUG: re-registering 'vl_api_%s_t_handler'."
745 "Handler was %llx, replaced by %llx",
746 c->name, am->msg_handlers[c->id], c->handler);
Dave Baracha1a093d2017-03-02 13:13:23 -0500747
Dave Barach371e4e12016-07-08 09:38:52 -0400748 am->msg_names[c->id] = c->name;
749 am->msg_handlers[c->id] = c->handler;
750 am->msg_cleanup_handlers[c->id] = c->cleanup;
751 am->msg_endian_handlers[c->id] = c->endian;
752 am->msg_print_handlers[c->id] = c->print;
753 am->message_bounce[c->id] = c->message_bounce;
754 am->is_mp_safe[c->id] = c->is_mp_safe;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700755
Dave Barach371e4e12016-07-08 09:38:52 -0400756 am->api_trace_cfg[c->id].size = c->size;
757 am->api_trace_cfg[c->id].trace_enable = c->traced;
758 am->api_trace_cfg[c->id].replay_enable = c->replay;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700759}
760
Dave Barach371e4e12016-07-08 09:38:52 -0400761/*
Ed Warnickecb9cada2015-12-08 15:45:58 -0700762 * vl_msg_api_set_handlers
763 * preserve the old API for a while
764 */
Dave Barach371e4e12016-07-08 09:38:52 -0400765void
766vl_msg_api_set_handlers (int id, char *name, void *handler, void *cleanup,
767 void *endian, void *print, int size, int traced)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700768{
Dave Barach371e4e12016-07-08 09:38:52 -0400769 vl_msg_api_msg_config_t cfg;
770 vl_msg_api_msg_config_t *c = &cfg;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700771
Dave Barachb7b92992018-10-17 10:38:51 -0400772 clib_memset (c, 0, sizeof (*c));
Dave Barach0691d6e2017-01-05 10:08:52 -0500773
Dave Barach371e4e12016-07-08 09:38:52 -0400774 c->id = id;
775 c->name = name;
776 c->handler = handler;
777 c->cleanup = cleanup;
778 c->endian = endian;
779 c->print = print;
Dave Barach371e4e12016-07-08 09:38:52 -0400780 c->traced = traced;
781 c->replay = 1;
782 c->message_bounce = 0;
783 c->is_mp_safe = 0;
784 vl_msg_api_config (c);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700785}
786
Dave Barach371e4e12016-07-08 09:38:52 -0400787void
Matej Perina75a17ec2017-09-21 17:03:27 +0200788vl_msg_api_clean_handlers (int msg_id)
789{
790 vl_msg_api_msg_config_t cfg;
791 vl_msg_api_msg_config_t *c = &cfg;
792
Dave Barachb7b92992018-10-17 10:38:51 -0400793 clib_memset (c, 0, sizeof (*c));
Matej Perina75a17ec2017-09-21 17:03:27 +0200794
795 c->id = msg_id;
796 vl_msg_api_config (c);
797}
798
799void
Dave Barach371e4e12016-07-08 09:38:52 -0400800vl_msg_api_set_cleanup_handler (int msg_id, void *fp)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700801{
Dave Barach371e4e12016-07-08 09:38:52 -0400802 api_main_t *am = &api_main;
803 ASSERT (msg_id > 0);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700804
Dave Barach371e4e12016-07-08 09:38:52 -0400805 vec_validate (am->msg_cleanup_handlers, msg_id);
806 am->msg_cleanup_handlers[msg_id] = fp;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700807}
808
Dave Barach371e4e12016-07-08 09:38:52 -0400809void
Florin Corase86a8ed2018-01-05 03:20:25 -0800810vl_msg_api_queue_handler (svm_queue_t * q)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700811{
Dave Barach371e4e12016-07-08 09:38:52 -0400812 uword msg;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700813
Mohsin Kazmi3fca5672018-01-04 18:57:26 +0100814 while (!svm_queue_sub (q, (u8 *) & msg, SVM_Q_WAIT, 0))
Dave Barach371e4e12016-07-08 09:38:52 -0400815 vl_msg_api_handler ((void *) msg);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700816}
817
Dave Barach371e4e12016-07-08 09:38:52 -0400818vl_api_trace_t *
819vl_msg_api_trace_get (api_main_t * am, vl_api_trace_which_t which)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700820{
Dave Barach371e4e12016-07-08 09:38:52 -0400821 switch (which)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700822 {
823 case VL_API_TRACE_RX:
Dave Barach371e4e12016-07-08 09:38:52 -0400824 return am->rx_trace;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700825 case VL_API_TRACE_TX:
Dave Barach371e4e12016-07-08 09:38:52 -0400826 return am->tx_trace;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700827 default:
Dave Barach371e4e12016-07-08 09:38:52 -0400828 return 0;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700829 }
830}
831
Dave Barach371e4e12016-07-08 09:38:52 -0400832void
833vl_noop_handler (void *mp)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700834{
Ed Warnickecb9cada2015-12-08 15:45:58 -0700835}
836
Ed Warnickecb9cada2015-12-08 15:45:58 -0700837
838static u8 post_mortem_dump_enabled;
839
Dave Barach80f54e22017-03-08 19:08:56 -0500840void
841vl_msg_api_post_mortem_dump_enable_disable (int enable)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700842{
Dave Barach80f54e22017-03-08 19:08:56 -0500843 post_mortem_dump_enabled = enable;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700844}
845
Dave Barach371e4e12016-07-08 09:38:52 -0400846void
847vl_msg_api_post_mortem_dump (void)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700848{
Dave Barach371e4e12016-07-08 09:38:52 -0400849 api_main_t *am = &api_main;
850 FILE *fp;
851 char filename[64];
852 int rv;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700853
Dave Barach371e4e12016-07-08 09:38:52 -0400854 if (post_mortem_dump_enabled == 0)
855 return;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700856
Dave Barach371e4e12016-07-08 09:38:52 -0400857 snprintf (filename, sizeof (filename), "/tmp/api_post_mortem.%d",
858 getpid ());
Ed Warnickecb9cada2015-12-08 15:45:58 -0700859
Dave Barach371e4e12016-07-08 09:38:52 -0400860 fp = fopen (filename, "w");
861 if (fp == NULL)
862 {
863 rv = write (2, "Couldn't create ", 16);
864 rv = write (2, filename, strlen (filename));
865 rv = write (2, "\n", 1);
866 return;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700867 }
Dave Barach371e4e12016-07-08 09:38:52 -0400868 rv = vl_msg_api_trace_save (am, VL_API_TRACE_RX, fp);
869 fclose (fp);
870 if (rv < 0)
871 {
872 rv = write (2, "Failed to save post-mortem API trace to ", 40);
873 rv = write (2, filename, strlen (filename));
874 rv = write (2, "\n", 1);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700875 }
Dave Barach371e4e12016-07-08 09:38:52 -0400876
Ed Warnickecb9cada2015-12-08 15:45:58 -0700877}
878
879/* Layered message handling support */
880
Dave Barach371e4e12016-07-08 09:38:52 -0400881void
882vl_msg_api_register_pd_handler (void *fp, u16 msg_id_host_byte_order)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700883{
Dave Barach371e4e12016-07-08 09:38:52 -0400884 api_main_t *am = &api_main;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700885
Dave Barach371e4e12016-07-08 09:38:52 -0400886 /* Mild idiot proofing */
887 if (msg_id_host_byte_order > 10000)
888 clib_warning ("msg_id_host_byte_order endian issue? %d arg vs %d",
889 msg_id_host_byte_order,
890 clib_net_to_host_u16 (msg_id_host_byte_order));
891 vec_validate (am->pd_msg_handlers, msg_id_host_byte_order);
892 am->pd_msg_handlers[msg_id_host_byte_order] = fp;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700893}
894
Dave Barach371e4e12016-07-08 09:38:52 -0400895int
896vl_msg_api_pd_handler (void *mp, int rv)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700897{
Dave Barach371e4e12016-07-08 09:38:52 -0400898 api_main_t *am = &api_main;
899 int (*fp) (void *, int);
900 u16 msg_id;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700901
Dave Barach371e4e12016-07-08 09:38:52 -0400902 if (clib_arch_is_little_endian)
903 msg_id = clib_net_to_host_u16 (*((u16 *) mp));
904 else
905 msg_id = *((u16 *) mp);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700906
Dave Barach371e4e12016-07-08 09:38:52 -0400907 if (msg_id >= vec_len (am->pd_msg_handlers)
908 || am->pd_msg_handlers[msg_id] == 0)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700909 return rv;
Dave Barach371e4e12016-07-08 09:38:52 -0400910
911 fp = am->pd_msg_handlers[msg_id];
912 rv = (*fp) (mp, rv);
913 return rv;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700914}
915
Dave Barach371e4e12016-07-08 09:38:52 -0400916void
917vl_msg_api_set_first_available_msg_id (u16 first_avail)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700918{
Dave Barach371e4e12016-07-08 09:38:52 -0400919 api_main_t *am = &api_main;
920
921 am->first_available_msg_id = first_avail;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700922}
923
Dave Barach371e4e12016-07-08 09:38:52 -0400924u16
Neale Rannse72be392017-04-26 13:59:20 -0700925vl_msg_api_get_msg_ids (const char *name, int n)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700926{
Dave Barach371e4e12016-07-08 09:38:52 -0400927 api_main_t *am = &api_main;
928 u8 *name_copy;
929 vl_api_msg_range_t *rp;
930 uword *p;
931 u16 rv;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700932
Dave Barach371e4e12016-07-08 09:38:52 -0400933 if (am->msg_range_by_name == 0)
934 am->msg_range_by_name = hash_create_string (0, sizeof (uword));
Ed Warnickecb9cada2015-12-08 15:45:58 -0700935
Dave Barach371e4e12016-07-08 09:38:52 -0400936 name_copy = format (0, "%s%c", name, 0);
937
938 p = hash_get_mem (am->msg_range_by_name, name_copy);
939 if (p)
940 {
941 clib_warning ("WARNING: duplicate message range registration for '%s'",
942 name_copy);
943 vec_free (name_copy);
944 return ((u16) ~ 0);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700945 }
946
Dave Barach371e4e12016-07-08 09:38:52 -0400947 if (n < 0 || n > 1024)
948 {
949 clib_warning
950 ("WARNING: bad number of message-IDs (%d) requested by '%s'",
951 n, name_copy);
952 vec_free (name_copy);
953 return ((u16) ~ 0);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700954 }
955
Dave Barach371e4e12016-07-08 09:38:52 -0400956 vec_add2 (am->msg_ranges, rp, 1);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700957
Dave Barach371e4e12016-07-08 09:38:52 -0400958 rv = rp->first_msg_id = am->first_available_msg_id;
959 am->first_available_msg_id += n;
960 rp->last_msg_id = am->first_available_msg_id - 1;
961 rp->name = name_copy;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700962
Dave Barach371e4e12016-07-08 09:38:52 -0400963 hash_set_mem (am->msg_range_by_name, name_copy, rp - am->msg_ranges);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700964
Dave Barach371e4e12016-07-08 09:38:52 -0400965 return rv;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700966}
Dave Barach371e4e12016-07-08 09:38:52 -0400967
Dave Barach557d1282016-11-10 14:22:49 -0500968void
Neale Rannse72be392017-04-26 13:59:20 -0700969vl_msg_api_add_msg_name_crc (api_main_t * am, const char *string, u32 id)
Dave Barach557d1282016-11-10 14:22:49 -0500970{
971 uword *p;
972
973 if (am->msg_index_by_name_and_crc == 0)
974 am->msg_index_by_name_and_crc = hash_create_string (0, sizeof (uword));
975
976 p = hash_get_mem (am->msg_index_by_name_and_crc, string);
977 if (p)
978 {
979 clib_warning ("attempt to redefine '%s' ignored...", string);
980 return;
981 }
982
983 hash_set_mem (am->msg_index_by_name_and_crc, string, id);
984}
985
Dave Barach0d056e52017-09-28 15:11:16 -0400986void
987vl_msg_api_add_version (api_main_t * am, const char *string,
988 u32 major, u32 minor, u32 patch)
989{
990 api_version_t version = {.major = major,.minor = minor,.patch = patch };
991 ASSERT (strlen (string) < 64);
Ole Troan7504e992017-10-10 08:43:35 +0200992 strncpy (version.name, string, 64 - 1);
Dave Barach0d056e52017-09-28 15:11:16 -0400993 vec_add1 (am->api_version_list, version);
994}
Dave Barach557d1282016-11-10 14:22:49 -0500995
Florin Corase86a8ed2018-01-05 03:20:25 -0800996u32
997vl_msg_api_get_msg_index (u8 * name_and_crc)
998{
999 api_main_t *am = &api_main;
1000 uword *p;
1001
1002 if (am->msg_index_by_name_and_crc)
1003 {
1004 p = hash_get_mem (am->msg_index_by_name_and_crc, name_and_crc);
1005 if (p)
1006 return p[0];
1007 }
1008 return ~0;
1009}
1010
Ole Troan73710c72018-06-04 22:27:49 +02001011void *
1012vl_msg_push_heap (void)
1013{
1014 api_main_t *am = &api_main;
1015 pthread_mutex_lock (&am->vlib_rp->mutex);
1016 return svm_push_data_heap (am->vlib_rp);
1017}
1018
1019void
1020vl_msg_pop_heap (void *oldheap)
1021{
1022 api_main_t *am = &api_main;
1023 svm_pop_heap (oldheap);
1024 pthread_mutex_unlock (&am->vlib_rp->mutex);
1025}
1026
Neale Ranns377860a2019-06-21 07:57:18 -07001027int
1028vl_api_to_api_string (u32 len, const char *buf, vl_api_string_t * str)
1029{
1030 clib_memcpy_fast (str->buf, buf, len);
1031 str->length = htonl (len);
1032 return len + sizeof (u32);
1033}
1034
1035int
1036vl_api_vec_to_api_string (const u8 * vec, vl_api_string_t * str)
1037{
1038 u32 len = vec_len (vec);
1039 clib_memcpy (str->buf, vec, len);
1040 str->length = htonl (len);
1041 return len + sizeof (u32);
1042}
1043
1044/* Return a pointer to the API string (not nul terminated */
1045u8 *
1046vl_api_from_api_string (vl_api_string_t * astr)
1047{
1048 return astr->buf;
1049}
1050
1051u32
1052vl_api_string_len (vl_api_string_t * astr)
1053{
Dave Barach9683c1e2019-07-01 09:42:41 -04001054 return clib_net_to_host_u32 (astr->length);
Neale Ranns377860a2019-06-21 07:57:18 -07001055}
1056
1057/*
1058 * Returns a new vector. Remember to free it after use.
1059 */
1060u8 *
1061vl_api_from_api_to_vec (vl_api_string_t * astr)
1062{
1063 u8 *v = 0;
Dave Barach9683c1e2019-07-01 09:42:41 -04001064 vec_add (v, astr->buf, clib_net_to_host_u32 (astr->length));
Neale Ranns377860a2019-06-21 07:57:18 -07001065 return v;
1066}
Ole Troan73710c72018-06-04 22:27:49 +02001067
Dave Barachb09f4d02019-07-15 16:00:03 -04001068void
1069vl_api_set_elog_main (elog_main_t * m)
1070{
1071 api_main_t *am = &api_main;
1072 am->elog_main = m;
1073}
1074
1075int
1076vl_api_set_elog_trace_api_messages (int enable)
1077{
1078 int rv;
1079 api_main_t *am = &api_main;
1080
1081 rv = am->elog_trace_api_messages;
1082 am->elog_trace_api_messages = enable;
1083 return rv;
1084}
1085
1086int
1087vl_api_get_elog_trace_api_messages (void)
1088{
1089 api_main_t *am = &api_main;
1090
1091 return am->elog_trace_api_messages;
1092}
1093
Dave Barach371e4e12016-07-08 09:38:52 -04001094/*
1095 * fd.io coding-style-patch-verification: ON
1096 *
1097 * Local Variables:
1098 * eval: (c-set-style "gnu")
1099 * End:
1100 */