[SMF] pfcp: Retrieve sess when response with SEID=0 is received (#1620)

3GPP TS 29.244 7.2.2.4.2 documents that the peer will set SEID=0 in the
response when we request something for a session not existing at the peer.
If that's the case, we still want to locate the local session which
originated the request, so let's store the local SEID in the xact when
submitting the message, so that we can retrieve the related SEID and
find the session if we receive SEID=0.
This commit is contained in:
Pau Espin 2022-06-28 04:19:57 +02:00 committed by GitHub
parent a3593c6890
commit 5eaf66262a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 23 additions and 2 deletions

View File

@ -65,6 +65,8 @@ typedef struct ogs_pfcp_xact_s {
ogs_timer_t *tm_delayed_commit; /**< Timer waiting for commit xact */
uint64_t local_seid; /**< Local SEID, expected in reply from peer */
void *assoc_xact; /**< Associated GTP transaction */
ogs_pkbuf_t *gtpbuf; /**< GTP packet buffer */

View File

@ -329,6 +329,8 @@ int smf_pfcp_send_modify_list(
ogs_assert(sess);
ogs_assert(xact);
xact->local_seid = sess->smf_n4_seid;
memset(&h, 0, sizeof(ogs_pfcp_header_t));
h.type = OGS_PFCP_SESSION_MODIFICATION_REQUEST_TYPE;
h.seid = sess->upf_n4_seid;
@ -366,6 +368,7 @@ int smf_5gc_pfcp_send_session_establishment_request(
ogs_expect_or_return_val(xact, OGS_ERROR);
xact->assoc_stream = stream;
xact->local_seid = sess->smf_n4_seid;
memset(&h, 0, sizeof(ogs_pfcp_header_t));
h.type = OGS_PFCP_SESSION_ESTABLISHMENT_REQUEST_TYPE;
@ -399,6 +402,7 @@ int smf_5gc_pfcp_send_all_pdr_modification_request(
ogs_expect_or_return_val(xact, OGS_ERROR);
xact->assoc_stream = stream;
xact->local_seid = sess->smf_n4_seid;
xact->modify_flags = flags | OGS_PFCP_MODIFY_SESSION;
ogs_list_init(&sess->pdr_to_modify_list);
@ -425,6 +429,7 @@ int smf_5gc_pfcp_send_qos_flow_list_modification_request(
ogs_expect_or_return_val(xact, OGS_ERROR);
xact->assoc_stream = stream;
xact->local_seid = sess->smf_n4_seid;
xact->modify_flags = flags | OGS_PFCP_MODIFY_SESSION;
rv = smf_pfcp_send_modify_list(
@ -450,6 +455,7 @@ int smf_5gc_pfcp_send_session_deletion_request(
xact->assoc_stream = stream;
xact->delete_trigger = trigger;
xact->local_seid = sess->smf_n4_seid;
memset(&h, 0, sizeof(ogs_pfcp_header_t));
h.type = OGS_PFCP_SESSION_DELETION_REQUEST_TYPE;
@ -482,6 +488,7 @@ int smf_epc_pfcp_send_session_establishment_request(
xact->epc = true; /* EPC PFCP transaction */
xact->assoc_xact = gtp_xact;
xact->local_seid = sess->smf_n4_seid;
memset(&h, 0, sizeof(ogs_pfcp_header_t));
h.type = OGS_PFCP_SESSION_ESTABLISHMENT_REQUEST_TYPE;
@ -514,6 +521,7 @@ int smf_epc_pfcp_send_all_pdr_modification_request(
xact->epc = true; /* EPC PFCP transaction */
xact->assoc_xact = gtp_xact;
xact->local_seid = sess->smf_n4_seid;
xact->modify_flags = flags | OGS_PFCP_MODIFY_SESSION;
xact->gtp_pti = gtp_pti;
@ -552,6 +560,7 @@ int smf_epc_pfcp_send_one_bearer_modification_request(
xact->epc = true; /* EPC PFCP transaction */
xact->assoc_xact = gtp_xact;
xact->local_seid = sess->smf_n4_seid;
xact->modify_flags = flags;
xact->gtp_pti = gtp_pti;
@ -604,6 +613,7 @@ int smf_epc_pfcp_send_session_deletion_request(
* - Delete Bearer Request/Response with DEDICATED BEARER.
*/
xact->assoc_xact = gtp_xact;
xact->local_seid = sess->smf_n4_seid;
memset(&h, 0, sizeof(ogs_pfcp_header_t));
h.type = OGS_PFCP_SESSION_DELETION_REQUEST_TYPE;
@ -683,6 +693,7 @@ int smf_pfcp_send_session_report_response(
ogs_pfcp_header_t h;
ogs_assert(xact);
xact->local_seid = sess->smf_n4_seid;
memset(&h, 0, sizeof(ogs_pfcp_header_t));
h.type = OGS_PFCP_SESSION_REPORT_RESPONSE_TYPE;

View File

@ -185,8 +185,16 @@ void smf_pfcp_state_associated(ogs_fsm_t *s, smf_event_t *e)
xact = e->pfcp_xact;
ogs_assert(xact);
if (message->h.seid_presence && message->h.seid != 0)
sess = smf_sess_find_by_seid(message->h.seid);
if (message->h.seid_presence && message->h.seid != 0) {
sess = smf_sess_find_by_seid(message->h.seid);
} else if (xact->local_seid) { /* rx no SEID or SEID=0 */
/* 3GPP TS 29.244 7.2.2.4.2: we receive SEID=0 under some
* conditions, such as cause "Session context not found". In those
* cases, we still want to identify the local session which
* originated the message, so try harder by using the SEID we
* locacally stored in xact when sending the original request: */
sess = smf_sess_find_by_seid(xact->local_seid);
}
if (sess)
e->sess = sess;