-
Notifications
You must be signed in to change notification settings - Fork 9
Filter and detect external traffic using Geneve option tags #383
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
Conversation
lib/oxide-vpc/src/engine/overlay.rs
Outdated
// 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. |
There was a problem hiding this comment.
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
.
There was a problem hiding this comment.
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!
There was a problem hiding this 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.
/// 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, | ||
} |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
58aad26
to
eaa7ce7
Compare
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).