Turn networking.interfaces into an attribute set
Thus networking.interfaces = [ { name = "eth0"; ipAddress = "192.168.15.1"; } ]; can now be written as networking.interfaces.eth0.ipAddress = "192.168.15.1"; The old notation still works though.
This commit is contained in:
parent
93f82dfeef
commit
97f087cd44
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
let pkgs = import <nixpkgs> { config = {}; inherit system; }; in
|
let pkgs = import <nixpkgs> { config = {}; inherit system; }; in
|
||||||
|
|
||||||
with pkgs;
|
with pkgs.lib;
|
||||||
with import ../lib/qemu-flags.nix;
|
with import ../lib/qemu-flags.nix;
|
||||||
|
|
||||||
rec {
|
rec {
|
||||||
@ -15,7 +15,7 @@ rec {
|
|||||||
# hostname and `configX' is a NixOS system configuration. Each
|
# hostname and `configX' is a NixOS system configuration. Each
|
||||||
# machine is given an arbitrary IP address in the virtual network.
|
# machine is given an arbitrary IP address in the virtual network.
|
||||||
buildVirtualNetwork =
|
buildVirtualNetwork =
|
||||||
nodes: let nodesOut = lib.mapAttrs (n: buildVM nodesOut) (assignIPAddresses nodes); in nodesOut;
|
nodes: let nodesOut = mapAttrs (n: buildVM nodesOut) (assignIPAddresses nodes); in nodesOut;
|
||||||
|
|
||||||
|
|
||||||
buildVM =
|
buildVM =
|
||||||
@ -27,7 +27,7 @@ rec {
|
|||||||
[ ../modules/virtualisation/qemu-vm.nix
|
[ ../modules/virtualisation/qemu-vm.nix
|
||||||
../modules/testing/test-instrumentation.nix # !!! should only get added for automated test runs
|
../modules/testing/test-instrumentation.nix # !!! should only get added for automated test runs
|
||||||
{ key = "no-manual"; services.nixosManual.enable = false; }
|
{ key = "no-manual"; services.nixosManual.enable = false; }
|
||||||
] ++ lib.optional minimal ../modules/testing/minimal-kernel.nix;
|
] ++ optional minimal ../modules/testing/minimal-kernel.nix;
|
||||||
extraArgs = { inherit nodes; };
|
extraArgs = { inherit nodes; };
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -39,51 +39,49 @@ rec {
|
|||||||
|
|
||||||
let
|
let
|
||||||
|
|
||||||
machines = lib.attrNames nodes;
|
machines = attrNames nodes;
|
||||||
|
|
||||||
machinesNumbered = lib.zipTwoLists machines (lib.range 1 254);
|
machinesNumbered = zipTwoLists machines (range 1 254);
|
||||||
|
|
||||||
nodes_ = lib.flip map machinesNumbered (m: lib.nameValuePair m.first
|
nodes_ = flip map machinesNumbered (m: nameValuePair m.first
|
||||||
[ ( { config, pkgs, nodes, ... }:
|
[ ( { config, pkgs, nodes, ... }:
|
||||||
let
|
let
|
||||||
interfacesNumbered = lib.zipTwoLists config.virtualisation.vlans (lib.range 1 255);
|
interfacesNumbered = zipTwoLists config.virtualisation.vlans (range 1 255);
|
||||||
interfaces =
|
interfaces = flip map interfacesNumbered ({ first, second }:
|
||||||
lib.flip map interfacesNumbered ({ first, second }:
|
nameValuePair "eth${toString second}"
|
||||||
{ name = "eth${toString second}";
|
{ ipAddress = "192.168.${toString first}.${toString m.second}";
|
||||||
ipAddress = "192.168.${toString first}.${toString m.second}";
|
|
||||||
subnetMask = "255.255.255.0";
|
subnetMask = "255.255.255.0";
|
||||||
}
|
});
|
||||||
);
|
|
||||||
in
|
in
|
||||||
{ key = "ip-address";
|
{ key = "ip-address";
|
||||||
config =
|
config =
|
||||||
{ networking.hostName = m.first;
|
{ networking.hostName = m.first;
|
||||||
|
|
||||||
networking.interfaces = interfaces;
|
networking.interfaces = listToAttrs interfaces;
|
||||||
|
|
||||||
networking.primaryIPAddress =
|
networking.primaryIPAddress =
|
||||||
lib.optionalString (interfaces != []) (lib.head interfaces).ipAddress;
|
optionalString (interfaces != []) (head interfaces).value.ipAddress;
|
||||||
|
|
||||||
# Put the IP addresses of all VMs in this machine's
|
# Put the IP addresses of all VMs in this machine's
|
||||||
# /etc/hosts file. If a machine has multiple
|
# /etc/hosts file. If a machine has multiple
|
||||||
# interfaces, use the IP address corresponding to
|
# interfaces, use the IP address corresponding to
|
||||||
# the first interface (i.e. the first network in its
|
# the first interface (i.e. the first network in its
|
||||||
# virtualisation.vlans option).
|
# virtualisation.vlans option).
|
||||||
networking.extraHosts = lib.flip lib.concatMapStrings machines
|
networking.extraHosts = flip concatMapStrings machines
|
||||||
(m: let config = (lib.getAttr m nodes).config; in
|
(m: let config = (getAttr m nodes).config; in
|
||||||
lib.optionalString (config.networking.primaryIPAddress != "")
|
optionalString (config.networking.primaryIPAddress != "")
|
||||||
("${config.networking.primaryIPAddress} " +
|
("${config.networking.primaryIPAddress} " +
|
||||||
"${config.networking.hostName}\n"));
|
"${config.networking.hostName}\n"));
|
||||||
|
|
||||||
virtualisation.qemu.options =
|
virtualisation.qemu.options =
|
||||||
lib.flip map interfacesNumbered
|
flip map interfacesNumbered
|
||||||
({ first, second }: qemuNICFlags second first m.second);
|
({ first, second }: qemuNICFlags second first m.second);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
(lib.getAttr m.first nodes)
|
(getAttr m.first nodes)
|
||||||
] );
|
] );
|
||||||
|
|
||||||
in lib.listToAttrs nodes_;
|
in listToAttrs nodes_;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -37,5 +37,5 @@ let virtualbox = config.boot.kernelPackages.virtualbox; in
|
|||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
networking.interfaces = [ { name = "vboxnet0"; ipAddress = "192.168.56.1"; prefixLength = 24; } ];
|
networking.interfaces.vboxnet0 = { ipAddress = "192.168.56.1"; prefixLength = 24; };
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@ let
|
|||||||
# Don't start dhclient on explicitly configured interfaces or on
|
# Don't start dhclient on explicitly configured interfaces or on
|
||||||
# interfaces that are part of a bridge.
|
# interfaces that are part of a bridge.
|
||||||
ignoredInterfaces =
|
ignoredInterfaces =
|
||||||
map (i: i.name) (filter (i: i ? ipAddress && i.ipAddress != "" ) config.networking.interfaces)
|
map (i: i.name) (filter (i: i.ipAddress != null) (attrValues config.networking.interfaces))
|
||||||
++ concatLists (attrValues (mapAttrs (n: v: v.interfaces) config.networking.bridges))
|
++ concatLists (attrValues (mapAttrs (n: v: v.interfaces) config.networking.bridges))
|
||||||
++ config.networking.dhcpcd.denyInterfaces;
|
++ config.networking.dhcpcd.denyInterfaces;
|
||||||
|
|
||||||
@ -104,6 +104,7 @@ in
|
|||||||
ExecStart = "@${dhcpcd}/sbin/dhcpcd dhcpcd --config ${dhcpcdConf}";
|
ExecStart = "@${dhcpcd}/sbin/dhcpcd dhcpcd --config ${dhcpcdConf}";
|
||||||
ExecReload = "${dhcpcd}/sbin/dhcpcd --rebind";
|
ExecReload = "${dhcpcd}/sbin/dhcpcd --rebind";
|
||||||
StandardError = "null";
|
StandardError = "null";
|
||||||
|
Restart = "always";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -5,7 +5,104 @@ with pkgs.lib;
|
|||||||
let
|
let
|
||||||
|
|
||||||
cfg = config.networking;
|
cfg = config.networking;
|
||||||
hasVirtuals = any (i: i.virtual) cfg.interfaces;
|
interfaces = attrValues cfg.interfaces;
|
||||||
|
hasVirtuals = any (i: i.virtual) interfaces;
|
||||||
|
|
||||||
|
interfaceOpts = { name, ... }: {
|
||||||
|
|
||||||
|
options = {
|
||||||
|
|
||||||
|
name = mkOption {
|
||||||
|
example = "eth0";
|
||||||
|
type = types.string;
|
||||||
|
description = "Name of the interface.";
|
||||||
|
};
|
||||||
|
|
||||||
|
ipAddress = mkOption {
|
||||||
|
default = null;
|
||||||
|
example = "10.0.0.1";
|
||||||
|
type = types.nullOr types.string;
|
||||||
|
description = ''
|
||||||
|
IP address of the interface. Leave empty to configure the
|
||||||
|
interface using DHCP.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
prefixLength = mkOption {
|
||||||
|
default = null;
|
||||||
|
example = 24;
|
||||||
|
type = types.nullOr types.int;
|
||||||
|
description = ''
|
||||||
|
Subnet mask of the interface, specified as the number of
|
||||||
|
bits in the prefix (<literal>24</literal>).
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
subnetMask = mkOption {
|
||||||
|
default = "";
|
||||||
|
example = "255.255.255.0";
|
||||||
|
type = types.string;
|
||||||
|
description = ''
|
||||||
|
Subnet mask of the interface, specified as a bitmask.
|
||||||
|
This is deprecated; use <option>prefixLength</option>
|
||||||
|
instead.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
macAddress = mkOption {
|
||||||
|
default = null;
|
||||||
|
example = "00:11:22:33:44:55";
|
||||||
|
type = types.nullOr types.string;
|
||||||
|
description = ''
|
||||||
|
MAC address of the interface. Leave empty to use the default.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
virtual = mkOption {
|
||||||
|
default = false;
|
||||||
|
type = types.bool;
|
||||||
|
description = ''
|
||||||
|
Whether this interface is virtual and should be created by tunctl.
|
||||||
|
This is mainly useful for creating bridges between a host a virtual
|
||||||
|
network such as VPN or a virtual machine.
|
||||||
|
|
||||||
|
Defaults to tap device, unless interface contains "tun" in its name.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
virtualOwner = mkOption {
|
||||||
|
default = "root";
|
||||||
|
type = types.uniq types.string;
|
||||||
|
description = ''
|
||||||
|
In case of a virtual device, the user who owns it.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
proxyARP = mkOption {
|
||||||
|
default = false;
|
||||||
|
type = types.bool;
|
||||||
|
description = ''
|
||||||
|
Turn on proxy_arp for this device (and proxy_ndp for ipv6).
|
||||||
|
This is mainly useful for creating pseudo-bridges between a real
|
||||||
|
interface and a virtual network such as VPN or a virtual machine for
|
||||||
|
interfaces that don't support real bridging (most wlan interfaces).
|
||||||
|
As ARP proxying acts slightly above the link-layer, below-ip traffic
|
||||||
|
isn't bridged, so things like DHCP won't work. The advantage above
|
||||||
|
using NAT lies in the fact that no IP addresses are shared, so all
|
||||||
|
hosts are reachable/routeable.
|
||||||
|
|
||||||
|
WARNING: turns on ip-routing, so if you have multiple interfaces, you
|
||||||
|
should think of the consequence and setup firewall rules to limit this.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
config = {
|
||||||
|
name = mkDefault name;
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
in
|
in
|
||||||
|
|
||||||
@ -66,121 +163,20 @@ in
|
|||||||
};
|
};
|
||||||
|
|
||||||
networking.interfaces = mkOption {
|
networking.interfaces = mkOption {
|
||||||
default = [];
|
default = {};
|
||||||
example = [
|
example =
|
||||||
{ name = "eth0";
|
{ eth0 = {
|
||||||
ipAddress = "131.211.84.78";
|
ipAddress = "131.211.84.78";
|
||||||
subnetMask = "255.255.255.128";
|
subnetMask = "255.255.255.128";
|
||||||
}
|
};
|
||||||
];
|
};
|
||||||
description = ''
|
description = ''
|
||||||
The configuration for each network interface. If
|
The configuration for each network interface. If
|
||||||
<option>networking.useDHCP</option> is true, then every
|
<option>networking.useDHCP</option> is true, then every
|
||||||
interface not listed here will be configured using DHCP.
|
interface not listed here will be configured using DHCP.
|
||||||
'';
|
'';
|
||||||
|
type = types.loaOf types.optionSet;
|
||||||
type = types.list types.optionSet;
|
options = [ interfaceOpts ];
|
||||||
|
|
||||||
options = {
|
|
||||||
|
|
||||||
name = mkOption {
|
|
||||||
example = "eth0";
|
|
||||||
type = types.string;
|
|
||||||
description = ''
|
|
||||||
Name of the interface.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
ipAddress = mkOption {
|
|
||||||
default = "";
|
|
||||||
example = "10.0.0.1";
|
|
||||||
type = types.string;
|
|
||||||
description = ''
|
|
||||||
IP address of the interface. Leave empty to configure the
|
|
||||||
interface using DHCP.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
prefixLength = mkOption {
|
|
||||||
default = null;
|
|
||||||
example = 24;
|
|
||||||
type = types.nullOr types.int;
|
|
||||||
description = ''
|
|
||||||
Subnet mask of the interface, specified as the number of
|
|
||||||
bits in the prefix (<literal>24</literal>).
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
subnetMask = mkOption {
|
|
||||||
default = "";
|
|
||||||
example = "255.255.255.0";
|
|
||||||
type = types.string;
|
|
||||||
description = ''
|
|
||||||
Subnet mask of the interface, specified as a bitmask.
|
|
||||||
This is deprecated; use <option>prefixLength</option>
|
|
||||||
instead.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
macAddress = mkOption {
|
|
||||||
default = "";
|
|
||||||
example = "00:11:22:33:44:55";
|
|
||||||
type = types.string;
|
|
||||||
description = ''
|
|
||||||
MAC address of the interface. Leave empty to use the default.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
virtual = mkOption {
|
|
||||||
default = false;
|
|
||||||
type = types.bool;
|
|
||||||
description = ''
|
|
||||||
Whether this interface is virtual and should be created by tunctl.
|
|
||||||
This is mainly useful for creating bridges between a host a virtual
|
|
||||||
network such as VPN or a virtual machine.
|
|
||||||
|
|
||||||
Defaults to tap device, unless interface contains "tun" in its name.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
virtualOwner = mkOption {
|
|
||||||
default = "root";
|
|
||||||
type = types.uniq types.string;
|
|
||||||
description = ''
|
|
||||||
In case of a virtual device, the user who owns it.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
proxyARP = mkOption {
|
|
||||||
default = false;
|
|
||||||
type = types.bool;
|
|
||||||
description = ''
|
|
||||||
Turn on proxy_arp for this device (and proxy_ndp for ipv6).
|
|
||||||
This is mainly useful for creating pseudo-bridges between a real
|
|
||||||
interface and a virtual network such as VPN or a virtual machine for
|
|
||||||
interfaces that don't support real bridging (most wlan interfaces).
|
|
||||||
As ARP proxying acts slightly above the link-layer, below-ip traffic
|
|
||||||
isn't bridged, so things like DHCP won't work. The advantage above
|
|
||||||
using NAT lies in the fact that no IP addresses are shared, so all
|
|
||||||
hosts are reachable/routeable.
|
|
||||||
|
|
||||||
WARNING: turns on ip-routing, so if you have multiple interfaces, you
|
|
||||||
should think of the consequence and setup firewall rules to limit this.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
networking.ifaces = mkOption {
|
|
||||||
default = listToAttrs
|
|
||||||
(map (iface: { name = iface.name; value = iface; }) config.networking.interfaces);
|
|
||||||
internal = true;
|
|
||||||
description = ''
|
|
||||||
The network interfaces in <option>networking.interfaces</option>
|
|
||||||
as an attribute set keyed on the interface name.
|
|
||||||
'';
|
|
||||||
};
|
};
|
||||||
|
|
||||||
networking.bridges = mkOption {
|
networking.bridges = mkOption {
|
||||||
@ -288,7 +284,7 @@ in
|
|||||||
''}
|
''}
|
||||||
|
|
||||||
# Turn on forwarding if any interface has enabled proxy_arp.
|
# Turn on forwarding if any interface has enabled proxy_arp.
|
||||||
${optionalString (any (i: i.proxyARP) cfg.interfaces) ''
|
${optionalString (any (i: i.proxyARP) interfaces) ''
|
||||||
echo 1 > /proc/sys/net/ipv4/ip_forward
|
echo 1 > /proc/sys/net/ipv4/ip_forward
|
||||||
''}
|
''}
|
||||||
|
|
||||||
@ -322,12 +318,12 @@ in
|
|||||||
echo "bringing up interface..."
|
echo "bringing up interface..."
|
||||||
ip link set "${i.name}" up
|
ip link set "${i.name}" up
|
||||||
''
|
''
|
||||||
+ optionalString (i.macAddress != "")
|
+ optionalString (i.macAddress != null)
|
||||||
''
|
''
|
||||||
echo "setting MAC address to ${i.macAddress}..."
|
echo "setting MAC address to ${i.macAddress}..."
|
||||||
ip link set "${i.name}" address "${i.macAddress}"
|
ip link set "${i.name}" address "${i.macAddress}"
|
||||||
''
|
''
|
||||||
+ optionalString (i.ipAddress != "")
|
+ optionalString (i.ipAddress != null)
|
||||||
''
|
''
|
||||||
cur=$(ip -4 -o a show dev "${i.name}" | awk '{print $4}')
|
cur=$(ip -4 -o a show dev "${i.name}" | awk '{print $4}')
|
||||||
# Only do a flush/add if it's necessary. This is
|
# Only do a flush/add if it's necessary. This is
|
||||||
@ -400,8 +396,8 @@ in
|
|||||||
};
|
};
|
||||||
|
|
||||||
in listToAttrs (
|
in listToAttrs (
|
||||||
map configureInterface cfg.interfaces ++
|
map configureInterface interfaces ++
|
||||||
map createTunDevice (filter (i: i.virtual) cfg.interfaces))
|
map createTunDevice (filter (i: i.virtual) interfaces))
|
||||||
// mapAttrs createBridgeDevice cfg.bridges
|
// mapAttrs createBridgeDevice cfg.bridges
|
||||||
// { "network-setup" = networkSetup; };
|
// { "network-setup" = networkSetup; };
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@ with pkgs.lib;
|
|||||||
|
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
before = [ "sshd.service" ];
|
before = [ "sshd.service" ];
|
||||||
after = [ "dhcpcd.service" ];
|
after = [ "network.target" ];
|
||||||
|
|
||||||
path = [ pkgs.curl pkgs.iproute ];
|
path = [ pkgs.curl pkgs.iproute ];
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ let
|
|||||||
miniupnpdConf = nodes: pkgs.writeText "miniupnpd.conf"
|
miniupnpdConf = nodes: pkgs.writeText "miniupnpd.conf"
|
||||||
''
|
''
|
||||||
ext_ifname=eth1
|
ext_ifname=eth1
|
||||||
listening_ip=${nodes.router.config.networking.ifaces.eth2.ipAddress}/24
|
listening_ip=${nodes.router.config.networking.interfaces.eth2.ipAddress}/24
|
||||||
allow 1024-65535 192.168.2.0/24 1024-65535
|
allow 1024-65535 192.168.2.0/24 1024-65535
|
||||||
'';
|
'';
|
||||||
|
|
||||||
@ -49,7 +49,7 @@ in
|
|||||||
{ environment.systemPackages = [ pkgs.transmission ];
|
{ environment.systemPackages = [ pkgs.transmission ];
|
||||||
virtualisation.vlans = [ 2 ];
|
virtualisation.vlans = [ 2 ];
|
||||||
networking.defaultGateway =
|
networking.defaultGateway =
|
||||||
nodes.router.config.networking.ifaces.eth2.ipAddress;
|
nodes.router.config.networking.interfaces.eth2.ipAddress;
|
||||||
};
|
};
|
||||||
|
|
||||||
client2 =
|
client2 =
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
{ config, pkgs, nodes, ... }:
|
{ config, pkgs, nodes, ... }:
|
||||||
{ virtualisation.vlans = [ 1 ];
|
{ virtualisation.vlans = [ 1 ];
|
||||||
networking.defaultGateway =
|
networking.defaultGateway =
|
||||||
nodes.router.config.networking.ifaces.eth2.ipAddress;
|
nodes.router.config.networking.interfaces.eth2.ipAddress;
|
||||||
};
|
};
|
||||||
|
|
||||||
router =
|
router =
|
||||||
|
Loading…
x
Reference in New Issue
Block a user