sdk

package
v0.0.0-...-af60b5d Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 13, 2026 License: AGPL-3.0 Imports: 18 Imported by: 0

Documentation

Overview

Design: docs/architecture/api/process-protocol.md — plugin SDK Detail: sdk_callbacks.go — On*/Set* callback registration methods Detail: sdk_engine.go — plugin-to-engine RPC methods Detail: sdk_dispatch.go — event loop and callback dispatch Detail: sdk_types.go — re-exported RPC type aliases Detail: union.go — event stream correlation Related: ../../../internal/component/plugin/ipc/tls.go — TLS transport and auth (SendAuth, PluginAcceptor) Related: ../../../internal/component/plugin/process/process.go — engine-side process lifecycle (startExternal forks + WaitForPlugin)

Package sdk provides a high-level SDK for creating ze plugins using the YANG RPC protocol over a single bidirectional connection.

Plugins communicate with the ze engine via a single connection (net.Pipe for internal plugins, TLS for external). MuxConn multiplexes bidirectional RPCs by distinguishing responses (verb=ok/error) from requests (verb=method).

The SDK handles the 5-stage startup protocol and event loop automatically.

Basic usage:

p := sdk.NewFromEnv("my-plugin")
p.OnEvent(func(event string) error { ... })
p.OnConfigure(func(sections []sdk.ConfigSection) error { ... })
p.Run(ctx, sdk.Registration{
    Families: []sdk.FamilyDecl{{Name: "ipv4/flow", Mode: "both"}},
})

Index

Constants

View Source
const (
	DefaultPluginHost = "127.0.0.1"
	DefaultPluginPort = "12700"
)

Default plugin transport address (matches hub config default listen address).

View Source
const (
	OperationAddInterface       = rpc.OperationAddInterface
	OperationRemoveInterface    = rpc.OperationRemoveInterface
	OperationAddAddress         = rpc.OperationAddAddress
	OperationRemoveAddress      = rpc.OperationRemoveAddress
	OperationSetProperty        = rpc.OperationSetProperty
	OperationAddBridgeMember    = rpc.OperationAddBridgeMember
	OperationRemoveBridgeMember = rpc.OperationRemoveBridgeMember
	OperationAddPeer            = rpc.OperationAddPeer
	OperationRemovePeer         = rpc.OperationRemovePeer
	OperationModifyPeer         = rpc.OperationModifyPeer
	OperationAddListener        = rpc.OperationAddListener
	OperationRemoveListener     = rpc.OperationRemoveListener
	OperationAddStaticRoute     = rpc.OperationAddStaticRoute
	OperationRemoveStaticRoute  = rpc.OperationRemoveStaticRoute
	OperationSetAdminDistance   = rpc.OperationSetAdminDistance
	OperationSetSysctl          = rpc.OperationSetSysctl
	OperationStartDHCP          = rpc.OperationStartDHCP
	OperationStopDHCP           = rpc.OperationStopDHCP
	OperationAddTunnel          = rpc.OperationAddTunnel
	OperationRemoveTunnel       = rpc.OperationRemoveTunnel
)

Config operation type values.

View Source
const (
	ResourceInterface    = rpc.ResourceInterface
	ResourceAddress      = rpc.ResourceAddress
	ResourcePeer         = rpc.ResourcePeer
	ResourceListener     = rpc.ResourceListener
	ResourceBridgeMember = rpc.ResourceBridgeMember
	ResourceStaticRoute  = rpc.ResourceStaticRoute
	ResourceSysctl       = rpc.ResourceSysctl
	ResourceDHCP         = rpc.ResourceDHCP
	ResourceTunnel       = rpc.ResourceTunnel
)

Resource kind values.

View Source
const (
	DoctorPhasePreConfig     = rpc.DoctorPhasePreConfig
	DoctorPhaseMissingConfig = rpc.DoctorPhaseMissingConfig
	DoctorPhasePostConfig    = rpc.DoctorPhasePostConfig
)

DoctorCheckPhase values: wire form is "pre-config", "missing-config", "post-config".

View Source
const (
	FilterUnspecified = rpc.FilterUnspecified
	FilterAccept      = rpc.FilterAccept
	FilterReject      = rpc.FilterReject
	FilterModify      = rpc.FilterModify
)

FilterAction values: wire form is "accept", "reject", "modify".

View Source
const (
	FilterDirectionUnspecified = rpc.FilterDirectionUnspecified
	FilterImport               = rpc.FilterImport
	FilterExport               = rpc.FilterExport
	FilterBoth                 = rpc.FilterBoth
)

FilterDirection values: wire form is "import", "export", "both".

View Source
const (
	OnErrorUnspecified = rpc.OnErrorUnspecified
	OnErrorReject      = rpc.OnErrorReject
	OnErrorAccept      = rpc.OnErrorAccept
)

OnErrorPolicy values: wire form is "reject", "accept".

View Source
const (
	CapEncodingUnspecified = rpc.CapEncodingUnspecified
	CapEncodingHex         = rpc.CapEncodingHex
	CapEncodingBase64      = rpc.CapEncodingBase64
	CapEncodingText        = rpc.CapEncodingText
)

CapEncoding values: wire form is "hex", "b64", "text".

Variables

This section is empty.

