Register cdp_input when enabled for the first time 42/14842/2
authorDave Barach <dave@barachs.net>
Sun, 16 Sep 2018 15:03:04 +0000 (11:03 -0400)
committerFlorin Coras <florin.coras@gmail.com>
Sun, 16 Sep 2018 23:35:03 +0000 (23:35 +0000)
Graceful handling of unknown tlv types

Change-Id: Idbc9ed524fc8b865c8e12571813cc73548bde480
Signed-off-by: Dave Barach <dave@barachs.net>
src/plugins/cdp/cdp.h
src/plugins/cdp/cdp_input.c
src/plugins/cdp/cdp_node.c

index 32a0782..ab2ab95 100644 (file)
@@ -95,6 +95,7 @@ typedef struct
 
   /* top-level state */
   int enabled;
+  int cdp_protocol_registered;
 
   /* Packet templates for different encap types */
   vlib_packet_template_t packet_templates[CDP_N_PACKET_TEMPLATES];
index fa993b8..bce8eeb 100644 (file)
@@ -276,13 +276,18 @@ cdp_packet_scan (cdp_main_t * cm, cdp_neighbor_t * n)
       tlv = (cdp_tlv_t *) cur;
       tlv->t = ntohs (tlv->t);
       tlv->l = ntohs (tlv->l);
-      if (tlv->t >= ARRAY_LEN (tlv_handlers))
-       return CDP_ERROR_BAD_TLV;
-      handler = &tlv_handlers[tlv->t];
-      fp = handler->process;
-      e = (*fp) (cm, n, tlv);
-      if (e)
-       return e;
+      /*
+       * Only process known TLVs. In practice, certain
+       * devices send tlv->t = 0xFF, perhaps as an EOF of sorts.
+       */
+      if (tlv->t < ARRAY_LEN (tlv_handlers))
+       {
+         handler = &tlv_handlers[tlv->t];
+         fp = handler->process;
+         e = (*fp) (cm, n, tlv);
+         if (e)
+           return e;
+       }
       /* tlv length includes (t, l) */
       cur += tlv->l;
     }
index 1336c56..ac7e764 100644 (file)
@@ -132,25 +132,7 @@ cdp_process (vlib_main_t * vm, vlib_node_runtime_t * rt, vlib_frame_t * f)
   /* So we can send events to the cdp process */
   cm->cdp_process_node_index = cdp_process_node.index;
 
-  /* Dynamically register the cdp input node with the snap classifier */
-  snap_register_input_protocol (vm, "cdp-input", 0xC /* ieee_oui, Cisco */ ,
-                               0x2000 /* protocol CDP */ ,
-                               cdp_input_node.index);
-
-  snap_register_input_protocol (vm, "cdp-input", 0xC /* ieee_oui, Cisco */ ,
-                               0x2004 /* protocol CDP */ ,
-                               cdp_input_node.index);
-
-#if 0                          /* retain for reference */
-  /* with the hdlc classifier */
-  hdlc_register_input_protocol (vm, HDLC_PROTOCOL_cdp, cdp_input_node.index);
-#endif
-
-  /* with ethernet input (for SRP) */
-  ethernet_register_input_type (vm, ETHERNET_TYPE_CDP /* CDP */ ,
-                               cdp_input_node.index);
-
-  /* Start w/ cdp effectively disabled */
+  /* Start w/ cdp disabled */
   poll_time_remaining = 86400.0;
 
   while (1)
@@ -166,6 +148,34 @@ cdp_process (vlib_main_t * vm, vlib_node_runtime_t * rt, vlib_frame_t * f)
          break;
 
        case CDP_EVENT_ENABLE:
+         if (!cm->cdp_protocol_registered)
+           {
+             /*
+              * Dynamically register the cdp input node
+              * with the snap classifier
+              */
+             snap_register_input_protocol (vm, "cdp-input",
+                                           0xC /* ieee_oui, Cisco */ ,
+                                           0x2000 /* protocol CDP */ ,
+                                           cdp_input_node.index);
+
+             snap_register_input_protocol (vm, "cdp-input",
+                                           0xC /* ieee_oui, Cisco */ ,
+                                           0x2004 /* protocol CDP */ ,
+                                           cdp_input_node.index);
+#if 0
+             /*
+              * Keep this code for reference...
+              * Register with the hdlc classifier
+              */
+             hdlc_register_input_protocol (vm, HDLC_PROTOCOL_cdp,
+                                           cdp_input_node.index);
+#endif
+             /* with ethernet input (for SRP) */
+             ethernet_register_input_type (vm, ETHERNET_TYPE_CDP /* CDP */ ,
+                                           cdp_input_node.index);
+             cm->cdp_protocol_registered = 1;
+           }
          poll_time_remaining = 10.0;
          break;