Bring up a complete 5G Standalone network — the Duranta gNB (nr-softmodem), the native OAI
CN5G core, and OAI's soft UE (nr-uesoftmodem) — entirely in software on one node over the OAI
RF simulator (RFsim). No SDR, no RF, no radio reservation. Register the UE, open a PDU session, reach
the internet, and measure throughput.
This is the fastest way to see the full OAI/Duranta 5G SA stack work end-to-end. The gNB runs as an
RFsim server and OAI's nr-uesoftmodem as an RFsim client, exchanging baseband samples over a
TCP socket instead of a USRP — so the whole stack (gNB + OAI CN5G core + UE) runs on a single COSMOS
server node. It is license-free and needs no radio hardware, so it runs on any COSMOS node.
Because there is no air interface, throughput is high (DL ≈ 164 / UL ≈ 84 Mbit/s). For the over-the-air
version with a real USRP and a commercial modem, see the companion
Duranta OTA tutorial.
After completing this tutorial you will be able to:
nr-uesoftmodem in software over RFsim on one node.LD_LIBRARY_PATH requirement.192.168.100.0/22 pool, and reach the internet.| Difficulty | Beginner–Intermediate |
| Estimated time | 20–30 min |
| Domain / sandbox | any COSMOS server node (no radio needed) |
| Topic group | Cellular (4G/5G/O-RAN) |
| Last verified | 2026-07-15 |
Background knowledge
ssh on Linux.Account & access
Devices / nodes
| Resource | Role | Qty | Notes |
|---|---|---|---|
| any COSMOS server node | gNB + OAI CN5G + nr-uesoftmodem (all-in-one) |
1 | no SDR — pure software |
Disk images
| Image | Load onto | Provides |
|---|---|---|
duranta.ndz |
your node | Duranta nr-softmodem + nr-uesoftmodem (/opt/duranta), OAI CN5G (/opt/oai-cn5g), configs, UHD 4.9 |
(duranta.ndz is a symlink to the latest dated build.)
Software components
| Component | Version | Source |
|---|---|---|
| Duranta gNB / nrUE (OAI fork) | preinstalled | /opt/duranta/cmake_targets/ran_build/build/{nr-softmodem,nr-uesoftmodem} |
| OAI CN5G (5GC) | develop (Docker) |
/opt/oai-cn5g/oai-cn5g-fed/docker-compose |
Spectrum / RF / special
00101, DNN oai, IMSI 001010123456780; UE pool 192.168.100.0/22Everything on one node; gNB ↔ UE over an RFsim TCP socket, UE ↔ core over the Docker bridge:
any COSMOS node
┌────────────────────────────────────────────────┐
│ OAI CN5G (Docker): AMF/SMF/UPF + oai-ext-dn │
│ UE pool 192.168.100.0/22, NAT → internet │
│ ▲ N2/N3 │
│ nr-softmodem ──RFsim TCP:4043──► nr-uesoftmodem │
│ (RFsim server, band n78) (RFsim client / UE) │
└────────────────────────────────────────────────┘
-r 0):ssh <username>@console.<domain>.cosmos-lab.org
omf load -i duranta.ndz -t <node> -r 0 -o 1200
omf tell -a on -t <node>
ssh root@<node>
cd /opt/oai-cn5g/oai-cn5g-fed/docker-compose
docker compose -f docker-compose-basic-nrf.yaml up -d
docker exec -i mysql mysql -uroot -plinux oai_db < /root/duranta/provision.sql # subscriber 001010123456780
docker compose -f docker-compose-basic-nrf.yaml ps # all NFs "healthy"
The core hands out UE IPs from 192.168.100.0/22; the oai-ext-dn container NATs UE traffic to the
internet.
OAI dlopens its lib*.so with an rpath baked to the original build dir, so every launch must set
LD_LIBRARY_PATH to the (relocated) build directory:
B=/opt/duranta/cmake_targets/ran_build/build
AMFIP=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' oai-amf)
sed -i "s#amf_ip_address.*ipv4.*#amf_ip_address = ({ ipv4 = \"$AMFIP\"; });#" /root/duranta/gnb-rfsim.conf 2>/dev/null || true
cd "$B"
setsid bash -c "export LD_LIBRARY_PATH=$B; exec ./nr-softmodem -O /root/duranta/gnb-rfsim.conf --rfsim" >/tmp/oai-gnb.log 2>&1 &
sleep 10
grep -aE 'is in service|NGAP_REGISTER_GNB_CNF' /tmp/oai-gnb.log | tail -2
[NR_RRC] cell PLMN 001.01 Cell ID ... is in service
B=/opt/duranta/cmake_targets/ran_build/build
cd "$B"
setsid bash -c "export LD_LIBRARY_PATH=$B; exec ./nr-uesoftmodem -O /root/duranta/ue-rfsim.conf --rfsim --rfsimulator.serveraddr 127.0.0.1" >/tmp/oai-ue.log 2>&1 &
sleep 12
grep -aiE 'PDU Session|oaitun|192.168.100' /tmp/oai-ue.log | tail -3
ip -br addr show oaitun_ue1
[NAS] PDU Session Establishment Accept, UE IPv4 192.168.100.2
oaitun_ue1 UNKNOWN 192.168.100.2/22
ping -I oaitun_ue1 -c 4 192.168.70.131 # OAI ext-DN
ping -I oaitun_ue1 -c 4 8.8.8.8 # the internet
4 packets transmitted, 4 received, 0% packet loss
cell PLMN 001.01 … is in service.PDU Session Establishment Accept; oaitun_ue1 has an IP in 192.168.100.0/22.ping 192.168.70.131 and ping 8.8.8.8 = 0% loss.docker exec -d oai-ext-dn iperf3 -s
iperf3 -c 192.168.70.131 -B 192.168.100.2 -R -t 12 # DL
iperf3 -c 192.168.70.131 -B 192.168.100.2 -t 12 # UL
Measured (RFsim, no air link): DL ≈ 164 / UL ≈ 84 Mbit/s, RTT ≈ 20 ms.
pkill -x nr-uesoftmodem; pkill -x nr-softmodem
docker compose -f /opt/oai-cn5g/oai-cn5g-fed/docker-compose/docker-compose-basic-nrf.yaml down
omf tell -a offh -t <node>
| Symptom | Likely cause | Fix |
|---|---|---|
dlopen(libparams_libconfig.so) … No such file → exits |
relocated build, stale rpath | export LD_LIBRARY_PATH=/opt/duranta/cmake_targets/ran_build/build before launch |
gNB: NGSetup fails / AMF not associated |
AMF container IP is dynamic | re-read docker inspect oai-amf and set amf_ip_address in the gNB .conf (Step 2) |
nrUE registers but no oaitun_ue1 / UL works but DL replies don't |
stale UPF F-TEID | docker compose restart oai-upf oai-smf |
UE ping 8.8.8.8 fails, ext-DN pings |
ext-dn NAT stale | confirm docker exec oai-ext-dn ping 8.8.8.8; the ext-dn UE_NETWORK must be 192.168.100.0/22 |
sb1/grid).omf-duranta; OAI libconfig + build — skill oai-gnb.basic-nrf config. Upstream: github.com/duranta-project/openairinterface5g.Author(s): COSMOS team · Last verified: 2026-07-15 · Tested image/release: duranta.ndz (Duranta/OAI nr-softmodem + nr-uesoftmodem + OAI CN5G), PLMN 00101, pool 192.168.100.0/22 · Tags: duranta, oai, openairinterface, oai-cn5g, 5g, sa, rfsim, soft, nruesoftmodem