Skip to content

Commit

Permalink
[PFCP/GTP] Incorrect TEI/SEID=0 (open5gs#3043)
Browse files Browse the repository at this point in the history
If eg. PCRF or AAA diameter link is not yet ready (eg. PCRF crashed),
and a client sends a CreateSessionRequest announcing its ow F-TEID,
then open5gs-smfd answers with Create Session Response Cause="Remote peer not responding",
but it is not setting the received F-TEID in the header of the response,
instead it sends with TEID=0.

As a result, the peer cannot match the CreateSessionResponse,
and needs to rely on its own timeout timer to figure out
that specific request failed.

See 3GPP TS 29.274 5.5 Usage of the GTPv2-C Header:

```
Bit 4 represents a "T" flag, which indicates if TEID field is present in the GTP-C header or not. If the "T" flag is
set to 0, then the TEID field shall not be present in the GTP-C header. If the "T" flag is set to 1, then the TEID
field shall immediately follow the Length field, in octets 5 to 8. Apart from the Echo Request, Echo Response
and Version Not Supported Indication messages, in all EPC specific messages the value of the "T" flag shall be
set to "1".
```

This happens with Delete Session Requests and can happen with any PFCP message.

I've fixed TEID/SEID to send the value in the reponse message as is if it was received.
  • Loading branch information
acetcom committed Apr 5, 2024
1 parent 990bfe9 commit 3064861
Show file tree
Hide file tree
Showing 22 changed files with 404 additions and 250 deletions.
2 changes: 1 addition & 1 deletion docs/_docs/guide/01-quickstart.md
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ MME-frDi = 127.0.0.2 :3868 for S6a
SGWC-gtpc = 127.0.0.3 :2123 for S11
SGWC-pfcp = 127.0.0.3 :8805 for Sxa

SMF-gtpc = 127.0.0.4 :2123 for S5c, N11
SMF-gtpc = 127.0.0.4 :2123 for S5c
SMF-gtpu = 127.0.0.4 :2152 for N4u (Sxu)
SMF-pfcp = 127.0.0.4 :8805 for N4 (Sxb)
SMF-frDi = 127.0.0.4 :3868 for Gx auth
Expand Down
91 changes: 73 additions & 18 deletions src/mme/mme-s11-handler.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,13 @@ static uint8_t esm_cause_from_gtp(uint8_t gtp_cause)
}

void mme_s11_handle_echo_request(
ogs_gtp_xact_t *xact, ogs_gtp2_echo_request_t *req)
ogs_gtp_xact_t *xact, ogs_gtp2_message_t *gtp2_message)
{
ogs_gtp2_echo_request_t *req = NULL;

ogs_assert(xact);
ogs_assert(gtp2_message);
req = &gtp2_message->echo_request;
ogs_assert(req);

ogs_debug("Receiving Echo Request");
Expand All @@ -72,14 +76,14 @@ void mme_s11_handle_echo_request(
}

void mme_s11_handle_echo_response(
ogs_gtp_xact_t *xact, ogs_gtp2_echo_response_t *rsp)
ogs_gtp_xact_t *xact, ogs_gtp2_message_t *gtp2_message)
{
/* Not Implemented */
}

