Skip to content

Conversation

@qmonnet
Copy link
Member

@qmonnet qmonnet commented Jan 16, 2026

Work in progress.

This needs to be rebased on top of #1198, once it is merged.
NOTE: this is now rebased on #1198 and could be merged to that PR so that we keep a consistent history of PRs vs features in github.

Currently, this PR also misses:

  • New tests to validate the behaviour of the changes in flow-filter
  • Equivalent changes in NAT context tables to handle the "default" destinations properly

@qmonnet qmonnet added this to the GW R2 milestone Jan 16, 2026
@qmonnet qmonnet requested a review from Fredi-raspall January 16, 2026 22:11
@qmonnet qmonnet self-assigned this Jan 16, 2026
@qmonnet qmonnet added the area/nat Related to Network Address Translation (NAT) label Jan 16, 2026
Base automatically changed from pr/qmonnet/default-vpc to main January 16, 2026 23:00
@qmonnet qmonnet force-pushed the pr/qmonnet/handle-default branch 2 times, most recently from f5d2633 to 5053ce2 Compare January 17, 2026 00:05
@Fredi-raspall Fredi-raspall force-pushed the pr/qmonnet/handle-default branch from 5053ce2 to 647b8ad Compare January 18, 2026 11:46
@Fredi-raspall Fredi-raspall changed the base branch from main to pr/fredi/expose_refined January 18, 2026 11:47
@qmonnet
Copy link
Member Author

qmonnet commented Jan 19, 2026

There's a bug in the logic, I need to address it.

The type doesn't seem necessary at this time, let's remove it to help
with clarity.

[ Quentin:
    Remove VpcdLookupResult from comments in flow-filter/src/tables.rs ]

Signed-off-by: Fredi Raspall <fredi@githedgehog.com>
Signed-off-by: Quentin Monnet <qmo@qmon.net>
@qmonnet qmonnet force-pushed the pr/qmonnet/handle-default branch from 647b8ad to 3b75fa7 Compare January 19, 2026 13:28
@qmonnet
Copy link
Member Author

qmonnet commented Jan 19, 2026

There's a bug in the logic, I need to address it.

Now fixed, and validated with a test.

I'm working on the NAT parts.

Make sure that we account for "default" VpcExpose when we retrieve the
destination VPC discriminant for the packet.

Internally, we don't add a prefix for the default destination into the
tables, because we'd have to handle overlap to some extent. Instead, we
add a per-source-prefix value to use as a fallback when no other
destination prefix match.

At the moment, the code assumes that each VPC accepts at most one
"default" destination.

Signed-off-by: Quentin Monnet <qmo@qmon.net>
Copy link
Contributor

@mvachhar mvachhar left a comment

Choose a reason for hiding this comment

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

This PR looks good, but I just want a discussion of the multiple defaults first.

pub fn empty() -> Self {
Self::default()
}
#[must_use]
Copy link
Contributor

Choose a reason for hiding this comment

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

Is the assumption that there is only a single default valid even in the presence of stateful NAT? For example, if connections originate from the default blocks, then stateful NAT would be able to resolve any ambiguity. What should the right behavior be in that case here? Should we just leave the destination vpc field empty? Do we have to handle that case now?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes, the code assumes that there is a single default at the moment. We still need to add the appropriate validation for that.

For example, if [...]

Not supported at the moment. Having multiple defaults would typically require a step to disambiguate the destination VPC - but we haven't thought out all the details yet. We could also rely on stateful NAT, but this is not the case at the moment (and not everybody agrees about it).

Should we just leave the destination vpc field empty

No, at the moment the destination VPC field is never empty when the packet leaves the flow-filter stage (unless we drop the packet). Note that following the change of rules regarding overlapping prefixes, we removed the code for setting the destination VPC from stateful NAT (69a5f6b).

Do we have to handle that case now?

I'd definitely defer to a future release rather than trying to hack something quick here, it feels like it requires more thinking at the moment.

Copy link
Contributor

Choose a reason for hiding this comment

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

Is the assumption that there is only a single default valid even in the presence of stateful NAT? For example, if connections originate from the default blocks, then stateful NAT would be able to resolve any ambiguity. What should the right behavior be in that case here? Should we just leave the destination vpc field empty? Do we have to handle that case now?

We could handle multiple defaults, but we'd probably need to augment the API to do the "right" thing. This was mentioned / asked in githedgehog/gateway#275 but there was no real discussion IIRC

Add unit test cases to validate the behaviour in the case of
default-destination VpcExpose objects. In such case, NAT must use the
relevant default destination to find what transformation rules it should
apply.

As it turns out, there is no change required in the code for NAT:

- For stateful NAT:
    - We don't currently support destination NAT with stateful NAT. So
      when a packet is sent to a default-destination VPC, we may apply
      stateful NAT for the source as usual, and won't apply destination
      NAT in the case of the default.
    - When the packet comes back, we have an entry in the session table
      so there's no need to look at the context from the config anyway.

- For stateless NAT, the stage does not enforce any validation on
  whether packets match existing local and remote prefixes (this is the
  role of the flow-filter stage instead). When we reaching the stateless
  NAT stage we already know the destination VPC (also from the
  flow-filter stage): if we find no matching prefix for destination NAT,
  we do not NAT. Given that default-destination VPCs don't support NAT,
  we're good.

Signed-off-by: Quentin Monnet <qmo@qmon.net>
@qmonnet qmonnet force-pushed the pr/qmonnet/handle-default branch from 96ec87f to 32803f2 Compare January 19, 2026 16:08
@qmonnet
Copy link
Member Author

qmonnet commented Jan 19, 2026

@Fredi-raspall I kept but changed your commit to keep just one line of log per lookup, let me know if you really prefer your version.

@qmonnet qmonnet marked this pull request as ready for review January 19, 2026 16:09
@qmonnet qmonnet requested a review from a team as a code owner January 19, 2026 16:09
@qmonnet
Copy link
Member Author

qmonnet commented Jan 19, 2026

NAT needed no change after all, it looks like this is ready for review 🎉

@Fredi-raspall
Copy link
Contributor

@Fredi-raspall I kept but changed your commit to keep just one line of log per lookup, let me know if you really prefer your version.

I preferred mine (even if more verbose) because I dislike debug prints

Be more explicit in the stateless NAT lookups, especially if those
do not provide a value.

Signed-off-by: Fredi Raspall <fredi@githedgehog.com>
Signed-off-by: Quentin Monnet <qmo@qmon.net>
@qmonnet qmonnet force-pushed the pr/qmonnet/handle-default branch from 32803f2 to 07b892f Compare January 19, 2026 16:20
@qmonnet qmonnet added the ci:-upgrade Disable VLAB upgrade tests label Jan 19, 2026
@qmonnet
Copy link
Member Author

qmonnet commented Jan 19, 2026

Discussed today in meeting - We support at most one default exposed to any given VPC for now, we'll open an issue to track support for multiple default.

@qmonnet qmonnet force-pushed the pr/qmonnet/handle-default branch from bf1f81b to 07b892f Compare January 19, 2026 18:08
@qmonnet qmonnet merged commit d99888b into pr/fredi/expose_refined Jan 19, 2026
46 of 51 checks passed
@qmonnet qmonnet deleted the pr/qmonnet/handle-default branch January 19, 2026 21:01
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) ci:-upgrade Disable VLAB upgrade tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants