fabric-network

star 2

Configure L2/L3 networking, FABnet, facility ports, VLANs, and IP addressing on FABRIC slices

fabric-testbed By fabric-testbed schedule Updated 2/26/2026

name: fabric-network description: Configure L2/L3 networking, FABnet, facility ports, VLANs, and IP addressing on FABRIC slices allowed-tools: - Read - Grep - Glob - Write - Edit - Bash

Instructions

When invoked, generate networking code for FABRIC slices. Determine the user's networking needs:

  1. L2 Networks (Bridge, PTP, STS) — Layer 2 Ethernet connectivity
  2. L3 FABnet — FABRIC's routed IPv4/IPv6 network across sites
  3. FABNetv4Ext — Public IPv4 addresses
  4. Facility Ports — External connectivity to campus/provider networks
  5. Sub-interfaces/VLANs — VLAN tagging on dedicated NICs
  6. Port Mirroring — Traffic capture

Guide users on NIC type selection based on their needs.

Important: Use the modern API pattern for networks:

  1. Create the network with slice.add_l2network() or slice.add_l3network()
  2. Set interface mode: iface.set_mode('auto')
  3. Add interface to network: net.add_interface(iface)
  4. For L3 routing: node.add_route(subnet=fablib.FABNETV4_SUBNET, next_hop=net.get_gateway())

API Reference

L2 Network Types

net = slice.add_l2network(
    name: str = None,
    interfaces: list[Interface] = [],  # Can pass here or use net.add_interface() after
    type: str = None,       # "L2Bridge", "L2PTP", "L2STS"
    subnet: ipaddress = None,  # For auto IP assignment
    gateway: ipaddress = None,
    user_data: dict = {},
) -> NetworkService
  • L2Bridge: Local Ethernet on a single site, unlimited interfaces
  • L2PTP: Point-to-point link between exactly 2 interfaces (can span sites)
  • L2STS: Site-to-site link between exactly 2 interfaces on different sites

L3 Network

net = slice.add_l3network(
    name: str = None,
    interfaces: list[Interface] = [],  # Can pass here or use net.add_interface() after
    type: str = "IPv4",     # "IPv4", "IPv6", "IPv4Ext", "IPv6Ext"
    user_data: dict = {},
    technology: str = None,
    subnet: ipaddress.ip_network = None,
    site: str = None,
) -> NetworkService

Network Methods

net.add_interface(iface)           # Add interface to network
net.get_gateway()                   # Get gateway for L3 networks
net.get_interfaces()                # Get all interfaces on network

Interface Configuration

iface.set_mode('auto')             # Auto IP from subnet
iface.set_mode('manual')           # Manual IP configuration
iface.set_mode('config')           # Default config mode
iface.get_ip_addr()                # Get assigned IP
iface.get_os_interface()           # Get OS device name (e.g., "ens7")

FABnet (Simplified L3 on Node)

node.add_fabnet(
    name: str = "FABNET",
    net_type: str = "IPv4",    # "IPv4" or "IPv6"
    nic_type: str = "NIC_Basic",
    routes: list = None,
    subnet: ipaddress.ip_network = None,
)

Routing

# High-level route (preferred)
node.add_route(
    subnet: IPv4Network | IPv6Network,
    next_hop: IPv4Address | IPv6Address | NetworkService,
)

# Low-level IP configuration (for manual setup)
node.ip_addr_add(addr, subnet, interface, persistent=None)
node.ip_link_up(subnet, interface)
node.ip_route_add(subnet, gateway, interface=None, persistent=None)

Sub-interfaces (VLANs)

interface.add_sub_interface(
    name: str,
    vlan: str,
    bw: int = 10,  # Bandwidth in Gbps
)

FABnet Subnet Constants

fablib.FABNETV4_SUBNET   # IPv4Network("10.128.0.0/10")
fablib.FABNETV6_SUBNET   # IPv6Network("2602:FCFB:00::/40")
fablib.FABNETV4EXT_SUBNET  # IPv4Network("23.134.232.0/22")

NIC Selection Guide