Functions

func DialTLSEnvRaw

func DialTLSEnvRaw(name string) (net.Conn, error)

DialTLSEnvRaw performs the same TLS dial + auth handshake as NewFromTLSEnv (same env vars, same defaults) but returns the raw, still-unwrapped net.Conn instead of an already-initialized *Plugin. The auth response is read via ipc.ReadLineRaw (byte-by-byte, no bufio buffering-ahead -- see ipc.Authenticate's doc comment for why this matters) instead of wrapping the connection in rpc.Conn, so the returned conn is left perfectly clean for a caller that builds its own *Plugin via NewWithConn later (e.g. a registry.Registration.RunEngine(conn net.Conn) func, which every plugin already implements this way for its INTERNAL invocation path).

Test-only today: internal/test/cli's `ze-test plugin-external <name>` command is the only caller, launching a registered engine plugin's own RunEngine as a genuine external subprocess to prove its IsInternal()-guarded refuse/warn behavior actually fires outside a synthetic net.Pipe() unit test (plan/learned/1045-plugin-process-boundary.md). Production external plugins should be built as standalone binaries using pkg/plugin (see examples/plugin/go/main.go), not this generic launcher.

func SignalContext

func SignalContext() (context.Context, context.CancelFunc)

SignalContext returns a context that cancels when the plugin process receives SIGINT or SIGTERM, plus a CancelFunc that releases the handler when Run returns. Every plugin's runEngine/main entry point should use this at the top of its lifecycle so in-flight blocking calls (backend Apply, long-running IPC waits) unblock cleanly on daemon shutdown.

Typical use:

func runEngine(conn net.Conn) int {
    p := sdk.NewWithConn("myplugin", conn)
    defer p.Close()

    ctx, cancel := sdk.SignalContext()
    defer cancel()

    // ... register callbacks ...

    if err := p.Run(ctx, sdk.Registration{...}); err != nil {
        return 1
    }
    return 0
}

Internal (goroutine-mode) plugins share the process with ze, so ze's own main signal handler also catches SIGTERM -- the per-plugin handler is a belt-and-braces safety net. Subprocess (fork-mode) plugins rely on this helper as their only signal-cancellation path; without it they would be killed by the default Go signal disposition without running deferreds.

Centralizing the signal set (SIGINT + SIGTERM) here means future additions (e.g. SIGHUP for live reload) update every plugin in one place.

Types

type AllPluginsReadyHandler

type AllPluginsReadyHandler func() error

AllPluginsReadyHandler runs via the event loop after all plugins are loaded and registries frozen. This is the only safe place to DispatchCommand targeting another plugin at startup.

type ByeHandler

type ByeHandler func(reason string)

ByeHandler handles shutdown notification with the shutdown reason.

type CapEncoding

type CapEncoding = rpc.CapEncoding

CapEncoding is the typed payload encoding for a CapabilityDecl.

type CapabilityDecl

type CapabilityDecl = rpc.CapabilityDecl

CapabilityDecl declares a BGP capability for OPEN injection.

type CommandDecl

type CommandDecl = rpc.CommandDecl

CommandDecl declares a command the plugin provides.

type ConfigApplyHandler

type ConfigApplyHandler func([]ConfigDiffSection) error

ConfigApplyHandler handles config apply in the reload pipeline.

type ConfigApplyOutput

type ConfigApplyOutput = rpc.ConfigApplyOutput

ConfigApplyOutput is the output for config-apply (reload).

type ConfigDiffSection

type ConfigDiffSection = rpc.ConfigDiffSection

ConfigDiffSection describes what changed in a single config root (reload).

type ConfigOperation

type ConfigOperation = rpc.ConfigOperation

ConfigOperation is one atomic operation in an ordering-sensitive config transaction.

type ConfigOperationApplyHandler

type ConfigOperationApplyHandler func(ConfigOperationApplyInput) (*ConfigOperationApplyOutput, error)

ConfigOperationApplyHandler handles applying one config operation.

type ConfigOperationApplyInput

type ConfigOperationApplyInput = rpc.ConfigOperationApplyInput

ConfigOperationApplyInput is the input for config-operation-apply.

type ConfigOperationApplyOutput

type ConfigOperationApplyOutput = rpc.ConfigOperationApplyOutput

ConfigOperationApplyOutput is the output for config-operation-apply.

type ConfigOperationCommitHandler

type ConfigOperationCommitHandler func(ConfigOperationCommitInput) error

ConfigOperationCommitHandler handles committing operation journals.

type ConfigOperationCommitInput

type ConfigOperationCommitInput = rpc.ConfigOperationCommitInput

ConfigOperationCommitInput is the input for config-operation-commit.

type ConfigOperationCommitOutput

type ConfigOperationCommitOutput = rpc.ConfigOperationCommitOutput

ConfigOperationCommitOutput is the output for config-operation-commit.

type ConfigOperationDecl

type ConfigOperationDecl = rpc.ConfigOperationDecl

ConfigOperationDecl declares operation callback support during Stage 1.

type ConfigOperationDecomposeHandler

type ConfigOperationDecomposeHandler func(ConfigOperationDecomposeInput) (*ConfigOperationDecomposeOutput, error)

ConfigOperationDecomposeHandler handles operation decomposition.

type ConfigOperationDecomposeInput

type ConfigOperationDecomposeInput = rpc.ConfigOperationDecomposeInput

ConfigOperationDecomposeInput is the input for config-operation-decompose.

type ConfigOperationDecomposeOutput

type ConfigOperationDecomposeOutput = rpc.ConfigOperationDecomposeOutput

ConfigOperationDecomposeOutput is the output for config-operation-decompose.

type ConfigOperationParams

type ConfigOperationParams = rpc.ConfigOperationParams

ConfigOperationParams carries operation-specific values.

type ConfigOperationRollbackHandler

type ConfigOperationRollbackHandler func(ConfigOperationRollbackInput) error

ConfigOperationRollbackHandler handles rolling back config operations.

type ConfigOperationRollbackInput

type ConfigOperationRollbackInput = rpc.ConfigOperationRollbackInput

ConfigOperationRollbackInput is the input for config-operation-rollback.

type ConfigOperationRollbackOutput

type ConfigOperationRollbackOutput = rpc.ConfigOperationRollbackOutput

ConfigOperationRollbackOutput is the output for config-operation-rollback.

type ConfigOperationType

type ConfigOperationType = rpc.ConfigOperationType

ConfigOperationType identifies one atomic config operation.

type ConfigOperationVerifyHandler

type ConfigOperationVerifyHandler func(ConfigOperationVerifyInput) error

ConfigOperationVerifyHandler handles operation verification.

type ConfigOperationVerifyInput

type ConfigOperationVerifyInput = rpc.ConfigOperationVerifyInput

ConfigOperationVerifyInput is the input for config-operation-verify.

type ConfigOperationVerifyOutput

type ConfigOperationVerifyOutput = rpc.ConfigOperationVerifyOutput

ConfigOperationVerifyOutput is the output for config-operation-verify.

type ConfigRollbackHandler

type ConfigRollbackHandler func(txID string) error

ConfigRollbackHandler handles config rollback in the transaction protocol.

type ConfigSection

type ConfigSection = rpc.ConfigSection

ConfigSection is a config section delivered during Stage 2.

type ConfigVerifyHandler

type ConfigVerifyHandler func([]ConfigSection) error

ConfigVerifyHandler handles config verification in the reload pipeline. Return nil to accept the candidate config, error to reject.

type ConfigVerifyOutput

type ConfigVerifyOutput = rpc.ConfigVerifyOutput

ConfigVerifyOutput is the output for config-verify (reload).

type ConfigureHandler

type ConfigureHandler func([]ConfigSection) error

ConfigureHandler handles Stage 2 config delivery. Return nil to accept, error to reject.

type DeclareCapabilitiesInput

type DeclareCapabilitiesInput = rpc.DeclareCapabilitiesInput

DeclareCapabilitiesInput is the input for declare-capabilities (Stage 3).

type DecodeCapabilityHandler

type DecodeCapabilityHandler func(code uint8, hex string) (any, error)

DecodeCapabilityHandler handles capability decoding requests. Returns a Go value (JSON-marshaled by the SDK).

type DecodeMPReachOutput

type DecodeMPReachOutput = rpc.DecodeMPReachOutput

DecodeMPReachOutput is the output for decode-mp-reach (plugin→engine).

type DecodeMPUnreachOutput

type DecodeMPUnreachOutput = rpc.DecodeMPUnreachOutput

DecodeMPUnreachOutput is the output for decode-mp-unreach (plugin→engine).

type DecodeNLRIHandler

type DecodeNLRIHandler func(family string, hex string) (any, error)

DecodeNLRIHandler handles NLRI decoding requests. Returns a Go value (JSON-marshaled by the SDK).

type DecodeNLRIOutput

type DecodeNLRIOutput = rpc.DecodeNLRIOutput

DecodeNLRIOutput is the output for decode-nlri (plugin→engine).

type DecodeUpdateOutput

type DecodeUpdateOutput = rpc.DecodeUpdateOutput

DecodeUpdateOutput is the output for decode-update (plugin→engine).

type DispatchCommandOutput

type DispatchCommandOutput = rpc.DispatchCommandOutput

DispatchCommandOutput is the output for dispatch-command (runtime).

type DoctorCheckDecl

type DoctorCheckDecl = rpc.DoctorCheckDecl

DoctorCheckDecl declares a doctor readiness check the plugin provides.

type DoctorCheckDiagnostic

type DoctorCheckDiagnostic = rpc.DoctorCheckDiagnostic

DoctorCheckDiagnostic is a single diagnostic result from a plugin doctor check.

type DoctorCheckHandler

type DoctorCheckHandler func(name string) ([]rpc.DoctorCheckDiagnostic, error)

DoctorCheckHandler handles doctor check requests. Receives the check name, returns diagnostics.

type DoctorCheckPhase

type DoctorCheckPhase = rpc.DoctorCheckPhase

DoctorCheckPhase determines when a doctor check runs relative to config loading.

type EncodeNLRIHandler

type EncodeNLRIHandler func(family string, args []string) (string, error)

EncodeNLRIHandler handles NLRI encoding requests. Returns hex-encoded NLRI.

type EncodeNLRIOutput

type EncodeNLRIOutput = rpc.EncodeNLRIOutput

EncodeNLRIOutput is the output for encode-nlri (plugin→engine).

type EnrichShowHandler

type EnrichShowHandler func(command, key, mode string, base map[string]any) (map[string]any, error)

EnrichShowHandler handles show enrichment requests. Receives the command, key, mode ("detail" or "brief"), and base data map. Returns enrichment data to merge into the base map.

type EnrichShowInput

type EnrichShowInput = rpc.EnrichShowInput

EnrichShowInput is the input for enrich-show (runtime callback).

type EnrichShowOutput

type EnrichShowOutput = rpc.EnrichShowOutput

EnrichShowOutput is the output for enrich-show (runtime callback).

type EnricherDecl

type EnricherDecl = rpc.EnricherDecl

EnricherDecl declares a show enricher the plugin provides.

type EventHandler

type EventHandler func(event string) error

EventHandler handles runtime text event delivery (one JSON-encoded event string per call).

type ExecuteCommandHandler

type ExecuteCommandHandler func(serial, command string, args []string, peer string) (string, any, error)

ExecuteCommandHandler handles command execution requests. Returns status, data (JSON-marshaled by the SDK), and error.

type ExecuteCommandOutput

type ExecuteCommandOutput = rpc.ExecuteCommandOutput

ExecuteCommandOutput is the output for execute-command (runtime).

type FamilyDecl

type FamilyDecl = rpc.FamilyDecl

FamilyDecl declares an address family the plugin handles.

type FilterAction

type FilterAction = rpc.FilterAction

FilterAction is the typed wire decision for a filter-update response.

type FilterDecl

type FilterDecl = rpc.FilterDecl

FilterDecl declares a named route filter the plugin offers.

type FilterDirection

type FilterDirection = rpc.FilterDirection

FilterDirection is the typed wire direction for a FilterDecl.

type FilterUpdateHandler

type FilterUpdateHandler func(*FilterUpdateInput) (*FilterUpdateOutput, error)

FilterUpdateHandler handles route filter requests (accept/reject/modify with optional delta).

type FilterUpdateInput

type FilterUpdateInput = rpc.FilterUpdateInput

FilterUpdateInput is the input for filter-update (runtime callback).

type FilterUpdateOutput

type FilterUpdateOutput = rpc.FilterUpdateOutput

FilterUpdateOutput is the output for filter-update (runtime callback).

type Journal

type Journal struct {
	// contains filtered or unexported fields
}

Journal records apply/undo pairs during a config transaction. Plugins call Record for each side-effecting change during apply. On rollback, the journal replays undos in reverse order. On commit (config/committed), the journal is discarded.

Safe for single-goroutine use within a plugin's apply handler. Not safe for concurrent use.

func NewJournal

func NewJournal() *Journal

NewJournal creates an empty journal.

func (*Journal) Discard

func (j *Journal) Discard()

Discard clears the journal without calling any undo functions. Called when the transaction commits successfully.

func (*Journal) Len

func (j *Journal) Len() int

Len returns the number of recorded entries.

func (*Journal) Record

func (j *Journal) Record(apply, undo func() error) error

Record calls apply immediately. If apply succeeds, the undo function is stored for potential rollback. If apply fails, undo is not stored and the error is returned.

func (*Journal) Rollback

func (j *Journal) Rollback() []error

Rollback calls all stored undo functions in reverse order. Every undo is called even if earlier ones fail. Returns all errors.

type OnErrorPolicy

type OnErrorPolicy = rpc.OnErrorPolicy

OnErrorPolicy is the typed failure policy for a FilterDecl.

type Plugin

type Plugin struct {
	// contains filtered or unexported fields
}

Plugin represents a ze plugin using the YANG RPC protocol.

func NewFromEnv

func NewFromEnv(name string) (*Plugin, error)

NewFromEnv creates a plugin by reading ZE_PLUGIN_HUB_HOST, ZE_PLUGIN_HUB_PORT, and ZE_PLUGIN_HUB_TOKEN environment variables. Connects to the engine via TLS.

func NewFromTLSEnv

func NewFromTLSEnv(name string) (*Plugin, error)

NewFromTLSEnv creates a plugin by reading ze.plugin.hub.host, ze.plugin.hub.port, ze.plugin.hub.token, and ze.plugin.cert.fp env vars (dot or underscore notation). Connects to the engine via TLS, authenticates, and returns a single-conn plugin. ze.plugin.hub.host defaults to 127.0.0.1, ze.plugin.hub.port defaults to 12700. ze.plugin.hub.token is required. If ze.plugin.cert.fp is set, the TLS handshake verifies the server cert fingerprint.

func NewWithConn

func NewWithConn(name string, conn net.Conn) *Plugin

NewWithConn creates a plugin with a single bidirectional connection. MuxConn is created immediately for bidirectional RPC multiplexing. For internal plugins, conn may be a BridgedConn carrying a DirectBridge reference for post-startup direct transport.

func NewWithIO

func NewWithIO(name string, reader io.ReadCloser, writer io.WriteCloser) *Plugin

NewWithIO creates a plugin from separate reader and writer streams. Use this for non-TCP transports (SSH channels, stdin/stdout pipes) where a net.Conn is not available. MuxConn is created immediately for bidirectional RPC multiplexing.

func (*Plugin) BatchValidate

func (p *Plugin) BatchValidate(ctx context.Context, decisions []rpc.ValidationDecision) (*rpc.BatchValidateResult, error)

BatchValidate sends a batch of RPKI validation decisions to adj-rib-in. Fast path: typed DirectBridge dispatch (no string serialization). Slow path: the JSON codec over the socket (rpc.MethodBatchValidate) for forked/external plugins without a typed slot.

func (*Plugin) Close

func (p *Plugin) Close() error

Close closes the underlying connections, unblocking any goroutines waiting on Read(). Must be called when the plugin is done to prevent goroutine and socket leaks. Safe to call multiple times.

func (*Plugin) DecodeMPReach

func (p *Plugin) DecodeMPReach(ctx context.Context, hex string, addPath bool) (*rpc.DecodeMPReachOutput, error)

DecodeMPReach requests MP_REACH_NLRI decoding from the engine. The engine parses the attribute value (AFI+SAFI+NH+NLRI) and returns the family, next-hop, and decoded NLRI. RFC 4760 Section 3.

func (*Plugin) DecodeMPUnreach

func (p *Plugin) DecodeMPUnreach(ctx context.Context, hex string, addPath bool) (*rpc.DecodeMPUnreachOutput, error)

DecodeMPUnreach requests MP_UNREACH_NLRI decoding from the engine. The engine parses the attribute value (AFI+SAFI+Withdrawn) and returns the family and decoded withdrawn NLRI. RFC 4760 Section 4.

func (*Plugin) DecodeNLRI

func (p *Plugin) DecodeNLRI(ctx context.Context, family, hex string) (json.RawMessage, error)

DecodeNLRI requests NLRI decoding from the engine via the plugin registry. The engine routes the request to the in-process decoder for the given family. Returns the JSON representation of the decoded NLRI.

func (*Plugin) DecodeUpdate

func (p *Plugin) DecodeUpdate(ctx context.Context, hex string, addPath bool) (string, error)

DecodeUpdate requests full UPDATE message decoding from the engine. The engine parses the UPDATE body (after 19-byte BGP header) and returns the ze-bgp JSON representation. RFC 4271 Section 4.3.

func (*Plugin) DispatchCommand

func (p *Plugin) DispatchCommand(ctx context.Context, command string) (status string, data json.RawMessage, err error)

DispatchCommand dispatches a command through the engine's command dispatcher. Returns the status and raw JSON data from the target handler's response. This enables inter-plugin communication: the engine routes the command to the target plugin via longest-match registry lookup and returns the full structured response. Error text from the handler is returned as a Go error (not in data).

func (*Plugin) DispatchCommandArgs

func (p *Plugin) DispatchCommandArgs(ctx context.Context, command string, args []string, peer string) (status string, data json.RawMessage, err error)

DispatchCommandArgs dispatches an exact registered command with pre-tokenized arguments through the engine's command dispatcher. It preserves the external dispatch-command API while avoiding command-string tokenization for internal data.

func (*Plugin) EmitEvent

func (p *Plugin) EmitEvent(ctx context.Context, namespace, eventType, direction, peerAddress, event string) (int, error)

EmitEvent pushes an event into the engine's delivery pipeline. The engine finds subscribers matching the namespace, event type, direction, and peer, then delivers the event string to each. Returns the number of subscribers reached.

func (*Plugin) EncodeNLRI

func (p *Plugin) EncodeNLRI(ctx context.Context, family string, args []string) (string, error)

EncodeNLRI requests NLRI encoding from the engine via the plugin registry. The engine routes the request to the in-process encoder for the given family. Returns hex-encoded NLRI bytes.

func (*Plugin) ForwardCached

func (p *Plugin) ForwardCached(ctx context.Context, updateIDs []uint64, destinations []string) error

ForwardCached forwards cached UPDATEs identified by updateIDs to the listed destination peers. Bypasses the update-route tokenise path (rs-fastpath-3).

destinations are peer IP address strings; the engine parses them once at the reactor boundary and maps them to resolved peers. updateIDs must have been delivered to this plugin via its event subscription while CacheConsumer is true -- the engine acks each id for this plugin after forwarding (FIFO on FIFO consumers, per-entry on CacheConsumerUnordered consumers).

Returns an error when the reactor cannot look up any of the updateIDs or the request cannot be dispatched. Individual per-destination failures are logged and do not fail the call.

func (*Plugin) InjectWireRoute

func (p *Plugin) InjectWireRoute(protocol, peerKey string, updateBody []byte) error

InjectWireRoute sends raw BGP UPDATE body bytes to the RIB under a named protocol. Zero-copy via DirectBridge typed handler (no hex encoding) for in-process plugins; a forked/external plugin with no typed slot falls back to the JSON codec over the socket (rpc.MethodInjectWireRoute). The method has no ctx parameter, so the fallback uses a background context.

func (*Plugin) IsInternal

func (p *Plugin) IsInternal() bool

IsInternal reports whether this plugin instance is running in-process with the engine (a DirectBridge was discovered on conn in NewWithConn) as opposed to a forked subprocess talking over TLS. True exactly when the engine started this plugin via the "internal" invocation mode (process.go's startInternal, which wraps the net.Pipe() end with rpc.NewBridgedConn).

A plugin that calls another in-process package's plain Go functions directly -- bypassing DirectBridge/DispatchCommand, e.g. as112 calling iface.RegisterOwnedAddresses -- MUST check this and refuse to start if false. Such a call is syntactically valid and returns no error when run external: it silently operates on the subprocess's own copy of the target package's state, never the engine process's.

func (*Plugin) OnAllPluginsReady

func (p *Plugin) OnAllPluginsReady(fn AllPluginsReadyHandler)

OnAllPluginsReady sets a callback that runs via the event loop after the engine has finished loading ALL plugins across ALL startup phases (config- path auto-load, explicit, family, event-type, send-type) and has frozen the dispatcher and plugin registries. This is the only place in startup where a plugin can safely DispatchCommand targeting another plugin, because only at this point is every other plugin's command guaranteed to be registered.

The handler is dispatched via the normal event loop, so it runs AFTER OnStarted has returned. It is delivered best-effort by the engine -- a plugin that has died before this point does not receive the callback.

The fn parameter takes no context: runtime calls should use context.Background() with an explicit timeout. Errors returned from fn are propagated as an RPC error response to the engine and logged there; the plugin continues running.

func (*Plugin) OnBye

func (p *Plugin) OnBye(fn ByeHandler)

OnBye sets the handler for shutdown notification.

func (*Plugin) OnConfigApply

func (p *Plugin) OnConfigApply(fn ConfigApplyHandler)

OnConfigApply sets the handler for config apply requests (reload pipeline). The handler receives diff sections describing what changed and returns nil to accept or an error to reject. If no handler is registered, config-apply returns OK (no-op).

func (*Plugin) OnConfigOperationApply

func (p *Plugin) OnConfigOperationApply(fn ConfigOperationApplyHandler)

OnConfigOperationApply sets the handler for applying one operation.

func (*Plugin) OnConfigOperationCommit

func (p *Plugin) OnConfigOperationCommit(fn ConfigOperationCommitHandler)

OnConfigOperationCommit sets the handler for committing operation journals.

func (*Plugin) OnConfigOperationDecompose

func (p *Plugin) OnConfigOperationDecompose(fn ConfigOperationDecomposeHandler)

OnConfigOperationDecompose sets the handler for operation decomposition.

func (*Plugin) OnConfigOperationRollback

func (p *Plugin) OnConfigOperationRollback(fn ConfigOperationRollbackHandler)

OnConfigOperationRollback sets the handler for rolling back operations.

func (*Plugin) OnConfigOperationVerify

func (p *Plugin) OnConfigOperationVerify(fn ConfigOperationVerifyHandler)

OnConfigOperationVerify sets the handler for operation verification.

func (*Plugin) OnConfigRollback

func (p *Plugin) OnConfigRollback(fn ConfigRollbackHandler)

OnConfigRollback sets the handler for config rollback requests (transaction protocol). The handler receives the transaction ID and should undo changes applied during this transaction (typically by calling journal.Rollback()). If no handler is registered, rollback is a no-op.

func (*Plugin) OnConfigVerify

func (p *Plugin) OnConfigVerify(fn ConfigVerifyHandler)

OnConfigVerify sets the handler for config verification requests (reload pipeline). The handler receives the full candidate config sections and returns nil to accept or an error to reject. If no handler is registered, config-verify returns OK (no-op).

func (*Plugin) OnConfigure

func (p *Plugin) OnConfigure(fn ConfigureHandler)

OnConfigure sets the handler for Stage 2 config delivery.

func (*Plugin) OnDecodeCapability

func (p *Plugin) OnDecodeCapability(fn DecodeCapabilityHandler)

OnDecodeCapability sets the handler for capability decoding requests. The handler receives the capability code and hex-encoded bytes, and returns a Go data structure. The SDK marshals it once into the response.

func (*Plugin) OnDecodeNLRI

func (p *Plugin) OnDecodeNLRI(fn DecodeNLRIHandler)

OnDecodeNLRI sets the handler for NLRI decoding requests. The handler receives the address family and hex-encoded NLRI, and returns a Go data structure. The SDK marshals it once into the response.

func (*Plugin) OnDoctorCheck

func (p *Plugin) OnDoctorCheck(fn DoctorCheckHandler)

OnDoctorCheck sets the handler for doctor check requests. The handler receives the check name and returns diagnostics. If no handler is registered, doctor-check returns empty diagnostics (no-op).

func (*Plugin) OnEncodeNLRI

func (p *Plugin) OnEncodeNLRI(fn EncodeNLRIHandler)

OnEncodeNLRI sets the handler for NLRI encoding requests. The handler receives the address family and arguments, and returns hex-encoded NLRI.

func (*Plugin) OnEnrichShow

func (p *Plugin) OnEnrichShow(fn EnrichShowHandler)

OnEnrichShow sets the handler for show enrichment requests. The handler receives the command, enricher key, and base data map, and returns enrichment data to merge into the base map. If no handler is registered, enrich-show returns empty data (no-op).

func (*Plugin) OnEvent

func (p *Plugin) OnEvent(fn EventHandler)

OnEvent sets the handler for runtime event delivery.

func (*Plugin) OnExecuteCommand

func (p *Plugin) OnExecuteCommand(fn ExecuteCommandHandler)

OnExecuteCommand sets the handler for command execution requests. The handler receives serial, command, args, peer and returns (status, data, error). The SDK marshals the data value into ExecuteCommandOutput.Data as json.RawMessage, producing a single marshal instead of double-encoding.

func (*Plugin) OnFilterUpdate

func (p *Plugin) OnFilterUpdate(fn FilterUpdateHandler)

OnFilterUpdate sets the handler for route filter requests (redistribution). The handler receives filter input (filter name, direction, peer, update text) and returns a PolicyResponse (accept/reject/modify with optional delta).

func (*Plugin) OnShareRegistry

func (p *Plugin) OnShareRegistry(fn ShareRegistryHandler)

OnShareRegistry sets the handler for Stage 4 registry delivery.

func (*Plugin) OnStarted

func (p *Plugin) OnStarted(fn StartedHandler)

OnStarted sets a callback that runs after the 5-stage startup completes but before the event loop begins. This is the safe place to make engine calls (e.g., SubscribeEvents) because the connection is no longer blocked by the startup coordinator. Do NOT make engine calls inside OnShareRegistry or OnConfigure -- those run while the engine is waiting for the response, causing a deadlock.

IMPORTANT: OnStarted fires after THIS plugin's 5-stage handshake completes but potentially BEFORE other plugins in later startup phases are loaded. Do NOT call DispatchCommand from OnStarted targeting a plugin that lives in a different startup phase: the dispatcher command registry may not yet contain the target command. Use OnAllPluginsReady for cross-plugin dispatches.

func (*Plugin) OnStructuredEvent

func (p *Plugin) OnStructuredEvent(fn StructuredEventHandler)

OnStructuredEvent sets the handler for structured event delivery via DirectBridge. When registered, the bridge delivers structured events directly (no text formatting). The handler receives []any where each element is a *rpc.StructuredEvent.

func (*Plugin) OnValidateOpen

func (p *Plugin) OnValidateOpen(fn ValidateOpenHandler)

OnValidateOpen sets the handler for OPEN validation requests. The handler receives both local and remote OPEN messages and returns accept/reject. When registered, WantsValidateOpen is automatically set in Stage 1 registration. If no handler is registered, validate-open returns accept (no-op).

func (*Plugin) ReleaseCached

func (p *Plugin) ReleaseCached(ctx context.Context, updateIDs []uint64) error

ReleaseCached acks the listed cached updateIDs for this plugin without forwarding to peers. Symmetric with ForwardCached for the "decided not to forward" path. rs-fastpath-3.

func (*Plugin) RouteInstall

func (p *Plugin) RouteInstall(ctx context.Context, routes []rpc.RouteInstallEntry) (installed uint32, err error)

RouteInstall inserts a batch of computed routes into the engine's process-wide Loc-RIB. It is the cross-process bridge for a FORKED route-installing plugin (OSPF, IS-IS): in-process the plugin writes locrib.Default() directly, but a forked subprocess gets a nil Loc-RIB (default.go returns nil under ze.plugin.hub.token), so it ships the ops here and the engine applies them to the real singleton, where sysrib's OnChange programs the kernel. Returns the number of routes applied. Each entry carries the protocol NAME; the engine re-resolves it to its own numeric ProtocolID.

func (*Plugin) RouteRemove

func (p *Plugin) RouteRemove(ctx context.Context, routes []rpc.RouteRemoveEntry) (removed uint32, err error)

RouteRemove withdraws a batch of routes from the engine's Loc-RIB by their (protocol, family, prefix, instance) identity. Symmetric with RouteInstall for the forked route-installing path. Returns the number of routes withdrawn.

func (*Plugin) Run

func (p *Plugin) Run(ctx context.Context, reg Registration) error

Run executes the 5-stage startup protocol and enters the event loop. Returns nil on clean shutdown (bye received), or error on failure.

func (*Plugin) SetCapabilities

func (p *Plugin) SetCapabilities(caps []CapabilityDecl)

SetCapabilities sets the capabilities to declare during Stage 3. Must be called before Run().

func (*Plugin) SetEncoding

func (p *Plugin) SetEncoding(enc string)

SetEncoding sets the event encoding preference ("json" or "text"). Must be called after SetStartupSubscriptions and before Run(). Text encoding uses space-delimited output parseable by strings.Fields instead of nested JSON requiring json.Unmarshal.

func (*Plugin) SetStartupSubscriptions

func (p *Plugin) SetStartupSubscriptions(events, peers []string, format string)

SetStartupSubscriptions sets event subscriptions to include in the "ready" RPC. The engine registers these atomically before SignalAPIReady, ensuring the plugin receives events from the very first route send. Must be called before Run().

This replaces the pattern of calling SubscribeEvents in OnStarted, which had a race condition: SignalAPIReady triggered route sends before the subscription RPC could be processed.

func (*Plugin) SubscribeEvents

func (p *Plugin) SubscribeEvents(ctx context.Context, events, peers []string, format string) error

SubscribeEvents requests event delivery from the engine.

func (*Plugin) UnsubscribeEvents

func (p *Plugin) UnsubscribeEvents(ctx context.Context) error

UnsubscribeEvents stops event delivery from the engine.

func (*Plugin) UpdateRoute

func (p *Plugin) UpdateRoute(ctx context.Context, peerSelector, command string) (announced, withdrawn uint32, err error)

UpdateRoute injects a route update to matching peers via the engine. Returns the number of NLRIs announced and withdrawn.

func (*Plugin) UpdateRouteSel

func (p *Plugin) UpdateRouteSel(ctx context.Context, sel *selector.Selector, command string) (announced, withdrawn uint32, err error)

UpdateRouteSel is the typed-selector variant of UpdateRoute. In-process plugins use this to pass a *selector.Selector through DirectBridge without stringifying. Falls back to the string path for external plugins.

func (*Plugin) UpdateRouteSelWithMeta

func (p *Plugin) UpdateRouteSelWithMeta(ctx context.Context, sel *selector.Selector, command string, meta map[string]any) (announced, withdrawn uint32, err error)

UpdateRouteSelWithMeta is the typed-selector variant of UpdateRouteWithMeta.

func (*Plugin) UpdateRouteWithMeta

func (p *Plugin) UpdateRouteWithMeta(ctx context.Context, peerSelector, command string, meta map[string]any) (announced, withdrawn uint32, err error)

UpdateRouteWithMeta injects a route update with metadata to matching peers. Meta is plumbed to CommandContext.Meta for the command dispatch path. For forwarded cached routes (peer-to-peer), ingress filters set ReceivedUpdate.Meta which egress filters read. Plugin-originated routes currently go through AnnounceNLRIBatch (direct send) where CommandContext.Meta is not yet consumed by egress filters. Pass nil meta for routes without metadata (equivalent to UpdateRoute).

type Registration

type Registration = rpc.DeclareRegistrationInput

Registration is the SDK name for the declare-registration input (Stage 1).

type RegistryCommand

type RegistryCommand = rpc.RegistryCommand

RegistryCommand is a command in the shared registry (Stage 4).

type ResourceKind

type ResourceKind = rpc.ResourceKind

ResourceKind identifies the resource an operation targets.

type ResourceRef

type ResourceRef = rpc.ResourceRef

ResourceRef is the solver-visible target for an operation.

type SchemaDecl

type SchemaDecl = rpc.SchemaDecl

SchemaDecl declares the YANG schema the plugin provides.

type ShareRegistryHandler

type ShareRegistryHandler func([]RegistryCommand)

ShareRegistryHandler handles Stage 4 registry delivery.

type StartedHandler

type StartedHandler func(ctx context.Context) error

StartedHandler runs after the 5-stage startup completes but before the event loop. Do NOT call DispatchCommand from here targeting other plugins; use AllPluginsReadyHandler.

type StructuredEventHandler

type StructuredEventHandler func(events []any) error

StructuredEventHandler handles structured event delivery via DirectBridge. Each element is a *rpc.StructuredEvent.

type Union

type Union struct {
	// contains filtered or unexported fields
}

Union correlates two asynchronous event streams by message ID and peer address. The consumer creates a union, feeds events via OnEvent, and receives joined pairs via the handler callback. If the secondary event doesn't arrive within the timeout, the handler is called with an empty secondary.

Stop() MUST be called when the Union is no longer needed to prevent goroutine leaks.

func NewUnion

func NewUnion(primaryType, secondaryType string, timeout time.Duration, handler func(primary, secondary string)) *Union

NewUnion creates a union that correlates events of primaryType and secondaryType. The handler is called with (primary event, secondary event) when both arrive, or (primary, "") on timeout/flush. If handler is nil, events are silently dropped.

Stop() MUST be called when the Union is no longer needed.

func (*Union) FlushPeer

func (u *Union) FlushPeer(peer string)

FlushPeer delivers all pending entries for the given peer with empty secondary.

func (*Union) OnEvent

func (u *Union) OnEvent(eventType, peer string, msgID uint64, event string)

OnEvent feeds an event into the union for correlation. eventType identifies which stream (primary or secondary). peer and msgID form the correlation key.

func (*Union) Stop

func (u *Union) Stop()

Stop stops the timeout sweep goroutine. Safe to call multiple times.

type UpdateRouteOutput

type UpdateRouteOutput = rpc.UpdateRouteOutput

UpdateRouteOutput is the output for update-route (runtime).

type ValidateOpenCapability

type ValidateOpenCapability = rpc.ValidateOpenCapability

ValidateOpenCapability is a single capability from an OPEN message.

type ValidateOpenHandler

type ValidateOpenHandler func(*ValidateOpenInput) *ValidateOpenOutput

ValidateOpenHandler handles OPEN validation requests. Returns accept/reject decision.

type ValidateOpenInput

type ValidateOpenInput = rpc.ValidateOpenInput

ValidateOpenInput is the input for validate-open (OPEN validation).

type ValidateOpenMessage

type ValidateOpenMessage = rpc.ValidateOpenMessage

ValidateOpenMessage represents one side of the OPEN exchange.

type ValidateOpenOutput

type ValidateOpenOutput = rpc.ValidateOpenOutput

ValidateOpenOutput is the output for validate-open (OPEN validation).

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL