From 89c46942df2c48e6872ff82edb743231f4d7ba11 Mon Sep 17 00:00:00 2001 From: aadvani-nvidia Date: Thu, 30 Jul 2026 11:44:01 -0700 Subject: [PATCH] Bug 6533524 Fix to Callhome failure in FMDS in Fnn mode (#4338) Description: In FNN mode with an L3 Physical tenant interface (is_l2_segment is false), the FMDS instance metadata gateway address (169.254.169.253/30) was never configured on the DPU in container mode. Root cause: fmds_gateway_vlan is determined by finding the first Physical-typed interface in tenant_interfaces. In FNN deployments, the Physical interface (pf0hpf_if) is typically an L3 linknet, so HasFmdsGateway is true was correctly set on that port. However, nvue_startup_fnn.conf only rendered 169.254.169.253/30 inside the IsL2Segment SVI block. The L3 interface IP block had no equivalent check. Fix: - Added HasFmdsGateway true check to the L3 interface IP block. - Added 3 tests via AI ## Related issues https://nvbugspro.nvidia.com/bug/6533524 ## Type of Change - [ ] **Add** - New feature or capability - [ ] **Change** - Changes in existing functionality - [ x] **Fix** - Bug fixes - [ ] **Remove** - Removed features or deprecated functionality - [ ] **Internal** - Internal changes (refactoring, tests, docs, etc.) ## Breaking Changes - [ ] **This PR contains breaking changes** ## Testing - [ ] Unit tests added/updated - [ ] Integration tests added/updated - [ ] Manual testing performed - [ ] No testing required (docs, internal refactor, etc.) ## Additional Notes Don't have a setup for testing, will be tested on demo2 once the fix is in. (cherry picked from commit 1d2f5e5202a771b3b206c94e2adec97a93680745) --- crates/agent/src/nvue.rs | 74 ++++++++++++++++++++ crates/agent/templates/nvue_startup_fnn.conf | 3 + 2 files changed, 77 insertions(+) diff --git a/crates/agent/src/nvue.rs b/crates/agent/src/nvue.rs index f7f5307625..9587332c61 100644 --- a/crates/agent/src/nvue.rs +++ b/crates/agent/src/nvue.rs @@ -2458,6 +2458,80 @@ mod tests { ); } + fn l3_phy_port_config(vlan: u16) -> PortConfig { + PortConfig { + is_l2_segment: false, + svi_ip: None, + ..phy_port_config(vlan) + } + } + + // FNN L3 (is_l2_segment=false): in container mode the FMDS gateway address + // must appear on the L3 interface's ip block, not an SVI. + #[test] + fn test_fmds_gateway_fnn_l3_container_mode_emits_address() { + let mut conf = minimal_nvue_config(); + conf.is_fnn = true; + conf.vpc_virtualization_type = VpcVirtualizationType::Fnn; + conf.is_dpu_os = false; + conf.fmds_gateway_vlan = Some(274); + conf.ct_routing_profile = Some(minimal_fnn_routing_profile()); + conf.ct_port_configs = vec![l3_phy_port_config(274)]; + let output = build(conf).expect("build should succeed"); + assert!( + output.contains("169.254.169.253/30"), + "expected FMDS gateway address on FNN L3 interface:\n{output}" + ); + } + + // FNN L3 in DPU-OS mode: 169.254.169.253/30 must NOT appear on pf0hpf_if + // (the startup template puts it on pf0dpu1_if instead). The naive + // `!contains(addr) || contains(pf0dpu1_if)` check is vacuously true because + // the FNN template always renders pf0dpu1_if in DPU-OS mode, so we parse the + // YAML and assert at the per-interface level. + #[test] + fn test_fmds_gateway_fnn_l3_dpu_os_mode_suppressed() { + let mut conf = minimal_nvue_config(); + conf.is_fnn = true; + conf.vpc_virtualization_type = VpcVirtualizationType::Fnn; + conf.is_dpu_os = true; + conf.fmds_gateway_vlan = Some(274); + conf.ct_routing_profile = Some(minimal_fnn_routing_profile()); + conf.ct_port_configs = vec![l3_phy_port_config(274)]; + let output = build(conf).expect("build should succeed"); + let docs: serde_yaml::Value = + serde_yaml::from_str(&output).expect("output should be valid YAML"); + let interfaces = &docs.as_sequence().unwrap()[1]["set"]["interface"]; + // The L3 interface must not carry the FMDS address. + assert!( + interfaces["pf0hpf_if"]["ip"]["address"]["169.254.169.253/30"].is_null(), + "DPU-OS mode must not put 169.254.169.253/30 on pf0hpf_if:\n{output}" + ); + // The startup-template interface (pf0dpu1_if) must carry it instead. + assert!( + !interfaces["pf0dpu1_if"]["ip"]["address"]["169.254.169.253/30"].is_null(), + "DPU-OS mode must put 169.254.169.253/30 on pf0dpu1_if:\n{output}" + ); + } + + // FNN with an L3 Physical port and a mismatched fmds_gateway_vlan should not + // emit the FMDS address (and should not panic). + #[test] + fn test_fmds_gateway_fnn_l3_vlan_mismatch_emits_nothing() { + let mut conf = minimal_nvue_config(); + conf.is_fnn = true; + conf.vpc_virtualization_type = VpcVirtualizationType::Fnn; + conf.is_dpu_os = false; + conf.fmds_gateway_vlan = Some(999); // no port has vlan 999 + conf.ct_routing_profile = Some(minimal_fnn_routing_profile()); + conf.ct_port_configs = vec![l3_phy_port_config(274)]; + let output = build(conf).expect("build should succeed even with mismatched vlan"); + assert!( + !output.contains("169.254.169.253/30"), + "mismatched vlan should not produce FMDS address on FNN L3 interface:\n{output}" + ); + } + #[test] fn test_fnn_no_interface_routing_profile_uses_vpc_allowed_anycast_prefixes() { // Build an FNN config with a VPC routing profile and no interface override. diff --git a/crates/agent/templates/nvue_startup_fnn.conf b/crates/agent/templates/nvue_startup_fnn.conf index 3617a7e2f9..d29c4b191b 100644 --- a/crates/agent/templates/nvue_startup_fnn.conf +++ b/crates/agent/templates/nvue_startup_fnn.conf @@ -123,6 +123,9 @@ {{- range $portConfig.IPs }} {{ . }}: {} {{/* In case of FNN L3, this is the first IP in the /31 in the prefix */}} {{- end }} + {{- if $portConfig.HasFmdsGateway }} + 169.254.169.253/30: {} + {{- end }} vrf: {{ $portConfig.VrfName }} {{/* The name of the VRF (VPC) this interface should be in */}} {{- else }} {{/* If the segment is L2, the interface should be configured in the bridge */}} bridge: