From 8bf68e858a30a9c04329668d2b5dd67e9ad6f5af Mon Sep 17 00:00:00 2001 From: Matus Fabian Date: Thu, 12 Jan 2017 04:24:35 -0800 Subject: SNAT: add API and test for NAT pool address from interface Change-Id: I2a868f736fae8d37b438c604a9284653ea415541 Signed-off-by: Matus Fabian --- src/plugins/snat/snat.c | 122 +++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 116 insertions(+), 6 deletions(-) (limited to 'src/plugins/snat/snat.c') diff --git a/src/plugins/snat/snat.c b/src/plugins/snat/snat.c index 94e05078..a1236cf7 100644 --- a/src/plugins/snat/snat.c +++ b/src/plugins/snat/snat.c @@ -1094,6 +1094,84 @@ static void *vl_api_snat_worker_dump_t_print FINISH; } +static int snat_add_interface_address(snat_main_t *sm, + u32 sw_if_index, + int is_del); + +static void +vl_api_snat_add_del_interface_addr_t_handler +(vl_api_snat_add_del_interface_addr_t * mp) +{ + snat_main_t * sm = &snat_main; + vl_api_snat_add_del_interface_addr_reply_t * rmp; + u8 is_del = mp->is_add == 0; + u32 sw_if_index = ntohl(mp->sw_if_index); + int rv = 0; + + VALIDATE_SW_IF_INDEX(mp); + + rv = snat_add_interface_address (sm, sw_if_index, is_del); + + BAD_SW_IF_INDEX_LABEL; + + REPLY_MACRO(VL_API_SNAT_ADD_DEL_INTERFACE_ADDR_REPLY); +} + +static void *vl_api_snat_add_del_interface_addr_t_print +(vl_api_snat_add_del_interface_addr_t * mp, void *handle) +{ + u8 * s; + + s = format (0, "SCRIPT: snat_add_del_interface_addr "); + s = format (s, "sw_if_index %d %s", + clib_host_to_net_u32(mp->sw_if_index), + mp->is_add ? "" : "del"); + + FINISH; +} + +static void +send_snat_interface_addr_details +(u32 sw_if_index, unix_shared_memory_queue_t * q, u32 context) +{ + vl_api_snat_interface_addr_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_ADDR_DETAILS+sm->msg_id_base); + rmp->sw_if_index = ntohl (sw_if_index); + rmp->context = context; + + vl_msg_api_send_shmem (q, (u8 *) & rmp); +} + +static void +vl_api_snat_interface_addr_dump_t_handler +(vl_api_snat_interface_addr_dump_t * mp) +{ + unix_shared_memory_queue_t *q; + snat_main_t * sm = &snat_main; + u32 * i; + + q = vl_api_client_index_to_input_queue (mp->client_index); + if (q == 0) + return; + + vec_foreach (i, sm->auto_add_sw_if_indices) + send_snat_interface_addr_details(*i, q, mp->context); +} + +static void *vl_api_snat_interface_addr_dump_t_print +(vl_api_snat_interface_addr_dump_t *mp, void * handle) +{ + u8 *s; + + s = format (0, "SCRIPT: snat_interface_addr_dump "); + + FINISH; +} + /* List of message types that this plugin understands */ #define foreach_snat_plugin_api_msg \ _(SNAT_ADD_ADDRESS_RANGE, snat_add_address_range) \ @@ -1105,7 +1183,9 @@ _(SNAT_SHOW_CONFIG, snat_show_config) \ _(SNAT_ADDRESS_DUMP, snat_address_dump) \ _(SNAT_INTERFACE_DUMP, snat_interface_dump) \ _(SNAT_SET_WORKERS, snat_set_workers) \ -_(SNAT_WORKER_DUMP, snat_worker_dump) +_(SNAT_WORKER_DUMP, snat_worker_dump) \ +_(SNAT_ADD_DEL_INTERFACE_ADDR, snat_add_del_interface_addr) \ +_(SNAT_INTERFACE_ADDR_DUMP, snat_interface_addr_dump) /* Set up the API message handling tables */ static clib_error_t * @@ -1840,7 +1920,7 @@ show_snat_command_fn (vlib_main_t * vm, snat_address_t * ap; vnet_main_t *vnm = vnet_get_main(); snat_main_per_thread_data_t *tsm; - u32 users_num = 0, sessions_num = 0, *worker; + u32 users_num = 0, sessions_num = 0, *worker, *sw_if_index; uword j = 0; if (unformat (input, "detail")) @@ -1870,6 +1950,16 @@ show_snat_command_fn (vlib_main_t * vm, i->is_inside ? "in" : "out"); })); + if (vec_len (sm->auto_add_sw_if_indices)) + { + vlib_cli_output (vm, "SNAT pool addresses interfaces:"); + vec_foreach (sw_if_index, sm->auto_add_sw_if_indices) + { + vlib_cli_output (vm, "%U", format_vnet_sw_interface_name, vnm, + vnet_get_sw_interface (vnm, *sw_if_index)); + } + } + vec_foreach (ap, sm->addresses) { u8 * s = format (0, ""); @@ -2011,7 +2101,9 @@ snat_ip4_add_del_interface_address_cb (ip4_main_t * im, } -static int snat_add_interface_address (snat_main_t *sm, u32 sw_if_index) +static int snat_add_interface_address (snat_main_t *sm, + u32 sw_if_index, + int is_del) { ip4_main_t * ip4_main = sm->ip4_main; ip4_address_t * first_int_addr; @@ -2023,9 +2115,24 @@ static int snat_add_interface_address (snat_main_t *sm, u32 sw_if_index) for (i = 0; i < vec_len(sm->auto_add_sw_if_indices); i++) { if (sm->auto_add_sw_if_indices[i] == sw_if_index) - return 0; + { + if (is_del) + { + /* if have address remove it */ + if (first_int_addr) + (void) snat_del_address (sm, first_int_addr[0]); + vec_del1(sm->auto_add_sw_if_indices, i); + } + else + return VNET_API_ERROR_VALUE_EXIST; + + return 0; + } } + if (is_del) + return VNET_API_ERROR_NO_SUCH_ENTRY; + /* add to the auto-address list */ vec_add1(sm->auto_add_sw_if_indices, sw_if_index); @@ -2045,6 +2152,7 @@ snat_add_interface_address_command_fn (vlib_main_t * vm, unformat_input_t _line_input, *line_input = &_line_input; u32 sw_if_index; int rv; + int is_del = 0; /* Get a line of input. */ if (!unformat_user (input, unformat_line_input, line_input)) @@ -2055,12 +2163,14 @@ snat_add_interface_address_command_fn (vlib_main_t * vm, if (unformat (line_input, "%U", unformat_vnet_sw_interface, sm->vnet_main, &sw_if_index)) ; + else if (unformat (line_input, "del")) + is_del = 1; else return clib_error_return (0, "unknown input '%U'", format_unformat_error, line_input); } - rv = snat_add_interface_address (sm, sw_if_index); + rv = snat_add_interface_address (sm, sw_if_index, is_del); switch (rv) { @@ -2076,6 +2186,6 @@ snat_add_interface_address_command_fn (vlib_main_t * vm, VLIB_CLI_COMMAND (snat_add_interface_address_command, static) = { .path = "snat add interface address", - .short_help = "snat add interface address ", + .short_help = "snat add interface address [del]", .function = snat_add_interface_address_command_fn, }; -- cgit 1.2.3-korg