[Day #11 PyATS Series] Parsing MAC Address Tables (Cisco/Arista/Palo Alto/Fortigate) using pyATS for Cisco [Python for Network Engineer]
Table of Contents
Introduction
Welcome to Day 11 of our 101 Days of pyATS (Vendor-Agnostic) journey. Today, we dive into an essential aspect of network validation – parsing MAC address tables across multiple vendors using pyATS. As a Python for Network Engineer practitioner, you must be able to quickly retrieve, parse, and validate Layer 2 forwarding information for troubleshooting and automation purposes.
MAC address tables are the backbone of Ethernet switching. They map MAC addresses to switch ports and VLANs, enabling efficient packet forwarding. In multi-vendor environments (Cisco, Arista, Palo Alto, Fortigate), syntax and outputs differ significantly. Manual parsing is time-consuming and error-prone. This is where pyATS and Genie parsers shine.
In this blog, we’ll:
- Automate MAC table collection and parsing from different vendor devices
- Write reusable Python scripts for large-scale deployments
- Leverage Genie parsers to normalize outputs across platforms
- Provide CLI examples, testbed configurations, and real-world validation screenshots
By the end, you’ll have a fully functional solution that scales to hundreds or even thousands of switches and firewalls, making it a critical skill in your Python for Network Engineer toolkit.
Topology Overview

- Cisco Switch – Core or access layer
- Arista Switch – Data center fabric
- Palo Alto Firewall – L2/bridge mode
- Fortigate Firewall – Transparent mode
The test runner connects via SSH, retrieves MAC address tables, and parses them in a vendor-agnostic manner.
Topology & Communications
- Protocol: SSH
- Access: Out-of-band management network
- pyATS Genie Parsers: Handles output differences
- Goal: Collect MAC address table and standardize for validation/reporting
Workflow Script: parse_mac_table.py
from genie.testbed import load from pyats import aetest class MACAddressTableParser(aetest.Testcase): @aetest.setup def setup(self, testbed): self.testbed = load(testbed) self.devices = ['cisco', 'arista', 'paloalto', 'fortigate'] @aetest.test def parse_mac_table(self): for device_name in self.devices: device = self.testbed.devices[device_name] device.connect(log_stdout=False) print(f"Connected to {device_name}") if device.os == 'iosxe': output = device.parse('show mac address-table') elif device.os == 'eos': output = device.parse('show mac address-table') elif device.os == 'panos': output = device.parse('show mac all') elif device.os == 'fortinet': output = device.parse('diagnose switch mac-address list') else: self.skipped(f"Unsupported OS for {device_name}") continue print(f"Parsed MAC table for {device_name}: {output}")
Explanation by Line
genie.testbed.load
– Loads device inventory from YAMLaetest.Testcase
– pyATS test class structuredevice.connect()
– Establishes SSH session- Conditional logic selects vendor-specific MAC table command
device.parse()
– Uses Genie parser to convert raw CLI output into structured Python dictionary- Printed results show normalized MAC table
testbed.yml Example
devices: cisco: os: iosxe type: switch credentials: default: username: admin password: admin connections: cli: protocol: ssh ip: 10.0.0.1 arista: os: eos type: switch credentials: default: username: admin password: admin connections: cli: protocol: ssh ip: 10.0.0.2 paloalto: os: panos type: firewall credentials: default: username: admin password: admin connections: cli: protocol: ssh ip: 10.0.0.3 fortigate: os: fortinet type: firewall credentials: default: username: admin password: admin connections: cli: protocol: ssh ip: 10.0.0.4
Post-Validation CLI Screenshots (Expected Output)
- Cisco: Parsed
show mac address-table
- Arista: Parsed
show mac address-table
- Palo Alto: Parsed
show mac all
- Fortigate: Parsed
diagnose switch mac-address list
Structured output example:
{ 'mac_table': { 'vlans': { '10': { 'mac_addresses': { '0011.2233.4455': { 'interfaces': ['Gig1/0/1'], 'entry_type': 'dynamic' } } } } } }
FAQs
Q1: Why should I use pyATS to parse MAC address tables instead of manual CLI commands?
A: Using pyATS automates the process of collecting and parsing MAC address tables across multiple devices and vendors. Manual CLI checks are time-consuming, prone to human errors, and difficult to scale. With pyATS and Genie parsers, you can programmatically retrieve structured MAC address data (in JSON or Python dict format), integrate it into compliance checks, generate reports, and run the same test across thousands of devices in minutes.
Q2: Does pyATS support MAC address parsing for multiple vendors (Cisco, Arista, Palo Alto, Fortigate)?
A: Yes. pyATS, along with Genie parsers, supports Cisco IOS, IOS-XE, NX-OS, and some third-party platforms like Arista. Palo Alto and Fortigate may not have native parsers, but you can still retrieve their CLI output via Unicon and create custom parsers using Python regular expressions or pyATS plugin extensions. This makes the workflow vendor-agnostic.
Q3: How does pyATS extract and structure MAC address table data?
A: pyATS connects to each device via SSH or API, runs the platform-specific MAC table command (e.g., show mac address-table
on Cisco IOS), and uses built-in Genie parsers to convert the raw text into structured Python dictionaries. This structured output makes it easy to filter by VLAN, interface, or MAC, and integrate with inventory systems or anomaly detection scripts.
Q4: Can I validate VLAN consistency across vendors using parsed MAC address tables?
A: Absolutely. Once pyATS parses the MAC address tables, you can cross-check VLAN-to-interface mappings between Cisco, Arista, Palo Alto, and Fortigate devices. This is crucial in multi-vendor environments where misconfigured VLANs or trunk ports can cause broadcast domain mismatches and connectivity issues.
Q5: How do I handle differences in MAC address table command outputs between vendors?
A: pyATS solves this by using abstraction models and vendor-specific parsers. For unsupported platforms (e.g., Fortigate), you can implement a custom parser or normalize the CLI output into a common data model. This ensures your scripts remain vendor-agnostic and reusable across different network platforms.
Q6: Can parsed MAC address tables be used for security audits?
A: Yes. With pyATS, you can build automated compliance checks to detect unauthorized devices, monitor MAC aging, and ensure sticky MAC configurations are correctly enforced. This is particularly useful in enterprise environments with strict NAC (Network Access Control) policies.
Q7: What are common errors when parsing MAC tables and how do I troubleshoot?
A: Common errors include missing Genie parser support for a specific OS, connection timeouts, or incomplete command outputs. To troubleshoot, first confirm the command is supported by Genie (genie parser list
), enable debug logs in pyATS, and if necessary, build a custom parser using regex or pyATS’ plugin system.
Q8: Can I export parsed MAC address data to CSV or integrate with other tools?
A: Yes. pyATS provides structured Python data that can be easily converted to CSV, JSON, or sent via APIs to tools like Ansible, Splunk, or ServiceNow. This makes it straightforward to create dashboards, reports, or feed the data into automated remediation workflows.
YouTube Link
Watch the Complete Python for Network Engineer: Parsing MAC address tables Cisco/Arista/Paloalto/Fortigate) Lab Demo & Explanation on our channel:
Join Our Training
Want to master Python for Network Engineer automation and vendor-agnostic testing?
Join Trainer Sagar Dhawan’s 3-month instructor-led training program. Learn:
- pyATS testbed design and advanced parsing
- Python scripting for large networks
- Ansible, RESTCONF, NETCONF automation
- Real-world multi-vendor use cases (Cisco, Arista, Palo Alto, Fortigate)
Build production-grade skills to scale your automation to thousands of devices.
Check the full course outline and enroll here
Enroll Now & Future‑Proof Your Career
Email: info@networkjourney.com
WhatsApp / Call: +91 97395 21088