flofi reworked#1636
Conversation
Add helpers to tell whether a validated manifest and peering uses IPv4 or IPv6 prefixes. We just need to check the first expose of the manifest, and (respectively) one of the two manifests, because these objects have been validated so we know they all use the same IP version. Signed-off-by: Quentin Monnet <qmo@qmon.net>
We don't support peerings with two manifests using different IP versions for the prefixes in their expose blocks. We should reject it at validation time. We already validate that all expose blocks in a given manifest use the same IP version for their prefixes, so there's no additional verification required on that side. Update a test in nat crate where we use both IP versions in a peering. Signed-off-by: Quentin Monnet <qmo@qmon.net>
Add helpers to see if the NAT mode for an expose block allows it to initiate and/or be at the receiving end of a connection. We'll use this later to rework the flow-filter implementation. Signed-off-by: Quentin Monnet <qmo@qmon.net>
This will help us make the code simpler later when reusing this method. Signed-off-by: Quentin Monnet <qmo@qmon.net>
We'll use this helper when reworking the flow-filter code. Signed-off-by: Quentin Monnet <qmo@qmon.net>
In preparation for using port ranges with ACL tables, implement trait From to convert types with ports into RangeSpec<u16> elements. Signed-off-by: Quentin Monnet <qmo@qmon.net>
This is a new, simpler version of the flow-filter, the main changes being that the logic has been simplified, because we can get rid of the logic regarding the "multiple matches" used by the legacy implementation, and the use of ACL tables for the lookups. The new stage is not plugged into the datapath pipeline, yet. Signed-off-by: Quentin Monnet <qmo@qmon.net>
Signed-off-by: Quentin Monnet <qmo@qmon.net>
Signed-off-by: Quentin Monnet <qmo@qmon.net>
Swap the flow-filter stage for its new, ACL-based implementation, but do not delete the legacy implementation (and setup) just yet. Signed-off-by: Quentin Monnet <qmo@qmon.net>
Add a bitmask field kind (value + mask) to the `MatchKey` derive and its companion `*Rule` type, alongside exact/prefix/range. A field matches when `input & mask == value & mask`, so a full mask is an exact match and a zero mask is a wildcard -- letting a single key field express "any" without fanning rules across separate tables. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Signed-off-by: Daniel Noland <daniel@githedgehog.com>
…ACL keys net: `#[repr(u8)]` on `Icmp4Type`, `TcpPort::MIN`/`MAX`, and `FixedSize` support so header field types can be packed into ACL key bytes. lpm: `From` impls building `RangeSpec<u16>` from prefix/port types. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Signed-off-by: Daniel Noland <daniel@githedgehog.com>
…Lookup Add a non-default `reference` cargo feature and gate the linear-scan reference backend behind it, so production builds link only the rte_acl backend. Share `DpdkAclLookup` via `Arc<dyn DynClassifier>` and derive `Clone` so a built classifier can be cheaply shared across pipeline workers. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Signed-off-by: Daniel Noland <daniel@githedgehog.com>
`flofi_two_table_key_shapes_build_and_classify`: proves an rte_acl key can carry a masked proto byte, one or two exact `u32` VNI fields, and v4/v6 prefix + port range, and that single and batched lookups classify correctly. `flofi_build_capacity_probe` (`#[ignore]`): characterizes build cost for disjoint vs overlapping rule sets, to inform a config-layer rule-count cap. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Signed-off-by: Daniel Noland <daniel@githedgehog.com>
Replace the per-VPC / per-protocol fan-out with four wide ACL tables (`{remote, local} x {v4, v6}`): source VPC, destination VPC and L4 protocol become key fields (exact / mask) rather than table-selection dimensions, so one rte_acl call resolves a heterogeneous batch. Routing is a two-stage lookup (destination -> peer + dst NAT, then source -> src NAT); a default expose lowers to a lowest-priority `/0` rule so longest-prefix-match handles it. `process` collects each rx burst and runs the lookups in batched rte_acl calls, partitioning by IP version without reordering output. The rte_acl backend is production; a linear-scan reference backend is the `cfg(test)` differential oracle. See `flofi/docs/two-table-redesign.md`.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Daniel Noland <daniel@githedgehog.com>
flofi now builds rte_acl classifiers when configuration is applied, which needs the EAL memory subsystem up. Initialize a minimal EAL (no hugepages / no PCI) early in `dataplane::main`, before `run_mgmt` applies the first config; the guard is held for the process. The real DPDK datapath driver must eventually take over EAL ownership (there is one `rte_eal_init` per process). The mgmt config-processor test starts the EAL for the same reason. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Signed-off-by: Daniel Noland <daniel@githedgehog.com>
|
Important Review skippedDraft detected. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Comment |
|
@daniel-noland I created a new branch: https://github.com/githedgehog/dataplane/tree/pr/qmonnet/flow-filter-v2 with my commits + your commits from this PR, with the following changes:
As discussed before, the name |
qmonnet
left a comment
There was a problem hiding this comment.
Here are some minor comments, but I haven't gone through - let alone assimilated - all the code changes yet, I'm still looking at this.
|
|
||
| [features] | ||
| default = [] | ||
| default = ["dpdk"] |
There was a problem hiding this comment.
What's the consequence of this change, does it mean the dataplane needs to prepare the DPDK components by default?
| } | ||
|
|
||
| // --------------------------------------------------------------------------------------------- | ||
| // SPIKE: de-risk the flofi two-table redesign field encoding (see flofi/docs/two-table-redesign.md). |
There was a problem hiding this comment.
We should probably not reference “flofi”, see my comment above - I created a new branch and cleaned these up.
| `flofi` is the pipeline stage that answers one question for every overlay packet: | ||
|
|
||
| > Given where this packet came from (source VPC + 5-tuple), **which destination VPC | ||
| > does it belong to, and what NAT does each end require** -- or should it be dropped? |
There was a problem hiding this comment.
That's actually two questions 🫣
| Some(vpcd) => writeln!(f, "default remote VPC: {vpcd}"), | ||
| None => writeln!(f, "default remote VPC: -"), | ||
| // ------------------------------------------------------------------------------------------------- | ||
| // Production (rte_acl / opaque): a one-line summary per table. |
There was a problem hiding this comment.
I don't understand that change, is this because we don't have a way to get more information from the ACL at runtime? Because if we have one, I'd prefer to get something more verbose to get a better idea of the table contents
| const PROTO_UDP: u8 = 17; | ||
| const PROTO_OTHER: u8 = 0; | ||
|
|
||
| const PORT_WILDCARD: RangeSpec<u16> = RangeSpec::new(0, u16::MAX); |
There was a problem hiding this comment.
We have an identical PORT_RANGE_WILDCARD in lpm/src/prefix/with_ports.rs
| const PROTO_TCP: u8 = 6; | ||
| const PROTO_UDP: u8 = 17; | ||
| const PROTO_OTHER: u8 = 0; |
There was a problem hiding this comment.
Nit: I have something like this instead for the user ACL PR:
| const PROTO_TCP: u8 = 6; | |
| const PROTO_UDP: u8 = 17; | |
| const PROTO_OTHER: u8 = 0; | |
| const PROTO_TCP: u8 = NextHeader::TCP.as_u8(); | |
| const PROTO_UDP: u8 = NextHeader::UDP.as_u8(); | |
| const PROTO_OTHER: u8 = 0; |
(requires marking as_u8() as const)
|
Rebased and somewhat reworked in #1638 |
No description provided.