LCOV - code coverage report
Current view: top level - vnet - interface_stats.c (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 9 65 13.8 %
Date: 2023-10-26 01:39:38 Functions: 19 30 63.3 %

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2018 Cisco and/or its affiliates.
       3             :  * Licensed under the Apache License, Version 2.0 (the "License");
       4             :  * you may not use this file except in compliance with the License.
       5             :  * You may obtain a copy of the License at:
       6             :  *
       7             :  *     http://www.apache.org/licenses/LICENSE-2.0
       8             :  *
       9             :  * Unless required by applicable law or agreed to in writing, software
      10             :  * distributed under the License is distributed on an "AS IS" BASIS,
      11             :  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      12             :  * See the License for the specific language governing permissions and
      13             :  * limitations under the License.
      14             :  */
      15             : 
      16             : #include <vlib/vlib.h>
      17             : #include <vnet/vnet.h>
      18             : #include <vppinfra/error.h>
      19             : 
      20             : #include <vnet/feature/feature.h>
      21             : #include <vnet/ethernet/ethernet.h>
      22             : 
      23             : #ifndef CLIB_MARCH_VARIANT
      24             : int
      25           0 : vnet_sw_interface_stats_collect_enable_disable (u32 sw_if_index, u8 enable)
      26             : {
      27             :   ethernet_interface_t *eif;
      28             :   vnet_sw_interface_t *si;
      29             :   ethernet_main_t *em;
      30             :   vnet_main_t *vnm;
      31             : 
      32           0 :   vnm = vnet_get_main ();
      33           0 :   em = &ethernet_main;
      34           0 :   si = vnet_get_sw_interface (vnm, sw_if_index);
      35             : 
      36             :   /*
      37             :    * only ethernet HW interfaces are supported at this time
      38             :    */
      39           0 :   if (si->type != VNET_SW_INTERFACE_TYPE_HARDWARE)
      40             :     {
      41           0 :       return (VNET_API_ERROR_INVALID_VALUE);
      42             :     }
      43             : 
      44           0 :   eif = ethernet_get_interface (em, si->hw_if_index);
      45             : 
      46           0 :   if (!eif)
      47             :     {
      48           0 :       return (VNET_API_ERROR_FEATURE_DISABLED);
      49             :     }
      50             : 
      51           0 :   vnet_feature_enable_disable ("device-input", "stats-collect-rx",
      52             :                                sw_if_index, enable, 0, 0);
      53           0 :   vnet_feature_enable_disable ("interface-output", "stats-collect-tx",
      54             :                                sw_if_index, enable, 0, 0);
      55             : 
      56           0 :   return (0);
      57             : }
      58             : #endif /* CLIB_MARCH_VARIANT */
      59             : 
      60             : static u8 *
      61           0 : format_stats_collect_trace (u8 * s, va_list * args)
      62             : {
      63           0 :   CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
      64           0 :   CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
      65             : 
      66           0 :   return s;
      67             : }
      68             : 
      69             : #define inc_counter(ctype, rx_tx)                               \
      70             : {                                                               \
      71             : }
      72             : 
      73             : static_always_inline uword
      74           0 : stats_collect_inline (vlib_main_t * vm,
      75             :                       vlib_node_runtime_t * node,
      76             :                       vlib_frame_t * frame, vlib_rx_or_tx_t rxtx)
      77             : {
      78             :   vnet_interface_counter_type_t ct;
      79             :   u32 n_left_from, *from, *to_next;
      80             :   u32 next_index;
      81           0 :   u32 sw_if_index = 0;
      82           0 :   u32 stats_n_packets[VNET_N_COMBINED_INTERFACE_COUNTER] = { 0 };
      83           0 :   u64 stats_n_bytes[VNET_N_COMBINED_INTERFACE_COUNTER] = { 0 };
      84             : 
      85           0 :   from = vlib_frame_vector_args (frame);
      86           0 :   n_left_from = frame->n_vectors;
      87           0 :   next_index = node->cached_next_index;
      88             : 
      89           0 :   while (n_left_from > 0)
      90             :     {
      91             :       u32 n_left_to_next;
      92             : 
      93           0 :       vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
      94             : 
      95           0 :       while (n_left_from > 0 && n_left_to_next > 0)
      96             :         {
      97             :           u32 bi0;
      98             :           vlib_buffer_t *b0;
      99           0 :           u32 next0 = 0;
     100             :           int b0_ctype;
     101             : 
     102             :           /* speculatively enqueue b0 to the current next frame */
     103           0 :           to_next[0] = bi0 = from[0];
     104           0 :           to_next += 1;
     105           0 :           n_left_to_next -= 1;
     106           0 :           from += 1;
     107           0 :           n_left_from -= 1;
     108             : 
     109           0 :           b0 = vlib_get_buffer (vm, bi0);
     110           0 :           sw_if_index = vnet_buffer (b0)->sw_if_index[rxtx];
     111             : 
     112           0 :           if (VLIB_RX == rxtx)
     113             :             {
     114             :               b0_ctype =
     115           0 :                 eh_dst_addr_to_rx_ctype (vlib_buffer_get_current (b0));
     116             :             }
     117             :           else
     118             :             {
     119             :               b0_ctype =
     120           0 :                 eh_dst_addr_to_tx_ctype (vlib_buffer_get_current (b0));
     121             :             }
     122             : 
     123           0 :           stats_n_bytes[b0_ctype] += vlib_buffer_length_in_chain (vm, b0);
     124           0 :           stats_n_packets[b0_ctype] += 1;
     125             : 
     126           0 :           vnet_feature_next (&next0, b0);
     127             : 
     128           0 :           vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next,
     129             :                                            n_left_to_next, bi0, next0);
     130             :         }
     131             : 
     132           0 :       if (VLIB_RX == rxtx)
     133             :         {
     134           0 :           foreach_rx_combined_interface_counter (ct)
     135             :           {
     136           0 :             vlib_increment_combined_counter
     137           0 :               (vnet_main.interface_main.combined_sw_if_counters + ct,
     138           0 :                vlib_get_thread_index (),
     139           0 :                sw_if_index, stats_n_packets[ct], stats_n_bytes[ct]);
     140             :           }
     141             :         }
     142             :       else
     143             :         {
     144           0 :           foreach_tx_combined_interface_counter (ct)
     145             :           {
     146           0 :             vlib_increment_combined_counter
     147           0 :               (vnet_main.interface_main.combined_sw_if_counters + ct,
     148           0 :                vlib_get_thread_index (),
     149           0 :                sw_if_index, stats_n_packets[ct], stats_n_bytes[ct]);
     150             :           }
     151             :         }
     152             : 
     153           0 :       vlib_put_next_frame (vm, node, next_index, n_left_to_next);
     154             :     }
     155             : 
     156           0 :   return frame->n_vectors;
     157             : }
     158             : 
     159        2300 : VLIB_NODE_FN (stats_collect_rx_node) (vlib_main_t * vm,
     160             :                                       vlib_node_runtime_t * node,
     161             :                                       vlib_frame_t * frame)
     162             : {
     163           0 :   return stats_collect_inline (vm, node, frame, VLIB_RX);
     164             : }
     165             : 
     166        2300 : VLIB_NODE_FN (stats_collect_tx_node) (vlib_main_t * vm,
     167             :                                       vlib_node_runtime_t * node,
     168             :                                       vlib_frame_t * frame)
     169             : {
     170           0 :   return stats_collect_inline (vm, node, frame, VLIB_TX);
     171             : }
     172             : 
     173             : /* *INDENT-OFF* */
     174      183788 : VLIB_REGISTER_NODE (stats_collect_rx_node) = {
     175             :   .vector_size = sizeof (u32),
     176             :   .format_trace = format_stats_collect_trace,
     177             :   .type = VLIB_NODE_TYPE_INTERNAL,
     178             :   .n_errors = 0,
     179             :   .n_next_nodes = 0,
     180             :   .name = "stats-collect-rx",
     181             : };
     182             : 
     183      183788 : VLIB_REGISTER_NODE (stats_collect_tx_node) = {
     184             :   .vector_size = sizeof (u32),
     185             :   .format_trace = format_stats_collect_trace,
     186             :   .type = VLIB_NODE_TYPE_INTERNAL,
     187             :   .n_errors = 0,
     188             :   .n_next_nodes = 0,
     189             :   .name = "stats-collect-tx",
     190             : };
     191             : 
     192       76635 : VNET_FEATURE_INIT (stats_collect_rx_node, static) = {
     193             :   .arc_name = "device-input",
     194             :   .node_name = "stats-collect-rx",
     195             :   .runs_before = VNET_FEATURES ("ethernet-input"),
     196             : };
     197             : 
     198       76635 : VNET_FEATURE_INIT (stats_collect_tx_node, static) = {
     199             :   .arc_name = "interface-output",
     200             :   .node_name = "stats-collect-tx",
     201             :   .runs_before = VNET_FEATURES ("interface-output-arc-end"),
     202             : };
     203             : 
     204             : /* *INDENT-ON* */
     205             : 
     206             : static clib_error_t *
     207         575 : stats_collect_init (vlib_main_t * vm)
     208             : {
     209         575 :   return 0;
     210             : }
     211             : 
     212       10943 : VLIB_INIT_FUNCTION (stats_collect_init);
     213             : 
     214             : 
     215             : /*
     216             :  * fd.io coding-style-patch-verification: ON
     217             :  *
     218             :  * Local Variables:
     219             :  * eval: (c-set-style "gnu")
     220             :  * End:
     221             :  */

Generated by: LCOV version 1.14