Skip to content

Commit

Permalink
Merge pull request #85170 from flokli/networking-virtual
Browse files Browse the repository at this point in the history
nixos/networking: fix setting MAC Address and MTU in networkd, fix tests
  • Loading branch information
rnhmjoj authored Apr 14, 2020
2 parents 10f4dfc + d1edd8b commit 86d71dd
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 52 deletions.
33 changes: 33 additions & 0 deletions nixos/modules/tasks/network-interfaces-scripted.nix
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,38 @@ let
'';
};

createNetworkLink = i:
let
deviceDependency = if (config.boot.isContainer || i.name == "lo")
then []
else [ (subsystemDevice i.name) ];
in
nameValuePair "network-link-${i.name}"
{ description = "Link configuration of ${i.name}";
wantedBy = [ "network-interfaces.target" ];
before = [ "network-interfaces.target" ];
bindsTo = deviceDependency;
after = [ "network-pre.target" ] ++ deviceDependency;
path = [ pkgs.iproute ];
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}"
'' + ''
echo -n "bringing up interface... "
ip link set "${i.name}" up && echo "done" || (echo "failed"; exit 1)
'';
};

createTunDevice = i: nameValuePair "${i.name}-netdev"
{ description = "Virtual Network Interface ${i.name}";
bindsTo = [ "dev-net-tun.device" ];
Expand Down Expand Up @@ -508,6 +540,7 @@ let
});

in listToAttrs (
map createNetworkLink interfaces ++
map configureAddrs interfaces ++
map createTunDevice (filter (i: i.virtual) interfaces))
// mapAttrs' createBridgeDevice cfg.bridges
Expand Down
7 changes: 6 additions & 1 deletion nixos/modules/tasks/network-interfaces-systemd.nix
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,12 @@ in
address = forEach (interfaceIps i)
(ip: "${ip.address}/${toString ip.prefixLength}");
networkConfig.IPv6PrivacyExtensions = "kernel";
} ];
linkConfig = optionalAttrs (i.macAddress != null) {
MACAddress = i.macAddress;
} // optionalAttrs (i.mtu != null) {
MTUBytes = toString i.mtu;
};
}];
})))
(mkMerge (flip mapAttrsToList cfg.bridges (name: bridge: {
netdevs."40-${name}" = {
Expand Down
38 changes: 6 additions & 32 deletions nixos/modules/tasks/network-interfaces.nix
Original file line number Diff line number Diff line change
Expand Up @@ -1031,6 +1031,11 @@ in
message = ''
Temporary addresses are only needed when IPv6 is enabled.
'';
})) ++ (forEach interfaces (i: {
assertion = (i.virtual && i.virtualType == "tun") -> i.macAddress == null;
message = ''
Setting a MAC Address for tun device ${i.name} isn't supported.
'';
})) ++ [
{
assertion = cfg.hostId == null || (stringLength cfg.hostId == 8 && isHexString cfg.hostId);
Expand Down Expand Up @@ -1140,38 +1145,7 @@ in
${cfg.localCommands}
'';
};
} // (listToAttrs (forEach interfaces (i:
let
deviceDependency = if (config.boot.isContainer || i.name == "lo")
then []
else [ (subsystemDevice i.name) ];
in
nameValuePair "network-link-${i.name}"
{ description = "Link configuration of ${i.name}";
wantedBy = [ "network-interfaces.target" ];
before = [ "network-interfaces.target" ];
bindsTo = deviceDependency;
after = [ "network-pre.target" ] ++ deviceDependency;
path = [ pkgs.iproute ];
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}"
'' + ''
echo -n "bringing up interface... "
ip link set "${i.name}" up && echo "done" || (echo "failed"; exit 1)
'';
})));

};
services.mstpd = mkIf needsMstpd { enable = true; };

