aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatus Fabian <matfabia@cisco.com>2017-04-12 03:36:13 -0700
committerOle Trøan <otroan@employees.org>2017-04-12 13:09:34 +0000
commit6a0946f078183361a5b757f6405165089b659c5c (patch)
tree23ea7f7b823f9e987e18234365dd90de013d308f
parentf3ebb452ca26318b75b8f93569c3c752f05aed25 (diff)
CGN: configurable timeouts
add API and CLI configuration of deterministic NAT session timeout for TCP, UDP and ICMP protocol Change-Id: I577440452e7eaedcb5d80501a7fd4b76e31e8c9c Signed-off-by: Matus Fabian <matfabia@cisco.com>
-rw-r--r--src/plugins/snat/in2out.c20
-rw-r--r--src/plugins/snat/snat.api55
-rw-r--r--src/plugins/snat/snat.c139
-rw-r--r--src/plugins/snat/snat.h6
-rw-r--r--src/plugins/snat/snat_test.c85
-rw-r--r--test/test_snat.py19
-rw-r--r--test/vpp_papi_provider.py27
7 files changed, 336 insertions, 15 deletions
diff --git a/src/plugins/snat/in2out.c b/src/plugins/snat/in2out.c
index 2dbaeb40355..1e8e14484c3 100644
--- a/src/plugins/snat/in2out.c
+++ b/src/plugins/snat/in2out.c
@@ -1687,16 +1687,16 @@ snat_det_in2out_node_fn (vlib_main_t * vm,
switch(ses0->state)
{
case SNAT_SESSION_UDP_ACTIVE:
- ses0->expire = now + SNAT_UDP_TIMEOUT;
+ ses0->expire = now + sm->udp_timeout;
break;
case SNAT_SESSION_TCP_SYN_SENT:
case SNAT_SESSION_TCP_FIN_WAIT:
case SNAT_SESSION_TCP_CLOSE_WAIT:
case SNAT_SESSION_TCP_LAST_ACK:
- ses0->expire = now + SNAT_TCP_TRANSITORY_TIMEOUT;
+ ses0->expire = now + sm->tcp_transitory_timeout;
break;
case SNAT_SESSION_TCP_ESTABLISHED:
- ses0->expire = now + SNAT_TCP_ESTABLISHED_TIMEOUT;
+ ses0->expire = now + sm->tcp_established_timeout;
break;
}
@@ -1831,16 +1831,16 @@ snat_det_in2out_node_fn (vlib_main_t * vm,
switch(ses1->state)
{
case SNAT_SESSION_UDP_ACTIVE:
- ses1->expire = now + SNAT_UDP_TIMEOUT;
+ ses1->expire = now + sm->udp_timeout;
break;
case SNAT_SESSION_TCP_SYN_SENT:
case SNAT_SESSION_TCP_FIN_WAIT:
case SNAT_SESSION_TCP_CLOSE_WAIT:
case SNAT_SESSION_TCP_LAST_ACK:
- ses1->expire = now + SNAT_TCP_TRANSITORY_TIMEOUT;
+ ses1->expire = now + sm->tcp_transitory_timeout;
break;
case SNAT_SESSION_TCP_ESTABLISHED:
- ses1->expire = now + SNAT_TCP_ESTABLISHED_TIMEOUT;
+ ses1->expire = now + sm->tcp_established_timeout;
break;
}
@@ -2011,16 +2011,16 @@ snat_det_in2out_node_fn (vlib_main_t * vm,
switch(ses0->state)
{
case SNAT_SESSION_UDP_ACTIVE:
- ses0->expire = now + SNAT_UDP_TIMEOUT;
+ ses0->expire = now + sm->udp_timeout;
break;
case SNAT_SESSION_TCP_SYN_SENT:
case SNAT_SESSION_TCP_FIN_WAIT:
case SNAT_SESSION_TCP_CLOSE_WAIT:
case SNAT_SESSION_TCP_LAST_ACK:
- ses0->expire = now + SNAT_TCP_TRANSITORY_TIMEOUT;
+ ses0->expire = now + sm->tcp_transitory_timeout;
break;
case SNAT_SESSION_TCP_ESTABLISHED:
- ses0->expire = now + SNAT_TCP_ESTABLISHED_TIMEOUT;
+ ses0->expire = now + sm->tcp_established_timeout;
break;
}
@@ -2218,7 +2218,7 @@ u32 icmp_match_in2out_det(snat_main_t *sm, vlib_node_runtime_t *node,
u32 now = (u32) vlib_time_now (sm->vlib_main);
ses0->state = SNAT_SESSION_ICMP_ACTIVE;
- ses0->expire = now + SNAT_ICMP_TIMEOUT;
+ ses0->expire = now + sm->icmp_timeout;
out:
*p_proto = protocol;
diff --git a/src/plugins/snat/snat.api b/src/plugins/snat/snat.api
index 92aa32b6dca..9689f5f9dfc 100644
--- a/src/plugins/snat/snat.api
+++ b/src/plugins/snat/snat.api
@@ -126,7 +126,8 @@ define snat_interface_details {
@param local_port - local port number
@param external_port - external port number
@param external_sw_if_index - external interface (if set
- external_ip_address is ignored)
+ external_ip_address is ignored, ~0 means not
+ used)
@param vfr_id - VRF ID
*/
define snat_add_static_mapping {
@@ -546,3 +547,55 @@ define snat_det_map_details {
u16 ports_per_host;
u32 ses_num;
};
+
+/** \brief Set values of timeouts for deterministic NAT (seconds, 0 = default)
+ @param client_index - opaque cookie to identify the sender
+ @param context - sender context, to match reply w/ request
+ @param udp - UDP timeout (default 300sec)
+ @param tcp_established - TCP established timeout (default 7440sec)
+ @param tcp_transitory - TCP transitory timeout (default 240sec)
+ @param icmp - ICMP timeout (default 60sec)
+*/
+define snat_det_set_timeouts {
+ u32 client_index;
+ u32 context;
+ u32 udp;
+ u32 tcp_established;
+ u32 tcp_transitory;
+ u32 icmp;
+};
+
+/** \brief Set values of timeouts for deterministic NAT reply
+ @param context - sender context, to match reply w/ request
+ @param retval - return code
+*/
+define snat_det_set_timeouts_reply {
+ u32 context;
+ i32 retval;
+};
+
+/** \brief Get values of timeouts for deterministic NAT (seconds)
+ @param client_index - opaque cookie to identify the sender
+ @param context - sender context, to match reply w/ request
+*/
+define snat_det_get_timeouts {
+ u32 client_index;
+ u32 context;
+};
+
+/** \brief Get values of timeouts for deterministic NAT reply
+ @param context - sender context, to match reply w/ request
+ @param retval - return code
+ @param udp - UDP timeout (default 300sec)
+ @param tcp_established - TCP established timeout (default 7440sec)
+ @param tcp_transitory - TCP transitory timeout (default 240sec)
+ @param icmp - ICMP timeout (default 60sec)
+*/
+define snat_det_get_timeouts_reply {
+ u32 context;
+ i32 retval;
+ u32 udp;
+ u32 tcp_established;
+ u32 tcp_transitory;
+ u32 icmp;
+};
diff --git a/src/plugins/snat/snat.c b/src/plugins/snat/snat.c
index 65d26b3cda2..24ef5df9a2f 100644
--- a/src/plugins/snat/snat.c
+++ b/src/plugins/snat/snat.c
@@ -1654,6 +1654,64 @@ static void * vl_api_snat_det_map_dump_t_print
FINISH;
}
+static void
+vl_api_snat_det_set_timeouts_t_handler
+(vl_api_snat_det_set_timeouts_t * mp)
+{
+ snat_main_t * sm = &snat_main;
+ vl_api_snat_det_set_timeouts_reply_t * rmp;
+ int rv = 0;
+
+ sm->udp_timeout = ntohl(mp->udp);
+ sm->tcp_established_timeout = ntohl(mp->tcp_established);
+ sm->tcp_transitory_timeout = ntohl(mp->tcp_transitory);
+ sm->icmp_timeout = ntohl(mp->icmp);
+
+ REPLY_MACRO (VL_API_SNAT_DET_SET_TIMEOUTS_REPLY);
+}
+
+static void *vl_api_snat_det_set_timeouts_t_print
+(vl_api_snat_det_set_timeouts_t *mp, void * handle)
+{
+ u8 * s;
+
+ s = format (0, "SCRIPT: snat_det_set_timeouts ");
+ s = format (s, "udp %d tcp_established %d tcp_transitory %d icmp %d\n",
+ ntohl(mp->udp),
+ ntohl(mp->tcp_established),
+ ntohl(mp->tcp_transitory),
+ ntohl(mp->icmp));
+
+ FINISH;
+}
+
+static void
+vl_api_snat_det_get_timeouts_t_handler
+(vl_api_snat_det_get_timeouts_t * mp)
+{
+ snat_main_t * sm = &snat_main;
+ vl_api_snat_det_get_timeouts_reply_t * rmp;
+ int rv = 0;
+
+ REPLY_MACRO2(VL_API_SNAT_DET_GET_TIMEOUTS_REPLY,
+ ({
+ rmp->udp = htonl(sm->udp_timeout);
+ rmp->tcp_established = htonl(sm->tcp_established_timeout);
+ rmp->tcp_transitory = htonl(sm->tcp_transitory_timeout);
+ rmp->icmp = htonl(sm->icmp_timeout);
+ }))
+}
+
+static void *vl_api_snat_det_get_timeouts_t_print
+(vl_api_snat_det_get_timeouts_t * mp, void * handle)
+{
+ u8 * s;
+
+ s = format(0, "SCRIPT: snat_det_get_timeouts");
+
+ FINISH;
+}
+
/* List of message types that this plugin understands */
#define foreach_snat_plugin_api_msg \
_(SNAT_ADD_ADDRESS_RANGE, snat_add_address_range) \
@@ -1674,7 +1732,10 @@ _(SNAT_USER_SESSION_DUMP, snat_user_session_dump) \
_(SNAT_ADD_DET_MAP, snat_add_det_map) \
_(SNAT_DET_FORWARD, snat_det_forward) \
_(SNAT_DET_REVERSE, snat_det_reverse) \
-_(SNAT_DET_MAP_DUMP, snat_det_map_dump)
+_(SNAT_DET_MAP_DUMP, snat_det_map_dump) \
+_(SNAT_DET_SET_TIMEOUTS, snat_det_set_timeouts) \
+_(SNAT_DET_GET_TIMEOUTS, snat_det_get_timeouts)
+
/* Set up the API message handling tables */
static clib_error_t *
@@ -1758,6 +1819,10 @@ static clib_error_t * snat_init (vlib_main_t * vm)
sm->workers = 0;
sm->fq_in2out_index = ~0;
sm->fq_out2in_index = ~0;
+ sm->udp_timeout = SNAT_UDP_TIMEOUT;
+ sm->tcp_established_timeout = SNAT_TCP_ESTABLISHED_TIMEOUT;
+ sm->tcp_transitory_timeout = SNAT_TCP_TRANSITORY_TIMEOUT;
+ sm->icmp_timeout = SNAT_ICMP_TIMEOUT;
p = hash_get_mem (tm->thread_registrations_by_name, "workers");
if (p)
@@ -2855,6 +2920,12 @@ show_snat_command_fn (vlib_main_t * vm,
if (sm->deterministic)
{
+ vlib_cli_output (vm, "udp timeout: %dsec", sm->udp_timeout);
+ vlib_cli_output (vm, "tcp-established timeout: %dsec",
+ sm->tcp_established_timeout);
+ vlib_cli_output (vm, "tcp-transitory timeout: %dsec",
+ sm->tcp_transitory_timeout);
+ vlib_cli_output (vm, "icmp timeout: %dsec", sm->icmp_timeout);
vlib_cli_output (vm, "%d deterministic mappings",
pool_elts (sm->det_maps));
if (verbose > 0)
@@ -3346,3 +3417,69 @@ VLIB_CLI_COMMAND (snat_det_reverse_command, static) = {
.short_help = "snat deterministic reverse <addr>:<port>",
.function = snat_det_reverse_command_fn,
};
+
+static clib_error_t *
+set_timeout_command_fn (vlib_main_t * vm,
+ unformat_input_t * input,
+ vlib_cli_command_t * cmd)
+{
+ snat_main_t *sm = &snat_main;
+ unformat_input_t _line_input, *line_input = &_line_input;
+ clib_error_t *error = 0;
+
+ /* Get a line of input. */
+ if (!unformat_user (input, unformat_line_input, line_input))
+ return 0;
+
+ while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat (line_input, "udp %u", &sm->udp_timeout))
+ ;
+ else if (unformat (line_input, "tcp-established %u",
+ &sm->tcp_established_timeout))
+ ;
+ else if (unformat (line_input, "tcp-transitory %u",
+ &sm->tcp_transitory_timeout))
+ ;
+ else if (unformat (line_input, "icmp %u", &sm->icmp_timeout))
+ ;
+ else if (unformat (line_input, "reset"))
+ {
+ sm->udp_timeout = SNAT_UDP_TIMEOUT;
+ sm->tcp_established_timeout = SNAT_TCP_ESTABLISHED_TIMEOUT;
+ sm->tcp_transitory_timeout = SNAT_TCP_TRANSITORY_TIMEOUT;
+ sm->icmp_timeout = SNAT_ICMP_TIMEOUT;
+ }
+ else
+ {
+ error = clib_error_return (0, "unknown input '%U'",
+ format_unformat_error, line_input);
+ goto done;
+ }
+ }
+
+ unformat_free (line_input);
+
+done:
+ unformat_free (line_input);
+
+ return error;
+}
+
+/*?
+ * @cliexpar
+ * @cliexstart{set snat deterministic timeout}
+ * Set values of timeouts for deterministic NAT (in seconds), use:
+ * vpp# set snat deterministic timeout udp 120 tcp-established 7500
+ * tcp-transitory 250 icmp 90
+ * To reset default values use:
+ * vpp# set snat deterministic timeout reset
+ * @cliexend
+?*/
+VLIB_CLI_COMMAND (set_timeout_command, static) = {
+ .path = "set snat deterministic timeout",
+ .function = set_timeout_command_fn,
+ .short_help =
+ "set snat deterministic timeout [udp <sec> | tcp-established <sec> "
+ "tcp-transitory <sec> | icmp <sec> | reset]",
+};
diff --git a/src/plugins/snat/snat.h b/src/plugins/snat/snat.h
index d0ffea7381c..92bc8d138b7 100644
--- a/src/plugins/snat/snat.h
+++ b/src/plugins/snat/snat.h
@@ -312,6 +312,12 @@ typedef struct snat_main_s {
/* tenant VRF aware address pool activation flag */
u8 vrf_mode;
+ /* values of various timeouts */
+ u32 udp_timeout;
+ u32 tcp_established_timeout;
+ u32 tcp_transitory_timeout;
+ u32 icmp_timeout;
+
/* API message ID base */
u16 msg_id_base;
diff --git a/src/plugins/snat/snat_test.c b/src/plugins/snat/snat_test.c
index e26a3958e3b..4117d9448aa 100644
--- a/src/plugins/snat/snat_test.c
+++ b/src/plugins/snat/snat_test.c
@@ -21,6 +21,7 @@
#include <vlibsocket/api.h>
#include <vppinfra/error.h>
#include <vnet/ip/ip.h>
+#include <snat/snat.h>
#define __plugin_msg_base snat_test_main.msg_id_base
#include <vlibapi/vat_helper_macros.h>
@@ -67,7 +68,8 @@ _(snat_add_static_mapping_reply) \
_(snat_set_workers_reply) \
_(snat_add_del_interface_addr_reply) \
_(snat_ipfix_enable_disable_reply) \
-_(snat_add_det_map_reply)
+_(snat_add_det_map_reply) \
+_(snat_det_set_timeouts_reply)
#define _(n) \
static void vl_api_##n##_t_handler \
@@ -111,7 +113,9 @@ _(SNAT_USER_SESSION_DETAILS, snat_user_session_details) \
_(SNAT_ADD_DET_MAP_REPLY, snat_add_det_map_reply) \
_(SNAT_DET_FORWARD_REPLY, snat_det_forward_reply) \
_(SNAT_DET_REVERSE_REPLY, snat_det_reverse_reply) \
-_(SNAT_DET_MAP_DETAILS, snat_det_map_details)
+_(SNAT_DET_MAP_DETAILS, snat_det_map_details) \
+_(SNAT_DET_SET_TIMEOUTS_REPLY, snat_det_set_timeouts_reply) \
+_(SNAT_DET_GET_TIMEOUTS_REPLY, snat_det_get_timeouts_reply)
static int api_snat_add_address_range (vat_main_t * vam)
{
@@ -893,6 +897,78 @@ static int api_snat_det_map_dump(vat_main_t * vam)
return ret;
}
+static int api_snat_det_set_timeouts (vat_main_t * vam)
+{
+ unformat_input_t * i = vam->input;
+ vl_api_snat_det_set_timeouts_t * mp;
+ u32 udp = SNAT_UDP_TIMEOUT;
+ u32 tcp_established = SNAT_TCP_ESTABLISHED_TIMEOUT;
+ u32 tcp_transitory = SNAT_TCP_TRANSITORY_TIMEOUT;
+ u32 icmp = SNAT_ICMP_TIMEOUT;
+ int ret;
+
+ if (unformat (i, "udp %d", &udp))
+ ;
+ else if (unformat (i, "tcp_established %d", &tcp_established))
+ ;
+ else if (unformat (i, "tcp_transitory %d", &tcp_transitory))
+ ;
+ else if (unformat (i, "icmp %d", &icmp))
+ ;
+ else
+ {
+ clib_warning("unknown input '%U'", format_unformat_error, i);
+ return -99;
+ }
+
+ M(SNAT_DET_SET_TIMEOUTS, mp);
+ mp->udp = htonl(udp);
+ mp->tcp_established = htonl(tcp_established);
+ mp->tcp_transitory = htonl(tcp_transitory);
+ mp->icmp = htonl(icmp);
+
+ S(mp);
+ W (ret);
+ return ret;
+}
+
+static void vl_api_snat_det_get_timeouts_reply_t_handler
+ (vl_api_snat_det_get_timeouts_reply_t *mp)
+{
+ snat_test_main_t * sm = &snat_test_main;
+ vat_main_t *vam = sm->vat_main;
+ i32 retval = ntohl (mp->retval);
+
+ if (retval >= 0)
+ {
+ fformat (vam->ofp, "udp timeout: %dsec\n", ntohl (mp->udp));
+ fformat (vam->ofp, "tcp-established timeout: %dsec",
+ ntohl (mp->tcp_established));
+ fformat (vam->ofp, "tcp-transitory timeout: %dsec",
+ ntohl (mp->tcp_transitory));
+ fformat (vam->ofp, "icmp timeout: %dsec", ntohl (mp->icmp));
+ }
+ vam->retval = retval;
+ vam->result_ready = 1;
+}
+
+static int api_snat_det_get_timeouts(vat_main_t * vam)
+{
+ vl_api_snat_det_get_timeouts_t * mp;
+ int ret;
+
+ if (vam->json_output)
+ {
+ clib_warning ("JSON output not supported for snat_show_config");
+ return -99;
+ }
+
+ M(SNAT_DET_GET_TIMEOUTS, mp);
+ S(mp);
+ W (ret);
+ return ret;
+}
+
/*
* List of messages that the api test plugin sends,
* and that the data plane plugin processes
@@ -922,7 +998,10 @@ _(snat_add_det_map, "in <in_addr>/<in_plen> out " \
"<out_addr>/<out_plen> [del]") \
_(snat_det_forward, "<in_addr>") \
_(snat_det_reverse, "<out_addr> <out_port>") \
-_(snat_det_map_dump, "")
+_(snat_det_map_dump, "") \
+_(snat_det_set_timeouts, "[udp <sec> | tcp_established <sec> | " \
+ "tcp_transitory <sec> | icmp <sec>]") \
+_(snat_det_get_timeouts, "")
static void
snat_vat_api_hookup (vat_main_t *vam)
diff --git a/test/test_snat.py b/test/test_snat.py
index 0708d440714..4739a7ceb7a 100644
--- a/test/test_snat.py
+++ b/test/test_snat.py
@@ -1345,10 +1345,29 @@ class TestDeterministicNAT(MethodHolder):
deterministic_mappings = self.vapi.snat_det_map_dump()
self.assertEqual(len(deterministic_mappings), 0)
+ def test_set_timeouts(self):
+ """ Set deterministic NAT timeouts """
+ timeouts_before = self.vapi.snat_det_get_timeouts()
+
+ self.vapi.snat_det_set_timeouts(timeouts_before.udp + 10,
+ timeouts_before.tcp_established + 10,
+ timeouts_before.tcp_transitory + 10,
+ timeouts_before.icmp + 10)
+
+ timeouts_after = self.vapi.snat_det_get_timeouts()
+
+ self.assertNotEqual(timeouts_before.udp, timeouts_after.udp)
+ self.assertNotEqual(timeouts_before.icmp, timeouts_after.icmp)
+ self.assertNotEqual(timeouts_before.tcp_established,
+ timeouts_after.tcp_established)
+ self.assertNotEqual(timeouts_before.tcp_transitory,
+ timeouts_after.tcp_transitory)
+
def clear_snat(self):
"""
Clear SNAT configuration.
"""
+ self.vapi.snat_det_set_timeouts()
deterministic_mappings = self.vapi.snat_det_map_dump()
for dsm in deterministic_mappings:
self.vapi.snat_add_det_map(dsm.in_addr,
diff --git a/test/vpp_papi_provider.py b/test/vpp_papi_provider.py
index ceb684b75f6..4541f01a1bd 100644
--- a/test/vpp_papi_provider.py
+++ b/test/vpp_papi_provider.py
@@ -1199,6 +1199,33 @@ class VppPapiProvider(object):
"""
return self.api(self.papi.snat_det_map_dump, {})
+ def snat_det_set_timeouts(
+ self,
+ udp=300,
+ tcp_established=7440,
+ tcp_transitory=240,
+ icmp=60):
+ """Set values of timeouts for deterministic NAT (in seconds)
+
+ :param udp - UDP timeout (Default value = 300)
+ :param tcp_established - TCP established timeout (Default value = 7440)
+ :param tcp_transitory - TCP transitory timeout (Default value = 240)
+ :param icmp - ICMP timeout (Default value = 60)
+ """
+ return self.api(
+ self.papi.snat_det_set_timeouts,
+ {'udp': udp,
+ 'tcp_established': tcp_established,
+ 'tcp_transitory': tcp_transitory,
+ 'icmp': icmp})
+
+ def snat_det_get_timeouts(self):
+ """Get values of timeouts for deterministic NAT
+
+ :return: Timeouts for deterministic NAT (in seconds)
+ """
+ return self.api(self.papi.snat_det_get_timeouts, {})
+
def control_ping(self):
self.api(self.papi.control_ping)