██╗ ██████╗ ██████╗ ██████╗ ██████╗ ███████╗███╗ ██╗
██║ ██╔═══██╗██╔═══██╗██╔══██╗██╔════╝ ██╔════╝████╗ ██║
██║ ██║ ██║██║ ██║██████╔╝██║ ███╗█████╗ ██╔██╗ ██║
██║ ██║ ██║██║ ██║██╔═══╝ ██║ ██║██╔══╝ ██║╚██╗██║
███████╗╚██████╔╝╚██████╔╝██║ ╚██████╔╝███████╗██║ ╚████║
╚══════╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═════╝ ╚══════╝╚═╝ ╚═══╝
Production-grade interactive CLI for Linux loopback interface
lifecycle management with FRR routing integration
- Introduction
- Key Features
- Architecture Overview
- Dependencies
- Installation
- Running the Application
- Use Cases
- Use Case 1 — Create a VRF and Loopbacks with BGP Advertisement
- Use Case 2 — Create Loopbacks with OSPF in an Existing VRF
- Use Case 3 — Bulk Loopback Creation Across Multiple VRFs
- Use Case 4 — Create Loopbacks from a Specific Subnet
- Use Case 5 — Move an Interface to a Different VRF
- Use Case 6 — Reconfigure an IP Address on an Interface
- Use Case 7 — Clean Up All Loopbacks by Tag
- Use Case 8 — Delete a VRF and All Its Interfaces
- Use Case 9 — Emergency Cleanup on Abrupt Exit
- State and Log Files
- FRR BGP VRF Model Reference
- Known Limitations
- Troubleshooting
LoopGen is a production-grade interactive command-line tool for Ubuntu Linux that manages the complete lifecycle of loopback (dummy) interfaces in VRF-aware network environments. It integrates directly with FRR (Free Range Routing) to automate routing protocol advertisement alongside every interface operation.
The tool is designed for network automation engineers, lab operators, and infrastructure teams who need to rapidly provision, test, and decommission loopback prefixes across multiple VRFs without writing one-off scripts or manually coordinating kernel operations with FRR configuration.
Managing loopbacks in a multi-VRF environment involves at least four separate systems:
| Layer | Without LoopGen |
|---|---|
| Linux kernel | Manual ip link, ip addr, ip route commands |
| VRF placement | Precise netlink ordering (enslave before IP assign) |
| FRR routing | Manual vtysh config for OSPF/BGP per VRF |
| State tracking | Custom scripts to remember what was created |
LoopGen handles all four layers from a single interactive menu — with validation, rollback on failure, and complete cleanup on exit.
- Zero shell parsing — all kernel operations use
pyroute2RTNETLINK directly - Atomic VRF placement — single netlink socket session guarantees interfaces land in the correct VRF routing table, not the main table
- FRR-aware cleanup — deleting an interface removes BGP/OSPF advertisements, FRR interface stanzas, and the kernel device in the correct order
- Full VRF lifecycle — create and delete entire VRFs including their FRR BGP/OSPF instances, interface stanzas, and kernel devices
- Emergency cleanup —
Ctrl+C,Ctrl+Z, andCtrl+\trigger an interactive cleanup wizard
| Feature | Description |
|---|---|
| VRF Discovery | Auto-detects all kernel VRF devices via pyroute2 RTNETLINK |
| Atomic VRF Placement | Single socket session: create → enslave → IP assign → UP |
| Loopback Creation | Bulk creation of dummy interfaces with sequential naming |
| IP Allocation | Random RFC1918 or from user-defined subnet |
| OSPF Integration | network statement or interface-level ip ospf area |
| BGP Integration | Correct router bgp <asn> vrf <name> per-VRF model |
| VRF Management | Create/delete VRFs in kernel and FRR in one step |
| Interface Manager | Move interfaces between VRFs, reconfigure IP addresses |
| FRR Cleanup | Removes BGP/OSPF advertisements AND FRR interface stanzas |
| State Persistence | JSON state file survives restarts |
| Emergency Cleanup | Signal handlers for SIGINT, SIGTSTP, SIGQUIT |
| Idempotency | State file prevents duplicate creation |
| Audit Logging | Full DEBUG log at /var/tmp/loopgen.log |
┌──────────────────────────────────────────────────────────────────┐
│ LoopGen CLI │
├──────────────┬───────────────┬───────────────┬───────────────────┤
│ StateManager │ KernelManager │ FRRManager │ DisplayManager │
│ │ │ │ │
│ JSON file │ pyroute2 │ vtysh │ PrettyTable │
│ /var/tmp/ │ RTNETLINK │ OSPF / BGP │ colorama │
│ loopgen_ │ (no shell │ VRF-aware │ grouped tables │
│ state.json │ parsing) │ config │ │
├──────────────┴───────────────┴───────────────┴───────────────────┤
│ LoopbackCreator │ CleanupManager │ VRFManager │ InterfaceManager │
└──────────────────────────────────────────────────────────────────┘
| Component | Responsibility |
|---|---|
StateManager |
JSON persistence, idempotency, tag/VRF indexing |
KernelManager |
All pyroute2 netlink ops — VRF, dummy interfaces, IP |
FRRManager |
vtysh OSPF/BGP config and removal, VRF stanza management |
IPUtils |
RFC1918 random IP, subnet allocation, conflict detection |
DisplayManager |
VRF-grouped PrettyTable display, FRR config output |
LoopbackCreator |
Creation wizard with VRF selection and FRR rollback |
CleanupManager |
Deletion by tag/name/all with FRR and kernel cleanup |
VRFManager |
Complete VRF lifecycle including BGP/OSPF instance removal |
InterfaceManager |
Move interfaces between VRFs, reconfigure IP addresses |
| Requirement | Minimum Version | Notes |
|---|---|---|
| Operating System | Ubuntu 20.04 LTS | Ubuntu 22.04 / 24.04 recommended |
| Linux Kernel | 5.4+ | Required for VRF RTNETLINK support |
| Python | 3.8 | importlib.metadata required (stdlib since 3.8) |
| Privileges | root / sudo | RTNETLINK write operations require CAP_NET_ADMIN |
| FRR | 8.0 | Optional — FRR features gracefully disabled if absent |
Install using pip install -r requirements.txt:
# requirements.txt
# Kernel networking — all interface/VRF operations via RTNETLINK
# No shell command parsing used anywhere
pyroute2>=0.7.0
# Terminal tables — grouped interface display
prettytable>=3.0.0
# Colored terminal output
colorama>=0.4.6
Note: LoopGen uses only Python standard library modules beyond these three packages (
json,logging,signal,subprocess,re,ipaddress,pathlib, etc.).
FRR is optional. Without it, LoopGen creates and manages kernel interfaces normally — routing protocol options are gracefully disabled.
To use OSPF or BGP integration:
| FRR Component | Purpose |
|---|---|
ospfd |
OSPF routing process for loopback advertisement |
bgpd |
BGP routing process for loopback advertisement |
pimd |
PIM multicast (if running, creates pimreg devices in VRFs) |
vtysh |
CLI interface — LoopGen uses this for all FRR operations |
# Clone the repository
git clone https://github.com/waqasdaar/LoopGen.git
cd loopgen
# Or download the single script directly
wget https://github.com/waqasdaar/LoopGen/blob/main/loopgen.py# Option A — using requirements.txt (recommended)
sudo pip3 install -r requirements.txt
# Option B — install packages individually
sudo pip3 install pyroute2 prettytable colorama
# Option C — virtual environment (development)
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
# Run as: sudo venv/bin/python loopgen.pySkip this step if you only need kernel interface management without routing protocol integration.
# Add FRR official repository
curl -s https://deb.frrouting.org/frr/keys.gpg \
| sudo tee /usr/share/keyrings/frrouting.gpg > /dev/null
echo "deb [signed-by=/usr/share/keyrings/frrouting.gpg] \
https://deb.frrouting.org/frr \
$(lsb_release -s -c) frr-stable" \
| sudo tee /etc/apt/sources.list.d/frr.list
sudo apt update && sudo apt install -y frr frr-pythontools
# Enable the daemons you need
sudo sed -i 's/bgpd=no/bgpd=yes/' /etc/frr/daemons
sudo sed -i 's/ospfd=no/ospfd=yes/' /etc/frr/daemons
# Restart FRR to apply daemon changes
sudo systemctl restart frr
sudo systemctl enable frr
# Verify FRR is running
sudo vtysh -c "show version"Required before using BGP features in LoopGen:
sudo vtysh << 'EOF'
configure terminal
router bgp 65000
bgp router-id 10.0.0.1
no bgp ebgp-requires-policy
address-family ipv4 unicast
exit-address-family
end
write memory
EOFRequired before using OSPF features in LoopGen:
sudo vtysh << 'EOF'
configure terminal
router ospf
ospf router-id 10.0.0.1
end
write memory
EOF# Verify Python dependencies
python3 -c "import pyroute2, prettytable, colorama; print('All OK')"
# Verify FRR connectivity
sudo vtysh -c "show version"
# Verify kernel VRF support
sudo ip link add vrf-test type vrf table 99
sudo ip link set vrf-test up
ip link show type vrf
sudo ip link del vrf-test
echo "Kernel VRF support: OK"LoopGen requires root privileges for RTNETLINK socket operations:
# Standard invocation
sudo python3 loopgen.py
# With virtual environment
sudo /path/to/venv/bin/python loopgen.pyOn successful startup you will see the LoopGen banner followed by the main menu:
██╗ ██████╗ ██████╗ ██████╗ ██████╗ ███████╗███╗ ██╗
██║ ██╔═══██╗██╔═══██╗██╔══██╗██╔════╝ ██╔════╝████╗ ██║
██║ ██║ ██║██║ ██║██████╔╝██║ ███╗█████╗ ██╔██╗ ██║
██║ ██║ ██║██║ ██║██╔═══╝ ██║ ██║██╔══╝ ██║╚██╗██║
███████╗╚██████╔╝╚██████╔╝██║ ╚██████╔╝███████╗██║ ╚████║
╚══════╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═════╝ ╚══════╝╚═╝ ╚═══╝
Production Loopback Manager + FRR | v2.9.7
State : /var/tmp/loopgen_state.json
Log : /var/tmp/loopgen.log
FRR: OK | Tracked: 0 | VRFs detected: 2
────────────────────────────────────────────────────
Main Menu
────────────────────────────────────────────────────
[1] Show Interfaces
[2] Create Loopbacks
[3] Cleanup Loopbacks
[4] Show FRR Running Config
[5] Show Detected VRFs
[6] VRF Manager ← create / delete VRFs
[7] Interface Manager ← move / reconfigure IPs
[8] Exit
────────────────────────────────────────────────────
➤ Select [1]:
| Option | Description |
|---|---|
[1] Show Interfaces |
Display all interfaces grouped by VRF. Excludes VRF master devices and FRR-internal pimreg devices. |
[2] Create Loopbacks |
Interactive wizard: select VRF(s), count, name prefix, IP mode, routing protocol. |
[3] Cleanup Loopbacks |
Delete tracked interfaces by tag, name, or all — removes FRR config and kernel devices. |
[4] Show FRR Config |
Print the complete FRR running configuration. |
[5] Show Detected VRFs |
List all kernel VRF devices with table IDs. |
[6] VRF Manager |
Create or delete VRFs (kernel + FRR BGP/OSPF/stanza). |
[7] Interface Manager |
Move interfaces to different VRFs or reconfigure IP addresses. |
[8] Exit |
Save state and exit cleanly. |
Scenario: Provision a new VRF vrf100 with routing table 100, then
create 3 loopback interfaces inside it and advertise them via BGP.
➤ Select [1]: 6 # VRF Manager
➤ Choice [4]: 1 # Create new VRF
➤ VRF name: vrf100
➤ Routing table ID: 100
➤ Proceed? [y/N]: y
✔ VRF 'vrf100' created (table=100)
What LoopGen did:
- Created kernel VRF device
vrf100with routing table 100 - Added FRR stanza
vrf vrf100 / exit-vrfto running config - Persisted entry to
/var/tmp/loopgen_state.json
➤ Select [1]: 2 # Create Loopbacks
Available VRFs:
[0] GRT
[1] vrf100 (table 100)
➤ VRF numbers: 1
➤ Number of loopbacks: 3
➤ Tag/label: bgp-test
➤ Interface name prefix: loop
➤ IP Mode [1]: 1 # Random RFC1918
➤ Protocol [1]: 3 # BGP
➤ Proceed? [y/N]: y
✔ loop001 ip=10.45.12.7/32 vrf=vrf100 tag=bgp-test protocol=BGP
✔ loop002 ip=172.19.88.41/32 vrf=vrf100 tag=bgp-test protocol=BGP
✔ loop003 ip=192.168.44.5/32 vrf=vrf100 tag=bgp-test protocol=BGP
sudo vtysh -c "show bgp vrf vrf100 ipv4 unicast"BGP table version is 3, local router ID is 10.0.0.1
Network Next Hop Metric Path
*> 10.45.12.7/32 0.0.0.0 0 i
*> 172.19.88.41/32 0.0.0.0 0 i
*> 192.168.44.5/32 0.0.0.0 0 i
ip -4 addr show master vrf1008: loop001: <BROADCAST,NOARP,UP,LOWER_UP>
inet 10.45.12.7/32 scope global loop001
9: loop002: <BROADCAST,NOARP,UP,LOWER_UP>
inet 172.19.88.41/32 scope global loop002
10: loop003: <BROADCAST,NOARP,UP,LOWER_UP>
inet 192.168.44.5/32 scope global loop003
Scenario: Create 2 loopback interfaces in vrf10 using OSPF network
statements in area 0.0.0.0.
➤ Select [1]: 2
Available VRFs:
[0] GRT
[1] vrf10 (table 10)
[2] vrf20 (table 20)
➤ VRF numbers: 1
➤ Number of loopbacks: 2
➤ Tag/label: ospf-loopbacks
➤ Interface name prefix: lo
➤ IP Mode [1]: 2 # From subnet
➤ Subnet: 10.100.0.0/24
➤ Protocol [1]: 2 # OSPF
➤ OSPF Method [1]: 1 # network statement
➤ OSPF area [0.0.0.0]: # Press Enter for default
➤ Proceed? [y/N]: y
✔ lo001 ip=10.100.0.1/32 vrf=vrf10 protocol=OSPF
✔ lo002 ip=10.100.0.2/32 vrf=vrf10 protocol=OSPF
sudo vtysh -c "show running-config" | grep -A5 "router ospf vrf vrf10"router ospf vrf vrf10
network 10.100.0.1/32 area 0.0.0.0
network 10.100.0.2/32 area 0.0.0.0
Scenario: Create loopbacks in both vrf10 and vrf20
simultaneously in one LoopGen session.
➤ Select [1]: 2
➤ VRF numbers: 1,2 # Comma-separated selection
─── VRF: vrf10
➤ Number of loopbacks: 4
➤ Tag/label: infra
➤ Interface name prefix: loop
➤ IP Mode: 1 # Random
➤ Protocol: 1 # None
─── VRF: vrf20
➤ Number of loopbacks: 4
➤ Tag/label: infra
➤ Interface name prefix: loop
➤ IP Mode: 1 # Random
➤ Protocol: 3 # BGP
➤ Proceed? [y/N]: y
✔ loop001 ip=10.x.x.x/32 vrf=vrf10 protocol=None
✔ loop002 ip=10.x.x.x/32 vrf=vrf10 protocol=None
✔ loop003 ip=10.x.x.x/32 vrf=vrf10 protocol=None
✔ loop004 ip=10.x.x.x/32 vrf=vrf10 protocol=None
✔ loop005 ip=10.x.x.x/32 vrf=vrf20 protocol=BGP
✔ loop006 ip=10.x.x.x/32 vrf=vrf20 protocol=BGP
✔ loop007 ip=10.x.x.x/32 vrf=vrf20 protocol=BGP
✔ loop008 ip=10.x.x.x/32 vrf=vrf20 protocol=BGP
Use
allinstead of index numbers to iterate every detected VRF including GRT.
Scenario: Allocate 5 management loopback addresses from
10.200.0.0/24 in vrf10 with no routing protocol.
➤ Select [1]: 2
➤ VRF numbers: 1 # vrf10
➤ Number of loopbacks: 5
➤ Tag/label: mgmt
➤ Interface name prefix: mgmt
➤ IP Mode [1]: 2 # From subnet
➤ Subnet: 10.200.0.0/24
➤ Protocol: 1 # None
➤ Proceed? [y/N]: y
✔ mgmt001 ip=10.200.0.1/32 vrf=vrf10 tag=mgmt
✔ mgmt002 ip=10.200.0.2/32 vrf=vrf10 tag=mgmt
✔ mgmt003 ip=10.200.0.3/32 vrf=vrf10 tag=mgmt
✔ mgmt004 ip=10.200.0.4/32 vrf=vrf10 tag=mgmt
✔ mgmt005 ip=10.200.0.5/32 vrf=vrf10 tag=mgmt
IPs are allocated sequentially from the subnet, skipping any address already in use on the system.
Scenario: Move loop001 from vrf10 to vrf20 and optionally
advertise it in BGP in the new VRF.
➤ Select [1]: 7 # Interface Manager
➤ Choice [3]: 1 # Move interface to a different VRF
Select Interface
────────────────
VRF: vrf10
┌───┬──────────┬───────┬────────────────┬──────┬──────────┐
│ # │Interface │ State │ IP Address │ Tag │ Protocol │
├───┼──────────┼───────┼────────────────┼──────┼──────────┤
│ 0 │ loop001 │ UP │ 10.200.0.1/32 │ mgmt │ None │
│ 1 │ loop002 │ UP │ 10.200.0.2/32 │ mgmt │ None │
└───┴──────────┴───────┴────────────────┴──────┴──────────┘
➤ Enter interface # or name: 0
Available VRFs:
[0] GRT
[1] vrf10 (table 10)
[2] vrf20 (table 20)
➤ Target VRF # or name: 2
Plan: Move loop001 → VRF vrf20
➤ Proceed? [y/N]: y
Advertise 10.200.0.1/32 in a routing protocol?
[1] No [2] OSPF [3] BGP
➤ Choice: 3
✔ BGP advertisement added for 10.200.0.1/32
✔ loop001 moved to VRF 'vrf20'.
Scenario: Change the IP address on mgmt003 from 10.200.0.3/32
to 172.16.50.10/32.
➤ Select [1]: 7 # Interface Manager
➤ Choice [3]: 2 # Reconfigure IP address
[grouped interface table shown — filtered by VRF]
➤ Enter interface # or name: mgmt003
Current IPs on mgmt003:
10.200.0.3/32
➤ Keep existing IP address(es)? [y/N]: n
➤ New IP address: 172.16.50.10
Plan: Replace IPs on mgmt003 with 172.16.50.10/32
➤ Proceed? [y/N]: y
Advertise 172.16.50.10/32 in a routing protocol?
[1] No [2] OSPF [3] BGP
➤ Choice: 1
✔ IP reconfigured on mgmt003: 172.16.50.10/32
LoopGen automatically:
- Removes any existing FRR routing advertisements for the old IP
- Removes the old IP from the kernel interface
- Assigns the new IP to the kernel interface
- Offers to advertise the new IP in OSPF or BGP
Scenario: Remove all interfaces tagged bgp-test created in
Use Case 1.
➤ Select [1]: 3 # Cleanup Loopbacks
[current interface table shown]
Cleanup Options:
[1] Keep all
[2] Delete ALL
[3] Delete by tag
[4] Delete by name
➤ Choice: 3
Available tags:
bgp-test (3 interface(s))
infra (8 interface(s))
mgmt (5 interface(s))
➤ Tag to delete: bgp-test
The following interfaces will be deleted:
• loop001
• loop002
• loop003
➤ Confirm deletion of 3 item(s)? [yes/N]: yes
ℹ Removing loop001 (ip=10.45.12.7/32 vrf=vrf100 protocol=BGP)
Removing BGP network 10.45.12.7/32 (vrf=vrf100 asn=65000) …
✔ BGP network 10.45.12.7/32 removed (vrf=vrf100)
✔ Deleted: loop001
ℹ Removing loop002 (ip=172.19.88.41/32 vrf=vrf100 protocol=BGP)
✔ BGP network 172.19.88.41/32 removed (vrf=vrf100)
✔ Deleted: loop002
ℹ Removing loop003 (ip=192.168.44.5/32 vrf=vrf100 protocol=BGP)
✔ BGP network 192.168.44.5/32 removed (vrf=vrf100)
✔ Deleted: loop003
Each deleted interface is fully cleaned from:
- FRR BGP/OSPF routing advertisements
- FRR interface stanza cache (
no interface <name>) - Linux kernel dummy device
- LoopGen state file
Scenario: Delete vrf100 which contains loopback interfaces and
FRR PIM internal devices.
➤ Select [1]: 6 # VRF Manager
➤ Choice [4]: 2 # Delete existing VRF
┌───┬──────────┬──────────┬──────────────────────────────────────┐
│ # │ VRF Name │ Table ID │ Enslaved Interfaces │
├───┼──────────┼──────────┼──────────────────────────────────────┤
│ 0 │ vrf10 │ 10 │ ens224, loop001, loop002, pimreg10 │
│ 1 │ vrf100 │ 100 │ pimreg100, pim6reg100 │
└───┴──────────┴──────────┴──────────────────────────────────────┘
FRR configuration to be removed:
• router bgp 65000 vrf vrf100
• vrf vrf100
➤ VRF number or name to delete: 1
[enslaved interface details shown]
➤ Delete VRF 'vrf100' and all its interfaces? [yes/N]: yes
[Step 1] No LoopGen-tracked interfaces.
[Step 2] Deleting kernel VRF device 'vrf100' …
✔ Kernel VRF device 'vrf100' deleted.
[Step 3] Clearing FRR PIM state for 'vrf100' …
✔ FRR-internal interfaces cleaned up.
[Step 4] Removing complete FRR configuration for VRF 'vrf100' …
[FRR] Removing BGP instance: router bgp 65000 vrf vrf100
✔ BGP instance removed: router bgp 65000 vrf vrf100
[FRR] Removing VRF stanza: vrf vrf100
✔ VRF stanza removed: vrf100
✔ FRR configuration for 'vrf100' fully removed.
[Step 5] Purging FRR interface stanzas …
✔ FRR interface stanzas purged.
✔ VRF 'vrf100' deleted successfully.
Scenario: A user presses Ctrl+C while LoopGen is running.
LoopGen intercepts the signal and offers to clean up all configuration
it created during the session.
^C
════════════════════════════════════════════════════════════════
Abrupt exit: SIGINT (Ctrl+C)
════════════════════════════════════════════════════════════════
Emergency Cleanup
┌──────────┬─────────────────┬────────┬──────────┬──────────┐
│Interface │ IP │ VRF │ Protocol │ Tag │
├──────────┼─────────────────┼────────┼──────────┼──────────┤
│ loop001 │ 10.45.12.7/32 │ vrf100 │ BGP │ bgp-test │
│ loop002 │ 172.19.88.41/32 │ vrf100 │ BGP │ bgp-test │
└──────────┴─────────────────┴────────┴──────────┴──────────┘
➤ Delete ALL configuration made by this script? [yes/No]: yes
Interface: loop001 ip=10.45.12.7/32 vrf=vrf100 protocol=BGP
➤ Delete loop001? [yes/No]: yes
[FRR] Removing BGP for 10.45.12.7
[Kernel] Deleting loop001
[FRR] Removing interface stanza loop001
[State] Removing loop001
✔ loop001 deleted
Interface: loop002 ip=172.19.88.41/32 vrf=vrf100 protocol=BGP
➤ Delete loop002? [yes/No]: yes
...
✔ loop002 deleted
Script-managed VRFs:
vrf100 table=100
➤ Delete script-managed VRFs? [yes/No]: yes
➤ Delete VRF 'vrf100'? [yes/No]: yes
[Kernel] Deleting VRF device vrf100
[FRR] Removing complete FRR config for VRF vrf100
✔ VRF 'vrf100' deleted
✔ Emergency cleanup complete.
Signal support:
Ctrl+C(SIGINT),Ctrl+Z(SIGTSTP), andCtrl+\(SIGQUIT) all trigger this cleanup flow.
Persists all interfaces and VRFs created by LoopGen across sessions. Written atomically (write-then-rename) to prevent corruption.
{
"version": "2.9.7",
"interfaces": {
"loop001": {
"interface": "loop001",
"ip": "10.45.12.7",
"prefix_len": 32,
"vrf": "vrf100",
"tag": "bgp-test",
"protocol": "BGP",
"ospf_method": "none",
"ospf_area": "0.0.0.0",
"bgp_asn": "65000",
"created_at": "2025-04-06T10:30:00Z"
}
},
"vrfs": {
"vrf100": {
"table": 100,
"created_at": "2025-04-06T10:25:00Z"
}
}
}Full DEBUG-level audit trail of every LoopGen operation.
# Follow live activity
sudo tail -f /var/tmp/loopgen.log
# Show only errors
sudo grep -i "error\|ERROR" /var/tmp/loopgen.log
# Show BGP removal steps
sudo grep -i "bgp" /var/tmp/loopgen.log
# Show all vtysh commands issued
sudo grep "vtysh:" /var/tmp/loopgen.logLoopGen uses the correct FRR per-VRF BGP instance model. Understanding this prevents confusion when inspecting FRR manually.
# Global Routing Table:
router bgp 65000
address-family ipv4 unicast
network 10.1.2.3/32
exit-address-family
# VRF instance — VRF name is on the ROUTER line:
router bgp 65000 vrf vrf20
address-family ipv4 unicast
network 172.16.50.10/32
exit-address-family
# WRONG — FRR rejects with "Unknown command":
router bgp 65000
address-family ipv4 unicast vrf vrf20 ← INVALID
network 172.16.50.10/32
See LIMITATIONS.md for the full table of known limitations, constraints, and workarounds.
# Check Python version
python3 --version # Must be 3.8+
# Check root privileges
sudo python3 loopgen.py
# Check all dependencies are installed
python3 -c "import pyroute2, prettytable, colorama; print('All OK')"# Check FRR is running
sudo systemctl status frr
# Test vtysh manually
sudo vtysh -c "show version"
# Restart FRR if needed
sudo systemctl restart frrCheck the LoopGen log for VRF membership verification:
sudo grep "verify_vrf_membership" /var/tmp/loopgen.logLoopGen issues no interface <name> after every kernel delete to
clear FRR's interface cache. If this fails, run manually:
sudo vtysh << 'EOF'
configure terminal
no interface loop001
no interface loop002
end
write memory
EOF# Remove a specific stale entry from the LoopGen state file
sudo python3 - << 'EOF'
import json
from pathlib import Path
p = Path("/var/tmp/loopgen_state.json")
d = json.loads(p.read_text())
d["interfaces"].pop("loop001", None)
p.write_text(json.dumps(d, indent=2))
print("Done — stale entry removed")
EOF# Check what BGP currently sees
sudo vtysh -c "show bgp vrf vrf100 ipv4 unicast"
# Check LoopGen log for removal steps
sudo grep "remove_bgp_network" /var/tmp/loopgen.log
# Manual removal if needed
sudo vtysh << 'EOF'
configure terminal
router bgp 65000 vrf vrf100
address-family ipv4 unicast
no network 10.45.12.7/32
exit-address-family
end
write memory
EOF