A single well-formed session is enough to see a procedure. A user-plane function, a serving gateway or a probe under load needs many subscribers, with GTP-U that still belongs to the tunnels the control plane just set up. You do not need a radio network or SIM cards for that, but you do need correlated identities, a rate you control, and a rule that the traffic never leaves an authorized lab.
This article compares a full lab core, a hand-built GTP-U loop, and a workflow with Mobile Core Generator. An earlier article covers how to produce GTPv2-C and PFCP captures without a live core; here the question is scale, and how to present that traffic to a lab UPF or SGW. Keep every live test on an isolated segment. Never point these tools at a production or third-party system.
What "many UEs" actually means
A useful load is more than a large pcap:
- Each subscriber is a session, not a copied packet. IMSIs, UE addresses, TEIDs and SEIDs have to be unique where the core would make them unique. Pasting the same Create Session a thousand times is not a thousand UEs.
- User plane follows control plane. GTP-U G-PDUs (UDP 2152) must use the F-TEIDs negotiated in GTPv2-C or PFCP. Otherwise the DUT forwards, drops or mis-counts for the wrong reason.
- You know which interface you are talking to. S11 or S5 towards an SGW/PGW, N4 towards a UPF, or GTP-U towards an already programmed user-plane port are different tests.
- Rate and duration are bounded. A loop of "as fast as possible" on the wrong adapter is how lab traffic escapes. Start on loopback or a fake node, then a dedicated lab NIC, with a finite session count and a stated packets/s.
Option 1: An open-source core and a traffic source
Projects such as Open5GS give you real SMF, UPF, SGW and PGW behaviour. Combined with a RAN simulator or a packet generator, they can attach many subscribers and pass user traffic.
Good for: end-to-end behaviour, interoperability, and learning how a core is deployed.
Limits: it is a deployment project. You size max.ue, fill a subscriber database, and you get the rate the stack happens to sustain. Generating a controlled mix of GTP-U applications, or a clean "N sessions then stop" evidence pack, still needs extra tooling. Mobile Core's own notes on Open5GS (raise global.max.ue, disable SMF CTF when there is no OCS, install IMSIs first) are worth reading if that is your DUT.
Option 2: Scapy (or a raw GTP-U loop)
You can loop Scapy (or another packet library) over a list of TEIDs and inner addresses, write a large pcap, and replay it.
Good for: a tiny, fully inspected set of G-PDUs when you already know the TEIDs.
Limits: you maintain the control-plane side yourself. Allocating TEIDs and SEIDs consistently, pairing Create Session or Session Establishment with later G-PDUs, and scaling to thousands of UEs becomes a project. A replay tool will send whatever you wrote, including mistakes.
Option 3: Mobile Core Generator at scale
Mobile Core Generator can build the population and then either write files or talk to a lab node. According to the product page and User Manual / CLI Reference (1.19.2):
- Generate > Subscribers (CLI:
gtpcore -scenario generate-bulk -job-json …) produces a control-plane PCAP, a normalized sessions JSON, and a linked GTP-U PCAP. You set subscriber count, protocol ownership (GTPv2, PFCP, or mixed), identity ranges, APN, and optional multisession (several sessions per IMSI, unique UE IP / TEID / SEID, shared IMSI). - GTP-U profiles wrap inner DNS, HTTP/HTTPS, FTP, SMTP, SIP/RTP, RTSP, ICMP, generic UDP or TCP in each session's tunnel. A correlated percentage can be less than 100% when you also want unrelated or error traffic (
unknown_fteid,unknown_msip,conflict). - Tools > Analyze / Scale reconstructs a session model from a known-good control-plane capture and can generate a larger population that follows that pattern — new identities and tunnels, not a raw byte-for-byte copy. The User Manual's example is: learn 20 Create Session exchanges, then generate 20,000 sessions.
- Send to network (
gtpcore replay) and, in Full Edition, probe (gtpcore probe) and the live driversgtpv2-live(MME or SGW-C towards an SGW/PGW) andpfcp-live(SMF towards a UPF) send at a ramped rate with a session count, concurrency, and a KPI / summary report.
Edition limits are sharp, and they apply to this workflow:
| Limit | Community Edition | Full Edition |
|---|---|---|
| Subscribers / sessions per job | Up to 100 | Unlimited (technical cap 100,000,000) |
| Send / probe rate | At most 1000 packets/s, including -topspeed |
Full speed |
Probe, gtpv2-live, pfcp-live, conformance suite |
Not available (exit code 3) | Included |
A compact bulk run, then a paced replay, looks like this:
gtpcore -scenario generate-bulk -job-json bulk_job.json -progress
gtpcore interfaces
gtpcore replay -pcap gtpu.pcap -iface NAME -rate 1000 -dst-ip 192.0.2.20 -dst-mac 00:11:22:33:44:55 -src-ip auto -src-mac auto -allow-remote
community/examples/bulk_job_example.json is a worked schema-1 job (25 subscribers, optional multisession and a GTP-U mix). The GUI button Export job... writes the current Subscribers profile as that JSON plus *_run.bat / *_run.sh for a lab server or CI.
Replay and probe rewrite only the outer IPv4/MAC you set (-dst-ip / -dst-mac, -src-ip auto for the selected interface) and recompute IPv4 and UDP checksums. Addresses inside GTP/PFCP IEs (F-TEID, F-SEID, PAA) are not changed — set those in the generator so they match the lab. Only Ethernet captures (link type 1) can be sent. Loopback is the default; any real interface needs -allow-remote.
When the DUT must establish the sessions itself, use the live drivers (Full Edition) after a local rehearsal:
gtpcore fake-pgw -listen 127.0.0.1:2123
gtpcore gtpv2-live -interface s11 -peer 127.0.0.1:2123 -pgw 127.0.0.1 -sessions 50 -rate 20
gtpcore fake-upf -listen 127.0.0.1:8805
gtpcore pfcp-live -upf 127.0.0.1:8805 -sessions 50 -rate 20
fake-pgw and fake-upf ship with every edition. On a real lab SGW or UPF, add -allow-remote, -node-ip, a modest -rate-start / -rate / -ramp, and -summary-json or -report-html. Optional -user-plane http (Full) runs a TCP/HTTP flow inside each established GTP-U tunnel; that is a functional path test, not a line-rate benchmark.
A practical load workflow
- Name the DUT and the interface. An SGW-C on S11, a UPF on N4, or a user-plane port that already has tunnels are different commands.
- Start inside the Community cap. Ten or twenty subscribers, one APN, a simple GTP-U profile (for example DNS), then inspect the sessions JSON and the two pcaps.
- Rehearse locally. Replay to loopback, or run
gtpv2-live/pfcp-liveagainstfake-pgw/fake-upf. Confirm TEIDs, SEIDs and inner addresses before you touch a real node. - Move to the lab NIC only when authorized. Tick Allow real network in the GUI, or pass
-allow-remote. Set target IP/MAC, a finite-rateor Packets/s, and a finite session or loop count. Do not start with-topspeedor Loop 0. - Scale in steps. Raise subscriber count (Full Edition above 100), then rate. Keep the summary or probe report next to the pcap. If you started from a real capture, scale only after the reconstructed model looks right.
Which tool when?
| Need | Good fit |
|---|---|
| Real end-to-end core behaviour | Open-source core + RAN / traffic source |
| A handful of G-PDUs with known TEIDs | Scapy, then a bounded replay |
| Many correlated subscribers + GTP-U files | Mobile Core generate-bulk / Subscribers |
| Grow a pattern learned from a lab capture | Analyze / Scale, after a small known-good file |
| Paced send of a ready pcap to a lab NIC | gtpcore replay (Community: ≤ 1000 pkt/s) |
| The node must create the sessions itself | Full: gtpv2-live or pfcp-live; start with fake-pgw / fake-upf |
Editions
Mobile Core Generator has a Community Edition, free for non-commercial evaluation, learning and compact lab scenarios (up to 100 subscribers/sessions, send-to-network capped at 1000 packets/s). The Full Edition is a one-time $89 license: it removes those limits and adds probe, the live drivers and the conformance suite. The current release runs on Windows 10/11 64-bit; a Linux build is available on request. Npcap is required for Send to network.
Explore Mobile Core Generator →
Limitations
- Community Edition cannot exceed 100 sessions in a generate or scale job, and cannot exceed 1000 packets/s on the wire, even with
-topspeed. gtpv2-live,pfcp-liveand probe are Full Edition (Community exits with code 3).- Outer IP/MAC rewrite does not update F-TEID, F-SEID or PAA inside signalling. Build those addresses for the lab.
- These commands are not a line-rate or DUT-certified throughput benchmark. Reports give session, Cause and latency figures for the run you launched.
- Never point replay, probe or a live driver at a production or third-party system.
FAQ
Can Community Edition generate 10,000 UEs?
No. The job fails before any file is written if the request is above 100 subscribers/sessions. Use a compact scenario in Community, or the Full Edition for larger populations.
Does generate-bulk already talk to the UPF?
No. It writes files. You replay or probe them, or you use pfcp-live / gtpv2-live when the node must answer signalling.
Why did the UPF or SGW ignore my GTP-U?
The usual cause is a TEID or inner address that does not match the session the node actually created. Check the sessions JSON against the DUT, and remember that replay does not rewrite F-TEIDs.
How do I try a live run without a DUT?
gtpcore fake-pgw -listen 127.0.0.1:2123 and gtpcore fake-upf -listen 127.0.0.1:8805 are built-in test doubles (all editions). Point gtpv2-live or pfcp-live at them on loopback first (those two drivers themselves need Full Edition).