Network Package Reference¶
pkg/network/— NetworkManager, CNI, VXLAN, IPAM, and Discovery.
Overview¶
The pkg/network package manages networking for Firecracker VMs, including bridge creation, TAP device setup, VXLAN overlay networks, and IP allocation.
Package Structure:
pkg/network/
├── manager.go # NetworkManager (orchestration)
├── vxlan.go # VXLAN overlay (cross-node)
├── cni.go # CNI plugin integration
├── cni_client.go # CNI client wrapper
├── netlink.go # Netlink operations
├── discovery.go # Consul peer discovery
├── tap_executor.go # TAP device creation
└── testhelpers/ # Test utilities
NetworkManager¶
File: manager.go
The NetworkManager orchestrates all network operations for VMs.
Type Definition¶
type NetworkManager struct {
config types.NetworkConfig
bridges map[string]bool
mu sync.RWMutex
tapDevices map[string]*TapDevice
ipAllocator *IPAllocator
natSetup bool
vxlanMgr *VXLANManager
peerDiscovery bool
peerCancel context.CancelFunc
nodeDiscovery types.NodeDiscovery
cniClient *CNIClient
pendingPeers []string
}
Configuration¶
type NetworkConfig struct {
BridgeName string // e.g., "swarm-br0"
Subnet string // e.g., "192.168.127.0/24"
BridgeIP string // e.g., "192.168.127.1/24"
IPMode string // "static" or "dhcp"
NATEnabled bool // Enable masquerading
VXLANEnabled bool // Enable cross-node overlay
VXLANPeers []string // Initial peer IPs
EnableRateLimit bool // Packet rate limiting
MaxPacketsPerSec int // Rate limit threshold
}
Constructor¶
func NewNetworkManager(config types.NetworkConfig) *NetworkManager
Example:
config := types.NetworkConfig{
BridgeName: "swarm-br0",
Subnet: "192.168.127.0/24",
BridgeIP: "192.168.127.1/24",
IPMode: "static",
NATEnabled: true,
VXLANEnabled: true,
}
nm := network.NewNetworkManager(config)
Methods¶
Init¶
func (nm *NetworkManager) Init(ctx context.Context) error
Purpose: Initialize network infrastructure.
Steps: 1. Create Linux bridge (swarm-br0) 2. Assign bridge IP address 3. Enable IP forwarding 4. Setup NAT/masquerading (if enabled) 5. Create VXLAN device (if enabled)
Example:
if err := nm.Init(ctx); err != nil {
log.Fatal(err)
}
CreateTapDevice¶
func (nm *NetworkManager) CreateTapDevice(ctx context.Context, taskID string) (*TapDevice, error)
Purpose: Create TAP device for VM and connect to bridge.
Parameters: - ctx — Context for cancellation - taskID — Unique task identifier
Returns: - TapDevice — TAP device info with allocated IP
Example:
tap, err := nm.CreateTapDevice(ctx, "task-abc123")
if err != nil {
return err
}
fmt.Printf("TAP: %s, IP: %s\n", tap.Name, tap.IP)
// Output: TAP: tap-abc123, IP: 192.168.127.42
RemoveTapDevice¶
func (nm *NetworkManager) RemoveTapDevice(ctx context.Context, taskID string) error
Purpose: Remove TAP device and release IP.
AllocateIP¶
func (nm *NetworkManager) AllocateIP(taskID string) (string, error)
Purpose: Allocate IP address for task.
Algorithm: 1. SHA-256 hash of task ID 2. Convert hash to IP offset in subnet 3. Linear probing for collision resolution 4. Skip gateway, network, and broadcast addresses
ReleaseIP¶
func (nm *NetworkManager) ReleaseIP(ip string) error
Purpose: Release IP back to pool.
UpdateVXLANPeers¶
func (nm *NetworkManager) UpdateVXLANPeers(peers []string) error
Purpose: Update VXLAN forwarding database with new peers.
Implementation:
# For each peer IP:
bridge fdb append dev vxlan100 dst <peer-ip> vni 100 port 4789
SetNodeDiscovery¶
func (nm *NetworkManager) SetNodeDiscovery(discovery types.NodeDiscovery)
Purpose: Set discovery provider (Consul) for dynamic peer updates.
IPAllocator¶
File: manager.go
Type Definition¶
type IPAllocator struct {
subnet *net.IPNet
gateway net.IP
allocated map[string]string // IP → VM ID mapping
mu sync.Mutex
}
Constructor¶
func NewIPAllocator(subnetStr, gatewayStr string) (*IPAllocator, error)
Methods¶
Allocate¶
func (a *IPAllocator) Allocate(vmID string) (string, error)
Purpose: Allocate deterministic IP for VM.
Algorithm:
func (a *IPAllocator) hashToIP(vmID string) net.IP {
h := sha256.New()
h.Write([]byte(vmID))
hash := h.Sum(nil)
// IPv4: use first 4 bytes of hash
n := binary.BigEndian.Uint32(hash[:4]) % (size - 2)
ipInt := subnetBase + n + 1
return net.IP(ipInt)
}
Collision Resolution:
// Linear probing - try next IP if collision
for i := 0; i < 256; i++ {
if !isGateway && !isAllocated {
allocated[ipStr] = vmID
return ipStr, nil
}
ip = incIP(ip)
}
VXLANManager¶
File: vxlan.go
The VXLANManager handles VXLAN overlay network setup and peer management.
Type Definition¶
type VXLANManager struct {
vxlanDevice string // e.g., "vxlan100"
vni int // VXLAN Network Identifier (100)
bridge string // Bridge to attach (swarm-br0)
port int // UDP port (4789)
localIP string // Local underlay IP
peers []string // Remote peer IPs
mu sync.RWMutex
}
Constructor¶
func NewVXLANManager(config VXLANConfig) (*VXLANManager, error)
Methods¶
Create¶
func (vx *VXLANManager) Create(ctx context.Context) error
Purpose: Create VXLAN device and attach to bridge.
Implementation:
# Create VXLAN device
ip link add vxlan100 type vxlan id 100 dstport 4789 local <local-ip>
# Attach to bridge
ip link set vxlan100 master swarm-br0
# Bring up
ip link set vxlan100 up
AddPeer¶
func (vx *VXLANManager) AddPeer(peerIP string) error
Purpose: Add remote peer to forwarding database.
Implementation:
bridge fdb append dev vxlan100 dst <peer-ip> vni 100 port 4789
Note: Uses fdb append to allow multiple peers per VNI.
RemovePeer¶
func (vx *VXLANManager) RemovePeer(peerIP string) error
Purpose: Remove peer from forwarding database.
UpdatePeers¶
func (vx *VXLANManager) UpdatePeers(peers []string) error
Purpose: Batch update all peers.
CNIClient¶
File: cni.go, cni_client.go
CNI integration for SwarmKit network attachments.
Type Definition¶
type CNIClient struct {
pluginDir string
configDir string
cacheDir string
}
type CNIConfig struct {
Name string
Type string
Bridge string
IPAM IPAMConfig
IsDefaultGateway bool
}
Constructor¶
func NewCNIClient(pluginDir, configDir string) *CNIClient
Methods¶
Add¶
func (c *CNIClient) Add(ctx context.Context, netName, ifaceName, containerID string, config *CNIConfig) (*CNIResult, error)
Purpose: Add network interface for container.
Returns:
type CNIResult struct {
Interfaces []CNIIface
IPs []CNIIP
Routes []CNIRoute
}
Del¶
func (c *CNIClient) Del(ctx context.Context, netName, ifaceName, containerID string) error
Purpose: Remove network interface.
Discovery¶
File: discovery.go
Consul-based peer discovery for VXLAN.
Functions¶
func getLocalIPFromInterface() string
Purpose: Auto-detect local IP for Consul registration.
Algorithm: 1. Get all network interfaces 2. Filter up, non-loopback interfaces 3. Prefer interfaces with gateway route 4. Return first valid IP
Netlink Operations¶
File: netlink.go
Low-level network operations using netlink.
Functions¶
CreateBridge¶
func CreateBridge(name string) error
Implementation:
ip link add <name> type bridge
ip link set <name> up
SetBridgeIP¶
func SetBridgeIP(name, ipCIDR string) error
Implementation:
ip addr add <ipCIDR> dev <name>
CreateTap¶
func CreateTap(name string) error
Implementation:
ip tuntap add dev <name> mode tap
ip link set <name> up
ConnectTapToBridge¶
func ConnectTapToBridge(tapName, bridgeName string) error
Implementation:
ip link set <tapName> master <bridgeName>
TAP Device¶
File: tap_executor.go
Type Definition¶
type TapDevice struct {
Name string // e.g., "tap-abc123"
Bridge string // e.g., "swarm-br0"
IP string // e.g., "192.168.127.42"
Netmask string // e.g., "255.255.255.0"
Gateway string // e.g., "192.168.127.1"
Subnet string // e.g., "192.168.127.0/24"
}
NAT/Masquerading¶
Enabled by default for VM internet access.
Implementation:
# Enable IP forwarding
sysctl -w net.ipv4.ip_forward=1
# Setup masquerading
iptables -t nat -A POSTROUTING -s 192.168.127.0/24 ! -o swarm-br0 -j MASQUERADE
Configuration:
network:
nat_enabled: true
Rate Limiting¶
Optional packet rate limiting on TAP devices.
Configuration:
network:
enable_rate_limit: true
max_packets_per_sec: 10000
Implementation:
# Using tc (traffic control)
tc qdisc add dev <tap> root handle 1: htb
tc class add dev <tap> parent 1: classid 1:1 htb rate <rate>
tc filter add dev <tap> parent 1: protocol ip prio 1 u32 match u32 0 0 flowid 1:1
Testing¶
Mock NetworkManager¶
type MockNetworkManager struct {
TapDevices map[string]*TapDevice
IPs map[string]string
}
func (m *MockNetworkManager) CreateTapDevice(ctx context.Context, taskID string) (*TapDevice, error) {
tap := &TapDevice{
Name: "tap-" + taskID,
IP: "192.168.127.42",
Gateway: "192.168.127.1",
}
m.TapDevices[taskID] = tap
return tap, nil
}
Error Handling¶
Common Errors¶
| Error | Cause | Resolution |
|---|---|---|
"invalid subnet" | Bad CIDR notation | Use valid format (e.g., 192.168.127.0/24) |
"bridge creation failed" | Permission denied | Run with root/capabilities |
"failed to allocate IP" | Subnet exhausted | Increase subnet size or cleanup VMs |
"vxlan device creation failed" | VXLAN module missing | Load vxlan kernel module |
Related Documentation¶
| Topic | Document |
|---|---|
| SwarmKit executor | SwarmKit Reference |
| User networking guide | Networking Guide |
| Architecture | Architecture Overview |