NAS: refactor Identity Request handler and enforce spec-compliant security checks (#217)
Align UE Identity Request handling with TS 24.501 by checking the NAS
security header and rejecting unprotected non-SUCI requests.
Also, refactor Identity Response identity selection based on the
requested identity types, add to a helper and handle unavailable
identities in the UE context.
Closes: #82
Reviewed-by: Robert Schmidt <robert.schmidt@openairinterface.org>
Reviewed-By: Rakesh Mundlamuri <rakesh.mundlamuri@openairinterface.org
Duranta is a Linux Foundation networking project and does not have
permission to display the trademarked OAI logo
(https://openairinterface.org/logo/), which belongs to the
OpenAirInterface Software Alliance (legal entity "OPENAIRINTERFACE").
Remove logo to avoid any legal problems.
Remove some superfluous text with HTML code in some documentation.
Signed-off-by: Robert Schmidt <robert.schmidt@openairinterface.org>
Complete NR L2/L3 Paging path from F1AP to NAS (gNB and UE) (#151)
This MR wires a 5GâNR paging flow across the stack, from F1AP Paging on
the DU down to PCCH scheduling in MAC/RLC, RRC/ASN encode/decode, and
UEâside NAS Service Request triggering, including the NR UE changes in
L1/L2.
It centralises paging PF/PO computation and PCCH scheduling in MAC,
using shared SSB/Type0âPDCCH and common PDSCH helpers that are also
reused by SIB1. On the UE, it enables decoding of NR PCCH messages,
matching ngâ5GâSâTMSI/fullIâRNTI, and conditionally initiating a
networkâtriggered Service Request when 5GMM state allows it. The change
set includes focused refactors and ASN.1 tests to validate the new
paging encode/decode path.
Changes:
- MAC gNB common helpers: Move SSB/Type0âPDCCH utilities from the
BCH scheduler into shared MAC primitives and introduce a reusableÂ
Type0âoccasion helper and common PDSCH RB/MCS/TBS sizing
- MAC paging PF/PO responsibility: Add a dedicated PCCH scheduler module
that implements TS 38.304 §7 PF/PO computation (defaultPagingCycle,
nAndPagingFrameOffset, Ns, SFNâbased PF formula and PO slot mapping)
and owns the âis this (frame,slot) a paging occasion for UE_ID?â
decision.
- F1AP -> MAC -> RLC PCCH path (gNB/DU): Have the DU decode F1AP Paging
with CN UE identity, build an NR RRC Paging message (PCCH) in MAC, and
hand it to RLC as a dedicated PCCH SDU together with UE_ID (5GâSâTMSI
mod 1024), using perâmodule PCCH storage. RAN UE paging identity
is explicitly rejected.
- Direct CU to DU paging path: Implement direct F1 Paging handling
in the NR RRC DL direct interface for RLC PCCH storage for laterÂ
scheduling.
- PCCH scheduling and NFAPIÂ integration (gNBÂ MAC): IntegrateÂ
schedule_nr_pcch() into the DL scheduler so that when a stored PCCH
SDU exists and the current (frame,slot) is a paging occasion, MACÂ
resolves the paging search space and CORESET, selects a beam (from SSB),
allocates CCEs and PDSCH resources, builds NFAPI DL_TTI PDUsÂ
(PDCCH + PDSCH with PâRNTI, DCI 1_0), and populates the matching
TX_DATA PDU, then clears the cached PCCH.
- DCI handling for PâRNTI paging: Adjust DCI payload preparation
to treat PâRNTI specially, returning after setting DMRS and antennaÂ
ports and skipping HARQ and UE scheduling state that do not exist for
paging, so paging DCIs no longer touch UE HARQ data structures.
- PHY UE RX Chain: DCI handling for PâRNTI on UE, monitor DCI on Paging
Occasions, process DCI 1_0 with CRC scrambled by PâRNTI on the pagingÂ
search space, trigger PDSCH decoding for PCCH based on that DCI, deliver
decoded PCCH to upper layers from the PHY/MAC side
- RRC/ASN paging encode API: Replace the legacy bufferâbased do_NR_PagingÂ
with a nr_paging_params_tâbased API returning a byte_array_t,
supporting both ngâ5GâSâTMSI and fullIâRNTI identities, and optional IEs
(e.g. accessType nonâ3GPP and pagingCause v17), and encoding viaÂ
uper_encode_to_new_buffer, with ownership and failure semantics clearlyÂ
defined for callers.
- UEâside PCCH reception and matching: Add UE MAC to RRC logic
to deliver PCCH SDUs to RRC, decode NR PCCH via a new nr_pcch_decode()Â
helper into an array of nr_paging_params_t, iterate PagingRecordList onÂ
the UE, compare MâTMSI/fullIâRNTI against local identity, and log whetherÂ
a paging match was found.
- NAS integration for networkâtriggered Service Request: On a UE paging
match, send a NAS_PAGING_IND from RRC to NAS and, when the UE has a
GUTI, is 5GMMâREGISTERED and in 5GMMâIDLE, generate and send a Service
Request uplink NAS message
- Tests and validation helpers: Extend nr_asn1 paging tests
to encode Paging via do_NR_Paging, decode it via nr_pcch_decode,
and verify roundâtrips for multiple ngâ5GâSâTMSI values, accessType,
and fullIâRNTI bit patterns, using a shared encode/decode helper thatÂ
exercises the same decoder path used by the UE.
Notes:
Paging handling currently supports CN UE paging
identity (5GâSâTMSI) only. RAN UE paging identity is logged and ignored.
A paging match triggers a Service Request only when the UE has a GUTI,
is 5GMMâREGISTERED, and in 5GMMâIDLE. T3346 and suspendâindication
handling are documented as future work and not implemented here.
Testing:
Tested with Open5gs. How to trigger Paging in Open5GS lab setup:
- Use gNB telnet to request NGAP UE Context Release: `rrc ctx_rel_req
<RRC_UE_ID>`
- Wait until AMF reports CM-IDLE (for example gNB-UEs is now 0).
- Generate downlink data from the Linux host to the UE IP: `ping
<UE_IP>`
- Host-originated downlink data will trigger paging.
Closes#74
Reviewed-by: Robert Schmidt <robert.schmidt@openairinterface.org>
Reviewed-by: Francesco Mani <email@francescomani.it>
- make internal links relative where applicable
- delete link to the wiki, as the documentation is in the main repo, not
the wiki
- remove some "example in oai code" as the examples either don't exist,
or are not in that place, and we can reasonably expect people to grep
Signed-off-by: Robert Schmidt <robert.schmidt@openairinterface.org>
Support for aperiodic SRS at gNB
Add support for aperiodic SRS, which currently, if activated, is
hardcoded to be periodically scheduled every 160 TTIs. The configuration
file has been changed, and instead of
do_SRS = 0/1
is now
do_SRS = "none"/"periodic"/"aperiodic"
Reviewed-By: Robert Schmidt <robert.schmidt@openairinterface.org>
Reviewed-By: Maxime Elkael <m.elkael@northeastern.edu>
doc: update 7.2 tutorial hardware and os configuration and add a doc to list supported hardware and OS
1. The hardware details in the tutorial were very old; now we are using
some new systems
2. There is no need now to mention the old kernel version and firmware
version
3. I removed the configuration with tuned-adm, as it is confusing
sometimes. So it is better to use just GRUB. I have an OAI tuned
profile ready, but I will do it on another MR. I will check if it
works well on kernel 7.X before pushing
4. Add a document to list the tested/supported hardware on which we have
tested OAI. In another MR I will use that document as reference for
other tutorials as well.
Reviewed-by: Robert Schmidt <robert.schmidt@openairinterface.org>
[FHI72] [M-plane] Implement dynamic compression
- CUS: dynamic compression type implemented -> tested end-to-end with
Benetel RU.
- CUSM: use compression parameters explicitly via gNB config file (if
set) for RU configuration via M-plane -> DL C/U-plane packets are
good. However, not tested with Benetel RU since not supported.
Reviewed-By: Robert Schmidt <robert.schmidt@openairinterface.org>
* use uint8_t instead of int16_t for `iq_width` (the value cannot be
negative)
* move <compression-type> outside the if condition since it's a mandatory
node
* use <compression-method> node
Signed-off-by: Teodora VladiÄ <teodora.vladic@openairinterface.org>
Add Fedora 44/Ubuntu 26 to list of supported distributions
See commits for more details. Includes a minor cleanup. What I tested
for U22/U24/U26 and F44 is
./build_oai --ninja -c -I -w USRP --gNB --nrUE
Reviewed-By: Luis Pereira <lpereira@allbesmart.pt>
Use the current OAI CI default UHD version. Update the documentation to
show how to install a recent version.
Signed-off-by: Robert Schmidt <robert.schmidt@openairinterface.org>
The existing patch (generated through sed) works also in UHD versions
beyond 4.8, so allow to use that.
Further, since sed is confusing, store the patch directly. Update the
dockerfiles so that docker copies the right file for UHD 4.8.
Signed-off-by: Robert Schmidt <robert.schmidt@openairinterface.org>
Refactor DLSCH/ULSCH scheduler: extract proportional fair policy behind function pointer interface
Motivation
The current `pf_dl()` is a ~600-line monolithic function that mixes
infrastructure concerns (UE iteration, HARQ management, CCE allocation,
MAC PDU generation) with the scheduling policy (PF priority, RB
allocation, MCS selection). This makes it hard to modify the scheduling
strategy, test alternatives, or offload scheduling to a GPU (cuMAC).
This MR refactors the DL and UL schedulers into a clean separation
between **infrastructure** and **policy**, using function pointers for
beam allocation and scheduling decisions. The data structures
(`nr_dl_candidate_t`, `nr_dl_sched_params_t`) are also designed to map
directly to cuMAC's
`cumacCellGrpUeStatus`/`cumacSchdSol`/`CumacCellGrpPrms`, to make future
integration smooth.
Changes
Goodput tracking fix
`dl_thr_ue` now tracks actual goodput in bps (EWMA of SDU byte deltas
per frame) instead of accumulating raw byte counts per slot, which are
not as straightforward to interpret (due to variations in TDD patterns
mostly). The new calculation matches closely with the throughput
measured with e.g. iperf.
Helper extraction from `pf_dl()` and `post_process_dlsch()`
- `find_first_available_rbs()` â first-fit contiguous RB allocation
- `setup_dl_harq_process()` â HARQ process management
- `generate_dl_mac_pdu()` â MAC CE + RLC data + padding
- `fill_dl_tx_request()` â FAPI TX_req filling
New scheduling interface
- **`nr_dl_candidate_t`** â per-UE flat struct with all immutable inputs
(buffer status, BLER, MCS limits, beam, BWP) and outputs (scheduled,
rbStart, rbSize, MCS). Kept relatively minimal for now, but it should
be easy to add more input metrics in the future.
- **`nr_dl_sched_params_t`** â per-beam cell-level context (VRB map,
available RBs, slot bitmap)
Function pointers (DL)
| Pointer | Default implementation | Role |
|---------|----------------------|------|
| `dl_ri_pmi_select` | `nr_dl_ri_pmi_select_default` | Rank/PMI selection |
| `dl_beam_select` | `nr_dl_beam_select_default` | Beam direction assignment |
| `dl_tda_select` | `nr_dl_tda_select_default` | Time-domain allocation |
| `dl_mcs_select` | `nr_dl_mcs_select_default` | MCS from BLER/SINR |
| `dl_rb_alloc` | `nr_dl_proportional_fair` | PRB allocation (PF policy) |
Function pointers (UL)
| Pointer | Default implementation | Role |
|---------|----------------------|------|
| `ul_ri_tpmi_select` | `nr_ul_ri_tpmi_select_default` | Rank/TPMI from SRS feedback |
| `ul_beam_select` | `nr_ul_beam_select_default` | Beam direction assignment |
| `ul_tda_select` | `nr_ul_tda_select_default` | Time-domain allocation |
| `ul_mcs_select` | `nr_ul_mcs_select_default` | MCS from BLER/SINR |
| `ul_rb_alloc` | `nr_ul_proportional_fair` | PRB allocation (retx first, then PF-sorted new-tx) |
All default implementations are in `gNB_scheduler_dlsch.c` (DL) and
`gNB_scheduler_ulsch.c` (UL).
MCS selection flow
The old `get_mcs_from_bler()` entangled two concerns: updating the BLER
estimate from HARQ feedback and deciding the MCS. These are now split:
- **BLER tracking is infrastructure's job**: `collect_dl_candidates()`
calls `update_dl_bler_stats()` which updates the BLER estimate from
HARQ round statistics.
- **MCS selection is the policy's job**: the proportional fair policy
calls `select_mcs_from_bler()` internally to adapt MCS based on the
BLER value. A different policy could use an entirely different MCS
strategy (e.g. cuMAC has its own `mcsSelectionLUT` + OLLA, one could
decide to opportunistically lower the MCS while increasing the PRB
allocation for reliability in some cases, etc).
For retransmissions, MCS/number of PRBs are passed as hints so the
policy can use them as-is if desired, but we don't enforce it (adaptive
HARQ possible too: the standard requires us to maintain TBS but in
theory it could be achieved via changing the MCS and number of RBs if we
wanted to).
Refactored flow
`nr_dl_schedule()` (formerly `pf_dl()`):
```
collect_dl_candidates() â build candidate array from UE list
schedule_dl_ues() â beam alloc + per-beam policy calls
for each scheduled candidate â CCE/PUCCH/TBS validation + post_process
```
Beam allocation and scheduling policy are two separate function
pointers, allowing each to be developed and tested independently (with
the goal in the future to add a parameter in the config file for each,
and telnet commands to hotswap).
`schedule_dl_ues()` wraps both into a single function: it first calls
beam allocation to assign candidates to beams, then iterates over beams
and calls the scheduling policy for each one. cuMAC performs joint beam
+ PRB allocation on the GPU, so when integrating later it will replace
`schedule_dl_ues()`.
Future work
- Channel matrix H from SRS on candidates for beam-aware scheduling
- Per-RB channel magnitude derived from SRS on candidates
- Config file parameters and telnet commands for hotswapping policies
- cuMAC integration via `schedule_dl_ues()` replacement
Reviewed-By: Robert Schmidt <robert.schmidt@openairinterface.org>
Multi-QoS Handling and PDU Session Modify
This MR implements comprehensive QoS flows handling and PDU Session
Modify procedures in the RRC layer, enabling full support for multiple
QoS flows per DRB and dynamic QoS management per 3GPP specs. Key
changes:
1. Multi-QoS Flows Support
- Multiple QoS flows per DRB: Support for multiple QoS flows mapped to a
single DRB
- Intelligent QoS-to-DRB mapping: Implements resource-type-aware
multiplexing based on 3GPP TS 23.501 Table 5.7.4-1
- DC-GBR flows (5QI 82-90): Dedicated DRB, max 1 flow per DRB
- GBR flows (5QI 1-4, 65-67, 71-76): Max 2 flows per DRB
- Non-GBR flows (5QI 5-11, 69-70, 79-80): Max 5 flows per DRB
- Aggregate cap: Maximum 5 flows per DRB
- 5QI validation: Early validation of standardized 5QI values (1-9,
65-90) during QoS flow setup/modify
2. PDU Session Modify Procedures
- Complete E1AP/RRC integration: Full Bearer Context Modification
support with DRB lifecycle management
- DRB To Setup/Modify/Remove lists: Complete support for all DRB
operations in Bearer Context Modification
- QoS flow operations: Support for QoS flow add, modify, and release
operations
- QoS flow mapping: Proper handling of QoS flow modifications in
DRB To Modify List
- Automatic DRB management: DRB setup, modification, and removal
based on QoS flow changes. Reuse existing DRBs if the incoming QoS
flow is compatible.
- Delayed transactions: PDU Session Modify added to delayed
transactions list for proper sequencing
3. GTP-U Tunnel Refactoring
- Architecture alignment:
- N3 tunnels: 1 per PDU session with QFI marking, container for
multiple bearers, supporting multiple QoS flows
- F1-U tunnels: 1 per DRB without QFI marking
- SDAP ownership of QoS: move QoS management to be fully owned by
SDAP
4. QoS Enhancements
- Dynamic5QI support: Full support for Dynamic5QI with packet delay
budget and packet error rate
- GBR QoS flows: Support for Guaranteed Bit Rate QoS flows with
GFBR/MFBR parameters
- DRB QoS aggregation: DRB-level QoS computed from all mapped QoS
flows using ARP priority (not 5QI priority)
- QoS priority level refactoring: Proper type definitions per 3GPP
TS 23.501 (QoS Priority Level: 1-127, ARP Priority Level: 1-15)
Technical Changes
RRC Layer
- Refactored `nr_rrc_add_bearers()` to support intelligent QoS-to-DRB
mapping
- Added `nr_rrc_update_qos()` for QoS flow add/modify with automatic DRB
assignment
- Implemented `nr_rrc_update_pdusession()` for QoS flow release and DRB
cleanup
- Consolidated F1 UE Context Modification Request handling
- Simplified PDU status tracking by removing intermediate states
- Added QoS flow and DRB removal utilities
- Updated RRC bearers tests with comprehensive multi-QoS testing
- Adapted `nr-cuup-load-test.c` to new GTP design
NGAP Layer
- Extended PDU Session Resource Modify Request Transfer with QoS
add/modify/release lists
- Added proper type definitions (`pdusession_mod_req_transfer_t`,
`qos_flow_to_release_t`)
- Fixed NGAP PDU Session Modify transfer encoding
GTP-U Layer
- Refactored tunnel creation API: scalar fields instead of arrays
- Split tunnel creation into `n3_gtpu_create()` and
`f1_drb_gtpu_create()`
- Added bearer-to-QFI mapping structure (`gtpv1u_rb_t`)
- Implemented QFI de-duplication and one-to-one QFI-to-bearer mapping
- Reduced inter-dependencies between LTE and NR
SDAP Layer
- Fixed default DRB tracking: Only one default DRB per SDAP entity per
PDU session (TS 37.324)
- Set default DRB to first DRB added when creating bearers
F1AP Layer
- Added GBR QoS Flow Information IE handling in CU
- Implemented DRB QoS aggregation from multiple QoS flows
- Extended F1AP test cases to support multiple QoS flows
Code Quality Improvements
- Improved error handling throughout the stack
- Enhanced logging and debugging capabilities
- Added comprehensive unit tests for multi-QoS scenarios
- Improved type safety and validation
Testing
The code was validated with Open5gs v2.7.6, OAI CN5G and COTS UE.
How to reproduce with Open5gs:
1. Start Open5gs
2. From the Open5gs web UI: add multiple QFIs to the same DNN.
3. Restart Open5gs
4. Run gNB and UE
The user will see the following:
1. QoS flows arrive via NGAP PDU Session Setup/Modify requests, each
with a QFI and 5QI.
2. The gNB assigns each flow to a DRB, creating a new DRB or reusing an
existing one based on 5QI compatibility (compatible flows, i.e. same
5QI characteristics, share a DRB)
3. At the SDAP layer, packets are tagged with QFI headers; at the GTP-U
layer, uplink packets include QFI in the PDU Session Container for
core network mapping.
Documentation
- Added comprehensive QoS flows handling documentation with 3GPP
standards references
- Updated PDU Session Modify sequence diagrams
Note
* This implementation aligns with:
- 3GPP TS 23.501 (QoS framework)
- 3GPP TS 38.413 (NGAP)
- 3GPP TS 37.324 (SDAP)
- 3GPP TS 38.463 (F1AP)
- 3GPP TS 29.281 (GTP-U)
- 3GPP TS 38.331 (RRC)
* Multi-QoS and PDU Session Modify are both added to this MR since QoS
flows update is triggered by PDU Session Modify in some scenarios
(e.g. with Open5gs, used for validation).
* Core functional changes introduced by commits with prefix "QoS
Handling" or "PDU Session Modify"
* This MR replaces the old !2703.
* This MR adopts relevant CU changes from !2836, namely:
* Adds new shared QoS types
* Add standardized 5QI table and helper
* Dynamic5QI support + validation
* Computation of DRB QoS (aggregate QoS) and priority/GBR
* F1AP DRB-level QoS
* Closes#541 (5QI validation)
* Closes#1075 (Optional NAS-PDU in PDU Session Setup Request)
Signed-off-by: Jaroslava Fiedlerova <jaroslava.fiedlerova@openairinterface.org>
Reviewed-by: Rakesh Mundlamuri <rakesh.mundlamuri@openairinterface.org>