summaryrefslogtreecommitdiffstats
path: root/src/vnet/bfd/bfd_udp.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/vnet/bfd/bfd_udp.c')
-rw-r--r--src/vnet/bfd/bfd_udp.c86
1 files changed, 79 insertions, 7 deletions
diff --git a/src/vnet/bfd/bfd_udp.c b/src/vnet/bfd/bfd_udp.c
index d8fd4a10529..97b1a737528 100644
--- a/src/vnet/bfd/bfd_udp.c
+++ b/src/vnet/bfd/bfd_udp.c
@@ -35,6 +35,7 @@
#include <vnet/dpo/receive_dpo.h>
#include <vnet/fib/fib_entry.h>
#include <vnet/fib/fib_table.h>
+#include <vpp/stats/stat_segment.h>
#include <vnet/bfd/bfd_debug.h>
#include <vnet/bfd/bfd_udp.h>
#include <vnet/bfd/bfd_main.h>
@@ -68,8 +69,10 @@ typedef struct
vlib_log_class_t log_class;
/* number of active udp4 sessions */
u32 udp4_sessions_count;
+ u32 udp4_sessions_count_stat_seg_entry;
/* number of active udp6 sessions */
u32 udp6_sessions_count;
+ u32 udp6_sessions_count_stat_seg_entry;
} bfd_udp_main_t;
static vlib_node_registration_t bfd_udp4_input_node;
@@ -79,6 +82,14 @@ static vlib_node_registration_t bfd_udp_echo6_input_node;
bfd_udp_main_t bfd_udp_main;
+void
+bfd_udp_update_stat_segment_entry (u32 entry, u64 value)
+{
+ vlib_stat_segment_lock ();
+ stat_segment_set_state_counter (entry, value);
+ vlib_stat_segment_unlock ();
+}
+
vnet_api_error_t
bfd_udp_set_echo_source (u32 sw_if_index)
{
@@ -94,7 +105,7 @@ bfd_udp_set_echo_source (u32 sw_if_index)
}
vnet_api_error_t
-bfd_udp_del_echo_source (u32 sw_if_index)
+bfd_udp_del_echo_source ()
{
bfd_udp_main.echo_source_sw_if_index = ~0;
bfd_udp_main.echo_source_is_set = 0;
@@ -372,13 +383,18 @@ bfd_add_udp6_transport (vlib_main_t * vm, u32 bi, const bfd_session_t * bs,
}
static void
-bfd_create_frame_to_next_node (vlib_main_t * vm, u32 bi, u32 next_node)
+bfd_create_frame_to_next_node (vlib_main_t *vm, bfd_main_t *bm,
+ const bfd_session_t *bs, u32 bi, u32 next_node,
+ vlib_combined_counter_main_t *tx_counter)
{
vlib_frame_t *f = vlib_get_frame_to_node (vm, next_node);
u32 *to_next = vlib_frame_vector_args (f);
to_next[0] = bi;
f->n_vectors = 1;
vlib_put_frame_to_node (vm, next_node, f);
+ vlib_buffer_t *b = vlib_get_buffer (vm, bi);
+ vlib_increment_combined_counter (tx_counter, vm->thread_index, bs->bs_idx, 1,
+ vlib_buffer_length_in_chain (vm, b));
}
int
@@ -435,25 +451,33 @@ bfd_udp_calc_next_node (const struct bfd_session_s *bs, u32 * next_node)
}
int
-bfd_transport_udp4 (vlib_main_t * vm, u32 bi, const struct bfd_session_s *bs)
+bfd_transport_udp4 (vlib_main_t *vm, u32 bi, const struct bfd_session_s *bs,
+ int is_echo)
{
u32 next_node;
int rv = bfd_udp_calc_next_node (bs, &next_node);
+ bfd_main_t *bm = bfd_udp_main.bfd_main;
if (rv)
{
- bfd_create_frame_to_next_node (vm, bi, next_node);
+ bfd_create_frame_to_next_node (vm, bm, bs, bi, next_node,
+ is_echo ? &bm->tx_echo_counter :
+ &bm->tx_counter);
}
return rv;
}
int
-bfd_transport_udp6 (vlib_main_t * vm, u32 bi, const struct bfd_session_s *bs)
+bfd_transport_udp6 (vlib_main_t *vm, u32 bi, const struct bfd_session_s *bs,
+ int is_echo)
{
u32 next_node;
int rv = bfd_udp_calc_next_node (bs, &next_node);
+ bfd_main_t *bm = bfd_udp_main.bfd_main;
if (rv)
{
- bfd_create_frame_to_next_node (vm, bi, next_node);
+ bfd_create_frame_to_next_node (
+ vm, bfd_udp_main.bfd_main, bs, bi, next_node,
+ is_echo ? &bm->tx_echo_counter : &bm->tx_counter);
}
return 1;
}
@@ -530,6 +554,8 @@ bfd_udp_add_session_internal (vlib_main_t * vm, bfd_udp_main_t * bum,
"returns %d", format_ip46_address, &key->peer_addr,
IP46_TYPE_ANY, key->sw_if_index, bus->adj_index);
++bum->udp4_sessions_count;
+ bfd_udp_update_stat_segment_entry (
+ bum->udp4_sessions_count_stat_seg_entry, bum->udp4_sessions_count);
if (1 == bum->udp4_sessions_count)
{
udp_register_dst_port (vm, UDP_DST_PORT_bfd4,
@@ -547,6 +573,8 @@ bfd_udp_add_session_internal (vlib_main_t * vm, bfd_udp_main_t * bum,
"returns %d", format_ip46_address, &key->peer_addr,
IP46_TYPE_ANY, key->sw_if_index, bus->adj_index);
++bum->udp6_sessions_count;
+ bfd_udp_update_stat_segment_entry (
+ bum->udp6_sessions_count_stat_seg_entry, bum->udp6_sessions_count);
if (1 == bum->udp6_sessions_count)
{
udp_register_dst_port (vm, UDP_DST_PORT_bfd6,
@@ -719,6 +747,8 @@ bfd_udp_del_session_internal (vlib_main_t * vm, bfd_session_t * bs)
{
case BFD_TRANSPORT_UDP4:
--bum->udp4_sessions_count;
+ bfd_udp_update_stat_segment_entry (
+ bum->udp4_sessions_count_stat_seg_entry, bum->udp4_sessions_count);
if (!bum->udp4_sessions_count)
{
udp_unregister_dst_port (vm, UDP_DST_PORT_bfd4, 1);
@@ -727,6 +757,8 @@ bfd_udp_del_session_internal (vlib_main_t * vm, bfd_session_t * bs)
break;
case BFD_TRANSPORT_UDP6:
--bum->udp6_sessions_count;
+ bfd_udp_update_stat_segment_entry (
+ bum->udp6_sessions_count_stat_seg_entry, bum->udp6_sessions_count);
if (!bum->udp6_sessions_count)
{
udp_unregister_dst_port (vm, UDP_DST_PORT_bfd6, 0);
@@ -1342,6 +1374,9 @@ bfd_udp_input (vlib_main_t * vm, vlib_node_runtime_t * rt,
next0 = BFD_UDP_INPUT_NEXT_NORMAL;
if (BFD_UDP_ERROR_NONE == error0)
{
+ vlib_increment_combined_counter (
+ &bm->rx_counter, vm->thread_index, bs->bs_idx, 1,
+ vlib_buffer_length_in_chain (vm, b0));
/*
* if everything went fine, check for poll bit, if present, re-use
* the buffer and based on (now updated) session parameters, send
@@ -1488,8 +1523,9 @@ bfd_udp_echo_input (vlib_main_t * vm, vlib_node_runtime_t * rt,
clib_memcpy_fast (t0->data, vlib_buffer_get_current (b0), len);
}
+ bfd_session_t *bs = NULL;
bfd_lock (bm);
- if (bfd_consume_echo_pkt (vm, bfd_udp_main.bfd_main, b0))
+ if ((bs = bfd_consume_echo_pkt (vm, bfd_udp_main.bfd_main, b0)))
{
b0->error = rt->errors[BFD_UDP_ERROR_NONE];
next0 = BFD_UDP_ECHO_INPUT_NEXT_NORMAL;
@@ -1512,6 +1548,14 @@ bfd_udp_echo_input (vlib_main_t * vm, vlib_node_runtime_t * rt,
}
bfd_unlock (bm);
+
+ if (bs)
+ {
+ vlib_increment_combined_counter (
+ &bm->rx_echo_counter, vm->thread_index, bs->bs_idx, 1,
+ vlib_buffer_length_in_chain (vm, b0));
+ }
+
vlib_set_next_frame_buffer (vm, rt, next0, bi0);
from += 1;
@@ -1640,6 +1684,32 @@ bfd_udp_sw_if_add_del (CLIB_UNUSED (vnet_main_t *vnm), u32 sw_if_index,
VNET_SW_INTERFACE_ADD_DEL_FUNCTION (bfd_udp_sw_if_add_del);
+clib_error_t *
+bfd_udp_stats_init (bfd_udp_main_t *bum)
+{
+ const char *name4 = "/bfd/udp4/sessions";
+ bum->udp4_sessions_count_stat_seg_entry =
+ stat_segment_new_entry ((u8 *) name4, STAT_DIR_TYPE_SCALAR_INDEX);
+
+ stat_segment_set_state_counter (bum->udp4_sessions_count_stat_seg_entry, 0);
+ if (~0 == bum->udp4_sessions_count_stat_seg_entry)
+ {
+ return clib_error_return (
+ 0, "Could not create stat segment entry for %s", name4);
+ }
+ const char *name6 = "/bfd/udp6/sessions";
+ bum->udp6_sessions_count_stat_seg_entry =
+ stat_segment_new_entry ((u8 *) name6, STAT_DIR_TYPE_SCALAR_INDEX);
+
+ if (~0 == bum->udp6_sessions_count_stat_seg_entry)
+ {
+ return clib_error_return (
+ 0, "Could not create stat segment entry for %s", name6);
+ }
+
+ return 0;
+}
+
/*
* setup function
*/
@@ -1671,6 +1741,8 @@ bfd_udp_init (vlib_main_t * vm)
ASSERT (node);
bfd_udp_main.ip6_midchain_idx = node->index;
+ bfd_udp_stats_init (&bfd_udp_main);
+
bfd_udp_main.log_class = vlib_log_register_class ("bfd", "udp");
vlib_log_debug (bfd_udp_main.log_class, "initialized");
return 0;