LCOV - code coverage report
Current view: top level - vnet/adj - adj_l2.c (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 53 61 86.9 %
Date: 2023-07-05 22:20:52 Functions: 15 22 68.2 %

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2016 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 <vnet/vnet.h>
      17             : #include <vnet/adj/adj_l2.h>
      18             : #include <vnet/ethernet/ethernet.h>
      19             : #include <vnet/ip/ip.h>
      20             : 
      21             : /**
      22             :  * @brief Trace data for a L2 Midchain
      23             :  */
      24             : typedef struct adj_l2_trace_t_ {
      25             :     /** Adjacency index taken. */
      26             :     u32 adj_index;
      27             : } adj_l2_trace_t;
      28             : 
      29             : static u8 *
      30        1699 : format_adj_l2_trace (u8 * s, va_list * args)
      31             : {
      32        1699 :     CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
      33        1699 :     CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
      34        1699 :     adj_l2_trace_t * t = va_arg (*args, adj_l2_trace_t *);
      35             : 
      36        1699 :     s = format (s, "adj-idx %d : %U",
      37             :                 t->adj_index,
      38             :                 format_ip_adjacency, t->adj_index, FORMAT_IP_ADJACENCY_NONE);
      39        1699 :     return s;
      40             : }
      41             : 
      42             : typedef enum adj_l2_rewrite_next_t_
      43             : {
      44             :     ADJ_L2_REWRITE_NEXT_DROP,
      45             : } adj_l2_rewrite_next_t;
      46             : 
      47             : always_inline uword
      48          28 : adj_l2_rewrite_inline (vlib_main_t * vm,
      49             :                        vlib_node_runtime_t * node,
      50             :                        vlib_frame_t * frame,
      51             :                        int is_midchain,
      52             :                        int do_counters)
      53             : {
      54          28 :     u32 * from = vlib_frame_vector_args (frame);
      55             :     u32 n_left_from, n_left_to_next, * to_next, next_index;
      56          28 :     u32 thread_index = vlib_get_thread_index();
      57          28 :     ethernet_main_t * em = &ethernet_main;
      58             : 
      59          28 :     n_left_from = frame->n_vectors;
      60          28 :     next_index = node->cached_next_index;
      61             : 
      62          56 :     while (n_left_from > 0)
      63             :     {
      64          28 :         vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
      65             : 
      66        2090 :         while (n_left_from > 0 && n_left_to_next > 0)
      67             :         {
      68             :             ip_adjacency_t * adj0;
      69             :             vlib_buffer_t * p0;
      70             :             char *h0;
      71        2062 :             u32 pi0, rw_len0, len0, adj_index0, next0 = 0;
      72             :             u32 tx_sw_if_index0;
      73             : 
      74        2062 :             pi0 = to_next[0] = from[0];
      75        2062 :             from += 1;
      76        2062 :             n_left_from -= 1;
      77        2062 :             to_next += 1;
      78        2062 :             n_left_to_next -= 1;
      79             : 
      80        2062 :             p0 = vlib_get_buffer (vm, pi0);
      81        2062 :             h0 = vlib_buffer_get_current (p0);
      82             : 
      83        2062 :             adj_index0 = vnet_buffer (p0)->ip.adj_index[VLIB_TX];
      84             : 
      85        2062 :             adj0 = adj_get (adj_index0);
      86             : 
      87             :             /* Guess we are writing on ip4 header. */
      88        2062 :             vnet_rewrite_one_header (adj0[0], h0,
      89             :                                      //sizeof (gre_header_t) +
      90             :                                      sizeof (ip4_header_t));
      91             : 
      92             :             /* Update packet buffer attributes/set output interface. */
      93        2062 :             rw_len0 = adj0[0].rewrite_header.data_bytes;
      94        2062 :             vnet_buffer(p0)->ip.save_rewrite_length = rw_len0;
      95        2062 :             vnet_buffer(p0)->sw_if_index[VLIB_TX] = adj0->rewrite_header.sw_if_index;
      96        2062 :             len0 = vlib_buffer_length_in_chain (vm, p0);
      97             :             /* since we are coming out of the L2 world, where the vlib_buffer
      98             :              * union is used for other things, make sure it is clean for
      99             :              * MPLS from now on.
     100             :              */
     101        2062 :             vnet_buffer(p0)->mpls.first = 0;
     102             : 
     103        2062 :             if (do_counters)
     104           0 :                 vlib_increment_combined_counter(&adjacency_counters,
     105             :                                                 thread_index,
     106             :                                                 adj_index0,
     107             :                                                 0, len0);
     108             : 
     109             :             /* Check MTU of outgoing interface. */
     110        2062 :             if (PREDICT_TRUE(len0 <= adj0[0].rewrite_header.max_l3_packet_bytes))
     111             :             {
     112             :                 /* Don't adjust the buffer for ttl issue; icmp-error node wants
     113             :                  * to see the IP header */
     114        2062 :                 p0->current_data -= rw_len0;
     115        2062 :                 p0->current_length += rw_len0;
     116        2062 :                 tx_sw_if_index0 = adj0[0].rewrite_header.sw_if_index;
     117             : 
     118        2062 :                 if (is_midchain)
     119             :                 {
     120        2062 :                     adj0->sub_type.midchain.fixup_func(
     121             :                         vm, adj0, p0,
     122             :                         adj0->sub_type.midchain.fixup_data);
     123             :                 }
     124             : 
     125        2062 :                 vnet_buffer (p0)->sw_if_index[VLIB_TX] = tx_sw_if_index0;
     126             : 
     127             :                 /*
     128             :                  * Follow the feature ARC. this will result eventually in
     129             :                  * the midchain-tx node
     130             :                  */
     131        2062 :                 if (PREDICT_FALSE (adj0->rewrite_header.flags &
     132             :                                    VNET_REWRITE_HAS_FEATURES))
     133           0 :                     vnet_feature_arc_start_w_cfg_index (
     134           0 :                         em->output_feature_arc_index,
     135             :                         tx_sw_if_index0,
     136             :                         &next0, p0,
     137             :                         adj0->ia_cfg_index);
     138             :                 else
     139        2062 :                     next0 = adj0[0].rewrite_header.next_index;
     140             :             }
     141             :             else
     142             :             {
     143             :                 /* can't fragment L2 */
     144           0 :                 next0 = ADJ_L2_REWRITE_NEXT_DROP;
     145             :             }
     146             : 
     147        2062 :             if (PREDICT_FALSE(p0->flags & VLIB_BUFFER_IS_TRACED))
     148             :             {
     149        2062 :                 adj_l2_trace_t *tr = vlib_add_trace (vm, node,
     150             :                                                      p0, sizeof (*tr));
     151        2062 :                 tr->adj_index = vnet_buffer(p0)->ip.adj_index[VLIB_TX];
     152             :             }
     153             : 
     154        2062 :             vlib_validate_buffer_enqueue_x1 (vm, node, next_index,
     155             :                                              to_next, n_left_to_next,
     156             :                                              pi0, next0);
     157             :         }
     158             : 
     159          28 :         vlib_put_next_frame (vm, node, next_index, n_left_to_next);
     160             :     }
     161             : 
     162          28 :     return frame->n_vectors;
     163             : }
     164             : 
     165        2236 : VLIB_NODE_FN (adj_l2_rewrite_node) (vlib_main_t * vm,
     166             :                 vlib_node_runtime_t * node,
     167             :                 vlib_frame_t * frame)
     168             : {
     169           0 :   if (adj_are_counters_enabled ())
     170           0 :       return adj_l2_rewrite_inline (vm, node, frame, 0, 1);
     171             :   else
     172           0 :       return adj_l2_rewrite_inline (vm, node, frame, 0, 0);
     173             : }
     174             : 
     175        2264 : VLIB_NODE_FN (adj_l2_midchain_node) (vlib_main_t * vm,
     176             :                  vlib_node_runtime_t * node,
     177             :                  vlib_frame_t * frame)
     178             : {
     179          28 :   if (adj_are_counters_enabled ())
     180           0 :       return adj_l2_rewrite_inline (vm, node, frame, 1, 1);
     181             :   else
     182          28 :       return adj_l2_rewrite_inline (vm, node, frame, 1, 0);
     183             : }
     184             : 
     185      178120 : VLIB_REGISTER_NODE (adj_l2_rewrite_node) = {
     186             :     .name = "adj-l2-rewrite",
     187             :     .vector_size = sizeof (u32),
     188             : 
     189             :     .format_trace = format_adj_l2_trace,
     190             : 
     191             :     .n_next_nodes = 1,
     192             :     .next_nodes = {
     193             :         [ADJ_L2_REWRITE_NEXT_DROP] = "error-drop",
     194             :     },
     195             : };
     196             : 
     197      178120 : VLIB_REGISTER_NODE (adj_l2_midchain_node) = {
     198             :     .name = "adj-l2-midchain",
     199             :     .vector_size = sizeof (u32),
     200             : 
     201             :     .format_trace = format_adj_l2_trace,
     202             : 
     203             :     .n_next_nodes = 1,
     204             :     .next_nodes = {
     205             :         [ADJ_L2_REWRITE_NEXT_DROP] = "error-drop",
     206             :     },
     207             : };

Generated by: LCOV version 1.14