Skip to content

New static NAT implementation #470

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

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open

Conversation

qmonnet
Copy link
Member

@qmonnet qmonnet commented May 14, 2025

This is a new implementation for static NAT.

The major changes for this new implementation are:

  • Use the actual user API objects to build the NAT tables, instead of the peering interfaces and other objects that we considered using in past representations.

  • Match addresses from a list of prefixes with exclusion prefixes to a similar list of prefixes with exclusion prefixes (rather than doing a simple prefix-to-prefix match, which would not correspond to the current API).

  • Restructure the lookups for NAT rules: use two successive tables for source NAT lookup instead of retrieving and "following" a peering to figure out what VPC's table should be checked.

  • Construction of the NAT rules have been moved to the mgmt crate, rather than living next to the NAT processing logics in the dataplane crate.

The code changes a lot since the previous implementation. As a consequence, the PR doesn't split very well into incremental changes; instead I'm re-adding new definitions as separate submodules, then removing most of the legacy code, and then at last I update the core of the logics in dataplane's nat/mod.rs, based on the new definitions introduced in the early commits.

After this Pull Request, the main follow-up items are:

@qmonnet qmonnet requested a review from a team as a code owner May 14, 2025 16:59
@qmonnet qmonnet requested review from daniel-noland and removed request for a team May 14, 2025 16:59
@qmonnet qmonnet added the area/nat Related to Network Address Translation (NAT) label May 14, 2025
@qmonnet qmonnet added this to the GW R1 milestone May 14, 2025
@qmonnet qmonnet force-pushed the pr/qmonnet/nat-impl-peerings branch 2 times, most recently from 2073be3 to 6fd7c41 Compare May 15, 2025 11:03
@qmonnet qmonnet requested a review from Fredi-raspall May 15, 2025 11:03
@mvachhar
Copy link
Contributor

Does this close any issues? If so we should mention them in the PR so it auto closes them.

@qmonnet
Copy link
Member Author

qmonnet commented May 16, 2025

I know, but this PR alone doesn't close an issue. The related one is #180, but we'll need the follow-ups listed above to have the complete feature working.

@qmonnet qmonnet force-pushed the pr/qmonnet/nat-impl-peerings branch from 6fd7c41 to 6bbd6e9 Compare May 20, 2025 14:43
@qmonnet qmonnet force-pushed the pr/qmonnet/nat-impl-peerings branch 5 times, most recently from 1bbe196 to d19fbc1 Compare May 26, 2025 01:13
@qmonnet qmonnet self-assigned this May 27, 2025
qmonnet added 7 commits May 27, 2025 17:50
Add an updated copy of the PrefixTrie implementation that we use for NAT
into the mgmt crate.

Here is how the copies differ:

- The new implementation for PrefixTrie<T> is generic and supports
  values other than Strings.
- The find() and find_ip() methods have been collapsed into a new
  lookup() method that takes an IP address as a parameter and returns
  the matching Prefix (in addition to the value) from the table lookup.
- Tracing macros that would decorate all functions have been removed.
- Some formatting have been improved, in particular the comments have
  been rewrapped with a line width of 100 characters.

The presence of the two copies in the repository is only temporary, we
do not need the two of them. The initial copy has been kept to avoid
breaking compilation in the dataplane crate, it will be removed in a
subsequent commit.

Signed-off-by: Quentin Monnet <[email protected]>
Add definitions for the NAT tables used that we plan to use for static
NAT. These tables are defined in the mgmt package, where they will later
(in future commits) be populated from the dataplane configuration,
before being handed over to the pipeline stage for NAT.

Signed-off-by: Quentin Monnet <[email protected]>
Add a function, in a separate submodule, to convert a peering into new
entries in a table with rules for static NAT.

Note: add_peering(table, peering) should be part of PerVniTable, but we
prefer to keep it in a separate submodule because it relies on
definitions from the external models, unlike the rest of the PerVniTable
implementation.

Also add functions to "optimise" a VpcExpose object _in the context of
NAT_, by collapsing allowed and excluded prefixes when possible.

Signed-off-by: Quentin Monnet <[email protected]>
Remove all parts of the current implementation that are related to the
representation of user API objects, as well as the parts related to our
own internal IpList structure.

Also remove all API-based definitions from the NAT submodule, as well as
our IpList implementation. A stub IpList submodule is left behind to
avoid breaking compilation, and because we'll provide a new
implementation for that structure in a future commit.

The remaining NAT code is left non-functioning after this commit (but
then, we didn't have fully working NAT so far anyway).

Instead of the deprecated NAT implementation, future commits will update
the submodule to switch to a new implementation based on the actual user
API, and using the table definitions that we've introduced in the latest
commits.

Signed-off-by: Quentin Monnet <[email protected]>
The previous IpList implementation would consider lists of prefixes such
that we would do a 1-to-1 mapping from one prefix into another prefix.

This new version assumes that, insead, we're doing a 1-to-1 mapping
between a list of prefixes and another list of prefixes, while taking
into account exclusion prefixes to apply to these lists.

This new IpList structure will be incorporated into the NAT logics in a
subsequent commit.

Signed-off-by: Quentin Monnet <[email protected]>
Reformat comments in the nat/mod.rs submodule, by using 100
character-wide lines for wrapping rather than 80 character-wide lines.

Also remove some macros supposed to allow dead code, but that were in
fact not necessary.

Signed-off-by: Quentin Monnet <[email protected]>
Reimplement static NAT (again). Use the new definitions of the
PrefixTrie structure, IpList structure, and NatTables structure
introduced in the latest commits.

The major changes for this new implementation are:

- Use the actual user API objects to build the NAT tables, instead of
  the peering interfaces and other objects that we considered using in
  past representations.

- Match addresses from a list of prefixes with exclusion prefixes to a
  similar list of prefixes with exclusion prefixes (rather than doing a
  simple prefix-to-prefix match, which would not correspond to the
  current API).

- Restructure the lookups for NAT rules: use two successive tables for
  source NAT lookup instead of retrieving and "following" a peering to
  figure out what VPC's table should be checked.

- Construction of the NAT rules have been moved to the mgmt crate,
  rather than living next to the NAT processing logics in the dataplane
  crate.

Add a new set of unit tests for the module.

Signed-off-by: Quentin Monnet <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/nat Related to Network Address Translation (NAT)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants