diff options
author | Ole Troan <ot@cisco.com> | 2019-09-19 01:08:30 +0200 |
---|---|---|
committer | Dave Barach <openvpp@barachs.net> | 2019-09-25 12:02:32 +0000 |
commit | 2a1ca787b9ca0021bd5da73450caedc2ff41c76d (patch) | |
tree | f9d879e07099f727ca565cfd8bc1624d3e7dc405 | |
parent | 33af8c1ed89f15cf0601ee891e9603bef16f2c93 (diff) |
api: split api generated files
Split generation of API message enum and the typedefs into
separate files, so that the type file can be included from
elsewhere.
Generate a C file for VPP that contains the API registration,
this was previously done via X macros by the C pre-
processor.
This allows deleting lots of skeleton/copy paste code
for each feature.
plugins/flowprobe
plugins/map
examples/sample-plugin
vnet/ipip
used as Guinea pigs.
Generate a C Test file for VAT, that does the same for VAT plugins.
Also add support for a per-message CLI option, that is currently
limited to VAT help text. option vat_help = "<help text>";
Type: refactor
Change-Id: I245e3104bb76f7e1fb69a59ab20cc7c8dfcdd460
Signed-off-by: Ole Troan <ot@cisco.com>
25 files changed, 338 insertions, 695 deletions
diff --git a/src/cmake/api.cmake b/src/cmake/api.cmake index 693c55d86b7..922c83a8b4d 100644 --- a/src/cmake/api.cmake +++ b/src/cmake/api.cmake @@ -26,7 +26,7 @@ function(vpp_generate_api_c_header file) add_custom_command (OUTPUT ${output_name} COMMAND mkdir -p ${output_dir} COMMAND ${VPP_APIGEN} - ARGS ${includedir} --includedir ${CMAKE_SOURCE_DIR} --input ${CMAKE_CURRENT_SOURCE_DIR}/${file} --output ${output_name} + ARGS ${includedir} --includedir ${CMAKE_SOURCE_DIR} --input ${CMAKE_CURRENT_SOURCE_DIR}/${file} --outputdir ${output_dir} --output ${output_name} DEPENDS ${VPP_APIGEN} ${CMAKE_CURRENT_SOURCE_DIR}/${file} COMMENT "Generating API header ${output_name}" ) diff --git a/src/cmake/library.cmake b/src/cmake/library.cmake index 488687c03d8..fd6c077ea21 100644 --- a/src/cmake/library.cmake +++ b/src/cmake/library.cmake @@ -48,6 +48,8 @@ macro(add_vpp_library lib) get_filename_component(dir ${file} DIRECTORY) install( FILES ${file} ${CMAKE_CURRENT_BINARY_DIR}/${file}.h + ${CMAKE_CURRENT_BINARY_DIR}/${file}_enum.h + ${CMAKE_CURRENT_BINARY_DIR}/${file}_types.h DESTINATION include/${lib}/${dir} COMPONENT vpp-dev ) diff --git a/src/examples/sample-plugin/sample/sample.c b/src/examples/sample-plugin/sample/sample.c index 91e8939f789..4aeb5358e95 100644 --- a/src/examples/sample-plugin/sample/sample.c +++ b/src/examples/sample-plugin/sample/sample.c @@ -24,38 +24,12 @@ #include <vlibapi/api.h> #include <vlibmemory/api.h> -/* define message IDs */ -#include <sample/sample_msg_enum.h> - -/* define message structures */ -#define vl_typedefs -#include <sample/sample_all_api_h.h> -#undef vl_typedefs - -/* define generated endian-swappers */ -#define vl_endianfun -#include <sample/sample_all_api_h.h> -#undef vl_endianfun - -/* instantiate all the print functions we know about */ -#define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__) -#define vl_printfun -#include <sample/sample_all_api_h.h> -#undef vl_printfun - -/* Get the API version number */ -#define vl_api_version(n,v) static u32 api_version=(v); -#include <sample/sample_all_api_h.h> -#undef vl_api_version +#include <sample/sample.api_enum.h> +#include <sample/sample.api_types.h> #define REPLY_MSG_ID_BASE sm->msg_id_base #include <vlibapi/api_helper_macros.h> -/* List of message types that this plugin understands */ - -#define foreach_sample_plugin_api_msg \ -_(SAMPLE_MACSWAP_ENABLE_DISABLE, sample_macswap_enable_disable) - /* *INDENT-OFF* */ VLIB_PLUGIN_REGISTER () = { .version = SAMPLE_PLUGIN_BUILD_VER, @@ -165,39 +139,8 @@ static void vl_api_sample_macswap_enable_disable_t_handler REPLY_MACRO(VL_API_SAMPLE_MACSWAP_ENABLE_DISABLE_REPLY); } -/** - * @brief Set up the API message handling tables. - */ -static clib_error_t * -sample_plugin_api_hookup (vlib_main_t *vm) -{ - sample_main_t * sm = &sample_main; -#define _(N,n) \ - vl_msg_api_set_handlers((VL_API_##N + sm->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); - foreach_sample_plugin_api_msg; -#undef _ - - return 0; -} - -#define vl_msg_name_crc_list -#include <sample/sample_all_api_h.h> -#undef vl_msg_name_crc_list - -static void -setup_message_id_table (sample_main_t * sm, api_main_t *am) -{ -#define _(id,n,crc) \ - vl_msg_api_add_msg_name_crc (am, #n "_" #crc, id + sm->msg_id_base); - foreach_vl_msg_name_crc_sample; -#undef _ -} +/* API definitions */ +#include <sample/sample.api.c> /** * @brief Initialize the sample plugin. @@ -205,25 +148,13 @@ setup_message_id_table (sample_main_t * sm, api_main_t *am) static clib_error_t * sample_init (vlib_main_t * vm) { sample_main_t * sm = &sample_main; - clib_error_t * error = 0; - u8 * name; sm->vnet_main = vnet_get_main (); - name = format (0, "sample_%08x%c", api_version, 0); - - /* Ask for a correctly-sized block of API message decode slots */ - sm->msg_id_base = vl_msg_api_get_msg_ids - ((char *) name, VL_MSG_FIRST_AVAILABLE); - - error = sample_plugin_api_hookup (vm); - /* Add our API messages to the global name_crc hash table */ - setup_message_id_table (sm, &api_main); + sm->msg_id_base = setup_message_id_table (); - vec_free(name); - - return error; + return 0; } VLIB_INIT_FUNCTION (sample_init); diff --git a/src/examples/sample-plugin/sample/sample_all_api_h.h b/src/examples/sample-plugin/sample/sample_all_api_h.h deleted file mode 100644 index 774d782f899..00000000000 --- a/src/examples/sample-plugin/sample/sample_all_api_h.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2015 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. - */ -/* Include the generated file, see BUILT_SOURCES in Makefile.am */ -#include <sample/sample.api.h> diff --git a/src/examples/sample-plugin/sample/sample_msg_enum.h b/src/examples/sample-plugin/sample/sample_msg_enum.h deleted file mode 100644 index af4172f7876..00000000000 --- a/src/examples/sample-plugin/sample/sample_msg_enum.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (c) 2015 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_sample_msg_enum_h -#define included_sample_msg_enum_h - -#include <vppinfra/byte_order.h> - -#define vl_msg_id(n,h) n, -typedef enum { -#include <sample/sample_all_api_h.h> - /* We'll want to know how many messages IDs we need... */ - VL_MSG_FIRST_AVAILABLE, -} vl_msg_id_t; -#undef vl_msg_id - -#endif /* included_sample_msg_enum_h */ diff --git a/src/examples/sample-plugin/sample/sample_test.c b/src/examples/sample-plugin/sample/sample_test.c index 6f645f7864d..df862bb3647 100644 --- a/src/examples/sample-plugin/sample/sample_test.c +++ b/src/examples/sample-plugin/sample/sample_test.c @@ -29,30 +29,8 @@ uword unformat_sw_if_index (unformat_input_t * input, va_list * args); /* Declare message IDs */ -#include <sample/sample_msg_enum.h> - -/* define message structures */ -#define vl_typedefs -#include <sample/sample_all_api_h.h> -#undef vl_typedefs - -/* declare message handlers for each api */ - -#define vl_endianfun /* define message structures */ -#include <sample/sample_all_api_h.h> -#undef vl_endianfun - -/* instantiate all the print functions we know about */ -#define vl_print(handle, ...) -#define vl_printfun -#include <sample/sample_all_api_h.h> -#undef vl_printfun - -/* Get the API version number. */ -#define vl_api_version(n,v) static u32 api_version=(v); -#include <sample/sample_all_api_h.h> -#undef vl_api_version - +#include <sample/sample.api_enum.h> +#include <sample/sample.api_types.h> typedef struct { /* API message ID base */ @@ -62,33 +40,6 @@ typedef struct { sample_test_main_t sample_test_main; -#define foreach_standard_reply_retval_handler \ -_(sample_macswap_enable_disable_reply) - -#define _(n) \ - static void vl_api_##n##_t_handler \ - (vl_api_##n##_t * mp) \ - { \ - vat_main_t * vam = sample_test_main.vat_main; \ - i32 retval = ntohl(mp->retval); \ - if (vam->async_mode) { \ - vam->async_errors += (retval < 0); \ - } else { \ - vam->retval = retval; \ - vam->result_ready = 1; \ - } \ - } -foreach_standard_reply_retval_handler; -#undef _ - -/* - * Table of message reply handlers, must include boilerplate handlers - * we just generated - */ -#define foreach_vpe_api_reply_msg \ -_(SAMPLE_MACSWAP_ENABLE_DISABLE_REPLY, sample_macswap_enable_disable_reply) - - static int api_sample_macswap_enable_disable (vat_main_t * vam) { unformat_input_t * i = vam->input; @@ -131,33 +82,4 @@ static int api_sample_macswap_enable_disable (vat_main_t * vam) * List of messages that the api test plugin sends, * and that the data plane plugin processes */ -#define foreach_vpe_api_msg \ -_(sample_macswap_enable_disable, "<intfc> [disable]") - -static void sample_api_hookup (vat_main_t *vam) -{ - sample_test_main_t * sm = &sample_test_main; - /* Hook up handlers for replies from the data plane plug-in */ -#define _(N,n) \ - vl_msg_api_set_handlers((VL_API_##N + sm->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); - foreach_vpe_api_reply_msg; -#undef _ - - /* API messages we can send */ -#define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n); - foreach_vpe_api_msg; -#undef _ - - /* Help strings */ -#define _(n,h) hash_set_mem (vam->help_by_name, #n, h); - foreach_vpe_api_msg; -#undef _ -} - -VAT_PLUGIN_REGISTER(sample); +#include <sample/sample.api_test.c> diff --git a/src/plugins/flowprobe/CMakeLists.txt b/src/plugins/flowprobe/CMakeLists.txt index b6e4996b20b..4c1d4f33320 100644 --- a/src/plugins/flowprobe/CMakeLists.txt +++ b/src/plugins/flowprobe/CMakeLists.txt @@ -19,10 +19,6 @@ add_vpp_plugin(flowprobe API_FILES flowprobe.api - INSTALL_HEADERS - flowprobe_all_api_h.h - flowprobe_msg_enum.h - API_TEST_SOURCES flowprobe_test.c ) diff --git a/src/plugins/flowprobe/flowprobe.api b/src/plugins/flowprobe/flowprobe.api index 5bbe011f363..830e4420e4e 100644 --- a/src/plugins/flowprobe/flowprobe.api +++ b/src/plugins/flowprobe/flowprobe.api @@ -28,6 +28,7 @@ autoreply manual_print define flowprobe_tx_interface_add_del /* Interface handle */ u32 sw_if_index; + option vat_help = "<intfc> [disable]"; }; autoreply define flowprobe_params @@ -39,4 +40,5 @@ autoreply define flowprobe_params u8 record_l4; u32 active_timer; /* ~0 is off, 0 is default */ u32 passive_timer; /* ~0 is off, 0 is default */ + option vat_help = "record <[l2] [l3] [l4]> [active <timer> passive <timer>]"; }; diff --git a/src/plugins/flowprobe/flowprobe.c b/src/plugins/flowprobe/flowprobe.c index 45de3a76be6..0b070219abd 100644 --- a/src/plugins/flowprobe/flowprobe.c +++ b/src/plugins/flowprobe/flowprobe.c @@ -32,34 +32,14 @@ #include <vlibmemory/api.h> /* define message IDs */ -#include <flowprobe/flowprobe_msg_enum.h> - -/* define message structures */ -#define vl_typedefs -#include <flowprobe/flowprobe_all_api_h.h> -#undef vl_typedefs - -/* define generated endian-swappers */ -#define vl_endianfun -#include <flowprobe/flowprobe_all_api_h.h> -#undef vl_endianfun - -/* instantiate all the print functions we know about */ -#define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__) -#define vl_printfun -#include <flowprobe/flowprobe_all_api_h.h> -#undef vl_printfun +#include <flowprobe/flowprobe.api_enum.h> +#include <flowprobe/flowprobe.api_types.h> flowprobe_main_t flowprobe_main; static vlib_node_registration_t flowprobe_timer_node; uword flowprobe_walker_process (vlib_main_t * vm, vlib_node_runtime_t * rt, vlib_frame_t * f); -/* Get the API version number */ -#define vl_api_version(n,v) static u32 api_version=(v); -#include <flowprobe/flowprobe_all_api_h.h> -#undef vl_api_version - #define REPLY_MSG_ID_BASE fm->msg_id_base #include <vlibapi/api_helper_macros.h> @@ -88,6 +68,7 @@ VNET_FEATURE_INIT (flow_perpacket_l2, static) = /* *INDENT-ON* */ /* Macro to finish up custom dump fns */ +#define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__) #define FINISH \ vec_add1 (s, 0); \ vl_print (handle, (char *)s); \ @@ -756,11 +737,6 @@ vl_api_flowprobe_params_t_handler (vl_api_flowprobe_params_t * mp) REPLY_MACRO (VL_API_FLOWPROBE_PARAMS_REPLY); } -/* List of message types that this plugin understands */ -#define foreach_flowprobe_plugin_api_msg \ -_(FLOWPROBE_TX_INTERFACE_ADD_DEL, flowprobe_tx_interface_add_del) \ -_(FLOWPROBE_PARAMS, flowprobe_params) - /* *INDENT-OFF* */ VLIB_PLUGIN_REGISTER () = { .version = VPP_BUILD_VER, @@ -980,42 +956,6 @@ VLIB_CLI_COMMAND (flowprobe_show_stats_command, static) = { }; /* *INDENT-ON* */ -/** - * @brief Set up the API message handling tables - * @param vm vlib_main_t * vlib main data structure pointer - * @returns 0 to indicate all is well - */ -static clib_error_t * -flowprobe_plugin_api_hookup (vlib_main_t * vm) -{ - flowprobe_main_t *fm = &flowprobe_main; -#define _(N,n) \ - vl_msg_api_set_handlers((VL_API_##N + fm->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); - foreach_flowprobe_plugin_api_msg; -#undef _ - - return 0; -} - -#define vl_msg_name_crc_list -#include <flowprobe/flowprobe_all_api_h.h> -#undef vl_msg_name_crc_list - -static void -setup_message_id_table (flowprobe_main_t * fm, api_main_t * am) -{ -#define _(id,n,crc) \ - vl_msg_api_add_msg_name_crc (am, #n "_" #crc, id + fm->msg_id_base); - foreach_vl_msg_name_crc_flowprobe; -#undef _ -} - /* * Main-core process, sending an interrupt to the per worker input * process that spins the per worker timer wheel. @@ -1076,6 +1016,8 @@ VLIB_REGISTER_NODE (flowprobe_timer_node,static) = { }; /* *INDENT-ON* */ +#include <flowprobe/flowprobe.api.c> + /** * @brief Set up the API message handling tables * @param vm vlib_main_t * vlib main data structure pointer @@ -1087,26 +1029,13 @@ flowprobe_init (vlib_main_t * vm) flowprobe_main_t *fm = &flowprobe_main; vlib_thread_main_t *tm = &vlib_thread_main; clib_error_t *error = 0; - u8 *name; u32 num_threads; int i; fm->vnet_main = vnet_get_main (); - /* Construct the API name */ - name = format (0, "flowprobe_%08x%c", api_version, 0); - /* Ask for a correctly-sized block of API message decode slots */ - fm->msg_id_base = vl_msg_api_get_msg_ids - ((char *) name, VL_MSG_FIRST_AVAILABLE); - - /* Hook up message handlers */ - error = flowprobe_plugin_api_hookup (vm); - - /* Add our API messages to the global name_crc hash table */ - setup_message_id_table (fm, &api_main); - - vec_free (name); + fm->msg_id_base = setup_message_id_table (); /* Set up time reference pair */ fm->vlib_time_0 = vlib_time_now (vm); diff --git a/src/plugins/flowprobe/flowprobe_all_api_h.h b/src/plugins/flowprobe/flowprobe_all_api_h.h deleted file mode 100644 index 1f30ecccf98..00000000000 --- a/src/plugins/flowprobe/flowprobe_all_api_h.h +++ /dev/null @@ -1,18 +0,0 @@ -/* - * flowprobe_all_api_h.h - plug-in api #include file - * - * Copyright (c) <current-year> <your-organization> - * 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. - */ -/* Include the generated file, see BUILT_SOURCES in Makefile.am */ -#include <flowprobe/flowprobe.api.h> diff --git a/src/plugins/flowprobe/flowprobe_msg_enum.h b/src/plugins/flowprobe/flowprobe_msg_enum.h deleted file mode 100644 index bc0b21c96c1..00000000000 --- a/src/plugins/flowprobe/flowprobe_msg_enum.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * flowprobe_msg_enum.h - vpp engine plug-in message enumeration - * - * Copyright (c) <current-year> <your-organization> - * 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_flowprobe_msg_enum_h -#define included_flowprobe_msg_enum_h - -#include <vppinfra/byte_order.h> - -#define vl_msg_id(n,h) n, -typedef enum -{ -#include <flowprobe/flowprobe_all_api_h.h> - /* We'll want to know how many messages IDs we need... */ - VL_MSG_FIRST_AVAILABLE, -} vl_msg_id_t; -#undef vl_msg_id - -#endif /* included_flowprobe_msg_enum_h */ diff --git a/src/plugins/flowprobe/flowprobe_test.c b/src/plugins/flowprobe/flowprobe_test.c index 53fdb23be5d..245707d417d 100644 --- a/src/plugins/flowprobe/flowprobe_test.c +++ b/src/plugins/flowprobe/flowprobe_test.c @@ -30,29 +30,8 @@ uword unformat_sw_if_index (unformat_input_t * input, va_list * args); /* Declare message IDs */ -#include <flowprobe/flowprobe_msg_enum.h> - -/* define message structures */ -#define vl_typedefs -#include <flowprobe/flowprobe_all_api_h.h> -#undef vl_typedefs - -/* declare message handlers for each api */ - -#define vl_endianfun /* define message structures */ -#include <flowprobe/flowprobe_all_api_h.h> -#undef vl_endianfun - -/* instantiate all the print functions we know about */ -#define vl_print(handle, ...) -#define vl_printfun -#include <flowprobe/flowprobe_all_api_h.h> -#undef vl_printfun - -/* Get the API version number. */ -#define vl_api_version(n,v) static u32 api_version=(v); -#include <flowprobe/flowprobe_all_api_h.h> -#undef vl_api_version +#include <flowprobe/flowprobe.api_enum.h> +#include <flowprobe/flowprobe.api_types.h> typedef struct { @@ -64,35 +43,6 @@ typedef struct flowprobe_test_main_t flowprobe_test_main; -#define foreach_standard_reply_retval_handler \ -_(flowprobe_tx_interface_add_del_reply) \ -_(flowprobe_params_reply) - -#define _(n) \ - static void vl_api_##n##_t_handler \ - (vl_api_##n##_t * mp) \ - { \ - vat_main_t * vam = flowprobe_test_main.vat_main; \ - i32 retval = ntohl(mp->retval); \ - if (vam->async_mode) { \ - vam->async_errors += (retval < 0); \ - } else { \ - vam->retval = retval; \ - vam->result_ready = 1; \ - } \ - } -foreach_standard_reply_retval_handler; -#undef _ - -/* - * Table of message reply handlers, must include boilerplate handlers - * we just generated - */ -#define foreach_vpe_api_reply_msg \ -_(FLOWPROBE_TX_INTERFACE_ADD_DEL_REPLY, \ - flowprobe_tx_interface_add_del_reply) \ -_(FLOWPROBE_PARAMS_REPLY, flowprobe_params_reply) - static int api_flowprobe_tx_interface_add_del (vat_main_t * vam) { @@ -201,38 +151,7 @@ api_flowprobe_params (vat_main_t * vam) * List of messages that the api test plugin sends, * and that the data plane plugin processes */ -#define foreach_vpe_api_msg \ -_(flowprobe_tx_interface_add_del, "<intfc> [disable]") \ -_(flowprobe_params, "record <[l2] [l3] [l4]> [active <timer> passive <timer>]") - -static void -flowprobe_api_hookup (vat_main_t * vam) -{ - flowprobe_test_main_t *sm = &flowprobe_test_main; - /* Hook up handlers for replies from the data plane plug-in */ -#define _(N,n) \ - vl_msg_api_set_handlers((VL_API_##N + sm->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); - foreach_vpe_api_reply_msg; -#undef _ - - /* API messages we can send */ -#define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n); - foreach_vpe_api_msg; -#undef _ - - /* Help strings */ -#define _(n,h) hash_set_mem (vam->help_by_name, #n, h); - foreach_vpe_api_msg; -#undef _ -} - -VAT_PLUGIN_REGISTER (flowprobe); +#include <flowprobe/flowprobe.api_test.c> /* * fd.io coding-style-patch-verification: ON diff --git a/src/plugins/map/CMakeLists.txt b/src/plugins/map/CMakeLists.txt index bf28e5ba2c3..5ebcb55e229 100644 --- a/src/plugins/map/CMakeLists.txt +++ b/src/plugins/map/CMakeLists.txt @@ -25,8 +25,6 @@ add_vpp_plugin(map map.api INSTALL_HEADERS - map_all_api_h.h - map_msg_enum.h map.h lpm.h ) diff --git a/src/plugins/map/map_all_api_h.h b/src/plugins/map/map_all_api_h.h deleted file mode 100644 index c622bec170b..00000000000 --- a/src/plugins/map/map_all_api_h.h +++ /dev/null @@ -1,24 +0,0 @@ - -/* - * map_all_api_h.h - skeleton vpp engine plug-in api #include file - * - * Copyright (c) 2018 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. - */ -/* Include the generated file, see BUILT_SOURCES in Makefile.am */ - -#ifdef vl_printfun -#include <vnet/format_fns.h> -#endif - -#include <map/map.api.h> diff --git a/src/plugins/map/map_api.c b/src/plugins/map/map_api.c index 654e1793064..159c9d7569b 100644 --- a/src/plugins/map/map_api.c +++ b/src/plugins/map/map_api.c @@ -19,30 +19,12 @@ #include <vnet/ip/ip_types_api.h> #include <map/map.h> -#include <map/map_msg_enum.h> +#include <map/map.api_enum.h> +#include <map/map.api_types.h> #include <vnet/ip/ip.h> #include <vnet/fib/fib_table.h> #include <vlibmemory/api.h> -#define vl_typedefs /* define message structures */ -#include <map/map_all_api_h.h> -#undef vl_typedefs - -#define vl_endianfun /* define message structures */ -#include <map/map_all_api_h.h> -#undef vl_endianfun - -/* instantiate all the print functions we know about */ -#define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__) -#define vl_printfun -#include <map/map_all_api_h.h> -#undef vl_printfun - -/* Get the API version number */ -#define vl_api_version(n,v) static u32 api_version=(v); -#include <map/map_all_api_h.h> -#undef vl_api_version - #define REPLY_MSG_ID_BASE mm->msg_id_base #include <vlibapi/api_helper_macros.h> @@ -672,65 +654,17 @@ vl_api_map_if_enable_disable_t_handler (vl_api_map_if_enable_disable_t * mp) REPLY_MACRO (VL_API_MAP_IF_ENABLE_DISABLE_REPLY); } - -#define foreach_map_plugin_api_msg \ -_(MAP_ADD_DOMAIN, map_add_domain) \ -_(MAP_DEL_DOMAIN, map_del_domain) \ -_(MAP_ADD_DEL_RULE, map_add_del_rule) \ -_(MAP_DOMAIN_DUMP, map_domain_dump) \ -_(MAP_RULE_DUMP, map_rule_dump) \ -_(MAP_IF_ENABLE_DISABLE, map_if_enable_disable) \ -_(MAP_SUMMARY_STATS, map_summary_stats) \ -_(MAP_PARAM_SET_FRAGMENTATION, map_param_set_fragmentation) \ -_(MAP_PARAM_SET_ICMP, map_param_set_icmp) \ -_(MAP_PARAM_SET_ICMP6, map_param_set_icmp6) \ -_(MAP_PARAM_ADD_DEL_PRE_RESOLVE, map_param_add_del_pre_resolve) \ -_(MAP_PARAM_SET_REASSEMBLY, map_param_set_reassembly) \ -_(MAP_PARAM_SET_SECURITY_CHECK, map_param_set_security_check) \ -_(MAP_PARAM_SET_TRAFFIC_CLASS, map_param_set_traffic_class) \ -_(MAP_PARAM_SET_TCP, map_param_set_tcp) \ -_(MAP_PARAM_GET, map_param_get) - -#define vl_msg_name_crc_list -#include <map/map_all_api_h.h> -#undef vl_msg_name_crc_list - -static void -setup_message_id_table (map_main_t * mm, api_main_t * am) -{ -#define _(id,n,crc) \ - vl_msg_api_add_msg_name_crc (am, #n "_" #crc, id + mm->msg_id_base); - foreach_vl_msg_name_crc_map; -#undef _ -} +/* API definitions */ +#include <vnet/format_fns.h> +#include <map/map.api.c> /* Set up the API message handling tables */ clib_error_t * map_plugin_api_hookup (vlib_main_t * vm) { map_main_t *mm = &map_main; - u8 *name = format (0, "map_%08x%c", api_version, 0); - - /* Ask for a correctly-sized block of API message decode slots */ - mm->msg_id_base = - vl_msg_api_get_msg_ids ((char *) name, VL_MSG_FIRST_AVAILABLE); -#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); - foreach_map_plugin_api_msg; -#undef _ - - /* - * Set up the (msg_name, crc, message-id) table - */ - setup_message_id_table (mm, &api_main); - vec_free (name); + mm->msg_id_base = setup_message_id_table (); return 0; } diff --git a/src/plugins/map/map_msg_enum.h b/src/plugins/map/map_msg_enum.h deleted file mode 100644 index b135cfc7510..00000000000 --- a/src/plugins/map/map_msg_enum.h +++ /dev/null @@ -1,31 +0,0 @@ - -/* - * map_msg_enum.h - skeleton vpp engine plug-in message enumeration - * - * Copyright (c) 2018 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_map_msg_enum_h -#define included_map_msg_enum_h - -#include <vppinfra/byte_order.h> - -#define vl_msg_id(n,h) n, -typedef enum { -#include <map/map_all_api_h.h> - /* We'll want to know how many messages IDs we need... */ - VL_MSG_FIRST_AVAILABLE, -} vl_msg_id_t; -#undef vl_msg_id - -#endif diff --git a/src/tools/vppapigen/vppapigen.py b/src/tools/vppapigen/vppapigen.py index 861b71ddf43..57a30fd3c29 100755 --- a/src/tools/vppapigen/vppapigen.py +++ b/src/tools/vppapigen/vppapigen.py @@ -259,12 +259,12 @@ class Define(): self.name = name self.flags = flags self.block = block - self.crc = str(block).encode() self.dont_trace = False self.manual_print = False self.manual_endian = False self.autoreply = False self.singular = False + self.options = {} for f in flags: if f == 'dont_trace': self.dont_trace = True @@ -279,8 +279,12 @@ class Define(): if isinstance(b, Option): if b[1] == 'singular' and b[2] == 'true': self.singular = True + else: + self.options[b.option] = b.value block.remove(b) + self.vla = vla_is_last_check(name, block) + self.crc = str(block).encode() def __repr__(self): return self.name + str(self.flags) + str(self.block) @@ -920,6 +924,7 @@ def main(): cliparser = argparse.ArgumentParser(description='VPP API generator') cliparser.add_argument('--pluginpath', default=""), cliparser.add_argument('--includedir', action='append'), + cliparser.add_argument('--outputdir', action='store'), cliparser.add_argument('--input', type=argparse.FileType('r', encoding='UTF-8'), default=sys.stdin) @@ -1011,7 +1016,7 @@ def main(): .format(module_path, err)) return 1 - result = plugin.run(filename, s) + result = plugin.run(args, filename, s) if result: print(result, file=args.output) else: diff --git a/src/tools/vppapigen/vppapigen_c.py b/src/tools/vppapigen/vppapigen_c.py index 7c383c27472..bab255c58a2 100644 --- a/src/tools/vppapigen/vppapigen_c.py +++ b/src/tools/vppapigen/vppapigen_c.py @@ -4,6 +4,7 @@ import os import time import sys from io import StringIO +import shutil datestring = datetime.datetime.utcfromtimestamp( int(os.environ.get('SOURCE_DATE_EPOCH', time.time()))) @@ -95,80 +96,16 @@ def api2c(fieldtype): return fieldtype -def typedefs(objs, filename): - name = filename.replace('.', '_') - output = '''\ +def typedefs(filename): + output = '''\ /****** Typedefs ******/ #ifdef vl_typedefs -#ifndef included_{module}_typedef -#define included_{module}_typedef -''' - output = output.format(module=name) - - for o in objs: - tname = o.__class__.__name__ - if tname == 'Using': - if 'length' in o.alias: - output += 'typedef %s vl_api_%s_t[%s];\n' % (o.alias['type'], o.name, o.alias['length']) - else: - output += 'typedef %s vl_api_%s_t;\n' % (o.alias['type'], o.name) - elif tname == 'Enum': - if o.enumtype == 'u32': - output += "typedef enum {\n" - else: - output += "typedef enum __attribute__((__packed__)) {\n" - - for b in o.block: - output += " %s = %s,\n" % (b[0], b[1]) - output += '} vl_api_%s_t;\n' % o.name - if o.enumtype != 'u32': - size1 = 'sizeof(vl_api_%s_t)' % o.name - size2 = 'sizeof(%s)' % o.enumtype - err_str = 'size of API enum %s is wrong' % o.name - output += ('STATIC_ASSERT(%s == %s, "%s");\n' - % (size1, size2, err_str)) - else: - if tname == 'Union': - output += "typedef VL_API_PACKED(union _vl_api_%s {\n" % o.name - else: - output += ("typedef VL_API_PACKED(struct _vl_api_%s {\n" - % o.name) - for b in o.block: - if b.type == 'Option': - continue - if b.type == 'Field': - output += " %s %s;\n" % (api2c(b.fieldtype), - b.fieldname) - elif b.type == 'Array': - if b.lengthfield: - output += " %s %s[0];\n" % (api2c(b.fieldtype), - b.fieldname) - else: - # Fixed length strings decay to nul terminated u8 - if b.fieldtype == 'string': - if b.modern_vla: - output += (' {} {};\n' - .format(api2c(b.fieldtype), - b.fieldname)) - else: - output += (' u8 {}[{}];\n' - .format(b.fieldname, b.length)) - else: - output += (" %s %s[%s];\n" % - (api2c(b.fieldtype), b.fieldname, - b.length)) - else: - raise ValueError("Error in processing type {} for {}" - .format(b, o.name)) - - output += '}) vl_api_%s_t;\n' % o.name - - output += "\n#endif" - output += "\n#endif\n\n" - +#include "{include}.api_types.h" +#endif +'''.format(include=filename) return output @@ -566,14 +503,258 @@ def version_tuple(s, module): return output +def generate_include_enum(s, module, stream): + write = stream.write + + if len(s['Define']): + write('typedef enum {\n') + for t in s['Define']: + write(' VL_API_{},\n'.format(t.name.upper())) + write(' VL_MSG_FIRST_AVAILABLE\n') + write('}} vl_api_{}_enum_t;\n'.format(module)) + +# +# Generate separate API _types file. +# +def generate_include_types(s, module, stream): + write = stream.write + + write('#ifndef included_{module}_api_types_h\n'.format(module=module)) + write('#define included_{module}_api_types_h\n'.format(module=module)) + + if len(s['Import']): + write('/* Imported API files */\n') + for i in s['Import']: + filename = i.filename.replace('plugins/', '') + write('#include <{}_types.h>\n'.format(filename)) + + for o in s['types'] + s['Define']: + tname = o.__class__.__name__ + if tname == 'Using': + if 'length' in o.alias: + write('typedef %s vl_api_%s_t[%s];\n' % (o.alias['type'], o.name, o.alias['length'])) + else: + write('typedef %s vl_api_%s_t;\n' % (o.alias['type'], o.name)) + elif tname == 'Enum': + if o.enumtype == 'u32': + write("typedef enum {\n") + else: + write("typedef enum __attribute__((packed)) {\n") + + for b in o.block: + write(" %s = %s,\n" % (b[0], b[1])) + write('} vl_api_%s_t;\n' % o.name) + if o.enumtype != 'u32': + size1 = 'sizeof(vl_api_%s_t)' % o.name + size2 = 'sizeof(%s)' % o.enumtype + err_str = 'size of API enum %s is wrong' % o.name + write('STATIC_ASSERT(%s == %s, "%s");\n' + % (size1, size2, err_str)) + else: + if tname == 'Union': + write("typedef union __attribute__ ((packed)) _vl_api_%s {\n" % o.name) + else: + write(("typedef struct __attribute__ ((packed)) _vl_api_%s {\n") + % o.name) + for b in o.block: + if b.type == 'Option': + continue + if b.type == 'Field': + write(" %s %s;\n" % (api2c(b.fieldtype), + b.fieldname)) + elif b.type == 'Array': + if b.lengthfield: + write(" %s %s[0];\n" % (api2c(b.fieldtype), + b.fieldname)) + else: + # Fixed length strings decay to nul terminated u8 + if b.fieldtype == 'string': + if b.modern_vla: + write(' {} {};\n' + .format(api2c(b.fieldtype), + b.fieldname)) + else: + write(' u8 {}[{}];\n' + .format(b.fieldname, b.length)) + else: + write(" %s %s[%s];\n" % + (api2c(b.fieldtype), b.fieldname, + b.length)) + else: + raise ValueError("Error in processing type {} for {}" + .format(b, o.name)) + + write('} vl_api_%s_t;\n' % o.name) + + write("\n#endif\n") + + +def generate_c_boilerplate(services, defines, file_crc, module, stream): + write = stream.write + + hdr = '''\ +#define vl_endianfun /* define message structures */ +#include "{module}.api.h" +#undef vl_endianfun + +/* instantiate all the print functions we know about */ +#define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__) +#define vl_printfun +#include "{module}.api.h" +#undef vl_printfun + +''' + + write(hdr.format(module=module)) + write('static u16\n') + write('setup_message_id_table (void) {\n') + write(' api_main_t *am = &api_main;\n') + write(' u16 msg_id_base = vl_msg_api_get_msg_ids ("{}_{crc:08x}", VL_MSG_FIRST_AVAILABLE);\n' + .format(module, crc=file_crc)) + + + for d in defines: + write(' vl_msg_api_add_msg_name_crc (am, "{n}_{crc:08x}",\n' + ' VL_API_{ID} + msg_id_base);\n' + .format(n=d.name, ID=d.name.upper(), crc=d.crc)) + for s in services: + write(' vl_msg_api_set_handlers(VL_API_{ID} + msg_id_base, "{n}",\n' + ' vl_api_{n}_t_handler, vl_noop_handler,\n' + ' vl_api_{n}_t_endian, vl_api_{n}_t_print,\n' + ' sizeof(vl_api_{n}_t), 1);\n' + .format(n=s.caller, ID=s.caller.upper())) + + write(' return msg_id_base;\n') + write('}\n') + + +def generate_c_test_plugin_boilerplate(services, defines, file_crc, module, stream): + write = stream.write + + define_hash = {d.name:d for d in defines} + replies = {} + + hdr = '''\ +#define vl_endianfun /* define message structures */ +#include "{module}.api.h" +#undef vl_endianfun + +/* instantiate all the print functions we know about */ +#define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__) +#define vl_printfun +#include "{module}.api.h" +#undef vl_printfun + +''' + + write(hdr.format(module=module)) + for s in services: + try: + d = define_hash[s.reply] + except: + continue + if d.manual_print: + write('/* Manual definition requested for: vl_api_{n}_t_hander() */\n' + .format(n=s.reply)) + continue + if not define_hash[s.caller].autoreply: + write('/* Only autoreply is supported (vl_api_{n}_t_hander()) */\n' + .format(n=s.reply)) + continue + write('static void\n') + write('vl_api_{n}_t_handler (vl_api_{n}_t * mp) {{\n'.format(n=s.reply)) + write(' vat_main_t * vam = {}_test_main.vat_main;\n'.format(module)) + write(' i32 retval = ntohl(mp->retval);\n') + write(' if (vam->async_mode) {\n') + write(' vam->async_errors += (retval < 0);\n') + write(' } else {\n') + write(' vam->retval = retval;\n') + write(' vam->result_ready = 1;\n') + write(' }\n') + write('}\n') + + write('static void\n') + write('setup_message_id_table (vat_main_t * vam, u16 msg_id_base) {\n') + for s in services: + write(' vl_msg_api_set_handlers(VL_API_{ID} + msg_id_base, "{n}",\n' + ' vl_api_{n}_t_handler, vl_noop_handler,\n' + ' vl_api_{n}_t_endian, vl_api_{n}_t_print,\n' + ' sizeof(vl_api_{n}_t), 1);\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)) + try: + write(' hash_set_mem (vam->help_by_name, "{n}", "{help}");\n' + .format(n=s.caller, help=define_hash[s.caller].options['vat_help'])) + except: + pass + + write('}\n') + + write('clib_error_t * vat_plugin_register (vat_main_t *vam)\n') + write('{\n') + write(' {n}_test_main_t * mainp = &{n}_test_main;\n'.format(n=module)) + write(' mainp->vat_main = vam;\n') + write(' mainp->msg_id_base = vl_client_get_first_plugin_msg_id ("{n}_{crc:08x}");\n' + .format(n=module, crc=file_crc)) + write(' if (mainp->msg_id_base == (u16) ~0)\n') + write(' return clib_error_return (0, "{} plugin not loaded...");\n'.format(module)) + write(' setup_message_id_table (vam, mainp->msg_id_base);\n') + write(' return 0;\n') + write('}\n') + + # # Plugin entry point # -def run(input_filename, s): +def run(args, input_filename, s): stream = StringIO() + + if not args.outputdir: + sys.stderr.write('Missing --outputdir argument') + return None + basename = os.path.basename(input_filename) filename, file_extension = os.path.splitext(basename) modulename = filename.replace('.', '_') + filename_enum = os.path.join(args.outputdir + '/' + basename + '_enum.h') + filename_types = os.path.join(args.outputdir + '/' + basename + '_types.h') + filename_c = os.path.join(args.outputdir + '/' + basename + '.c') + filename_c_test = os.path.join(args.outputdir + '/' + basename + '_test.c') + + # Generate separate types file + st = StringIO() + generate_include_types(s, modulename, st) + with open (filename_types, 'w') as fd: + st.seek (0) + shutil.copyfileobj (st, fd) + st.close() + + # Generate separate enum file + st = StringIO() + generate_include_enum(s, modulename, st) + with open (filename_enum, 'w') as fd: + st.seek (0) + shutil.copyfileobj (st, fd) + st.close() + + # Generate separate C file + st = StringIO() + generate_c_boilerplate(s['Service'], s['Define'], s['file_crc'], + modulename, st) + with open (filename_c, 'w') as fd: + st.seek (0) + shutil.copyfileobj(st, fd) + st.close() + + # Generate separate C test file + # This is only supported for plugins at the moment + st = StringIO() + generate_c_test_plugin_boilerplate(s['Service'], s['Define'], s['file_crc'], + modulename, st) + with open (filename_c_test, 'w') as fd: + st.seek (0) + shutil.copyfileobj(st, fd) + st.close() output = top_boilerplate.format(datestring=datestring, input_filename=basename) @@ -581,10 +762,11 @@ def run(input_filename, s): output += msg_ids(s) output += msg_names(s) output += msg_name_crc_list(s, filename) - output += typedefs(s['types'] + s['Define'], filename + file_extension) + output += typedefs(modulename) printfun_types(s['types'], stream, modulename) printfun(s['Define'], stream, modulename) output += stream.getvalue() + stream.close() output += endianfun(s['types'] + s['Define'], modulename) output += version_tuple(s, basename) output += bottom_boilerplate.format(input_filename=basename, diff --git a/src/tools/vppapigen/vppapigen_json.py b/src/tools/vppapigen/vppapigen_json.py index f67a3d62da1..c2a2b7d0682 100644 --- a/src/tools/vppapigen/vppapigen_json.py +++ b/src/tools/vppapigen/vppapigen_json.py @@ -61,7 +61,7 @@ def walk_defs(s, is_message=False): # # Plugin entry point # -def run(filename, s): +def run(args, filename, s): j = {} j['types'] = (walk_defs([o for o in s['types'] diff --git a/src/vlibapi/api_helper_macros.h b/src/vlibapi/api_helper_macros.h index 3a011dae2b6..2662df8356b 100644 --- a/src/vlibapi/api_helper_macros.h +++ b/src/vlibapi/api_helper_macros.h @@ -59,6 +59,21 @@ do { \ vl_api_send_msg (rp, (u8 *)rmp); \ } while(0); +#define REPLY_MACRO_DETAILS2(t, body) \ +do { \ + vl_api_registration_t *rp; \ + rv = vl_msg_api_pd_handler (mp, rv); \ + rp = vl_api_client_index_to_registration (mp->client_index); \ + if (rp == 0) \ + return; \ + \ + rmp = vl_msg_api_alloc (sizeof (*rmp)); \ + rmp->_vl_msg_id = htons((t)+(REPLY_MSG_ID_BASE)); \ + rmp->context = mp->context; \ + do {body;} while (0); \ + vl_api_send_msg (rp, (u8 *)rmp); \ +} while(0); + #define REPLY_MACRO3(t, n, body) \ do { \ vl_api_registration_t *rp; \ diff --git a/src/vnet/ip/ip_format_fns.h b/src/vnet/ip/ip_format_fns.h index b0e0c10d715..0c2e0661ba0 100644 --- a/src/vnet/ip/ip_format_fns.h +++ b/src/vnet/ip/ip_format_fns.h @@ -20,8 +20,7 @@ static inline u8 *format_vl_api_ip6_address_t (u8 * s, va_list * args); static inline u8 *format_vl_api_ip4_address_t (u8 * s, va_list * args); #include <vnet/ip/format.h> -#define vl_typedefs -#include <vnet/ip/ip_types.api.h> +#include <vnet/ip/ip_types.api_types.h> static inline u8 * format_vl_api_ip6_address_t (u8 * s, va_list * args) diff --git a/src/vnet/ip/ip_types_api.h b/src/vnet/ip/ip_types_api.h index 09ca0e6e1a0..11891dec7c1 100644 --- a/src/vnet/ip/ip_types_api.h +++ b/src/vnet/ip/ip_types_api.h @@ -24,15 +24,7 @@ #include <vnet/fib/fib_types.h> #include <vnet/mfib/mfib_types.h> #include <vlibapi/api_types.h> - -/** - * Forward declarations so we need not #include the API definitions here - */ -typedef u8 vl_api_ip6_address_t[16]; -typedef u8 vl_api_ip4_address_t[4]; -struct _vl_api_address; -struct _vl_api_prefix; -struct _vl_api_mprefix; +#include <vnet/ip/ip.api_types.h> /** * These enum decode/encodes use 'int' as the type for the enum becuase diff --git a/src/vnet/ipip/ipip.h b/src/vnet/ipip/ipip.h index 7eecebb1054..c55d1d7c644 100644 --- a/src/vnet/ipip/ipip.h +++ b/src/vnet/ipip/ipip.h @@ -111,6 +111,8 @@ typedef struct bool ip4_protocol_registered; bool ip6_protocol_registered; + + u16 msg_id_base; } ipip_main_t; extern ipip_main_t ipip_main; diff --git a/src/vnet/ipip/ipip_api.c b/src/vnet/ipip/ipip_api.c index d88047560a9..da0cb169296 100644 --- a/src/vnet/ipip/ipip_api.c +++ b/src/vnet/ipip/ipip_api.c @@ -21,35 +21,18 @@ #include <vnet/interface.h> #include <vnet/ipip/ipip.h> #include <vnet/vnet.h> -#include <vnet/vnet_msg_enum.h> #include <vnet/ip/ip_types_api.h> -#define vl_typedefs /* define message structures */ -#include <vnet/vnet_all_api_h.h> -#undef vl_typedefs - -#define vl_endianfun /* define message structures */ -#include <vnet/vnet_all_api_h.h> -#undef vl_endianfun - -/* instantiate all the print functions we know about */ -#define vl_print(handle, ...) vlib_cli_output(handle, __VA_ARGS__) -#define vl_printfun -#include <vnet/vnet_all_api_h.h> -#undef vl_printfun +#include <vnet/ipip/ipip.api_enum.h> +#include <vnet/ipip/ipip.api_types.h> +#define REPLY_MSG_ID_BASE im->msg_id_base #include <vlibapi/api_helper_macros.h> -#define foreach_vpe_api_msg \ - _(IPIP_ADD_TUNNEL, ipip_add_tunnel) \ - _(IPIP_DEL_TUNNEL, ipip_del_tunnel) \ - _(IPIP_6RD_ADD_TUNNEL, ipip_6rd_add_tunnel) \ - _(IPIP_6RD_DEL_TUNNEL, ipip_6rd_del_tunnel) \ - _(IPIP_TUNNEL_DUMP, ipip_tunnel_dump) - static void vl_api_ipip_add_tunnel_t_handler (vl_api_ipip_add_tunnel_t * mp) { + ipip_main_t *im = &ipip_main; vl_api_ipip_add_tunnel_reply_t *rmp; int rv = 0; u32 fib_index, sw_if_index = ~0; @@ -99,6 +82,7 @@ out: static void vl_api_ipip_del_tunnel_t_handler (vl_api_ipip_del_tunnel_t * mp) { + ipip_main_t *im = &ipip_main; vl_api_ipip_del_tunnel_reply_t *rmp; int rv = ipip_del_tunnel (ntohl (mp->sw_if_index)); @@ -107,51 +91,44 @@ vl_api_ipip_del_tunnel_t_handler (vl_api_ipip_del_tunnel_t * mp) } static void -send_ipip_tunnel_details (ipip_tunnel_t * t, - vl_api_registration_t * reg, u32 context) +send_ipip_tunnel_details (ipip_tunnel_t * t, vl_api_ipip_tunnel_dump_t * mp) { + ipip_main_t *im = &ipip_main; vl_api_ipip_tunnel_details_t *rmp; bool is_ipv6 = t->transport == IPIP_TRANSPORT_IP6 ? true : false; fib_table_t *ft; - - rmp = vl_msg_api_alloc (sizeof (*rmp)); - clib_memset (rmp, 0, sizeof (*rmp)); - rmp->_vl_msg_id = htons (VL_API_IPIP_TUNNEL_DETAILS); - - ip_address_encode (&t->tunnel_src, IP46_TYPE_ANY, &rmp->tunnel.src); - ip_address_encode (&t->tunnel_dst, IP46_TYPE_ANY, &rmp->tunnel.dst); + int rv = 0; ft = fib_table_get (t->fib_index, (is_ipv6 ? FIB_PROTOCOL_IP6 : FIB_PROTOCOL_IP4)); - rmp->tunnel.table_id = htonl (ft->ft_table_id); - rmp->tunnel.instance = htonl (t->user_instance); - rmp->tunnel.sw_if_index = htonl (t->sw_if_index); - rmp->context = context; - - vl_api_send_msg (reg, (u8 *) rmp); + /* *INDENT-OFF* */ + REPLY_MACRO_DETAILS2(VL_API_IPIP_TUNNEL_DETAILS, + ({ + ip_address_encode (&t->tunnel_src, IP46_TYPE_ANY, &rmp->tunnel.src); + ip_address_encode (&t->tunnel_dst, IP46_TYPE_ANY, &rmp->tunnel.dst); + rmp->tunnel.table_id = htonl (ft->ft_table_id); + rmp->tunnel.instance = htonl (t->user_instance); + rmp->tunnel.sw_if_index = htonl (t->sw_if_index); + })); + /* *INDENT-ON* */ } static void vl_api_ipip_tunnel_dump_t_handler (vl_api_ipip_tunnel_dump_t * mp) { - vl_api_registration_t *reg; - ipip_main_t *gm = &ipip_main; + ipip_main_t *im = &ipip_main; ipip_tunnel_t *t; u32 sw_if_index; - reg = vl_api_client_index_to_registration (mp->client_index); - if (!reg) - return; - sw_if_index = ntohl (mp->sw_if_index); if (sw_if_index == ~0) { /* *INDENT-OFF* */ - pool_foreach(t, gm->tunnels, + pool_foreach(t, im->tunnels, ({ - send_ipip_tunnel_details(t, reg, mp->context); + send_ipip_tunnel_details(t, mp); })); /* *INDENT-ON* */ } @@ -159,13 +136,14 @@ vl_api_ipip_tunnel_dump_t_handler (vl_api_ipip_tunnel_dump_t * mp) { t = ipip_tunnel_db_find_by_sw_if_index (sw_if_index); if (t) - send_ipip_tunnel_details (t, reg, mp->context); + send_ipip_tunnel_details (t, mp); } } static void vl_api_ipip_6rd_add_tunnel_t_handler (vl_api_ipip_6rd_add_tunnel_t * mp) { + ipip_main_t *im = &ipip_main; vl_api_ipip_6rd_add_tunnel_reply_t *rmp; u32 sixrd_tunnel_index, ip4_fib_index, ip6_fib_index; int rv; @@ -201,6 +179,7 @@ vl_api_ipip_6rd_add_tunnel_t_handler (vl_api_ipip_6rd_add_tunnel_t * mp) static void vl_api_ipip_6rd_del_tunnel_t_handler (vl_api_ipip_6rd_del_tunnel_t * mp) { + ipip_main_t *im = &ipip_main; vl_api_ipip_6rd_del_tunnel_reply_t *rmp; int rv = sixrd_del_tunnel (ntohl (mp->sw_if_index)); @@ -215,34 +194,19 @@ vl_api_ipip_6rd_del_tunnel_t_handler (vl_api_ipip_6rd_del_tunnel_t * mp) * added the client registration handlers. * See .../vlib-api/vlibmemory/memclnt_vlib.c:memclnt_process() */ -#define vl_msg_name_crc_list -#include <vnet/vnet_all_api_h.h> -#undef vl_msg_name_crc_list - -static void -setup_message_id_table (api_main_t * am) -{ -#define _(id, n, crc) vl_msg_api_add_msg_name_crc(am, #n "_" #crc, id); - foreach_vl_msg_name_crc_ipip; -#undef _ -} +/* API definitions */ +#include <vnet/format_fns.h> +#include <vnet/ipip/ipip.api.c> static clib_error_t * ipip_api_hookup (vlib_main_t * vm) { - api_main_t *am = &api_main; - -#define _(N, n) \ - 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), 1); - foreach_vpe_api_msg; -#undef _ + ipip_main_t *im = &ipip_main; /* * Set up the (msg_name, crc, message-id) table */ - setup_message_id_table (am); + im->msg_id_base = setup_message_id_table (); return 0; } diff --git a/src/vnet/vnet_all_api_h.h b/src/vnet/vnet_all_api_h.h index 83991106c8b..3b5140e1ed2 100644 --- a/src/vnet/vnet_all_api_h.h +++ b/src/vnet/vnet_all_api_h.h @@ -39,7 +39,6 @@ #include <vnet/devices/virtio/vhost_user.api.h> #include <vnet/devices/tap/tapv2.api.h> #include <vnet/gre/gre.api.h> -#include <vnet/ipip/ipip.api.h> #include <vnet/interface.api.h> #include <vnet/l2/l2.api.h> #include <vnet/l2tp/l2tp.api.h> |