Skip to content
40 changes: 38 additions & 2 deletions controlplane/ffi/agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,42 @@ func (m ShmDeviceConfig) AsRawPtr() unsafe.Pointer {
return unsafe.Pointer(m.ptr)
}

type FFIAgent interface {
DPAgent
DPDataProvider
}

type DPAgent interface {
ModuleAgent
FunctionAgent
PipelineAgent
DeviceAgent
TakeError() error
CleanError()
CleanUp() error
Close() error
}

type ModuleAgent interface {
UpdateModules(modules []ModuleConfig) error
DeleteModuleConfig(configName string) error
}

type FunctionAgent interface {
UpdateFunction(functionConfig FunctionConfig) error
DeleteFunction(name string) error
}

type PipelineAgent interface {
UpdatePipeline(pipelineConfig PipelineConfig) error
DeletePipeline(name string) error
}

type DeviceAgent interface {
UpdatePlainDevices(devices []DeviceConfig) error
UpdateDevices(devices []ShmDeviceConfig) error
}

type Agent struct {
name string
ptr *C.struct_agent
Expand Down Expand Up @@ -133,8 +169,8 @@ func (m *Agent) UpdateModules(modules []ModuleConfig) error {
return nil
}

func (m *Agent) DPConfig() *DPConfig {
return &DPConfig{
func (m *Agent) DPConfig() DPConfig {
return &DPConfigImpl{
ptr: C.agent_dp_config(m.ptr),
}
}
Expand Down
70 changes: 50 additions & 20 deletions controlplane/ffi/shm.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,36 @@ import (
"github.com/yanet-platform/yanet2/bindings/go/cerrors"
)

type DPDataProvider interface {
DPConfig() DPConfig
}

type DPConfig interface {
DPObserver
CounterAggregator
AllModulePositions(string) []ModuleReference
}

type DPObserver interface {
NumaIdx() uint32
WorkerCount() uint32
Modules() []DPModule
CPConfigs() []CPConfig
Functions() []Function
Pipelines() []Pipeline
Agents() []AgentInfo
Devices() []DeviceInfo
}

type CounterAggregator interface {
DeviceCounters(deviceName string) []CounterInfo
PipelineCounters(deviceName string, pipelineName string) []CounterInfo
FunctionCounters(deviceName string, pipelineName string, functionName string) []CounterInfo
ChainCounters(deviceName string, pipelineName string, functionName string, chainName string) []CounterInfo
ModuleCounters(deviceName string, pipelineName string, functionName string, chainName string, moduleType string, moduleName string, counterQuery []string) []CounterInfo
PerformanceCounters(deviceName string, pipelineName string, functionName string, chainName string, moduleType string, moduleName string) (*PerformanceCounters, error)
}

// SharedMemory represents a handle to YANET shared memory segment.
type SharedMemory struct {
ptr *C.struct_yanet_shm
Expand Down Expand Up @@ -64,10 +94,10 @@ func (m *SharedMemory) AsRawPtr() unsafe.Pointer {
}

// DPConfig gets configuration of the dataplane instance from shared memory.
func (m *SharedMemory) DPConfig(instanceIdx uint32) *DPConfig {
func (m *SharedMemory) DPConfig(instanceIdx uint32) DPConfig {
ptr := C.yanet_shm_dp_config(m.ptr, C.uint32_t(instanceIdx))

return &DPConfig{ptr: ptr}
return &DPConfigImpl{ptr: ptr}
}

// AgentAttach attaches a module agent to shared memory on the dataplane instance.
Expand Down Expand Up @@ -136,24 +166,24 @@ func (m *SharedMemory) AgentsAttach(
}

// DPConfig represents a handle to dataplane configuration.
type DPConfig struct {
type DPConfigImpl struct {
ptr *C.struct_dp_config
}

func NewDPConfigFromRaw(ptr unsafe.Pointer) *DPConfig {
return &DPConfig{ptr: (*C.struct_dp_config)(ptr)}
func NewDPConfigFromRaw(ptr unsafe.Pointer) *DPConfigImpl {
Copy link

Copilot AI Apr 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now that DPConfig is an exported interface, NewDPConfigFromRaw returning *DPConfigImpl (and DPConfigImpl being exported) leaks the implementation type into the public API. To keep the interface abstraction consistent for callers and reduce surface area, consider making the implementation type unexported and/or changing NewDPConfigFromRaw to return DPConfig instead of *DPConfigImpl.

Suggested change
func NewDPConfigFromRaw(ptr unsafe.Pointer) *DPConfigImpl {
func NewDPConfigFromRaw(ptr unsafe.Pointer) DPConfig {

Copilot uses AI. Check for mistakes.
return &DPConfigImpl{ptr: (*C.struct_dp_config)(ptr)}
}

func (m *DPConfig) NumaIdx() uint32 {
func (m *DPConfigImpl) NumaIdx() uint32 {
return uint32(C.dataplane_instance_numa_idx(m.ptr))
}

func (m *DPConfig) WorkerCount() uint32 {
func (m *DPConfigImpl) WorkerCount() uint32 {
return uint32(C.dataplane_instance_worker_count(m.ptr))
}

// Modules returns a list of dataplane modules available.
func (m *DPConfig) Modules() []DPModule {
func (m *DPConfigImpl) Modules() []DPModule {
ptr := C.yanet_get_dp_module_list_info(m.ptr)
defer C.dp_module_list_info_free(ptr)

Expand All @@ -174,7 +204,7 @@ func (m *DPConfig) Modules() []DPModule {
return out
}

func (m *DPConfig) CPConfigs() []CPConfig {
func (m *DPConfigImpl) CPConfigs() []CPConfig {
cpModulesListInfo := C.yanet_get_cp_module_list_info(m.ptr)
defer C.cp_module_list_info_free(cpModulesListInfo)

Expand Down Expand Up @@ -210,7 +240,7 @@ type Function struct {
}

// Functions returns all functions configurations from the dataplane.
func (m *DPConfig) Functions() []Function {
func (m *DPConfigImpl) Functions() []Function {
functionListInfo := C.yanet_get_cp_function_list_info(m.ptr)
defer C.cp_function_list_info_free(functionListInfo)

Expand Down Expand Up @@ -251,7 +281,7 @@ func (m *DPConfig) Functions() []Function {
}

// Pipelines returns all pipeline configurations from the dataplane.
func (m *DPConfig) Pipelines() []Pipeline {
func (m *DPConfigImpl) Pipelines() []Pipeline {
pipelineListInfo := C.yanet_get_cp_pipeline_list_info(m.ptr)
defer C.cp_pipeline_list_info_free(pipelineListInfo)

Expand All @@ -278,7 +308,7 @@ func (m *DPConfig) Pipelines() []Pipeline {
}

// Agents returns all agent information from the dataplane.
func (m *DPConfig) Agents() []AgentInfo {
func (m *DPConfigImpl) Agents() []AgentInfo {
agentListInfo := C.yanet_get_cp_agent_list_info(m.ptr)
defer C.cp_agent_list_info_free(agentListInfo)

Expand Down Expand Up @@ -384,7 +414,7 @@ type DeviceInfo struct {
}

// Devices returns all device information from the dataplane.
func (m *DPConfig) Devices() []DeviceInfo {
func (m *DPConfigImpl) Devices() []DeviceInfo {
deviceListInfo := C.yanet_get_cp_device_list_info(m.ptr)
if deviceListInfo == nil {
return nil
Expand Down Expand Up @@ -446,7 +476,7 @@ type CounterInfo struct {
Values [][]uint64
}

func (m *DPConfig) encodeCounters(
func (m *DPConfigImpl) encodeCounters(
counters *C.struct_counter_handle_list,
) []CounterInfo {
res := make([]CounterInfo, 0)
Expand Down Expand Up @@ -481,7 +511,7 @@ func (m *DPConfig) encodeCounters(
return res
}

func (m *DPConfig) DeviceCounters(
func (m *DPConfigImpl) DeviceCounters(
deviceName string,
) []CounterInfo {
cDeviceName := C.CString(deviceName)
Expand All @@ -497,7 +527,7 @@ func (m *DPConfig) DeviceCounters(
}

// PipelineCounters returns pipeline counters
func (m *DPConfig) PipelineCounters(
func (m *DPConfigImpl) PipelineCounters(
deviceName string,
pipelineName string,
) []CounterInfo {
Expand All @@ -515,7 +545,7 @@ func (m *DPConfig) PipelineCounters(
return m.encodeCounters(counters)
}

func (m *DPConfig) FunctionCounters(
func (m *DPConfigImpl) FunctionCounters(
deviceName string,
pipelineName string,
functionName string,
Expand All @@ -541,7 +571,7 @@ func (m *DPConfig) FunctionCounters(
return m.encodeCounters(counters)
}

func (m *DPConfig) ChainCounters(
func (m *DPConfigImpl) ChainCounters(
deviceName string,
pipelineName string,
functionName string,
Expand Down Expand Up @@ -574,7 +604,7 @@ func (m *DPConfig) ChainCounters(
// ModuleCounters returns module counters, optionally filtered by name.
//
// If counterQuery is nil or empty, returns all counters.
func (m *DPConfig) ModuleCounters(
func (m *DPConfigImpl) ModuleCounters(
deviceName string,
pipelineName string,
functionName string,
Expand Down Expand Up @@ -661,7 +691,7 @@ type PerformanceCounters struct {
// Performance counters provide detailed timing and batch processing statistics
// for module execution, including mean latency and latency distribution across
// different batch sizes, as well as tx/rx packet and byte counters.
func (m *DPConfig) PerformanceCounters(
func (m *DPConfigImpl) PerformanceCounters(
deviceName string,
pipelineName string,
functionName string,
Expand Down
14 changes: 7 additions & 7 deletions controlplane/internal/gateway/inspect_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ func (m *InspectService) Inspect(
return response, nil
}

func (m *InspectService) dpModules(dpConfig *ffi.DPConfig) []*ynpb.DPModuleInfo {
func (m *InspectService) dpModules(dpConfig ffi.DPConfig) []*ynpb.DPModuleInfo {
modules := dpConfig.Modules()

out := make([]*ynpb.DPModuleInfo, len(modules))
Expand All @@ -60,7 +60,7 @@ func (m *InspectService) dpModules(dpConfig *ffi.DPConfig) []*ynpb.DPModuleInfo
return out
}

func (m *InspectService) cpConfigs(dpConfig *ffi.DPConfig) []*ynpb.CPConfigInfo {
func (m *InspectService) cpConfigs(dpConfig ffi.DPConfig) []*ynpb.CPConfigInfo {
configs := dpConfig.CPConfigs()

out := make([]*ynpb.CPConfigInfo, len(configs))
Expand All @@ -75,7 +75,7 @@ func (m *InspectService) cpConfigs(dpConfig *ffi.DPConfig) []*ynpb.CPConfigInfo
return out
}

func (m *InspectService) functions(dpConfig *ffi.DPConfig) []*ynpb.FunctionInfo {
func (m *InspectService) functions(dpConfig ffi.DPConfig) []*ynpb.FunctionInfo {
functions := dpConfig.Functions()
if len(functions) == 0 {
return nil
Expand Down Expand Up @@ -109,7 +109,7 @@ func (m *InspectService) functions(dpConfig *ffi.DPConfig) []*ynpb.FunctionInfo
return out
}

func (m *InspectService) pipelines(dpConfig *ffi.DPConfig) []*ynpb.PipelineInfo {
func (m *InspectService) pipelines(dpConfig ffi.DPConfig) []*ynpb.PipelineInfo {
pipelines := dpConfig.Pipelines()

out := make([]*ynpb.PipelineInfo, len(pipelines))
Expand All @@ -128,7 +128,7 @@ func (m *InspectService) pipelines(dpConfig *ffi.DPConfig) []*ynpb.PipelineInfo
return out
}

func (m *InspectService) agents(dpConfig *ffi.DPConfig) []*ynpb.AgentInfo {
func (m *InspectService) agents(dpConfig ffi.DPConfig) []*ynpb.AgentInfo {
agents := dpConfig.Agents()

out := make([]*ynpb.AgentInfo, len(agents))
Expand All @@ -154,7 +154,7 @@ func (m *InspectService) agents(dpConfig *ffi.DPConfig) []*ynpb.AgentInfo {
return out
}

func (m *InspectService) devices(dpConfig *ffi.DPConfig) []*ynpb.DeviceInfo {
func (m *InspectService) devices(dpConfig ffi.DPConfig) []*ynpb.DeviceInfo {
devices := dpConfig.Devices()
if len(devices) == 0 {
return nil
Expand Down Expand Up @@ -189,6 +189,6 @@ func (m *InspectService) devices(dpConfig *ffi.DPConfig) []*ynpb.DeviceInfo {
return out
}

func (m *InspectService) numaIdx(dpConfig *ffi.DPConfig) uint32 {
func (m *InspectService) numaIdx(dpConfig ffi.DPConfig) uint32 {
return dpConfig.NumaIdx()
}
2 changes: 1 addition & 1 deletion modules/balancer/agent/go/ffi/agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ func (a *BalancerAgent) Inspect() *AgentInspect {
return inspect
}

func (a *BalancerAgent) DPConfig() *yanet.DPConfig {
func (a *BalancerAgent) DPConfig() yanet.DPConfig {
dpConfig := C.balancer_agent_dp_config(a.handle)
return yanet.NewDPConfigFromRaw(unsafe.Pointer(dpConfig))
}
4 changes: 4 additions & 0 deletions modules/forward/controlplane/backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,7 @@ func (m *backend) UpdateModule(name string, rules []cforward.ForwardRule) (Modul
func (m *backend) DeleteModule(name string) error {
return m.agent.DeleteModuleConfig(name)
}

func (m *backend) Agent() ffi.FFIAgent {
return m.agent
}
7 changes: 7 additions & 0 deletions modules/forward/controlplane/forwardpb/forward.proto
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ syntax = "proto3";
package forwardpb;

import "common/filterpb/filter.proto";
import "common/commonpb/metric.proto";

option go_package = "github.com/yanet-platform/yanet2/modules/forward/controlplane/forwardpb;forwardpb";

Expand All @@ -20,6 +21,8 @@ service ForwardService {
// Allows to delete forward config if it is not referenced
// by any pipeline.
rpc DeleteConfig(DeleteConfigRequest) returns (DeleteConfigResponse);

rpc GetMetrics(GetMetricsRequest) returns (GetMetricsResponse);
}

message Config {
Expand Down Expand Up @@ -77,3 +80,7 @@ message DeleteConfigRequest {
}

message DeleteConfigResponse { bool deleted = 1; }

message GetMetricsRequest {}

message GetMetricsResponse { repeated commonpb.Metric metrics = 1; }
Loading
Loading