Skip to content

network: compile policy files through public egress rules - #1298

Draft
Enrique Saurez (esaurez) wants to merge 1 commit into
esaurez/slim-2.1.2-sl2.4d-20261105from
esaurez/slim-4.3.1-sl6.7a-20261105
Draft

Enrique Saurez (esaurez) wants to merge 1 commit into
esaurez/slim-2.1.2-sl2.4d-20261105from
esaurez/slim-4.3.1-sl6.7a-20261105

Conversation

@esaurez

@esaurez Enrique Saurez (esaurez) commented Nov 6, 2026 •

Copy link
Copy Markdown
Contributor

Part of #1124

What and why

Build on #1293: policy files now construct the existing
public EgressRule, Destination, and PortSelector values and compile
each action through NetworkPolicy::native_egress_rules().

The reader no longer imports private address or lowering types. It retains
both flat and MXC JSON forms, CIDR spellings and exclusions, protocol and
port semantics, canonical native output, and every existing limit.
Actions still compile independently so allow errors precede deny errors.
Earlier CIDR errors retain precedence over later JSON-field errors, parsing
errors precede native-output budgets, and flat-rule diagnostics keep their
original field paths.

The public parser avoids merging a single destination that is already
normalized, preserving the existing merge-work bound. The lowerer loses
only reader-specific input helpers. There is no second compiler, new public
API, visibility change, or change to shared normalization results.

Tests

check_test_changes.py against the PR base reports one modified existing
test helper and three added tests
; this PR carries tests-modified.

The existing properties::lower_lifted helper now converts the reader's
public rules through the existing public-rule parser before invoking its
original test-only lifted-budget lowerer. Its limit, independent reference
model, generators, canonicality/redundancy checks, packet equivalence,
action independence, and all assertions remain unchanged. No old test is
retired or weakened.

New owning-module unit tests:

  • both_forms_build_public_rules: both JSON forms preserve destinations,
    exceptions, protocol selectors, and unexpanded port ranges in public values.
  • cidr_errors_precede_later_json_errors: earlier malformed addresses or
    exclusions retain precedence and original flat/MXC field paths.
  • parsing_precedes_native_budgets_and_allow_precedes_deny: malformed input
    wins over an already-exceeded native budget, without a partial rule
    accidentally subsuming the earlier rules; allow still precedes deny.
Existing policy tests kept, by name

policy/tests.rs:

test_compiles_inclusive_tcp_and_udp_ranges
test_lowers_each_range_to_one_native_range_rule
test_keeps_a_denied_port_inside_an_allowed_range
test_merges_adjacent_and_overlapping_ranges_of_one_network
test_keeps_network_range_whole_when_adjacent_rule_changes_union
test_rejects_invalid_port_shapes_and_values
test_reports_invalid_port_ranges_clearly
test_compiles_protocol_selectors_with_and_without_ports
test_protocol_wide_rules_cover_their_port_rules_only
test_address_only_rules_cover_protocol_wide_rules
test_protocol_wide_rules_share_the_native_rule_budget
test_normalizes_host_bits_like_the_native_cidr_parser
test_subtracts_rule_local_cidr_exclusions
test_compiles_mxc_destination_and_port_unions
test_deduplicates_overlapping_exclusions_and_collapses_safe_prefixes
test_rejects_exclusions_outside_parent_or_wrong_family
test_compiles_ipv6_networks_with_every_selector
test_compiles_one_allowed_ipv6_network_with_a_denied_address
test_flat_rules_accept_ipv6_networks
test_keeps_each_address_family_separate
test_lowers_the_destinations_of_each_family_separately
test_subtracts_ipv6_exclusions
test_rejects_ipv6_scopes
test_both_families_share_the_native_rule_budget
test_rejects_invalid_mxc_rule_shapes
test_rejects_unknown_and_malformed_fields
test_rejects_duplicate_json_fields
test_empty_destination_does_not_expand_port_range
test_limits_the_actual_policy_read
test_reports_oversized_json_integer_rejection
test_many_source_networks_can_collapse_within_native_budget
test_accepts_exact_256_rule_boundaries
test_rejects_257_rules_before_materializing_them
test_overlapping_segments_do_not_inflate_native_rule_budget
test_bounds_exclusions_times_port_segments
test_delays_fragment_conversion_until_after_covering_union
test_validates_redundant_rules_before_canonicalization
test_address_only_rule_covers_large_protocol_range
test_address_only_rule_prunes_redundant_port_events_before_sweep
test_partial_address_only_coverage_keeps_protocol_union_compact
test_partial_address_only_canonicalization_does_not_bridge_gaps
rules_share_their_destinations_among_their_selectors

