[ovs-dev] [PATCH] LLDP: add new command to show LLDP neighbor info

Rick Zhong winsome8282 at 163.com
Wed Mar 24 03:56:25 UTC 2021


Dear OVS reviewers/supervisors:


This patch is related to LLDP which provides a new command "ovs-appctl lldp/neighbor" to show LLDP neighbor info when LLDP is enabled on OVS interfaces.


With this new command, user is enable to get LLDP neighbor info even if not in SPB network.


One limitation is that when multiple peer Management IP addresses are found by LLDP, only one Management IP address is displayed by the command.


The patch is well-tested on Linux.


Related commit: af4b3d3 and e4bc70c (add new command to show LLDP neighbor info #349)


Signed-off-by: Rick Zhong (winsome8282 at 163.com)


=================================================================================
diff --git a/lib/ovs-lldp.c b/lib/ovs-lldp.c
index 05c1dd434..4c8ab9126 100644
--- a/lib/ovs-lldp.c
+++ b/lib/ovs-lldp.c
@@ -324,6 +324,84 @@ aa_print_isid_status(struct ds *ds, struct lldp *lldp) OVS_REQUIRES(mutex)
     }
 }
 
+static void
+lldp_print_neighbor_port(struct ds *ds, struct lldpd_hardware *hw)
+{
+    struct lldpd_port *port;
+
+    LIST_FOR_EACH (port, p_entries, &hw->h_rports) {
+        const char *none_str = "";
+        char *id = NULL;
+        const char *name = NULL;
+        const char *port_id = NULL;
+        char ipaddress[INET6_ADDRSTRLEN + 1];
+        memset(ipaddress, 0, INET6_ADDRSTRLEN + 1);
+
+        if (port->p_chassis) {
+            if (port->p_chassis->c_id_len > 0) {
+                chassisid_to_string(port->p_chassis->c_id,
+                                    port->p_chassis->c_id_len, &id);
+            }
+
+            name = port->p_chassis->c_name;
+
+            struct lldpd_mgmt *mgmt;
+            LIST_FOR_EACH (mgmt, m_entries, &port->p_chassis->c_mgmt) {
+                int af;
+                size_t alen;
+                switch (mgmt->m_family) {
+                    case LLDPD_AF_IPV4:
+                        alen = INET_ADDRSTRLEN + 1;
+                        af = AF_INET;
+                        break;
+                    case LLDPD_AF_IPV6:
+                        alen = INET6_ADDRSTRLEN + 1;
+                        af = AF_INET6;
+                        break;
+                    default:
+                        continue;
+                }
+
+                if (inet_ntop(af, &mgmt->m_addr, ipaddress, alen) == NULL) {
+                    continue;
+                }
+                break;
+            }
+        }
+
+        port_id = port->p_id;
+
+        ds_put_format(ds, "  Neighbor Chassis ID: %s\n",
+                      id ? id : none_str);
+        ds_put_format(ds, "  Neighbor Chassis SysName: %s\n",
+                      name ? name : none_str);
+        ds_put_format(ds, "  Neighbor Management IP: %s\n",
+                      ipaddress);
+        ds_put_format(ds, "  Neighbor Port ID: %s\n",
+                      port_id ? port_id : none_str);
+
+        if (id != NULL) {
+            free(id);
+        }
+    }
+}
+
+static void
+lldp_print_neighbor(struct ds *ds, struct lldp *lldp) OVS_REQUIRES(mutex)
+{
+    struct lldpd_hardware *hw;
+
+    ds_put_format(ds, "LLDP: %s\n", lldp->name);
+
+    if (!lldp->lldpd) {
+        return;
+    }
+
+    LIST_FOR_EACH (hw, h_entries, &lldp->lldpd->g_hardware) {
+        lldp_print_neighbor_port(ds, hw);
+    }
+}
+
 static void
 aa_unixctl_status(struct unixctl_conn *conn, int argc OVS_UNUSED,
                   const char *argv[] OVS_UNUSED, void *aux OVS_UNUSED)
@@ -382,6 +460,25 @@ aa_unixctl_statistics(struct unixctl_conn *conn, int argc OVS_UNUSED,
     unixctl_command_reply(conn, ds_cstr(&ds));
 }
 
+static void
+lldp_unixctl_show_neighbor(struct unixctl_conn *conn, int argc OVS_UNUSED,
+                  const char *argv[] OVS_UNUSED, void *aux OVS_UNUSED)
+    OVS_EXCLUDED(mutex)
+{
+    struct lldp *lldp;
+    struct ds ds = DS_EMPTY_INITIALIZER;
+
+    ovs_mutex_lock(&mutex);
+
+    HMAP_FOR_EACH (lldp, hmap_node, all_lldps) {
+        lldp_print_neighbor(&ds, lldp);
+    }
+    unixctl_command_reply(conn, ds_cstr(&ds));
+    ds_destroy(&ds);
+
+    ovs_mutex_unlock(&mutex);
+}
+
 /* An Auto Attach mapping was configured.  Populate the corresponding
  * structures in the LLDP hardware.
  */
@@ -649,6 +746,8 @@ lldp_init(void)
                              aa_unixctl_show_isid, NULL);
     unixctl_command_register("autoattach/statistics", "[bridge]", 0, 1,
                              aa_unixctl_statistics, NULL);
+    unixctl_command_register("lldp/neighbor", "[bridge]", 0, 1,
+                             lldp_unixctl_show_neighbor, NULL);
 }
 
 /* Returns true if 'lldp' should process packets from 'flow'.  Sets
=================================================================================


Regards,
Rick Zhong


More information about the dev mailing list