From: Dave Barach Date: Sun, 16 Sep 2018 15:03:04 +0000 (-0400) Subject: Register cdp_input when enabled for the first time X-Git-Tag: v18.10-rc1~176 X-Git-Url: https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commitdiff_plain;h=40ea3f59dca497e5f4b5a8440a9c8c2e37396701 Register cdp_input when enabled for the first time Graceful handling of unknown tlv types Change-Id: Idbc9ed524fc8b865c8e12571813cc73548bde480 Signed-off-by: Dave Barach --- diff --git a/src/plugins/cdp/cdp.h b/src/plugins/cdp/cdp.h index 32a07825ecb..ab2ab95e895 100644 --- a/src/plugins/cdp/cdp.h +++ b/src/plugins/cdp/cdp.h @@ -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]; diff --git a/src/plugins/cdp/cdp_input.c b/src/plugins/cdp/cdp_input.c index fa993b84def..bce8eebe7b0 100644 --- a/src/plugins/cdp/cdp_input.c +++ b/src/plugins/cdp/cdp_input.c @@ -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; } diff --git a/src/plugins/cdp/cdp_node.c b/src/plugins/cdp/cdp_node.c index 1336c567287..ac7e7642dae 100644 --- a/src/plugins/cdp/cdp_node.c +++ b/src/plugins/cdp/cdp_node.c @@ -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;