From patchwork Wed Jun 25 10:27:08 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Changliang Wu X-Patchwork-Id: 2102469 X-Patchwork-Delegate: aconole@redhat.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=smartx-com.20230601.gappssmtp.com header.i=@smartx-com.20230601.gappssmtp.com header.a=rsa-sha256 header.s=20230601 header.b=XHymQ9zG; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=2605:bc80:3010::137; helo=smtp4.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=patchwork.ozlabs.org) Received: from smtp4.osuosl.org (smtp4.osuosl.org [IPv6:2605:bc80:3010::137]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4bRygS2Rfcz20KF for ; Wed, 25 Jun 2025 20:27:32 +1000 (AEST) Received: from localhost (localhost [127.0.0.1]) by smtp4.osuosl.org (Postfix) with ESMTP id 4868141CDE; Wed, 25 Jun 2025 10:27:43 +0000 (UTC) X-Virus-Scanned: amavis at osuosl.org Received: from smtp4.osuosl.org ([127.0.0.1]) by localhost (smtp4.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP id 2rm8GEXZ74oB; Wed, 25 Jun 2025 10:27:42 +0000 (UTC) X-Comment: SPF check N/A for local connections - client-ip=140.211.9.56; helo=lists.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver= DKIM-Filter: OpenDKIM Filter v2.11.0 smtp4.osuosl.org 1B0C841CA1 Authentication-Results: smtp4.osuosl.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=smartx-com.20230601.gappssmtp.com header.i=@smartx-com.20230601.gappssmtp.com header.a=rsa-sha256 header.s=20230601 header.b=XHymQ9zG Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by smtp4.osuosl.org (Postfix) with ESMTPS id 1B0C841CA1; Wed, 25 Jun 2025 10:27:42 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 04ED9C02A6; Wed, 25 Jun 2025 10:27:42 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from smtp4.osuosl.org (smtp4.osuosl.org [140.211.166.137]) by lists.linuxfoundation.org (Postfix) with ESMTP id 61581C02A6 for ; Wed, 25 Jun 2025 10:27:41 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp4.osuosl.org (Postfix) with ESMTP id 5EC4141CD1 for ; Wed, 25 Jun 2025 10:27:41 +0000 (UTC) X-Virus-Scanned: amavis at osuosl.org Received: from smtp4.osuosl.org ([127.0.0.1]) by localhost (smtp4.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP id QdC3sxHBOxmN for ; Wed, 25 Jun 2025 10:27:40 +0000 (UTC) Received-SPF: Pass (mailfrom) identity=mailfrom; client-ip=2607:f8b0:4864:20::42e; helo=mail-pf1-x42e.google.com; envelope-from=changliang.wu@smartx.com; receiver= DMARC-Filter: OpenDMARC Filter v1.4.2 smtp4.osuosl.org 466DC40C75 Authentication-Results: smtp4.osuosl.org; dmarc=pass (p=none dis=none) header.from=smartx.com DKIM-Filter: OpenDKIM Filter v2.11.0 smtp4.osuosl.org 466DC40C75 Received: from mail-pf1-x42e.google.com (mail-pf1-x42e.google.com [IPv6:2607:f8b0:4864:20::42e]) by smtp4.osuosl.org (Postfix) with ESMTPS id 466DC40C75 for ; Wed, 25 Jun 2025 10:27:40 +0000 (UTC) Received: by mail-pf1-x42e.google.com with SMTP id d2e1a72fcca58-747abb3cd0bso649821b3a.1 for ; Wed, 25 Jun 2025 03:27:40 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=smartx-com.20230601.gappssmtp.com; s=20230601; t=1750847259; x=1751452059; darn=openvswitch.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=N7RPSYjpzk/Xtt4pQyj3iVjMOtMNJtbLIjlA+5lZPPc=; b=XHymQ9zGzgRxu/TwiCnNIr2igmj8oRBa3xv4CN1qyM5mvizLEvojU3WllBMvxESQPq I36LfF6ArYujOtcsJ9PigSFIRhHZRCwVf3I4aD8ljTtWd7Seah/awjIoOOC5B+H5Zrh1 wL60orOGymqTp5tBtoMQNgb6XC6e4uWWQtvRdP5BX2do19vHjbIKPYWbuSnEJ2zH/L4L CHvJq1+eoLjKkUfrp4rX839Mj8O0jwp86Qr2c77gAB2nxIoWXytmxMbKjgc1wQUuFpVk GbJeQYzKnqtsTI0hpnEONIaiyC8+4zky0mIurCPUSTbMeAWmKbBUAro/QYOn5x8wWuk9 V2Qg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1750847259; x=1751452059; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=N7RPSYjpzk/Xtt4pQyj3iVjMOtMNJtbLIjlA+5lZPPc=; b=NmSUiuyFyh1dGnKWMLaBOLOywWytoPT3w1Ppiuqd+TjBBbQp8Nf2pZ91s9KPB7Jg5T sYVrT9FmNMeYs8w6BblYXNRjcEa/CFUPOQHydGw7inNDW39+jCpcz1Qy+56YqLR8LaCl 3N5ESTjY9OUfio53KcHKtKwqrvxOi1jOXSfJPYymggMsUWX9BUIq7wqtZ+hTPh2h1Azb thDdk4rEBCxys32jI4Aukg1lWiwtOvHjYqbofbGhuy9eZFOSXMlcBcpb8TIaBp6BEF7i ydJpt/MdsV2AtcT9XCATjyQX7deiXZ7PquRZZW/sDOsYWe3hSei1Sl0iroDTcfYOvEwb 9waA== X-Forwarded-Encrypted: i=1; AJvYcCVot9gBriA6Mp+PBR5lZDklV65qXC+tl0rF/ZGoXUGxM/M3JNb3X40pmW2kzG7/pV0/m5Q=@openvswitch.org X-Gm-Message-State: AOJu0YxnsjIZ+AjrmtpHfyC/THTfkE7MXDxMhxLoCQxMSOJbmHu8G+zL RmSKatMp0piuG1qQx4yhtz1+s5bwshKpvBOX6eAa/ix2wq7t+DXJeFyjiOthqo0iLTM= X-Gm-Gg: ASbGncvQOdHh/oYCgabpJ9jkBLtolH3nJTwgyQjz9DlRdrl0g++PDj7c8yn/42dqoLW 24Li+Zew12CHzQAxIfIB8YtOLr/XUiROnT4d09vb6cAqyg7KUXEkFf6625K3riz02MO+ESq0+bF +Bejp22Dmcj/Q+A6LNI8wVRlgbJNQJebq2kiFjsublFwhkMJG6AD1MpgOBzVAUnSBVpCvnXqWsf 45ipGmHZmXtCt3J7IZ+/u47GUUb18FRg3dPBt8dHnVqn6J7Q7vO68buKitx0V62QyUjsOZD6ul+ yGvhQiryxJ+qW5MfKSe+dliAM++fJESaz49og2q6eEwnlprICQZrjB1XHnAbRvghoNRlh7HxJlR rk9diBXTlQqbxidQomUjY6wyPdlvEPUf0orfECQfE2OBodzMCe+kMY2PhBUw= X-Google-Smtp-Source: AGHT+IFMDqVYvvzmITM8MLpmaAmz0HjG0MALP07b/zYqCuODF7/yCs7/OH2ciexVIJtNz1J8DEZEDQ== X-Received: by 2002:a17:902:c409:b0:235:e1e4:edb0 with SMTP id d9443c01a7336-238024c0447mr113391975ad.22.1750847259250; Wed, 25 Jun 2025 03:27:39 -0700 (PDT) Received: from localhost.localdomain ([154.64.226.185]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-237d83f1e1fsm133350635ad.83.2025.06.25.03.27.36 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 25 Jun 2025 03:27:38 -0700 (PDT) From: Changliang Wu To: aconole@redhat.com, echaudro@redhat.com, i.maximets@ovn.org, dev@openvswitch.org Date: Wed, 25 Jun 2025 18:27:08 +0800 Message-ID: <20250625102710.822034-2-changliang.wu@smartx.com> X-Mailer: git-send-email 2.43.5 In-Reply-To: <20250625102710.822034-1-changliang.wu@smartx.com> References: <20250625102710.822034-1-changliang.wu@smartx.com> MIME-Version: 1.0 Subject: [ovs-dev] [PATCH 1/3] lldp: Add ovs-appctl lldp/neighbor command. X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" New appctl 'lldp/neighbor' displays lldp neighbor information. Support json output with --format json --pretty Signed-off-by: Changliang Wu --- NEWS | 1 + lib/ovs-lldp.c | 327 +++++++++++++++++++++++++++++++++++++ vswitchd/ovs-vswitchd.8.in | 4 + 3 files changed, 332 insertions(+) diff --git a/NEWS b/NEWS index d7231fabc..c66b41e64 100644 --- a/NEWS +++ b/NEWS @@ -15,6 +15,7 @@ Post-v3.5.0 core file size. - ovs-appctl: * Added JSON output support to the 'ovs/route/show' command. + * Added 'lldp/neighbor' command that displays lldp neighbor infomation. - SSL/TLS: * Support for deprecated TLSv1 and TLSv1.1 protocols on OpenFlow and database connections is now removed. diff --git a/lib/ovs-lldp.c b/lib/ovs-lldp.c index 152777248..da8faf873 100644 --- a/lib/ovs-lldp.c +++ b/lib/ovs-lldp.c @@ -35,8 +35,11 @@ #include #include #include "openvswitch/dynamic-string.h" +#include "openvswitch/json.h" #include "flow.h" #include "openvswitch/list.h" +#include "lldp/lldp-const.h" +#include "lldp/lldp-tlv.h" #include "lldp/lldpd.h" #include "lldp/lldpd-structs.h" #include "netdev.h" @@ -310,6 +313,281 @@ aa_print_isid_status(struct ds *ds, struct lldp *lldp) OVS_REQUIRES(mutex) } } +static void +lldp_print_neighbor(struct ds *ds, struct lldp *lldp) OVS_REQUIRES(mutex) +{ + struct lldpd_hardware *hw; + struct lldpd_port *port; + const char *none_str = ""; + + if (!lldp->lldpd) { + return; + } + + LIST_FOR_EACH (hw, h_entries, &lldp->lldpd->g_hardware) { + LIST_FOR_EACH (port, p_entries, &hw->h_rports) { + if (!port->p_chassis) { + continue; + } + ds_put_format(ds, "Interface: %s\n", lldp->name); + ds_put_format(ds, " Chassis:\n"); + + struct ds id = DS_EMPTY_INITIALIZER; + if (port->p_chassis->c_id_len > 0) { + ds_put_hex_with_delimiter(&id, port->p_chassis->c_id, + port->p_chassis->c_id_len, ":"); + } + ds_put_format(ds, " Chassis ID:\t %s\n", + id.length ? ds_cstr_ro(&id) : none_str); + ds_put_format(ds, " SysName:\t %s\n", + strlen(port->p_chassis->c_name) + ? port->p_chassis->c_name + : none_str); + ds_put_format(ds, " SysDescr:\t %s\n", + strlen(port->p_chassis->c_descr) + ? port->p_chassis->c_descr + : none_str); + ds_destroy(&id); + + struct lldpd_mgmt *mgmt; + LIST_FOR_EACH (mgmt, m_entries, &port->p_chassis->c_mgmt) { + struct in6_addr ip; + switch (mgmt->m_family) { + case LLDPD_AF_IPV4: + in6_addr_set_mapped_ipv4(&ip, mgmt->m_addr.inet.s_addr); + break; + case LLDPD_AF_IPV6: ip = mgmt->m_addr.inet6; break; + default: continue; + } + ds_put_format(ds, " MgmtIP:\t "); + ipv6_format_mapped(&ip, ds); + ds_put_format(ds, "\n"); + ds_put_format(ds, " MgmtIface:\t %d\n", mgmt->m_iface); + } + + if (port->p_chassis->c_cap_available & LLDP_CAP_BRIDGE) { + ds_put_format(ds, " Capability:\t Bridge, %s\n", + port->p_chassis->c_cap_enabled & LLDP_CAP_BRIDGE + ? "on" + : "off"); + } + if (port->p_chassis->c_cap_available & LLDP_CAP_ROUTER) { + ds_put_format(ds, " Capability:\t Router, %s\n", + port->p_chassis->c_cap_enabled & LLDP_CAP_ROUTER + ? "on" + : "off"); + } + if (port->p_chassis->c_cap_available & LLDP_CAP_WLAN) { + ds_put_format(ds, " Capability:\t Wlan, %s\n", + port->p_chassis->c_cap_enabled & LLDP_CAP_WLAN + ? "on" + : "off"); + } + if (port->p_chassis->c_cap_available & LLDP_CAP_STATION) { + ds_put_format(ds, " Capability:\t Station, %s\n", + port->p_chassis->c_cap_enabled & LLDP_CAP_STATION + ? "on" + : "off"); + } + + ds_put_format(ds, " Port:\n"); + + if (port->p_id_subtype == LLDP_PORTID_SUBTYPE_LLADDR) { + ds_init(&id); + if (port->p_id_len > 0) { + ds_put_hex_with_delimiter(&id, (uint8_t *) port->p_id, + port->p_id_len, ":"); + } + ds_put_format(ds, " PortID:\t %s\n", + id.length ? ds_cstr_ro(&id) : none_str); + ds_destroy(&id); + } else { + ds_put_format(ds, " PortID:\t %.*s\n", + (int) (port->p_id ? port->p_id_len + : strlen(none_str)), + port->p_id ?: none_str); + } + ds_put_format(ds, " PortDescr:\t %s\n", + strlen(port->p_descr) ? port->p_descr : none_str); + ds_put_format(ds, " TTL:\t %d\n", port->p_chassis->c_ttl); + + ds_put_format(ds, "-----------------------------------------------" + "--------------------------------\n"); + } + } +} + +static void +lldp_print_neighbor_json(struct json *interface_array_json, struct lldp *lldp) + OVS_REQUIRES(mutex) +{ + struct lldpd_hardware *hw; + struct lldpd_port *port; + const char *none_str = ""; + + if (!lldp->lldpd) { + return; + } + + LIST_FOR_EACH (hw, h_entries, &lldp->lldpd->g_hardware) { + LIST_FOR_EACH (port, p_entries, &hw->h_rports) { + if (!port->p_chassis) { + continue; + } + + struct json *interface_item_json = json_object_create(); + struct json *interface_item_warp_json = json_object_create(); + struct json *chassis_json = json_object_create(); + struct json *chassis_sys_json = json_object_create(); + struct json *chassis_id_json = json_object_create(); + struct json *chassis_mgmt_ip_json = json_array_create_empty(); + struct json *chassis_mgmt_iface_json = json_array_create_empty(); + struct json *chassis_capability_json = json_array_create_empty(); + struct json *chassis_capability_item_json; + struct json *port_json = json_object_create(); + struct json *port_id_json = json_object_create(); + + struct ds id = DS_EMPTY_INITIALIZER; + if (port->p_chassis->c_id_len > 0) { + ds_put_hex_with_delimiter(&id, port->p_chassis->c_id, + port->p_chassis->c_id_len, ":"); + } + + json_object_put(chassis_id_json, "type", + json_string_create("mac")); + json_object_put(chassis_id_json, "value", + json_string_create(id.length ? ds_cstr_ro(&id) + : none_str)); + json_object_put(chassis_sys_json, "id", chassis_id_json); + + json_object_put(chassis_json, + strlen(port->p_chassis->c_name) + ? port->p_chassis->c_name + : none_str, + chassis_sys_json); + + json_object_put(chassis_sys_json, "descr", + json_string_create(strlen(port->p_chassis->c_descr) + ? port->p_chassis->c_descr + : none_str)); + + ds_destroy(&id); + + struct lldpd_mgmt *mgmt; + struct in6_addr ip; + char addr_str[INET6_ADDRSTRLEN]; + LIST_FOR_EACH (mgmt, m_entries, &port->p_chassis->c_mgmt) { + switch (mgmt->m_family) { + case LLDPD_AF_IPV4: + in6_addr_set_mapped_ipv4(&ip, mgmt->m_addr.inet.s_addr); + break; + case LLDPD_AF_IPV6: ip = mgmt->m_addr.inet6; break; + default: continue; + } + + ipv6_string_mapped(addr_str, &ip); + json_array_add(chassis_mgmt_ip_json, + json_string_create(addr_str)); + json_array_add(chassis_mgmt_iface_json, + json_integer_create(mgmt->m_iface)); + } + json_object_put(chassis_sys_json, "mgmt-ip", chassis_mgmt_ip_json); + json_object_put(chassis_sys_json, "mgmt-iface", + chassis_mgmt_iface_json); + + if (port->p_chassis->c_cap_available & LLDP_CAP_BRIDGE) { + chassis_capability_item_json = json_object_create(); + json_object_put(chassis_capability_item_json, "type", + json_string_create("Bridge")); + json_object_put( + chassis_capability_item_json, "enabled", + json_boolean_create(port->p_chassis->c_cap_enabled & + LLDP_CAP_BRIDGE)); + json_array_add(chassis_capability_json, + chassis_capability_item_json); + } + if (port->p_chassis->c_cap_available & LLDP_CAP_ROUTER) { + chassis_capability_item_json = json_object_create(); + json_object_put(chassis_capability_item_json, "type", + json_string_create("Router")); + json_object_put( + chassis_capability_item_json, "enabled", + json_boolean_create(port->p_chassis->c_cap_enabled & + LLDP_CAP_ROUTER)); + json_array_add(chassis_capability_json, + chassis_capability_item_json); + } + if (port->p_chassis->c_cap_available & LLDP_CAP_WLAN) { + chassis_capability_item_json = json_object_create(); + json_object_put(chassis_capability_item_json, "type", + json_string_create("Wlan")); + json_object_put( + chassis_capability_item_json, "enabled", + json_boolean_create(port->p_chassis->c_cap_enabled & + LLDP_CAP_WLAN)); + json_array_add(chassis_capability_json, + chassis_capability_item_json); + } + if (port->p_chassis->c_cap_available & LLDP_CAP_STATION) { + chassis_capability_item_json = json_object_create(); + json_object_put(chassis_capability_item_json, "type", + json_string_create("Station")); + json_object_put( + chassis_capability_item_json, "enabled", + json_boolean_create(port->p_chassis->c_cap_enabled & + LLDP_CAP_STATION)); + json_array_add(chassis_capability_json, + chassis_capability_item_json); + } + json_object_put(chassis_sys_json, "capability", + chassis_capability_json); + + if (port->p_id_subtype == LLDP_PORTID_SUBTYPE_LLADDR) { + ds_init(&id); + if (port->p_id_len > 0) { + ds_put_hex_with_delimiter(&id, port->p_id, port->p_id_len, + ":"); + } + json_object_put(port_id_json, "type", + json_string_create("mac")); + json_object_put(port_id_json, "value", + json_string_create(id.length ? ds_cstr_ro(&id) + : none_str)); + + ds_destroy(&id); + } else { + json_object_put(port_id_json, "type", + json_string_create("ifname")); + if (port->p_id) { + struct ds port_ds = DS_EMPTY_INITIALIZER; + ds_put_buffer(&port_ds, port->p_id, port->p_id_len); + json_object_put(port_id_json, "value", + json_string_create(ds_cstr_ro(&port_ds))); + ds_destroy(&port_ds); + } else { + json_object_put(port_id_json, "value", + json_string_create(none_str)); + } + } + json_object_put(port_json, "id", port_id_json); + + json_object_put(port_json, "desc", + json_string_create(strlen(port->p_descr) + ? port->p_descr + : none_str)); + json_object_put(port_json, "ttl", + json_integer_create(port->p_chassis->c_ttl)); + + json_object_put(interface_item_json, "chassis", chassis_json); + json_object_put(interface_item_json, "port", port_json); + + json_object_put(interface_item_warp_json, lldp->name, + interface_item_json); + json_array_add(interface_array_json, interface_item_warp_json); + } + } +} + static void aa_unixctl_status(struct unixctl_conn *conn, int argc OVS_UNUSED, const char *argv[] OVS_UNUSED, void *aux OVS_UNUSED) @@ -368,6 +646,53 @@ 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, + const char *argv[], void *aux OVS_UNUSED) + OVS_EXCLUDED(mutex) +{ + struct lldp *lldp; + + if (unixctl_command_get_output_format(conn) == UNIXCTL_OUTPUT_FMT_JSON) { + struct json *lldp_json = json_object_create(); + struct json *interface_json = json_object_create(); + struct json *interface_array_json = json_array_create_empty(); + + ovs_mutex_lock(&mutex); + HMAP_FOR_EACH (lldp, hmap_node, all_lldps) { + if (argc > 1 && strcmp(argv[1], lldp->name)) { + continue; + } + lldp_print_neighbor_json(interface_array_json,lldp); + } + ovs_mutex_unlock(&mutex); + + json_object_put(interface_json, "interface", interface_array_json); + json_object_put(lldp_json, "lldp", interface_json); + + unixctl_command_reply_json(conn, lldp_json); + } else { + struct ds ds = DS_EMPTY_INITIALIZER; + + ds_put_format(&ds, "--------------------------------------------------" + "-----------------------------\nLLDP neighbor:\n" + "--------------------------------------------------" + "-----------------------------\n"); + + ovs_mutex_lock(&mutex); + HMAP_FOR_EACH (lldp, hmap_node, all_lldps) { + if (argc > 1 && strcmp(argv[1], lldp->name)) { + continue; + } + lldp_print_neighbor(&ds, lldp); + } + ovs_mutex_unlock(&mutex); + + unixctl_command_reply(conn, ds_cstr(&ds)); + ds_destroy(&ds); + } +} + /* An Auto Attach mapping was configured. Populate the corresponding * structures in the LLDP hardware. */ @@ -635,6 +960,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", "[interface]", 0, 1, + lldp_unixctl_show_neighbor, NULL); } /* Returns true if 'lldp' should process packets from 'flow'. Sets diff --git a/vswitchd/ovs-vswitchd.8.in b/vswitchd/ovs-vswitchd.8.in index 98e58951d..51b0a46b5 100644 --- a/vswitchd/ovs-vswitchd.8.in +++ b/vswitchd/ovs-vswitchd.8.in @@ -149,6 +149,10 @@ enabled. Force the fault status of the CFM module on \fIinterface\fR (or all interfaces if none is given) to be \fIstatus\fR. \fIstatus\fR can be "true", "false", or "normal" which reverts to the standard behavior. +.IP "\fBlldp/neighbor\fR [\fIinterface\fR]" +Displays detailed information about LLDP neighbors on \fIinterface\fR. +If \fIinterface\fR is not specified, then it displays detailed information +about all interfaces with LLDP enabled. .IP "\fBstp/tcn\fR [\fIbridge\fR]" Forces a topology change event on \fIbridge\fR if it's running STP. This may cause it to send Topology Change Notifications to its peers and flush From patchwork Wed Jun 25 10:27:09 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Changliang Wu X-Patchwork-Id: 2102470 X-Patchwork-Delegate: aconole@redhat.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=smartx-com.20230601.gappssmtp.com header.i=@smartx-com.20230601.gappssmtp.com header.a=rsa-sha256 header.s=20230601 header.b=pwaaRmmV; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=140.211.166.138; helo=smtp1.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=patchwork.ozlabs.org) Received: from smtp1.osuosl.org (smtp1.osuosl.org [140.211.166.138]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4bRygf4Dyhz1ymW for ; Wed, 25 Jun 2025 20:27:42 +1000 (AEST) Received: from localhost (localhost [127.0.0.1]) by smtp1.osuosl.org (Postfix) with ESMTP id 8ECA280D5C; Wed, 25 Jun 2025 10:27:52 +0000 (UTC) X-Virus-Scanned: amavis at osuosl.org Received: from smtp1.osuosl.org ([127.0.0.1]) by localhost (smtp1.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP id SL1B68aY-Bs7; Wed, 25 Jun 2025 10:27:51 +0000 (UTC) X-Comment: SPF check N/A for local connections - client-ip=140.211.9.56; helo=lists.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver= DKIM-Filter: OpenDKIM Filter v2.11.0 smtp1.osuosl.org 17CE280D19 Authentication-Results: smtp1.osuosl.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=smartx-com.20230601.gappssmtp.com header.i=@smartx-com.20230601.gappssmtp.com header.a=rsa-sha256 header.s=20230601 header.b=pwaaRmmV Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by smtp1.osuosl.org (Postfix) with ESMTPS id 17CE280D19; Wed, 25 Jun 2025 10:27:51 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id F38B6C02A6; Wed, 25 Jun 2025 10:27:50 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from smtp3.osuosl.org (smtp3.osuosl.org [IPv6:2605:bc80:3010::136]) by lists.linuxfoundation.org (Postfix) with ESMTP id 23D06C02A7 for ; Wed, 25 Jun 2025 10:27:49 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp3.osuosl.org (Postfix) with ESMTP id 4317A613FD for ; Wed, 25 Jun 2025 10:27:45 +0000 (UTC) X-Virus-Scanned: amavis at osuosl.org Received: from smtp3.osuosl.org ([127.0.0.1]) by localhost (smtp3.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP id tVxfiJ7ZqdlJ for ; Wed, 25 Jun 2025 10:27:44 +0000 (UTC) Received-SPF: Pass (mailfrom) identity=mailfrom; client-ip=2607:f8b0:4864:20::62a; helo=mail-pl1-x62a.google.com; envelope-from=changliang.wu@smartx.com; receiver= DMARC-Filter: OpenDMARC Filter v1.4.2 smtp3.osuosl.org 1FBD260E50 Authentication-Results: smtp3.osuosl.org; dmarc=pass (p=none dis=none) header.from=smartx.com DKIM-Filter: OpenDKIM Filter v2.11.0 smtp3.osuosl.org 1FBD260E50 Authentication-Results: smtp3.osuosl.org; dkim=pass (2048-bit key) header.d=smartx-com.20230601.gappssmtp.com header.i=@smartx-com.20230601.gappssmtp.com header.a=rsa-sha256 header.s=20230601 header.b=pwaaRmmV Received: from mail-pl1-x62a.google.com (mail-pl1-x62a.google.com [IPv6:2607:f8b0:4864:20::62a]) by smtp3.osuosl.org (Postfix) with ESMTPS id 1FBD260E50 for ; Wed, 25 Jun 2025 10:27:43 +0000 (UTC) Received: by mail-pl1-x62a.google.com with SMTP id d9443c01a7336-236377f00a1so18679985ad.3 for ; Wed, 25 Jun 2025 03:27:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=smartx-com.20230601.gappssmtp.com; s=20230601; t=1750847263; x=1751452063; darn=openvswitch.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=svmD4hg/gQI5ngeVxZW8mGeeBboGBS0XOUksD8xUMKs=; b=pwaaRmmVA2B26i2x/IG/d4HIHiC1/Cr5B7HUnMy+XaVcOlfxgZDYC9glfzgnKoc2h+ 4aEwInRfMfymdnU7v7RPHso/5ru7rgsuOIzEgAFeNL6CM00qGNbVybyRFEOnyi6/DjT6 V8dfMOvoipNLVxscjeGomM0oQ2lSbNXvNnOXJHc647Z1Mu9uBNqk7iDxH69m5fSt3oeS 0mqe19cHuds2/B8hizmIjmr928SgiEVuiLsSLJR4nk3bOstfQvc/NRRfiyQsCyqyHRHD 0pj15IGXG2WodMX4zzyGaToHVpn0Vp6kd+12TM5wTzdTEU/FezIR1irveZslBG+n6PKJ ZiNw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1750847263; x=1751452063; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=svmD4hg/gQI5ngeVxZW8mGeeBboGBS0XOUksD8xUMKs=; b=N7m2zbgKptwmVKasSOAEOQ5vtI6VsB1p+bohmvE/L8wQofGvNiWkqboKyk1oK5fK/g msFiSUiS8lqjPODShOzXwxCka2GEkv1efV4ozqQvsBvFxD5NJMb2Trev1iDTuxkt8yVL u0QBjD1ewYjTUwwnMHpQwLw9GqeqqRf144mp+sUPC+gLMEcdV8bOrWmNA2/ixiYYdLAA bNKnVpM60JTf0GmeRBGnZDQ810o2Acpf80JWAWlTnLAJTcK8S4xdwVjOChfUwS3yCPi6 dn0eEzOXaCPX/uPmvHj/ka2MgQ+ZOXsdCdaDXsTS/r9ZddhrgrZPWeIYVPAX/NXtiVIF EGSw== X-Forwarded-Encrypted: i=1; AJvYcCU0S5p9OZPLVB9lU5LRjvm7rj3R3ps4XdsfjgS3LGjzrYXLfkZ/f3LyMDezpZXvXMU6qhU=@openvswitch.org X-Gm-Message-State: AOJu0YxGG+OrEtXrmh1Qi0ss2S2GK7A2QuPZLjDUIB+9t26jtR+1ynTo EpQXVAs8LNSO9zp03rYobZHNEz799/gnJ23ZuZ1WWICEtCd7GyfUtJ/VIavGqrXOAXfvnta0C8Q SaU2v7Xoe3w== X-Gm-Gg: ASbGncta5vT+PxeQyDJBSxoFjU0MVHW60Jd2nfNgtVZ5RhVZX/MuDW8KKXAny1kJDwx JKMQBCNZkMOnA2WSTtCfR9p62oQn0SO1hVVhAwiKLxD2QL4vtHGWT0fyoP/T/9XKd+q3thDh6Xu JRyD6Tn9yDivRfZgLUprwjkYO+HZ21vIiL3mobIlDAk2Q61rIztzmLnkJJlGLInfJKrAkqurjPZ jtc8m/Gnze5ajSlzALIcvNWfndgzL0cR7fCHpNDj73BBUEHK/GuigAnYkUqBxpqZN89fhnEgRLz /ykVIlyqG0ly41RQWOOewDGbJepyQWZIZf3tFLjXCgHYb/TEOJm1yT26S7Or4ArKGWRgVfIFuME uNDRTJROCBaKAXapemXHKJ/ZFH7pc9aW4k9KubwQoul6ZpVOg X-Google-Smtp-Source: AGHT+IHGjkkMaJuLxe4YULQeqAHNKRy96HQRKvSm09A+4aKK6MemSxOskvD+DhijR84/TXRjj0zDsA== X-Received: by 2002:a17:902:d48b:b0:234:d2fb:2d28 with SMTP id d9443c01a7336-23823f873e9mr50629255ad.2.1750847263106; Wed, 25 Jun 2025 03:27:43 -0700 (PDT) Received: from localhost.localdomain ([154.64.226.185]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-237d83f1e1fsm133350635ad.83.2025.06.25.03.27.40 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 25 Jun 2025 03:27:42 -0700 (PDT) From: Changliang Wu To: aconole@redhat.com, echaudro@redhat.com, i.maximets@ovn.org, dev@openvswitch.org Date: Wed, 25 Jun 2025 18:27:09 +0800 Message-ID: <20250625102710.822034-3-changliang.wu@smartx.com> X-Mailer: git-send-email 2.43.5 In-Reply-To: <20250625102710.822034-1-changliang.wu@smartx.com> References: <20250625102710.822034-1-changliang.wu@smartx.com> MIME-Version: 1.0 Subject: [ovs-dev] [PATCH 2/3] lldp: Decode dot1 dot3 tlv and display in lldp/neighbor. X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" Signed-off-by: Changliang Wu --- NEWS | 1 + lib/lldp/lldp-const.h | 41 +++--- lib/lldp/lldp.c | 76 +++++++++- lib/lldp/lldpd-structs.h | 24 ++++ lib/ovs-lldp.c | 303 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 427 insertions(+), 18 deletions(-) diff --git a/NEWS b/NEWS index c66b41e64..72e0f495e 100644 --- a/NEWS +++ b/NEWS @@ -16,6 +16,7 @@ Post-v3.5.0 - ovs-appctl: * Added JSON output support to the 'ovs/route/show' command. * Added 'lldp/neighbor' command that displays lldp neighbor infomation. + Support for lldp dot1 and dot3 tlv. - SSL/TLS: * Support for deprecated TLSv1 and TLSv1.1 protocols on OpenFlow and database connections is now removed. diff --git a/lib/lldp/lldp-const.h b/lib/lldp/lldp-const.h index 8c5c0733e..7b9c74149 100644 --- a/lib/lldp/lldp-const.h +++ b/lib/lldp/lldp-const.h @@ -85,6 +85,11 @@ #define LLDP_DOT3_MAU_10GIGBASELW 39 #define LLDP_DOT3_MAU_10GIGBASESW 40 +#define LLDP_DOT3_POWER_PORT_CLASS (1 << 0) +#define LLDP_DOT3_POWER_SUPPORT (1 << 1) +#define LLDP_DOT3_POWER_ENABLED (1 << 2) +#define LLDP_DOT3_POWER_PAIRCONTROL (1 << 3) + /* Dot3 Power Devicetype */ #define LLDP_DOT3_POWER_PSE 1 #define LLDP_DOT3_POWER_PD 2 @@ -112,23 +117,27 @@ #define LLDP_DOT3_POWER_PRIO_HIGH 2 #define LLDP_DOT3_POWER_PRIO_LOW 3 +/* Auto-Negotiation Support/Status field, from RFC 4836 */ +#define LLDP_DOT3_LINK_AUTONEG_SUPPORT (1 << 0) +#define LLDP_DOT3_LINK_AUTONEG_ENABLED (1 << 1) + /* PMD Auto-Negotiation Advertised Capability field, from RFC 3636 */ -#define LLDP_DOT3_LINK_AUTONEG_OTHER 0x8000 -#define LLDP_DOT3_LINK_AUTONEG_10BASE_T 0x4000 -#define LLDP_DOT3_LINK_AUTONEG_10BASET_FD 0x2000 -#define LLDP_DOT3_LINK_AUTONEG_100BASE_T4 0x1000 -#define LLDP_DOT3_LINK_AUTONEG_100BASE_TX 0x0800 -#define LLDP_DOT3_LINK_AUTONEG_100BASE_TXFD 0x0400 -#define LLDP_DOT3_LINK_AUTONEG_100BASE_T2 0x0200 -#define LLDP_DOT3_LINK_AUTONEG_100BASE_T2FD 0x0100 -#define LLDP_DOT3_LINK_AUTONEG_FDX_PAUSE 0x0080 -#define LLDP_DOT3_LINK_AUTONEG_FDX_APAUSE 0x0040 -#define LLDP_DOT3_LINK_AUTONEG_FDX_SPAUSE 0x0020 -#define LLDP_DOT3_LINK_AUTONEG_FDX_BPAUSE 0x0010 -#define LLDP_DOT3_LINK_AUTONEG_1000BASE_X 0x0008 -#define LLDP_DOT3_LINK_AUTONEG_1000BASE_XFD 0x0004 -#define LLDP_DOT3_LINK_AUTONEG_1000BASE_T 0x0002 -#define LLDP_DOT3_LINK_AUTONEG_1000BASE_TFD 0x0001 +#define LLDP_DOT3_LINK_AUTONEG_OTHER 0x8000 +#define LLDP_DOT3_LINK_AUTONEG_10BASE_T 0x4000 +#define LLDP_DOT3_LINK_AUTONEG_10BASE_T_FD 0x2000 +#define LLDP_DOT3_LINK_AUTONEG_100BASE_T4 0x1000 +#define LLDP_DOT3_LINK_AUTONEG_100BASE_TX 0x0800 +#define LLDP_DOT3_LINK_AUTONEG_100BASE_TX_FD 0x0400 +#define LLDP_DOT3_LINK_AUTONEG_100BASE_T2 0x0200 +#define LLDP_DOT3_LINK_AUTONEG_100BASE_T2_FD 0x0100 +#define LLDP_DOT3_LINK_AUTONEG_FDX_PAUSE 0x0080 +#define LLDP_DOT3_LINK_AUTONEG_FDX_APAUSE 0x0040 +#define LLDP_DOT3_LINK_AUTONEG_FDX_SPAUSE 0x0020 +#define LLDP_DOT3_LINK_AUTONEG_FDX_BPAUSE 0x0010 +#define LLDP_DOT3_LINK_AUTONEG_1000BASE_X 0x0008 +#define LLDP_DOT3_LINK_AUTONEG_1000BASE_X_FD 0x0004 +#define LLDP_DOT3_LINK_AUTONEG_1000BASE_T 0x0002 +#define LLDP_DOT3_LINK_AUTONEG_1000BASE_T_FD 0x0001 /* Capabilities */ #define LLDP_CAP_OTHER 0x01 diff --git a/lib/lldp/lldp.c b/lib/lldp/lldp.c index 6fdcfef56..136247100 100644 --- a/lib/lldp/lldp.c +++ b/lib/lldp/lldp.c @@ -18,6 +18,7 @@ */ #include +#include "lldp-tlv.h" #include "lldpd.h" #include #include @@ -567,10 +568,81 @@ lldp_decode(struct lldpd *cfg OVS_UNUSED, char *frame, int s, CHECK_TLV_SIZE(1 + sizeof orgid, "Organisational"); PEEK_BYTES(orgid, sizeof orgid); tlv_subtype = PEEK_UINT8; + uint8_t tlv_org_size; if (memcmp(dot1, orgid, sizeof orgid) == 0) { - hardware->h_rx_unrecognized_cnt++; + switch (tlv_subtype) { + case LLDP_TLV_DOT1_PVID: + CHECK_TLV_SIZE(2, "Dot1 Port VLAN ID"); + port->p_dot1.pvid = PEEK_UINT16; + port->p_dot1_enable |= (1 << LLDP_TLV_DOT1_PVID); + break; + case LLDP_TLV_DOT1_PPVID: + CHECK_TLV_SIZE(2, "Dot1 Port And Protocol VLAN ID"); + port->p_dot1.ppvid = PEEK_UINT16; + port->p_dot1_enable |= (1 << LLDP_TLV_DOT1_PPVID); + break; + case LLDP_TLV_DOT1_VLANNAME: + case LLDP_TLV_DOT1_PI: + if (tlv_subtype == LLDP_TLV_DOT1_VLANNAME) { + CHECK_TLV_SIZE(2, "DOT1 VLAN ID"); + port->p_dot1.vlan_id = PEEK_UINT16; + port->p_dot1_enable |= (1 << LLDP_TLV_DOT1_VLANNAME); + } + CHECK_TLV_SIZE(1, "DOT1 VLAN Name/PI Length"); + tlv_org_size = PEEK_UINT8; + if (tlv_org_size < 1) { + VLOG_DBG("empty dot1 vlan name/pi tlv received on %s", + hardware->h_ifname); + goto malformed; + } + CHECK_TLV_SIZE(tlv_org_size, "DOT1 VLAN Name/PI"); + b = xzalloc(tlv_org_size + 1); + PEEK_BYTES(b, tlv_org_size); + if (tlv_subtype == LLDP_TLV_DOT1_VLANNAME) { + free(port->p_dot1.vlan_name); + port->p_dot1.vlan_name = b; + } else if (tlv_subtype == LLDP_TLV_DOT1_PI) { + free(port->p_dot1.pi); + port->p_dot1.pi = b; + port->p_dot1_enable |= (1 << LLDP_TLV_DOT1_PI); + } + break; + default: + VLOG_INFO("unknown org tlv [%02x:%02x:%02x] received " + "on %s", + orgid[0], orgid[1], orgid[2], + hardware->h_ifname); + hardware->h_rx_unrecognized_cnt++; + } } else if (memcmp(dot3, orgid, sizeof orgid) == 0) { - hardware->h_rx_unrecognized_cnt++; + switch (tlv_subtype) { + case LLDP_TLV_DOT3_MAC: + CHECK_TLV_SIZE(5, "DOT3 MAC"); + port->p_dot3.auto_nego = PEEK_UINT8; + port->p_dot3.pmd_auto_nego = PEEK_UINT16; + port->p_dot3.mau = PEEK_UINT16; + port->p_dot3_enable |= (1 << LLDP_TLV_DOT3_MAC); + break; + case LLDP_TLV_DOT3_POWER: + CHECK_TLV_SIZE(3, "DOT3 MDI"); + port->p_dot3.mdi = PEEK_UINT8; + port->p_dot3.pse = PEEK_UINT8; + port->p_dot3.power_class = PEEK_UINT8; + port->p_dot3_enable |= (1 << LLDP_TLV_DOT3_POWER); + break; + case LLDP_TLV_DOT3_LA: break; + case LLDP_TLV_DOT3_MFS: + CHECK_TLV_SIZE(3, "DOT3 MFS"); + port->p_dot3.mfs = PEEK_UINT16; + port->p_dot3_enable |= (1 << LLDP_TLV_DOT3_MFS); + break; + default: + VLOG_INFO("unknown org tlv [%02x:%02x:%02x] received " + "on %s", + orgid[0], orgid[1], orgid[2], + hardware->h_ifname); + hardware->h_rx_unrecognized_cnt++; + } } else if (memcmp(med, orgid, sizeof orgid) == 0) { /* LLDP-MED */ hardware->h_rx_unrecognized_cnt++; diff --git a/lib/lldp/lldpd-structs.h b/lib/lldp/lldpd-structs.h index fe5d5f9f8..bb8939db1 100644 --- a/lib/lldp/lldpd-structs.h +++ b/lib/lldp/lldpd-structs.h @@ -79,6 +79,24 @@ struct lldpd_chassis { /* WARNING: any change to this structure should also be reflected into `lldpd_copy_chassis()` which is not using marshaling. */ +struct lldpd_tlv_dot1 { + u_int16_t pvid; /* Port VLAN identifier */ + u_int16_t ppvid; /* Port and protocol VLAN identifier */ + char *vlan_name; /* VLAN Name in LLDP_TLV_DOT1_VLANNAME */ + u_int16_t vlan_id; /* VLAN ID in LLDP_TLV_DOT1_VLANNAME */ + char *pi; /* protocol identity */ +}; + +struct lldpd_tlv_dot3 { + u_int8_t auto_nego; /* auto-negotiation support/status */ + u_int16_t pmd_auto_nego; /* PMD auto-negotiation advertised capability */ + u_int16_t mau; /* Operational MAU type */ + u_int8_t mdi; /* MDI power support */ + u_int8_t pse; /* PSE power pair */ + u_int8_t power_class; /* Port class */ + u_int16_t mfs; /* Maximum 802.3 frame size */ +}; + struct lldpd_port { struct ovs_list p_entries; struct lldpd_chassis *p_chassis; /* Attached chassis */ @@ -98,6 +116,12 @@ struct lldpd_port { char *p_descr; u_int16_t p_mfs; struct lldpd_aa_element_tlv p_element; + /* Bitmask for dot1 tlv received */ + u_int16_t p_dot1_enable; + struct lldpd_tlv_dot1 p_dot1; + /* Bitmask for dot3 tlv received */ + u_int16_t p_dot3_enable; + struct lldpd_tlv_dot3 p_dot3; struct ovs_list p_isid_vlan_maps; /* Contains "struct lldpd_aa_isid_vlan_maps_tlv"s. */ }; diff --git a/lib/ovs-lldp.c b/lib/ovs-lldp.c index da8faf873..b1febb355 100644 --- a/lib/ovs-lldp.c +++ b/lib/ovs-lldp.c @@ -313,6 +313,303 @@ aa_print_isid_status(struct ds *ds, struct lldp *lldp) OVS_REQUIRES(mutex) } } +static void +lldp_print_neighbor_port_dot1(struct ds *ds, struct lldpd_port *port) +{ + if (port->p_dot1_enable & + ((1 << LLDP_TLV_DOT1_PVID) | (1 << LLDP_TLV_DOT1_VLANNAME))) { + ds_put_format(ds, " VLAN: \t"); + } + if (port->p_dot1_enable & (1 << LLDP_TLV_DOT1_PVID)) { + ds_put_format(ds, " %d, ", port->p_dot1.pvid); + if (!(port->p_dot1_enable & (1 << LLDP_TLV_DOT1_VLANNAME)) && + port->p_dot1.pvid > 0) { + ds_put_format(ds, "pvid: yes"); + } + } + if (port->p_dot1_enable & (1 << LLDP_TLV_DOT1_VLANNAME)) { + ds_put_format(ds, "pvid: %s", + port->p_dot1.pvid == port->p_dot1.vlan_id ? "yes" + : "no"); + if (port->p_dot1.vlan_name) { + ds_put_format(ds, ", %s", port->p_dot1.vlan_name); + } + } + ds_put_format(ds, "\n"); +} + +static void +lldp_print_neighbor_port_dot1_json(struct json *interface_item_json, + struct lldpd_port *port) +{ + struct json *vlan_json = NULL; + if (port->p_dot1_enable & (1 << LLDP_TLV_DOT1_PVID)) { + if (!vlan_json) { + vlan_json = json_object_create(); + } + json_object_put(vlan_json, "vlan-id", + json_integer_create(port->p_dot1.pvid)); + + if (!(port->p_dot1_enable & (1 << LLDP_TLV_DOT1_VLANNAME)) && + port->p_dot1.pvid > 0) { + json_object_put(vlan_json, "pvid", json_boolean_create(true)); + } + } + if (port->p_dot1_enable & (1 << LLDP_TLV_DOT1_VLANNAME)) { + if (!vlan_json) { + vlan_json = json_object_create(); + } + json_object_put( + vlan_json, "pvid", + json_boolean_create( + port->p_dot1.pvid == port->p_dot1.vlan_id ? true : false)); + if (port->p_dot1.vlan_name) { + json_object_put(vlan_json, "value", + json_string_create(port->p_dot1.vlan_name)); + } + } + if (vlan_json) { + json_object_put(interface_item_json, "vlan", vlan_json); + } + + if (port->p_dot1_enable & (1 << LLDP_TLV_DOT1_PPVID)) { + struct json *ppid_json = json_object_create(); + json_object_put(ppid_json, "supported", + port->p_dot1.ppvid & LLDP_PPVID_CAP_SUPPORTED + ? json_boolean_create(true) + : json_boolean_create(false)); + json_object_put(ppid_json, "enabled", + port->p_dot1.ppvid & LLDP_PPVID_CAP_ENABLED + ? json_boolean_create(true) + : json_boolean_create(false)); + json_object_put(interface_item_json, "ppid", ppid_json); + } +} + +static void +lldp_dot3_autoneg_advertised(struct ds *ds, uint16_t pmd_auto_nego, int bithd, + int bitfd, const char *type) +{ + if (!((pmd_auto_nego & bithd) || (pmd_auto_nego & bitfd))) { + return; + } + + ds_put_format(ds, " Adv:\t %s", type); + if (bithd != bitfd) { + ds_put_format(ds, ", HD: %s, FD: %s\n", + (pmd_auto_nego & bithd) ? "yes" : "no", + (pmd_auto_nego & bitfd) ? "yes" : "no"); + } +} + +static void +lldp_dot3_autoneg_advertised_json(struct json **advertised_json, + uint16_t pmd_auto_nego, int bithd, int bitfd, + const char *type) +{ + if (!((pmd_auto_nego & bithd) || (pmd_auto_nego & bitfd))) { + return; + } + + if (!*advertised_json) { + *advertised_json = json_array_create_empty(); + } + + struct json *advertised_item_json = json_object_create(); + json_object_put(advertised_item_json, "type", json_string_create(type)); + if (bithd != bitfd) { + json_object_put(advertised_item_json, "hd", + json_boolean_create((pmd_auto_nego & bithd) ? true + : false)); + json_object_put(advertised_item_json, "fd", + json_boolean_create((pmd_auto_nego & bitfd) ? true + : false)); + } + json_array_add(*advertised_json, advertised_item_json); +} + +static void +lldp_print_neighbor_port_dot3(struct ds *ds, struct lldpd_port *port) +{ + if (port->p_dot3_enable & (1 << LLDP_TLV_DOT3_MFS)) { + ds_put_format(ds, " MFS:\t %d\n", port->p_dot3.mfs); + } + + if (port->p_dot3_enable & (1 << LLDP_TLV_DOT3_MAC)) { + ds_put_format( + ds, " PMD autoneg: supported: %s, enabled: %s\n", + port->p_dot3.auto_nego & LLDP_DOT3_LINK_AUTONEG_SUPPORT ? "yes" + : "no", + port->p_dot3.auto_nego & LLDP_DOT3_LINK_AUTONEG_ENABLED ? "yes" + : "no"); + + lldp_dot3_autoneg_advertised(ds, port->p_dot3.pmd_auto_nego, + LLDP_DOT3_LINK_AUTONEG_10BASE_T, + LLDP_DOT3_LINK_AUTONEG_10BASE_T_FD, + "10Base-T"); + lldp_dot3_autoneg_advertised(ds, port->p_dot3.pmd_auto_nego, + LLDP_DOT3_LINK_AUTONEG_100BASE_T4, + LLDP_DOT3_LINK_AUTONEG_100BASE_T4, + "100Base-T4"); + lldp_dot3_autoneg_advertised(ds, port->p_dot3.pmd_auto_nego, + LLDP_DOT3_LINK_AUTONEG_100BASE_TX, + LLDP_DOT3_LINK_AUTONEG_100BASE_TX_FD, + "100Base-TX"); + lldp_dot3_autoneg_advertised(ds, port->p_dot3.pmd_auto_nego, + LLDP_DOT3_LINK_AUTONEG_100BASE_T2, + LLDP_DOT3_LINK_AUTONEG_100BASE_T2_FD, + "100Base-T2"); + lldp_dot3_autoneg_advertised(ds, port->p_dot3.pmd_auto_nego, + LLDP_DOT3_LINK_AUTONEG_1000BASE_X, + LLDP_DOT3_LINK_AUTONEG_1000BASE_X_FD, + "1000Base-X"); + lldp_dot3_autoneg_advertised(ds, port->p_dot3.pmd_auto_nego, + LLDP_DOT3_LINK_AUTONEG_1000BASE_T, + LLDP_DOT3_LINK_AUTONEG_1000BASE_T_FD, + "1000Base-T"); + lldp_dot3_autoneg_advertised(ds, port->p_dot3.pmd_auto_nego, + LLDP_DOT3_LINK_AUTONEG_FDX_PAUSE, + LLDP_DOT3_LINK_AUTONEG_FDX_PAUSE, + "FDX_PAUSE"); + lldp_dot3_autoneg_advertised(ds, port->p_dot3.pmd_auto_nego, + LLDP_DOT3_LINK_AUTONEG_FDX_APAUSE, + LLDP_DOT3_LINK_AUTONEG_FDX_APAUSE, + "FDX_APAUSE"); + lldp_dot3_autoneg_advertised(ds, port->p_dot3.pmd_auto_nego, + LLDP_DOT3_LINK_AUTONEG_FDX_SPAUSE, + LLDP_DOT3_LINK_AUTONEG_FDX_SPAUSE, + "FDX_SPAUSE"); + lldp_dot3_autoneg_advertised(ds, port->p_dot3.pmd_auto_nego, + LLDP_DOT3_LINK_AUTONEG_FDX_BPAUSE, + LLDP_DOT3_LINK_AUTONEG_FDX_BPAUSE, + "FDX_BPAUSE"); + + ds_put_format(ds, " MAU oper type:\t %d\n", port->p_dot3.mau); + } + + if (port->p_dot3_enable & (1 << LLDP_TLV_DOT3_POWER)) { + ds_put_format( + ds, + " MDI Power:\t supported: %s, enabled: %s, pair control: %s\n", + port->p_dot3.mdi & LLDP_DOT3_POWER_SUPPORT ? "yes" : "no", + port->p_dot3.mdi & LLDP_DOT3_POWER_ENABLED ? "yes" : "no", + port->p_dot3.mdi & LLDP_DOT3_POWER_PAIRCONTROL ? "yes" : "no"); + + ds_put_format(ds, " Device type:\t %s\n", + port->p_dot3.mdi & LLDP_DOT3_POWER_PORT_CLASS ? "PSE" + : "PD"); + } +} + +static void +lldp_print_neighbor_port_dot3_json(struct json *port_json, + struct lldpd_port *port) +{ + if (port->p_dot3_enable & (1 << LLDP_TLV_DOT3_MAC)) { + struct json *auto_nego_json = json_object_create(); + json_object_put(auto_nego_json, "supported", + port->p_dot3.auto_nego & LLDP_DOT3_LINK_AUTONEG_SUPPORT + ? json_boolean_create(true) + : json_boolean_create(false)); + json_object_put(auto_nego_json, "enabled", + port->p_dot3.auto_nego & LLDP_DOT3_LINK_AUTONEG_ENABLED + ? json_boolean_create(true) + : json_boolean_create(false)); + + struct json *advertised_json = NULL; + lldp_dot3_autoneg_advertised_json(&advertised_json, + port->p_dot3.pmd_auto_nego, + LLDP_DOT3_LINK_AUTONEG_10BASE_T, + LLDP_DOT3_LINK_AUTONEG_10BASE_T_FD, + "10Base-T"); + lldp_dot3_autoneg_advertised_json(&advertised_json, + port->p_dot3.pmd_auto_nego, + LLDP_DOT3_LINK_AUTONEG_100BASE_T4, + LLDP_DOT3_LINK_AUTONEG_100BASE_T4, + "100Base-T4"); + lldp_dot3_autoneg_advertised_json(&advertised_json, + port->p_dot3.pmd_auto_nego, + LLDP_DOT3_LINK_AUTONEG_100BASE_TX, + LLDP_DOT3_LINK_AUTONEG_100BASE_TX_FD, + "100Base-TX"); + lldp_dot3_autoneg_advertised_json(&advertised_json, + port->p_dot3.pmd_auto_nego, + LLDP_DOT3_LINK_AUTONEG_100BASE_T2, + LLDP_DOT3_LINK_AUTONEG_100BASE_T2_FD, + "100Base-T2"); + lldp_dot3_autoneg_advertised_json(&advertised_json, + port->p_dot3.pmd_auto_nego, + LLDP_DOT3_LINK_AUTONEG_1000BASE_X, + LLDP_DOT3_LINK_AUTONEG_1000BASE_X_FD, + "1000Base-X"); + lldp_dot3_autoneg_advertised_json(&advertised_json, + port->p_dot3.pmd_auto_nego, + LLDP_DOT3_LINK_AUTONEG_1000BASE_T, + LLDP_DOT3_LINK_AUTONEG_1000BASE_T_FD, + "1000Base-T"); + lldp_dot3_autoneg_advertised_json(&advertised_json, + port->p_dot3.pmd_auto_nego, + LLDP_DOT3_LINK_AUTONEG_FDX_PAUSE, + LLDP_DOT3_LINK_AUTONEG_FDX_PAUSE, + "FDX_PAUSE"); + lldp_dot3_autoneg_advertised_json(&advertised_json, + port->p_dot3.pmd_auto_nego, + LLDP_DOT3_LINK_AUTONEG_FDX_APAUSE, + LLDP_DOT3_LINK_AUTONEG_FDX_APAUSE, + "FDX_APAUSE"); + lldp_dot3_autoneg_advertised_json(&advertised_json, + port->p_dot3.pmd_auto_nego, + LLDP_DOT3_LINK_AUTONEG_FDX_SPAUSE, + LLDP_DOT3_LINK_AUTONEG_FDX_SPAUSE, + "FDX_SPAUSE"); + lldp_dot3_autoneg_advertised_json(&advertised_json, + port->p_dot3.pmd_auto_nego, + LLDP_DOT3_LINK_AUTONEG_FDX_BPAUSE, + LLDP_DOT3_LINK_AUTONEG_FDX_BPAUSE, + "FDX_BPAUSE"); + if (advertised_json) { + json_object_put(auto_nego_json, "advertised", advertised_json); + } + + json_object_put(auto_nego_json, "current", + json_integer_create(port->p_dot3.mau)); + + json_object_put(port_json, "auto-negotiation", auto_nego_json); + } + + if (port->p_dot3_enable & (1 << LLDP_TLV_DOT3_POWER)) { + struct json *power_json = json_object_create(); + + json_object_put( + power_json, "device-type", + json_string_create( + port->p_dot3.mdi & LLDP_DOT3_POWER_PORT_CLASS ? "PSE" : "PD")); + + json_object_put( + power_json, "supported", + json_boolean_create( + port->p_dot3.mdi & LLDP_DOT3_POWER_SUPPORT ? true : false)); + + json_object_put( + power_json, "enabled", + json_boolean_create( + port->p_dot3.mdi & LLDP_DOT3_POWER_ENABLED ? true : false)); + + json_object_put(power_json, "paircontrol", + json_boolean_create(port->p_dot3.mdi & + LLDP_DOT3_POWER_PAIRCONTROL + ? true + : false)); + + json_object_put(port_json, "power", power_json); + } + + if (port->p_dot3_enable & (1 << LLDP_TLV_DOT3_MFS)) { + json_object_put(port_json, "mfs", + json_integer_create(port->p_dot3.mfs)); + } +} + static void lldp_print_neighbor(struct ds *ds, struct lldp *lldp) OVS_REQUIRES(mutex) { @@ -411,6 +708,9 @@ lldp_print_neighbor(struct ds *ds, struct lldp *lldp) OVS_REQUIRES(mutex) strlen(port->p_descr) ? port->p_descr : none_str); ds_put_format(ds, " TTL:\t %d\n", port->p_chassis->c_ttl); + lldp_print_neighbor_port_dot3(ds, port); + lldp_print_neighbor_port_dot1(ds, port); + ds_put_format(ds, "-----------------------------------------------" "--------------------------------\n"); } @@ -578,6 +878,9 @@ lldp_print_neighbor_json(struct json *interface_array_json, struct lldp *lldp) json_object_put(port_json, "ttl", json_integer_create(port->p_chassis->c_ttl)); + lldp_print_neighbor_port_dot1_json(interface_item_json, port); + lldp_print_neighbor_port_dot3_json(port_json, port); + json_object_put(interface_item_json, "chassis", chassis_json); json_object_put(interface_item_json, "port", port_json); From patchwork Wed Jun 25 10:27:10 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Changliang Wu X-Patchwork-Id: 2102471 X-Patchwork-Delegate: aconole@redhat.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=smartx-com.20230601.gappssmtp.com header.i=@smartx-com.20230601.gappssmtp.com header.a=rsa-sha256 header.s=20230601 header.b=Pk7pGu2G; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=openvswitch.org (client-ip=2605:bc80:3010::136; helo=smtp3.osuosl.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=patchwork.ozlabs.org) Received: from smtp3.osuosl.org (smtp3.osuosl.org [IPv6:2605:bc80:3010::136]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4bRygt2Yk9z1ymW for ; Wed, 25 Jun 2025 20:27:54 +1000 (AEST) Received: from localhost (localhost [127.0.0.1]) by smtp3.osuosl.org (Postfix) with ESMTP id 2E17A606DF; Wed, 25 Jun 2025 10:28:05 +0000 (UTC) X-Virus-Scanned: amavis at osuosl.org Received: from smtp3.osuosl.org ([127.0.0.1]) by localhost (smtp3.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP id Yfha9mcfyC5e; Wed, 25 Jun 2025 10:28:03 +0000 (UTC) X-Comment: SPF check N/A for local connections - client-ip=2605:bc80:3010:104::8cd3:938; helo=lists.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver= DKIM-Filter: OpenDKIM Filter v2.11.0 smtp3.osuosl.org 5310D612C1 Authentication-Results: smtp3.osuosl.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=smartx-com.20230601.gappssmtp.com header.i=@smartx-com.20230601.gappssmtp.com header.a=rsa-sha256 header.s=20230601 header.b=Pk7pGu2G Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [IPv6:2605:bc80:3010:104::8cd3:938]) by smtp3.osuosl.org (Postfix) with ESMTPS id 5310D612C1; Wed, 25 Jun 2025 10:28:03 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 3A153C02A7; Wed, 25 Jun 2025 10:28:03 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@lists.linuxfoundation.org Received: from smtp2.osuosl.org (smtp2.osuosl.org [IPv6:2605:bc80:3010::133]) by lists.linuxfoundation.org (Postfix) with ESMTP id 0B1F2C02A6 for ; Wed, 25 Jun 2025 10:28:02 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp2.osuosl.org (Postfix) with ESMTP id 80FAD41E2B for ; Wed, 25 Jun 2025 10:27:49 +0000 (UTC) X-Virus-Scanned: amavis at osuosl.org Received: from smtp2.osuosl.org ([127.0.0.1]) by localhost (smtp2.osuosl.org [127.0.0.1]) (amavis, port 10024) with ESMTP id y4tZsV7PWo95 for ; Wed, 25 Jun 2025 10:27:47 +0000 (UTC) Received-SPF: Pass (mailfrom) identity=mailfrom; client-ip=2607:f8b0:4864:20::634; helo=mail-pl1-x634.google.com; envelope-from=changliang.wu@smartx.com; receiver= DMARC-Filter: OpenDMARC Filter v1.4.2 smtp2.osuosl.org B107B4194D Authentication-Results: smtp2.osuosl.org; dmarc=pass (p=none dis=none) header.from=smartx.com DKIM-Filter: OpenDKIM Filter v2.11.0 smtp2.osuosl.org B107B4194D Authentication-Results: smtp2.osuosl.org; dkim=pass (2048-bit key) header.d=smartx-com.20230601.gappssmtp.com header.i=@smartx-com.20230601.gappssmtp.com header.a=rsa-sha256 header.s=20230601 header.b=Pk7pGu2G Received: from mail-pl1-x634.google.com (mail-pl1-x634.google.com [IPv6:2607:f8b0:4864:20::634]) by smtp2.osuosl.org (Postfix) with ESMTPS id B107B4194D for ; Wed, 25 Jun 2025 10:27:47 +0000 (UTC) Received: by mail-pl1-x634.google.com with SMTP id d9443c01a7336-236377f00easo74790875ad.1 for ; Wed, 25 Jun 2025 03:27:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=smartx-com.20230601.gappssmtp.com; s=20230601; t=1750847267; x=1751452067; darn=openvswitch.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=GNXOak2RydeIYbRIF76gU5quIl3L0uamMsTwAirs2qI=; b=Pk7pGu2GS0dNkblhKTpb5gXP+RkzJIiqy8JVa9fg+NFxSQZEptCToDlS9rrHi8eGF/ PHzRvfs9tOJmBw2vxRS7Ho+ozbWyKhUILVWXvVAGAFVfV3wsatzutWpxA/fsPbzodifT a6OQzB37JOaXx4a6ECotzbtTJ+vfnyq8liwcVUlCFySZ+EV4hQDZ7P8VGNKc/R+6BA3Q 7zAR0FctGdqz9FDW/TKrX1CA2Q4Pn/AyeiRg24DtBtQmoRFcrGpt0RrXCtprhumZCW/D 6lsi8eN9Tipt+ag1tkSZIp/OgR6pisCfaXcHaSFInierD3M6QF0phgZ4DfqFVIjxRcS/ P2hw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1750847267; x=1751452067; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=GNXOak2RydeIYbRIF76gU5quIl3L0uamMsTwAirs2qI=; b=iEgAhxOTGWmgUUpQWKTCrAvEoKxM+Equssp7+vtyAs5gwvKj4L84ya6+eoPNpLijZ9 NDzcXvB3abYZiEL1Pghhx5kGfAurIr35gz/EpR8gY1cQ0nRiBEcPJ/Vhl/UAsfx/Ewzc isqFEswygcIuYSe3RZJV/B5FvxQ+Vfx5Ie5XVz+07j9IG6wCGlWgseVXkWmfiy/eYpIz T9Xu/N3nbwrPghjQNMPtzGtXFhec6szISanwvsTyAzjWpxpsQc8OicptWqKArDHExl2n CWRwU0mOrEkc4l7+CZh6bsgYWTNWFN3bXst6/DqLyP3+K+2BYHmEG1LCL3d5wcWkscYa 4MkA== X-Forwarded-Encrypted: i=1; AJvYcCV5pHhJYlNiN4W/C/n/IsZidp1PsbV0cwQ4CEX2SS6TTjW3twt7Eh+GzwPcoV6OTjch/i0=@openvswitch.org X-Gm-Message-State: AOJu0YwB1e+B+XTE2CrwEW14u1c/tFUCk5u+uOPACKmOxRIqzr0Bpdf6 cCDSMlDf0UtpxccocqQgQ+vfYIvDiRVtXrPWFIdsw2xedAeoAAhO4DHBHps0/xvD6E4= X-Gm-Gg: ASbGncu1L9OnR0sOrmnGiQzVbasu6paxhd/qiw/7wc8RjwDN3+7pTyl2zb+H3pOiZ2k vLzPbXdbFC5y4cNBncmKsT60IluixVBe/D9hFCUi6s3ngTn0COVaWT17OKSLIXICvFkJQ7QF+Nq DQr3LKpO/wtH3b4xUtyg37qB4eyKFRHG4d/xEXOBQepxoRNbF/Ok69mKdT8p+PudWLiRhX0Kzfo WX6MHH9XQq+HV4rDQ4bqkhQQGjqd0Zr2HqVr9Lfc49d64ZkSREOfDFljVwsIWK3Xya8n3LJGr5C pt/94e1XCRyvRsc19KqzmAMsfTNaM/DhaHjdOdjtVtMNcsoNIAwLCoqGl0cHaaZx17/Q6JvLxNC IxoOzOYJyQeOSMqgcEADtIsvCV+oahtDwQpIBKwOAi1i6mykl X-Google-Smtp-Source: AGHT+IEb/Zc/99HmxKrSR9lOJnhm/15xSqJyKPjcFoO84eTT/i8X9wXXqziVUdUUOmbEE7ClrCXIvg== X-Received: by 2002:a17:902:fc4d:b0:234:f182:a754 with SMTP id d9443c01a7336-23824081fa3mr47766515ad.47.1750847266800; Wed, 25 Jun 2025 03:27:46 -0700 (PDT) Received: from localhost.localdomain ([154.64.226.185]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-237d83f1e1fsm133350635ad.83.2025.06.25.03.27.44 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 25 Jun 2025 03:27:46 -0700 (PDT) From: Changliang Wu To: aconole@redhat.com, echaudro@redhat.com, i.maximets@ovn.org, dev@openvswitch.org Date: Wed, 25 Jun 2025 18:27:10 +0800 Message-ID: <20250625102710.822034-4-changliang.wu@smartx.com> X-Mailer: git-send-email 2.43.5 In-Reply-To: <20250625102710.822034-1-changliang.wu@smartx.com> References: <20250625102710.822034-1-changliang.wu@smartx.com> MIME-Version: 1.0 Subject: [ovs-dev] [PATCH 3/3] tests: lldp: Add testcases for lldp/neighbor. X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: ovs-dev-bounces@openvswitch.org Sender: "dev" Signed-off-by: Changliang Wu --- tests/automake.mk | 1 + tests/ovs-lldp.at | 335 +++++++++++++++++++++++++++++++++++++++++++++ tests/testsuite.at | 1 + 3 files changed, 337 insertions(+) create mode 100644 tests/ovs-lldp.at diff --git a/tests/automake.mk b/tests/automake.mk index 59f538761..a453a0c4b 100644 --- a/tests/automake.mk +++ b/tests/automake.mk @@ -68,6 +68,7 @@ TESTSUITE_AT = \ tests/tunnel.at \ tests/tunnel-push-pop.at \ tests/tunnel-push-pop-ipv6.at \ + tests/ovs-lldp.at \ tests/ovs-router.at \ tests/lockfile.at \ tests/reconnect.at \ diff --git a/tests/ovs-lldp.at b/tests/ovs-lldp.at new file mode 100644 index 000000000..15103b83c --- /dev/null +++ b/tests/ovs-lldp.at @@ -0,0 +1,335 @@ +AT_BANNER([ovs-lldp]) + +AT_SETUP([lldp - check lldp neighbor display]) + +OVS_VSWITCHD_START([]) + +AT_CHECK([ + ovs-vsctl set bridge br0 \ + datapath_type=dummy +], [0]) + +AT_CHECK([ + ovs-vsctl add-port br0 p1 -- set Interface p1 type=dummy \ + lldp:enable=true +], [0]) + +AT_CHECK([ovs-appctl netdev-dummy/receive p1 \ +'0180c200000ee878eecf78d588cc020704e878eecf78a80416054769676162697445746865726e6574312f302f3332060200790808746f5f37305f33310a0b424a59442d36372e3233370c1d48334320436f6d7761726520506c6174666f726d20536f6674776172650e0403140114100c0501c0a843ed020000027b00fe060080c2010bb8fe070080c202020000fe100080c203000109564c414e2030303031fe060080c2060000fe090080c2070100000000fe0900120f01036c01001efe0c00120f020101011000000000fe0600120f0428000000']) + +AT_CHECK([ovs-appctl lldp/neighbor p1], [0], [dnl +------------------------------------------------------------------------------- +LLDP neighbor: +------------------------------------------------------------------------------- +Interface: p1 + Chassis: + Chassis ID: e8:78:ee:cf:78:a8 + SysName: BJYD-67.237 + SysDescr: H3C Comware Platform Software + MgmtIP: 192.168.67.237 + MgmtIface: 635 + Capability: Bridge, on + Capability: Router, on + Port: + PortID: GigabitEthernet1/0/32 + PortDescr: to_70_31 + TTL: 121 + MFS: 10240 + PMD autoneg: supported: yes, enabled: yes + Adv: 10Base-T, HD: yes, FD: yes + Adv: 100Base-TX, HD: yes, FD: yes + Adv: 1000Base-T, HD: no, FD: yes + MAU oper type: 30 + MDI Power: supported: no, enabled: no, pair control: no + Device type: PSE + VLAN: 3000, pvid: no, VLAN 0001 +------------------------------------------------------------------------------- +]) + +AT_CHECK([ovs-appctl --format json lldp/neighbor p1 | jq .lldp.interface[\[0\]].p1], [0], [dnl +[{ + "chassis": { + "BJYD-67.237": { + "capability": [ + { + "enabled": true, + "type": "Bridge" + }, + { + "enabled": true, + "type": "Router" + } + ], + "descr": "H3C Comware Platform Software", + "id": { + "type": "mac", + "value": "e8:78:ee:cf:78:a8" + }, + "mgmt-iface": [ + 635 + ], + "mgmt-ip": [ + "192.168.67.237" + ] + } + }, + "port": { + "auto-negotiation": { + "advertised": [ + { + "fd": true, + "hd": true, + "type": "10Base-T" + }, + { + "fd": true, + "hd": true, + "type": "100Base-TX" + }, + { + "fd": true, + "hd": false, + "type": "1000Base-T" + } + ], + "current": 30, + "enabled": true, + "supported": true + }, + "desc": "to_70_31", + "id": { + "type": "ifname", + "value": "GigabitEthernet1/0/32" + }, + "mfs": 10240, + "power": { + "device-type": "PSE", + "enabled": false, + "paircontrol": false, + "supported": false + }, + "ttl": 121 + }, + "ppid": { + "enabled": false, + "supported": false + }, + "vlan": { + "pvid": false, + "value": "VLAN 0001", + "vlan-id": 3000 + } +}] +]) + +AT_CHECK([ovs-appctl netdev-dummy/receive p1 \ +'0180c200000e38a91c18a11c88cc02070438a91c18a10a0415054769676162697445746865726e6574312f302f3506020079081e4769676162697445746865726e6574312f302f3520496e746572666163650a0e37462d6a696572752d636875616e0c1d48334320436f6d7761726520506c6174666f726d20536f6674776172650e0403140114100c0501c0a843ea020000027b00fe060080c2010001fe070080c202020000fe100080c203000109564c414e2030303031fe060080c2060000fe090080c2070100000000fe0900120f01036c01001efe0c00120f0203010113000000fffe0600120f042800fe0900120f0301000000000000']) + +AT_CHECK([ovs-appctl lldp/neighbor p1], [0], [dnl +------------------------------------------------------------------------------- +LLDP neighbor: +------------------------------------------------------------------------------- +Interface: p1 + Chassis: + Chassis ID: e8:78:ee:cf:78:a8 + SysName: BJYD-67.237 + SysDescr: H3C Comware Platform Software + MgmtIP: 192.168.67.237 + MgmtIface: 635 + Capability: Bridge, on + Capability: Router, on + Port: + PortID: GigabitEthernet1/0/32 + PortDescr: to_70_31 + TTL: 121 + MFS: 10240 + PMD autoneg: supported: yes, enabled: yes + Adv: 10Base-T, HD: yes, FD: yes + Adv: 100Base-TX, HD: yes, FD: yes + Adv: 1000Base-T, HD: no, FD: yes + MAU oper type: 30 + MDI Power: supported: no, enabled: no, pair control: no + Device type: PSE + VLAN: 3000, pvid: no, VLAN 0001 +------------------------------------------------------------------------------- +Interface: p1 + Chassis: + Chassis ID: 38:a9:1c:18:a1:0a + SysName: 7F-jieru-chuan + SysDescr: H3C Comware Platform Software + MgmtIP: 192.168.67.234 + MgmtIface: 635 + Capability: Bridge, on + Capability: Router, on + Port: + PortID: GigabitEthernet1/0/5 + PortDescr: GigabitEthernet1/0/5 Interface + TTL: 121 + MFS: 10240 + PMD autoneg: supported: yes, enabled: yes + Adv: 10Base-T, HD: yes, FD: yes + Adv: 100Base-TX, HD: yes, FD: yes + Adv: 1000Base-T, HD: no, FD: yes + MAU oper type: 30 + MDI Power: supported: yes, enabled: no, pair control: no + Device type: PSE + VLAN: 1, pvid: yes, VLAN 0001 +------------------------------------------------------------------------------- +]) + +AT_CHECK([ovs-appctl --format json lldp/neighbor p1 | jq .lldp.interface ], [0], [dnl +[[ + { + "p1": { + "chassis": { + "BJYD-67.237": { + "capability": [ + { + "enabled": true, + "type": "Bridge" + }, + { + "enabled": true, + "type": "Router" + } + ], + "descr": "H3C Comware Platform Software", + "id": { + "type": "mac", + "value": "e8:78:ee:cf:78:a8" + }, + "mgmt-iface": [ + 635 + ], + "mgmt-ip": [ + "192.168.67.237" + ] + } + }, + "port": { + "auto-negotiation": { + "advertised": [ + { + "fd": true, + "hd": true, + "type": "10Base-T" + }, + { + "fd": true, + "hd": true, + "type": "100Base-TX" + }, + { + "fd": true, + "hd": false, + "type": "1000Base-T" + } + ], + "current": 30, + "enabled": true, + "supported": true + }, + "desc": "to_70_31", + "id": { + "type": "ifname", + "value": "GigabitEthernet1/0/32" + }, + "mfs": 10240, + "power": { + "device-type": "PSE", + "enabled": false, + "paircontrol": false, + "supported": false + }, + "ttl": 121 + }, + "ppid": { + "enabled": false, + "supported": false + }, + "vlan": { + "pvid": false, + "value": "VLAN 0001", + "vlan-id": 3000 + } + } + }, + { + "p1": { + "chassis": { + "7F-jieru-chuan": { + "capability": [ + { + "enabled": true, + "type": "Bridge" + }, + { + "enabled": true, + "type": "Router" + } + ], + "descr": "H3C Comware Platform Software", + "id": { + "type": "mac", + "value": "38:a9:1c:18:a1:0a" + }, + "mgmt-iface": [ + 635 + ], + "mgmt-ip": [ + "192.168.67.234" + ] + } + }, + "port": { + "auto-negotiation": { + "advertised": [ + { + "fd": true, + "hd": true, + "type": "10Base-T" + }, + { + "fd": true, + "hd": true, + "type": "100Base-TX" + }, + { + "fd": true, + "hd": false, + "type": "1000Base-T" + } + ], + "current": 30, + "enabled": true, + "supported": true + }, + "desc": "GigabitEthernet1/0/5 Interface", + "id": { + "type": "ifname", + "value": "GigabitEthernet1/0/5" + }, + "mfs": 10240, + "power": { + "device-type": "PSE", + "enabled": false, + "paircontrol": false, + "supported": true + }, + "ttl": 121 + }, + "ppid": { + "enabled": false, + "supported": false + }, + "vlan": { + "pvid": true, + "value": "VLAN 0001", + "vlan-id": 1 + } + } + } +]] +]) + +AT_CLEANUP \ No newline at end of file diff --git a/tests/testsuite.at b/tests/testsuite.at index 9d77a9f51..f80656076 100644 --- a/tests/testsuite.at +++ b/tests/testsuite.at @@ -66,6 +66,7 @@ m4_include([tests/ofproto-dpif.at]) m4_include([tests/bridge.at]) m4_include([tests/netdev-type.at]) m4_include([tests/ovsdb.at]) +m4_include([tests/ovs-lldp.at]) m4_include([tests/ovs-vsctl.at]) m4_include([tests/stp.at]) m4_include([tests/rstp.at])