From fd0d50879f475a1b15cedb4ab49059a02c45ccfd Mon Sep 17 00:00:00 2001 From: Matus Fabian Date: Tue, 18 Dec 2018 01:08:51 -0800 Subject: [PATCH] NAT: total users and sessions gauges (VPP-1484) Change-Id: I41a82e21571d5c64d01af72cd88c3983afac26ed Signed-off-by: Matus Fabian --- src/plugins/nat/dslite.c | 10 ++++++++ src/plugins/nat/dslite.h | 4 +++ src/plugins/nat/dslite_in2out.c | 8 ++++++ src/plugins/nat/nat.c | 18 ++++++++++++++ src/plugins/nat/nat.h | 4 +++ src/plugins/nat/nat64.c | 55 ++++++++++++++++++++++++++++++++++------- src/plugins/nat/nat64.h | 4 +++ src/plugins/nat/nat64_in2out.c | 35 ++++++++++++++++++++++++++ src/plugins/nat/nat64_out2in.c | 21 ++++++++++++++++ src/plugins/nat/nat_inlines.h | 4 +++ test/test_nat.py | 33 +++++++++++++++++++++++++ 11 files changed, 187 insertions(+), 9 deletions(-) diff --git a/src/plugins/nat/dslite.c b/src/plugins/nat/dslite.c index 12c813200ec..883acecb052 100644 --- a/src/plugins/nat/dslite.c +++ b/src/plugins/nat/dslite.c @@ -67,6 +67,16 @@ dslite_init (vlib_main_t * vm) dm->is_ce = 0; + /* Init counters */ + dm->total_b4s.name = "total-b4s"; + dm->total_b4s.stat_segment_name = "/dslite/total-b4s"; + vlib_validate_simple_counter (&dm->total_b4s, 0); + vlib_zero_simple_counter (&dm->total_b4s, 0); + dm->total_sessions.name = "total-sessions"; + dm->total_sessions.stat_segment_name = "/dslite/total-sessions"; + vlib_validate_simple_counter (&dm->total_sessions, 0); + vlib_zero_simple_counter (&dm->total_sessions, 0); + dslite_dpo_module_init (); } diff --git a/src/plugins/nat/dslite.h b/src/plugins/nat/dslite.h index 73902e3a077..066bfcf1379 100644 --- a/src/plugins/nat/dslite.h +++ b/src/plugins/nat/dslite.h @@ -87,6 +87,10 @@ typedef struct u32 first_worker_index; u16 port_per_thread; + /* counters/gauges */ + vlib_simple_counter_main_t total_b4s; + vlib_simple_counter_main_t total_sessions; + /* If set then the DSLite component behaves as CPE/B4 * otherwise it behaves as AFTR */ u8 is_ce; diff --git a/src/plugins/nat/dslite_in2out.c b/src/plugins/nat/dslite_in2out.c index 5c1de19b8b2..cbb5d987d01 100644 --- a/src/plugins/nat/dslite_in2out.c +++ b/src/plugins/nat/dslite_in2out.c @@ -71,6 +71,10 @@ slow_path (dslite_main_t * dm, dslite_session_key_t * in2out_key, b4_index = b4_kv.value = b4 - dm->per_thread_data[thread_index].b4s; clib_bihash_add_del_16_8 (&dm->per_thread_data[thread_index].b4_hash, &b4_kv, 1); + + vlib_set_simple_counter (&dm->total_b4s, thread_index, 0, + pool_elts (dm-> + per_thread_data[thread_index].b4s)); } else { @@ -139,6 +143,10 @@ slow_path (dslite_main_t * dm, dslite_session_key_t * in2out_key, clib_dlist_addtail (dm->per_thread_data[thread_index].list_pool, s->per_b4_list_head_index, elt - dm->per_thread_data[thread_index].list_pool); + + vlib_set_simple_counter (&dm->total_sessions, thread_index, 0, + pool_elts (dm->per_thread_data + [thread_index].sessions)); } s->in2out = *in2out_key; diff --git a/src/plugins/nat/nat.c b/src/plugins/nat/nat.c index 2e1aa770581..c2c812d114b 100755 --- a/src/plugins/nat/nat.c +++ b/src/plugins/nat/nat.c @@ -322,6 +322,9 @@ nat_user_get_or_create (snat_main_t * sm, ip4_address_t * addr, u32 fib_index, /* add user */ if (clib_bihash_add_del_8_8 (&tsm->user_hash, &kv, 1)) nat_log_warn ("user_hash keay add failed"); + + vlib_set_simple_counter (&sm->total_users, thread_index, 0, + pool_elts (tsm->users)); } else { @@ -397,6 +400,8 @@ nat_session_alloc_or_recycle (snat_main_t * sm, snat_user_t * u, per_user_translation_list_elt - tsm->list_pool); s->user_index = u - tsm->users; + vlib_set_simple_counter (&sm->total_sessions, thread_index, 0, + pool_elts (tsm->sessions)); } return s; @@ -471,6 +476,9 @@ nat_ed_session_alloc (snat_main_t * sm, snat_user_t * u, u32 thread_index, s->per_user_list_head_index, per_user_translation_list_elt - tsm->list_pool); } + + vlib_set_simple_counter (&sm->total_sessions, thread_index, 0, + pool_elts (tsm->sessions)); } return s; @@ -2207,6 +2215,16 @@ snat_init (vlib_main_t * vm) nat_dpo_module_init (); + /* Init counters */ + sm->total_users.name = "total-users"; + sm->total_users.stat_segment_name = "/nat44/total-users"; + vlib_validate_simple_counter (&sm->total_users, 0); + vlib_zero_simple_counter (&sm->total_users, 0); + sm->total_sessions.name = "total-sessions"; + sm->total_sessions.stat_segment_name = "/nat44/total-sessions"; + vlib_validate_simple_counter (&sm->total_sessions, 0); + vlib_zero_simple_counter (&sm->total_sessions, 0); + /* Init IPFIX logging */ snat_ipfix_logging_init (vm); diff --git a/src/plugins/nat/nat.h b/src/plugins/nat/nat.h index e851e2f98f7..06d0decc9ab 100644 --- a/src/plugins/nat/nat.h +++ b/src/plugins/nat/nat.h @@ -532,6 +532,10 @@ typedef struct snat_main_s u16 mss_clamping; u16 mss_value_net; + /* counters/gauges */ + vlib_simple_counter_main_t total_users; + vlib_simple_counter_main_t total_sessions; + /* API message ID base */ u16 msg_id_base; diff --git a/src/plugins/nat/nat64.c b/src/plugins/nat/nat64.c index 8bcca2b33d3..4dbfb05c78c 100644 --- a/src/plugins/nat/nat64.c +++ b/src/plugins/nat/nat64.c @@ -240,6 +240,16 @@ nat64_init (vlib_main_t * vm) vec_add1 (im->add_del_interface_address_callbacks, cb4); nm->ip4_main = im; + /* Init counters */ + nm->total_bibs.name = "total-bibs"; + nm->total_bibs.stat_segment_name = "/nat64/total-bibs"; + vlib_validate_simple_counter (&nm->total_bibs, 0); + vlib_zero_simple_counter (&nm->total_bibs, 0); + nm->total_sessions.name = "total-sessions"; + nm->total_sessions.stat_segment_name = "/nat64/total-sessions"; + vlib_validate_simple_counter (&nm->total_sessions, 0); + vlib_zero_simple_counter (&nm->total_sessions, 0); + return 0; } @@ -319,7 +329,13 @@ nat64_add_del_pool_addr (ip4_address_t * addr, u32 vrf_id, u8 is_add) /* Delete sessions using address */ /* *INDENT-OFF* */ vec_foreach (db, nm->db) - nat64_db_free_out_addr (db, &a->addr); + { + nat64_db_free_out_addr (db, &a->addr); + vlib_set_simple_counter (&nm->total_bibs, db - nm->db, 0, + db->bib.bib_entries_num); + vlib_set_simple_counter (&nm->total_sessions, db - nm->db, 0, + db->st.st_entries_num); + } #define _(N, id, n, s) \ clib_bitmap_free (a->busy_##n##_port_bitmap); foreach_snat_protocol @@ -584,12 +600,16 @@ nat64_static_bib_worker_fn (vlib_main_t * vm, vlib_node_runtime_t * rt, continue; if (static_bib->is_add) - (void) nat64_db_bib_entry_create (db, &static_bib->in_addr, - &static_bib->out_addr, - static_bib->in_port, - static_bib->out_port, - static_bib->fib_index, - static_bib->proto, 1); + { + (void) nat64_db_bib_entry_create (db, &static_bib->in_addr, + &static_bib->out_addr, + static_bib->in_port, + static_bib->out_port, + static_bib->fib_index, + static_bib->proto, 1); + vlib_set_simple_counter (&nm->total_bibs, thread_index, 0, + db->bib.bib_entries_num); + } else { addr.as_u64[0] = static_bib->in_addr.as_u64[0]; @@ -598,7 +618,13 @@ nat64_static_bib_worker_fn (vlib_main_t * vm, vlib_node_runtime_t * rt, static_bib->proto, static_bib->fib_index, 1); if (bibe) - nat64_db_bib_entry_free (db, bibe); + { + nat64_db_bib_entry_free (db, bibe); + vlib_set_simple_counter (&nm->total_bibs, thread_index, 0, + db->bib.bib_entries_num); + vlib_set_simple_counter (&nm->total_sessions, thread_index, 0, + db->st.st_entries_num); + } } static_bib->done = 1; @@ -703,6 +729,9 @@ nat64_add_del_static_bib_entry (ip6_address_t * in_addr, fib_index, proto, 1); if (!bibe) return VNET_API_ERROR_UNSPECIFIED; + + vlib_set_simple_counter (&nm->total_bibs, thread_index, 0, + db->bib.bib_entries_num); } } else @@ -711,7 +740,11 @@ nat64_add_del_static_bib_entry (ip6_address_t * in_addr, return VNET_API_ERROR_NO_SUCH_ENTRY; if (!nm->sm->num_workers) - nat64_db_bib_entry_free (db, bibe); + { + nat64_db_bib_entry_free (db, bibe); + vlib_set_simple_counter (&nm->total_bibs, thread_index, 0, + db->bib.bib_entries_num); + } } if (nm->sm->num_workers) @@ -1143,6 +1176,10 @@ nat64_expire_worker_walk_fn (vlib_main_t * vm, vlib_node_runtime_t * rt, u32 now = (u32) vlib_time_now (vm); nad64_db_st_free_expired (db, now); + vlib_set_simple_counter (&nm->total_bibs, thread_index, 0, + db->bib.bib_entries_num); + vlib_set_simple_counter (&nm->total_sessions, thread_index, 0, + db->st.st_entries_num); return 0; } diff --git a/src/plugins/nat/nat64.h b/src/plugins/nat/nat64.h index d365e12b2f7..0a60571a069 100644 --- a/src/plugins/nat/nat64.h +++ b/src/plugins/nat/nat64.h @@ -108,6 +108,10 @@ typedef struct /* The process node which orcherstrates the cleanup */ u32 nat64_expire_walk_node_index; + /* counters/gauges */ + vlib_simple_counter_main_t total_bibs; + vlib_simple_counter_main_t total_sessions; + ip4_main_t *ip4_main; snat_main_t *sm; } nat64_main_t; diff --git a/src/plugins/nat/nat64_in2out.c b/src/plugins/nat/nat64_in2out.c index 372931c7e4b..660df093bf9 100644 --- a/src/plugins/nat/nat64_in2out.c +++ b/src/plugins/nat/nat64_in2out.c @@ -221,6 +221,9 @@ nat64_in2out_tcp_udp_set_cb (ip6_header_t * ip6, ip4_header_t * ip4, sport, out_port, fib_index, proto, 0); if (!bibe) return -1; + + vlib_set_simple_counter (&nm->total_bibs, ctx->thread_index, 0, + db->bib.bib_entries_num); } nat64_extract_ip4 (&ip6->dst_address, &daddr.ip4, fib_index); @@ -229,6 +232,9 @@ nat64_in2out_tcp_udp_set_cb (ip6_header_t * ip6, ip4_header_t * ip4, &daddr.ip4, dport); if (!ste) return -1; + + vlib_set_simple_counter (&nm->total_sessions, ctx->thread_index, 0, + db->st.st_entries_num); } ip4->src_address.as_u32 = bibe->out_addr.as_u32; @@ -312,6 +318,9 @@ nat64_in2out_icmp_set_cb (ip6_header_t * ip6, ip4_header_t * ip4, void *arg) fib_index, IP_PROTOCOL_ICMP, 0); if (!bibe) return -1; + + vlib_set_simple_counter (&nm->total_bibs, ctx->thread_index, 0, + db->bib.bib_entries_num); } nat64_extract_ip4 (&ip6->dst_address, &daddr.ip4, fib_index); @@ -320,6 +329,9 @@ nat64_in2out_icmp_set_cb (ip6_header_t * ip6, ip4_header_t * ip4, void *arg) &daddr.ip4, 0); if (!ste) return -1; + + vlib_set_simple_counter (&nm->total_sessions, ctx->thread_index, 0, + db->st.st_entries_num); } nat64_session_reset_timeout (ste, ctx->vm); @@ -549,6 +561,9 @@ nat64_in2out_unk_proto_set_cb (ip6_header_t * ip6, ip4_header_t * ip4, 0); if (!bibe) return -1; + + vlib_set_simple_counter (&nm->total_bibs, s_ctx->thread_index, 0, + db->bib.bib_entries_num); } nat64_extract_ip4 (&ip6->dst_address, &daddr.ip4, fib_index); @@ -556,6 +571,9 @@ nat64_in2out_unk_proto_set_cb (ip6_header_t * ip6, ip4_header_t * ip4, nat64_db_st_entry_create (db, bibe, &ip6->dst_address, &daddr.ip4, 0); if (!ste) return -1; + + vlib_set_simple_counter (&nm->total_sessions, s_ctx->thread_index, 0, + db->st.st_entries_num); } nat64_session_reset_timeout (ste, s_ctx->vm); @@ -635,6 +653,9 @@ nat64_in2out_tcp_udp_hairpinning (vlib_main_t * vm, vlib_buffer_t * b, sport, out_port, fib_index, proto, 0); if (!bibe) return -1; + + vlib_set_simple_counter (&nm->total_bibs, thread_index, 0, + db->bib.bib_entries_num); } nat64_extract_ip4 (&ip6->dst_address, &daddr.ip4, fib_index); @@ -643,6 +664,9 @@ nat64_in2out_tcp_udp_hairpinning (vlib_main_t * vm, vlib_buffer_t * b, &daddr.ip4, dport); if (!ste) return -1; + + vlib_set_simple_counter (&nm->total_sessions, thread_index, 0, + db->st.st_entries_num); } if (proto == IP_PROTOCOL_TCP) @@ -890,6 +914,9 @@ nat64_in2out_unk_proto_hairpinning (vlib_main_t * vm, vlib_buffer_t * b, 0); if (!bibe) return -1; + + vlib_set_simple_counter (&nm->total_bibs, thread_index, 0, + db->bib.bib_entries_num); } nat64_extract_ip4 (&ip6->dst_address, &daddr.ip4, fib_index); @@ -897,6 +924,9 @@ nat64_in2out_unk_proto_hairpinning (vlib_main_t * vm, vlib_buffer_t * b, nat64_db_st_entry_create (db, bibe, &ip6->dst_address, &daddr.ip4, 0); if (!ste) return -1; + + vlib_set_simple_counter (&nm->total_sessions, thread_index, 0, + db->st.st_entries_num); } nat64_session_reset_timeout (ste, vm); @@ -1510,6 +1540,8 @@ nat64_in2out_reass_node_fn (vlib_main_t * vm, node->errors[NAT64_IN2OUT_ERROR_NO_TRANSLATION]; goto trace0; } + vlib_set_simple_counter (&nm->total_bibs, thread_index, + 0, db->bib.bib_entries_num); } nat64_extract_ip4 (&ip60->dst_address, &daddr0.ip4, fib_index0); @@ -1524,6 +1556,9 @@ nat64_in2out_reass_node_fn (vlib_main_t * vm, node->errors[NAT64_IN2OUT_ERROR_NO_TRANSLATION]; goto trace0; } + + vlib_set_simple_counter (&nm->total_sessions, thread_index, + 0, db->st.st_entries_num); } reass0->sess_index = nat64_db_st_entry_get_index (db, ste0); diff --git a/src/plugins/nat/nat64_out2in.c b/src/plugins/nat/nat64_out2in.c index ba35de1e2a1..437052fc441 100644 --- a/src/plugins/nat/nat64_out2in.c +++ b/src/plugins/nat/nat64_out2in.c @@ -165,6 +165,12 @@ nat64_out2in_tcp_udp_set_cb (ip4_header_t * ip4, ip6_header_t * ip6, nat64_compose_ip6 (&ip6_saddr, &ip4->src_address, bibe->fib_index); ste = nat64_db_st_entry_create (db, bibe, &ip6_saddr, &saddr.ip4, sport); + + if (!ste) + return -1; + + vlib_set_simple_counter (&nm->total_sessions, ctx->thread_index, 0, + db->st.st_entries_num); } ip6->src_address.as_u64[0] = ste->in_r_addr.as_u64[0]; @@ -240,6 +246,12 @@ nat64_out2in_icmp_set_cb (ip4_header_t * ip4, ip6_header_t * ip6, void *arg) nat64_compose_ip6 (&ip6_saddr, &ip4->src_address, bibe->fib_index); ste = nat64_db_st_entry_create (db, bibe, &ip6_saddr, &saddr.ip4, 0); + + if (!ste) + return -1; + + vlib_set_simple_counter (&nm->total_sessions, ctx->thread_index, 0, + db->st.st_entries_num); } nat64_session_reset_timeout (ste, ctx->vm); @@ -397,6 +409,12 @@ nat64_out2in_unk_proto_set_cb (ip4_header_t * ip4, ip6_header_t * ip6, nat64_compose_ip6 (&ip6_saddr, &ip4->src_address, bibe->fib_index); ste = nat64_db_st_entry_create (db, bibe, &ip6_saddr, &saddr.ip4, 0); + + if (!ste) + return -1; + + vlib_set_simple_counter (&nm->total_sessions, ctx->thread_index, 0, + db->st.st_entries_num); } nat64_session_reset_timeout (ste, ctx->vm); @@ -802,6 +820,9 @@ nat64_out2in_reass_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node, node->errors[NAT64_OUT2IN_ERROR_NO_TRANSLATION]; goto trace0; } + + vlib_set_simple_counter (&nm->total_sessions, thread_index, + 0, db->st.st_entries_num); } reass0->sess_index = nat64_db_st_entry_get_index (db, ste0); reass0->thread_index = thread_index; diff --git a/src/plugins/nat/nat_inlines.h b/src/plugins/nat/nat_inlines.h index 38cfc379245..db5063c412b 100644 --- a/src/plugins/nat/nat_inlines.h +++ b/src/plugins/nat/nat_inlines.h @@ -159,6 +159,8 @@ nat44_delete_user_with_no_session (snat_main_t * sm, snat_user_t * u, pool_put_index (tsm->list_pool, u->sessions_per_user_list_head_index); pool_put (tsm->users, u); clib_bihash_add_del_8_8 (&tsm->user_hash, &kv, 0); + vlib_set_simple_counter (&sm->total_users, thread_index, 0, + pool_elts (tsm->users)); } } @@ -177,6 +179,8 @@ nat44_delete_session (snat_main_t * sm, snat_session_t * ses, clib_dlist_remove (tsm->list_pool, ses->per_user_index); pool_put_index (tsm->list_pool, ses->per_user_index); pool_put (tsm->sessions, ses); + vlib_set_simple_counter (&sm->total_sessions, thread_index, 0, + pool_elts (tsm->sessions)); u_key.addr = ses->in2out.addr; u_key.fib_index = ses->in2out.fib_index; diff --git a/test/test_nat.py b/test/test_nat.py index 81aae4bd59e..e3aa267c805 100644 --- a/test/test_nat.py +++ b/test/test_nat.py @@ -1015,6 +1015,10 @@ class MethodHolder(VppTestCase): """ Verify that there is no NAT44 user """ users = self.vapi.nat44_user_dump() self.assertEqual(len(users), 0) + users = self.statistics.get_counter('/nat44/total-users') + self.assertEqual(users[0][0], 0) + sessions = self.statistics.get_counter('/nat44/total-sessions') + self.assertEqual(sessions[0][0], 0) def verify_ipfix_max_entries_per_user(self, data, limit, src_addr): """ @@ -1566,6 +1570,11 @@ class TestNAT44(MethodHolder): '/err/nat44-out2in/good out2in packets processed') self.assertEqual(err - totaln, 3) + users = self.statistics.get_counter('/nat44/total-users') + self.assertEqual(users[0][0], 1) + sessions = self.statistics.get_counter('/nat44/total-sessions') + self.assertEqual(sessions[0][0], 3) + def test_dynamic_icmp_errors_in2out_ttl_1(self): """ NAT44 handling of client packets with TTL=1 """ @@ -4105,6 +4114,11 @@ class TestNAT44EndpointDependent(MethodHolder): '/err/nat44-ed-out2in/good out2in packets processed') self.assertEqual(err - totaln, 2) + users = self.statistics.get_counter('/nat44/total-users') + self.assertEqual(users[0][0], 1) + sessions = self.statistics.get_counter('/nat44/total-sessions') + self.assertEqual(sessions[0][0], 3) + def test_forwarding(self): """ NAT44 forwarding test """ @@ -6936,6 +6950,8 @@ class TestNAT64(MethodHolder): self.assertEqual(bibe.i_port, in_port) self.assertEqual(bibe.o_port, out_port) self.assertEqual(static_bib_num, 1) + bibs = self.statistics.get_counter('/nat64/total-bibs') + self.assertEqual(bibs[0][0], 1) self.vapi.nat64_add_del_static_bib(in_addr, out_addr, @@ -6949,6 +6965,8 @@ class TestNAT64(MethodHolder): if bibe.is_static: static_bib_num += 1 self.assertEqual(static_bib_num, 0) + bibs = self.statistics.get_counter('/nat64/total-bibs') + self.assertEqual(bibs[0][0], 0) def test_set_timeouts(self): """ Set NAT64 timeouts """ @@ -7031,6 +7049,11 @@ class TestNAT64(MethodHolder): '/err/nat64-out2in/good out2in packets processed') self.assertEqual(err - totaln, 3) + bibs = self.statistics.get_counter('/nat64/total-bibs') + self.assertEqual(bibs[0][0], 3) + sessions = self.statistics.get_counter('/nat64/total-sessions') + self.assertEqual(sessions[0][0], 3) + # in2out pkts = self.create_stream_in_ip6(self.pg0, self.pg1) self.pg0.add_stream(pkts) @@ -8094,6 +8117,11 @@ class TestNAT64(MethodHolder): vrf_id=prefix.vrf_id, is_add=0) + bibs = self.statistics.get_counter('/nat64/total-bibs') + self.assertEqual(bibs[0][0], 0) + sessions = self.statistics.get_counter('/nat64/total-sessions') + self.assertEqual(sessions[0][0], 0) + def tearDown(self): super(TestNAT64, self).tearDown() if not self.vpp_dead: @@ -8286,6 +8314,11 @@ class TestDSlite(MethodHolder): self.assertEqual(capture[IPv6].dst, self.pg1.remote_hosts[1].ip6) self.assertTrue(capture.haslayer(ICMPv6EchoReply)) + b4s = self.statistics.get_counter('/dslite/total-b4s') + self.assertEqual(b4s[0][0], 2) + sessions = self.statistics.get_counter('/dslite/total-sessions') + self.assertEqual(sessions[0][0], 3) + def tearDown(self): super(TestDSlite, self).tearDown() if not self.vpp_dead: -- 2.16.6