LCOV - code coverage report
Current view: top level - plugins/unittest - mpcap_node.c (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 89 91 97.8 %
Date: 2023-07-05 22:20:52 Functions: 9 9 100.0 %

          Line data    Source code
       1             : /*
       2             :  * mpcap_node.c - unit-test plugin mapped pcap test node
       3             :  *
       4             :  * Copyright (c) <current-year> <your-organization>
       5             :  * Licensed under the Apache License, Version 2.0 (the "License");
       6             :  * you may not use this file except in compliance with the License.
       7             :  * You may obtain a copy of the License at:
       8             :  *
       9             :  *     http://www.apache.org/licenses/LICENSE-2.0
      10             :  *
      11             :  * Unless required by applicable law or agreed to in writing, software
      12             :  * distributed under the License is distributed on an "AS IS" BASIS,
      13             :  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      14             :  * See the License for the specific language governing permissions and
      15             :  * limitations under the License.
      16             :  */
      17             : #include <vlib/vlib.h>
      18             : #include <vnet/vnet.h>
      19             : #include <vnet/pg/pg.h>
      20             : #include <vppinfra/error.h>
      21             : #include <vnet/mpcap.h>
      22             : #include <vnet/ethernet/ethernet.h>
      23             : 
      24             : static mpcap_main_t test_mpcap_main = {
      25             :   .file_name = "/tmp/mpcap_unittest.pcap",
      26             :   .n_packets_to_capture = 15,
      27             :   .packet_type = MPCAP_PACKET_TYPE_ethernet,
      28             : };
      29             : 
      30             : typedef struct
      31             : {
      32             :   u32 sw_if_index;
      33             :   u32 next_index;
      34             : } mpcap_trace_t;
      35             : 
      36             : #ifndef CLIB_MARCH_VARIANT
      37             : 
      38             : /* packet trace format function */
      39             : static u8 *
      40          30 : format_mpcap_trace (u8 * s, va_list * args)
      41             : {
      42          30 :   CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
      43          30 :   CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
      44          30 :   mpcap_trace_t *t = va_arg (*args, mpcap_trace_t *);
      45             : 
      46          30 :   s = format (s, "MPCAP: sw_if_index %d, next index %d\n",
      47             :               t->sw_if_index, t->next_index);
      48          30 :   return s;
      49             : }
      50             : 
      51             : vlib_node_registration_t mpcap_node;
      52             : 
      53             : #endif /* CLIB_MARCH_VARIANT */
      54             : 
      55             : #define foreach_mpcap_error \
      56             : _(PROCESSED, "Mapped pcap packets processed")
      57             : 
      58             : typedef enum
      59             : {
      60             : #define _(sym,str) MPCAP_ERROR_##sym,
      61             :   foreach_mpcap_error
      62             : #undef _
      63             :     MPCAP_N_ERROR,
      64             : } mpcap_error_t;
      65             : 
      66             : #ifndef CLIB_MARCH_VARIANT
      67             : static char *mpcap_error_strings[] = {
      68             : #define _(sym,string) string,
      69             :   foreach_mpcap_error
      70             : #undef _
      71             : };
      72             : #endif /* CLIB_MARCH_VARIANT */
      73             : 
      74             : typedef enum
      75             : {
      76             :   MPCAP_NEXT_DROP,
      77             :   MPCAP_N_NEXT,
      78             : } mpcap_next_t;
      79             : 
      80             : always_inline uword
      81           1 : mpcap_inline (vlib_main_t * vm,
      82             :               vlib_node_runtime_t * node, vlib_frame_t * frame,
      83             :               int is_ip4, int is_trace)
      84             : {
      85             :   u32 n_left_from, *from;
      86             :   vlib_buffer_t *bufs[VLIB_FRAME_SIZE], **b;
      87             :   u16 nexts[VLIB_FRAME_SIZE], *next;
      88           1 :   mpcap_main_t *mm = &test_mpcap_main;
      89           1 :   int i = 0;
      90           1 :   f64 now = vlib_time_now (vm);
      91           1 :   u32 error_index = node->errors[MPCAP_ERROR_PROCESSED];
      92             : 
      93           1 :   if (!(mm->flags & MPCAP_FLAG_INIT_DONE))
      94             :     {
      95             :       clib_error_t *error;
      96             : 
      97           1 :       error = mpcap_init (mm);
      98           1 :       if (error)
      99           0 :         clib_error_report (error);
     100           1 :       mm->flags |= MPCAP_FLAG_INIT_DONE;
     101             :     }
     102             : 
     103           1 :   from = vlib_frame_vector_args (frame);
     104           1 :   n_left_from = frame->n_vectors;
     105             : 
     106           1 :   vlib_get_buffers (vm, from, bufs, n_left_from);
     107           1 :   b = bufs;
     108           1 :   next = nexts;
     109             : 
     110           4 :   while (n_left_from >= 4)
     111             :     {
     112             :       /* Prefetch next iteration. */
     113           3 :       if (PREDICT_TRUE (n_left_from >= 8))
     114             :         {
     115           2 :           vlib_prefetch_buffer_header (b[4], STORE);
     116           2 :           vlib_prefetch_buffer_header (b[5], STORE);
     117           2 :           vlib_prefetch_buffer_header (b[6], STORE);
     118           2 :           vlib_prefetch_buffer_header (b[7], STORE);
     119           2 :           clib_prefetch_store (b[4]->data);
     120           2 :           clib_prefetch_store (b[5]->data);
     121           2 :           clib_prefetch_store (b[6]->data);
     122           2 :           clib_prefetch_store (b[7]->data);
     123             :         }
     124             : 
     125           3 :       next[0] = 0;
     126           3 :       next[1] = 0;
     127           3 :       next[2] = 0;
     128           3 :       next[3] = 0;
     129             : 
     130           3 :       b[0]->error = error_index;
     131           3 :       b[1]->error = error_index;
     132           3 :       b[2]->error = error_index;
     133           3 :       b[3]->error = error_index;
     134             : 
     135           3 :       mpcap_add_buffer (mm, vm, now, from[i++],
     136           3 :                         vlib_buffer_length_in_chain (vm, b[0]));
     137             : 
     138           3 :       mpcap_add_buffer (mm, vm, now, from[i++],
     139           3 :                         vlib_buffer_length_in_chain (vm, b[1]));
     140             : 
     141           3 :       mpcap_add_buffer (mm, vm, now, from[i++],
     142           3 :                         vlib_buffer_length_in_chain (vm, b[2]));
     143             : 
     144           3 :       mpcap_add_buffer (mm, vm, now, from[i++],
     145           3 :                         vlib_buffer_length_in_chain (vm, b[3]));
     146             : 
     147           3 :       if (is_trace)
     148             :         {
     149           3 :           if (b[0]->flags & VLIB_BUFFER_IS_TRACED)
     150             :             {
     151           3 :               mpcap_trace_t *t = vlib_add_trace (vm, node, b[0], sizeof (*t));
     152           3 :               t->next_index = next[0];
     153           3 :               t->sw_if_index = vnet_buffer (b[0])->sw_if_index[VLIB_RX];
     154             :             }
     155           3 :           if (b[1]->flags & VLIB_BUFFER_IS_TRACED)
     156             :             {
     157           3 :               mpcap_trace_t *t = vlib_add_trace (vm, node, b[1], sizeof (*t));
     158           3 :               t->next_index = next[1];
     159           3 :               t->sw_if_index = vnet_buffer (b[1])->sw_if_index[VLIB_RX];
     160             :             }
     161           3 :           if (b[2]->flags & VLIB_BUFFER_IS_TRACED)
     162             :             {
     163           3 :               mpcap_trace_t *t = vlib_add_trace (vm, node, b[2], sizeof (*t));
     164           3 :               t->next_index = next[2];
     165           3 :               t->sw_if_index = vnet_buffer (b[2])->sw_if_index[VLIB_RX];
     166             :             }
     167           3 :           if (b[3]->flags & VLIB_BUFFER_IS_TRACED)
     168             :             {
     169           3 :               mpcap_trace_t *t = vlib_add_trace (vm, node, b[3], sizeof (*t));
     170           3 :               t->next_index = next[3];
     171           3 :               t->sw_if_index = vnet_buffer (b[3])->sw_if_index[VLIB_RX];
     172             :             }
     173             :         }
     174             : 
     175           3 :       b += 4;
     176           3 :       next += 4;
     177           3 :       n_left_from -= 4;
     178             :     }
     179             : 
     180           4 :   while (n_left_from > 0)
     181             :     {
     182           3 :       mpcap_add_buffer (mm, vm, now, from[i++],
     183           3 :                         vlib_buffer_length_in_chain (vm, b[0]));
     184           3 :       next[0] = 0;
     185           3 :       b[0]->error = error_index;
     186             : 
     187           3 :       if (is_trace)
     188             :         {
     189           3 :           if (b[0]->flags & VLIB_BUFFER_IS_TRACED)
     190             :             {
     191           3 :               mpcap_trace_t *t = vlib_add_trace (vm, node, b[0], sizeof (*t));
     192           3 :               t->next_index = next[0];
     193           3 :               t->sw_if_index = vnet_buffer (b[0])->sw_if_index[VLIB_RX];
     194             :             }
     195             :         }
     196             : 
     197           3 :       b += 1;
     198           3 :       next += 1;
     199           3 :       n_left_from -= 1;
     200             :     }
     201             : 
     202           1 :   vlib_buffer_enqueue_to_next (vm, node, from, nexts, frame->n_vectors);
     203             : 
     204           1 :   return frame->n_vectors;
     205             : }
     206             : 
     207         560 : VLIB_NODE_FN (mpcap_node) (vlib_main_t * vm, vlib_node_runtime_t * node,
     208             :                            vlib_frame_t * frame)
     209             : {
     210           1 :   if (PREDICT_FALSE (node->flags & VLIB_NODE_FLAG_TRACE))
     211           1 :     return mpcap_inline (vm, node, frame, 1 /* is_ip4 */ ,
     212             :                          1 /* is_trace */ );
     213             :   else
     214           0 :     return mpcap_inline (vm, node, frame, 1 /* is_ip4 */ ,
     215             :                          0 /* is_trace */ );
     216             : }
     217             : 
     218             : /* *INDENT-OFF* */
     219             : #ifndef CLIB_MARCH_VARIANT
     220       23519 : VLIB_REGISTER_NODE (mpcap_node) =
     221             : {
     222             :   .name = "mpcap-unittest",
     223             :   .vector_size = sizeof (u32),
     224             :   .format_trace = format_mpcap_trace,
     225             :   .format_buffer = format_ethernet_header_with_length,
     226             :   .unformat_buffer = unformat_ethernet_header,
     227             : 
     228             :   .type = VLIB_NODE_TYPE_INTERNAL,
     229             : 
     230             :   .n_errors = ARRAY_LEN(mpcap_error_strings),
     231             :   .error_strings = mpcap_error_strings,
     232             : 
     233             :   .n_next_nodes = MPCAP_N_NEXT,
     234             : 
     235             :   /* edit / add dispositions here */
     236             :   .next_nodes =
     237             :   {
     238             :     [MPCAP_NEXT_DROP] = "error-drop",
     239             :   },
     240             : };
     241             : 
     242             : static clib_error_t *
     243         559 : mpcap_node_init (vlib_main_t *vm)
     244             : {
     245             :   /* So we can send ethernet/IP packets from the pg... */
     246         559 :   ethernet_setup_node (vm, mpcap_node.index);
     247         559 :   return 0;
     248             : }
     249        5039 : VLIB_INIT_FUNCTION (mpcap_node_init);
     250             : 
     251             : #endif /* CLIB_MARCH_VARIANT */
     252             : /* *INDENT-ON* */
     253             : 
     254             : /*
     255             :  * fd.io coding-style-patch-verification: ON
     256             :  *
     257             :  * Local Variables:
     258             :  * eval: (c-set-style "gnu")
     259             :  * End:
     260             :  */

Generated by: LCOV version 1.14