Repository navigation
[DONT REVIEW] microVM: let a platform restore install a new network policy on a NIC template - #4767
Merged
Pedro Henrique Penna (ppenna) merged 2 commits intoOct 27, 2026
Conversation
A platform snapshot is a template that each clone restores, and a clone of a template with a NIC needs its own network policy. Restore requires the policy that the snapshot recorded, because the endpoint may have held flows, listeners, and forwards under it, and the guest may have learned a DNS server and announced its listeners under it. A NIC captured with a complete deny-all policy is different. The policy denies every guest frame, host loopback, and inbound access, and keeps no proxy endpoint, so the endpoint held no flows, listeners, or forwards, and the guest learned no DNS server and announces no listeners. Nothing in such a snapshot depends on the policy beyond the NIC's identity. Add microvm_network_template_policy, which binds that policy to a NIC's identity, as a capture with --network-egress deny and --host-loopback deny, without rules, a proxy, or ingress, records it. Add validate_microvm_network_replacement, which checks that a snapshot's network records exactly that policy for its own identity, and returns the policy for the restore contract, which keeps it whatever policy replaces it. The saved record must equal the template's in the encoding that the policy has today: version 3 without IPv6, or version 4 with it. Versions 0 to 2 encode neither the host-loopback action nor the proxy endpoint, so no snapshot that records one is a template, whatever its digest. A replacement keeps the captured identity, so it may name IPv6 destinations only when that identity has IPv6, rather than install rules that could never match. The manifest format does not change: a template is recognized from what every networked snapshot already records, including those captured before this change. Unit tests cover templates with and without IPv6, replacements that open every direction, the near misses (deny-all egress with host loopback, a proxy, ingress, host-loopback ingress, rules that deny every destination, and allow-all egress), the legacy encodings, a noncanonical identity, and IPv6 rules on templates with and without IPv6. See microsoft/nvx#536. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
A platform restore takes its NIC's identity from the snapshot and requires the captured policy, and every snapshot rejects private-network ingress, explicit host-loopback access, and host-loopback forwards, whose listeners and bound ports are live host attachments. One template therefore served one network policy, and none with inbound access. Add --restore-network-policy, with which a platform restore installs the network policy of its own options in place of the complete deny-all that its NIC template was captured with. The NIC keeps its captured identity: the restore binds the policy to it, as it binds a matching policy today, and still rejects --net. The same code as at a cold boot validates the policy, so the checks of its proxy, endpoints, rules, ingress, and forwards are a cold boot's, and only the IPv6 rule of validate_microvm_network_replacement is new. The device installs the policy when it is built, and the endpoint binds its forwards when it is resolved, both before any vCPU runs, so the restored guest never runs under the template's policy or a partial one, and a forward that cannot bind its port fails the restore. A restore that wants no connectivity passes the template's deny-all. The restore contract still compares the whole network record exactly: it expects the template's deny-all, which the record must hold, rather than the installed policy. The option therefore admits only a platform snapshot, which prepare_restore checks, with a NIC, which effective_microvm_network checks, whose record is the complete deny-all of its identity. Every other restore, of any tier, keeps the same-policy rule, and so does a template's restore without the option. With the option, a restore may also publish the guest's listeners and forward host ports: the snapshot refusals of --network-ingress allow, --host-loopback allow, and --host-loopback-forward admit such a restore, and keep refusing captures and every other restore. The option is refused on a cold boot, where clap's requirement of --restore-snapshot does not hold once --kernel is present, and on a standard machine. The guest keeps its captured command line, which has no virtnet_dns= or virtnet_ingress= token under a deny-all policy, so it learns its DNS server and whether to announce its listeners from its host after the restore. Unit tests cover the CLI rules, the restore's tier check, and restores of one template with eight policies: the template's deny-all, allow-all egress, IPv4 and IPv6 rules, exact endpoints, a proxy, explicit host loopback with TCP and UDP forwards, and private-network ingress with and without host loopback. Each installs the requested policy, keeps the identity, and expects the template's contract. They also cover the refusals of a snapshot that is not a template, of one without a NIC, of a proxy or endpoint that does not suit the captured identity, of a new address, and of IPv6 rules on a template that predates IPv6, and that a template's restore without the option keeps its policy. The CLI reference, the snapshot guide, and the snapshot format describe the option. See microsoft/nvx#536. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Pedro Henrique Penna (ppenna)
merged commit Oct 27, 2026
57d0a18
into
feature/microvm/dev
169 of 176 checks passed
Pedro Henrique Penna (ppenna)
added a commit
to microsoft/nvx
that referenced
this pull request
Oct 27, 2026
Record the two commits that the previous commit pins as positions 348 and 349 of the microVM chain, and move the NVX pin to d2338ea22. Position 348 pins amd.genoa.v2, a second revision of the Genoa CPU profile that position 282 pins, and makes CPUID 0x80000008 EDX a limit of the derivation policy of positions 159-269. Position 349 records the nested-WHP Genoa host that amd.genoa.v2 serves as a test fixture. They add to the CPU profile work that no PR maps yet rather than fix mapped work, so they join positions 158-333, 341-343, 346, and 347 as unassigned. Add them to the chain and to the table of the commits after the mapped tip, and extend the scope. The pin is now 192 commits past the mapped tip. Positions 346 and 347 are no longer only a proposal: microsoft/openvmm#4767 merged them, so position 347, 57d0a18b3, is the head of feature/microvm/dev. Say so in the scope, and name microsoft/openvmm#4769 as the proposal of positions 348 and 349. Part of #928 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This was referenced Oct 27, 2026
fork-updater Bot
pushed a commit
to sheeeng/microsoft-nvx
that referenced
this pull request
Oct 28, 2026
Pin microsoft/openvmm#4767 at 57d0a18b3b542dce3f0787e60f3c48296b40d30e, two commits on e68871cc6, the previous pin, which is the head of feature/microvm/dev. The first recognizes a NIC template: a platform snapshot whose NIC was captured with the complete deny-all policy, --network-egress deny and --host-loopback deny without egress rules, a proxy, or ingress. Its guest learned no DNS server and announces no listeners, and its endpoint held no flows, listeners, or forwards, so nothing in the snapshot depends on its policy beyond the NIC's identity. A snapshot's network record identifies a template only in digest encodings from version 3 on, since earlier ones record neither the host-loopback action nor the proxy endpoint. The manifest format does not change. The second adds --restore-network-policy, with which a platform restore installs the network policy of its own options in place of the template's deny-all, including private-network ingress, explicit host loopback, and host-loopback forwards, which snapshots refused. The same code as at a cold boot validates the policy, which is bound to the NIC's captured identity, and the device installs it, with its forwards bound, before any vCPU runs; a forward that cannot bind its port fails the restore. The restore contract still compares the whole network record, against the template's deny-all. Captures, other tiers, and restores without the option keep the same-policy rule. Part of microsoft#536 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
fork-updater Bot
pushed a commit
to sheeeng/microsoft-nvx
that referenced
this pull request
Oct 28, 2026
Record the two commits that the previous commit pins as positions 346 and 347 of the microVM chain, and move the NVX pin to 57d0a18b3. Position 346 recognizes a NIC template, a platform snapshot whose NIC was captured with the complete deny-all policy, from the policy digest that every networked snapshot records. Position 347 adds --restore-network-policy, which installs a restore's own policy on such a template. They add behavior rather than fix a mapped commit, and they change the snapshot network policy and the forward refusal that PR21's position 129 added and the snapshot refusals of the unassigned positions 306 and 307, so they stay unassigned, like positions 341-343. Note in the table's remarks that assigning them means revisiting that work. The pin is now 190 commits past the mapped tip. Positions 344 and 345 are no longer only a proposal: microsoft/openvmm#4762 merged them, so position 345, e68871cc6, is the head of feature/microvm/dev. Say so in the scope, and name microsoft/openvmm#4767 as the proposal of positions 346 and 347. Part of microsoft#536 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This was referenced Oct 29, 2026
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.
Lets a microVM platform restore install a network policy of its own in place of the complete deny-all policy that its NIC template was captured with, before any vCPU runs, including private-network ingress, explicit host-loopback access, and host-loopback forwards, for microsoft/nvx#536. This is a new feature of the platform tier rather than a fixup.
Based on
feature/microvm/dev. This branch is two commits directly one68871cc6, the head offeature/microvm/devand the revision that NVX'sdevpins.A NIC template is a platform NIC captured with a complete deny-all (
3e3a454c5)Restore required the policy that a snapshot recorded, because its endpoint may have held flows, listeners, and forwards under it, and its guest may have learned a DNS server and announced its listeners under it. A NIC captured with a complete deny-all policy is different: the policy denies every guest frame, host loopback, and inbound access, and keeps no proxy endpoint, so nothing in the snapshot depends on it beyond the NIC's identity.
microvm_network_template_policybinds that policy to a NIC's identity, as a capture with--network-egress denyand--host-loopback deny, without rules, a proxy, or ingress, records it.validate_microvm_network_replacementchecks that a snapshot's network record is exactly that policy's for its own identity, in the encoding that the policy has today, version 3 without IPv6 or version 4 with it, and returns it for the restore contract. Versions 0 to 2 encode neither the host-loopback action nor the proxy endpoint, so no snapshot that records one is a template. A replacement keeps the captured identity, so it may name IPv6 destinations only when that identity has IPv6.The manifest format does not change: a template is recognized from what every networked snapshot already records, including those captured before this change.
--restore-network-policy(57d0a18b3)With the option, a platform restore installs the network policy of its own options in place of the template's deny-all:
--net.prepare_restorechecks, with a NIC, whicheffective_microvm_networkchecks, whose record is the complete deny-all of its identity.--network-ingress allow,--host-loopback allow, and--host-loopback-forwardadmit such a restore, and keep refusing captures and every other restore. Every other restore, of any tier, keeps the same-policy rule, and so does a template's restore without the option.--restore-snapshotdoes not hold once--kernelis present, and on a standard machine.The guest keeps its captured command line, which has no
virtnet_dns=orvirtnet_ingress=token under a deny-all policy, so it learns its DNS server and whether to announce its listeners from its host after the restore (microsoft/nvx#838 and microsoft/nvx#850).Tests
openvmm_helpers::snapshot::microvm:only_a_complete_deny_all_network_is_a_template(templates with and without IPv6; replacements that open every direction; deny-all egress with host loopback, a proxy, ingress, host-loopback ingress, rules that deny every destination, and allow-all egress; the legacy encodings, which the same-policy rule still accepts; a noncanonical identity) anda_template_replacement_names_ipv6_only_with_an_ipv6_identity.microvm::network:a_complete_deny_all_capture_records_a_template;a_template_restore_installs_a_new_policy_and_keeps_the_identity, which restores one template with eight policies (the template's deny-all, allow-all egress, IPv4 and IPv6 rules, exact endpoints, a proxy, explicit host loopback with TCP and UDP forwards, and private-network ingress with and without host loopback), each installing the requested policy, keeping the identity, and expecting the template's contract, and checks that a template's restore without the option keeps its policy;only_a_template_admits_a_new_policy; anda_template_restore_binds_its_policy_to_the_captured_identity(a proxy or endpoint that does not suit the identity, a new address, IPv6 rules on a template that predates IPv6).microvm::restore:only_a_platform_restore_replaces_the_network_policy, for every tier.cli_args::microvm:test_microvm_restore_network_policy_requires_a_microvm_restore, and the snapshot cases oftest_microvm_host_loopback_allow_publishes_guest_listenersandtest_microvm_private_network_ingress_publishes_guest_listeners, which now cover the restore with the option, including the early check that runs before the snapshot is opened.Validation
cargo clippy --all-targetsandcargo doc --no-depsforopenvmm_helpersandopenvmm_entry;cargo nextest run --profile agentfor both (335 passed); andcargo xtask fmt --fix(clean).platform-network-policymicroVM scenario, on Linux/MSHV, Linux/KVM, and Windows/WHP hosts: the scenario, which restores one NIC template with the template's deny-all, egress rules, explicit host loopback with a forward and private-network ingress, and a proxy, passes in 16.2, 13.6, and 37.6 s, and NVX's default microVM suite passes 40/40 on each. Every clone keeps the template's MAC, IPv4, and IPv6 addresses and reaches exactly what its policy admits, and the refused restores fail before the guest runs, the busy forward port withfailed to create socket for port forward. With the unpatchede68871cc6on KVM, the template's capture succeeds and the first clone's restore fails atunexpected argument '--restore-network-policy'.Notes