api: verify message size on receipt

When a message is received, verify that it's sufficiently large to
accomodate any VLAs within message. To do that, we need a way to
calculate message size including any VLAs. This patch adds such
funcionality to vppapigen and necessary C code to use those to validate
message size on receipt. Drop messages which are malformed.

Type: improvement
Signed-off-by: Klement Sekera <ksekera@cisco.com>
Change-Id: I2903aa21dee84be6822b064795ba314de46c18f4
This commit is contained in:
Klement Sekera
2021-11-22 21:26:20 +01:00
committed by Ole Tr�an
parent 755042dec0
commit 9b7e8acf79
16 changed files with 280 additions and 88 deletions
+6 -1
View File
@@ -548,6 +548,10 @@ _(APP_DEL_CERT_KEY_PAIR_REPLY, app_del_cert_key_pair_reply)
#include <vnet/session/session.api.h>
#undef vl_endianfun
#define vl_calcsizefun
#include <vnet/session/session.api.h>
#undef vl_calcsizefun
#define vl_printfun
#include <vnet/session/session.api.h>
#undef vl_printfun
@@ -573,7 +577,8 @@ echo_api_hookup (echo_main_t * em)
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);
vl_api_##n##_t_tojson, vl_api_##n##_t_fromjson, \
vl_api_##n##_t_calc_size);
foreach_quic_echo_msg;
#undef _
}
+5 -1
View File
@@ -242,6 +242,9 @@ api_trace_clear_capture (vat_main_t * vam)
#define vl_printfun
#include <tracedump/tracedump.api.h>
#undef vl_printfun
#define vl_calcsizefun
#include <tracedump/tracedump.api.h>
#undef vl_calcsizefun
void
manual_setup_message_id_table (vat_main_t * vam)
@@ -251,7 +254,8 @@ manual_setup_message_id_table (vat_main_t * vam)
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);
vl_api_trace_details_t_tojson, vl_api_trace_details_t_fromjson,
vl_api_trace_details_t_calc_size);
}
#define VL_API_LOCAL_SETUP_MESSAGE_ID_TABLE manual_setup_message_id_table
+100 -10
View File
@@ -210,7 +210,8 @@ class ToJSON():
if b[1] == 0:
continue
write(' if (a & {})\n'.format(b[0]))
write(' cJSON_AddItemToArray(array, cJSON_CreateString("{}"));\n'.format(b[0]))
write(
' cJSON_AddItemToArray(array, cJSON_CreateString("{}"));\n'.format(b[0]))
write(' return array;\n')
write('}\n')
@@ -685,7 +686,7 @@ TOP_BOILERPLATE = '''\
|| defined(vl_printfun) ||defined(vl_endianfun) \\
|| defined(vl_api_version)||defined(vl_typedefs) \\
|| defined(vl_msg_name)||defined(vl_msg_name_crc_list) \\
|| defined(vl_api_version_tuple)
|| defined(vl_api_version_tuple) || defined(vl_calcsizefun)
/* ok, something was selected */
#else
#warning no content included from {input_filename}
@@ -750,7 +751,7 @@ def msg_name_crc_list(s, suffix):
for t in s['Define']:
output += "\\\n_(VL_API_%s, %s, %08x) " % \
(t.name.upper(), t.name, t.crc)
(t.name.upper(), t.name, t.crc)
output += "\n#endif"
return output
@@ -970,13 +971,13 @@ static inline void *vl_api_{name}_t_print{suffix} (vl_api_{name}_t *a, void *han
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(' (void)s;\n')
write(' char *out = cJSON_Print(o);\n')
write(' vl_print(handle, out);\n');
write(' vl_print(handle, out);\n')
write(' cJSON_Delete(o);\n')
write(' cJSON_free(out);\n');
write(' cJSON_free(out);\n')
write(' return handle;\n')
write('}\n\n');
write('}\n\n')
write("\n#endif")
write("\n#endif /* vl_printfun */\n")
@@ -1145,7 +1146,7 @@ static inline void vl_api_{name}_t_endian (vl_api_{name}_t *a)
'''
for t in objs:
if t.__class__.__name__ == 'Enum' or t.__class__.__name__ == 'EnumFlag' :
if t.__class__.__name__ == 'Enum' or t.__class__.__name__ == 'EnumFlag':
output += signature.format(name=t.name)
if t.enumtype in ENDIAN_STRINGS:
output += (' *a = {}(*a);\n'
@@ -1187,6 +1188,78 @@ static inline void vl_api_{name}_t_endian (vl_api_{name}_t *a)
return output
def calc_size_fun(objs, modulename):
'''Main entry point for calculate size function generation'''
output = '''\
/****** Calculate size functions *****/\n\
#ifdef vl_calcsizefun
#ifndef included_{module}_calcsizefun
#define included_{module}_calcsizefun
'''
output = output.format(module=modulename)
signature = '''\
/* calculate message size of message in network byte order */
static inline uword vl_api_{name}_t_calc_size (vl_api_{name}_t *a)
{{
'''
for o in objs:
tname = o.__class__.__name__
output += signature.format(name=o.name)
output += f" return sizeof(*a)"
if tname == 'Using':
if 'length' in o.alias:
try:
tmp = int(o.alias['length'])
if tmp == 0:
raise (f"Unexpected length '0' for alias {o}")
except:
# output += f" + vl_api_{o.alias.name}_t_calc_size({o.name})"
print("culprit:")
print(o)
print(dir(o.alias))
print(o.alias)
raise
elif tname == 'Enum' or tname == 'EnumFlag':
pass
else:
for b in o.block:
if b.type == 'Option':
continue
elif b.type == 'Field':
if b.fieldtype.startswith('vl_api_'):
output += f" - sizeof(a->{b.fieldname})"
output += f" + {b.fieldtype}_calc_size(&a->{b.fieldname})"
elif b.type == 'Array':
if b.lengthfield:
m = list(filter(lambda x: x.fieldname == b.lengthfield, o.block))
if len(m) != 1:
raise Exception(f"Expected 1 match for field '{b.lengthfield}', got '{m}'")
lf = m[0]
if lf.fieldtype in ENDIAN_STRINGS:
output += f" + {ENDIAN_STRINGS[lf.fieldtype]}(a->{b.lengthfield}) * sizeof(a->{b.fieldname}[0])"
elif lf.fieldtype == "u8":
output += f" + a->{b.lengthfield} * sizeof(a->{b.fieldname}[0])"
else:
raise Exception(f"Don't know how to endian swap {lf.fieldtype}")
else:
# Fixed length strings decay to nul terminated u8
if b.fieldtype == 'string':
if b.modern_vla:
output += f" + vl_api_string_len(&a->{b.fieldname})"
output += ";\n"
output += '}\n\n'
output += "\n#endif"
output += "\n#endif /* vl_calcsizefun */\n\n"
return output
def version_tuple(s, module):
'''Generate semantic version string'''
output = '''\
@@ -1336,6 +1409,10 @@ def generate_c_boilerplate(services, defines, counters, file_crc,
#include "{module}.api.h"
#undef vl_endianfun
#define vl_calcsizefun
#include "{module}.api.h"
#undef vl_calsizefun
/* instantiate all the print functions we know about */
#define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
#define vl_printfun
@@ -1371,6 +1448,7 @@ def generate_c_boilerplate(services, defines, counters, file_crc,
' .print_json = vl_api_{n}_t_print_json,\n'
' .tojson = vl_api_{n}_t_tojson,\n'
' .fromjson = vl_api_{n}_t_fromjson,\n'
' .calc_size = vl_api_{n}_t_calc_size,\n'
' .is_autoendian = {auto}}};\n'
.format(n=s.caller, ID=s.caller.upper(),
auto=d.autoendian))
@@ -1389,6 +1467,7 @@ def generate_c_boilerplate(services, defines, counters, file_crc,
' .print_json = vl_api_{n}_t_print_json,\n'
' .tojson = vl_api_{n}_t_tojson,\n'
' .fromjson = vl_api_{n}_t_fromjson,\n'
' .calc_size = vl_api_{n}_t_calc_size,\n'
' .is_autoendian = {auto}}};\n'
.format(n=s.reply, ID=s.reply.upper(),
auto=d.autoendian))
@@ -1427,6 +1506,10 @@ def generate_c_test_boilerplate(services, defines, file_crc, module, plugin,
#include "{module}.api.h"
#undef vl_endianfun
#define vl_calcsizefun
#include "{module}.api.h"
#undef vl_calsizefun
/* instantiate all the print functions we know about */
#define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
#define vl_printfun
@@ -1488,7 +1571,8 @@ def generate_c_test_boilerplate(services, defines, file_crc, module, plugin,
' 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'
' vl_api_{n}_t_fromjson,\n'
' vl_api_{n}_t_calc_size);\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))
@@ -1510,7 +1594,8 @@ def generate_c_test_boilerplate(services, defines, file_crc, module, plugin,
' 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'
' vl_api_{n}_t_fromjson,\n'
' vl_api_{n}_t_calc_size);\n'
.format(n=e, ID=e.upper()))
write('}\n')
@@ -1729,6 +1814,10 @@ def generate_c_test2_boilerplate(services, defines, module, stream):
#include "{module}.api.h"
#undef vl_endianfun
#define vl_calcsizefun
#include "{module}.api.h"
#undef vl_calsizefun
#define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
#define vl_printfun
#include "{module}.api.h"
@@ -1863,6 +1952,7 @@ def run(args, apifilename, s):
output += stream.getvalue()
stream.close()
output += endianfun(s['types'] + s['Define'], modulename)
output += calc_size_fun(s['types'] + s['Define'], modulename)
output += version_tuple(s, basename)
output += BOTTOM_BOILERPLATE.format(input_filename=basename,
file_crc=s['file_crc'])
+9 -5
View File
@@ -64,6 +64,10 @@
#include <vlibmemory/memclnt.api.h>
#undef vl_endianfun
#define vl_calcsizefun
#include <vlibmemory/memclnt.api.h>
#undef vl_calcsizefun
/* instantiate all the print functions we know about */
#if VPP_API_TEST_BUILTIN == 0
#define vl_print(handle, ...)
@@ -2737,11 +2741,11 @@ void
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_json, vl_api_##n##_t_tojson, \
vl_api_##n##_t_fromjson);
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_json, vl_api_##n##_t_tojson, \
vl_api_##n##_t_fromjson, vl_api_##n##_t_calc_size);
foreach_vpe_api_reply_msg;
#if VPP_API_TEST_BUILTIN == 0
foreach_standalone_reply_msg;
+6 -1
View File
@@ -276,6 +276,10 @@ vl_api_app_del_cert_key_pair_reply_t_handler (
#include <vnet/session/session.api.h>
#undef vl_endianfun
#define vl_calcsizefun
#include <vnet/session/session.api.h>
#undef vl_calcsizefun
/* instantiate all the print functions we know about */
#define vl_printfun
#include <vnet/session/session.api.h>
@@ -303,7 +307,8 @@ vcl_bapi_hookup (void)
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);
vl_api_##n##_t_tojson, vl_api_##n##_t_fromjson, \
vl_api_##n##_t_calc_size);
foreach_sock_msg;
#undef _
}
+11 -6
View File
@@ -132,6 +132,7 @@ typedef struct
void *print_json; /**< message print function (JSON format) */
void *tojson; /**< binary to JSON convert function */
void *fromjson; /**< JSON to binary convert function */
void *calc_size; /**< message size calculation */
int size; /**< message size */
int traced; /**< is this message to be traced? */
int replay; /**< is this message to be replayed? */
@@ -170,17 +171,18 @@ VL_MSG_API_POISON (const void *a)
}
/* api_shared.c prototypes */
void vl_msg_api_handler (void *the_msg);
void vl_msg_api_handler_no_free (void *the_msg);
void vl_msg_api_handler_no_trace_no_free (void *the_msg);
void vl_msg_api_trace_only (void *the_msg);
void vl_msg_api_handler (void *the_msg, uword msg_len);
void vl_msg_api_handler_no_free (void *the_msg, uword msg_len);
void vl_msg_api_handler_no_trace_no_free (void *the_msg, uword msg_len);
void vl_msg_api_trace_only (void *the_msg, uword msg_len);
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_socket_handler (void *the_msg, uword msg_len);
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 *tojson, void *fromjson,
void *validate_size);
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);
@@ -251,6 +253,9 @@ typedef struct api_main_t
/** Message convert function vector */
void *(**msg_fromjson_handlers) (cJSON *, int *);
/** Message calc size function vector */
uword (**msg_calc_size_funcs) (void *);
/** Message name vector */
const char **msg_names;
+60 -29
View File
@@ -500,8 +500,8 @@ vl_msg_api_barrier_release (void)
}
always_inline void
msg_handler_internal (api_main_t * am,
void *the_msg, int trace_it, int do_it, int free_it)
msg_handler_internal (api_main_t *am, void *the_msg, uword msg_len,
int trace_it, int do_it, int free_it)
{
u16 id = clib_net_to_host_u16 (*((u16 *) the_msg));
u8 *(*print_fp) (void *, void *);
@@ -545,8 +545,35 @@ msg_handler_internal (api_main_t * am,
}
}
if (do_it)
uword calc_size = 0;
uword (*calc_size_fp) (void *);
calc_size_fp = am->msg_calc_size_funcs[id];
ASSERT (NULL != calc_size_fp);
if (calc_size_fp)
{
calc_size = (*calc_size_fp) (the_msg);
ASSERT (calc_size <= msg_len);
if (calc_size > msg_len)
{
clib_warning (
"Truncated message '%s' (id %u) received, calculated size "
"%lu is bigger than actual size %llu, message dropped.",
am->msg_names[id], id, calc_size, msg_len);
}
}
else
{
clib_warning ("Message '%s' (id %u) has NULL calc_size_func, cannot "
"verify message size is correct",
am->msg_names[id], id);
}
/* don't process message if it's truncated, otherwise byte swaps
* and stuff could corrupt memory even beyond message if it's malicious
* e.g. VLA length field set to 1M elements, but VLA empty */
if (do_it && calc_size <= msg_len)
{
if (!am->is_mp_safe[id])
{
vl_msg_api_barrier_trace_context (am->msg_names[id]);
@@ -569,6 +596,7 @@ msg_handler_internal (api_main_t * am,
if (PREDICT_FALSE (vec_len (am->perf_counter_cbs) != 0))
clib_call_callbacks (am->perf_counter_cbs, am, id,
1 /* after */ );
if (!am->is_mp_safe[id])
vl_msg_api_barrier_release ();
}
@@ -767,32 +795,30 @@ vl_msg_api_handler_with_vm_node (api_main_t * am, svm_region_t * vlib_rp,
}
void
vl_msg_api_handler (void *the_msg)
vl_msg_api_handler (void *the_msg, uword msg_len)
{
api_main_t *am = vlibapi_get_main ();
msg_handler_internal (am, the_msg,
(am->rx_trace
&& am->rx_trace->enabled) /* trace_it */ ,
1 /* do_it */ , 1 /* free_it */ );
msg_handler_internal (am, the_msg, msg_len,
(am->rx_trace && am->rx_trace->enabled) /* trace_it */,
1 /* do_it */, 1 /* free_it */);
}
void
vl_msg_api_handler_no_free (void *the_msg)
vl_msg_api_handler_no_free (void *the_msg, uword msg_len)
{
api_main_t *am = vlibapi_get_main ();
msg_handler_internal (am, the_msg,
(am->rx_trace
&& am->rx_trace->enabled) /* trace_it */ ,
1 /* do_it */ , 0 /* free_it */ );
msg_handler_internal (am, the_msg, msg_len,
(am->rx_trace && am->rx_trace->enabled) /* trace_it */,
1 /* do_it */, 0 /* free_it */);
}
void
vl_msg_api_handler_no_trace_no_free (void *the_msg)
vl_msg_api_handler_no_trace_no_free (void *the_msg, uword msg_len)
{
api_main_t *am = vlibapi_get_main ();
msg_handler_internal (am, the_msg, 0 /* trace_it */ , 1 /* do_it */ ,
0 /* free_it */ );
msg_handler_internal (am, the_msg, msg_len, 0 /* trace_it */, 1 /* do_it */,
0 /* free_it */);
}
/*
@@ -805,14 +831,13 @@ vl_msg_api_handler_no_trace_no_free (void *the_msg)
*
*/
void
vl_msg_api_trace_only (void *the_msg)
vl_msg_api_trace_only (void *the_msg, uword msg_len)
{
api_main_t *am = vlibapi_get_main ();
msg_handler_internal (am, the_msg,
(am->rx_trace
&& am->rx_trace->enabled) /* trace_it */ ,
0 /* do_it */ , 0 /* free_it */ );
msg_handler_internal (am, the_msg, msg_len,
(am->rx_trace && am->rx_trace->enabled) /* trace_it */,
0 /* do_it */, 0 /* free_it */);
}
void
@@ -863,14 +888,13 @@ vl_msg_api_get_msg_length (void *msg_arg)
* vl_msg_api_socket_handler
*/
void
vl_msg_api_socket_handler (void *the_msg)
vl_msg_api_socket_handler (void *the_msg, uword msg_len)
{
api_main_t *am = vlibapi_get_main ();
msg_handler_internal (am, the_msg,
(am->rx_trace
&& am->rx_trace->enabled) /* trace_it */ ,
1 /* do_it */ , 0 /* free_it */ );
msg_handler_internal (am, the_msg, msg_len,
(am->rx_trace && am->rx_trace->enabled) /* trace_it */,
1 /* do_it */, 0 /* free_it */);
}
#define foreach_msg_api_vector \
@@ -882,6 +906,7 @@ vl_msg_api_socket_handler (void *the_msg)
_ (msg_print_json_handlers) \
_ (msg_tojson_handlers) \
_ (msg_fromjson_handlers) \
_ (msg_calc_size_funcs) \
_ (api_trace_cfg) \
_ (message_bounce) \
_ (is_mp_safe) \
@@ -927,6 +952,7 @@ vl_msg_api_config (vl_msg_api_msg_config_t * c)
am->msg_print_json_handlers[c->id] = c->print_json;
am->msg_tojson_handlers[c->id] = c->tojson;
am->msg_fromjson_handlers[c->id] = c->fromjson;
am->msg_calc_size_funcs[c->id] = c->calc_size;
am->message_bounce[c->id] = c->message_bounce;
am->is_mp_safe[c->id] = c->is_mp_safe;
am->is_autoendian[c->id] = c->is_autoendian;
@@ -948,7 +974,8 @@ vl_msg_api_config (vl_msg_api_msg_config_t * c)
void
vl_msg_api_set_handlers (int id, char *name, void *handler, void *cleanup,
void *endian, void *print, int size, int traced,
void *print_json, void *tojson, void *fromjson)
void *print_json, void *tojson, void *fromjson,
void *calc_size)
{
vl_msg_api_msg_config_t cfg;
vl_msg_api_msg_config_t *c = &cfg;
@@ -969,6 +996,7 @@ vl_msg_api_set_handlers (int id, char *name, void *handler, void *cleanup,
c->tojson = tojson;
c->fromjson = fromjson;
c->print_json = print_json;
c->calc_size = calc_size;
vl_msg_api_config (c);
}
@@ -999,8 +1027,11 @@ vl_msg_api_queue_handler (svm_queue_t * q)
{
uword msg;
while (!svm_queue_sub (q, (u8 *) & msg, SVM_Q_WAIT, 0))
vl_msg_api_handler ((void *) msg);
while (!svm_queue_sub (q, (u8 *) &msg, SVM_Q_WAIT, 0))
{
msgbuf_t *msgbuf = (msgbuf_t *) ((u8 *) msg - offsetof (msgbuf_t, data));
vl_msg_api_handler ((void *) msg, ntohl (msgbuf->data_len));
}
}
u32
+17 -11
View File
@@ -58,6 +58,10 @@
#include <vlibmemory/vl_memory_api_h.h>
#undef vl_endianfun
#define vl_calcsizefun
#include <vlibmemory/vl_memory_api_h.h>
#undef vl_calcsizefun
static void
vl_api_get_first_msg_id_t_handler (vl_api_get_first_msg_id_t *mp)
{
@@ -177,6 +181,7 @@ vlib_api_init (void)
c->print_json = vl_api_##n##_t_print_json; \
c->tojson = vl_api_##n##_t_tojson; \
c->fromjson = vl_api_##n##_t_fromjson; \
c->calc_size = vl_api_##n##_t_calc_size; \
c->size = sizeof (vl_api_##n##_t); \
c->traced = 1; /* trace, so these msgs print */ \
c->replay = 0; /* don't replay client create/delete msgs */ \
@@ -505,8 +510,9 @@ api_rx_from_node (vlib_main_t *vm, vlib_node_runtime_t *node,
vec_add (long_msg, msg, msg_len);
}
msg = long_msg;
msg_len = vec_len (long_msg);
}
vl_msg_api_handler_no_trace_no_free (msg);
vl_msg_api_handler_no_trace_no_free (msg, msg_len);
}
/* Free what we've been given. */
@@ -704,20 +710,20 @@ 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_api_##n##_t_print_json, \
vl_api_##n##_t_tojson, vl_api_##n##_t_fromjson);
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, vl_api_##n##_t_calc_size);
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_api_##n##_t_print_json, \
vl_api_##n##_t_tojson, vl_api_##n##_t_fromjson);
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, vl_api_##n##_t_calc_size);
foreach_plugin_trace_msg;
#undef _
+21 -8
View File
@@ -39,6 +39,10 @@
#include <vlibmemory/vl_memory_api_h.h>
#undef vl_endianfun
#define vl_calcsizefun
#include <vlibmemory/vl_memory_api_h.h>
#undef vl_calcsizefun
/* instantiate all the print functions we know about */
#define vl_print(handle, ...) clib_warning (__VA_ARGS__)
#define vl_printfun
@@ -240,7 +244,8 @@ vl_client_connect (const char *name, int ctx_quota, int input_queue_size)
}
rv = clib_net_to_host_u32 (rp->response);
vl_msg_api_handler ((void *) rp);
msgbuf_t *msgbuf = (msgbuf_t *) ((u8 *) rp - offsetof (msgbuf_t, data));
vl_msg_api_handler ((void *) rp, ntohl (msgbuf->data_len));
break;
}
return (rv);
@@ -289,6 +294,7 @@ vl_client_disconnect (void)
svm_queue_t *vl_input_queue;
api_main_t *am = vlibapi_get_main ();
time_t begin;
msgbuf_t *msgbuf;
vl_input_queue = am->vl_input_queue;
vl_client_send_disconnect (0 /* wait for reply */ );
@@ -321,10 +327,12 @@ vl_client_disconnect (void)
if (ntohs (rp->_vl_msg_id) != VL_API_MEMCLNT_DELETE_REPLY)
{
clib_warning ("queue drain: %d", ntohs (rp->_vl_msg_id));
vl_msg_api_handler ((void *) rp);
msgbuf = (msgbuf_t *) ((u8 *) rp - offsetof (msgbuf_t, data));
vl_msg_api_handler ((void *) rp, ntohl (msgbuf->data_len));
continue;
}
vl_msg_api_handler ((void *) rp);
msgbuf = (msgbuf_t *) ((u8 *) rp - offsetof (msgbuf_t, data));
vl_msg_api_handler ((void *) rp, ntohl (msgbuf->data_len));
break;
}
@@ -364,11 +372,11 @@ vl_client_install_client_message_handlers (void)
{
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); \
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, vl_api_##n##_t_calc_size); \
am->api_trace_cfg[VL_API_##N].replay_enable = 0;
foreach_api_msg;
#undef _
@@ -569,6 +577,11 @@ vl_client_get_first_plugin_msg_id (const char *plugin_name)
old_handler = am->msg_handlers[VL_API_GET_FIRST_MSG_ID_REPLY];
am->msg_handlers[VL_API_GET_FIRST_MSG_ID_REPLY] = (void *)
vl_api_get_first_msg_id_reply_t_handler;
if (!am->msg_calc_size_funcs[VL_API_GET_FIRST_MSG_ID_REPLY])
{
am->msg_calc_size_funcs[VL_API_GET_FIRST_MSG_ID_REPLY] =
(uword (*) (void *)) vl_api_get_first_msg_id_reply_t_calc_size;
}
/* Ask the data-plane for the message-ID base of the indicated plugin */
mm->first_msg_id_reply_ready = 0;
+10 -6
View File
@@ -45,6 +45,10 @@
#include <vlibmemory/vl_memory_api_h.h>
#undef vl_endianfun
#define vl_calcsizefun
#include <vlibmemory/vl_memory_api_h.h>
#undef vl_calcsizefun
socket_main_t socket_main;
#define SOCK_API_REG_HANDLE_BIT (1<<31)
@@ -200,7 +204,7 @@ vl_socket_process_api_msg (vl_api_registration_t * rp, i8 * input_v)
u8 *the_msg = (u8 *) (mbp->data);
socket_main.current_rp = rp;
vl_msg_api_socket_handler (the_msg);
vl_msg_api_socket_handler (the_msg, ntohl (mbp->data_len));
socket_main.current_rp = 0;
}
@@ -792,11 +796,11 @@ vl_sock_api_init (vlib_main_t * vm)
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, \
vl_api_##n##_t_print_json, vl_api_##n##_t_tojson, \
vl_api_##n##_t_fromjson); \
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, vl_api_##n##_t_calc_size); \
am->api_trace_cfg[VL_API_##N].replay_enable = 0;
foreach_vlib_api_msg;
#undef _
+10 -6
View File
@@ -36,6 +36,10 @@
#include <vlibmemory/vl_memory_api_h.h>
#undef vl_endianfun
#define vl_calcsizefun
#include <vlibmemory/vl_memory_api_h.h>
#undef vl_calcsizefun
/* instantiate all the print functions we know about */
#define vl_print(handle, ...) clib_warning (__VA_ARGS__)
#define vl_printfun
@@ -134,7 +138,7 @@ vl_socket_client_read_internal (socket_client_main_t * scm, int wait)
if (vec_len (scm->socket_rx_buffer) >= data_len + sizeof (*mbp))
{
vl_msg_api_socket_handler ((void *) (mbp->data));
vl_msg_api_socket_handler ((void *) (mbp->data), data_len);
if (vec_len (scm->socket_rx_buffer) == data_len + sizeof (*mbp))
_vec_len (scm->socket_rx_buffer) = 0;
@@ -433,11 +437,11 @@ 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), 0, \
vl_api_##n##_t_print_json, vl_api_##n##_t_tojson, \
vl_api_##n##_t_fromjson);
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, vl_api_##n##_t_calc_size);
foreach_sock_client_api_msg;
#undef _
}
+3 -1
View File
@@ -514,7 +514,9 @@ vl_api_add_del_ip_punt_redirect_v2_t_handler (
goto out;
if (0 != n_paths)
vec_validate (rpaths, n_paths - 1);
{
vec_validate (rpaths, n_paths - 1);
}
for (ii = 0; ii < n_paths; ii++)
{
+4
View File
@@ -36,6 +36,10 @@
#include <vnet/ip/ip.api.h>
#undef vl_endianfun
#define vl_calcsizefun
#include <vnet/ip/ip.api.h>
#undef vl_calcsizefun
typedef struct
{
/* API message ID base */
+4
View File
@@ -26,6 +26,10 @@
#include <vnet/ipsec/ipsec.api.h>
#undef vl_endianfun
#define vl_calcsizefun
#include <vnet/ipsec/ipsec.api.h>
#undef vl_calcsizefun
typedef struct
{
/* API message ID base */
+4
View File
@@ -28,6 +28,10 @@
#include <vnet/l2/l2.api.h>
#undef vl_endianfun
#define vl_calcsizefun
#include <vnet/l2/l2.api.h>
#undef vl_calcsizefun
typedef struct
{
/* API message ID base */
+10 -3
View File
@@ -39,6 +39,10 @@
#include <vnet/srmpls/sr_mpls.api.h>
#undef vl_endianfun
#define vl_calcsizefun
#include <vnet/srmpls/sr_mpls.api.h>
#undef vl_calcsizefun
#define vl_printfun
#include <vnet/srmpls/sr_mpls.api.h>
#undef vl_printfun
@@ -194,7 +198,8 @@ sr_mpls_api_hookup (vlib_main_t * vm)
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);
vl_api_##n##_t_tojson, vl_api_##n##_t_fromjson, \
vl_api_##n##_t_calc_size);
foreach_vpe_api_msg;
#undef _
@@ -207,7 +212,8 @@ sr_mpls_api_hookup (vlib_main_t * vm)
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);
vl_api_sr_mpls_policy_add_t_tojson, vl_api_sr_mpls_policy_add_t_fromjson,
vl_api_sr_mpls_policy_add_t_calc_size);
/*
* Manually register the sr policy mod msg, so we trace enough bytes
@@ -218,7 +224,8 @@ sr_mpls_api_hookup (vlib_main_t * vm)
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);
vl_api_sr_mpls_policy_mod_t_tojson, vl_api_sr_mpls_policy_mod_t_fromjson,
vl_api_sr_mpls_policy_mod_t_calc_size);
/*
* Set up the (msg_name, crc, message-id) table