2019-06-14 09:10:59 +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>
|
2019-06-14 09:10:59 +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/>.
|
|
|
|
*/
|
|
|
|
|
2019-09-13 12:07:47 +00:00
|
|
|
#include "ogs-gtp.h"
|
2017-11-30 11:13:15 +00:00
|
|
|
|
2019-06-11 13:10:47 +00:00
|
|
|
#include "mme-event.h"
|
2023-07-06 16:03:42 +00:00
|
|
|
#include "mme-gn-build.h"
|
2019-06-11 13:10:47 +00:00
|
|
|
#include "mme-gtp-path.h"
|
2019-11-15 14:56:55 +00:00
|
|
|
#include "mme-path.h"
|
|
|
|
#include "s1ap-path.h"
|
2019-06-11 13:10:47 +00:00
|
|
|
#include "mme-s11-build.h"
|
|
|
|
#include "mme-sm.h"
|
2017-03-23 14:05:40 +00:00
|
|
|
|
2023-07-06 16:03:42 +00:00
|
|
|
static void _gtpv1v2_c_recv_cb(short when, ogs_socket_t fd, void *data)
|
2017-03-24 04:19:36 +00:00
|
|
|
{
|
2019-04-27 14:54:30 +00:00
|
|
|
int rv;
|
2019-11-15 14:56:55 +00:00
|
|
|
char buf[OGS_ADDRSTRLEN];
|
|
|
|
|
2019-06-08 15:50:02 +00:00
|
|
|
ssize_t size;
|
2019-04-27 14:54:30 +00:00
|
|
|
mme_event_t *e = NULL;
|
|
|
|
ogs_pkbuf_t *pkbuf = NULL;
|
2019-11-07 14:07:29 +00:00
|
|
|
ogs_sockaddr_t from;
|
2019-11-15 14:56:55 +00:00
|
|
|
mme_sgw_t *sgw = NULL;
|
2023-07-06 16:03:42 +00:00
|
|
|
mme_sgsn_t *sgsn = NULL;
|
|
|
|
uint8_t gtp_ver;
|
2017-03-26 15:48:33 +00:00
|
|
|
|
2019-04-27 14:54:30 +00:00
|
|
|
ogs_assert(fd != INVALID_SOCKET);
|
2017-03-24 04:19:36 +00:00
|
|
|
|
2019-09-13 12:07:47 +00:00
|
|
|
pkbuf = ogs_pkbuf_alloc(NULL, OGS_MAX_SDU_LEN);
|
2020-09-07 03:53:38 +00:00
|
|
|
ogs_assert(pkbuf);
|
2019-09-13 12:07:47 +00:00
|
|
|
ogs_pkbuf_put(pkbuf, OGS_MAX_SDU_LEN);
|
2019-06-08 14:42:12 +00:00
|
|
|
|
2019-11-07 14:07:29 +00:00
|
|
|
size = ogs_recvfrom(fd, pkbuf->data, pkbuf->len, 0, &from);
|
2019-06-08 15:50:02 +00:00
|
|
|
if (size <= 0) {
|
|
|
|
ogs_log_message(OGS_LOG_ERROR, ogs_socket_errno,
|
2019-11-07 14:07:29 +00:00
|
|
|
"ogs_recvfrom() failed");
|
2019-06-08 14:42:12 +00:00
|
|
|
ogs_pkbuf_free(pkbuf);
|
2019-04-27 14:54:30 +00:00
|
|
|
return;
|
2017-03-24 04:19:36 +00:00
|
|
|
}
|
|
|
|
|
2019-06-08 15:50:02 +00:00
|
|
|
ogs_pkbuf_trim(pkbuf, size);
|
|
|
|
|
2023-07-06 16:03:42 +00:00
|
|
|
gtp_ver = ((ogs_gtp2_header_t *)pkbuf->data)->version;
|
|
|
|
switch (gtp_ver) {
|
|
|
|
case 1:
|
|
|
|
sgsn = mme_sgsn_find_by_addr(&from);
|
|
|
|
if (!sgsn) {
|
|
|
|
ogs_error("Unknown SGSN : %s", OGS_ADDR(&from, buf));
|
|
|
|
ogs_pkbuf_free(pkbuf);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
ogs_assert(sgsn);
|
|
|
|
e = mme_event_new(MME_EVENT_GN_MESSAGE);
|
|
|
|
ogs_assert(e);
|
|
|
|
e->gnode = &sgsn->gnode;
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
sgw = mme_sgw_find_by_addr(&from);
|
|
|
|
if (!sgw) {
|
|
|
|
ogs_error("Unknown SGW : %s", OGS_ADDR(&from, buf));
|
|
|
|
ogs_pkbuf_free(pkbuf);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
ogs_assert(sgw);
|
|
|
|
e = mme_event_new(MME_EVENT_S11_MESSAGE);
|
|
|
|
ogs_assert(e);
|
|
|
|
e->gnode = &sgw->gnode;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
ogs_warn("Rx unexpected GTP version %u", gtp_ver);
|
2019-12-08 07:31:15 +00:00
|
|
|
ogs_pkbuf_free(pkbuf);
|
2019-11-15 14:56:55 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2019-04-27 14:54:30 +00:00
|
|
|
e->pkbuf = pkbuf;
|
2019-11-07 14:07:29 +00:00
|
|
|
|
2020-08-26 03:05:01 +00:00
|
|
|
rv = ogs_queue_push(ogs_app()->queue, e);
|
2019-05-06 14:13:26 +00:00
|
|
|
if (rv != OGS_OK) {
|
|
|
|
ogs_error("ogs_queue_push() failed:%d", (int)rv);
|
|
|
|
ogs_pkbuf_free(e->pkbuf);
|
|
|
|
mme_event_free(e);
|
|
|
|
}
|
2017-03-24 04:19:36 +00:00
|
|
|
}
|
|
|
|
|
2019-11-15 14:56:55 +00:00
|
|
|
static void timeout(ogs_gtp_xact_t *xact, void *data)
|
|
|
|
{
|
2023-01-23 01:37:22 +00:00
|
|
|
int r;
|
2019-11-15 14:56:55 +00:00
|
|
|
mme_ue_t *mme_ue = NULL;
|
|
|
|
enb_ue_t *enb_ue = NULL;
|
|
|
|
mme_sess_t *sess = NULL;
|
2020-11-07 22:27:12 +00:00
|
|
|
mme_bearer_t *bearer = NULL;
|
2019-11-15 14:56:55 +00:00
|
|
|
uint8_t type = 0;
|
|
|
|
|
|
|
|
ogs_assert(xact);
|
|
|
|
type = xact->seq[0].type;
|
|
|
|
|
|
|
|
switch (type) {
|
2022-04-29 12:28:16 +00:00
|
|
|
case OGS_GTP2_MODIFY_BEARER_REQUEST_TYPE:
|
2022-04-12 22:07:39 +00:00
|
|
|
case OGS_GTP2_RELEASE_ACCESS_BEARERS_REQUEST_TYPE:
|
|
|
|
case OGS_GTP2_CREATE_INDIRECT_DATA_FORWARDING_TUNNEL_REQUEST_TYPE:
|
|
|
|
case OGS_GTP2_DELETE_INDIRECT_DATA_FORWARDING_TUNNEL_REQUEST_TYPE:
|
2020-11-07 22:27:12 +00:00
|
|
|
mme_ue = data;
|
|
|
|
ogs_assert(mme_ue);
|
|
|
|
break;
|
2022-04-12 22:07:39 +00:00
|
|
|
case OGS_GTP2_CREATE_SESSION_REQUEST_TYPE:
|
|
|
|
case OGS_GTP2_DELETE_SESSION_REQUEST_TYPE:
|
2019-11-15 14:56:55 +00:00
|
|
|
sess = data;
|
|
|
|
ogs_assert(sess);
|
|
|
|
mme_ue = sess->mme_ue;
|
|
|
|
ogs_assert(mme_ue);
|
2020-11-07 22:27:12 +00:00
|
|
|
break;
|
2022-04-12 22:07:39 +00:00
|
|
|
case OGS_GTP2_BEARER_RESOURCE_COMMAND_TYPE:
|
2020-11-07 22:27:12 +00:00
|
|
|
bearer = data;
|
|
|
|
ogs_assert(bearer);
|
|
|
|
sess = bearer->sess;
|
|
|
|
ogs_assert(sess);
|
|
|
|
mme_ue = sess->mme_ue;
|
|
|
|
ogs_assert(mme_ue);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
ogs_fatal("Invalid type [%d]", type);
|
|
|
|
ogs_assert_if_reached();
|
|
|
|
break;
|
|
|
|
}
|
2019-11-15 14:56:55 +00:00
|
|
|
|
2020-11-07 22:27:12 +00:00
|
|
|
ogs_assert(mme_ue);
|
|
|
|
|
|
|
|
switch (type) {
|
2022-04-12 22:07:39 +00:00
|
|
|
case OGS_GTP2_DELETE_SESSION_REQUEST_TYPE:
|
2021-03-09 05:28:07 +00:00
|
|
|
/*
|
|
|
|
* If SESSION_CONTEXT_WILL_DELETED(MME_UE) is not cleared,
|
|
|
|
* The MME cannot send Delete-Session-Request to the SGW-C.
|
|
|
|
* As such, it could be the infinite loop occurred in EMM state machine.
|
|
|
|
*
|
|
|
|
* To prevent this situation,
|
|
|
|
* force clearing SESSION_CONTEXT_WILL_DELETED variable
|
|
|
|
* when MME does not receive Delete-Session-Response message from SGW-C.
|
|
|
|
*/
|
|
|
|
CLEAR_SESSION_CONTEXT(mme_ue);
|
|
|
|
|
2020-10-29 02:59:27 +00:00
|
|
|
enb_ue = enb_ue_cycle(mme_ue->enb_ue);
|
2019-11-15 14:56:55 +00:00
|
|
|
if (enb_ue) {
|
2023-01-23 01:37:22 +00:00
|
|
|
r = s1ap_send_ue_context_release_command(enb_ue,
|
2019-11-15 14:56:55 +00:00
|
|
|
S1AP_Cause_PR_nas, S1AP_CauseNas_normal_release,
|
2023-01-23 01:37:22 +00:00
|
|
|
S1AP_UE_CTX_REL_UE_CONTEXT_REMOVE, 0);
|
|
|
|
ogs_expect(r == OGS_OK);
|
|
|
|
ogs_assert(r != OGS_ERROR);
|
2019-11-15 14:56:55 +00:00
|
|
|
} else {
|
|
|
|
ogs_warn("No S1 Context");
|
|
|
|
}
|
|
|
|
break;
|
2022-04-12 22:07:39 +00:00
|
|
|
case OGS_GTP2_BEARER_RESOURCE_COMMAND_TYPE:
|
2020-11-07 22:27:12 +00:00
|
|
|
/* Nothing to do */
|
|
|
|
break;
|
2019-11-15 14:56:55 +00:00
|
|
|
default:
|
|
|
|
mme_send_delete_session_or_mme_ue_context_release(mme_ue);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
ogs_error("GTP Timeout : IMSI[%s] Message-Type[%d]",
|
|
|
|
mme_ue->imsi_bcd, type);
|
|
|
|
}
|
|
|
|
|
2019-10-27 08:41:14 +00:00
|
|
|
int mme_gtp_open(void)
|
2017-12-07 04:27:17 +00:00
|
|
|
{
|
2019-04-27 14:54:30 +00:00
|
|
|
int rv;
|
2019-05-31 14:22:22 +00:00
|
|
|
ogs_socknode_t *node = NULL;
|
2019-04-27 14:54:30 +00:00
|
|
|
ogs_sock_t *sock = NULL;
|
2018-09-23 04:16:40 +00:00
|
|
|
mme_sgw_t *sgw = NULL;
|
2023-07-06 16:03:42 +00:00
|
|
|
mme_sgsn_t *sgsn = NULL;
|
2017-12-07 04:27:17 +00:00
|
|
|
|
2021-03-15 01:01:55 +00:00
|
|
|
ogs_list_for_each(&ogs_gtp_self()->gtpc_list, node) {
|
2019-09-13 12:07:47 +00:00
|
|
|
sock = ogs_gtp_server(node);
|
2021-04-21 08:24:17 +00:00
|
|
|
if (!sock) return OGS_ERROR;
|
2019-10-31 05:17:43 +00:00
|
|
|
|
2020-08-26 03:05:01 +00:00
|
|
|
node->poll = ogs_pollset_add(ogs_app()->pollset,
|
2023-07-06 16:03:42 +00:00
|
|
|
OGS_POLLIN, sock->fd, _gtpv1v2_c_recv_cb, sock);
|
2021-04-21 08:24:17 +00:00
|
|
|
ogs_assert(node->poll);
|
2019-04-27 14:54:30 +00:00
|
|
|
}
|
2021-03-15 01:01:55 +00:00
|
|
|
ogs_list_for_each(&ogs_gtp_self()->gtpc_list6, node) {
|
2019-09-13 12:07:47 +00:00
|
|
|
sock = ogs_gtp_server(node);
|
2021-04-21 08:24:17 +00:00
|
|
|
if (!sock) return OGS_ERROR;
|
2019-10-31 05:17:43 +00:00
|
|
|
|
2020-08-26 03:05:01 +00:00
|
|
|
node->poll = ogs_pollset_add(ogs_app()->pollset,
|
2023-07-06 16:03:42 +00:00
|
|
|
OGS_POLLIN, sock->fd, _gtpv1v2_c_recv_cb, sock);
|
2021-04-21 08:24:17 +00:00
|
|
|
ogs_assert(node->poll);
|
2019-04-27 14:54:30 +00:00
|
|
|
}
|
2017-12-07 04:27:17 +00:00
|
|
|
|
2021-03-15 01:01:55 +00:00
|
|
|
OGS_SETUP_GTPC_SERVER;
|
2017-12-07 04:27:17 +00:00
|
|
|
|
2023-05-04 10:11:19 +00:00
|
|
|
mme_self()->pgw_addr = mme_pgw_addr_find_by_apn_enb(
|
2019-05-18 15:24:15 +00:00
|
|
|
&mme_self()->pgw_list, AF_INET, NULL);
|
2023-05-04 10:11:19 +00:00
|
|
|
mme_self()->pgw_addr6 = mme_pgw_addr_find_by_apn_enb(
|
2019-05-18 15:24:15 +00:00
|
|
|
&mme_self()->pgw_list, AF_INET6, NULL);
|
2019-04-27 14:54:30 +00:00
|
|
|
ogs_assert(mme_self()->pgw_addr || mme_self()->pgw_addr6);
|
2017-12-03 12:34:39 +00:00
|
|
|
|
2019-06-14 09:10:59 +00:00
|
|
|
ogs_list_for_each(&mme_self()->sgw_list, sgw) {
|
2019-09-13 12:07:47 +00:00
|
|
|
rv = ogs_gtp_connect(
|
2021-03-15 01:01:55 +00:00
|
|
|
ogs_gtp_self()->gtpc_sock, ogs_gtp_self()->gtpc_sock6,
|
2023-07-06 16:03:42 +00:00
|
|
|
&sgw->gnode);
|
|
|
|
ogs_assert(rv == OGS_OK);
|
|
|
|
}
|
|
|
|
|
|
|
|
ogs_list_for_each(&mme_self()->sgsn_list, sgsn) {
|
|
|
|
rv = ogs_gtp_connect(
|
|
|
|
ogs_gtp_self()->gtpc_sock, ogs_gtp_self()->gtpc_sock6,
|
|
|
|
&sgsn->gnode);
|
2019-04-27 14:54:30 +00:00
|
|
|
ogs_assert(rv == OGS_OK);
|
2018-01-09 07:37:05 +00:00
|
|
|
}
|
|
|
|
|
2019-04-27 14:54:30 +00:00
|
|
|
return OGS_OK;
|
2017-12-02 05:17:32 +00:00
|
|
|
}
|
|
|
|
|
2019-10-27 08:41:14 +00:00
|
|
|
void mme_gtp_close(void)
|
2017-03-23 14:05:40 +00:00
|
|
|
{
|
2021-03-15 01:01:55 +00:00
|
|
|
ogs_socknode_remove_all(&ogs_gtp_self()->gtpc_list);
|
|
|
|
ogs_socknode_remove_all(&ogs_gtp_self()->gtpc_list6);
|
2017-03-23 14:05:40 +00:00
|
|
|
}
|
2017-09-07 06:56:31 +00:00
|
|
|
|
2022-04-14 08:34:55 +00:00
|
|
|
int mme_gtp_send_create_session_request(mme_sess_t *sess, int create_action)
|
2017-09-08 07:46:37 +00:00
|
|
|
{
|
2019-04-27 14:54:30 +00:00
|
|
|
int rv;
|
2022-04-12 22:07:39 +00:00
|
|
|
ogs_gtp2_header_t h;
|
2019-04-27 14:54:30 +00:00
|
|
|
ogs_pkbuf_t *pkbuf = NULL;
|
2019-09-13 12:07:47 +00:00
|
|
|
ogs_gtp_xact_t *xact = NULL;
|
2017-09-08 07:46:37 +00:00
|
|
|
mme_ue_t *mme_ue = NULL;
|
2022-04-29 12:28:16 +00:00
|
|
|
sgw_ue_t *sgw_ue = NULL;
|
2017-09-08 07:46:37 +00:00
|
|
|
|
|
|
|
mme_ue = sess->mme_ue;
|
2019-04-27 14:54:30 +00:00
|
|
|
ogs_assert(mme_ue);
|
2022-04-29 12:28:16 +00:00
|
|
|
sgw_ue = sgw_ue_cycle(mme_ue->sgw_ue);
|
|
|
|
ogs_assert(sgw_ue);
|
|
|
|
|
|
|
|
if (create_action == OGS_GTP_CREATE_IN_PATH_SWITCH_REQUEST) {
|
|
|
|
sgw_ue = sgw_ue_cycle(sgw_ue->target_ue);
|
|
|
|
ogs_assert(sgw_ue);
|
|
|
|
}
|
2017-09-08 07:46:37 +00:00
|
|
|
|
2022-04-12 22:07:39 +00:00
|
|
|
memset(&h, 0, sizeof(ogs_gtp2_header_t));
|
|
|
|
h.type = OGS_GTP2_CREATE_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
|
|
|
h.teid_presence = OGS_GTP2_TEID_PRESENCE;
|
2022-04-29 12:28:16 +00:00
|
|
|
h.teid = sgw_ue->sgw_s11_teid;
|
2017-09-08 07:46:37 +00:00
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
pkbuf = mme_s11_build_create_session_request(h.type, sess, create_action);
|
2023-01-23 15:01:36 +00:00
|
|
|
if (!pkbuf) {
|
|
|
|
ogs_error("mme_s11_build_create_session_request() failed");
|
|
|
|
return OGS_ERROR;
|
|
|
|
}
|
2017-09-08 07:46:37 +00:00
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
xact = ogs_gtp_xact_local_create(sgw_ue->gnode, &h, pkbuf, timeout, sess);
|
2023-01-23 15:01:36 +00:00
|
|
|
if (!xact) {
|
|
|
|
ogs_error("ogs_gtp_xact_local_create() failed");
|
|
|
|
return OGS_ERROR;
|
|
|
|
}
|
2022-04-14 08:34:55 +00:00
|
|
|
xact->create_action = create_action;
|
2023-12-20 18:15:47 +00:00
|
|
|
xact->local_teid = mme_ue->gn.mme_gn_teid;
|
2017-09-08 07:46:37 +00:00
|
|
|
|
2019-09-13 12:07:47 +00:00
|
|
|
rv = ogs_gtp_xact_commit(xact);
|
2019-11-29 06:31:22 +00:00
|
|
|
ogs_expect(rv == OGS_OK);
|
2021-05-16 03:22:10 +00:00
|
|
|
|
|
|
|
return rv;
|
2017-09-08 07:46:37 +00:00
|
|
|
}
|
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
int mme_gtp_send_modify_bearer_request(
|
|
|
|
mme_ue_t *mme_ue, int uli_presence, int modify_action)
|
2017-09-07 06:56:31 +00:00
|
|
|
{
|
2019-04-27 14:54:30 +00:00
|
|
|
int rv;
|
2017-09-07 06:56:31 +00:00
|
|
|
|
2019-09-13 12:07:47 +00:00
|
|
|
ogs_gtp_xact_t *xact = NULL;
|
2022-04-29 12:28:16 +00:00
|
|
|
sgw_ue_t *sgw_ue = NULL;
|
2017-09-07 06:56:31 +00:00
|
|
|
|
2022-04-12 22:07:39 +00:00
|
|
|
ogs_gtp2_header_t h;
|
2019-04-27 14:54:30 +00:00
|
|
|
ogs_pkbuf_t *pkbuf = NULL;
|
2017-09-07 06:56:31 +00:00
|
|
|
|
2019-04-27 14:54:30 +00:00
|
|
|
ogs_assert(mme_ue);
|
2022-04-29 12:28:16 +00:00
|
|
|
sgw_ue = mme_ue->sgw_ue;
|
|
|
|
ogs_assert(sgw_ue);
|
2017-09-07 06:56:31 +00:00
|
|
|
|
2022-04-12 22:07:39 +00:00
|
|
|
memset(&h, 0, sizeof(ogs_gtp2_header_t));
|
|
|
|
h.type = OGS_GTP2_MODIFY_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
|
|
|
h.teid_presence = OGS_GTP2_TEID_PRESENCE;
|
2022-04-29 12:28:16 +00:00
|
|
|
h.teid = sgw_ue->sgw_s11_teid;
|
2017-09-07 06:56:31 +00:00
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
pkbuf = mme_s11_build_modify_bearer_request(h.type, mme_ue, uli_presence);
|
2023-01-23 15:01:36 +00:00
|
|
|
if (!pkbuf) {
|
|
|
|
ogs_error("mme_s11_build_modify_bearer_request() failed");
|
|
|
|
return OGS_ERROR;
|
|
|
|
}
|
2017-09-07 06:56:31 +00:00
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
xact = ogs_gtp_xact_local_create(sgw_ue->gnode, &h, pkbuf, timeout, mme_ue);
|
2023-01-23 15:01:36 +00:00
|
|
|
if (!xact) {
|
|
|
|
ogs_error("ogs_gtp_xact_local_create() failed");
|
|
|
|
return OGS_ERROR;
|
|
|
|
}
|
2022-04-29 12:28:16 +00:00
|
|
|
xact->modify_action = modify_action;
|
2023-12-20 18:15:47 +00:00
|
|
|
xact->local_teid = mme_ue->gn.mme_gn_teid;
|
2017-09-07 06:56:31 +00:00
|
|
|
|
2019-09-13 12:07:47 +00:00
|
|
|
rv = ogs_gtp_xact_commit(xact);
|
2019-11-29 06:31:22 +00:00
|
|
|
ogs_expect(rv == OGS_OK);
|
2021-05-16 03:22:10 +00:00
|
|
|
|
|
|
|
return rv;
|
2017-09-07 06:56:31 +00:00
|
|
|
}
|
|
|
|
|
2022-05-12 13:52:36 +00:00
|
|
|
int mme_gtp_send_delete_session_request(
|
|
|
|
sgw_ue_t *sgw_ue, mme_sess_t *sess, int action)
|
2017-09-07 13:22:42 +00:00
|
|
|
{
|
2019-04-27 14:54:30 +00:00
|
|
|
int rv;
|
|
|
|
ogs_pkbuf_t *s11buf = NULL;
|
2022-04-12 22:07:39 +00:00
|
|
|
ogs_gtp2_header_t h;
|
2019-09-13 12:07:47 +00:00
|
|
|
ogs_gtp_xact_t *xact = NULL;
|
2017-09-07 13:22:42 +00:00
|
|
|
mme_ue_t *mme_ue = NULL;
|
|
|
|
|
2020-10-22 21:53:13 +00:00
|
|
|
ogs_assert(action);
|
2019-04-27 14:54:30 +00:00
|
|
|
ogs_assert(sess);
|
2017-09-07 13:22:42 +00:00
|
|
|
mme_ue = sess->mme_ue;
|
2019-04-27 14:54:30 +00:00
|
|
|
ogs_assert(mme_ue);
|
2022-04-29 12:28:16 +00:00
|
|
|
ogs_assert(sgw_ue);
|
2017-09-07 13:22:42 +00:00
|
|
|
|
2022-04-12 22:07:39 +00:00
|
|
|
memset(&h, 0, sizeof(ogs_gtp2_header_t));
|
|
|
|
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
|
|
|
h.teid_presence = OGS_GTP2_TEID_PRESENCE;
|
2022-04-29 12:28:16 +00:00
|
|
|
h.teid = sgw_ue->sgw_s11_teid;
|
2017-09-07 13:22:42 +00:00
|
|
|
|
2022-05-12 13:52:36 +00:00
|
|
|
s11buf = mme_s11_build_delete_session_request(h.type, sess, action);
|
2023-01-23 15:01:36 +00:00
|
|
|
if (!s11buf) {
|
|
|
|
ogs_error("mme_s11_build_delete_session_request() failed");
|
|
|
|
return OGS_ERROR;
|
|
|
|
}
|
2017-09-07 13:22:42 +00:00
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
xact = ogs_gtp_xact_local_create(sgw_ue->gnode, &h, s11buf, timeout, sess);
|
2023-01-23 15:01:36 +00:00
|
|
|
if (!xact) {
|
|
|
|
ogs_error("ogs_gtp_xact_local_create() failed");
|
|
|
|
return OGS_ERROR;
|
|
|
|
}
|
2020-10-22 21:53:13 +00:00
|
|
|
xact->delete_action = action;
|
2023-12-20 18:15:47 +00:00
|
|
|
xact->local_teid = mme_ue->gn.mme_gn_teid;
|
2024-02-27 12:16:50 +00:00
|
|
|
ogs_debug("delete_session_request - xact:%p, sess:%p", xact, sess);
|
2017-09-07 13:22:42 +00:00
|
|
|
|
2019-09-13 12:07:47 +00:00
|
|
|
rv = ogs_gtp_xact_commit(xact);
|
2019-11-29 06:31:22 +00:00
|
|
|
ogs_expect(rv == OGS_OK);
|
2021-05-16 03:22:10 +00:00
|
|
|
|
|
|
|
return rv;
|
2017-09-07 13:22:42 +00:00
|
|
|
}
|
|
|
|
|
2020-10-22 21:53:13 +00:00
|
|
|
void mme_gtp_send_delete_all_sessions(mme_ue_t *mme_ue, int action)
|
2017-09-07 14:51:06 +00:00
|
|
|
{
|
|
|
|
mme_sess_t *sess = NULL, *next_sess = NULL;
|
2022-04-29 12:28:16 +00:00
|
|
|
sgw_ue_t *sgw_ue = NULL;
|
2017-09-07 14:51:06 +00:00
|
|
|
|
2019-04-27 14:54:30 +00:00
|
|
|
ogs_assert(mme_ue);
|
2022-04-29 12:28:16 +00:00
|
|
|
sgw_ue = mme_ue->sgw_ue;
|
|
|
|
ogs_assert(sgw_ue);
|
2020-10-22 21:53:13 +00:00
|
|
|
ogs_assert(action);
|
2019-06-14 09:10:59 +00:00
|
|
|
|
2024-02-27 12:16:50 +00:00
|
|
|
MME_UE_CHECK(OGS_LOG_DEBUG, mme_ue);
|
2023-02-20 11:49:48 +00:00
|
|
|
ogs_list_for_each_safe(&mme_ue->sess_list, next_sess, sess) {
|
2019-06-14 09:10:59 +00:00
|
|
|
if (MME_HAVE_SGW_S1U_PATH(sess)) {
|
2023-02-20 11:49:48 +00:00
|
|
|
mme_gtp_send_delete_session_request(sgw_ue, sess, action);
|
2019-06-14 09:10:59 +00:00
|
|
|
} else {
|
2023-05-05 09:06:25 +00:00
|
|
|
MME_SESS_CLEAR(sess);
|
2017-09-07 14:51:06 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-05-16 03:22:10 +00:00
|
|
|
int mme_gtp_send_create_bearer_response(
|
2020-11-07 22:27:12 +00:00
|
|
|
mme_bearer_t *bearer, uint8_t cause_value)
|
2017-09-07 06:56:31 +00:00
|
|
|
{
|
2019-04-27 14:54:30 +00:00
|
|
|
int rv;
|
2017-09-07 06:56:31 +00:00
|
|
|
|
2019-09-13 12:07:47 +00:00
|
|
|
ogs_gtp_xact_t *xact = NULL;
|
2017-09-07 06:56:31 +00:00
|
|
|
mme_ue_t *mme_ue = NULL;
|
2022-04-29 12:28:16 +00:00
|
|
|
sgw_ue_t *sgw_ue = NULL;
|
2017-09-07 06:56:31 +00:00
|
|
|
|
2022-04-12 22:07:39 +00:00
|
|
|
ogs_gtp2_header_t h;
|
2019-04-27 14:54:30 +00:00
|
|
|
ogs_pkbuf_t *pkbuf = NULL;
|
2017-09-07 06:56:31 +00:00
|
|
|
|
2019-04-27 14:54:30 +00:00
|
|
|
ogs_assert(bearer);
|
2017-09-07 06:56:31 +00:00
|
|
|
mme_ue = bearer->mme_ue;
|
2019-04-27 14:54:30 +00:00
|
|
|
ogs_assert(mme_ue);
|
2022-04-29 12:28:16 +00:00
|
|
|
sgw_ue = mme_ue->sgw_ue;
|
|
|
|
ogs_assert(sgw_ue);
|
2021-07-15 12:20:56 +00:00
|
|
|
xact = ogs_gtp_xact_cycle(bearer->create.xact);
|
2022-08-19 08:23:10 +00:00
|
|
|
if (!xact) {
|
|
|
|
ogs_warn("GTP transaction(CREATE) has already been removed");
|
|
|
|
return OGS_OK;
|
|
|
|
}
|
2017-09-07 06:56:31 +00:00
|
|
|
|
2022-04-12 22:07:39 +00:00
|
|
|
memset(&h, 0, sizeof(ogs_gtp2_header_t));
|
|
|
|
h.type = OGS_GTP2_CREATE_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
|
|
|
h.teid_presence = OGS_GTP2_TEID_PRESENCE;
|
2022-04-29 12:28:16 +00:00
|
|
|
h.teid = sgw_ue->sgw_s11_teid;
|
2017-09-07 06:56:31 +00:00
|
|
|
|
2020-11-07 22:27:12 +00:00
|
|
|
pkbuf = mme_s11_build_create_bearer_response(h.type, bearer, cause_value);
|
2023-01-23 15:01:36 +00:00
|
|
|
if (!pkbuf) {
|
|
|
|
ogs_error("mme_s11_build_create_bearer_response() failed");
|
|
|
|
return OGS_ERROR;
|
|
|
|
}
|
2017-09-07 06:56:31 +00:00
|
|
|
|
2019-09-13 12:07:47 +00:00
|
|
|
rv = ogs_gtp_xact_update_tx(xact, &h, pkbuf);
|
2023-01-23 15:01:36 +00:00
|
|
|
if (rv != OGS_OK) {
|
|
|
|
ogs_error("ogs_gtp_xact_update_tx() failed");
|
|
|
|
return OGS_ERROR;
|
|
|
|
}
|
2017-09-07 06:56:31 +00:00
|
|
|
|
2019-09-13 12:07:47 +00:00
|
|
|
rv = ogs_gtp_xact_commit(xact);
|
2019-11-29 06:31:22 +00:00
|
|
|
ogs_expect(rv == OGS_OK);
|
2021-05-16 03:22:10 +00:00
|
|
|
|
|
|
|
return rv;
|
2017-09-07 06:56:31 +00:00
|
|
|
}
|
2017-09-07 10:44:08 +00:00
|
|
|
|
2021-05-16 03:22:10 +00:00
|
|
|
int mme_gtp_send_update_bearer_response(
|
2020-11-07 22:27:12 +00:00
|
|
|
mme_bearer_t *bearer, uint8_t cause_value)
|
2018-01-17 07:01:11 +00:00
|
|
|
{
|
2019-04-27 14:54:30 +00:00
|
|
|
int rv;
|
2018-01-17 07:01:11 +00:00
|
|
|
|
2019-09-13 12:07:47 +00:00
|
|
|
ogs_gtp_xact_t *xact = NULL;
|
2018-01-17 07:01:11 +00:00
|
|
|
mme_ue_t *mme_ue = NULL;
|
2022-04-29 12:28:16 +00:00
|
|
|
sgw_ue_t *sgw_ue = NULL;
|
2018-01-17 07:01:11 +00:00
|
|
|
|
2022-04-12 22:07:39 +00:00
|
|
|
ogs_gtp2_header_t h;
|
2019-04-27 14:54:30 +00:00
|
|
|
ogs_pkbuf_t *pkbuf = NULL;
|
2018-01-17 07:01:11 +00:00
|
|
|
|
2019-04-27 14:54:30 +00:00
|
|
|
ogs_assert(bearer);
|
2018-01-17 07:01:11 +00:00
|
|
|
mme_ue = bearer->mme_ue;
|
2019-04-27 14:54:30 +00:00
|
|
|
ogs_assert(mme_ue);
|
2022-04-29 12:28:16 +00:00
|
|
|
sgw_ue = mme_ue->sgw_ue;
|
|
|
|
ogs_assert(sgw_ue);
|
2021-07-15 12:20:56 +00:00
|
|
|
xact = ogs_gtp_xact_cycle(bearer->update.xact);
|
2022-08-19 08:23:10 +00:00
|
|
|
if (!xact) {
|
|
|
|
ogs_warn("GTP transaction(UPDATE) has already been removed");
|
|
|
|
return OGS_OK;
|
|
|
|
}
|
2018-01-17 07:01:11 +00:00
|
|
|
|
2022-04-12 22:07:39 +00:00
|
|
|
memset(&h, 0, sizeof(ogs_gtp2_header_t));
|
|
|
|
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
|
|
|
h.teid_presence = OGS_GTP2_TEID_PRESENCE;
|
2022-04-29 12:28:16 +00:00
|
|
|
h.teid = sgw_ue->sgw_s11_teid;
|
2018-01-17 07:01:11 +00:00
|
|
|
|
2020-11-07 22:27:12 +00:00
|
|
|
pkbuf = mme_s11_build_update_bearer_response(h.type, bearer, cause_value);
|
2023-01-23 15:01:36 +00:00
|
|
|
if (!pkbuf) {
|
|
|
|
ogs_error("mme_s11_build_update_bearer_response() failed");
|
|
|
|
return OGS_ERROR;
|
|
|
|
}
|
2018-01-17 07:01:11 +00:00
|
|
|
|
2019-09-13 12:07:47 +00:00
|
|
|
rv = ogs_gtp_xact_update_tx(xact, &h, pkbuf);
|
2023-01-23 15:01:36 +00:00
|
|
|
if (rv != OGS_OK) {
|
|
|
|
ogs_error("ogs_gtp_xact_update_tx() failed");
|
|
|
|
return OGS_ERROR;
|
|
|
|
}
|
2018-01-17 07:01:11 +00:00
|
|
|
|
2019-09-13 12:07:47 +00:00
|
|
|
rv = ogs_gtp_xact_commit(xact);
|
2019-11-29 06:31:22 +00:00
|
|
|
ogs_expect(rv == OGS_OK);
|
2021-05-16 03:22:10 +00:00
|
|
|
|
|
|
|
return rv;
|
2018-01-17 07:01:11 +00:00
|
|
|
}
|
|
|
|
|
2021-05-16 03:22:10 +00:00
|
|
|
int mme_gtp_send_delete_bearer_response(
|
2020-11-07 22:27:12 +00:00
|
|
|
mme_bearer_t *bearer, uint8_t cause_value)
|
2018-01-16 13:14:59 +00:00
|
|
|
{
|
2019-04-27 14:54:30 +00:00
|
|
|
int rv;
|
2018-01-16 13:14:59 +00:00
|
|
|
|
2019-09-13 12:07:47 +00:00
|
|
|
ogs_gtp_xact_t *xact = NULL;
|
2018-01-16 13:14:59 +00:00
|
|
|
mme_ue_t *mme_ue = NULL;
|
2022-04-29 12:28:16 +00:00
|
|
|
sgw_ue_t *sgw_ue = NULL;
|
2018-01-16 13:14:59 +00:00
|
|
|
|
2022-04-12 22:07:39 +00:00
|
|
|
ogs_gtp2_header_t h;
|
2019-04-27 14:54:30 +00:00
|
|
|
ogs_pkbuf_t *pkbuf = NULL;
|
2018-01-16 13:14:59 +00:00
|
|
|
|
2019-04-27 14:54:30 +00:00
|
|
|
ogs_assert(bearer);
|
2018-01-16 13:14:59 +00:00
|
|
|
mme_ue = bearer->mme_ue;
|
2019-04-27 14:54:30 +00:00
|
|
|
ogs_assert(mme_ue);
|
2022-04-29 12:28:16 +00:00
|
|
|
sgw_ue = mme_ue->sgw_ue;
|
|
|
|
ogs_assert(sgw_ue);
|
2021-07-15 12:20:56 +00:00
|
|
|
xact = ogs_gtp_xact_cycle(bearer->delete.xact);
|
2022-08-19 08:23:10 +00:00
|
|
|
if (!xact) {
|
|
|
|
ogs_warn("GTP transaction(DELETE) has already been removed");
|
|
|
|
return OGS_OK;
|
|
|
|
}
|
2018-01-16 13:14:59 +00:00
|
|
|
|
2022-04-12 22:07:39 +00:00
|
|
|
memset(&h, 0, sizeof(ogs_gtp2_header_t));
|
|
|
|
h.type = OGS_GTP2_DELETE_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
|
|
|
h.teid_presence = OGS_GTP2_TEID_PRESENCE;
|
2022-04-29 12:28:16 +00:00
|
|
|
h.teid = sgw_ue->sgw_s11_teid;
|
2018-01-16 13:14:59 +00:00
|
|
|
|
2020-11-07 22:27:12 +00:00
|
|
|
pkbuf = mme_s11_build_delete_bearer_response(h.type, bearer, cause_value);
|
2023-01-23 15:01:36 +00:00
|
|
|
if (!pkbuf) {
|
|
|
|
ogs_error("mme_s11_build_delete_bearer_response() failed");
|
|
|
|
return OGS_ERROR;
|
|
|
|
}
|
2018-01-16 13:14:59 +00:00
|
|
|
|
2019-09-13 12:07:47 +00:00
|
|
|
rv = ogs_gtp_xact_update_tx(xact, &h, pkbuf);
|
2023-01-23 15:01:36 +00:00
|
|
|
if (rv != OGS_OK) {
|
|
|
|
ogs_error("ogs_gtp_xact_update_tx() failed");
|
|
|
|
return OGS_ERROR;
|
|
|
|
}
|
2018-01-16 13:14:59 +00:00
|
|
|
|
2019-09-13 12:07:47 +00:00
|
|
|
rv = ogs_gtp_xact_commit(xact);
|
2019-11-29 06:31:22 +00:00
|
|
|
ogs_expect(rv == OGS_OK);
|
2021-05-16 03:22:10 +00:00
|
|
|
|
|
|
|
return rv;
|
2018-01-16 13:14:59 +00:00
|
|
|
}
|
|
|
|
|
2021-05-16 03:22:10 +00:00
|
|
|
int mme_gtp_send_release_access_bearers_request(mme_ue_t *mme_ue, int action)
|
2017-09-07 10:44:08 +00:00
|
|
|
{
|
2019-04-27 14:54:30 +00:00
|
|
|
int rv;
|
2022-04-12 22:07:39 +00:00
|
|
|
ogs_gtp2_header_t h;
|
2019-04-27 14:54:30 +00:00
|
|
|
ogs_pkbuf_t *pkbuf = NULL;
|
2019-09-13 12:07:47 +00:00
|
|
|
ogs_gtp_xact_t *xact = NULL;
|
2022-04-29 12:28:16 +00:00
|
|
|
sgw_ue_t *sgw_ue = NULL;
|
2017-09-07 10:44:08 +00:00
|
|
|
|
2020-11-07 22:27:12 +00:00
|
|
|
ogs_assert(action);
|
2019-04-27 14:54:30 +00:00
|
|
|
ogs_assert(mme_ue);
|
2022-04-29 12:28:16 +00:00
|
|
|
sgw_ue = mme_ue->sgw_ue;
|
|
|
|
ogs_assert(sgw_ue);
|
2017-09-07 10:44:08 +00:00
|
|
|
|
2022-04-12 22:07:39 +00:00
|
|
|
memset(&h, 0, sizeof(ogs_gtp2_header_t));
|
|
|
|
h.type = OGS_GTP2_RELEASE_ACCESS_BEARERS_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
|
|
|
h.teid_presence = OGS_GTP2_TEID_PRESENCE;
|
2022-04-29 12:28:16 +00:00
|
|
|
h.teid = sgw_ue->sgw_s11_teid;
|
2017-09-07 10:44:08 +00:00
|
|
|
|
2019-11-30 07:45:09 +00:00
|
|
|
pkbuf = mme_s11_build_release_access_bearers_request(h.type);
|
2023-01-23 15:01:36 +00:00
|
|
|
if (!pkbuf) {
|
|
|
|
ogs_error("mme_s11_build_release_access_bearers_request() failed");
|
|
|
|
return OGS_ERROR;
|
|
|
|
}
|
2017-09-07 10:44:08 +00:00
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
xact = ogs_gtp_xact_local_create(sgw_ue->gnode, &h, pkbuf, timeout, mme_ue);
|
2023-01-23 15:01:36 +00:00
|
|
|
if (!xact) {
|
|
|
|
ogs_error("ogs_gtp_xact_local_create() failed");
|
|
|
|
return OGS_ERROR;
|
|
|
|
}
|
2020-11-07 22:27:12 +00:00
|
|
|
xact->release_action = action;
|
2023-12-20 18:15:47 +00:00
|
|
|
xact->local_teid = mme_ue->gn.mme_gn_teid;
|
2017-09-07 10:44:08 +00:00
|
|
|
|
2019-09-13 12:07:47 +00:00
|
|
|
rv = ogs_gtp_xact_commit(xact);
|
2019-11-29 06:31:22 +00:00
|
|
|
ogs_expect(rv == OGS_OK);
|
2021-05-16 03:22:10 +00:00
|
|
|
|
|
|
|
return rv;
|
2017-09-07 10:44:08 +00:00
|
|
|
}
|
2017-09-13 07:22:39 +00:00
|
|
|
|
2020-11-07 22:27:12 +00:00
|
|
|
void mme_gtp_send_release_all_ue_in_enb(mme_enb_t *enb, int action)
|
|
|
|
{
|
|
|
|
mme_ue_t *mme_ue = NULL;
|
2022-05-15 13:37:38 +00:00
|
|
|
enb_ue_t *enb_ue = NULL, *next = NULL;
|
2020-11-07 22:27:12 +00:00
|
|
|
|
2022-05-15 13:37:38 +00:00
|
|
|
ogs_list_for_each_safe(&enb->enb_ue_list, next, enb_ue) {
|
2020-11-07 22:27:12 +00:00
|
|
|
mme_ue = enb_ue->mme_ue;
|
|
|
|
|
2021-01-05 04:24:22 +00:00
|
|
|
if (mme_ue) {
|
2022-04-14 23:24:33 +00:00
|
|
|
if (action == OGS_GTP_RELEASE_S1_CONTEXT_REMOVE_BY_LO_CONNREFUSED) {
|
2022-05-15 13:37:38 +00:00
|
|
|
/*
|
|
|
|
* https://github.com/open5gs/open5gs/pull/1497
|
|
|
|
*
|
|
|
|
* 1. eNB, SGW-U and UPF go offline at the same time.
|
|
|
|
* 2. MME sends Release Access Bearer Request to SGW-C
|
|
|
|
* 3. SGW-C/SMF sends PFCP modification,
|
|
|
|
* but SGW-U/UPF does not respond.
|
|
|
|
* 4. MME does not receive Release Access Bearer Response.
|
|
|
|
* 5. timeout()
|
|
|
|
* 6. MME sends Delete Session Request to the SGW-C/SMF
|
|
|
|
* 7. No SGW-U/UPF, so timeout()
|
|
|
|
* 8. MME sends UEContextReleaseRequest enb_ue.
|
|
|
|
* 9. But there is no enb_ue, so MME crashed.
|
|
|
|
*
|
|
|
|
* To solve this situation,
|
|
|
|
* Execute enb_ue_unlink(mme_ue) and enb_ue_remove(enb_ue)
|
|
|
|
* before mme_gtp_send_release_access_bearers_request()
|
|
|
|
*/
|
|
|
|
enb_ue_unlink(mme_ue);
|
2022-04-14 23:24:33 +00:00
|
|
|
enb_ue_remove(enb_ue);
|
|
|
|
}
|
2022-05-15 13:37:38 +00:00
|
|
|
|
|
|
|
ogs_assert(OGS_OK ==
|
|
|
|
mme_gtp_send_release_access_bearers_request(mme_ue, action));
|
2021-01-05 04:24:22 +00:00
|
|
|
} else {
|
|
|
|
ogs_warn("mme_gtp_send_release_all_ue_in_enb()");
|
|
|
|
ogs_warn(" ENB_UE_S1AP_ID[%d] MME_UE_S1AP_ID[%d] Action[%d]",
|
|
|
|
enb_ue->enb_ue_s1ap_id, enb_ue->mme_ue_s1ap_id, action);
|
|
|
|
|
2021-01-25 04:43:42 +00:00
|
|
|
if (action == OGS_GTP_RELEASE_S1_CONTEXT_REMOVE_BY_LO_CONNREFUSED ||
|
|
|
|
action == OGS_GTP_RELEASE_S1_CONTEXT_REMOVE_BY_RESET_ALL) {
|
2021-01-05 04:24:22 +00:00
|
|
|
enb_ue_remove(enb_ue);
|
|
|
|
} else {
|
|
|
|
/* At this point, it does not support other action */
|
|
|
|
ogs_assert_if_reached();
|
|
|
|
}
|
|
|
|
}
|
2020-11-07 22:27:12 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-05-16 03:22:10 +00:00
|
|
|
int mme_gtp_send_downlink_data_notification_ack(
|
2020-11-07 22:27:12 +00:00
|
|
|
mme_bearer_t *bearer, uint8_t cause_value)
|
|
|
|
{
|
|
|
|
int rv;
|
|
|
|
mme_ue_t *mme_ue = NULL;
|
2022-04-29 12:28:16 +00:00
|
|
|
sgw_ue_t *sgw_ue = NULL;
|
2020-11-07 22:27:12 +00:00
|
|
|
ogs_gtp_xact_t *xact = NULL;
|
|
|
|
|
2022-04-12 22:07:39 +00:00
|
|
|
ogs_gtp2_header_t h;
|
2020-11-07 22:27:12 +00:00
|
|
|
ogs_pkbuf_t *s11buf = NULL;
|
|
|
|
|
|
|
|
ogs_assert(bearer);
|
2021-07-15 12:20:56 +00:00
|
|
|
xact = ogs_gtp_xact_cycle(bearer->notify.xact);
|
2022-08-19 08:23:10 +00:00
|
|
|
if (!xact) {
|
|
|
|
ogs_warn("GTP transaction(NOTIFY) has already been removed");
|
|
|
|
return OGS_OK;
|
|
|
|
}
|
2020-11-07 22:27:12 +00:00
|
|
|
mme_ue = bearer->mme_ue;
|
|
|
|
ogs_assert(mme_ue);
|
2022-04-29 12:28:16 +00:00
|
|
|
sgw_ue = mme_ue->sgw_ue;
|
|
|
|
ogs_assert(sgw_ue);
|
2020-11-07 22:27:12 +00:00
|
|
|
|
|
|
|
/* Build Downlink data notification ack */
|
2022-04-12 22:07:39 +00:00
|
|
|
memset(&h, 0, sizeof(ogs_gtp2_header_t));
|
|
|
|
h.type = OGS_GTP2_DOWNLINK_DATA_NOTIFICATION_ACKNOWLEDGE_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
|
|
|
h.teid_presence = OGS_GTP2_TEID_PRESENCE;
|
2022-04-29 12:28:16 +00:00
|
|
|
h.teid = sgw_ue->sgw_s11_teid;
|
2020-11-07 22:27:12 +00:00
|
|
|
|
|
|
|
s11buf = mme_s11_build_downlink_data_notification_ack(h.type, cause_value);
|
2023-01-23 15:01:36 +00:00
|
|
|
if (!s11buf) {
|
|
|
|
ogs_error("mme_s11_build_downlink_data_notification_ack() failed");
|
|
|
|
return OGS_ERROR;
|
|
|
|
}
|
2020-11-07 22:27:12 +00:00
|
|
|
|
|
|
|
rv = ogs_gtp_xact_update_tx(xact, &h, s11buf);
|
2023-01-23 15:01:36 +00:00
|
|
|
if (rv != OGS_OK) {
|
|
|
|
ogs_error("ogs_gtp_xact_update_tx() failed");
|
|
|
|
return OGS_ERROR;
|
|
|
|
}
|
2020-11-07 22:27:12 +00:00
|
|
|
|
|
|
|
rv = ogs_gtp_xact_commit(xact);
|
|
|
|
ogs_expect(rv == OGS_OK);
|
|
|
|
|
2021-05-16 03:22:10 +00:00
|
|
|
return rv;
|
2020-11-07 22:27:12 +00:00
|
|
|
}
|
|
|
|
|
2021-05-16 03:22:10 +00:00
|
|
|
int mme_gtp_send_create_indirect_data_forwarding_tunnel_request(
|
2017-09-13 07:22:39 +00:00
|
|
|
mme_ue_t *mme_ue)
|
|
|
|
{
|
2019-04-27 14:54:30 +00:00
|
|
|
int rv;
|
2022-04-12 22:07:39 +00:00
|
|
|
ogs_gtp2_header_t h;
|
2019-04-27 14:54:30 +00:00
|
|
|
ogs_pkbuf_t *pkbuf = NULL;
|
2019-09-13 12:07:47 +00:00
|
|
|
ogs_gtp_xact_t *xact = NULL;
|
2022-04-29 12:28:16 +00:00
|
|
|
sgw_ue_t *sgw_ue = NULL;
|
2017-09-13 07:22:39 +00:00
|
|
|
|
2019-04-27 14:54:30 +00:00
|
|
|
ogs_assert(mme_ue);
|
2022-04-29 12:28:16 +00:00
|
|
|
sgw_ue = mme_ue->sgw_ue;
|
|
|
|
ogs_assert(sgw_ue);
|
2017-09-13 07:22:39 +00:00
|
|
|
|
2022-04-12 22:07:39 +00:00
|
|
|
memset(&h, 0, sizeof(ogs_gtp2_header_t));
|
|
|
|
h.type = OGS_GTP2_CREATE_INDIRECT_DATA_FORWARDING_TUNNEL_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
|
|
|
h.teid_presence = OGS_GTP2_TEID_PRESENCE;
|
2022-04-29 12:28:16 +00:00
|
|
|
h.teid = sgw_ue->sgw_s11_teid;
|
2017-09-13 07:22:39 +00:00
|
|
|
|
2019-11-30 07:45:09 +00:00
|
|
|
pkbuf = mme_s11_build_create_indirect_data_forwarding_tunnel_request(
|
|
|
|
h.type, mme_ue);
|
2023-01-23 15:01:36 +00:00
|
|
|
if (!pkbuf) {
|
|
|
|
ogs_error("mme_s11_build_create_indirect_data_forwarding_"
|
|
|
|
"tunnel_request() failed");
|
|
|
|
return OGS_ERROR;
|
|
|
|
}
|
2017-09-13 07:22:39 +00:00
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
xact = ogs_gtp_xact_local_create(sgw_ue->gnode, &h, pkbuf, timeout, mme_ue);
|
2023-01-23 15:01:36 +00:00
|
|
|
if (!xact) {
|
|
|
|
ogs_error("ogs_gtp_xact_local_create() failed");
|
|
|
|
return OGS_ERROR;
|
|
|
|
}
|
2023-12-20 18:15:47 +00:00
|
|
|
xact->local_teid = mme_ue->gn.mme_gn_teid;
|
2017-09-13 07:22:39 +00:00
|
|
|
|
2019-09-13 12:07:47 +00:00
|
|
|
rv = ogs_gtp_xact_commit(xact);
|
2019-11-29 06:31:22 +00:00
|
|
|
ogs_expect(rv == OGS_OK);
|
2021-05-16 03:22:10 +00:00
|
|
|
|
|
|
|
return rv;
|
2017-09-13 07:22:39 +00:00
|
|
|
}
|
2017-09-14 05:18:47 +00:00
|
|
|
|
2021-05-16 03:22:10 +00:00
|
|
|
int mme_gtp_send_delete_indirect_data_forwarding_tunnel_request(
|
2021-02-01 04:01:15 +00:00
|
|
|
mme_ue_t *mme_ue, int action)
|
2017-09-14 05:18:47 +00:00
|
|
|
{
|
2019-04-27 14:54:30 +00:00
|
|
|
int rv;
|
2022-04-12 22:07:39 +00:00
|
|
|
ogs_gtp2_header_t h;
|
2019-04-27 14:54:30 +00:00
|
|
|
ogs_pkbuf_t *pkbuf = NULL;
|
2019-09-13 12:07:47 +00:00
|
|
|
ogs_gtp_xact_t *xact = NULL;
|
2022-04-29 12:28:16 +00:00
|
|
|
sgw_ue_t *sgw_ue = NULL;
|
2017-09-14 05:18:47 +00:00
|
|
|
|
2021-02-01 04:01:15 +00:00
|
|
|
ogs_assert(action);
|
2019-04-27 14:54:30 +00:00
|
|
|
ogs_assert(mme_ue);
|
2022-04-29 12:28:16 +00:00
|
|
|
sgw_ue = mme_ue->sgw_ue;
|
|
|
|
ogs_assert(sgw_ue);
|
2017-09-14 05:18:47 +00:00
|
|
|
|
2022-04-12 22:07:39 +00:00
|
|
|
memset(&h, 0, sizeof(ogs_gtp2_header_t));
|
|
|
|
h.type = OGS_GTP2_DELETE_INDIRECT_DATA_FORWARDING_TUNNEL_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
|
|
|
h.teid_presence = OGS_GTP2_TEID_PRESENCE;
|
2022-04-29 12:28:16 +00:00
|
|
|
h.teid = sgw_ue->sgw_s11_teid;
|
2017-09-14 05:18:47 +00:00
|
|
|
|
2019-09-13 12:07:47 +00:00
|
|
|
pkbuf = ogs_pkbuf_alloc(NULL, OGS_TLV_MAX_HEADROOM);
|
2023-01-23 15:01:36 +00:00
|
|
|
if (!pkbuf) {
|
|
|
|
ogs_error("ogs_pkbuf_alloc() failed");
|
|
|
|
return OGS_ERROR;
|
|
|
|
}
|
2019-09-13 12:07:47 +00:00
|
|
|
ogs_pkbuf_reserve(pkbuf, OGS_TLV_MAX_HEADROOM);
|
2017-09-14 05:18:47 +00:00
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
xact = ogs_gtp_xact_local_create(sgw_ue->gnode, &h, pkbuf, timeout, mme_ue);
|
2023-01-23 15:01:36 +00:00
|
|
|
if (!xact) {
|
|
|
|
ogs_error("ogs_gtp_xact_local_create() failed");
|
|
|
|
return OGS_ERROR;
|
|
|
|
}
|
2021-02-01 04:01:15 +00:00
|
|
|
xact->delete_indirect_action = action;
|
2023-12-20 18:15:47 +00:00
|
|
|
xact->local_teid = mme_ue->gn.mme_gn_teid;
|
2017-09-14 05:18:47 +00:00
|
|
|
|
2019-09-13 12:07:47 +00:00
|
|
|
rv = ogs_gtp_xact_commit(xact);
|
2019-11-29 06:31:22 +00:00
|
|
|
ogs_expect(rv == OGS_OK);
|
2021-05-16 03:22:10 +00:00
|
|
|
|
|
|
|
return rv;
|
2017-09-14 05:18:47 +00:00
|
|
|
}
|
2019-12-28 12:46:30 +00:00
|
|
|
|
2021-05-16 03:22:10 +00:00
|
|
|
int mme_gtp_send_bearer_resource_command(
|
2020-05-23 02:24:48 +00:00
|
|
|
mme_bearer_t *bearer, ogs_nas_eps_message_t *nas_message)
|
2019-12-28 12:46:30 +00:00
|
|
|
{
|
|
|
|
int rv;
|
2022-04-12 22:07:39 +00:00
|
|
|
ogs_gtp2_header_t h;
|
2019-12-28 12:46:30 +00:00
|
|
|
ogs_pkbuf_t *pkbuf = NULL;
|
|
|
|
ogs_gtp_xact_t *xact = NULL;
|
|
|
|
|
|
|
|
mme_ue_t *mme_ue = NULL;
|
2022-04-29 12:28:16 +00:00
|
|
|
sgw_ue_t *sgw_ue = NULL;
|
2019-12-28 12:46:30 +00:00
|
|
|
|
|
|
|
ogs_assert(bearer);
|
|
|
|
mme_ue = bearer->mme_ue;
|
|
|
|
ogs_assert(mme_ue);
|
2022-04-29 12:28:16 +00:00
|
|
|
sgw_ue = mme_ue->sgw_ue;
|
|
|
|
ogs_assert(sgw_ue);
|
2019-12-28 12:46:30 +00:00
|
|
|
|
2022-04-12 22:07:39 +00:00
|
|
|
memset(&h, 0, sizeof(ogs_gtp2_header_t));
|
|
|
|
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
|
|
|
h.teid_presence = OGS_GTP2_TEID_PRESENCE;
|
2022-04-29 12:28:16 +00:00
|
|
|
h.teid = sgw_ue->sgw_s11_teid;
|
2019-12-28 12:46:30 +00:00
|
|
|
|
|
|
|
pkbuf = mme_s11_build_bearer_resource_command(h.type, bearer, nas_message);
|
2023-01-23 15:01:36 +00:00
|
|
|
if (!pkbuf) {
|
|
|
|
ogs_error("mme_s11_build_bearer_resource_command() failed");
|
|
|
|
return OGS_ERROR;
|
|
|
|
}
|
2019-12-28 12:46:30 +00:00
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
xact = ogs_gtp_xact_local_create(sgw_ue->gnode, &h, pkbuf, timeout, bearer);
|
2023-01-23 15:01:36 +00:00
|
|
|
if (!xact) {
|
|
|
|
ogs_error("ogs_gtp_xact_local_create() failed");
|
|
|
|
return OGS_ERROR;
|
|
|
|
}
|
2019-12-28 12:46:30 +00:00
|
|
|
xact->xid |= OGS_GTP_CMD_XACT_ID;
|
2023-12-20 18:15:47 +00:00
|
|
|
xact->local_teid = mme_ue->gn.mme_gn_teid;
|
2019-12-28 12:46:30 +00:00
|
|
|
|
|
|
|
rv = ogs_gtp_xact_commit(xact);
|
|
|
|
ogs_expect(rv == OGS_OK);
|
2021-05-16 03:22:10 +00:00
|
|
|
|
|
|
|
return rv;
|
2021-06-06 13:35:46 +00:00
|
|
|
}
|
2023-07-06 16:03:42 +00:00
|
|
|
|
2024-01-16 10:13:47 +00:00
|
|
|
/*************************
|
|
|
|
* GTPv1C (Gn interface):
|
|
|
|
*************************/
|
|
|
|
|
|
|
|
int mme_gtp1_send_sgsn_context_request(
|
|
|
|
mme_sgsn_t *sgsn, mme_ue_t *mme_ue)
|
|
|
|
{
|
|
|
|
int rv;
|
|
|
|
ogs_gtp1_header_t h;
|
|
|
|
ogs_pkbuf_t *pkbuf = NULL;
|
|
|
|
ogs_gtp_xact_t *xact = NULL;
|
|
|
|
|
|
|
|
ogs_assert(sgsn);
|
|
|
|
|
|
|
|
memset(&h, 0, sizeof(ogs_gtp1_header_t));
|
|
|
|
h.type = OGS_GTP1_SGSN_CONTEXT_REQUEST_TYPE;
|
|
|
|
h.teid = 0;
|
|
|
|
|
|
|
|
pkbuf = mme_gn_build_sgsn_context_request(mme_ue);
|
|
|
|
if (!pkbuf) {
|
|
|
|
ogs_error("mme_gn_build_ran_information_relay() failed");
|
|
|
|
return OGS_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
xact = ogs_gtp1_xact_local_create(&sgsn->gnode, &h, pkbuf, NULL, NULL);
|
|
|
|
if (!xact) {
|
|
|
|
ogs_error("ogs_gtp1_xact_local_create() failed");
|
|
|
|
return OGS_ERROR;
|
|
|
|
}
|
|
|
|
/* TS 29.060 8.2: "The SGSN Context Request message, where the Tunnel
|
|
|
|
* Endpoint Identifier shall be set to all zeroes." */
|
|
|
|
xact->local_teid = 0;
|
|
|
|
|
|
|
|
rv = ogs_gtp_xact_commit(xact);
|
|
|
|
ogs_expect(rv == OGS_OK);
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2023-12-11 16:18:11 +00:00
|
|
|
int mme_gtp1_send_sgsn_context_response(
|
|
|
|
mme_ue_t *mme_ue, uint8_t cause, ogs_gtp_xact_t *xact)
|
|
|
|
{
|
|
|
|
int rv;
|
|
|
|
ogs_gtp1_header_t h;
|
|
|
|
ogs_pkbuf_t *pkbuf = NULL;
|
|
|
|
|
|
|
|
memset(&h, 0, sizeof(ogs_gtp1_header_t));
|
|
|
|
h.type = OGS_GTP1_SGSN_CONTEXT_RESPONSE_TYPE;
|
|
|
|
h.teid = mme_ue ? mme_ue->gn.sgsn_gn_teid : 0;
|
|
|
|
|
|
|
|
pkbuf = mme_gn_build_sgsn_context_response(mme_ue, cause);
|
|
|
|
if (!pkbuf) {
|
|
|
|
ogs_error("mme_gn_build_sgsn_context_response() failed");
|
|
|
|
return OGS_ERROR;
|
|
|
|
}
|
|
|
|
xact->local_teid = mme_ue ? mme_ue->gn.mme_gn_teid : 0;
|
|
|
|
|
|
|
|
rv = ogs_gtp1_xact_update_tx(xact, &h, pkbuf);
|
|
|
|
if (rv != OGS_OK) {
|
|
|
|
ogs_error("ogs_gtp1_xact_update_tx() failed");
|
|
|
|
return OGS_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
rv = ogs_gtp_xact_commit(xact);
|
|
|
|
ogs_expect(rv == OGS_OK);
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
2023-07-06 16:03:42 +00:00
|
|
|
|
2024-01-16 10:13:47 +00:00
|
|
|
int mme_gtp1_send_sgsn_context_ack(
|
|
|
|
mme_ue_t *mme_ue, uint8_t cause, ogs_gtp_xact_t *xact)
|
|
|
|
{
|
|
|
|
int rv;
|
|
|
|
ogs_gtp1_header_t h;
|
|
|
|
ogs_pkbuf_t *pkbuf = NULL;
|
|
|
|
|
|
|
|
ogs_assert(mme_ue);
|
|
|
|
|
|
|
|
memset(&h, 0, sizeof(ogs_gtp1_header_t));
|
|
|
|
h.type = OGS_GTP1_SGSN_CONTEXT_ACKNOWLEDGE_TYPE;
|
|
|
|
h.teid = mme_ue->gn.sgsn_gn_teid;
|
|
|
|
|
|
|
|
pkbuf = mme_gn_build_sgsn_context_ack(mme_ue, cause);
|
|
|
|
if (!pkbuf) {
|
|
|
|
ogs_error("mme_gn_build_sgsn_context_response() failed");
|
|
|
|
return OGS_ERROR;
|
|
|
|
}
|
|
|
|
xact->local_teid = mme_ue->gn.mme_gn_teid;
|
|
|
|
|
|
|
|
rv = ogs_gtp1_xact_update_tx(xact, &h, pkbuf);
|
|
|
|
if (rv != OGS_OK) {
|
|
|
|
ogs_error("ogs_gtp1_xact_update_tx() failed");
|
|
|
|
return OGS_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
rv = ogs_gtp_xact_commit(xact);
|
|
|
|
ogs_expect(rv == OGS_OK);
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2023-07-06 16:03:42 +00:00
|
|
|
int mme_gtp1_send_ran_information_relay(
|
|
|
|
mme_sgsn_t *sgsn, const uint8_t *buf, size_t len,
|
|
|
|
const ogs_nas_rai_t *rai, uint16_t cell_id)
|
|
|
|
{
|
|
|
|
int rv;
|
|
|
|
ogs_gtp1_header_t h;
|
|
|
|
ogs_pkbuf_t *pkbuf = NULL;
|
|
|
|
ogs_gtp_xact_t *xact = NULL;
|
|
|
|
|
|
|
|
ogs_assert(sgsn);
|
|
|
|
ogs_assert(buf);
|
|
|
|
|
|
|
|
memset(&h, 0, sizeof(ogs_gtp1_header_t));
|
|
|
|
h.type = OGS_GTP1_RAN_INFORMATION_RELAY_TYPE;
|
|
|
|
h.teid = 0;
|
|
|
|
|
|
|
|
pkbuf = mme_gn_build_ran_information_relay(h.type, buf, len, rai, cell_id);
|
|
|
|
if (!pkbuf) {
|
|
|
|
ogs_error("mme_gn_build_ran_information_relay() failed");
|
|
|
|
return OGS_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
xact = ogs_gtp1_xact_local_create(&sgsn->gnode, &h, pkbuf, NULL, NULL);
|
|
|
|
if (!xact) {
|
|
|
|
ogs_error("ogs_gtp1_xact_local_create() failed");
|
|
|
|
return OGS_ERROR;
|
|
|
|
}
|
|
|
|
/* TS 29.060 8.2: "The RAN Information Relay message, where the Tunnel
|
|
|
|
* Endpoint Identifier shall be set to all zeroes." */
|
|
|
|
xact->local_teid = 0;
|
|
|
|
|
|
|
|
rv = ogs_gtp_xact_commit(xact);
|
|
|
|
ogs_expect(rv == OGS_OK);
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|