FermiHDI HD SDK — Interface Binding Contract¶
This document defines the mandatory interface binding requirements for the FermiHDI HD SDK
(hd_sdk). All consumers must supply explicit network interface names when initializing
the SDK. The SDK itself never reads environment variables for interface names.
Background¶
FermiHDI HD separates network traffic across three dedicated planes:
| Plane | Default Port | Protocol | Docker Compose Interface | K8s Interface Order |
|---|---|---|---|---|
| Data Plane | 6987 | FHDWP | eth1 (hd_dataplane) |
1st listed network |
| Control Plane | 6986 | HTTPS/mTLS | eth0 (hd_controlplane) |
2nd listed network |
| Observability | 8080 | HTTP | eth2 (hd_observability) |
3rd listed network |
Docker Compose Interface Order¶
In Docker Compose, multiple networks attached to a container are assigned kernel interface names in alphabetical order by network name:
Kubernetes Interface Order¶
In Kubernetes with Multus (or similar CNI), interfaces are assigned in the order the networks
are listed in the pod annotation. Follow the same data/control/observability order as above
to guarantee eth0 = control, eth1 = data, eth2 = observability.
C++ SDK Constructors¶
// Ingest client — binds the FHDWP data plane transport to data_plane_interface,
// and the control plane to control_plane_interface.
// Pass empty strings to bind to all interfaces (0.0.0.0).
explicit FermiHDIIngestClient(const std::string& data_plane_interface = "",
const std::string& control_plane_interface = "");
// Query client — same semantics as above.
explicit FermiHDIQueryClient(const std::string& proxy_url = "",
const std::string& data_plane_interface = "",
const std::string& control_plane_interface = "");
Example (C++, Docker Compose sandbox)¶
// Docker Compose: hd_controlplane=eth0, hd_dataplane=eth1
auto ingest_client = std::make_unique<fermihdi::sdk::FermiHDIIngestClient>("eth1", "eth0");
auto query_client = std::make_unique<fermihdi::sdk::FermiHDIQueryClient>("", "eth1", "eth0");
Go SDK¶
The Go CGO wrapper exposes two constructors:
// Convenience wrapper that binds to all interfaces (0.0.0.0).
func NewQueryClient(proxyURL string) *QueryClient
// Full constructor with explicit interface names.
// dataPlaneIface: kernel interface name for FHDWP data receive port (e.g. "eth1").
// ctrlPlaneIface: kernel interface name for mTLS control plane (e.g. "eth0").
func NewQueryClientWithInterfaces(proxyURL, dataPlaneIface, ctrlPlaneIface string) *QueryClient
Example (Go, using env vars set by Docker Compose or K8s)¶
// The consumer service reads interface names from env vars (set by compose.yml / K8s manifests)
// and forwards them to the SDK. The SDK itself does not read env vars.
dataPlane := os.Getenv("FERMIHDI_DATA_PLANE_INTERFACE") // e.g. "eth1"
ctrlPlane := os.Getenv("FERMIHDI_CONTROL_PLANE_INTERFACE") // e.g. "eth0"
client := fermihdi.NewQueryClientWithInterfaces(proxyURL, dataPlane, ctrlPlane)
Environment Variables (Consumer Services Only)¶
Consumer services (hd_graphql, hd_mcp, hd_data_explore, hd_ipflow_graphql) must
set the following environment variables in their Docker Compose environment: blocks or
Kubernetes manifests:
| Variable | Purpose | Example Value |
|---|---|---|
FERMIHDI_DATA_PLANE_INTERFACE |
Interface name for FHDWP data plane traffic | eth1 |
FERMIHDI_CONTROL_PLANE_INTERFACE |
Interface name for mTLS control plane traffic | eth0 |
FERMIHDI_OBSERVABILITY_INTERFACE |
Interface whose address is bound into the client certificate's SANs. The SDK serves no health or metrics endpoint of its own — see the API reference. | eth2 |
[!IMPORTANT] These env vars are consumed by the application layer (Go/Python wrappers), not by the C++ SDK directly. The application layer must read these values and pass them to the SDK constructor. Do not rely on the SDK to read env vars automatically.
[!WARNING] Failing to supply interface names results in the SDK binding to
0.0.0.0(all interfaces). In a segmented network deployment, this causes the HD engine's reactor to receive its own internalSIGUSR1/SIGUSR2signals on the HTTP library's thread pool, leading toSIGSEGV. Always provide explicit interface names in production.