Skip to content

flofi reworked#1636

Draft
daniel-noland wants to merge 16 commits into
mainfrom
flofi-2
Draft

flofi reworked#1636
daniel-noland wants to merge 16 commits into
mainfrom
flofi-2

Conversation

@daniel-noland

Copy link
Copy Markdown
Collaborator

No description provided.

qmonnet and others added 16 commits July 8, 2026 19:35
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>
@coderabbitai

coderabbitai Bot commented Jul 15, 2026

Copy link
Copy Markdown

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: c2a84809-8b8d-4def-a6a2-8152aa9a9144

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Comment @coderabbitai help to get the list of available commands.

@qmonnet

qmonnet commented Jul 16, 2026

Copy link
Copy Markdown
Member

@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:

  • Rebased on main
  • Some minor fixes for Display, and to have the dataplane compile with Loom/Shuttle
  • More importantly, I renamed flofi as flow-filter (and the corresponding types Flofi* as FlowFilter*), and removed all references to flofi, including in your commits.
  • The rest of your commits should be unchanged

As discussed before, the name flofi was temporary, but I didn't expect you'd build that much code on top of my branch. Can you please use the new one going forward?

@qmonnet qmonnet left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

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.

Comment thread acl/Cargo.toml

[features]
default = []
default = ["dpdk"]

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

What's the consequence of this change, does it mean the dataplane needs to prepare the DPDK components by default?

Comment thread acl/src/dpdk/dyn_table.rs
}

// ---------------------------------------------------------------------------------------------
// SPIKE: de-risk the flofi two-table redesign field encoding (see flofi/docs/two-table-redesign.md).

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We should probably not reference “flofi”, see my comment above - I created a new branch and cleaned these up.

Comment thread flofi/README.md
Comment on lines +8 to +11
`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?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

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.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

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);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We have an identical PORT_RANGE_WILDCARD in lpm/src/prefix/with_ports.rs

Comment on lines +87 to +89
const PROTO_TCP: u8 = 6;
const PROTO_UDP: u8 = 17;
const PROTO_OTHER: u8 = 0;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Nit: I have something like this instead for the user ACL PR:

Suggested change
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)

@qmonnet

qmonnet commented Jul 16, 2026

Copy link
Copy Markdown
Member

Rebased and somewhat reworked in #1638

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.

2 participants