<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: routecrushlab</title>
    <description>The latest articles on DEV Community by routecrushlab (@routecrushlab).</description>
    <link>https://dev.to/routecrushlab</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4183814%2F091248c9-513f-4768-959f-0fd43d9cab3c.jpg</url>
      <title>DEV Community: routecrushlab</title>
      <link>https://dev.to/routecrushlab</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/routecrushlab"/>
    <language>en</language>
    <item>
      <title>See why BGP picked that path — a browser X-ray for your containerlab lab</title>
      <dc:creator>routecrushlab</dc:creator>
      <pubDate>Wed, 14 Oct 2026 06:45:35 +0000</pubDate>
      <link>https://dev.to/routecrushlab/see-why-bgp-picked-that-path-a-browser-x-ray-for-your-containerlab-lab-3e</link>
      <guid>https://dev.to/routecrushlab/see-why-bgp-picked-that-path-a-browser-x-ray-for-your-containerlab-lab-3e</guid>
      <description>&lt;p&gt;You can read &lt;code&gt;show ip bgp&lt;/code&gt;. You can read &lt;code&gt;show ip ospf neighbor&lt;/code&gt;. But when a lab has five routers and something is off, the picture of what the &lt;em&gt;whole lab&lt;/em&gt; is doing still lives only in your head — you build it router by router, command by command.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;network-xray&lt;/strong&gt; draws that picture for you. It reads the state your routers actually report and shows, in the browser, what is happening inside each router: who it is adjacent to, which routes it installed, and &lt;strong&gt;why a BGP best path won&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;It is open source (MIT): &lt;a href="https://github.com/rclab-dev/network-xray" rel="noopener noreferrer"&gt;https://github.com/rclab-dev/network-xray&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What it shows
&lt;/h2&gt;

&lt;p&gt;Start from the topology graph you already use (for example &lt;code&gt;containerlab graph&lt;/code&gt;). Click a router, and its &lt;strong&gt;DeepDive&lt;/strong&gt; opens: forwarding direction, OSPF / BGP adjacencies, the routing table — and the best-path decision.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjstcsevfev71g16kxlsr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjstcsevfev71g16kxlsr.png" alt=" " width="800" height="352"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It is not a simulator. It draws the state the routers returned, so when you change a config or take a link down, the picture changes with it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why did BGP pick that path?
&lt;/h3&gt;

&lt;p&gt;For BGP it lines up the candidate paths and shows &lt;strong&gt;which comparison decided the winner&lt;/strong&gt;. In the lab below, two ISPs advertise 8.8.8.0/24. Change the LocalPref and the best path flips in place — no lab rebuild.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fzq3hwcx6340x208upej5.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fzq3hwcx6340x208upej5.gif" alt="Change the LocalPref and the best path flips between r3 and r2 — recorded from a real FRR / containerlab lab" width="600" height="259"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Links go down, the picture follows
&lt;/h3&gt;

&lt;p&gt;The collector (see &lt;em&gt;Try it&lt;/em&gt; below) runs with &lt;code&gt;--watch&lt;/code&gt; and re-reads the lab every few seconds. Shut an interface and you watch the adjacency drop and the route disappear; bring it back and it recovers.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fh59gofpihzje7r9klqfu.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fh59gofpihzje7r9klqfu.gif" alt="OSPF goes Full, a link drops, the route is lost, then it recovers" width="800" height="720"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Example: break it, look inside, fix it
&lt;/h2&gt;

&lt;p&gt;Every practice problem starts from a lab that is broken on purpose. Take the two-ISP lab above in its broken version: r1 hears 8.8.8.0/24 from a fast ISP (r2) and a slow one (r3), yet traffic takes the slow one. Open r1's DeepDive and the Best-Path Decision gives the reason in one line: &lt;strong&gt;best path by LocPrf (100 &amp;gt; 50)&lt;/strong&gt; — something is lowering the LocalPref of the fast path.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Flapfp1uhnz8esllkq1cf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Flapfp1uhnz8esllkq1cf.png" alt=" " width="800" height="352"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Fix the route-map on r1 (&lt;code&gt;set local-preference 150&lt;/code&gt; for the path from r2), and the picture re-decides from the routers' new state a few seconds later: the best path moves to r2 (&lt;strong&gt;150 &amp;gt; 100&lt;/strong&gt;), the forwarding arrow follows, and the problem banner turns to &lt;strong&gt;✓ Solved&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fricr1q668ag989godpog.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fricr1q668ag989godpog.png" alt=" " width="800" height="820"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Each problem marks the route that matters, so whichever router's DeepDive you open, that route is selected automatically (when the router has it) and its forwarding arrow is drawn.&lt;/p&gt;

