nixos/network-interfaces: Support mac address and mtu universally

wip/yesman
William A. Kennington III 10 years ago
parent 2057d9087f
commit c7d46687c5
  1. 54
      nixos/modules/tasks/network-interfaces-scripted.nix
  2. 9
      nixos/modules/tasks/network-interfaces-systemd.nix
  3. 53
      nixos/modules/tasks/network-interfaces.nix

@ -80,65 +80,44 @@ in
''; '';
}; };
# For each interface <foo>, create a job ‘<foo>-cfg.service" # For each interface <foo>, create a job ‘network-addresses-<foo>.service"
# that performs static configuration. It has a "wants" # that performs static address configuration. It has a "wants"
# dependency on ‘<foo>.service’, which is supposed to create # dependency on ‘<foo>.service’, which is supposed to create
# the interface and need not exist (i.e. for hardware # the interface and need not exist (i.e. for hardware
# interfaces). It has a binds-to dependency on the actual # interfaces). It has a binds-to dependency on the actual
# network device, so it only gets started after the interface # network device, so it only gets started after the interface
# has appeared, and it's stopped when the interface # has appeared, and it's stopped when the interface
# disappears. # disappears.
configureInterface = i: configureAddrs = i:
let let
ips = interfaceIps i; ips = interfaceIps i;
in in
nameValuePair "${i.name}-cfg" nameValuePair "network-addresses-${i.name}"
{ description = "Configuration of ${i.name}"; { description = "Addresss configuration of ${i.name}";
wantedBy = [ "network-interfaces.target" ]; wantedBy = [ "network-interfaces.target" ];
before = [ "network-interfaces.target" ];
bindsTo = [ (subsystemDevice i.name) ]; bindsTo = [ (subsystemDevice i.name) ];
after = [ (subsystemDevice i.name) ]; after = [ (subsystemDevice i.name) ];
serviceConfig.Type = "oneshot"; serviceConfig.Type = "oneshot";
serviceConfig.RemainAfterExit = true; serviceConfig.RemainAfterExit = true;
path = [ pkgs.iproute pkgs.gawk ];
script = script =
'' ''
echo "bringing up interface..." echo "bringing up interface..."
ip link set "${i.name}" up ip link set "${i.name}" up
''
+ optionalString (i.macAddress != null)
''
echo "setting MAC address to ${i.macAddress}..."
ip link set "${i.name}" address "${i.macAddress}"
''
+ optionalString (i.mtu != null)
''
echo "setting MTU to ${toString i.mtu}..."
ip link set "${i.name}" mtu "${toString i.mtu}"
''
# Ip Setup restart_network_interfaces=false
+ '' + flip concatMapStrings (ips) (ip:
''
curIps=$(ip -o a show dev "${i.name}" | awk '{print $4}')
# Only do an add if it's necessary. This is
# useful when the Nix store is accessed via this
# interface (e.g. in a QEMU VM test).
restart_network_interfaces=false
''
+ flip concatMapStrings (ips) (ip:
let let
address = "${ip.address}/${toString ip.prefixLength}"; address = "${ip.address}/${toString ip.prefixLength}";
in in
'' ''
echo "checking ip ${address}..." echo "checking ip ${address}..."
if ! echo "$curIps" | grep "${address}" >/dev/null 2>&1; then if out=$(ip addr add "${address}" dev "${i.name}" 2>&1); then
if out=$(ip addr add "${address}" dev "${i.name}" 2>&1); then echo "added ip ${address}..."
echo "added ip ${address}..." restart_network_setup=true
restart_network_setup=true elif ! echo "$out" | grep "File exists" >/dev/null 2>&1; then
elif ! echo "$out" | grep "File exists" >/dev/null 2>&1; then echo "failed to add ${address}"
echo "failed to add ${address}" exit 1
exit 1
fi
fi fi
'') '')
+ optionalString (ips != [ ]) + optionalString (ips != [ ])
@ -154,8 +133,7 @@ in
preStop = preStop =
'' ''
echo "releasing configured ip's..." echo "releasing configured ip's..."
'' '' + flip concatMapStrings (ips) (ip:
+ flip concatMapStrings (ips) (ip:
let let
address = "${ip.address}/${toString ip.prefixLength}"; address = "${ip.address}/${toString ip.prefixLength}";
in in
@ -321,7 +299,7 @@ in
}); });
in listToAttrs ( in listToAttrs (
map configureInterface interfaces ++ map configureAddrs interfaces ++
map createTunDevice (filter (i: i.virtual) interfaces)) map createTunDevice (filter (i: i.virtual) interfaces))
// mapAttrs' createBridgeDevice cfg.bridges // mapAttrs' createBridgeDevice cfg.bridges
// mapAttrs' createBondDevice cfg.bonds // mapAttrs' createBondDevice cfg.bonds

