[Day #43 PyATS Series] Neighbor Discovery (CDP/LLDP) Validation Using pyATS for Cisco [Python for Network Engineer]
Table of Contents
Introduction on the Key Points
Neighbor discovery protocols like CDP (Cisco Discovery Protocol) and LLDP (Link Layer Discovery Protocol) play a crucial role in identifying directly connected devices in a network. As a Python for Network Engineer practitioner, automating neighbor validation ensures accurate documentation, topology mapping, and quick troubleshooting without relying on manual show
commands.
In large networks, engineers often face these challenges:
- Manual neighbor verification is slow and error-prone.
- Topology mismatches due to incorrect cabling or patching.
- Limited visibility across multi-vendor environments.
Using pyATS, you can automatically collect and validate neighbor information across Cisco and other vendor devices. This automation ensures consistent link verification, helps in detecting unauthorized devices, and aids in network audits.
Topology Overview
Our sample topology includes multiple network devices:

- Access_SW1: Cisco Catalyst Switch running CDP and LLDP
- Dist_SW1: Arista Switch running LLDP
- Core_RTR: Cisco Router running CDP
The goal is to validate that each device correctly discovers its neighbors, regardless of vendor differences.
Topology & Communications
- CDP: Cisco proprietary protocol for neighbor discovery.
- LLDP: IEEE standard protocol, supported by Cisco, Arista, Palo Alto, and Fortinet.
- pyATS Communication: Uses SSH to connect to each device.
- Data Collection: Parses
show cdp neighbors
andshow lldp neighbors
. - Cross-Vendor: If a neighbor uses LLDP and the local device uses CDP, validation still occurs using LLDP output parsing.
Workflow Script
from genie.testbed import load def validate_neighbors(device): device.connect(log_stdout=False) cdp_output = device.parse('show cdp neighbors detail') lldp_output = device.parse('show lldp neighbors detail') device.disconnect() neighbors = { "cdp": [], "lldp": [] } # Collect CDP neighbors for intf, data in cdp_output.get('index', {}).items(): neighbors["cdp"].append({ "neighbor_id": data.get("device_id"), "platform": data.get("platform"), "port": data.get("port_id") }) # Collect LLDP neighbors for intf, data in lldp_output.get('interfaces', {}).items(): for neighbor_name, neighbor_data in data.get('port_id', {}).items(): neighbors["lldp"].append({ "neighbor_id": neighbor_name, "system_name": neighbor_data }) return neighbors if __name__ == "__main__": testbed = load('testbed.yml') results = {} for name, device in testbed.devices.items(): print(f"Checking neighbors on {name}...") results[name] = validate_neighbors(device) print("Neighbor discovery validation completed:", results)
Explanation by Line
- Imports: Uses Genie to load the testbed.
- validate_neighbors: Connects to a device and parses both CDP and LLDP neighbor outputs.
- Data extraction: Converts raw CLI data into structured dictionaries.
- Cross-vendor validation: Collects neighbors from both protocols to support Cisco and non-Cisco devices.
- Results dictionary: Summarizes neighbor relationships for all devices.
testbed.yml Example
testbed: name: neighbor_validation devices: Access_SW1: os: iosxe type: switch connections: cli: protocol: ssh ip: 192.168.1.10 credentials: default: username: admin password: admin123 Dist_SW1: os: eos type: switch connections: cli: protocol: ssh ip: 192.168.1.11 credentials: default: username: admin password: admin123 Core_RTR: os: iosxr type: router connections: cli: protocol: ssh ip: 192.168.1.12 credentials: default: username: admin password: admin123
Post-validation CLI Screenshots (Real Expected Output)
Cisco CDP Output:
Switch# show cdp neighbors detail Device ID: Dist_SW1 Platform: Arista vEOS, Capabilities: Switch Interface: Gig1/0/1, Port ID (outgoing port): Eth1 Holdtime : 120 sec ...
Cisco LLDP Output:
Switch# show lldp neighbors detail Local Intf: Gig1/0/2 Chassis id: 00:11:22:33:44:55 Port id: Eth2 System Name: Core_RTR ...
Script Result:
{ "Access_SW1": { "cdp": [ { "neighbor_id": "Dist_SW1", "platform": "Arista vEOS", "port": "Eth1" } ], "lldp": [ { "neighbor_id": "Core_RTR", "system_name": "Core_RTR" } ] }, "Dist_SW1": { ... }, "Core_RTR": { ... } }
FAQs
1. What is the purpose of validating neighbor discovery using pyATS?
Validating neighbor discovery ensures that CDP and LLDP information accurately reflects physical and logical network connections. Automating this process with pyATS allows engineers to detect cabling errors, unauthorized devices, and topology mismatches quickly without manual CLI checks.
2. Does pyATS support both CDP and LLDP across different vendors?
Yes. pyATS supports parsing both Cisco Discovery Protocol (CDP) and Link Layer Discovery Protocol (LLDP) outputs. This makes it possible to validate neighbors across Cisco, Arista, Palo Alto, and Fortinet devices in a single, vendor-agnostic test.
3. Can I detect missing or unexpected neighbors with this automation?
Absolutely. By defining an expected neighbor list for each interface, you can use pyATS to flag missing connections or detect unauthorized devices connected to your network.
4. Is it safe to run neighbor discovery validation in production?
Yes. The script is read-only—it only runs show
commands like show cdp neighbors detail
and show lldp neighbors detail
. It does not modify device configurations, making it safe for production environments.
5. How can I integrate neighbor discovery validation into a CI/CD pipeline?
You can schedule the pyATS script to run automatically via Jenkins, GitHub Actions, or cron jobs. The JSON output can be stored in version control to track topology changes over time.
6. Does this script work in both physical and virtual lab environments?
Yes. Whether you’re using physical switches and routers or virtual platforms like vIOS, vEOS, or GNS3, pyATS can connect via SSH and parse neighbor information consistently.
7. How does pyATS handle devices that only support LLDP but not CDP?
If a device doesn’t support CDP, pyATS automatically parses LLDP outputs, ensuring neighbor discovery works across multi-vendor devices without any manual adjustments.
8. Can the neighbor data be visualized in a network topology diagram?
Yes. The parsed neighbor data from pyATS can be exported to NetworkX, Graphviz, or custom dashboards to automatically generate real-time topology diagrams.
YouTube Link
Watch the Complete Python for Network Engineer: Neighbor Discovery (CDP/LLDP) Validation Using pyATS for Cisco [Python for Network Engineer] Lab Demo & Explanation on our channel:
Join Our Training
Automating neighbor discovery with pyATS saves hours of manual verification, ensures correct topology mapping, and prevents misconfigurations.
Trainer Sagar Dhawan offers a 3-month instructor-led training that teaches Python, Ansible, APIs, and Cisco DevNet automation skills. You’ll learn how to:
- Automate CDP and LLDP neighbor discovery
- Build multi-vendor network validation tools
- Integrate pyATS with dashboards and CI/CD pipelines
Join Our Training to become an expert in Python for Network Engineer automation.
Enroll Now & Future‑Proof Your Career
Email: info@networkjourney.com
WhatsApp / Call: +91 97395 21088