summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/plugins/snat/snat.api32
-rw-r--r--src/plugins/snat/snat.c52
-rw-r--r--src/plugins/snat/snat_test.c44
-rw-r--r--test/test_snat.py22
-rw-r--r--test/vpp_papi_provider.py7
5 files changed, 153 insertions, 4 deletions
diff --git a/src/plugins/snat/snat.api b/src/plugins/snat/snat.api
index 612830f9a6e..92aa32b6dca 100644
--- a/src/plugins/snat/snat.api
+++ b/src/plugins/snat/snat.api
@@ -514,3 +514,35 @@ define snat_det_reverse_reply {
u8 is_ip4;
u8 in_addr[16];
};
+
+/** \brief Dump S-NAT deterministic mappings
+ @param client_index - opaque cookie to identify the sender
+ @param context - sender context, to match reply w/ request
+*/
+define snat_det_map_dump {
+ u32 client_index;
+ u32 context;
+};
+
+/** \brief S-NAT users response
+ @param context - sender context, to match reply w/ request
+ @param is_ip4 - 1 if address type is IPv4
+ @param in_addr - inside IP address
+ @param in_plen - inside IP address prefix length
+ @param out_addr - outside IP address
+ @param out_plen - outside IP address prefix length
+ @param sharing_ratio - outside to inside address sharing ratio
+ @param ports_per_host - number of ports available to a host
+ @param ses_num - number of sessions belonging to this mapping
+*/
+define snat_det_map_details {
+ u32 context;
+ u8 is_ip4;
+ u8 in_addr[16];
+ u8 in_plen;
+ u8 out_addr[16];
+ u8 out_plen;
+ u32 sharing_ratio;
+ u16 ports_per_host;
+ u32 ses_num;
+};
diff --git a/src/plugins/snat/snat.c b/src/plugins/snat/snat.c
index 16fbbdf6599..a735eb8adc6 100644
--- a/src/plugins/snat/snat.c
+++ b/src/plugins/snat/snat.c
@@ -1703,6 +1703,55 @@ static void *vl_api_snat_det_reverse_t_print
FINISH;
}
+static void
+sent_snat_det_map_details
+(snat_det_map_t * m, unix_shared_memory_queue_t * q, u32 context)
+{
+ vl_api_snat_det_map_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_DET_MAP_DETAILS+sm->msg_id_base);
+ rmp->is_ip4 = 1;
+ clib_memcpy (rmp->in_addr, &m->in_addr, 4);
+ rmp->in_plen = m->in_plen;
+ clib_memcpy (rmp->out_addr, &m->out_addr, 4);
+ rmp->out_plen = m->out_plen;
+ rmp->sharing_ratio = htonl (m->sharing_ratio);
+ rmp->ports_per_host = htons (m->ports_per_host);
+ rmp->ses_num = htonl (m->ses_num);
+ rmp->context = context;
+
+ vl_msg_api_send_shmem (q, (u8 *) & rmp);
+}
+
+static void
+vl_api_snat_det_map_dump_t_handler
+(vl_api_snat_det_map_dump_t * mp)
+{
+ unix_shared_memory_queue_t *q;
+ snat_main_t * sm = &snat_main;
+ snat_det_map_t * m;
+
+ q = vl_api_client_index_to_input_queue (mp->client_index);
+ if (q == 0)
+ return;
+
+ vec_foreach(m, sm->det_maps)
+ sent_snat_det_map_details(m, q, mp->context);
+}
+
+static void * vl_api_snat_det_map_dump_t_print
+(vl_api_snat_det_map_dump_t *mp, void * handle)
+{
+ u8 * s;
+
+ s = format (0, "SCRIPT: snat_det_map_dump ");
+
+ FINISH;
+}
+
/* List of message types that this plugin understands */
#define foreach_snat_plugin_api_msg \
_(SNAT_ADD_ADDRESS_RANGE, snat_add_address_range) \
@@ -1722,7 +1771,8 @@ _(SNAT_USER_DUMP, snat_user_dump) \
_(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_REVERSE, snat_det_reverse) \
+_(SNAT_DET_MAP_DUMP, snat_det_map_dump)
/* Set up the API message handling tables */
static clib_error_t *
diff --git a/src/plugins/snat/snat_test.c b/src/plugins/snat/snat_test.c
index 39db45cd8be..e26a3958e3b 100644
--- a/src/plugins/snat/snat_test.c
+++ b/src/plugins/snat/snat_test.c
@@ -110,7 +110,8 @@ _(SNAT_USER_DETAILS, snat_user_details) \
_(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_REVERSE_REPLY, snat_det_reverse_reply) \
+_(SNAT_DET_MAP_DETAILS, snat_det_map_details)
static int api_snat_add_address_range (vat_main_t * vam)
{
@@ -854,6 +855,44 @@ static int api_snat_det_reverse (vat_main_t * vam)
return ret;
}
+static void vl_api_snat_det_map_details_t_handler
+ (vl_api_snat_det_map_details_t *mp)
+{
+ snat_test_main_t * sm = &snat_test_main;
+ vat_main_t *vam = sm->vat_main;
+
+ fformat (vam->ofp, "Deterministic S-NAT mapping in %U/%d out %U/%d "
+ "ports per host %d sharing ratio %d "
+ "number of sessions %d",
+ format_ip4_address, mp->in_addr, mp->in_plen,
+ format_ip4_address, mp->out_addr, mp->out_plen,
+ ntohs(mp->ports_per_host), ntohl(mp->sharing_ratio),
+ ntohl(mp->ses_num));
+}
+
+static int api_snat_det_map_dump(vat_main_t * vam)
+{
+ vl_api_snat_det_map_dump_t * mp;
+ vl_api_snat_control_ping_t *mp_ping;
+ int ret;
+
+ if (vam->json_output)
+ {
+ clib_warning ("JSON output not supported for snat_det_map_dump");
+ return -99;
+ }
+
+ M(SNAT_DET_MAP_DUMP, mp);
+ S(mp);
+
+ /* Use a control ping for synchronization */
+ M(SNAT_CONTROL_PING, mp_ping);
+ S(mp_ping);
+
+ W (ret);
+ return ret;
+}
+
/*
* List of messages that the api test plugin sends,
* and that the data plane plugin processes
@@ -882,7 +921,8 @@ _(snat_user_session_dump, "ip_address <ip> vrf_id <table-id>") \
_(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_reverse, "<out_addr> <out_port>") \
+_(snat_det_map_dump, "")
static void
snat_vat_api_hookup (vat_main_t *vam)
diff --git a/test/test_snat.py b/test/test_snat.py
index 78919a026ed..7084f00208f 100644
--- a/test/test_snat.py
+++ b/test/test_snat.py
@@ -1322,11 +1322,31 @@ class TestDeterministicNAT(VppTestCase):
rep2 = self.vapi.snat_det_reverse(out_addr_n, rep1.out_port_hi)
self.assertEqual(rep2.in_addr[:4], in_addr_t_n)
+ deterministic_mappings = self.vapi.snat_det_map_dump()
+ self.assertEqual(len(deterministic_mappings), 1)
+ dsm = deterministic_mappings[0]
+ self.assertEqual(in_addr_n, dsm.in_addr[:4])
+ self.assertEqual(in_plen, dsm.in_plen)
+ self.assertEqual(out_addr_n, dsm.out_addr[:4])
+ self.assertEqual(out_plen, dsm.out_plen)
+
+ def clear_snat(self):
+ """
+ Clear SNAT configuration.
+ """
+ deterministic_mappings = self.vapi.snat_det_map_dump()
+ for dsm in deterministic_mappings:
+ self.vapi.snat_add_det_map(dsm.in_addr,
+ dsm.in_plen,
+ dsm.out_addr,
+ dsm.out_plen,
+ is_add=0)
+
def tearDown(self):
super(TestDeterministicNAT, self).tearDown()
if not self.vpp_dead:
self.logger.info(self.vapi.cli("show snat detail"))
-
+ self.clear_snat()
if __name__ == '__main__':
unittest.main(testRunner=VppTestRunner)
diff --git a/test/vpp_papi_provider.py b/test/vpp_papi_provider.py
index 3d6af8afd55..0062b72b62e 100644
--- a/test/vpp_papi_provider.py
+++ b/test/vpp_papi_provider.py
@@ -1179,6 +1179,13 @@ class VppPapiProvider(object):
{'out_addr': out_addr,
'out_port': out_port})
+ def snat_det_map_dump(self):
+ """Dump S-NAT deterministic mappings
+
+ :return: Dictionary of S-NAT deterministic mappings
+ """
+ return self.api(self.papi.snat_det_map_dump, {})
+
def control_ping(self):
self.api(self.papi.control_ping)