&lt;h2&gt;
  
  
  Update: it also works on ipSpace BGP Labs
&lt;/h2&gt;

&lt;p&gt;Labs you build yourself rarely have just two neighbors per router, so I also tried a lab I did not write: "Use BGP Route Reflectors" from Ivan Pepelnjak's &lt;a href="https://bgplabs.net/" rel="noopener noreferrer"&gt;BGP Labs&lt;/a&gt;, started with &lt;a href="https://netlab.tools/" rel="noopener noreferrer"&gt;netlab&lt;/a&gt;. The route reflector s1 has four  neighbors (l1–l4); its DeepDive draws all four links at once, each coming in from where that neighbor sits on the overview, and the angles follow when you drag s1 (interactive template &lt;code&gt;xray-graph-nextui.html&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;Since v1.0.3, netlab can also start network-xray for you as a tool: add three lines to the topology and run &lt;code&gt;netlab up&lt;/code&gt;&lt;br&gt;
(&lt;a href="https://github.com/rclab-dev/network-xray#readme" rel="noopener noreferrer"&gt;how&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjcba4kjjjudrlpulft7t.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjcba4kjjjudrlpulft7t.gif" alt="s1 with four neighbors: the DeepDive draws all four links, and they re-angle when s1 is dragged on the overview" width="720" height="191"&gt;&lt;/a&gt;  &lt;/p&gt;

&lt;p&gt;&lt;em&gt;Topology: BGP Labs "Use BGP Route Reflectors" (Ivan Pepelnjak / ipSpace.net, MIT license, &lt;a href="https://bgplabs.net/ibgp/3-rr/" rel="noopener noreferrer"&gt;https://bgplabs.net/ibgp/3-rr/&lt;/a&gt;). Started  with netlab, drawn with network-xray.&lt;/em&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Try it
&lt;/h2&gt;
&lt;h3&gt;
  
  
  The shortest way: one script
&lt;/h3&gt;

&lt;p&gt;With containerlab installed, one command deploys the two-ISP lab from the LocalPref GIF above, keeps collecting its state, and opens the graph:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/rclab-dev/network-xray
&lt;span class="nb"&gt;cd &lt;/span&gt;network-xray
./demo.sh examples/q21-bgp-lp/q21.clab.yml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then open &lt;code&gt;http://&amp;lt;your machine&amp;gt;:8080/&lt;/code&gt; (port busy? add one: &lt;code&gt;./demo.sh examples/q21-bgp-lp/q21.clab.yml 8081&lt;/code&gt;). The script calls &lt;code&gt;sudo containerlab deploy&lt;/code&gt;; if your user can run containerlab without sudo, start it as &lt;code&gt;SUDO= ./demo.sh …&lt;/code&gt;. Stop with Ctrl-C, then &lt;code&gt;sudo containerlab destroy -t examples/q21-bgp-lp/q21.clab.yml --cleanup&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  In your own containerlab lab
&lt;/h3&gt;

&lt;p&gt;Two steps: start the collector, then open &lt;code&gt;containerlab graph&lt;/code&gt; with the network-xray template.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/rclab-dev/network-xray

&lt;span class="c"&gt;# 1. collect the lab's state and keep re-reading it (use ospf or bgp for your lab)&lt;/span&gt;
node ./network-xray/clab-xray-collect.js lab.clab.yml ./network-xray bgp &lt;span class="nt"&gt;--exclude-mgmt&lt;/span&gt; &lt;span class="nt"&gt;--watch&lt;/span&gt; &amp;amp;

&lt;span class="c"&gt;# 2. open your usual topology graph with the X-ray template&lt;/span&gt;
containerlab graph &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--topo&lt;/span&gt; lab.clab.yml &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--template&lt;/span&gt; ./network-xray/xray-graph.html &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--static-dir&lt;/span&gt; ./network-xray
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;--exclude-mgmt&lt;/code&gt; leaves the management network out of the picture. &lt;code&gt;containerlab graph&lt;/code&gt; serves on port 50080 by default (&lt;code&gt;http://&amp;lt;your machine&amp;gt;:50080/&lt;/code&gt;; change it with &lt;code&gt;-s 0.0.0.0:&amp;lt;port&amp;gt;&lt;/code&gt;). Click any router to look inside it. Verified with &lt;strong&gt;FRR&lt;/strong&gt; and &lt;strong&gt;Nokia SR Linux&lt;/strong&gt; (a mixed FRR + SR Linux lab renders the same way).&lt;/p&gt;

&lt;p&gt;Want to drag nodes around and have the open DeepDive follow? Use &lt;code&gt;--template ./network-xray/xray-graph-nextui.html&lt;/code&gt; instead (an opt-in interactive graph built on NeXt UI).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Flot5j2blf0ti4nyyoa3c.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Flot5j2blf0ti4nyyoa3c.gif" alt="containerlab deploy, then graph with the X-ray template, click a node" width="800" height="613"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  No containerlab? Use a Codespace
&lt;/h3&gt;

&lt;p&gt;The README has an &lt;strong&gt;Open in GitHub Codespaces&lt;/strong&gt; button. It deploys a 3-router FRR lab and opens the X-ray view on port 8600 in about 2–3 minutes. It runs on a 4-core machine from your own Codespaces quota, so delete the codespace when you are done.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbg6g8jb7xcfnrg1it043.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbg6g8jb7xcfnrg1it043.gif" alt=" " width="719" height="482"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Or just paste output
&lt;/h3&gt;

&lt;p&gt;The &lt;a href="https://rclab-dev.github.io/network-xray/" rel="noopener noreferrer"&gt;gallery&lt;/a&gt; draws from &lt;code&gt;show&lt;/code&gt; output you paste in (FRR and SR Linux today). No install. Handy if you write about networking and want a "this is what the router is doing right now" picture next to your text.&lt;/p&gt;

&lt;h2&gt;
  
  
  Practice problems with a pass check
&lt;/h2&gt;

&lt;p&gt;network-xray also comes with troubleshooting problems from &lt;a href="https://routecrushlab.com/?lang=en&amp;amp;ref=devto" rel="noopener noreferrer"&gt;RouteCrushLab&lt;/a&gt;, packaged for containerlab. Each problem has a &lt;strong&gt;broken&lt;/strong&gt; starting version and a &lt;strong&gt;fixed&lt;/strong&gt; version (GitHub releases). Fix the lab, and when the routers' state meets the condition — adjacency up, route installed, the ping target reachable — the problem banner shows &lt;strong&gt;✓ Solved&lt;/strong&gt;. It checks state, not config lines, so a different fix from the write-up usually passes too. q1–q21 are out.&lt;/p&gt;

&lt;p&gt;You can add the same check to your own lab by writing a &lt;code&gt;check&lt;/code&gt; in &lt;code&gt;problem.json&lt;/code&gt; (&lt;a href="https://github.com/rclab-dev/network-xray/blob/main/docs/problem-format.md" rel="noopener noreferrer"&gt;docs/problem-format.md&lt;/a&gt;).&lt;/p&gt;

&lt;h2&gt;
  
  
  What's next
&lt;/h2&gt;

&lt;p&gt;Today: containerlab with FRR and SR Linux. &lt;strong&gt;CML2 and IOS-XE support is in progress&lt;/strong&gt; — not released yet. If you run another NOS, a sanitized sample of its &lt;code&gt;show&lt;/code&gt; output in an issue helps a lot.&lt;/p&gt;

&lt;p&gt;It is far from finished. If something is drawn wrong, or you want it to look different, please open an issue: &lt;a href="https://github.com/rclab-dev/network-xray/issues" rel="noopener noreferrer"&gt;https://github.com/rclab-dev/network-xray/issues&lt;/a&gt;&lt;/p&gt;




&lt;ul&gt;
&lt;li&gt;GitHub: &lt;a href="https://github.com/rclab-dev/network-xray" rel="noopener noreferrer"&gt;https://github.com/rclab-dev/network-xray&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Gallery: &lt;a href="https://rclab-dev.github.io/network-xray/" rel="noopener noreferrer"&gt;https://rclab-dev.github.io/network-xray/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;network-xray is an independent project and is not affiliated with, endorsed by, or sponsored by ipSpace.net.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>networking</category>
      <category>containerlab</category>
      <category>bgp</category>
      <category>opensource</category>
    </item>
  </channel>
</rss>
