liminix

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

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 ''