@ -59,15 +59,6 @@ in
networks."99-main" = genericNetwork mkDefault; networks."99-main" = genericNetwork mkDefault;
} }
(mkMerge (flip map interfaces (i: { (mkMerge (flip map interfaces (i: {
links."40-${i.name}" = {
matchConfig.Name = i.name;
linkConfig =
(optionalAttrs (i.macAddress != null) {
MACAddress = i.macAddress;
}) // (optionalAttrs (i.mtu != null) {
MTUBytes = toString i.mtu;
});
};
netdevs = mkIf i.virtual ( netdevs = mkIf i.virtual (
let let
devType = if i.virtualType != null then i.virtualType devType = if i.virtualType != null then i.virtualType

@ -11,6 +11,10 @@ let
hasSits = cfg.sits != { }; hasSits = cfg.sits != { };
hasBonds = cfg.bonds != { }; hasBonds = cfg.bonds != { };
# We must escape interfaces due to the systemd interpretation
subsystemDevice = interface:
"sys-subsystem-net-devices-${escapeSystemdPath interface}.device";
addrOpts = v: addrOpts = v:
assert v == 4 || v == 6; assert v == 4 || v == 6;
{ {
@ -623,19 +627,42 @@ in
++ optional hasVirtuals pkgs.tunctl ++ optional hasVirtuals pkgs.tunctl
++ optional cfg.enableIPv6 pkgs.ndisc6; ++ optional cfg.enableIPv6 pkgs.ndisc6;
systemd.services.network-local-commands = { systemd.services = {
description = "Extra networking commands."; network-local-commands = {
before = [ "network.target" "network-online.target" ]; description = "Extra networking commands.";
wantedBy = [ "network.target" "network-online.target" ]; before = [ "network.target" "network-online.target" ];
unitConfig.ConditionCapability = "CAP_NET_ADMIN"; wantedBy = [ "network.target" "network-online.target" ];
path = [ pkgs.iproute ]; unitConfig.ConditionCapability = "CAP_NET_ADMIN";
serviceConfig.Type = "oneshot"; path = [ pkgs.iproute ];
serviceConfig.RemainAfterExit = true; serviceConfig.Type = "oneshot";
script = '' serviceConfig.RemainAfterExit = true;
# Run any user-specified commands. script = ''
${cfg.localCommands} # Run any user-specified commands.
''; ${cfg.localCommands}
}; '';
};
} // (listToAttrs (flip map interfaces (i:
nameValuePair "network-link-${i.name}"
{ description = "Link configuration of ${i.name}";
wantedBy = [ "network-interfaces.target" ];
before = [ "network-interfaces.target" ];
bindsTo = [ (subsystemDevice i.name) ];
after = [ (subsystemDevice i.name) ];
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
};
script =
''
echo "Configuring link..."
'' + optionalString (i.macAddress != null) ''
echo "setting MAC address to ${i.macAddress}..."
ip link set "${i.name}" address "${i.macAddress}"
'' + optionalString (i.mtu != null) ''
echo "setting MTU to ${toString i.mtu}..."
ip link set "${i.name}" mtu "${toString i.mtu}"
'';
})));
}; };
} }

Loading…
Cancel
Save