This commit is contained in:
catvayor 2025-02-22 19:08:31 +01:00
commit b8acdcef16
Signed by: lbailly
GPG key ID: CE3E645251AC63F3
5 changed files with 353 additions and 0 deletions

2
.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
.direnv
.envrc

14
shell.nix Normal file
View file

@ -0,0 +1,14 @@
let
pkgs = import <nixpkgs> { };
inherit (pkgs.lib) getExe getExe';
in
pkgs.mkShell {
packages = with pkgs; [
nixos-shell
(pkgs.writeShellScriptBin "connect_to_vm" ''
${getExe pkgs.sshpass} -p 'vxlan' \
${getExe' pkgs.openssh "ssh"} root@localhost -p 2222 \
-o "StrictHostKeyChecking no" -o "UserKnownHostsFile=/dev/null"
'')
];
}

1
vm.nix Symbolic link
View file

@ -0,0 +1 @@
vm/vm.nix

51
vm/common.nix Normal file
View file

@ -0,0 +1,51 @@
{ pkgs, lib, config, ... }: {
environment.defaultPackages = [
pkgs.inetutils
pkgs.tcpdump
pkgs.iperf
];
networking = {
useNetworkd = true;
firewall.enable = false;
};
systemd.network.enable = true;
nix = {
nixPath = [
"nixpkgs=${toString <nixpkgs>}"
];
channel.enable = false;
settings = {
nix-path = config.nix.nixPath;
experimental-features = [
"pipe-operator"
"nix-command"
];
};
package = pkgs.lix;
};
users.users.root = {
password = "vxlan";
initialHashedPassword = lib.mkForce null;
};
systemd = {
timers."tx-onload" = {
wantedBy = [ "timers.target" ];
timerConfig.OnStartupSec = 30;
};
services."tx-onload" = {
script = ''
${lib.getExe' pkgs.busybox "ip"} l |\
grep '^[0-9]' |\
sed 's/^[0-9]*: \(.*\)\(@.*\)\?: .*$/\1/' |\
xargs --replace=%I ${lib.getExe pkgs.ethtool} -K %I tx off tx-checksumming off
'';
};
};
system.stateVersion = "25.05";
}

285
vm/vm.nix Normal file
View file

@ -0,0 +1,285 @@
{
pkgs,
lib,
...
}:
let
inherit (lib)
imap
flatten
listToAttrs
;
access-topology = [
[
1000
1001
1002
1003
]
[
1000
1001
1002
1003
]
];
br_name = sw: vni: "sw${toString sw}-vni${toString vni}";
client_name = sw: vni: "h-${br_name sw vni}";
vtep_name = sw: vni: "v-${toString sw}-${toString vni}";
sw_name = sw: "sw${toString sw}";
vtep_br_name = sw: vni: "br${vtep_name sw vni}";
vtep_vxlan_name = sw: vni: "x${vtep_name sw vni}";
clients =
listToAttrs
<| flatten
<| imap (
sw:
map (vni: {
name = client_name sw vni;
value = {
privateNetwork = true;
ephemeral = true;
hostBridge = br_name sw vni;
autoStart = true;
config = {
imports = [ ./common.nix ];
networking.hostName = client_name sw vni;
services.resolved.enable = false;
systemd.network.networks = {
"10-eth0" = {
name = "eth0";
address = [ "10.0.${toString sw}.${toString (vni - 999)}/16" ];
linkConfig.Promiscuous = true;
};
};
};
};
})
) access-topology;
switchs =
listToAttrs
<| imap (sw: vnis: {
name = sw_name sw;
value = {
privateNetwork = true;
ephemeral = true;
hostBridge = "br0";
autoStart = true;
extraVeths =
listToAttrs
<| map (vni: {
name = vtep_name sw vni;
value.hostBridge = br_name sw vni;
}) vnis;
config = {
imports = [ ./common.nix ];
networking.hostName = sw_name sw;
services.resolved.enable = false;
systemd.network = {
networks =
{
"10-eth0" = {
name = "eth0";
address = [ "10.0.0.${toString (sw + 1)}/24" ];
networkConfig.VXLAN = map (vtep_vxlan_name sw) vnis;
linkConfig.Promiscuous = true;
};
}
// listToAttrs (
flatten
<| map (vni: [
{
name = "10-${vtep_name sw vni}";
value = {
name = vtep_name sw vni;
linkConfig.Promiscuous = true;
networkConfig = {
Bridge = vtep_br_name sw vni;
LinkLocalAddressing = false;
LLDP = false;
EmitLLDP = false;
IPv6AcceptRA = false;
IPv6SendRA = false;
};
};
}
{
name = "10-${vtep_br_name sw vni}";
value = {
name = vtep_br_name sw vni;
linkConfig.Promiscuous = true;
networkConfig = {
LinkLocalAddressing = false;
LLDP = false;
EmitLLDP = false;
IPv6AcceptRA = false;
IPv6SendRA = false;
};
};
}
{
name = "10-${vtep_vxlan_name sw vni}";
value = {
name = vtep_vxlan_name sw vni;
linkConfig.Promiscuous = true;
networkConfig = {
Bridge = vtep_br_name sw vni;
LinkLocalAddressing = false;
LLDP = false;
EmitLLDP = false;
IPv6AcceptRA = false;
IPv6SendRA = false;
};
};
}
]) vnis
);
netdevs = listToAttrs (
flatten
<| map (vni: [
{
name = "10-${vtep_br_name sw vni}";
value = {
netdevConfig = {
Name = vtep_br_name sw vni;
Kind = "bridge";
};
bridgeConfig.STP = false;
};
}
{
name = "10-${vtep_vxlan_name sw vni}";
value = {
netdevConfig = {
Name = vtep_vxlan_name sw vni;
Kind = "vxlan";
};
vxlanConfig = {
VNI = vni;
Remote = "10.0.0.1";
Local = "10.0.0.${toString (sw + 1)}";
DestinationPort = 4789;
PortRange = 4789;
};
};
}
]) vnis
);
};
};
};
}) access-topology;
in
{
virtualisation = {
memorySize = 4 * 1024;
cores = 4;
diskImage = null;
forwardPorts = [
{
from = "host";
host.port = 2222;
guest.port = 22;
}
];
};
nixos-shell.mounts = {
mountHome = false;
extraMounts."/vxlan" = {
target = ./..;
cache = "none";
};
};
imports = [ ./common.nix ];
services.openssh = {
enable = true;
settings.PermitRootLogin = "yes";
};
environment.defaultPackages = [
pkgs.pwru
];
containers =
{
"router" = {
privateNetwork = true;
ephemeral = true;
hostBridge = "br0";
bindMounts."/vxlan".hostPath = "/vxlan";
autoStart = true;
config = {
imports = [ ./common.nix ];
services.resolved.enable = false;
systemd.network.networks = {
"10-eth0" = {
name = "eth0";
address = [ "10.0.0.1/24" ];
};
};
};
};
}
// switchs
// clients;
systemd.network =
let
brs = [ "br0" ] ++ flatten (imap (sw: map (br_name sw)) access-topology);
in
{
networks =
listToAttrs
<|
map (name: {
name = "10-${name}";
value = {
inherit name;
linkConfig.Promiscuous = true;
networkConfig = {
LinkLocalAddressing = false;
LLDP = false;
EmitLLDP = false;
IPv6AcceptRA = false;
IPv6SendRA = false;
};
};
}) brs
++ flatten (
imap (
sw:
map (vni: {
name = "10-${vtep_name sw vni}";
value = {
name = vtep_name sw vni;
linkConfig.Promiscuous = true;
networkConfig = {
LinkLocalAddressing = false;
LLDP = false;
EmitLLDP = false;
IPv6AcceptRA = false;
IPv6SendRA = false;
};
};
})
) access-topology
);
netdevs =
listToAttrs
<| map (name: {
name = "10-${name}";
value = {
netdevConfig = {
Name = name;
Kind = "bridge";
};
bridgeConfig.STP = false;
};
}) brs;
};
}