Use Case NIC Model Notes
Basic connectivity, FABnet NIC_Basic Shared, 1 port, most common
High-throughput experiments NIC_ConnectX_6 Dedicated, dual 100G ports
Legacy 25G experiments NIC_ConnectX_5 Dedicated, dual 25G ports
400G experiments NIC_ConnectX_7_400 Dedicated, 400G
SmartNIC programming NIC_BlueField_2_ConnectX_6 Dedicated, programmable
VLANs/sub-interfaces NIC_ConnectX_6 or NIC_ConnectX_5 Dedicated NICs only

Patterns

L2 Bridge with Auto IP (Same Site)

from ipaddress import IPv4Network

slice = fablib.new_slice(name="l2-bridge")
site = fablib.get_random_site()

subnet = IPv4Network("192.168.1.0/24")

# Create network with subnet for auto IP
net = slice.add_l2network(name="lan", subnet=subnet)

node1 = slice.add_node(name="node1", site=site)
iface1 = node1.add_component(model="NIC_Basic", name="nic1").get_interfaces()[0]
iface1.set_mode('auto')
net.add_interface(iface1)

node2 = slice.add_node(name="node2", site=site)
iface2 = node2.add_component(model="NIC_Basic", name="nic1").get_interfaces()[0]
iface2.set_mode('auto')
net.add_interface(iface2)

slice.submit()

# Verify — IPs are auto-assigned
node2_addr = node2.get_interface(network_name="lan").get_ip_addr()
stdout, stderr = node1.execute(f"ping -c 5 {node2_addr}")

L2 Point-to-Point (Cross-Site)

from ipaddress import IPv4Network

slice = fablib.new_slice(name="l2-ptp")
[site1, site2] = fablib.get_random_sites(count=2)

subnet = IPv4Network("10.0.0.0/30")

net = slice.add_l2network(name="ptp-link", subnet=subnet, type="L2PTP")

node1 = slice.add_node(name="node1", site=site1)
iface1 = node1.add_component(model="NIC_Basic", name="nic1").get_interfaces()[0]
iface1.set_mode('auto')
net.add_interface(iface1)

node2 = slice.add_node(name="node2", site=site2)
iface2 = node2.add_component(model="NIC_Basic", name="nic1").get_interfaces()[0]
iface2.set_mode('auto')
net.add_interface(iface2)

slice.submit()

# Verify
node2_addr = node2.get_interface(network_name="ptp-link").get_ip_addr()
stdout, stderr = node1.execute(f"ping -c 5 {node2_addr}")

FABnet IPv4 (Cross-Site L3 — Recommended)

from ipaddress import IPv4Network

slice = fablib.new_slice(name="fabnet-v4")
[site1, site2, site3] = fablib.get_random_sites(count=3)

# Create per-site L3 networks
net1 = slice.add_l3network(name="net1", type="IPv4")
net2 = slice.add_l3network(name="net2", type="IPv4")
net3 = slice.add_l3network(name="net3", type="IPv4")

# Node 1
node1 = slice.add_node(name="node1", site=site1)
iface1 = node1.add_component(model="NIC_Basic", name="nic1").get_interfaces()[0]
iface1.set_mode('auto')
net1.add_interface(iface1)
node1.add_route(subnet=fablib.FABNETV4_SUBNET, next_hop=net1.get_gateway())

# Node 2
node2 = slice.add_node(name="node2", site=site2)
iface2 = node2.add_component(model="NIC_Basic", name="nic1").get_interfaces()[0]
iface2.set_mode('auto')
net2.add_interface(iface2)
node2.add_route(subnet=fablib.FABNETV4_SUBNET, next_hop=net2.get_gateway())

# Node 3
node3 = slice.add_node(name="node3", site=site3)
iface3 = node3.add_component(model="NIC_Basic", name="nic1").get_interfaces()[0]
iface3.set_mode('auto')
net3.add_interface(iface3)
node3.add_route(subnet=fablib.FABNETV4_SUBNET, next_hop=net3.get_gateway())

slice.submit()

# All nodes can reach each other via FABnet
for node in slice.get_nodes():
    for net_name in ["net1", "net2", "net3"]:
        try:
            iface = node.get_interface(network_name=net_name)
            print(f"{node.get_name()} on {net_name}: {iface.get_ip_addr()}")
        except:
            pass

