api: API trace improvements
Type: improvement * add support for JSON format in API trace * add ability to replay JSON API trace in both VPP and VAT2 * use CRC for backward compatibility check during JSON API replay * fix API trace CLI (and remove duplicits) * remove custom dump * remove vppapitrace.py * update docs accordingly Change-Id: I5294f68bebe6cbe738630f457f3a87720e06486b Signed-off-by: Filip Tehlar <ftehlar@cisco.com> Signed-off-by: Ole Troan <ot@cisco.com>
This commit is contained in:
+2
-2
@@ -4,6 +4,6 @@
|
||||
About
|
||||
=====
|
||||
|
||||
**VPP Version:** 21.06-rc0~304-ga73e7568c
|
||||
**VPP Version:** 21.10-rc0~204-g13e841847
|
||||
|
||||
**Built on:** Fri Feb 19 23:40:45 GMT 2021
|
||||
**Built on:** Thu Jul 22 23:44:06 GMT 2021
|
||||
|
||||
@@ -206,11 +206,10 @@ out the set of plugins:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
DBGvpp# api trace custom-dump /tmp/api_trace
|
||||
vl_api_trace_plugin_msg_ids: abf_54307ba2 first 846 last 855
|
||||
vl_api_trace_plugin_msg_ids: acl_0d7265b0 first 856 last 893
|
||||
vl_api_trace_plugin_msg_ids: cdp_8f707b96 first 894 last 895
|
||||
vl_api_trace_plugin_msg_ids: flowprobe_f2f0286c first 898 last 901
|
||||
DBGvpp# api trace dump /tmp/api_trace
|
||||
vl_api_trace_plugin_msg_ids: arp_cfdf7292 first 49 last 56
|
||||
vl_api_trace_plugin_msg_ids: ip6_nd_ac628462 first 57 last 69
|
||||
vl_api_trace_plugin_msg_ids: rd_cp_8a996e86 first 70 last 71
|
||||
<etc>
|
||||
|
||||
Here, we see the "abf," "acl," "cdp," and "flowprobe" plugins. Use the
|
||||
@@ -239,7 +238,7 @@ __________________________
|
||||
Along the same lines, it may be necessary to manufacture [simulated]
|
||||
physical interfaces so that an API trace will replay correctly. "show
|
||||
interface" on the trace origin system can help. An API trace
|
||||
"custom-dump" as shown above may make it obvious how many loopback
|
||||
dump as shown above may make it obvious how many loopback
|
||||
interfaces to create. If you see vhost interfaces being created and
|
||||
then configured, the first such configuration message in the trace
|
||||
will tell you how many physical interfaces were involved.
|
||||
|
||||
@@ -1,58 +1,59 @@
|
||||
.. _interface:
|
||||
|
||||
.. toctree::
|
||||
|
||||
.. note:: For a complete list of CLI Debug commands refer to the Debug CLI section of the `Source Code Documents <https://docs.fd.io/vpp/18.07/clicmd.html>`_ .
|
||||
|
||||
|
||||
API Trace
|
||||
===========
|
||||
|
||||
Summary/Usage
|
||||
--------------
|
||||
|
||||
api trace [on|off][first <*n*>][last <*n*>][status][free][post-mortem-on][dump|custom-dump|save|replay <*file*>]
|
||||
|
||||
Description
|
||||
------------
|
||||
|
||||
Display, replay, or save a binary API trace.
|
||||
|
||||
Declaration and Implementation
|
||||
-------------------------------
|
||||
|
||||
**Declaration:** api_trace_command (src/vlibmemory/vlib_api_cli.c line 783)
|
||||
|
||||
**Implementation:** api_trace_command_fn
|
||||
|
||||
Clear Trace
|
||||
=============
|
||||
|
||||
Summary/Usage
|
||||
--------------
|
||||
Clear trace buffer and free memory.
|
||||
Declaration and implementation
|
||||
|
||||
**Declaration:** clear_trace_cli (src/vlib/trace.c line 519)
|
||||
|
||||
**Implementation:** cli_clear_trace_buffer
|
||||
|
||||
Show Trace
|
||||
===========
|
||||
|
||||
`Show Trace <../show/show.html#show-trace>`_
|
||||
|
||||
Trace Add
|
||||
===========
|
||||
|
||||
Summary/Usage
|
||||
--------------
|
||||
|
||||
Trace given number of packets.
|
||||
|
||||
Declaration and Implementation
|
||||
-------------------------------
|
||||
|
||||
**Declaration:** add_trace_cli (src/vlib/trace.c line 405)
|
||||
|
||||
**Implementation:** cli_add_trace_buffer
|
||||
.. _interface:
|
||||
|
||||
.. toctree::
|
||||
|
||||
.. note:: For a complete list of CLI Debug commands refer to the Debug CLI section of the `Source Code Documents <https://docs.fd.io/vpp/18.07/clicmd.html>`_ .
|
||||
|
||||
|
||||
API Trace
|
||||
===========
|
||||
|
||||
Summary/Usage
|
||||
--------------
|
||||
|
||||
api trace [tx][on|off][first <n>][last <n>][status][free]
|
||||
[post-mortem-on][dump|dump-file|dump-json|save|tojson|save-json|replay <file>][nitems <n>][initializers <file>]
|
||||
|
||||
Description
|
||||
------------
|
||||
|
||||
Display, replay, or save a binary API trace.
|
||||
|
||||
Declaration and Implementation
|
||||
-------------------------------
|
||||
|
||||
**Declaration:** api_trace_command (src/vlibmemory/vlib_api_cli.c line 783)
|
||||
|
||||
**Implementation:** api_trace_command_fn
|
||||
|
||||
Clear Trace
|
||||
=============
|
||||
|
||||
Summary/Usage
|
||||
--------------
|
||||
Clear trace buffer and free memory.
|
||||
Declaration and implementation
|
||||
|
||||
**Declaration:** clear_trace_cli (src/vlib/trace.c line 519)
|
||||
|
||||
**Implementation:** cli_clear_trace_buffer
|
||||
|
||||
Show Trace
|
||||
===========
|
||||
|
||||
`Show Trace <../show/show.html#show-trace>`_
|
||||
|
||||
Trace Add
|
||||
===========
|
||||
|
||||
Summary/Usage
|
||||
--------------
|
||||
|
||||
Trace given number of packets.
|
||||
|
||||
Declaration and Implementation
|
||||
-------------------------------
|
||||
|
||||
**Declaration:** add_trace_cli (src/vlib/trace.c line 405)
|
||||
|
||||
**Implementation:** cli_add_trace_buffer
|
||||
|
||||
@@ -569,10 +569,11 @@ echo_api_hookup (echo_main_t * em)
|
||||
return;
|
||||
|
||||
#define _(N, n) \
|
||||
vl_msg_api_set_handlers (REPLY_MSG_ID_BASE + VL_API_##N, #n, \
|
||||
vl_api_##n##_t_handler, vl_noop_handler, \
|
||||
vl_api_##n##_t_endian, vl_api_##n##_t_print, \
|
||||
sizeof (vl_api_##n##_t), 1);
|
||||
vl_msg_api_set_handlers ( \
|
||||
REPLY_MSG_ID_BASE + VL_API_##N, #n, vl_api_##n##_t_handler, \
|
||||
vl_noop_handler, vl_api_##n##_t_endian, vl_api_##n##_t_print, \
|
||||
sizeof (vl_api_##n##_t), 1, vl_api_##n##_t_print_json, \
|
||||
vl_api_##n##_t_tojson, vl_api_##n##_t_fromjson);
|
||||
foreach_quic_echo_msg;
|
||||
#undef _
|
||||
}
|
||||
|
||||
@@ -143,14 +143,12 @@ connect_to_vpp (char *name)
|
||||
if (mm->msg_id_base == (u16) ~ 0)
|
||||
return -1;
|
||||
|
||||
#define _(N,n) \
|
||||
vl_msg_api_set_handlers((VL_API_##N + mm->msg_id_base), \
|
||||
#n, \
|
||||
vl_api_##n##_t_handler, \
|
||||
vl_noop_handler, \
|
||||
vl_api_##n##_t_endian, \
|
||||
vl_api_##n##_t_print, \
|
||||
sizeof(vl_api_##n##_t), 1);
|
||||
#define _(N, n) \
|
||||
vl_msg_api_set_handlers ((VL_API_##N + mm->msg_id_base), #n, \
|
||||
vl_api_##n##_t_handler, vl_noop_handler, \
|
||||
vl_api_##n##_t_endian, vl_api_##n##_t_print, \
|
||||
sizeof (vl_api_##n##_t), 1, vl_api_##n##_t_tojson, \
|
||||
vl_api_##n##_t_fromjson);
|
||||
foreach_mactime_api_msg;
|
||||
#undef _
|
||||
|
||||
|
||||
@@ -246,12 +246,12 @@ api_trace_clear_capture (vat_main_t * vam)
|
||||
void
|
||||
manual_setup_message_id_table (vat_main_t * vam)
|
||||
{
|
||||
vl_msg_api_set_handlers (VL_API_TRACE_DETAILS
|
||||
+ tracedump_test_main.msg_id_base, "trace_details",
|
||||
vl_api_trace_details_t_handler, vl_noop_handler,
|
||||
vl_api_trace_details_t_endian,
|
||||
vl_api_trace_details_t_print,
|
||||
sizeof (vl_api_trace_details_t), 1);
|
||||
vl_msg_api_set_handlers (
|
||||
VL_API_TRACE_DETAILS + tracedump_test_main.msg_id_base, "trace_details",
|
||||
vl_api_trace_details_t_handler, vl_noop_handler,
|
||||
vl_api_trace_details_t_endian, vl_api_trace_details_t_print,
|
||||
sizeof (vl_api_trace_details_t), 1, vl_api_trace_details_t_print_json,
|
||||
vl_api_trace_details_t_tojson, vl_api_trace_details_t_fromjson);
|
||||
}
|
||||
|
||||
#define VL_API_LOCAL_SETUP_MESSAGE_ID_TABLE manual_setup_message_id_table
|
||||
|
||||
@@ -66,7 +66,10 @@ class ToJSON():
|
||||
write('#ifndef included_{}_api_tojson_h\n'.format(self.module))
|
||||
write('#define included_{}_api_tojson_h\n'.format(self.module))
|
||||
write('#include <vppinfra/cJSON.h>\n\n')
|
||||
write('#include <vat2/jsonconvert.h>\n\n')
|
||||
write('#include <vppinfra/jsonformat.h>\n\n')
|
||||
if self.module == 'interface_types':
|
||||
write('#define vl_printfun\n')
|
||||
write('#include <vnet/interface_types.api.h>\n\n')
|
||||
|
||||
def footer(self):
|
||||
'''Output the bottom boilerplate.'''
|
||||
@@ -231,6 +234,8 @@ class ToJSON():
|
||||
write(' cJSON *o = cJSON_CreateObject();\n')
|
||||
write(' cJSON_AddStringToObject(o, "_msgname", "{}");\n'
|
||||
.format(o.name))
|
||||
write(' cJSON_AddStringToObject(o, "_crc", "{crc:08x}");\n'
|
||||
.format(crc=o.crc))
|
||||
|
||||
for t in o.block:
|
||||
self._dispatch[t.type](self, t)
|
||||
@@ -312,7 +317,7 @@ class FromJSON():
|
||||
write('#ifndef included_{}_api_fromjson_h\n'.format(self.module))
|
||||
write('#define included_{}_api_fromjson_h\n'.format(self.module))
|
||||
write('#include <vppinfra/cJSON.h>\n\n')
|
||||
write('#include <vat2/jsonconvert.h>\n\n')
|
||||
write('#include <vppinfra/jsonformat.h>\n\n')
|
||||
write('#pragma GCC diagnostic ignored "-Wunused-label"\n')
|
||||
|
||||
def is_base_type(self, t):
|
||||
@@ -338,7 +343,7 @@ class FromJSON():
|
||||
if o.modern_vla:
|
||||
write(' char *p = cJSON_GetStringValue(item);\n')
|
||||
write(' size_t plen = strlen(p);\n')
|
||||
write(' {msgvar} = realloc({msgvar}, {msgsize} + plen);\n'
|
||||
write(' {msgvar} = cJSON_realloc({msgvar}, {msgsize} + plen, {msgsize});\n'
|
||||
.format(msgvar=msgvar, msgsize=msgsize))
|
||||
write(' if ({msgvar} == 0) goto error;\n'.format(msgvar=msgvar))
|
||||
write(' vl_api_c_string_to_api_string(p, (void *){msgvar} + '
|
||||
@@ -393,7 +398,7 @@ class FromJSON():
|
||||
cJSON *array = cJSON_GetObjectItem(o, "{n}");
|
||||
int size = cJSON_GetArraySize(array);
|
||||
{lfield} = size;
|
||||
{realloc} = realloc({realloc}, {msgsize} + sizeof({t}) * size);
|
||||
{realloc} = cJSON_realloc({realloc}, {msgsize} + sizeof({t}) * size, {msgsize});
|
||||
{t} *d = (void *){realloc} + {msgsize};
|
||||
{msgsize} += sizeof({t}) * size;
|
||||
for (i = 0; i < size; i++) {{
|
||||
@@ -419,8 +424,8 @@ class FromJSON():
|
||||
write(' if (!s) goto error;\n')
|
||||
write(' {} = vec_len(s);\n'.format(lfield))
|
||||
|
||||
write(' {realloc} = realloc({realloc}, {msgsize} + '
|
||||
'vec_len(s));\n'.format(msgvar=msgvar, msgsize=msgsize, realloc=realloc))
|
||||
write(' {realloc} = cJSON_realloc({realloc}, {msgsize} + '
|
||||
'vec_len(s), {msgsize});\n'.format(msgvar=msgvar, msgsize=msgsize, realloc=realloc))
|
||||
write(' memcpy((void *){realloc} + {msgsize}, s, '
|
||||
'vec_len(s));\n'.format(realloc=realloc, msgsize=msgsize))
|
||||
write(' {msgsize} += vec_len(s);\n'.format(msgsize=msgsize))
|
||||
@@ -553,7 +558,7 @@ class FromJSON():
|
||||
write(' cJSON *item __attribute__ ((unused));\n')
|
||||
write(' u8 *s __attribute__ ((unused));\n')
|
||||
write(' int l = sizeof(vl_api_{}_t);\n'.format(o.name))
|
||||
write(' vl_api_{}_t *a = malloc(l);\n'.format(o.name))
|
||||
write(' vl_api_{}_t *a = cJSON_malloc(l);\n'.format(o.name))
|
||||
write('\n')
|
||||
|
||||
for t in o.block:
|
||||
@@ -573,7 +578,7 @@ class FromJSON():
|
||||
|
||||
if error:
|
||||
write('\n error:\n')
|
||||
write(' free(a);\n')
|
||||
write(' cJSON_free(a);\n')
|
||||
write(' return 0;\n')
|
||||
write('}\n')
|
||||
|
||||
@@ -928,10 +933,13 @@ def printfun(objs, stream, modulename):
|
||||
#define _uword_cast long
|
||||
#endif
|
||||
|
||||
#include "{module}.api_tojson.h"
|
||||
#include "{module}.api_fromjson.h"
|
||||
|
||||
'''
|
||||
|
||||
signature = '''\
|
||||
static inline void *vl_api_{name}_t_print (vl_api_{name}_t *a, void *handle)
|
||||
static inline void *vl_api_{name}_t_print{suffix} (vl_api_{name}_t *a, void *handle)
|
||||
{{
|
||||
u8 *s = 0;
|
||||
u32 indent __attribute__((unused)) = 2;
|
||||
@@ -946,7 +954,7 @@ static inline void *vl_api_{name}_t_print (vl_api_{name}_t *a, void *handle)
|
||||
if t.manual_print:
|
||||
write("/***** manual: vl_api_%s_t_print *****/\n\n" % t.name)
|
||||
continue
|
||||
write(signature.format(name=t.name))
|
||||
write(signature.format(name=t.name, suffix=''))
|
||||
write(' /* Message definition: vl_api_{}_t: */\n'.format(t.name))
|
||||
write(" s = format(s, \"vl_api_%s_t:\");\n" % t.name)
|
||||
for o in t.block:
|
||||
@@ -957,6 +965,16 @@ static inline void *vl_api_{name}_t_print (vl_api_{name}_t *a, void *handle)
|
||||
write(' return handle;\n')
|
||||
write('}\n\n')
|
||||
|
||||
write(signature.format(name=t.name, suffix='_json'))
|
||||
write(' cJSON * o = vl_api_{}_t_tojson(a);\n'.format(t.name))
|
||||
write(' (void)s;\n');
|
||||
write(' char *out = cJSON_Print(o);\n')
|
||||
write(' vl_print(handle, out);\n');
|
||||
write(' cJSON_Delete(o);\n')
|
||||
write(' cJSON_free(out);\n');
|
||||
write(' return handle;\n')
|
||||
write('}\n\n');
|
||||
|
||||
write("\n#endif")
|
||||
write("\n#endif /* vl_printfun */\n")
|
||||
|
||||
@@ -1346,6 +1364,9 @@ def generate_c_boilerplate(services, defines, counters, file_crc,
|
||||
' .print = vl_api_{n}_t_print,\n'
|
||||
' .traced = 1,\n'
|
||||
' .replay = 1,\n'
|
||||
' .print_json = vl_api_{n}_t_print_json,\n'
|
||||
' .tojson = vl_api_{n}_t_tojson,\n'
|
||||
' .fromjson = vl_api_{n}_t_fromjson,\n'
|
||||
' .is_autoendian = {auto}}};\n'
|
||||
.format(n=s.caller, ID=s.caller.upper(),
|
||||
auto=d.autoendian))
|
||||
@@ -1359,6 +1380,11 @@ def generate_c_boilerplate(services, defines, counters, file_crc,
|
||||
' .cleanup = vl_noop_handler,\n'
|
||||
' .endian = vl_api_{n}_t_endian,\n'
|
||||
' .print = vl_api_{n}_t_print,\n'
|
||||
' .traced = 1,\n'
|
||||
' .replay = 1,\n'
|
||||
' .print_json = vl_api_{n}_t_print_json,\n'
|
||||
' .tojson = vl_api_{n}_t_tojson,\n'
|
||||
' .fromjson = vl_api_{n}_t_fromjson,\n'
|
||||
' .is_autoendian = {auto}}};\n'
|
||||
.format(n=s.reply, ID=s.reply.upper(),
|
||||
auto=d.autoendian))
|
||||
@@ -1455,7 +1481,10 @@ def generate_c_test_boilerplate(services, defines, file_crc, module, plugin,
|
||||
' vl_noop_handler,\n'
|
||||
' vl_api_{n}_t_endian, '
|
||||
' vl_api_{n}_t_print,\n'
|
||||
' sizeof(vl_api_{n}_t), 1);\n'
|
||||
' sizeof(vl_api_{n}_t), 1,\n'
|
||||
' vl_api_{n}_t_print_json,\n'
|
||||
' vl_api_{n}_t_tojson,\n'
|
||||
' vl_api_{n}_t_fromjson);\n'
|
||||
.format(n=s.reply, ID=s.reply.upper()))
|
||||
write(' hash_set_mem (vam->function_by_name, "{n}", api_{n});\n'
|
||||
.format(n=s.caller))
|
||||
@@ -1474,7 +1503,10 @@ def generate_c_test_boilerplate(services, defines, file_crc, module, plugin,
|
||||
' vl_noop_handler,\n'
|
||||
' vl_api_{n}_t_endian, '
|
||||
' vl_api_{n}_t_print,\n'
|
||||
' sizeof(vl_api_{n}_t), 1);\n'
|
||||
' sizeof(vl_api_{n}_t), 1,\n'
|
||||
' vl_api_{n}_t_print_json,\n'
|
||||
' vl_api_{n}_t_tojson,\n'
|
||||
' vl_api_{n}_t_fromjson);\n'
|
||||
.format(n=e, ID=e.upper()))
|
||||
|
||||
write('}\n')
|
||||
@@ -1526,7 +1558,7 @@ api_{n} (cJSON *o)
|
||||
mp->_vl_msg_id = vac_get_msg_index(VL_API_{N}_CRC);
|
||||
vl_api_{n}_t_endian(mp);
|
||||
vac_write((char *)mp, len);
|
||||
free(mp);
|
||||
cJSON_free(mp);
|
||||
|
||||
/* Read reply */
|
||||
char *p;
|
||||
@@ -1559,7 +1591,7 @@ api_{n} (cJSON *o)
|
||||
mp->_vl_msg_id = msg_id;
|
||||
vl_api_{n}_t_endian(mp);
|
||||
vac_write((char *)mp, len);
|
||||
free(mp);
|
||||
cJSON_free(mp);
|
||||
|
||||
vat2_control_ping(123); // FIX CONTEXT
|
||||
cJSON *reply = cJSON_CreateArray();
|
||||
@@ -1615,7 +1647,7 @@ api_{n} (cJSON *o)
|
||||
|
||||
vl_api_{n}_t_endian(mp);
|
||||
vac_write((char *)mp, len);
|
||||
free(mp);
|
||||
cJSON_free(mp);
|
||||
|
||||
cJSON *reply = cJSON_CreateArray();
|
||||
|
||||
@@ -1713,13 +1745,16 @@ def generate_c_test2_boilerplate(services, defines, module, stream):
|
||||
continue
|
||||
c_test_api_service(s, s.stream, stream)
|
||||
|
||||
write('void vat2_register_function(char *, cJSON * (*)(cJSON *), cJSON * (*)(void *));\n')
|
||||
write('void vat2_register_function(char *, cJSON * (*)(cJSON *), cJSON * (*)(void *), u32);\n')
|
||||
# write('__attribute__((constructor))')
|
||||
write('clib_error_t *\n')
|
||||
write('vat2_register_plugin (void) {\n')
|
||||
for s in services:
|
||||
write(' vat2_register_function("{n}", api_{n}, (cJSON * (*)(void *))vl_api_{n}_t_tojson);\n'
|
||||
.format(n=s.caller))
|
||||
if s.reply not in define_hash:
|
||||
continue
|
||||
crc = define_hash[s.caller].crc
|
||||
write(' vat2_register_function("{n}", api_{n}, (cJSON * (*)(void *))vl_api_{n}_t_tojson, 0x{crc:08x});\n'
|
||||
.format(n=s.caller, crc=crc))
|
||||
write(' return 0;\n')
|
||||
write('}\n')
|
||||
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
vppapitrace.py
|
||||
File diff suppressed because it is too large
Load Diff
@@ -2627,7 +2627,9 @@ vat_api_hookup (vat_main_t * vam)
|
||||
#define _(N, n) \
|
||||
vl_msg_api_set_handlers (VL_API_##N + 1, #n, vl_api_##n##_t_handler_uni, \
|
||||
vl_noop_handler, vl_api_##n##_t_endian, \
|
||||
vl_api_##n##_t_print, sizeof (vl_api_##n##_t), 1);
|
||||
vl_api_##n##_t_print, sizeof (vl_api_##n##_t), 1, \
|
||||
vl_api_##n##_t_print_json, vl_api_##n##_t_tojson, \
|
||||
vl_api_##n##_t_fromjson);
|
||||
foreach_vpe_api_reply_msg;
|
||||
#if VPP_API_TEST_BUILTIN == 0
|
||||
foreach_standalone_reply_msg;
|
||||
|
||||
@@ -18,7 +18,6 @@ add_vpp_executable(vat2 ENABLE_EXPORTS
|
||||
SOURCES
|
||||
main.c
|
||||
plugin.c
|
||||
jsonconvert.c
|
||||
|
||||
DEPENDS api_headers
|
||||
|
||||
@@ -41,7 +40,6 @@ vpp_generate_api_c_header (test/vat2_test.api)
|
||||
add_vpp_executable(test_vat2 ENABLE_EXPORTS NO_INSTALL
|
||||
SOURCES
|
||||
test/vat2_test.c
|
||||
jsonconvert.c
|
||||
|
||||
DEPENDS api_headers
|
||||
|
||||
@@ -57,7 +55,6 @@ add_vpp_executable(test_vat2 ENABLE_EXPORTS NO_INSTALL
|
||||
|
||||
if("${CMAKE_VERSION}" VERSION_GREATER_EQUAL "3.13" AND "${CMAKE_C_COMPILER_ID}" MATCHES "(Apple)?[Cc]lang")
|
||||
set(TARGET_NAME test_vat2)
|
||||
set(COV_SOURCES ${CMAKE_SOURCE_DIR}/vat2/jsonconvert.c)
|
||||
|
||||
message("Building with llvm Code Coverage Tools ${TARGET_NAME}")
|
||||
target_compile_options(${TARGET_NAME} PRIVATE -fprofile-instr-generate -fcoverage-mapping)
|
||||
@@ -96,7 +93,6 @@ endif()
|
||||
##############################################################################
|
||||
install(
|
||||
FILES
|
||||
jsonconvert.h
|
||||
vat2_helpers.h
|
||||
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/vat2
|
||||
COMPONENT vpp-dev
|
||||
|
||||
@@ -1,105 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2020 Cisco and/or its affiliates.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef included_json_convert_h
|
||||
#define included_json_convert_h
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <vppinfra/cJSON.h>
|
||||
#include <vnet/ethernet/mac_address.h>
|
||||
#include <vnet/ip/ip6_packet.h>
|
||||
#include <vnet/ip/ip_types.api_types.h>
|
||||
#include <vnet/ethernet/ethernet_types.api_types.h>
|
||||
|
||||
#define foreach_vat2_fromjson \
|
||||
_(i8) \
|
||||
_(u8) \
|
||||
_(i16) \
|
||||
_(u16) \
|
||||
_(i32) \
|
||||
_(u32) \
|
||||
_(u64) \
|
||||
_(f64)
|
||||
|
||||
#define _(T) \
|
||||
int vl_api_ ##T## _fromjson(cJSON *o, T *d);
|
||||
foreach_vat2_fromjson
|
||||
#undef _
|
||||
|
||||
/* Prototypes */
|
||||
int
|
||||
vl_api_bool_fromjson (cJSON *o, bool *d);
|
||||
int vl_api_ip4_address_t_fromjson (void **mp, int *len, cJSON *o,
|
||||
vl_api_ip4_address_t *a);
|
||||
int vl_api_ip4_prefix_t_fromjson (void **mp, int *len, cJSON *o,
|
||||
vl_api_ip4_prefix_t *a);
|
||||
int vl_api_ip4_address_with_prefix_t_fromjson (void **mp, int *len, cJSON *o,
|
||||
vl_api_ip4_prefix_t *a);
|
||||
int vl_api_ip6_address_t_fromjson (void **mp, int *len, cJSON *o,
|
||||
vl_api_ip6_address_t *a);
|
||||
int vl_api_ip6_prefix_t_fromjson (void **mp, int *len, cJSON *o,
|
||||
vl_api_ip6_prefix_t *a);
|
||||
int vl_api_ip6_address_with_prefix_t_fromjson (void **mp, int *len, cJSON *o,
|
||||
vl_api_ip6_prefix_t *a);
|
||||
int vl_api_address_t_fromjson (void **mp, int *len, cJSON *o,
|
||||
vl_api_address_t *a);
|
||||
int vl_api_prefix_t_fromjson (void **mp, int *len, cJSON *o,
|
||||
vl_api_prefix_t *a);
|
||||
int vl_api_address_with_prefix_t_fromjson (void **mp, int *len, cJSON *o,
|
||||
vl_api_prefix_t *a);
|
||||
int vl_api_mac_address_t_fromjson (void **mp, int *len, cJSON *o,
|
||||
vl_api_mac_address_t *a);
|
||||
|
||||
uword unformat_ip4_address (unformat_input_t *input, va_list *args);
|
||||
uword unformat_ip6_address (unformat_input_t *input, va_list *args);
|
||||
u8 *format_ip6_address (u8 *s, va_list *args);
|
||||
uword unformat_mac_address (unformat_input_t *input, va_list *args);
|
||||
u8 *format_ip4_address (u8 *s, va_list *args);
|
||||
u8 *format_vl_api_interface_index_t (u8 *s, va_list *args);
|
||||
u8 *format_vl_api_timestamp_t (u8 *s, va_list *args);
|
||||
u8 *format_vl_api_timedelta_t (u8 *s, va_list *args);
|
||||
uword unformat_vl_api_timedelta_t (unformat_input_t *input, va_list *args);
|
||||
uword unformat_vl_api_timestamp_t (unformat_input_t *input, va_list *args);
|
||||
u8 *format_vl_api_gbp_scope_t (u8 *s, va_list *args);
|
||||
uword unformat_vl_api_gbp_scope_t (unformat_input_t *input, va_list *args);
|
||||
|
||||
int vl_api_c_string_to_api_string (const char *buf, vl_api_string_t *str);
|
||||
void vl_api_string_cJSON_AddToObject (cJSON *const object,
|
||||
const char *const name,
|
||||
vl_api_string_t *astr);
|
||||
|
||||
u8 *u8string_fromjson (cJSON *o, char *fieldname);
|
||||
int u8string_fromjson2 (cJSON *o, char *fieldname, u8 *data);
|
||||
int vl_api_u8_string_fromjson (cJSON *o, u8 *s, int len);
|
||||
|
||||
#define foreach_vat2_tojson \
|
||||
_(ip4_address) \
|
||||
_(ip4_prefix) \
|
||||
_(ip6_address) \
|
||||
_(ip6_prefix) \
|
||||
_(address) \
|
||||
_(prefix) \
|
||||
_(mac_address)
|
||||
|
||||
#define _(T) \
|
||||
cJSON *vl_api_ ##T## _t_tojson(vl_api_ ##T## _t *);
|
||||
foreach_vat2_tojson
|
||||
#undef _
|
||||
|
||||
cJSON *vl_api_ip4_address_with_prefix_t_tojson (vl_api_ip4_prefix_t *a);
|
||||
cJSON *vl_api_ip6_address_with_prefix_t_tojson (vl_api_ip6_prefix_t *a);
|
||||
cJSON *vl_api_address_with_prefix_t_tojson (vl_api_prefix_t *a);
|
||||
|
||||
#endif
|
||||
+60
-8
@@ -18,7 +18,7 @@
|
||||
#include <stdbool.h>
|
||||
#include <ctype.h>
|
||||
#include <getopt.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <vlib/vlib.h>
|
||||
#include <vlibapi/api_types.h>
|
||||
#include <vppinfra/hash.h>
|
||||
@@ -30,6 +30,33 @@
|
||||
#include <limits.h>
|
||||
#include "vat2.h"
|
||||
|
||||
/*
|
||||
* Filter these messages as they are used to manage the API connection to VPP
|
||||
*/
|
||||
char *filter_messages_strings[] = { "memclnt_create",
|
||||
"memclnt_delete",
|
||||
"sockclnt_create",
|
||||
"sockclnt_delete",
|
||||
"memclnt_rx_thread_suspend",
|
||||
"memclnt_read_timeout",
|
||||
"rx_thread_exit",
|
||||
"trace_plugin_msg_ids",
|
||||
0 };
|
||||
|
||||
static bool
|
||||
filter_message (char *msgname)
|
||||
{
|
||||
char **p = filter_messages_strings;
|
||||
|
||||
while (*p)
|
||||
{
|
||||
if (strcmp (*p, msgname) == 0)
|
||||
return true;
|
||||
p++;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
uword *function_by_name;
|
||||
bool debug = false;
|
||||
|
||||
@@ -89,15 +116,16 @@ struct apifuncs_s
|
||||
{
|
||||
cJSON (*f) (cJSON *);
|
||||
cJSON (*tojson) (void *);
|
||||
u32 crc;
|
||||
};
|
||||
|
||||
struct apifuncs_s *apifuncs = 0;
|
||||
|
||||
void
|
||||
vat2_register_function (char *name, cJSON (*f) (cJSON *),
|
||||
cJSON (*tojson) (void *))
|
||||
cJSON (*tojson) (void *), u32 crc)
|
||||
{
|
||||
struct apifuncs_s funcs = { .f = f, .tojson = tojson };
|
||||
struct apifuncs_s funcs = { .f = f, .tojson = tojson, .crc = crc };
|
||||
vec_add1 (apifuncs, funcs);
|
||||
hash_set_mem (function_by_name, name, vec_len (apifuncs) - 1);
|
||||
}
|
||||
@@ -105,12 +133,28 @@ vat2_register_function (char *name, cJSON (*f) (cJSON *),
|
||||
static int
|
||||
vat2_exec_command_by_name (char *msgname, cJSON *o)
|
||||
{
|
||||
if (filter_message (msgname))
|
||||
return 0;
|
||||
|
||||
cJSON *crc_obj = cJSON_GetObjectItem (o, "_crc");
|
||||
if (!crc_obj)
|
||||
{
|
||||
fprintf (stderr, "Missing '_crc' element!\n");
|
||||
return -1;
|
||||
}
|
||||
char *crc_str = cJSON_GetStringValue (crc_obj);
|
||||
u32 crc = (u32) strtol (crc_str, NULL, 16);
|
||||
|
||||
uword *p = hash_get_mem (function_by_name, msgname);
|
||||
if (!p)
|
||||
{
|
||||
fprintf (stderr, "No such command %s", msgname);
|
||||
fprintf (stderr, "No such command %s\n", msgname);
|
||||
return -1;
|
||||
}
|
||||
if (crc != apifuncs[p[0]].crc)
|
||||
{
|
||||
fprintf (stderr, "API CRC does not match: %s!\n", msgname);
|
||||
}
|
||||
|
||||
cJSON *(*fp) (cJSON *);
|
||||
fp = (void *) apifuncs[p[0]].f;
|
||||
@@ -143,9 +187,10 @@ vat2_exec_command (cJSON *o)
|
||||
}
|
||||
|
||||
char *name = cJSON_GetStringValue (msg_id_obj);
|
||||
assert (name);
|
||||
|
||||
return vat2_exec_command_by_name (name, o);
|
||||
}
|
||||
|
||||
static void
|
||||
print_template (char *msgname)
|
||||
{
|
||||
@@ -307,6 +352,12 @@ int main (int argc, char **argv)
|
||||
}
|
||||
}
|
||||
|
||||
if (!msgname && !filename)
|
||||
{
|
||||
print_help ();
|
||||
exit (-1);
|
||||
}
|
||||
|
||||
/* Read message from file */
|
||||
if (filename) {
|
||||
if (argc > index)
|
||||
@@ -325,6 +376,7 @@ int main (int argc, char **argv)
|
||||
fprintf(stderr, "%s: can't open file: %s\n", argv[0], filename);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
chunksize = bufsize = 1024;
|
||||
char *buf = malloc(bufsize);
|
||||
while ((n = fread (buf + n_read, 1, chunksize, f)))
|
||||
@@ -339,17 +391,17 @@ int main (int argc, char **argv)
|
||||
fclose(f);
|
||||
if (n_read) {
|
||||
o = cJSON_Parse(buf);
|
||||
free(buf);
|
||||
if (!o) {
|
||||
fprintf(stderr, "%s: Failed parsing JSON input: %s\n", argv[0], cJSON_GetErrorPtr());
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
free (buf);
|
||||
}
|
||||
|
||||
if (!msgname && !filename)
|
||||
if (!o)
|
||||
{
|
||||
print_help ();
|
||||
fprintf (stderr, "%s: Failed parsing JSON input\n", argv[0]);
|
||||
exit (-1);
|
||||
}
|
||||
|
||||
|
||||
@@ -196,6 +196,7 @@ struct tests tests[] = {
|
||||
"[\"2001:db8::23\", \"2001:db8::23\"] }" },
|
||||
{ .s = "{\"_msgname\": \"test_empty\"}" },
|
||||
{ .s = "{\"_msgname\": \"test_interface\", \"sw_if_index\": 100 }" },
|
||||
{ .s = "{\"_msgname\": \"test_interface\", \"sw_if_index\": 4294967295 }" },
|
||||
};
|
||||
|
||||
int main (int argc, char **argv)
|
||||
|
||||
+5
-4
@@ -299,10 +299,11 @@ vcl_bapi_hookup (void)
|
||||
return;
|
||||
|
||||
#define _(N, n) \
|
||||
vl_msg_api_set_handlers (REPLY_MSG_ID_BASE + VL_API_##N, #n, \
|
||||
vl_api_##n##_t_handler, vl_noop_handler, \
|
||||
vl_api_##n##_t_endian, vl_api_##n##_t_print, \
|
||||
sizeof (vl_api_##n##_t), 1);
|
||||
vl_msg_api_set_handlers ( \
|
||||
REPLY_MSG_ID_BASE + VL_API_##N, #n, vl_api_##n##_t_handler, \
|
||||
vl_noop_handler, vl_api_##n##_t_endian, vl_api_##n##_t_print, \
|
||||
sizeof (vl_api_##n##_t), 1, vl_api_##n##_t_print_json, \
|
||||
vl_api_##n##_t_tojson, vl_api_##n##_t_fromjson);
|
||||
foreach_sock_msg;
|
||||
#undef _
|
||||
}
|
||||
|
||||
+7
-2
@@ -36,8 +36,8 @@ typedef CLIB_PACKED ( struct {
|
||||
}) vl_api_trace_file_header_t;
|
||||
/* *INDENT-ON* */
|
||||
|
||||
int vl_msg_api_trace_save (api_main_t * am,
|
||||
vl_api_trace_which_t which, FILE * fp);
|
||||
int vl_msg_api_trace_save (api_main_t *am, vl_api_trace_which_t which,
|
||||
FILE *fp, u8 is_json);
|
||||
|
||||
#define VLIB_API_INIT_FUNCTION(x) VLIB_DECLARE_INIT_FUNCTION(x,api_init)
|
||||
|
||||
@@ -123,6 +123,11 @@ vlib_node_t ***vlib_node_unserialize (u8 * vector);
|
||||
|
||||
u32 vl_msg_api_get_msg_length (void *msg_arg);
|
||||
|
||||
typedef int (*vl_msg_traverse_trace_fn) (u8 *, void *);
|
||||
|
||||
int vl_msg_traverse_trace (vl_api_trace_t *tp, vl_msg_traverse_trace_fn fn,
|
||||
void *ctx);
|
||||
|
||||
#endif /* included_api_h */
|
||||
/*
|
||||
* fd.io coding-style-patch-verification: ON
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
|
||||
#include <vppinfra/clib_error.h>
|
||||
#include <vppinfra/elog.h>
|
||||
#include <vppinfra/cJSON.h>
|
||||
#include <vlibapi/api_types.h>
|
||||
#include <svm/svm_common.h>
|
||||
#include <svm/queue.h>
|
||||
@@ -128,6 +129,9 @@ typedef struct
|
||||
void *cleanup; /**< non-default message cleanup handler */
|
||||
void *endian; /**< message endian function */
|
||||
void *print; /**< message print function */
|
||||
void *print_json; /**< message print function (JSON format) */
|
||||
void *tojson; /**< binary to JSON convert function */
|
||||
void *fromjson; /**< JSON to binary convert function */
|
||||
int size; /**< message size */
|
||||
int traced; /**< is this message to be traced? */
|
||||
int replay; /**< is this message to be replayed? */
|
||||
@@ -173,11 +177,10 @@ void vl_msg_api_trace_only (void *the_msg);
|
||||
void vl_msg_api_cleanup_handler (void *the_msg);
|
||||
void vl_msg_api_replay_handler (void *the_msg);
|
||||
void vl_msg_api_socket_handler (void *the_msg);
|
||||
void vl_msg_api_set_handlers (int msg_id, char *msg_name,
|
||||
void *handler,
|
||||
void *cleanup,
|
||||
void *endian,
|
||||
void *print, int msg_size, int traced);
|
||||
void vl_msg_api_set_handlers (int msg_id, char *msg_name, void *handler,
|
||||
void *cleanup, void *endian, void *print,
|
||||
int msg_size, int traced, void *print_json,
|
||||
void *tojson, void *fromjson);
|
||||
void vl_msg_api_clean_handlers (int msg_id);
|
||||
void vl_msg_api_config (vl_msg_api_msg_config_t *);
|
||||
void vl_msg_api_set_cleanup_handler (int msg_id, void *fp);
|
||||
@@ -241,9 +244,21 @@ typedef struct api_main_t
|
||||
/** Message print function vector */
|
||||
void (**msg_print_handlers) (void *, void *);
|
||||
|
||||
/** Message print function vector in JSON */
|
||||
void (**msg_print_json_handlers) (void *, void *);
|
||||
|
||||
/** Message convert function vector */
|
||||
cJSON *(**msg_tojson_handlers) (void *);
|
||||
|
||||
/** Message convert function vector */
|
||||
void *(**msg_fromjson_handlers) (cJSON *, int *);
|
||||
|
||||
/** Message name vector */
|
||||
const char **msg_names;
|
||||
|
||||
/** API message ID by name hash table */
|
||||
uword *msg_id_by_name;
|
||||
|
||||
/** Don't automatically free message buffer vetor */
|
||||
u8 *message_bounce;
|
||||
|
||||
|
||||
+182
-101
File diff suppressed because it is too large
Load Diff
@@ -57,3 +57,9 @@ add_dependencies(vlibmemoryclient vlibmemory_api_headers)
|
||||
add_vat_test_library(vlib
|
||||
vlibapi_test.c
|
||||
)
|
||||
##############################################################################
|
||||
# VAT2 plugins
|
||||
##############################################################################
|
||||
add_vpp_test_library(vlibmemoryclient
|
||||
memclnt.api
|
||||
)
|
||||
|
||||
@@ -29,7 +29,6 @@ service {
|
||||
/*
|
||||
* Create a client registration
|
||||
*/
|
||||
manual_print
|
||||
define memclnt_create {
|
||||
u32 context; /* opaque value to be returned in the reply */
|
||||
i32 ctx_quota; /* requested punt context quota */
|
||||
@@ -49,7 +48,6 @@ define memclnt_create_reply {
|
||||
/*
|
||||
* Delete a client registration
|
||||
*/
|
||||
manual_print
|
||||
define memclnt_delete {
|
||||
u32 index; /* index, used e.g. by API trace replay */
|
||||
u64 handle; /* handle by which vlib knows this client */
|
||||
@@ -137,7 +135,7 @@ define api_versions_reply {
|
||||
* at api trace replay time
|
||||
*/
|
||||
|
||||
manual_print define trace_plugin_msg_ids
|
||||
define trace_plugin_msg_ids
|
||||
{
|
||||
u32 client_index;
|
||||
u32 context;
|
||||
|
||||
@@ -52,16 +52,6 @@
|
||||
#include <vlibmemory/vl_memory_api_h.h>
|
||||
#undef vl_printfun
|
||||
|
||||
static inline void *
|
||||
vl_api_trace_plugin_msg_ids_t_print (vl_api_trace_plugin_msg_ids_t *a,
|
||||
void *handle)
|
||||
{
|
||||
vl_print (handle, "vl_api_trace_plugin_msg_ids: %s first %u last %u\n",
|
||||
a->plugin_name, clib_host_to_net_u16 (a->first_msg_id),
|
||||
clib_host_to_net_u16 (a->last_msg_id));
|
||||
return handle;
|
||||
}
|
||||
|
||||
/* instantiate all the endian swap functions we know about */
|
||||
#define vl_endianfun
|
||||
#include <vlibmemory/vl_memory_api_h.h>
|
||||
@@ -154,6 +144,12 @@ vlib_api_init (void)
|
||||
vl_msg_api_msg_config_t cfg;
|
||||
vl_msg_api_msg_config_t *c = &cfg;
|
||||
|
||||
cJSON_Hooks cjson_hooks = {
|
||||
.malloc_fn = clib_mem_alloc,
|
||||
.free_fn = clib_mem_free,
|
||||
};
|
||||
cJSON_InitHooks (&cjson_hooks);
|
||||
|
||||
clib_memset (c, 0, sizeof (*c));
|
||||
|
||||
#define _(N, n) \
|
||||
@@ -689,19 +685,25 @@ rpc_api_hookup (vlib_main_t *vm)
|
||||
{
|
||||
api_main_t *am = vlibapi_get_main ();
|
||||
#define _(N, n) \
|
||||
vl_msg_api_set_handlers ( \
|
||||
VL_API_##N, #n, vl_api_##n##_t_handler, vl_noop_handler, vl_noop_handler, \
|
||||
vl_api_##n##_t_print, sizeof (vl_api_##n##_t), 0 /* do not trace */);
|
||||
vl_msg_api_set_handlers (VL_API_##N, #n, vl_api_##n##_t_handler, \
|
||||
vl_noop_handler, vl_noop_handler, \
|
||||
vl_api_##n##_t_print, sizeof (vl_api_##n##_t), \
|
||||
0 /* do not trace */, vl_api_##n##_t_print_json, \
|
||||
vl_api_##n##_t_tojson, vl_api_##n##_t_fromjson);
|
||||
foreach_rpc_api_msg;
|
||||
#undef _
|
||||
|
||||
#define _(N, n) \
|
||||
vl_msg_api_set_handlers ( \
|
||||
VL_API_##N, #n, vl_api_##n##_t_handler, vl_noop_handler, vl_noop_handler, \
|
||||
vl_api_##n##_t_print, sizeof (vl_api_##n##_t), 1 /* do trace */);
|
||||
vl_msg_api_set_handlers (VL_API_##N, #n, vl_api_##n##_t_handler, \
|
||||
vl_noop_handler, vl_noop_handler, \
|
||||
vl_api_##n##_t_print, sizeof (vl_api_##n##_t), \
|
||||
1 /* do trace */, vl_api_##n##_t_print_json, \
|
||||
vl_api_##n##_t_tojson, vl_api_##n##_t_fromjson);
|
||||
foreach_plugin_trace_msg;
|
||||
#undef _
|
||||
|
||||
am->api_trace_cfg[VL_API_TRACE_PLUGIN_MSG_IDS].replay_enable = 0;
|
||||
|
||||
/* No reason to halt the parade to create a trace record... */
|
||||
am->is_mp_safe[VL_API_TRACE_PLUGIN_MSG_IDS] = 1;
|
||||
rpc_call_main_thread_cb_fn = vl_api_rpc_call_main_thread;
|
||||
|
||||
@@ -38,26 +38,6 @@
|
||||
#include <vlibmemory/vl_memory_api_h.h>
|
||||
#undef vl_endianfun
|
||||
|
||||
static inline void *
|
||||
vl_api_memclnt_create_t_print (vl_api_memclnt_create_t * a, void *handle)
|
||||
{
|
||||
vl_print (handle, "vl_api_memclnt_create_t:\n");
|
||||
vl_print (handle, "name: %s\n", a->name);
|
||||
vl_print (handle, "input_queue: 0x%wx\n", a->input_queue);
|
||||
vl_print (handle, "context: %u\n", (unsigned) a->context);
|
||||
vl_print (handle, "ctx_quota: %ld\n", (long) a->ctx_quota);
|
||||
return handle;
|
||||
}
|
||||
|
||||
static inline void *
|
||||
vl_api_memclnt_delete_t_print (vl_api_memclnt_delete_t * a, void *handle)
|
||||
{
|
||||
vl_print (handle, "vl_api_memclnt_delete_t:\n");
|
||||
vl_print (handle, "index: %u\n", (unsigned) a->index);
|
||||
vl_print (handle, "handle: 0x%wx\n", a->handle);
|
||||
return handle;
|
||||
}
|
||||
|
||||
volatile int **vl_api_queue_cursizes;
|
||||
|
||||
static void
|
||||
@@ -417,11 +397,11 @@ vl_api_memclnt_keepalive_t_handler (vl_api_memclnt_keepalive_t * mp)
|
||||
* don't trace memclnt_keepalive[_reply] msgs
|
||||
*/
|
||||
|
||||
#define foreach_vlib_api_msg \
|
||||
_(MEMCLNT_CREATE, memclnt_create, 1) \
|
||||
_(MEMCLNT_DELETE, memclnt_delete, 1) \
|
||||
_(MEMCLNT_KEEPALIVE, memclnt_keepalive, 0) \
|
||||
_(MEMCLNT_KEEPALIVE_REPLY, memclnt_keepalive_reply, 0)
|
||||
#define foreach_vlib_api_msg \
|
||||
_ (MEMCLNT_CREATE, memclnt_create, 0) \
|
||||
_ (MEMCLNT_DELETE, memclnt_delete, 0) \
|
||||
_ (MEMCLNT_KEEPALIVE, memclnt_keepalive, 0) \
|
||||
_ (MEMCLNT_KEEPALIVE_REPLY, memclnt_keepalive_reply, 0)
|
||||
|
||||
/*
|
||||
* memory_api_init
|
||||
|
||||
@@ -362,14 +362,14 @@ _(MEMCLNT_KEEPALIVE, memclnt_keepalive)
|
||||
void
|
||||
vl_client_install_client_message_handlers (void)
|
||||
{
|
||||
|
||||
#define _(N,n) \
|
||||
vl_msg_api_set_handlers(VL_API_##N, #n, \
|
||||
vl_api_##n##_t_handler, \
|
||||
noop_handler, \
|
||||
vl_api_##n##_t_endian, \
|
||||
vl_api_##n##_t_print, \
|
||||
sizeof(vl_api_##n##_t), 1);
|
||||
api_main_t *am = vlibapi_get_main ();
|
||||
#define _(N, n) \
|
||||
vl_msg_api_set_handlers (VL_API_##N, #n, vl_api_##n##_t_handler, \
|
||||
noop_handler, vl_api_##n##_t_endian, \
|
||||
vl_api_##n##_t_print, sizeof (vl_api_##n##_t), 0, \
|
||||
vl_api_##n##_t_print_json, vl_api_##n##_t_tojson, \
|
||||
vl_api_##n##_t_fromjson); \
|
||||
am->api_trace_cfg[VL_API_##N].replay_enable = 0;
|
||||
foreach_api_msg;
|
||||
#undef _
|
||||
}
|
||||
|
||||
+19
-12
@@ -495,7 +495,13 @@ vl_api_sockclnt_create_t_handler (vl_api_sockclnt_create_t * mp)
|
||||
|
||||
regp = socket_main.current_rp;
|
||||
|
||||
ASSERT (regp->registration_type == REGISTRATION_TYPE_SOCKET_SERVER);
|
||||
/* client already connected through shared memory? */
|
||||
if (!regp || regp->registration_type != REGISTRATION_TYPE_SOCKET_SERVER)
|
||||
{
|
||||
clib_warning (
|
||||
"unsupported API call: already connected though shared memory?");
|
||||
return;
|
||||
}
|
||||
|
||||
regp->name = format (0, "%s%c", mp->name, 0);
|
||||
|
||||
@@ -765,14 +771,15 @@ reply:
|
||||
vl_sock_api_send_fd_msg (cf->file_descriptor, &memfd->fd, 1);
|
||||
}
|
||||
|
||||
#define foreach_vlib_api_msg \
|
||||
_(SOCKCLNT_CREATE, sockclnt_create, 1) \
|
||||
_(SOCKCLNT_DELETE, sockclnt_delete, 1) \
|
||||
_(SOCK_INIT_SHM, sock_init_shm, 1)
|
||||
#define foreach_vlib_api_msg \
|
||||
_ (SOCKCLNT_CREATE, sockclnt_create, 0) \
|
||||
_ (SOCKCLNT_DELETE, sockclnt_delete, 0) \
|
||||
_ (SOCK_INIT_SHM, sock_init_shm, 0)
|
||||
|
||||
clib_error_t *
|
||||
vl_sock_api_init (vlib_main_t * vm)
|
||||
{
|
||||
api_main_t *am = vlibapi_get_main ();
|
||||
clib_file_main_t *fm = &file_main;
|
||||
clib_file_t template = { 0 };
|
||||
vl_api_registration_t *rp;
|
||||
@@ -784,13 +791,13 @@ vl_sock_api_init (vlib_main_t * vm)
|
||||
if (sm->socket_name == 0)
|
||||
return 0;
|
||||
|
||||
#define _(N,n,t) \
|
||||
vl_msg_api_set_handlers(VL_API_##N, #n, \
|
||||
vl_api_##n##_t_handler, \
|
||||
vl_noop_handler, \
|
||||
vl_api_##n##_t_endian, \
|
||||
vl_api_##n##_t_print, \
|
||||
sizeof(vl_api_##n##_t), t);
|
||||
#define _(N, n, t) \
|
||||
vl_msg_api_set_handlers (VL_API_##N, #n, vl_api_##n##_t_handler, \
|
||||
vl_noop_handler, vl_api_##n##_t_endian, \
|
||||
vl_api_##n##_t_print, sizeof (vl_api_##n##_t), t, \
|
||||
vl_api_##n##_t_print_json, vl_api_##n##_t_tojson, \
|
||||
vl_api_##n##_t_fromjson); \
|
||||
am->api_trace_cfg[VL_API_##N].replay_enable = 0;
|
||||
foreach_vlib_api_msg;
|
||||
#undef _
|
||||
|
||||
|
||||
@@ -432,13 +432,12 @@ void
|
||||
vl_sock_client_install_message_handlers (void)
|
||||
{
|
||||
|
||||
#define _(N,n) \
|
||||
vl_msg_api_set_handlers(VL_API_##N, #n, \
|
||||
vl_api_##n##_t_handler, \
|
||||
noop_handler, \
|
||||
vl_api_##n##_t_endian, \
|
||||
vl_api_##n##_t_print, \
|
||||
sizeof(vl_api_##n##_t), 1);
|
||||
#define _(N, n) \
|
||||
vl_msg_api_set_handlers (VL_API_##N, #n, vl_api_##n##_t_handler, \
|
||||
noop_handler, vl_api_##n##_t_endian, \
|
||||
vl_api_##n##_t_print, sizeof (vl_api_##n##_t), 0, \
|
||||
vl_api_##n##_t_print_json, vl_api_##n##_t_tojson, \
|
||||
vl_api_##n##_t_fromjson);
|
||||
foreach_sock_client_api_msg;
|
||||
#undef _
|
||||
}
|
||||
|
||||
+422
-84
File diff suppressed because it is too large
Load Diff
@@ -190,10 +190,11 @@ sr_mpls_api_hookup (vlib_main_t * vm)
|
||||
vec_free (name);
|
||||
|
||||
#define _(N, n) \
|
||||
vl_msg_api_set_handlers (REPLY_MSG_ID_BASE + VL_API_##N, #n, \
|
||||
vl_api_##n##_t_handler, vl_noop_handler, \
|
||||
vl_api_##n##_t_endian, vl_api_##n##_t_print, \
|
||||
sizeof (vl_api_##n##_t), 1);
|
||||
vl_msg_api_set_handlers ( \
|
||||
REPLY_MSG_ID_BASE + VL_API_##N, #n, vl_api_##n##_t_handler, \
|
||||
vl_noop_handler, vl_api_##n##_t_endian, vl_api_##n##_t_print, \
|
||||
sizeof (vl_api_##n##_t), 1, vl_api_##n##_t_print_json, \
|
||||
vl_api_##n##_t_tojson, vl_api_##n##_t_fromjson);
|
||||
foreach_vpe_api_msg;
|
||||
#undef _
|
||||
|
||||
@@ -201,21 +202,23 @@ sr_mpls_api_hookup (vlib_main_t * vm)
|
||||
* Manually register the sr policy add msg, so we trace enough bytes
|
||||
* to capture a typical segment list
|
||||
*/
|
||||
vl_msg_api_set_handlers (REPLY_MSG_ID_BASE + VL_API_SR_MPLS_POLICY_ADD,
|
||||
"sr_mpls_policy_add",
|
||||
vl_api_sr_mpls_policy_add_t_handler,
|
||||
vl_noop_handler, vl_api_sr_mpls_policy_add_t_endian,
|
||||
vl_api_sr_mpls_policy_add_t_print, 256, 1);
|
||||
vl_msg_api_set_handlers (
|
||||
REPLY_MSG_ID_BASE + VL_API_SR_MPLS_POLICY_ADD, "sr_mpls_policy_add",
|
||||
vl_api_sr_mpls_policy_add_t_handler, vl_noop_handler,
|
||||
vl_api_sr_mpls_policy_add_t_endian, vl_api_sr_mpls_policy_add_t_print, 256,
|
||||
1, vl_api_sr_mpls_policy_add_t_print_json,
|
||||
vl_api_sr_mpls_policy_mod_t_tojson, vl_api_sr_mpls_policy_mod_t_fromjson);
|
||||
|
||||
/*
|
||||
* Manually register the sr policy mod msg, so we trace enough bytes
|
||||
* to capture a typical segment list
|
||||
*/
|
||||
vl_msg_api_set_handlers (REPLY_MSG_ID_BASE + VL_API_SR_MPLS_POLICY_MOD,
|
||||
"sr_mpls_policy_mod",
|
||||
vl_api_sr_mpls_policy_mod_t_handler,
|
||||
vl_noop_handler, vl_api_sr_mpls_policy_mod_t_endian,
|
||||
vl_api_sr_mpls_policy_mod_t_print, 256, 1);
|
||||
vl_msg_api_set_handlers (
|
||||
REPLY_MSG_ID_BASE + VL_API_SR_MPLS_POLICY_MOD, "sr_mpls_policy_mod",
|
||||
vl_api_sr_mpls_policy_mod_t_handler, vl_noop_handler,
|
||||
vl_api_sr_mpls_policy_mod_t_endian, vl_api_sr_mpls_policy_mod_t_print, 256,
|
||||
1, vl_api_sr_mpls_policy_mod_t_print_json,
|
||||
vl_api_sr_mpls_policy_mod_t_tojson, vl_api_sr_mpls_policy_mod_t_fromjson);
|
||||
|
||||
/*
|
||||
* Set up the (msg_name, crc, message-id) table
|
||||
|
||||
@@ -101,14 +101,6 @@ cleanup (void)
|
||||
clib_memset(pm, 0, sizeof(*pm));
|
||||
}
|
||||
|
||||
/*
|
||||
* Satisfy external references when -lvlib is not available.
|
||||
*/
|
||||
void vlib_cli_output (struct vlib_main_t * vm, char * fmt, ...)
|
||||
{
|
||||
clib_warning ("vlib_cli_output called...");
|
||||
}
|
||||
|
||||
void
|
||||
vac_free (void * msg)
|
||||
{
|
||||
|
||||
@@ -39,7 +39,7 @@ install(
|
||||
add_definitions(-fvisibility=hidden)
|
||||
|
||||
# Ensure symbols from cJSON are exported
|
||||
set_source_files_properties( cJSON.c PROPERTIES
|
||||
set_source_files_properties( cJSON.c jsonformat.c PROPERTIES
|
||||
COMPILE_DEFINITIONS " CJSON_API_VISIBILITY " )
|
||||
|
||||
|
||||
@@ -62,6 +62,7 @@ set(VPPINFRA_SRCS
|
||||
hash.c
|
||||
heap.c
|
||||
interrupt.c
|
||||
jsonformat.c
|
||||
longjmp.S
|
||||
macros.c
|
||||
maplog.c
|
||||
@@ -140,6 +141,7 @@ set(VPPINFRA_HEADERS
|
||||
hash.h
|
||||
heap.h
|
||||
interrupt.h
|
||||
jsonformat.h
|
||||
lb_hash_hash.h
|
||||
llist.h
|
||||
lock.h
|
||||
|
||||
+49
-36
@@ -157,7 +157,7 @@ typedef struct internal_hooks
|
||||
{
|
||||
void *(CJSON_CDECL *allocate)(size_t size);
|
||||
void (CJSON_CDECL *deallocate)(void *pointer);
|
||||
void *(CJSON_CDECL *reallocate)(void *pointer, size_t size);
|
||||
void *(CJSON_CDECL *reallocate)(void *pointer, size_t new_size, size_t old_size);
|
||||
} internal_hooks;
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
@@ -170,16 +170,20 @@ static void CJSON_CDECL internal_free(void *pointer)
|
||||
{
|
||||
free(pointer);
|
||||
}
|
||||
static void * CJSON_CDECL internal_realloc(void *pointer, size_t size)
|
||||
{
|
||||
return realloc(pointer, size);
|
||||
}
|
||||
#else
|
||||
#define internal_malloc malloc
|
||||
#define internal_free free
|
||||
#define internal_realloc realloc
|
||||
#endif
|
||||
|
||||
static void * CJSON_CDECL internal_realloc(void *pointer, size_t new_size,
|
||||
size_t old_size)
|
||||
{
|
||||
return realloc(pointer, new_size);
|
||||
}
|
||||
|
||||
static void *
|
||||
cjson_realloc_internal (void *ptr, size_t new_size, size_t old_size);
|
||||
|
||||
/* strlen of character literals resolved at compile time */
|
||||
#define static_strlen(string_literal) (sizeof(string_literal) - sizeof(""))
|
||||
|
||||
@@ -213,7 +217,7 @@ CJSON_PUBLIC(void) cJSON_InitHooks(cJSON_Hooks* hooks)
|
||||
/* Reset hooks */
|
||||
global_hooks.allocate = malloc;
|
||||
global_hooks.deallocate = free;
|
||||
global_hooks.reallocate = realloc;
|
||||
global_hooks.reallocate = internal_realloc;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -233,7 +237,11 @@ CJSON_PUBLIC(void) cJSON_InitHooks(cJSON_Hooks* hooks)
|
||||
global_hooks.reallocate = NULL;
|
||||
if ((global_hooks.allocate == malloc) && (global_hooks.deallocate == free))
|
||||
{
|
||||
global_hooks.reallocate = realloc;
|
||||
global_hooks.reallocate = internal_realloc;
|
||||
}
|
||||
else
|
||||
{
|
||||
global_hooks.reallocate = cjson_realloc_internal;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -435,6 +443,27 @@ typedef struct
|
||||
internal_hooks hooks;
|
||||
} printbuffer;
|
||||
|
||||
static void *
|
||||
cjson_realloc_internal (void *ptr, size_t new_size, size_t old_size)
|
||||
{
|
||||
size_t copy_size;
|
||||
if (old_size < new_size)
|
||||
copy_size = old_size;
|
||||
else
|
||||
copy_size = new_size;
|
||||
|
||||
unsigned char *newbuffer = global_hooks.allocate(new_size);
|
||||
if (!newbuffer)
|
||||
{
|
||||
global_hooks.deallocate(ptr);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memcpy (newbuffer, ptr, copy_size);
|
||||
global_hooks.deallocate (ptr);
|
||||
return newbuffer;
|
||||
}
|
||||
|
||||
/* realloc printbuffer if necessary to have at least "needed" bytes more */
|
||||
static unsigned char* ensure(printbuffer * const p, size_t needed)
|
||||
{
|
||||
@@ -486,34 +515,13 @@ static unsigned char* ensure(printbuffer * const p, size_t needed)
|
||||
newsize = needed * 2;
|
||||
}
|
||||
|
||||
if (p->hooks.reallocate != NULL)
|
||||
newbuffer = p->hooks.reallocate (p->buffer, newsize, p->length);
|
||||
if (newbuffer == NULL)
|
||||
{
|
||||
/* reallocate with realloc if available */
|
||||
newbuffer = (unsigned char*)p->hooks.reallocate(p->buffer, newsize);
|
||||
if (newbuffer == NULL)
|
||||
{
|
||||
p->hooks.deallocate(p->buffer);
|
||||
p->length = 0;
|
||||
p->buffer = NULL;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* otherwise reallocate manually */
|
||||
newbuffer = (unsigned char*)p->hooks.allocate(newsize);
|
||||
if (!newbuffer)
|
||||
{
|
||||
p->hooks.deallocate(p->buffer);
|
||||
p->length = 0;
|
||||
p->buffer = NULL;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memcpy (newbuffer, p->buffer, p->offset + 1);
|
||||
p->hooks.deallocate (p->buffer);
|
||||
p->hooks.deallocate(p->buffer);
|
||||
p->length = 0;
|
||||
p->buffer = NULL;
|
||||
return NULL;
|
||||
}
|
||||
p->length = newsize;
|
||||
p->buffer = newbuffer;
|
||||
@@ -1208,7 +1216,7 @@ static unsigned char *print(const cJSON * const item, cJSON_bool format, const i
|
||||
/* check if reallocate is available */
|
||||
if (hooks->reallocate != NULL)
|
||||
{
|
||||
printed = (unsigned char*) hooks->reallocate(buffer->buffer, buffer->offset + 1);
|
||||
printed = (unsigned char*) hooks->reallocate(buffer->buffer, buffer->offset + 1, default_buffer_size);
|
||||
if (printed == NULL) {
|
||||
goto fail;
|
||||
}
|
||||
@@ -3112,3 +3120,8 @@ CJSON_PUBLIC(void) cJSON_free(void *object)
|
||||
{
|
||||
global_hooks.deallocate(object);
|
||||
}
|
||||
|
||||
CJSON_PUBLIC(void *) cJSON_realloc(void *object, size_t new_size, size_t old_size)
|
||||
{
|
||||
return global_hooks.reallocate(object, new_size, old_size);
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user