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-2024 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 "s11-handler.h"
|
|
|
|
|
2022-05-12 13:52:36 +00:00
|
|
|
static void gtp_sess_timeout(ogs_gtp_xact_t *xact, void *data)
|
2020-08-13 00:31:22 +00:00
|
|
|
{
|
|
|
|
sgwc_sess_t *sess = data;
|
|
|
|
sgwc_ue_t *sgwc_ue = NULL;
|
|
|
|
uint8_t type = 0;
|
|
|
|
|
|
|
|
ogs_assert(xact);
|
|
|
|
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_DELETE_SESSION_REQUEST_TYPE:
|
2020-11-07 22:27:12 +00:00
|
|
|
ogs_error("[%s] No Delete Session Response", sgwc_ue->imsi_bcd);
|
2021-01-08 20:09:02 +00:00
|
|
|
if (!sgwc_sess_cycle(sess)) {
|
2022-04-29 12:28:16 +00:00
|
|
|
ogs_error("[%s] Session has already been removed",
|
2021-01-08 20:09:02 +00:00
|
|
|
sgwc_ue->imsi_bcd);
|
|
|
|
break;
|
|
|
|
}
|
2021-05-16 03:22:10 +00:00
|
|
|
ogs_assert(OGS_OK ==
|
|
|
|
sgwc_pfcp_send_session_deletion_request(sess, NULL, NULL));
|
2020-11-07 22:27:12 +00:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
ogs_error("GTP Timeout : IMSI[%s] Message-Type[%d]",
|
|
|
|
sgwc_ue->imsi_bcd, type);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-05-12 13:52:36 +00:00
|
|
|
static void gtp_bearer_timeout(ogs_gtp_xact_t *xact, void *data)
|
2020-11-07 22:27:12 +00:00
|
|
|
{
|
|
|
|
sgwc_bearer_t *bearer = data;
|
|
|
|
sgwc_sess_t *sess = NULL;
|
|
|
|
sgwc_ue_t *sgwc_ue = NULL;
|
|
|
|
uint8_t type = 0;
|
|
|
|
|
|
|
|
ogs_assert(xact);
|
|
|
|
ogs_assert(bearer);
|
|
|
|
sess = bearer->sess;
|
|
|
|
ogs_assert(sess);
|
|
|
|
sgwc_ue = sess->sgwc_ue;
|
|
|
|
ogs_assert(sgwc_ue);
|
|
|
|
|
|
|
|
type = xact->seq[0].type;
|
|
|
|
|
2020-08-13 00:31:22 +00:00
|
|
|
ogs_error("GTP Timeout : IMSI[%s] Message-Type[%d]",
|
|
|
|
sgwc_ue->imsi_bcd, type);
|
|
|
|
}
|
|
|
|
|
2022-05-12 13:52:36 +00:00
|
|
|
static void pfcp_sess_timeout(ogs_pfcp_xact_t *xact, void *data)
|
|
|
|
{
|
|
|
|
uint8_t type;
|
|
|
|
|
|
|
|
ogs_assert(xact);
|
|
|
|
type = xact->seq[0].type;
|
|
|
|
|
|
|
|
switch (type) {
|
|
|
|
case OGS_PFCP_SESSION_ESTABLISHMENT_REQUEST_TYPE:
|
|
|
|
ogs_error("No PFCP session establishment response");
|
|
|
|
break;
|
|
|
|
case OGS_PFCP_SESSION_MODIFICATION_REQUEST_TYPE:
|
|
|
|
ogs_error("No PFCP session modification response");
|
|
|
|
break;
|
|
|
|
case OGS_PFCP_SESSION_DELETION_REQUEST_TYPE:
|
|
|
|
ogs_error("No PFCP session deletion response");
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
ogs_error("Not implemented [type:%d]", type);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-10-21 00:00:02 +00:00
|
|
|
/* This code was created in case it will be used later,
|
|
|
|
* and is currently not being used. */
|
2020-08-13 00:31:22 +00:00
|
|
|
static uint8_t pfcp_cause_from_gtp(uint8_t gtp_cause)
|
|
|
|
{
|
|
|
|
switch (gtp_cause) {
|
2022-04-12 22:07:39 +00:00
|
|
|
case OGS_GTP2_CAUSE_REQUEST_ACCEPTED:
|
2020-08-13 00:31:22 +00:00
|
|
|
return OGS_PFCP_CAUSE_REQUEST_ACCEPTED;
|
2022-04-12 22:07:39 +00:00
|
|
|
case OGS_GTP2_CAUSE_REQUEST_REJECTED_REASON_NOT_SPECIFIED:
|
2020-08-13 00:31:22 +00:00
|
|
|
return OGS_PFCP_CAUSE_REQUEST_REJECTED;
|
2022-04-12 22:07:39 +00:00
|
|
|
case OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND:
|
2020-08-13 00:31:22 +00:00
|
|
|
return OGS_PFCP_CAUSE_SESSION_CONTEXT_NOT_FOUND;
|
2022-04-12 22:07:39 +00:00
|
|
|
case OGS_GTP2_CAUSE_MANDATORY_IE_MISSING:
|
2020-08-13 00:31:22 +00:00
|
|
|
return OGS_PFCP_CAUSE_MANDATORY_IE_MISSING;
|
2022-04-12 22:07:39 +00:00
|
|
|
case OGS_GTP2_CAUSE_CONDITIONAL_IE_MISSING:
|
2020-08-13 00:31:22 +00:00
|
|
|
return OGS_PFCP_CAUSE_CONDITIONAL_IE_MISSING;
|
2022-04-12 22:07:39 +00:00
|
|
|
case OGS_GTP2_CAUSE_INVALID_LENGTH:
|
2020-08-13 00:31:22 +00:00
|
|
|
return OGS_PFCP_CAUSE_INVALID_LENGTH;
|
2022-04-12 22:07:39 +00:00
|
|
|
case OGS_GTP2_CAUSE_MANDATORY_IE_INCORRECT:
|
2020-08-13 00:31:22 +00:00
|
|
|
return OGS_PFCP_CAUSE_MANDATORY_IE_INCORRECT;
|
2022-04-12 22:07:39 +00:00
|
|
|
case OGS_GTP2_CAUSE_INVALID_MESSAGE_FORMAT:
|
2020-08-13 00:31:22 +00:00
|
|
|
return OGS_PFCP_CAUSE_INVALID_FORWARDING_POLICY;
|
2022-04-12 22:07:39 +00:00
|
|
|
case OGS_GTP2_CAUSE_REMOTE_PEER_NOT_RESPONDING:
|
2020-08-13 00:31:22 +00:00
|
|
|
return OGS_PFCP_CAUSE_NO_ESTABLISHED_PFCP_ASSOCIATION;
|
2022-04-12 22:07:39 +00:00
|
|
|
case OGS_GTP2_CAUSE_SEMANTIC_ERROR_IN_THE_TFT_OPERATION:
|
2020-08-13 00:31:22 +00:00
|
|
|
return OGS_PFCP_CAUSE_RULE_CREATION_MODIFICATION_FAILURE;
|
2022-04-12 22:07:39 +00:00
|
|
|
case OGS_GTP2_CAUSE_GTP_C_ENTITY_CONGESTION:
|
2020-08-13 00:31:22 +00:00
|
|
|
return OGS_PFCP_CAUSE_PFCP_ENTITY_IN_CONGESTION;
|
2022-04-12 22:07:39 +00:00
|
|
|
case OGS_GTP2_CAUSE_NO_RESOURCES_AVAILABLE:
|
2020-08-13 00:31:22 +00:00
|
|
|
return OGS_PFCP_CAUSE_NO_RESOURCES_AVAILABLE;
|
2022-04-12 22:07:39 +00:00
|
|
|
case OGS_GTP2_CAUSE_SERVICE_NOT_SUPPORTED:
|
2020-08-13 00:31:22 +00:00
|
|
|
return OGS_PFCP_CAUSE_SERVICE_NOT_SUPPORTED;
|
2022-04-12 22:07:39 +00:00
|
|
|
case OGS_GTP2_CAUSE_SYSTEM_FAILURE:
|
2020-08-13 00:31:22 +00:00
|
|
|
return OGS_PFCP_CAUSE_SYSTEM_FAILURE;
|
|
|
|
default:
|
|
|
|
return OGS_PFCP_CAUSE_SYSTEM_FAILURE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return OGS_PFCP_CAUSE_SYSTEM_FAILURE;
|
|
|
|
}
|
|
|
|
|
|
|
|
void sgwc_s11_handle_create_session_request(
|
|
|
|
sgwc_ue_t *sgwc_ue, ogs_gtp_xact_t *s11_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 i;
|
2020-08-13 00:31:22 +00:00
|
|
|
uint8_t cause_value = 0;
|
|
|
|
|
|
|
|
sgwc_sess_t *sess = NULL;
|
|
|
|
sgwc_bearer_t *bearer = NULL;
|
|
|
|
|
2022-04-12 22:07:39 +00:00
|
|
|
ogs_gtp2_create_session_request_t *req = NULL;
|
2020-08-13 00:31:22 +00:00
|
|
|
|
|
|
|
uint16_t decoded;
|
2022-04-12 22:07:39 +00:00
|
|
|
ogs_gtp2_f_teid_t *mme_s11_teid = NULL;
|
2022-04-29 12:28:16 +00:00
|
|
|
ogs_gtp2_f_teid_t *pgw_s5c_teid = NULL;
|
2022-04-12 22:07:39 +00:00
|
|
|
ogs_gtp2_uli_t uli;
|
|
|
|
ogs_gtp2_bearer_qos_t bearer_qos;
|
2021-11-15 06:49:58 +00:00
|
|
|
char apn[OGS_MAX_APN_LEN+1];
|
2020-08-13 00:31:22 +00:00
|
|
|
|
|
|
|
ogs_assert(s11_xact);
|
|
|
|
ogs_assert(gtpbuf);
|
|
|
|
ogs_assert(message);
|
|
|
|
req = &message->create_session_request;
|
|
|
|
ogs_assert(req);
|
|
|
|
|
|
|
|
ogs_debug("Create Session Request");
|
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
/************************
|
|
|
|
* Check SGWC-UE 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 (!sgwc_ue) {
|
|
|
|
ogs_error("No Context");
|
|
|
|
cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND;
|
|
|
|
}
|
|
|
|
|
|
|
|
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-29 12:28:16 +00:00
|
|
|
OGS_GTP2_CREATE_SESSION_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->imsi.presence == 0) {
|
|
|
|
ogs_error("No IMSI");
|
2022-04-14 08:34:55 +00:00
|
|
|
cause_value = OGS_GTP2_CAUSE_CONDITIONAL_IE_MISSING;
|
2020-08-13 00:31:22 +00:00
|
|
|
}
|
2022-05-12 13:52:36 +00:00
|
|
|
if (req->bearer_contexts_to_be_created[0].presence == 0) {
|
2020-08-13 00:31:22 +00:00
|
|
|
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
|
|
|
}
|
2022-05-12 13:52:36 +00:00
|
|
|
if (req->bearer_contexts_to_be_created[0].eps_bearer_id.presence == 0) {
|
2020-08-13 00:31:22 +00:00
|
|
|
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
|
|
|
}
|
2022-05-12 13:52:36 +00:00
|
|
|
if (req->bearer_contexts_to_be_created[0].bearer_level_qos.presence == 0) {
|
2020-10-01 17:27:58 +00:00
|
|
|
ogs_error("No Bearer QoS");
|
2022-04-12 22:07:39 +00:00
|
|
|
cause_value = OGS_GTP2_CAUSE_MANDATORY_IE_MISSING;
|
2020-10-01 17:27:58 +00:00
|
|
|
}
|
2020-08-13 00:31:22 +00:00
|
|
|
if (req->access_point_name.presence == 0) {
|
|
|
|
ogs_error("No APN");
|
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->sender_f_teid_for_control_plane.presence == 0) {
|
|
|
|
ogs_error("No Sender F-TEID");
|
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->pgw_s5_s8_address_for_control_plane_or_pmip.presence == 0) {
|
|
|
|
ogs_error("No PGW IP");
|
2022-04-14 08:34:55 +00:00
|
|
|
cause_value = OGS_GTP2_CAUSE_CONDITIONAL_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) {
|
[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);
|
2020-08-13 00:31:22 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Add Session */
|
2021-10-01 13:41:03 +00:00
|
|
|
ogs_assert(0 < ogs_fqdn_parse(apn,
|
|
|
|
req->access_point_name.data,
|
2022-01-22 00:34:38 +00:00
|
|
|
ogs_min(req->access_point_name.len, OGS_MAX_APN_LEN)));
|
2020-08-13 00:31:22 +00:00
|
|
|
sess = sgwc_sess_find_by_ebi(sgwc_ue,
|
2022-05-12 13:52:36 +00:00
|
|
|
req->bearer_contexts_to_be_created[0].eps_bearer_id.u8);
|
2020-08-13 00:31:22 +00:00
|
|
|
if (sess) {
|
2022-03-22 13:52:10 +00:00
|
|
|
ogs_info("OLD Session Release [IMSI:%s,APN:%s]",
|
2021-03-08 12:25:09 +00:00
|
|
|
sgwc_ue->imsi_bcd, sess->session.name);
|
2020-08-13 00:31:22 +00:00
|
|
|
sgwc_sess_remove(sess);
|
|
|
|
}
|
|
|
|
sess = sgwc_sess_add(sgwc_ue, apn);
|
|
|
|
ogs_assert(sess);
|
|
|
|
|
2023-04-15 09:54:03 +00:00
|
|
|
ogs_info("UE IMSI[%s] APN[%s]", sgwc_ue->imsi_bcd, sess->session.name);
|
|
|
|
|
2020-08-13 00:31:22 +00:00
|
|
|
/* Set User Location Information */
|
2022-04-14 08:34:55 +00:00
|
|
|
if (req->user_location_information.presence == 1) {
|
|
|
|
decoded = ogs_gtp2_parse_uli(&uli, &req->user_location_information);
|
|
|
|
ogs_assert(req->user_location_information.len == decoded);
|
|
|
|
|
|
|
|
sgwc_ue->uli_presence = true;
|
|
|
|
|
|
|
|
ogs_nas_to_plmn_id(&sgwc_ue->e_tai.plmn_id, &uli.tai.nas_plmn_id);
|
|
|
|
sgwc_ue->e_tai.tac = uli.tai.tac;
|
|
|
|
ogs_nas_to_plmn_id(&sgwc_ue->e_cgi.plmn_id, &uli.e_cgi.nas_plmn_id);
|
|
|
|
sgwc_ue->e_cgi.cell_id = uli.e_cgi.cell_id;
|
|
|
|
|
|
|
|
ogs_debug(" TAI[PLMN_ID:%06x,TAC:%d]",
|
|
|
|
ogs_plmn_id_hexdump(&sgwc_ue->e_tai.plmn_id),
|
|
|
|
sgwc_ue->e_tai.tac);
|
|
|
|
ogs_debug(" E_CGI[PLMN_ID:%06x,CELL_ID:0x%x]",
|
|
|
|
ogs_plmn_id_hexdump(&sgwc_ue->e_cgi.plmn_id),
|
|
|
|
sgwc_ue->e_cgi.cell_id);
|
|
|
|
}
|
2021-05-05 13:51:50 +00:00
|
|
|
|
2020-08-13 00:31:22 +00:00
|
|
|
/* Select SGW-U based on UE Location Information */
|
|
|
|
sgwc_sess_select_sgwu(sess);
|
|
|
|
|
|
|
|
/* Check if selected SGW-U is associated with SGW-C */
|
|
|
|
ogs_assert(sess->pfcp_node);
|
|
|
|
if (!OGS_FSM_CHECK(&sess->pfcp_node->sm, sgwc_pfcp_state_associated)) {
|
[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,
|
|
|
|
OGS_GTP2_CAUSE_REMOTE_PEER_NOT_RESPONDING);
|
2020-08-13 00:31:22 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Remove all previous bearer */
|
|
|
|
sgwc_bearer_remove_all(sess);
|
|
|
|
|
2022-05-12 13:52:36 +00:00
|
|
|
/* Setup Bearer */
|
|
|
|
for (i = 0; i < OGS_BEARER_PER_UE; i++) {
|
|
|
|
if (req->bearer_contexts_to_be_created[i].presence == 0)
|
|
|
|
break;
|
|
|
|
if (req->bearer_contexts_to_be_created[i].eps_bearer_id.presence == 0) {
|
|
|
|
ogs_error("No EPS Bearer ID");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (req->bearer_contexts_to_be_created[i].
|
|
|
|
bearer_level_qos.presence == 0) {
|
|
|
|
ogs_error("No Bearer QoS");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
decoded = ogs_gtp2_parse_bearer_qos(&bearer_qos,
|
|
|
|
&req->bearer_contexts_to_be_created[i].bearer_level_qos);
|
|
|
|
ogs_assert(decoded ==
|
|
|
|
req->bearer_contexts_to_be_created[i].bearer_level_qos.len);
|
|
|
|
|
|
|
|
bearer = sgwc_bearer_add(sess);
|
|
|
|
ogs_assert(bearer);
|
|
|
|
|
|
|
|
/* Set Bearer EBI */
|
|
|
|
bearer->ebi = req->bearer_contexts_to_be_created[i].eps_bearer_id.u8;
|
|
|
|
|
|
|
|
if (req->bearer_contexts_to_be_created[i].s1_u_enodeb_f_teid.presence) {
|
|
|
|
|
|
|
|
sgwc_tunnel_t *dl_tunnel = NULL;
|
|
|
|
ogs_pfcp_far_t *far = NULL;
|
|
|
|
ogs_gtp2_f_teid_t *enb_s1u_teid = NULL;
|
|
|
|
|
|
|
|
dl_tunnel = sgwc_dl_tunnel_in_bearer(bearer);
|
|
|
|
ogs_assert(dl_tunnel);
|
|
|
|
|
|
|
|
/* Data Plane(DL) : eNB-S1U */
|
|
|
|
enb_s1u_teid = req->bearer_contexts_to_be_created[i].
|
|
|
|
s1_u_enodeb_f_teid.data;
|
|
|
|
dl_tunnel->remote_teid = be32toh(enb_s1u_teid->teid);
|
|
|
|
|
|
|
|
ogs_assert(OGS_OK ==
|
|
|
|
ogs_gtp2_f_teid_to_ip(enb_s1u_teid, &dl_tunnel->remote_ip));
|
|
|
|
|
|
|
|
far = dl_tunnel->far;
|
|
|
|
ogs_assert(far);
|
|
|
|
|
|
|
|
far->apply_action = OGS_PFCP_APPLY_ACTION_FORW;
|
|
|
|
|
|
|
|
ogs_assert(OGS_OK == ogs_pfcp_ip_to_outer_header_creation(
|
|
|
|
&dl_tunnel->remote_ip, &far->outer_header_creation,
|
|
|
|
&far->outer_header_creation_len));
|
|
|
|
far->outer_header_creation.teid = dl_tunnel->remote_teid;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (req->bearer_contexts_to_be_created[i].s5_s8_u_sgw_f_teid.presence) {
|
2020-08-13 00:31:22 +00:00
|
|
|
|
2022-05-12 13:52:36 +00:00
|
|
|
sgwc_tunnel_t *ul_tunnel = NULL;
|
|
|
|
ogs_pfcp_far_t *far = NULL;
|
|
|
|
ogs_gtp2_f_teid_t *pgw_s5u_teid = NULL;
|
|
|
|
|
|
|
|
ul_tunnel = sgwc_ul_tunnel_in_bearer(bearer);
|
|
|
|
ogs_assert(ul_tunnel);
|
|
|
|
|
|
|
|
/* Data Plane(UL) : PGW-S5U */
|
|
|
|
pgw_s5u_teid = req->bearer_contexts_to_be_created[i].
|
|
|
|
s5_s8_u_sgw_f_teid.data;
|
|
|
|
ul_tunnel->remote_teid = be32toh(pgw_s5u_teid->teid);
|
|
|
|
|
|
|
|
ogs_assert(OGS_OK ==
|
|
|
|
ogs_gtp2_f_teid_to_ip(pgw_s5u_teid, &ul_tunnel->remote_ip));
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Set Session QoS from Default Bearer Level QoS */
|
|
|
|
if (i == 0) {
|
|
|
|
sess->session.qos.index = bearer_qos.qci;
|
|
|
|
sess->session.qos.arp.priority_level = bearer_qos.priority_level;
|
|
|
|
sess->session.qos.arp.pre_emption_capability =
|
|
|
|
bearer_qos.pre_emption_capability;
|
|
|
|
sess->session.qos.arp.pre_emption_vulnerability =
|
|
|
|
bearer_qos.pre_emption_vulnerability;
|
|
|
|
}
|
|
|
|
}
|
2020-08-13 00:31:22 +00:00
|
|
|
|
|
|
|
/* Receive Control Plane(DL) : MME-S11 */
|
|
|
|
mme_s11_teid = req->sender_f_teid_for_control_plane.data;
|
|
|
|
ogs_assert(mme_s11_teid);
|
|
|
|
sgwc_ue->mme_s11_teid = be32toh(mme_s11_teid->teid);
|
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
/* Receive Control Plane(UL) : PGW-S5C */
|
|
|
|
pgw_s5c_teid = req->pgw_s5_s8_address_for_control_plane_or_pmip.data;
|
|
|
|
ogs_assert(pgw_s5c_teid);
|
|
|
|
sess->pgw_s5c_teid = be32toh(pgw_s5c_teid->teid);
|
|
|
|
|
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);
|
|
|
|
|
2021-05-16 03:22:10 +00:00
|
|
|
ogs_assert(OGS_OK ==
|
2023-04-15 09:54:03 +00:00
|
|
|
sgwc_pfcp_send_session_establishment_request(
|
|
|
|
sess, s11_xact, gtpbuf, 0));
|
2020-08-13 00:31:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void sgwc_s11_handle_modify_bearer_request(
|
|
|
|
sgwc_ue_t *sgwc_ue, ogs_gtp_xact_t *s11_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-04-29 12:28:16 +00:00
|
|
|
int i = 0;
|
2020-08-13 00:31:22 +00:00
|
|
|
uint16_t decoded;
|
2022-04-29 12:28:16 +00:00
|
|
|
uint8_t cause_value = 0;
|
|
|
|
|
|
|
|
OGS_LIST(pfcp_xact_list);
|
|
|
|
ogs_pfcp_xact_t *pfcp_xact = NULL;
|
2020-08-13 00:31:22 +00:00
|
|
|
|
2020-10-26 02:43:53 +00:00
|
|
|
sgwc_sess_t *sess = NULL;
|
2020-08-13 00:31:22 +00:00
|
|
|
sgwc_bearer_t *bearer = NULL;
|
|
|
|
sgwc_tunnel_t *dl_tunnel = NULL;
|
|
|
|
ogs_pfcp_far_t *far = NULL;
|
|
|
|
ogs_ip_t remote_ip;
|
|
|
|
ogs_ip_t zero_ip;
|
|
|
|
|
2022-04-12 22:07:39 +00:00
|
|
|
ogs_gtp2_modify_bearer_request_t *req = NULL;
|
|
|
|
|
|
|
|
ogs_gtp2_uli_t uli;
|
|
|
|
ogs_gtp2_f_teid_t *enb_s1u_teid = NULL;
|
2020-08-13 00:31:22 +00:00
|
|
|
|
|
|
|
ogs_assert(s11_xact);
|
|
|
|
ogs_assert(message);
|
|
|
|
req = &message->modify_bearer_request;
|
|
|
|
ogs_assert(req);
|
|
|
|
|
|
|
|
ogs_debug("Modify Bearer Request");
|
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
/************************
|
|
|
|
* Check SGWC-UE 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 (!sgwc_ue) {
|
|
|
|
ogs_error("No Context");
|
2022-04-29 12:28:16 +00:00
|
|
|
cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND;
|
2020-08-13 00:31:22 +00:00
|
|
|
}
|
|
|
|
|
2022-04-29 12:28:16 +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-29 12:28:16 +00:00
|
|
|
OGS_GTP2_MODIFY_BEARER_RESPONSE_TYPE, cause_value);
|
2020-08-13 00:31:22 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
/*****************************************
|
|
|
|
* Check Mandatory/Conditional IE Missing
|
|
|
|
*****************************************/
|
|
|
|
ogs_assert(cause_value == OGS_GTP2_CAUSE_REQUEST_ACCEPTED);
|
2020-10-26 02:43:53 +00:00
|
|
|
|
2022-05-12 13:52:36 +00:00
|
|
|
for (i = 0; i < OGS_BEARER_PER_UE; i++) {
|
2022-04-29 12:28:16 +00:00
|
|
|
ogs_pfcp_xact_t *current_xact = NULL;
|
2020-08-13 00:31:22 +00:00
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
if (req->bearer_contexts_to_be_modified[i].presence == 0) {
|
|
|
|
cause_value = OGS_GTP2_CAUSE_MANDATORY_IE_MISSING;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (req->bearer_contexts_to_be_modified[i].eps_bearer_id.
|
|
|
|
presence == 0) {
|
|
|
|
cause_value = OGS_GTP2_CAUSE_MANDATORY_IE_MISSING;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (req->bearer_contexts_to_be_modified[i].s1_u_enodeb_f_teid.
|
|
|
|
presence == 0) {
|
|
|
|
cause_value = OGS_GTP2_CAUSE_MANDATORY_IE_MISSING;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
bearer = sgwc_bearer_find_by_ue_ebi(sgwc_ue,
|
|
|
|
req->bearer_contexts_to_be_modified[i].eps_bearer_id.u8);
|
|
|
|
if (!bearer) {
|
|
|
|
ogs_error("Unknown EPS Bearer ID[%d]",
|
|
|
|
req->bearer_contexts_to_be_modified[i].eps_bearer_id.u8);
|
|
|
|
cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
sess = bearer->sess;
|
|
|
|
ogs_assert(sess);
|
|
|
|
|
|
|
|
ogs_list_for_each_entry(&pfcp_xact_list, pfcp_xact, tmpnode) {
|
|
|
|
if (sess == pfcp_xact->data) {
|
|
|
|
current_xact = pfcp_xact;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!current_xact) {
|
2022-05-12 13:52:36 +00:00
|
|
|
current_xact = ogs_pfcp_xact_local_create(
|
|
|
|
sess->pfcp_node, pfcp_sess_timeout, sess);
|
2022-04-29 12:28:16 +00:00
|
|
|
ogs_assert(current_xact);
|
|
|
|
|
2022-05-12 13:52:36 +00:00
|
|
|
current_xact->assoc_xact = s11_xact;
|
|
|
|
current_xact->modify_flags = OGS_PFCP_MODIFY_SESSION|
|
|
|
|
OGS_PFCP_MODIFY_DL_ONLY|OGS_PFCP_MODIFY_ACTIVATE;
|
|
|
|
if (gtpbuf) {
|
|
|
|
current_xact->gtpbuf = ogs_pkbuf_copy(gtpbuf);
|
|
|
|
ogs_assert(current_xact->gtpbuf);
|
|
|
|
}
|
2022-06-30 01:35:03 +00:00
|
|
|
current_xact->local_seid = sess->sgwc_sxa_seid;
|
2022-05-12 13:52:36 +00:00
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
ogs_list_add(&pfcp_xact_list, ¤t_xact->tmpnode);
|
|
|
|
}
|
|
|
|
|
|
|
|
dl_tunnel = sgwc_dl_tunnel_in_bearer(bearer);
|
|
|
|
ogs_assert(dl_tunnel);
|
|
|
|
|
|
|
|
/* Data Plane(DL) : eNB-S1U */
|
|
|
|
enb_s1u_teid =
|
|
|
|
req->bearer_contexts_to_be_modified[i].s1_u_enodeb_f_teid.data;
|
|
|
|
dl_tunnel->remote_teid = be32toh(enb_s1u_teid->teid);
|
|
|
|
|
|
|
|
ogs_assert(OGS_OK == ogs_gtp2_f_teid_to_ip(enb_s1u_teid, &remote_ip));
|
|
|
|
|
|
|
|
memset(&zero_ip, 0, sizeof(ogs_ip_t));
|
2020-08-13 00:31:22 +00:00
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
if (memcmp(&dl_tunnel->remote_ip, &zero_ip, sizeof(ogs_ip_t)) != 0 &&
|
|
|
|
memcmp(&dl_tunnel->remote_ip, &remote_ip, sizeof(ogs_ip_t)) != 0) {
|
|
|
|
|
|
|
|
ogs_assert(sess->pfcp_node);
|
|
|
|
|
|
|
|
/* eNB IP is changed during handover */
|
|
|
|
if (sess->pfcp_node->up_function_features.empu) {
|
|
|
|
current_xact->modify_flags |= OGS_PFCP_MODIFY_END_MARKER;
|
|
|
|
} else {
|
|
|
|
ogs_error("SGW-U does not support End Marker");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
memcpy(&dl_tunnel->remote_ip, &remote_ip, sizeof(ogs_ip_t));
|
|
|
|
|
|
|
|
far = dl_tunnel->far;
|
|
|
|
ogs_assert(far);
|
|
|
|
|
|
|
|
far->apply_action = OGS_PFCP_APPLY_ACTION_FORW;
|
|
|
|
|
|
|
|
ogs_assert(OGS_OK ==
|
|
|
|
ogs_pfcp_ip_to_outer_header_creation(&dl_tunnel->remote_ip,
|
|
|
|
&far->outer_header_creation, &far->outer_header_creation_len));
|
|
|
|
far->outer_header_creation.teid = dl_tunnel->remote_teid;
|
|
|
|
|
|
|
|
ogs_list_add(¤t_xact->bearer_to_modify_list,
|
|
|
|
&bearer->to_modify_node);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (i == 0) {
|
|
|
|
ogs_error("No 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-04-29 12:28:16 +00:00
|
|
|
OGS_GTP2_MODIFY_BEARER_RESPONSE_TYPE, cause_value);
|
2020-08-13 00:31:22 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (req->user_location_information.presence == 1) {
|
2022-04-14 08:34:55 +00:00
|
|
|
decoded = ogs_gtp2_parse_uli(&uli, &req->user_location_information);
|
2020-08-13 00:31:22 +00:00
|
|
|
ogs_assert(req->user_location_information.len == decoded);
|
2022-04-14 08:34:55 +00:00
|
|
|
|
|
|
|
sgwc_ue->uli_presence = true;
|
|
|
|
|
2021-05-05 13:51:50 +00:00
|
|
|
ogs_nas_to_plmn_id(&sgwc_ue->e_tai.plmn_id, &uli.tai.nas_plmn_id);
|
2020-08-13 00:31:22 +00:00
|
|
|
sgwc_ue->e_tai.tac = uli.tai.tac;
|
2021-05-05 13:51:50 +00:00
|
|
|
ogs_nas_to_plmn_id(&sgwc_ue->e_cgi.plmn_id, &uli.e_cgi.nas_plmn_id);
|
2020-08-13 00:31:22 +00:00
|
|
|
sgwc_ue->e_cgi.cell_id = uli.e_cgi.cell_id;
|
2022-04-14 08:34:55 +00:00
|
|
|
|
2020-08-13 00:31:22 +00:00
|
|
|
ogs_debug(" TAI[PLMN_ID:%06x,TAC:%d]",
|
|
|
|
ogs_plmn_id_hexdump(&sgwc_ue->e_tai.plmn_id),
|
|
|
|
sgwc_ue->e_tai.tac);
|
2021-12-17 02:37:36 +00:00
|
|
|
ogs_debug(" E_CGI[PLMN_ID:%06x,CELL_ID:0x%x]",
|
2020-08-13 00:31:22 +00:00
|
|
|
ogs_plmn_id_hexdump(&sgwc_ue->e_cgi.plmn_id),
|
|
|
|
sgwc_ue->e_cgi.cell_id);
|
|
|
|
}
|
|
|
|
|
|
|
|
ogs_debug(" MME_S11_TEID[%d] SGW_S11_TEID[%d]",
|
|
|
|
sgwc_ue->mme_s11_teid, sgwc_ue->sgw_s11_teid);
|
|
|
|
ogs_debug(" ENB_S1U_TEID[%d] SGW_S1U_TEID[%d]",
|
|
|
|
dl_tunnel->remote_teid, dl_tunnel->local_teid);
|
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
ogs_list_for_each_entry(&pfcp_xact_list, pfcp_xact, tmpnode)
|
2022-05-12 13:52:36 +00:00
|
|
|
sgwc_pfcp_send_bearer_to_modify_list(pfcp_xact->data, pfcp_xact);
|
2020-08-13 00:31:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void sgwc_s11_handle_delete_session_request(
|
|
|
|
sgwc_ue_t *sgwc_ue, ogs_gtp_xact_t *s11_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_sess_t *sess = NULL;
|
|
|
|
ogs_gtp_xact_t *s5c_xact = NULL;
|
2022-04-12 22:07:39 +00:00
|
|
|
ogs_gtp2_delete_session_request_t *req = NULL;
|
2022-05-12 13:52:36 +00:00
|
|
|
ogs_gtp2_indication_t *indication = NULL;
|
2020-08-13 00:31:22 +00:00
|
|
|
|
|
|
|
ogs_assert(s11_xact);
|
|
|
|
ogs_assert(gtpbuf);
|
|
|
|
ogs_assert(message);
|
|
|
|
req = &message->delete_session_request;
|
|
|
|
ogs_assert(req);
|
|
|
|
|
|
|
|
ogs_debug("Delete Session Request");
|
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
/************************
|
|
|
|
* Check SGWC-UE Context
|
|
|
|
************************/
|
2022-04-12 22:07:39 +00:00
|
|
|
cause_value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED;
|
2020-08-13 00:31:22 +00:00
|
|
|
|
|
|
|
if (!sgwc_ue) {
|
2020-11-07 22:27:12 +00:00
|
|
|
ogs_error("No Context");
|
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 {
|
|
|
|
if (req->linked_eps_bearer_id.presence == 0) {
|
|
|
|
ogs_error("No EPS Bearer ID");
|
|
|
|
cause_value = OGS_GTP2_CAUSE_MANDATORY_IE_MISSING;
|
|
|
|
}
|
2020-08-13 00:31:22 +00:00
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
if (cause_value == OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
|
|
|
sess = sgwc_sess_find_by_ebi(sgwc_ue, req->linked_eps_bearer_id.u8);
|
|
|
|
if (!sess) {
|
|
|
|
ogs_error("Unknown EPS Bearer [IMSI:%s, EBI:%d]",
|
|
|
|
sgwc_ue->imsi_bcd, req->linked_eps_bearer_id.u8);
|
|
|
|
cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND;
|
|
|
|
}
|
|
|
|
}
|
2022-03-04 17:58:53 +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_DELETE_SESSION_RESPONSE_TYPE, cause_value);
|
2020-08-13 00:31:22 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-05-12 13:52:36 +00:00
|
|
|
/*****************************************
|
|
|
|
* Check Mandatory/Conditional IE Missing
|
|
|
|
*****************************************/
|
|
|
|
ogs_assert(cause_value == OGS_GTP2_CAUSE_REQUEST_ACCEPTED);
|
|
|
|
|
|
|
|
if (req->indication_flags.presence &&
|
|
|
|
req->indication_flags.data && req->indication_flags.len) {
|
|
|
|
indication = req->indication_flags.data;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (indication &&
|
|
|
|
indication->operation_indication == 1 &&
|
|
|
|
indication->scope_indication == 1) {
|
|
|
|
ogs_error("Invalid Indication");
|
[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_DELETE_SESSION_RESPONSE_TYPE,
|
|
|
|
OGS_GTP2_CAUSE_INVALID_MESSAGE_FORMAT);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
/********************
|
|
|
|
* Check ALL Context
|
|
|
|
********************/
|
2020-08-13 00:31:22 +00:00
|
|
|
ogs_assert(sgwc_ue);
|
|
|
|
ogs_assert(sess);
|
2020-09-22 18:03:45 +00:00
|
|
|
ogs_assert(sess->gnode);
|
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-05-12 13:52:36 +00:00
|
|
|
if (indication &&
|
|
|
|
indication->operation_indication == 0 &&
|
|
|
|
indication->scope_indication == 1) {
|
2020-08-13 00:31:22 +00:00
|
|
|
|
2022-05-12 13:52:36 +00:00
|
|
|
ogs_assert(OGS_OK ==
|
|
|
|
sgwc_pfcp_send_session_deletion_request(sess, s11_xact, gtpbuf));
|
2020-08-13 00:31:22 +00:00
|
|
|
|
2022-05-12 13:52:36 +00:00
|
|
|
} else {
|
|
|
|
message->h.type = OGS_GTP2_DELETE_SESSION_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;
|
2022-05-12 13:52:36 +00:00
|
|
|
message->h.teid = sess->pgw_s5c_teid;
|
2020-08-13 00:31:22 +00:00
|
|
|
|
2022-05-12 13:52:36 +00:00
|
|
|
gtpbuf = ogs_gtp2_build_msg(message);
|
2023-01-23 15:01:36 +00:00
|
|
|
if (!gtpbuf) {
|
|
|
|
ogs_error("ogs_gtp2_build_msg() failed");
|
|
|
|
return;
|
|
|
|
}
|
2020-08-13 00:31:22 +00:00
|
|
|
|
2022-05-12 13:52:36 +00:00
|
|
|
s5c_xact = ogs_gtp_xact_local_create(
|
|
|
|
sess->gnode, &message->h, gtpbuf, gtp_sess_timeout, sess);
|
2023-01-23 15:01:36 +00:00
|
|
|
if (!s5c_xact) {
|
|
|
|
ogs_error("ogs_gtp_xact_local_create() failed");
|
|
|
|
return;
|
|
|
|
}
|
2022-10-25 12:22:14 +00:00
|
|
|
s5c_xact->local_teid = sess->sgw_s5c_teid;
|
2022-05-12 13:52:36 +00:00
|
|
|
|
|
|
|
ogs_gtp_xact_associate(s11_xact, s5c_xact);
|
|
|
|
|
|
|
|
rv = ogs_gtp_xact_commit(s5c_xact);
|
|
|
|
ogs_expect(rv == OGS_OK);
|
|
|
|
}
|
2020-08-13 00:31:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void sgwc_s11_handle_create_bearer_response(
|
|
|
|
sgwc_ue_t *sgwc_ue, ogs_gtp_xact_t *s11_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-04-29 12:28:16 +00:00
|
|
|
ogs_gtp2_cause_t *cause = NULL;
|
2020-08-13 00:31:22 +00:00
|
|
|
uint8_t cause_value;
|
|
|
|
uint16_t decoded;
|
|
|
|
|
|
|
|
sgwc_sess_t *sess = NULL;
|
|
|
|
sgwc_bearer_t *bearer = NULL;
|
|
|
|
sgwc_tunnel_t *dl_tunnel = NULL, *ul_tunnel = NULL;
|
|
|
|
ogs_pfcp_far_t *far = NULL;
|
|
|
|
|
|
|
|
ogs_gtp_xact_t *s5c_xact = NULL;
|
|
|
|
|
2022-04-12 22:07:39 +00:00
|
|
|
ogs_gtp2_create_bearer_response_t *rsp = NULL;
|
|
|
|
ogs_gtp2_f_teid_t *sgw_s1u_teid = NULL, *enb_s1u_teid = NULL;
|
|
|
|
ogs_gtp2_uli_t uli;
|
2020-08-13 00:31:22 +00:00
|
|
|
|
2022-07-16 04:27:18 +00:00
|
|
|
ogs_assert(sgwc_ue);
|
2020-08-13 00:31:22 +00:00
|
|
|
ogs_assert(message);
|
|
|
|
rsp = &message->create_bearer_response;
|
|
|
|
ogs_assert(rsp);
|
|
|
|
|
|
|
|
ogs_debug("Create Bearer Response");
|
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
/********************
|
|
|
|
* Check Transaction
|
|
|
|
********************/
|
|
|
|
ogs_assert(s11_xact);
|
|
|
|
s5c_xact = s11_xact->assoc_xact;
|
|
|
|
ogs_assert(s5c_xact);
|
|
|
|
|
|
|
|
if (s11_xact->xid & OGS_GTP_CMD_XACT_ID)
|
|
|
|
/* MME received Bearer Resource Modification Request */
|
|
|
|
bearer = s5c_xact->data;
|
|
|
|
else
|
|
|
|
bearer = s11_xact->data;
|
|
|
|
|
|
|
|
ogs_assert(bearer);
|
|
|
|
sess = bearer->sess;
|
|
|
|
ogs_assert(sess);
|
2020-11-07 22:27:12 +00:00
|
|
|
|
|
|
|
rv = ogs_gtp_xact_commit(s11_xact);
|
|
|
|
ogs_expect(rv == OGS_OK);
|
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
/*****************************************
|
|
|
|
* Check Mandatory/Conditional IE Missing
|
|
|
|
*****************************************/
|
2022-07-16 04:27:18 +00:00
|
|
|
cause_value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED;
|
2022-04-29 12:28:16 +00:00
|
|
|
|
2020-11-07 22:27:12 +00:00
|
|
|
if (rsp->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-11-07 22:27:12 +00:00
|
|
|
}
|
|
|
|
if (rsp->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-11-07 22:27:12 +00:00
|
|
|
}
|
|
|
|
if (rsp->bearer_contexts.s1_u_enodeb_f_teid.presence == 0) {
|
|
|
|
ogs_error("No eNB 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
|
|
|
}
|
|
|
|
if (rsp->bearer_contexts.s4_u_sgsn_f_teid.presence == 0) {
|
|
|
|
ogs_error("No SGW 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
|
|
|
}
|
2020-08-13 00:31:22 +00:00
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
if (rsp->cause.presence == 0) {
|
2020-08-13 00:31:22 +00:00
|
|
|
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
|
|
|
}
|
2022-04-29 12:28:16 +00:00
|
|
|
if (rsp->bearer_contexts.cause.presence == 0) {
|
|
|
|
ogs_error("No Bearer Cause");
|
|
|
|
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) {
|
2021-05-16 03:22:10 +00:00
|
|
|
ogs_assert(OGS_OK ==
|
|
|
|
sgwc_pfcp_send_bearer_modification_request(
|
2020-11-07 22:27:12 +00:00
|
|
|
bearer, NULL, NULL,
|
2021-05-16 03:22:10 +00:00
|
|
|
OGS_PFCP_MODIFY_UL_ONLY|OGS_PFCP_MODIFY_REMOVE));
|
[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 Cause Value
|
|
|
|
********************/
|
|
|
|
ogs_assert(cause_value == OGS_GTP2_CAUSE_REQUEST_ACCEPTED);
|
|
|
|
|
|
|
|
cause = rsp->bearer_contexts.cause.data;
|
|
|
|
ogs_assert(cause);
|
|
|
|
cause_value = cause->value;
|
|
|
|
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
2022-09-25 10:16:32 +00:00
|
|
|
ogs_error("GTP Cause [Value:%d]", cause_value);
|
2022-04-29 12:28:16 +00:00
|
|
|
ogs_assert(OGS_OK ==
|
|
|
|
sgwc_pfcp_send_bearer_modification_request(
|
|
|
|
bearer, NULL, NULL,
|
|
|
|
OGS_PFCP_MODIFY_UL_ONLY|OGS_PFCP_MODIFY_REMOVE));
|
[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 ALL Context
|
|
|
|
********************/
|
|
|
|
ogs_assert(sgwc_ue);
|
|
|
|
ogs_assert(sess);
|
|
|
|
ogs_assert(bearer);
|
|
|
|
|
2020-08-13 00:31:22 +00:00
|
|
|
/* Correlate with SGW-S1U-TEID */
|
|
|
|
sgw_s1u_teid = rsp->bearer_contexts.s4_u_sgsn_f_teid.data;
|
|
|
|
ogs_assert(sgw_s1u_teid);
|
|
|
|
|
|
|
|
/* Find the Tunnel by SGW-S1U-TEID */
|
2020-10-26 02:43:53 +00:00
|
|
|
ul_tunnel = sgwc_tunnel_find_by_teid(sgwc_ue, be32toh(sgw_s1u_teid->teid));
|
2020-08-13 00:31:22 +00:00
|
|
|
ogs_assert(ul_tunnel);
|
|
|
|
dl_tunnel = sgwc_dl_tunnel_in_bearer(bearer);
|
|
|
|
ogs_assert(dl_tunnel);
|
|
|
|
|
|
|
|
/* Set EBI */
|
|
|
|
bearer->ebi = rsp->bearer_contexts.eps_bearer_id.u8;
|
|
|
|
|
|
|
|
/* Data Plane(DL) : eNB-S1U */
|
|
|
|
enb_s1u_teid = rsp->bearer_contexts.s1_u_enodeb_f_teid.data;
|
|
|
|
dl_tunnel->remote_teid = be32toh(enb_s1u_teid->teid);
|
|
|
|
|
|
|
|
ogs_debug(" ENB_S1U_TEID[%d] SGW_S1U_TEID[%d]",
|
|
|
|
dl_tunnel->remote_teid, dl_tunnel->local_teid);
|
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
ogs_assert(OGS_OK ==
|
|
|
|
ogs_gtp2_f_teid_to_ip(enb_s1u_teid, &dl_tunnel->remote_ip));
|
2020-08-13 00:31:22 +00:00
|
|
|
|
|
|
|
far = dl_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(&dl_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 = dl_tunnel->remote_teid;
|
|
|
|
|
2022-04-14 08:34:55 +00:00
|
|
|
if (rsp->user_location_information.presence == 1) {
|
|
|
|
decoded = ogs_gtp2_parse_uli(&uli, &rsp->user_location_information);
|
|
|
|
ogs_assert(rsp->user_location_information.len == decoded);
|
|
|
|
|
|
|
|
sgwc_ue->uli_presence = true;
|
|
|
|
|
|
|
|
ogs_nas_to_plmn_id(&sgwc_ue->e_tai.plmn_id, &uli.tai.nas_plmn_id);
|
|
|
|
sgwc_ue->e_tai.tac = uli.tai.tac;
|
|
|
|
ogs_nas_to_plmn_id(&sgwc_ue->e_cgi.plmn_id, &uli.e_cgi.nas_plmn_id);
|
|
|
|
sgwc_ue->e_cgi.cell_id = uli.e_cgi.cell_id;
|
|
|
|
|
|
|
|
ogs_debug(" TAI[PLMN_ID:%06x,TAC:%d]",
|
|
|
|
ogs_plmn_id_hexdump(&sgwc_ue->e_tai.plmn_id),
|
|
|
|
sgwc_ue->e_tai.tac);
|
|
|
|
ogs_debug(" E_CGI[PLMN_ID:%06x,CELL_ID:0x%x]",
|
|
|
|
ogs_plmn_id_hexdump(&sgwc_ue->e_cgi.plmn_id),
|
|
|
|
sgwc_ue->e_cgi.cell_id);
|
|
|
|
}
|
2020-08-13 00:31:22 +00:00
|
|
|
|
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_DL_ONLY|OGS_PFCP_MODIFY_CREATE));
|
2020-08-13 00:31:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void sgwc_s11_handle_update_bearer_response(
|
|
|
|
sgwc_ue_t *sgwc_ue, ogs_gtp_xact_t *s11_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-04-29 12:28:16 +00:00
|
|
|
ogs_gtp2_cause_t *cause = NULL;
|
2020-08-13 00:31:22 +00:00
|
|
|
uint8_t cause_value;
|
|
|
|
ogs_pkbuf_t *pkbuf = NULL;
|
|
|
|
ogs_gtp_xact_t *s5c_xact = NULL;
|
|
|
|
sgwc_sess_t *sess = NULL;
|
|
|
|
sgwc_bearer_t *bearer = NULL;
|
2022-04-12 22:07:39 +00:00
|
|
|
ogs_gtp2_update_bearer_response_t *rsp = NULL;
|
2020-08-13 00:31:22 +00:00
|
|
|
|
2022-07-16 04:27:18 +00:00
|
|
|
ogs_assert(sgwc_ue);
|
2020-08-13 00:31:22 +00:00
|
|
|
ogs_assert(message);
|
2020-11-07 22:27:12 +00:00
|
|
|
rsp = &message->update_bearer_response;
|
|
|
|
ogs_assert(rsp);
|
2020-08-13 00:31:22 +00:00
|
|
|
|
|
|
|
ogs_debug("Update Bearer Response");
|
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
/********************
|
|
|
|
* Check Transaction
|
|
|
|
********************/
|
|
|
|
ogs_assert(s11_xact);
|
|
|
|
s5c_xact = s11_xact->assoc_xact;
|
|
|
|
ogs_assert(s5c_xact);
|
2020-11-07 22:27:12 +00:00
|
|
|
|
|
|
|
if (s11_xact->xid & OGS_GTP_CMD_XACT_ID)
|
|
|
|
/* MME received Bearer Resource Modification Request */
|
|
|
|
bearer = s5c_xact->data;
|
|
|
|
else
|
|
|
|
bearer = s11_xact->data;
|
|
|
|
|
|
|
|
ogs_assert(bearer);
|
|
|
|
sess = bearer->sess;
|
|
|
|
ogs_assert(sess);
|
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
rv = ogs_gtp_xact_commit(s11_xact);
|
|
|
|
ogs_expect(rv == OGS_OK);
|
2020-11-07 22:27:12 +00:00
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
/*****************************************
|
|
|
|
* Check Mandatory/Conditional IE Missing
|
|
|
|
*****************************************/
|
2022-07-16 04:27:18 +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 (rsp->bearer_contexts.presence == 0) {
|
|
|
|
ogs_error("No Bearer");
|
|
|
|
cause_value = OGS_GTP2_CAUSE_MANDATORY_IE_MISSING;
|
|
|
|
}
|
|
|
|
if (rsp->bearer_contexts.eps_bearer_id.presence == 0) {
|
|
|
|
ogs_error("No EPS Bearer ID");
|
|
|
|
cause_value = OGS_GTP2_CAUSE_MANDATORY_IE_MISSING;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (rsp->cause.presence == 0) {
|
2020-08-13 00:31:22 +00:00
|
|
|
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
|
|
|
}
|
2022-04-29 12:28:16 +00:00
|
|
|
if (rsp->bearer_contexts.cause.presence == 0) {
|
|
|
|
ogs_error("No Bearer Cause");
|
|
|
|
cause_value = OGS_GTP2_CAUSE_MANDATORY_IE_MISSING;
|
|
|
|
}
|
|
|
|
|
|
|
|
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_UPDATE_BEARER_RESPONSE_TYPE, cause_value);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/********************
|
|
|
|
* Check Cause Value
|
|
|
|
********************/
|
|
|
|
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
|
|
|
cause = rsp->bearer_contexts.cause.data;
|
|
|
|
ogs_assert(cause);
|
|
|
|
cause_value = cause->value;
|
2022-04-12 22:07:39 +00:00
|
|
|
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
2022-09-25 10:16:32 +00:00
|
|
|
ogs_error("GTP Bearer Cause [VALUE:%d]", cause_value);
|
[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
|
|
|
cause = rsp->cause.data;
|
|
|
|
ogs_assert(cause);
|
|
|
|
cause_value = cause->value;
|
|
|
|
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
2022-09-25 10:16:32 +00:00
|
|
|
ogs_error("GTP Cause [Value:%d]", cause_value);
|
[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_UPDATE_BEARER_RESPONSE_TYPE, cause_value);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/********************
|
|
|
|
* Check ALL Context
|
|
|
|
********************/
|
|
|
|
ogs_assert(sgwc_ue);
|
|
|
|
ogs_assert(sess);
|
|
|
|
|
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_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;
|
2020-08-13 00:31:22 +00:00
|
|
|
message->h.teid = sess->pgw_s5c_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
|
|
|
|
|
|
|
rv = ogs_gtp_xact_update_tx(s5c_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
|
|
|
|
|
|
|
rv = ogs_gtp_xact_commit(s5c_xact);
|
|
|
|
ogs_expect(rv == OGS_OK);
|
|
|
|
}
|
|
|
|
|
|
|
|
void sgwc_s11_handle_delete_bearer_response(
|
|
|
|
sgwc_ue_t *sgwc_ue, ogs_gtp_xact_t *s11_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;
|
|
|
|
ogs_gtp_xact_t *s5c_xact = NULL;
|
|
|
|
|
|
|
|
sgwc_sess_t *sess = NULL;
|
|
|
|
sgwc_bearer_t *bearer = NULL;
|
2022-04-12 22:07:39 +00:00
|
|
|
ogs_gtp2_delete_bearer_response_t *rsp = NULL;
|
2020-08-13 00:31:22 +00:00
|
|
|
|
2022-07-16 04:27:18 +00:00
|
|
|
ogs_assert(sgwc_ue);
|
2020-08-13 00:31:22 +00:00
|
|
|
ogs_assert(message);
|
2020-11-07 22:27:12 +00:00
|
|
|
rsp = &message->delete_bearer_response;
|
|
|
|
ogs_assert(rsp);
|
2020-08-13 00:31:22 +00:00
|
|
|
|
|
|
|
ogs_debug("Delete Bearer Response");
|
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
/********************
|
|
|
|
* Check Transaction
|
|
|
|
********************/
|
|
|
|
ogs_assert(s11_xact);
|
|
|
|
s5c_xact = s11_xact->assoc_xact;
|
|
|
|
ogs_assert(s5c_xact);
|
2020-11-07 22:27:12 +00:00
|
|
|
|
|
|
|
if (s11_xact->xid & OGS_GTP_CMD_XACT_ID)
|
|
|
|
/* MME received Bearer Resource Modification Request */
|
|
|
|
bearer = s5c_xact->data;
|
|
|
|
else
|
|
|
|
bearer = s11_xact->data;
|
|
|
|
|
|
|
|
ogs_assert(bearer);
|
|
|
|
sess = bearer->sess;
|
|
|
|
ogs_assert(sess);
|
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
rv = ogs_gtp_xact_commit(s11_xact);
|
|
|
|
ogs_expect(rv == OGS_OK);
|
2020-11-07 22:27:12 +00:00
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
/************************
|
|
|
|
* Check SGWC-UE Context
|
|
|
|
************************/
|
|
|
|
cause_value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED;
|
2020-08-13 00:31:22 +00:00
|
|
|
|
2021-06-21 13:36:38 +00:00
|
|
|
if (rsp->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.
|
|
|
|
*/
|
|
|
|
if (rsp->cause.presence) {
|
2022-04-12 22:07:39 +00:00
|
|
|
ogs_gtp2_cause_t *cause = rsp->cause.data;
|
2021-06-21 13:36:38 +00:00
|
|
|
ogs_assert(cause);
|
|
|
|
|
|
|
|
cause_value = cause->value;
|
2022-04-12 22:07:39 +00:00
|
|
|
if (cause_value == OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
2021-06-21 13:36:38 +00:00
|
|
|
} else {
|
2022-09-25 10:16:32 +00:00
|
|
|
ogs_error("GTP Cause [Value:%d]", cause_value);
|
2021-06-21 13:36:38 +00:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
ogs_error("No Cause");
|
|
|
|
}
|
2020-08-13 00:31:22 +00:00
|
|
|
|
2021-06-21 13:36:38 +00:00
|
|
|
ogs_assert(OGS_OK ==
|
|
|
|
sgwc_pfcp_send_session_deletion_request(sess, s5c_xact, gtpbuf));
|
|
|
|
} else {
|
|
|
|
/*
|
|
|
|
* << 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.
|
|
|
|
*/
|
|
|
|
if (rsp->bearer_contexts.presence == 0) {
|
|
|
|
ogs_error("No Bearer");
|
|
|
|
}
|
|
|
|
if (rsp->bearer_contexts.eps_bearer_id.presence == 0) {
|
|
|
|
ogs_error("No EPS Bearer ID");
|
|
|
|
}
|
2020-08-13 00:31:22 +00:00
|
|
|
|
2021-06-21 13:36:38 +00:00
|
|
|
if (rsp->cause.presence) {
|
2022-04-12 22:07:39 +00:00
|
|
|
ogs_gtp2_cause_t *cause = rsp->cause.data;
|
2021-06-21 13:36:38 +00:00
|
|
|
ogs_assert(cause);
|
|
|
|
|
|
|
|
cause_value = cause->value;
|
2022-04-12 22:07:39 +00:00
|
|
|
if (cause_value == OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
2021-06-21 13:36:38 +00:00
|
|
|
if (rsp->bearer_contexts.cause.presence) {
|
|
|
|
cause = rsp->bearer_contexts.cause.data;
|
|
|
|
ogs_assert(cause);
|
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
if (cause_value == OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
|
|
|
} else {
|
2022-09-25 10:16:32 +00:00
|
|
|
ogs_error("GTP Cause [Value:%d]", cause_value);
|
2022-04-29 12:28:16 +00:00
|
|
|
}
|
2021-06-21 13:36:38 +00:00
|
|
|
} else {
|
|
|
|
ogs_error("No Cause");
|
|
|
|
}
|
2020-08-13 00:31:22 +00:00
|
|
|
} else {
|
2022-09-25 10:16:32 +00:00
|
|
|
ogs_error("GTP Cause [Value:%d]", cause_value);
|
2020-08-13 00:31:22 +00:00
|
|
|
}
|
2020-11-07 22:27:12 +00:00
|
|
|
} else {
|
2021-06-21 13:36:38 +00:00
|
|
|
ogs_error("No Cause");
|
2020-08-13 00:31:22 +00:00
|
|
|
}
|
|
|
|
|
2022-07-16 04:27:18 +00:00
|
|
|
ogs_debug(" MME_S11_TEID[%d] SGW_S11_TEID[%d]",
|
|
|
|
sgwc_ue->mme_s11_teid, sgwc_ue->sgw_s11_teid);
|
2021-06-21 13:36:38 +00:00
|
|
|
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
|
|
|
|
2021-06-21 13:36:38 +00:00
|
|
|
ogs_assert(OGS_OK ==
|
|
|
|
sgwc_pfcp_send_bearer_modification_request(
|
|
|
|
bearer, s5c_xact, gtpbuf, OGS_PFCP_MODIFY_REMOVE));
|
|
|
|
}
|
2020-08-13 00:31:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void sgwc_s11_handle_release_access_bearers_request(
|
|
|
|
sgwc_ue_t *sgwc_ue, ogs_gtp_xact_t *s11_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
|
|
|
{
|
|
|
|
sgwc_sess_t *sess = NULL;
|
2022-04-29 12:28:16 +00:00
|
|
|
uint8_t cause_value;
|
2020-08-13 00:31:22 +00:00
|
|
|
|
2022-04-12 22:07:39 +00:00
|
|
|
ogs_gtp2_release_access_bearers_request_t *req = NULL;
|
2020-08-13 00:31:22 +00:00
|
|
|
|
|
|
|
ogs_assert(s11_xact);
|
|
|
|
ogs_assert(message);
|
|
|
|
req = &message->release_access_bearers_request;
|
|
|
|
ogs_assert(req);
|
|
|
|
|
|
|
|
ogs_debug("Release Access Bearers Request");
|
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
/************************
|
|
|
|
* Check SGWC-UE Context
|
|
|
|
************************/
|
|
|
|
cause_value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED;
|
2020-08-13 00:31:22 +00:00
|
|
|
|
|
|
|
if (!sgwc_ue) {
|
2022-04-29 12:28:16 +00:00
|
|
|
ogs_error("No Context");
|
|
|
|
cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND;
|
2020-08-13 00:31:22 +00:00
|
|
|
}
|
|
|
|
|
2022-04-29 12:28:16 +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-29 12:28:16 +00:00
|
|
|
OGS_GTP2_RELEASE_ACCESS_BEARERS_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-08-13 00:31:22 +00:00
|
|
|
ogs_assert(sgwc_ue);
|
|
|
|
|
|
|
|
ogs_debug(" MME_S11_TEID[%d] SGW_S11_TEID[%d]",
|
|
|
|
sgwc_ue->mme_s11_teid, sgwc_ue->sgw_s11_teid);
|
|
|
|
|
|
|
|
ogs_list_for_each(&sgwc_ue->sess_list, sess) {
|
|
|
|
|
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(
|
2020-08-13 00:31:22 +00:00
|
|
|
sess, s11_xact, gtpbuf,
|
2021-05-16 03:22:10 +00:00
|
|
|
OGS_PFCP_MODIFY_DL_ONLY|OGS_PFCP_MODIFY_DEACTIVATE));
|
2020-08-13 00:31:22 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void sgwc_s11_handle_downlink_data_notification_ack(
|
|
|
|
sgwc_ue_t *sgwc_ue, ogs_gtp_xact_t *s11_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;
|
|
|
|
|
2020-11-07 22:27:12 +00:00
|
|
|
sgwc_bearer_t *bearer = NULL;
|
2020-08-13 00:31:22 +00:00
|
|
|
sgwc_sess_t *sess = NULL;
|
|
|
|
|
2022-04-12 22:07:39 +00:00
|
|
|
ogs_gtp2_downlink_data_notification_acknowledge_t *ack = NULL;
|
2020-08-13 00:31:22 +00:00
|
|
|
|
|
|
|
ogs_assert(message);
|
|
|
|
ack = &message->downlink_data_notification_acknowledge;
|
|
|
|
ogs_assert(ack);
|
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
/********************
|
|
|
|
* Check Transaction
|
|
|
|
********************/
|
|
|
|
ogs_assert(s11_xact);
|
2020-11-07 22:27:12 +00:00
|
|
|
bearer = s11_xact->data;
|
|
|
|
ogs_assert(bearer);
|
|
|
|
sess = bearer->sess;
|
2020-08-13 00:31:22 +00:00
|
|
|
ogs_assert(sess);
|
2020-11-07 22:27:12 +00:00
|
|
|
|
2020-08-13 00:31:22 +00:00
|
|
|
rv = ogs_gtp_xact_commit(s11_xact);
|
|
|
|
ogs_expect(rv == OGS_OK);
|
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
/************************
|
|
|
|
* Check SGWC-UE Context
|
|
|
|
************************/
|
2020-08-13 00:31:22 +00:00
|
|
|
if (ack->cause.presence) {
|
2022-04-12 22:07:39 +00:00
|
|
|
ogs_gtp2_cause_t *cause = ack->cause.data;
|
2020-08-13 00:31:22 +00:00
|
|
|
ogs_assert(cause);
|
|
|
|
|
|
|
|
cause_value = cause->value;
|
2022-08-01 23:10:52 +00:00
|
|
|
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED &&
|
|
|
|
cause_value != OGS_GTP2_CAUSE_UE_ALREADY_RE_ATTACHED)
|
2022-09-25 10:16:32 +00:00
|
|
|
ogs_warn("GTP Cause [Value:%d] - PFCP_CAUSE[%d]",
|
2020-10-21 00:00:02 +00:00
|
|
|
cause_value, pfcp_cause_from_gtp(cause_value));
|
2020-08-13 00:31:22 +00:00
|
|
|
} else {
|
|
|
|
ogs_error("No Cause");
|
|
|
|
}
|
|
|
|
|
|
|
|
ogs_debug("Downlink Data Notification Acknowledge");
|
2022-04-29 12:28:16 +00:00
|
|
|
if (sgwc_ue) {
|
|
|
|
ogs_debug(" MME_S11_TEID[%d] SGW_S11_TEID[%d]",
|
|
|
|
sgwc_ue->mme_s11_teid, sgwc_ue->sgw_s11_teid);
|
|
|
|
}
|
2020-08-13 00:31:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void sgwc_s11_handle_create_indirect_data_forwarding_tunnel_request(
|
|
|
|
sgwc_ue_t *sgwc_ue, ogs_gtp_xact_t *s11_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, i;
|
|
|
|
|
|
|
|
sgwc_sess_t *sess = NULL;
|
|
|
|
sgwc_bearer_t *bearer = NULL;
|
|
|
|
sgwc_tunnel_t *tunnel = NULL;
|
|
|
|
ogs_pfcp_far_t *far = NULL;
|
2022-04-12 22:07:39 +00:00
|
|
|
|
|
|
|
ogs_gtp2_create_indirect_data_forwarding_tunnel_request_t *req = NULL;
|
|
|
|
ogs_gtp2_f_teid_t *req_teid = NULL;
|
2022-04-29 12:28:16 +00:00
|
|
|
uint8_t cause_value = 0;
|
2020-08-13 00:31:22 +00:00
|
|
|
|
|
|
|
ogs_assert(s11_xact);
|
|
|
|
ogs_assert(message);
|
|
|
|
req = &message->create_indirect_data_forwarding_tunnel_request;
|
|
|
|
ogs_assert(req);
|
|
|
|
|
|
|
|
ogs_debug("Create Indirect Data Forwarding Tunnel Request");
|
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
/************************
|
|
|
|
* Check SGWC-UE Context
|
|
|
|
************************/
|
|
|
|
cause_value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED;
|
2020-08-13 00:31:22 +00:00
|
|
|
|
|
|
|
if (!sgwc_ue) {
|
2022-04-29 12:28:16 +00:00
|
|
|
ogs_error("No Context");
|
|
|
|
cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND;
|
2020-08-13 00:31:22 +00:00
|
|
|
}
|
|
|
|
|
2022-04-29 12:28:16 +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_INDIRECT_DATA_FORWARDING_TUNNEL_RESPONSE_TYPE,
|
2022-04-29 12:28:16 +00:00
|
|
|
cause_value);
|
2020-08-13 00:31:22 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
/********************
|
|
|
|
* Check ALL Context
|
|
|
|
********************/
|
|
|
|
ogs_assert(sgwc_ue);
|
|
|
|
|
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);
|
|
|
|
|
|
|
|
for (i = 0; req->bearer_contexts[i].presence; i++) {
|
|
|
|
if (req->bearer_contexts[i].eps_bearer_id.presence == 0) {
|
|
|
|
ogs_error("No EBI");
|
[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_INDIRECT_DATA_FORWARDING_TUNNEL_RESPONSE_TYPE,
|
|
|
|
OGS_GTP2_CAUSE_MANDATORY_IE_MISSING);
|
2020-08-13 00:31:22 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-04-12 22:07:39 +00:00
|
|
|
bearer = sgwc_bearer_find_by_ue_ebi(sgwc_ue,
|
2020-08-13 00:31:22 +00:00
|
|
|
req->bearer_contexts[i].eps_bearer_id.u8);
|
|
|
|
ogs_assert(bearer);
|
|
|
|
|
|
|
|
if (req->bearer_contexts[i].s1_u_enodeb_f_teid.presence) {
|
|
|
|
req_teid = req->bearer_contexts[i].s1_u_enodeb_f_teid.data;
|
|
|
|
ogs_assert(req_teid);
|
|
|
|
|
|
|
|
tunnel = sgwc_tunnel_add(bearer,
|
2022-04-12 22:07:39 +00:00
|
|
|
OGS_GTP2_F_TEID_SGW_GTP_U_FOR_DL_DATA_FORWARDING);
|
2020-08-13 00:31:22 +00:00
|
|
|
ogs_assert(tunnel);
|
|
|
|
|
|
|
|
tunnel->remote_teid = be32toh(req_teid->teid);
|
|
|
|
|
2022-04-12 22:07:39 +00:00
|
|
|
rv = ogs_gtp2_f_teid_to_ip(req_teid, &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(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_INDIRECT_DATA_FORWARDING_TUNNEL_RESPONSE_TYPE,
|
|
|
|
OGS_GTP2_CAUSE_MANDATORY_IE_MISSING);
|
2020-08-13 00:31:22 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
far = 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(
|
|
|
|
&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 = tunnel->remote_teid;
|
|
|
|
|
|
|
|
ogs_debug(" SGW_DL_TEID[%d] ENB_DL_TEID[%d]",
|
|
|
|
tunnel->local_teid, tunnel->remote_teid);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (req->bearer_contexts[i].s12_rnc_f_teid.presence) {
|
|
|
|
req_teid = req->bearer_contexts[i].s12_rnc_f_teid.data;
|
|
|
|
ogs_assert(req_teid);
|
|
|
|
|
|
|
|
tunnel = sgwc_tunnel_add(bearer,
|
2022-04-12 22:07:39 +00:00
|
|
|
OGS_GTP2_F_TEID_SGW_GTP_U_FOR_UL_DATA_FORWARDING);
|
2020-08-13 00:31:22 +00:00
|
|
|
ogs_assert(tunnel);
|
|
|
|
|
|
|
|
tunnel->remote_teid = be32toh(req_teid->teid);
|
|
|
|
|
2022-04-12 22:07:39 +00:00
|
|
|
rv = ogs_gtp2_f_teid_to_ip(req_teid, &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(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_INDIRECT_DATA_FORWARDING_TUNNEL_RESPONSE_TYPE,
|
|
|
|
OGS_GTP2_CAUSE_MANDATORY_IE_MISSING);
|
2020-08-13 00:31:22 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
far = 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(
|
|
|
|
&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 = tunnel->remote_teid;
|
|
|
|
|
|
|
|
ogs_debug(" SGW_UL_TEID[%d] ENB_UL_TEID[%d]",
|
|
|
|
tunnel->local_teid, tunnel->remote_teid);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ogs_list_for_each(&sgwc_ue->sess_list, sess) {
|
|
|
|
|
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(
|
2020-08-13 00:31:22 +00:00
|
|
|
sess, s11_xact, gtpbuf,
|
2021-05-16 03:22:10 +00:00
|
|
|
OGS_PFCP_MODIFY_INDIRECT|OGS_PFCP_MODIFY_CREATE));
|
2020-08-13 00:31:22 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void sgwc_s11_handle_delete_indirect_data_forwarding_tunnel_request(
|
|
|
|
sgwc_ue_t *sgwc_ue, ogs_gtp_xact_t *s11_xact,
|
2022-04-12 22:07:39 +00:00
|
|
|
ogs_pkbuf_t *gtpbuf, ogs_gtp2_message_t *recv_message)
|
2020-08-13 00:31:22 +00:00
|
|
|
{
|
|
|
|
sgwc_sess_t *sess = NULL;
|
2022-04-29 12:28:16 +00:00
|
|
|
uint8_t cause_value = 0;
|
2020-08-13 00:31:22 +00:00
|
|
|
|
|
|
|
ogs_assert(s11_xact);
|
|
|
|
|
|
|
|
ogs_debug("Delete Indirect Data Forwarding Tunnel Request");
|
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
/************************
|
|
|
|
* Check SGWC-UE Context
|
|
|
|
************************/
|
|
|
|
cause_value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED;
|
2020-08-13 00:31:22 +00:00
|
|
|
|
|
|
|
if (!sgwc_ue) {
|
2022-04-29 12:28:16 +00:00
|
|
|
ogs_error("No Context");
|
|
|
|
cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND;
|
2020-08-13 00:31:22 +00:00
|
|
|
}
|
|
|
|
|
2022-04-29 12:28:16 +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_DELETE_INDIRECT_DATA_FORWARDING_TUNNEL_RESPONSE_TYPE,
|
2022-04-29 12:28:16 +00:00
|
|
|
cause_value);
|
2020-08-13 00:31:22 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
/********************
|
|
|
|
* Check ALL Context
|
|
|
|
********************/
|
2020-08-13 00:31:22 +00:00
|
|
|
ogs_assert(sgwc_ue);
|
|
|
|
|
|
|
|
ogs_debug(" MME_S11_TEID[%d] SGW_S11_TEID[%d]",
|
|
|
|
sgwc_ue->mme_s11_teid, sgwc_ue->sgw_s11_teid);
|
|
|
|
|
|
|
|
ogs_list_for_each(&sgwc_ue->sess_list, sess) {
|
|
|
|
|
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(
|
2020-08-13 00:31:22 +00:00
|
|
|
sess, s11_xact, gtpbuf,
|
2021-05-16 03:22:10 +00:00
|
|
|
OGS_PFCP_MODIFY_INDIRECT| OGS_PFCP_MODIFY_REMOVE));
|
2020-08-13 00:31:22 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void sgwc_s11_handle_bearer_resource_command(
|
|
|
|
sgwc_ue_t *sgwc_ue, ogs_gtp_xact_t *s11_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;
|
|
|
|
ogs_pkbuf_t *pkbuf = NULL;
|
2022-04-12 22:07:39 +00:00
|
|
|
ogs_gtp2_bearer_resource_command_t *cmd = NULL;
|
2020-08-13 00:31:22 +00:00
|
|
|
|
|
|
|
uint8_t cause_value = 0;
|
|
|
|
ogs_gtp_xact_t *s5c_xact = NULL;
|
|
|
|
|
|
|
|
sgwc_sess_t *sess = NULL;
|
2020-11-07 22:27:12 +00:00
|
|
|
sgwc_bearer_t *bearer = NULL;
|
2020-08-13 00:31:22 +00:00
|
|
|
|
|
|
|
ogs_assert(s11_xact);
|
|
|
|
ogs_assert(message);
|
2022-04-29 12:28:16 +00:00
|
|
|
cmd = &message->bearer_resource_command;
|
|
|
|
ogs_assert(cmd);
|
2020-08-13 00:31:22 +00:00
|
|
|
|
|
|
|
ogs_debug("Bearer Resource Command");
|
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
/************************
|
|
|
|
* Check SGWC-UE Context
|
|
|
|
************************/
|
2022-04-12 22:07:39 +00:00
|
|
|
cause_value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED;
|
2020-08-13 00:31:22 +00:00
|
|
|
|
|
|
|
if (!sgwc_ue) {
|
2022-04-29 12:28:16 +00:00
|
|
|
ogs_error("No Context");
|
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 {
|
|
|
|
if (cmd->linked_eps_bearer_id.presence == 0) {
|
|
|
|
ogs_error("No Linked EPS Bearer ID");
|
|
|
|
cause_value = OGS_GTP2_CAUSE_MANDATORY_IE_MISSING;
|
|
|
|
}
|
2020-08-13 00:31:22 +00:00
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
if (cause_value == OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
|
|
|
uint8_t ebi = cmd->linked_eps_bearer_id.u8;
|
2021-01-11 04:36:12 +00:00
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
if (cmd->eps_bearer_id.presence)
|
|
|
|
ebi = cmd->eps_bearer_id.u8;
|
2021-01-11 04:36:12 +00:00
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
bearer = sgwc_bearer_find_by_ue_ebi(sgwc_ue, ebi);
|
|
|
|
if (!bearer) {
|
|
|
|
ogs_error("No Context for Linked EPS Bearer ID[%d:%d]",
|
|
|
|
cmd->linked_eps_bearer_id.u8, ebi);
|
|
|
|
cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND;
|
|
|
|
}
|
|
|
|
}
|
2020-08-13 00:31:22 +00:00
|
|
|
}
|
|
|
|
|
2022-04-29 12:28:16 +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-29 12:28:16 +00:00
|
|
|
OGS_GTP2_BEARER_RESOURCE_FAILURE_INDICATION_TYPE, cause_value);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*****************************************
|
|
|
|
* Check Mandatory/Conditional IE Missing
|
|
|
|
*****************************************/
|
|
|
|
ogs_assert(cause_value == OGS_GTP2_CAUSE_REQUEST_ACCEPTED);
|
|
|
|
|
|
|
|
if (cmd->procedure_transaction_id.presence == 0) {
|
|
|
|
ogs_error("No PTI");
|
|
|
|
cause_value = OGS_GTP2_CAUSE_MANDATORY_IE_MISSING;
|
|
|
|
}
|
|
|
|
if (cmd->traffic_aggregate_description.presence == 0) {
|
|
|
|
ogs_error("No Traffic aggregate description(TAD)");
|
|
|
|
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) {
|
[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
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
/********************
|
|
|
|
* Check ALL Context
|
|
|
|
********************/
|
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);
|
2020-09-22 18:03:45 +00:00
|
|
|
ogs_assert(sess->gnode);
|
2022-04-29 12:28:16 +00:00
|
|
|
ogs_assert(sgwc_ue);
|
|
|
|
|
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_BEARER_RESOURCE_COMMAND_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 = sess->pgw_s5c_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
|
|
|
|
|
|
|
s5c_xact = ogs_gtp_xact_local_create(
|
2022-05-12 13:52:36 +00:00
|
|
|
sess->gnode, &message->h, pkbuf, gtp_bearer_timeout, bearer);
|
2023-01-23 15:01:36 +00:00
|
|
|
if (!s5c_xact) {
|
|
|
|
ogs_error("ogs_gtp_xact_local_create() failed");
|
|
|
|
return;
|
|
|
|
}
|
2022-07-16 04:27:18 +00:00
|
|
|
s5c_xact->local_teid = sess->sgw_s5c_teid;
|
2020-08-13 00:31:22 +00:00
|
|
|
|
|
|
|
ogs_gtp_xact_associate(s11_xact, s5c_xact);
|
|
|
|
|
|
|
|
rv = ogs_gtp_xact_commit(s5c_xact);
|
|
|
|
ogs_expect(rv == OGS_OK);
|
|
|
|
}
|