Repository navigation
network: support IPv6 in the portable profile and its egress policies - #455
Merged
Pedro Henrique Penna (ppenna) merged 5 commits intoOct 10, 2026
Conversation
Contributor
There was a problem hiding this comment.
🟡 Changes recommended
The branch currently conflicts with dev, and its IPv6 documentation incorrectly omits the automatically generated link-local address.
3 open findings
What changed in this PR
Adds dual-stack networking and IPv6-aware egress policies across NVX, its guest, OpenVMM integration, and sandbox API.
Changes:
- Enables and configures deterministic guest IPv6 identities.
- Supports family-separated IPv4/IPv6 policy compilation and enforcement.
- Adds unit, snapshot, and cross-backend IPv6 acceptance coverage.
- Pins OpenVMM PR #126 (
4f7306e9b), stacked on open PR #124.
| File | Description |
|---|---|
aci_edge_sandboxes/README.md |
Documents dual-stack sandbox networking. |
aci_edge_sandboxes/model/src/cidr.rs |
Generalizes CIDR operations to IPv6. |
aci_edge_sandboxes/src/openvmm/config.rs |
Documents derived IPv6 configuration. |
aci_edge_sandboxes/src/openvmm/mod.rs |
Updates backend capability documentation. |
aci_edge_sandboxes/src/openvmm/network.rs |
Expands IPv6 policy rules for OpenVMM. |
aci_edge_sandboxes/tests/openvmm_e2e.rs |
Adds IPv6 policy enforcement tests. |
aci_edge_sandboxes/tests/openvmm_fake.rs |
Verifies generated IPv6 arguments. |
aci_edge_sandboxes/tests/validation.rs |
Accepts valid IPv6 policy inputs. |
doc/design/cold-boot.md |
Documents IPv6 boot parameters. |
doc/design/integrated-implementation-status.md |
Records dual-stack implementation status. |
doc/design/machine-and-device-abi.md |
Defines the IPv6 network ABI. |
doc/design/validation.md |
Describes IPv6 validation coverage. |
doc/guests/ubuntu-guest.md |
Updates Ubuntu networking requirements. |
doc/run.md |
Documents IPv6 identities and rules. |
doc/usage.md |
Updates CLI networking reference. |
guest/common/init |
Configures the guest IPv6 address and route. |
kernel/config-microvm |
Enables IPv6 without SIT tunneling. |
openvmm |
Pins IPv6-capable OpenVMM revision. |
scripts/nvx.py |
Updates IPv6 policy CLI help. |
scripts/nvx_tools/build.py |
Validates required network kernel options. |
scripts/nvx_tools/build_constants.py |
Defines required network configuration. |
scripts/nvx_tools/egress_policy.py |
Compiles IPv4 and IPv6 policy files. |
scripts/nvx_tools/microvm_test_scripts/host-loopback-policy.sh.in |
Detects dual-stack listeners. |
scripts/nvx_tools/microvm_test_scripts/ipv6-egress-policy.sh.in |
Probes IPv6 policy behavior. |
scripts/nvx_tools/microvm_test_scripts/ipv6-egress-snapshot.sh.in |
Tests IPv6 across restore. |
scripts/nvx_tools/microvm_test_scripts/virtio-net.sh |
Checks the guest IPv6 identity. |
scripts/nvx_tools/microvm_tests.py |
Adds the IPv6 acceptance scenario. |
scripts/nvx_tools/release.py |
Verifies release kernel networking options. |
scripts/test_egress_policy.py |
Tests IPv6 policy compilation. |
scripts/test_microvm_tests.py |
Tests IPv6 scenario orchestration. |
scripts/test_nvx_tools.py |
Tests kernel configuration assertions. |
🧠 Review effort: Balanced
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Pedro Henrique Penna (ppenna)
force-pushed
the
agents/fix-issue-280-add-tests-validate-implementation
branch
from
October 9, 2026 20:00
76491f3 to
f6490cb
Compare
Pedro Henrique Penna (ppenna)
force-pushed
the
agents/fix-issue-280-add-tests-validate-implementation
branch
from
October 9, 2026 20:38
f6490cb to
c34e2b4
Compare
Pedro Henrique Penna (ppenna)
force-pushed
the
agents/fix-issue-280-add-tests-validate-implementation
branch
from
October 9, 2026 20:59
c34e2b4 to
3a35b9b
Compare
Pedro Henrique Penna (ppenna)
force-pushed
the
agents/fix-issue-280-add-tests-validate-implementation
branch
from
October 9, 2026 22:54
3a35b9b to
758e77f
Compare
Pedro Henrique Penna (ppenna)
force-pushed
the
agents/fix-issue-280-add-tests-validate-implementation
branch
from
October 9, 2026 23:38
758e77f to
5a71fd6
Compare
Contributor
There was a problem hiding this comment.
🔵 Needs a closer look
The cross-repository networking and ABI change depends on open OpenVMM PR #126, while exact-head OpenVMM CI remains in progress.
0 open findings
1 resolved since last review
🧠 Review effort: Balanced
Pedro Henrique Penna (ppenna)
force-pushed
the
agents/fix-issue-280-add-tests-validate-implementation
branch
from
October 10, 2026 00:08
5a71fd6 to
019122f
Compare
e5bf79776 (nanvix/openvmm#126), on top of the port ranges that dev pins, makes the portable profile's NIC dual-stack. OpenVMM derives the IPv6 identity from the IPv4 one by embedding the guest and gateway addresses in fd00::/96 with a prefix of 96 plus the IPv4 prefix, so --net 10.0.0.2/24 gives the guest fd00::a00:2/120 behind fd00::a00:1, and it passes the identity to the guest as the virtnet_ip6= and virtnet_gw6= kernel tokens, which callers may not supply. Consomme answers Neighbor Discovery and ICMPv6 echo for the gateway, which shares the IPv4 gateway's MAC address, and maps the gateway's TCP and UDP flows onto ::1 when host loopback is allowed. It drops IPv4-mapped destinations, which host dual-stack sockets would otherwise follow to IPv4 addresses that the policy never checked, and no longer panics on a truncated ICMPv6 message. --network-egress-allow and --network-egress-deny accept IPv6 networks in the same CIDR[:PROTOCOL[:PORT[-PORT]]] form, such as 2001:db8::/32:tcp:443, 2001:db8::/32:tcp:8000-8010, or ::/0. A rule matches only destinations of its own family, deny rules still take precedence, and a deny default blocks the IPv6 traffic that no IPv6 rule allows; an IPv6 ICMP rule matches ICMPv6. The guest may only solicit neighbors: the gateway under an allow default or with an IPv6 allow rule, like ARP for the IPv4 gateway, and other on-link addresses that the rules admit. Packets with IPv6 extension headers are denied, and the legacy policy modes deny all IPv6. The guest names the IPv4 gateway as its DNS server when the policy allows DNS to it, and otherwise the IPv6 gateway when it allows DNS to that one, so a policy that allows DNS over IPv6 alone still gives the guest a resolver. Policies bound to the IPv6 identity use canonical encoding version 4, and snapshots record the identity, whose tokens platform-tier snapshots accept as platform configuration; a snapshot that predates IPv6 restores IPv4-only with its version-3 digest. run and sandbox pass these rules to OpenVMM unchanged, so the help of their --network-egress-allow and --network-egress-deny now names IPv4 or IPv6 CIDRs, the usage reference and the run guide document the rule families and the DNS server, and the cold-boot and machine ABI designs document the reserved tokens, the derived identity, the DNS server, and the policy. The guest kernel has no IPv6 yet, so guests ignore the new tokens until the next commit configures them. nvx.py verify passes with this pin. Part of #280. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The pinned OpenVMM gives the portable profile's NIC an IPv6 identity, but the microVM kernel was built without IPv6, so guests had no IPv6 path for the identity or for IPv6 egress rules (#280). The kernel now enables CONFIG_IPV6. It keeps CONFIG_IPV6_SIT, which IPv6 enables by default, disabled: SIT would add an sit0 device that decapsulates IPv6 from IPv4 packets, so the guest's interfaces stay lo and the NIC. The kernel build asserts the network configuration that the portable profile needs, CONFIG_INET, CONFIG_IPV6, CONFIG_VIRTIO_NET, and no SIT, in the generated configuration, and nvx.py verify checks it in the checked-in and the built configurations. The common init reads virtnet_ip6= and virtnet_gw6=. Before it brings the NIC up, it disables router advertisements, address autoconfiguration from them, and duplicate address detection on it, so that, besides the kernel's link-local address, the static identity is the link's only IPv6 configuration and is usable as soon as it is assigned. After the IPv4 configuration, it assigns the address and installs the IPv6 default route with busybox ip, which the Alpine, Ubuntu, and Azure Linux guests all ship, and reports a failure on the console like the IPv4 steps. Without the tokens, the guest configures IPv4 alone. The virtio-net scenario, which the Ubuntu and Azure Linux smoke tests also run, now checks the tokens and reads the kernel's address and route tables, so each guest's userland must have configured the identity. With IPv6, busybox nc listens on a dual-stack socket, which the kernel lists among IPv6 sockets, so the host-loopback-policy scenario now looks for its guest listener in /proc/net/tcp6 as well as /proc/net/tcp. Unit tests cover the network configuration assertion, the checked-in configuration, and that listener check. The run guide and the usage reference describe the dual-stack NIC, and the Ubuntu guest guide no longer lists IPv6 among the kernel features that it omits. Part of #280. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
An egress policy file accepted only IPv4 destinations and exclusions, so a policy could not allow or deny the IPv6 destinations that the pinned OpenVMM now filters (#280). A destination's cidr and its except entries may now be IPv6 networks, in the MXC shape and in the flat one, and each exclusion must belong to its destination's family. The destinations of each family in a rule lower to native rules of that family, and a rule without destinations now matches every IPv4 and IPv6 destination, as MXC specifies. Each family is lowered on its own, with the same canonical, covered-only widening, protocol coverage, port ranges, and rule-local exclusions as IPv4, and both families share the 256-rule limit of each action. Lowered rules list IPv4 before IPv6. Host bits are normalized like IPv4 ones, and IPv6 scope IDs are rejected, because native rules cannot carry them. Unit tests cover IPv6 destinations with each selector, one allowed IPv6 network with a denied address, the flat form with IPv6, the separation of the families between rules, within a rule's destinations, and in a rule's exclusions, IPv6 exclusions, scope IDs, the shared rule budget, and a rule without destinations, which now also lowers to ::/0. The run guide's schema, the usage reference, and the help of --network-egress-policy-file describe both families. Part of #280. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The OpenVMM backend rejected IPv6 network.egress destinations with policy_validation before provisioning, because OpenVMM's rules were IPv4-only. MXC allows both families (#280). The pinned OpenVMM accepts IPv6 rules, so the backend now expands them exactly like IPv4 ones: exceptions, which must belong to their destination's family, are subtracted from it, a port range becomes one OpenVMM range rule per network, and any with a port or a port range becomes a TCP and a UDP rule. A rule without destinations now matches every destination of both families, 0.0.0.0/0 and ::/0, where it matched IPv4 alone. The model's Cidr now represents either family, so both share the bounded subtraction, and expansions beyond 256 OpenVMM rules are still rejected. Unit tests cover IPv6 expansion with exceptions and mixed families, a rule without destinations, and IPv6 subtraction. The validation tests now accept IPv6 rules before probing and reject oversized expansions with separate port ranges instead, and the fake OpenVMM test checks that IPv6 rules reach OpenVMM's command line beside IPv4 port ranges. The new end-to-end test ipv6_network_policies_are_enforced probes TCP to the gateway's DNS service over IPv4 and IPv6 under eight policies: an allow default, an IPv6 and an IPv4 rule that each admit only their own family, the ::/0 wildcard, a rule without destinations, an IPv6 rule for another network, deny precedence for the IPv6 gateway, and an IPv6 deny rule under an allow default. The README and the backend's documentation describe the dual-stack NIC and the gateway that the guest names as its DNS server. Part of #280. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
No scenario sent IPv6 traffic through the portable profile or checked that egress rules filter it (#280). The ipv6-egress-policy scenario, in the default suite, boots one guest per case through the public nvx.py run, with an MXC-shaped egress policy file and ingress denied. The guest first requires the virtnet_ip6= and virtnet_gw6= tokens and finds its address and IPv6 default route in the kernel's tables, so a guest without a working IPv6 stack fails before it probes, and reports the DNS server that its resolver names, which the harness compares with the case's: the IPv4 gateway when the policy allows DNS to it, otherwise the IPv6 gateway when it allows DNS to that one, and none otherwise. It then probes TCP on a named port and on the next one, UDP on the named port, and ICMPv6 echo toward the IPv6 gateway, and TCP on the named port over IPv4, and the harness requires exactly the case's traffic to pass: the guest reports each TCP response and ping, and the host observes each TCP connection and UDP datagram on ports that it reserves on ::1 and 127.0.0.1. The cases are an allow default without rules, which must pass every probe, a deny default without rules, which must block both families, IPv6 rules for one TCP port, for a range of TCP ports, which lowers to one native range rule, and for UDP and ICMP, deny precedence within ::/0, a rule for one TCP port without destinations, which must admit that port in both families as MXC specifies, IPv4 rules under a deny default that must not admit IPv6, and an IPv6 deny rule under an allow default that must not block IPv4. The scenario then captures a guest whose only rule admits IPv6 TCP to the named port once it has reached the host, requires OpenVMM to reject a restore with the IPv4 rule for the same port, and restores the snapshot with the original rule, after which the guest must reach the host over IPv6 again. Finally, OpenVMM must reject an IPv6 rule with a /129 prefix before boot. Each case's policy, its compiled OpenVMM rules, and the observations are recorded in ipv6-egress-policy-results.json. Unit tests cover the identity, the cases, their compiled rules and DNS servers, each case's public command and policy file, the snapshot and rejection commands, leaked and missed traffic on either side, an unexpected DNS server, a restore that accepts a changed policy or misses the host, both guest scripts under a POSIX shell, the port reservation with real sockets and without IPv6 loopback, and the scenario's dispatch. The validation design describes the scenario. Fixes #280. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Pedro Henrique Penna (ppenna)
force-pushed
the
agents/fix-issue-280-add-tests-validate-implementation
branch
from
October 10, 2026 00:10
019122f to
90efb16
Compare
Pedro Henrique Penna (ppenna)
deleted the
agents/fix-issue-280-add-tests-validate-implementation
branch
October 10, 2026 02:49
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.



Fixes #280 with nanvix/openvmm#126: the portable microVM network profile is dual-stack, and egress policies allow or deny IPv6 networks next to IPv4 ones, with deny precedence, family-separated rules, port ranges, and a deny default that blocks IPv6 too. The guest kernel and init configure the IPv6 identity,
runandsandboxpass IPv6 rules through, egress policy files compile IPv6 networks and exclusions in the MXC shape, where a rule withouttomatches both families,aci_edge_sandboxesexpresses IPv6 rules in OpenVMM, and a newtest-microvmscenario sends IPv4 and IPv6 traffic through allowed and denied paths.Why
The portable profile was IPv4-only. The guest kernel had no IPv6, the guest had no IPv6 identity, and OpenVMM's egress rules could name only IPv4 destinations: an active policy dropped every IPv6 frame, while an inactive one passed IPv6 to Consomme unfiltered, so no policy could admit an IPv6 destination or say how IPv6 relates to its IPv4 rules. Egress policy files rejected IPv6 networks, and the
aci_edge_sandboxesOpenVMM backend rejected them withpolicy_validation, although MXC'snetwork.egressrules name IPv4 or IPv6 CIDRs and a rule withouttomatches both families.Commits
24e187c86openvmm: pin IPv6 in the portable network profile and its egress rulese5bf79776runandsandboxhelp, the usage reference, and the run guide's native rule form and DNS server; the cold-boot and machine ABI designsf745c4201guest: configure the portable profile's IPv6 identityCONFIG_IPV6without SIT, asserted by the kernel build andnvx.py verify; the common init's static IPv6 address and default route;virtio-netchecks the identity on every guest;host-loopback-policyfinds its now dual-stack guest listener; the run guide, the usage reference, and the Ubuntu guest guide07c7506c6network: compile IPv6 networks in egress policiestocovers both families, and each family lowers, with port ranges as native range rules, within the shared 256-rule limits; the run guide's schema18a8a69c6aci_edge_sandboxes: express IPv6 egress rules in OpenVMMCidr; the validation, fake OpenVMM, and end-to-end tests; the README90efb165ctest-microvm: verify IPv6 egress policiesipv6-egress-policyscenario in the default suite, with MXC-shaped policy files, its unit tests, and the validation designEach commit passes
nvx.py verify, the NVX unit tests, and ruff on its own.Behavior
--net 10.0.0.2/24gives the guestfd00::a00:2/120behind the gatewayfd00::a00:1: the IPv6 identity embeds the IPv4 one in the unique local prefixfd00::/96. The guest configures it statically, without router advertisements, autoconfiguration from them, or duplicate address detection. Besides the kernel's EUI-64 link-local address, which OpenVMM admits only as the source of Neighbor Solicitations, such as Linux's unicast reachability probes, the guest's only IPv6 address is the unique local one, so standard address selection still prefers IPv4 for destinations that have both. The IPv6 gateway answers Neighbor Discovery and echo requests, serves DNS, and maps TCP and UDP to::1like the IPv4 gateway maps them to127.0.0.1.--network-egress allowwithout rulesdenywithout rulesdenywith2001:db8:1::/64:tcp:443allowed and2001:db8:1::123denied, the issue's example2001:db8:1::/64, except2001:db8:1::123denywith2001:db8::/32:tcp:8000-8010allowed2001:db8::/32denywith::/0alloweddenywith0.0.0.0/0alloweddenywith an MXC rule for TCP 443 withouttoallowwithfd00::/8deniedfd00::/8--allow-host,--block-host, or--allow-endpointA rule matches only its own family, deny rules take precedence, an IPv6 ICMP rule matches ICMPv6, and IPv6 rules take port ranges like IPv4 ones. Neighbor Discovery of the IPv6 gateway is allowed like ARP of the IPv4 gateway: under an
allowdefault or with any IPv6 allow rule. IPv6 packets with extension headers and IPv4-mapped destinations are never forwarded, since a dual-stack host socket would follow a mapped address to IPv4. The guest names the IPv4 gateway as its DNS server when the policy allows DNS to it, and otherwise the IPv6 gateway when the policy allows DNS to that one. A snapshot taken before this change keeps its policy digest and restores IPv4-only, and a platform-tier snapshot treats the IPv6 bootstrap tokens as platform configuration, like the IPv4 ones.The
ipv6-egress-policyscenario boots nine guests throughnvx.py runwith MXC-shaped policy files, with the guest at192.0.2.2/24, sofd00::c000:202/120behindfd00::c000:201. Each guest first finds its address and IPv6 default route in the kernel's tables, then probes TCP on a named port and on the next one, UDP on the named port, and ICMPv6 echo toward the IPv6 gateway, and TCP on the named port over IPv4. The scenario requires exactly the expected probes to pass and the expected DNS server, and its observations were identical on bare-metal KVM, MSHV, and WHP hosts and on a local WHP host:allow-all192.0.2.1deny-allallow-ipv6-tcp-portallow-ipv6-tcp-rangeallow-ipv6-udp-icmpfd00::c000:201deny-ipv6-tcp-port::/0; deny the IPv6 gateway on TCP, named portfd00::c000:201allow-tcp-port-without-totoallow-ipv4-only0.0.0.0/0192.0.2.1deny-ipv6-onlyfd00::/8192.0.2.1The host observed each TCP connection and UDP datagram in the ✓ cells and none in the ✗ cells; Consomme answers echo requests to the gateway itself, so only the guest observes ICMPv6. The results file records each case's compiled rules: the range case lowers to the single native rule
fd00::c000:201/128:tcp:20000-20001, and the rule withouttoto0.0.0.0/0:tcp:20000and::/0:tcp:20000. The scenario then snapshots a guest whose only rule admits IPv6 TCP to the named port, rejects a restore with the IPv4 rule for that port, and restores with the original rule, after which the guest reaches the host over IPv6 again. Finally, OpenVMM rejects an IPv6 rule with a/129prefix before boot.Review
nc -llisten on a dual-stack socket, whichhost-loopback-policylooked for only in/proc/net/tcp; it now reads/proc/net/tcp6too.dev,dd9744a8b. aci_edge_sandboxes: add settings for image references #452, doc: list every packaged guest artifact in the release layout #456, doc: describe the Azure Linux guest in the design #457, and doc: document source-collection prerequisites and release archives #458 and two baseline updates applied without conflicts, andgit range-diffshows each commit unchanged by that step; network: support MXC-shaped rule-local CIDR exclusions #447 and network: select egress traffic by destination-port range #451 needed the merges described here. The policy compiler parses the MXC shape for both families, where a rule withouttocovers0.0.0.0/0and::/0as MXC specifies, and lowers each family's port ranges to native range rules within the shared budget.aci_edge_sandboxesuses network: select egress traffic by destination-port range #451's range selectors with IPv6 networks, and its tests now reach the 256-rule limit with separate ports, since one range is one rule. The OpenVMM change is rebased onto net_backend_resources: select egress rules by destination-port range nanvix/openvmm#125, so IPv6 rules takePORT-PORTranges and the version 4 policy encoding tags each rule's family ahead of ci: materialize Windows release provenance from run head #125's range bytes. A code review of the rebased branch found no significant issues.autoconf=0only disables autoconfiguration from router advertisements. The init comment, the run guide, and the machine ABI now say so. The link-local address stays: Linux sends unicast reachability probes from it, and OpenVMM admits Neighbor Solicitations from it for that reason. The review also flagged validation of earlier pins that this description still named; the description now names the gitlink,e5bf79776, on which the validation below ran, and the scenario's range case exercises IPv6 port ranges end to end.snapshot-tierson every backend: a platform-tier capture rolled back, because OpenVMM's platform snapshot validation acceptedvirtnet_ip=but notvirtnet_ip6=orvirtnet_gw6=and so treated the dual-stack identity as tenant configuration. microVM: add IPv6 to the portable network profile and its egress rules nanvix/openvmm#126 now accepts the IPv6 tokens as platform configuration (e5bf79776), with a unit test that fails without the change, and the pin moved to it. Earlier attempts of that run failed only to pull images from Docker Hub, which rate-limited and timed out GitHub-hosted runners for about an hour; other pull requests failed the same way.Validation
e5bf79776:cargo nextestfornet_backend_resources,consomme,net_consomme,openvmm_defs,openvmm_helpers,openvmm_entry, andvirtio_net: 574 passed on Windows with Rust 1.95.0, and 622 passed, 1 skipped, on Linux onprometheus30.clippy --all-targets, rustdoc with-D warnings, andxtask fmtare clean for every modified package, andopenvmm_coreandpetritype-check. nanvix/openvmm has started none of its OpenVMM workflows since 2026-10-08, neither OpenVMM PR for [repo-status] NVX Daily Status Report - 2026-09-19 #126, even after reopening it, nor OpenVMM CI for themainpush of Harden source provenance integrity #124 and ci: materialize Windows release provenance from run head #125, so this PR's OpenVMM jobs carry the exact-pin CI.nvx.py verify; the validate-nvx unit suites, 858 tests on Windows and on Linux (prometheus32), withHOMEpointing to an empty directory so that a test that commits in a temporary repository does not inherit this machine's SSH commit signing, and the adversarial suite; ruff; and pyright for Linux and Windows. On5a71fd69a, whose tree differs from this head only indev's later baseline data and doc: document source-collection prerequisites and release archives #458's documentation: shellcheck and shfmt with the pinned images, the host-skill suite, and per-commit checks, in which each commit passesnvx.py verify, the unit suites, and ruff on its own. Foraci_edge_sandboxes, with aci_edge_sandboxes: add settings for image references #452's settings merged:fmt --all, clippy with-D warningsfor both feature sets, the tests (204 with all features, 141 with the defaults), the artifact bundling check, rustdoc with-D warnings, and the Rust 1.89 MSRV check.prometheus32KVM,prometheus30MSHV,prometheus28WHP), with OpenVMM built from the pin on each host, on758e77f7f, whose commitsgit range-diffshows identical to this head's, before the rebase onto aci_edge_sandboxes: add settings for image references #452 and later: the microVM steps that CI runs, that is, the full defaulttest-microvmsuite, which includesipv6-egress-policy, thel3-l4-egress-*scenarios,host-loopback-policy,network-snapshot, andsnapshot-tiers; managed sandbox acceptance (managed-exec-configandsandbox-lifecycle); CI's Ubuntu and Azure Linux sets; on KVM, CI's extended Ubuntu set; and the tennvx.py test-aci-edge-sandboxeshypervisor tests, includingipv6_network_policies_are_enforced. On5a71fd69a, after the rebase onto aci_edge_sandboxes: add settings for image references #452, doc: list every packaged guest artifact in the release layout #456, and doc: describe the Azure Linux guest in the design #457, the aci hypervisor tests, which exercise aci_edge_sandboxes: add settings for image references #452's agent change, andipv6-egress-policypassed again on all four hosts.ipv6-egress-policy's observations were identical everywhere. The kernel and initramfs artifacts were built withbuild-guest --guest all, which passed the new kernel configuration assertion, from this head's kernel and guest sources except the init comment; the Ubuntu distro layer and smoke scratch for sandbox acceptance came from CI.Dependencies
e5bf79776), the pinned revision, based on nanvix/openvmmmain(f4566bab0), whichdevpins. Merge it by fast-forwardingmain, as Harden source provenance integrity #124 and ci: materialize Windows release provenance from run head #125 were, so that the pin stays onmain.