LCOV - code coverage report
Current view: top level - plugins/cdp - cdp_node.c (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 42 52 80.8 %
Date: 2023-10-26 01:39:38 Functions: 5 5 100.0 %

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2011-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             : #include <cdp/cdp.h>
      16             : #include <vnet/ethernet/packet.h>
      17             : 
      18             : /** \file
      19             : 
      20             :     2 x CDP graph nodes: an "interior" node to process
      21             :     incoming announcements, and a "process" node to periodically
      22             :     send announcements.
      23             : 
      24             :     The interior node is neither pipelined nor dual-looped, because
      25             :     it would be very unusual to see more than one CDP packet in
      26             :     a given input frame. So, it's a very simple / straightforward
      27             :     example.
      28             : */
      29             : 
      30             : /*
      31             :  * packet counter strings
      32             :  * Dump these counters via the "show error" CLI command
      33             :  */
      34             : static char *cdp_error_strings[] = {
      35             : #define _(sym,string) string,
      36             :   foreach_cdp_error
      37             : #undef _
      38             : };
      39             : 
      40             : /*
      41             :  * We actually send all cdp pkts to the "error" node after scanning
      42             :  * them, so the graph node has only one next-index. The "error-drop"
      43             :  * node automatically bumps our per-node packet counters for us.
      44             :  */
      45             : typedef enum
      46             : {
      47             :   CDP_INPUT_NEXT_NORMAL,
      48             :   CDP_INPUT_N_NEXT,
      49             : } cdp_next_t;
      50             : 
      51             : /*
      52             :  * Process a frame of cdp packets
      53             :  * Expect 1 packet / frame
      54             :  */
      55             : static uword
      56           3 : cdp_node_fn (vlib_main_t * vm,
      57             :              vlib_node_runtime_t * node, vlib_frame_t * frame)
      58             : {
      59             :   u32 n_left_from, *from;
      60             :   cdp_input_trace_t *t0;
      61             : 
      62           3 :   from = vlib_frame_vector_args (frame);        /* array of buffer indices */
      63           3 :   n_left_from = frame->n_vectors;    /* number of buffer indices */
      64             : 
      65           6 :   while (n_left_from > 0)
      66             :     {
      67             :       u32 bi0;
      68             :       vlib_buffer_t *b0;
      69             :       u32 next0, error0;
      70             : 
      71           3 :       bi0 = from[0];
      72           3 :       b0 = vlib_get_buffer (vm, bi0);
      73             : 
      74           3 :       next0 = CDP_INPUT_NEXT_NORMAL;
      75             : 
      76             :       /* scan this cdp pkt. error0 is the counter index to bump */
      77           3 :       error0 = cdp_input (vm, b0, bi0);
      78           3 :       b0->error = node->errors[error0];
      79             : 
      80             :       /* If this pkt is traced, snapshoot the data */
      81           3 :       if (b0->flags & VLIB_BUFFER_IS_TRACED)
      82             :         {
      83             :           int len;
      84           3 :           t0 = vlib_add_trace (vm, node, b0, sizeof (*t0));
      85           3 :           len = (b0->current_length < sizeof (t0->data))
      86           3 :             ? b0->current_length : sizeof (t0->data);
      87           3 :           t0->len = len;
      88           3 :           clib_memcpy (t0->data, vlib_buffer_get_current (b0), len);
      89             :         }
      90             :       /* push this pkt to the next graph node, always error-drop */
      91           3 :       vlib_set_next_frame_buffer (vm, node, next0, bi0);
      92             : 
      93           3 :       from += 1;
      94           3 :       n_left_from -= 1;
      95             :     }
      96             : 
      97           3 :   return frame->n_vectors;
      98             : }
      99             : 
     100             : /*
     101             :  * cdp input graph node declaration
     102             :  */
     103             : /* *INDENT-OFF* */
     104      169388 : VLIB_REGISTER_NODE (cdp_input_node, static) = {
     105             :   .function = cdp_node_fn,
     106             :   .name = "cdp-input",
     107             :   .vector_size = sizeof (u32),
     108             :   .type = VLIB_NODE_TYPE_INTERNAL,
     109             : 
     110             :   .n_errors = CDP_N_ERROR,
     111             :   .error_strings = cdp_error_strings,
     112             : 
     113             :   .format_trace = cdp_input_format_trace,
     114             : 
     115             :   .n_next_nodes = CDP_INPUT_N_NEXT,
     116             :   .next_nodes = {
     117             :     [CDP_INPUT_NEXT_NORMAL] = "error-drop",
     118             :   },
     119             : };
     120             : /* *INDENT-ON* */
     121             : 
     122             : /*
     123             :  * cdp periodic function
     124             :  */
     125             : static uword
     126           1 : cdp_process (vlib_main_t * vm, vlib_node_runtime_t * rt, vlib_frame_t * f)
     127             : {
     128           1 :   cdp_main_t *cm = &cdp_main;
     129             :   f64 poll_time_remaining;
     130           1 :   uword event_type, *event_data = 0;
     131             : 
     132             :   /* Start w/ cdp disabled */
     133           1 :   poll_time_remaining = 86400.0;
     134             : 
     135             :   while (1)
     136             :     {
     137             :       /* sleep until next poll time, or msg serialize event occurs */
     138           4 :       poll_time_remaining =
     139           5 :         vlib_process_wait_for_event_or_clock (vm, poll_time_remaining);
     140             : 
     141           4 :       event_type = vlib_process_get_events (vm, &event_data);
     142           4 :       switch (event_type)
     143             :         {
     144           0 :         case ~0:                /* no events => timeout */
     145           0 :           break;
     146             : 
     147           4 :         case CDP_EVENT_ENABLE:
     148           4 :           if (!cm->cdp_protocol_registered)
     149             :             {
     150             :               /*
     151             :                * Dynamically register the cdp input node
     152             :                * with the snap classifier
     153             :                */
     154           1 :               snap_register_input_protocol (vm, "cdp-input",
     155             :                                             0xC /* ieee_oui, Cisco */ ,
     156             :                                             0x2000 /* protocol CDP */ ,
     157             :                                             cdp_input_node.index);
     158             : 
     159           1 :               snap_register_input_protocol (vm, "cdp-input",
     160             :                                             0xC /* ieee_oui, Cisco */ ,
     161             :                                             0x2004 /* protocol CDP */ ,
     162             :                                             cdp_input_node.index);
     163             : #if 0
     164             :               /*
     165             :                * Keep this code for reference...
     166             :                * Register with the hdlc classifier
     167             :                */
     168             :               hdlc_register_input_protocol (vm, HDLC_PROTOCOL_cdp,
     169             :                                             cdp_input_node.index);
     170             : #endif
     171             :               /* with ethernet input (for SRP) */
     172           1 :               ethernet_register_input_type (vm, ETHERNET_TYPE_CDP /* CDP */ ,
     173             :                                             cdp_input_node.index);
     174           1 :               cm->cdp_protocol_registered = 1;
     175             :             }
     176           4 :           poll_time_remaining = 10.0;
     177           4 :           break;
     178             : 
     179           0 :         case CDP_EVENT_DISABLE:
     180           0 :           poll_time_remaining = 86400.0;
     181           0 :           break;
     182             : 
     183           0 :         default:
     184           0 :           clib_warning ("BUG: event type 0x%wx", event_type);
     185           0 :           break;
     186             :         }
     187           4 :       vec_reset_length (event_data);
     188             : 
     189             :       /* peer timeout scan, send announcements */
     190           4 :       if (vlib_process_suspend_time_is_zero (poll_time_remaining))
     191             :         {
     192           0 :           cdp_periodic (vm);
     193           0 :           poll_time_remaining = 10.0;
     194             :         }
     195             :     }
     196             : 
     197             :   return 0;
     198             : }
     199             : 
     200             : void
     201           4 : vnet_cdp_create_periodic_process (cdp_main_t * cmp)
     202             : {
     203             :   /* Already created the process node? */
     204           4 :   if (cmp->cdp_process_node_index > 0)
     205           3 :     return;
     206             : 
     207             :   /* No, create it now and make a note of the node index */
     208           1 :   cmp->cdp_process_node_index = vlib_process_create
     209             :     (cmp->vlib_main, "cdp-process",
     210             :      cdp_process, 16 /* log2_n_stack_bytes */ );
     211             : }
     212             : 
     213             : /*
     214             :  * fd.io coding-style-patch-verification: ON
     215             :  *
     216             :  * Local Variables:
     217             :  * eval: (c-set-style "gnu")
     218             :  * End:
     219             :  */

Generated by: LCOV version 1.14