ipSpace.net blog

Author Archives: ipSpace.net blog

Netmiko vs Ansible: Executing Scripts

My initial “configuring Arista cEOS with Netmiko or Ansible” test was a bit biased. netlab generates the final configuration snippets in both cases (due to Ansible FUBARs we had to deal with), but then Netmiko just sends the configuration commands to the switch (after entering configuration mode), while the Ansible eos_config module executes show running, identifies the difference, and sends only the changes to the device.

While that use case is highly relevant (after all, we’re configuring network devices ;) I really should have done an apples-to-apples comparison, and FRRouting virtual machines are the ideal playground.

Configuring SRv6 Layer-3 Services on Junos

Now that we know what we need to make layer-3 services (BGP-free core transporting IPv4 and IPv6 traffic) work with SRv6, let’s go through the steps needed to configure them on Junos, continuing from the baseline SRv6 with IS-IS configuration (and again relying on the excellent SRv6 Micro-SID (uSID) Basics article1 by Krzysztof Szarkowicz).

In the BGP-Free Network Core with SRv6, we identified the components we need (assuming IBGP+IGP design):

Crazy Delay: IOS XR OSPFv2 Default Route Origination

I decided to make Netmiko the default configuration deployment method netlab uses for Cisco IOS XR. It works great, and I don’t have to worry about whether the user runs IOS XRd control-plane (in which case scripts work) or vRouter (in which case there’s a VM inside the container, so no luck).

After fixing the initial glitches (more on that another time), all integration tests passed except the OSPFv2 default origination test. It turns out the default waiting time (30 seconds) is way too low; Cisco IOS XR needs almost 90 seconds (after its reboot completes) to originate the OSPFv2 default route.

Sample netlab SRv6 Lab Topologies

With the growing number of SRv6 implementations that netlab supports, it made sense to create a set of topologies to help you get started exploring the SRv6 world. The sample topologies include:

Read the getting started document and have fun exploring the scenarios 😎

Netmiko vs Ansible: Does It Matter?

We launched device configuration with Netmiko in the September 2026 netlab release and made it easier to use in the October 2026 release. It will become the default configuration method for several popular platforms (Arista EOS, Cisco IOS, Cisco Nexus OS, Cisco IOS XR, FRRouting virtual machines) in a few months, but before doing that, I wanted to check whether the change matters.

TL&DR: Yes, it does.

BGP-Free Network Core with SRv6

The concept of a BGP-free core is decades old:

  • The network core routers (P routers in MPLS terminology) do not carry BGP routes; BGP routes are exchanged solely between network edge routers.
  • The core routers thus cannot use the customer IP addresses in the packet forwarding process.
  • The edge routers (PE routers in MPLS terminology) know how to reach BGP next hops using an encapsulation mechanism that makes IP packets opaque to the network core.
Interestingly, the concept predates Cisco’s Tag Switching (later MPLS) by at least a decade; that’s how all ATM and Frame Relay networks worked (with ATM VPI/VCI or Frame Relay DLCI used as the in-network addresses).

The Crappy Cisco IOS CLI Error Reporting

TL&DR: It’s really hard to figure out when a Cisco IOS box configured via its CLI reports a configuration error.

One of the drawbacks of using Netmiko to configure network devices is its inherent lack of error detection – while it can switch into configuration mode and exit it (including a commit operation if needed), it doesn’t detect configuration errors.

No big deal (I thought); the configuration error messages generated by Cisco IOS always start with a percent sign (%), so I’d just use that as the error_pattern parameter of the send_config_from_file command. A few integration test failures later, that turned out to be a bad idea; Cisco IOS starts errors and warnings with the percentage sign, and there’s absolutely no reliable way to differentiate between the two.

netlab 26.10: SRv6, More Netmiko

netlab release 26.10 adds new SRv6 implementations and features:

  • Full SRv6 support (IS-IS, layer-3 services, L3VPN) on Junos
  • SRv6 with IS-IS and SRv6 layer-3 services on Nokia SR Linux
  • IPv4 layer-3 services with SRv6 locators exchanged over EBGP on FRRouting and Cisco IOS XR

Other new features include:

Worth Reading: Don’t Fight the Users’ Desire Paths

Chris Siebenmann publishes articles written from an interesting perspective: he’s a Unix herder at a university (based on my ancient, similar experience, that’s usually worse than herding cats).

In one of his recent articles, he applied the desire paths ideas to IT: don’t fight how people are doing things; either kindly nudge them in the right direction, or help them get stuff done the way they like to get it done, but in the least harmful way. I could definitely use some of his wisdom decades ago 🤷🏻‍♂️.

Prefix Sets: Simplifying netlab ACLs and Prefix Filters

When I implemented prefix filters in netlab (release 1.9.0), I wanted them to match the final device configurations as closely as possible, including the one prefix per entry rule to match the device configuration sequence numbers. That worked well, but resulted in YAML bloat, since each matching prefix requires several lines of YAML.

We tried to use the same approach with ACLs but quickly gave up when we realized the port not in range operation requires multiple ACL entries on most platforms. With the matching sequence numbers paradigm gone with the wind, it made no sense to limit ourselves to one prefix per ACL entry – the initial ACL entry implementation already accepted lists of prefixes and expanded them into ACL entries.

Using Syslog in netlab Labs

netlab release 26.09 added support for Syslog clients and servers. We implemented the clients on numerous platforms; the only Syslog server implementation is the dnsmasq container.

Adding Syslog to a netlab lab is (almost) trivial:

  • You have to (re)build the dnsmasq container with the netlab clab build dnsmasq command to add rsyslogd to the container image
  • When you add a dnsmasq node to a lab, it automatically starts a Syslog server
  • The Syslog client is enabled on other nodes (or globally) with the services.syslog.server setting.

The OSPF MTU Mismatch Saga

The OSPF is stuck in database exchange state symptom is probably familiar to every networking engineer who ever had to pass a certification exam. It’s caused by the MTU mismatch between adjacent OSPF routers.

The recent (unexpected) trip into the how crazy is it to declare your interface MTU to be zero wonderland uncovered way more than I ever wanted to know about this arcane topic. Here are a few highlights (thanks a million to Aleksey Popov for researching this topic and posting information here, here, and here).

Sunsetting netlab Vagrant/libvirt provider

When I started the netlab project, Vagrant was the go-to tool if you wanted to build a virtual environment described in a text configuration file (an idea popularized as infrastructure-as-code). It wasn’t ideal for what we were doing, but a tool rarely does a great job when used far away from its intended use case.

netlab initially supported Vagrant with VirtualBox, quickly adding support for KVM/libvirt through the vagrant-libvirt plugin. Life was good… until it wasn’t.

How vagrant-libvirt Plugin Deals with Duplicate Subnets

TL&DR: Badly. The vagrant-libvirt plugin mysteriously crashes when an existing virtual network (with a different libvirt name) uses the same IP subnet as the desired management network.

Background: netlab is using the vagrant-libvirt plugin to manage libvirt/KVM virtual machines with Vagrant. As I already have that infrastructure, I use it to start standalone virtual machines (usually to test various Ubuntu releases) on my Linux server. Things work great… until they don’t.

Here’s how I managed to waste half a day chasing imaginary gremlins caused by a simple error.

1 2 3 … 6