virtualisation.vswitch = mkIf (cfg.vswitches != { }) { enable = true; };
Expand Down
50 changes: 31 additions & 19 deletions nixos/tests/networking.nix
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,7 @@ let
useDHCP = false;
interfaces.eth1 = {
ipv4.addresses = mkOverride 0 [ ];
mtu = 1343;
useDHCP = true;
};
interfaces.eth2.ipv4.addresses = mkOverride 0 [ ];
Expand All @@ -216,6 +217,9 @@ let
with subtest("Wait until we have an ip address on each interface"):
client.wait_until_succeeds("ip addr show dev eth1 | grep -q '192.168.1'")
with subtest("ensure MTU is set"):
assert "mtu 1343" in client.succeed("ip link show dev eth1")
with subtest("Test vlan 1"):
client.wait_until_succeeds("ping -c 1 192.168.1.1")
client.wait_until_succeeds("ping -c 1 192.168.1.2")
Expand Down Expand Up @@ -455,11 +459,14 @@ let
ipv4.addresses = [ { address = "192.168.1.1"; prefixLength = 24; } ];
ipv6.addresses = [ { address = "2001:1470:fffd:2096::"; prefixLength = 64; } ];
virtual = true;
mtu = 1342;
macAddress = "02:de:ad:be:ef:01";
};
networking.interfaces.tun0 = {
ipv4.addresses = [ { address = "192.168.1.2"; prefixLength = 24; } ];
ipv6.addresses = [ { address = "2001:1470:fffd:2097::"; prefixLength = 64; } ];
virtual = true;
mtu = 1343;
};
};

Expand All @@ -471,7 +478,7 @@ let
with subtest("Wait for networking to come up"):
machine.start()
machine.wait_for_unit("network-online.target")
machine.wait_for_unit("network.target")
with subtest("Test interfaces set up"):
list = machine.succeed("ip tuntap list | sort").strip()
Expand All @@ -486,7 +493,12 @@ let
""".format(
list, targetList
)
with subtest("Test MTU and MAC Address are configured"):
assert "mtu 1342" in machine.succeed("ip link show dev tap0")
assert "mtu 1343" in machine.succeed("ip link show dev tun0")
assert "02:de:ad:be:ef:01" in machine.succeed("ip link show dev tap0")
'' # network-addresses-* only exist in scripted networking
+ optionalString (!networkd) ''
with subtest("Test interfaces clean up"):
machine.succeed("systemctl stop network-addresses-tap0")
machine.sleep(10)
Expand Down Expand Up @@ -602,27 +614,27 @@ let
};

testScript = ''
targetIPv4Table = """
10.0.0.0/16 proto static scope link mtu 1500
192.168.1.0/24 proto kernel scope link src 192.168.1.2
192.168.2.0/24 via 192.168.1.1 proto static
""".strip()
targetIPv6Table = """
2001:1470:fffd:2097::/64 proto kernel metric 256 pref medium
2001:1470:fffd:2098::/64 via fdfd:b3f0::1 proto static metric 1024 pref medium
fdfd:b3f0::/48 proto static metric 1024 pref medium
""".strip()
targetIPv4Table = [
"10.0.0.0/16 proto static scope link mtu 1500",
"192.168.1.0/24 proto kernel scope link src 192.168.1.2",
"192.168.2.0/24 via 192.168.1.1 proto static",
]
targetIPv6Table = [
"2001:1470:fffd:2097::/64 proto kernel metric 256 pref medium",
"2001:1470:fffd:2098::/64 via fdfd:b3f0::1 proto static metric 1024 pref medium",
"fdfd:b3f0::/48 proto static metric 1024 pref medium",
]
machine.start()
machine.wait_for_unit("network.target")
with subtest("test routing tables"):
ipv4Table = machine.succeed("ip -4 route list dev eth0 | head -n3").strip()
ipv6Table = machine.succeed("ip -6 route list dev eth0 | head -n3").strip()
assert (
ipv4Table == targetIPv4Table
), """
assert [
l.strip() for l in ipv4Table.splitlines()
] == targetIPv4Table, """
The IPv4 routing table does not match the expected one:
Result:
{}
Expand All @@ -631,9 +643,9 @@ let
""".format(
ipv4Table, targetIPv4Table
)
assert (
ipv6Table == targetIPv6Table
), """
assert [
l.strip() for l in ipv6Table.splitlines()
] == targetIPv6Table, """
The IPv6 routing table does not match the expected one:
Result:
{}
Expand Down

0 comments on commit 86d71dd

Please sign in to comment.