Skip to content

packet patterns 🌶️ 🌶️ 🌶️#1463

Merged
mvachhar merged 2 commits intomainfrom
pr/daniel-noland/dis
Apr 15, 2026
Merged

packet patterns 🌶️ 🌶️ 🌶️#1463
mvachhar merged 2 commits intomainfrom
pr/daniel-noland/dis

Conversation

@daniel-noland
Copy link
Copy Markdown
Collaborator

@daniel-noland daniel-noland commented Apr 14, 2026

Match on the shape of a packet!

[!NOTE] I think this is the last round of significant structure changes before I can get down to cutting PRs for the ACL stuff 🥳


Adds headers::pat, a protocol-aware pattern matching API for Headers. The matcher chain uses Within<T> bounds (from #1445) to enforce valid layer ordering at compile time and runtime gap checks to catch silently skipped layers (e.g. an unaccounted-for VLAN between Ethernet and IPv4).

  • Both immutable (pat()) and mutable (pat_mut()) variants are provided, with mutable access via split borrows and split_first_mut no unsafe code is used (directly).
  • Embedded ICMP error payloads are reachable through .embedded() with a nested sub-tuple, supporting the NAT rewrite path required by RFC 5508. The abstraction is zero-cost: cargo-show-asm confirms the generated assembly is identical to hand-written code.
  • IPv6 extension headers are silently skipped by default from IP positions (the common case), but become strict once any extension is explicitly matched in the chain.
  • VLANs are always strict.
  • Optional methods (opt_*) distinguish "genuinely absent" from "wrong variant present": a wrong variant is a miss, not absence.
  • Utility combinators .when(), .inspect(), and .otherwise() are available at any chain position

@daniel-noland daniel-noland added the dont-merge Do not merge this Pull Request label Apr 14, 2026
@daniel-noland daniel-noland force-pushed the pr/daniel-noland/dis branch 6 times, most recently from c407b74 to 2d381d0 Compare April 15, 2026 04:28
@daniel-noland daniel-noland self-assigned this Apr 15, 2026
@daniel-noland daniel-noland changed the title dis packet (ai assisted, undergoing additional review by human coauthor) packet patterns! Apr 15, 2026
@daniel-noland daniel-noland removed the dont-merge Do not merge this Pull Request label Apr 15, 2026
Copy link
Copy Markdown
Collaborator Author

@daniel-noland daniel-noland left a comment

Choose a reason for hiding this comment

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

notes for agent

Comment thread net/src/headers/pat.rs Outdated
Comment thread net/src/headers/pat.rs Outdated
Comment thread net/src/headers/pat.rs Outdated
@daniel-noland daniel-noland requested a review from Copilot April 15, 2026 04:30
@daniel-noland daniel-noland added enhancement New feature or request ci:+vlab Enable VLAB tests labels Apr 15, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds protocol-aware “packet pattern” matching over Headers, using type-level layer adjacency (Within<T>) to enforce valid layer transitions at compile time while performing strict runtime gap checks for VLANs (and optionally IPv6 extensions).

Changes:

  • Moved Within<T> and all layer-ordering/conformance impls into a new headers::within module.
  • Added headers::pat providing immutable/mutable matchers (pat() / pat_mut()) plus embedded ICMP payload matching.
  • Adjusted visibility of EmbeddedHeaders fields to support matcher implementation.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
net/src/headers/within.rs Centralizes Within<T> trait + ordering/conformance graph (incl. IPv6 extensions + embedded headers).
net/src/headers/pat.rs Introduces the pattern-matching API, including mutable + embedded matchers and tests.
net/src/headers/mod.rs Wires in within and exposes the new pat module.
net/src/headers/embedded.rs Widens EmbeddedHeaders field visibility for matcher access.
net/src/headers/builder.rs Removes local Within definition/impls and re-exports the moved trait.

Comment thread net/src/headers/embedded.rs Outdated
Comment thread net/src/headers/pat.rs Outdated
Comment thread net/src/headers/pat.rs Outdated
Comment thread net/src/headers/pat.rs
Comment thread net/src/headers/pat.rs Outdated
@daniel-noland daniel-noland force-pushed the pr/daniel-noland/dis branch 2 times, most recently from 48cda1d to 8b1c7d6 Compare April 15, 2026 04:47
@daniel-noland daniel-noland requested a review from Copilot April 15, 2026 04:48
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.

Comment thread net/src/headers/pat.rs
Comment thread net/src/headers/pat.rs
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.

Comment thread net/src/headers/within.rs
Comment thread net/src/headers/pat.rs
Comment thread net/src/headers/pat.rs
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.

Comment thread net/src/headers/pat.rs Outdated
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.

Comment thread net/src/headers/pat.rs
/// been consumed (`net_ext.len() == ext_cursor`).
///
/// This is a sealed implementation detail -- all impls are provided by
/// this module and users never need to reference this trait directly.
Copy link

Copilot AI Apr 15, 2026

Choose a reason for hiding this comment

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

confidence: 8
tags: [docs]

ExtGapCheck is documented as a sealed implementation detail that users “never need to reference”, but it is declared pub inside the public headers::pat module, making it part of the crate’s public API surface. To keep the public API minimal (and align docs with reality), consider reducing its visibility (e.g., pub(crate)/pub(super)) and relying on the existing #![allow(private_bounds)], or keep it pub but add #[doc(hidden)] to avoid advertising it as public API.

Suggested change
/// this module and users never need to reference this trait directly.
/// this module and users never need to reference this trait directly.
#[doc(hidden)]

Copilot uses AI. Check for mistakes.
@daniel-noland daniel-noland force-pushed the pr/daniel-noland/dis branch 4 times, most recently from b650ad5 to fa8f1ae Compare April 15, 2026 05:56
@daniel-noland daniel-noland requested a review from Copilot April 15, 2026 05:56
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 4 out of 5 changed files in this pull request and generated 2 comments.

Comment thread net/src/headers/within.rs Outdated
Comment thread net/src/headers/pat.rs
@daniel-noland daniel-noland force-pushed the pr/daniel-noland/dis branch 2 times, most recently from 94dbfe4 to 138589d Compare April 15, 2026 06:07
daniel-noland and others added 2 commits April 15, 2026 00:09
Move the Within<T> trait and all layer-ordering impls out of the
feature-gated builder module into headers::within (always compiled).

Also:
- Add Within impls for Net/Transport enums (no-op conform) for
  enum-level pattern matching
- Add Within impls for EmbeddedHeaders (after Icmp4/Icmp6) and
  truncated transport types for embedded ICMP payload matching
- Add EmbeddedStart marker for embedded matcher entry position
- Re-export EmbeddedStart publicly from headers module
- Make EmbeddedHeaders.{net, net_ext, transport} pub(super) for
  the pattern matcher (narrowed from pub(crate))

The enum-level Within impls use no-op conform because the concrete
variant is unknown statically.  The builder is safe from these:
HeaderStack::stack additionally requires Blank, which enums do not
implement -- stacking Net or Transport directly is a compile error.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Daniel Noland <daniel@githedgehog.com>
Adds Matcher/MatcherMut builders for type-safe, adjacency-checked
packet header pattern matching, plus EmbeddedMatcher/EmbeddedMatcherMut
for mutable access to ICMP error payloads (required for NAT per
RFC 5508).

48 tests total: bolero fuzz tests for all positive/negative matching,
plus adversarial tests using HeadersBuilder to verify graceful behavior
on structurally broken headers (mismatched IP/ICMP versions, transport
without net, VLANs without net, embedded without ICMP, empty headers).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Daniel Noland <daniel@githedgehog.com>
@daniel-noland daniel-noland changed the title packet patterns! packet patterns 🌶️ 🌶️ 🌶️ Apr 15, 2026
@daniel-noland daniel-noland marked this pull request as ready for review April 15, 2026 06:10
@daniel-noland daniel-noland requested a review from a team as a code owner April 15, 2026 06:10
@daniel-noland daniel-noland requested review from qmonnet and removed request for a team April 15, 2026 06:10
Copy link
Copy Markdown
Contributor

@mvachhar mvachhar left a comment

Choose a reason for hiding this comment

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

Wow, there is a lot of tedious stuff in here. It looks reasonable, though I am relying on the fact that the tests pass rather than a detailed analysis of every case in the implementation. I'm unhappy about the tuple expansion stuff, but without variadic templates, there isn't much alternative. In the C++ world, this type of thing did pay off for Boost which had very ergonomic APIs. Eventually C++ added variadic templates and alot of the ugliness went away. I hope the same happens in Rust.

Comment thread net/src/headers/pat.rs
impl_tuple_append!(A, B, C, D, E, F, G, H, I, J, K, L, M);
impl_tuple_append!(A, B, C, D, E, F, G, H, I, J, K, L, M, N);
impl_tuple_append!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O);
impl_tuple_append!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I thought I was done with this crap. Rust needs variadic generics!

@mvachhar mvachhar added this pull request to the merge queue Apr 15, 2026
Merged via the queue into main with commit 606b21b Apr 15, 2026
26 of 28 checks passed
@mvachhar mvachhar deleted the pr/daniel-noland/dis branch April 15, 2026 22:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci:+vlab Enable VLAB tests enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants