140 lines
4.4 KiB
Nix
140 lines
4.4 KiB
Nix
{ clanLib, ... }:
|
|
{
|
|
_class = "clan.service";
|
|
manifest.name = "apple-network";
|
|
manifest.description = "This service will create an instance of `atalkd` for each peer to talk to Apple machines over Apple Talk protocol and automatically connect each peer using vxlan over Yggdrasil network to achieve Apple Talk over internet experience";
|
|
manifest.readme = builtins.readFile ./README.md;
|
|
manifest.categories = [ "Network" ];
|
|
|
|
roles.peer = {
|
|
description = "A gateway machine that allow classic Apple machines to connect to other Apple machines over the internet";
|
|
|
|
interface =
|
|
{ lib, ... }:
|
|
{
|
|
options = {
|
|
zone_name = lib.mkOption {
|
|
type = with lib.types; str;
|
|
description = "Zone name for Apple Talk protocol";
|
|
default = "Default";
|
|
};
|
|
};
|
|
};
|
|
|
|
perInstance =
|
|
{ roles, settings, ... }:
|
|
{
|
|
nixosModule =
|
|
{
|
|
lib,
|
|
config,
|
|
pkgs,
|
|
...
|
|
}:
|
|
let
|
|
vxlanPort = 4789;
|
|
|
|
getYggdrasilIP =
|
|
machineName:
|
|
if config.clan.core.vars.generators.yggdrasil.files.address ? value then
|
|
clanLib.getPublicValue {
|
|
flake = config.clan.core.settings.directory;
|
|
machine = machineName;
|
|
generator = "yggdrasil";
|
|
file = "address";
|
|
default = null;
|
|
}
|
|
else
|
|
throw "clanService/yggdrasil is required";
|
|
|
|
noSelfPeers = builtins.filter (peerName: peerName != config.clan.core.settings.machine.name) (
|
|
lib.mapAttrsToList (machineName: _: machineName) roles.peer.machines
|
|
);
|
|
|
|
sortedPeers = builtins.sort (x: y: x < y) (
|
|
lib.mapAttrsToList (machineName: _: machineName) roles.peer.machines
|
|
);
|
|
|
|
getMachineIndex = machineName: lib.lists.findFirstIndex (x: x == machineName) null sortedPeers;
|
|
|
|
selfVXAddress = "192.168.254.${
|
|
lib.toString ((getMachineIndex config.clan.core.settings.machine.name) + 1)
|
|
}/24";
|
|
in
|
|
{
|
|
|
|
services.atalkd = {
|
|
enable = true;
|
|
interfaces = {
|
|
vxlan.config = ''
|
|
-router -phase 2 -net 1 -zone "${settings.zone_name}"
|
|
'';
|
|
};
|
|
};
|
|
|
|
networking.useNetworkd = true;
|
|
|
|
networking.firewall.interfaces."ygg".allowedUDPPorts = [ vxlanPort ];
|
|
|
|
boot.kernelModules = [ "vxlan" ];
|
|
|
|
systemd.network.netdevs =
|
|
builtins.listToAttrs (
|
|
map (
|
|
peerName:
|
|
(lib.nameValuePair "10-apl-vxlan-${peerName}" {
|
|
enable = true;
|
|
netdevConfig = {
|
|
Name = "vxlan-${peerName}";
|
|
Kind = "vxlan";
|
|
};
|
|
vxlanConfig = {
|
|
VNI = (getMachineIndex config.clan.core.settings.machine.name) + (getMachineIndex peerName);
|
|
Remote = getYggdrasilIP peerName;
|
|
DestinationPort = vxlanPort;
|
|
Independent = true;
|
|
};
|
|
})
|
|
) noSelfPeers
|
|
)
|
|
// {
|
|
"10-apl-vxlan" = {
|
|
enable = true;
|
|
netdevConfig = {
|
|
Kind = "bridge";
|
|
Name = "vxlan";
|
|
};
|
|
bridgeConfig = {
|
|
STP = true;
|
|
};
|
|
};
|
|
};
|
|
|
|
systemd.network.networks =
|
|
builtins.listToAttrs (
|
|
map (
|
|
peerName:
|
|
(lib.nameValuePair "10-apl-vxlan-${peerName}" {
|
|
enable = true;
|
|
matchConfig.Name = "vxlan-${peerName}";
|
|
networkConfig.Bridge = "vxlan";
|
|
})
|
|
) noSelfPeers
|
|
)
|
|
// {
|
|
"10-apl-vxlan" = {
|
|
enable = true;
|
|
matchConfig.Name = "vxlan";
|
|
address = [ selfVXAddress ];
|
|
};
|
|
};
|
|
|
|
environment.systemPackages = [
|
|
pkgs.netatalk
|
|
pkgs.bridge-utils
|
|
];
|
|
};
|
|
};
|
|
};
|
|
}
|