LCOV - code coverage report
Current view: top level - plugins/l3xc - l3xc_node.c (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 78 80 97.5 %
Date: 2023-07-05 22:20:52 Functions: 11 12 91.7 %

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2019 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 <plugins/l3xc/l3xc.h>
      17             : #include <vnet/feature/feature.h>
      18             : 
      19             : typedef enum l3xc_next_t_
      20             : {
      21             :   L3XC_NEXT_DROP,
      22             :   L3XC_N_NEXT,
      23             : } l3xc_next_t;
      24             : 
      25             : typedef struct l3xc_input_trace_t_
      26             : {
      27             :   index_t l3xci;
      28             :   index_t lbi;
      29             : } l3xc_input_trace_t;
      30             : 
      31             : typedef enum
      32             : {
      33             : #define l3xc_error(n,s) L3XC_ERROR_##n,
      34             : #include "l3xc_error.def"
      35             : #undef l3xc_error
      36             :   L3XC_N_ERROR,
      37             : } l3xc_error_t;
      38             : 
      39             : always_inline uword
      40           1 : l3xc_input_inline (vlib_main_t * vm,
      41             :                    vlib_node_runtime_t * node,
      42             :                    vlib_frame_t * frame, fib_protocol_t fproto)
      43             : {
      44             :   vlib_buffer_t *bufs[VLIB_FRAME_SIZE], **b;
      45             :   u16 nexts[VLIB_FRAME_SIZE], *next;
      46             :   u32 n_left, *from;
      47             : 
      48           1 :   from = vlib_frame_vector_args (frame);
      49           1 :   n_left = frame->n_vectors;
      50           1 :   b = bufs;
      51           1 :   next = nexts;
      52             : 
      53           1 :   vlib_get_buffers (vm, from, bufs, n_left);
      54             : 
      55          16 :   while (n_left >= 8)
      56             :     {
      57             :       const l3xc_t *l3xc0, *l3xc1, *l3xc2, *l3xc3;
      58             :       u32 l3xci0, l3xci1, l3xci2, l3xci3;
      59             :       u32 next_u32;
      60             : 
      61             :       /* Prefetch next iteration. */
      62             :       {
      63          15 :         vlib_prefetch_buffer_header (b[4], LOAD);
      64          15 :         vlib_prefetch_buffer_header (b[5], LOAD);
      65          15 :         vlib_prefetch_buffer_header (b[6], LOAD);
      66          15 :         vlib_prefetch_buffer_header (b[7], LOAD);
      67             :       }
      68             : 
      69          15 :       l3xci0 =
      70          15 :         *(u32 *) vnet_feature_next_with_data (&next_u32, b[0],
      71             :                                               sizeof (l3xci0));
      72          15 :       l3xci1 =
      73          15 :         *(u32 *) vnet_feature_next_with_data (&next_u32, b[1],
      74             :                                               sizeof (l3xci1));
      75          15 :       l3xci2 =
      76          15 :         *(u32 *) vnet_feature_next_with_data (&next_u32, b[2],
      77             :                                               sizeof (l3xci2));
      78          15 :       l3xci3 =
      79          15 :         *(u32 *) vnet_feature_next_with_data (&next_u32, b[3],
      80             :                                               sizeof (l3xci3));
      81             : 
      82          15 :       l3xc0 = l3xc_get (l3xci0);
      83          15 :       l3xc1 = l3xc_get (l3xci1);
      84          15 :       l3xc2 = l3xc_get (l3xci2);
      85          15 :       l3xc3 = l3xc_get (l3xci3);
      86             : 
      87          15 :       next[0] = l3xc0->l3xc_dpo.dpoi_next_node;
      88          15 :       next[1] = l3xc1->l3xc_dpo.dpoi_next_node;
      89          15 :       next[2] = l3xc2->l3xc_dpo.dpoi_next_node;
      90          15 :       next[3] = l3xc3->l3xc_dpo.dpoi_next_node;
      91             : 
      92          15 :       vnet_buffer (b[0])->ip.adj_index[VLIB_TX] = l3xc0->l3xc_dpo.dpoi_index;
      93          15 :       vnet_buffer (b[1])->ip.adj_index[VLIB_TX] = l3xc1->l3xc_dpo.dpoi_index;
      94          15 :       vnet_buffer (b[2])->ip.adj_index[VLIB_TX] = l3xc2->l3xc_dpo.dpoi_index;
      95          15 :       vnet_buffer (b[3])->ip.adj_index[VLIB_TX] = l3xc3->l3xc_dpo.dpoi_index;
      96             : 
      97          15 :       if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE)))
      98             :         {
      99          15 :           if (PREDICT_FALSE (b[0]->flags & VLIB_BUFFER_IS_TRACED))
     100             :             {
     101             :               l3xc_input_trace_t *tr;
     102             : 
     103          15 :               tr = vlib_add_trace (vm, node, b[0], sizeof (*tr));
     104          15 :               tr->l3xci = l3xci0;
     105          15 :               tr->lbi = vnet_buffer (b[0])->ip.adj_index[VLIB_TX];
     106             :             }
     107          15 :           if (PREDICT_FALSE (b[1]->flags & VLIB_BUFFER_IS_TRACED))
     108             :             {
     109             :               l3xc_input_trace_t *tr;
     110             : 
     111          15 :               tr = vlib_add_trace (vm, node, b[1], sizeof (*tr));
     112          15 :               tr->l3xci = l3xci1;
     113          15 :               tr->lbi = vnet_buffer (b[1])->ip.adj_index[VLIB_TX];
     114             :             }
     115          15 :           if (PREDICT_FALSE (b[2]->flags & VLIB_BUFFER_IS_TRACED))
     116             :             {
     117             :               l3xc_input_trace_t *tr;
     118             : 
     119          15 :               tr = vlib_add_trace (vm, node, b[2], sizeof (*tr));
     120          15 :               tr->l3xci = l3xci2;
     121          15 :               tr->lbi = vnet_buffer (b[2])->ip.adj_index[VLIB_TX];
     122             :             }
     123          15 :           if (PREDICT_FALSE (b[3]->flags & VLIB_BUFFER_IS_TRACED))
     124             :             {
     125             :               l3xc_input_trace_t *tr;
     126             : 
     127          15 :               tr = vlib_add_trace (vm, node, b[3], sizeof (*tr));
     128          15 :               tr->l3xci = l3xci3;
     129          15 :               tr->lbi = vnet_buffer (b[3])->ip.adj_index[VLIB_TX];
     130             :             }
     131             :         }
     132             : 
     133          15 :       b += 4;
     134          15 :       next += 4;
     135          15 :       n_left -= 4;
     136             :     }
     137             : 
     138           8 :   while (n_left > 0)
     139             :     {
     140             :       u32 l3xci0, next_u32;
     141             :       const l3xc_t *l3xc0;
     142             : 
     143           7 :       l3xci0 =
     144           7 :         *(u32 *) vnet_feature_next_with_data (&next_u32, b[0],
     145             :                                               sizeof (l3xci0));
     146             : 
     147           7 :       l3xc0 = l3xc_get (l3xci0);
     148             : 
     149           7 :       next[0] = l3xc0->l3xc_dpo.dpoi_next_node;
     150             : 
     151           7 :       vnet_buffer (b[0])->ip.adj_index[VLIB_TX] = l3xc0->l3xc_dpo.dpoi_index;
     152             : 
     153           7 :       if (PREDICT_FALSE (b[0]->flags & VLIB_BUFFER_IS_TRACED))
     154             :         {
     155             :           l3xc_input_trace_t *tr;
     156             : 
     157           7 :           tr = vlib_add_trace (vm, node, b[0], sizeof (*tr));
     158           7 :           tr->l3xci = l3xci0;
     159           7 :           tr->lbi = vnet_buffer (b[0])->ip.adj_index[VLIB_TX];
     160             :         }
     161             : 
     162           7 :       b += 1;
     163           7 :       next += 1;
     164           7 :       n_left -= 1;
     165             :     }
     166             : 
     167           1 :   vlib_buffer_enqueue_to_next (vm, node, from, nexts, frame->n_vectors);
     168           1 :   return frame->n_vectors;
     169             : }
     170             : 
     171             : static uword
     172           1 : l3xc_input_ip4 (vlib_main_t * vm,
     173             :                 vlib_node_runtime_t * node, vlib_frame_t * frame)
     174             : {
     175           1 :   return l3xc_input_inline (vm, node, frame, FIB_PROTOCOL_IP4);
     176             : }
     177             : 
     178             : static uword
     179           0 : l3xc_input_ip6 (vlib_main_t * vm,
     180             :                 vlib_node_runtime_t * node, vlib_frame_t * frame)
     181             : {
     182           0 :   return l3xc_input_inline (vm, node, frame, FIB_PROTOCOL_IP6);
     183             : }
     184             : 
     185             : static u8 *
     186          50 : format_l3xc_input_trace (u8 * s, va_list * args)
     187             : {
     188          50 :   CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
     189          50 :   CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
     190          50 :   l3xc_input_trace_t *t = va_arg (*args, l3xc_input_trace_t *);
     191             : 
     192          50 :   s = format (s, "l3xc-index:%d lb-index:%d", t->l3xci, t->lbi);
     193          50 :   return s;
     194             : }
     195             : 
     196             : static char *l3xc_error_strings[] = {
     197             : #define l3xc_error(n,s) s,
     198             : #include "l3xc_error.def"
     199             : #undef l3xc_error
     200             : };
     201             : 
     202             : /* *INDENT-OFF* */
     203      108120 : VLIB_REGISTER_NODE (l3xc_ip4_node) =
     204             : {
     205             :   .function = l3xc_input_ip4,
     206             :   .name = "l3xc-input-ip4",
     207             :   .vector_size = sizeof (u32),
     208             :   .format_trace = format_l3xc_input_trace,
     209             :   .type = VLIB_NODE_TYPE_INTERNAL,
     210             :   .n_errors = L3XC_N_ERROR,
     211             :   .error_strings = l3xc_error_strings,
     212             :   .n_next_nodes = L3XC_N_NEXT,
     213             :   .next_nodes =
     214             :   {
     215             :     [L3XC_NEXT_DROP] = "error-drop",
     216             :   }
     217             : };
     218             : 
     219      108120 : VLIB_REGISTER_NODE (l3xc_ip6_node) =
     220             : {
     221             :   .function = l3xc_input_ip6,
     222             :   .name = "l3xc-input-ip6",
     223             :   .vector_size = sizeof (u32),
     224             :   .format_trace = format_l3xc_input_trace,
     225             :   .type = VLIB_NODE_TYPE_INTERNAL,
     226             :   .n_errors = 0,
     227             :   .n_next_nodes = L3XC_N_NEXT,
     228             : 
     229             :   .next_nodes =
     230             :   {
     231             :     [L3XC_NEXT_DROP] = "error-drop",
     232             :   }
     233             : };
     234             : 
     235       45943 : VNET_FEATURE_INIT (l3xc_ip4_feat, static) =
     236             : {
     237             :   .arc_name = "ip4-unicast",
     238             :   .node_name = "l3xc-input-ip4",
     239             :   .runs_after = VNET_FEATURES ("acl-plugin-in-ip4-fa"),
     240             : };
     241             : 
     242       45943 : VNET_FEATURE_INIT (l3xc_ip6_feat, static) =
     243             : {
     244             :   .arc_name = "ip6-unicast",
     245             :   .node_name = "l3xc-input-ip6",
     246             :   .runs_after = VNET_FEATURES ("acl-plugin-in-ip6-fa"),
     247             : };
     248             : /* *INDENT-ON* */
     249             : 
     250             : /*
     251             :  * fd.io coding-style-patch-verification: ON
     252             :  *
     253             :  * Local Variables:
     254             :  * eval: (c-set-style "gnu")
     255             :  * End:
     256             :  */

Generated by: LCOV version 1.14