From 812afe712b62484b4390fa048c76fe8bf4cd0a12 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Beno=C3=AEt=20Ganne?= Date: Tue, 15 Oct 2019 10:51:11 +0200 Subject: [PATCH] rdma: add rdma API MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Type: feature Change-Id: I590612989cb3c114f8d99227ad36c3434e998597 Signed-off-by: Benoît Ganne --- src/plugins/rdma/CMakeLists.txt | 9 +++ src/plugins/rdma/api.c | 108 +++++++++++++++++++++++++++++++ src/plugins/rdma/cli.c | 27 +------- src/plugins/rdma/format.c | 5 +- src/plugins/rdma/rdma.api | 75 ++++++++++++++++++++++ src/plugins/rdma/rdma.h | 6 +- src/plugins/rdma/test_api.c | 137 ++++++++++++++++++++++++++++++++++++++++ src/plugins/rdma/unformat.c | 63 ++++++++++++++++++ 8 files changed, 401 insertions(+), 29 deletions(-) create mode 100644 src/plugins/rdma/api.c create mode 100644 src/plugins/rdma/rdma.api create mode 100644 src/plugins/rdma/test_api.c create mode 100644 src/plugins/rdma/unformat.c diff --git a/src/plugins/rdma/CMakeLists.txt b/src/plugins/rdma/CMakeLists.txt index 432330dc55d..eaf747db54f 100644 --- a/src/plugins/rdma/CMakeLists.txt +++ b/src/plugins/rdma/CMakeLists.txt @@ -43,10 +43,12 @@ include_directories(${IBVERBS_INCLUDE_DIR}) add_vpp_plugin(rdma SOURCES + api.c cli.c device.c format.c plugin.c + unformat.c input.c output.c @@ -54,6 +56,13 @@ add_vpp_plugin(rdma input.c output.c + API_FILES + rdma.api + + API_TEST_SOURCES + unformat.c + test_api.c + LINK_FLAGS "${RDMA_LINK_FLAGS}" diff --git a/src/plugins/rdma/api.c b/src/plugins/rdma/api.c new file mode 100644 index 00000000000..cd3c36065f2 --- /dev/null +++ b/src/plugins/rdma/api.c @@ -0,0 +1,108 @@ +/* + *------------------------------------------------------------------ + * Copyright (c) 2019 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 +#include + +#include + +#include +#include + +/* define message IDs */ +#include +#include + +#include + +static void +vl_api_rdma_create_t_handler (vl_api_rdma_create_t * mp) +{ + vlib_main_t *vm = vlib_get_main (); + rdma_main_t *rm = &rdma_main; + vl_api_rdma_create_reply_t *rmp; + rdma_create_if_args_t args; + int rv; + + clib_memset (&args, 0, sizeof (rdma_create_if_args_t)); + + args.ifname = mp->host_if; + args.name = mp->name; + args.rxq_num = ntohs (mp->rxq_num); + args.rxq_size = ntohs (mp->rxq_size); + args.txq_size = ntohs (mp->txq_size); + + rdma_create_if (vm, &args); + rv = args.rv; + + /* *INDENT-OFF* */ + REPLY_MACRO2 (VL_API_RDMA_CREATE_REPLY + rm->msg_id_base, + ({ + rmp->sw_if_index = ntohl (args.sw_if_index); + })); + /* *INDENT-ON* */ +} + +static void +vl_api_rdma_delete_t_handler (vl_api_rdma_delete_t * mp) +{ + vlib_main_t *vm = vlib_get_main (); + vnet_main_t *vnm = vnet_get_main (); + rdma_main_t *rm = &rdma_main; + vl_api_rdma_delete_reply_t *rmp; + rdma_device_t *rd; + vnet_hw_interface_t *hw; + int rv = 0; + + hw = + vnet_get_sup_hw_interface_api_visible_or_null (vnm, + htonl (mp->sw_if_index)); + if (hw == NULL || rdma_device_class.index != hw->dev_class_index) + { + rv = VNET_API_ERROR_INVALID_INTERFACE; + goto reply; + } + + rd = pool_elt_at_index (rm->devices, hw->dev_instance); + + rdma_delete_if (vm, rd); + +reply: + REPLY_MACRO (VL_API_RDMA_DELETE_REPLY + rm->msg_id_base); +} + +/* set tup the API message handling tables */ +#include +static clib_error_t * +rdma_plugin_api_hookup (vlib_main_t * vm) +{ + rdma_main_t *rm = &rdma_main; + + /* ask for a correctly-sized block of API message decode slots */ + rm->msg_id_base = setup_message_id_table (); + return 0; +} + +VLIB_API_INIT_FUNCTION (rdma_plugin_api_hookup); + +/* + * fd.io coding-style-patch-verification: ON + * + * Local Variables: + * eval: (c-set-style "gnu") + * End: + */ diff --git a/src/plugins/rdma/cli.c b/src/plugins/rdma/cli.c index d4ef17d020c..3f39cfeb66b 100644 --- a/src/plugins/rdma/cli.c +++ b/src/plugins/rdma/cli.c @@ -30,32 +30,11 @@ static clib_error_t * rdma_create_command_fn (vlib_main_t * vm, unformat_input_t * input, vlib_cli_command_t * cmd) { - unformat_input_t _line_input, *line_input = &_line_input; rdma_create_if_args_t args; - /* Get a line of input. */ - if (!unformat_user (input, unformat_line_input, line_input)) - return 0; - - clib_memset (&args, 0, sizeof (rdma_create_if_args_t)); - - while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) - { - if (unformat (line_input, "host-if %s", &args.ifname)) - ; - else if (unformat (line_input, "name %s", &args.name)) - ; - else if (unformat (line_input, "rx-queue-size %u", &args.rxq_size)) - ; - else if (unformat (line_input, "tx-queue-size %u", &args.txq_size)) - ; - else if (unformat (line_input, "num-rx-queues %u", &args.rxq_num)) - ; - else - return clib_error_return (0, "unknown input `%U'", - format_unformat_error, input); - } - unformat_free (line_input); + if (!unformat_user (input, unformat_rdma_create_if_args, &args)) + return clib_error_return (0, "unknown input `%U'", + format_unformat_error, input); rdma_create_if (vm, &args); diff --git a/src/plugins/rdma/format.c b/src/plugins/rdma/format.c index 7a97339746f..c9553b21e41 100644 --- a/src/plugins/rdma/format.c +++ b/src/plugins/rdma/format.c @@ -16,10 +16,7 @@ */ #include -#include -#include -#include - +#include #include u8 * diff --git a/src/plugins/rdma/rdma.api b/src/plugins/rdma/rdma.api new file mode 100644 index 00000000000..f04eee2456e --- /dev/null +++ b/src/plugins/rdma/rdma.api @@ -0,0 +1,75 @@ +/* + *------------------------------------------------------------------ + * Copyright (c) 2019 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. + *------------------------------------------------------------------ + */ + +option version = "1.0.0"; + +/** \brief + @param client_index - opaque cookie to identify the sender + @param context - sender context, to match reply w/ request + @param host_if - Linux netdev interface name + @param name - new rdma interface name + @param rxq_num - number of receive queues + @param rxq_size - receive queue size + @param txq_size - transmit queue size +*/ + +define rdma_create +{ + u32 client_index; + u32 context; + + string host_if[64]; + string name[64]; + u16 rxq_num; + u16 rxq_size; + u16 txq_size; + option vat_help = " [name ] [rx-queue-size ] [tx-queue-size ] [num-rx-queues ]"; +}; + +/** \brief + @param context - sender context, to match reply w/ request + @param retval - return value for request + @param sw_if_index - software index for the new rdma interface +*/ + +define rdma_create_reply +{ + u32 context; + i32 retval; + u32 sw_if_index; +}; + +/** \brief + @param client_index - opaque cookie to identify the sender + @param context - sender context, to match reply w/ request + @param sw_if_index - interface index +*/ + +autoreply define rdma_delete +{ + u32 client_index; + u32 context; + + u32 sw_if_index; + option vat_help = ""; +}; + +/* + * Local Variables: + * eval: (c-set-style "gnu") + * End: + */ diff --git a/src/plugins/rdma/rdma.h b/src/plugins/rdma/rdma.h index 0aae4985276..6e602cb31df 100644 --- a/src/plugins/rdma/rdma.h +++ b/src/plugins/rdma/rdma.h @@ -20,6 +20,9 @@ #include #include +#include +#include +#include #define foreach_rdma_device_flags \ _(0, ERROR, "error") \ @@ -94,6 +97,7 @@ typedef struct { rdma_device_t *devices; vlib_log_class_t log_class; + u16 msg_id_base; } rdma_main_t; extern rdma_main_t rdma_main; @@ -118,10 +122,10 @@ void rdma_delete_if (vlib_main_t * vm, rdma_device_t * rd); extern vlib_node_registration_t rdma_input_node; extern vnet_device_class_t rdma_device_class; -/* format.c */ format_function_t format_rdma_device; format_function_t format_rdma_device_name; format_function_t format_rdma_input_trace; +unformat_function_t unformat_rdma_create_if_args; typedef struct { diff --git a/src/plugins/rdma/test_api.c b/src/plugins/rdma/test_api.c new file mode 100644 index 00000000000..cfd65c029c2 --- /dev/null +++ b/src/plugins/rdma/test_api.c @@ -0,0 +1,137 @@ +/* + *------------------------------------------------------------------ + * Copyright (c) 2019 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 +#include +#include +#include + +#include +#include +#include + +#include +#include + +#define __plugin_msg_base rdma_test_main.msg_id_base +#include + +/* declare message IDs */ +#include +#include + +typedef struct +{ + /* API message ID base */ + u16 msg_id_base; + vat_main_t *vat_main; +} rdma_test_main_t; + +rdma_test_main_t rdma_test_main; + +/* rdma create API */ +static int +api_rdma_create (vat_main_t * vam) +{ + vl_api_rdma_create_t *mp; + rdma_create_if_args_t args; + int ret; + + if (!unformat_user (vam->input, unformat_rdma_create_if_args, &args)) + { + clib_warning ("unknown input `%U'", format_unformat_error, vam->input); + return -99; + } + + M (RDMA_CREATE, mp); + + snprintf ((char *) mp->host_if, sizeof (mp->host_if), "%s", args.ifname); + snprintf ((char *) mp->name, sizeof (mp->name), "%s", args.name); + mp->rxq_num = clib_host_to_net_u16 (args.rxq_num); + mp->rxq_size = clib_host_to_net_u16 (args.rxq_size); + mp->txq_size = clib_host_to_net_u16 (args.txq_size); + + S (mp); + W (ret); + + return ret; +} + +/* rdma-create reply handler */ +static void +vl_api_rdma_create_reply_t_handler (vl_api_rdma_create_reply_t * mp) +{ + vat_main_t *vam = rdma_test_main.vat_main; + i32 retval = ntohl (mp->retval); + + if (retval == 0) + { + fformat (vam->ofp, "created rdma with sw_if_index %d\n", + ntohl (mp->sw_if_index)); + } + + vam->retval = retval; + vam->result_ready = 1; + vam->regenerate_interface_table = 1; +} + +/* rdma delete API */ +static int +api_rdma_delete (vat_main_t * vam) +{ + unformat_input_t *i = vam->input; + vl_api_rdma_delete_t *mp; + u32 sw_if_index = 0; + u8 index_defined = 0; + int ret; + + while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) + { + if (unformat (i, "sw_if_index %u", &sw_if_index)) + index_defined = 1; + else + { + clib_warning ("unknown input '%U'", format_unformat_error, i); + return -99; + } + } + + if (!index_defined) + { + errmsg ("missing sw_if_index\n"); + return -99; + } + + M (RDMA_DELETE, mp); + + mp->sw_if_index = clib_host_to_net_u32 (sw_if_index); + + S (mp); + W (ret); + + return ret; +} + +#include + +/* + * fd.io coding-style-patch-verification: ON + * + * Local Variables: + * eval: (c-set-style "gnu") + * End: + */ diff --git a/src/plugins/rdma/unformat.c b/src/plugins/rdma/unformat.c new file mode 100644 index 00000000000..0b4a1212500 --- /dev/null +++ b/src/plugins/rdma/unformat.c @@ -0,0 +1,63 @@ +/* + *------------------------------------------------------------------ + * Copyright (c) 2019 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 +#include + +uword +unformat_rdma_create_if_args (unformat_input_t * input, va_list * vargs) +{ + rdma_create_if_args_t *args = va_arg (*vargs, rdma_create_if_args_t *); + unformat_input_t _line_input, *line_input = &_line_input; + uword ret = 1; + + if (!unformat_user (input, unformat_line_input, line_input)) + return 0; + + clib_memset (args, 0, sizeof (*args)); + + while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) + { + if (unformat (line_input, "host-if %s", &args->ifname)) + ; + else if (unformat (line_input, "name %s", &args->name)) + ; + else if (unformat (line_input, "rx-queue-size %u", &args->rxq_size)) + ; + else if (unformat (line_input, "tx-queue-size %u", &args->txq_size)) + ; + else if (unformat (line_input, "num-rx-queues %u", &args->rxq_num)) + ; + else + { + /* return failure on unknown input */ + ret = 0; + break; + } + } + + unformat_free (line_input); + return ret; +} + +/* + * fd.io coding-style-patch-verification: ON + * + * Local Variables: + * eval: (c-set-style "gnu") + * End: + */ -- 2.16.6