@@ -21,13 +21,14 @@ use std::collections::BTreeMap;
2121use std:: fmt:: Write ;
2222
2323use carbide_dpf:: types:: {
24- DHCP_SERVER_SERVICE_NAME , DOCA_HBN_SERVICE_NAME , DOCA_WEAVE_DHCP_AGENT_SERVICE_NAME ,
25- DOCA_WEAVE_FLOW_CONTROLLER_SERVICE_NAME , DOCA_XPLANE_SERVICE_NAME , DPU_AGENT_SERVICE_NAME ,
26- DTS_SERVICE_NAME , DpuServiceInterfaceTemplateDefinition , FMDS_SERVICE_NAME ,
27- OTEL_COLLECTOR_SERVICE_NAME ,
24+ DHCP_SERVER_SERVICE_NAME , DOCA_HBN_SERVICE_NAME , DOCA_HBN_SERVICE_NETWORK ,
25+ DOCA_WEAVE_DHCP_AGENT_SERVICE_NAME , DOCA_WEAVE_FLOW_CONTROLLER_SERVICE_NAME ,
26+ DOCA_XPLANE_SERVICE_NAME , DPU_AGENT_SERVICE_NAME , DTS_SERVICE_NAME ,
27+ DpuServiceInterfaceTemplateDefinition , FMDS_SERVICE_NAME , OTEL_COLLECTOR_SERVICE_NAME ,
2828} ;
2929use carbide_dpf:: {
3030 IntOrString , ServiceDefinition , ServiceInterface , ServiceNAD , ServiceNADResourceType ,
31+ ServiceVpcSlots ,
3132} ;
3233
3334use crate :: cfg:: file:: {
@@ -59,7 +60,6 @@ pub(crate) const DOCA_HBN_SERVICE_HELM_NAME: &str = "doca-hbn";
5960pub ( crate ) const DOCA_HBN_SERVICE_HELM_VERSION : & str = "3.4.0" ;
6061pub ( crate ) const DOCA_HBN_SERVICE_IMAGE_NAME : & str = "doca_hbn" ;
6162pub ( crate ) const DOCA_HBN_SERVICE_IMAGE_TAG : & str = "3.4.0-doca3.4.0" ;
62- pub ( crate ) const DOCA_HBN_SERVICE_NETWORK : & str = "mybrhbn" ;
6363
6464/// DHCP Service Definitions
6565pub ( crate ) const DHCP_SERVER_SERVICE_HELM_NAME : & str = "nico-dhcp-server" ;
@@ -130,50 +130,6 @@ pub(crate) const COMPILE_TIME_IMAGE_TAG: &str = match option_env!("CARBIDE_BUILD
130130 None => "" ,
131131} ;
132132
133- fn doca_hbn_service_interfaces (
134- interfaces : & [ DpuServiceInterfaceTemplateDefinition ] ,
135- extra_interfaces : & [ String ] ,
136- ) -> Vec < ServiceInterface > {
137- let mut service_interfaces =
138- dpu_service_interfaces ( interfaces, DOCA_HBN_SERVICE_NAME , DOCA_HBN_SERVICE_NETWORK ) ;
139- service_interfaces. extend ( extra_interfaces. iter ( ) . map ( |name| ServiceInterface {
140- name : name. clone ( ) ,
141- network : DOCA_HBN_SERVICE_NETWORK . to_string ( ) ,
142- } ) ) ;
143- service_interfaces
144- }
145-
146- /// Generates deterministic service-VPC interface names after checking HBN capacity.
147- pub ( crate ) fn service_vpc_interfaces (
148- interfaces : & [ DpuServiceInterfaceTemplateDefinition ] ,
149- slot_count : u32 ,
150- ) -> Result < Vec < String > , String > {
151- let mut hbn_interface_names = doca_hbn_service_interfaces ( interfaces, & [ ] )
152- . into_iter ( )
153- . map ( |interface| interface. name )
154- . collect :: < std:: collections:: BTreeSet < _ > > ( ) ;
155-
156- let total = usize:: try_from ( slot_count)
157- . ok ( )
158- . and_then ( |slot_count| hbn_interface_names. len ( ) . checked_add ( slot_count) )
159- . ok_or_else ( || "HBN interface count exceeds usize" . to_string ( ) ) ?;
160- if total > 32 {
161- return Err ( format ! (
162- "HBN interface count {total} exceeds the supported maximum of 32"
163- ) ) ;
164- }
165-
166- let generated = ( 0 ..slot_count)
167- . map ( |slot| format ! ( "iface_svc_{slot}" ) )
168- . collect :: < Vec < _ > > ( ) ;
169- for name in & generated {
170- if !hbn_interface_names. insert ( name. clone ( ) ) {
171- return Err ( format ! ( "HBN interface name {name:?} is not unique" ) ) ;
172- }
173- }
174-
175- Ok ( generated)
176- }
177133fn dhcp_server_service_interfaces (
178134 interfaces : & [ DpuServiceInterfaceTemplateDefinition ] ,
179135) -> Vec < ServiceInterface > {
@@ -482,9 +438,14 @@ fn reassert_api_owned_value(
482438pub ( crate ) fn doca_hbn_service (
483439 cfg : & DpfServiceConfig ,
484440 dpu_interfaces : & [ DpuServiceInterfaceTemplateDefinition ] ,
485- extra_interfaces : & [ String ] ,
441+ service_vpc_slots : ServiceVpcSlots ,
486442) -> ServiceDefinition {
487- let interfaces = doca_hbn_service_interfaces ( dpu_interfaces, extra_interfaces) ;
443+ let mut interfaces = dpu_service_interfaces (
444+ dpu_interfaces,
445+ DOCA_HBN_SERVICE_NAME ,
446+ DOCA_HBN_SERVICE_NETWORK ,
447+ ) ;
448+ service_vpc_slots. append_hbn_interfaces ( & mut interfaces) ;
488449 let mut helm_values = serde_json:: json!( {
489450 "image" : {
490451 "repository" : cfg. docker_repo_url,
@@ -892,12 +853,12 @@ pub(crate) fn mandatory_services(
892853 resolved : & DpfResolvedMandatoryServicesConfig ,
893854 bootstrap_ca : & DpfDpuAgentBootstrapCa ,
894855 interfaces : & [ DpuServiceInterfaceTemplateDefinition ] ,
895- service_vpc_interfaces : & [ String ] ,
856+ service_vpc_slots : ServiceVpcSlots ,
896857 node_auth : & NodeAuthConfig ,
897858) -> Vec < ServiceDefinition > {
898859 let mut service_vec = vec ! [
899860 dts_service( & resolved. base. dts) ,
900- doca_hbn_service( & resolved. base. doca_hbn, interfaces, service_vpc_interfaces ) ,
861+ doca_hbn_service( & resolved. base. doca_hbn, interfaces, service_vpc_slots ) ,
901862 dhcp_server_service( & resolved. base. dhcp_server, interfaces) ,
902863 dpu_agent_service( & resolved. base. dpu_agent, bootstrap_ca) ,
903864 // Not `node_auth.enabled` directly: an operator staging a disable
@@ -974,12 +935,8 @@ mod tests {
974935
975936 // HBN receives p0, p1, the PF, the VF, and the configured external attachment; its SF
976937 // count and startup YAML agree.
977- let service_vpc_interfaces = service_vpc_interfaces ( & interfaces, 1 ) . unwrap ( ) ;
978- let hbn = doca_hbn_service (
979- & default_doca_hbn_service ( ) ,
980- & interfaces,
981- & service_vpc_interfaces,
982- ) ;
938+ let service_vpc_slots = ServiceVpcSlots :: new ( 1 ) . unwrap ( ) ;
939+ let hbn = doca_hbn_service ( & default_doca_hbn_service ( ) , & interfaces, service_vpc_slots) ;
983940 assert_eq ! ( hbn. interfaces. len( ) , 5 ) ;
984941 assert_eq ! (
985942 hbn. helm_values. as_ref( ) . unwrap( ) [ "resources" ] [ "nvidia.com/bf_sf" ] ,
@@ -1013,16 +970,6 @@ mod tests {
1013970 ) ;
1014971 }
1015972
1016- #[ test]
1017- fn service_vpc_interfaces_are_deterministic_and_capacity_checked ( ) {
1018- let interfaces = build_effective_dpu_interfaces ( 16 , None ) ;
1019- assert_eq ! (
1020- service_vpc_interfaces( & interfaces, 2 ) . unwrap( ) ,
1021- [ "iface_svc_0" . to_string( ) , "iface_svc_1" . to_string( ) ]
1022- ) ;
1023- assert ! ( service_vpc_interfaces( & interfaces, 15 ) . is_err( ) ) ;
1024- }
1025-
1026973 /// Verifies operator Helm values cannot disconnect HBN's SF request from its interfaces.
1027974 #[ test]
1028975 fn hbn_sf_count_remains_topology_derived ( ) {
@@ -1039,7 +986,7 @@ mod tests {
1039986 let interfaces = build_dpu_interfaces_vec ( ) ;
1040987
1041988 // Ordinary resource overrides remain effective, while the SF count follows inventory.
1042- let hbn = doca_hbn_service ( & config, & interfaces, & [ ] ) ;
989+ let hbn = doca_hbn_service ( & config, & interfaces, ServiceVpcSlots :: default ( ) ) ;
1043990 let helm_values = hbn. helm_values . unwrap ( ) ;
1044991 assert_eq ! ( helm_values[ "resources" ] [ "memory" ] , "8Gi" ) ;
1045992 assert_eq ! (
@@ -1159,7 +1106,11 @@ mod tests {
11591106 fn hbn_and_dts_omit_image_pull_secrets_by_default ( ) {
11601107 // HBN and DTS pull from the public DOCA registry: no imagePullSecrets unless configured.
11611108 let interfaces = build_dpu_interfaces_vec ( ) ;
1162- let hbn = doca_hbn_service ( & default_doca_hbn_service ( ) , & interfaces, & [ ] ) ;
1109+ let hbn = doca_hbn_service (
1110+ & default_doca_hbn_service ( ) ,
1111+ & interfaces,
1112+ ServiceVpcSlots :: default ( ) ,
1113+ ) ;
11631114 assert ! (
11641115 hbn. helm_values. unwrap( ) . get( "imagePullSecrets" ) . is_none( ) ,
11651116 "HBN must not emit imagePullSecrets without a configured secret"
@@ -1180,7 +1131,7 @@ mod tests {
11801131 let mut hbn_cfg = default_doca_hbn_service ( ) ;
11811132 hbn_cfg. docker_image_pull_secret = Some ( "private-pull-secret" . to_string ( ) ) ;
11821133 assert_eq ! (
1183- doca_hbn_service( & hbn_cfg, & interfaces, & [ ] )
1134+ doca_hbn_service( & hbn_cfg, & interfaces, ServiceVpcSlots :: default ( ) )
11841135 . helm_values
11851136 . unwrap( ) [ "imagePullSecrets" ] ,
11861137 expected
@@ -1646,12 +1597,18 @@ mod tests {
16461597 let bootstrap_ca = DpfDpuAgentBootstrapCa :: default ( ) ;
16471598
16481599 let fmds_mode = |node_auth : & NodeAuthConfig | {
1649- mandatory_services ( & resolved, & bootstrap_ca, & [ ] , & [ ] , node_auth)
1650- . into_iter ( )
1651- . find ( |s| s. name == FMDS_SERVICE_NAME )
1652- . and_then ( |s| s. helm_values )
1653- . and_then ( |v| v. get ( "useNodeTokens" ) . and_then ( serde_json:: Value :: as_bool) )
1654- . expect ( "fmds renders useNodeTokens" )
1600+ mandatory_services (
1601+ & resolved,
1602+ & bootstrap_ca,
1603+ & [ ] ,
1604+ ServiceVpcSlots :: default ( ) ,
1605+ node_auth,
1606+ )
1607+ . into_iter ( )
1608+ . find ( |s| s. name == FMDS_SERVICE_NAME )
1609+ . and_then ( |s| s. helm_values )
1610+ . and_then ( |v| v. get ( "useNodeTokens" ) . and_then ( serde_json:: Value :: as_bool) )
1611+ . expect ( "fmds renders useNodeTokens" )
16551612 } ;
16561613
16571614 let derived_on = NodeAuthConfig {
0 commit comments