LCOV - code coverage report
Current view: top level - vnet/adj - adj_nsh.c (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 6 52 11.5 %
Date: 2023-07-05 22:20:52 Functions: 16 26 61.5 %

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2017 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_nsh.h>
      18             : #include <vnet/ip/ip.h>
      19             : 
      20             : #ifndef CLIB_MARCH_VARIANT
      21             : nsh_main_placeholder_t nsh_main_placeholder;
      22             : #endif /* CLIB_MARCH_VARIANT */
      23             : 
      24             : /**
      25             :  * @brief Trace data for a NSH Midchain
      26             :  */
      27             : typedef struct adj_nsh_trace_t_ {
      28             :     /** Adjacency index taken. */
      29             :     u32 adj_index;
      30             : } adj_nsh_trace_t;
      31             : 
      32             : static u8 *
      33           0 : format_adj_nsh_trace (u8 * s, va_list * args)
      34             : {
      35           0 :     CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
      36           0 :     CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
      37           0 :     adj_nsh_trace_t * t = va_arg (*args, adj_nsh_trace_t *);
      38             : 
      39           0 :     s = format (s, "adj-idx %d : %U",
      40             :                 t->adj_index,
      41             :                 format_ip_adjacency, t->adj_index, FORMAT_IP_ADJACENCY_NONE);
      42           0 :     return s;
      43             : }
      44             : 
      45             : typedef enum adj_nsh_rewrite_next_t_
      46             : {
      47             :     ADJ_NSH_REWRITE_NEXT_DROP,
      48             : } adj_gpe_rewrite_next_t;
      49             : 
      50             : always_inline uword
      51           0 : adj_nsh_rewrite_inline (vlib_main_t * vm,
      52             :                        vlib_node_runtime_t * node,
      53             :                        vlib_frame_t * frame,
      54             :                        int is_midchain)
      55             : {
      56           0 :     u32 * from = vlib_frame_vector_args (frame);
      57             :     u32 n_left_from, n_left_to_next, * to_next, next_index;
      58           0 :     u32 thread_index = vlib_get_thread_index();
      59             : 
      60           0 :     n_left_from = frame->n_vectors;
      61           0 :     next_index = node->cached_next_index;
      62             : 
      63           0 :     while (n_left_from > 0)
      64             :     {
      65           0 :         vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
      66             : 
      67           0 :         while (n_left_from > 0 && n_left_to_next > 0)
      68             :         {
      69             :             ip_adjacency_t * adj0;
      70             :             vlib_buffer_t * p0;
      71             :             char *h0;
      72           0 :             u32 pi0, rw_len0, adj_index0, next0 = 0;
      73             :             u32 tx_sw_if_index0;
      74             : 
      75           0 :             pi0 = to_next[0] = from[0];
      76           0 :             from += 1;
      77           0 :             n_left_from -= 1;
      78           0 :             to_next += 1;
      79           0 :             n_left_to_next -= 1;
      80             : 
      81           0 :             p0 = vlib_get_buffer (vm, pi0);
      82           0 :             h0 = vlib_buffer_get_current (p0);
      83             : 
      84           0 :             adj_index0 = vnet_buffer (p0)->ip.adj_index[VLIB_TX];
      85             : 
      86             :             /* We should never rewrite a pkt using the MISS adjacency */
      87           0 :             ASSERT(adj_index0);
      88             : 
      89           0 :             adj0 = adj_get (adj_index0);
      90             : 
      91             :             /* Guess we are only writing on simple IP4 header. */
      92           0 :             vnet_rewrite_one_header(adj0[0], h0, sizeof(ip4_header_t));
      93             : 
      94             :             /* Update packet buffer attributes/set output interface. */
      95           0 :             rw_len0 = adj0[0].rewrite_header.data_bytes;
      96           0 :             vnet_buffer(p0)->ip.save_rewrite_length = rw_len0;
      97             : 
      98           0 :             vlib_increment_combined_counter(&adjacency_counters,
      99             :                                             thread_index,
     100             :                                             adj_index0,
     101             :                                             /* packet increment */ 0,
     102             :                                             /* byte increment */ rw_len0);
     103             : 
     104             :             /* Check MTU of outgoing interface. */
     105           0 :             if (PREDICT_TRUE((vlib_buffer_length_in_chain (vm, p0)  <=
     106             :                               adj0[0].rewrite_header.max_l3_packet_bytes)))
     107             :             {
     108             :                 /* Don't adjust the buffer for ttl issue; icmp-error node wants
     109             :                  * to see the IP header */
     110           0 :                 p0->current_data -= rw_len0;
     111           0 :                 p0->current_length += rw_len0;
     112           0 :                 tx_sw_if_index0 = adj0[0].rewrite_header.sw_if_index;
     113             : 
     114           0 :                 if (is_midchain)
     115             :                 {
     116           0 :                     adj0->sub_type.midchain.fixup_func(
     117             :                         vm, adj0, p0,
     118             :                         adj0->sub_type.midchain.fixup_data);
     119             :                 }
     120             : 
     121           0 :                 vnet_buffer (p0)->sw_if_index[VLIB_TX] = tx_sw_if_index0;
     122             : 
     123             :                 /*
     124             :                  * Follow the feature ARC. this will result eventually in
     125             :                  * the midchain-tx node
     126             :                  */
     127           0 :                 vnet_feature_arc_start (nsh_main_placeholder.output_feature_arc_index,
     128             :                                         tx_sw_if_index0, &next0, p0);
     129             :             }
     130             :             else
     131             :             {
     132             :                 /* can't fragment NSH */
     133           0 :                 next0 = ADJ_NSH_REWRITE_NEXT_DROP;
     134             :             }
     135             : 
     136           0 :             if (PREDICT_FALSE(p0->flags & VLIB_BUFFER_IS_TRACED))
     137             :             {
     138           0 :                 adj_nsh_trace_t *tr = vlib_add_trace (vm, node,
     139             :                                                      p0, sizeof (*tr));
     140           0 :                 tr->adj_index = vnet_buffer(p0)->ip.adj_index[VLIB_TX];
     141             :             }
     142             : 
     143           0 :             vlib_validate_buffer_enqueue_x1 (vm, node, next_index,
     144             :                                              to_next, n_left_to_next,
     145             :                                              pi0, next0);
     146             :         }
     147             : 
     148           0 :         vlib_put_next_frame (vm, node, next_index, n_left_to_next);
     149             :     }
     150             : 
     151           0 :     return frame->n_vectors;
     152             : }
     153             : 
     154        2236 : VLIB_NODE_FN (adj_nsh_rewrite_node) (vlib_main_t * vm,
     155             :                 vlib_node_runtime_t * node,
     156             :                 vlib_frame_t * frame)
     157             : {
     158           0 :     return adj_nsh_rewrite_inline (vm, node, frame, 0);
     159             : }
     160             : 
     161        2236 : VLIB_NODE_FN (adj_nsh_midchain_node) (vlib_main_t * vm,
     162             :                  vlib_node_runtime_t * node,
     163             :                  vlib_frame_t * frame)
     164             : {
     165           0 :     return adj_nsh_rewrite_inline (vm, node, frame, 1);
     166             : }
     167             : 
     168      178120 : VLIB_REGISTER_NODE (adj_nsh_rewrite_node) = {
     169             :     .name = "adj-nsh-rewrite",
     170             :     .vector_size = sizeof (u32),
     171             : 
     172             :     .format_trace = format_adj_nsh_trace,
     173             : 
     174             :     .n_next_nodes = 1,
     175             :     .next_nodes = {
     176             :         [ADJ_NSH_REWRITE_NEXT_DROP] = "error-drop",
     177             :     },
     178             : };
     179             : 
     180      178120 : VLIB_REGISTER_NODE (adj_nsh_midchain_node) = {
     181             :     .name = "adj-nsh-midchain",
     182             :     .vector_size = sizeof (u32),
     183             : 
     184             :     .format_trace = format_adj_nsh_trace,
     185             : 
     186             :     .n_next_nodes = 1,
     187             :     .next_nodes = {
     188             :         [ADJ_NSH_REWRITE_NEXT_DROP] = "error-drop",
     189             :     },
     190             : };
     191             : 
     192             : /* Built-in ip4 tx feature path definition */
     193             : /* *INDENT-OFF* */
     194        1119 : VNET_FEATURE_ARC_INIT (nsh_output, static) =
     195             : {
     196             :   .arc_name  = "nsh-output",
     197             :   .start_nodes = VNET_FEATURES ("adj-nsh-midchain"),
     198             :   .arc_index_ptr = &nsh_main_placeholder.output_feature_arc_index,
     199             : };
     200             : 
     201       70583 : VNET_FEATURE_INIT (nsh_tx_drop, static) =
     202             : {
     203             :   .arc_name = "nsh-output",
     204             :   .node_name = "error-drop",
     205             :   .runs_before = 0,     /* not before any other features */
     206             : };
     207             : /* *INDENT-ON* */

Generated by: LCOV version 1.14