void mme_s11_handle_create_session_response(
ogs_gtp_xact_t *xact, mme_ue_t *mme_ue_from_teid,
ogs_gtp2_create_session_response_t *rsp)
ogs_gtp2_message_t *gtp2_message)
{
int i, r, rv;
uint8_t cause_value = OGS_GTP2_CAUSE_UNDEFINED_VALUE;
Expand All @@ -100,6 +104,10 @@ void mme_s11_handle_create_session_response(
uint16_t decoded = 0;
int create_action = 0;

ogs_gtp2_create_session_response_t *rsp = NULL;

ogs_assert(gtp2_message);
rsp = &gtp2_message->create_session_response;
ogs_assert(rsp);

ogs_debug("Create Session Response");
Expand Down Expand Up @@ -472,7 +480,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_gtp2_modify_bearer_response_t *rsp)
ogs_gtp2_message_t *gtp2_message)
{
int r, rv;
uint8_t cause_value = OGS_GTP2_CAUSE_UNDEFINED_VALUE;
Expand All @@ -482,6 +490,10 @@ void mme_s11_handle_modify_bearer_response(
mme_ue_t *mme_ue = NULL;
sgw_ue_t *sgw_ue = NULL;

ogs_gtp2_modify_bearer_response_t *rsp = NULL;

ogs_assert(gtp2_message);
rsp = &gtp2_message->modify_bearer_response;
ogs_assert(rsp);

ogs_debug("Modify Bearer Response");
Expand Down Expand Up @@ -586,7 +598,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_gtp2_delete_session_response_t *rsp)
ogs_gtp2_message_t *gtp2_message)
{
int r, rv;
uint8_t cause_value = OGS_GTP2_CAUSE_UNDEFINED_VALUE;
Expand All @@ -595,6 +607,10 @@ void mme_s11_handle_delete_session_response(
mme_sess_t *sess = NULL;
mme_ue_t *mme_ue = NULL;

ogs_gtp2_delete_session_response_t *rsp = NULL;

ogs_assert(gtp2_message);
rsp = &gtp2_message->delete_session_response;
ogs_assert(rsp);

ogs_debug("Delete Session Response");
Expand Down Expand Up @@ -778,7 +794,7 @@ void mme_s11_handle_delete_session_response(

void mme_s11_handle_create_bearer_request(
ogs_gtp_xact_t *xact, mme_ue_t *mme_ue,
ogs_gtp2_create_bearer_request_t *req)
ogs_gtp2_message_t *gtp2_message)
{
int r;
uint8_t cause_value = OGS_GTP2_CAUSE_UNDEFINED_VALUE;
Expand All @@ -790,7 +806,11 @@ void mme_s11_handle_create_bearer_request(
ogs_gtp2_f_teid_t *pgw_s5u_teid = NULL;
ogs_gtp2_bearer_qos_t bearer_qos;

ogs_gtp2_create_bearer_request_t *req = NULL;

ogs_assert(xact);
ogs_assert(gtp2_message);
req = &gtp2_message->create_bearer_request;
ogs_assert(req);

ogs_debug("Create Bearer Request");
Expand Down Expand Up @@ -823,7 +843,8 @@ void mme_s11_handle_create_bearer_request(
}

if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
ogs_gtp2_send_error_message(xact, sgw_ue ? sgw_ue->sgw_s11_teid : 0,
ogs_gtp2_send_error_message(xact,
sgw_ue ? sgw_ue->sgw_s11_teid : gtp2_message->h.teid,
OGS_GTP2_CREATE_BEARER_RESPONSE_TYPE, cause_value);
return;
}
Expand Down Expand Up @@ -859,7 +880,8 @@ void mme_s11_handle_create_bearer_request(
}

if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
ogs_gtp2_send_error_message(xact, sgw_ue ? sgw_ue->sgw_s11_teid : 0,
ogs_gtp2_send_error_message(xact,
sgw_ue ? sgw_ue->sgw_s11_teid : gtp2_message->h.teid,
OGS_GTP2_CREATE_BEARER_RESPONSE_TYPE, cause_value);
return;
}
Expand Down Expand Up @@ -982,7 +1004,7 @@ void mme_s11_handle_create_bearer_request(

void mme_s11_handle_update_bearer_request(
ogs_gtp_xact_t *xact, mme_ue_t *mme_ue,
ogs_gtp2_update_bearer_request_t *req)
ogs_gtp2_message_t *gtp2_message)
{
int r;
uint8_t cause_value = OGS_GTP2_CAUSE_UNDEFINED_VALUE;
Expand All @@ -991,7 +1013,11 @@ void mme_s11_handle_update_bearer_request(
sgw_ue_t *sgw_ue = NULL;
ogs_gtp2_bearer_qos_t bearer_qos;

ogs_gtp2_update_bearer_request_t *req = NULL;

ogs_assert(xact);
ogs_assert(gtp2_message);
req = &gtp2_message->update_bearer_request;
ogs_assert(req);

ogs_debug("Update Bearer Request");
Expand Down Expand Up @@ -1028,7 +1054,8 @@ void mme_s11_handle_update_bearer_request(
}

if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
ogs_gtp2_send_error_message(xact, sgw_ue ? sgw_ue->sgw_s11_teid : 0,
ogs_gtp2_send_error_message(xact,
sgw_ue ? sgw_ue->sgw_s11_teid : gtp2_message->h.teid,
OGS_GTP2_UPDATE_BEARER_RESPONSE_TYPE, cause_value);
return;
}
Expand Down Expand Up @@ -1129,7 +1156,7 @@ void mme_s11_handle_update_bearer_request(

void mme_s11_handle_delete_bearer_request(
ogs_gtp_xact_t *xact, mme_ue_t *mme_ue,
ogs_gtp2_delete_bearer_request_t *req)
ogs_gtp2_message_t *gtp2_message)
{
int r;
uint8_t cause_value = OGS_GTP2_CAUSE_UNDEFINED_VALUE;
Expand All @@ -1138,7 +1165,11 @@ void mme_s11_handle_delete_bearer_request(
mme_sess_t *sess = NULL;
sgw_ue_t *sgw_ue = NULL;

ogs_gtp2_delete_bearer_request_t *req = NULL;

ogs_assert(xact);
ogs_assert(gtp2_message);
req = &gtp2_message->delete_bearer_request;
ogs_assert(req);

ogs_debug("Delete Bearer Request");
Expand Down Expand Up @@ -1199,7 +1230,8 @@ void mme_s11_handle_delete_bearer_request(
}

if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
ogs_gtp2_send_error_message(xact, sgw_ue ? sgw_ue->sgw_s11_teid : 0,
ogs_gtp2_send_error_message(xact,
sgw_ue ? sgw_ue->sgw_s11_teid : gtp2_message->h.teid,
OGS_GTP2_DELETE_BEARER_RESPONSE_TYPE,
OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND);
return;
Expand Down Expand Up @@ -1250,7 +1282,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_gtp2_release_access_bearers_response_t *rsp)
ogs_gtp2_message_t *gtp2_message)
{
int r, rv;
uint8_t cause_value = OGS_GTP2_CAUSE_UNDEFINED_VALUE;
Expand All @@ -1262,6 +1294,10 @@ void mme_s11_handle_release_access_bearers_response(
mme_sess_t *sess = NULL;
mme_bearer_t *bearer = NULL;

ogs_gtp2_release_access_bearers_response_t *rsp = NULL;

ogs_assert(gtp2_message);
rsp = &gtp2_message->release_access_bearers_response;
ogs_assert(rsp);

ogs_debug("Release Access Bearers Response");
Expand Down Expand Up @@ -1415,15 +1451,19 @@ void mme_s11_handle_release_access_bearers_response(

void mme_s11_handle_downlink_data_notification(
ogs_gtp_xact_t *xact, mme_ue_t *mme_ue,
ogs_gtp2_downlink_data_notification_t *noti)
ogs_gtp2_message_t *gtp2_message)
{
uint8_t cause_value = OGS_GTP2_CAUSE_UNDEFINED_VALUE;
int r;

mme_bearer_t *bearer = NULL;
sgw_ue_t *sgw_ue = NULL;

ogs_gtp2_downlink_data_notification_t *noti = NULL;

ogs_assert(xact);
ogs_assert(gtp2_message);
noti = &gtp2_message->downlink_data_notification;
ogs_assert(noti);

ogs_debug("Downlink Data Notification");
Expand Down Expand Up @@ -1456,7 +1496,8 @@ void mme_s11_handle_downlink_data_notification(
}

if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
ogs_gtp2_send_error_message(xact, sgw_ue ? sgw_ue->sgw_s11_teid : 0,
ogs_gtp2_send_error_message(xact,
sgw_ue ? sgw_ue->sgw_s11_teid : gtp2_message->h.teid,
OGS_GTP2_DOWNLINK_DATA_NOTIFICATION_ACKNOWLEDGE_TYPE,
OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND);
return;
Expand Down Expand Up @@ -1558,7 +1599,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_gtp2_create_indirect_data_forwarding_tunnel_response_t *rsp)
ogs_gtp2_message_t *gtp2_message)
{
int i, r, rv;
uint8_t cause_value = OGS_GTP2_CAUSE_UNDEFINED_VALUE;
Expand All @@ -1570,6 +1611,10 @@ void mme_s11_handle_create_indirect_data_forwarding_tunnel_response(

ogs_gtp2_f_teid_t *teid = NULL;

ogs_gtp2_create_indirect_data_forwarding_tunnel_response_t *rsp = NULL;

ogs_assert(gtp2_message);
rsp = &gtp2_message->create_indirect_data_forwarding_tunnel_response;
ogs_assert(rsp);

ogs_debug("Create Indirect Data Forwarding Tunnel Response");
Expand Down Expand Up @@ -1694,7 +1739,7 @@ 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_gtp2_delete_indirect_data_forwarding_tunnel_response_t *rsp)
ogs_gtp2_message_t *gtp2_message)
{
int r, rv;
uint8_t cause_value = OGS_GTP2_CAUSE_UNDEFINED_VALUE;
Expand All @@ -1703,6 +1748,10 @@ void mme_s11_handle_delete_indirect_data_forwarding_tunnel_response(
mme_ue_t *mme_ue = NULL;
sgw_ue_t *sgw_ue = NULL;

ogs_gtp2_delete_indirect_data_forwarding_tunnel_response_t *rsp = NULL;

ogs_assert(gtp2_message);
rsp = &gtp2_message->delete_indirect_data_forwarding_tunnel_response;
ogs_assert(rsp);

ogs_debug("Delete Indirect Data Forwarding Tunnel Response");
Expand Down Expand Up @@ -1804,7 +1853,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_gtp2_bearer_resource_failure_indication_t *ind)
ogs_gtp2_message_t *gtp2_message)
{
int r, rv;
uint8_t cause_value = OGS_GTP2_CAUSE_UNDEFINED_VALUE;
Expand All @@ -1814,6 +1863,12 @@ void mme_s11_handle_bearer_resource_failure_indication(
mme_ue_t *mme_ue = NULL;
sgw_ue_t *sgw_ue = NULL;

ogs_gtp2_bearer_resource_failure_indication_t *ind = NULL;

ogs_assert(gtp2_message);
ind = &gtp2_message->bearer_resource_failure_indication;
ogs_assert(ind);

ogs_debug("Bearer Resource Failure Indication");

/********************
Expand Down
26 changes: 13 additions & 13 deletions src/mme/mme-s11-handler.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,44 +27,44 @@ extern "C" {
#endif

void mme_s11_handle_echo_request(
ogs_gtp_xact_t *xact, ogs_gtp2_echo_request_t *req);
ogs_gtp_xact_t *xact, ogs_gtp2_message_t *gtp2_message);
void mme_s11_handle_echo_response(
ogs_gtp_xact_t *xact, ogs_gtp2_echo_response_t *rsp);
ogs_gtp_xact_t *xact, ogs_gtp2_message_t *gtp2_message);
void mme_s11_handle_create_session_response(
ogs_gtp_xact_t *xact, mme_ue_t *mme_ue,
ogs_gtp2_create_session_response_t *rsp);
ogs_gtp2_message_t *gtp2_message);
void mme_s11_handle_modify_bearer_response(
ogs_gtp_xact_t *xact, mme_ue_t *mme_ue,
ogs_gtp2_modify_bearer_response_t *rsp);
ogs_gtp2_message_t *gtp2_message);
void mme_s11_handle_delete_session_response(
ogs_gtp_xact_t *xact, mme_ue_t *mme_ue,
ogs_gtp2_delete_session_response_t *rsp);
ogs_gtp2_message_t *gtp2_message);
void mme_s11_handle_create_bearer_request(
ogs_gtp_xact_t *xact, mme_ue_t *mme_ue,
ogs_gtp2_create_bearer_request_t *req);
ogs_gtp2_message_t *gtp2_message);
void mme_s11_handle_update_bearer_request(
ogs_gtp_xact_t *xact, mme_ue_t *mme_ue,
ogs_gtp2_update_bearer_request_t *req);
ogs_gtp2_message_t *gtp2_message);
void mme_s11_handle_delete_bearer_request(
ogs_gtp_xact_t *xact, mme_ue_t *mme_ue,
ogs_gtp2_delete_bearer_request_t *req);
ogs_gtp2_message_t *gtp2_message);

void mme_s11_handle_release_access_bearers_response(
ogs_gtp_xact_t *xact, mme_ue_t *mme_ue,
ogs_gtp2_release_access_bearers_response_t *rsp);
ogs_gtp2_message_t *gtp2_message);
void mme_s11_handle_downlink_data_notification(
ogs_gtp_xact_t *xact, mme_ue_t *mme_ue,
ogs_gtp2_downlink_data_notification_t *noti);
ogs_gtp2_message_t *gtp2_message);
void mme_s11_handle_create_indirect_data_forwarding_tunnel_response(
ogs_gtp_xact_t *xact, mme_ue_t *mme_ue,
ogs_gtp2_create_indirect_data_forwarding_tunnel_response_t *rsp);
ogs_gtp2_message_t *gtp2_message);
void mme_s11_handle_delete_indirect_data_forwarding_tunnel_response(
ogs_gtp_xact_t *xact, mme_ue_t *mme_ue,
ogs_gtp2_delete_indirect_data_forwarding_tunnel_response_t *rsp);
ogs_gtp2_message_t *gtp2_message);

void mme_s11_handle_bearer_resource_failure_indication(
ogs_gtp_xact_t *xact, mme_ue_t *mme_ue,
ogs_gtp2_bearer_resource_failure_indication_t *ind);
ogs_gtp2_message_t *gtp2_message);

#ifdef __cplusplus
}
Expand Down
Loading

0 comments on commit 3064861

Please sign in to comment.