default.nix (2819B)
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) 18 elemAt 19 map 20 head 21 tail 22 toString 23 ; 24 25 indentLines = 26 offset: lines: 27 if lines == [ ] then 28 "" 29 else 30 let 31 line = head lines; 32 isOpen = hasInfix "{" line; 33 isClose = hasInfix "}" line; 34 offset' = offset + (if isOpen then 4 else 0) + (if isClose then -4 else 0); 35 padding = offset: substring 0 offset " "; 36 in 37 if (isClose && !isOpen) then 38 (padding offset') + line + "\n" + indentLines offset' (tail lines) 39 else 40 (padding offset) + line + "\n" + indentLines offset' (tail lines); 41 42 indent = text: indentLines 0 (splitString "\n" text); 43 44 dochain = 45 { 46 name, 47 type, 48 family, 49 rules, 50 policy ? null, 51 priority ? "filter", 52 hook ? null, 53 }: 54 '' 55 chain ${name} { 56 ${if hook != null then "type ${type} hook ${hook} priority ${priority}; policy ${policy};" else ""} 57 ${concatStringsSep "\n" rules} 58 } 59 ''; 60 61 doset = 62 { 63 name, 64 type, 65 elements ? [ ], 66 extraText ? null, 67 ... 68 }: 69 '' 70 set ${name} { 71 type ${type} 72 ${ 73 if elements != [ ] then 74 "elements = { ${concatStringsSep ", " (builtins.trace elements elements)} }" 75 else 76 "" 77 } 78 ${optionalString (extraText != null) extraText} 79 } 80 ''; 81 82 domap = 83 { 84 name, 85 type, 86 elements ? [ ], 87 extraText ? null, 88 ... 89 }: 90 let 91 colonize = 92 v: 93 let 94 ty = elemAt (attrsToList v) 0; 95 in 96 "${ty.name}: ${ty.value}"; 97 in 98 '' 99 map ${name} { 100 type ${colonize type} 101 ${ 102 if elements != [ ] then 103 "elements = { ${concatStringsSep ", " (mapAttrsToList (k: v: "${k}: ${toString v}") elements)} }" 104 else 105 "" 106 } 107 ${optionalString (extraText != null) extraText} 108 } 109 ''; 110 111 dochainorset = 112 { 113 kind ? "chain", 114 ... 115 }@params: 116 { 117 chain = dochain; 118 set = doset; 119 map = domap; 120 } 121 .${kind} 122 params; 123 124 dotable = family: chains: '' 125 table ${family} table-${family} { 126 ${concatStringsSep "\n" (map dochainorset chains)} 127 } 128 ''; 129 categorise = 130 chains: groupBy ({ family, ... }: family) (mapAttrsToList (n: v: { name = n; } // v) chains); 131 in 132 writeScript name '' 133 #!${nftables}/sbin/nft -f 134 135 flush ruleset 136 137 ${indent (concatStringsSep "\n" (mapAttrsToList dotable (categorise ruleset)))} 138 ''