Skip to content

feat(dhcp): hold IPv6 DNS resolvers in DhcpConfig alongside IPv4#2685

Closed
chet wants to merge 1 commit into
NVIDIA:mainfrom
chet:gh-issue-2638
Closed

feat(dhcp): hold IPv6 DNS resolvers in DhcpConfig alongside IPv4#2685
chet wants to merge 1 commit into
NVIDIA:mainfrom
chet:gh-issue-2638

Conversation

@chet

@chet chet commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds a parallel IPv6 nameserver field to the DhcpConfig the agent hands to forge-dhcp-server, so a host's IPv6 DNS resolvers have somewhere to live alongside the existing IPv4 carbide_nameservers.

  • dhcp_server_control.proto and the DhcpConfig model gain carbide_nameservers_v6 (field 9), with #[serde(default, skip_serializing_if = "Vec::is_empty")] so IPv4-only configs serialize byte-identically and configs written by older agents still deserialize.
  • Both gRPC conversions (From<ModelDhcpConfig> / TryFrom<proto::DhcpConfig>) handle the new field; the IPv4 path is untouched.
  • Tests cover the field round-tripping through serde and both proto conversions, including a malformed-address rejection.

This is plumbing ahead of a consumer — nothing reads the IPv6 field until the delivery channel lands (see #2644 / #1263).

Implements #2638. Part of the #2628 epic (dual-stack DNS resolver advertisement for IPv6).

Draft pending review.

@copy-pr-bot

copy-pr-bot Bot commented Jun 18, 2026

Copy link
Copy Markdown

Auto-sync is disabled for draft pull requests in this repository. Workflows must be run manually.

Contributors can view more details about this message here.

@coderabbitai

coderabbitai Bot commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 6214e5ac-b50b-447f-9084-84fe580c663a

📥 Commits

Reviewing files that changed from the base of the PR and between e1928f8 and 7e9c6c9.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (6)
  • crates/agent/src/dhcp_server_grpc_client.rs
  • crates/agent/src/ethernet_virtualization.rs
  • crates/dhcp-server/Cargo.toml
  • crates/dhcp-server/proto/dhcp_server_control.proto
  • crates/dhcp-server/src/grpc_server.rs
  • crates/rpc-utils/src/dhcp.rs
🚧 Files skipped from review as they are similar to previous changes (5)
  • crates/agent/src/dhcp_server_grpc_client.rs
  • crates/dhcp-server/proto/dhcp_server_control.proto
  • crates/rpc-utils/src/dhcp.rs
  • crates/agent/src/ethernet_virtualization.rs
  • crates/dhcp-server/src/grpc_server.rs

Summary by CodeRabbit

Release Notes

  • New Features

    • Added support for IPv6 DNS nameservers in DHCP configuration, enabling DHCPv6 DNS option support.
  • Tests

    • Added comprehensive test coverage for IPv6 nameserver validation and serialization behavior.

Walkthrough

The PR adds carbide_nameservers_v6 (a list of IPv6 DNS nameservers for DHCPv6 option 23) to the DhcpConfig proto message (field 9), the DhcpConfig Rust model struct in rpc-utils, the TryFrom conversion in the DHCP server gRPC handler, and the From conversion in the agent gRPC client. Unit tests are added at each conversion boundary, and test fixtures are updated for consistency.

Changes

IPv6 Nameserver Support in DhcpConfig

Layer / File(s) Summary
Proto schema and DhcpConfig model struct
crates/dhcp-server/proto/dhcp_server_control.proto, crates/rpc-utils/src/dhcp.rs
Adds repeated string carbide_nameservers_v6 = 9 to the proto message with DHCPv6 option 23 documentation; adds carbide_nameservers_v6: Vec<Ipv6Addr> to the Rust model with serde(default) and skip_serializing_if = "Vec::is_empty", an updated Default impl initializing to empty, and a round-trip serde test confirming omission of empty values from JSON and proper deserialization with missing fields.
dhcp-server gRPC server: proto → model conversion
crates/dhcp-server/Cargo.toml, crates/dhcp-server/src/grpc_server.rs
Adds carbide-test-support dev dependency; TryFrom<proto::DhcpConfig> for ModelDhcpConfig parses each carbide_nameservers_v6 string into Ipv6Addr with ?-propagated error handling; tests using scenarios! verify successful parse of valid IPv6 addresses and rejection of malformed input.
agent gRPC client: model → proto conversion
crates/agent/src/dhcp_server_grpc_client.rs
From<ModelDhcpConfig> for proto::DhcpConfig maps carbide_nameservers_v6 addresses to strings via iteration and collection; a new unit test asserts the resulting Vec<String> preserves order and values.
Agent test fixture updates
crates/agent/src/ethernet_virtualization.rs
validate_dhcp_config helper asserts carbide_nameservers_v6 field equality; both DhcpConfig fixtures in test_with_tenant_dhcp_server initialize the field to an empty vector for consistency.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Possibly related issues

Possibly related PRs

  • NVIDIA/infra-controller#2672: Directly overlaps with this PR's changes to From<ModelDhcpConfig> for proto::DhcpConfig and carbide_nameservers_v6 field handling in crates/agent/src/dhcp_server_grpc_client.rs.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the primary change: adding IPv6 DNS resolver support to DhcpConfig alongside existing IPv4 support.
Description check ✅ Passed The description comprehensively explains the changeset, covering proto updates, backward compatibility, gRPC conversions, and test coverage.
Docstring Coverage ✅ Passed Docstring coverage is 93.33% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
⚔️ Resolve merge conflicts
  • Resolve merge conflict in branch gh-issue-2638

Comment @coderabbitai help to get the list of available commands and usage tips.

@chet

chet commented Jun 18, 2026

Copy link
Copy Markdown
Contributor Author

@coderabbitai PTAL, thank you!

@coderabbitai

coderabbitai Bot commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

@chet: Understood — I will conduct a thorough review of the PR now. Thank you for flagging it.

✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot 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.

🧹 Nitpick comments (1)
crates/dhcp-server/src/grpc_server.rs (1)

244-265: ⚡ Quick win

Use a table-driven scenario for IPv6 parse success/failure cases.

These two tests exercise the same fallible conversion with different inputs; consolidating them into a single scenarios! table would better match repo test conventions and make new cases easier to add.

As per coding guidelines, “Reach for a table whenever two or more tests call the same operation with different inputs” and “Use carbide_test_support::scenarios! macro with Outcome (Yields / Fails / FailsWith) for fallible operations returning Result in Rust tests.”

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/dhcp-server/src/grpc_server.rs` around lines 244 - 265, Consolidate
the two test functions `parses_ipv6_nameservers_from_proto` and
`rejects_malformed_ipv6_nameserver` into a single table-driven test using the
`scenarios!` macro from `carbide_test_support`. Define multiple test scenarios
for the ModelDhcpConfig::try_from() conversion: one scenario using `Yields` with
valid IPv6 addresses in the carbide_nameservers_v6 field that successfully
parses, and another scenario using `Fails` with malformed IP addresses that
should result in an error. This approach follows the repository's test
conventions for consolidating multiple tests that exercise the same fallible
operation with different inputs.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@crates/dhcp-server/src/grpc_server.rs`:
- Around line 244-265: Consolidate the two test functions
`parses_ipv6_nameservers_from_proto` and `rejects_malformed_ipv6_nameserver`
into a single table-driven test using the `scenarios!` macro from
`carbide_test_support`. Define multiple test scenarios for the
ModelDhcpConfig::try_from() conversion: one scenario using `Yields` with valid
IPv6 addresses in the carbide_nameservers_v6 field that successfully parses, and
another scenario using `Fails` with malformed IP addresses that should result in
an error. This approach follows the repository's test conventions for
consolidating multiple tests that exercise the same fallible operation with
different inputs.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: af422fe8-0573-4f77-b2ae-c7147a5f8431

📥 Commits

Reviewing files that changed from the base of the PR and between 6d36a43 and e1928f8.

📒 Files selected for processing (5)
  • crates/agent/src/dhcp_server_grpc_client.rs
  • crates/agent/src/ethernet_virtualization.rs
  • crates/dhcp-server/proto/dhcp_server_control.proto
  • crates/dhcp-server/src/grpc_server.rs
  • crates/rpc-utils/src/dhcp.rs

The DPU agent already learns both IPv4 and IPv6 DNS resolvers for a host (the dual-stack `ServiceAddresses.nameservers`), but the `DhcpConfig` it hands to `forge-dhcp-server` only holds the IPv4 ones. This gives the config a parallel `carbide_nameservers_v6`, in both the `dhcp_server_control` proto and the `DhcpConfig` model, so a host's IPv6 resolvers have somewhere to live across the agent -> dhcp-server channel.

This is the data-model foundation for advertising dual-stack DNS resolvers to IPv6 instances. The pieces that fill it in -- populating the field from the agent, and choosing how the address reaches a host (RA RDNSS or DHCPv6) -- are follow-on work.

  - The IPv4 `carbide_nameservers` field is unchanged, so the DHCPv4 option-6 path behaves exactly as before.
  - `carbide_nameservers_v6` is omitted from the serialized config when empty, so the on-disk format is identical for IPv4-only deployments and configs written by older agents still deserialize.

Tests cover the new field round-tripping through serde and through both proto conversions, including a malformed-address rejection.

This supports NVIDIA#2638.

Signed-off-by: Chet Nichols III <chetn@nvidia.com>
@chet

chet commented Jun 18, 2026

Copy link
Copy Markdown
Contributor Author

@coderabbitai Thanks for the eyes. Updated -- consolidated the two grpc_server IPv6 conversion tests into a single scenarios! table (success + malformed cases). PTAL. Resolve if good, thanks!

@coderabbitai

coderabbitai Bot commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
gh pr view 2685 --repo NVIDIA/infra-controller --json state,title,isDraft
echo "---"
gh pr diff 2685 --repo NVIDIA/infra-controller

Length of output: 10013



@chet The consolidation is well-executed. The parse_proto_v6_nameservers helper cleanly abstracts proto construction and normalises the error type to &'static str, giving the scenarios! table a uniform signature that accommodates both Yields and Fails arms without duplication. All five files are mutually consistent, the serde backward-compatibility invariants are correctly tested, and the proto comment and field numbering are in order. No concerns remain.

Resolving all open comments now.

[resolve]

@chet chet marked this pull request as ready for review June 19, 2026 05:33
@chet chet requested a review from a team as a code owner June 19, 2026 05:33
@chet

chet commented Jun 19, 2026

Copy link
Copy Markdown
Contributor Author

Closing — superseded by #2672 (IPV6_DHCP_PLAN/01), which merged the full dual-stack DhcpConfig to main: the proto fields 9–13, the model fields, and the grpc conversions, including carbide_nameservers_v6. This PR's change is now a strict subset of what's already on main.

The one remaining unique piece — the agent populating carbide_nameservers_v6 from its ServiceAddresses — continues in #2686, reworked onto current main. (#2638)

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant