udp: add basic stats per connection 23/42823/3
authorFlorin Coras <[email protected]>
Wed, 16 Apr 2025 06:02:33 +0000 (02:02 -0400)
committerDave Barach <[email protected]>
Wed, 16 Apr 2025 19:34:51 +0000 (19:34 +0000)
Type: improvement

Change-Id: I95a3b9c85f4b6ab94250fc8fb5f2a4a142a2f833
Signed-off-by: Florin Coras <[email protected]>
src/vnet/udp/udp.c
src/vnet/udp/udp.h
src/vnet/udp/udp_cli.c
src/vnet/udp/udp_input.c

index 661a0f6..d997da2 100644 (file)
@@ -303,6 +303,8 @@ udp_push_one_header (vlib_main_t *vm, udp_connection_t *uc, vlib_buffer_t *b,
       vnet_buffer (b)->tcp.flags |= UDP_CONN_F_LISTEN;
     }
 
+  uc->bytes_out += vlib_buffer_length_in_chain (vm, b);
+  uc->dgrams_out += 1;
   uh->checksum =
     udp_compute_checksum (vm, b, udp_csum_offload (uc), uc->c_is_ip4);
 
index c6f8675..2e280f7 100644 (file)
@@ -87,6 +87,11 @@ typedef struct
   u32 sw_if_index;                     /**< connection sw_if_index */
   u32 next_node_index; /**< Can be used to control next node in output */
   u32 next_node_opaque; /**< Opaque to pass to next node */
+  u64 bytes_in;                /**< bytes received */
+  u64 dgrams_in;       /**< rfc4113 dgrams received  */
+  u64 bytes_out;       /**< bytes sent */
+  u64 dgrams_out;      /**< rfc4113 dgrams sent */
+  u32 errors_in;       /**< rfc4113 dgrams in errors */
 } udp_connection_t;
 
 #define udp_csum_offload(uc) (!((uc)->cfg_flags & UDP_CFG_F_NO_CSUM_OFFLOAD))
index dd1da0a..adae993 100644 (file)
@@ -90,19 +90,36 @@ format_udp_connection_flags (u8 * s, va_list * args)
   return s;
 }
 
+static u8 *
+format_udp_stats (u8 *s, va_list *args)
+{
+  udp_connection_t *uc = va_arg (*args, udp_connection_t *);
+  u32 indent = format_get_indent (s);
+  s = format (s, "in dgrams %lu bytes %lu err %lu\n", uc->dgrams_in,
+             uc->bytes_in, uc->errors_in);
+  s = format (s, "%Uout dgrams %lu bytes %lu", format_white_space, indent,
+             uc->dgrams_out, uc->bytes_out);
+  return s;
+}
+
 static u8 *
 format_udp_vars (u8 * s, va_list * args)
 {
   udp_connection_t *uc = va_arg (*args, udp_connection_t *);
 
-  s = format (s, " index %u%U flags: %U\n", uc->c_c_index,
+  s = format (s, " index %u cfg: %U flags: %U\n", uc->c_c_index,
              format_udp_cfg_flags, uc, format_udp_connection_flags, uc);
-  s = format (s, " fib_index: %u next_node: %u opaque: %u ", uc->c_fib_index,
+  s = format (s, " fib_index %u next_node %u opaque %u", uc->c_fib_index,
              uc->next_node_index, uc->next_node_opaque);
-  if (!(uc->flags & UDP_CONN_F_LISTEN))
-    s = format (s, " sw_if_index: %d mss: %u\n", uc->sw_if_index, uc->mss);
-  else
-    s = format (s, "\n");
+
+  if (uc->flags & UDP_CONN_F_LISTEN)
+    {
+      s = format (s, "\n");
+      return s;
+    }
+
+  s = format (s, " sw_if_index %d mss %u\n", uc->sw_if_index, uc->mss);
+  s = format (s, " stats: %U\n", format_udp_stats, uc);
 
   return s;
 }
index 693824f..19cc04c 100644 (file)
@@ -146,7 +146,15 @@ udp_connection_enqueue (udp_connection_t * uc0, session_t * s0,
 
       /* Expect cl udp enqueue to fail because fifo enqueue */
       if (PREDICT_FALSE (wrote0 == 0))
-       *error0 = UDP_ERROR_FIFO_FULL;
+       {
+         *error0 = UDP_ERROR_FIFO_FULL;
+         uc0->errors_in += 1;
+       }
+      else
+       {
+         uc0->bytes_in += wrote0;
+         uc0->dgrams_in += 1;
+       }
 
       return;
     }
@@ -155,6 +163,7 @@ udp_connection_enqueue (udp_connection_t * uc0, session_t * s0,
       < hdr0->data_length + sizeof (session_dgram_hdr_t))
     {
       *error0 = UDP_ERROR_FIFO_FULL;
+      uc0->errors_in += 1;
       return;
     }
 
@@ -175,7 +184,15 @@ udp_connection_enqueue (udp_connection_t * uc0, session_t * s0,
   /* In some rare cases, session_enqueue_dgram_connection can fail because a
    * chunk cannot be allocated in the RX FIFO */
   if (PREDICT_FALSE (wrote0 == 0))
-    *error0 = UDP_ERROR_FIFO_NOMEM;
+    {
+      *error0 = UDP_ERROR_FIFO_NOMEM;
+      uc0->errors_in += 1;
+    }
+  else
+    {
+      uc0->bytes_in += wrote0;
+      uc0->dgrams_in += 1;
+    }
 }
 
 always_inline session_t *