Table of Contents
Introduction on the Key Points
In today’s deep dive, we’re shifting gears from basic connectivity to something every network engineer must master — dynamic routing protocols.
In the real world, we don’t hardcode routes between every single device. That’s where protocols like OSPF and BGP come in — to dynamically advertise, learn, and propagate routes. But how do we validate that these routes are learned properly across different vendors like Cisco, Arista, Palo Alto, and Fortinet?
That’s exactly what we’ll explore today using pyATS — Cisco’s Python-powered, vendor-agnostic automation toolkit — along with Genie for parsing routing outputs. If you’re a beginner looking to bridge Python with networking, this blog is your sweet spot for Python for Network Engineer use cases.
Topology Overview

We’ll use a simple multi-vendor testbed that includes:
- Cisco IOS-XE Router: Runs OSPF and BGP
- Arista EOS Switch: Learns routes via OSPF
- Palo Alto Firewall: Learns routes via BGP
- FortiGate Firewall: Static route + OSPF redistribution
Each node exchanges routing information dynamically and can reach each other’s loopbacks. Our goal is to verify that each device has the expected prefixes via OSPF/BGP and then validate end-to-end ping across these loopbacks using pyATS
.
Why Vendor-Agnostic Testing Matters
In modern enterprise networks, multi-vendor is the norm. Gone are the days when everything was Cisco. You may deploy:
- Arista for leaf/spine fabric
- Cisco for core routing
- Palo Alto for perimeter security
- Fortinet for branch or SD-WAN
With such diversity, verifying routing behavior becomes a challenge. You can’t rely on a single-vendor monitoring or CLI format.
That’s why vendor-agnostic testing with tools like pyATS
is a game-changer. It lets you:
- Run the same tests across different platforms
- Normalize CLI outputs with Genie parsers
- Reduce human error in route validation
- Automate ping reachability between any endpoints
This builds confidence in your routing policies, redistribution strategies, and convergence testing.
Topology & Communications
Device | Role | Routing Protocol | Loopback IP | Vendor |
---|---|---|---|---|
R1 | Core Router | OSPF + BGP | 1.1.1.1 | Cisco IOS-XE |
SW1 | Leaf Switch | OSPF | 2.2.2.2 | Arista EOS |
FW1 | Perimeter | BGP | 3.3.3.3 | Palo Alto |
FW2 | Branch/Edge | Static + OSPF | 4.4.4.4 | FortiGate |
Each device advertises its loopback via OSPF or BGP. We will:
- Use
pyATS
to learn OSPF and BGP routes. - Check if the expected prefixes are present.
- Automate ping tests across loopbacks.
Workflow Script
from genie.testbed import load import logging # Enable logs logging.basicConfig(level=logging.INFO) # Load testbed testbed = load("testbed.yml") # Define target prefixes expected_routes = { "R1": ["2.2.2.2", "3.3.3.3", "4.4.4.4"], "SW1": ["1.1.1.1", "3.3.3.3", "4.4.4.4"], "FW1": ["1.1.1.1", "2.2.2.2", "4.4.4.4"], "FW2": ["1.1.1.1", "2.2.2.2", "3.3.3.3"] } for device_name, routes in expected_routes.items(): device = testbed.devices[device_name] device.connect(log_stdout=False) # Parse routing table if device.os in ["iosxe", "eos"]: output = device.parse("show ip route") elif device.os == "panos": output = device.parse("show routing route") elif device.os == "fortinet": output = device.parse("get router info routing-table all") else: continue logging.info(f"--- {device_name} ---") for ip in routes: found = ip in str(output) logging.info(f"Route to {ip} found: {found}")
Explanation by Line
testbed = load("testbed.yml")
: Loads all device SSH details.expected_routes
: Dictionary of what each device should learn..connect()
: Establishes SSH connection to the device.parse(...)
: Uses Genie to normalize CLI outputs per platform.ip in str(output)
: Searches for loopback IPs in the routing table.logging.info
: Logs presence/absence of expected routes.
This lets you programmatically verify dynamic routing without depending on manual show ip route
.
testbed.yml Example
testbed: name: MultiVendorRouting credentials: default: username: admin password: admin123 devices: R1: os: iosxe type: router connections: cli: protocol: ssh ip: 10.0.0.1 SW1: os: eos type: switch connections: cli: protocol: ssh ip: 10.0.0.2 FW1: os: panos type: firewall connections: cli: protocol: ssh ip: 10.0.0.3 FW2: os: fortinet type: firewall connections: cli: protocol: ssh ip: 10.0.0.4
Multi-Vendor CLI Screenshots
Here are real CLI outputs from each platform:
Cisco IOS-XE (R1)
R1# show ip route B 3.3.3.3 [20/0] via 10.0.0.3 O 2.2.2.2 [110/2] via 10.0.0.2
Arista EOS (SW1)
SW1# show ip route O 1.1.1.1/32 via 10.0.0.1 O 3.3.3.3/32 via 10.0.0.3
Palo Alto (FW1)
> show routing route 3.3.3.3/32 BGP 10.0.0.1
FortiGate (FW2)
get router info routing-table all 1.1.1.1/32 via 10.0.0.1 2.2.2.2/32 via 10.0.0.2
FAQs
1. How does pyATS help in learning OSPF and BGP?
Answer:
pyATS offers a programmable and repeatable framework that allows you to validate routing protocol behavior in a lab or production environment. For learning OSPF and BGP, pyATS lets you script ping tests, route validation, neighbor status checks, and even convergence timing. Instead of manually typing show commands, you can create automated workflows to ensure OSPF and BGP routes are forming and functioning as expected across Cisco, Arista, Palo Alto, and FortiGate devices.
2. Can pyATS test routing protocol reachability across multi-vendor networks?
Answer:
Yes. That’s one of its strongest features. With vendor-agnostic support, pyATS can SSH into Cisco, Arista, Palo Alto, and FortiGate devices using a single testbed file and check ping reachability, BGP peering, and OSPF neighbor relationships. This is particularly useful when validating real-world scenarios like Internet edge routing or hybrid cloud connections that span different vendors.
3. How do I verify OSPF or BGP neighbor status with pyATS?
Answer:
You can use the built-in parse
or learn
capabilities of pyATS Genie to extract structured data from commands like show ip ospf neighbor
or show ip bgp summary
. Once parsed, you can assert the neighbor state is Full
or Established
depending on the protocol. This can be part of a pyATS test script that checks for successful adjacency and reachability.
4. What if a route is missing—can pyATS detect that?
Answer:
Absolutely. By parsing the routing table using commands like show ip route
(Cisco) or show route
(Arista/Juniper), pyATS can extract the route entries and validate the existence (or absence) of specific prefixes. You can write tests that fail if a particular loopback or network prefix isn’t present, which is crucial in BGP route learning validation.
5. Is it possible to simulate OSPF or BGP failures using pyATS?
Answer:
While pyATS itself doesn’t generate traffic or perform failovers, you can integrate it with infrastructure automation (like Ansible or Python scripts) to shut interfaces or remove configs, then use pyATS to validate how OSPF or BGP reacts. This allows for automated failure testing, such as verifying that BGP reroutes traffic after a peer failure or OSPF reconverges after a link goes down.
6. Do I need to install separate parsers for BGP or OSPF outputs?
Answer:
No additional parsers are required. pyATS + Genie includes parsers for standard routing protocol outputs. For example, genie.parse("show ip ospf neighbor")
on a Cisco router will return a Python dictionary containing neighbor states, interface names, and IPs. This applies similarly to BGP and can work with multiple vendors when appropriate commands are defined.
7. How do I include Palo Alto and FortiGate in routing protocol validation?
Answer:
While Palo Alto and FortiGate support static routing and dynamic protocols like BGP or OSPF, their CLI outputs differ from traditional network OS. You can use raw
command outputs with regex parsing in pyATS for these vendors. For example, use execute("show routing route")
on Palo Alto and post-process it to check for specific prefixes or neighbor states. Although not as structured as Cisco’s Genie parsers, it works well for ping tests and route visibility.
YouTube Link
Watch the Complete Python for Network Engineer: Learning Routing Protocols: Learn OSPF, Learn BGP (Ping Tests) Using pyATS (Vendor-Agnostic) — Cisco/Arista/Palo Alto/Fortigate Lab Demo & Explanation on our channel:
Join Our Training
If this kind of real-world, multi-vendor automation excites you, I invite you to join our 3-month instructor-led program:
Python + Ansible + APIs for Network Engineers
Led by me, Trainer Sagar Dhawan, this course is designed to turn you from CLI-only to automation-ready. You’ll learn how to:
- Automate real labs with Cisco, Arista, Palo Alto & Fortinet
- Build test scripts with pyATS, Ansible, and Python
- Parse and validate BGP/OSPF, VLANs, ACLs, NATs, and more
- Work with REST APIs, NETCONF/YANG, and Jinja2 templating
- Build your own automation lab and collect configs, pings, or traceroutes
Enroll Now & Future‑Proof Your Career
Email: info@networkjourney.com
WhatsApp / Call: +91 97395 21088
Don’t be left behind in the CLI world. Master “Python for Network Engineer” workflows.
Enroll Now and Transform Your Networking Career