Configure L2/L3 networking, FABnet, facility ports, VLANs, and IP addressing on FABRIC slices
When invoked, generate networking code for FABRIC slices. Determine the user's networking needs:
Guide users on NIC type selection based on their needs.
Important: Use the modern API pattern for networks:
slice.add_l2network() or slice.add_l3network()iface.set_mode('auto')net.add_interface(iface)node.add_route(subnet=fablib.FABNETV4_SUBNET, next_hop=net.get_gateway())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
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
net.add_interface(iface) # Add interface to network
net.get_gateway() # Get gateway for L3 networks
net.get_interfaces() # Get all interfaces on network
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")
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,
)
# 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)
interface.add_sub_interface(
name: str,
vlan: str,
bw: int = 10, # Bandwidth in Gbps
)
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")
| 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 |
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}")
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}")
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
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()
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()}")
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()
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}")