Skip to content

OpenVMM prerequisite: fixed NIC with pre-vCPU mutable policy on platform restore #536

Description

Parent: #535. Parallel OpenVMM prerequisite 6b. VMM implementation/review belongs in nanvix/openvmm. This prerequisite closes on VMM policy and restore-barrier tests; #543 pins the combined VMM revision and proves guest-activated NVX network/proxy/forward behavior. Its end-to-end gate is not a prerequisite for starting #543. Current nvx::host::network omits a NIC for absent or simple deny-all networking, and OpenVMM restores the saved NIC/egress-policy identity exactly. Existing host-loopback/ingress work (#512 and #495) and optional guest ingress Rust port #533 do not make policy-independent restore work.

Missing VMM contract

  • Add an explicit template topology mode: capture one fixed NIC with deny-all connectivity, stable identity/MMIO/IRQ/geometry and no tenant policy. The saved MAC, IPv4/IPv6 address/prefix and gateway identity are immutable template-key inputs; a different address family/CIDR requires another compatible template or an explicit fail-closed mismatch, not guest-only address rewriting. Ordinary no-network cold boots still omit the NIC.
  • Version only the platform-template restore contract to replace egress, host-loopback, proxy and forward policy while preserving device topology. Lift snapshot/restore host-loopback and forward restrictions only for this new template contract; do not capture tenant routes or weaken old snapshots. Construct/enforce deny-all before any restored vCPU executes; atomically create the authorized requested policy/listeners before releasing that barrier. A failed listener bind or policy install aborts restore. Guest-side DNS/proxy activation is later configuration, not the VMM enforcement boundary. If a policy publishes guest listeners to private/host-loopback peers, version an optional announcement mode (none/private/host-loopback): install its VMM listener policy before vCPUs run and announce from the guest after that enforcement is active. No ingress daemon starts for no-network cases; reuse optional Port nvx-ingress to Rust #533 where needed rather than requiring it for every launch. Coordinate one combined template ABI with the image-slot and aggregate changes microvm: at a platform restore, attach an aggregate export to the dormant filesystem slot #540/nvx-rs: reuse a platform template across mapped paths and network policies #543.
  • A no-network restore retains the fixed NIC but keeps it unconfigured and deny-all. Policy installation, authorization or version failures terminate the restore; no stale/permissive policy and no silent cold fallback. Preserve exact-match checks for old/workload snapshots. No device hotplug.

Acceptance

  • VMM tests prove packets cannot escape under the capture/restore barrier, including an install failure and a restore requesting no connectivity.
  • Same immutable template restores with two different authorized policies and with deny-all, without changing its NIC identity.
  • VMM restore tests exercise egress, host-loopback, proxy, forwards and optional private/host-loopback ingress, including mismatched saved addressing/IPv6 family, listener bind failure and packets before release of the vCPU barrier; host-policy vectors match VMM enforcement. nvx-rs: reuse a platform template across mapped paths and network policies #543 owns the combined NVX pin and real guest-activated end-to-end proof.
  • Keep this independent of the dormant aggregate change: the two VMM prerequisites can be developed/reviewed separately before full template acceptance.

Activity

  1. ppenna commented on Oct 23, 2026

    @ppenna
    Contributor

    Folding in #799, which asked for the same change and is now closed as a duplicate of this issue. These are its code-level notes, with corrections from review. OpenVMM links use 79a501b6, the revision that NVX's dev pins, and NVX links use dev at 2df68ba9.

    Gates that refuse a new policy today. None of them depends on the tier.

    1. Option validation refuses --network-ingress allow, --host-loopback allow, and --host-loopback-forward with --snapshot-destination or --restore-snapshot (cli_args/microvm.rs#L731-L739, #L1225-L1229, #L1239-L1247). It runs with the saved machine contract at hand, but not the tier, which only the manifest records. validate_early_options also refuses explicit host loopback right after argument parsing, before the snapshot is opened (lib.rs#L2754).
    2. validate_microvm_network_policy requires the saved policy mode, digest, and active flag.
    3. validate_restore_contract builds the expected contract from the restore-time policy, and the comparison checks the whole network record (microvm.rs#L1626-L1629).

    Already in place. The endpoint isn't snapshot state: Consomme has no save or restore code. The device installs the restore-time policy when it's built (virtio_net/src/lib.rs#L618), and the endpoint binds every explicit forward when it's resolved (resolver.rs#L67-L109). Both happen before any vCPU runs, so a busy forward port already fails the restore. Whether the endpoint consumes listener announcements follows the policy (egress.rs#L893-L908).

    Eligibility from the digest. #799 proposed deciding eligibility from saved state alone, without a manifest change: rebuild the canonical complete deny-all policy (host loopback denied, no proxy, no ingress) for the saved identity, compare its digest with the saved one, and require the platform tier. The explicit template mode of this issue is the alternative. With the digest:

    • Require encoding version 3 or later. Versions 0 to 2 encode neither the host-loopback action nor the proxy endpoint, and under version 1, deny-all with and without a proxy hash the same.
    • Plain --network-egress deny leaves host loopback allowed, so its digest isn't a complete deny-all's, although the policy drops every guest frame either way (egress.rs#L1253-L1258). As this issue notes, nvx::host::network attaches no NIC for a deny-all policy that denies host loopback, and when host loopback is left to OpenVMM, it attaches one with plain --network-egress deny (mod.rs#L660-L683). The digest rule alone would therefore admit no template that NVX launches today.
    • Check the restore-time policy against the saved identity, not the saved encoding version. Ingress and explicit host loopback need encoding version 5, which a version 3 or 4 snapshot can't represent (canonical_bytes_for_version).

    Not enough on its own.

    Snapshots without a tier have the same rule, and neither this issue nor #543 covers them. #800 tracks them, together with an nvx run bug that keeps it from restoring any snapshot that has a NIC.

  2. esaurez commented on Oct 24, 2026

    @esaurez
    ContributorAuthor

    This issue is now a child of #835, the OpenVMM stage of platform clones (#833), and #850 brings it into the shared libraries. Its body predates the current design, and its parent, #535, is closed. Could it be aligned with #835's description? In short:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

No labels
No labels

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions