LCOV - code coverage report
Current view: top level - vnet/ethernet - p2p_ethernet_input.c (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 36 87 41.4 %
Date: 2023-10-26 01:39:38 Functions: 7 11 63.6 %

          Line data    Source code
       1             : /*
       2             :  * node.c: p2p ethernet vpp node
       3             :  *
       4             :  * Copyright (c) 2016 Cisco and/or its affiliates.
       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             : 
      18             : #include <vlib/vlib.h>
      19             : #include <vnet/vnet.h>
      20             : #include <vppinfra/error.h>
      21             : 
      22             : #include <vnet/ethernet/p2p_ethernet.h>
      23             : 
      24             : #include <vppinfra/error.h>
      25             : #include <vppinfra/elog.h>
      26             : 
      27             : extern vlib_node_registration_t p2p_ethernet_input_node;
      28             : 
      29             : /* packet trace format function */
      30             : static u8 *
      31           0 : format_p2p_ethernet_trace (u8 * s, va_list * args)
      32             : {
      33           0 :   CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
      34           0 :   CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
      35           0 :   p2p_ethernet_trace_t *t = va_arg (*args, p2p_ethernet_trace_t *);
      36             : 
      37           0 :   vnet_main_t *vnm = &vnet_main;
      38           0 :   s = format (s, "P2P ethernet: %U -> %U",
      39             :               format_vnet_sw_if_index_name, vnm, t->sw_if_index,
      40             :               format_vnet_sw_if_index_name, vnm, t->p2pe_sw_if_index);
      41             : 
      42           0 :   return s;
      43             : }
      44             : 
      45             : #define foreach_p2p_ethernet_error                      \
      46             : _(HITS, "P2P ethernet incoming packets processed")
      47             : 
      48             : typedef enum
      49             : {
      50             : #define _(sym,str) P2PE_ERROR_##sym,
      51             :   foreach_p2p_ethernet_error
      52             : #undef _
      53             :     P2PE_N_ERROR,
      54             : } p2p_ethernet_error_t;
      55             : 
      56             : static char *p2p_ethernet_error_strings[] = {
      57             : #define _(sym,string) string,
      58             :   foreach_p2p_ethernet_error
      59             : #undef _
      60             : };
      61             : 
      62        2307 : VLIB_NODE_FN (p2p_ethernet_input_node) (vlib_main_t * vm,
      63             :                                         vlib_node_runtime_t * node,
      64             :                                         vlib_frame_t * frame)
      65             : {
      66           7 :   u32 thread_index = vm->thread_index;
      67           7 :   u32 n_trace = vlib_get_trace_count (vm, node);
      68             :   u32 n_left_from, *from, *to_next;
      69             :   u32 next_index;
      70           7 :   u32 n_p2p_ethernet_packets = 0;
      71           7 :   vlib_combined_counter_main_t *cm =
      72           7 :     vnet_get_main ()->interface_main.combined_sw_if_counters;
      73             : 
      74           7 :   from = vlib_frame_vector_args (frame);
      75           7 :   n_left_from = frame->n_vectors;
      76           7 :   next_index = node->cached_next_index;
      77             : 
      78          14 :   while (n_left_from > 0)
      79             :     {
      80             :       u32 n_left_to_next;
      81             : 
      82           7 :       vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
      83             : 
      84           7 :       while (n_left_from >= 4 && n_left_to_next >= 2)
      85             :         {
      86             :           u32 bi0, bi1;
      87             :           vlib_buffer_t *b0, *b1;
      88           0 :           u32 next0 = 0, next1 = 0;
      89             :           u32 sw_if_index0, sw_if_index1;
      90             :           ethernet_header_t *en0, *en1;
      91             :           u32 rx0, rx1;
      92             : 
      93           0 :           bi0 = from[0];
      94           0 :           bi1 = from[1];
      95           0 :           to_next[0] = bi0;
      96           0 :           to_next[1] = bi1;
      97           0 :           from += 2;
      98           0 :           to_next += 2;
      99           0 :           n_left_to_next -= 2;
     100           0 :           n_left_from -= 2;
     101             : 
     102           0 :           b0 = vlib_get_buffer (vm, bi0);
     103           0 :           b1 = vlib_get_buffer (vm, bi1);
     104             : 
     105           0 :           en0 = vlib_buffer_get_current (b0);
     106           0 :           sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_RX];
     107           0 :           en1 = vlib_buffer_get_current (b1);
     108           0 :           sw_if_index1 = vnet_buffer (b1)->sw_if_index[VLIB_RX];
     109             : 
     110           0 :           vnet_feature_next (&next0, b0);
     111           0 :           vnet_feature_next (&next1, b1);
     112             : 
     113           0 :           rx0 = p2p_ethernet_lookup (sw_if_index0, en0->src_address);
     114           0 :           rx1 = p2p_ethernet_lookup (sw_if_index1, en1->src_address);
     115             : 
     116           0 :           if (rx0 != ~0)
     117             :             {
     118             :               /* Send pkt to p2p_ethernet RX interface */
     119           0 :               vnet_buffer (b0)->sw_if_index[VLIB_RX] = rx0;
     120           0 :               n_p2p_ethernet_packets += 1;
     121             : 
     122           0 :               if (PREDICT_FALSE
     123             :                   (n_trace > 0
     124             :                    && vlib_trace_buffer (vm, node, next_index, b0,
     125             :                                          1 /* follow_chain */ )))
     126             :                 {
     127             :                   p2p_ethernet_trace_t *t0;
     128           0 :                   vlib_set_trace_count (vm, node, --n_trace);
     129           0 :                   t0 = vlib_add_trace (vm, node, b0, sizeof (*t0));
     130           0 :                   t0->sw_if_index = sw_if_index0;
     131           0 :                   t0->p2pe_sw_if_index = rx0;
     132             :                 }
     133             : 
     134           0 :               vlib_increment_combined_counter (cm, thread_index, rx0, 1,
     135             :                                                vlib_buffer_length_in_chain
     136             :                                                (vm, b0));
     137             :             }
     138           0 :           if (rx1 != ~0)
     139             :             {
     140             :               /* Send pkt to p2p_ethernet RX interface */
     141           0 :               vnet_buffer (b1)->sw_if_index[VLIB_RX] = rx1;
     142           0 :               n_p2p_ethernet_packets += 1;
     143             : 
     144           0 :               if (PREDICT_FALSE
     145             :                   (n_trace > 0
     146             :                    && vlib_trace_buffer (vm, node, next_index, b1,
     147             :                                          1 /* follow_chain */ )))
     148             :                 {
     149             :                   p2p_ethernet_trace_t *t1;
     150           0 :                   vlib_set_trace_count (vm, node, --n_trace);
     151           0 :                   t1 = vlib_add_trace (vm, node, b1, sizeof (*t1));
     152           0 :                   t1->sw_if_index = sw_if_index1;
     153           0 :                   t1->p2pe_sw_if_index = rx1;
     154             :                 }
     155             : 
     156           0 :               vlib_increment_combined_counter (cm, thread_index, rx1, 1,
     157             :                                                vlib_buffer_length_in_chain
     158             :                                                (vm, b1));
     159             :             }
     160             : 
     161             :           /* verify speculative enqueue, maybe switch current next frame */
     162           0 :           vlib_validate_buffer_enqueue_x1 (vm, node, next_index,
     163             :                                            to_next, n_left_to_next,
     164             :                                            bi0, next0);
     165           0 :           vlib_validate_buffer_enqueue_x1 (vm, node, next_index,
     166             :                                            to_next, n_left_to_next,
     167             :                                            bi1, next1);
     168             :         }
     169             : 
     170          16 :       while (n_left_from > 0 && n_left_to_next > 0)
     171             :         {
     172             :           u32 bi0;
     173             :           vlib_buffer_t *b0;
     174           9 :           u32 next0 = 0;
     175             :           u32 sw_if_index0;
     176             :           ethernet_header_t *en0;
     177             :           u32 rx0;
     178             : 
     179           9 :           bi0 = from[0];
     180           9 :           to_next[0] = bi0;
     181           9 :           from += 1;
     182           9 :           to_next += 1;
     183           9 :           n_left_from -= 1;
     184           9 :           n_left_to_next -= 1;
     185             : 
     186           9 :           b0 = vlib_get_buffer (vm, bi0);
     187             : 
     188           9 :           en0 = vlib_buffer_get_current (b0);
     189           9 :           sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_RX];
     190             : 
     191           9 :           vnet_feature_next (&next0, b0);
     192             : 
     193           9 :           rx0 = p2p_ethernet_lookup (sw_if_index0, en0->src_address);
     194           9 :           if (rx0 != ~0)
     195             :             {
     196             :               /* Send pkt to p2p_ethernet RX interface */
     197           2 :               vnet_buffer (b0)->sw_if_index[VLIB_RX] = rx0;
     198           2 :               n_p2p_ethernet_packets += 1;
     199             : 
     200           2 :               if (PREDICT_FALSE
     201             :                   (n_trace > 0
     202             :                    && vlib_trace_buffer (vm, node, next_index, b0,
     203             :                                          1 /* follow_chain */ )))
     204             :                 {
     205             :                   p2p_ethernet_trace_t *t0;
     206           0 :                   vlib_set_trace_count (vm, node, --n_trace);
     207           0 :                   t0 = vlib_add_trace (vm, node, b0, sizeof (*t0));
     208           0 :                   t0->sw_if_index = sw_if_index0;
     209           0 :                   t0->p2pe_sw_if_index = rx0;
     210             :                 }
     211             : 
     212           2 :               vlib_increment_combined_counter (cm, thread_index, rx0, 1,
     213             :                                                vlib_buffer_length_in_chain
     214             :                                                (vm, b0));
     215             :             }
     216             :           else
     217             :             {
     218           7 :               if (PREDICT_FALSE (n_trace > 0))
     219             :                 {
     220           0 :                   node->flags |= VLIB_NODE_FLAG_TRACE;
     221             :                 }
     222             :             }
     223             : 
     224             :           /* verify speculative enqueue, maybe switch current next frame */
     225           9 :           vlib_validate_buffer_enqueue_x1 (vm, node, next_index,
     226             :                                            to_next, n_left_to_next,
     227             :                                            bi0, next0);
     228             :         }
     229           7 :       vlib_put_next_frame (vm, node, next_index, n_left_to_next);
     230             :     }
     231             : 
     232           7 :   vlib_node_increment_counter (vm, p2p_ethernet_input_node.index,
     233             :                                P2PE_ERROR_HITS, n_p2p_ethernet_packets);
     234             : 
     235           7 :   return frame->n_vectors;
     236             : }
     237             : 
     238             : /* *INDENT-OFF* */
     239      183788 : VLIB_REGISTER_NODE (p2p_ethernet_input_node) = {
     240             :   .name = "p2p-ethernet-input",
     241             :   .vector_size = sizeof (u32),
     242             :   .format_trace = format_p2p_ethernet_trace,
     243             :   .type = VLIB_NODE_TYPE_INTERNAL,
     244             :   .flags = VLIB_NODE_FLAG_TRACE_SUPPORTED,
     245             : 
     246             :   .n_errors = ARRAY_LEN(p2p_ethernet_error_strings),
     247             :   .error_strings = p2p_ethernet_error_strings,
     248             : 
     249             :   .n_next_nodes = 1,
     250             : 
     251             :   /* edit / add dispositions here */
     252             :   .next_nodes = {
     253             :     [0] = "error-drop",
     254             :   },
     255             : };
     256             : /* *INDENT-ON* */
     257             : 
     258             : /*
     259             :  * fd.io coding-style-patch-verification: ON
     260             :  *
     261             :  * Local Variables:
     262             :  * eval: (c-set-style "gnu")
     263             :  * End:
     264             :  */

Generated by: LCOV version 1.14