diff --git a/lib/pfcp/xact.h b/lib/pfcp/xact.h index c1b857b37..3eaa3d07b 100644 --- a/lib/pfcp/xact.h +++ b/lib/pfcp/xact.h @@ -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 */ diff --git a/src/smf/pfcp-path.c b/src/smf/pfcp-path.c index 958df2c56..e2b9e1c0f 100644 --- a/src/smf/pfcp-path.c +++ b/src/smf/pfcp-path.c @@ -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; diff --git a/src/smf/pfcp-sm.c b/src/smf/pfcp-sm.c index 9487ce951..329b60e74 100644 --- a/src/smf/pfcp-sm.c +++ b/src/smf/pfcp-sm.c @@ -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;