docs(architecture): ADR 0018 — Hermit raw NIC access strategy (Proposed) - #4
Closed
LeTuR wants to merge 1 commit into
Closed
docs(architecture): ADR 0018 — Hermit raw NIC access strategy (Proposed)#4LeTuR wants to merge 1 commit into
LeTuR wants to merge 1 commit into
Conversation
Phase-1 PR B research (against the live `hermit-os/kernel` HEAD, 2026-05-25) confirmed that upstream Hermit exposes no public API for raw L2 frame access — every relevant type (`NetworkDriver` trait, concrete drivers, the `NIC` static holding the smoltcp `Interface`) is `pub(crate)`, and the application-facing `hermit-abi` surface is strictly POSIX sockets (no `AF_PACKET`, no `SOCK_RAW`). This is incompatible with ADR 0017's "smoltcp wire layer only, app owns the data path" without an additional decision: do we fork upstream, switch substrates, or relax the architecture? ADR 0018 records the research finding and proposes the path forward. The recommendation is **a minimal fork of `hermit-os/kernel`** that flips three `pub(crate)` items to `pub` and adds a `take_nics()` accessor — ~50 lines of delta — pinned via `[patch.crates-io]`. This preserves every reason ADR 0017 was made (Rust-native, single toolchain, kernel-space app, smoltcp::wire available) while unblocking phase-1 PR B/C. Four alternatives are weighed and rejected: revert to Unikraft, custom no_std + virtio-pmd, wait for upstream PR, or relax to Hermit's std::net (which fundamentally can't satisfy a forwarding device). Each rejection cites the specific architecture requirement(s) it would violate. ADR 0017 gets a forward-pointer to 0018 in its header so readers see the open question alongside the original decision. Status: Proposed — the ADR ends with three confirmation questions for the deciders. Until those are answered, phase-1 PRs B and C are on hold.
Owner
Author
|
Closing — superseded by a substrate-pivot ADR (Hermit's lack of public raw-frame access is being treated as a substrate mismatch, not a patch-able gap). New ADR coming on a fresh branch. |
3 tasks
LeTuR
added a commit
that referenced
this pull request
May 25, 2026
Phase-1 PR B research found that upstream `hermit-os/kernel` does not expose a public raw-frame API — every relevant layer is `pub(crate)` and the application-facing `hermit-abi` is POSIX sockets only. A firewall is a forwarding device; the socket layer terminates flows and cannot pass them through. The previous draft of ADR 0018 (closed PR #4) proposed forking hermit-os/kernel. That's been rejected on reconsideration: a fork papers over a substrate mismatch (Hermit's model is "app uses network stack"; ours is "app IS network stack") rather than fixing the underlying choice. This ADR pivots the substrate back to **Unikraft** (the original ADR 0001 choice) while keeping Rust as the application language and smoltcp::wire as the parser library. Both of those clauses from ADR 0017 stay live; only the Hermit substrate clause is superseded. The two reasons ADR 0017 cited for choosing Hermit over Unikraft don't survive contact with the implementation: - "Rust-native single toolchain" was true but the Rust we'd write has to fight Hermit's design intent. - "Unikraft's value-add (C library catalog) is mostly libs we no longer use" was wrong: we DO want one specific piece — `lib-uknetdev` — which is exactly the raw-frame device API the thurward data path needs per ADR 0013 and chapter 02. Four alternatives weighed and rejected: fork hermit-os/kernel, distroless Linux + Rust + AF_PACKET, wait for upstream Hermit PR, MirageOS. Each rejection cites the architecture requirement(s) it would violate or the asymmetric cost. Status: Proposed. The ADR ends with three confirmation questions for the deciders. On acceptance, a follow-up PR updates ADR 0017 (status note), ADR 0001 (status note), the chapter docs that name Hermit specifically, ADR 0010's supply-chain section, and the in-progress `versions.lock` (currently lists Hermit TBDs from PR #3).
LeTuR
added a commit
that referenced
this pull request
May 25, 2026
Phase-1 PR B research found that upstream `hermit-os/kernel` does not expose a public raw-frame API — every relevant layer is `pub(crate)` and the application-facing `hermit-abi` is POSIX sockets only. A firewall is a forwarding device; the socket layer terminates flows and cannot pass them through. The previous draft of ADR 0018 (closed PR #4) proposed forking hermit-os/kernel. That's been rejected on reconsideration: a fork papers over a substrate mismatch (Hermit's model is "app uses network stack"; ours is "app IS network stack") rather than fixing the underlying choice. This ADR pivots the substrate back to **Unikraft** (the original ADR 0001 choice) while keeping Rust as the application language and smoltcp::wire as the parser library. Both of those clauses from ADR 0017 stay live; only the Hermit substrate clause is superseded. The two reasons ADR 0017 cited for choosing Hermit over Unikraft don't survive contact with the implementation: - "Rust-native single toolchain" was true but the Rust we'd write has to fight Hermit's design intent. - "Unikraft's value-add (C library catalog) is mostly libs we no longer use" was wrong: we DO want one specific piece — `lib-uknetdev` — which is exactly the raw-frame device API the thurward data path needs per ADR 0013 and chapter 02. Four alternatives weighed and rejected: fork hermit-os/kernel, distroless Linux + Rust + AF_PACKET, wait for upstream Hermit PR, MirageOS. Each rejection cites the architecture requirement(s) it would violate or the asymmetric cost. Status: Proposed. The ADR ends with three confirmation questions for the deciders. On acceptance, a follow-up PR updates ADR 0017 (status note), ADR 0001 (status note), the chapter docs that name Hermit specifically, ADR 0010's supply-chain section, and the in-progress `versions.lock` (currently lists Hermit TBDs from PR #3).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Phase-1 PR B research surfaced a real architectural blocker: upstream
hermit-os/kerneldoes not expose any public API for raw L2 frame access. Every relevant type (NetworkDrivertrait, concrete drivers, theNICstatic holding the smoltcpInterface) ispub(crate). The application-facinghermit-abisurface is strictly POSIX sockets — noAF_PACKET, noSOCK_RAW, no FFI hatch.This is incompatible with ADR 0017's "smoltcp wire layer only, app owns the data path" without an additional decision.
This PR records the finding and proposes the path forward as a Proposed ADR. Implementation (PR B/C) is on hold until this lands as Accepted.
The recommendation
Fork
hermit-os/kernelat v0.13.2 with a minimal patch (~50 lines):pub(crate)→pub(theNetworkDrivertrait and the device statics)pub fn take_nics() -> Vec<Box<dyn NetworkDriver>>accessor[patch.crates-io]inCargo.tomlThis preserves every reason ADR 0017 was made (Rust-native, single toolchain, kernel-space app, smoltcp::wire available, QEMU/KVM + Firecracker deployment targets) while unblocking phase-1 PR B/C.
Alternatives weighed and rejected
Open question for deciders
The ADR ends with three confirmation questions:
forks/hermit-kernel/subtree + a[patch.crates-io]line pinning a thurward-controlled fork?Once accepted, ADR 0017's "Consequences" section gets a pointer here and ADR 0010's supply-chain section documents the new
versions.lockfield.Test plan