Pr/fredi/masquerade timeouts#1501
Pr/fredi/masquerade timeouts#1501Fredi-raspall wants to merge 15 commits intopr/fredi/fix_dockerfilefrom
Conversation
Nat the first packet of a port-forwarded flow using the state created. This helps in consistency and in exposing a single method to nat a packet. Signed-off-by: Fredi Raspall <fredi@githedgehog.com>
Signed-off-by: Fredi Raspall <fredi@githedgehog.com>
Let masquerading and port forwarding use the same type for actions. Signed-off-by: Fredi Raspall <fredi@githedgehog.com>
Signed-off-by: Fredi Raspall <fredi@githedgehog.com>
Write packet port-forwarding utils using the new pattern matching. Return failures as errors and log them. Signed-off-by: Fredi Raspall <fredi@githedgehog.com>
The utils: - use the new pattern matching - distinguish between source and destination address/port nat. Signed-off-by: Fredi Raspall <fredi@githedgehog.com>
Use the new functions based on header pattern matching to masquerade flows. Signed-off-by: Fredi Raspall <fredi@githedgehog.com>
Rename: PortFwFlowStatus -> NatFlowStatus AtomicPortFwFlowStatus -> AtomicNatFlowStatus .. so that the same types can be used for masquerading Signed-off-by: Fredi Raspall <fredi@githedgehog.com>
Moves the types renamed in the prior commit to common/ so that they can be used for masquerading. Note that while the types are moved, the uses of the types and semantics may be NAT flavor specific. In other words, only the types are moved but not some of the implementations. Signed-off-by: Fredi Raspall <fredi@githedgehog.com>
Add field status with type AtomicNatFlowStatus to the masquerade states created for the flow pair to masquerade traffic. Signed-off-by: Fredi Raspall <fredi@githedgehog.com>
Adds simple flow status state machines for masqueraded flows.
With the state machine defined:
1) icmp traffic can only be oneway or twoway. The timeout for
icmp traffic will not configurable by the user.
2) UDP traffic can be in oneway, twoway or established (3 way).
Only when reaching established flow timeouts will be the ones
configured by the user.
3) TCP traffic uses the same SM as for port-forwarding, reversed.
Until flows reach established state, their timeouts will not
be the user configured ones.
Signed-off-by: Fredi Raspall <fredi@githedgehog.com>
- Set the initial timeout for a masqueraded flow. - Update FlowStatus of masqueraded flows according to SM and proto. - Set subsequent flow timeouts depending on the FlowStatus. Signed-off-by: Fredi Raspall <fredi@githedgehog.com>
Allow "patching" the flow status depending on the application. This is only implemented for DNS and relying on transport ports as application identifiers. Signed-off-by: Fredi Raspall <fredi@githedgehog.com>
There was a problem hiding this comment.
Pull request overview
This PR refactors stateful NAT masquerading to include a shared flow-status state machine and protocol-aware timeout behavior, while also unifying several NAT/port-forwarding types and packet header access patterns.
Changes:
- Introduces shared NAT types (
NatAction,NatFlowStatus,AtomicNatFlowStatus) and applies them across port-forwarding and masquerading. - Adds masquerade-specific protocol/state-machine logic and rewrites packet mangling using the newer header pattern-matching API.
- Adjusts flow timeout behavior for masqueraded flows (pre-establishment vs established, DNS special-casing, etc.) and updates related formatting/logging.
Reviewed changes
Copilot reviewed 21 out of 22 changed files in this pull request and generated 10 comments.
Show a summary per file
| File | Description |
|---|---|
| net/src/packet/mod.rs | Updates TryHeaders/TryHeadersMut impls to return concrete Headers. |
| net/src/headers/mod.rs | Changes TryHeaders/TryHeadersMut traits to return &Headers / &mut Headers. |
| net/src/flows/flow_key.rs | Removes Uni wrapper doc example. |
| net/src/flows/flow_info.rs | Adds tracectl trace target initialization; adjusts flow invalidation logging. |
| net/src/flows/display.rs | Tweaks flow display formatting strings. |
| net/Cargo.toml | Adds linkme and tracectl dependencies for net crate usage. |
| nat/src/stateful/state.rs | Unifies masquerade action type with NatAction and adds shared atomic flow status + translation view helper. |
| nat/src/stateful/protocol.rs | New masquerade flow-status state machine (UDP/TCP/ICMP + DNS special handling). |
| nat/src/stateful/packet.rs | New masquerade packet rewrite implementation using header pattern matching. |
| nat/src/stateful/nf.rs | Integrates masquerade status machine and internal timeouts into the stateful NAT datapath. |
| nat/src/stateful/mod.rs | Wires in new packet and protocol modules. |
| nat/src/stateful/flows.rs | Updates to use unified NatAction. |
| nat/src/portfw/test.rs | Updates tests to use unified NatFlowStatus instead of portfw-specific status type. |
| nat/src/portfw/protocol.rs | Replaces portfw-specific status machine types with NatFlowStatus (and updates logic). |
| nat/src/portfw/packet.rs | Refactors portfw NAT packet mangling to return typed errors and use header pattern matching. |
| nat/src/portfw/nf.rs | Updates port-forwarding NF to handle new nat_packet() error-returning API and unified action type. |
| nat/src/portfw/icmp_handling.rs | Updates ICMP error handling to use unified NatAction and new nat_packet() Result API. |
| nat/src/portfw/flow_state.rs | Unifies port-forward flow state action/status types with new shared NAT types. |
| nat/src/port.rs | Adjusts NatPort display formatting. |
| nat/src/lib.rs | Adds new common module and removes Clone from NatTranslationData. |
| nat/src/common/mod.rs | New shared NAT action/status/atomic types for both masquerade and port-forwarding. |
| Dockerfile | Changes runtime user directive from USER root to numeric USER 0. |
| Cargo.lock | Updates lockfile for new dependencies. |
| /// Perform src or dst nat for a packet, depending on the action indicated in state | ||
| pub(crate) fn nat_packet<Buf: PacketBufferMut>( | ||
| pub fn nat_packet<Buf: PacketBufferMut>( | ||
| packet: &mut Packet<Buf>, | ||
| state: &PortFwState, | ||
| ) -> bool { | ||
| ) -> Result<bool, NatPacketError> { | ||
| match state.action() { | ||
| PortFwAction::DstNat => dnat_packet(packet, state.use_ip().inner(), state.use_port()), | ||
| PortFwAction::SrcNat => snat_packet(packet, state.use_ip(), state.use_port()), | ||
| NatAction::DstNat => dnat_packet(packet, state.use_ip().inner(), state.use_port()), | ||
| NatAction::SrcNat => snat_packet(packet, state.use_ip(), state.use_port()), | ||
| } |
There was a problem hiding this comment.
confidence: 10
tags: ["logic", "style"]nat_packet is declared pub but lives in a private module (portfw::packet is not public). This will trigger the unreachable_pub lint (and fail under -D warnings). Make the function pub(crate)/pub(super) (or expose the module intentionally) to match its actual visibility requirements.
| ) -> Result<(), NatPacketError> { | ||
| debug!("Natting packet using {xlate} (masquerading flow)"); | ||
| match xlate.action { | ||
| NatAction::SrcNat => snat(packet, xlate.use_ip.try_into().unwrap(), xlate.nat_port), // FIXME |
There was a problem hiding this comment.
confidence: 9
tags: ["logic", "style"]masquerade() uses xlate.use_ip.try_into().unwrap() to obtain a UnicastIpAddr for SNAT. This can panic if use_ip isn’t unicast (and the comment indicates this is known). Prefer making unicast-ness an invariant (e.g., store UnicastIpAddr in NatTranslate/MasqueradeState for SNAT) or return a typed error instead of unwrapping.
| NatAction::SrcNat => snat(packet, xlate.use_ip.try_into().unwrap(), xlate.nat_port), // FIXME | |
| NatAction::SrcNat => { | |
| let src_ip: UnicastIpAddr = xlate | |
| .use_ip | |
| .try_into() | |
| .map_err(|_| NatPacketError::UnsupportedTraffic)?; | |
| snat(packet, src_ip, xlate.nat_port) | |
| } |
There was a problem hiding this comment.
Yup, forgot to address the fixme
- fix displays for clearer logs - remove duplicate logs - add tracing target to net/flows. We can't have linkme as a dependency of net, so we declare the target in flow-entry on behalf of net. Signed-off-by: Fredi Raspall <fredi@githedgehog.com>
Signed-off-by: Fredi Raspall <fredi@githedgehog.com>
be4f7fc to
4d91336
Compare
Fixes: https://github.com/githedgehog/internal/issues/364
NOTE: this targets #1499