Skip to content

[1/3] [nat] move PortRange to struct - #334

Open
nicolaskagami wants to merge 1 commit into
mainfrom
nsk/nat-1-portrange
Open

[1/3] [nat] move PortRange to struct#334
nicolaskagami wants to merge 1 commit into
mainfrom
nsk/nat-1-portrange

Conversation

@nicolaskagami

@nicolaskagami nicolaskagami commented Aug 6, 2026

Copy link
Copy Markdown

This PR:

  • Moves the PortRange trait into a struct, validating the low <= high invariant by construction.
  • Simplifies overlap function.

This is the first of 3 PRs simplifying and de-duplicating some of the nat.rs code.

Left for future work:

  • Expanding PortRange usage further.
  • Storing ranges in a way that codifies its non-overlapping invariant and stores sorted for faster operations.

@internet-diglett internet-diglett left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall looks good! Just a few comments.

Comment thread dpd/src/nat.rs
pub high: u16,
#[derive(PartialEq)]
pub(crate) struct Ipv6NatEntry {
pub ports: PortRange,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minor nit: port is a very overloaded term inside of dendrite (grepping for ports gives a lot of unrelated results). Maybe we should be more explicit and name this field port_range? I also notice that there is a convention of naming fields that are a single item thing and naming collections / iterators of a type thing**s**, so this also avoids creating confusion there.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice catch!

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we use "L4 port" in Omicron and OPTE similar situations, which might be a good option.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you suggesting PortRange be called L4PortRange?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, sorry if that wasn't clear. One could also rename the ports field to something like l4_ports.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just making sure. Sounds good to me 👍

Comment thread dpd/src/nat.rs

#[derive(Clone, PartialEq)]
pub(crate) struct Ipv4NatEntry {
pub ports: PortRange,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same as above

Comment thread dpd/src/nat.rs
Comment thread dpd/src/nat.rs
Comment on lines +151 to +170
assert_eq!(first_mapping(2, 2), Some(0));
assert_eq!(first_mapping(4, 5), Some(0));
assert_eq!(first_mapping(5, 6), None);
assert_eq!(first_mapping(5, 7), Some(1));
assert_eq!(first_mapping(2, 6), Some(0));
assert_eq!(first_mapping(5, 5), None);
assert_eq!(first_mapping(5, 20), Some(1));
assert_eq!(first_mapping(12, 12), Some(2));
assert_eq!(first_mapping(18, 18), Some(2));
assert_eq!(first_mapping(19, 19), None);
assert_eq!(first_mapping(19, 40), None);
assert_eq!(first_mapping(0, 0), None);
assert_eq!(first_mapping(0, 2), Some(0));
assert_eq!(space(0, 0), Some(0));
assert_eq!(space(0, 1), None);
assert_eq!(space(11, 11), Some(2));
assert_eq!(space(19, 32), Some(3));
assert_eq!(space(0, 2), None);
assert_eq!(space(3, 5), None);
assert_eq!(space(3, 8), None);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could this be a good candidate for property based testing?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess so, but in this case it would be enforcing a property that's basically the same as what we already have in the code. I like to think of tests like this as a way of giving the developer a feel for how it works more so than actually exercising functionality.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess that was a roundabout way of me asking "it seems we need a lot of cases to exercise this code... are we sure we've covered all of them?"

(I'm actually not sure either way, it just stood out to me)

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just adapted the tests that were already there since this purposefully a quite mechanical PR with no new semantics.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants