@@ -100,20 +100,26 @@ use std::os::fd::{AsFd, AsRawFd, FromRawFd, OwnedFd, RawFd};
100100use std:: path:: PathBuf ;
101101use std:: str:: FromStr ;
102102
103- #[ derive( Debug , Clone , PartialEq , serde:: Serialize ) ]
104- pub enum PortArg {
105- PCI ( PciAddress ) , // DPDK driver
106- KERNEL ( InterfaceName ) , // kernel driver
107- }
108-
109- #[ derive( Debug , Clone , serde:: Serialize ) ]
103+ #[ derive(
104+ CheckBytes ,
105+ Clone ,
106+ Debug ,
107+ Eq ,
108+ PartialEq ,
109+ rkyv:: Archive ,
110+ rkyv:: Deserialize ,
111+ rkyv:: Serialize ,
112+ serde:: Deserialize ,
113+ serde:: Serialize ,
114+ ) ]
115+ #[ rkyv( attr( derive( PartialEq , Eq , Debug ) ) ) ]
110116#[ allow( unused) ]
111117pub struct InterfaceArg {
112118 pub interface : InterfaceName ,
113- pub port : Option < PortArg > ,
119+ pub port : NetworkDeviceDescription ,
114120}
115121
116- impl FromStr for PortArg {
122+ impl FromStr for NetworkDeviceDescription {
117123 type Err = String ;
118124 fn from_str ( input : & str ) -> Result < Self , Self :: Err > {
119125 let ( disc, value) = input
@@ -123,12 +129,12 @@ impl FromStr for PortArg {
123129 match disc {
124130 "pci" => {
125131 let pciaddr = PciAddress :: try_from ( value) . map_err ( |e| e. to_string ( ) ) ?;
126- Ok ( PortArg :: PCI ( pciaddr) )
132+ Ok ( NetworkDeviceDescription :: Pci ( pciaddr) )
127133 }
128134 "kernel" => {
129135 let kernelif = InterfaceName :: try_from ( value)
130136 . map_err ( |e| format ! ( "Bad kernel interface name: {e}" ) ) ?;
131- Ok ( PortArg :: KERNEL ( kernelif) )
137+ Ok ( NetworkDeviceDescription :: Kernel ( kernelif) )
132138 }
133139 _ => Err ( format ! (
134140 "Unknown discriminant '{disc}': allowed values are pci|kernel"
@@ -141,21 +147,12 @@ impl FromStr for InterfaceArg {
141147 type Err = String ;
142148 fn from_str ( input : & str ) -> Result < Self , Self :: Err > {
143149 if let Some ( ( first, second) ) = input. split_once ( '=' ) {
144- let interface = InterfaceName :: try_from ( first)
145- . map_err ( |e| format ! ( "Bad interface name: {e}" ) ) ?;
146-
147- let port = PortArg :: from_str ( second) ?;
148- Ok ( InterfaceArg {
149- interface,
150- port : Some ( port) ,
151- } )
150+ let interface =
151+ InterfaceName :: try_from ( first) . map_err ( |e| format ! ( "Bad interface name: {e}" ) ) ?;
152+ let port = NetworkDeviceDescription :: from_str ( second) ?;
153+ Ok ( InterfaceArg { interface, port } )
152154 } else {
153- let interface = InterfaceName :: try_from ( input)
154- . map_err ( |e| format ! ( "Bad interface name: {e}" ) ) ?;
155- Ok ( InterfaceArg {
156- interface,
157- port : None ,
158- } )
155+ Err ( format ! ( "invalid interface argument: {input}" ) )
159156 }
160157 }
161158}
@@ -503,7 +500,7 @@ impl Display for NetworkDeviceDescription {
503500#[ rkyv( attr( derive( Debug , PartialEq , Eq ) ) ) ]
504501pub struct DpdkDriverConfigSection {
505502 /// Network devices to use with DPDK (identified by PCI address)
506- pub use_nics : Vec < NetworkDeviceDescription > ,
503+ pub interfaces : Vec < InterfaceArg > ,
507504 /// DPDK EAL (Environment Abstraction Layer) initialization arguments
508505 pub eal_args : Vec < String > ,
509506}
@@ -545,7 +542,7 @@ pub struct DpdkDriverConfigSection {
545542#[ rkyv( attr( derive( PartialEq , Eq , Debug ) ) ) ]
546543pub struct KernelDriverConfigSection {
547544 /// Kernel network interfaces to manage
548- pub interfaces : Vec < InterfaceName > ,
545+ pub interfaces : Vec < InterfaceArg > ,
549546}
550547
551548/// Configuration for the dataplane's command-line interface (CLI).
@@ -734,6 +731,8 @@ pub struct ConfigServerSection {
734731pub struct LaunchConfiguration {
735732 /// Dynamic configuration server settings
736733 pub config_server : ConfigServerSection ,
734+ /// Number of dataplane worker threads / cores
735+ pub dataplane_workers : usize ,
737736 /// Packet processing driver configuration
738737 pub driver : DriverConfigSection ,
739738 /// CLI server configuration
@@ -744,6 +743,32 @@ pub struct LaunchConfiguration {
744743 pub tracing : TracingConfigSection ,
745744 /// Metrics collection configuration
746745 pub metrics : MetricsConfigSection ,
746+ /// Profileing collection configuration
747+ pub profiling : ProfilingConfigSection ,
748+ }
749+
750+ #[ derive(
751+ Debug , Clone , PartialEq , Eq , serde:: Serialize , rkyv:: Serialize , rkyv:: Deserialize , rkyv:: Archive ,
752+ ) ]
753+ #[ rkyv( attr( derive( PartialEq , Eq , Debug ) ) ) ]
754+ pub struct ProfilingConfigSection {
755+ /// The URL of the pryroscope url
756+ pub pyroscope_url : Option < String > ,
757+ /// Frequency with which we collect stack traces
758+ pub frequency : u32 ,
759+ }
760+
761+ impl ProfilingConfigSection {
762+ pub const DEFAULT_FREQUENCY : u32 = 100 ;
763+ }
764+
765+ impl Default for ProfilingConfigSection {
766+ fn default ( ) -> Self {
767+ Self {
768+ pyroscope_url : None ,
769+ frequency : Self :: DEFAULT_FREQUENCY ,
770+ }
771+ }
747772}
748773
749774impl LaunchConfiguration {
@@ -1191,26 +1216,19 @@ impl TryFrom<CmdArgs> for LaunchConfiguration {
11911216 type Error = InvalidCmdArguments ;
11921217
11931218 fn try_from ( value : CmdArgs ) -> Result < Self , InvalidCmdArguments > {
1194- let use_nics: Vec < _ > = value
1195- . interfaces ( )
1196- . map ( |x| match x. port {
1197- Some ( PortArg :: KERNEL ( name) ) => NetworkDeviceDescription :: Kernel ( name) ,
1198- Some ( PortArg :: PCI ( address) ) => NetworkDeviceDescription :: Pci ( address) ,
1199- None => todo ! ( ) , // I am not clear what this case means
1200- } )
1201- . collect ( ) ;
12021219 Ok ( LaunchConfiguration {
12031220 config_server : ConfigServerSection {
12041221 address : value
12051222 . grpc_address ( )
12061223 . map_err ( InvalidCmdArguments :: InvalidGrpcAddress ) ?,
12071224 } ,
1225+ dataplane_workers : value. num_workers . into ( ) ,
12081226 driver : match & value. driver {
12091227 Some ( driver) if driver == "dpdk" => {
12101228 // TODO: adjust command line to specify lcore usage more flexibly in next PR
1211- let eal_args = use_nics
1212- . iter ( )
1213- . map ( |nic| match nic {
1229+ let eal_args = value
1230+ . interfaces ( )
1231+ . map ( |nic| match nic. port {
12141232 NetworkDeviceDescription :: Pci ( pci_address) => {
12151233 Ok ( [ "--allow" . to_string ( ) , format ! ( "{pci_address}" ) ] )
12161234 }
@@ -1224,23 +1242,15 @@ impl TryFrom<CmdArgs> for LaunchConfiguration {
12241242 . into_iter ( )
12251243 . flatten ( )
12261244 . collect ( ) ;
1227- DriverConfigSection :: Dpdk ( DpdkDriverConfigSection { use_nics, eal_args } )
1245+
1246+ DriverConfigSection :: Dpdk ( DpdkDriverConfigSection {
1247+ interfaces : value. interfaces ( ) . collect ( ) ,
1248+ eal_args,
1249+ } )
12281250 }
12291251 Some ( driver) if driver == "kernel" => {
12301252 DriverConfigSection :: Kernel ( KernelDriverConfigSection {
1231- interfaces : use_nics
1232- . iter ( )
1233- . map ( |nic| match nic {
1234- NetworkDeviceDescription :: Pci ( address) => {
1235- Err ( InvalidCmdArguments :: UnsupportedByDriver (
1236- UnsupportedByDriver :: Kernel ( * address) ,
1237- ) )
1238- }
1239- NetworkDeviceDescription :: Kernel ( interface) => {
1240- Ok ( interface. clone ( ) )
1241- }
1242- } )
1243- . collect :: < Result < _ , _ > > ( ) ?,
1253+ interfaces : value. interfaces ( ) . collect ( ) ,
12441254 } )
12451255 }
12461256 Some ( other) => Err ( InvalidCmdArguments :: InvalidDriver ( other. clone ( ) ) ) ?,
@@ -1271,6 +1281,10 @@ impl TryFrom<CmdArgs> for LaunchConfiguration {
12711281 metrics : MetricsConfigSection {
12721282 address : value. metrics_address ( ) ,
12731283 } ,
1284+ profiling : ProfilingConfigSection {
1285+ pyroscope_url : value. pyroscope_url ( ) . map ( std:: string:: ToString :: to_string) ,
1286+ frequency : ProfilingConfigSection :: DEFAULT_FREQUENCY ,
1287+ } ,
12741288 } )
12751289 }
12761290}
@@ -1561,6 +1575,7 @@ impl CmdArgs {
15611575 self . metrics_address
15621576 }
15631577
1578+ #[ must_use]
15641579 pub fn pyroscope_url ( & self ) -> Option < & url:: Url > {
15651580 self . pyroscope_url . as_ref ( )
15661581 }
@@ -1575,7 +1590,7 @@ mod tests {
15751590 use hardware:: pci:: function:: Function ;
15761591 use net:: interface:: InterfaceName ;
15771592
1578- use crate :: { InterfaceArg , PortArg } ;
1593+ use crate :: { InterfaceArg , NetworkDeviceDescription } ;
15791594 use std:: str:: FromStr ;
15801595
15811596 #[ test]
@@ -1585,29 +1600,22 @@ mod tests {
15851600 assert_eq ! ( spec. interface. as_ref( ) , "GbEth1.9000" ) ;
15861601 assert_eq ! (
15871602 spec. port,
1588- Some ( PortArg :: PCI ( PciAddress :: new(
1603+ NetworkDeviceDescription :: Pci ( PciAddress :: new(
15891604 Domain :: from( 0 ) ,
15901605 Bus :: new( 2 ) ,
15911606 Device :: try_from( 1 ) . unwrap( ) ,
15921607 Function :: try_from( 7 ) . unwrap( )
1593- ) ) )
1608+ ) )
15941609 ) ;
15951610
15961611 // interface + port as kernel interface
15971612 let spec =
InterfaceArg :: from_str ( "[email protected] " ) . unwrap ( ) ; 15981613 assert_eq ! ( spec. interface. as_ref( ) , "GbEth1.9000" ) ;
15991614 assert_eq ! (
16001615 spec. port,
1601- Some ( PortArg :: KERNEL (
1602- InterfaceName :: try_from( "enp2s1.100" ) . unwrap( )
1603- ) )
1616+ NetworkDeviceDescription :: Kernel ( InterfaceName :: try_from( "enp2s1.100" ) . unwrap( ) )
16041617 ) ;
16051618
1606- // interface only (backwards compatibility)
1607- let spec = InterfaceArg :: from_str ( "GbEth1.9000" ) . unwrap ( ) ;
1608- assert_eq ! ( spec. interface. as_ref( ) , "GbEth1.9000" ) ;
1609- assert ! ( spec. port. is_none( ) ) ;
1610-
16111619 // bad pci address
16121620 assert ! ( InterfaceArg :: from_str( "GbEth1.9000=pci@0000:02:01" ) . is_err( ) ) ;
16131621
0 commit comments