Skip to content
Docs / dflux Runner
ContactGet started

Environments

An environment is the model of the network the engine drives against: which network functions are in scope, and the wire-level transports they speak over. This page covers the conceptual shape — the two-table layout, NF roles, and how the engine validates a flow against it.

The two-table model

Every environment has exactly two top-level tables:

YAML
  • nfs — what NFs exist, what role each one plays, which transport each one uses.
  • transports — wire stacks, indexed by ID. Each one declares one protocol stack plus the local + peer details that protocol needs.

NFs reference transports by ID. Multiple NFs can share a transport (two MMEs on one Diameter peer pool). Most labs use one NF per transport for clarity.

This split is deliberate. The same Diameter transport can serve multiple Diameter-side NFs without duplicating peer tables; the same gNB-properties block can pair with different NGAP transports across environments.

A typical multi-NF environment, visualised — two gNBs sharing one NGAP transport, plus an MME on its own Diameter transport, plus a remote UDM on SBI:

NF roles

Thirteen roles ship today, covering 5G core, 4G EPC, and a generic external escape hatch:

Code

Each shipped flow declares the role it simulates. The engine validates this against the environment at startup: a flow with nf: gnb won't run against an environment that declares no gNB. Mistakes fail fast at engine init, not mid-flow.

external is the convention for non-3GPP peers — vendor admin APIs, k8s control planes, internal management endpoints. The shipped REST flows use it.

Role-specific properties

Two NFs need additional identity beyond name + transport:

gNB carries the identity it advertises in NGSetupRequest:

YAML

AMF carries the identity it advertises in NGSetupResponse:

YAML

Other roles (MME, UDM, AUSF, PCRF, …) don't need a properties block — their identity is fully captured by the transport's protocol-specific config.

Transport blocks per protocol

YAML

Each protocol has its own sub-block.

  • NGAPmode: client | server, local_sctp, local_gtpu, peers: [{ address, port }].
  • Diameter — RFC 6733 shape: a local identity, a peers table, a routes realm-based routing table.
  • SBI — HTTP/2 client (base_url) or server (listen.addr/port) + optional tls, oauth2.
  • REST — same shape as SBI without OpenAPI typed bodies + per-binding auth: { type, token_env, … }.
  • PFCP — UDP/8805; mode: client | server, local, peer, node_id.

Full field tables live in the Environment schema reference.

Validation at load

When the engine loads an environment, it cross-checks every NF reference:

  • Every nfs[].transport must point to an existing transports[] ID.
  • Every transport's protocol: must match exactly one populated sub-block (e.g. protocol: ngap requires ngap: set; diameter: must be empty).
  • gNB-role NFs must have an NGAP transport. AMF-role NFs same.
  • A flow loaded against this environment must have an NF of the role it declares.

Failures fail-fast at startup, not mid-run. CLI prints the offending field and line.

Multi-NF environments

A single environment can declare every NF the daemon needs. Example: simulate two gNBs sharing one NGAP transport, plus an MME on Diameter, plus a remote UDM on SBI — see config/lab-multinf.yaml.

YAML

Multi-protocol flows drive multiple transports on a single UE — see Multi-protocol flows guide.

Where environments live in the daemon

In CLI mode, the environment is -c <file> — read once, discarded after the run. In daemon mode, environments are persisted in the control plane and sent to the agent as job payload. Schedules and on-demand runs reference an environment by id.

The same YAML schema applies in both modes — the control plane stores it as the body of an environment row.

Where to go next