summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/plugins/nat/nat.h1
-rw-r--r--src/plugins/nat/nat_api.c64
-rw-r--r--src/plugins/nat/test/test_nat.py105
3 files changed, 170 insertions, 0 deletions
diff --git a/src/plugins/nat/nat.h b/src/plugins/nat/nat.h
index d0882e07bab..8ec0c62a800 100644
--- a/src/plugins/nat/nat.h
+++ b/src/plugins/nat/nat.h
@@ -1428,6 +1428,7 @@ typedef struct
u16 src_port, dst_port;
} tcp_udp_header_t;
+u8 *format_user_kvp (u8 * s, va_list * args);
#endif /* __included_nat_h__ */
/*
* fd.io coding-style-patch-verification: ON
diff --git a/src/plugins/nat/nat_api.c b/src/plugins/nat/nat_api.c
index 37af77d11c1..201c9d4730d 100644
--- a/src/plugins/nat/nat_api.c
+++ b/src/plugins/nat/nat_api.c
@@ -1586,6 +1586,62 @@ send_nat44_user_details (snat_user_t * u, vl_api_registration_t * reg,
}
static void
+nat_ed_user_create_helper (snat_main_per_thread_data_t * tsm,
+ snat_session_t * s)
+{
+ snat_user_key_t k;
+ k.addr = s->in2out.addr;
+ k.fib_index = s->in2out.fib_index;
+ clib_bihash_kv_8_8_t key, value;
+ key.key = k.as_u64;
+ snat_user_t *u;
+ if (clib_bihash_search_8_8 (&tsm->user_hash, &key, &value))
+ {
+ pool_get (tsm->users, u);
+ u->addr = k.addr;
+ u->fib_index = k.fib_index;
+ u->nsessions = 0;
+ u->nstaticsessions = 0;
+ key.value = u - tsm->users;
+ clib_bihash_add_del_8_8 (&tsm->user_hash, &key, 1);
+ }
+ else
+ {
+ u = pool_elt_at_index (tsm->users, value.value);
+ }
+ if (snat_is_session_static (s))
+ {
+ ++u->nstaticsessions;
+ }
+ else
+ {
+ ++u->nsessions;
+ }
+}
+
+static void
+nat_ed_users_create (snat_main_per_thread_data_t * tsm)
+{
+ snat_session_t *s;
+ /* *INDENT-OFF* */
+ pool_foreach (s, tsm->sessions, { nat_ed_user_create_helper (tsm, s); });
+ /* *INDENT-ON* */
+}
+
+static void
+nat_ed_users_destroy (snat_main_per_thread_data_t * tsm)
+{
+ snat_user_t *u;
+ /* *INDENT-OFF* */
+ pool_flush (u, tsm->users, { });
+ /* *INDENT-ON* */
+ clib_bihash_free_8_8 (&tsm->user_hash);
+ clib_bihash_init_8_8 (&tsm->user_hash, "users", snat_main.user_buckets,
+ snat_main.user_memory_size);
+ clib_bihash_set_kvp_format_fn_8_8 (&tsm->user_hash, format_user_kvp);
+}
+
+static void
vl_api_nat44_user_dump_t_handler (vl_api_nat44_user_dump_t * mp)
{
vl_api_registration_t *reg;
@@ -1603,10 +1659,18 @@ vl_api_nat44_user_dump_t_handler (vl_api_nat44_user_dump_t * mp)
/* *INDENT-OFF* */
vec_foreach (tsm, sm->per_thread_data)
{
+ if (sm->endpoint_dependent)
+ {
+ nat_ed_users_create (tsm);
+ }
pool_foreach (u, tsm->users,
({
send_nat44_user_details (u, reg, mp->context);
}));
+ if (sm->endpoint_dependent)
+ {
+ nat_ed_users_destroy (tsm);
+ }
}
/* *INDENT-ON* */
}
diff --git a/src/plugins/nat/test/test_nat.py b/src/plugins/nat/test/test_nat.py
index 1b3c7e7a8b1..c2f5f51a054 100644
--- a/src/plugins/nat/test/test_nat.py
+++ b/src/plugins/nat/test/test_nat.py
@@ -7090,6 +7090,111 @@ class TestNAT44EndpointDependent(MethodHolder):
capture = self.pg2.get_capture(1)
self.verify_syslog_sess(capture[0][Raw].load, False)
+ def test_ed_users_dump(self):
+ """ API test - nat44_user_dump """
+ flags = self.config_flags.NAT_IS_INSIDE
+ self.vapi.nat44_interface_add_del_feature(
+ sw_if_index=self.pg0.sw_if_index,
+ flags=flags, is_add=1)
+ self.vapi.nat44_interface_add_del_feature(
+ sw_if_index=self.pg1.sw_if_index,
+ is_add=1)
+ self.vapi.nat44_forwarding_enable_disable(enable=1)
+
+ real_ip = self.pg0.remote_ip4
+ alias_ip = self.nat_addr
+ flags = self.config_flags.NAT_IS_ADDR_ONLY
+ self.vapi.nat44_add_del_static_mapping(is_add=1,
+ local_ip_address=real_ip,
+ external_ip_address=alias_ip,
+ external_sw_if_index=0xFFFFFFFF,
+ flags=flags)
+
+ users = self.vapi.nat44_user_dump()
+ self.assertEqual(len(users), 0)
+ try:
+ # in2out - static mapping match
+
+ pkts = self.create_stream_out(self.pg1)
+ self.pg1.add_stream(pkts)
+ self.pg_enable_capture(self.pg_interfaces)
+ self.pg_start()
+ capture = self.pg0.get_capture(len(pkts))
+ self.verify_capture_in(capture, self.pg0)
+
+ pkts = self.create_stream_in(self.pg0, self.pg1)
+ self.pg0.add_stream(pkts)
+ self.pg_enable_capture(self.pg_interfaces)
+ self.pg_start()
+ capture = self.pg1.get_capture(len(pkts))
+ self.verify_capture_out(capture, same_port=True)
+
+ users = self.vapi.nat44_user_dump()
+ self.assertEqual(len(users), 1)
+ static_user = users[0]
+ self.assertEqual(static_user.nstaticsessions, 3)
+ self.assertEqual(static_user.nsessions, 0)
+
+ # in2out - no static mapping match
+
+ host0 = self.pg0.remote_hosts[0]
+ self.pg0.remote_hosts[0] = self.pg0.remote_hosts[1]
+ try:
+ pkts = self.create_stream_out(self.pg1,
+ dst_ip=self.pg0.remote_ip4,
+ use_inside_ports=True)
+ self.pg1.add_stream(pkts)
+ self.pg_enable_capture(self.pg_interfaces)
+ self.pg_start()
+ capture = self.pg0.get_capture(len(pkts))
+ self.verify_capture_in(capture, self.pg0)
+
+ pkts = self.create_stream_in(self.pg0, self.pg1)
+ self.pg0.add_stream(pkts)
+ self.pg_enable_capture(self.pg_interfaces)
+ self.pg_start()
+ capture = self.pg1.get_capture(len(pkts))
+ self.verify_capture_out(capture, nat_ip=self.pg0.remote_ip4,
+ same_port=True)
+ finally:
+ self.pg0.remote_hosts[0] = host0
+
+ users = self.vapi.nat44_user_dump()
+ self.assertEqual(len(users), 2)
+ if str(users[0].ip_address) == self.pg0.remote_hosts[0].ip4:
+ non_static_user = users[1]
+ static_user = users[0]
+ else:
+ non_static_user = users[0]
+ static_user = users[1]
+ self.assertEqual(static_user.nstaticsessions, 3)
+ self.assertEqual(static_user.nsessions, 0)
+ self.assertEqual(non_static_user.nstaticsessions, 0)
+ self.assertEqual(non_static_user.nsessions, 3)
+
+ users = self.vapi.nat44_user_dump()
+ self.assertEqual(len(users), 2)
+ if str(users[0].ip_address) == self.pg0.remote_hosts[0].ip4:
+ non_static_user = users[1]
+ static_user = users[0]
+ else:
+ non_static_user = users[0]
+ static_user = users[1]
+ self.assertEqual(static_user.nstaticsessions, 3)
+ self.assertEqual(static_user.nsessions, 0)
+ self.assertEqual(non_static_user.nstaticsessions, 0)
+ self.assertEqual(non_static_user.nsessions, 3)
+
+ finally:
+ self.vapi.nat44_forwarding_enable_disable(enable=0)
+ flags = self.config_flags.NAT_IS_ADDR_ONLY
+ self.vapi.nat44_add_del_static_mapping(
+ is_add=0,
+ local_ip_address=real_ip,
+ external_ip_address=alias_ip,
+ external_sw_if_index=0xFFFFFFFF,
+ flags=flags)
+
def tearDown(self):
super(TestNAT44EndpointDependent, self).tearDown()
if not self.vpp_dead: