A reproducible 5G Standalone (SA) smart-factory network slicing lab built with Open5GS, UERANSIM, Docker Compose, and a custom web dashboard for control, observability, transport policy, and automated validation.
This project is designed to make 5G slicing visible, measurable, and explainable. It provides a local environment where multiple slices run simultaneously, each with distinct user-plane behavior, QoS shaping, subscriber mappings, and test thresholds.
- 1. Project Summary
- 2. Smart Factory Use Cases and Why 5G Fits
- 3. System Architecture
- 4. Key Features
- 5. Repository Structure
- 6. Prerequisites
- 7. Quick Start
- 8. Running the Dashboard
- 9. How the Demo Works End to End
- 10. Configuration and Data Model
- 11. UI Dashboard Guide
- 12. Automated Test and Validation Pipeline
- 13. API Overview
- 14. Metrics and Report Outputs
- 15. Troubleshooting
- 16. Final Deliverables
- 17. Acknowledgements
- 18. Glossary
- 19. Authors
This repository implements a smart-factory-oriented 5G SA slicing demo with the following capabilities:
- Multi-slice topology with dedicated SMF and UPF instances per slice.
- UERANSIM gNB and multiple UEs mapped to slices.
- Per-slice QoS shaping using
tcinside UPF containers. - Per-slice transport filtering using
iptablesinside UPF containers. - Subscriber provisioning workflows through
open5gs-dbctland MongoDB. - Live dashboard with topology, status, metrics, logs, transport controls, and configuration editors.
- Automated ping and iPerf based validation with test history and generated HTML reports.
Primary runtime scenario for the dashboard:
compose-files/network-slicing/docker-compose.yaml
A smart factory typically carries multiple traffic classes over the same physical infrastructure. Those traffic classes have conflicting requirements:
- Robot control traffic needs low latency and predictable behavior.
- Vision inspection and AR/video traffic need sustained throughput.
- Large fleets of sensors produce many low-bandwidth flows that can tolerate delay.
- Enterprise and engineering traffic needs reliable connectivity but should not disturb critical control traffic.
- Experimental workloads need a safe space to test policy changes.
A single best-effort network profile is usually a poor fit for all of these at the same time.
5G slicing is a strong fit because it allows one shared infrastructure to host multiple logical service profiles with independent policy and traffic treatment.
This project demonstrates that alignment by mapping each slice to a factory-like service class:
| Slice | Category | Example smart-factory role | Why it fits 5G slicing |
|---|---|---|---|
| Slice A | eMBB | Video inspection, AR guidance, high-volume telemetry dashboards | High throughput focus with lower added latency and higher bandwidth caps |
| Slice B | URLLC | Robot coordination, safety interlocks, control signaling | Lower latency targets and tighter QoS settings |
| Slice C | mMTC | Dense sensors, meters, machine state reporting | Lower throughput expectations and higher latency tolerance |
| Slice D | Enterprise | Engineering workstations, HMIs, admin services | Balanced performance with moderate latency and throughput |
| Slice E | Experimental | Testing new QoS/transport policies | Safe sandbox for tuning and demonstrating policy impact |
The dashboard includes named presets in dashboard/data/use-cases.json that apply slice-wide QoS values and validation thresholds:
- Objective: Balanced throughput and latency across all factory zones with clear differentiation between slices.
- Slice configuration: 5 slices (eMBB, URLLC, mMTC, Enterprise, Experimental) mapped to dedicated SMF/UPF pairs.
- QoS setup:
- Slice A: 120 Mbps, +0 ms
- Slice B: 60 Mbps, +10 ms
- Slice C: 20 Mbps, +40 ms
- Slice D: 80 Mbps, +15 ms
- Slice E: 30 Mbps, +25 ms
- Expected behavior: eMBB throughput dominates; URLLC remains low latency; mMTC tolerates higher latency.
- Automated verification:
- UEs attached and PDU sessions established
- Subnet correctness per slice
- Latency, loss, throughput within thresholds
- QoS enforcement vs max rate
- Expected KPIs: Latency and throughput thresholds defined in
use-cases.jsonper slice.
- Objective: Prioritize URLLC and Enterprise slices with strict latency targets.
- Slice configuration: Same mapping, but with tighter URLLC/Enterprise thresholds.
- QoS setup:
- Slice A: 150 Mbps, +0 ms
- Slice B: 80 Mbps, +5 ms
- Slice C: 15 Mbps, +60 ms
- Slice D: 100 Mbps, +8 ms
- Slice E: 25 Mbps, +30 ms
- Expected behavior: URLLC and Enterprise achieve lower latency; mMTC is de-prioritized.
- Automated verification: Same checks as Factory Balanced, evaluated with stricter thresholds.
- Expected KPIs: Lower latency targets for Slice B and Slice D.
- Objective: mMTC-heavy traffic with tolerance for higher latency while protecting eMBB throughput.
- Slice configuration: Same mapping, with QoS emphasizing Slice A throughput.
- QoS setup:
- Slice A: 140 Mbps, +0 ms
- Slice B: 50 Mbps, +15 ms
- Slice C: 25 Mbps, +80 ms
- Slice D: 70 Mbps, +20 ms
- Slice E: 35 Mbps, +35 ms
- Expected behavior: High tolerance on Slice C, stable throughput for Slice A.
- Automated verification: Same checks as Factory Balanced, evaluated with IoT-focused thresholds.
- Expected KPIs: Higher acceptable latency for Slice C, preserved throughput for Slice A.
These presets help answer practical questions such as:
- What happens if the factory shifts from balanced operation to a control-priority mode?
- Can the current slice QoS still satisfy latency and throughput thresholds?
- Which slices degrade first under stricter policies?
This project combines four layers:
- 5G Core and RAN simulation (Open5GS + UERANSIM)
- Container orchestration and networking (Docker Compose)
- Control and automation (Python backend + Bash scripts)
- Visualization and operations UI (SPA dashboard)
High-level traffic path:
UE containers -> gNB (UERANSIM) -> Open5GS Core (AMF/SMF/UPF...) -> Data plane / transport path
There is no separate external SDN controller in this implementation.
Instead, the dashboard backend acts as the control plane by:
- Orchestrating Docker Compose services
- Rewriting Open5GS and UERANSIM YAML configs
- Applying
tcQoS inside UPF containers - Applying
iptablestransport rules inside UPF containers - Running test scripts and evaluating results
The table below describes the role of each runtime component. For the corresponding on-disk directory layout, see Section 5 (Repository Structure).
| Component | Implementation | Role |
|---|---|---|
| 5G Core | Open5GS containers | Core network functions (AMF, SMF, UPF, NRF, NSSF) |
| RAN/UE simulation | UERANSIM containers | gNB and UE behavior |
| Dashboard backend | dashboard/server.py |
API server, SSE snapshots, orchestration, config application |
| Test engine | dashboard/backend/test_engine.py |
Test run orchestration, evaluation, report generation |
| Frontend UI | dashboard/index.html, dashboard/app.js, dashboard/styles.css |
Control center and visualization |
| Metrics collection | scripts/collect-metrics.sh, scripts/run-iperf.sh |
Ping and iPerf automation |
| Persistence | JSON files under dashboard/data and metrics under metrics/ |
UI config/state and test artifacts |
The system handles two distinct types of flows:
- Control Plane Flow: User → Dashboard → API → Backend → Docker → Config/QoS/Testing
- Data Plane Flow: UE → gNB → 5G Core → UPF (QoS) → Network
The backend builds a periodic snapshot that includes:
- Stack status
- Topology
- Slices
- Parsed metrics
- UE states
- Test history revision metadata
This snapshot is streamed to the UI using Server-Sent Events (SSE) at /api/stream, with a polling fallback in the frontend if SSE becomes unhealthy.
- Slice-aware topology and service monitoring
- Live UE attach/PDU/IP status
- Slice configuration editor (IDs, QoS, mapping, UE assignments)
- Subscriber provisioning and subscriber profile templates
- PLMN / S-NSSAI profile application across configs
- Transport controls (
tc+iptables) per slice - Automated validation (ping + iPerf + threshold checks)
- Historical test runs and generated HTML reports
- Dashboard-driven demo initialization and shutdown
The directories below map directly to the runtime components listed in Section 3.3 (Runtime Components).
.
├── build-files/
│ └── images/
│ ├── amf-open5gs/
│ ├── ausf-open5gs/
│ ├── base-open5gs/
│ ├── base-ueransim/
│ ├── bsf-open5gs/
│ ├── gnb-ueransim/
│ ├── mongodb/
│ ├── nrf-open5gs/
│ ├── nssf-open5gs/
│ ├── packetrusher/
│ ├── pcf-open5gs/
│ ├── scp-open5gs/
│ ├── sepp-open5gs/
│ ├── smf-open5gs/
│ ├── udm-open5gs/
│ ├── udr-open5gs/
│ ├── ue-ueransim/
│ ├── upf-open5gs/
│ └── webui-open5gs/
├── compose-files/
│ ├── basic/
│ │ ├── packetrusher/
│ │ └── ueransim/
│ ├── network-slicing/ # Primary runtime scenario
│ ├── roaming/
│ ├── scp/
│ │ ├── model-c/
│ │ └── model-d/
│ └── speed-test/
├── configs/
│ ├── basic/
│ │ ├── packetrusher/
│ │ └── ueransim/
│ ├── network-slicing/ # Open5GS + UERANSIM YAML configs
│ ├── roaming/
│ ├── scp/
│ │ ├── model-c/
│ │ └── model-d/
│ └── speed-test/
├── dashboard/
│ ├── backend/ # test_engine.py and orchestration helpers
│ └── data/ # Persistent JSON state (slices, subscribers, profiles, history)
├── docs/
│ ├── diagrams/
│ ├── images/
│ └── team-1g/
│ ├── research-papers/
│ ├── terminal-screenschots/
│ ├── wireshark-captures/
│ └── wireshark-screenshots/
├── explain/
├── metrics/
│ └── runs/ # Per-run test artifacts (CSV, JSON, HTML reports)
└── scripts/ # Bash automation (start-demo, collect-metrics, run-iperf)
| Requirement | Minimum / Tested version | Notes |
|---|---|---|
| OS | Ubuntu 24.04 LTS (Noble Numbat) | Kernel must support tc, netem, and iptables |
| Docker Engine | Latest stable | User must have permission to run Docker commands |
| Docker Compose | v2 (docker compose subcommand) |
The docker-compose v1 standalone binary is not supported |
| Python | 3.x | Required to run dashboard/server.py |
| Bash | Any modern version | Required for all scripts under scripts/ |
These versions are defined in build-files/open5gs.env and are used when building or pulling images:
| Component | Version |
|---|---|
| Open5GS | v2.7.6 |
| UERANSIM | v3.2.7 |
| MongoDB | 6.0 |
| Node.js | 20 |
| Ubuntu (base image) | jammy (22.04) |
| PacketRusher | main |
| PacketRusher Go | 1.21.3 |
| PacketRusher Ubuntu | focal (20.04) |
- The dashboard backend serves the frontend and API together. Do not open
dashboard/index.htmlviafile://. tcandiptablescommands are executed inside UPF containers, so no additional host-level kernel modules need to be manually loaded beyond what Docker provides.
In the default Docker Compose setup in this repo, it's not needed to manually put personal machine IP into the configs because the containers use Docker network aliases such as gnb.ueransim.org and amf.open5gs.org.
If UERANSIM is run with custom networking (or without the provided Docker aliases), the place where the machine/reachable IP must be set is:
configs/network-slicing/gnb.yamllinkIpngapIpgtpIp
And if the UE cannot resolve gnb.ueransim.org, update the gNB target in:
configs/network-slicing/ue*.yamlgnbSearchList(replacegnb.ueransim.orgwith the reachable gNB IP/hostname)
If only the dashboard is accessed from another device on LAN, no config file change is needed; just open:
http://<your-machine-ip>:8088
./scripts/start-demo.shThis script bootstraps the full stack — starting services, seeding subscribers, and verifying UE tunnel assignment. For a detailed description of what each stage does and how the dashboard interacts with the result, see Section 9 (How the Demo Works End to End).
python3 dashboard/server.pyExpected output:
- The server prints the URL (default
http://localhost:8088) - If port
8088is busy andDASHBOARD_PORTis not set, it tries nearby ports and prints the fallback port.
Open the URL printed by the backend, typically:
http://localhost:8088
From the UI:
- Click
Shutdown Stack - The stop action runs asynchronously and the UI tracks completion in the background.
Or manually:
docker compose -f compose-files/network-slicing/docker-compose.yaml --env-file build-files/open5gs.env downThe dashboard is a single-page application (SPA) served by the Python backend.
Startup sequence:
- Loads initial topology and slice definitions from
/api/topology - Loads use cases and PLMN profiles from
/api/profiles/list - Loads subscribers, metrics, QoS status, slice config, subscriber profiles, transport state, and test history
- Opens an SSE connection to
/api/stream - Falls back to periodic polling if SSE health degrades
This section explains what happens at each stage of a demo session. The startup commands themselves are in Section 7 (Quick Start).
Running the start script performs the following in sequence:
- Starts the network slicing Docker Compose stack.
- Force-recreates AMF/NSSF/SMF/UPF services so latest config edits are loaded.
- Waits for MongoDB readiness.
- Seeds (and refreshes) 12 subscribers with slice assignments.
- Ensures
access_restriction_data=0for those subscribers. - Restarts or recreates gNB and UE containers.
- Waits for UE tunnel IP assignment (
uesimtun*) and validates expected slice-subnet prefixes. - Verifies per-UE gateway reachability and performs one automatic UE restart if recovery is needed.
Once the backend is running and the dashboard is open:
- Verify the API/JS status chips are healthy.
- Click
Initialize Demo. - Wait for the backend to run
scripts/start-demo.shto completion. - The UI refreshes topology, subscribers, QoS, and transport state.
- The UI automatically launches a baseline all-UE test.
Note:
scripts/start-demo.shstarts and seeds the stack. The baseline automated test is a separate step triggered by the dashboard only afterInitialize Democompletes.
- View live progress in the Tests page and slice-specific pages.
- Apply a use-case preset or manual QoS changes.
- Re-run tests and compare results in Test History and Metrics pages.
- Export/view the generated HTML report for documentation or grading evidence.
This file is the central dashboard-facing slice model. Each slice includes:
- identity (
id,name,category) - S-NSSAI values (
sst,sd) - data network (
dnn) - core mapping (
smf,upf,upf_device) - addressing (
subnet,gateway) - state and QoS (
active,priority,qos.max_rate_mbit,qos.additional_latency_ms) - UE assignment (
ues)
Default slice set in this project:
| Slice ID | Category | SMF | UPF | Subnet | Default UE mapping |
|---|---|---|---|---|---|
slice-a |
eMBB | smf1 |
upf1 |
10.45.0.0/16 |
ue1, ue2, ue3 |
slice-b |
URLLC | smf2 |
upf2 |
10.46.0.0/16 |
ue4, ue5 |
slice-c |
mMTC | smf3 |
upf3 |
10.47.0.0/16 |
ue6, ue7, ue8, ue9 |
slice-d |
Enterprise | smf4 |
upf4 |
10.48.0.0/16 |
ue10, ue11 |
slice-e |
Experimental | smf5 |
upf5 |
10.49.0.0/16 |
ue12 |
Each use case defines two things:
qos_presets: Desired max rate and added latency per slice.thresholds: Validation thresholds used by the test engine (latency, P95, loss, throughput).
This separation is important:
- QoS presets configure behavior.
- Thresholds define pass criteria for validation.
These profiles let MCC/MNC be applied and SD values across multiple config files in one action.
The backend profile apply flow updates:
amf.yamlnssf.yamlsmf1.yamltosmf5.yamlgnb.yamlue1.yamltoue12.yamldashboard/data/slices.jsonSD values
This file stores reusable provisioning templates (key, OPC, AMF, DNN, SST, SD) for the Subscribers page.
This file stores per-slice rule definitions used to generate iptables rules inside each UPF container.
This file stores a compact history of prior runs and is augmented by scanning actual test artifacts in metrics/runs/<run_id>/.
When slices in the dashboard are saved/applied:
- The frontend sends the slice list to
/api/slices/save. - The backend sanitizes fields (e.g.,
sd, numeric values, booleans, gateway fallback). /api/slices/applyrewrites Open5GS/UERANSIM YAML files for active slices.- Config sync normalizes SMF
dnnlist format and removes stalenssf.sliceblocks before restart. - The backend restarts/starts/stops relevant services (
amf,nssf,gnb, slice SMFs/UPFs/UEs).
This section documents the dashboard at the page-group level and focuses on operational purpose and impact on the smart-factory slicing workflow, rather than a field-by-field UI transcription.
The dashboard navbar is organized into four groups that align with the lifecycle of a slicing demonstration:
| Navbar group | Operational function | Typical usage stage |
|---|---|---|
Control |
System state awareness and runtime traffic behavior control | Startup, monitoring, live adjustments |
Validation |
Measurement, verification, and evidence generation | Before/after policy changes, final demonstration |
Configuration |
Persistent slice/subscriber/profile definition management | Initial setup, scenario changes |
Slice Pages |
Slice-scoped operational views | Focused debugging and per-slice comparison |
The dashboard is not a static visual layer. It is the operational front end for the backend orchestrator in dashboard/server.py.
At runtime, the UI:
- Consumes a periodic live snapshot via SSE (
/api/stream) for status, topology, metrics, UE state, and test revision signals - Invokes targeted REST endpoints for configuration changes and control actions
- Updates views after state-changing operations (QoS apply, slice apply, tests, subscriber changes)
This model ensures the UI reflects actual system state rather than only intended settings.
The grouped pages support a standard demonstration workflow:
- Use
Controlpages to confirm the system is online and inspect current slice behavior. - Use
Configurationpages to define slices, subscriber data, and profiles. - Apply transport/QoS changes in
Controland scenario presets inConfiguration. - Use
Validationpages to measure and verify expected behavior. - Use
Slice Pagesfor slice-specific analysis when a single slice needs focused inspection or retesting.
These pages support real-time operation of the slicing environment and provide the shortest path to understanding current network state.
Purpose:
- Provide an operational summary of demo readiness, slice health, and recent control activity.
Impact on the smart-factory use case:
- This page supports rapid go/no-go decisions before a demonstration or experiment run
- It is the fastest place to verify whether the slices are behaving differently enough to represent distinct industrial traffic classes
- It reduces time spent switching pages during live presentations by aggregating readiness, KPI trends, and recent actions
Purpose:
- Present the current slice-aware deployment structure, container roles, service status, and logical data paths.
Impact on the smart-factory use case:
- This page provides architectural evidence that the demo is implemented as multiple coordinated network functions rather than a single traffic-shaping script.
- It helps explain to reviewers or instructors how slice isolation is represented in the deployed topology (SMF/UPF mapping, RAN/core relationships, transport presence).
- It accelerates root-cause analysis when a use-case outcome looks incorrect but the issue is actually a stopped service or broken service dependency.
Purpose:
- Apply and inspect per-slice transport behavior using
tcandiptableson the UPF side.
Impact on the smart-factory use case:
- This page is the operational mechanism for demonstrating differentiated treatment of traffic classes across slices.
- It provides direct evidence that traffic behavior changes are implemented in the data path (through live
tcandiptablesstate), not only in high-level configuration metadata. - It enables controlled experiments where the team can adjust shaping or filtering and immediately validate the effect through the
Validationpages.
These pages produce and inspect the measurable evidence used to show that slice behavior matches the intended use-case design.
Purpose:
- Run automated validation workflows and review historical results with report artifacts.
Impact on the smart-factory use case:
- This page converts the demonstration from a visual claim into a repeatable validation process using latency, loss, throughput, subnet, and session checks.
- It supports scenario-level and targeted validation (
all,slice,ue), which is critical when demonstrating both full-system behavior and focused slice behavior. - It provides report outputs suitable for grading, documentation, and reproducibility.
Purpose:
- Present the latest parsed ping and iPerf measurements in a direct UE-level view.
Impact on the smart-factory use case:
- This page provides the raw KPI view needed to confirm whether automated test outcomes are reasonable.
- It supports comparative interpretation across slices (for example, throughput-oriented vs latency-oriented slices) without requiring report generation for every iteration.
- It is the primary reference for manual performance inspection during QoS tuning.
Purpose:
- Provide service-level log access for runtime diagnosis and fault isolation.
Impact on the smart-factory use case:
- This page is essential when a failed validation result is caused by control-plane or registration issues rather than QoS policy.
- It shortens debugging cycles by keeping operational troubleshooting inside the same dashboard workflow used for configuration and validation.
- It supports demonstration robustness by enabling fast recovery when a service misbehaves during live runs.
These pages define the persistent inputs that shape the behavior of the network slicing environment.
Purpose:
- Manage the canonical slice model (
dashboard/data/slices.json) and apply it to the Open5GS/UERANSIM runtime configuration.
Impact on the smart-factory use case:
- This page controls the mapping from industrial traffic categories to concrete network behavior (slice IDs, SMF/UPF mapping, UE assignment, IP plan, QoS defaults).
- It allows the team to evolve the demonstration design without manually editing multiple YAML files for each change.
- It provides the configuration bridge between scenario definition and executable network topology.
Purpose:
- Provision and inspect Open5GS subscriber records used by the UEs in the slicing scenario.
Impact on the smart-factory use case:
- Subscriber provisioning is a prerequisite for attach and PDU session establishment, so this page directly affects whether any use-case validation can run.
- It enables rapid correction of subscriber/slice mismatches without leaving the dashboard workflow.
- It supports repeatability when resetting or re-seeding the environment between experiments.
Purpose:
- Manage reusable scenario presets for QoS behavior and PLMN/S-NSSAI identity values.
Impact on the smart-factory use case:
- QoS presets allow fast switching between demonstration narratives (for example balanced operation vs mission-critical prioritization) without manual per-slice edits.
- PLMN/S-NSSAI profiles support controlled reconfiguration of identity-related values across the stack and UEs.
- This page improves repeatability by making common scenario transitions explicit and reusable.
These pages are generated dynamically from the configured slice set and provide a slice-scoped operational perspective.
Purpose:
- Provide a focused view of one slice, combining slice-scoped operational state, KPIs, and validation actions.
Impact on the smart-factory use case:
- These pages support targeted demonstrations where one industrial traffic class must be analyzed in isolation (for example URLLC latency behavior or eMBB throughput behavior).
- They reduce cognitive load during debugging by filtering the system view to the slice under investigation.
- They are particularly useful for iterative tuning, where QoS changes and slice-specific tests are repeated until the observed behavior matches the intended use-case profile.
This section explains how tests work behind the UI.
Tests can be started from:
Testspage (Run Test)- Dynamic slice page (
Run Slice Test) - Dashboard
Initialize Demoflow (baseline all-UE test after bootstrap)
The backend test engine (dashboard/backend/test_engine.py) performs these steps:
- Create a unique
run_idand register a running test in memory. - Resolve test scope (
all,slice,ue) to a UE list. - Build environment variables for the scripts.
- Run
scripts/collect-metrics.sh(ping collector). - Run
scripts/run-iperf.sh(iPerf collector). - Parse latest CSV outputs from the run directory.
- Evaluate validation checks against the selected use-case thresholds.
- Generate an HTML report file.
- Update in-memory run state and persisted test history.
Key environment variables passed from the test engine to the collectors:
| Variable | Purpose |
|---|---|
OUTPUT_DIR |
Per-run artifact folder (metrics/runs/<run_id>/) |
UE_LIST |
Scope-limited list of UEs to test |
UE_SLICE_MAP |
UE-to-slice key mapping used by collectors |
SLICE_UPF_MAP |
Slice key to UPF service mapping |
SLICE_GW_MAP |
Slice key to gateway IP mapping |
SLICE_MAX_RATE_MAP |
Slice key to QoS cap mapping (used for iPerf rate limits/QoS checks) |
PING_TARGET |
Ping target (auto by default for per-slice gateway) or explicit host/IP |
PING_TARGET_FALLBACK |
Fallback ping target when auto cannot resolve a per-slice gateway |
PING_COUNT |
Ping packets per UE |
PING_EXEC_TIMEOUT |
Max per-UE ping command runtime |
DURATION |
iPerf duration in seconds |
IPERF_CONNECT_TIMEOUT_MS |
iPerf client connect timeout (ms) |
IPERF_EXTRA_TIMEOUT |
Extra iPerf runtime buffer (seconds) |
RUN_UPLINK_IPERF |
Enable uplink iPerf (default 0, downlink-only validation) |
Runtime budget behavior:
- The test engine computes ping/iPerf command timeouts dynamically from UE count, ping count, and iPerf duration.
What it does:
- Runs
pinginside each selected UE container - Parses packet counts and RTT stats
- Computes a P95 RTT estimate from raw ping replies
- Writes
slice-metrics-<timestamp>.csv
Default values and overrides:
- Target defaults to
auto(per-slice gateway viaSLICE_GW_MAP), then falls back toPING_TARGET_FALLBACK(default8.8.8.8) - Ping count defaults to
10unless overridden via CLI arg orPING_COUNT - Per-UE execution timeout defaults to
PING_COUNT + 15seconds unlessPING_EXEC_TIMEOUTis set
Collector robustness behavior:
- Pings are sent through the detected UE tunnel interface (
uesimtun*) with bounded command timeout. - If a UE returns zero replies, the collector restarts that UE once and retries.
- If ping cannot run, the script still writes a failed CSV row (100% loss) instead of dropping data.
What it does:
- Groups UEs by slice using
UE_SLICE_MAP - Resolves each slice to its UPF and gateway IP
- Starts an iPerf3 server inside the slice's UPF container
- Runs required downlink iPerf for each UE and optional uplink when
RUN_UPLINK_IPERF=1 - Writes per-UE JSON files and an aggregate CSV file
- Tracks success/fail/skip counts and returns a meaningful exit code
Important implementation detail:
- This script does not use one external iPerf server container.
- It starts iPerf servers inside the corresponding UPF containers to keep tests slice-aware.
Collector robustness behavior:
- Attempts to install
iperf3in containers if missing (using common package managers, with bounded timeout attempts) - Starts/verifies iPerf servers in UPFs and cleans up iPerf processes on exit
- Retries failed downlink runs once (and can restart UE once for recovery)
- Records
0.000Mbps rows for unavailable UEs/services instead of silently dropping samples - Uplink is marked skipped by default unless explicitly enabled
Per-slice checks include:
UE AttachPDU SessionSubnet MatchLatency AvgLatency P95Packet LossThroughputQoS Enforcement
How QoS Enforcement is evaluated:
- The engine compares downlink throughput samples to the configured/preset QoS cap.
- It expects observed throughput to stay within approximately 120% of the configured max rate.
all: evaluates all slices with their associated UEsslice: evaluates one slice and its mapped UEsue: evaluates the slice containing the selected UE, filtered to that UE
Threshold source:
- The selected use case from
dashboard/data/use-cases.json - If no use case is selected, report labeling may show no use case and some checks may effectively become permissive/fallback depending on data availability
- If
PING_TARGET=auto, reports label the target asslice-gateway
Backend and UI statuses commonly displayed:
PASSPASS (WARN)RUNNING
Current report behavior:
- The generated HTML report always summarizes validation and tool status.
- A run becomes
PASSonly when validation checks pass and both collectors succeed. - Otherwise it is surfaced as
PASS (WARN)with an issue breakdown.
Generated report includes:
- Run metadata (run id, scope, target, use case)
- Overall and validation status
- Tool status (ping and iPerf)
- Issue breakdown list
- Test conditions (ping target/count, iPerf duration)
- Per-slice evaluation table with checks, metrics, thresholds, and QoS cap
The backend exposes a REST-style API plus SSE for the dashboard.
| Method | Endpoint | Purpose |
|---|---|---|
| GET | /api/health |
Basic backend health check |
| GET | /api/status |
Stack status summary and service details |
| GET | /api/topology |
Topology nodes and slice definitions |
| GET | /api/ues |
UE states with slice mapping and metrics |
| GET | /api/metrics/latest |
Latest parsed ping and iPerf metrics (empty when no UE runtime is online) |
| GET | /api/stream |
Live SSE snapshot stream |
| GET | /api/logs |
Service logs tail (service, tail) |
| Method | Endpoint | Purpose |
|---|---|---|
| POST | /api/stack/start |
Start stack (docker compose up -d) |
| POST | /api/stack/stop |
Initiate async stack stop (docker compose down) |
| GET | /api/stack/stop/status |
Read async stack-stop task state/result |
| POST | /api/service/restart |
Restart one service |
| POST | /api/service/action |
Start/stop one service |
| POST | /api/ues/restart |
Restart one UE or all UEs |
| GET | /api/slices |
Load slice definitions |
| POST | /api/slices/save |
Save sanitized slice definitions |
| POST | /api/slices/apply |
Apply slice config to YAML + restart/start/stop services |
| GET | /api/profiles/list |
Load PLMN profiles and use-case presets |
| POST | /api/profiles/save |
Save a PLMN profile |
| POST | /api/profiles/apply |
Apply PLMN/SD profile across config files |
| Method | Endpoint | Purpose |
|---|---|---|
| GET | /api/qos/status |
Read tc qdisc state per slice |
| POST | /api/qos/apply |
Apply QoS (tc) to a slice UPF |
| GET | /api/transport/status |
Read tc and iptables state per slice |
| GET | /api/transport/rules |
Load persisted transport rules |
| POST | /api/transport/iptables |
Add/delete/flush per-slice iptables rules |
| GET | /api/subscribers |
List subscribers from MongoDB (db_not_running hint when DB is offline) |
| POST | /api/subscribers/add |
Add subscriber via open5gs-dbctl |
| POST | /api/subscribers/remove |
Remove subscriber via IMSI |
| GET | /api/subscriber-profiles |
Load subscriber profile templates |
| POST | /api/subscriber-profiles/save |
Save subscriber profile templates |
| Method | Endpoint | Purpose |
|---|---|---|
| POST | /api/tests/run |
Start a background test run |
| GET | /api/tests/<run_id> |
Poll test run status and logs |
| GET | /api/tests/history |
List known historical test runs |
| GET | /api/tests/export |
Export run metadata/details |
| GET | /api/tests/report |
View generated HTML report |
| GET | /api/start-demo/status |
Track Initialize Demo backend command state |
| POST | /api/start-demo |
Run scripts/start-demo.sh asynchronously |
Generated artifacts are written under metrics/ and are treated as runtime outputs.
Common outputs:
metrics/slice-metrics-<timestamp>.csvmetrics/iperf-<timestamp>.csvmetrics/iperf-<timestamp>-<ue>-<direction>.jsonmetrics/runs/<run_id>/slice-metrics-*.csvmetrics/runs/<run_id>/iperf-*.csvmetrics/runs/<run_id>/report-<run_id>.html
Repository hygiene note:
metrics/is ignored in.gitignoreso generated artifacts do not get committed.
Dashboard opens but buttons do nothing
Likely cause: opened dashboard/index.html directly via file://.
Fix: run python3 dashboard/server.py and open http://localhost:8088 (or the port printed by the server).
Port 8088 is busy
If DASHBOARD_PORT is not set, the backend tries nearby ports and prints the selected port. To set an explicit port:
DASHBOARD_PORT=8089 python3 dashboard/server.pyCheck:
- Docker daemon is running
- images can be pulled (first run may take time)
- MongoDB container starts successfully
- user has permission to run Docker commands
Helpful pages:
Topology(service status)Logs(container logs)Testsactivity log (if failure occurs after bootstrap)
Check:
- Subscribers were seeded correctly
- gNB and UEs were restarted/recreated
- slice IDs (
SST/SD) and DNN values are consistent amf,nssf,smf*,upf*, andgnbare running
Useful logs:
amfsmf1tosmf5gnb- affected
ueX
Possible causes:
- Ping target not reachable from UE containers
- No UE PDU session
- Container networking not ready yet
Fix options:
- retry after UE attach is stable
- set a reachable
PING_TARGET - run a smaller scoped test first
Possible causes:
iperf3missing in UE or UPF container- target UPF not running
- slice mappings missing or inconsistent
Notes:
- The script attempts to install
iperf3automatically in several common container package-manager environments. - If all runs are skipped, the collector returns a non-success code and the UI/report will surface warnings.
Check:
- correct slice selected
- UPF container is running
upf_devicein slice config matches the actual tunnel devicetc/iptablescommand output in Transport page status panes
This usually means one or more of the following happened:
- validation threshold was not satisfied (latency, loss, throughput, subnet, etc.)
- ping collector failed or was incomplete
- iPerf collector failed or was skipped
Use:
- Tests page run log
- Test History
View HTMLreport - Metrics page raw values
- Slice page checklist and charts
Expected behavior:
- Stack shutdown is asynchronous; API can briefly disconnect while containers stop.
Check:
- Run
GET /api/stack/stop/statusand inspectrunning,last.code, and error text. - Use
Topologyrefresh after shutdown completes to confirm all services are down.
Meaning:
- MongoDB (
dbservice) is not currently running, so subscriber reads are intentionally returned as unavailable.
Fix:
- Start the stack or explicitly start the
dbservice, then reload subscribers.
Expected behavior:
- The backend returns an empty metrics payload when no UE containers are running to avoid showing stale telemetry.
This project was developed in an academic and applied systems context, and it benefited from multiple forms of support.
- We thank Prof. Dr. Armin Lehmann for guidance, feedback, and teaching support throughout the project.
- We thank the Frankfurt University of Applied Sciences for the learning environment, curriculum, and technical foundation that made this work possible.
This project acknowledges the responsible use of AI-assisted tools during research and implementation, including support in:
- technical research and concept clarification,
- implementation planning and iteration,
- frontend and backend development assistance,
- integration troubleshooting (including Docker image and container workflow integration),
- documentation drafting and refinement.
All AI-assisted outputs were reviewed, adapted, and validated by the project team before inclusion.
- 5G SA: 5G Standalone architecture using a 5G Core, not LTE EPC.
- RAN: Radio Access Network. In this project, simulated by UERANSIM gNB and UEs.
- gNB: Next-generation base station in 5G.
- UE: User Equipment (device). Here, simulated devices in containers (
ue1toue12). - Core (5GC): The 5G Core network functions (AMF, SMF, UPF, etc.).
- AMF: Access and Mobility Management Function.
- SMF: Session Management Function.
- UPF: User Plane Function.
- NRF: Network Repository Function (service registry/discovery).
- NSSF: Network Slice Selection Function.
- AUSF: Authentication Server Function.
- UDM: Unified Data Management.
- UDR: Unified Data Repository.
- PCF: Policy Control Function.
- BSF: Binding Support Function.
- PDU Session: Data session that provides a UE with IP connectivity through the core.
- DNN: Data Network Name (similar to APN concept in practice).
- PLMN: Public Land Mobile Network identifier (MCC + MNC).
- MCC: Mobile Country Code.
- MNC: Mobile Network Code.
- IMSI: International Mobile Subscriber Identity.
- S-NSSAI: Single Network Slice Selection Assistance Information (slice identifier).
- SST: Slice/Service Type component of S-NSSAI.
- SD: Slice Differentiator component of S-NSSAI.
- eMBB: Enhanced Mobile Broadband (throughput-oriented service class).
- URLLC: Ultra-Reliable Low-Latency Communications (latency-sensitive service class).
- mMTC: Massive Machine-Type Communications (high-density, typically low-bandwidth devices).
- QoS: Quality of Service, used to shape/limit traffic behavior.
- Priority: In this project, the
tc/HTB class priority used for slice traffic treatment. - Latency: Time delay experienced by packets, commonly measured as RTT in milliseconds.
- P95 latency: 95th percentile latency (95% of samples are at or below this value).
- Packet loss: Percentage of packets that do not reach the destination.
- Throughput: Data transfer rate, usually shown in Mbps.
- Jitter: Variation in packet delay over time.
- Docker Compose: Tool for defining and running multi-container applications.
tc: Linux traffic control utility used for shaping and queueing.- HTB: Hierarchical Token Bucket, a
tcqdisc/class discipline for rate control. netem: Linux traffic emulator used to add delay/loss/jitter-like effects (delay is used here).iptables: Linux packet filtering and NAT rule tool.- Chain: A named list of packet filtering rules in
iptables. - SSE: Server-Sent Events, a one-way streaming mechanism from server to browser used for live snapshots.
- SPA: Single-Page Application. The dashboard frontend operates as an SPA.
- API: Application Programming Interface. The dashboard backend exposes
/api/*endpoints. - KPI: Key Performance Indicator (for example latency and throughput summaries).
- CSV: Comma-Separated Values file used for collected metrics data.
- JSON: JavaScript Object Notation file format used for UI config/state.
- Open5GS: Open-source implementation of 5G Core network functions.
- UERANSIM: Open-source 5G RAN/UE simulator.
open5gs-dbctl: Helper script used to add/remove subscribers in the Open5GS MongoDB.
| Member | Name | GitHub ID |
|---|---|---|
| 1 | Aditya Praveen Shidhaye |
@axiomsbane |
| 2 | Priyanshu Bandyopadhyay |
@prnshubn |
| 3 | Pradeep Buddhiram Patwa |
@pradeeppatwa |
| 4 | Akshay Ganesh Gudekar |
@Akshay-Gudekar |
| 5 | Vikas Rathore |
@vikasrathore7229 |
| 6 | Taibaz Pathan |
@Taibaz-Pathan |


