원클릭으로
fabric-routing
Configure static routes, IP forwarding, WireGuard VPN, sshuttle tunnels, and performance tuning on FABRIC
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
메뉴
Configure static routes, IP forwarding, WireGuard VPN, sshuttle tunnels, and performance tuning on FABRIC
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
SOC 직업 분류 기준
Run iPerf3 network performance benchmarks with optional CPU pinning and SmartNIC optimization
Generate FABRIC testbed environment setup, configuration validation, and SSH key management code
Deploy Docker containers and Kubernetes clusters on FABRIC nodes
Connect FABRIC to external testbeds via facility ports and set up port mirroring
Provision and flash Xilinx U280 FPGAs on FABRIC nodes
Provision GPU nodes on FABRIC with driver installation and CUDA setup
| name | fabric-routing |
| description | Configure static routes, IP forwarding, WireGuard VPN, sshuttle tunnels, and performance tuning on FABRIC |
| allowed-tools | ["Read","Grep","Glob","Write","Edit","Bash"] |
When invoked, generate code for routing and tunneling on FABRIC nodes. Options include:
Ask the user what connectivity problem they're solving.
Use the modern API pattern: create networks with add_l2network(subnet=...), use iface.set_mode('auto') and net.add_interface(iface) for auto IP configuration.
# High-level route (preferred for FABnet)
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)
from ipaddress import IPv4Network
from fabrictestbed_extensions.fablib.fablib import FablibManager
fablib = FablibManager()
slice = fablib.new_slice(name="routing-experiment")
[site1, site2, site3] = fablib.get_random_sites(count=3)
net1_subnet = IPv4Network("192.168.1.0/24")
net2_subnet = IPv4Network("192.168.2.0/24")
# Create L2 networks with subnets for auto IP
net1 = slice.add_l2network(name="net1", subnet=net1_subnet)
net2 = slice.add_l2network(name="net2", subnet=net2_subnet)
# Node1 on site1 — connected to net1
node1 = slice.add_node(name="Node1", site=site1, image="default_ubuntu_24")
iface1 = node1.add_component(model="NIC_Basic", name="nic1").get_interfaces()[0]
iface1.set_mode('auto')
net1.add_interface(iface1)
# Node2 on site2 — bridging node with interfaces on both networks
node2 = slice.add_node(name="Node2", site=site2, image="default_ubuntu_24")
iface2a = node2.add_component(model="NIC_Basic", name="nic1").get_interfaces()[0]
iface2a.set_mode('auto')
net1.add_interface(iface2a)
iface2b = node2.add_component(model="NIC_Basic", name="nic2").get_interfaces()[0]
iface2b.set_mode('auto')
net2.add_interface(iface2b)
# Node3 on site3 — connected to net2
node3 = slice.add_node(name="Node3", site=site3, image="default_ubuntu_24")
iface3 = node3.add_component(model="NIC_Basic", name="nic1").get_interfaces()[0]
iface3.set_mode('auto')
net2.add_interface(iface3)
slice.submit()
# Enable IP forwarding on bridging node (Node2)
node2 = slice.get_node("Node2")
node2.execute("echo 1 | sudo tee /proc/sys/net/ipv4/ip_forward")
node2.execute("sudo sysctl -w net.ipv4.ip_forward=1")
# Get auto-assigned addresses
node1 = slice.get_node("Node1")
node3 = slice.get_node("Node3")
node2_net1_addr = node2.get_interface(network_name="net1").get_ip_addr()
node2_net2_addr = node2.get_interface(network_name="net2").get_ip_addr()
node3_addr = node3.get_interface(network_name="net2").get_ip_addr()
# Add static routes
node1.execute(f"sudo ip route add {net2_subnet} via {node2_net1_addr}")
node3.execute(f"sudo ip route add {net1_subnet} via {node2_net2_addr}")
# Test end-to-end connectivity
stdout, stderr = node1.execute(f"ping -c 5 {node3_addr}")
print(stdout)
# Create two nodes with FABnet for underlay
slice = fablib.new_slice(name="wireguard-overlay")
[site1, site2] = fablib.get_random_sites(count=2)
net1_subnet = IPv4Network("192.168.1.0/24")
net2_subnet = IPv4Network("192.168.2.0/24")
net1 = slice.add_l2network(name="net1", subnet=net1_subnet)
net2 = slice.add_l2network(name="net2", subnet=net2_subnet)
# Node1 on net1
node1 = slice.add_node(name="Node1", site=site1, image="default_ubuntu_24")
iface1 = node1.add_component(model="NIC_Basic", name="nic1").get_interfaces()[0]
iface1.set_mode('auto')
net1.add_interface(iface1)
# Node2 bridging both nets
node2 = slice.add_node(name="Node2", site=site2, image="default_ubuntu_24")
iface2a = node2.add_component(model="NIC_Basic", name="nic1").get_interfaces()[0]
iface2a.set_mode('auto')
net1.add_interface(iface2a)
iface2b = node2.add_component(model="NIC_Basic", name="nic2").get_interfaces()[0]
iface2b.set_mode('auto')
net2.add_interface(iface2b)
# Node3 on net2
node3 = slice.add_node(name="Node3", site=site2, image="default_ubuntu_24")
iface3 = node3.add_component(model="NIC_Basic", name="nic1").get_interfaces()[0]
iface3.set_mode('auto')
net2.add_interface(iface3)
slice.submit()
node1 = slice.get_node("Node1")
node2 = slice.get_node("Node2")
node3 = slice.get_node("Node3")
# Get addresses
node1_net1_addr = node1.get_interface(network_name="net1").get_ip_addr()
node2_net2_addr = node2.get_interface(network_name="net2").get_ip_addr()
node3_net2_addr = node3.get_interface(network_name="net2").get_ip_addr()
node2_net2_ifc_name = node2.get_interface(network_name="net2").get_os_interface()
# Install WireGuard and generate keys
keys = {}
for node in [node1, node2, node3]:
node.execute("sudo apt-get update -qq && sudo apt-get install -y -qq wireguard", quiet=True)
node.execute("wg genkey | tee privatekey | wg pubkey > publickey")
priv_key, _ = node.execute("cat privatekey", quiet=True)
pub_key, _ = node.execute("cat publickey", quiet=True)
keys[node.get_name()] = {"public": pub_key.strip(), "private": priv_key.strip()}
# Configure WireGuard on Node1
node1_wg_conf = f"""\
[Interface]
PrivateKey = {keys["Node1"]["private"]}
Address = 10.0.0.1/24
ListenPort = 51820
[Peer]
PublicKey = {keys["Node2"]["public"]}
Endpoint = {node1_net1_addr}:51820
AllowedIPs = 10.0.0.0/24, {net2_subnet}
PersistentKeepalive = 25
"""
node1.execute(f"echo '{node1_wg_conf}' | sudo tee /etc/wireguard/wg0.conf > /dev/null")
# Configure WireGuard on Node2 (relay with NAT)
node2_wg_conf = f"""\
[Interface]
PrivateKey = {keys["Node2"]["private"]}
Address = 10.0.0.2/24
ListenPort = 51820
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o {node2_net2_ifc_name} -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o {node2_net2_ifc_name} -j MASQUERADE
[Peer]
PublicKey = {keys["Node1"]["public"]}
Endpoint = {node1_net1_addr}:51820
AllowedIPs = 10.0.0.1/32
PersistentKeepalive = 25
[Peer]
PublicKey = {keys["Node3"]["public"]}
Endpoint = {node3_net2_addr}:51820
AllowedIPs = 10.0.0.3/32
PersistentKeepalive = 25
"""
node2.execute(f"echo '{node2_wg_conf}' | sudo tee /etc/wireguard/wg0.conf > /dev/null")
# Configure WireGuard on Node3
node3_wg_conf = f"""\
[Interface]
PrivateKey = {keys["Node3"]["private"]}
Address = 10.0.0.3/24
ListenPort = 51820
[Peer]
PublicKey = {keys["Node2"]["public"]}
Endpoint = {node2_net2_addr}:51820
AllowedIPs = 10.0.0.0/24, {net1_subnet}
PersistentKeepalive = 25
"""
node3.execute(f"echo '{node3_wg_conf}' | sudo tee /etc/wireguard/wg0.conf > /dev/null")
# Enable IP forwarding on Node2
node2.execute("sudo sysctl -w net.ipv4.ip_forward=1")
# Start WireGuard
for node in [node1, node2, node3]:
node.execute("sudo systemctl enable wg-quick@wg0 && sudo systemctl start wg-quick@wg0")
# Test tunnel
stdout, _ = node1.execute("ping -c 5 10.0.0.3")
print(stdout)
stdout, _ = node3.execute("ping -c 5 10.0.0.1")
print(stdout)
sshuttle provides transparent TCP proxy access through a relay node via SSH.
# After creating a 3-node slice with Node2 as bridge...
# Install sshuttle on nodes
for node in slice.get_nodes():
node.execute("sudo apt-get update -qq && sudo apt-get install -y -qq sshuttle net-tools", quiet=True)
node1 = slice.get_node("Node1")
node2 = slice.get_node("Node2")
node3 = slice.get_node("Node3")
node2_net1_addr = node2.get_interface(network_name="net1").get_ip_addr()
node3_addr = node3.get_interface(network_name="net2").get_ip_addr()
# Start sshuttle on Node1 to tunnel to Node3 via Node2
cmd = (
f"sudo sshuttle --method=nat "
f"--ssh-cmd 'ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null' "
f"-r root@{node2_net1_addr} {net2_subnet} --daemon"
)
node1.execute(cmd)
# Add route to force traffic through iptables
node1.execute(f"sudo ip route add {net2_subnet} via 127.0.0.1 dev lo")
# Test TCP connectivity (sshuttle only supports TCP, not ICMP)
stdout, stderr = node1.execute(f"nc -zv {node3_addr} 22")
print(stdout, stderr)
# Optimize network buffer sizes for high-throughput experiments
tune_commands = [
# Increase socket buffer sizes
"sudo sysctl -w net.core.rmem_max=67108864",
"sudo sysctl -w net.core.wmem_max=67108864",
"sudo sysctl -w net.core.rmem_default=67108864",
"sudo sysctl -w net.core.wmem_default=67108864",
# TCP buffer sizes (min, default, max)
"sudo sysctl -w net.ipv4.tcp_rmem='4096 87380 67108864'",
"sudo sysctl -w net.ipv4.tcp_wmem='4096 87380 67108864'",
# Enable TCP window scaling and timestamps
"sudo sysctl -w net.ipv4.tcp_window_scaling=1",
"sudo sysctl -w net.ipv4.tcp_timestamps=1",
# Increase backlog
"sudo sysctl -w net.core.netdev_max_backlog=250000",
# BBR congestion control
"sudo sysctl -w net.ipv4.tcp_congestion_control=bbr",
"sudo sysctl -w net.core.default_qdisc=fq",
# Enable MTU probing
"sudo sysctl -w net.ipv4.tcp_mtu_probing=1",
]
for cmd in tune_commands:
node.execute(cmd)
# Install Docker
node.execute("sudo apt-get update -qq && sudo apt-get install -y -qq docker.io")
node.execute("sudo systemctl enable docker && sudo systemctl start docker")
node.execute("sudo usermod -aG docker $(whoami)")
# Create a Docker bridge network
node.execute("sudo docker network create --subnet=172.20.0.0/16 fabric-docker-net")
# Install OVS
node.execute("sudo apt-get update -qq && sudo apt-get install -y -qq openvswitch-switch")
# Create a bridge
node.execute("sudo ovs-vsctl add-br br0")
# Add a FABRIC interface to the bridge
iface_name = node.get_interface(network_name="lan").get_os_interface()
node.execute(f"sudo ovs-vsctl add-port br0 {iface_name}")
# Configure the bridge IP
node.execute("sudo ip addr add 192.168.1.1/24 dev br0")
node.execute("sudo ip link set br0 up")
sudo sysctl -w net.ipv4.ip_forward=1persistent=True on ip_route_add and ip_addr_add for routes that survive rebootsiface.get_os_interface() to get the OS-level device name for low-level config