2020-08-13 00:31:22 +00:00
|
|
|
/*
|
[GTP/PFCP]] incorrect dst TEI=0/SEID=0 (#3043)
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 TEI=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.
This also happens in PFCP, so to solve this problem, I added teid/seid_presence
to the interface that sends the error message as shown below.
void ogs_gtp2_send_error_message(ogs_gtp_xact_t *xact,
int teid_presence, uint32_t teid, uint8_t type, uint8_t cause_value);
void ogs_pfcp_send_error_message(
ogs_pfcp_xact_t *xact, int seid_presence, uint64_t seid, uint8_t type,
uint8_t cause_value, uint16_t offending_ie_value);
2024-03-23 01:00:08 +00:00
|
|
|
* Copyright (C) 2019-2024444 by Sukchan Lee <acetcom@gmail.com>
|
2020-08-13 00:31:22 +00:00
|
|
|
*
|
|
|
|
* This file is part of Open5GS.
|
|
|
|
*
|
|
|
|
* This program is free software: you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU Affero General Public License as published by
|
|
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "gtp-path.h"
|
|
|
|
#include "pfcp-path.h"
|
|
|
|
|
|
|
|
#include "s5c-handler.h"
|
|
|
|
|
2020-11-07 22:27:12 +00:00
|
|
|
static void bearer_timeout(ogs_gtp_xact_t *xact, void *data)
|
2020-08-13 00:31:22 +00:00
|
|
|
{
|
2020-11-07 22:27:12 +00:00
|
|
|
sgwc_bearer_t *bearer = data;
|
|
|
|
sgwc_sess_t *sess = NULL;
|
2020-08-13 00:31:22 +00:00
|
|
|
sgwc_ue_t *sgwc_ue = NULL;
|
|
|
|
uint8_t type = 0;
|
|
|
|
|
|
|
|
ogs_assert(xact);
|
2020-11-07 22:27:12 +00:00
|
|
|
ogs_assert(bearer);
|
|
|
|
sess = bearer->sess;
|
2020-08-13 00:31:22 +00:00
|
|
|
ogs_assert(sess);
|
|
|
|
sgwc_ue = sess->sgwc_ue;
|
|
|
|
ogs_assert(sgwc_ue);
|
|
|
|
|
|
|
|
type = xact->seq[0].type;
|
|
|
|
|
2020-11-07 22:27:12 +00:00
|
|
|
switch (type) {
|
2022-04-12 22:07:39 +00:00
|
|
|
case OGS_GTP2_UPDATE_BEARER_REQUEST_TYPE:
|
2020-11-07 22:27:12 +00:00
|
|
|
ogs_error("[%s] No Update Bearer Response", sgwc_ue->imsi_bcd);
|
|
|
|
break;
|
2022-04-12 22:07:39 +00:00
|
|
|
case OGS_GTP2_DELETE_BEARER_REQUEST_TYPE:
|
2020-11-07 22:27:12 +00:00
|
|
|
ogs_error("[%s] No Delete Bearer Response", sgwc_ue->imsi_bcd);
|
2021-01-08 20:09:02 +00:00
|
|
|
if (!sgwc_bearer_cycle(bearer)) {
|
2022-04-29 12:28:16 +00:00
|
|
|
ogs_error("[%s] Bearer has already been removed",
|
|
|
|
sgwc_ue->imsi_bcd);
|
2021-01-08 20:09:02 +00:00
|
|
|
break;
|
|
|
|
}
|
2021-05-16 03:22:10 +00:00
|
|
|
ogs_assert(OGS_OK ==
|
|
|
|
sgwc_pfcp_send_bearer_modification_request(
|
|
|
|
bearer, NULL, NULL, OGS_PFCP_MODIFY_REMOVE));
|
2020-11-07 22:27:12 +00:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
ogs_error("GTP Timeout : IMSI[%s] Message-Type[%d]",
|
|
|
|
sgwc_ue->imsi_bcd, type);
|
|
|
|
}
|
2020-08-13 00:31:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void sgwc_s5c_handle_create_session_response(
|
|
|
|
sgwc_sess_t *sess, ogs_gtp_xact_t *s5c_xact,
|
2022-04-12 22:07:39 +00:00
|
|
|
ogs_pkbuf_t *gtpbuf, ogs_gtp2_message_t *message)
|
2020-08-13 00:31:22 +00:00
|
|
|
{
|
2022-05-12 13:52:36 +00:00
|
|
|
int rv, i;
|
2022-12-02 00:10:49 +00:00
|
|
|
uint8_t cause_value = OGS_GTP2_CAUSE_UNDEFINED_VALUE;
|
|
|
|
uint8_t session_cause = OGS_GTP2_CAUSE_UNDEFINED_VALUE;
|
|
|
|
uint8_t bearer_cause = OGS_GTP2_CAUSE_UNDEFINED_VALUE;
|
2020-08-13 00:31:22 +00:00
|
|
|
|
|
|
|
sgwc_ue_t *sgwc_ue = NULL;
|
|
|
|
sgwc_bearer_t *bearer = NULL;
|
|
|
|
sgwc_tunnel_t *ul_tunnel = NULL;
|
|
|
|
ogs_pfcp_far_t *far = NULL;
|
|
|
|
|
2022-04-12 22:07:39 +00:00
|
|
|
ogs_gtp2_f_teid_t *pgw_s5c_teid = NULL;
|
|
|
|
ogs_gtp2_f_teid_t *pgw_s5u_teid = NULL;
|
2020-08-13 00:31:22 +00:00
|
|
|
|
2022-04-12 22:07:39 +00:00
|
|
|
ogs_gtp2_create_session_response_t *rsp = NULL;
|
2020-08-13 00:31:22 +00:00
|
|
|
ogs_gtp_xact_t *s11_xact = NULL;
|
2022-05-28 08:06:36 +00:00
|
|
|
ogs_gtp_node_t *pgw = NULL;
|
2020-08-13 00:31:22 +00:00
|
|
|
|
|
|
|
ogs_assert(gtpbuf);
|
|
|
|
ogs_assert(message);
|
|
|
|
rsp = &message->create_session_response;
|
|
|
|
ogs_assert(rsp);
|
|
|
|
|
|
|
|
ogs_debug("Create Session Response");
|
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
/********************
|
|
|
|
* 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);
|
|
|
|
|
2022-12-02 00:10:49 +00:00
|
|
|
/************************
|
|
|
|
* Getting Cause Value
|
|
|
|
************************/
|
|
|
|
if (rsp->cause.presence && rsp->cause.data) {
|
|
|
|
ogs_gtp2_cause_t *cause = rsp->cause.data;
|
|
|
|
ogs_assert(cause);
|
|
|
|
session_cause = cause->value;
|
|
|
|
}
|
|
|
|
|
2022-09-25 09:55:04 +00:00
|
|
|
/************************
|
|
|
|
* Check Session Context
|
|
|
|
*
|
|
|
|
* - Session could be deleted before a message is received from SMF.
|
|
|
|
************************/
|
|
|
|
cause_value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED;
|
|
|
|
|
|
|
|
if (!sess) {
|
2022-12-02 00:10:49 +00:00
|
|
|
ogs_error("No Context in TEID [Cause:%d]", session_cause);
|
2022-09-25 09:55:04 +00:00
|
|
|
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) {
|
[GTP/PFCP]] incorrect dst TEI=0/SEID=0 (#3043)
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 TEI=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.
This also happens in PFCP, so to solve this problem, I added teid/seid_presence
to the interface that sends the error message as shown below.
void ogs_gtp2_send_error_message(ogs_gtp_xact_t *xact,
int teid_presence, uint32_t teid, uint8_t type, uint8_t cause_value);
void ogs_pfcp_send_error_message(
ogs_pfcp_xact_t *xact, int seid_presence, uint64_t seid, uint8_t type,
uint8_t cause_value, uint16_t offending_ie_value);
2024-03-23 01:00:08 +00:00
|
|
|
ogs_gtp2_send_error_message(s11_xact,
|
|
|
|
sgwc_ue ? OGS_GTP2_TEID_PRESENCE : OGS_GTP2_TEID_NO_PRESENCE,
|
|
|
|
sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
|
2022-09-25 09:55:04 +00:00
|
|
|
OGS_GTP2_CREATE_SESSION_RESPONSE_TYPE, cause_value);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
/*****************************************
|
|
|
|
* Check Mandatory/Conditional IE Missing
|
|
|
|
*****************************************/
|
2022-09-25 09:55:04 +00:00
|
|
|
ogs_assert(cause_value == OGS_GTP2_CAUSE_REQUEST_ACCEPTED);
|
2022-03-05 02:27:22 +00:00
|
|
|
|
|
|
|
if (rsp->pgw_s5_s8__s2a_s2b_f_teid_for_pmip_based_interface_or_for_gtp_based_control_plane_interface.presence == 0) {
|
2022-12-02 00:10:49 +00:00
|
|
|
ogs_error("No GTP TEID [Cause:%d]", session_cause);
|
2022-04-14 08:34:55 +00:00
|
|
|
cause_value = OGS_GTP2_CAUSE_CONDITIONAL_IE_MISSING;
|
2020-08-13 00:31:22 +00:00
|
|
|
}
|
2020-09-11 01:50:20 +00:00
|
|
|
if (rsp->pdn_address_allocation.presence) {
|
|
|
|
ogs_paa_t paa;
|
|
|
|
|
|
|
|
memcpy(&paa, rsp->pdn_address_allocation.data,
|
|
|
|
ogs_min(sizeof(paa), rsp->pdn_address_allocation.len));
|
2022-04-29 12:28:16 +00:00
|
|
|
|
|
|
|
if (!OGS_PDU_SESSION_TYPE_IS_VALID(paa.session_type)) {
|
2022-12-02 00:10:49 +00:00
|
|
|
ogs_error("Unknown PDN Type %u, Cause:%d",
|
|
|
|
paa.session_type, session_cause);
|
2022-04-29 12:28:16 +00:00
|
|
|
cause_value = OGS_GTP2_CAUSE_MANDATORY_IE_INCORRECT;
|
2020-09-11 01:50:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
} else {
|
2022-12-02 00:10:49 +00:00
|
|
|
ogs_error("No PDN Address Allocation [Cause:%d]", session_cause);
|
2022-04-14 08:34:55 +00:00
|
|
|
cause_value = OGS_GTP2_CAUSE_CONDITIONAL_IE_MISSING;
|
2020-09-11 01:50:20 +00:00
|
|
|
}
|
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
if (rsp->cause.presence == 0) {
|
2022-12-02 00:10:49 +00:00
|
|
|
ogs_error("No Cause [VALUE:%d]", session_cause);
|
2022-05-12 13:52:36 +00:00
|
|
|
cause_value = OGS_GTP2_CAUSE_CONDITIONAL_IE_MISSING;
|
2022-04-29 12:28:16 +00:00
|
|
|
}
|
|
|
|
|
2022-04-12 22:07:39 +00:00
|
|
|
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
[GTP/PFCP]] incorrect dst TEI=0/SEID=0 (#3043)
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 TEI=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.
This also happens in PFCP, so to solve this problem, I added teid/seid_presence
to the interface that sends the error message as shown below.
void ogs_gtp2_send_error_message(ogs_gtp_xact_t *xact,
int teid_presence, uint32_t teid, uint8_t type, uint8_t cause_value);
void ogs_pfcp_send_error_message(
ogs_pfcp_xact_t *xact, int seid_presence, uint64_t seid, uint8_t type,
uint8_t cause_value, uint16_t offending_ie_value);
2024-03-23 01:00:08 +00:00
|
|
|
ogs_gtp2_send_error_message(s11_xact,
|
|
|
|
sgwc_ue ? OGS_GTP2_TEID_PRESENCE : OGS_GTP2_TEID_NO_PRESENCE,
|
|
|
|
sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
|
2022-04-12 22:07:39 +00:00
|
|
|
OGS_GTP2_CREATE_SESSION_RESPONSE_TYPE, cause_value);
|
2022-03-05 02:27:22 +00:00
|
|
|
return;
|
2020-11-07 22:27:12 +00:00
|
|
|
}
|
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
/********************
|
2022-03-05 02:27:22 +00:00
|
|
|
* Check Cause Value
|
2022-04-29 12:28:16 +00:00
|
|
|
********************/
|
2022-04-12 22:07:39 +00:00
|
|
|
ogs_assert(cause_value == OGS_GTP2_CAUSE_REQUEST_ACCEPTED);
|
2020-11-07 22:27:12 +00:00
|
|
|
|
2022-05-12 13:52:36 +00:00
|
|
|
for (i = 0; i < OGS_BEARER_PER_UE; i++) {
|
2022-12-02 00:10:49 +00:00
|
|
|
ogs_gtp2_cause_t *cause = NULL;
|
2022-05-12 13:52:36 +00:00
|
|
|
if (rsp->bearer_contexts_created[i].cause.presence == 0) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
cause = rsp->bearer_contexts_created[i].cause.data;
|
2022-12-02 00:10:49 +00:00
|
|
|
if (cause == NULL) {
|
|
|
|
ogs_error("No Cause Data");
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
bearer_cause = cause->value;
|
|
|
|
if (bearer_cause != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
|
|
|
ogs_error("GTP Bearer Cause [VALUE:%d]", bearer_cause);
|
[GTP/PFCP]] incorrect dst TEI=0/SEID=0 (#3043)
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 TEI=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.
This also happens in PFCP, so to solve this problem, I added teid/seid_presence
to the interface that sends the error message as shown below.
void ogs_gtp2_send_error_message(ogs_gtp_xact_t *xact,
int teid_presence, uint32_t teid, uint8_t type, uint8_t cause_value);
void ogs_pfcp_send_error_message(
ogs_pfcp_xact_t *xact, int seid_presence, uint64_t seid, uint8_t type,
uint8_t cause_value, uint16_t offending_ie_value);
2024-03-23 01:00:08 +00:00
|
|
|
ogs_gtp2_send_error_message(s11_xact,
|
|
|
|
sgwc_ue ? OGS_GTP2_TEID_PRESENCE :
|
|
|
|
OGS_GTP2_TEID_NO_PRESENCE,
|
|
|
|
sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
|
2022-12-02 00:10:49 +00:00
|
|
|
OGS_GTP2_CREATE_SESSION_RESPONSE_TYPE, bearer_cause);
|
2022-05-12 13:52:36 +00:00
|
|
|
return;
|
|
|
|
}
|
2020-11-07 22:27:12 +00:00
|
|
|
}
|
|
|
|
|
2022-12-02 00:10:49 +00:00
|
|
|
if (session_cause != OGS_GTP2_CAUSE_REQUEST_ACCEPTED &&
|
|
|
|
session_cause != OGS_GTP2_CAUSE_REQUEST_ACCEPTED_PARTIALLY &&
|
|
|
|
session_cause !=
|
2022-04-12 22:07:39 +00:00
|
|
|
OGS_GTP2_CAUSE_NEW_PDN_TYPE_DUE_TO_NETWORK_PREFERENCE &&
|
2022-12-02 00:10:49 +00:00
|
|
|
session_cause !=
|
2022-04-12 22:07:39 +00:00
|
|
|
OGS_GTP2_CAUSE_NEW_PDN_TYPE_DUE_TO_SINGLE_ADDRESS_BEARER_ONLY) {
|
2022-12-02 00:10:49 +00:00
|
|
|
ogs_error("GTP Cause [VALUE:%d]", session_cause);
|
[GTP/PFCP]] incorrect dst TEI=0/SEID=0 (#3043)
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 TEI=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.
This also happens in PFCP, so to solve this problem, I added teid/seid_presence
to the interface that sends the error message as shown below.
void ogs_gtp2_send_error_message(ogs_gtp_xact_t *xact,
int teid_presence, uint32_t teid, uint8_t type, uint8_t cause_value);
void ogs_pfcp_send_error_message(
ogs_pfcp_xact_t *xact, int seid_presence, uint64_t seid, uint8_t type,
uint8_t cause_value, uint16_t offending_ie_value);
2024-03-23 01:00:08 +00:00
|
|
|
ogs_gtp2_send_error_message(s11_xact,
|
|
|
|
sgwc_ue ? OGS_GTP2_TEID_PRESENCE : OGS_GTP2_TEID_NO_PRESENCE,
|
|
|
|
sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
|
2022-12-02 00:10:49 +00:00
|
|
|
OGS_GTP2_CREATE_SESSION_RESPONSE_TYPE, session_cause);
|
2020-08-13 00:31:22 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
/********************
|
|
|
|
* Check ALL Context
|
|
|
|
********************/
|
|
|
|
ogs_assert(sgwc_ue);
|
|
|
|
ogs_assert(sess);
|
2020-11-07 22:27:12 +00:00
|
|
|
|
2022-05-12 13:52:36 +00:00
|
|
|
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);
|
2020-08-13 00:31:22 +00:00
|
|
|
|
2022-05-12 13:52:36 +00:00
|
|
|
for (i = 0; i < OGS_BEARER_PER_UE; i++) {
|
|
|
|
if (rsp->bearer_contexts_created[i].presence == 0) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (rsp->bearer_contexts_created[i].eps_bearer_id.presence == 0) {
|
|
|
|
ogs_error("No EPS Bearer ID");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (rsp->bearer_contexts_created[i].s5_s8_u_sgw_f_teid.presence == 0) {
|
|
|
|
ogs_error("No GTP TEID");
|
|
|
|
break;
|
|
|
|
}
|
2020-08-13 00:31:22 +00:00
|
|
|
|
2022-05-12 13:52:36 +00:00
|
|
|
/* EPS Bearer ID */
|
|
|
|
bearer = sgwc_bearer_find_by_sess_ebi(sess,
|
|
|
|
rsp->bearer_contexts_created[i].eps_bearer_id.u8);
|
|
|
|
if (!bearer) {
|
[GTP/PFCP]] incorrect dst TEI=0/SEID=0 (#3043)
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 TEI=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.
This also happens in PFCP, so to solve this problem, I added teid/seid_presence
to the interface that sends the error message as shown below.
void ogs_gtp2_send_error_message(ogs_gtp_xact_t *xact,
int teid_presence, uint32_t teid, uint8_t type, uint8_t cause_value);
void ogs_pfcp_send_error_message(
ogs_pfcp_xact_t *xact, int seid_presence, uint64_t seid, uint8_t type,
uint8_t cause_value, uint16_t offending_ie_value);
2024-03-23 01:00:08 +00:00
|
|
|
ogs_gtp2_send_error_message(s11_xact,
|
|
|
|
sgwc_ue ? OGS_GTP2_TEID_PRESENCE :
|
|
|
|
OGS_GTP2_TEID_NO_PRESENCE,
|
|
|
|
sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
|
2022-05-12 13:52:36 +00:00
|
|
|
OGS_GTP2_CREATE_SESSION_RESPONSE_TYPE,
|
|
|
|
OGS_GTP2_CAUSE_MANDATORY_IE_MISSING);
|
|
|
|
return;
|
|
|
|
}
|
2020-08-13 00:31:22 +00:00
|
|
|
|
2022-05-12 13:52:36 +00:00
|
|
|
ul_tunnel = sgwc_ul_tunnel_in_bearer(bearer);
|
|
|
|
ogs_assert(ul_tunnel);
|
2020-12-03 06:16:57 +00:00
|
|
|
|
2022-05-12 13:52:36 +00:00
|
|
|
ogs_debug(" SGW_S5U_TEID[%d] PGW_S5U_TEID[%d]",
|
|
|
|
ul_tunnel->local_teid, ul_tunnel->remote_teid);
|
|
|
|
|
|
|
|
/* Receive Data Plane(UL) : PGW-S5U */
|
|
|
|
pgw_s5u_teid = rsp->bearer_contexts_created[i].s5_s8_u_sgw_f_teid.data;
|
|
|
|
ogs_assert(pgw_s5u_teid);
|
|
|
|
ul_tunnel->remote_teid = be32toh(pgw_s5u_teid->teid);
|
|
|
|
|
|
|
|
rv = ogs_gtp2_f_teid_to_ip(pgw_s5u_teid, &ul_tunnel->remote_ip);
|
|
|
|
if (rv != OGS_OK) {
|
[GTP/PFCP]] incorrect dst TEI=0/SEID=0 (#3043)
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 TEI=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.
This also happens in PFCP, so to solve this problem, I added teid/seid_presence
to the interface that sends the error message as shown below.
void ogs_gtp2_send_error_message(ogs_gtp_xact_t *xact,
int teid_presence, uint32_t teid, uint8_t type, uint8_t cause_value);
void ogs_pfcp_send_error_message(
ogs_pfcp_xact_t *xact, int seid_presence, uint64_t seid, uint8_t type,
uint8_t cause_value, uint16_t offending_ie_value);
2024-03-23 01:00:08 +00:00
|
|
|
ogs_gtp2_send_error_message(s11_xact,
|
|
|
|
sgwc_ue ? OGS_GTP2_TEID_PRESENCE :
|
|
|
|
OGS_GTP2_TEID_NO_PRESENCE,
|
|
|
|
sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
|
2022-05-12 13:52:36 +00:00
|
|
|
OGS_GTP2_CREATE_SESSION_RESPONSE_TYPE,
|
|
|
|
OGS_GTP2_CAUSE_MANDATORY_IE_MISSING);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
far = ul_tunnel->far;
|
|
|
|
ogs_assert(far);
|
|
|
|
|
|
|
|
far->apply_action = OGS_PFCP_APPLY_ACTION_FORW;
|
|
|
|
|
|
|
|
ogs_assert(OGS_OK ==
|
|
|
|
ogs_pfcp_ip_to_outer_header_creation(&ul_tunnel->remote_ip,
|
|
|
|
&far->outer_header_creation, &far->outer_header_creation_len));
|
|
|
|
far->outer_header_creation.teid = ul_tunnel->remote_teid;
|
|
|
|
}
|
2020-08-13 00:31:22 +00:00
|
|
|
|
|
|
|
/* Receive Control Plane(UL) : PGW-S5C */
|
|
|
|
pgw_s5c_teid = rsp->pgw_s5_s8__s2a_s2b_f_teid_for_pmip_based_interface_or_for_gtp_based_control_plane_interface.data;
|
|
|
|
ogs_assert(pgw_s5c_teid);
|
|
|
|
sess->pgw_s5c_teid = be32toh(pgw_s5c_teid->teid);
|
|
|
|
|
2022-05-28 08:06:36 +00:00
|
|
|
pgw = ogs_gtp_node_find_by_f_teid(&sgwc_self()->pgw_s5c_list, pgw_s5c_teid);
|
|
|
|
if (!pgw) {
|
|
|
|
pgw = ogs_gtp_node_add_by_f_teid(
|
|
|
|
&sgwc_self()->pgw_s5c_list,
|
|
|
|
pgw_s5c_teid, ogs_gtp_self()->gtpc_port);
|
|
|
|
ogs_assert(pgw);
|
|
|
|
|
|
|
|
rv = ogs_gtp_connect(
|
|
|
|
ogs_gtp_self()->gtpc_sock, ogs_gtp_self()->gtpc_sock6, pgw);
|
|
|
|
ogs_assert(rv == OGS_OK);
|
|
|
|
}
|
|
|
|
/* Setup GTP Node */
|
|
|
|
OGS_SETUP_GTP_NODE(sess, pgw);
|
|
|
|
|
2021-05-16 03:22:10 +00:00
|
|
|
ogs_assert(OGS_OK ==
|
2022-05-12 13:52:36 +00:00
|
|
|
sgwc_pfcp_send_session_modification_request(
|
|
|
|
sess, s11_xact, gtpbuf,
|
2021-05-16 03:22:10 +00:00
|
|
|
OGS_PFCP_MODIFY_UL_ONLY|OGS_PFCP_MODIFY_ACTIVATE));
|
2020-08-13 00:31:22 +00:00
|
|
|
}
|
|
|
|
|
2022-07-16 04:27:18 +00:00
|
|
|
void sgwc_s5c_handle_modify_bearer_response(
|
2020-08-13 00:31:22 +00:00
|
|
|
sgwc_sess_t *sess, ogs_gtp_xact_t *s5c_xact,
|
2022-04-12 22:07:39 +00:00
|
|
|
ogs_pkbuf_t *gtpbuf, ogs_gtp2_message_t *message)
|
2020-08-13 00:31:22 +00:00
|
|
|
{
|
|
|
|
int rv;
|
2022-12-02 00:10:49 +00:00
|
|
|
uint8_t cause_value = OGS_GTP2_CAUSE_UNDEFINED_VALUE;
|
|
|
|
uint8_t session_cause = OGS_GTP2_CAUSE_UNDEFINED_VALUE;
|
2022-07-16 04:27:18 +00:00
|
|
|
int modify_action;
|
2020-08-13 00:31:22 +00:00
|
|
|
|
|
|
|
sgwc_ue_t *sgwc_ue = NULL;
|
2022-07-16 04:27:18 +00:00
|
|
|
ogs_pkbuf_t *pkbuf = NULL;
|
2020-08-13 00:31:22 +00:00
|
|
|
|
|
|
|
ogs_gtp_xact_t *s11_xact = NULL;
|
2022-07-16 04:27:18 +00:00
|
|
|
ogs_gtp2_modify_bearer_response_t *rsp = NULL;
|
2020-08-13 00:31:22 +00:00
|
|
|
|
|
|
|
ogs_assert(message);
|
2022-07-16 04:27:18 +00:00
|
|
|
rsp = &message->modify_bearer_response;
|
2020-08-13 00:31:22 +00:00
|
|
|
ogs_assert(rsp);
|
|
|
|
|
2022-07-16 04:27:18 +00:00
|
|
|
ogs_debug("Modify Bearer Response");
|
2020-08-13 00:31:22 +00:00
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
/********************
|
|
|
|
* Check Transaction
|
|
|
|
********************/
|
|
|
|
ogs_assert(s5c_xact);
|
|
|
|
s11_xact = s5c_xact->assoc_xact;
|
|
|
|
ogs_assert(s11_xact);
|
2022-07-16 04:27:18 +00:00
|
|
|
modify_action = s5c_xact->modify_action;
|
2022-04-29 12:28:16 +00:00
|
|
|
|
|
|
|
rv = ogs_gtp_xact_commit(s5c_xact);
|
|
|
|
ogs_expect(rv == OGS_OK);
|
|
|
|
|
2022-12-02 00:10:49 +00:00
|
|
|
/************************
|
|
|
|
* Getting Cause Value
|
|
|
|
************************/
|
|
|
|
if (rsp->cause.presence && rsp->cause.data) {
|
|
|
|
ogs_gtp2_cause_t *cause = rsp->cause.data;
|
|
|
|
ogs_assert(cause);
|
|
|
|
session_cause = cause->value;
|
|
|
|
}
|
|
|
|
|
2022-09-25 09:55:04 +00:00
|
|
|
/************************
|
|
|
|
* Check Session Context
|
|
|
|
*
|
|
|
|
* - Session could be deleted before a message is received from SMF.
|
|
|
|
************************/
|
|
|
|
cause_value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED;
|
|
|
|
|
|
|
|
if (!sess) {
|
2022-12-02 00:10:49 +00:00
|
|
|
ogs_error("No Context in TEID [Cause:%d]", session_cause);
|
2022-09-25 09:55:04 +00:00
|
|
|
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)
|
[GTP/PFCP]] incorrect dst TEI=0/SEID=0 (#3043)
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 TEI=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.
This also happens in PFCP, so to solve this problem, I added teid/seid_presence
to the interface that sends the error message as shown below.
void ogs_gtp2_send_error_message(ogs_gtp_xact_t *xact,
int teid_presence, uint32_t teid, uint8_t type, uint8_t cause_value);
void ogs_pfcp_send_error_message(
ogs_pfcp_xact_t *xact, int seid_presence, uint64_t seid, uint8_t type,
uint8_t cause_value, uint16_t offending_ie_value);
2024-03-23 01:00:08 +00:00
|
|
|
ogs_gtp2_send_error_message(s11_xact,
|
|
|
|
sgwc_ue ? OGS_GTP2_TEID_PRESENCE : OGS_GTP2_TEID_NO_PRESENCE,
|
|
|
|
sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
|
|
|
|
OGS_GTP2_CREATE_SESSION_RESPONSE_TYPE, cause_value);
|
2022-09-25 09:55:04 +00:00
|
|
|
else
|
[GTP/PFCP]] incorrect dst TEI=0/SEID=0 (#3043)
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 TEI=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.
This also happens in PFCP, so to solve this problem, I added teid/seid_presence
to the interface that sends the error message as shown below.
void ogs_gtp2_send_error_message(ogs_gtp_xact_t *xact,
int teid_presence, uint32_t teid, uint8_t type, uint8_t cause_value);
void ogs_pfcp_send_error_message(
ogs_pfcp_xact_t *xact, int seid_presence, uint64_t seid, uint8_t type,
uint8_t cause_value, uint16_t offending_ie_value);
2024-03-23 01:00:08 +00:00
|
|
|
ogs_gtp2_send_error_message(s11_xact,
|
|
|
|
sgwc_ue ? OGS_GTP2_TEID_PRESENCE : OGS_GTP2_TEID_NO_PRESENCE,
|
|
|
|
sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
|
|
|
|
OGS_GTP2_MODIFY_BEARER_RESPONSE_TYPE, cause_value);
|
2022-09-25 09:55:04 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
/*****************************************
|
|
|
|
* Check Mandatory/Conditional IE Missing
|
|
|
|
*****************************************/
|
2022-09-25 09:55:04 +00:00
|
|
|
ogs_assert(cause_value == OGS_GTP2_CAUSE_REQUEST_ACCEPTED);
|
2020-08-13 00:31:22 +00:00
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
if (rsp->cause.presence == 0) {
|
2022-12-02 00:10:49 +00:00
|
|
|
ogs_error("No Cause [VALUE:%d]", session_cause);
|
2022-04-12 22:07:39 +00:00
|
|
|
cause_value = OGS_GTP2_CAUSE_MANDATORY_IE_MISSING;
|
2020-08-13 00:31:22 +00:00
|
|
|
}
|
|
|
|
|
2022-04-12 22:07:39 +00:00
|
|
|
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
2022-07-16 04:27:18 +00:00
|
|
|
if (modify_action == OGS_GTP_MODIFY_IN_PATH_SWITCH_REQUEST)
|
[GTP/PFCP]] incorrect dst TEI=0/SEID=0 (#3043)
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 TEI=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.
This also happens in PFCP, so to solve this problem, I added teid/seid_presence
to the interface that sends the error message as shown below.
void ogs_gtp2_send_error_message(ogs_gtp_xact_t *xact,
int teid_presence, uint32_t teid, uint8_t type, uint8_t cause_value);
void ogs_pfcp_send_error_message(
ogs_pfcp_xact_t *xact, int seid_presence, uint64_t seid, uint8_t type,
uint8_t cause_value, uint16_t offending_ie_value);
2024-03-23 01:00:08 +00:00
|
|
|
ogs_gtp2_send_error_message(s11_xact,
|
|
|
|
sgwc_ue ? OGS_GTP2_TEID_PRESENCE : OGS_GTP2_TEID_NO_PRESENCE,
|
|
|
|
sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
|
|
|
|
OGS_GTP2_CREATE_SESSION_RESPONSE_TYPE, cause_value);
|
2022-07-16 04:27:18 +00:00
|
|
|
else
|
[GTP/PFCP]] incorrect dst TEI=0/SEID=0 (#3043)
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 TEI=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.
This also happens in PFCP, so to solve this problem, I added teid/seid_presence
to the interface that sends the error message as shown below.
void ogs_gtp2_send_error_message(ogs_gtp_xact_t *xact,
int teid_presence, uint32_t teid, uint8_t type, uint8_t cause_value);
void ogs_pfcp_send_error_message(
ogs_pfcp_xact_t *xact, int seid_presence, uint64_t seid, uint8_t type,
uint8_t cause_value, uint16_t offending_ie_value);
2024-03-23 01:00:08 +00:00
|
|
|
ogs_gtp2_send_error_message(s11_xact,
|
|
|
|
sgwc_ue ? OGS_GTP2_TEID_PRESENCE : OGS_GTP2_TEID_NO_PRESENCE,
|
|
|
|
sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
|
|
|
|
OGS_GTP2_MODIFY_BEARER_RESPONSE_TYPE, cause_value);
|
2022-04-29 12:28:16 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/********************
|
|
|
|
* Check Cause Value
|
|
|
|
********************/
|
|
|
|
ogs_assert(cause_value == OGS_GTP2_CAUSE_REQUEST_ACCEPTED);
|
|
|
|
|
2022-12-02 00:10:49 +00:00
|
|
|
if (session_cause != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
|
|
|
ogs_error("GTP Cause [VALUE:%d]", session_cause);
|
2022-07-16 04:27:18 +00:00
|
|
|
if (modify_action == OGS_GTP_MODIFY_IN_PATH_SWITCH_REQUEST)
|
[GTP/PFCP]] incorrect dst TEI=0/SEID=0 (#3043)
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 TEI=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.
This also happens in PFCP, so to solve this problem, I added teid/seid_presence
to the interface that sends the error message as shown below.
void ogs_gtp2_send_error_message(ogs_gtp_xact_t *xact,
int teid_presence, uint32_t teid, uint8_t type, uint8_t cause_value);
void ogs_pfcp_send_error_message(
ogs_pfcp_xact_t *xact, int seid_presence, uint64_t seid, uint8_t type,
uint8_t cause_value, uint16_t offending_ie_value);
2024-03-23 01:00:08 +00:00
|
|
|
ogs_gtp2_send_error_message(s11_xact,
|
|
|
|
sgwc_ue ? OGS_GTP2_TEID_PRESENCE : OGS_GTP2_TEID_NO_PRESENCE,
|
|
|
|
sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
|
|
|
|
OGS_GTP2_CREATE_SESSION_RESPONSE_TYPE, session_cause);
|
2022-07-16 04:27:18 +00:00
|
|
|
else
|
[GTP/PFCP]] incorrect dst TEI=0/SEID=0 (#3043)
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 TEI=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.
This also happens in PFCP, so to solve this problem, I added teid/seid_presence
to the interface that sends the error message as shown below.
void ogs_gtp2_send_error_message(ogs_gtp_xact_t *xact,
int teid_presence, uint32_t teid, uint8_t type, uint8_t cause_value);
void ogs_pfcp_send_error_message(
ogs_pfcp_xact_t *xact, int seid_presence, uint64_t seid, uint8_t type,
uint8_t cause_value, uint16_t offending_ie_value);
2024-03-23 01:00:08 +00:00
|
|
|
ogs_gtp2_send_error_message(s11_xact,
|
|
|
|
sgwc_ue ? OGS_GTP2_TEID_PRESENCE : OGS_GTP2_TEID_NO_PRESENCE,
|
|
|
|
sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
|
|
|
|
OGS_GTP2_MODIFY_BEARER_RESPONSE_TYPE, session_cause);
|
2022-04-29 12:28:16 +00:00
|
|
|
return;
|
2020-08-13 00:31:22 +00:00
|
|
|
}
|
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
/********************
|
|
|
|
* Check ALL Context
|
|
|
|
********************/
|
2022-06-30 00:11:31 +00:00
|
|
|
ogs_assert(sgwc_ue);
|
2022-07-16 04:27:18 +00:00
|
|
|
ogs_assert(sess);
|
2022-04-29 12:28:16 +00:00
|
|
|
|
2020-08-13 00:31:22 +00:00
|
|
|
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);
|
|
|
|
|
2022-07-16 04:27:18 +00:00
|
|
|
if (modify_action == OGS_GTP_MODIFY_IN_PATH_SWITCH_REQUEST) {
|
|
|
|
ogs_assert(OGS_OK ==
|
|
|
|
sgwc_gtp_send_create_session_response(sess, s11_xact));
|
|
|
|
} else {
|
|
|
|
message->h.type = OGS_GTP2_MODIFY_BEARER_RESPONSE_TYPE;
|
[GTP/PFCP]] incorrect dst TEI=0/SEID=0 (#3043)
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 TEI=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.
This also happens in PFCP, so to solve this problem, I added teid/seid_presence
to the interface that sends the error message as shown below.
void ogs_gtp2_send_error_message(ogs_gtp_xact_t *xact,
int teid_presence, uint32_t teid, uint8_t type, uint8_t cause_value);
void ogs_pfcp_send_error_message(
ogs_pfcp_xact_t *xact, int seid_presence, uint64_t seid, uint8_t type,
uint8_t cause_value, uint16_t offending_ie_value);
2024-03-23 01:00:08 +00:00
|
|
|
message->h.teid_presence = OGS_GTP2_TEID_PRESENCE;
|
2022-07-16 04:27:18 +00:00
|
|
|
message->h.teid = sgwc_ue->mme_s11_teid;
|
|
|
|
|
|
|
|
pkbuf = ogs_gtp2_build_msg(message);
|
2023-01-23 15:01:36 +00:00
|
|
|
if (!pkbuf) {
|
|
|
|
ogs_error("ogs_gtp2_build_msg() failed");
|
|
|
|
return;
|
|
|
|
}
|
2022-07-16 04:27:18 +00:00
|
|
|
|
|
|
|
rv = ogs_gtp_xact_update_tx(s11_xact, &message->h, pkbuf);
|
2023-01-23 15:01:36 +00:00
|
|
|
if (rv != OGS_OK) {
|
|
|
|
ogs_error("ogs_gtp_xact_update_tx() failed");
|
|
|
|
return;
|
|
|
|
}
|
2022-07-16 04:27:18 +00:00
|
|
|
|
|
|
|
rv = ogs_gtp_xact_commit(s11_xact);
|
|
|
|
ogs_expect(rv == OGS_OK);
|
|
|
|
}
|
2020-08-13 00:31:22 +00:00
|
|
|
}
|
|
|
|
|
2022-07-16 04:27:18 +00:00
|
|
|
void sgwc_s5c_handle_delete_session_response(
|
2021-06-21 13:36:38 +00:00
|
|
|
sgwc_sess_t *sess, ogs_gtp_xact_t *s5c_xact,
|
2022-04-12 22:07:39 +00:00
|
|
|
ogs_pkbuf_t *gtpbuf, ogs_gtp2_message_t *message)
|
2021-06-21 13:36:38 +00:00
|
|
|
{
|
|
|
|
int rv;
|
2022-12-02 00:10:49 +00:00
|
|
|
uint8_t cause_value = OGS_GTP2_CAUSE_UNDEFINED_VALUE;
|
|
|
|
uint8_t session_cause = OGS_GTP2_CAUSE_UNDEFINED_VALUE;
|
2021-06-21 13:36:38 +00:00
|
|
|
|
|
|
|
sgwc_ue_t *sgwc_ue = NULL;
|
|
|
|
|
|
|
|
ogs_gtp_xact_t *s11_xact = NULL;
|
2022-07-16 04:27:18 +00:00
|
|
|
ogs_gtp2_delete_session_response_t *rsp = NULL;
|
2021-06-21 13:36:38 +00:00
|
|
|
|
|
|
|
ogs_assert(message);
|
2022-07-16 04:27:18 +00:00
|
|
|
rsp = &message->delete_session_response;
|
2021-06-21 13:36:38 +00:00
|
|
|
ogs_assert(rsp);
|
|
|
|
|
2022-07-16 04:27:18 +00:00
|
|
|
ogs_debug("Delete Session Response");
|
2021-06-21 13:36:38 +00:00
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
/********************
|
|
|
|
* 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);
|
|
|
|
|
2022-12-02 00:10:49 +00:00
|
|
|
/************************
|
|
|
|
* Getting Cause Value
|
|
|
|
************************/
|
|
|
|
if (rsp->cause.presence && rsp->cause.data) {
|
|
|
|
ogs_gtp2_cause_t *cause = rsp->cause.data;
|
|
|
|
ogs_assert(cause);
|
|
|
|
session_cause = cause->value;
|
|
|
|
}
|
|
|
|
|
2022-09-25 09:55:04 +00:00
|
|
|
/************************
|
|
|
|
* Check Session Context
|
|
|
|
*
|
|
|
|
* - Session could be deleted before a message is received from SMF.
|
|
|
|
************************/
|
|
|
|
cause_value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED;
|
|
|
|
|
|
|
|
if (!sess) {
|
2022-12-02 00:10:49 +00:00
|
|
|
ogs_error("No Context in TEID [Cause:%d]", session_cause);
|
2022-09-25 09:55:04 +00:00
|
|
|
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) {
|
[GTP/PFCP]] incorrect dst TEI=0/SEID=0 (#3043)
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 TEI=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.
This also happens in PFCP, so to solve this problem, I added teid/seid_presence
to the interface that sends the error message as shown below.
void ogs_gtp2_send_error_message(ogs_gtp_xact_t *xact,
int teid_presence, uint32_t teid, uint8_t type, uint8_t cause_value);
void ogs_pfcp_send_error_message(
ogs_pfcp_xact_t *xact, int seid_presence, uint64_t seid, uint8_t type,
uint8_t cause_value, uint16_t offending_ie_value);
2024-03-23 01:00:08 +00:00
|
|
|
ogs_gtp2_send_error_message(s11_xact,
|
|
|
|
sgwc_ue ? OGS_GTP2_TEID_PRESENCE : OGS_GTP2_TEID_NO_PRESENCE,
|
|
|
|
sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
|
2022-09-25 09:55:04 +00:00
|
|
|
OGS_GTP2_DELETE_SESSION_RESPONSE_TYPE, cause_value);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-10-25 12:22:14 +00:00
|
|
|
/********************
|
|
|
|
* Check Cause Value
|
|
|
|
********************/
|
2022-09-25 09:55:04 +00:00
|
|
|
ogs_assert(cause_value == OGS_GTP2_CAUSE_REQUEST_ACCEPTED);
|
2021-06-21 13:36:38 +00:00
|
|
|
|
2022-12-02 00:10:49 +00:00
|
|
|
if (rsp->cause.presence == 0) {
|
|
|
|
ogs_error("No Cause [VALUE:%d]", session_cause);
|
2022-04-12 22:07:39 +00:00
|
|
|
cause_value = OGS_GTP2_CAUSE_MANDATORY_IE_MISSING;
|
2021-06-21 13:36:38 +00:00
|
|
|
}
|
|
|
|
|
2022-12-02 00:10:49 +00:00
|
|
|
if (session_cause != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
|
|
|
ogs_error("GTP Cause [VALUE:%d] - Ignored", session_cause);
|
2022-04-29 12:28:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/********************
|
|
|
|
* Check ALL Context
|
|
|
|
********************/
|
2022-06-30 00:11:31 +00:00
|
|
|
ogs_assert(sess);
|
2022-07-16 04:27:18 +00:00
|
|
|
ogs_assert(sgwc_ue);
|
2022-04-29 12:28:16 +00:00
|
|
|
|
2022-07-16 04:27:18 +00:00
|
|
|
/* Remove a pgw session */
|
2021-06-21 13:36:38 +00:00
|
|
|
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);
|
|
|
|
|
2022-07-16 04:27:18 +00:00
|
|
|
/*
|
|
|
|
* 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));
|
2021-06-21 13:36:38 +00:00
|
|
|
}
|
|
|
|
|
2020-08-13 00:31:22 +00:00
|
|
|
void sgwc_s5c_handle_create_bearer_request(
|
|
|
|
sgwc_sess_t *sess, ogs_gtp_xact_t *s5c_xact,
|
2022-04-12 22:07:39 +00:00
|
|
|
ogs_pkbuf_t *gtpbuf, ogs_gtp2_message_t *message)
|
2020-08-13 00:31:22 +00:00
|
|
|
{
|
|
|
|
int rv;
|
|
|
|
uint8_t cause_value = 0;
|
|
|
|
|
|
|
|
sgwc_ue_t *sgwc_ue = NULL;
|
|
|
|
sgwc_bearer_t *bearer = NULL;
|
|
|
|
sgwc_tunnel_t *ul_tunnel = NULL;
|
|
|
|
ogs_pfcp_far_t *far = NULL;
|
|
|
|
|
2022-04-12 22:07:39 +00:00
|
|
|
ogs_gtp2_create_bearer_request_t *req = NULL;
|
|
|
|
ogs_gtp2_f_teid_t *pgw_s5u_teid = NULL;
|
2020-08-13 00:31:22 +00:00
|
|
|
|
|
|
|
ogs_assert(message);
|
|
|
|
req = &message->create_bearer_request;
|
|
|
|
ogs_assert(req);
|
|
|
|
|
|
|
|
ogs_debug("Create Bearer Request");
|
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
/********************
|
|
|
|
* Check Transaction
|
|
|
|
********************/
|
|
|
|
ogs_assert(s5c_xact);
|
|
|
|
|
|
|
|
/************************
|
|
|
|
* Check Session Context
|
|
|
|
************************/
|
2022-04-12 22:07:39 +00:00
|
|
|
cause_value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED;
|
2020-08-13 00:31:22 +00:00
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
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) {
|
[GTP/PFCP]] incorrect dst TEI=0/SEID=0 (#3043)
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 TEI=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.
This also happens in PFCP, so to solve this problem, I added teid/seid_presence
to the interface that sends the error message as shown below.
void ogs_gtp2_send_error_message(ogs_gtp_xact_t *xact,
int teid_presence, uint32_t teid, uint8_t type, uint8_t cause_value);
void ogs_pfcp_send_error_message(
ogs_pfcp_xact_t *xact, int seid_presence, uint64_t seid, uint8_t type,
uint8_t cause_value, uint16_t offending_ie_value);
2024-03-23 01:00:08 +00:00
|
|
|
ogs_gtp2_send_error_message(s5c_xact,
|
|
|
|
sess ? OGS_GTP2_TEID_PRESENCE : OGS_GTP2_TEID_NO_PRESENCE,
|
|
|
|
sess ? sess->pgw_s5c_teid : 0,
|
2022-04-29 12:28:16 +00:00
|
|
|
OGS_GTP2_CREATE_BEARER_RESPONSE_TYPE, cause_value);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*****************************************
|
|
|
|
* Check Mandatory/Conditional IE Missing
|
|
|
|
*****************************************/
|
|
|
|
ogs_assert(cause_value == OGS_GTP2_CAUSE_REQUEST_ACCEPTED);
|
|
|
|
|
2020-08-13 00:31:22 +00:00
|
|
|
if (req->linked_eps_bearer_id.presence == 0) {
|
|
|
|
ogs_error("No Linked EBI");
|
2022-04-12 22:07:39 +00:00
|
|
|
cause_value = OGS_GTP2_CAUSE_MANDATORY_IE_MISSING;
|
2020-08-13 00:31:22 +00:00
|
|
|
}
|
|
|
|
if (req->bearer_contexts.presence == 0) {
|
|
|
|
ogs_error("No Bearer");
|
2022-04-12 22:07:39 +00:00
|
|
|
cause_value = OGS_GTP2_CAUSE_MANDATORY_IE_MISSING;
|
2020-08-13 00:31:22 +00:00
|
|
|
}
|
|
|
|
if (req->bearer_contexts.eps_bearer_id.presence == 0) {
|
|
|
|
ogs_error("No EPS Bearer ID");
|
2022-04-12 22:07:39 +00:00
|
|
|
cause_value = OGS_GTP2_CAUSE_MANDATORY_IE_MISSING;
|
2020-08-13 00:31:22 +00:00
|
|
|
}
|
2021-10-26 06:26:10 +00:00
|
|
|
if (req->bearer_contexts.s4_u_sgsn_f_teid.presence == 0) {
|
2020-08-13 00:31:22 +00:00
|
|
|
ogs_error("No GTP TEID");
|
2022-04-29 12:28:16 +00:00
|
|
|
cause_value = OGS_GTP2_CAUSE_CONDITIONAL_IE_MISSING;
|
2020-11-07 22:27:12 +00:00
|
|
|
}
|
|
|
|
|
2022-04-12 22:07:39 +00:00
|
|
|
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
[GTP/PFCP]] incorrect dst TEI=0/SEID=0 (#3043)
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 TEI=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.
This also happens in PFCP, so to solve this problem, I added teid/seid_presence
to the interface that sends the error message as shown below.
void ogs_gtp2_send_error_message(ogs_gtp_xact_t *xact,
int teid_presence, uint32_t teid, uint8_t type, uint8_t cause_value);
void ogs_pfcp_send_error_message(
ogs_pfcp_xact_t *xact, int seid_presence, uint64_t seid, uint8_t type,
uint8_t cause_value, uint16_t offending_ie_value);
2024-03-23 01:00:08 +00:00
|
|
|
ogs_gtp2_send_error_message(s5c_xact,
|
|
|
|
sess ? OGS_GTP2_TEID_PRESENCE : OGS_GTP2_TEID_NO_PRESENCE,
|
|
|
|
sess ? sess->pgw_s5c_teid : 0,
|
2022-04-12 22:07:39 +00:00
|
|
|
OGS_GTP2_CREATE_BEARER_RESPONSE_TYPE, cause_value);
|
2020-08-13 00:31:22 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
/********************
|
|
|
|
* Check ALL Context
|
|
|
|
********************/
|
|
|
|
ogs_assert(sess);
|
2020-08-13 00:31:22 +00:00
|
|
|
ogs_assert(sgwc_ue);
|
|
|
|
|
|
|
|
bearer = sgwc_bearer_add(sess);
|
|
|
|
ogs_assert(bearer);
|
|
|
|
ul_tunnel = sgwc_ul_tunnel_in_bearer(bearer);
|
|
|
|
ogs_assert(ul_tunnel);
|
|
|
|
|
|
|
|
/* Receive Data Plane(UL) : PGW-S5U */
|
2021-10-26 06:26:10 +00:00
|
|
|
pgw_s5u_teid = req->bearer_contexts.s4_u_sgsn_f_teid.data;
|
2020-08-13 00:31:22 +00:00
|
|
|
ogs_assert(pgw_s5u_teid);
|
|
|
|
ul_tunnel->remote_teid = be32toh(pgw_s5u_teid->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);
|
|
|
|
ogs_debug(" SGW_S5U_TEID[%d] PGW_S5U_TEID[%d]",
|
|
|
|
ul_tunnel->local_teid, ul_tunnel->remote_teid);
|
|
|
|
|
2022-04-12 22:07:39 +00:00
|
|
|
rv = ogs_gtp2_f_teid_to_ip(pgw_s5u_teid, &ul_tunnel->remote_ip);
|
2020-08-13 00:31:22 +00:00
|
|
|
if (rv != OGS_OK) {
|
[GTP/PFCP]] incorrect dst TEI=0/SEID=0 (#3043)
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 TEI=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.
This also happens in PFCP, so to solve this problem, I added teid/seid_presence
to the interface that sends the error message as shown below.
void ogs_gtp2_send_error_message(ogs_gtp_xact_t *xact,
int teid_presence, uint32_t teid, uint8_t type, uint8_t cause_value);
void ogs_pfcp_send_error_message(
ogs_pfcp_xact_t *xact, int seid_presence, uint64_t seid, uint8_t type,
uint8_t cause_value, uint16_t offending_ie_value);
2024-03-23 01:00:08 +00:00
|
|
|
ogs_gtp2_send_error_message(s5c_xact,
|
|
|
|
sess ? OGS_GTP2_TEID_PRESENCE : OGS_GTP2_TEID_NO_PRESENCE,
|
|
|
|
sess ? sess->pgw_s5c_teid : 0,
|
2022-04-12 22:07:39 +00:00
|
|
|
OGS_GTP2_CREATE_BEARER_RESPONSE_TYPE,
|
|
|
|
OGS_GTP2_CAUSE_MANDATORY_IE_MISSING);
|
2020-08-13 00:31:22 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
far = ul_tunnel->far;
|
|
|
|
ogs_assert(far);
|
|
|
|
|
2020-12-03 06:16:57 +00:00
|
|
|
far->apply_action = OGS_PFCP_APPLY_ACTION_FORW;
|
|
|
|
|
2021-06-06 13:35:46 +00:00
|
|
|
ogs_assert(OGS_OK ==
|
|
|
|
ogs_pfcp_ip_to_outer_header_creation(&ul_tunnel->remote_ip,
|
|
|
|
&far->outer_header_creation, &far->outer_header_creation_len));
|
2020-08-13 00:31:22 +00:00
|
|
|
far->outer_header_creation.teid = ul_tunnel->remote_teid;
|
|
|
|
|
2021-05-16 03:22:10 +00:00
|
|
|
ogs_assert(OGS_OK ==
|
|
|
|
sgwc_pfcp_send_bearer_modification_request(
|
2020-08-13 00:31:22 +00:00
|
|
|
bearer, s5c_xact, gtpbuf,
|
2021-05-16 03:22:10 +00:00
|
|
|
OGS_PFCP_MODIFY_UL_ONLY|OGS_PFCP_MODIFY_CREATE));
|
2020-08-13 00:31:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void sgwc_s5c_handle_update_bearer_request(
|
|
|
|
sgwc_sess_t *sess, ogs_gtp_xact_t *s5c_xact,
|
2022-04-12 22:07:39 +00:00
|
|
|
ogs_pkbuf_t *gtpbuf, ogs_gtp2_message_t *message)
|
2020-08-13 00:31:22 +00:00
|
|
|
{
|
|
|
|
int rv;
|
|
|
|
uint8_t cause_value = 0;
|
|
|
|
ogs_gtp_xact_t *s11_xact = NULL;
|
2022-04-12 22:07:39 +00:00
|
|
|
ogs_gtp2_update_bearer_request_t *req = NULL;
|
2020-08-13 00:31:22 +00:00
|
|
|
ogs_pkbuf_t *pkbuf = NULL;
|
|
|
|
sgwc_ue_t *sgwc_ue = NULL;
|
2020-11-07 22:27:12 +00:00
|
|
|
sgwc_bearer_t *bearer = NULL;
|
2020-08-13 00:31:22 +00:00
|
|
|
|
|
|
|
ogs_assert(message);
|
|
|
|
req = &message->update_bearer_request;
|
|
|
|
ogs_assert(req);
|
|
|
|
|
|
|
|
ogs_debug("Update Bearer Request");
|
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
/********************
|
|
|
|
* Check Transaction
|
|
|
|
********************/
|
|
|
|
ogs_assert(s5c_xact);
|
2020-08-13 00:31:22 +00:00
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
/************************
|
|
|
|
* Check Session Context
|
|
|
|
************************/
|
|
|
|
cause_value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED;
|
2020-08-13 00:31:22 +00:00
|
|
|
|
2020-11-07 22:27:12 +00:00
|
|
|
if (!sess) {
|
2022-04-29 12:28:16 +00:00
|
|
|
ogs_error("No Context in TEID");
|
2022-04-12 22:07:39 +00:00
|
|
|
cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND;
|
2022-04-29 12:28:16 +00:00
|
|
|
} else {
|
|
|
|
sgwc_ue = sess->sgwc_ue;
|
|
|
|
ogs_assert(sgwc_ue);
|
|
|
|
|
|
|
|
if (req->bearer_contexts.presence == 0) {
|
|
|
|
ogs_error("No Bearer");
|
|
|
|
cause_value = OGS_GTP2_CAUSE_MANDATORY_IE_MISSING;
|
|
|
|
}
|
|
|
|
if (req->bearer_contexts.eps_bearer_id.presence == 0) {
|
|
|
|
ogs_error("No EPS Bearer ID");
|
|
|
|
cause_value = OGS_GTP2_CAUSE_MANDATORY_IE_MISSING;
|
|
|
|
}
|
2020-11-07 22:27:12 +00:00
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
if (cause_value == OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
|
|
|
bearer = sgwc_bearer_find_by_sess_ebi(sess,
|
2020-11-07 22:27:12 +00:00
|
|
|
req->bearer_contexts.eps_bearer_id.u8);
|
2022-04-29 12:28:16 +00:00
|
|
|
if (!bearer) {
|
|
|
|
ogs_error("No Context for EPS Bearer ID[%d]",
|
|
|
|
req->bearer_contexts.eps_bearer_id.u8);
|
|
|
|
cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND;
|
|
|
|
}
|
|
|
|
}
|
2020-11-07 22:27:12 +00:00
|
|
|
}
|
|
|
|
|
2022-04-12 22:07:39 +00:00
|
|
|
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
[GTP/PFCP]] incorrect dst TEI=0/SEID=0 (#3043)
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 TEI=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.
This also happens in PFCP, so to solve this problem, I added teid/seid_presence
to the interface that sends the error message as shown below.
void ogs_gtp2_send_error_message(ogs_gtp_xact_t *xact,
int teid_presence, uint32_t teid, uint8_t type, uint8_t cause_value);
void ogs_pfcp_send_error_message(
ogs_pfcp_xact_t *xact, int seid_presence, uint64_t seid, uint8_t type,
uint8_t cause_value, uint16_t offending_ie_value);
2024-03-23 01:00:08 +00:00
|
|
|
ogs_gtp2_send_error_message(s5c_xact,
|
|
|
|
sess ? OGS_GTP2_TEID_PRESENCE : OGS_GTP2_TEID_NO_PRESENCE,
|
|
|
|
sess ? sess->pgw_s5c_teid : 0,
|
2022-04-12 22:07:39 +00:00
|
|
|
OGS_GTP2_UPDATE_BEARER_RESPONSE_TYPE, cause_value);
|
2020-08-13 00:31:22 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
/********************
|
|
|
|
* Check ALL Context
|
|
|
|
********************/
|
2020-11-07 22:27:12 +00:00
|
|
|
ogs_assert(sess);
|
|
|
|
ogs_assert(bearer);
|
2020-08-13 00:31:22 +00:00
|
|
|
ogs_assert(sgwc_ue);
|
2020-09-22 18:03:45 +00:00
|
|
|
ogs_assert(sgwc_ue->gnode);
|
2020-08-13 00:31:22 +00:00
|
|
|
|
2020-11-07 22:27:12 +00:00
|
|
|
ogs_debug(" EBI[%d]", bearer->ebi);
|
2020-08-13 00:31:22 +00:00
|
|
|
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);
|
|
|
|
|
2022-04-12 22:07:39 +00:00
|
|
|
message->h.type = OGS_GTP2_UPDATE_BEARER_REQUEST_TYPE;
|
[GTP/PFCP]] incorrect dst TEI=0/SEID=0 (#3043)
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 TEI=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.
This also happens in PFCP, so to solve this problem, I added teid/seid_presence
to the interface that sends the error message as shown below.
void ogs_gtp2_send_error_message(ogs_gtp_xact_t *xact,
int teid_presence, uint32_t teid, uint8_t type, uint8_t cause_value);
void ogs_pfcp_send_error_message(
ogs_pfcp_xact_t *xact, int seid_presence, uint64_t seid, uint8_t type,
uint8_t cause_value, uint16_t offending_ie_value);
2024-03-23 01:00:08 +00:00
|
|
|
message->h.teid_presence = OGS_GTP2_TEID_PRESENCE;
|
2020-08-13 00:31:22 +00:00
|
|
|
message->h.teid = sgwc_ue->mme_s11_teid;
|
|
|
|
|
2022-04-12 22:07:39 +00:00
|
|
|
pkbuf = ogs_gtp2_build_msg(message);
|
2023-01-23 15:01:36 +00:00
|
|
|
if (!pkbuf) {
|
|
|
|
ogs_error("ogs_gtp2_build_msg() failed");
|
|
|
|
return;
|
|
|
|
}
|
2020-08-13 00:31:22 +00:00
|
|
|
|
|
|
|
s11_xact = s5c_xact->assoc_xact;
|
|
|
|
if (!s11_xact) {
|
|
|
|
s11_xact = ogs_gtp_xact_local_create(
|
2020-11-07 22:27:12 +00:00
|
|
|
sgwc_ue->gnode, &message->h, pkbuf, bearer_timeout, bearer);
|
2023-01-23 15:01:36 +00:00
|
|
|
if (!s11_xact) {
|
|
|
|
ogs_error("ogs_gtp_xact_local_create() failed");
|
|
|
|
return;
|
|
|
|
}
|
2022-10-25 12:22:14 +00:00
|
|
|
s11_xact->local_teid = sgwc_ue->sgw_s11_teid;
|
2020-08-13 00:31:22 +00:00
|
|
|
|
|
|
|
ogs_gtp_xact_associate(s5c_xact, s11_xact);
|
|
|
|
} else {
|
|
|
|
rv = ogs_gtp_xact_update_tx(s11_xact, &message->h, pkbuf);
|
2023-01-23 15:01:36 +00:00
|
|
|
if (rv != OGS_OK) {
|
|
|
|
ogs_error("ogs_gtp_xact_update_tx() failed");
|
|
|
|
return;
|
|
|
|
}
|
2020-08-13 00:31:22 +00:00
|
|
|
}
|
2022-07-16 04:27:18 +00:00
|
|
|
s11_xact->local_teid = sgwc_ue->sgw_s11_teid;
|
2020-08-13 00:31:22 +00:00
|
|
|
|
|
|
|
rv = ogs_gtp_xact_commit(s11_xact);
|
|
|
|
ogs_expect(rv == OGS_OK);
|
|
|
|
|
|
|
|
ogs_debug("Update Bearer Request : SGW <-- PGW");
|
|
|
|
}
|
|
|
|
|
|
|
|
void sgwc_s5c_handle_delete_bearer_request(
|
|
|
|
sgwc_sess_t *sess, ogs_gtp_xact_t *s5c_xact,
|
2022-04-12 22:07:39 +00:00
|
|
|
ogs_pkbuf_t *gtpbuf, ogs_gtp2_message_t *message)
|
2020-08-13 00:31:22 +00:00
|
|
|
{
|
|
|
|
int rv;
|
|
|
|
uint8_t cause_value = 0;
|
|
|
|
ogs_gtp_xact_t *s11_xact = NULL;
|
2022-04-12 22:07:39 +00:00
|
|
|
ogs_gtp2_delete_bearer_request_t *req = NULL;
|
2020-08-13 00:31:22 +00:00
|
|
|
ogs_pkbuf_t *pkbuf = NULL;
|
|
|
|
sgwc_ue_t *sgwc_ue = NULL;
|
2020-11-07 22:27:12 +00:00
|
|
|
sgwc_bearer_t *bearer = NULL;
|
2020-08-13 00:31:22 +00:00
|
|
|
|
|
|
|
ogs_assert(message);
|
|
|
|
req = &message->delete_bearer_request;
|
|
|
|
ogs_assert(req);
|
|
|
|
|
|
|
|
ogs_debug("Delete Bearer Request");
|
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
/********************
|
|
|
|
* Check Transaction
|
|
|
|
********************/
|
|
|
|
ogs_assert(s5c_xact);
|
2020-08-13 00:31:22 +00:00
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
/************************
|
|
|
|
* Check Session Context
|
|
|
|
************************/
|
|
|
|
cause_value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED;
|
2020-11-07 22:27:12 +00:00
|
|
|
|
2020-08-13 00:31:22 +00:00
|
|
|
if (!sess) {
|
2022-04-29 12:28:16 +00:00
|
|
|
ogs_error("No Context in TEID");
|
2022-04-12 22:07:39 +00:00
|
|
|
cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND;
|
2022-04-29 12:28:16 +00:00
|
|
|
} else {
|
|
|
|
sgwc_ue = sess->sgwc_ue;
|
|
|
|
ogs_assert(sgwc_ue);
|
2020-08-13 00:31:22 +00:00
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
if (req->linked_eps_bearer_id.presence == 0 &&
|
|
|
|
req->eps_bearer_ids.presence == 0) {
|
|
|
|
ogs_error("No Linked EBI or EPS Bearer ID");
|
|
|
|
cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (cause_value == OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
|
|
|
uint8_t ebi;
|
|
|
|
|
|
|
|
if (req->linked_eps_bearer_id.presence) {
|
|
|
|
/*
|
|
|
|
* << Linked EPS Bearer ID >>
|
|
|
|
*
|
|
|
|
* 1. SMF sends Delete Bearer Request(DEFAULT BEARER) to SGW/MME.
|
|
|
|
* 2. MME sends Delete Bearer Response to SGW/SMF.
|
|
|
|
*
|
|
|
|
* OR
|
|
|
|
*
|
|
|
|
* 1. SMF sends Delete Bearer Request(DEFAULT BEARER) to ePDG.
|
|
|
|
* 2. ePDG sends Delete Bearer Response(DEFAULT BEARER) to SMF.
|
|
|
|
*/
|
|
|
|
ebi = req->linked_eps_bearer_id.u8;
|
|
|
|
} else if (req->eps_bearer_ids.presence) {
|
|
|
|
/*
|
|
|
|
* << EPS Bearer IDs >>
|
|
|
|
*
|
|
|
|
* 1. MME sends Bearer Resource Command to SGW/SMF.
|
|
|
|
* 2. SMF sends Delete Bearer Request(DEDICATED BEARER)
|
|
|
|
* to SGW/MME.
|
|
|
|
* 3. MME sends Delete Bearer Response(DEDICATED BEARER)
|
|
|
|
* to SGW/SMF.
|
|
|
|
*
|
|
|
|
* OR
|
|
|
|
*
|
|
|
|
* 1. SMF sends Delete Bearer Request(DEDICATED BEARER)
|
|
|
|
* to SGW/MME.
|
|
|
|
* 2. MME sends Delete Bearer Response(DEDICATED BEARER)
|
|
|
|
* to SGW/SMF.
|
|
|
|
*/
|
|
|
|
ebi = req->eps_bearer_ids.u8;
|
|
|
|
} else
|
|
|
|
ogs_assert_if_reached();
|
|
|
|
|
|
|
|
bearer = sgwc_bearer_find_by_sess_ebi(sess, ebi);
|
|
|
|
if (!bearer) {
|
|
|
|
ogs_error("No Context for EPS Bearer ID[%d]", ebi);
|
|
|
|
cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND;
|
|
|
|
}
|
|
|
|
}
|
2020-08-13 00:31:22 +00:00
|
|
|
}
|
|
|
|
|
2022-04-12 22:07:39 +00:00
|
|
|
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
[GTP/PFCP]] incorrect dst TEI=0/SEID=0 (#3043)
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 TEI=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.
This also happens in PFCP, so to solve this problem, I added teid/seid_presence
to the interface that sends the error message as shown below.
void ogs_gtp2_send_error_message(ogs_gtp_xact_t *xact,
int teid_presence, uint32_t teid, uint8_t type, uint8_t cause_value);
void ogs_pfcp_send_error_message(
ogs_pfcp_xact_t *xact, int seid_presence, uint64_t seid, uint8_t type,
uint8_t cause_value, uint16_t offending_ie_value);
2024-03-23 01:00:08 +00:00
|
|
|
ogs_gtp2_send_error_message(s5c_xact,
|
|
|
|
sess ? OGS_GTP2_TEID_PRESENCE : OGS_GTP2_TEID_NO_PRESENCE,
|
|
|
|
sess ? sess->pgw_s5c_teid : 0,
|
2022-04-12 22:07:39 +00:00
|
|
|
OGS_GTP2_DELETE_BEARER_RESPONSE_TYPE, cause_value);
|
2020-08-13 00:31:22 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
/********************
|
|
|
|
* Check ALL Context
|
|
|
|
********************/
|
2020-11-07 22:27:12 +00:00
|
|
|
ogs_assert(sess);
|
|
|
|
ogs_assert(bearer);
|
2020-08-13 00:31:22 +00:00
|
|
|
ogs_assert(sgwc_ue);
|
2020-09-22 18:03:45 +00:00
|
|
|
ogs_assert(sgwc_ue->gnode);
|
2020-08-13 00:31:22 +00:00
|
|
|
|
2020-11-07 22:27:12 +00:00
|
|
|
ogs_debug(" EBI[%d]", bearer->ebi);
|
2020-08-13 00:31:22 +00:00
|
|
|
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);
|
|
|
|
|
2022-04-12 22:07:39 +00:00
|
|
|
message->h.type = OGS_GTP2_DELETE_BEARER_REQUEST_TYPE;
|
[GTP/PFCP]] incorrect dst TEI=0/SEID=0 (#3043)
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 TEI=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.
This also happens in PFCP, so to solve this problem, I added teid/seid_presence
to the interface that sends the error message as shown below.
void ogs_gtp2_send_error_message(ogs_gtp_xact_t *xact,
int teid_presence, uint32_t teid, uint8_t type, uint8_t cause_value);
void ogs_pfcp_send_error_message(
ogs_pfcp_xact_t *xact, int seid_presence, uint64_t seid, uint8_t type,
uint8_t cause_value, uint16_t offending_ie_value);
2024-03-23 01:00:08 +00:00
|
|
|
message->h.teid_presence = OGS_GTP2_TEID_PRESENCE;
|
2020-08-13 00:31:22 +00:00
|
|
|
message->h.teid = sgwc_ue->mme_s11_teid;
|
|
|
|
|
2022-04-12 22:07:39 +00:00
|
|
|
pkbuf = ogs_gtp2_build_msg(message);
|
2023-01-23 15:01:36 +00:00
|
|
|
if (!pkbuf) {
|
|
|
|
ogs_error("ogs_gtp2_build_msg() failed");
|
|
|
|
return;
|
|
|
|
}
|
2020-08-13 00:31:22 +00:00
|
|
|
|
|
|
|
s11_xact = s5c_xact->assoc_xact;
|
|
|
|
if (!s11_xact) {
|
2021-06-21 13:36:38 +00:00
|
|
|
/*
|
|
|
|
* 1. SMF sends Delete Bearer Request(DEFAULT BEARER) to SGW/MME.
|
|
|
|
* 2. MME sends Delete Bearer Response to SGW/SMF.
|
|
|
|
*
|
|
|
|
* OR
|
|
|
|
*
|
|
|
|
* 1. SMF sends Delete Bearer Request(DEFAULT BEARER) to ePDG.
|
|
|
|
* 2. ePDG sends Delete Bearer Response(DEFAULT BEARER) to SMF.
|
|
|
|
*
|
|
|
|
* OR
|
|
|
|
*
|
|
|
|
* 1. SMF sends Delete Bearer Request(DEDICATED BEARER) to SGW/MME.
|
|
|
|
* 2. MME sends Delete Bearer Response(DEDICATED BEARER) to SGW/SMF.
|
|
|
|
*/
|
2020-08-13 00:31:22 +00:00
|
|
|
s11_xact = ogs_gtp_xact_local_create(
|
2020-11-07 22:27:12 +00:00
|
|
|
sgwc_ue->gnode, &message->h, pkbuf, bearer_timeout, bearer);
|
2023-01-23 15:01:36 +00:00
|
|
|
if (!s11_xact) {
|
|
|
|
ogs_error("ogs_gtp_xact_local_create() failed");
|
|
|
|
return;
|
|
|
|
}
|
2022-10-25 12:22:14 +00:00
|
|
|
s11_xact->local_teid = sgwc_ue->sgw_s11_teid;
|
2020-08-13 00:31:22 +00:00
|
|
|
|
|
|
|
ogs_gtp_xact_associate(s5c_xact, s11_xact);
|
|
|
|
} else {
|
2021-06-21 13:36:38 +00:00
|
|
|
/*
|
|
|
|
* 1. MME sends Bearer Resource Command to SGW/SMF.
|
|
|
|
* 2. SMF sends Delete Bearer Request(DEDICATED BEARER) to SGW/MME.
|
|
|
|
* 3. MME sends Delete Bearer Response(DEDICATED BEARER) to SGW/SMF.
|
|
|
|
*/
|
2020-08-13 00:31:22 +00:00
|
|
|
rv = ogs_gtp_xact_update_tx(s11_xact, &message->h, pkbuf);
|
2023-01-23 15:01:36 +00:00
|
|
|
if (rv != OGS_OK) {
|
|
|
|
ogs_error("ogs_gtp_xact_update_tx() failed");
|
|
|
|
return;
|
|
|
|
}
|
2020-08-13 00:31:22 +00:00
|
|
|
}
|
2022-07-16 04:27:18 +00:00
|
|
|
s11_xact->local_teid = sgwc_ue->sgw_s11_teid;
|
2020-08-13 00:31:22 +00:00
|
|
|
|
|
|
|
rv = ogs_gtp_xact_commit(s11_xact);
|
|
|
|
ogs_expect(rv == OGS_OK);
|
|
|
|
}
|
|
|
|
|
|
|
|
void sgwc_s5c_handle_bearer_resource_failure_indication(
|
|
|
|
sgwc_sess_t *sess, ogs_gtp_xact_t *s5c_xact,
|
2022-04-12 22:07:39 +00:00
|
|
|
ogs_pkbuf_t *gtpbuf, ogs_gtp2_message_t *message)
|
2020-08-13 00:31:22 +00:00
|
|
|
{
|
|
|
|
uint8_t cause_value = 0;
|
|
|
|
ogs_gtp_xact_t *s11_xact = NULL;
|
2022-04-12 22:07:39 +00:00
|
|
|
ogs_gtp2_bearer_resource_failure_indication_t *ind = NULL;
|
2020-08-13 00:31:22 +00:00
|
|
|
|
|
|
|
sgwc_ue_t *sgwc_ue = NULL;
|
|
|
|
|
|
|
|
ogs_assert(message);
|
|
|
|
ind = &message->bearer_resource_failure_indication;
|
|
|
|
ogs_assert(ind);
|
|
|
|
|
|
|
|
ogs_debug("Bearer Resource Failure Indication");
|
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
/********************
|
|
|
|
* Check Transaction
|
|
|
|
********************/
|
|
|
|
ogs_assert(s5c_xact);
|
|
|
|
s11_xact = s5c_xact->assoc_xact;
|
|
|
|
ogs_assert(s11_xact);
|
|
|
|
|
2022-09-25 09:55:04 +00:00
|
|
|
/************************
|
|
|
|
* Check Session Context
|
|
|
|
*
|
|
|
|
* - Session could be deleted before a message is received from SMF.
|
|
|
|
************************/
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
/********************
|
|
|
|
* Check Cause Value
|
|
|
|
********************/
|
2020-08-13 00:31:22 +00:00
|
|
|
if (ind->cause.presence) {
|
2022-04-12 22:07:39 +00:00
|
|
|
ogs_gtp2_cause_t *cause = ind->cause.data;
|
2020-08-13 00:31:22 +00:00
|
|
|
ogs_assert(cause);
|
|
|
|
|
|
|
|
cause_value = cause->value;
|
|
|
|
} else {
|
|
|
|
ogs_error("No Cause");
|
2022-04-12 22:07:39 +00:00
|
|
|
cause_value = OGS_GTP2_CAUSE_MANDATORY_IE_MISSING;
|
2020-08-13 00:31:22 +00:00
|
|
|
}
|
|
|
|
|
[GTP/PFCP]] incorrect dst TEI=0/SEID=0 (#3043)
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 TEI=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.
This also happens in PFCP, so to solve this problem, I added teid/seid_presence
to the interface that sends the error message as shown below.
void ogs_gtp2_send_error_message(ogs_gtp_xact_t *xact,
int teid_presence, uint32_t teid, uint8_t type, uint8_t cause_value);
void ogs_pfcp_send_error_message(
ogs_pfcp_xact_t *xact, int seid_presence, uint64_t seid, uint8_t type,
uint8_t cause_value, uint16_t offending_ie_value);
2024-03-23 01:00:08 +00:00
|
|
|
ogs_gtp2_send_error_message(s11_xact,
|
|
|
|
sgwc_ue ? OGS_GTP2_TEID_PRESENCE : OGS_GTP2_TEID_NO_PRESENCE,
|
|
|
|
sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
|
2022-04-12 22:07:39 +00:00
|
|
|
OGS_GTP2_BEARER_RESOURCE_FAILURE_INDICATION_TYPE, cause_value);
|
2020-08-13 00:31:22 +00:00
|
|
|
}
|