default.nix (2670B)
1 { 2 nftables, 3 writeScript, 4 lib, 5 }: 6 name: ruleset: 7 let 8 inherit (lib.strings) 9 concatStringsSep 10 splitString 11 hasInfix 12 substring 13 optionalString 14 ; 15 inherit (lib.lists) groupBy; 16 inherit (lib.attrsets) attrsToList mapAttrsToList; 17 inherit (builtins) elemAt map head tail toString; 18 19 indentLines = 20 offset: lines: 21 if lines == [ ] then 22 "" 23 else 24 let 25 line = head lines; 26 isOpen = hasInfix "{" line; 27 isClose = hasInfix "}" line; 28 offset' = offset + (if isOpen then 4 else 0) + (if isClose then -4 else 0); 29 padding = offset: substring 0 offset " "; 30 in 31 if (isClose && !isOpen) then 32 (padding offset') + line + "\n" + indentLines offset' (tail lines) 33 else 34 (padding offset) + line + "\n" + indentLines offset' (tail lines); 35 36 indent = text: indentLines 0 (splitString "\n" text); 37 38 dochain = 39 { 40 name, 41 type, 42 family, 43 rules, 44 policy ? null, 45 priority ? "filter", 46 hook ? null, 47 }: 48 '' 49 chain ${name} { 50 ${if hook != null then "type ${type} hook ${hook} priority ${priority}; policy ${policy};" else ""} 51 ${concatStringsSep "\n" rules} 52 } 53 ''; 54 55 doset = 56 { 57 name, 58 type, 59 elements ? [ ], 60 extraText ? null, 61 ... 62 }: 63 '' 64 set ${name} { 65 type ${type} 66 ${if elements != [ ] then "elements = { ${concatStringsSep ", " (builtins.trace elements elements)} }" else ""} 67 ${optionalString (extraText != null) extraText} 68 } 69 ''; 70 71 domap = 72 { 73 name, 74 type, 75 elements ? [ ], 76 extraText ? null, 77 ... 78 }: 79 let 80 colonize = v: 81 let ty = elemAt (attrsToList v) 0; in "${ty.name}: ${ty.value}"; 82 in '' 83 map ${name} { 84 type ${colonize type} 85 ${if elements != [ ] then "elements = { ${concatStringsSep ", " (mapAttrsToList (k: v : "${k}: ${toString v}") elements)} }" else ""} 86 ${optionalString (extraText != null) extraText} 87 } 88 ''; 89 90 dochainorset = 91 { 92 kind ? "chain", 93 ... 94 }@params: 95 { 96 chain = dochain; 97 set = doset; 98 map = domap; 99 } 100 .${kind} 101 params; 102 103 dotable = family: chains: '' 104 table ${family} table-${family} { 105 ${concatStringsSep "\n" (map dochainorset chains)} 106 } 107 ''; 108 categorise = 109 chains: groupBy ({ family, ... }: family) (mapAttrsToList (n: v: { name = n; } // v) chains); 110 in 111 writeScript name '' 112 #!${nftables}/sbin/nft -f 113 114 flush ruleset 115 116 ${indent (concatStringsSep "\n" (mapAttrsToList dotable (categorise ruleset)))} 117 ''