When the UE sends a Tracking Area Update (TAU) Request with active_flag=0,
the MME previously sent TAU Accept without verifying the EPS Bearer Context
Status (EBCS). This caused stale bearer sessions to remain in the MME even
if the UE had already released them.
According to 3GPP TS 24.301 §5.5.3.2, the MME should release any bearer
not reported in the UE’s EBCS when active_flag=0. This patch introduces
mme_send_delete_session_or_tau_accept(), which compares the UE’s EBCS bitmask
with the MME session list and deletes any missing default bearer session
before sending TAU Accept.
If no mismatch is found, TAU Accept is sent immediately. The Delete Session
response triggers TAU Accept when deletions are required. This ensures that
the TAU Accept message reflects the UE’s current bearer context accurately.
Also includes:
- Added OGS_GTP_DELETE_SEND_TAU_ACCEPT handling in mme-s11-handler.c
- Simplified EBCS structure (uint16_t value) for bitmask comparison
- Updated TAU-related tests with realistic EBI bitmasks (0x20, 0x60)
This change aligns TAU handling with 3GPP 24.301 and prevents bearer
mismatch issues between UE and EPC during TAU.
When the NGSetupRequest contains an invalid GlobalRANNodeID or
BroadcastPLMNItem with a malformed PLMNIdentity, the AMF previously
performed memcpy() without checking the buffer size. This could lead
to invalid memory access and crash.
Fix by validating PLMNIdentity size against sizeof(ogs_plmn_id_t) and
sending NGSetupFailure with CauseProtocol_semantic_error if invalid.
Also add regression tests:
- Build malformed NGSetupRequest with incorrect PLMNIdentity size
- Verify AMF does not crash and returns NGSetupFailure
This resolves the crash reported in issue #4087.
This commit adds Xn and N2 handover procedures to the Home-Routed Roaming code.
Direct forwarding is now fully operational.
Indirect forwarding for N2 handovers is not yet supported.
To preserve the GTP-U header and extension header (even without QER)
along the source gNB -> V-UPF -> target gNB path, future work will create
PDRs without Outer Header Removal IE and FARs without Outer Header Creation IE
and implement the necessary UPF logic.
In the previous implementation, the AMF would send a Partial-handover error
indication whenever it encountered a session not found in the subscriber DB,
even if valid sessions remained. This resulted in unexpected error responses
during NG handover.
To resolve this, we record the initial SMF transaction count before iterating
through the UE session list. Sessions without a valid SMF context now produce
a warning and are skipped, while continuing to send Handover Notify messages
for provisioned sessions. After processing, we compare the SMF transaction
count to the initial value. If no valid sessions were handled, we send a
Partial-handover error indication.
With this change, unprovisioned sessions no longer trigger a premature error
indication, allowing valid PDU sessions to complete NG handover successfully.
Fix missing N2 signaling when tunnel information is unchanged,
causing AMF crash on repeated PathSwitchRequest
When a second PathSwitchRequest arrives without any tunnel changes,
the handler previously returned HTTP 204 No Content and omitted N2 information.
This led to a fatal assertion in the AMF SM context, since it expected
to receive updated N2 data even when the tunnel remained the same.
This patch modifies ngap_handle_path_switch_request_transfer to build
and send the N2 SM buffer in the “else” branch.
It calls ngap_build_path_switch_request_ack_transfer to construct
the Path Switch Request Acknowledge N2 message and then delivers it
with smf_sbi_send_sm_context_updated_data_n2smbuf.
A new test case is also added to verify that N2 signaling is correctly
transmitted when tunnel parameters have not changed.
* [AMF] Fix UE context transfer when only NRF is client
If UE context transfer is initiated and the new AMF does not get the
old AMF from NRF or no UE context is retrieved from the old AMF,
we do not want to reject UE registration. Send identity request instead.
Test "transfer-error-case" is added into the commit.
* [tests] Unite tests for UE context transfer
All tests for UE context transfer with different configs are placed
into test folder transfer.
* [tests] Make two binaries for UE context transfer tests
For each test config a different test binary is created.
This commit adds support for processing network-initiated PDU Session
Modification in a home-routed roaming context, following section 4.3.3.3
of the specification.
- Add support for PDU Session Release in 3GPP TS 23.502 section 4.3.4.3
Note: PCF-initiated release flow for Home-Routed Roaming is not implemented;
- Fix N4 release step ordering in 3GPP TS 23.502 section 4.3.4.2 UE or network requested PDU Session Release for Non-Roaming and Roaming with Local Breakout
Renamed backup/restore security context functions to save/restore
memento and updated flag to "can_restore_context". Updated AMF and MME
state machines to restore context on failure, preventing malicious
deletion triggered by spoofed NAS messages.
- Backup sensitive security context fields (e.g. xres, kasme, rand, autn,
keys, counters) when transitioning from REGISTERED state.
- Set the can_restore_security_context flag in common_register_state()
based on whether the transition originates from a REGISTERED or
de-registered state.
- In emm_state_authentication(), restore the security context and revert
to the REGISTERED state on authentication failure only if restoration
is allowed; otherwise, transition to an exception state.
- Remove the redundant unconditional state transition in the cleanup block
to prevent overriding a valid restoration.
Previously, the EPC used the UE-provided KSI directly in the Authentication
Request (except for the special case where the UE sent
OGS_NAS_KSI_NO_KEY_IS_AVAILABLE, which was reset to 0).
This commit changes the EPC to follow the 5G Core approach
for issuing KSI in Attach-Request.
Now, when a Attach Request is received and a new Authentication Vector is
generated, the EPC performs the following steps:
- Extract the KSI value from the UE's request.
- Increment the extracted KSI by 1.
- Use the incremented KSI in the Authentication Request sent to the UE.
This detailed process ensures that the EPC issues the KSI consistently
with 5G Core standards, improving key management and interoperability.
Previously, sample.yaml was used for both 5GC and EPC attach tests.
Because SMF had SBI configured, it sent a register PUT to NRF even in
EPC-only tests (where nrf/scp was not run), leading to a missing HTTP
response and connection timer expiry.
Now, attach.yaml is used for EPC, preventing the unwanted NRF registration.
Previously, policies were configured via YAML files without MongoDB.
This update enhances the YAML approach by adding the 'supi_range' key to
filter policies based on UE SUPI ranges. When both 'supi_range' and
'plmn_id' are provided, both conditions must be met.
Note that PLMN-ID filtering will be deprecated in a future release.
In case that mapped HPLMN SST was not set by the UE in the request to
Establish PDU Session, AMF/SMF would assume it is set to 0 (since the
recent change to allow SST value 0).
3GPP TS 23.003: 28.4.2 Format of the S-NSSAI
The SST field may have standardized and non-standardized values. Values
0 to 127 belong to the standardized SST range and they are defined in
3GPP TS 23.501 [119]. Values 128 to 255 belong to the Operator-specific
range.
Added support for binding to local IP addresses in ogs_sctp_client and
ogs_sctp_server, and correct SGsAP configuration
Implemented the ability to bind to one or multiple local IP addresses using
`sctp_bindx()` in both the `ogs_sctp_client()` and `ogs_sctp_server()` APIs.
Users can now specify local addresses in the configuration files under the new
`local_addresses` field, reducing unnecessary complexity and signaling caused
by binding to `ANY_ADDR`.
This update addresses issue https://osmocom.org/issues/6509 by ensuring
correct operation in multi-interface and complex networking setups.
Additionally, corrected the `sgsap` configuration by changing it
from `server` to `client`, and added support for specifying `local_addresses`
for local binding as follows:
```
sgsap:
client:
- address: msc.open5gs.org # SCTP server address configured on the MSC/VL
local_address: 127.0.0.2 # SCTP local IP addresses to be bound in the M
```
- Added support for the N9 For Roaming interface type:
- Core interface act as V-UPF.
- Access interface act as H-UPF.
- Modified V-UPF behavior:
- V-UPF updates only the TEID and IP Address in the GTP-U header.
- The content following the Extension Header is passed through directly
between the UE and H-UPF.
This implementation ensures seamless data flow between the UE, V-UPF, and H-UPF
while maintaining integrity for Home Routed Roaming scenarios.
Resolved an issue where Handover was failing when attempting to handover
from GNB-ID/eNB-ID 1 to GNB-ID/eNB-ID 0.
The problem occurred because the hash table managing GNB_ID values would
remove any entry with the default GNB-ID/eNB-ID of 0 before re-adding entries.
Consequently, any GNB/eNB configured with a GNB-ID/eNB-ID of 0
would be inadvertently deleted whenever another GNB was added.
This fix modifies the handling of the hash table to prevent the default
GNB-ID/eNB-ID (0) from being removed unintentionally, allowing handovers
between GNB-ID/eNB-ID 0 and other GNBs/eNBs to proceed without error.
While experimenting with CSFB, it was observed that when the UE returns
to E-UTRAN after a CS call, the UE performs a Tracking Area Update
with a combined Tracking Area/Location Area update and IMSI attach.
Currently, Open5GS's MME simply responds with a TAU Accept message
but does not inform the MSC/VLR.
As a result, no further MT (Mobile Terminated) CS/SMS services are possible
in cases where the MSC/VLR only attempts paging on GERAN.
However, some MSC/VLR implementations with fast fallback may still attempt
paging on E-UTRAN, allowing MT CS/SMS services to function intermittently.
According to 3GPP TS 29.118 Section 5.2.2 Procedures in the MME,
specifically Section 5.2.2.2.1, if the timer Ts6-1 is not running,
the MME shall start the location update for non-EPS services procedure
upon receiving a combined Tracking Area Update Request indicating
combined TA/LA updating with IMSI attach. However, SGs timers are not
implemented in Open5GS, which is a separate issue.
To comply with the specification and ensure that the MSC/VLR is informed
when the UE becomes reachable via SGs, the following changes have been
implemented:
1. Delay UEContextReleaseCommand:
When the active_flag is set to 0, the UEContextReleaseCommand is now delayed
until the MME receives the TAU Complete message from the UE. This ensures
that the UE has acknowledged the new P-TMSI before the network releases
the context, maintaining proper synchronization between the UE and the network.
2. Include Mobile Identity Only When P-TMSI Changes:
The Mobile Identity is now included in the Attach/TAU Accept messages
only when the MSC/VLR updates the P-TMSI. This ensures that the UE receives
the Mobile Identity information solely when there is an actual change
in the P-TMSI, preventing unnecessary or incorrect handling
of TAU Complete messages.
3. Send SGsAP-REALLOCATION-COMPLETE Conditionally:
The SGsAP-REALLOCATION-COMPLETE message is now sent to the MSC/VLR
only upon receiving a Attach/TAU Complete message from the UE.
This confirmation indicates that the UE has successfully updated its P-TMSI,
ensuring that the MSC/VLR is accurately informed of the change.
4. Handle P-TMSI Confirmation:
When the MSC/VLR updates the P-TMSI, Open5GS stores the new P-TMSI
in the next field of the mme_ue structure. Upon receiving the TAU Complete
message from the UE, indicating acknowledgment of the new P-TMSI,
Open5GS confirms the update by transferring the P-TMSI from the next field
to the current field. This ensures that the MME maintains an accurate and
up-to-date record of the P-TMSI as confirmed by the UE.
Implement support for Node-Identifier IE in GTPv2 S2b Create-Session-Request
to SMF for Diameter S6b integration
This patch adds support for processing the Node-Identifier IE within GTPv2
Create-Session-Request messages sent via the S2b interface to the SMF.
When the ePDG includes the Node-Identifier IE containing both host and realm
of the AAA-Server, the SMF now uses this information to populate
the Destination-Realm and Destination-Host AVPs in the Diameter S6b AAR message.
This enables seamless integration and allows the SMF to route requests directly
to the appropriate AAA-Server, enhancing interoperability in setups
where the host and realm data are required by the Diameter network.
1. Set packet filter identifier values to 0 when the UE requests to:
- Create new QoS rule
- Modify existing QoS rule and replace all packet filters
- Modify existing QoS rule and add packet filters - As specified in TS24.501, section 9.11.4.13, Table 9.11.4.13.1.
2. Revise QoS rule modification logic:
- Instead of replacing packet filters based on their identifiers (EPC approach), update the implementation to delete all existing packet filters within the QoS rule and add new ones.
- This ensures that when modifying an existing QoS rule to replace all packet filters, the packet filters are correctly reset and updated per 5G Core requirements.
- **Correct Packet Filter Identifier Handling:**
Remove the addition of +1 when searching for the packet filter context using `smf_pf_find_by_identifier()` in the 5G Core SMF. According to 3GPP TS24.008 Section 10.5.6.12 and TS24.501 Section 9.11.4.13, the Packet Filter Identifier should range from 1 to 15 (or 0 to 15) depending on the operation and should be used directly as received from the UE.
- **Adjust Maximum Number of Packet Filter Identifiers:**
Change the maximum number of Packet Filter Identifiers from **16** to **15** in the SMF to comply with the 3GPP specifications. The standards specify that the number of packet filters shall be greater than 0 and less than or equal to 15 for certain operations.
**Background:**
In the current 5GC implementation, the SMF incorrectly adds +1 to the identifier received from the UE and allows up to 16 identifiers, leading to mismatches and potential communication issues. These discrepancies cause the SMF to fail in correctly locating the packet filter context, resulting in improper QoS rule enforcement.
**Changes Made:**
- **For Packet Filter Identifier Handling:**
- Updated the SMF code to use the identifier received from the UE directly without modification:
```c
// Corrected code for 5GC:
pf = smf_pf_find_by_identifier(
qos_flow, qos_rule[i].pf[j].identifier);
```
- **For Maximum Number of Packet Filter Identifiers:**
- Adjusted the code to enforce a maximum of 15 packet filters as per the specifications.
**Impact:**
- **Compliance:**
- Ensures that the 5GC implementation of Open5GS adheres to the 3GPP TS24.008 and TS24.501 specifications regarding Packet Filter Identifier handling and limits.
- **Functionality:**
- Corrects the mapping and management of packet filters between the UE and SMF in 5GC, preventing potential communication issues and misconfigurations.
- **EPC Implementation:**
- The EPC implementation remains unaffected by these changes. EPC correctly handles the Packet Filter Identifier by decrementing it by 1 before sending it to the UE and adding +1 when searching for the packet filter context.
**Conclusion:**
By making these adjustments, we ensure proper synchronization between the UE and SMF in the 5G Core and maintain compliance with the 3GPP specifications. This fix resolves the mismatches caused by incorrect identifier handling and enforces the correct limit on the number of packet filters, enhancing the reliability and standards compliance of the 5GC implementation without impacting the existing correct behavior in EPC.
Decrement the Packet Filter Identifier by 1 before sending it to the UE
during GSM message construction. This correction ensures proper synchronization
between the UE and SMF, allowing `smf_pf_find_by_identifier()` to accurately
locate the corresponding `pf` context without adjusting the identifier
during the search.
This fix aligns the 5GC implementation with the EPC behavior,
where the identifier was correctly decremented before transmission to the UE,
preventing mismatches and synchronization issues.
SMF selection according to 4.3.2.2.3 of TS23.502.
V-SMF makes discovery in the V-NRF according to V-NSSF.
H-SMF makes discovery in the H-NRF according to H-NSSF.
(The AMF goes through the V-NSSF and forwards the message seeking the NRF to the H-NSSF.)
NF should accept 204 No Content for Update Subscription requests.
According to 3GPP 29.510 NRF specification document in figure 5.2.2.5.6.1
NRF may return 204 or 200 for success update operations.
2a. On success, if the NRF accepts the extension of the lifetime
of the subscription, and it accepts the requested value for the "validityTime"
attribute, a response with status code "204 No Content" shall be returned.
2b. On success, if the NRF accepts the extension of the lifetime
of the subscription, but it assigns a validity time different than
the value suggested by the NF Service Consumer, a "200 OK" response code shall
be returned. The response shall contain the new resource representation
of the "subscription" resource, which includes the new validity time,
as determined by the NRF, after which the subscription becomes invalid.
I changed it so that all NFs can receive both 200 and 204 STATUS.
I also changed the default behavior of NRFs to respond with 204,
which is NO CONTEXT.
When exiting a diameter interface, the session state data could be NULL.
So we added code to check the session state data
to prevent SIGSEGV occurring.
I created ogs_sbi_xact_find_by_id() with a hash
to replace ogs_sbi_xact_cycle().
Modified to find the xact via xact->id
when making an HTTP request with the SBI client function
and waiting for the HTTP response.
Pool library has the following issues with XXX_cycle,
including mme_enb_cycle()/amf_ue_cycle()
```
INIT POOL(SIZE:5)
Alloc Node1
Alloc Node2
Alloc Node3
Alloc Node4
Alloc Node5
Free Node4
Free Node3
PoolCycle(Node4) is NULL (Freed...OK!)
PoolCycle(Node3) is NULL (Freed...OK!)
Alloc Node6
Alloc Node7
PoolCycle(Node4) is Not NULL (Freed...but NOK!)
PoolCycle(Node3) is Not NULL (Freed...but NOK!)
PoolCycle(Node6) is Not NULL (Allocated...OK!)
PoolCycle(Node7) is Not NULL (Allocated...OK!)
```
If we use ogs_poll_alloc() to create and allocate a node,
the correct behavior of calling ogs_pool_free() on this node
and then later calling ogs_pool_cycle() on this node must always return NULL.
However, the behavior of calling ogs_pool_cycle() on this node
in the future may return a “valid” pointer.
To solve the problem, we added hash id to the pool memory and
ogs_pool_find_by_id() function is added.
Consider the following situation.
```
1. SMF->SGW-C->MME: First Update Bearer Request
2. MME->UE: First Modify EPS bearer context request
3. SMF->SGW-C->MME: Second Update Bearer Request
4. MME->UE: Second Modify EPS bearer context request
5. UE->MME: First Modify EPS bearer context accept
6. MME->SGW-C->SMF: First Update Bearer Response
7. UE->MME: Second Modify EPS bearer context accept
8. MME->SGW-C->SMF: Second Update Bearer Response
```
Until now, only one GTP transaction was managed for one bearer.
Therefore, if the UE does not send an EPS Modify bearer accept to the MME,
and the SMF/SGW-C sends an Update Bearer Request to the MME,
The NEW update bearer request overwrites the OLD that was previously managed.
So we modified it to manage them simultaneously.
However, we don't know if this is the right way to implement it.
So if the SMF/SGW-C sends 5 MMEs of Update Bearer Request and
the UE sends only 3 MMEs of Modify EPS bearer context accept,
we have no way to associate it.
Therefore, it's implemented so that we just process them sequentially and
2 of them are just timeout.