-
-
Notifications
You must be signed in to change notification settings - Fork 14.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
lib.network: add ipv6 parser #318712
lib.network: add ipv6 parser #318712
Conversation
d2bceb3
to
69089c5
Compare
lib/network/default.nix
Outdated
in | ||
assert lib.asserts.assertMsg ( | ||
builtins.length addr == 8 | ||
) "_parseNormalized expected to recieve normalized IPv6 address"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
) "_parseNormalized expected to recieve normalized IPv6 address"; | |
) "_parseNormalized expects a normalized IPv6 address"; |
But what does "normalized" in this case even mean? I don't think the function name matches its purpose well.
To address your questions:
Yes currently they would all get exposed, you have to put them into a let binding to make them truly internal. Take a look at https://github.com/NixOS/nixpkgs/blob/master/lib/fileset/default.nix#L103 as an example.
Some of them are some of them aren't, please take a look at the example
no, we should keep them separate and preferably go for small prs, e.g. once the parser is fine merge this pr and then do another v6 one for cidr related functions. |
8ad8940
to
5f1b84c
Compare
5f1b84c
to
05c8c7b
Compare
@Janik-Haag @mweinelt I refactored the code and moved internal functions to internal.nix. Can you review again please? |
05c8c7b
to
1ed35a9
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is getting into shape. There are some smaller points left to do, and you should add a lot more comments explaining different parts, I think. This part of lib currently is very undocumented internally compared to others like lib.fileset or lib.generators.
lib/network/internal.nix
Outdated
if 1 <= n && n <= ipv6Bits then | ||
n | ||
else | ||
throw "${apiName}: IPv6 subnet should be in range [1;${toString ipv6Bits}], got ${toString n}"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Uh, I don't think we want to pass around the function name here, this will only get more confusing to debug because your output would gaslight the user, once other functions rely on the ${apiName} function internally.
lib/network/default.nix
Outdated
api = "lib.network.ipv6.fromString"; | ||
|
||
splittedAddr = _ipv6.split api addr; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please remove the "api" part.
lib/network/internal.nix
Outdated
emptyExpected = | ||
if hasPrefix || hasSuffix then | ||
2 | ||
else if hasInfix then | ||
1 | ||
else | ||
0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be moved in the same scope as the emptyCount definition
lib/network/internal.nix
Outdated
ipv6Bits = 128; | ||
ipv6Pieces = 8; | ||
ipv6PieceBits = 16; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should link to the corresponding RFC definitions, and maybe write a comment explaining them, since these are magic numbers to anyone unfamiliar with networking.
lib/network/internal.nix
Outdated
let | ||
zeros = genList (_: "0") (ipv6Pieces - piecesNoEmptyLen); | ||
in | ||
if hasPrefix then zeros ++ piecesNoEmpty else piecesNoEmpty ++ zeros | ||
else if hasInfix then | ||
concatMap ( | ||
piece: if piece == "" then genList (_: "0") (ipv6Pieces - piecesNoEmptyLen) else [ piece ] | ||
) pieces |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can reuse the zeros variable in line 68 in the concatMap function, because it's doing the same.
lib/network/internal.nix
Outdated
let | ||
splitted = strings.splitString "/" addr; | ||
splittedLength = length splitted; | ||
in | ||
if splittedLength == 1 then # [ ip ] | ||
{ | ||
address = parseIpv6FromString apiName addr; | ||
prefixLength = 64; # /64 is a standard size IPv6 subnet as defined by the IETF. | ||
} | ||
else if splittedLength == 2 then # [ ip subnet ] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should be stricter with the user input and don't silently just set some prefix but instead fail saying that it's not a cidr address.
Also, usually the assumption I'm familiar with if you just don't specify a prefix is that you get a /128.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree, 128 sounds more logical if prefix length is omitted.
I think we should be stricter with the user input and don't silently just set some prefix but instead fail saying that it's not a cidr address.
I added one fromString
function and user can use both default and cidr notation. I don't see a reason to create two separate API functions like fromString
and fromCidrString
, because this can be easily observed from the passed string - if it contains a /
, then we try to parse it as cidr notation.
1ed35a9
to
504a79b
Compare
Co-authored-by: lucasew <lucas59356@gmail.com>
504a79b
to
9a035ac
Compare
Add a library function to parse and validate an IPv6 address from a string. It can parse the first two versions of an IPv6 address according to https://datatracker.ietf.org/doc/html/rfc4291#section-2.2. The third form "x:x:x:x:x:x.d.d.d.d" is not yet implemented. Optionally parser can accept prefix length (128 is default). Add shell script network.sh to test IPv6 parser functionality.
9a035ac
to
d559eed
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@infinisil as a lib code owner, do you want to give this a review before we merge it?
This pull request has been mentioned on NixOS Discourse. There might be relevant details there: https://discourse.nixos.org/t/showcase-nixpkgs-network-library/48897/1 |
Description of changes
string. It can parse the first two versions of an IPv6 address according
to https://datatracker.ietf.org/doc/html/rfc4291#section-2.2. The third
form "x:x:x:x:x:x.d.d.d.d" is not yet implemented.
Mentor: @Janik-Haag
Things done
Add a 👍 reaction to pull requests you find important.