From ad8015be47a8d7d4c1f94b51ad9c70e37cc29cbf Mon Sep 17 00:00:00 2001 From: Steven Date: Sun, 29 Oct 2017 22:10:46 -0700 Subject: [PATCH] devices: Add binary API for set interface rx-mode Also add vat test code to test the subject API. The format is sw_interface_set_rx_mode sw_if_index [queue ] Change-Id: Ib810d85d430077865bead8cc08a070f8ae478225 Signed-off-by: Steven --- src/vat/api_format.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++ src/vnet/interface.api | 20 +++++++++++++++ src/vnet/interface_api.c | 29 ++++++++++++++++++++++ src/vnet/interface_cli.c | 49 ++++++++++++++++++++++-------------- src/vnet/interface_funcs.h | 8 ++++++ 5 files changed, 150 insertions(+), 18 deletions(-) diff --git a/src/vat/api_format.c b/src/vat/api_format.c index c6b6317ef18..de63bc394a9 100644 --- a/src/vat/api_format.c +++ b/src/vat/api_format.c @@ -5044,6 +5044,7 @@ static void vl_api_flow_classify_details_t_handler_json #define foreach_standard_reply_retval_handler \ _(sw_interface_set_flags_reply) \ _(sw_interface_add_del_address_reply) \ +_(sw_interface_set_rx_mode_reply) \ _(sw_interface_set_table_reply) \ _(sw_interface_set_mpls_enable_reply) \ _(sw_interface_set_vpath_reply) \ @@ -5232,6 +5233,7 @@ _(CLI_REPLY, cli_reply) \ _(CLI_INBAND_REPLY, cli_inband_reply) \ _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY, \ sw_interface_add_del_address_reply) \ +_(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply) \ _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply) \ _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \ _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply) \ @@ -6232,6 +6234,64 @@ api_sw_interface_set_flags (vat_main_t * vam) return ret; } +static int +api_sw_interface_set_rx_mode (vat_main_t * vam) +{ + unformat_input_t *i = vam->input; + vl_api_sw_interface_set_rx_mode_t *mp; + u32 sw_if_index; + u8 sw_if_index_set = 0; + int ret; + u8 queue_id_valid = 0; + u32 queue_id; + vnet_hw_interface_rx_mode mode = VNET_HW_INTERFACE_RX_MODE_UNKNOWN; + + /* Parse args required to build the message */ + while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) + { + if (unformat (i, "queue %d", &queue_id)) + queue_id_valid = 1; + else if (unformat (i, "polling")) + mode = VNET_HW_INTERFACE_RX_MODE_POLLING; + else if (unformat (i, "interrupt")) + mode = VNET_HW_INTERFACE_RX_MODE_INTERRUPT; + else if (unformat (i, "adaptive")) + mode = VNET_HW_INTERFACE_RX_MODE_ADAPTIVE; + else + if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index)) + sw_if_index_set = 1; + else if (unformat (i, "sw_if_index %d", &sw_if_index)) + sw_if_index_set = 1; + else + break; + } + + if (sw_if_index_set == 0) + { + errmsg ("missing interface name or sw_if_index"); + return -99; + } + if (mode == VNET_HW_INTERFACE_RX_MODE_UNKNOWN) + { + errmsg ("missing rx-mode"); + return -99; + } + + /* Construct the API message */ + M (SW_INTERFACE_SET_RX_MODE, mp); + mp->sw_if_index = ntohl (sw_if_index); + mp->mode = mode; + mp->queue_id_valid = queue_id_valid; + mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0; + + /* send it... */ + S (mp); + + /* Wait for a reply, return the good/bad news... */ + W (ret); + return ret; +} + static int api_sw_interface_clear_stats (vat_main_t * vam) { @@ -21651,6 +21711,8 @@ _(sw_interface_set_flags, \ " | sw_if_index admin-up | admin-down link-up | link down") \ _(sw_interface_add_del_address, \ " | sw_if_index | [del] [del-all] ") \ +_(sw_interface_set_rx_mode, \ + " | sw_if_index [queue ] ") \ _(sw_interface_set_table, \ " | sw_if_index vrf [ipv6]") \ _(sw_interface_set_mpls_enable, \ diff --git a/src/vnet/interface.api b/src/vnet/interface.api index 2f2e8373357..a6fd5ad60d4 100644 --- a/src/vnet/interface.api +++ b/src/vnet/interface.api @@ -391,6 +391,26 @@ autoreply define sw_interface_set_mac_address u8 mac_address[6]; }; +/** \brief Set an interface's rx-mode + @param client_index - opaque cookie to identify the sender + @param context - sender context, to match reply w/ request + @param sw_if_index - the interface whose rx-mode will be set + @param queue_id_valid - 1 = the queue_id field is valid. 0 means all + queue_id's + @param queue_id - the queue number whose rx-mode will be set. Only valid + if queue_id_valid is 1 + @param mode - polling=1, interrupt=2, adaptive=3 +*/ +autoreply define sw_interface_set_rx_mode +{ + u32 client_index; + u32 context; + u32 sw_if_index; + u8 queue_id_valid; + u32 queue_id; + u8 mode; +}; + /* * Local Variables: * eval: (c-set-style "gnu") diff --git a/src/vnet/interface_api.c b/src/vnet/interface_api.c index c19f0a84297..a6414bc9ac6 100644 --- a/src/vnet/interface_api.c +++ b/src/vnet/interface_api.c @@ -54,6 +54,7 @@ _(SW_INTERFACE_SET_MTU, sw_interface_set_mtu) \ _(WANT_INTERFACE_EVENTS, want_interface_events) \ _(SW_INTERFACE_DUMP, sw_interface_dump) \ _(SW_INTERFACE_ADD_DEL_ADDRESS, sw_interface_add_del_address) \ +_(SW_INTERFACE_SET_RX_MODE, sw_interface_set_rx_mode) \ _(SW_INTERFACE_SET_TABLE, sw_interface_set_table) \ _(SW_INTERFACE_GET_TABLE, sw_interface_get_table) \ _(SW_INTERFACE_SET_UNNUMBERED, sw_interface_set_unnumbered) \ @@ -907,6 +908,34 @@ out: REPLY_MACRO (VL_API_SW_INTERFACE_SET_MAC_ADDRESS_REPLY); } +static void vl_api_sw_interface_set_rx_mode_t_handler + (vl_api_sw_interface_set_rx_mode_t * mp) +{ + vl_api_sw_interface_set_rx_mode_reply_t *rmp; + vnet_main_t *vnm = vnet_get_main (); + u32 sw_if_index = ntohl (mp->sw_if_index); + vnet_sw_interface_t *si; + clib_error_t *error; + int rv = 0; + + VALIDATE_SW_IF_INDEX (mp); + + si = vnet_get_sw_interface (vnm, sw_if_index); + error = set_hw_interface_change_rx_mode (vnm, si->hw_if_index, + mp->queue_id_valid, + ntohl (mp->queue_id), mp->mode); + if (error) + { + rv = VNET_API_ERROR_UNIMPLEMENTED; + clib_error_report (error); + goto out; + } + + BAD_SW_IF_INDEX_LABEL; +out: + REPLY_MACRO (VL_API_SW_INTERFACE_SET_RX_MODE_REPLY); +} + /* * vpe_api_hookup * Add vpe's API message handlers to the table. diff --git a/src/vnet/interface_cli.c b/src/vnet/interface_cli.c index 15dc7f8d504..e5efb1faef7 100644 --- a/src/vnet/interface_cli.c +++ b/src/vnet/interface_cli.c @@ -1347,6 +1347,33 @@ set_hw_interface_rx_mode (vnet_main_t * vnm, u32 hw_if_index, return 0; } +clib_error_t * +set_hw_interface_change_rx_mode (vnet_main_t * vnm, u32 hw_if_index, + u8 queue_id_valid, u32 queue_id, + vnet_hw_interface_rx_mode mode) +{ + clib_error_t *error = 0; + vnet_hw_interface_t *hw; + int i; + + hw = vnet_get_hw_interface (vnm, hw_if_index); + + if (queue_id_valid == 0) + { + for (i = 0; i < vec_len (hw->dq_runtime_index_by_queue); i++) + { + error = set_hw_interface_rx_mode (vnm, hw_if_index, i, mode); + if (error) + break; + } + hw->default_rx_mode = mode; + } + else + error = set_hw_interface_rx_mode (vnm, hw_if_index, queue_id, mode); + + return (error); +} + static clib_error_t * set_interface_rx_mode (vlib_main_t * vm, unformat_input_t * input, vlib_cli_command_t * cmd) @@ -1354,12 +1381,10 @@ set_interface_rx_mode (vlib_main_t * vm, unformat_input_t * input, clib_error_t *error = 0; unformat_input_t _line_input, *line_input = &_line_input; vnet_main_t *vnm = vnet_get_main (); - vnet_hw_interface_t *hw; u32 hw_if_index = (u32) ~ 0; u32 queue_id = (u32) ~ 0; vnet_hw_interface_rx_mode mode = VNET_HW_INTERFACE_RX_MODE_UNKNOWN; - int i; - u8 input_queue_id = 0; + u8 queue_id_valid = 0; if (!unformat_user (input, unformat_line_input, line_input)) return 0; @@ -1370,7 +1395,7 @@ set_interface_rx_mode (vlib_main_t * vm, unformat_input_t * input, (line_input, "%U", unformat_vnet_hw_interface, vnm, &hw_if_index)) ; else if (unformat (line_input, "queue %d", &queue_id)) - input_queue_id = 1; + queue_id_valid = 1; else if (unformat (line_input, "polling")) mode = VNET_HW_INTERFACE_RX_MODE_POLLING; else if (unformat (line_input, "interrupt")) @@ -1394,20 +1419,8 @@ set_interface_rx_mode (vlib_main_t * vm, unformat_input_t * input, if (mode == VNET_HW_INTERFACE_RX_MODE_UNKNOWN) return clib_error_return (0, "please specify valid rx-mode"); - hw = vnet_get_hw_interface (vnm, hw_if_index); - - if (input_queue_id == 0) - { - for (i = 0; i < vec_len (hw->dq_runtime_index_by_queue); i++) - { - error = set_hw_interface_rx_mode (vnm, hw_if_index, i, mode); - if (error) - break; - } - hw->default_rx_mode = mode; - } - else - error = set_hw_interface_rx_mode (vnm, hw_if_index, queue_id, mode); + error = set_hw_interface_change_rx_mode (vnm, hw_if_index, queue_id_valid, + queue_id, mode); return (error); } diff --git a/src/vnet/interface_funcs.h b/src/vnet/interface_funcs.h index 142bef57465..6f7ed111e46 100644 --- a/src/vnet/interface_funcs.h +++ b/src/vnet/interface_funcs.h @@ -276,6 +276,14 @@ clib_error_t *vnet_hw_interface_change_mac_address (vnet_main_t * vnm, u32 hw_if_index, u64 mac_address); +/* Change rx-mode */ +clib_error_t *set_hw_interface_change_rx_mode (vnet_main_t * vnm, + u32 hw_if_index, + u8 queue_id_valid, + u32 queue_id, + vnet_hw_interface_rx_mode + mode); + /* Formats sw/hw interface. */ format_function_t format_vnet_hw_interface; format_function_t format_vnet_hw_interface_rx_mode; -- 2.16.6