policy/tests/grammar.rs:

the_root_is_an_object_of_allow_and_deny_arrays
rules_are_objects
mxc_and_flat_fields_do_not_mix
unknown_fields_are_refused
fields_appear_once
destinations_need_one_cidr_string
cidrs_are_ipv4_or_ipv6_networks
host_bits_are_cleared
ipv6_scopes_are_refused
exceptions_lie_within_their_network_and_family
protocols_are_tcp_udp_icmp_or_any
ports_need_tcp_udp_or_any
ports_are_integers_from_1_to_65535
end_ports_follow_their_ports
destinations_and_ports_are_nonempty_arrays
each_action_lowers_to_at_most_256_native_rules
unreadable_files_fail_with_an_io_error
files_are_at_most_1_mib
files_are_utf8
files_are_json
arrays_and_objects_nest_at_most_32_deep

policy/tests/properties.rs:

policies_lower_to_canonical_rules_that_match_exactly
order_repetition_and_halves_change_no_lowering
broken_policies_compile_or_fail
policy_files_compile_as_the_format_reads_them
arbitrary_bytes_compile_or_fail
crowded_actions_are_refused_exactly_when_they_need_more_than_256_rules
networks_at_the_ends_of_each_family_have_the_properties

policy/tests/model.rs:

the_model_reads_cidrs_as_the_format_documents
the_model_reads_native_rules_back_as_written
the_model_finds_differences_redundancy_and_uncanonical_rules

policy/tests/generator.rs:

files_are_written_as_json_dumps_writes_them
the_model_reads_every_spelling_as_its_network

policy/json/tests.rs:

repeated_fields_name_their_object
nesting_is_limited
only_rfc_8259_json_is_read
values_read_as_serde_json_reads_them
documents_name_their_root
objects_with_the_number_field_stay_objects_with_arbitrary_precision
numbers_read_alike_with_arbitrary_precision

Validation

Qualification uses a clean local merge of this PR's unchanged head with
256ebe3dd9c23f20da94503b55d678d1193e392d. Earlier results on the original
base are historical, not substitutes for these runs.

Check Result
Windows: complete applicable Rust action, all five warning-denied Clippy feature configurations, all-features/default/no-feature tests, docs, MSRV, real synthetic-release bundling, protocol-only/host-only runtime adapter configurations PASS
Linux: complete Rust action, both API snapshots, macOS cross-check, musl guest lint/build/integration checks, all three runtime adapter configurations PASS
OpenVMM protocol vectors and CPU profiles, both platforms PASS
Linux quality action: Ruff, both Pyright platforms, Markdown links, test layout, kernel configuration, pinned ShellCheck/shfmt, 25 Specula wiring tests and PowerShell syntax PASS
Linux Python CLI modules, adversarial tooling, host-profile resolver and all CLI helps PASS: 1810 tests (35 platform skips), 84 tests, 4 tests
Windows Python CLI modules PASS: all 1810 tests (67 platform skips)
Windows adversarial tooling, host-profile resolver and all CLI helps PASS: 84 tests (11 Linux-only skips), 4 tests
Native guest binaries, Alpine image and static runtime adapter guest, built from the merged sources PASS; current-source image validation on both platforms
WHP: complete affected network/egress and public sandbox selection PASS: all 15 in one uninterrupted run
WHP canonical runtime adapter PASS: all 156 scenarios of 11 targets, serial, none ignored
MSHV: complete affected selection and canonical runtime adapter PASS: all 15; all 156 scenarios of 11 targets, serial, none ignored
Independent read-only source review No significant findings after correcting the new budget-precedence proof
GitHub Copilot review of 5190a0c10525577155e4a5446cde148475bc3b20 Clear: no active review issues or unresolved threads

