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;
}
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;
}
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;
}
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;
@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 {
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;
+};
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) \
_(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 *
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)
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)
.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]",
+};
/* 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;
#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>
_(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 \
_(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)
{
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
"<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)
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,
"""
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)