forked from DGNum/liminix
59 lines
1.5 KiB
Nix
59 lines
1.5 KiB
Nix
|
{
|
||
|
nftables
|
||
|
, writeScript
|
||
|
, lib
|
||
|
} :
|
||
|
name : ruleset :
|
||
|
let
|
||
|
inherit (lib.strings) concatStringsSep splitString hasInfix substring;
|
||
|
inherit (lib.lists) groupBy;
|
||
|
inherit (lib.attrsets) mapAttrsToList nameValuePair;
|
||
|
inherit (builtins) map listToAttrs replaceStrings head tail;
|
||
|
|
||
|
indentLines = offset : lines :
|
||
|
if lines == []
|
||
|
then ""
|
||
|
else
|
||
|
let
|
||
|
line = head lines;
|
||
|
isOpen = hasInfix "{" line;
|
||
|
isClose = hasInfix "}" line;
|
||
|
offset' = offset +
|
||
|
(if isOpen then 4 else 0) +
|
||
|
(if isClose then -4 else 0);
|
||
|
padding = offset: substring 0 offset " ";
|
||
|
in
|
||
|
if (isClose && !isOpen)
|
||
|
then
|
||
|
(padding offset') + line + "\n" + indentLines offset' (tail lines)
|
||
|
else
|
||
|
(padding offset) + line + "\n" + indentLines offset' (tail lines);
|
||
|
|
||
|
indent = text : indentLines 0 (splitString "\n" text);
|
||
|
|
||
|
dochain = { name, type, family, rules, policy ? null, hook ? null } : ''
|
||
|
chain ${name} {
|
||
|
${if hook != null
|
||
|
then "type ${type} hook ${hook}; policy ${policy};"
|
||
|
else ""
|
||
|
}
|
||
|
${concatStringsSep "\n" rules}
|
||
|
}
|
||
|
'';
|
||
|
dotable = family : chains : ''
|
||
|
table ${family} ${family} {
|
||
|
${concatStringsSep "\n" (map dochain chains)}
|
||
|
}
|
||
|
'';
|
||
|
categorise = chains :
|
||
|
groupBy
|
||
|
({ family, ... } : family)
|
||
|
(mapAttrsToList (n : v : v // { name = n; }) chains);
|
||
|
in writeScript name ''
|
||
|
#!${nftables}/sbin/nft -cf
|
||
|
|
||
|
flush ruleset
|
||
|
|
||
|
${indent (concatStringsSep "\n" (mapAttrsToList dotable (categorise ruleset)))}
|
||
|
''
|