Skip to content

Commit

Permalink
[GTP] Refine error code path without assertion
Browse files Browse the repository at this point in the history
Refer to #1635, #1620, #1606, #1594
  • Loading branch information
acetcom committed Jun 30, 2022
1 parent b1d982a commit ad159d1
Show file tree
Hide file tree
Showing 11 changed files with 72 additions and 8 deletions.
3 changes: 3 additions & 0 deletions lib/gtp/xact.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */

Expand Down
3 changes: 2 additions & 1 deletion lib/pfcp/xact.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down
7 changes: 7 additions & 0 deletions src/mme/mme-gtp-path.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down
14 changes: 14 additions & 0 deletions src/mme/mme-sm.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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;
Expand All @@ -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;
Expand All @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion src/sgwc/pfcp-sm.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

Expand Down
29 changes: 25 additions & 4 deletions src/sgwc/sgwc-sm.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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) {
Expand All @@ -255,17 +272,20 @@ 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(
sess, gtp_xact, recvbuf, &gtp_message);
break;
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_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:
sgwc_s5c_handle_create_bearer_request(
sess, gtp_xact, recvbuf, &gtp_message);
Expand All @@ -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;
Expand Down
4 changes: 4 additions & 0 deletions src/sgwc/sxa-handler.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -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);

Expand Down
2 changes: 2 additions & 0 deletions src/smf/binding.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down
1 change: 1 addition & 0 deletions src/smf/gtp-path.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion src/smf/pfcp-sm.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
13 changes: 12 additions & 1 deletion src/smf/smf-sm.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit ad159d1

Please sign in to comment.