From 0e355867f211a922c5b21ddbbb073eb2c35430b9 Mon Sep 17 00:00:00 2001 From: "Sar Ashki, Babak" Date: Mon, 24 Feb 2020 06:01:03 -0800 Subject: [PATCH] lldpd client add show interfaces cmd from upstream commit a54f6012efff77c966f533b8ef35b8627e3c8212 --- src/client/client.h | 2 + src/client/display.c | 99 ++++++++++++++++++++++++++++++++++------- src/client/lldpcli.8.in | 20 +++++++++ src/client/show.c | 44 ++++++++++++++++++ src/daemon/lldpd.c | 1 + 5 files changed, 151 insertions(+), 15 deletions(-) diff --git a/src/client/client.h b/src/client/client.h index e3ee352..8da3e3f 100644 --- a/src/client/client.h +++ b/src/client/client.h @@ -131,6 +131,8 @@ void display_interfaces_stats(lldpctl_conn_t *, struct writer *, struct cmd_env *); void display_interface_stats(lldpctl_conn_t *, struct writer *, lldpctl_atom_t *); +void display_local_interfaces(lldpctl_conn_t *, struct writer *, + struct cmd_env *, int, int); diff --git a/src/client/display.c b/src/client/display.c index cbd0e31..2769890 100644 --- a/src/client/display.c +++ b/src/client/display.c @@ -349,7 +349,8 @@ display_port(struct writer *w, lldpctl_atom_t *port, int details) tag_datatag(w, "descr", "PortDescr", lldpctl_atom_get_str(port, lldpctl_k_port_descr)); - if (details) + if (details && + lldpctl_atom_get_int(port, lldpctl_k_port_ttl) > 0) tag_datatag(w, "ttl", "TTL", lldpctl_atom_get_str(port, lldpctl_k_port_ttl)); @@ -473,6 +474,38 @@ display_port(struct writer *w, lldpctl_atom_t *port, int details) tag_end(w); } +static void +display_local_ttl(struct writer *w, lldpctl_conn_t *conn, int details) +{ + char *ttl; + long int tx_hold; + long int tx_interval; + + lldpctl_atom_t *configuration; + configuration = lldpctl_get_configuration(conn); + if (!configuration) { + log_warnx("lldpctl", "not able to get configuration. %s", + lldpctl_last_strerror(conn)); + return; + } + + tx_hold = lldpctl_atom_get_int(configuration, lldpctl_k_config_tx_hold); + tx_interval = lldpctl_atom_get_int(configuration, lldpctl_k_config_tx_interval); + + if (asprintf(&ttl, "%lu", tx_hold*tx_interval) == -1) { + log_warnx("lldpctl", "not enough memory to build TTL."); + goto end; + } + + tag_start(w, "ttl", "TTL"); + tag_attr(w, "ttl", "", ttl); + tag_end(w); + free(ttl); +end: + lldpctl_atom_dec_ref(configuration); + return; +} + static void display_vlans(struct writer *w, lldpctl_atom_t *port) { @@ -582,43 +615,51 @@ display_local_chassis(lldpctl_conn_t *conn, struct writer *w, void display_interface(lldpctl_conn_t *conn, struct writer *w, int hidden, - lldpctl_atom_t *iface, lldpctl_atom_t *neighbor, int details, int protocol) + lldpctl_atom_t *iface, lldpctl_atom_t *port, int details, int protocol) { + int local = 0; + if (!hidden && - lldpctl_atom_get_int(neighbor, lldpctl_k_port_hidden)) + lldpctl_atom_get_int(port, lldpctl_k_port_hidden)) return; /* user might have specified protocol to filter on display */ if ((protocol != LLDPD_MODE_MAX) && - (protocol != lldpctl_atom_get_int(neighbor, lldpctl_k_port_protocol))) + (protocol != lldpctl_atom_get_int(port, lldpctl_k_port_protocol))) return; - lldpctl_atom_t *chassis = lldpctl_atom_get(neighbor, lldpctl_k_port_chassis); + /* Infer local / remote port from the port index (remote == 0) */ + local = lldpctl_atom_get_int(port, lldpctl_k_port_index)>0?1:0; + + lldpctl_atom_t *chassis = lldpctl_atom_get(port, lldpctl_k_port_chassis); tag_start(w, "interface", "Interface"); tag_attr(w, "name", "", lldpctl_atom_get_str(iface, lldpctl_k_interface_name)); tag_attr(w, "via" , "via", - lldpctl_atom_get_str(neighbor, lldpctl_k_port_protocol)); + lldpctl_atom_get_str(port, lldpctl_k_port_protocol)); if (details > DISPLAY_BRIEF) { - tag_attr(w, "rid" , "RID", - lldpctl_atom_get_str(chassis, lldpctl_k_chassis_index)); + if (!local) + tag_attr(w, "rid" , "RID", + lldpctl_atom_get_str(chassis, lldpctl_k_chassis_index)); tag_attr(w, "age" , "Time", - display_age(lldpctl_atom_get_int(neighbor, lldpctl_k_port_age))); + display_age(lldpctl_atom_get_int(port, lldpctl_k_port_age))); } display_chassis(w, chassis, details); - display_port(w, neighbor, details); + display_port(w, port, details); + if (details && local) + display_local_ttl(w, conn, details); if (details == DISPLAY_DETAILS) { - display_vlans(w, neighbor); - display_ppvids(w, neighbor); - display_pids(w, neighbor); - display_med(w, neighbor, chassis); + display_vlans(w, port); + display_ppvids(w, port); + display_pids(w, port); + display_med(w, port, chassis); } lldpctl_atom_dec_ref(chassis); - display_custom_tlvs(w, neighbor); + display_custom_tlvs(w, port); tag_end(w); } @@ -675,6 +716,34 @@ display_interfaces(lldpctl_conn_t *conn, struct writer *w, tag_end(w); } + +/** + * Display information about local interfaces. + * + * @param conn Connection to lldpd. + * @param w Writer. + * @param hidden Whatever to show hidden ports. + * @param env Environment from which we may find the list of ports. + * @param details Level of details we need (DISPLAY_*). + */ +void +display_local_interfaces(lldpctl_conn_t *conn, struct writer *w, + struct cmd_env *env, + int hidden, int details) +{ + lldpctl_atom_t *iface; + int protocol = LLDPD_MODE_MAX; + + tag_start(w, "lldp", "LLDP interfaces"); + while ((iface = cmd_iterate_on_interfaces(conn, env))) { + lldpctl_atom_t *port; + port = lldpctl_get_port(iface); + display_interface(conn, w, hidden, iface, port, details, protocol); + lldpctl_atom_dec_ref(port); + } + tag_end(w); + } + void display_stat(struct writer *w, const char *tag, const char *descr, long unsigned int cnt) diff --git a/src/client/lldpcli.8.in b/src/client/lldpcli.8.in index 1a20fa8..8a4123e 100644 --- a/src/client/lldpcli.8.in +++ b/src/client/lldpcli.8.in @@ -134,6 +134,26 @@ one or several ports, the information displayed is limited to the given list of ports. .Ed +.Cd show interfaces +.Op ports Ar ethX Op ,... +.Op Cd details | summary +.Op Cd hidden +.Bd -ragged -offset XXXXXX +Display information about each local interface known by +.Xr lldpd 8 +daemon. With +.Cd summary , +only the name and the port description of each local interface will be +displayed. On the other hand, with +.Cd details , +all available information will be displayed, giving a verbose +view. When using +.Cd hidden , +also display local ports hidden by the smart filter. When specifying +one or several ports, the information displayed is limited to the +given list of ports. +.Ed + .Cd show chassis .Op Cd details | summary .Bd -ragged -offset XXXXXX diff --git a/src/client/show.c b/src/client/show.c index fa704b8..8ba8acb 100644 --- a/src/client/show.c +++ b/src/client/show.c @@ -48,6 +48,35 @@ cmd_show_neighbors(struct lldpctl_conn_t *conn, struct writer *w, return 1; } +/** + * Show interfaces. + * + * The environment will contain the following keys: + * - C{ports} list of ports we want to restrict showing. + * - C{hidden} if we should show hidden ports. + * - C{summary} if we want to show only a summary + * - C{detailed} for a detailed overview + */ +static int +cmd_show_interfaces(struct lldpctl_conn_t *conn, struct writer *w, + struct cmd_env *env, void *arg) +{ + log_debug("lldpctl", "show interfaces data (%s) %s hidden interfaces", + cmdenv_get(env, "summary")?"summary": + cmdenv_get(env, "detailed")?"detailed": + "normal", cmdenv_get(env, "hidden")?"with":"without"); + if (cmdenv_get(env, "ports")) + log_debug("lldpctl", "restrict to the following ports: %s", + cmdenv_get(env, "ports")); + + display_local_interfaces(conn, w, env, !!cmdenv_get(env, "hidden"), + cmdenv_get(env, "summary")?DISPLAY_BRIEF: + cmdenv_get(env, "detailed")?DISPLAY_DETAILS: + DISPLAY_NORMAL); + + return 1; +} + /** * Show chassis. * @@ -286,6 +315,12 @@ register_commands_show(struct cmd_node *root) "Show neighbors data", NULL, NULL, NULL); + struct cmd_node *interfaces = commands_new( + show, + "interfaces", + "Show interfaces data", + NULL, NULL, NULL); + struct cmd_node *chassis = commands_new( show, "chassis", @@ -306,6 +341,15 @@ register_commands_show(struct cmd_node *root) register_common_commands(neighbors, 1); + /* Interfaces data */ + commands_new(interfaces, + NEWLINE, + "Show interfaces data", + NULL, cmd_show_interfaces, NULL); + + cmd_restrict_ports(interfaces); + register_common_commands(interfaces, 0); + /* Chassis data */ commands_new(chassis, NEWLINE, diff --git a/src/daemon/lldpd.c b/src/daemon/lldpd.c index 97df38e..8ce38a9 100644 --- a/src/daemon/lldpd.c +++ b/src/daemon/lldpd.c @@ -1037,6 +1037,7 @@ lldpd_send(struct lldpd_hardware *hardware) cfg->g_protocols[i].name); cfg->g_protocols[i].send(cfg, hardware); + hardware->h_lport.p_protocol = cfg->g_protocols[i].mode; sent++; break; } -- 2.23.0