LCOV - code coverage report
Current view: top level - vnet/ip - ip4_options.c (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 39 42 92.9 %
Date: 2023-10-26 01:39:38 Functions: 5 5 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             : /**
      17             :  * @brief Handle IPv4 header options in the data-path
      18             :  */
      19             : 
      20             : #include <vnet/ip/ip.h>
      21             : 
      22             : typedef enum ip4_options_next_t_
      23             : {
      24             :   IP4_OPTIONS_NEXT_PUNT,
      25             :   IP4_OPTIONS_NEXT_LOCAL,
      26             :   IP4_OPTIONS_N_NEXT,
      27             : } ip4_options_next_t;
      28             : 
      29             : typedef struct ip4_options_trace_t_
      30             : {
      31             :   u8 option[4];
      32             : } ip4_options_trace_t;
      33             : 
      34         597 : VLIB_NODE_FN (ip4_options_node) (vlib_main_t * vm,
      35             :                                  vlib_node_runtime_t * node,
      36             :                                  vlib_frame_t * frame)
      37             : {
      38             :   uword n_left_from, n_left_to_next, next_index;
      39             :   u32 *from, *to_next;
      40             : 
      41          22 :   from = vlib_frame_vector_args (frame);
      42          22 :   n_left_from = frame->n_vectors;
      43          22 :   next_index = 0;
      44             : 
      45          44 :   while (n_left_from > 0)
      46             :     {
      47          22 :       vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
      48             : 
      49             :       /*
      50             :        * IP options packets, when properly used, are very low rate,
      51             :        * so this code is not dual-looped for extra performance.
      52             :        */
      53          46 :       while (n_left_from > 0 && n_left_to_next > 0)
      54             :         {
      55             :           ip4_options_next_t next;
      56             :           ip4_header_t *ip4;
      57             :           vlib_buffer_t *b;
      58             :           u8 *options;
      59             :           u32 bi;
      60             : 
      61          24 :           bi = from[0];
      62          24 :           from += 1;
      63          24 :           n_left_from -= 1;
      64          24 :           to_next[0] = bi;
      65          24 :           to_next += 1;
      66          24 :           n_left_to_next -= 1;
      67             : 
      68          24 :           b = vlib_get_buffer (vm, bi);
      69          24 :           ip4 = vlib_buffer_get_current (b);
      70          24 :           next = IP4_OPTIONS_NEXT_PUNT;
      71             : 
      72          24 :           options = (u8 *) (ip4 + 1);
      73             : 
      74             :           /*
      75             :            * mask out the copy flag to leave the option type
      76             :            */
      77          24 :           switch (options[0] & 0x7f)
      78             :             {
      79          24 :             case IP4_ROUTER_ALERT_OPTION:
      80             :               /*
      81             :                * check the option length
      82             :                */
      83          24 :               if (options[1] != 4)
      84           0 :                 break;
      85             :               /*
      86             :                * if it's an IGMP packet, pass up the local stack
      87             :                */
      88          24 :               if (IP_PROTOCOL_IGMP == ip4->protocol)
      89             :                 {
      90          24 :                   ip_lookup_set_buffer_fib_index (
      91             :                     ip4_main.fib_index_by_sw_if_index, b);
      92          24 :                   next = IP4_OPTIONS_NEXT_LOCAL;
      93             :                 }
      94          24 :               break;
      95           0 :             default:
      96           0 :               break;
      97             :             }
      98             : 
      99          24 :           if (b->flags & VLIB_BUFFER_IS_TRACED)
     100             :             {
     101             :               ip4_options_trace_t *t =
     102          24 :                 vlib_add_trace (vm, node, b, sizeof (*t));
     103             : 
     104          24 :               clib_memcpy_fast (t->option, options, 4);
     105             :             }
     106          24 :           vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next,
     107             :                                            n_left_to_next, bi, next);
     108             : 
     109             :         }
     110             : 
     111          22 :       vlib_put_next_frame (vm, node, next_index, n_left_to_next);
     112             :     }
     113          22 :   return frame->n_vectors;
     114             : }
     115             : 
     116             : u8 *
     117           4 : format_ip4_options_trace (u8 * s, va_list * args)
     118             : {
     119           4 :   CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
     120           4 :   CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
     121           4 :   ip4_options_trace_t *t = va_arg (*args, ip4_options_trace_t *);
     122           4 :   u32 indent = format_get_indent (s);
     123             : 
     124           4 :   s = format (s, "%Uoption:[0x%x,0x%x,0x%x,0x%x]",
     125             :               format_white_space, indent,
     126           4 :               t->option[0], t->option[1], t->option[2], t->option[3]);
     127           4 :   return s;
     128             : }
     129             : 
     130             : /* *INDENT-OFF* */
     131      183788 : VLIB_REGISTER_NODE (ip4_options_node) = {
     132             :   .name = "ip4-options",
     133             :   .vector_size = sizeof (u32),
     134             : 
     135             :   .n_next_nodes = IP4_OPTIONS_N_NEXT,
     136             :   .next_nodes = {
     137             :     [IP4_OPTIONS_NEXT_PUNT] = "ip4-punt",
     138             :     [IP4_OPTIONS_NEXT_LOCAL] = "ip4-local",
     139             :   },
     140             :   .format_buffer = format_ip4_header,
     141             :   .format_trace = format_ip4_options_trace,
     142             : };
     143             : /* *INDENT-ON* */
     144             : 
     145             : /*
     146             :  * fd.io coding-style-patch-verification: ON
     147             :  *
     148             :  * Local Variables:
     149             :  * eval: (c-set-style "gnu")
     150             :  * End:
     151             :  */

Generated by: LCOV version 1.14