default.nix (1672B)
1 { 2 nftables 3 , writeScript 4 , lib 5 } : 6 name : ruleset : 7 let 8 inherit (lib.strings) concatStringsSep splitString hasInfix substring; 9 inherit (lib.lists) groupBy; 10 inherit (lib.attrsets) mapAttrsToList nameValuePair; 11 inherit (builtins) map listToAttrs replaceStrings head tail; 12 13 indentLines = offset : lines : 14 if lines == [] 15 then "" 16 else 17 let 18 line = head lines; 19 isOpen = hasInfix "{" line; 20 isClose = hasInfix "}" line; 21 offset' = offset + 22 (if isOpen then 4 else 0) + 23 (if isClose then -4 else 0); 24 padding = offset: substring 0 offset " "; 25 in 26 if (isClose && !isOpen) 27 then 28 (padding offset') + line + "\n" + indentLines offset' (tail lines) 29 else 30 (padding offset) + line + "\n" + indentLines offset' (tail lines); 31 32 indent = text : indentLines 0 (splitString "\n" text); 33 34 dochain = { name, type, family, rules, 35 policy ? null, 36 priority ? "filter", 37 hook ? null } : '' 38 chain ${name} { 39 ${if hook != null 40 then "type ${type} hook ${hook} priority ${priority}; policy ${policy};" 41 else "" 42 } 43 ${concatStringsSep "\n" rules} 44 } 45 ''; 46 dotable = family : chains : '' 47 table ${family} table-${family} { 48 ${concatStringsSep "\n" (map dochain chains)} 49 } 50 ''; 51 categorise = chains : 52 groupBy 53 ({ family, ... } : family) 54 (mapAttrsToList (n : v : v // { name = n; }) chains); 55 in writeScript name '' 56 #!${nftables}/sbin/nft -f 57 58 flush ruleset 59 60 ${indent (concatStringsSep "\n" (mapAttrsToList dotable (categorise ruleset)))} 61 ''