The WHP selection comprises directional-network-policy,
host-loopback-policy, private-network-ingress, ipv6-egress-policy,
l3-l4-egress-policy, l3-l4-egress-port-ranges,
l3-l4-egress-protocols, network-snapshot, endpoint-policy-snapshot,
untiered-network-policy, platform-network-policy, managed-exec-config,
sandbox-lifecycle, sandbox-proxy-only, and sandbox-ram-upper.

Windows Python commands use native CPython 3.14.9. The unittest command
uses the standalone interpreter, task-local compatible dependencies, a
physical short temporary directory, and Git's usr\bin shell on PATH.
The adversarial command also uses the standalone interpreter; resolver
and help commands use a native virtual environment with the same shell
PATH. The first merged
unittest run reported a CSV replacement WinError 5 and is retained as a
failed attempt, not counted as a pass. A subsequent complete run reported
two Git shell timeouts. No tests or timeouts were relaxed.

The first WHP adapter run found a copied scratch template's inherited
read-only attribute and one time-repair failure. Only the workspace copy's
attribute was corrected; the immutable input and its digest were unchanged.
Both focused checks and a new complete 156-scenario run passed. The failed
full run is retained, not counted as green.

Both CLIs, guest binaries, Alpine image and static adapter executable were
built from the merged sources. OpenVMM and kernel inputs come from
v0.1.0-dev.256ebe3dd9c2, with OpenVMM
9cec2b89245f41f2126f9a787c5e43a0d84b7154. Every consumed input was
rehashed after copying; current runtime and kernel/Alpine/Ubuntu source
provenance validators passed on both platforms. No release CLI or guest
image replaced a candidate build.

CI's quality action runs only on Ubuntu (ci.yml, quality job). Its
Specula suite imports POSIX fcntl and is not applicable to native Windows.
Additional Windows lint/type/format and PowerShell syntax checks passed.

KVM execution and OpenVMM's upstream suites remain with their owning CI.
This PR does not claim the complete Ubuntu/Azure Linux runtime matrix.
No manual CI run, Ready transition, or merge is requested.

Build the existing destination and port selector values from both JSON forms, and use the native egress query for each action. Preserve field diagnostics, parsing precedence, canonical rules and resource limits without exposing the private lowerer.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: be2e3770-0238-43d9-9d0a-2302f94943ff
@esaurez Enrique Saurez (esaurez) added the tests-modified Changes existing tests, test data, or test wiring label Nov 6, 2026
@github-actions

github-actions Bot commented Nov 6, 2026

Copy link
Copy Markdown
Contributor

This pull request changes existing tests

It modifies or removes 1 existing test asset(s), listed below. Review each with care: a change to a test can hide a regression that the test caught. See doc/contribute.md#changes-to-existing-tests.

Test code

Change What Before After
modified helper fn lower_lifted in host::network::policy::tests::properties nvx-rs/src/host/network/policy/tests/properties.rs:128 nvx-rs/src/host/network/policy/tests/properties.rs:128

Relocated unchanged: 0; added: 3. Compared the merge base 059fd784e110 with 5190a0c10525.

Copilot AI left a comment

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.

🟢 Approval recommended

No active review issues are identified for the policy-file reader refactor.

No open issues 🎉

What changed in this PR

Refactors the policy-file reader to build public egress rules and compile them through NetworkPolicy::native_egress_rules(). This advances #1124’s separation of CLI policy parsing from private network internals without changing visibility or adding public API.

Changes:

  • Routes flat and MXC JSON policies through public rule types while preserving diagnostics and compilation limits.
  • Avoids redundant normalization for single destinations and removes reader-specific lowering helpers.
  • Adapts the property-test helper and adds tests for public rule construction and error precedence.
File Description
nvx-rs/​src/​host/​network/​rule.rs Skips redundant grouping for a single normalized destination.
nvx-rs/​src/​host/​network/​policy/​tests/​properties.rs Converts public rules before invoking the lifted-budget test lowerer.
nvx-rs/​src/​host/​network/​policy/​tests.rs Adds rule-construction and diagnostic-precedence tests.
nvx-rs/​src/​host/​network/​policy/​mod.rs Builds public rule values and compiles actions through the public query.
nvx-rs/​src/​host/​network/​lowering.rs Removes input helpers no longer needed by the reader.

Review effort: Balanced

This branch has not been deployed

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

Labels

feat-nvx-refactor tests-modified Changes existing tests, test data, or test wiring

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants