[SMF] Handle late setup responses during PFCP deletion

A PDU session resource setup response can be followed immediately by
a UE deregistration request. The AMF sends a /modify request carrying
PDU_RES_SETUP_RSP, then a /release request for the same session,
without waiting for the /modify response.

The apparent ordering reversal does not require /release to arrive
before /modify. It can occur inside the SMF event queue:

1. The SMF handles /modify first. Its N2 SM information is copied into
   a separate SMF_EVT_NGAP_MESSAGE event and appended to the queue.
   The HTTP response is deferred until that event is processed.

2. If /release is already queued, it is processed before the newly
   appended NGAP event. The session enters wait_pfcp_deletion and
   starts PFCP session deletion.

3. The queued PDU_RES_SETUP_RSP event is then dispatched to
   wait_pfcp_deletion instead of the operational state.

Thus, the HTTP requests can be handled in arrival order while the
actual setup-response processing is overtaken by session release.

Previously, wait_pfcp_deletion did not handle SMF_EVT_NGAP_MESSAGE.
The setup response was therefore discarded without replying to the
original /modify request, leaving an outstanding SBI transaction in
the AMF and causing resource-leak warnings at shutdown.

Return 204 No Content for PDU_RES_SETUP_RSP in this state, matching
the existing behavior in wait_5gc_n1_n2_release. Acknowledge the
obsolete setup report without activating the session or changing
the ongoing PFCP deletion procedure.
This commit is contained in:
Sukchan Lee 2026-09-29 20:56:00 +09:00
parent 94136b13df
commit 84e68de802

View file

@ -3136,6 +3136,38 @@ void smf_gsm_state_wait_pfcp_deletion(ogs_fsm_t *s, smf_event_t *e)
ogs_assert_if_reached();
}
break;
case SMF_EVT_NGAP_MESSAGE:
smf_ue = smf_ue_find_by_id(sess->smf_ue_id);
ogs_assert(smf_ue);
stream_id = OGS_POINTER_TO_UINT(e->h.sbi.data);
ogs_assert(stream_id >= OGS_MIN_POOL_ID &&
stream_id <= OGS_MAX_POOL_ID);
stream = ogs_sbi_stream_find_by_id(stream_id);
if (!stream) {
ogs_error("STREAM has already been removed [%d]", stream_id);
break;
}
switch (e->ngap.type) {
case OpenAPI_n2_sm_info_type_PDU_RES_SETUP_RSP:
/*
* The N2 SM info of /modify is queued again, so a /release
* already in the queue can move the session here first.
* Acknowledge it without activating the session being deleted,
* as in smf_gsm_state_wait_5gc_n1_n2_release().
*/
ogs_warn("[%s:%d] Late PDU_RES_SETUP_RSP during PFCP deletion",
smf_ue->supi, sess->psi);
ogs_assert(true == ogs_sbi_send_http_status_no_content(stream));
break;
default:
ogs_error("[%s:%d] Unknown message[%d]",
smf_ue->supi, sess->psi, e->ngap.type);
}
break;
}
}