A NixOS module for configuring networks using systemd-networkd. Supports bonds, bridges, VLANs, and other complex networking setups.
- Interface renaming
- Interface bonding (active-backup, LACP, etc.)
- Bridge configuration for VMs and containers
- VLAN tagging
- Custom routing and multiple interfaces
- Validates your config so you don't lock yourself out
├── default.nix # Main entry point
├── options/ # Option definitions
│ ├── default.nix # Main options definition
│ ├── common.nix # Shared utilities & option generators
│ ├── interface.nix # Interface-specific options
│ ├── bond.nix # Bond-specific options
│ ├── bridge.nix # Bridge-specific options
│ └── vlan.nix # VLAN-specific options
└── config/ # Configuration implementations
├── default.nix # Config index
├── implementation.nix # Main configuration logic
├── processing.nix # Data processing & collection
├── validation.nix # Validation logic
└── generation.nix # systemd-networkd generators
nix-networkd provides a unified configuration system where all network types (interfaces, bonds, bridges, VLANs) can be configured with IP addresses using the same options. This section explains both the common IP configuration options and the type-specific options for each network type.
These options work on all network types: interfaces, bonds, bridges, and VLANs.
# Example: This same structure works for any network type
host.network.interfaces.eth0 = {
# ... type-specific options ...
ipv4 = {
type = "static";
addresses = [ "192.168.1.10/24" ];
gateway = "192.168.1.1";
};
ipv6 = {
enable = true;
type = "static";
addresses = [ "2001:db8::10/64" ];
gateway = "2001:db8::1";
};
};ipv4.enable- Enable IPv4 (default:true)ipv4.type- Configuration method:"static"- Manual IP configuration"dynamic"- DHCP
ipv4.addresses- List of IP addresses with prefix length- Example:
[ "192.168.1.10/24" "10.0.0.5/8" ]
- Example:
ipv4.gateway- Default gateway addressipv4.gatewayOnLink- Gateway is directly reachable (default:true)ipv4.routes- Additional static routes (list of{ routeConfig = {...}; })ipv4.priority- Route metric/priority (lower = higher priority)
ipv6.enable- Enable IPv6 (default:false)ipv6.type- Configuration method:"static"- Manual IP configuration"dynamic"- DHCPv6"slaac"- StateLess Address AutoConfiguration (default)
ipv6.addresses- List of IP addresses with prefix length- Example:
[ "2001:db8::10/64" ]
- Example:
ipv6.gateway- Default gateway addressipv6.gatewayOnLink- Gateway is directly reachable (default:true)ipv6.routes- Additional static routes (list of{ routeConfig = {...}; })ipv6.priority- Route metric/priority (lower = higher priority)ipv6.acceptRA- Accept Router Advertisements for SLAAC (default:true)
These options are available on all network interface types (interfaces, bonds, bridges, VLANs):
Custom routing tables can be defined at the module level for use with advanced routing scenarios:
host.network.routeTables = {
"vrack-pool" = 200;
"dmz-table" = 201;
"backup-routes" = 202;
};routeTables- Attribute set where keys are table names and values are table IDs (1-4294967295)- Tables are automatically registered in
/etc/iproute2/rt_tables - Can be referenced by name in route and routing policy rule configurations
- Essential for policy-based routing, multi-homing, and traffic isolation
routes- List of additional routes for this interface. Each route can have the following options:Destination- The destination prefix of the route (e.g.,"10.0.0.0/24")Gateway- The gateway address for the route (e.g.,"192.168.1.1")Table- The table identifier for the route (e.g.,"main","local", or custom table name fromrouteTables)OnLink- Whether the gateway is on-link/directly reachable (boolean)Metric- The metric/priority of the route (integer)Scope- The scope of the route ("global","link","host")PreferredSource- The preferred source address of the routeProtocol- The protocol identifier for the route (e.g.,"static")Type- The type of route (e.g.,"unicast","blackhole")
routingPolicyRules- List of routing policy rules for this interface. Each rule can have the following options:From- Source address prefix to match (e.g.,"192.168.1.0/24")To- Destination address prefix to match (e.g.,"10.0.0.0/8")Table- Routing table identifier to look up (e.g.,"main", or custom table name fromrouteTables)Priority- Priority of this rule (lower number = higher priority, e.g.,1000)FirewallMark- Firewall mark value to match (e.g.,"0x123")IncomingInterface- Incoming interface to matchOutgoingInterface- Outgoing interface to matchSourcePort- Source IP port or port range to matchDestinationPort- Destination IP port or port range to matchIPProtocol- IP protocol to match (e.g.,"tcp","udp")InvertRule- Whether to invert the rule (boolean)Family- Address family for the rule ("ipv4","ipv6")User- User ID or range to matchSuppressPrefixLength- Suppress routing decisions with prefix length N or lessSuppressInterfaceGroup- Suppress routing decisions with the same interface group
Each network type has its own specific configuration options in addition to the common IP configuration above.
Required:
mac- MAC address to match for this interface
Optional:
routes- List of additional routes for this interfaceroutingPolicyRules- List of routing policy rules for this interface
Example:
host.network.interfaces.eth0 = {
mac = "00:11:22:33:44:55";
routes = [
{
Destination = "0.0.0.0/0";
Gateway = "192.168.1.1";
Table = "local";
OnLink = true;
}
];
routingPolicyRules = [
{
From = "192.168.1.0/24";
Table = "local";
Priority = 1000;
}
];
ipv4 = {
type = "static";
addresses = [ "192.168.1.10/24" ];
gateway = "192.168.1.1";
};
};Note: Interfaces are automatically renamed from udev names (like ens3, enp0s3) to your specified names (like eth0, eth1). This provides predictable interface naming regardless of hardware detection order.
Required:
interfaces- List of interface names to bond
Optional:
mode- Bonding mode (default:"active-backup")"active-backup"- One active, others standby"802.3ad"- LACP aggregation"balance-rr","balance-xor","balance-tlb","balance-alb"- Load balancing modes"broadcast"- Broadcast on all interfaces
primaryInterface- Primary interface name for active-backup modemac- Optional MAC address for the bondmiimonFreq- Link monitoring frequency in ms (default: 100)lacpRate- LACP rate for 802.3ad:"slow"(30s) or"fast"(1s)xmitHashPolicy- Load balancing hash policy:"layer2","layer2+3","layer3+4", etc.
Example:
host.network.bonds.bond0 = {
interfaces = [ "eth0" "eth1" ];
mode = "active-backup";
primaryInterface = "eth0";
ipv4 = {
type = "static";
addresses = [ "192.168.1.10/24" ];
gateway = "192.168.1.1";
};
};Required:
interfaces- List of interface names to bridge (can include physical interfaces, bonds)
Optional:
mac- Optional MAC address for the bridge
Example:
host.network.bridges.br0 = {
interfaces = [ "eth0" "bond0" ];
ipv4 = {
type = "static";
addresses = [ "192.168.1.10/24" ];
gateway = "192.168.1.1";
};
};Required:
id- VLAN ID (1-4094)interface- Parent interface name (physical interface, bond, or bridge)
Example:
host.network.vlans.vlan100 = {
id = 100;
interface = "eth0";
ipv4 = {
type = "static";
addresses = [ "192.168.100.10/24" ];
gateway = "192.168.100.1";
};
};MIT License - see LICENSE file for details.