Skip to content

Conversation

FelixMcFelix
Copy link
Collaborator

@FelixMcFelix FelixMcFelix commented Aug 21, 2023

This PR uses the presence of a min-sized Geneve TLV to detect packets on a given VNI which are originally external to the rack. To correctly filter such traffic at the firewall, the semantics of the Address::Vni host filter have changed to mean 'internal traffic on this Vni'. Accordingly, I've added simple option parsing/emission.

This will require changes to Dendrite to correctly emit the new option on any SNAT transformations on ingress to the rack, as well as an OANA registration for option type 0.

Aims to fix #380 (in tandem with oxidecomputer/dendrite#606).

@FelixMcFelix FelixMcFelix marked this pull request as ready for review August 23, 2023 20:44
@FelixMcFelix FelixMcFelix requested a review from luqmana August 25, 2023 10:28
Comment on lines 382 to 385
// XXX: This is now slightly overloaded to mean "packet
// originated from the VPC which has this VNI".
// Unsure if we want to have sled agent add a
// VNI && (not external) predicate.
Copy link
Contributor

Choose a reason for hiding this comment

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

I think that's fine, the user facing firewall API doesn't even deal in VNI's directly, but rather VPC originated traffic and sled-agent translates it to the corresponding VNI.

If we did want to separate out things a bit, perhaps instead we could add a new meta tag to indicate internal/external and then update the predicate generated for Address::Vni:

            (_, Address::Vni(vni)) => Some(Predicate::And(
                Predicate::Meta(ACTION_META_EXTERNAL.to_string(), "false".to_string()),
                Predicate::Meta(ACTION_META_VNI.to_string(), vni.to_string()),
            )),

(Predicate::And doesn't exist but i imagine would be straight forward)

Otherwise, I would at the very least add a comment here explaining why we only conditionally add ACTION_META_VNI.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Thanks, Luqman -- I'll explain this via comment for now, though I may have one or two tweaks after testing with sidecar-lite!

Copy link
Contributor

@luqmana luqmana left a comment

Choose a reason for hiding this comment

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

Thanks Kyle. Pending testing end-to-end, looks good.

Comment on lines +397 to +404
/// Geneve options defined by Oxide, [`GENEVE_OPT_CLASS_OXIDE`].
#[non_exhaustive]
pub enum OxideOption {
/// A tag indicating that this packet originated from outside the VPC.
///
/// Option Type `0`. Currently includes no body.
External,
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Need to update https://github.com/oxidecomputer/oana#geneve-options with the new option type.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Okay, I have a PR opened.

Integrates some simple handling to ensure that received packets:
* Don't have obvious opt-length violations,
* Don't have any critical options unknown to OPTE,
* Feed relevant data into `GeneveMeta`.
I've added one option, `(0x0129, 0x00)` to provisionally test tagging &
filtering VPC-external packets as needed by #380.

I'm not currently emitting any options from `GeneveMeta` back into wire
format, since this first option should not likely be emitted by OPTE.
Simplest possible solution: we change the meaning of the VNI match
rule to 'traffic originated on this VNI'. The gating factor is that
packets do *not* have the `(0x0129, 0x00)` Geneve TLV appended to them.
This seems to play nicely with the full test suite, but needs the
requisite Dendrite changes.

As an alternative, we could modify sled-agent to push 'VNI = x' and
'Origin = internal', but that would maybe require more far reaching
changes (and a new rule definition).
The remaining integration tests had some outbound->inbound
interactions that we probably wanted to capture and test the new logic
on -- this appears to capture UFT entries allowing reply traffic as
required.
@FelixMcFelix FelixMcFelix merged commit f1967a5 into master Sep 13, 2023
@FelixMcFelix FelixMcFelix deleted the tagged-external-pkts branch September 13, 2023 22:32
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.

Firewall rules using VPC as target should allow/deny traffic based on private IP, not external IP
2 participants