Configuring environments
An environment is a YAML file that declares the network functions (NFs) dflux Runner simulates or talks to, plus the wire-level transports those NFs use. CLI runs load it via -c <file>; agent-mode jobs receive an environment payload from the control plane. This guide covers the top-level shape and each protocol's transport block. For the full field-by-field reference, see the environment schema.
; agent-mode jobs receive an environment payload from the control plane. This guide covers the top-level shape and each protocol's transport block. For the full field-by-field reference, see the environment schema.">
Top-level shape
Each NF references one transport by ID. Multiple NFs can share a transport (two MMEs on one Diameter peer pool) — but most labs use one NF per transport for clarity.
gNB properties
Set when role: gnb. Identity for the NGAP TX/RX pipeline; wire details live on the NGAP transport.
uplane: arms a user-plane traffic generator — see user-plane testing. auto_reply.handover_request: true makes the gNB stub-reply to inbound HandoverRequest so the source-side handover flow can complete (used by templates/gnb/handover_source.yaml).
AMF properties
Set when role: amf. Identity for AMF-mode (server) NGAP. The listen endpoint lives on the NGAP transport (mode: server); this block carries what the AMF advertises in NGSetupResponse.
Empty allowed_gnbs: means accept any gNB. Match is by RanNodeName against NGSetupRequest.RanNodeName.
NGAP transport
mode: client (default when peers: is non-empty) dials the listed AMFs on SCTP/38412. mode: server binds local_sctp and accepts inbound gNB associations (use empty peers: here).
local_gtpu is the IP the gNB advertises in PduSessionResourceSetupResponse for the N3 GTP-U tunnel — set it to whichever NIC the UPF will reach.
NGAP is 3GPP TS 38.413; SCTP is RFC 4960. The Payload Protocol Identifier is auto-set per NGAP convention.
Diameter transport
Diameter follows RFC 6733 shape: one local identity, a peer table, and a realm-based routing table.
Application IDs:
- S6a:
16777251(3GPP TS 29.272) - Gx:
16777238(3GPP TS 29.212) - Rx:
16777236(3GPP TS 29.214)
connection_mode sets the local node's role toward this peer:
initiator— dial the peer (default).responder— wait for the peer to dial. Requireslocal.listen.both— dial and accept inbound connections.
local_action follows RFC 6733 §6.1: local, relay, proxy, redirect. Default is relay.
SBI transport
SBI is HTTP/2 (3GPP TS 29.500-series). One binding is one mode — client (base_url) or server (listen).
oauth2.client_secret_env resolves the secret from an environment variable — never put secrets in YAML.
REST transport
Generic HTTP/2 for non-3GPP peers (Edge-admin REST, k8s API, internal management endpoints). Same shape as SBI but with no OpenAPI typed bodies — flow authors send arbitrary JSON via message_body:.
Shipped templates for Edge-admin REST are templates/rest/edge_admin_client.yaml and templates/rest/edge_admin_server.yaml, paired with config/lab-rest.yaml. For Diameter-side Edge filter/policy loopback (not REST), use config/lab-edge.yaml with the Edge Diameter templates under templates/edge/.
Auth type: values: none, basic (username_env + password_env), bearer (token_env), api_key (header + value_env). For Edge-admin bearer auth, export the token in EDGE_ADMIN_TOKEN — never put secrets in YAML.
PFCP transport
PFCP is UDP/8805 (3GPP TS 29.244). Conceptually NGAP-shaped (typed binary codec, per-session UE state) but on UDP rather than SCTP.
node_id.type: ipv4, ipv6, fqdn. The node ID is what the binding advertises in AssociationSetupRequest/Response and other node-level messages.
Multi-NF environments
A single environment can declare every NF a run needs. Example: simulate a gNB pair plus an MME plus a remote UDM in one config (see config/lab-multinf.yaml).
Multi-protocol flows (templates/multinf/) drive multiple transports on a single UE — see multi-protocol flows.
Troubleshooting
transport %q not declared in transports: — an NF references a transport ID that isn't in transports:. Typo or stale ID.
flow %q targets nf=%q but env declares no NF of that role — the flow's nf: field names a role with no matching NF in the environment. Matching is by role, not by name. Add an NF of that role.
Diameter peer hangs on CER — destination_host and destination_realm must match what the remote advertises in CEA. The shipped lab-diameter.yaml has comments showing what the remote-side origin_host/origin_realm need to be.
Gx/Rx flows can't find AVPs — extend the embedded dictionary via diameter_dictionary_path: if the PCRF ships custom AVPs not in the bundled Diameter set.
Where to go next
- Environment schema — the full field-by-field reference for every block above.
- Multi-protocol flows — drive several transports from one environment.
- User-plane testing — arm the gNB
uplane:traffic generator.