summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/plugins/snat/snat.api2
-rw-r--r--src/plugins/snat/snat.c63
-rw-r--r--src/plugins/snat/snat_test.c20
-rw-r--r--test/test_snat.py7
4 files changed, 86 insertions, 6 deletions
diff --git a/src/plugins/snat/snat.api b/src/plugins/snat/snat.api
index decbacf5c2f..c429f05f14b 100644
--- a/src/plugins/snat/snat.api
+++ b/src/plugins/snat/snat.api
@@ -167,6 +167,7 @@ define snat_static_mapping_dump {
@param protocol - IP protocol
@param local_port - local port number
@param external_port - external port number
+ @param external_sw_if_index - external interface
@param vfr_id - VRF ID
*/
define snat_static_mapping_details {
@@ -178,6 +179,7 @@ define snat_static_mapping_details {
u8 protocol;
u16 local_port;
u16 external_port;
+ u32 external_sw_if_index;
u32 vrf_id;
};
diff --git a/src/plugins/snat/snat.c b/src/plugins/snat/snat.c
index ba6463c889e..73854a7ab3d 100644
--- a/src/plugins/snat/snat.c
+++ b/src/plugins/snat/snat.c
@@ -1084,6 +1084,30 @@ send_snat_static_mapping_details
clib_memcpy (rmp->external_ip_address, &(m->external_addr), 4);
rmp->local_port = htons (m->local_port);
rmp->external_port = htons (m->external_port);
+ rmp->external_sw_if_index = ~0;
+ rmp->vrf_id = htonl (m->vrf_id);
+ rmp->protocol = snat_proto_to_ip_proto (m->proto);
+ rmp->context = context;
+
+ vl_msg_api_send_shmem (q, (u8 *) & rmp);
+}
+
+static void
+send_snat_static_map_resolve_details
+(snat_static_map_resolve_t * m, unix_shared_memory_queue_t * q, u32 context)
+{
+ vl_api_snat_static_mapping_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_STATIC_MAPPING_DETAILS+sm->msg_id_base);
+ rmp->is_ip4 = 1;
+ rmp->addr_only = m->addr_only;
+ clib_memcpy (rmp->local_ip_address, &(m->l_addr), 4);
+ rmp->local_port = htons (m->l_port);
+ rmp->external_port = htons (m->e_port);
+ rmp->external_sw_if_index = htonl (m->sw_if_index);
rmp->vrf_id = htonl (m->vrf_id);
rmp->protocol = snat_proto_to_ip_proto (m->proto);
rmp->context = context;
@@ -1098,6 +1122,8 @@ vl_api_snat_static_mapping_dump_t_handler
unix_shared_memory_queue_t *q;
snat_main_t * sm = &snat_main;
snat_static_mapping_t * m;
+ snat_static_map_resolve_t *rp;
+ int j;
q = vl_api_client_index_to_input_queue (mp->client_index);
if (q == 0)
@@ -1107,6 +1133,12 @@ vl_api_snat_static_mapping_dump_t_handler
({
send_snat_static_mapping_details (m, q, mp->context);
}));
+
+ for (j = 0; j < vec_len (sm->to_resolve); j++)
+ {
+ rp = sm->to_resolve + j;
+ send_snat_static_map_resolve_details (rp, q, mp->context);
+ }
}
static void *vl_api_snat_static_mapping_dump_t_print
@@ -2248,6 +2280,28 @@ u8 * format_snat_static_mapping (u8 * s, va_list * args)
return s;
}
+u8 * format_snat_static_map_to_resolve (u8 * s, va_list * args)
+{
+ snat_static_map_resolve_t *m = va_arg (*args, snat_static_map_resolve_t *);
+ vnet_main_t *vnm = vnet_get_main();
+
+ if (m->addr_only)
+ s = format (s, "local %U external %U vrf %d",
+ format_ip4_address, &m->l_addr,
+ format_vnet_sw_interface_name, vnm,
+ vnet_get_sw_interface (vnm, m->sw_if_index),
+ m->vrf_id);
+ else
+ s = format (s, "%U local %U:%d external %U:%d vrf %d",
+ format_snat_protocol, m->proto,
+ format_ip4_address, &m->l_addr, m->l_port,
+ format_vnet_sw_interface_name, vnm,
+ vnet_get_sw_interface (vnm, m->sw_if_index), m->e_port,
+ m->vrf_id);
+
+ return s;
+}
+
static clib_error_t *
show_snat_command_fn (vlib_main_t * vm,
unformat_input_t * input,
@@ -2263,6 +2317,7 @@ show_snat_command_fn (vlib_main_t * vm,
snat_main_per_thread_data_t *tsm;
u32 users_num = 0, sessions_num = 0, *worker, *sw_if_index;
uword j = 0;
+ snat_static_map_resolve_t *rp;
if (unformat (input, "detail"))
verbose = 1;
@@ -2383,13 +2438,19 @@ show_snat_command_fn (vlib_main_t * vm,
}));
}
- if (pool_elts (sm->static_mappings))
+ if (pool_elts (sm->static_mappings) || vec_len (sm->to_resolve))
{
vlib_cli_output (vm, "static mappings:");
pool_foreach (m, sm->static_mappings,
({
vlib_cli_output (vm, "%U", format_snat_static_mapping, m);
}));
+ for (j = 0; j < vec_len (sm->to_resolve); j++)
+ {
+ rp = sm->to_resolve + j;
+ vlib_cli_output (vm, "%U", format_snat_static_map_to_resolve,
+ rp);
+ }
}
}
}
diff --git a/src/plugins/snat/snat_test.c b/src/plugins/snat/snat_test.c
index a8cb8cc0eb5..136c1c49e78 100644
--- a/src/plugins/snat/snat_test.c
+++ b/src/plugins/snat/snat_test.c
@@ -310,12 +310,26 @@ static void vl_api_snat_static_mapping_details_t_handler
snat_test_main_t * sm = &snat_test_main;
vat_main_t *vam = sm->vat_main;
- if (mp->addr_only)
+ if (mp->addr_only && mp->external_sw_if_index != ~0)
+ fformat (vam->ofp, "%15U%6s%15d%6s%11d%6d\n",
+ format_ip4_address, &mp->local_ip_address, "",
+ ntohl (mp->external_sw_if_index), "",
+ ntohl (mp->vrf_id),
+ mp->protocol);
+ else if (mp->addr_only && mp->external_sw_if_index == ~0)
fformat (vam->ofp, "%15U%6s%15U%6s%11d%6d\n",
format_ip4_address, &mp->local_ip_address, "",
format_ip4_address, &mp->external_ip_address, "",
ntohl (mp->vrf_id),
mp->protocol);
+ else if (!mp->addr_only && mp->external_sw_if_index != ~0)
+ fformat (vam->ofp, "%15U%6d%15d%6d%11d%6d\n",
+ format_ip4_address, &mp->local_ip_address,
+ ntohs (mp->local_port),
+ ntohl (mp->external_sw_if_index),
+ ntohs (mp->external_port),
+ ntohl (mp->vrf_id),
+ mp->protocol);
else
fformat (vam->ofp, "%15U%6d%15U%6d%11d%6d\n",
format_ip4_address, &mp->local_ip_address,
@@ -340,8 +354,8 @@ static int api_snat_static_mapping_dump(vat_main_t * vam)
}
fformat (vam->ofp, "%21s%21s\n", "local", "external");
- fformat (vam->ofp, "%15s%6s%15s%6s%11s%6s\n", "address", "port", "address",
- "port", "vrf", "proto");
+ fformat (vam->ofp, "%15s%6s%15s%6s%11s%6s\n", "address", "port",
+ "address/if_idx", "port", "vrf", "proto");
M(SNAT_STATIC_MAPPING_DUMP, mp);
S(mp);
diff --git a/test/test_snat.py b/test/test_snat.py
index 967d4b37c71..9d2070a078c 100644
--- a/test/test_snat.py
+++ b/test/test_snat.py
@@ -790,9 +790,11 @@ class TestSNAT(VppTestCase):
self.snat_add_static_mapping('1.2.3.4',
external_sw_if_index=self.pg7.sw_if_index)
- # no static mappings
+ # static mappings with external interface
static_mappings = self.vapi.snat_static_mapping_dump()
- self.assertEqual(0, len(static_mappings))
+ self.assertEqual(1, len(static_mappings))
+ self.assertEqual(self.pg7.sw_if_index,
+ static_mappings[0].external_sw_if_index)
# configure interface address and check static mappings
self.pg7.config_ip4()
@@ -800,6 +802,7 @@ class TestSNAT(VppTestCase):
self.assertEqual(1, len(static_mappings))
self.assertEqual(static_mappings[0].external_ip_address[0:4],
self.pg7.local_ip4n)
+ self.assertEqual(0xFFFFFFFF, static_mappings[0].external_sw_if_index)
# remove interface address and check static mappings
self.pg7.unconfig_ip4()