From 588144ab4552a5f54b692016ff0543decc28d1ea Mon Sep 17 00:00:00 2001 From: Matus Fabian Date: Mon, 24 Oct 2016 03:30:00 -0700 Subject: VPP-459: SNAT dump API for in and out interfaces Change-Id: Ie0cba0778b094eaafa960d3f432199e1e3b2d116 Signed-off-by: Matus Fabian --- plugins/snat-plugin/snat/snat.api | 20 ++++ plugins/snat-plugin/snat/snat.c | 172 +++++++++++++++++++++++------------ plugins/snat-plugin/snat/snat.h | 8 ++ plugins/snat-plugin/snat/snat_test.c | 41 ++++++++- 4 files changed, 180 insertions(+), 61 deletions(-) (limited to 'plugins/snat-plugin/snat') diff --git a/plugins/snat-plugin/snat/snat.api b/plugins/snat-plugin/snat/snat.api index b2a21cf2b64..d7d41f2000d 100644 --- a/plugins/snat-plugin/snat/snat.api +++ b/plugins/snat-plugin/snat/snat.api @@ -92,6 +92,26 @@ define snat_interface_add_del_feature_reply { i32 retval; }; +/** \brief Dump interfaces with S-NAT feature + @param client_index - opaque cookie to identify the sender + @param context - sender context, to match reply w/ request +*/ +define snat_interface_dump { + u32 client_index; + u32 context; +}; + +/** \brief S-NAT interface details response + @param context - sender context, to match reply w/ request + @param is_inside - 1 if inside, 0 if outside + @param sw_if_index - software index of the interface +*/ +define snat_interface_details { + u32 context; + u8 is_inside; + u32 sw_if_index; +}; + /** \brief Add/delete S-NAT static mapping @param client_index - opaque cookie to identify the sender @param context - sender context, to match reply w/ request diff --git a/plugins/snat-plugin/snat/snat.c b/plugins/snat-plugin/snat/snat.c index 8490bd83374..505f501d250 100644 --- a/plugins/snat-plugin/snat/snat.c +++ b/plugins/snat-plugin/snat/snat.c @@ -529,6 +529,57 @@ int snat_add_static_mapping(ip4_address_t l_addr, ip4_address_t e_addr, return 0; } +static int snat_interface_add_del (u32 sw_if_index, u8 is_inside, int is_del) +{ + snat_main_t *sm = &snat_main; + snat_interface_t *i; + u32 ci; + ip4_main_t * im = &ip4_main; + ip_lookup_main_t * lm = &im->lookup_main; + ip_config_main_t * rx_cm = &lm->feature_config_mains[VNET_IP_RX_UNICAST_FEAT]; + u32 feature_index; + + if (sm->static_mapping_only && !(sm->static_mapping_connection_tracking)) + feature_index = is_inside ? sm->rx_feature_in2out_fast + : sm->rx_feature_out2in_fast; + else + feature_index = is_inside ? sm->rx_feature_in2out + : sm->rx_feature_out2in; + + ci = rx_cm->config_index_by_sw_if_index[sw_if_index]; + ci = (is_del + ? vnet_config_del_feature + : vnet_config_add_feature) + (sm->vlib_main, &rx_cm->config_main, + ci, + feature_index, + 0 /* config struct */, + 0 /* sizeof config struct*/); + rx_cm->config_index_by_sw_if_index[sw_if_index] = ci; + + pool_foreach (i, sm->interfaces, + ({ + if (i->sw_if_index == sw_if_index) + { + if (is_del) + pool_put (sm->interfaces, i); + else + return VNET_API_ERROR_VALUE_EXIST; + + return 0; + } + })); + + if (is_del) + return VNET_API_ERROR_NO_SUCH_ENTRY; + + pool_get (sm->interfaces, i); + i->sw_if_index = sw_if_index; + i->is_inside = is_inside; + + return 0; +} + static void vl_api_snat_add_address_range_t_handler (vl_api_snat_add_address_range_t * mp) @@ -650,32 +701,11 @@ vl_api_snat_interface_add_del_feature_t_handler vl_api_snat_interface_add_del_feature_reply_t * rmp; u8 is_del = mp->is_add == 0; u32 sw_if_index = ntohl(mp->sw_if_index); - u32 ci; - ip4_main_t * im = &ip4_main; - ip_lookup_main_t * lm = &im->lookup_main; - ip_config_main_t * rx_cm = &lm->feature_config_mains[VNET_IP_RX_UNICAST_FEAT]; - u32 feature_index; int rv = 0; VALIDATE_SW_IF_INDEX(mp); - if (sm->static_mapping_only && !(sm->static_mapping_connection_tracking)) - feature_index = mp->is_inside ? sm->rx_feature_in2out_fast - : sm->rx_feature_out2in_fast; - else - feature_index = mp->is_inside ? sm->rx_feature_in2out - : sm->rx_feature_out2in; - - ci = rx_cm->config_index_by_sw_if_index[sw_if_index]; - ci = (is_del - ? vnet_config_del_feature - : vnet_config_add_feature) - (sm->vlib_main, &rx_cm->config_main, - ci, - feature_index, - 0 /* config struct */, - 0 /* sizeof config struct*/); - rx_cm->config_index_by_sw_if_index[sw_if_index] = ci; + rv = snat_interface_add_del (sw_if_index, mp->is_inside, is_del); BAD_SW_IF_INDEX_LABEL; @@ -697,6 +727,50 @@ static void *vl_api_snat_interface_add_del_feature_t_print } static void +send_snat_interface_details +(snat_interface_t * i, unix_shared_memory_queue_t * q, u32 context) +{ + vl_api_snat_interface_details_t *rmp; + snat_main_t * sm = &snat_main; + + rmp = vl_msg_api_alloc (sizeof (*rmp)); + memset (rmp, 0, sizeof (*rmp)); + rmp->_vl_msg_id = ntohs (VL_API_SNAT_INTERFACE_DETAILS+sm->msg_id_base); + rmp->sw_if_index = ntohl (i->sw_if_index); + rmp->is_inside = i->is_inside; + rmp->context = context; + + vl_msg_api_send_shmem (q, (u8 *) & rmp); +} + +static void +vl_api_snat_interface_dump_t_handler +(vl_api_snat_interface_dump_t * mp) +{ + unix_shared_memory_queue_t *q; + snat_main_t * sm = &snat_main; + snat_interface_t * i; + + q = vl_api_client_index_to_input_queue (mp->client_index); + if (q == 0) + return; + + pool_foreach (i, sm->interfaces, + ({ + send_snat_interface_details(i, q, mp->context); + })); +} + +static void *vl_api_snat_interface_dump_t_print +(vl_api_snat_interface_dump_t *mp, void * handle) +{ + u8 *s; + + s = format (0, "SCRIPT: snat_interface_dump "); + + FINISH; +}static void + vl_api_snat_add_static_mapping_t_handler (vl_api_snat_add_static_mapping_t * mp) { @@ -866,7 +940,8 @@ _(SNAT_ADD_STATIC_MAPPING, snat_add_static_mapping) \ _(SNAT_CONTROL_PING, snat_control_ping) \ _(SNAT_STATIC_MAPPING_DUMP, snat_static_mapping_dump) \ _(SNAT_SHOW_CONFIG, snat_show_config) \ -_(SNAT_ADDRESS_DUMP, snat_address_dump) +_(SNAT_ADDRESS_DUMP, snat_address_dump) \ +_(SNAT_INTERFACE_DUMP, snat_interface_dump) /* Set up the API message handling tables */ static clib_error_t * @@ -1132,13 +1207,8 @@ snat_feature_command_fn (vlib_main_t * vm, { unformat_input_t _line_input, *line_input = &_line_input; vnet_main_t * vnm = vnet_get_main(); - snat_main_t * sm = &snat_main; - ip4_main_t * im = &ip4_main; - ip_lookup_main_t * lm = &im->lookup_main; - ip_config_main_t * rx_cm = &lm->feature_config_mains[VNET_IP_RX_UNICAST_FEAT]; clib_error_t * error = 0; - u32 sw_if_index, ci; - u32 feature_index; + u32 sw_if_index; u32 * inside_sw_if_indices = 0; u32 * outside_sw_if_indices = 0; int is_del = 0; @@ -1168,47 +1238,19 @@ snat_feature_command_fn (vlib_main_t * vm, if (vec_len (inside_sw_if_indices)) { - if (sm->static_mapping_only && !(sm->static_mapping_connection_tracking)) - feature_index = sm->rx_feature_in2out_fast; - else - feature_index = sm->rx_feature_in2out; - for (i = 0; i < vec_len(inside_sw_if_indices); i++) { sw_if_index = inside_sw_if_indices[i]; - ci = rx_cm->config_index_by_sw_if_index[sw_if_index]; - ci = (is_del - ? vnet_config_del_feature - : vnet_config_add_feature) - (vm, &rx_cm->config_main, - ci, - feature_index, - 0 /* config struct */, - 0 /* sizeof config struct*/); - rx_cm->config_index_by_sw_if_index[sw_if_index] = ci; + snat_interface_add_del (sw_if_index, 1, is_del); } } if (vec_len (outside_sw_if_indices)) { - if (sm->static_mapping_only && !(sm->static_mapping_connection_tracking)) - feature_index = sm->rx_feature_out2in_fast; - else - feature_index = sm->rx_feature_out2in; - for (i = 0; i < vec_len(outside_sw_if_indices); i++) { sw_if_index = outside_sw_if_indices[i]; - ci = rx_cm->config_index_by_sw_if_index[sw_if_index]; - ci = (is_del - ? vnet_config_del_feature - : vnet_config_add_feature) - (vm, &rx_cm->config_main, - ci, - feature_index, - 0 /* config struct */, - 0 /* sizeof config struct*/); - rx_cm->config_index_by_sw_if_index[sw_if_index] = ci; + snat_interface_add_del (sw_if_index, 0, is_del); } } @@ -1498,6 +1540,8 @@ show_snat_command_fn (vlib_main_t * vm, snat_main_t * sm = &snat_main; snat_user_t * u; snat_static_mapping_t *m; + snat_interface_t *i; + vnet_main_t *vnm = vnet_get_main(); if (unformat (input, "detail")) verbose = 1; @@ -1517,6 +1561,16 @@ show_snat_command_fn (vlib_main_t * vm, vlib_cli_output (vm, "SNAT mode: dynamic translations enabled"); } + if (verbose > 0) + { + pool_foreach (i, sm->interfaces, + ({ + vlib_cli_output (vm, "%U %s", format_vnet_sw_interface_name, vnm, + vnet_get_sw_interface (vnm, i->sw_if_index), + i->is_inside ? "in" : "out"); + })); + } + if (sm->static_mapping_only && !(sm->static_mapping_connection_tracking)) { vlib_cli_output (vm, "%d static mappings", diff --git a/plugins/snat-plugin/snat/snat.h b/plugins/snat-plugin/snat/snat.h index 531da284e93..1469f60e59d 100644 --- a/plugins/snat-plugin/snat/snat.h +++ b/plugins/snat-plugin/snat/snat.h @@ -126,6 +126,11 @@ typedef struct { u32 fib_index; } snat_static_mapping_t; +typedef struct { + u32 sw_if_index; + u8 is_inside; +} snat_interface_t; + typedef struct { /* Main lookup tables */ clib_bihash_8_8_t out2in; @@ -149,6 +154,9 @@ typedef struct { /* Static mapping pool */ snat_static_mapping_t * static_mappings; + /* Interface pool */ + snat_interface_t * interfaces; + /* Vector of outside addresses */ snat_address_t * addresses; diff --git a/plugins/snat-plugin/snat/snat_test.c b/plugins/snat-plugin/snat/snat_test.c index 29577e92607..e03c9eeccdd 100644 --- a/plugins/snat-plugin/snat/snat_test.c +++ b/plugins/snat-plugin/snat/snat_test.c @@ -90,7 +90,8 @@ _(SNAT_ADD_STATIC_MAPPING_REPLY, snat_add_static_mapping_reply) \ _(SNAT_CONTROL_PING_REPLY, snat_control_ping_reply) \ _(SNAT_STATIC_MAPPING_DETAILS, snat_static_mapping_details) \ _(SNAT_SHOW_CONFIG_REPLY, snat_show_config_reply) \ -_(SNAT_ADDRESS_DETAILS, snat_address_details) +_(SNAT_ADDRESS_DETAILS, snat_address_details) \ +_(SNAT_INTERFACE_DETAILS, snat_interface_details) /* M: construct, but don't yet send a message */ #define M(T,t) \ @@ -437,6 +438,41 @@ static int api_snat_address_dump(vat_main_t * vam) return 0; } +static void vl_api_snat_interface_details_t_handler + (vl_api_snat_interface_details_t *mp) +{ + snat_test_main_t * sm = &snat_test_main; + vat_main_t *vam = sm->vat_main; + + fformat (vam->ofp, "sw_if_index %d %s\n", ntohl (mp->sw_if_index), + mp->is_inside ? "in" : "out"); +} + +static int api_snat_interface_dump(vat_main_t * vam) +{ + snat_test_main_t * sm = &snat_test_main; + f64 timeout; + vl_api_snat_interface_dump_t * mp; + + if (vam->json_output) + { + clib_warning ("JSON output not supported for snat_address_dump"); + return -99; + } + + M(SNAT_INTERFACE_DUMP, snat_interface_dump); + S; + /* Use a control ping for synchronization */ + { + vl_api_snat_control_ping_t *mp; + M (SNAT_CONTROL_PING, snat_control_ping); + S; + } + W; + /* NOTREACHED */ + return 0; +} + /* * List of messages that the api test plugin sends, * and that the data plane plugin processes @@ -449,7 +485,8 @@ _(snat_add_static_mapping, "local_addr external_addr " \ "[local_port ] [external_port ] [vrf ] [del]") \ _(snat_static_mapping_dump, "") \ _(snat_show_config, "") \ -_(snat_address_dump, "") +_(snat_address_dump, "") \ +_(snat_interface_dump, "") void vat_api_hookup (vat_main_t *vam) { -- cgit 1.2.3-korg