Simplified FABnet (Using node.add_fabnet)

slice = fablib.new_slice(name="simple-fabnet")

node1 = slice.add_node(name="node1", site="TACC")
node1.add_fabnet(net_type="IPv4")

node2 = slice.add_node(name="node2", site="UCSD")
node2.add_fabnet(net_type="IPv4")

slice.submit()

FABNetv4Ext (Public IPs)

slice = fablib.new_slice(name="public-ip")

node1 = slice.add_node(name="web-server", site="TACC", cores=4, ram=8, disk=50)
nic1 = node1.add_component(model="NIC_Basic", name="nic1")
iface1 = nic1.get_interfaces()[0]
iface1.set_mode('auto')

ext_net = slice.add_l3network(name="ext-net", type="IPv4Ext")
ext_net.add_interface(iface1)

slice.submit()

# The node gets a public IP
iface = node1.get_interface(network_name="ext-net")
print(f"Public IP: {iface.get_ip_addr()}")

VLAN Sub-interfaces

slice = fablib.new_slice(name="vlan-experiment")

node = slice.add_node(name="node1", site="TACC")
# Must use a dedicated NIC for VLANs
nic = node.add_component(model="NIC_ConnectX_6", name="nic1")

iface = nic.get_interfaces()[0]
sub1 = iface.add_sub_interface(name="vlan100", vlan="100", bw=10)
sub2 = iface.add_sub_interface(name="vlan200", vlan="200", bw=10)

# Connect sub-interfaces to different networks
net1 = slice.add_l2network(name="net-vlan100", interfaces=[sub1])
net2 = slice.add_l2network(name="net-vlan200", interfaces=[sub2])

slice.submit()

Multi-Subnet with Static Routing

from ipaddress import IPv4Network

slice = fablib.new_slice(name="multi-subnet")
site = fablib.get_random_site()

net1_subnet = IPv4Network("192.168.1.0/24")
net2_subnet = IPv4Network("192.168.2.0/24")

# Create L2 networks
net1 = slice.add_l2network(name="net1", subnet=net1_subnet)
net2 = slice.add_l2network(name="net2", subnet=net2_subnet)

# Node1 on subnet 1
node1 = slice.add_node(name="node1", site=site)
iface1 = node1.add_component(model="NIC_Basic", name="nic1").get_interfaces()[0]
iface1.set_mode('auto')
net1.add_interface(iface1)

# Router bridging both subnets
router = slice.add_node(name="router", site=site)
r_iface1 = router.add_component(model="NIC_Basic", name="r-nic1").get_interfaces()[0]
r_iface1.set_mode('auto')
net1.add_interface(r_iface1)

r_iface2 = router.add_component(model="NIC_Basic", name="r-nic2").get_interfaces()[0]
r_iface2.set_mode('auto')
net2.add_interface(r_iface2)

# Node2 on subnet 2
node2 = slice.add_node(name="node2", site=site)
iface2 = node2.add_component(model="NIC_Basic", name="nic1").get_interfaces()[0]
iface2.set_mode('auto')
net2.add_interface(iface2)

slice.submit()

# Enable routing on router node
router.execute("sudo sysctl -w net.ipv4.ip_forward=1")

# Get auto-assigned IPs for routing
router_net1_ip = router.get_interface(network_name="net1").get_ip_addr()
router_net2_ip = router.get_interface(network_name="net2").get_ip_addr()

# Add static routes on endpoints
node1.execute(f"sudo ip route add {net2_subnet} via {router_net1_ip}")
node2.execute(f"sudo ip route add {net1_subnet} via {router_net2_ip}")

# Test end-to-end
node2_addr = node2.get_interface(network_name="net2").get_ip_addr()
stdout, stderr = node1.execute(f"ping -c 5 {node2_addr}")
Install via CLI
npx skills add https://github.com/fabric-testbed/claude-plugin-marketplace --skill fabric-network
Repository Details
star Stars 2
call_split Forks 0
navigation Branch main
article Path SKILL.md
More from Creator
fabric-testbed
fabric-testbed Explore all skills →