LCOV - code coverage report
Current view: top level - vnet/dpo - ip6_ll_dpo.c (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 48 51 94.1 %
Date: 2023-07-05 22:20:52 Functions: 10 10 100.0 %

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2018 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             :  * @brief
      17             :  * The data-path object representing performing a lookup in the IPv6
      18             :  * link local table
      19             :  */
      20             : 
      21             : #include <vnet/dpo/ip6_ll_dpo.h>
      22             : #include <vnet/ip/ip6_ll_table.h>
      23             : 
      24             : /**
      25             :  * @brief the IP6 link-local DPO is global
      26             :  */
      27             : static dpo_id_t ip6_ll_dpo = {
      28             :   .dpoi_type = DPO_IP6_LL,
      29             :   .dpoi_proto = DPO_PROTO_IP6,
      30             :   .dpoi_index = 0,
      31             : };
      32             : 
      33             : const dpo_id_t *
      34        2741 : ip6_ll_dpo_get (void)
      35             : {
      36        2741 :   return (&ip6_ll_dpo);
      37             : }
      38             : 
      39             : static void
      40       13705 : ip6_ll_dpo_lock (dpo_id_t * dpo)
      41             : {
      42             :   /*
      43             :    * not maintaining a lock count on the ip6_ll, they are const global and
      44             :    * never die.
      45             :    */
      46       13705 : }
      47             : 
      48             : static void
      49       11995 : ip6_ll_dpo_unlock (dpo_id_t * dpo)
      50             : {
      51       11995 : }
      52             : 
      53             : static u8 *
      54         202 : format_ip6_ll_dpo (u8 * s, va_list * ap)
      55             : {
      56         202 :   CLIB_UNUSED (index_t index) = va_arg (*ap, index_t);
      57         202 :   CLIB_UNUSED (u32 indent) = va_arg (*ap, u32);
      58             : 
      59         202 :   return (format (s, "ip6-link-local"));
      60             : }
      61             : 
      62             : const static dpo_vft_t ip6_ll_vft = {
      63             :   .dv_lock = ip6_ll_dpo_lock,
      64             :   .dv_unlock = ip6_ll_dpo_unlock,
      65             :   .dv_format = format_ip6_ll_dpo,
      66             : };
      67             : 
      68             : /**
      69             :  * @brief The per-protocol VLIB graph nodes that are assigned to a ip6_ll
      70             :  *        object.
      71             :  *
      72             :  * this means that these graph nodes are ones from which a ip6_ll is the
      73             :  * parent object in the DPO-graph.
      74             :  */
      75             : const static char *const ip6_null_nodes[] = {
      76             :   "ip6-link-local",
      77             :   NULL,
      78             : };
      79             : 
      80             : const static char *const *const ip6_ll_nodes[DPO_PROTO_NUM] = {
      81             :   [DPO_PROTO_IP6] = ip6_null_nodes,
      82             : };
      83             : 
      84             : typedef struct ip6_ll_dpo_trace_t_
      85             : {
      86             :   u32 fib_index;
      87             :   u32 sw_if_index;
      88             : } ip6_ll_dpo_trace_t;
      89             : 
      90             : /**
      91             :  * @brief Exit nodes from a IP6_LL
      92             :  */
      93             : typedef enum ip6_ll_next_t_
      94             : {
      95             :   IP6_LL_NEXT_DROP,
      96             :   IP6_LL_NEXT_LOOKUP,
      97             :   IP6_LL_NEXT_NUM,
      98             : } ip6_ll_next_t;
      99             : 
     100             : typedef enum ip6_ll_error_t_
     101             : {
     102             :   IP6_LL_ERROR_NO_TABLE,
     103             : } ip6_ll_error_t;
     104             : 
     105             : always_inline uword
     106          45 : ip6_ll_dpo_inline (vlib_main_t * vm,
     107             :                    vlib_node_runtime_t * node, vlib_frame_t * frame)
     108             : {
     109             :   u32 n_left_from, next_index, *from, *to_next;
     110             : 
     111          45 :   from = vlib_frame_vector_args (frame);
     112          45 :   n_left_from = frame->n_vectors;
     113          45 :   next_index = node->cached_next_index;
     114             : 
     115          90 :   while (n_left_from > 0)
     116             :     {
     117             :       u32 n_left_to_next;
     118             : 
     119          45 :       vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
     120             : 
     121          90 :       while (n_left_from > 0 && n_left_to_next > 0)
     122             :         {
     123             :           u32 bi0, fib_index0, next0;
     124             :           vlib_buffer_t *p0;
     125             : 
     126          45 :           bi0 = from[0];
     127          45 :           to_next[0] = bi0;
     128          45 :           from += 1;
     129          45 :           to_next += 1;
     130          45 :           n_left_from -= 1;
     131          45 :           n_left_to_next -= 1;
     132          45 :           next0 = IP6_LL_NEXT_LOOKUP;
     133             : 
     134          45 :           p0 = vlib_get_buffer (vm, bi0);
     135             : 
     136             :           /* use the packet's RX interface to pick the link-local FIB */
     137             :           fib_index0 =
     138          45 :             ip6_ll_fib_get (vnet_buffer (p0)->sw_if_index[VLIB_RX]);
     139             : 
     140          45 :           if (~0 == fib_index0)
     141             :             {
     142           0 :               next0 = IP6_LL_NEXT_DROP;
     143           0 :               p0->error = node->errors[IP6_LL_ERROR_NO_TABLE];
     144           0 :               goto trace0;
     145             :             }
     146             : 
     147             :           /* write that fib index into the packet so it's used in the
     148             :            * lookup node next */
     149          45 :           vnet_buffer (p0)->sw_if_index[VLIB_TX] = fib_index0;
     150             : 
     151          45 :         trace0:
     152          45 :           if (PREDICT_FALSE (p0->flags & VLIB_BUFFER_IS_TRACED))
     153             :             {
     154          45 :               ip6_ll_dpo_trace_t *tr = vlib_add_trace (vm, node, p0,
     155             :                                                        sizeof (*tr));
     156          45 :               tr->sw_if_index = vnet_buffer (p0)->sw_if_index[VLIB_RX];
     157          45 :               tr->fib_index = fib_index0;
     158             :             }
     159          45 :           vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next,
     160             :                                            n_left_to_next, bi0, next0);
     161             :         }
     162             : 
     163          45 :       vlib_put_next_frame (vm, node, next_index, n_left_to_next);
     164             :     }
     165             : 
     166          45 :   return frame->n_vectors;
     167             : }
     168             : 
     169             : static u8 *
     170          28 : format_ip6_ll_dpo_trace (u8 * s, va_list * args)
     171             : {
     172          28 :   CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
     173          28 :   CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
     174          28 :   ip6_ll_dpo_trace_t *t = va_arg (*args, ip6_ll_dpo_trace_t *);
     175             : 
     176          28 :   s = format (s, "sw_if_index:%d fib_index:%d", t->sw_if_index, t->fib_index);
     177          28 :   return s;
     178             : }
     179             : 
     180             : static uword
     181          45 : ip6_ll_dpo_switch (vlib_main_t * vm,
     182             :                    vlib_node_runtime_t * node, vlib_frame_t * frame)
     183             : {
     184          45 :   return (ip6_ll_dpo_inline (vm, node, frame));
     185             : }
     186             : 
     187             : static char *ip6_ll_dpo_error_strings[] = {
     188             :   [IP6_LL_ERROR_NO_TABLE] = "Interface is not mapped to an IP6-LL table",
     189             : };
     190             : 
     191             : /**
     192             :  * @brief
     193             :  */
     194             : /* *INDENT-OFF* */
     195      178120 : VLIB_REGISTER_NODE (ip6_ll_dpo_node) =
     196             : {
     197             :   .function = ip6_ll_dpo_switch,
     198             :   .name = "ip6-link-local",
     199             :   .vector_size = sizeof (u32),
     200             :   .format_trace = format_ip6_ll_dpo_trace,
     201             :   .n_errors = ARRAY_LEN (ip6_ll_dpo_error_strings),
     202             :   .error_strings = ip6_ll_dpo_error_strings,
     203             :   .n_next_nodes = IP6_LL_NEXT_NUM,
     204             :   .next_nodes = {
     205             :     [IP6_LL_NEXT_DROP] = "ip6-drop",
     206             :     [IP6_LL_NEXT_LOOKUP] = "ip6-lookup",
     207             :   },
     208             : };
     209             : /* *INDENT-ON* */
     210             : 
     211             : void
     212         559 : ip6_ll_dpo_module_init (void)
     213             : {
     214         559 :   dpo_register (DPO_IP6_LL, &ip6_ll_vft, ip6_ll_nodes);
     215         559 : }
     216             : 
     217             : /*
     218             :  * fd.io coding-style-patch-verification: ON
     219             :  *
     220             :  * Local Variables:
     221             :  * eval: (c-set-style "gnu")
     222             :  * End:
     223             :  */

Generated by: LCOV version 1.14