FD.io VPP  v17.04.2-2-ga8f93f8
Vector Packet Processing
lldp_cli.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2011-2016 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  * @file
18  * @brief LLDP CLI handling
19  *
20  */
22 #include <vnet/lldp/lldp_node.h>
23 
24 #ifndef ETHER_ADDR_LEN
25 #include <net/ethernet.h>
26 #endif
27 
28 typedef enum lldp_cfg_err
29 {
34 
35 static clib_error_t *
36 lldp_cfg_err_to_clib_err (lldp_cfg_err_t e)
37 {
38 
39  switch (e)
40  {
41  case lldp_ok:
42  return 0;
43  case lldp_not_supported:
44  return clib_error_return (0, "not supported");
45  case lldp_invalid_arg:
46  return clib_error_return (0, "invalid argument");
47  }
48  return 0;
49 }
50 
51 static lldp_cfg_err_t
52 lldp_cfg_intf_set (u32 hw_if_index, int enable)
53 {
54  lldp_main_t *lm = &lldp_main;
55  vnet_main_t *vnm = lm->vnet_main;
57  const vnet_hw_interface_t *hi = vnet_get_hw_interface (vnm, hw_if_index);
58  const ethernet_interface_t *eif = ethernet_get_interface (em, hw_if_index);
59 
60  if (!eif)
61  {
62  return lldp_not_supported;
63  }
64 
65  if (enable)
66  {
67  lldp_intf_t *n = lldp_get_intf (lm, hw_if_index);
68  if (n)
69  {
70  /* already enabled */
71  return 0;
72  }
73  n = lldp_create_intf (lm, hw_if_index);
74  const vnet_sw_interface_t *sw =
77  {
78  lldp_schedule_intf (lm, n);
79  }
80  }
81  else
82  {
83  lldp_intf_t *n = lldp_get_intf (lm, hi->sw_if_index);
84  lldp_delete_intf (lm, n);
85  }
86 
87  return 0;
88 }
89 
90 static clib_error_t *
92  vlib_cli_command_t * cmd)
93 {
94  lldp_main_t *lm = &lldp_main;
95  vnet_main_t *vnm = lm->vnet_main;
96  u32 hw_if_index;
97  int enable = 0;
98 
99  if (unformat (input, "%U %U", unformat_vnet_hw_interface, vnm, &hw_if_index,
101  {
102  return
103  lldp_cfg_err_to_clib_err (lldp_cfg_intf_set (hw_if_index, enable));
104  }
105  else
106  {
107  return clib_error_return (0, "unknown input `%U'",
108  format_unformat_error, input);
109  }
110  return 0;
111 }
112 
113 static lldp_cfg_err_t
114 lldp_cfg_set (u8 ** host, int hold_time, int tx_interval)
115 {
116  lldp_main_t *lm = &lldp_main;
117  int reschedule = 0;
118  if (host && *host)
119  {
120  vec_free (lm->sys_name);
121  lm->sys_name = *host;
122  *host = NULL;
123  }
124  if (hold_time)
125  {
126  if (hold_time < LLDP_MIN_TX_HOLD || hold_time > LLDP_MAX_TX_HOLD)
127  {
128  return lldp_invalid_arg;
129  }
130  if (lm->msg_tx_hold != hold_time)
131  {
132  lm->msg_tx_hold = hold_time;
133  reschedule = 1;
134  }
135  }
136  if (tx_interval)
137  {
138  if (tx_interval < LLDP_MIN_TX_INTERVAL ||
139  tx_interval > LLDP_MAX_TX_INTERVAL)
140  {
141  return lldp_invalid_arg;
142  }
143  if (lm->msg_tx_interval != tx_interval)
144  {
145  reschedule = 1;
146  lm->msg_tx_interval = tx_interval;
147  }
148  }
149  if (reschedule)
150  {
153  }
154  return lldp_ok;
155 }
156 
157 static clib_error_t *
159  vlib_cli_command_t * cmd)
160 {
161  int hold_time = 0;
162  int tx_interval = 0;
163  u8 *host = NULL;
164  clib_error_t *ret = NULL;
165 
167  {
168  if (unformat (input, "system-name %s", &host))
169  {
170  }
171  else if (unformat (input, "tx-hold %d", &hold_time))
172  {
173  if (hold_time < LLDP_MIN_TX_HOLD || hold_time > LLDP_MAX_TX_HOLD)
174  {
175  ret =
177  "invalid tx-hold `%d' (out of range <%d,%d>)",
178  hold_time, LLDP_MIN_TX_HOLD,
179  LLDP_MAX_TX_HOLD);
180  goto out;
181  }
182  }
183  else if (unformat (input, "tx-interval %d", &tx_interval))
184  {
185  if (tx_interval < LLDP_MIN_TX_INTERVAL ||
186  tx_interval > LLDP_MAX_TX_INTERVAL)
187  {
188  ret =
190  "invalid tx-interval `%d' (out of range <%d,%d>)",
191  tx_interval, LLDP_MIN_TX_INTERVAL,
193  goto out;
194  }
195  }
196  else
197  {
198  ret = clib_error_return (0, "unknown input `%U'",
199  format_unformat_error, input);
200  goto out;
201  }
202  }
203  ret =
204  lldp_cfg_err_to_clib_err (lldp_cfg_set (&host, hold_time, tx_interval));
205 out:
206  vec_free (host);
207  return ret;
208 }
209 
210 /* *INDENT-OFF* */
211 VLIB_CLI_COMMAND(set_interface_lldp_cmd, static) = {
212  .path = "set interface lldp",
213  .short_help = "set interface lldp <interface> (enable | disable) ",
214  .function = lldp_intf_cmd,
215 };
216 
217 VLIB_CLI_COMMAND(set_lldp_cmd, static) = {
218  .path = "set lldp",
219  .short_help = "set lldp [system-name <string>] [tx-hold <value>] "
220  "[tx-interval <value>]",
221  .function = lldp_cfg_cmd,
222 };
223 /* *INDENT-ON* */
224 
225 static const char *
227 {
228  switch (t)
229  {
230 #define F(num, val, str) \
231  case num: \
232  return str;
234 #undef F
235  }
236  return "unknown chassis subtype";
237 }
238 
239 static const char *
241 {
242  switch (t)
243  {
244 #define F(num, val, str) \
245  case num: \
246  return str;
248 #undef F
249  }
250  return "unknown port subtype";
251 }
252 
253 /*
254  * format port id subtype&value
255  *
256  * @param va - 1st argument - unsigned - port id subtype
257  * @param va - 2nd argument - u8* - port id
258  * @param va - 3rd argument - unsigned - port id length
259  * @param va - 4th argument - int - 1 for detailed output, 0 for simple
260  */
261 u8 *
262 format_lldp_port_id (u8 * s, va_list * va)
263 {
264  const lldp_port_id_subtype_t subtype = va_arg (*va, unsigned);
265  const u8 *id = va_arg (*va, u8 *);
266  const unsigned len = va_arg (*va, unsigned);
267  const int detail = va_arg (*va, int);
268  if (!id)
269  {
270  return s;
271  }
272  switch (subtype)
273  {
274  case LLDP_PORT_ID_SUBTYPE_NAME (intf_alias):
275  /* fallthrough */
276  case LLDP_PORT_ID_SUBTYPE_NAME (port_comp):
277  /* fallthrough */
278  case LLDP_PORT_ID_SUBTYPE_NAME (local):
279  /* fallthrough */
280  case LLDP_PORT_ID_SUBTYPE_NAME (intf_name):
281  if (detail)
282  {
283  s = format (s, "%U(%s)", format_ascii_bytes, id, len,
284  lldp_port_id_subtype_str (subtype));
285  }
286  else
287  {
288  s = format (s, "%U", format_ascii_bytes, id, len);
289  }
290  break;
291  case LLDP_PORT_ID_SUBTYPE_NAME (mac_addr):
292  if (ETHER_ADDR_LEN == len)
293  {
294  if (detail)
295  {
296  s = format (s, "%U(%s)", format_mac_address, id,
297  lldp_port_id_subtype_str (subtype));
298  }
299  else
300  {
301  s = format (s, "%U", format_mac_address, id);
302  }
303  break;
304  }
305  /* fallthrough */
306  case LLDP_PORT_ID_SUBTYPE_NAME (net_addr):
307  /* TODO */
308  /* fallthrough */
309  default:
310  if (detail)
311  {
312  s = format (s, "%U(%s)", format_hex_bytes, id, len,
313  lldp_port_id_subtype_str (subtype));
314  }
315  else
316  {
317  s = format (s, "%U", format_hex_bytes, id, len);
318  }
319  break;
320  }
321  return s;
322 }
323 
324 /*
325  * format chassis id subtype&value
326  *
327  * @param s format string
328  * @param va - 1st argument - unsigned - chassis id subtype
329  * @param va - 2nd argument - u8* - chassis id
330  * @param va - 3rd argument - unsigned - chassis id length
331  * @param va - 4th argument - int - 1 for detailed output, 0 for simple
332  */
333 u8 *
334 format_lldp_chassis_id (u8 * s, va_list * va)
335 {
336  const lldp_chassis_id_subtype_t subtype =
337  va_arg (*va, lldp_chassis_id_subtype_t);
338  const u8 *id = va_arg (*va, u8 *);
339  const unsigned len = va_arg (*va, unsigned);
340  const int detail = va_arg (*va, int);
341  if (!id)
342  {
343  return s;
344  }
345  switch (subtype)
346  {
347  case LLDP_CHASS_ID_SUBTYPE_NAME (chassis_comp):
348  /* fallthrough */
349  case LLDP_CHASS_ID_SUBTYPE_NAME (intf_alias):
350  /* fallthrough */
351  case LLDP_CHASS_ID_SUBTYPE_NAME (port_comp):
352  /* fallthrough */
353  case LLDP_PORT_ID_SUBTYPE_NAME (local):
354  /* fallthrough */
355  case LLDP_CHASS_ID_SUBTYPE_NAME (intf_name):
356  if (detail)
357  {
358  s = format (s, "%U(%s)", format_ascii_bytes, id, len,
359  lldp_chassis_id_subtype_str (subtype));
360  }
361  else
362  {
363  s = format (s, "%U", format_ascii_bytes, id, len);
364  }
365  break;
366  case LLDP_CHASS_ID_SUBTYPE_NAME (mac_addr):
367  if (ETHER_ADDR_LEN == len)
368  {
369  if (detail)
370  {
371  s = format (s, "%U(%s)", format_mac_address, id,
372  lldp_chassis_id_subtype_str (subtype));
373  }
374  else
375  {
376  s = format (s, "%U", format_mac_address, id);
377  }
378  break;
379  }
380  /* fallthrough */
381  case LLDP_CHASS_ID_SUBTYPE_NAME (net_addr):
382  /* TODO */
383  default:
384  if (detail)
385  {
386  s = format (s, "%U(%s)", format_hex_bytes, id, len,
387  lldp_chassis_id_subtype_str (subtype));
388  }
389  else
390  {
391  s = format (s, "%U", format_hex_bytes, id, len);
392  }
393  break;
394  }
395  return s;
396 }
397 
398 /*
399  * convert a tlv code to human-readable string
400  */
401 static const char *
403 {
404  switch (t)
405  {
406 #define F(n, t, s) \
407  case n: \
408  return s;
410 #undef F
411  }
412  return "unknown lldp tlv";
413 }
414 
415 /*
416  * format a single LLDP TLV
417  *
418  * @param s format string
419  * @param va variable list - pointer to lldp_tlv_t is expected
420  */
421 u8 *
422 format_lldp_tlv (u8 * s, va_list * va)
423 {
424  const lldp_tlv_t *tlv = va_arg (*va, lldp_tlv_t *);
425  if (!tlv)
426  {
427  return s;
428  }
429  u16 l = lldp_tlv_get_length (tlv);
430  switch (lldp_tlv_get_code (tlv))
431  {
432  case LLDP_TLV_NAME (chassis_id):
433  s = format (s, "%U", format_lldp_chassis_id,
434  ((lldp_chassis_id_tlv_t *) tlv)->subtype,
435  ((lldp_chassis_id_tlv_t *) tlv)->id,
436  l - STRUCT_SIZE_OF (lldp_chassis_id_tlv_t, subtype), 1);
437  break;
438  case LLDP_TLV_NAME (port_id):
439  s = format (s, "%U", format_lldp_port_id,
440  ((lldp_port_id_tlv_t *) tlv)->subtype,
441  ((lldp_port_id_tlv_t *) tlv)->id,
442  l - STRUCT_SIZE_OF (lldp_port_id_tlv_t, subtype), 1);
443  break;
444  case LLDP_TLV_NAME (ttl):
445  s = format (s, "%d", ntohs (((lldp_ttl_tlv_t *) tlv)->ttl));
446  break;
447  case LLDP_TLV_NAME (sys_name):
448  /* fallthrough */
449  case LLDP_TLV_NAME (sys_desc):
450  s = format (s, "%U", format_ascii_bytes, tlv->v, l);
451  break;
452  default:
453  s = format (s, "%U", format_hex_bytes, tlv->v, l);
454  }
455 
456  return s;
457 }
458 
459 static u8 *
460 format_time_ago (u8 * s, va_list * va)
461 {
462  f64 ago = va_arg (*va, double);
463  f64 now = va_arg (*va, double);
464  if (ago < 0.01)
465  {
466  return format (s, "never");
467  }
468  return format (s, "%.1fs ago", now - ago);
469 }
470 
471 static u8 *
473 {
474  vnet_main_t *vnm = &vnet_main;
475  const lldp_intf_t *n;
476  const vnet_hw_interface_t *hw;
477  const vnet_sw_interface_t *sw;
478  s = format (s, "LLDP configuration:\n");
479  if (lm->sys_name)
480  {
481  s = format (s, "Configured system name: %U\n", format_ascii_bytes,
482  lm->sys_name, vec_len (lm->sys_name));
483  }
484  s = format (s, "Configured tx-hold: %d\n", (int) lm->msg_tx_hold);
485  s = format (s, "Configured tx-interval: %d\n", (int) lm->msg_tx_interval);
486  s = format (s, "\nLLDP-enabled interface table:\n");
487  f64 now = vlib_time_now (vm);
488 
489  /* *INDENT-OFF* */
490  pool_foreach(
491  n, lm->intfs, ({
492  hw = vnet_get_hw_interface(vnm, n->hw_if_index);
493  sw = vnet_get_sw_interface(lm->vnet_main, hw->sw_if_index);
494  /* Interface shutdown */
495  if (!(sw->flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP))
496  {
497  s = format(s, "\nInterface name: %s\nInterface/peer state: "
498  "interface down\nLast packet sent: %U\n",
499  hw->name, format_time_ago, n->last_sent, now);
500  }
501  else if (now < n->last_heard + n->ttl)
502  {
503  s = format(s,
504  "\nInterface name: %s\nInterface/peer state: "
505  "active\nPeer chassis ID: %U\nRemote port ID: %U\nLast "
506  "packet sent: %U\nLast packet received: %U\n",
507  hw->name, format_lldp_chassis_id, n->chassis_id_subtype,
508  n->chassis_id, vec_len(n->chassis_id), 1,
509  format_lldp_port_id, n->port_id_subtype, n->port_id,
510  vec_len(n->port_id), 1, format_time_ago, n->last_sent,
511  now, format_time_ago, n->last_heard, now);
512  }
513  else
514  {
515  s = format(s, "\nInterface name: %s\nInterface/peer state: "
516  "inactive(timeout)\nLast known peer chassis ID: "
517  "%U\nLast known peer port ID: %U\nLast packet sent: "
518  "%U\nLast packet received: %U\n",
519  hw->name, format_lldp_chassis_id, n->chassis_id_subtype,
520  n->chassis_id, vec_len(n->chassis_id), 1,
521  format_lldp_port_id, n->port_id_subtype, n->port_id,
522  vec_len(n->port_id), 1, format_time_ago, n->last_sent,
523  now, format_time_ago, n->last_heard, now);
524  }
525  }));
526  /* *INDENT-ON* */
527  return s;
528 }
529 
530 static u8 *
531 format_lldp_intfs (u8 * s, va_list * va)
532 {
533  vlib_main_t *vm = va_arg (*va, vlib_main_t *);
534  const lldp_main_t *lm = va_arg (*va, lldp_main_t *);
535  const int detail = va_arg (*va, int);
536  vnet_main_t *vnm = &vnet_main;
537  const lldp_intf_t *n;
538 
539  if (detail)
540  {
541  return format_lldp_intfs_detail (s, vm, lm);
542  }
543 
544  f64 now = vlib_time_now (vm);
545  s = format (s, "%-25s %-25s %-25s %=15s %=15s %=10s\n", "Local interface",
546  "Peer chassis ID", "Remote port ID", "Last heard", "Last sent",
547  "Status");
548 
549  /* *INDENT-OFF* */
550  pool_foreach(
551  n, lm->intfs, ({
552  const vnet_hw_interface_t *hw =
553  vnet_get_hw_interface(vnm, n->hw_if_index);
554  const vnet_sw_interface_t *sw =
555  vnet_get_sw_interface(lm->vnet_main, hw->sw_if_index);
556  /* Interface shutdown */
557  if (!(sw->flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP))
558  continue;
559  if (now < n->last_heard + n->ttl)
560  {
561  s = format(s, "%-25s %-25U %-25U %=15U %=15U %=10s\n", hw->name,
562  format_lldp_chassis_id, n->chassis_id_subtype,
563  n->chassis_id, vec_len(n->chassis_id), 0,
564  format_lldp_port_id, n->port_id_subtype, n->port_id,
565  vec_len(n->port_id), 0, format_time_ago, n->last_heard,
566  now, format_time_ago, n->last_sent, now, "active");
567  }
568  else
569  {
570  s = format(s, "%-25s %-25s %-25s %=15U %=15U %=10s\n", hw->name,
571  "", "", format_time_ago, n->last_heard, now,
572  format_time_ago, n->last_sent, now, "inactive");
573  }
574  }));
575  /* *INDENT-ON* */
576  return s;
577 }
578 
579 static clib_error_t *
582 {
583  lldp_main_t *lm = &lldp_main;
584 
585  if (unformat (input, "detail"))
586  {
587  vlib_cli_output (vm, "%U\n", format_lldp_intfs, vm, lm, 1);
588  }
589  else
590  {
591  vlib_cli_output (vm, "%U\n", format_lldp_intfs, vm, lm, 0);
592  }
593  return 0;
594 }
595 
596 /* *INDENT-OFF* */
598  .path = "show lldp",
599  .short_help = "show lldp [detail]",
600  .function = show_lldp,
601 };
602 /* *INDENT-ON* */
603 
604 /*
605  * packet trace format function, very similar to
606  * lldp_packet_scan except that we call the per TLV format
607  * functions instead of the per TLV processing functions
608  */
609 u8 *
610 lldp_input_format_trace (u8 * s, va_list * args)
611 {
612  CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
613  CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
614  const lldp_input_trace_t *t = va_arg (*args, lldp_input_trace_t *);
615  const u8 *cur;
616  const lldp_tlv_t *tlv;
617  cur = t->data;
618  while (((cur + lldp_tlv_get_length ((lldp_tlv_t *) cur)) <
619  t->data + t->len))
620  {
621  tlv = (lldp_tlv_t *) cur;
622  if (cur == t->data)
623  {
624  s = format (s, "TLV #%d(%s): %U\n", lldp_tlv_get_code (tlv),
626  format_lldp_tlv, tlv);
627  }
628  else
629  {
630  s = format (s, " TLV #%d(%s): %U\n", lldp_tlv_get_code (tlv),
632  format_lldp_tlv, tlv);
633  }
634  cur += STRUCT_SIZE_OF (lldp_tlv_t, head) + lldp_tlv_get_length (tlv);
635  }
636 
637  return s;
638 }
639 
640 /*
641  * fd.io coding-style-patch-verification: ON
642  *
643  * Local Variables:
644  * eval: (c-set-style "gnu")
645  * End:
646  */
unformat_function_t unformat_vnet_hw_interface
lldp_main_t lldp_main
Definition: lldp_input.c:117
vmrglw vmrglh hi
vnet_main_t * vnet_main
Definition: lldp_node.h:70
#define LLDP_CHASS_ID_SUBTYPE_NAME(t)
Definition: lldp_protocol.h:81
#define LLDP_MAX_TX_HOLD
Definition: lldp_node.h:95
#define CLIB_UNUSED(x)
Definition: clib.h:79
lldp_chassis_id_subtype_t
Definition: lldp_protocol.h:85
static const char * lldp_tlv_code_str(lldp_tlv_code_t t)
Definition: lldp_cli.c:402
u8 * format_ascii_bytes(u8 *s, va_list *va)
Definition: std-formats.c:74
static lldp_cfg_err_t lldp_cfg_intf_set(u32 hw_if_index, int enable)
Definition: lldp_cli.c:52
#define NULL
Definition: clib.h:55
lldp_intf_t * intfs
Definition: lldp_node.h:51
static f64 vlib_time_now(vlib_main_t *vm)
Definition: main.h:185
void lldp_schedule_intf(lldp_main_t *lm, lldp_intf_t *n)
Definition: lldp_node.c:242
static vnet_hw_interface_t * vnet_get_hw_interface(vnet_main_t *vnm, u32 hw_if_index)
static vnet_sw_interface_t * vnet_get_sw_interface(vnet_main_t *vnm, u32 sw_if_index)
lldp_intf_t * lldp_get_intf(lldp_main_t *lm, u32 hw_if_index)
Definition: lldp_input.c:212
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:418
u16 ttl
Definition: lldp_node.h:42
static lldp_cfg_err_t lldp_cfg_set(u8 **host, int hold_time, int tx_interval)
Definition: lldp_cli.c:114
static u8 * format_lldp_intfs_detail(u8 *s, vlib_main_t *vm, const lldp_main_t *lm)
Definition: lldp_cli.c:472
#define LLDP_MAX_TX_INTERVAL
Definition: lldp_node.h:97
u8 * format_lldp_tlv(u8 *s, va_list *va)
Definition: lldp_cli.c:422
u16 lldp_tlv_get_length(const lldp_tlv_t *tlv)
Definition: lldp_input.c:98
ethernet_main_t ethernet_main
Definition: ethernet.h:273
u8 * format_lldp_chassis_id(u8 *s, va_list *va)
Definition: lldp_cli.c:334
u8 msg_tx_hold
Definition: lldp_node.h:82
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
Definition: pool.h:376
u8 * format_mac_address(u8 *s, va_list *args)
Definition: lisp_types.c:198
u8 * lldp_input_format_trace(u8 *s, va_list *args)
Definition: lldp_cli.c:610
#define F(num, val, str)
void lldp_delete_intf(lldp_main_t *lm, lldp_intf_t *n)
Definition: lldp_output.c:162
u8 * format_hex_bytes(u8 *s, va_list *va)
Definition: std-formats.c:84
#define clib_error_return(e, args...)
Definition: error.h:111
#define LLDP_MIN_TX_INTERVAL
Definition: lldp_node.h:96
#define LLDP_MIN_TX_HOLD
Definition: lldp_node.h:94
lldp_tlv_code_t lldp_tlv_get_code(const lldp_tlv_t *tlv)
Definition: lldp_input.c:86
static clib_error_t * show_lldp(vlib_main_t *vm, unformat_input_t *input, CLIB_UNUSED(vlib_cli_command_t *lmd))
Definition: lldp_cli.c:580
static void vlib_process_signal_event(vlib_main_t *vm, uword node_index, uword type_opaque, uword data)
Definition: node_funcs.h:930
u16 msg_tx_interval
Definition: lldp_node.h:91
static clib_error_t * lldp_intf_cmd(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: lldp_cli.c:91
struct _unformat_input_t unformat_input_t
vnet_main_t vnet_main
Definition: misc.c:43
#define LLDP_PORT_ID_SUBTYPE_NAME(t)
static u8 * format_time_ago(u8 *s, va_list *va)
Definition: lldp_cli.c:460
static vlib_cli_command_t show_lldp_command
(constructor) VLIB_CLI_COMMAND (show_lldp_command)
Definition: lldp_cli.c:597
#define UNFORMAT_END_OF_INPUT
Definition: format.h:143
static const char * lldp_chassis_id_subtype_str(lldp_chassis_id_subtype_t t)
Definition: lldp_cli.c:226
vlib_main_t * vm
Definition: buffer.c:276
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:340
static clib_error_t * lldp_cfg_cmd(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: lldp_cli.c:158
static const char * lldp_port_id_subtype_str(lldp_port_id_subtype_t t)
Definition: lldp_cli.c:240
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:154
#define VNET_SW_INTERFACE_FLAG_ADMIN_UP
Definition: interface.h:536
unsigned int u32
Definition: types.h:88
static clib_error_t * lldp_cfg_err_to_clib_err(lldp_cfg_err_t e)
Definition: lldp_cli.c:36
u32 lldp_process_node_index
Definition: lldp_node.h:57
lldp_port_id_subtype_t
vlib_main_t * vlib_main
Definition: lldp_node.h:69
unsigned short u16
Definition: types.h:57
ethernet_interface_t * ethernet_get_interface(ethernet_main_t *em, u32 hw_if_index)
Definition: interface.c:672
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
double f64
Definition: types.h:142
uword unformat_vlib_enable_disable(unformat_input_t *input, va_list *args)
Definition: format.c:116
unsigned char u8
Definition: types.h:56
enum lldp_cfg_err lldp_cfg_err_t
static u8 * format_lldp_intfs(u8 *s, va_list *va)
Definition: lldp_cli.c:531
LLDP global declarations.
u8 * format_unformat_error(u8 *s, va_list *va)
Definition: unformat.c:91
#define STRUCT_SIZE_OF(t, f)
Definition: clib.h:64
u8 * format_lldp_port_id(u8 *s, va_list *va)
Definition: lldp_cli.c:262
lldp_intf_t * lldp_create_intf(lldp_main_t *lm, u32 hw_if_index)
Definition: lldp_input.c:224
lldp_tlv_code_t
Definition: lldp_protocol.h:46
lldp_cfg_err
Definition: lldp_cli.c:28
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:577
u8 * sys_name
Definition: lldp_node.h:73
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:971
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:169
#define LLDP_TLV_NAME(t)
Definition: lldp_protocol.h:44