diff --git a/lib/gtp/xact.h b/lib/gtp/xact.h index 89a453efe..9ff3f5cc4 100644 --- a/lib/gtp/xact.h +++ b/lib/gtp/xact.h @@ -86,6 +86,9 @@ typedef struct ogs_gtp_xact_s { ogs_timer_t *tm_holding; /**< Timer waiting for holding message */ uint8_t holding_rcount; + uint32_t local_teid; /**< Local TEID, + expected in reply from peer */ + void *assoc_xact; /**< Associated GTP transaction */ void *pfcp_xact; /**< Associated PFCP transaction */ diff --git a/lib/pfcp/xact.h b/lib/pfcp/xact.h index 3eaa3d07b..bd03a9ab1 100644 --- a/lib/pfcp/xact.h +++ b/lib/pfcp/xact.h @@ -65,7 +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 */ + 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/mme/mme-gtp-path.c b/src/mme/mme-gtp-path.c index 581799352..688a0aaac 100644 --- a/src/mme/mme-gtp-path.c +++ b/src/mme/mme-gtp-path.c @@ -228,6 +228,7 @@ int mme_gtp_send_create_session_request(mme_sess_t *sess, int create_action) xact = ogs_gtp_xact_local_create(sgw_ue->gnode, &h, pkbuf, timeout, sess); ogs_expect_or_return_val(xact, OGS_ERROR); xact->create_action = create_action; + xact->local_teid = mme_ue->mme_s11_teid; rv = ogs_gtp_xact_commit(xact); ogs_expect(rv == OGS_OK); @@ -260,6 +261,7 @@ int mme_gtp_send_modify_bearer_request( xact = ogs_gtp_xact_local_create(sgw_ue->gnode, &h, pkbuf, timeout, mme_ue); ogs_expect_or_return_val(xact, OGS_ERROR); xact->modify_action = modify_action; + xact->local_teid = mme_ue->mme_s11_teid; rv = ogs_gtp_xact_commit(xact); ogs_expect(rv == OGS_OK); @@ -292,6 +294,7 @@ int mme_gtp_send_delete_session_request( xact = ogs_gtp_xact_local_create(sgw_ue->gnode, &h, s11buf, timeout, sess); ogs_expect_or_return_val(xact, OGS_ERROR); xact->delete_action = action; + xact->local_teid = mme_ue->mme_s11_teid; rv = ogs_gtp_xact_commit(xact); ogs_expect(rv == OGS_OK); @@ -470,6 +473,7 @@ int mme_gtp_send_release_access_bearers_request(mme_ue_t *mme_ue, int action) xact = ogs_gtp_xact_local_create(sgw_ue->gnode, &h, pkbuf, timeout, mme_ue); ogs_expect_or_return_val(xact, OGS_ERROR); xact->release_action = action; + xact->local_teid = mme_ue->mme_s11_teid; rv = ogs_gtp_xact_commit(xact); ogs_expect(rv == OGS_OK); @@ -586,6 +590,7 @@ int mme_gtp_send_create_indirect_data_forwarding_tunnel_request( xact = ogs_gtp_xact_local_create(sgw_ue->gnode, &h, pkbuf, timeout, mme_ue); ogs_expect_or_return_val(xact, OGS_ERROR); + xact->local_teid = mme_ue->mme_s11_teid; rv = ogs_gtp_xact_commit(xact); ogs_expect(rv == OGS_OK); @@ -618,6 +623,7 @@ int mme_gtp_send_delete_indirect_data_forwarding_tunnel_request( xact = ogs_gtp_xact_local_create(sgw_ue->gnode, &h, pkbuf, timeout, mme_ue); ogs_expect_or_return_val(xact, OGS_ERROR); xact->delete_indirect_action = action; + xact->local_teid = mme_ue->mme_s11_teid; rv = ogs_gtp_xact_commit(xact); ogs_expect(rv == OGS_OK); @@ -652,6 +658,7 @@ int mme_gtp_send_bearer_resource_command( xact = ogs_gtp_xact_local_create(sgw_ue->gnode, &h, pkbuf, timeout, bearer); ogs_expect_or_return_val(xact, OGS_ERROR); xact->xid |= OGS_GTP_CMD_XACT_ID; + xact->local_teid = mme_ue->mme_s11_teid; rv = ogs_gtp_xact_commit(xact); ogs_expect(rv == OGS_OK); diff --git a/src/mme/mme-s11-handler.c b/src/mme/mme-s11-handler.c index 744757956..f0ca12663 100644 --- a/src/mme/mme-s11-handler.c +++ b/src/mme/mme-s11-handler.c @@ -78,7 +78,7 @@ void mme_s11_handle_echo_response( } void mme_s11_handle_create_session_response( - ogs_gtp_xact_t *xact, mme_ue_t *mme_ue_from_teid, + ogs_gtp_xact_t *xact, mme_ue_t *mme_ue, ogs_gtp2_create_session_response_t *rsp) { int rv, i; @@ -91,7 +91,6 @@ void mme_s11_handle_create_session_response( mme_bearer_t *bearer = NULL; mme_sess_t *sess = NULL; - mme_ue_t *mme_ue = NULL; sgw_ue_t *source_ue = NULL, *target_ue = NULL; ogs_session_t *session = NULL; ogs_gtp2_bearer_qos_t bearer_qos; @@ -99,6 +98,7 @@ void mme_s11_handle_create_session_response( uint16_t decoded = 0; int create_action = 0; + ogs_assert(mme_ue); ogs_assert(rsp); ogs_debug("Create Session Response"); @@ -110,8 +110,6 @@ void mme_s11_handle_create_session_response( create_action = xact->create_action; sess = xact->data; ogs_assert(sess); - mme_ue = sess->mme_ue; - ogs_assert(mme_ue); source_ue = sgw_ue_cycle(mme_ue->sgw_ue); ogs_assert(source_ue); @@ -131,11 +129,6 @@ void mme_s11_handle_create_session_response( ************************/ cause_value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED; - if (!mme_ue_from_teid) { - ogs_error("No Context in TEID"); - cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND; - } - if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) { if (create_action == OGS_GTP_CREATE_IN_ATTACH_REQUEST) { ogs_error("[%s] Attach reject", mme_ue->imsi_bcd); @@ -400,7 +393,7 @@ void mme_s11_handle_create_session_response( } void mme_s11_handle_modify_bearer_response( - ogs_gtp_xact_t *xact, mme_ue_t *mme_ue_from_teid, + ogs_gtp_xact_t *xact, mme_ue_t *mme_ue, ogs_gtp2_modify_bearer_response_t *rsp) { int rv; @@ -408,9 +401,9 @@ void mme_s11_handle_modify_bearer_response( int modify_action = 0; ogs_gtp2_cause_t *cause = NULL; - mme_ue_t *mme_ue = NULL; sgw_ue_t *sgw_ue = NULL; + ogs_assert(mme_ue); ogs_assert(rsp); ogs_debug("Modify Bearer Response"); @@ -420,8 +413,6 @@ void mme_s11_handle_modify_bearer_response( ********************/ ogs_assert(xact); modify_action = xact->modify_action; - mme_ue = xact->data; - ogs_assert(mme_ue); sgw_ue = sgw_ue_cycle(mme_ue->sgw_ue); ogs_assert(sgw_ue); @@ -433,11 +424,6 @@ void mme_s11_handle_modify_bearer_response( ************************/ cause_value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED; - if (!mme_ue_from_teid) { - ogs_error("No Context in TEID"); - cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND; - } - if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) { mme_send_delete_session_or_mme_ue_context_release(mme_ue); return; @@ -494,7 +480,7 @@ void mme_s11_handle_modify_bearer_response( } void mme_s11_handle_delete_session_response( - ogs_gtp_xact_t *xact, mme_ue_t *mme_ue_from_teid, + ogs_gtp_xact_t *xact, mme_ue_t *mme_ue, ogs_gtp2_delete_session_response_t *rsp) { int rv; @@ -502,8 +488,8 @@ void mme_s11_handle_delete_session_response( int action = 0; sgw_ue_t *source_ue = NULL, *target_ue = NULL; mme_sess_t *sess = NULL; - mme_ue_t *mme_ue = NULL; + ogs_assert(mme_ue); ogs_assert(rsp); ogs_debug("Delete Session Response"); @@ -516,8 +502,6 @@ void mme_s11_handle_delete_session_response( ogs_assert(action); sess = xact->data; ogs_assert(sess); - mme_ue = sess->mme_ue; - ogs_assert(mme_ue); target_ue = sgw_ue_cycle(mme_ue->sgw_ue); ogs_assert(target_ue); @@ -532,13 +516,6 @@ void mme_s11_handle_delete_session_response( rv = ogs_gtp_xact_commit(xact); ogs_expect_or_return(rv == OGS_OK); - /************************ - * Check MME-UE Context - ************************/ - if (!mme_ue_from_teid) { - ogs_error("No Context in TEID"); - } - /******************** * Check Cause Value ********************/ @@ -1076,7 +1053,7 @@ void mme_s11_handle_delete_bearer_request( } void mme_s11_handle_release_access_bearers_response( - ogs_gtp_xact_t *xact, mme_ue_t *mme_ue_from_teid, + ogs_gtp_xact_t *xact, mme_ue_t *mme_ue, ogs_gtp2_release_access_bearers_response_t *rsp) { int rv; @@ -1085,10 +1062,10 @@ void mme_s11_handle_release_access_bearers_response( enb_ue_t *enb_ue = NULL; sgw_ue_t *sgw_ue = NULL;; - mme_ue_t *mme_ue = NULL; mme_sess_t *sess = NULL; mme_bearer_t *bearer = NULL; + ogs_assert(mme_ue); ogs_assert(rsp); ogs_debug("Release Access Bearers Response"); @@ -1099,21 +1076,12 @@ void mme_s11_handle_release_access_bearers_response( ogs_assert(xact); action = xact->release_action; ogs_assert(action); - mme_ue = xact->data; - ogs_assert(mme_ue); sgw_ue = sgw_ue_cycle(mme_ue->sgw_ue); ogs_assert(sgw_ue); rv = ogs_gtp_xact_commit(xact); ogs_expect_or_return(rv == OGS_OK); - /*********************** - * Check MME-UE Context - ***********************/ - if (!mme_ue_from_teid) { - ogs_error("No Context in TEID"); - } - /******************** * Check Cause Value ********************/ @@ -1365,7 +1333,7 @@ void mme_s11_handle_downlink_data_notification( } void mme_s11_handle_create_indirect_data_forwarding_tunnel_response( - ogs_gtp_xact_t *xact, mme_ue_t *mme_ue_from_teid, + ogs_gtp_xact_t *xact, mme_ue_t *mme_ue, ogs_gtp2_create_indirect_data_forwarding_tunnel_response_t *rsp) { int rv; @@ -1373,12 +1341,12 @@ void mme_s11_handle_create_indirect_data_forwarding_tunnel_response( ogs_gtp2_cause_t *cause = NULL; sgw_ue_t *sgw_ue = NULL; mme_bearer_t *bearer = NULL; - mme_ue_t *mme_ue = NULL; enb_ue_t *source_ue = NULL; int i; ogs_gtp2_f_teid_t *teid = NULL; + ogs_assert(mme_ue); ogs_assert(rsp); ogs_debug("Create Indirect Data Forwarding Tunnel Response"); @@ -1386,9 +1354,6 @@ void mme_s11_handle_create_indirect_data_forwarding_tunnel_response( /******************** * Check Transaction ********************/ - ogs_assert(xact); - mme_ue = xact->data; - ogs_assert(mme_ue); sgw_ue = sgw_ue_cycle(mme_ue->sgw_ue); ogs_assert(sgw_ue); @@ -1400,11 +1365,6 @@ void mme_s11_handle_create_indirect_data_forwarding_tunnel_response( ************************/ cause_value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED; - if (!mme_ue_from_teid) { - ogs_error("No Context in TEID"); - cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND; - } - if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) { mme_send_delete_session_or_mme_ue_context_release(mme_ue); return; @@ -1483,16 +1443,16 @@ void mme_s11_handle_create_indirect_data_forwarding_tunnel_response( } void mme_s11_handle_delete_indirect_data_forwarding_tunnel_response( - ogs_gtp_xact_t *xact, mme_ue_t *mme_ue_from_teid, + ogs_gtp_xact_t *xact, mme_ue_t *mme_ue, ogs_gtp2_delete_indirect_data_forwarding_tunnel_response_t *rsp) { int rv; uint8_t cause_value = 0; ogs_gtp2_cause_t *cause = NULL; int action = 0; - mme_ue_t *mme_ue = NULL; sgw_ue_t *sgw_ue = NULL; + ogs_assert(mme_ue); ogs_assert(rsp); ogs_debug("Delete Indirect Data Forwarding Tunnel Response"); @@ -1503,8 +1463,6 @@ void mme_s11_handle_delete_indirect_data_forwarding_tunnel_response( ogs_assert(xact); action = xact->delete_indirect_action; ogs_assert(action); - mme_ue = xact->data; - ogs_assert(mme_ue); sgw_ue = sgw_ue_cycle(mme_ue->sgw_ue); ogs_assert(sgw_ue); @@ -1516,11 +1474,6 @@ void mme_s11_handle_delete_indirect_data_forwarding_tunnel_response( ************************/ cause_value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED; - if (!mme_ue_from_teid) { - ogs_error("No Context in TEID"); - cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND; - } - if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) { mme_send_delete_session_or_mme_ue_context_release(mme_ue); return; @@ -1578,7 +1531,7 @@ void mme_s11_handle_delete_indirect_data_forwarding_tunnel_response( } void mme_s11_handle_bearer_resource_failure_indication( - ogs_gtp_xact_t *xact, mme_ue_t *mme_ue_from_teid, + ogs_gtp_xact_t *xact, mme_ue_t *mme_ue, ogs_gtp2_bearer_resource_failure_indication_t *ind) { int rv; @@ -1586,11 +1539,12 @@ void mme_s11_handle_bearer_resource_failure_indication( mme_bearer_t *bearer = NULL; mme_sess_t *sess = NULL; - mme_ue_t *mme_ue = NULL; sgw_ue_t *sgw_ue = NULL; ogs_debug("Bearer Resource Failure Indication"); + ogs_assert(mme_ue); + /******************** * Check Transaction ********************/ @@ -1599,17 +1553,12 @@ void mme_s11_handle_bearer_resource_failure_indication( ogs_assert(ind); sess = bearer->sess; ogs_assert(sess); - mme_ue = sess->mme_ue; - ogs_assert(mme_ue); sgw_ue = sgw_ue_cycle(mme_ue->sgw_ue); ogs_assert(sgw_ue); rv = ogs_gtp_xact_commit(xact); ogs_expect_or_return(rv == OGS_OK); - if (!mme_ue_from_teid) - ogs_error("No Context in TEID"); - /******************** * Check Cause Value ********************/ diff --git a/src/mme/mme-sm.c b/src/mme/mme-sm.c index 799f51a74..33bf3f913 100644 --- a/src/mme/mme-sm.c +++ b/src/mme/mme-sm.c @@ -562,6 +562,13 @@ void mme_state_operational(ogs_fsm_t *s, mme_event_t *e) if (gtp_message.h.teid_presence && gtp_message.h.teid != 0) { /* Cause is not "Context not found" */ mme_ue = mme_ue_find_by_teid(gtp_message.h.teid); + } else if (xact->local_teid) { /* rx no TEID or TEID=0 */ + /* 3GPP TS 29.274 5.5.2: we receive TEID=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 TEID we + * locally stored in xact when sending the original request: */ + mme_ue = mme_ue_find_by_teid(xact->local_teid); } switch (gtp_message.h.type) { @@ -572,14 +579,17 @@ void mme_state_operational(ogs_fsm_t *s, mme_event_t *e) mme_s11_handle_echo_response(xact, >p_message.echo_response); break; case OGS_GTP2_CREATE_SESSION_RESPONSE_TYPE: + if (!gtp_message.h.teid_presence) ogs_error("No TEID"); mme_s11_handle_create_session_response( xact, mme_ue, >p_message.create_session_response); break; case OGS_GTP2_MODIFY_BEARER_RESPONSE_TYPE: + if (!gtp_message.h.teid_presence) ogs_error("No TEID"); mme_s11_handle_modify_bearer_response( xact, mme_ue, >p_message.modify_bearer_response); break; case OGS_GTP2_DELETE_SESSION_RESPONSE_TYPE: + if (!gtp_message.h.teid_presence) ogs_error("No TEID"); mme_s11_handle_delete_session_response( xact, mme_ue, >p_message.delete_session_response); break; @@ -596,6 +606,7 @@ void mme_state_operational(ogs_fsm_t *s, mme_event_t *e) xact, mme_ue, >p_message.delete_bearer_request); break; case OGS_GTP2_RELEASE_ACCESS_BEARERS_RESPONSE_TYPE: + if (!gtp_message.h.teid_presence) ogs_error("No TEID"); mme_s11_handle_release_access_bearers_response( xact, mme_ue, >p_message.release_access_bearers_response); break; @@ -604,16 +615,19 @@ void mme_state_operational(ogs_fsm_t *s, mme_event_t *e) xact, mme_ue, >p_message.downlink_data_notification); break; case OGS_GTP2_CREATE_INDIRECT_DATA_FORWARDING_TUNNEL_RESPONSE_TYPE: + if (!gtp_message.h.teid_presence) ogs_error("No TEID"); mme_s11_handle_create_indirect_data_forwarding_tunnel_response( xact, mme_ue, >p_message.create_indirect_data_forwarding_tunnel_response); break; case OGS_GTP2_DELETE_INDIRECT_DATA_FORWARDING_TUNNEL_RESPONSE_TYPE: + if (!gtp_message.h.teid_presence) ogs_error("No TEID"); mme_s11_handle_delete_indirect_data_forwarding_tunnel_response( xact, mme_ue, >p_message.delete_indirect_data_forwarding_tunnel_response); break; case OGS_GTP2_BEARER_RESOURCE_FAILURE_INDICATION_TYPE: + if (!gtp_message.h.teid_presence) ogs_error("No TEID"); mme_s11_handle_bearer_resource_failure_indication( xact, mme_ue, >p_message.bearer_resource_failure_indication); diff --git a/src/sgwc/pfcp-sm.c b/src/sgwc/pfcp-sm.c index 7e392c2eb..b46ad7f49 100644 --- a/src/sgwc/pfcp-sm.c +++ b/src/sgwc/pfcp-sm.c @@ -190,7 +190,7 @@ void sgwc_pfcp_state_associated(ogs_fsm_t *s, sgwc_event_t *e) * 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: */ + * locally stored in xact when sending the original request: */ sess = sgwc_sess_find_by_seid(xact->local_seid); } @@ -216,32 +216,28 @@ void sgwc_pfcp_state_associated(ogs_fsm_t *s, sgwc_event_t *e) &message->pfcp_association_setup_response); break; case OGS_PFCP_SESSION_ESTABLISHMENT_RESPONSE_TYPE: - if (!message->h.seid_presence) - ogs_error("No SEID"); + if (!message->h.seid_presence) ogs_error("No SEID"); sgwc_sxa_handle_session_establishment_response( sess, xact, e->gtp_message, &message->pfcp_session_establishment_response); break; case OGS_PFCP_SESSION_MODIFICATION_RESPONSE_TYPE: - if (!message->h.seid_presence) - ogs_error("No SEID"); + if (!message->h.seid_presence) ogs_error("No SEID"); sgwc_sxa_handle_session_modification_response( sess, xact, e->gtp_message, &message->pfcp_session_modification_response); break; case OGS_PFCP_SESSION_DELETION_RESPONSE_TYPE: - if (!message->h.seid_presence) - ogs_error("No SEID"); + if (!message->h.seid_presence) ogs_error("No SEID"); sgwc_sxa_handle_session_deletion_response( sess, xact, e->gtp_message, &message->pfcp_session_deletion_response); break; case OGS_PFCP_SESSION_REPORT_REQUEST_TYPE: - if (!message->h.seid_presence) - ogs_error("No SEID"); + if (!message->h.seid_presence) ogs_error("No SEID"); sgwc_sxa_handle_session_report_request( sess, xact, &message->pfcp_session_report_request); break; diff --git a/src/sgwc/s11-handler.c b/src/sgwc/s11-handler.c index 1b580ed29..365ff5df4 100644 --- a/src/sgwc/s11-handler.c +++ b/src/sgwc/s11-handler.c @@ -688,6 +688,7 @@ void sgwc_s11_handle_create_bearer_response( ogs_gtp2_f_teid_t *sgw_s1u_teid = NULL, *enb_s1u_teid = NULL; ogs_gtp2_uli_t uli; + ogs_assert(sgwc_ue); ogs_assert(message); rsp = &message->create_bearer_response; ogs_assert(rsp); @@ -714,30 +715,10 @@ void sgwc_s11_handle_create_bearer_response( rv = ogs_gtp_xact_commit(s11_xact); ogs_expect(rv == OGS_OK); - /************************ - * Check SGWC-UE Context - ************************/ - cause_value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED; - - if (!sgwc_ue) { - ogs_error("No Context in TEID"); - cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND; - } - - if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) { - ogs_assert(OGS_OK == - sgwc_pfcp_send_bearer_modification_request( - bearer, NULL, NULL, - OGS_PFCP_MODIFY_UL_ONLY|OGS_PFCP_MODIFY_REMOVE)); - ogs_gtp_send_error_message(s5c_xact, sess ? sess->pgw_s5c_teid : 0, - OGS_GTP2_CREATE_BEARER_RESPONSE_TYPE, cause_value); - return; - } - /***************************************** * Check Mandatory/Conditional IE Missing *****************************************/ - ogs_assert(cause_value == OGS_GTP2_CAUSE_REQUEST_ACCEPTED); + cause_value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED; if (rsp->bearer_contexts.presence == 0) { ogs_error("No Bearer"); @@ -872,6 +853,7 @@ void sgwc_s11_handle_update_bearer_response( sgwc_bearer_t *bearer = NULL; ogs_gtp2_update_bearer_response_t *rsp = NULL; + ogs_assert(sgwc_ue); ogs_assert(message); rsp = &message->update_bearer_response; ogs_assert(rsp); @@ -898,26 +880,10 @@ void sgwc_s11_handle_update_bearer_response( rv = ogs_gtp_xact_commit(s11_xact); ogs_expect(rv == OGS_OK); - /************************ - * Check SGWC-UE Context - ************************/ - cause_value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED; - - if (!sgwc_ue) { - ogs_error("No Context in TEID"); - cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND; - } - - if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) { - ogs_gtp_send_error_message(s5c_xact, sess ? sess->pgw_s5c_teid : 0, - OGS_GTP2_UPDATE_BEARER_RESPONSE_TYPE, cause_value); - return; - } - /***************************************** * Check Mandatory/Conditional IE Missing *****************************************/ - ogs_assert(cause_value == OGS_GTP2_CAUSE_REQUEST_ACCEPTED); + cause_value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED; if (rsp->bearer_contexts.presence == 0) { ogs_error("No Bearer"); @@ -1004,6 +970,7 @@ void sgwc_s11_handle_delete_bearer_response( sgwc_bearer_t *bearer = NULL; ogs_gtp2_delete_bearer_response_t *rsp = NULL; + ogs_assert(sgwc_ue); ogs_assert(message); rsp = &message->delete_bearer_response; ogs_assert(rsp); @@ -1035,11 +1002,6 @@ void sgwc_s11_handle_delete_bearer_response( ************************/ cause_value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED; - if (!sgwc_ue) { - ogs_error("No Context in TEID"); - cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND; - } - if (rsp->linked_eps_bearer_id.presence) { /* * << Linked EPS Bearer ID >> @@ -1111,10 +1073,8 @@ void sgwc_s11_handle_delete_bearer_response( ogs_error("No Cause"); } - if (sgwc_ue) { - ogs_debug(" MME_S11_TEID[%d] SGW_S11_TEID[%d]", - sgwc_ue->mme_s11_teid, sgwc_ue->sgw_s11_teid); - } + ogs_debug(" MME_S11_TEID[%d] SGW_S11_TEID[%d]", + sgwc_ue->mme_s11_teid, sgwc_ue->sgw_s11_teid); ogs_debug(" SGW_S5C_TEID[0x%x] PGW_S5C_TEID[0x%x]", sess->sgw_s5c_teid, sess->pgw_s5c_teid); @@ -1513,6 +1473,7 @@ void sgwc_s11_handle_bearer_resource_command( s5c_xact = ogs_gtp_xact_local_create( sess->gnode, &message->h, pkbuf, gtp_bearer_timeout, bearer); ogs_expect_or_return(s5c_xact); + s5c_xact->local_teid = sess->sgw_s5c_teid; ogs_gtp_xact_associate(s11_xact, s5c_xact); diff --git a/src/sgwc/s5c-handler.c b/src/sgwc/s5c-handler.c index b76440a9b..63f88e128 100644 --- a/src/sgwc/s5c-handler.c +++ b/src/sgwc/s5c-handler.c @@ -79,6 +79,9 @@ void sgwc_s5c_handle_create_session_response( ogs_gtp_xact_t *s11_xact = NULL; ogs_gtp_node_t *pgw = NULL; + ogs_assert(sess); + sgwc_ue = sess->sgwc_ue; + ogs_assert(sgwc_ue); ogs_assert(gtpbuf); ogs_assert(message); rsp = &message->create_session_response; @@ -96,30 +99,10 @@ void sgwc_s5c_handle_create_session_response( rv = ogs_gtp_xact_commit(s5c_xact); ogs_expect(rv == OGS_OK); - /************************ - * Check Session Context - ************************/ - cause_value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED; - - if (!sess) { - ogs_error("No Context in TEID"); - cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND; - } else { - sgwc_ue = sess->sgwc_ue; - ogs_assert(sgwc_ue); - } - - if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) { - ogs_gtp_send_error_message( - s11_xact, sgwc_ue ? sgwc_ue->mme_s11_teid : 0, - OGS_GTP2_CREATE_SESSION_RESPONSE_TYPE, cause_value); - return; - } - /***************************************** * Check Mandatory/Conditional IE Missing *****************************************/ - ogs_assert(cause_value == OGS_GTP2_CAUSE_REQUEST_ACCEPTED); + cause_value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED; if (rsp->pgw_s5_s8__s2a_s2b_f_teid_for_pmip_based_interface_or_for_gtp_based_control_plane_interface.presence == 0) { ogs_error("No GTP TEID"); @@ -282,108 +265,6 @@ void sgwc_s5c_handle_create_session_response( OGS_PFCP_MODIFY_UL_ONLY|OGS_PFCP_MODIFY_ACTIVATE)); } -void sgwc_s5c_handle_delete_session_response( - sgwc_sess_t *sess, ogs_gtp_xact_t *s5c_xact, - ogs_pkbuf_t *gtpbuf, ogs_gtp2_message_t *message) -{ - int rv; - ogs_gtp2_cause_t *cause = NULL; - uint8_t cause_value; - - sgwc_ue_t *sgwc_ue = NULL; - - ogs_gtp_xact_t *s11_xact = NULL; - ogs_gtp2_delete_session_response_t *rsp = NULL; - - ogs_assert(message); - rsp = &message->delete_session_response; - ogs_assert(rsp); - - ogs_debug("Delete Session Response"); - - /******************** - * Check Transaction - ********************/ - ogs_assert(s5c_xact); - s11_xact = s5c_xact->assoc_xact; - ogs_assert(s11_xact); - - rv = ogs_gtp_xact_commit(s5c_xact); - ogs_expect(rv == OGS_OK); - - /************************ - * Check Session Context - ************************/ - cause_value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED; - - if (!sess) { - ogs_error("No Context in TEID"); - cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND; - } else { - sgwc_ue = sess->sgwc_ue; - ogs_assert(sgwc_ue); - } - - if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) { - ogs_gtp_send_error_message( - s11_xact, sgwc_ue ? sgwc_ue->mme_s11_teid : 0, - OGS_GTP2_DELETE_SESSION_RESPONSE_TYPE, cause_value); - return; - } - - /***************************************** - * Check Mandatory/Conditional IE Missing - *****************************************/ - ogs_assert(cause_value == OGS_GTP2_CAUSE_REQUEST_ACCEPTED); - - if (rsp->cause.presence == 0) { - ogs_error("No Cause"); - cause_value = OGS_GTP2_CAUSE_MANDATORY_IE_MISSING; - } - - if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) { - ogs_gtp_send_error_message( - s11_xact, sgwc_ue ? sgwc_ue->mme_s11_teid : 0, - OGS_GTP2_DELETE_SESSION_RESPONSE_TYPE, cause_value); - return; - } - - /******************** - * Check Cause Value - ********************/ - ogs_assert(cause_value == OGS_GTP2_CAUSE_REQUEST_ACCEPTED); - - cause = rsp->cause.data; - ogs_assert(cause); - cause_value = cause->value; - if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) { - ogs_error("GTP Failed [CAUSE:%d]", cause_value); - ogs_gtp_send_error_message( - s11_xact, sgwc_ue ? sgwc_ue->mme_s11_teid : 0, - OGS_GTP2_DELETE_SESSION_RESPONSE_TYPE, cause_value); - return; - } - - /******************** - * Check ALL Context - ********************/ - ogs_assert(sess); - ogs_assert(sgwc_ue); - - /* Remove a pgw session */ - ogs_debug(" MME_S11_TEID[%d] SGW_S11_TEID[%d]", - sgwc_ue->mme_s11_teid, sgwc_ue->sgw_s11_teid); - ogs_debug(" SGW_S5C_TEID[0x%x] PGW_S5C_TEID[0x%x]", - sess->sgw_s5c_teid, sess->pgw_s5c_teid); - - /* - * 1. MME sends Delete Session Request to SGW/SMF. - * 2. SMF sends Delete Session Response to SGW/MME. - */ - ogs_assert(OGS_OK == - sgwc_pfcp_send_session_deletion_request(sess, s11_xact, gtpbuf)); -} - void sgwc_s5c_handle_modify_bearer_response( sgwc_sess_t *sess, ogs_gtp_xact_t *s5c_xact, ogs_pkbuf_t *gtpbuf, ogs_gtp2_message_t *message) @@ -399,6 +280,9 @@ void sgwc_s5c_handle_modify_bearer_response( ogs_gtp_xact_t *s11_xact = NULL; ogs_gtp2_modify_bearer_response_t *rsp = NULL; + ogs_assert(sess); + sgwc_ue = sess->sgwc_ue; + ogs_assert(sgwc_ue); ogs_assert(message); rsp = &message->modify_bearer_response; ogs_assert(rsp); @@ -416,35 +300,10 @@ void sgwc_s5c_handle_modify_bearer_response( rv = ogs_gtp_xact_commit(s5c_xact); ogs_expect(rv == OGS_OK); - /************************ - * Check Session Context - ************************/ - cause_value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED; - - if (!sess) { - ogs_error("No Context in TEID"); - cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND; - } else { - sgwc_ue = sess->sgwc_ue; - ogs_assert(sgwc_ue); - } - - if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) { - if (modify_action == OGS_GTP_MODIFY_IN_PATH_SWITCH_REQUEST) - ogs_gtp_send_error_message( - s11_xact, sgwc_ue ? sgwc_ue->mme_s11_teid : 0, - OGS_GTP2_CREATE_SESSION_RESPONSE_TYPE, cause_value); - else - ogs_gtp_send_error_message( - s11_xact, sgwc_ue ? sgwc_ue->mme_s11_teid : 0, - OGS_GTP2_MODIFY_BEARER_RESPONSE_TYPE, cause_value); - return; - } - /***************************************** * Check Mandatory/Conditional IE Missing *****************************************/ - ogs_assert(cause_value == OGS_GTP2_CAUSE_REQUEST_ACCEPTED); + cause_value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED; if (rsp->cause.presence == 0) { ogs_error("No Cause"); @@ -513,6 +372,91 @@ void sgwc_s5c_handle_modify_bearer_response( } } +void sgwc_s5c_handle_delete_session_response( + sgwc_sess_t *sess, ogs_gtp_xact_t *s5c_xact, + ogs_pkbuf_t *gtpbuf, ogs_gtp2_message_t *message) +{ + int rv; + ogs_gtp2_cause_t *cause = NULL; + uint8_t cause_value; + + sgwc_ue_t *sgwc_ue = NULL; + + ogs_gtp_xact_t *s11_xact = NULL; + ogs_gtp2_delete_session_response_t *rsp = NULL; + + ogs_assert(sess); + sgwc_ue = sess->sgwc_ue; + ogs_assert(sgwc_ue); + ogs_assert(message); + rsp = &message->delete_session_response; + ogs_assert(rsp); + + ogs_debug("Delete Session Response"); + + /******************** + * Check Transaction + ********************/ + ogs_assert(s5c_xact); + s11_xact = s5c_xact->assoc_xact; + ogs_assert(s11_xact); + + rv = ogs_gtp_xact_commit(s5c_xact); + ogs_expect(rv == OGS_OK); + + /***************************************** + * Check Mandatory/Conditional IE Missing + *****************************************/ + cause_value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED; + + if (rsp->cause.presence == 0) { + ogs_error("No Cause"); + cause_value = OGS_GTP2_CAUSE_MANDATORY_IE_MISSING; + } + + if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) { + ogs_gtp_send_error_message( + s11_xact, sgwc_ue ? sgwc_ue->mme_s11_teid : 0, + OGS_GTP2_DELETE_SESSION_RESPONSE_TYPE, cause_value); + return; + } + + /******************** + * Check Cause Value + ********************/ + ogs_assert(cause_value == OGS_GTP2_CAUSE_REQUEST_ACCEPTED); + + cause = rsp->cause.data; + ogs_assert(cause); + cause_value = cause->value; + if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) { + ogs_error("GTP Failed [CAUSE:%d]", cause_value); + ogs_gtp_send_error_message( + s11_xact, sgwc_ue ? sgwc_ue->mme_s11_teid : 0, + OGS_GTP2_DELETE_SESSION_RESPONSE_TYPE, cause_value); + return; + } + + /******************** + * Check ALL Context + ********************/ + ogs_assert(sess); + ogs_assert(sgwc_ue); + + /* Remove a pgw session */ + ogs_debug(" MME_S11_TEID[%d] SGW_S11_TEID[%d]", + sgwc_ue->mme_s11_teid, sgwc_ue->sgw_s11_teid); + ogs_debug(" SGW_S5C_TEID[0x%x] PGW_S5C_TEID[0x%x]", + sess->sgw_s5c_teid, sess->pgw_s5c_teid); + + /* + * 1. MME sends Delete Session Request to SGW/SMF. + * 2. SMF sends Delete Session Response to SGW/MME. + */ + ogs_assert(OGS_OK == + sgwc_pfcp_send_session_deletion_request(sess, s11_xact, gtpbuf)); +} + void sgwc_s5c_handle_create_bearer_request( sgwc_sess_t *sess, ogs_gtp_xact_t *s5c_xact, ogs_pkbuf_t *gtpbuf, ogs_gtp2_message_t *message) @@ -725,6 +669,7 @@ void sgwc_s5c_handle_update_bearer_request( rv = ogs_gtp_xact_update_tx(s11_xact, &message->h, pkbuf); ogs_expect_or_return(rv == OGS_OK); } + s11_xact->local_teid = sgwc_ue->sgw_s11_teid; rv = ogs_gtp_xact_commit(s11_xact); ogs_expect(rv == OGS_OK); @@ -874,6 +819,7 @@ void sgwc_s5c_handle_delete_bearer_request( rv = ogs_gtp_xact_update_tx(s11_xact, &message->h, pkbuf); ogs_expect_or_return(rv == OGS_OK); } + s11_xact->local_teid = sgwc_ue->sgw_s11_teid; rv = ogs_gtp_xact_commit(s11_xact); ogs_expect(rv == OGS_OK); @@ -889,6 +835,9 @@ void sgwc_s5c_handle_bearer_resource_failure_indication( sgwc_ue_t *sgwc_ue = NULL; + ogs_assert(sess); + sgwc_ue = sess->sgwc_ue; + ogs_assert(sgwc_ue); ogs_assert(message); ind = &message->bearer_resource_failure_indication; ogs_assert(ind); @@ -902,17 +851,6 @@ void sgwc_s5c_handle_bearer_resource_failure_indication( s11_xact = s5c_xact->assoc_xact; ogs_assert(s11_xact); - /************************ - * Check Session Context - ************************/ - if (!sess) { - ogs_error("No Context in TEID"); - cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND; - } else { - sgwc_ue = sess->sgwc_ue; - ogs_assert(sgwc_ue); - } - /******************** * Check Cause Value ********************/ diff --git a/src/sgwc/sgwc-sm.c b/src/sgwc/sgwc-sm.c index 2dc8ab197..b6e1d4a63 100644 --- a/src/sgwc/sgwc-sm.c +++ b/src/sgwc/sgwc-sm.c @@ -157,6 +157,13 @@ void sgwc_state_operational(ogs_fsm_t *s, sgwc_event_t *e) if (gtp_message.h.teid_presence && gtp_message.h.teid != 0) { /* Cause is not "Context not found" */ sgwc_ue = sgwc_ue_find_by_teid(gtp_message.h.teid); + } else if (gtp_xact->local_teid) { /* rx no TEID or TEID=0 */ + /* 3GPP TS 29.274 5.5.2: we receive TEID=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 TEID we + * locally stored in xact when sending the original request: */ + sgwc_ue = sgwc_ue_find_by_teid(gtp_xact->local_teid); } switch(gtp_message.h.type) { @@ -185,14 +192,17 @@ void sgwc_state_operational(ogs_fsm_t *s, sgwc_event_t *e) sgwc_ue, gtp_xact, recvbuf, >p_message); break; case OGS_GTP2_CREATE_BEARER_RESPONSE_TYPE: + if (!gtp_message.h.teid_presence) ogs_error("No TEID"); sgwc_s11_handle_create_bearer_response( sgwc_ue, gtp_xact, recvbuf, >p_message); break; case OGS_GTP2_UPDATE_BEARER_RESPONSE_TYPE: + if (!gtp_message.h.teid_presence) ogs_error("No TEID"); sgwc_s11_handle_update_bearer_response( sgwc_ue, gtp_xact, recvbuf, >p_message); break; case OGS_GTP2_DELETE_BEARER_RESPONSE_TYPE: + if (!gtp_message.h.teid_presence) ogs_error("No TEID"); sgwc_s11_handle_delete_bearer_response( sgwc_ue, gtp_xact, recvbuf, >p_message); break; @@ -245,6 +255,13 @@ void sgwc_state_operational(ogs_fsm_t *s, sgwc_event_t *e) if (gtp_message.h.teid_presence && gtp_message.h.teid != 0) { sess = sgwc_sess_find_by_teid(gtp_message.h.teid); + } else if (gtp_xact->local_teid) { /* rx no TEID or TEID=0 */ + /* 3GPP TS 29.274 5.5.2: we receive TEID=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 TEID we + * locally stored in xact when sending the original request: */ + sess = sgwc_sess_find_by_teid(gtp_xact->local_teid); } switch(gtp_message.h.type) { @@ -255,15 +272,18 @@ void sgwc_state_operational(ogs_fsm_t *s, sgwc_event_t *e) sgwc_handle_echo_response(gtp_xact, >p_message.echo_response); break; case OGS_GTP2_CREATE_SESSION_RESPONSE_TYPE: + if (!gtp_message.h.teid_presence) ogs_error("No TEID"); sgwc_s5c_handle_create_session_response( sess, gtp_xact, recvbuf, >p_message); break; - case OGS_GTP2_DELETE_SESSION_RESPONSE_TYPE: - sgwc_s5c_handle_delete_session_response( + case OGS_GTP2_MODIFY_BEARER_RESPONSE_TYPE: + if (!gtp_message.h.teid_presence) ogs_error("No TEID"); + sgwc_s5c_handle_modify_bearer_response( sess, gtp_xact, recvbuf, >p_message); break; - case OGS_GTP2_MODIFY_BEARER_RESPONSE_TYPE: - sgwc_s5c_handle_modify_bearer_response( + case OGS_GTP2_DELETE_SESSION_RESPONSE_TYPE: + if (!gtp_message.h.teid_presence) ogs_error("No TEID"); + sgwc_s5c_handle_delete_session_response( sess, gtp_xact, recvbuf, >p_message); break; case OGS_GTP2_CREATE_BEARER_REQUEST_TYPE: @@ -279,6 +299,7 @@ void sgwc_state_operational(ogs_fsm_t *s, sgwc_event_t *e) sess, gtp_xact, recvbuf, >p_message); break; case OGS_GTP2_BEARER_RESOURCE_FAILURE_INDICATION_TYPE: + if (!gtp_message.h.teid_presence) ogs_error("No TEID"); sgwc_s5c_handle_bearer_resource_failure_indication( sess, gtp_xact, recvbuf, >p_message); break; diff --git a/src/sgwc/sxa-handler.c b/src/sgwc/sxa-handler.c index 8b3308902..a4f5ca277 100644 --- a/src/sgwc/sxa-handler.c +++ b/src/sgwc/sxa-handler.c @@ -378,6 +378,7 @@ void sgwc_sxa_handle_session_establishment_response( s5c_xact = ogs_gtp_xact_local_create( sess->gnode, &send_message.h, pkbuf, sess_timeout, sess); ogs_expect_or_return(s5c_xact); + s5c_xact->local_teid = sess->sgw_s5c_teid; s5c_xact->modify_action = OGS_GTP_MODIFY_IN_PATH_SWITCH_REQUEST; @@ -415,6 +416,7 @@ void sgwc_sxa_handle_session_establishment_response( s5c_xact = ogs_gtp_xact_local_create( sess->gnode, &recv_message->h, pkbuf, sess_timeout, sess); ogs_expect_or_return(s5c_xact); + s5c_xact->local_teid = sess->sgw_s5c_teid; } ogs_gtp_xact_associate(s11_xact, s5c_xact); @@ -731,6 +733,7 @@ void sgwc_sxa_handle_session_modification_response( s11_xact = ogs_gtp_xact_local_create(sgwc_ue->gnode, &recv_message->h, pkbuf, bearer_timeout, bearer); ogs_expect_or_return(s11_xact); + s11_xact->local_teid = sgwc_ue->sgw_s11_teid; ogs_gtp_xact_associate(s5c_xact, s11_xact); @@ -1020,6 +1023,7 @@ void sgwc_sxa_handle_session_modification_response( sess->gnode, &recv_message->h, pkbuf, sess_timeout, sess); ogs_expect_or_return(s5c_xact); + s5c_xact->local_teid = sess->sgw_s5c_teid; ogs_gtp_xact_associate(s11_xact, s5c_xact); diff --git a/src/smf/binding.c b/src/smf/binding.c index ef3922b07..9b3260b7d 100644 --- a/src/smf/binding.c +++ b/src/smf/binding.c @@ -369,6 +369,7 @@ void smf_bearer_binding(smf_sess_t *sess) xact = ogs_gtp_xact_local_create( sess->gnode, &h, pkbuf, gtp_bearer_timeout, bearer); ogs_expect_or_return(xact); + xact->local_teid = sess->smf_n4_teid; if (ogs_list_count(&bearer->pf_to_add_list) > 0) xact->update_flags |= OGS_GTP_MODIFY_TFT_UPDATE; @@ -438,6 +439,7 @@ int smf_gtp2_send_create_bearer_request(smf_bearer_t *bearer) xact = ogs_gtp_xact_local_create( sess->gnode, &h, pkbuf, gtp_bearer_timeout, bearer); ogs_expect_or_return_val(xact, OGS_ERROR); + xact->local_teid = sess->smf_n4_teid; rv = ogs_gtp_xact_commit(xact); ogs_expect(rv == OGS_OK); diff --git a/src/smf/gtp-path.c b/src/smf/gtp-path.c index f4ef18e49..f5b35d7a7 100644 --- a/src/smf/gtp-path.c +++ b/src/smf/gtp-path.c @@ -542,6 +542,7 @@ int smf_gtp2_send_delete_bearer_request( xact = ogs_gtp_xact_local_create( sess->gnode, &h, pkbuf, bearer_timeout, bearer); ogs_expect_or_return_val(xact, OGS_ERROR); + xact->local_teid = sess->smf_n4_teid; rv = ogs_gtp_xact_commit(xact); ogs_expect(rv == OGS_OK); diff --git a/src/smf/pfcp-path.c b/src/smf/pfcp-path.c index e2b9e1c0f..1eb2021af 100644 --- a/src/smf/pfcp-path.c +++ b/src/smf/pfcp-path.c @@ -402,7 +402,6 @@ 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); @@ -429,7 +428,6 @@ 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( @@ -521,7 +519,6 @@ 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; @@ -560,7 +557,6 @@ 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; diff --git a/src/smf/pfcp-sm.c b/src/smf/pfcp-sm.c index b2bc35da6..e30f682c1 100644 --- a/src/smf/pfcp-sm.c +++ b/src/smf/pfcp-sm.c @@ -192,7 +192,7 @@ void smf_pfcp_state_associated(ogs_fsm_t *s, smf_event_t *e) * 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: */ + * locally stored in xact when sending the original request: */ sess = smf_sess_find_by_seid(xact->local_seid); } if (sess) @@ -220,15 +220,13 @@ void smf_pfcp_state_associated(ogs_fsm_t *s, smf_event_t *e) &message->pfcp_association_setup_response); break; case OGS_PFCP_SESSION_ESTABLISHMENT_RESPONSE_TYPE: - if (!message->h.seid_presence) - ogs_error("No SEID"); + if (!message->h.seid_presence) ogs_error("No SEID"); ogs_assert(sess); ogs_fsm_dispatch(&sess->sm, e); break; case OGS_PFCP_SESSION_MODIFICATION_RESPONSE_TYPE: - if (!message->h.seid_presence) - ogs_error("No SEID"); + if (!message->h.seid_presence) ogs_error("No SEID"); if (xact->epc) smf_epc_n4_handle_session_modification_response( sess, xact, e->gtp2_message, @@ -239,15 +237,13 @@ void smf_pfcp_state_associated(ogs_fsm_t *s, smf_event_t *e) break; case OGS_PFCP_SESSION_DELETION_RESPONSE_TYPE: - if (!message->h.seid_presence) - ogs_error("No SEID"); + if (!message->h.seid_presence) ogs_error("No SEID"); ogs_assert(sess); ogs_fsm_dispatch(&sess->sm, e); break; case OGS_PFCP_SESSION_REPORT_REQUEST_TYPE: - if (!message->h.seid_presence) - ogs_error("No SEID"); + if (!message->h.seid_presence) ogs_error("No SEID"); smf_n4_handle_session_report_request( sess, xact, &message->pfcp_session_report_request); break; diff --git a/src/smf/s5c-handler.c b/src/smf/s5c-handler.c index a7b30c979..e98130ad7 100644 --- a/src/smf/s5c-handler.c +++ b/src/smf/s5c-handler.c @@ -595,6 +595,7 @@ void smf_s5c_handle_create_bearer_response( smf_bearer_t *bearer = NULL; ogs_pfcp_far_t *dl_far = NULL; + ogs_assert(sess); ogs_assert(rsp); ogs_debug("Create Bearer Response"); @@ -614,11 +615,6 @@ void smf_s5c_handle_create_bearer_response( ************************/ cause_value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED; - if (!sess) { - ogs_error("No Context in TEID"); - cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND; - } - if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) { ogs_assert(OGS_OK == smf_epc_pfcp_send_one_bearer_modification_request( @@ -770,6 +766,7 @@ void smf_s5c_handle_update_bearer_response( uint64_t pfcp_flags = 0; smf_bearer_t *bearer = NULL; + ogs_assert(sess); ogs_assert(rsp); ogs_debug("Update Bearer Response"); @@ -786,24 +783,10 @@ void smf_s5c_handle_update_bearer_response( rv = ogs_gtp_xact_commit(xact); ogs_expect(rv == OGS_OK); - /************************ - * Check Session Context - ************************/ - cause_value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED; - - if (!sess) { - ogs_error("No Context in TEID"); - cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND; - } - - if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) { - return; - } - /***************************************** * Check Mandatory/Conditional IE Missing *****************************************/ - ogs_assert(cause_value == OGS_GTP2_CAUSE_REQUEST_ACCEPTED); + cause_value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED; if (rsp->bearer_contexts.presence == 0) { ogs_error("No Bearer"); @@ -887,6 +870,7 @@ bool smf_s5c_handle_delete_bearer_response( uint8_t cause_value; smf_bearer_t *bearer = NULL; + ogs_assert(sess); ogs_assert(rsp); ogs_debug("Delete Bearer Response"); @@ -901,18 +885,10 @@ bool smf_s5c_handle_delete_bearer_response( rv = ogs_gtp_xact_commit(xact); ogs_expect(rv == OGS_OK); - /************************ - * Check Session Context - ************************/ - if (!sess) - ogs_error("No Context in TEID"); - /******************** * Check ALL Context ********************/ ogs_assert(bearer); - sess = bearer->sess; - ogs_assert(sess); if (rsp->linked_eps_bearer_id.presence) { /* diff --git a/src/smf/smf-sm.c b/src/smf/smf-sm.c index a7d0e5232..19fd8e249 100644 --- a/src/smf/smf-sm.c +++ b/src/smf/smf-sm.c @@ -115,8 +115,15 @@ void smf_state_operational(ogs_fsm_t *s, smf_event_t *e) } e->gtp_xact = gtp_xact; - if (gtp2_message.h.teid != 0) { + if (gtp2_message.h.teid_presence && gtp2_message.h.teid != 0) { sess = smf_sess_find_by_teid(gtp2_message.h.teid); + } else if (gtp_xact->local_teid) { /* rx no TEID or TEID=0 */ + /* 3GPP TS 29.274 5.5.2: we receive TEID=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 TEID we + * locally stored in xact when sending the original request: */ + sess = smf_sess_find_by_teid(gtp_xact->local_teid); } switch(gtp2_message.h.type) { @@ -161,18 +168,18 @@ void smf_state_operational(ogs_fsm_t *s, smf_event_t *e) sess, gtp_xact, recvbuf, >p2_message.modify_bearer_request); break; case OGS_GTP2_CREATE_BEARER_RESPONSE_TYPE: + if (!gtp2_message.h.teid_presence) ogs_error("No TEID"); smf_s5c_handle_create_bearer_response( sess, gtp_xact, >p2_message.create_bearer_response); break; case OGS_GTP2_UPDATE_BEARER_RESPONSE_TYPE: + if (!gtp2_message.h.teid_presence) ogs_error("No TEID"); smf_s5c_handle_update_bearer_response( sess, gtp_xact, >p2_message.update_bearer_response); break; case OGS_GTP2_DELETE_BEARER_RESPONSE_TYPE: - if (!sess) { - /* TODO: NACK the message */ - break; - } + if (!gtp2_message.h.teid_presence) ogs_error("No TEID"); + ogs_assert(sess); e->sess = sess; ogs_fsm_dispatch(&sess->sm, e); break;