summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/krebs/genipv6.nix92
-rw-r--r--lib/types.nix24
2 files changed, 116 insertions, 0 deletions
diff --git a/lib/krebs/genipv6.nix b/lib/krebs/genipv6.nix
new file mode 100644
index 000000000..8d5ca1667
--- /dev/null
+++ b/lib/krebs/genipv6.nix
@@ -0,0 +1,92 @@
+lib:
+with lib;
+let {
+ body = netname: subnetname: suffix: rec {
+ address = let
+ suffix' =
+ if hasEmptyGroup (parseAddress suffix)
+ then suffix
+ else joinAddress "::" suffix;
+ in
+ checkAddress addressLength (joinAddress subnetPrefix suffix');
+ addressCIDR = "${address}/${toString addressLength}";
+ addressLength = 128;
+
+ inherit netname;
+ netCIDR = "${netAddress}/${toString netPrefixLength}";
+ netAddress = joinAddress netPrefix "::";
+ netHash = toString {
+ retiolum = 0;
+ wirelum = 1;
+ }.${netname};
+ netPrefix = "42:${netHash}";
+ netPrefixLength = {
+ retiolum = 32;
+ wirelum = 32;
+ }.${netname};
+
+ inherit subnetname;
+ subnetCIDR = "${subnetAddress}/${toString subnetPrefixLength}";
+ subnetAddress = joinAddress subnetPrefix "::";
+ subnetHash = hash subnetname;
+ subnetPrefix = joinAddress netPrefix subnetHash;
+ subnetPrefixLength = netPrefixLength + 16;
+
+ inherit suffix;
+ suffixLength = addressLength - subnetPrefixLength;
+ };
+
+ hash = s: head (match "0*(.*)" (substring 0 4 (hashString "sha256" s)));
+
+ dropLast = n: xs: reverseList (drop n (reverseList xs));
+ takeLast = n: xs: reverseList (take n (reverseList xs));
+
+ hasEmptyPrefix = xs: take 2 xs == ["" ""];
+ hasEmptySuffix = xs: takeLast 2 xs == ["" ""];
+ hasEmptyInfix = xs: any (x: x == "") (trimEmpty 2 xs);
+
+ hasEmptyGroup = xs:
+ any (p: p xs) [hasEmptyPrefix hasEmptyInfix hasEmptySuffix];
+
+ ltrimEmpty = n: xs: if hasEmptyPrefix xs then drop n xs else xs;
+ rtrimEmpty = n: xs: if hasEmptySuffix xs then dropLast n xs else xs;
+ trimEmpty = n: xs: rtrimEmpty n (ltrimEmpty n xs);
+
+ parseAddress = splitString ":";
+ formatAddress = concatStringsSep ":";
+
+ check = s: c: if !c then throw "${s}" else true;
+
+ checkAddress = maxaddrlen: addr: let
+ parsedaddr = parseAddress addr;
+ normalizedaddr = trimEmpty 1 parsedaddr;
+ in
+ assert (check "address malformed; lone leading colon: ${addr}" (
+ head parsedaddr == "" -> tail (take 2 parsedaddr) == ""
+ ));
+ assert (check "address malformed; lone trailing colon ${addr}" (
+ last parsedaddr == "" -> head (takeLast 2 parsedaddr) == ""
+ ));
+ assert (check "address malformed; too many successive colons: ${addr}" (
+ length (filter (x: x == "") normalizedaddr) > 1 -> addr == [""]
+ ));
+ assert (check "address malformed: ${addr}" (
+ all (test "[0-9a-f]{0,4}") parsedaddr
+ ));
+ assert (check "address is too long: ${addr}" (
+ length normalizedaddr * 16 <= maxaddrlen
+ ));
+ addr;
+
+ joinAddress = prefix: suffix: let
+ parsedPrefix = parseAddress prefix;
+ parsedSuffix = parseAddress suffix;
+ normalizePrefix = rtrimEmpty 2 parsedPrefix;
+ normalizeSuffix = ltrimEmpty 2 parsedSuffix;
+ delimiter =
+ optional (length (normalizePrefix ++ normalizeSuffix) < 8 &&
+ (hasEmptySuffix parsedPrefix || hasEmptyPrefix parsedSuffix))
+ "";
+ in
+ formatAddress (normalizePrefix ++ delimiter ++ normalizeSuffix);
+}
diff --git a/lib/types.nix b/lib/types.nix
index 41e75154e..17c1688fa 100644
--- a/lib/types.nix
+++ b/lib/types.nix
@@ -192,6 +192,28 @@ rec {
}));
default = null;
};
+ wireguard = mkOption {
+ type = nullOr (submodule ({ config, ... }: {
+ options = {
+ port = mkOption {
+ type = int;
+ description = "tinc port to use to connect to host";
+ default = 51820;
+ };
+ pubkey = mkOption {
+ type = wireguard-pubkey;
+ };
+ subnets = mkOption {
+ type = listOf cidr;
+ description = ''
+ wireguard subnets,
+ this defines how routing behaves for hosts that can't reach each other.
+ '';
+ default = [];
+ };
+ };
+ }));
+ };
};
});
@@ -548,4 +570,6 @@ rec {
check = filename.check;
merge = mergeOneOption;
};
+
+ wireguard-pubkey = str;
}