diff options
author | Dave Barach <dave@barachs.net> | 2018-03-10 14:57:00 -0500 |
---|---|---|
committer | Dave Barach <dave@barachs.net> | 2018-03-10 15:27:58 -0500 |
commit | aaacfbc5b15b0653489ad2e80db48151a4375ece (patch) | |
tree | cbe4228c1e674116563229e52bc5e9d73229b5af /src/vnet/cdp | |
parent | fde0929d9362eac5c416f658e1d2031d01a02337 (diff) |
Move the vnet cdp protocol implementation to a plugin
Add a binary API and debug cli to enable/disable cdp. cdp is disabled
by default.
Change-Id: I307c7e38dfda38e36ff3325f65de7036c34d89b1
Signed-off-by: Dave Barach <dave@barachs.net>
Diffstat (limited to 'src/vnet/cdp')
-rw-r--r-- | src/vnet/cdp/cdp.pg | 7 | ||||
-rw-r--r-- | src/vnet/cdp/cdp_input.c | 506 | ||||
-rw-r--r-- | src/vnet/cdp/cdp_node.c | 208 | ||||
-rw-r--r-- | src/vnet/cdp/cdp_node.h | 147 | ||||
-rw-r--r-- | src/vnet/cdp/cdp_periodic.c | 515 | ||||
-rw-r--r-- | src/vnet/cdp/cdp_protocol.h | 186 |
6 files changed, 0 insertions, 1569 deletions
diff --git a/src/vnet/cdp/cdp.pg b/src/vnet/cdp/cdp.pg deleted file mode 100644 index b6ba18656c2..00000000000 --- a/src/vnet/cdp/cdp.pg +++ /dev/null @@ -1,7 +0,0 @@ -packet-generator new { - name cdp - limit 1 - node cdp-input - size 374-374 - data { hex 0x02b46b96000100096978676265000500bf436973636f20494f5320536f6674776172652c2043333735304520536f66747761726520284333373530452d554e4956455253414c2d4d292c2056657273696f6e2031322e32283335295345352c2052454c4541534520534f4654574152452028666331290a436f707972696768742028632920313938362d3230303720627920436973636f2053797374656d732c20496e632e0a436f6d70696c6564205468752031392d4a756c2d30372031363a3137206279206e616368656e00060018636973636f2057532d4333373530452d3234544400020011000000010101cc0004000000000003001b54656e4769676162697445746865726e6574312f302f3100040008000000280008002400000c011200000000ffffffff010221ff000000000000001e7a50f000ff000000090004000a00060001000b0005010012000500001300050000160011000000010101cc000400000000001a00100000000100000000ffffffff } -} diff --git a/src/vnet/cdp/cdp_input.c b/src/vnet/cdp/cdp_input.c deleted file mode 100644 index 3574de68534..00000000000 --- a/src/vnet/cdp/cdp_input.c +++ /dev/null @@ -1,506 +0,0 @@ -/* - * Copyright (c) 2011-2016 Cisco and/or its affiliates. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include <vnet/cdp/cdp_node.h> - -cdp_main_t cdp_main; - -#define DEBUG_TLV_DUMP 0 /* 1=> dump TLV's to stdout while processing them */ - -/* Reliable multicast messages we use to keep peers updated */ -mc_serialize_msg_t serialize_cdp_neighbor_msg; -mc_serialize_msg_t serialize_cdp_keepalive_msg; - -/* - * ported from an unspecified Cisco cdp implementation. - * Compute / return in HOST byte order. 0 => good checksum. - */ -u16 -cdp_checksum (void *p, int count) -{ - u32 sum; - u16 i, *data; - - data = p; - sum = 0; - while (count > 1) - { - sum += ntohs (*data); - data++; - count -= 2; - } - - if (count > 0) - sum += *(char *) data; - - while (sum >> 16) - { - sum = (sum & 0xFFFF) + (sum >> 16); - } - - i = (i16) sum; - return (~i); -} - -/* TLV handler table */ -typedef struct -{ - char *name; - u32 tlv_id; - void *format; - void *process; -} tlv_handler_t; - -static tlv_handler_t tlv_handlers[]; - -/* Display a generic TLV as a set of hex bytes */ -static u8 * -format_generic_tlv (u8 * s, va_list * va) -{ - cdp_tlv_t *t = va_arg (*va, cdp_tlv_t *); - tlv_handler_t *h = &tlv_handlers[t->t]; - - s = format (s, "%s(%d): %U\n", h->name, - t->t, format_hex_bytes, t->v, t->l - sizeof (*t)); - return s; -} - -/* Ignore / skip a TLV we don't support */ -static cdp_error_t -process_generic_tlv (cdp_main_t * cm, cdp_neighbor_t * n, cdp_tlv_t * t) -{ -#if DEBUG_TLV_DUMP > 0 - fformat (stdout, "%U", format_generic_tlv, t); -#endif - - return CDP_ERROR_NONE; -} - -/* print a text tlv */ -static u8 * -format_text_tlv (u8 * s, va_list * va) -{ - cdp_tlv_t *t = va_arg (*va, cdp_tlv_t *); - tlv_handler_t *h = &tlv_handlers[t->t]; - int i; - - s = format (s, "%s(%d): ", h->name, t->t); - - for (i = 0; i < (t->l - sizeof (*t)); i++) - vec_add1 (s, t->v[i]); - - vec_add1 (s, '\n'); - return s; -} - -#if DEBUG_TLV_DUMP == 0 -/* gcc warning be gone */ -CLIB_UNUSED (static cdp_error_t - process_text_tlv (cdp_main_t * cm, cdp_neighbor_t * n, - cdp_tlv_t * t)); -#endif - -/* process / skip a generic text TLV that we don't support */ -static cdp_error_t -process_text_tlv (cdp_main_t * cm, cdp_neighbor_t * n, cdp_tlv_t * t) -{ -#if DEBUG_TLV_DUMP > 0 - fformat (stdout, "%U\n", format_text_tlv, t); -#endif - - return CDP_ERROR_NONE; -} - -/* per-TLV format function definitions */ -#define format_unused_tlv format_generic_tlv -#define format_device_name_tlv format_text_tlv -#define format_address_tlv format_generic_tlv -#define format_port_id_tlv format_text_tlv -#define format_capabilities_tlv format_generic_tlv -#define format_version_tlv format_text_tlv -#define format_platform_tlv format_text_tlv -#define format_ipprefix_tlv format_generic_tlv -#define format_hello_tlv format_generic_tlv -#define format_vtp_domain_tlv format_generic_tlv -#define format_native_vlan_tlv format_generic_tlv -#define format_duplex_tlv format_generic_tlv -#define format_appl_vlan_tlv format_generic_tlv -#define format_trigger_tlv format_generic_tlv -#define format_power_tlv format_generic_tlv -#define format_mtu_tlv format_generic_tlv -#define format_trust_tlv format_generic_tlv -#define format_cos_tlv format_generic_tlv -#define format_sysname_tlv format_generic_tlv -#define format_sysobject_tlv format_generic_tlv -#define format_mgmt_addr_tlv format_generic_tlv -#define format_physical_loc_tlv format_generic_tlv -#define format_mgmt_addr2_tlv format_generic_tlv -#define format_power_requested_tlv format_generic_tlv -#define format_power_available_tlv format_generic_tlv -#define format_port_unidirectional_tlv format_generic_tlv -#define format_unknown_28_tlv format_generic_tlv -#define format_energywise_tlv format_generic_tlv -#define format_unknown_30_tlv format_generic_tlv -#define format_spare_poe_tlv format_generic_tlv - -/* tlv ID=0 is a mistake */ -static cdp_error_t -process_unused_tlv (cdp_main_t * cm, cdp_neighbor_t * n, cdp_tlv_t * t) -{ - return CDP_ERROR_BAD_TLV; -} - -/* list of text TLV's that we snapshoot */ -#define foreach_text_to_struct_tlv \ -_(device_name,DEBUG_TLV_DUMP) \ -_(version,DEBUG_TLV_DUMP) \ -_(platform,DEBUG_TLV_DUMP) \ -_(port_id,DEBUG_TLV_DUMP) - -#define _(z,dbg) \ -static \ -cdp_error_t process_##z##_tlv (cdp_main_t *cm, cdp_neighbor_t *n, \ - cdp_tlv_t *t) \ -{ \ - int i; \ - if (dbg) \ - fformat(stdout, "%U\n", format_text_tlv, t); \ - \ - if (n->z) \ - _vec_len(n->z) = 0; \ - \ - for (i = 0; i < (t->l - sizeof (*t)); i++) \ - vec_add1(n->z, t->v[i]); \ - \ - vec_add1(n->z, 0); \ - \ - return CDP_ERROR_NONE; \ -} - -foreach_text_to_struct_tlv -#undef _ -#define process_address_tlv process_generic_tlv -#define process_capabilities_tlv process_generic_tlv -#define process_ipprefix_tlv process_generic_tlv -#define process_hello_tlv process_generic_tlv -#define process_vtp_domain_tlv process_generic_tlv -#define process_native_vlan_tlv process_generic_tlv -#define process_duplex_tlv process_generic_tlv -#define process_appl_vlan_tlv process_generic_tlv -#define process_trigger_tlv process_generic_tlv -#define process_power_tlv process_generic_tlv -#define process_mtu_tlv process_generic_tlv -#define process_trust_tlv process_generic_tlv -#define process_cos_tlv process_generic_tlv -#define process_sysname_tlv process_generic_tlv -#define process_sysobject_tlv process_generic_tlv -#define process_mgmt_addr_tlv process_generic_tlv -#define process_physical_loc_tlv process_generic_tlv -#define process_mgmt_addr2_tlv process_generic_tlv -#define process_power_requested_tlv process_generic_tlv -#define process_power_available_tlv process_generic_tlv -#define process_port_unidirectional_tlv process_generic_tlv -#define process_unknown_28_tlv process_generic_tlv -#define process_energywise_tlv process_generic_tlv -#define process_unknown_30_tlv process_generic_tlv -#define process_spare_poe_tlv process_generic_tlv -static tlv_handler_t tlv_handlers[] = { -#define _(a) {#a, CDP_TLV_##a, format_##a##_tlv, process_##a##_tlv}, - foreach_cdp_tlv_type -#undef _ -}; - -#if DEBUG_TLV_DUMP == 0 -CLIB_UNUSED (static u8 * format_cdp_hdr (u8 * s, va_list * va)); -#endif - -static u8 * -format_cdp_hdr (u8 * s, va_list * va) -{ - cdp_hdr_t *h = va_arg (*va, cdp_hdr_t *); - - s = format (s, "version %d, ttl %d(secs), cksum 0x%04x\n", - h->version, h->ttl, h->checksum); - return s; -} - -static cdp_error_t -process_cdp_hdr (cdp_main_t * cm, cdp_neighbor_t * n, cdp_hdr_t * h) -{ -#if DEBUG_TLV_DUMP > 0 - fformat (stdout, "%U", format_cdp_hdr, h); -#endif - - if (h->version != 1 && h->version != 2) - return CDP_ERROR_PROTOCOL_VERSION; - - n->ttl_in_seconds = h->ttl; - - return CDP_ERROR_NONE; -} - -/* scan a cdp packet; header, then tlv's */ -static int -cdp_packet_scan (cdp_main_t * cm, cdp_neighbor_t * n) -{ - u8 *cur = n->last_rx_pkt; - cdp_hdr_t *h; - cdp_tlv_t *tlv; - cdp_error_t e = CDP_ERROR_NONE; - tlv_handler_t *handler; - cdp_error_t (*fp) (cdp_main_t *, cdp_neighbor_t *, cdp_tlv_t *); - u16 computed_checksum; - - computed_checksum = cdp_checksum (cur, vec_len (cur)); - - if (computed_checksum) - return CDP_ERROR_CHECKSUM; - - h = (cdp_hdr_t *) cur; - - e = process_cdp_hdr (cm, n, h); - if (e) - return e; - - cur = (u8 *) (h + 1); - - while (cur < n->last_rx_pkt + vec_len (n->last_rx_pkt) - 1) - { - 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; - /* tlv length includes (t, l) */ - cur += tlv->l; - } - - return CDP_ERROR_NONE; -} - -/* - * cdp input routine - */ -cdp_error_t -cdp_input (vlib_main_t * vm, vlib_buffer_t * b0, u32 bi0) -{ - cdp_main_t *cm = &cdp_main; - cdp_neighbor_t *n; - uword *p, nbytes; - cdp_error_t e; - uword last_packet_signature; - - /* find or create a neighbor pool entry for the (sw) interface - upon which we received this pkt */ - p = hash_get (cm->neighbor_by_sw_if_index, - vnet_buffer (b0)->sw_if_index[VLIB_RX]); - - if (p == 0) - { - pool_get (cm->neighbors, n); - memset (n, 0, sizeof (*n)); - n->sw_if_index = vnet_buffer (b0)->sw_if_index[VLIB_RX]; - n->packet_template_index = (u8) ~ 0; - hash_set (cm->neighbor_by_sw_if_index, n->sw_if_index, - n - cm->neighbors); - } - else - { - n = pool_elt_at_index (cm->neighbors, p[0]); - } - - /* - * typical clib idiom. Don't repeatedly allocate and free - * the per-neighbor rx buffer. Reset its apparent length to zero - * and reuse it. - */ - - if (n->last_rx_pkt) - _vec_len (n->last_rx_pkt) = 0; - - /* cdp disabled on this interface, we're done */ - if (n->disabled) - return CDP_ERROR_DISABLED; - - /* - * Make sure the per-neighbor rx buffer is big enough to hold - * the data we're about to copy - */ - vec_validate (n->last_rx_pkt, vlib_buffer_length_in_chain (vm, b0) - 1); - - /* - * Coalesce / copy e the buffer chain into the per-neighbor - * rx buffer - */ - nbytes = vlib_buffer_contents (vm, bi0, n->last_rx_pkt); - ASSERT (nbytes <= vec_len (n->last_rx_pkt)); - - /* - * Compute Jenkins hash of the new packet, decide if we need to - * actually parse through the TLV's. CDP packets are all identical, - * so unless we time out the peer, we don't need to process the packet. - */ - last_packet_signature = - hash_memory (n->last_rx_pkt, vec_len (n->last_rx_pkt), 0xd00b); - - if (n->last_packet_signature_valid && - n->last_packet_signature == last_packet_signature) - { - e = CDP_ERROR_CACHE_HIT; - } - else - { - /* Actually scan the packet */ - e = cdp_packet_scan (cm, n); - n->last_packet_signature_valid = 1; - n->last_packet_signature = last_packet_signature; - } - - if (e == CDP_ERROR_NONE) - { - n->last_heard = vlib_time_now (vm); - } - - return e; -} - -/* - * setup neighbor hash table - */ -static clib_error_t * -cdp_init (vlib_main_t * vm) -{ - clib_error_t *error; - cdp_main_t *cm = &cdp_main; - void vnet_cdp_node_reference (void); - - vnet_cdp_node_reference (); - - if ((error = vlib_call_init_function (vm, cdp_periodic_init))) - return error; - - cm->vlib_main = vm; - cm->vnet_main = vnet_get_main (); - cm->neighbor_by_sw_if_index = hash_create (0, sizeof (uword)); - - return 0; -} - -VLIB_INIT_FUNCTION (cdp_init); - - -static u8 * -format_cdp_neighbors (u8 * s, va_list * va) -{ - CLIB_UNUSED (vlib_main_t * vm) = va_arg (*va, vlib_main_t *); - cdp_main_t *cm = va_arg (*va, cdp_main_t *); - vnet_main_t *vnm = &vnet_main; - cdp_neighbor_t *n; - vnet_hw_interface_t *hw; - - s = format (s, - "%=25s %=15s %=25s %=10s\n", - "Our Port", "Peer System", "Peer Port", "Last Heard"); - - /* *INDENT-OFF* */ - pool_foreach (n, cm->neighbors, - ({ - hw = vnet_get_sup_hw_interface (vnm, n->sw_if_index); - - if (n->disabled == 0) - s = format (s, "%=25s %=15s %=25s %=10.1f\n", - hw->name, n->device_name, n->port_id, - n->last_heard); - })); - /* *INDENT-ON* */ - return s; -} - - -static clib_error_t * -show_cdp (vlib_main_t * vm, - unformat_input_t * input, vlib_cli_command_t * cmd) -{ - cdp_main_t *cm = &cdp_main; - - vlib_cli_output (vm, "%U\n", format_cdp_neighbors, vm, cm); - - return 0; -} - -/* *INDENT-OFF* */ -VLIB_CLI_COMMAND (show_cdp_command, static) = { - .path = "show cdp", - .short_help = "Show cdp command", - .function = show_cdp, -}; -/* *INDENT-ON* */ - - -/* - * packet trace format function, very similar to - * cdp_packet_scan except that we call the per TLV format - * functions instead of the per TLV processing functions - */ -u8 * -cdp_input_format_trace (u8 * s, va_list * args) -{ - CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *); - CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *); - cdp_input_trace_t *t = va_arg (*args, cdp_input_trace_t *); - u8 *cur; - cdp_hdr_t *h; - cdp_tlv_t *tlv; - tlv_handler_t *handler; - u8 *(*fp) (cdp_tlv_t *); - - cur = t->data; - - h = (cdp_hdr_t *) cur; - s = format (s, "%U", format_cdp_hdr, h); - - cur = (u8 *) (h + 1); - - while (cur < t->data + t->len) - { - tlv = (cdp_tlv_t *) cur; - tlv->t = ntohs (tlv->t); - tlv->l = ntohs (tlv->l); - if (tlv->t >= ARRAY_LEN (tlv_handlers)) - { - s = format (s, "BAD_TLV\n"); - break; - } - handler = &tlv_handlers[tlv->t]; - fp = handler->format; - s = format (s, " %U", fp, tlv); - /* tlv length includes (t, l) */ - cur += tlv->l; - } - - return s; -} - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "gnu") - * End: - */ diff --git a/src/vnet/cdp/cdp_node.c b/src/vnet/cdp/cdp_node.c deleted file mode 100644 index 39ac4a908fb..00000000000 --- a/src/vnet/cdp/cdp_node.c +++ /dev/null @@ -1,208 +0,0 @@ -/* - * Copyright (c) 2011-2016 Cisco and/or its affiliates. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include <vnet/cdp/cdp_node.h> -#include <vnet/ethernet/packet.h> - -static vlib_node_registration_t cdp_process_node; - -/** \file - - 2 x CDP graph nodes: an "interior" node to process - incoming announcements, and a "process" node to periodically - send announcements. - - The interior node is neither pipelined nor dual-looped, because - it would be very unusual to see more than one CDP packet in - a given input frame. So, it's a very simple / straighforward - example. -*/ - -/* - * packet counter strings - * Dump these counters via the "show error" CLI command - */ -static char *cdp_error_strings[] = { -#define _(sym,string) string, - foreach_cdp_error -#undef _ -}; - -/* - * We actually send all cdp pkts to the "error" node after scanning - * them, so the graph node has only one next-index. The "error-drop" - * node automatically bumps our per-node packet counters for us. - */ -typedef enum -{ - CDP_INPUT_NEXT_NORMAL, - CDP_INPUT_N_NEXT, -} cdp_next_t; - -/* - * Process a frame of cdp packets - * Expect 1 packet / frame - */ -static uword -cdp_node_fn (vlib_main_t * vm, - vlib_node_runtime_t * node, vlib_frame_t * frame) -{ - u32 n_left_from, *from; - cdp_input_trace_t *t0; - - from = vlib_frame_vector_args (frame); /* array of buffer indices */ - n_left_from = frame->n_vectors; /* number of buffer indices */ - - while (n_left_from > 0) - { - u32 bi0; - vlib_buffer_t *b0; - u32 next0, error0; - - bi0 = from[0]; - b0 = vlib_get_buffer (vm, bi0); - - next0 = CDP_INPUT_NEXT_NORMAL; - - /* scan this cdp pkt. error0 is the counter index to bump */ - error0 = cdp_input (vm, b0, bi0); - b0->error = node->errors[error0]; - - /* If this pkt is traced, snapshoot the data */ - if (b0->flags & VLIB_BUFFER_IS_TRACED) - { - int len; - t0 = vlib_add_trace (vm, node, b0, sizeof (*t0)); - len = (b0->current_length < sizeof (t0->data)) - ? b0->current_length : sizeof (t0->data); - t0->len = len; - clib_memcpy (t0->data, vlib_buffer_get_current (b0), len); - } - /* push this pkt to the next graph node, always error-drop */ - vlib_set_next_frame_buffer (vm, node, next0, bi0); - - from += 1; - n_left_from -= 1; - } - - return frame->n_vectors; -} - -/* - * cdp input graph node declaration - */ -/* *INDENT-OFF* */ -VLIB_REGISTER_NODE (cdp_input_node, static) = { - .function = cdp_node_fn, - .name = "cdp-input", - .vector_size = sizeof (u32), - .type = VLIB_NODE_TYPE_INTERNAL, - - .n_errors = CDP_N_ERROR, - .error_strings = cdp_error_strings, - - .format_trace = cdp_input_format_trace, - - .n_next_nodes = CDP_INPUT_N_NEXT, - .next_nodes = { - [CDP_INPUT_NEXT_NORMAL] = "error-drop", - }, -}; -/* *INDENT-ON* */ - -/* - * cdp periodic function - */ -static uword -cdp_process (vlib_main_t * vm, vlib_node_runtime_t * rt, vlib_frame_t * f) -{ - cdp_main_t *cm = &cdp_main; - f64 poll_time_remaining; - uword event_type, *event_data = 0; - - /* 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); - - poll_time_remaining = 10.0 /* seconds */ ; - while (1) - { - /* sleep until next poll time, or msg serialize event occurs */ - poll_time_remaining = - vlib_process_wait_for_event_or_clock (vm, poll_time_remaining); - - event_type = vlib_process_get_events (vm, &event_data); - switch (event_type) - { - case ~0: /* no events => timeout */ - break; - - default: - clib_warning ("BUG: event type 0x%wx", event_type); - break; - } - if (event_data) - _vec_len (event_data) = 0; - - /* peer timeout scan, send announcements */ - if (vlib_process_suspend_time_is_zero (poll_time_remaining)) - { - cdp_periodic (vm); - poll_time_remaining = 10.0; - } - } - - return 0; -} - -/* - * cdp periodic node declaration - */ -/* *INDENT-OFF* */ -VLIB_REGISTER_NODE (cdp_process_node, static) = { - .function = cdp_process, - .type = VLIB_NODE_TYPE_PROCESS, - .name = "cdp-process", -}; -/* *INDENT-ON* */ - -void -vnet_cdp_node_reference (void) -{ -} - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "gnu") - * End: - */ diff --git a/src/vnet/cdp/cdp_node.h b/src/vnet/cdp/cdp_node.h deleted file mode 100644 index 21086c02527..00000000000 --- a/src/vnet/cdp/cdp_node.h +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Copyright (c) 2011-2016 Cisco and/or its affiliates. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#ifndef __included_cdp_node_h__ -#define __included_cdp_node_h__ - -#include <vlib/vlib.h> -#include <vlib/unix/unix.h> - -#include <vnet/snap/snap.h> -#include <vnet/hdlc/hdlc.h> -#include <vnet/hdlc/packet.h> - -#include <vppinfra/format.h> -#include <vppinfra/hash.h> - -#include <vnet/cdp/cdp_protocol.h> - -typedef enum -{ - CDP_PACKET_TEMPLATE_ETHERNET, - CDP_PACKET_TEMPLATE_HDLC, - CDP_PACKET_TEMPLATE_SRP, - CDP_N_PACKET_TEMPLATES, -} cdp_packet_template_id_t; - -typedef struct -{ - /* neighbor's vlib software interface index */ - u32 sw_if_index; - - /* Timers */ - f64 last_heard; - f64 last_sent; - - /* Neighbor time-to-live (usually 180s) */ - u8 ttl_in_seconds; - - /* "no cdp run" or similar */ - u8 disabled; - - /* tx packet template id for this neighbor */ - u8 packet_template_index; - - /* Jenkins hash optimization: avoid tlv scan, send short keepalive msg */ - u8 last_packet_signature_valid; - uword last_packet_signature; - - /* Info we actually keep about each neighbor */ - u8 *device_name; - u8 *version; - u8 *port_id; - u8 *platform; - - /* last received packet, for the J-hash optimization */ - u8 *last_rx_pkt; -} cdp_neighbor_t; - -#define foreach_neighbor_string_field \ -_(device_name) \ -_(version) \ -_(port_id) \ -_(platform) - -typedef struct -{ - /* pool of cdp neighbors */ - cdp_neighbor_t *neighbors; - - /* tx pcap debug enable */ - u8 tx_pcap_debug; - - /* rapidly find a neighbor by vlib software interface index */ - uword *neighbor_by_sw_if_index; - - /* Background process node index */ - u32 cdp_process_node_index; - - /* Packet templates for different encap types */ - vlib_packet_template_t packet_templates[CDP_N_PACKET_TEMPLATES]; - - /* convenience variables */ - vlib_main_t *vlib_main; - vnet_main_t *vnet_main; -} cdp_main_t; - -extern cdp_main_t cdp_main; - -/* Packet counters */ -#define foreach_cdp_error \ -_ (NONE, "good cdp packets (processed)") \ -_ (CACHE_HIT, "good cdp packets (cache hit)") \ -_ (BAD_TLV, "cdp packets with bad TLVs") \ -_ (PROTOCOL_VERSION, "cdp packets with bad protocol versions") \ -_ (CHECKSUM, "cdp packets with bad checksums") \ -_ (DISABLED, "cdp packets received on disabled interfaces") - -typedef enum -{ -#define _(sym,str) CDP_ERROR_##sym, - foreach_cdp_error -#undef _ - CDP_N_ERROR, -} cdp_error_t; - -/* cdp packet trace capture */ -typedef struct -{ - u32 len; - u8 data[400]; -} cdp_input_trace_t; - -typedef enum -{ - CDP_EVENT_SEND_NEIGHBOR, - CDP_EVENT_SEND_KEEPALIVE, -} cdp_process_event_t; - - -cdp_error_t cdp_input (vlib_main_t * vm, vlib_buffer_t * b0, u32 bi0); -void cdp_periodic (vlib_main_t * vm); -void cdp_keepalive (cdp_main_t * cm, cdp_neighbor_t * n); -u16 cdp_checksum (void *p, int count); -u8 *cdp_input_format_trace (u8 * s, va_list * args); - -serialize_function_t serialize_cdp_main, unserialize_cdp_main; - -#endif /* __included_cdp_node_h__ */ - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "gnu") - * End: - */ diff --git a/src/vnet/cdp/cdp_periodic.c b/src/vnet/cdp/cdp_periodic.c deleted file mode 100644 index 8899c49ce9c..00000000000 --- a/src/vnet/cdp/cdp_periodic.c +++ /dev/null @@ -1,515 +0,0 @@ -/* - * Copyright (c) 2011-2016 Cisco and/or its affiliates. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include <vnet/cdp/cdp_node.h> -#include <vppinfra/hash.h> -#include <vnet/unix/pcap.h> -#include <vnet/srp/srp.h> -#include <vnet/ppp/ppp.h> -#include <vnet/hdlc/hdlc.h> -#include <vnet/srp/packet.h> - -/* - * Generate a set of specific CDP TLVs. - * - * $$$ eventually these need to fish better data from - * other data structures; e.g. the hostname, software version info - * etc. - */ - -static void -add_device_name_tlv (vnet_hw_interface_t * hw, u8 ** t0p) -{ - cdp_tlv_t *t = (cdp_tlv_t *) * t0p; - - t->t = htons (CDP_TLV_device_name); - t->l = htons (3 + sizeof (*t)); - clib_memcpy (&t->v, "VPP", 3); - - *t0p += ntohs (t->l); -} - -static void -add_port_id_tlv (vnet_hw_interface_t * hw, u8 ** t0p) -{ - cdp_tlv_t *t = (cdp_tlv_t *) * t0p; - - t->t = htons (CDP_TLV_port_id); - t->l = htons (vec_len (hw->name) + sizeof (*t)); - clib_memcpy (&t->v, hw->name, vec_len (hw->name)); - *t0p += ntohs (t->l); -} - -static void -add_version_tlv (vnet_hw_interface_t * hw, u8 ** t0p) -{ - cdp_tlv_t *t = (cdp_tlv_t *) * t0p; - - t->t = htons (CDP_TLV_version); - t->l = htons (12 + sizeof (*t)); - clib_memcpy (&t->v, "VPP Software", 12); - *t0p += ntohs (t->l); -} - -static void -add_platform_tlv (vnet_hw_interface_t * hw, u8 ** t0p) -{ - cdp_tlv_t *t = (cdp_tlv_t *) * t0p; - - t->t = htons (CDP_TLV_platform); - t->l = htons (2 + sizeof (*t)); - clib_memcpy (&t->v, "SW", 2); - *t0p += ntohs (t->l); -} - -static void -add_capability_tlv (vnet_hw_interface_t * hw, u8 ** t0p) -{ - cdp_tlv_t *t = (cdp_tlv_t *) * t0p; - u32 capabilities; - - t->t = htons (CDP_TLV_capabilities); - t->l = htons (4 + sizeof (*t)); - capabilities = CDP_ROUTER_DEVICE; - capabilities = htonl (capabilities); - clib_memcpy (&t->v, &capabilities, sizeof (capabilities)); - *t0p += ntohs (t->l); -} - -static void -add_tlvs (cdp_main_t * cm, vnet_hw_interface_t * hw, u8 ** t0p) -{ - add_device_name_tlv (hw, t0p); - add_port_id_tlv (hw, t0p); - add_version_tlv (hw, t0p); - add_platform_tlv (hw, t0p); - add_capability_tlv (hw, t0p); -} - -/* - * send a cdp pkt on an ethernet interface - */ -static void -send_ethernet_hello (cdp_main_t * cm, cdp_neighbor_t * n, int count) -{ - u32 *to_next; - ethernet_llc_snap_and_cdp_header_t *h0; - vnet_hw_interface_t *hw; - u32 bi0; - vlib_buffer_t *b0; - u8 *t0; - u16 checksum; - int nbytes_to_checksum; - int i; - vlib_frame_t *f; - vlib_main_t *vm = cm->vlib_main; - vnet_main_t *vnm = cm->vnet_main; - - for (i = 0; i < count; i++) - { - /* - * see cdp_periodic_init() to understand what's already painted - * into the buffer by the packet template mechanism - */ - h0 = vlib_packet_template_get_packet - (vm, &cm->packet_templates[n->packet_template_index], &bi0); - - if (!h0) - break; - - /* Add the interface's ethernet source address */ - hw = vnet_get_sup_hw_interface (vnm, n->sw_if_index); - - clib_memcpy (h0->ethernet.src_address, hw->hw_address, - vec_len (hw->hw_address)); - - t0 = (u8 *) & h0->cdp.data; - - /* add TLVs */ - add_tlvs (cm, hw, &t0); - - /* add the cdp packet checksum */ - nbytes_to_checksum = t0 - (u8 *) & h0->cdp; - checksum = cdp_checksum (&h0->cdp, nbytes_to_checksum); - h0->cdp.checksum = htons (checksum); - - /* Set the outbound packet length */ - b0 = vlib_get_buffer (vm, bi0); - b0->current_length = nbytes_to_checksum + sizeof (*h0) - - sizeof (cdp_hdr_t); - - /* And the outbound interface */ - vnet_buffer (b0)->sw_if_index[VLIB_TX] = hw->sw_if_index; - - /* Set the 802.3 ethernet length */ - h0->ethernet.len = htons (b0->current_length - - sizeof (ethernet_802_3_header_t)); - - /* And output the packet on the correct interface */ - f = vlib_get_frame_to_node (vm, hw->output_node_index); - to_next = vlib_frame_vector_args (f); - to_next[0] = bi0; - f->n_vectors = 1; - - vlib_put_frame_to_node (vm, hw->output_node_index, f); - n->last_sent = vlib_time_now (vm); - } -} - -/* - * send a cdp pkt on an hdlc interface - */ -static void -send_hdlc_hello (cdp_main_t * cm, cdp_neighbor_t * n, int count) -{ - u32 *to_next; - hdlc_and_cdp_header_t *h0; - vnet_hw_interface_t *hw; - u32 bi0; - vlib_buffer_t *b0; - u8 *t0; - u16 checksum; - int nbytes_to_checksum; - int i; - vlib_frame_t *f; - vlib_main_t *vm = cm->vlib_main; - vnet_main_t *vnm = cm->vnet_main; - - for (i = 0; i < count; i++) - { - /* - * see cdp_periodic_init() to understand what's already painted - * into the buffer by the packet template mechanism - */ - h0 = vlib_packet_template_get_packet - (vm, &cm->packet_templates[n->packet_template_index], &bi0); - - hw = vnet_get_sup_hw_interface (vnm, n->sw_if_index); - - t0 = (u8 *) & h0->cdp.data; - - /* add TLVs */ - add_tlvs (cm, hw, &t0); - - /* add the cdp packet checksum */ - nbytes_to_checksum = t0 - (u8 *) & h0->cdp; - checksum = cdp_checksum (&h0->cdp, nbytes_to_checksum); - h0->cdp.checksum = htons (checksum); - - /* Set the outbound packet length */ - b0 = vlib_get_buffer (vm, bi0); - b0->current_length = nbytes_to_checksum + sizeof (*h0) - - sizeof (cdp_hdr_t); - - /* And output the packet on the correct interface */ - f = vlib_get_frame_to_node (vm, hw->output_node_index); - to_next = vlib_frame_vector_args (f); - to_next[0] = bi0; - f->n_vectors = 1; - - vlib_put_frame_to_node (vm, hw->output_node_index, f); - n->last_sent = vlib_time_now (vm); - } -} - -/* - * send a cdp pkt on an srp interface - */ -static void -send_srp_hello (cdp_main_t * cm, cdp_neighbor_t * n, int count) -{ - u32 *to_next; - srp_and_cdp_header_t *h0; - vnet_hw_interface_t *hw; - u32 bi0; - vlib_buffer_t *b0; - u8 *t0; - u16 checksum; - int nbytes_to_checksum; - int i; - vlib_frame_t *f; - vlib_main_t *vm = cm->vlib_main; - vnet_main_t *vnm = cm->vnet_main; - - for (i = 0; i < count; i++) - { - /* - * see cdp_periodic_init() to understand what's already painted - * into the buffer by the packet template mechanism - */ - h0 = vlib_packet_template_get_packet - (vm, &cm->packet_templates[n->packet_template_index], &bi0); - - hw = vnet_get_sup_hw_interface (vnm, n->sw_if_index); - - t0 = (u8 *) & h0->cdp.data; - - /* add TLVs */ - add_tlvs (cm, hw, &t0); - - /* Add the interface's ethernet source address */ - clib_memcpy (h0->ethernet.src_address, hw->hw_address, - vec_len (hw->hw_address)); - - /* add the cdp packet checksum */ - nbytes_to_checksum = t0 - (u8 *) & h0->cdp; - checksum = cdp_checksum (&h0->cdp, nbytes_to_checksum); - h0->cdp.checksum = htons (checksum); - - /* Set the outbound packet length */ - b0 = vlib_get_buffer (vm, bi0); - b0->current_length = nbytes_to_checksum + sizeof (*h0) - - sizeof (cdp_hdr_t); - - /* And output the packet on the correct interface */ - f = vlib_get_frame_to_node (vm, hw->output_node_index); - to_next = vlib_frame_vector_args (f); - to_next[0] = bi0; - f->n_vectors = 1; - - vlib_put_frame_to_node (vm, hw->output_node_index, f); - n->last_sent = vlib_time_now (vm); - } -} - -/* - * Decide which cdp packet template to use - */ -static int -pick_packet_template (cdp_main_t * cm, cdp_neighbor_t * n) -{ - n->packet_template_index = CDP_PACKET_TEMPLATE_ETHERNET; - - return 0; -} - -/* Send a cdp neighbor announcement */ -static void -send_hello (cdp_main_t * cm, cdp_neighbor_t * n, int count) -{ - if (n->packet_template_index == (u8) ~ 0) - { - /* If we don't know how to talk to this peer, don't try again */ - if (pick_packet_template (cm, n)) - { - n->last_sent = 1e70; - return; - } - } - - switch (n->packet_template_index) - { - case CDP_PACKET_TEMPLATE_ETHERNET: - send_ethernet_hello (cm, n, count); - break; - - case CDP_PACKET_TEMPLATE_HDLC: - send_hdlc_hello (cm, n, count); - break; - - case CDP_PACKET_TEMPLATE_SRP: - send_srp_hello (cm, n, count); - break; - - default: - ASSERT (0); - } - n->last_sent = vlib_time_now (cm->vlib_main); -} - -static void -delete_neighbor (cdp_main_t * cm, cdp_neighbor_t * n, int want_broadcast) -{ - hash_unset (cm->neighbor_by_sw_if_index, n->sw_if_index); - vec_free (n->device_name); - vec_free (n->version); - vec_free (n->port_id); - vec_free (n->platform); - vec_free (n->last_rx_pkt); - pool_put (cm->neighbors, n); -} - -void -cdp_periodic (vlib_main_t * vm) -{ - cdp_main_t *cm = &cdp_main; - cdp_neighbor_t *n; - f64 now = vlib_time_now (vm); - vnet_sw_interface_t *sw; - static u32 *delete_list = 0; - int i; - static cdp_neighbor_t **n_list = 0; - - /* *INDENT-OFF* */ - pool_foreach (n, cm->neighbors, - ({ - vec_add1 (n_list, n); - })); - /* *INDENT-ON* */ - - /* Across all cdp neighbors known to the system */ - for (i = 0; i < vec_len (n_list); i++) - { - n = n_list[i]; - - /* "no cdp run" provisioned on the interface? */ - if (n->disabled == 1) - continue; - - sw = vnet_get_sw_interface (cm->vnet_main, n->sw_if_index); - - /* Interface shutdown or rx timeout? */ - if (!(sw->flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP) - || (now > (n->last_heard + (f64) n->ttl_in_seconds))) - /* add to list of neighbors to delete */ - vec_add1 (delete_list, n - cm->neighbors); - else if (n->last_sent == 0.0) - /* First time, send 3 hellos */ - send_hello (cm, n, 3 /* three to begin with */ ); - else if (now > (n->last_sent + (((f64) n->ttl_in_seconds) / 6.0))) - /* Normal keepalive, send one */ - send_hello (cm, n, 1 /* one as a keepalive */ ); - } - - for (i = 0; i < vec_len (delete_list); i++) - { - n = vec_elt_at_index (cm->neighbors, delete_list[i]); - delete_neighbor (cm, n, 1); - } - if (delete_list) - _vec_len (delete_list) = 0; - if (n_list) - _vec_len (n_list) = 0; -} - -static clib_error_t * -cdp_periodic_init (vlib_main_t * vm) -{ - cdp_main_t *cm = &cdp_main; - - /* Create the ethernet cdp hello packet template */ - { - ethernet_llc_snap_and_cdp_header_t h; - - memset (&h, 0, sizeof (h)); - - /* Send to 01:00:0c:cc:cc */ - h.ethernet.dst_address[0] = 0x01; - /* h.ethernet.dst_address[1] = 0x00; (memset) */ - h.ethernet.dst_address[2] = 0x0C; - h.ethernet.dst_address[3] = 0xCC; - h.ethernet.dst_address[4] = 0xCC; - h.ethernet.dst_address[5] = 0xCC; - - /* leave src address blank (fill in at send time) */ - - /* leave length blank (fill in at send time) */ - - /* LLC */ - h.llc.dst_sap = h.llc.src_sap = 0xAA; /* SNAP */ - h.llc.control = 0x03; /* UI (no extended control bytes) */ - - /* SNAP */ - /* h.snap.oui[0] = 0x00; (memset) */ - /* h.snap.oui[1] = 0x00; (memset) */ - h.snap.oui[2] = 0x0C; /* Cisco = 0x00000C */ - h.snap.protocol = htons (0x2000); /* CDP = 0x2000 */ - - /* CDP */ - h.cdp.version = 2; - h.cdp.ttl = 180; - - vlib_packet_template_init - (vm, &cm->packet_templates[CDP_PACKET_TEMPLATE_ETHERNET], - /* data */ &h, - sizeof (h), - /* alloc chunk size */ 8, - "cdp-ethernet"); - } - -#if 0 /* retain for reference */ - - /* Create the hdlc cdp hello packet template */ - { - hdlc_and_cdp_header_t h; - - memset (&h, 0, sizeof (h)); - - h.hdlc.address = 0x0f; - /* h.hdlc.control = 0; (memset) */ - h.hdlc.protocol = htons (0x2000); /* CDP = 0x2000 */ - - /* CDP */ - h.cdp.version = 2; - h.cdp.ttl = 180; - - vlib_packet_template_init - (vm, &cm->packet_templates[CDP_PACKET_TEMPLATE_HDLC], - /* data */ &h, - sizeof (h), - /* alloc chunk size */ 8, - "cdp-hdlc"); - } - - /* Create the srp cdp hello packet template */ - { - srp_and_cdp_header_t h; - - memset (&h, 0, sizeof (h)); - - /* Send to 01:00:0c:cc:cc */ - h.ethernet.dst_address[0] = 0x01; - /* h.ethernet.dst_address[1] = 0x00; (memset) */ - h.ethernet.dst_address[2] = 0x0C; - h.ethernet.dst_address[3] = 0xCC; - h.ethernet.dst_address[4] = 0xCC; - h.ethernet.dst_address[5] = 0xCC; - - /* leave src address blank (fill in at send time) */ - - /* The srp header is filled in at xmt */ - h.srp.ttl = 1; - h.srp.priority = 7; - h.srp.mode = SRP_MODE_data; - srp_header_compute_parity (&h.srp); - - /* Inner ring and parity will be set at send time */ - - h.ethernet.type = htons (0x2000); /* CDP = 0x2000 */ - - /* CDP */ - h.cdp.version = 2; - h.cdp.ttl = 180; - - vlib_packet_template_init - (vm, &cm->packet_templates[CDP_PACKET_TEMPLATE_SRP], - /* data */ &h, - sizeof (h), - /* alloc chunk size */ 8, - "cdp-srp"); - } -#endif - - return 0; -} - -VLIB_INIT_FUNCTION (cdp_periodic_init); - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "gnu") - * End: - */ diff --git a/src/vnet/cdp/cdp_protocol.h b/src/vnet/cdp/cdp_protocol.h deleted file mode 100644 index dc6c66d52c3..00000000000 --- a/src/vnet/cdp/cdp_protocol.h +++ /dev/null @@ -1,186 +0,0 @@ -/* - * Copyright (c) 2011-2016 Cisco and/or its affiliates. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#ifndef __included_cdp_protocol_h__ -#define __included_cdp_protocol_h__ - -#include <vnet/ethernet/ethernet.h> /* for ethernet_header_t */ -#include <vnet/llc/llc.h> -#include <vnet/snap/snap.h> -#include <vnet/srp/packet.h> - -typedef CLIB_PACKED (struct - { - u8 version; - u8 ttl; - u16 checksum; /* 1's complement of the 1's complement sum */ - u8 data[0]; - }) cdp_hdr_t; - -typedef struct -{ - u8 dst_address[6]; - u8 src_address[6]; - u16 len; -} ethernet_802_3_header_t; - -typedef CLIB_PACKED (struct - { - ethernet_802_3_header_t ethernet; - llc_header_t llc; snap_header_t snap; cdp_hdr_t cdp; - }) ethernet_llc_snap_and_cdp_header_t; - -typedef CLIB_PACKED (struct - { - hdlc_header_t hdlc; cdp_hdr_t cdp; - }) hdlc_and_cdp_header_t; - -typedef CLIB_PACKED (struct - { - srp_header_t srp; - ethernet_header_t ethernet; cdp_hdr_t cdp; - }) srp_and_cdp_header_t; - -typedef CLIB_PACKED (struct - { - u16 t; - u16 l; - u8 v[0]; - }) cdp_tlv_t; - -/* - * TLV codes. - */ -#define foreach_cdp_tlv_type \ -_(unused) \ -_(device_name) /* uniquely identifies the device */ \ -_(address) /* list of addresses this device has */ \ -_(port_id) /* port CDP packet was sent out on */ \ -_(capabilities) /* funct. capabilities of the device */ \ -_(version) /* version */ \ -_(platform) /* hardware platform of this device */ \ -_(ipprefix) /* An IP network prefix */ \ -_(hello) /* Pprotocol piggyback hello msg */ \ -_(vtp_domain) /* VTP management domain */ \ -_(native_vlan) /* Native VLAN number */ \ -_(duplex) /* The interface duplex mode */ \ -_(appl_vlan) /* Appliance VLAN-ID TLV */ \ -_(trigger) /* For sending trigger TLV msgs. */ \ -_(power) /* Power consumption of that device */ \ -_(mtu) /* MTU defined for sending intf. */ \ -_(trust) /* Extended trust TLV */ \ -_(cos) /* COS for Untrusted Port TLV */ \ -_(sysname) /* System name (FQDN of device) */ \ -_(sysobject) /* OID of sysObjectID MIB object */ \ -_(mgmt_addr) /* SNMP manageable addrs. of device */ \ -_(physical_loc) /* Physical Location of the device */ \ -_(mgmt_addr2) /* External Port-ID */ \ -_(power_requested) \ -_(power_available) \ -_(port_unidirectional) \ -_(unknown_28) \ -_(energywise) \ -_(unknown_30) \ -_(spare_poe) - -typedef enum -{ -#define _(t) CDP_TLV_##t, - foreach_cdp_tlv_type -#undef _ -} cdp_tlv_code_t; - -/* - The address TLV looks as follows: - - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Number of addresses | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | IDRP encoded address | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - - An address is encoded in IDRP format: - - 0 1 2 3 - 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | PT | PT Length | Protocol (variable) ... - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Address length | Address (variable) ... - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - - PT: Protocol type - 1 = NLPID format - 2 = 802.2 format - - PT Length: - Length of protocol field, 1 for PT = 1, and either 3 or 8 for - 802.2 format depending if SNAP is used for PT = 2. - - The encodings for the other protocols have the following format: - - field: <SSAP><DSAP><CTRL><-------OUI------><protocl_TYPE> - | | | | | | | | | - bytes: 0 1 2 3 4 5 6 7 8 - - where the first 3 bytes are 0xAAAA03 for SNAP encoded addresses. - The OUI is 000000 for ethernet and <protocl_TYPE> - is the assigned Ethernet type code for the particular protocol. - e.g. for DECnet the encoding is AAAA03 000000 6003. - for IPv6 the encoding is AAAA03 000000 86DD -*/ - -/* - * Capabilities. - */ - -#define CDP_ROUTER_DEVICE 0x0001 -#define CDP_TB_DEVICE 0x0002 -#define CDP_SRB_DEVICE 0x0004 -#define CDP_SWITCH_DEVICE 0x0008 -#define CDP_HOST_DEVICE 0x0010 -#define CDP_IGMP_DEVICE 0x0020 -#define CDP_REPEATER_DEVICE 0x0040 - -/* - The protocol-hello TLV looks as follows: - - 0 1 2 3 - 012345678901234567890123456789012345678 - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Type | Length | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | OUI | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Protocol ID | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | up to 27 bytes of message | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -*/ - -/* - * These macros define the valid values for the Duplex TLV. - */ -#define CDP_DUPLEX_TLV_HALF 0x0 -#define CDP_DUPLEX_TLV_FULL 0x1 - -#endif /* __included_cdp_protocol_h__ */ - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "gnu") - * End: - */ |