Skip to content

[2/3] [nat] introduce NatAddress trait - #335

Open
nicolaskagami wants to merge 1 commit into
nsk/nat-1-portrangefrom
nsk/nat-2-nat-family
Open

[2/3] [nat] introduce NatAddress trait#335
nicolaskagami wants to merge 1 commit into
nsk/nat-1-portrangefrom
nsk/nat-2-nat-family

Conversation

@nicolaskagami

@nicolaskagami nicolaskagami commented Aug 6, 2026

Copy link
Copy Markdown

This PR:

  • Introduces a NatAddress trait, tying each IP address family to its p4 table, match key, and action types. Replaces duplicated per-family entry points.

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

Obs: Changes are almost entirely equivalent, except for the ordering of some things and the log message nat tables -> nat table.

@nicolaskagami nicolaskagami self-assigned this Aug 6, 2026
@nicolaskagami nicolaskagami changed the title [2/3] [nat] introduce NatFamily trait [2/3] [nat] introduce NatAddress trait Aug 6, 2026
@nicolaskagami
nicolaskagami marked this pull request as ready for review August 6, 2026 18:00
Comment thread dpd/src/nat.rs Outdated
Comment thread dpd/src/table/nat.rs
}
}

impl NatAddress for Ipv4Addr {

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.

Instead of implementing NatAddress for a raw V4 or V6 addr, would it make sense to create newtypes around them that provides additional validation (i.e. do we want to allow creation of a NAT entry for any Ipv4 / Ipv6 address?), and implement this trait for the newtype?

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.

We could, but I didn't want to add new functionality on these PRs.

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.

additional validations could be added later

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 really feel like such a structure should be added on a dedicated PR, where we can discuss the semantics we want to enforce.

@nicolaskagami
nicolaskagami force-pushed the nsk/nat-2-nat-family branch 2 times, most recently from 22d9c68 to 1b86758 Compare August 7, 2026 13:47
Comment thread dpd/src/nat.rs Outdated
Comment thread dpd/src/nat.rs Outdated
Comment thread dpd/src/table/nat.rs
}
}

impl NatAddress for Ipv4Addr {

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.

additional validations could be added later

Tie each IP address family to its p4 table, match key, and action types
via a trait, with the table operations provided as default methods.
Replaces the duplicated per-family entry points.

@bnaecker bnaecker 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.

Looks good, nice cleanup. Just a few questions / nits.

Comment thread dpd/src/nat.rs
Comment on lines 624 to +625
nat.ipv6_mappings.clear();
if let Err(e) = nat::reset_ipv6(switch) {
error!(switch.log, "failed to reset ipv6 nat table: {:?}", e);
Err(e)
} else {
Ok(())
}
table::nat::reset::<Ipv6Addr>(switch)

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.

This predates your PR, but it might make sense to swap the order of operations here. If we fail to delete the entries on switch table, we'll have already cleared the local mappings, and have some torn state. Could we move the nat.ipv6_mappings.clear() call after a successful call to table::nat::reset?

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.

Good catch. Definitely an underlying bug I can happily fix. This could've made the mapping representation drift from the actual switch state.

Comment thread dpd/src/nat.rs
} else {
Ok(())
}
table::nat::reset::<Ipv4Addr>(switch)

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 here, I'd argue we should swap clearing the in-memory and switch-table mappings.

Comment thread dpd/src/table/nat.rs
s.table_dump::<A::MatchKey, A::Action>(A::TABLE, from_hardware)
}

pub(crate) fn counter_fetch<A: NatAddress>(

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.

Small nit, but I think the counter- and dump-related functions can be private to the table mod. They're only called from dpd/src/table/mod.rs (e.g., line 333), not more generally in the dpd crate.

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.

Yeah, they could be pub(super)

Comment thread dpd/src/table/nat.rs
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