PFCP PDR precedence is a uint32_t. In Open5GS the default
OGS_PFCP_DEFAULT_PDR_PRECEDENCE is 65535. The previous assert enforced
(0,255), which is incorrect and causes valid configurations to abort.
Remove the assert and pass the precedence through as-is.
Fixes assertion failures seen in TC_pdu_sess_modification in
osmo-ttcn3-hacks.
The older version of the code was wrong (or at least not exactly
correct) in many (corner) cases.
* Split the parsing of Packet Filter List into its own helper function
to simplify the code
* Improve error logging to provide more info on which QoS rule failed.
* Add some extra logic checking match between 'Length of QoS rule' and
existance of m+1 and m+2 bytes.
* Correct logic checking expected/unexpected presence of m+1 and m+2
octets based on Rule Operation Code according to specs.
Home-Routed roaming: during Xn/N2 handover the source gNB may forward
remaining DL data to the core using UL PDU Session Information (PSC).
On the V-UPF the PSC was lost on the indirect path because OHR+OHC
removed the incoming GTP-U header (and its extensions) and we did not
recreate PSC when no QER/QFI was provisioned by the V-SMF.
This change makes the V-UPF rebuild a DL PSC for the target gNB even
when QER is absent, limited to the Access->Access indirect path
(source gNB -> V-UPF -> target gNB).
Why this is needed in HR:
- In HR deployments the V-SMF typically does not provision QER/QFI for
the temporary indirect path. Without recreating PSC from recvhdr, the
extension header disappears after OHR+OHC and the target gNB cannot
see the QFI during handover buffering/forwarding.
Previously, Outer Header Removal was set according to PDU session type.
However, outer header IP version is independent of inner packet IP version or
PDU session type. It typically depends on UPF and gNB configuration. Set it to
GTP-U/UDP/IP to handle both IPv4 and IPv6 cases, according to TS 29.244, Table
8.2.64-1, Note 4: "The CP function shall use this value to instruct UP function
to remove the GTP-U/UDP/IP header regardless it is IPv4 or IPv6."
No changes at UPF are necessary because it already ignores Outer Header Removal
Description type and Kernel correctly decapsulates the outer IP header at
socket level.
This change moves the call to fd_msg_new_answer_from_req so that the answer
header is created immediately after the incoming request is received,
ensuring that the ans pointer is initialized before any message‐specific
allocations or parsing take place.
This refactoring guarantees that the answer message is set up once and early,
which improves readability and ensures that proper cleanup can occur
without repeated steps.
Refer to:
- Issues #4012
- Pull Request #4034
- Commit f23d7a5
Add robust error checks and logging to MME, SMF, PCRF, and HSS
Diameter callback functions. Prevent assertion failures by
handling unexpected or late messages gracefully.
Instead of aborting the AMF when an SM context release is requested during the
security-mode state, log an error and allow the system to continue operating.
This avoids a fatal assertion failure and improves overall availability. The
error message "Invalid state transition: cannot release SM Context during
security-mode state" provides a clear debug trace for issue #4012.
This change revises the existing ogs_addaddrinfo() function to handle
partial failures without aborting the process, ensure proper cleanup
of any nodes allocated before an error, and emit more informative logs
(including getaddrinfo() errors and situations where no usable addresses
are returned).
By introducing “tail” and “first_new” pointers, new entries can be appended
to an existing list and safely detached if memory allocation fails mid‐stream.
On top of that, a new helper API, ogs_sockaddr_from_ip_or_fqdn(), was added.
It automatically detects whether its input is a numeric IPv4/IPv6 literal
or a hostname (using AI_NUMERICHOST when appropriate), then delegates
resolution to ogs_addaddrinfo().
Errors are logged at the error level but do not trigger a fatal exit,
and any partial lists are cleaned up before returning.
Finally, the SMF configuration parser in context.c was updated to use
this new API for “p-cscf” entries, allowing both raw IP addresses
and DNS names in smf.yaml.
Corresponding adjustments were made in context.h (to change the p_cscf
and p_cscf6 arrays to mutable char pointers) and in the cleanup routine
smf_context_final() to free any dynamically allocated strings.
Together, these improvements eliminate duplicate parsing logic,
streamline configuration handling, and increase the overall resilience
of address resolution across Open5GS.
This change revises the existing ogs_addaddrinfo() function to handle
partial failures without aborting the process, ensure proper cleanup
of any nodes allocated before an error, and emit more informative logs
(including getaddrinfo() errors and situations where no usable addresses
are returned).
By introducing “tail” and “first_new” pointers, new entries can be appended
to an existing list and safely detached if memory allocation fails mid‐stream.
On top of that, a new helper API, ogs_sockaddr_from_ip_or_fqdn(), was added.
It automatically detects whether its input is a numeric IPv4/IPv6 literal
or a hostname (using AI_NUMERICHOST when appropriate), then delegates
resolution to ogs_addaddrinfo().
Errors are logged at the error level but do not trigger a fatal exit,
and any partial lists are cleaned up before returning.
Finally, the SMF configuration parser in context.c was updated to use
this new API for “p-cscf” entries, allowing both raw IP addresses
and DNS names in smf.yaml.
Corresponding adjustments were made in context.h (to change the p_cscf
and p_cscf6 arrays to mutable char pointers) and in the cleanup routine
smf_context_final() to free any dynamically allocated strings.
Together, these improvements eliminate duplicate parsing logic,
streamline configuration handling, and increase the overall resilience
of address resolution across Open5GS.
This commit fixes compilation errors in the SMF GSM state handlers
by declaring and initializing the n2smbuf variable at the top of
both smf_gsm_state_operational and smf_gsm_state_wait_pfcp_deletion,
and removes the redundant type specifiers from the switch‐case assignments.
Added a handler to catch invalid NAMF_COMM API messages
and prevent assertion failures, and upgraded related SBI log statements
from warnings to errors.
This update adds a comprehensive description of the Home Routed Roaming
functionality, enhances the architecture section and message
flow diagrams to illustrate the new routing process, and provides
clear configuration examples and command‑line snippets to assist
users with setup.
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.
If gsm_build_pdu_session_establishment_accept() fails due to invalid PCO,
the SMF previously hit an assertion and crashed. This patch adds a proper
error check and transitions to the reject state to prevent the crash.
This was originally reported in issue #3969.
A missing error handling path in 'smf_gsm_state_wait_pfcp_establishment'
led to an assertion failure.
Problem:
During inter-eNB/RAN handover scenarios, such as S1/N2 handover followed by X2/Xn handover cancellation,
the UE context may end up partially moved or duplicated across multiple eNBs. If the handover
is canceled by the target eNB and followed by subsequent UE Context Release or PathSwitchRequest
procedures, the MME can crash due to inconsistent context state. Specifically, when deassociating
the mme_ue <-> enb_ue (or amf_ue <-> ran_ue) pair, the code unconditionally resets the association
fields (`mme_ue->enb_ue_id`, `enb_ue->mme_ue_id`, etc.), even if they no longer reflect an actual
association due to the earlier handover cancellation.
Root Cause:
The MME or AMF state machine incorrectly assumes that the associated context IDs are still valid
and proceeds to unlink the context. When the PathSwitchRequest arrives after the UE context has
been (partially or fully) released, the assertion `enb_ue != NULL` or the mismatch in expected ID
(e.g., `mme_ue->enb_ue_id != enb_ue->id`) leads to a crash.
Solution:
This patch introduces stricter association validation before unlinking UE contexts. Specifically:
- The unlinking functions such as `enb_ue_unlink()` and `amf_ue_deassociate()` were replaced with
more explicit versions: `enb_ue_deassociate_mme_ue()` and `amf_ue_deassociate_ran_ue()`, which
compare the current context ID with the expected one.
- If the ID mismatch is detected, the deassociation is skipped and a detailed error is logged
(rather than crashing with an assertion).
- This approach prevents crashes during handover cancellation cases and avoids incorrectly
cleaning up a context that is already associated with a new peer.
Additionally:
- The same pattern was applied consistently across MME and AMF modules including:
- `s1ap-handler.c`, `mme-context.c`, `mme-s11-handler.c`, `mme-gtp-path.c`
- `ngap-handler.c`, `nsmf-handler.c`, `sbi-path.c`
- All previously direct field resets (`xxx_ue->xxx_ue_id = OGS_INVALID_POOL_ID`) are now guarded
with validation logic.
- Logging was improved to aid in debugging unexpected deassociation cases.
This change improves robustness of the MME/AMF against abnormal handover procedures and
ensures graceful handling of late context release requests or race conditions during
handover cancel and re-establishment.
Fixes: assertion failure in `sgw_ue_check_if_relocated()` during PathSwitchRequest
Add a check to ensure only IPv4, IPv6, or IPv4v6 PDN types are allowed.
For any other (unknown) PDN type, send a PDN Connectivity Reject with cause
Unknown PDN Type instead of proceeding to a fatal assertion.
This prevents the MME from crashing when it receives a malformed NAS message.
In certain race conditions, the AMF could receive an SBI response
after the RAN UE context has already been removed.
The ran_ue_find_by_id assertions in
both amf_npcf_am_policy_control_build_create and
amf_nsmf_pdusession_build_create_sm_context would
trigger a fatal abort.
This change removes those assertions so that late SBI client events are
safely ignored and do not crash the AMF.
During PDU Session release, under memory pressure or upon receiving
an RST_STREAM, the SMF could still attempt to process an already-closed
HTTP/2 stream. This led to a fatal assert(stream) in smf_state_operational(),
terminating the entire SMF process even though the error affected
only a single UE context.
This commit adds a null check for the stream before sending the HTTP status.
If the stream has already been removed, SMF now logs an error instead of
asserting.
Previously, if the AMF received an smf-select-data response (or related SBI
messages) from the NUDM-SDM after the UE context had been released, the GMM
state machine would hit an unhandled event and abort with a fatal assertion.
This commit adds a new case for OGS_SBI_SERVICE_NAME_NUDM_SDM
in gmm_state_exception(), explicitly ignoring SBI messages for AM_DATA,
SMF_SELECT_DATA, UE_CONTEXT_IN_SMF_DATA, and SDM_SUBSCRIPTIONS
(with a warning log).
Any truly unexpected resource names now emit an error log instead
of triggering assert_if_reached. As a result, the AMF will safely drop late
NUDM-SDM responses without crashing.
Previously, malformed S-NSSAI parameters could trigger a fatal assertion in
amf_update_allowed_nssai when the UE had zero slices in its subscription
database. This patch introduces an explicit check for amf_ue->num_of_slice == 0,
logs a clear error message including the UE’s SUPI, and returns false to
reject the registration.
The removed assertion prevents AMF crashes and ensures
that other UEs continue to be served normally.
Previously, malformed Protocol Configuration Options (PCO) data would trigger
ogs_assert failures in both the generic parser and SMF build routines,
causing the SMF process to abort unconditionally.
This commit replaces those fatal assertions with conditional checks:
In ogs_pco_parse(), switch from ogs_assert(size == data_len) to
ogs_expect(size == data_len), allowing the function to return gracefully.
In SMF's PCO build (smf_pco_build) and all downstream build paths
(including GN, GSM, S5C modules), replace ogs_assert(pco_len > 0)
with explicit if (pco_len <= 0) checks that:
Ensure that malformed or incomplete PCOs no longer crash the process,
but instead are handled cleanly so the network function can continue operating.
When SM Context creation fails (e.g. 504 from SMF) the AMF continued
to build and send a NAS downlink message by dynamically looking up
the AMF UE context from ran_ue->amf_ue_id inside ngap_build_downlink_nas_transport().
If ran_ue_deassociate() had already removed that mapping, the lookup
would return NULL, triggering a fatal assertion and crashing the AMF.
This patch changes:
1. nas_5gs_send_to_downlink_nas_transport() and
ngap_build_downlink_nas_transport() signatures to accept an
explicit amf_ue_t * parameter alongside ran_ue_t *.
2. All calls to nas_5gs_send_to_downlink_nas_transport() to pass
the correct amf_ue pointer (from sess->amf_ue_id).
3. Removal of the dynamic lookup and fatal assertion in
ngap_build_downlink_nas_transport(), replacing it with
ogs_assert(amf_ue) on the passed-in context.
By carrying the valid AMF UE context through the call chain, we
ensure that downlink NAS transport always has a correct pointer,
even when the ran_ue-to-amf_ue mapping has been cleared. This
prevents invalid internal state transitions and eliminates the
ngap_build_downlink_nas_transport() crash when handling SMF failures.
SM context release in initial‐context‐setup should not abort the AMF.
Use ogs_error instead of ogs_assert_if_reached to log
the invalid state transition and maintain process availability.
Any unexpected HTTP methods or resource names generate an error
and an assertion, ensuring that truly invalid cases are caught.
By adding these checks and early exits, we avoid fatal assertion failures
in scenarios where the AMF’s state machine would otherwise have no matching
transition for a late SBI callback.
In upf_sess_add, replace the unconditional assertion on sess with a check
that detects when the session pool is exhausted. If allocation fails,
log an error message (“Maximum number of Session reached”) and
return NULL instead of aborting the process.
This change prevents the UPF from crashing when the PFCP session limit (4096) is
exceeded and allows it to reject additional session establishment requests
cleanly.
In lib/sbi/message.c parse_multipart(), http->content may be NULL.
This occurs on empty-body multipart POSTs and causes a segfault.
Add guard to check http->content, log an error, and return OGS_ERROR.
In state_operational, guard against dispatching to NF instance FSMs whose
state has been reset to zero by ogs_fsm_fini() in event_termination(). Drop any
incoming SBI events for those instances and log an error, preventing assertion
failures when late HTTP callbacks arrive after an asynchronous SIGTERM shutdown.
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.