nixos/networkd: allow specifying FirewallMark mask
This commit is contained in:
parent
e7ce68d67b
commit
8b4cd01f90
@ -12,6 +12,7 @@ let
|
||||
concatStringsSep
|
||||
const
|
||||
elem
|
||||
elemAt
|
||||
filter
|
||||
filterAttrs
|
||||
flatten
|
||||
@ -21,11 +22,14 @@ let
|
||||
isFloat
|
||||
isList
|
||||
isPath
|
||||
isString
|
||||
length
|
||||
makeBinPath
|
||||
makeSearchPathOutput
|
||||
mapAttrs
|
||||
mapAttrsToList
|
||||
mapNullable
|
||||
match
|
||||
mkAfter
|
||||
mkIf
|
||||
optional
|
||||
@ -101,6 +105,8 @@ in rec {
|
||||
optional (attr ? ${name} && ! isByteFormat attr.${name})
|
||||
"Systemd ${group} field `${name}' must be in byte format [0-9]+[KMGT].";
|
||||
|
||||
toIntBaseDetected = value: assert (match "[0-9]+|0x[0-9a-fA-F]+" value) != null; (builtins.fromTOML "v=${value}").v;
|
||||
|
||||
hexChars = stringToCharacters "0123456789abcdefABCDEF";
|
||||
|
||||
isMacAddress = s: stringLength s == 17
|
||||
@ -156,6 +162,23 @@ in rec {
|
||||
optional (attr ? ${name} && !(((isInt attr.${name} || isFloat attr.${name}) && min <= attr.${name} && max >= attr.${name}) || elem attr.${name} values))
|
||||
"Systemd ${group} field `${name}' is not a value in range [${toString min},${toString max}], or one of ${toString values}";
|
||||
|
||||
assertRangeWithOptionalMask = name: min: max: group: attr:
|
||||
if (attr ? ${name}) then
|
||||
if isInt attr.${name} then
|
||||
assertRange name min max group attr
|
||||
else if isString attr.${name} then
|
||||
let
|
||||
fields = match "([0-9]+|0x[0-9a-fA-F]+)(/([0-9]+|0x[0-9a-fA-F]+))?" attr.${name};
|
||||
in if fields == null then ["Systemd ${group} field `${name}' must either be an integer or two integers separated by a slash (/)."]
|
||||
else let
|
||||
value = toIntBaseDetected (elemAt fields 0);
|
||||
mask = mapNullable toIntBaseDetected (elemAt fields 2);
|
||||
in
|
||||
optional (!(min <= value && max >= value)) "Systemd ${group} field `${name}' has main value outside the range [${toString min},${toString max}]."
|
||||
++ optional (mask != null && !(min <= mask && max >= mask)) "Systemd ${group} field `${name}' has mask outside the range [${toString min},${toString max}]."
|
||||
else ["Systemd ${group} field `${name}' must either be an integer or a string."]
|
||||
else [];
|
||||
|
||||
assertMinimum = name: min: group: attr:
|
||||
optional (attr ? ${name} && attr.${name} < min)
|
||||
"Systemd ${group} field `${name}' must be greater than or equal to ${toString min}";
|
||||
|
@ -778,8 +778,7 @@ let
|
||||
])
|
||||
(assertInt "TypeOfService")
|
||||
(assertRange "TypeOfService" 0 255)
|
||||
(assertInt "FirewallMark")
|
||||
(assertRange "FirewallMark" 1 4294967295)
|
||||
(assertRangeWithOptionalMask "FirewallMark" 1 4294967295)
|
||||
(assertInt "Priority")
|
||||
(assertPortOrPortRange "SourcePort")
|
||||
(assertPortOrPortRange "DestinationPort")
|
||||
|
@ -57,6 +57,8 @@ let generateNodeConf = { lib, pkgs, config, privk, pubk, peerId, nodeId, ...}: {
|
||||
{ Table = 30; From = "192.168.1.1"; To = "192.168.1.2"; SourcePort = 666 ; DestinationPort = 667; }
|
||||
{ Table = 40; IPProtocol = "tcp"; InvertRule = true; }
|
||||
{ Table = 50; IncomingInterface = "eth1"; Family = "ipv4"; }
|
||||
{ Table = 60; FirewallMark = 4; }
|
||||
{ Table = 70; FirewallMark = "16/0x1f"; }
|
||||
];
|
||||
};
|
||||
};
|
||||
@ -119,5 +121,9 @@ testScript = ''
|
||||
)
|
||||
# IPProtocol + InvertRule
|
||||
node1.succeed("sudo ip rule | grep 'not from all ipproto tcp lookup 40'")
|
||||
# FirewallMark without a mask
|
||||
node1.succeed("sudo ip rule | grep 'from all fwmark 0x4 lookup 60'")
|
||||
# FirewallMark with a mask
|
||||
node1.succeed("sudo ip rule | grep 'from all fwmark 0x10/0x1f lookup 70'")
|
||||
'';
|
||||
})
|
||||
|
Loading…
Reference in New Issue
Block a user