Skip to content
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

nat: Use iptrie instead of custom LPM implementation #230

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

qmonnet
Copy link
Member

@qmonnet qmonnet commented Feb 14, 2025

Replace our PrefixTrie implementation with the one from the iptrie crate.

We get some added complexity due to the fact that (as far as I can tell, and in spite of what the crate's README says) there seems to be no way to store a type that represents both IPv4 and IPv6 prefixes; so we end up with two distinct maps. We wrap these into a struct PrefixTrie (distinct from the one we had so far: it no longer implements the map), to avoid dealing with IP versions in the implmementation of the PifTable and the GlobalContext. We also have to implement the Debug trait for the PrefixTrie, given that the LPM map we use does not provide it.

PrefixTrie's insert() function will eventually be reworked, when we change the definition of the endpoints to use CIDR objects rather than a combination of address + prefix length.

Note: iptrie is also introduced in #211.

@qmonnet qmonnet added the area/nat Related to Network Address Translation (NAT) label Feb 14, 2025
@qmonnet qmonnet requested a review from a team as a code owner February 14, 2025 03:15
@qmonnet qmonnet requested review from Fredi-raspall and removed request for a team February 14, 2025 03:15
dpdk = { workspace = true }
iptrie = { workspace = true }
Copy link
Contributor

Choose a reason for hiding this comment

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

Same here. Nothing wrong, you'll have to deal with it when merge/rebase.
Raising this because I'd actually merge #211 first for the reason mentioned below.

Copy link
Member Author

Choose a reason for hiding this comment

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

If it's the exact same change for this line, I expect git/GitHub is able to silently discard this chunk when rebasing, so it shouldn't create a merge conflict, whichever PR gets in first.

for key in keys {
if let Some(val) = &node.value {
best_match = Some(val.clone());
fn insert(&mut self, addr: &IpAddr, len: &u8, value: String) -> Result<(), NatError> {
Copy link
Contributor

Choose a reason for hiding this comment

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

This is absolutely fine. However, in #211, I added an enum Prefix that works for both IPv4 and IPv6. I would use that type here so that:

  • the same implementation works also for IPv6 (with minor tweaks like using trie_ipv4 or trie_ipv6)
  • we don't leak the Ipv4Prefix, Ipv6Prefix type (specific to the iptrie) outside of the "scope" where they are absolutely needed. The Prefix uses "standard" types.
  • we have a common type to represent prefixes throughout.

Copy link
Contributor

Choose a reason for hiding this comment

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

Oh, sorry, now I realize that you added also IPv6.
Up to you then to use Prefix.

Copy link
Member Author

Choose a reason for hiding this comment

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

I'll take a look, thanks.

Note also that iptrie might support both IPv4 and IPv6 in a single map in the near future.

dataplane/src/nat.rs Outdated Show resolved Hide resolved
dataplane/src/nat.rs Outdated Show resolved Hide resolved
Copy link
Contributor

@Fredi-raspall Fredi-raspall left a comment

Choose a reason for hiding this comment

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

Nice work Quentin!

Replace our PrefixTrie implementation with the one from the iptrie
crate.

We get some added complexity due to the fact that (as far as I can tell,
and in spite of what the crate's README says) there seems to be no way
to store a type that represents both IPv4 and IPv6 prefixes; so we end
up with two distinct maps. We wrap these into a struct PrefixTrie
(distinct from the one we had so far: it no longer implements the map),
to avoid dealing with IP versions in the implmementation of the PifTable
and the GlobalContext. We also have to implement the Debug trait for the
PrefixTrie, given that the LPM map we use does not provide it.

PrefixTrie's insert() function will eventually be reworked, when we
change the definition of the endpoints to use CIDR objects rather than a
combination of address + prefix length.

Signed-off-by: Quentin Monnet <[email protected]>
@qmonnet qmonnet force-pushed the pr/qmonnet/nat-iptrie branch from 36a29c8 to b7720bc Compare February 14, 2025 11:38
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