[GTP] Refine error code path without assertion

Refer to #1635, #1620, #1606, #1594
This commit is contained in:
Sukchan Lee 2022-06-30 10:53:19 +09:00
parent b1d982a1ee
commit ad159d1755
11 changed files with 72 additions and 8 deletions

View File

@ -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 */

View File

@ -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 */

View File

@ -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);

View File

@ -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, &gtp_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, &gtp_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, &gtp_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, &gtp_message.delete_session_response);
break;
@ -596,6 +606,7 @@ void mme_state_operational(ogs_fsm_t *s, mme_event_t *e)
xact, mme_ue, &gtp_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, &gtp_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, &gtp_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,
&gtp_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,
&gtp_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,
&gtp_message.bearer_resource_failure_indication);

View File

@ -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);
}

View File

@ -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, &gtp_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, &gtp_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, &gtp_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, &gtp_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, &gtp_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, &gtp_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, &gtp_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, &gtp_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, &gtp_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, &gtp_message);
break;

View File

@ -382,6 +382,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;
@ -419,6 +420,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);
@ -752,6 +754,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);
@ -1041,6 +1044,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);

View File

@ -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);

View File

@ -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);

View File

@ -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)

View File

@ -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,16 +168,20 @@ void smf_state_operational(ogs_fsm_t *s, smf_event_t *e)
sess, gtp_xact, recvbuf, &gtp2_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, &gtp2_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, &gtp2_message.update_bearer_response);
break;
case OGS_GTP2_DELETE_BEARER_RESPONSE_TYPE:
if (!gtp2_message.h.teid_presence) ogs_error("No TEID");
if (!sess) {
/* TODO: NACK the message */
ogs_error("TODO: NACK the message");
break;
}
e->sess = sess;