2020-08-13 00:31:22 +00:00
|
|
|
/*
|
|
|
|
* Copyright (C) 2019 by Sukchan Lee <acetcom@gmail.com>
|
|
|
|
*
|
|
|
|
* 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 "pfcp-path.h"
|
|
|
|
#include "gtp-path.h"
|
|
|
|
#include "sxa-handler.h"
|
|
|
|
|
|
|
|
static uint8_t gtp_cause_from_pfcp(uint8_t pfcp_cause)
|
|
|
|
{
|
|
|
|
switch (pfcp_cause) {
|
|
|
|
case OGS_PFCP_CAUSE_REQUEST_ACCEPTED:
|
2022-04-12 22:07:39 +00:00
|
|
|
return OGS_GTP2_CAUSE_REQUEST_ACCEPTED;
|
2020-08-13 00:31:22 +00:00
|
|
|
case OGS_PFCP_CAUSE_REQUEST_REJECTED:
|
2022-04-12 22:07:39 +00:00
|
|
|
return OGS_GTP2_CAUSE_REQUEST_REJECTED_REASON_NOT_SPECIFIED;
|
2020-08-13 00:31:22 +00:00
|
|
|
case OGS_PFCP_CAUSE_SESSION_CONTEXT_NOT_FOUND:
|
2022-04-12 22:07:39 +00:00
|
|
|
return OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND;
|
2020-08-13 00:31:22 +00:00
|
|
|
case OGS_PFCP_CAUSE_MANDATORY_IE_MISSING:
|
2022-04-12 22:07:39 +00:00
|
|
|
return OGS_GTP2_CAUSE_MANDATORY_IE_MISSING;
|
2020-08-13 00:31:22 +00:00
|
|
|
case OGS_PFCP_CAUSE_CONDITIONAL_IE_MISSING:
|
2022-04-12 22:07:39 +00:00
|
|
|
return OGS_GTP2_CAUSE_CONDITIONAL_IE_MISSING;
|
2020-08-13 00:31:22 +00:00
|
|
|
case OGS_PFCP_CAUSE_INVALID_LENGTH:
|
2022-04-12 22:07:39 +00:00
|
|
|
return OGS_GTP2_CAUSE_INVALID_LENGTH;
|
2020-08-13 00:31:22 +00:00
|
|
|
case OGS_PFCP_CAUSE_MANDATORY_IE_INCORRECT:
|
2022-04-12 22:07:39 +00:00
|
|
|
return OGS_GTP2_CAUSE_MANDATORY_IE_INCORRECT;
|
2020-08-13 00:31:22 +00:00
|
|
|
case OGS_PFCP_CAUSE_INVALID_FORWARDING_POLICY:
|
|
|
|
case OGS_PFCP_CAUSE_INVALID_F_TEID_ALLOCATION_OPTION:
|
2022-04-12 22:07:39 +00:00
|
|
|
return OGS_GTP2_CAUSE_INVALID_MESSAGE_FORMAT;
|
2020-08-13 00:31:22 +00:00
|
|
|
case OGS_PFCP_CAUSE_NO_ESTABLISHED_PFCP_ASSOCIATION:
|
2022-04-12 22:07:39 +00:00
|
|
|
return OGS_GTP2_CAUSE_REMOTE_PEER_NOT_RESPONDING;
|
2020-08-13 00:31:22 +00:00
|
|
|
case OGS_PFCP_CAUSE_RULE_CREATION_MODIFICATION_FAILURE:
|
2022-04-12 22:07:39 +00:00
|
|
|
return OGS_GTP2_CAUSE_SEMANTIC_ERROR_IN_THE_TFT_OPERATION;
|
2020-08-13 00:31:22 +00:00
|
|
|
case OGS_PFCP_CAUSE_PFCP_ENTITY_IN_CONGESTION:
|
2022-04-12 22:07:39 +00:00
|
|
|
return OGS_GTP2_CAUSE_GTP_C_ENTITY_CONGESTION;
|
2020-08-13 00:31:22 +00:00
|
|
|
case OGS_PFCP_CAUSE_NO_RESOURCES_AVAILABLE:
|
2022-04-12 22:07:39 +00:00
|
|
|
return OGS_GTP2_CAUSE_NO_RESOURCES_AVAILABLE;
|
2020-08-13 00:31:22 +00:00
|
|
|
case OGS_PFCP_CAUSE_SERVICE_NOT_SUPPORTED:
|
2022-04-12 22:07:39 +00:00
|
|
|
return OGS_GTP2_CAUSE_SERVICE_NOT_SUPPORTED;
|
2020-08-13 00:31:22 +00:00
|
|
|
case OGS_PFCP_CAUSE_SYSTEM_FAILURE:
|
2022-04-12 22:07:39 +00:00
|
|
|
return OGS_GTP2_CAUSE_SYSTEM_FAILURE;
|
2020-08-13 00:31:22 +00:00
|
|
|
default:
|
2022-04-12 22:07:39 +00:00
|
|
|
return OGS_GTP2_CAUSE_SYSTEM_FAILURE;
|
2020-08-13 00:31:22 +00:00
|
|
|
}
|
|
|
|
|
2022-04-12 22:07:39 +00:00
|
|
|
return OGS_GTP2_CAUSE_SYSTEM_FAILURE;
|
2020-08-13 00:31:22 +00:00
|
|
|
}
|
|
|
|
|
2020-11-07 22:27:12 +00:00
|
|
|
static void 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_CREATE_SESSION_REQUEST_TYPE:
|
2020-11-07 22:27:12 +00:00
|
|
|
ogs_error("[%s] No Create Session Response", sgwc_ue->imsi_bcd);
|
2021-01-08 20:09:02 +00:00
|
|
|
if (!sgwc_sess_cycle(sess)) {
|
|
|
|
ogs_warn("[%s] Session has already been removed",
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void bearer_timeout(ogs_gtp_xact_t *xact, void *data)
|
|
|
|
{
|
|
|
|
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;
|
|
|
|
|
|
|
|
switch (type) {
|
2022-04-12 22:07:39 +00:00
|
|
|
case OGS_GTP2_CREATE_BEARER_REQUEST_TYPE:
|
2020-11-07 22:27:12 +00:00
|
|
|
ogs_error("[%s] No Create Bearer Response", sgwc_ue->imsi_bcd);
|
2021-01-08 20:09:02 +00:00
|
|
|
if (!sgwc_bearer_cycle(bearer)) {
|
|
|
|
ogs_warn("[%s] Bearer has already been removed", sgwc_ue->imsi_bcd);
|
|
|
|
break;
|
|
|
|
}
|
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));
|
2020-11-07 22:27:12 +00:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
ogs_error("GTP Timeout : IMSI[%s] Message-Type[%d]",
|
|
|
|
sgwc_ue->imsi_bcd, type);
|
|
|
|
}
|
2020-08-13 00:31:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void sgwc_sxa_handle_session_establishment_response(
|
|
|
|
sgwc_sess_t *sess, ogs_pfcp_xact_t *pfcp_xact,
|
2022-04-29 12:28:16 +00:00
|
|
|
ogs_gtp2_message_t *recv_message,
|
2020-08-13 00:31:22 +00:00
|
|
|
ogs_pfcp_session_establishment_response_t *pfcp_rsp)
|
|
|
|
{
|
2022-04-29 12:28:16 +00:00
|
|
|
int rv;
|
2020-08-13 00:31:22 +00:00
|
|
|
uint8_t cause_value = 0;
|
2020-10-26 02:43:53 +00:00
|
|
|
|
2020-08-13 00:31:22 +00:00
|
|
|
ogs_pfcp_f_seid_t *up_f_seid = NULL;
|
|
|
|
|
2022-05-12 13:52:36 +00:00
|
|
|
int sgw_s5c_len;
|
|
|
|
ogs_gtp2_f_teid_t sgw_s5c_teid;
|
2022-04-12 22:07:39 +00:00
|
|
|
ogs_gtp2_f_teid_t *pgw_s5c_teid = NULL;
|
2020-08-13 00:31:22 +00:00
|
|
|
|
2022-05-12 13:52:36 +00:00
|
|
|
int i, num_of_sgw_s5u;
|
|
|
|
uint8_t ebi[OGS_BEARER_PER_UE];
|
|
|
|
int sgw_s5u_len[OGS_BEARER_PER_UE];
|
|
|
|
ogs_gtp2_f_teid_t sgw_s5u_teid[OGS_BEARER_PER_UE];
|
|
|
|
|
2020-08-13 00:31:22 +00:00
|
|
|
ogs_gtp_xact_t *s11_xact = NULL, *s5c_xact = NULL;
|
|
|
|
ogs_gtp_node_t *pgw = NULL;
|
|
|
|
|
|
|
|
sgwc_ue_t *sgwc_ue = NULL;
|
|
|
|
sgwc_bearer_t *bearer = NULL;
|
|
|
|
sgwc_tunnel_t *dl_tunnel = NULL;
|
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
ogs_gtp2_create_session_request_t *create_session_request = NULL;
|
2020-08-13 00:31:22 +00:00
|
|
|
ogs_pkbuf_t *pkbuf = NULL;
|
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
ogs_gtp2_indication_t *indication = NULL;
|
|
|
|
|
2021-03-31 10:59:57 +00:00
|
|
|
ogs_debug("Session Establishment Response");
|
|
|
|
|
2020-08-13 00:31:22 +00:00
|
|
|
ogs_assert(pfcp_xact);
|
|
|
|
ogs_assert(pfcp_rsp);
|
2022-04-29 12:28:16 +00:00
|
|
|
ogs_assert(recv_message);
|
2020-08-13 00:31:22 +00:00
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
create_session_request = &recv_message->create_session_request;
|
|
|
|
ogs_assert(create_session_request);
|
2020-08-13 00:31:22 +00:00
|
|
|
|
|
|
|
s11_xact = pfcp_xact->assoc_xact;
|
|
|
|
ogs_assert(s11_xact);
|
|
|
|
|
|
|
|
ogs_pfcp_xact_commit(pfcp_xact);
|
|
|
|
|
2022-04-12 22:07:39 +00:00
|
|
|
cause_value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED;
|
2020-08-13 00:31:22 +00:00
|
|
|
|
2022-06-30 00:11:38 +00:00
|
|
|
if (!sess) {
|
|
|
|
ogs_warn("No Context");
|
|
|
|
cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND;
|
|
|
|
}
|
|
|
|
|
2020-08-13 00:31:22 +00:00
|
|
|
if (pfcp_rsp->up_f_seid.presence == 0) {
|
|
|
|
ogs_error("No UP F-SEID");
|
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 (pfcp_rsp->cause.presence) {
|
|
|
|
if (pfcp_rsp->cause.u8 != OGS_PFCP_CAUSE_REQUEST_ACCEPTED) {
|
|
|
|
ogs_warn("PFCP Cause [%d] : Not Accepted", pfcp_rsp->cause.u8);
|
|
|
|
cause_value = gtp_cause_from_pfcp(pfcp_rsp->cause.u8);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
ogs_error("No Cause");
|
2022-04-12 22:07:39 +00:00
|
|
|
cause_value = OGS_GTP2_CAUSE_MANDATORY_IE_MISSING;
|
2020-08-13 00:31:22 +00:00
|
|
|
}
|
|
|
|
|
2022-04-12 22:07:39 +00:00
|
|
|
if (cause_value == OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
2020-10-26 02:43:53 +00:00
|
|
|
int i;
|
|
|
|
|
|
|
|
uint8_t pfcp_cause_value = OGS_PFCP_CAUSE_REQUEST_ACCEPTED;
|
|
|
|
uint8_t offending_ie_value = 0;
|
|
|
|
|
2022-04-16 05:08:56 +00:00
|
|
|
sgwc_tunnel_t *tunnel = NULL;
|
|
|
|
ogs_pfcp_pdr_t *pdr = NULL;
|
|
|
|
ogs_pfcp_far_t *far = NULL;
|
|
|
|
|
2020-10-26 02:43:53 +00:00
|
|
|
ogs_assert(sess);
|
|
|
|
for (i = 0; i < OGS_MAX_NUM_OF_PDR; i++) {
|
|
|
|
pdr = ogs_pfcp_handle_created_pdr(
|
|
|
|
&sess->pfcp, &pfcp_rsp->created_pdr[i],
|
|
|
|
&pfcp_cause_value, &offending_ie_value);
|
|
|
|
|
|
|
|
if (!pdr)
|
|
|
|
break;
|
2022-04-16 05:08:56 +00:00
|
|
|
}
|
2020-10-26 02:43:53 +00:00
|
|
|
|
2022-04-16 05:08:56 +00:00
|
|
|
ogs_list_for_each(&sess->pfcp.pdr_list, pdr) {
|
2021-03-15 01:01:55 +00:00
|
|
|
far = pdr->far;
|
|
|
|
ogs_assert(far);
|
|
|
|
|
|
|
|
if (pdr->src_if == OGS_PFCP_INTERFACE_CP_FUNCTION)
|
2021-06-06 13:35:46 +00:00
|
|
|
ogs_assert(OGS_ERROR != ogs_pfcp_setup_pdr_gtpu_node(pdr));
|
2020-10-26 02:43:53 +00:00
|
|
|
|
2021-03-15 01:01:55 +00:00
|
|
|
if (far->dst_if == OGS_PFCP_INTERFACE_CP_FUNCTION)
|
|
|
|
ogs_pfcp_far_teid_hash_set(far);
|
|
|
|
|
|
|
|
tunnel = sgwc_tunnel_find_by_pdr_id(sess, pdr->id);
|
|
|
|
if (tunnel) {
|
|
|
|
ogs_assert(sess->pfcp_node);
|
|
|
|
if (sess->pfcp_node->up_function_features.ftup &&
|
|
|
|
pdr->f_teid_len) {
|
|
|
|
if (tunnel->local_addr)
|
|
|
|
ogs_freeaddrinfo(tunnel->local_addr);
|
|
|
|
if (tunnel->local_addr6)
|
|
|
|
ogs_freeaddrinfo(tunnel->local_addr6);
|
|
|
|
|
2021-06-06 13:35:46 +00:00
|
|
|
ogs_assert(OGS_OK ==
|
|
|
|
ogs_pfcp_f_teid_to_sockaddr(
|
2021-03-15 01:01:55 +00:00
|
|
|
&pdr->f_teid, pdr->f_teid_len,
|
2021-06-06 13:35:46 +00:00
|
|
|
&tunnel->local_addr, &tunnel->local_addr6));
|
2021-03-15 01:01:55 +00:00
|
|
|
tunnel->local_teid = pdr->f_teid.teid;
|
|
|
|
}
|
2020-10-26 02:43:53 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
cause_value = gtp_cause_from_pfcp(pfcp_cause_value);
|
|
|
|
}
|
|
|
|
|
2022-04-12 22:07:39 +00:00
|
|
|
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
2020-08-13 00:31:22 +00:00
|
|
|
if (sess) sgwc_ue = sess->sgwc_ue;
|
|
|
|
ogs_gtp_send_error_message(
|
|
|
|
s11_xact, 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;
|
|
|
|
}
|
|
|
|
|
|
|
|
ogs_assert(sess);
|
|
|
|
|
2022-05-12 13:52:36 +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
|
|
|
|
2022-05-12 13:52:36 +00:00
|
|
|
/* Data Plane(DL) : SGW-S5U */
|
|
|
|
i = 0;
|
|
|
|
ogs_list_for_each(&sess->bearer_list, bearer) {
|
|
|
|
ogs_assert(i < OGS_BEARER_PER_UE);
|
|
|
|
|
|
|
|
dl_tunnel = sgwc_dl_tunnel_in_bearer(bearer);
|
|
|
|
ogs_assert(dl_tunnel);
|
|
|
|
|
|
|
|
ogs_debug(" SGW_S5U_TEID[%d] PGW_S5U_TEID[%d]",
|
|
|
|
dl_tunnel->local_teid, dl_tunnel->remote_teid);
|
|
|
|
|
|
|
|
if (dl_tunnel->local_addr == NULL && dl_tunnel->local_addr6 == NULL) {
|
|
|
|
ogs_error("No UP F-TEID");
|
|
|
|
ogs_gtp_send_error_message(
|
|
|
|
s11_xact, sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
|
|
|
|
OGS_GTP2_CREATE_SESSION_RESPONSE_TYPE,
|
|
|
|
OGS_GTP2_CAUSE_GRE_KEY_NOT_FOUND);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
ebi[i] = bearer->ebi;
|
|
|
|
|
|
|
|
memset(&sgw_s5u_teid[i], 0, sizeof(ogs_gtp2_f_teid_t));
|
|
|
|
sgw_s5u_teid[i].teid = htobe32(dl_tunnel->local_teid);
|
|
|
|
sgw_s5u_teid[i].interface_type = dl_tunnel->interface_type;
|
|
|
|
ogs_assert(dl_tunnel->local_addr || dl_tunnel->local_addr6);
|
|
|
|
rv = ogs_gtp2_sockaddr_to_f_teid(
|
|
|
|
dl_tunnel->local_addr, dl_tunnel->local_addr6,
|
|
|
|
&sgw_s5u_teid[i], &sgw_s5u_len[i]);
|
|
|
|
ogs_assert(rv == OGS_OK);
|
|
|
|
|
|
|
|
i++;
|
2020-10-26 02:43:53 +00:00
|
|
|
}
|
|
|
|
|
2022-05-12 13:52:36 +00:00
|
|
|
num_of_sgw_s5u = i;
|
2020-08-13 00:31:22 +00:00
|
|
|
|
|
|
|
/* Send Control Plane(DL) : SGW-S5C */
|
2022-04-12 22:07:39 +00:00
|
|
|
memset(&sgw_s5c_teid, 0, sizeof(ogs_gtp2_f_teid_t));
|
|
|
|
sgw_s5c_teid.interface_type = OGS_GTP2_F_TEID_S5_S8_SGW_GTP_C;
|
2020-08-13 00:31:22 +00:00
|
|
|
sgw_s5c_teid.teid = htobe32(sess->sgw_s5c_teid);
|
2022-04-12 22:07:39 +00:00
|
|
|
rv = ogs_gtp2_sockaddr_to_f_teid(
|
2021-03-15 01:01:55 +00:00
|
|
|
ogs_gtp_self()->gtpc_addr, ogs_gtp_self()->gtpc_addr6,
|
2022-04-29 12:28:16 +00:00
|
|
|
&sgw_s5c_teid, &sgw_s5c_len);
|
2020-08-13 00:31:22 +00:00
|
|
|
ogs_assert(rv == OGS_OK);
|
|
|
|
|
2022-05-12 13:52:36 +00:00
|
|
|
/* UP F-SEID */
|
|
|
|
up_f_seid = pfcp_rsp->up_f_seid.data;
|
|
|
|
ogs_assert(up_f_seid);
|
|
|
|
sess->sgwu_sxa_seid = be64toh(up_f_seid->seid);
|
2020-08-13 00:31:22 +00:00
|
|
|
|
2022-05-28 08:06:36 +00:00
|
|
|
/* Receive Control Plane(UL) : PGW-S5C */
|
2022-04-29 12:28:16 +00:00
|
|
|
pgw_s5c_teid = create_session_request->
|
|
|
|
pgw_s5_s8_address_for_control_plane_or_pmip.data;
|
2020-08-13 00:31:22 +00:00
|
|
|
ogs_assert(pgw_s5c_teid);
|
|
|
|
|
|
|
|
pgw = ogs_gtp_node_find_by_f_teid(&sgwc_self()->pgw_s5c_list, pgw_s5c_teid);
|
|
|
|
if (!pgw) {
|
|
|
|
pgw = ogs_gtp_node_add_by_f_teid(
|
2021-03-15 01:01:55 +00:00
|
|
|
&sgwc_self()->pgw_s5c_list,
|
|
|
|
pgw_s5c_teid, ogs_gtp_self()->gtpc_port);
|
2020-08-13 00:31:22 +00:00
|
|
|
ogs_assert(pgw);
|
|
|
|
|
|
|
|
rv = ogs_gtp_connect(
|
2021-03-15 01:01:55 +00:00
|
|
|
ogs_gtp_self()->gtpc_sock, ogs_gtp_self()->gtpc_sock6, pgw);
|
2020-08-13 00:31:22 +00:00
|
|
|
ogs_assert(rv == OGS_OK);
|
|
|
|
}
|
|
|
|
/* Setup GTP Node */
|
|
|
|
OGS_SETUP_GTP_NODE(sess, pgw);
|
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
/* Check Indication */
|
|
|
|
if (create_session_request->indication_flags.presence &&
|
|
|
|
create_session_request->indication_flags.data &&
|
|
|
|
create_session_request->indication_flags.len) {
|
|
|
|
indication = create_session_request->indication_flags.data;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (indication && indication->operation_indication) {
|
|
|
|
ogs_gtp2_message_t send_message;
|
|
|
|
ogs_gtp2_modify_bearer_request_t *modify_bearer_request =
|
|
|
|
&send_message.modify_bearer_request;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Operation Indication:
|
|
|
|
* This flag shall be set to 1 on the S4/S11 interface
|
|
|
|
* for a TAU/RAU procedure with SGW relocation, Enhanced
|
|
|
|
* SRNS Relocation with SGW relocation, X2-based handovers
|
|
|
|
* with SGW relocation and MME triggered Serving GW relocation
|
|
|
|
*/
|
|
|
|
memset(&send_message, 0, sizeof(ogs_gtp2_message_t));
|
|
|
|
|
|
|
|
send_message.h.type = OGS_GTP2_MODIFY_BEARER_REQUEST_TYPE;
|
|
|
|
send_message.h.teid = sess->pgw_s5c_teid;
|
|
|
|
|
|
|
|
/* Send Control Plane(DL) : SGW-S5C */
|
|
|
|
modify_bearer_request->sender_f_teid_for_control_plane.presence = 1;
|
|
|
|
modify_bearer_request->sender_f_teid_for_control_plane.
|
|
|
|
data = &sgw_s5c_teid;
|
|
|
|
modify_bearer_request->sender_f_teid_for_control_plane.
|
|
|
|
len = sgw_s5c_len;
|
|
|
|
|
2022-05-12 13:52:36 +00:00
|
|
|
for (i = 0; i < num_of_sgw_s5u; i++) {
|
|
|
|
modify_bearer_request->bearer_contexts_to_be_modified[i].
|
|
|
|
presence = 1;
|
|
|
|
modify_bearer_request->bearer_contexts_to_be_modified[i].
|
|
|
|
eps_bearer_id.presence = 1;
|
|
|
|
|
|
|
|
/* Bearer Context : EBI */
|
|
|
|
modify_bearer_request->bearer_contexts_to_be_modified[i].
|
|
|
|
eps_bearer_id.u8 = ebi[i];
|
|
|
|
|
|
|
|
/* Data Plane(DL) : SGW-S5U */
|
|
|
|
modify_bearer_request->bearer_contexts_to_be_modified[i].
|
|
|
|
s4_u_sgsn_f_teid.presence = 1;
|
|
|
|
modify_bearer_request->bearer_contexts_to_be_modified[i].
|
|
|
|
s4_u_sgsn_f_teid.data = &sgw_s5u_teid[i];
|
|
|
|
modify_bearer_request->bearer_contexts_to_be_modified[i].
|
|
|
|
s4_u_sgsn_f_teid.len = sgw_s5u_len[i];
|
|
|
|
}
|
2022-04-29 12:28:16 +00:00
|
|
|
|
|
|
|
pkbuf = ogs_gtp2_build_msg(&send_message);
|
|
|
|
ogs_expect_or_return(pkbuf);
|
2020-08-13 00:31:22 +00:00
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
ogs_assert(sess->gnode);
|
|
|
|
s5c_xact = ogs_gtp_xact_local_create(
|
|
|
|
sess->gnode, &send_message.h, pkbuf, sess_timeout, sess);
|
|
|
|
ogs_expect_or_return(s5c_xact);
|
2022-05-12 13:52:36 +00:00
|
|
|
|
|
|
|
s5c_xact->modify_action = OGS_GTP_MODIFY_IN_PATH_SWITCH_REQUEST;
|
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
} else {
|
2022-05-12 13:52:36 +00:00
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
/* Create Session Request */
|
|
|
|
recv_message->h.type = OGS_GTP2_CREATE_SESSION_REQUEST_TYPE;
|
|
|
|
recv_message->h.teid = sess->pgw_s5c_teid;
|
|
|
|
|
|
|
|
/* Send Control Plane(DL) : SGW-S5C */
|
|
|
|
create_session_request->sender_f_teid_for_control_plane.presence = 1;
|
|
|
|
create_session_request->sender_f_teid_for_control_plane.
|
|
|
|
data = &sgw_s5c_teid;
|
|
|
|
create_session_request->sender_f_teid_for_control_plane.
|
|
|
|
len = sgw_s5c_len;
|
|
|
|
|
|
|
|
/* Remove PGW-S5C */
|
|
|
|
create_session_request->pgw_s5_s8_address_for_control_plane_or_pmip.
|
|
|
|
presence = 0;
|
|
|
|
|
|
|
|
/* Bearer Contexts */
|
2022-05-12 13:52:36 +00:00
|
|
|
for (i = 0; i < num_of_sgw_s5u; i++) {
|
|
|
|
create_session_request->bearer_contexts_to_be_created[i].
|
|
|
|
s5_s8_u_sgw_f_teid.presence = 1;
|
|
|
|
create_session_request->bearer_contexts_to_be_created[i].
|
|
|
|
s5_s8_u_sgw_f_teid.data = &sgw_s5u_teid[i];
|
|
|
|
create_session_request->bearer_contexts_to_be_created[i].
|
|
|
|
s5_s8_u_sgw_f_teid.len = sgw_s5u_len[i];
|
|
|
|
}
|
2022-04-29 12:28:16 +00:00
|
|
|
|
|
|
|
pkbuf = ogs_gtp2_build_msg(recv_message);
|
|
|
|
ogs_expect_or_return(pkbuf);
|
2020-08-13 00:31:22 +00:00
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
ogs_assert(sess->gnode);
|
|
|
|
s5c_xact = ogs_gtp_xact_local_create(
|
|
|
|
sess->gnode, &recv_message->h, pkbuf, sess_timeout, sess);
|
|
|
|
ogs_expect_or_return(s5c_xact);
|
|
|
|
}
|
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);
|
|
|
|
}
|
|
|
|
|
|
|
|
void sgwc_sxa_handle_session_modification_response(
|
|
|
|
sgwc_sess_t *sess, ogs_pfcp_xact_t *pfcp_xact,
|
2022-04-12 22:07:39 +00:00
|
|
|
ogs_gtp2_message_t *recv_message,
|
2020-08-13 00:31:22 +00:00
|
|
|
ogs_pfcp_session_modification_response_t *pfcp_rsp)
|
|
|
|
{
|
|
|
|
int i, rv, len = 0;
|
|
|
|
uint8_t cause_value = 0;
|
|
|
|
uint64_t flags;
|
|
|
|
|
|
|
|
ogs_gtp_xact_t *s11_xact = NULL;
|
|
|
|
ogs_gtp_xact_t *s5c_xact = NULL;
|
|
|
|
|
2022-04-12 22:07:39 +00:00
|
|
|
ogs_gtp2_message_t send_message;
|
2020-08-13 00:31:22 +00:00
|
|
|
|
|
|
|
sgwc_bearer_t *bearer = NULL;
|
|
|
|
sgwc_tunnel_t *dl_tunnel = NULL, *ul_tunnel = NULL;
|
|
|
|
sgwc_ue_t *sgwc_ue = NULL;
|
|
|
|
|
|
|
|
ogs_pkbuf_t *pkbuf = NULL;
|
|
|
|
|
2022-04-12 22:07:39 +00:00
|
|
|
ogs_gtp2_cause_t cause;
|
2020-08-13 00:31:22 +00:00
|
|
|
|
2021-03-31 10:59:57 +00:00
|
|
|
ogs_debug("Session Modification Response");
|
|
|
|
|
2020-08-13 00:31:22 +00:00
|
|
|
ogs_assert(pfcp_xact);
|
|
|
|
ogs_assert(pfcp_rsp);
|
|
|
|
|
|
|
|
flags = pfcp_xact->modify_flags;
|
|
|
|
ogs_assert(flags);
|
|
|
|
|
2022-04-12 22:07:39 +00:00
|
|
|
cause_value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED;
|
2020-08-13 00:31:22 +00:00
|
|
|
|
2020-11-07 22:27:12 +00:00
|
|
|
if (flags & OGS_PFCP_MODIFY_SESSION) {
|
2022-06-30 00:11:38 +00:00
|
|
|
if (!sess) {
|
|
|
|
ogs_warn("No Context");
|
|
|
|
|
|
|
|
sess = pfcp_xact->data;
|
|
|
|
ogs_assert(sess);
|
|
|
|
|
|
|
|
cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND;
|
|
|
|
}
|
2020-11-07 22:27:12 +00:00
|
|
|
sgwc_ue = sess->sgwc_ue;
|
|
|
|
ogs_assert(sgwc_ue);
|
|
|
|
|
|
|
|
} else {
|
|
|
|
bearer = pfcp_xact->data;
|
|
|
|
ogs_assert(bearer);
|
2022-06-30 00:11:38 +00:00
|
|
|
|
|
|
|
if (!sess) {
|
|
|
|
ogs_warn("No Context");
|
|
|
|
|
|
|
|
sess = bearer->sess;
|
|
|
|
ogs_assert(sess);
|
|
|
|
|
|
|
|
cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND;
|
|
|
|
}
|
|
|
|
|
2020-11-07 22:27:12 +00:00
|
|
|
sgwc_ue = bearer->sgwc_ue;
|
|
|
|
ogs_assert(sgwc_ue);
|
2020-08-13 00:31:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (pfcp_rsp->cause.presence) {
|
|
|
|
if (pfcp_rsp->cause.u8 != OGS_PFCP_CAUSE_REQUEST_ACCEPTED) {
|
|
|
|
ogs_warn("PFCP Cause [%d] : Not Accepted", pfcp_rsp->cause.u8);
|
|
|
|
cause_value = gtp_cause_from_pfcp(pfcp_rsp->cause.u8);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
ogs_error("No Cause");
|
2022-04-12 22:07:39 +00:00
|
|
|
cause_value = OGS_GTP2_CAUSE_MANDATORY_IE_MISSING;
|
2020-08-13 00:31:22 +00:00
|
|
|
}
|
|
|
|
|
2022-04-12 22:07:39 +00:00
|
|
|
if (cause_value == OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
2020-10-26 02:43:53 +00:00
|
|
|
uint8_t pfcp_cause_value = OGS_PFCP_CAUSE_REQUEST_ACCEPTED;
|
|
|
|
uint8_t offending_ie_value = 0;
|
|
|
|
|
2022-04-16 05:08:56 +00:00
|
|
|
sgwc_tunnel_t *tunnel = NULL;
|
|
|
|
ogs_pfcp_pdr_t *pdr = NULL;
|
|
|
|
ogs_pfcp_far_t *far = NULL;
|
|
|
|
|
2022-05-15 14:35:41 +00:00
|
|
|
OGS_LIST(pdr_to_create_list);
|
|
|
|
|
2021-03-15 01:01:55 +00:00
|
|
|
ogs_assert(sess);
|
2020-10-26 02:43:53 +00:00
|
|
|
|
2022-04-16 05:08:56 +00:00
|
|
|
ogs_list_copy(&pdr_to_create_list, &pfcp_xact->pdr_to_create_list);
|
|
|
|
|
|
|
|
for (i = 0; i < OGS_MAX_NUM_OF_PDR; i++) {
|
2020-10-26 02:43:53 +00:00
|
|
|
pdr = ogs_pfcp_handle_created_pdr(
|
|
|
|
&sess->pfcp, &pfcp_rsp->created_pdr[i],
|
|
|
|
&pfcp_cause_value, &offending_ie_value);
|
|
|
|
|
|
|
|
if (!pdr)
|
|
|
|
break;
|
2022-04-16 05:08:56 +00:00
|
|
|
}
|
2020-10-26 02:43:53 +00:00
|
|
|
|
2022-04-16 05:08:56 +00:00
|
|
|
ogs_list_for_each_entry(&pdr_to_create_list, pdr, to_create_node) {
|
2021-03-15 01:01:55 +00:00
|
|
|
far = pdr->far;
|
|
|
|
ogs_assert(far);
|
|
|
|
|
|
|
|
if (pdr->src_if == OGS_PFCP_INTERFACE_CP_FUNCTION)
|
2021-06-06 13:35:46 +00:00
|
|
|
ogs_assert(OGS_ERROR != ogs_pfcp_setup_pdr_gtpu_node(pdr));
|
2020-10-26 02:43:53 +00:00
|
|
|
|
2021-03-15 01:01:55 +00:00
|
|
|
if (far->dst_if == OGS_PFCP_INTERFACE_CP_FUNCTION)
|
|
|
|
ogs_pfcp_far_teid_hash_set(far);
|
|
|
|
|
|
|
|
tunnel = sgwc_tunnel_find_by_pdr_id(sess, pdr->id);
|
|
|
|
if (tunnel) {
|
|
|
|
ogs_assert(sess->pfcp_node);
|
|
|
|
if (sess->pfcp_node->up_function_features.ftup &&
|
|
|
|
pdr->f_teid_len) {
|
|
|
|
if (tunnel->local_addr)
|
|
|
|
ogs_freeaddrinfo(tunnel->local_addr);
|
|
|
|
if (tunnel->local_addr6)
|
|
|
|
ogs_freeaddrinfo(tunnel->local_addr6);
|
|
|
|
|
2021-06-06 13:35:46 +00:00
|
|
|
ogs_assert(OGS_OK ==
|
|
|
|
ogs_pfcp_f_teid_to_sockaddr(
|
2021-03-15 01:01:55 +00:00
|
|
|
&pdr->f_teid, pdr->f_teid_len,
|
2021-06-06 13:35:46 +00:00
|
|
|
&tunnel->local_addr, &tunnel->local_addr6));
|
2021-03-15 01:01:55 +00:00
|
|
|
tunnel->local_teid = pdr->f_teid.teid;
|
|
|
|
}
|
2020-10-26 02:43:53 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
cause_value = gtp_cause_from_pfcp(pfcp_cause_value);
|
|
|
|
}
|
|
|
|
|
2022-04-12 22:07:39 +00:00
|
|
|
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
2021-02-01 04:01:15 +00:00
|
|
|
/*
|
|
|
|
* You should not change the following order to support
|
|
|
|
* OGS_PFCP_MODIFY_REMOVE|OGS_PFCP_MODIFY_CREATE.
|
|
|
|
*
|
|
|
|
* 1. if (flags & OGS_PFCP_MODIFY_REMOVE) {
|
|
|
|
* 2. } else if (flags & OGS_PFCP_MODIFY_CREATE) {
|
|
|
|
* }
|
|
|
|
*/
|
|
|
|
if (flags & OGS_PFCP_MODIFY_REMOVE) {
|
2020-08-13 00:31:22 +00:00
|
|
|
s5c_xact = pfcp_xact->assoc_xact;
|
|
|
|
|
2020-11-07 22:27:12 +00:00
|
|
|
if (s5c_xact) {
|
|
|
|
ogs_gtp_send_error_message(
|
|
|
|
s5c_xact, sess ? sess->pgw_s5c_teid : 0,
|
2022-04-12 22:07:39 +00:00
|
|
|
OGS_GTP2_DELETE_BEARER_RESPONSE_TYPE, cause_value);
|
2020-11-07 22:27:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
sgwc_bearer_remove(bearer);
|
2021-02-01 04:01:15 +00:00
|
|
|
} else if (flags & OGS_PFCP_MODIFY_CREATE) {
|
|
|
|
s5c_xact = pfcp_xact->assoc_xact;
|
|
|
|
ogs_assert(s5c_xact);
|
|
|
|
|
|
|
|
ogs_gtp_send_error_message(
|
|
|
|
s5c_xact, sess ? sess->pgw_s5c_teid : 0,
|
2022-04-12 22:07:39 +00:00
|
|
|
OGS_GTP2_CREATE_BEARER_RESPONSE_TYPE, cause_value);
|
2021-02-01 04:01:15 +00:00
|
|
|
|
2020-08-13 00:31:22 +00:00
|
|
|
|
|
|
|
} else if (flags & OGS_PFCP_MODIFY_ACTIVATE) {
|
|
|
|
if (flags & OGS_PFCP_MODIFY_UL_ONLY) {
|
|
|
|
s11_xact = pfcp_xact->assoc_xact;
|
|
|
|
ogs_assert(s11_xact);
|
|
|
|
|
|
|
|
ogs_gtp_send_error_message(
|
|
|
|
s11_xact, 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
|
|
|
|
|
|
|
} else if (flags & OGS_PFCP_MODIFY_DL_ONLY) {
|
|
|
|
s11_xact = pfcp_xact->assoc_xact;
|
|
|
|
ogs_assert(s11_xact);
|
|
|
|
|
|
|
|
ogs_gtp_send_error_message(
|
|
|
|
s11_xact, sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
|
2022-04-12 22:07:39 +00:00
|
|
|
OGS_GTP2_MODIFY_BEARER_RESPONSE_TYPE, cause_value);
|
2020-08-13 00:31:22 +00:00
|
|
|
} else {
|
|
|
|
ogs_fatal("Invalid modify_flags[0x%llx]", (long long)flags);
|
|
|
|
ogs_assert_if_reached();
|
|
|
|
}
|
|
|
|
} else if (flags & OGS_PFCP_MODIFY_DEACTIVATE) {
|
|
|
|
s11_xact = pfcp_xact->assoc_xact;
|
|
|
|
ogs_assert(s11_xact);
|
|
|
|
|
|
|
|
ogs_gtp_send_error_message(
|
|
|
|
s11_xact, sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
|
2022-04-12 22:07:39 +00:00
|
|
|
OGS_GTP2_RELEASE_ACCESS_BEARERS_RESPONSE_TYPE, cause_value);
|
2020-08-13 00:31:22 +00:00
|
|
|
}
|
|
|
|
|
2020-09-22 03:07:08 +00:00
|
|
|
ogs_pfcp_xact_commit(pfcp_xact);
|
2020-08-13 00:31:22 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-03-03 14:17:28 +00:00
|
|
|
if (flags & OGS_PFCP_MODIFY_SESSION) {
|
|
|
|
|
|
|
|
/* Nothing */
|
|
|
|
|
|
|
|
} else {
|
|
|
|
ogs_assert(bearer);
|
|
|
|
|
|
|
|
dl_tunnel = sgwc_dl_tunnel_in_bearer(bearer);
|
|
|
|
ogs_assert(dl_tunnel);
|
|
|
|
ul_tunnel = sgwc_ul_tunnel_in_bearer(bearer);
|
|
|
|
ogs_assert(ul_tunnel);
|
|
|
|
}
|
|
|
|
|
2021-02-01 04:01:15 +00:00
|
|
|
/*
|
|
|
|
* You should not change the following order to support
|
|
|
|
* OGS_PFCP_MODIFY_REMOVE|OGS_PFCP_MODIFY_CREATE.
|
|
|
|
*
|
|
|
|
* 1. if (flags & OGS_PFCP_MODIFY_REMOVE) {
|
|
|
|
* 2. } else if (flags & OGS_PFCP_MODIFY_CREATE) {
|
|
|
|
* }
|
|
|
|
*/
|
|
|
|
if (flags & OGS_PFCP_MODIFY_REMOVE) {
|
|
|
|
if (flags & OGS_PFCP_MODIFY_INDIRECT) {
|
|
|
|
s11_xact = pfcp_xact->assoc_xact;
|
|
|
|
ogs_assert(s11_xact);
|
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
ogs_pfcp_xact_commit(pfcp_xact);
|
2021-02-01 04:01:15 +00:00
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
ogs_assert(flags & OGS_PFCP_MODIFY_SESSION);
|
2022-05-12 13:52:36 +00:00
|
|
|
if (SGWC_SESSION_SYNC_DONE(sgwc_ue,
|
2022-04-29 12:28:16 +00:00
|
|
|
OGS_PFCP_SESSION_MODIFICATION_REQUEST_TYPE, flags)) {
|
2021-02-01 04:01:15 +00:00
|
|
|
|
|
|
|
sgwc_tunnel_t *tunnel = NULL, *next_tunnel = NULL;
|
2022-04-12 22:07:39 +00:00
|
|
|
ogs_gtp2_delete_indirect_data_forwarding_tunnel_response_t
|
2021-02-01 04:01:15 +00:00
|
|
|
*gtp_rsp = NULL;
|
|
|
|
|
|
|
|
ogs_list_for_each(&sgwc_ue->sess_list, sess) {
|
|
|
|
ogs_list_for_each(&sess->bearer_list, bearer) {
|
|
|
|
ogs_list_for_each_safe(&bearer->tunnel_list,
|
|
|
|
next_tunnel, tunnel) {
|
|
|
|
if (tunnel->interface_type ==
|
2022-04-12 22:07:39 +00:00
|
|
|
OGS_GTP2_F_TEID_SGW_GTP_U_FOR_DL_DATA_FORWARDING ||
|
2021-02-01 04:01:15 +00:00
|
|
|
tunnel->interface_type ==
|
2022-04-12 22:07:39 +00:00
|
|
|
OGS_GTP2_F_TEID_SGW_GTP_U_FOR_UL_DATA_FORWARDING) {
|
2021-02-01 04:01:15 +00:00
|
|
|
sgwc_tunnel_remove(tunnel);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
gtp_rsp = &send_message.
|
|
|
|
delete_indirect_data_forwarding_tunnel_response;
|
|
|
|
ogs_assert(gtp_rsp);
|
|
|
|
|
2022-04-12 22:07:39 +00:00
|
|
|
memset(&send_message, 0, sizeof(ogs_gtp2_message_t));
|
2021-02-01 04:01:15 +00:00
|
|
|
|
|
|
|
memset(&cause, 0, sizeof(cause));
|
2022-04-12 22:07:39 +00:00
|
|
|
cause.value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED;
|
2021-02-01 04:01:15 +00:00
|
|
|
|
|
|
|
gtp_rsp->cause.presence = 1;
|
|
|
|
gtp_rsp->cause.data = &cause;
|
|
|
|
gtp_rsp->cause.len = sizeof(cause);
|
|
|
|
|
|
|
|
send_message.h.type =
|
2022-04-12 22:07:39 +00:00
|
|
|
OGS_GTP2_DELETE_INDIRECT_DATA_FORWARDING_TUNNEL_RESPONSE_TYPE;
|
2021-02-01 04:01:15 +00:00
|
|
|
send_message.h.teid = sgwc_ue->mme_s11_teid;
|
|
|
|
|
2022-04-12 22:07:39 +00:00
|
|
|
pkbuf = ogs_gtp2_build_msg(&send_message);
|
2021-02-01 04:01:15 +00:00
|
|
|
ogs_expect_or_return(pkbuf);
|
|
|
|
|
|
|
|
rv = ogs_gtp_xact_update_tx(s11_xact, &send_message.h, pkbuf);
|
|
|
|
ogs_expect_or_return(rv == OGS_OK);
|
|
|
|
|
|
|
|
rv = ogs_gtp_xact_commit(s11_xact);
|
|
|
|
ogs_expect(rv == OGS_OK);
|
|
|
|
}
|
|
|
|
|
|
|
|
} else {
|
|
|
|
s5c_xact = pfcp_xact->assoc_xact;
|
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
ogs_pfcp_xact_commit(pfcp_xact);
|
|
|
|
|
2021-02-01 04:01:15 +00:00
|
|
|
if (s5c_xact) {
|
|
|
|
ogs_assert(recv_message);
|
2022-04-12 22:07:39 +00:00
|
|
|
recv_message->h.type = OGS_GTP2_DELETE_BEARER_RESPONSE_TYPE;
|
2021-02-01 04:01:15 +00:00
|
|
|
recv_message->h.teid = sess->pgw_s5c_teid;
|
|
|
|
|
2022-04-12 22:07:39 +00:00
|
|
|
pkbuf = ogs_gtp2_build_msg(recv_message);
|
2021-02-01 04:01:15 +00:00
|
|
|
ogs_expect_or_return(pkbuf);
|
|
|
|
|
|
|
|
rv = ogs_gtp_xact_update_tx(s5c_xact, &recv_message->h, pkbuf);
|
|
|
|
ogs_expect_or_return(rv == OGS_OK);
|
|
|
|
|
|
|
|
rv = ogs_gtp_xact_commit(s5c_xact);
|
|
|
|
ogs_expect(rv == OGS_OK);
|
|
|
|
}
|
|
|
|
|
|
|
|
sgwc_bearer_remove(bearer);
|
|
|
|
}
|
|
|
|
|
|
|
|
} else if (flags & OGS_PFCP_MODIFY_CREATE) {
|
2020-08-13 00:31:22 +00:00
|
|
|
if (flags & OGS_PFCP_MODIFY_UL_ONLY) {
|
2022-04-12 22:07:39 +00:00
|
|
|
ogs_gtp2_create_bearer_request_t *gtp_req = NULL;
|
|
|
|
ogs_gtp2_f_teid_t sgw_s1u_teid;
|
2020-08-13 00:31:22 +00:00
|
|
|
|
|
|
|
s5c_xact = pfcp_xact->assoc_xact;
|
|
|
|
ogs_assert(s5c_xact);
|
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
ogs_pfcp_xact_commit(pfcp_xact);
|
|
|
|
|
2020-10-21 00:00:02 +00:00
|
|
|
ogs_assert(recv_message);
|
2020-08-13 00:31:22 +00:00
|
|
|
gtp_req = &recv_message->create_bearer_request;
|
|
|
|
ogs_assert(gtp_req);
|
|
|
|
|
|
|
|
/* Send Data Plane(UL) : SGW-S1U */
|
2022-04-12 22:07:39 +00:00
|
|
|
memset(&sgw_s1u_teid, 0, sizeof(ogs_gtp2_f_teid_t));
|
2020-08-13 00:31:22 +00:00
|
|
|
sgw_s1u_teid.interface_type = ul_tunnel->interface_type;
|
|
|
|
sgw_s1u_teid.teid = htobe32(ul_tunnel->local_teid);
|
2020-10-26 02:43:53 +00:00
|
|
|
ogs_assert(ul_tunnel->local_addr || ul_tunnel->local_addr6);
|
2022-04-12 22:07:39 +00:00
|
|
|
rv = ogs_gtp2_sockaddr_to_f_teid(
|
2020-08-13 00:31:22 +00:00
|
|
|
ul_tunnel->local_addr, ul_tunnel->local_addr6,
|
|
|
|
&sgw_s1u_teid, &len);
|
2021-06-06 13:35:46 +00:00
|
|
|
ogs_assert(rv == OGS_OK);
|
2020-08-13 00:31:22 +00:00
|
|
|
gtp_req->bearer_contexts.s1_u_enodeb_f_teid.presence = 1;
|
|
|
|
gtp_req->bearer_contexts.s1_u_enodeb_f_teid.data = &sgw_s1u_teid;
|
|
|
|
gtp_req->bearer_contexts.s1_u_enodeb_f_teid.len = len;
|
|
|
|
|
2022-04-12 22:07:39 +00:00
|
|
|
recv_message->h.type = OGS_GTP2_CREATE_BEARER_REQUEST_TYPE;
|
2020-08-13 00:31:22 +00:00
|
|
|
recv_message->h.teid = sgwc_ue->mme_s11_teid;
|
|
|
|
|
2022-04-12 22:07:39 +00:00
|
|
|
pkbuf = ogs_gtp2_build_msg(recv_message);
|
2020-08-13 00:31:22 +00:00
|
|
|
ogs_expect_or_return(pkbuf);
|
|
|
|
|
2020-09-22 18:03:45 +00:00
|
|
|
ogs_assert(sgwc_ue->gnode);
|
2020-11-07 22:27:12 +00:00
|
|
|
ogs_assert(bearer);
|
|
|
|
s11_xact = ogs_gtp_xact_local_create(sgwc_ue->gnode,
|
|
|
|
&recv_message->h, pkbuf, bearer_timeout, bearer);
|
2020-08-13 00:31:22 +00:00
|
|
|
ogs_expect_or_return(s11_xact);
|
|
|
|
|
|
|
|
ogs_gtp_xact_associate(s5c_xact, s11_xact);
|
|
|
|
|
|
|
|
rv = ogs_gtp_xact_commit(s11_xact);
|
|
|
|
ogs_expect(rv == OGS_OK);
|
|
|
|
|
|
|
|
} else if (flags & OGS_PFCP_MODIFY_DL_ONLY) {
|
2022-04-12 22:07:39 +00:00
|
|
|
ogs_gtp2_create_bearer_response_t *gtp_rsp = NULL;
|
|
|
|
ogs_gtp2_f_teid_t sgw_s5u_teid, pgw_s5u_teid;
|
2020-08-13 00:31:22 +00:00
|
|
|
|
|
|
|
s5c_xact = pfcp_xact->assoc_xact;
|
|
|
|
ogs_assert(s5c_xact);
|
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
ogs_pfcp_xact_commit(pfcp_xact);
|
|
|
|
|
2020-10-21 00:00:02 +00:00
|
|
|
ogs_assert(recv_message);
|
2020-08-13 00:31:22 +00:00
|
|
|
gtp_rsp = &recv_message->create_bearer_response;
|
|
|
|
ogs_assert(gtp_rsp);
|
|
|
|
|
|
|
|
/* Remove SGW-S1U-TEID */
|
|
|
|
gtp_rsp->bearer_contexts.s4_u_sgsn_f_teid.presence = 0;
|
|
|
|
|
|
|
|
/* Remove S1U-F-TEID */
|
|
|
|
gtp_rsp->bearer_contexts.s1_u_enodeb_f_teid.presence = 0;
|
|
|
|
|
|
|
|
/* Data Plane(DL) : SGW-S5U */
|
2022-03-03 14:17:28 +00:00
|
|
|
ogs_assert(dl_tunnel);
|
2022-04-12 22:07:39 +00:00
|
|
|
memset(&sgw_s5u_teid, 0, sizeof(ogs_gtp2_f_teid_t));
|
|
|
|
sgw_s5u_teid.interface_type = OGS_GTP2_F_TEID_S5_S8_SGW_GTP_U;
|
2020-08-13 00:31:22 +00:00
|
|
|
sgw_s5u_teid.teid = htobe32(dl_tunnel->local_teid);
|
2020-10-26 02:43:53 +00:00
|
|
|
ogs_assert(dl_tunnel->local_addr || dl_tunnel->local_addr6);
|
2022-04-12 22:07:39 +00:00
|
|
|
rv = ogs_gtp2_sockaddr_to_f_teid(
|
2020-08-13 00:31:22 +00:00
|
|
|
dl_tunnel->local_addr, dl_tunnel->local_addr6,
|
|
|
|
&sgw_s5u_teid, &len);
|
2021-06-06 13:35:46 +00:00
|
|
|
ogs_assert(rv == OGS_OK);
|
2020-08-13 00:31:22 +00:00
|
|
|
gtp_rsp->bearer_contexts.s5_s8_u_sgw_f_teid.presence = 1;
|
|
|
|
gtp_rsp->bearer_contexts.s5_s8_u_sgw_f_teid.data = &sgw_s5u_teid;
|
|
|
|
gtp_rsp->bearer_contexts.s5_s8_u_sgw_f_teid.len = len;
|
|
|
|
|
|
|
|
/* Data Plane(UL) : PGW-S5U */
|
2022-03-03 14:17:28 +00:00
|
|
|
ogs_assert(ul_tunnel);
|
2022-04-12 22:07:39 +00:00
|
|
|
pgw_s5u_teid.interface_type = OGS_GTP2_F_TEID_S5_S8_PGW_GTP_U;
|
2020-08-13 00:31:22 +00:00
|
|
|
pgw_s5u_teid.teid = htobe32(ul_tunnel->remote_teid);
|
2022-04-12 22:07:39 +00:00
|
|
|
rv = ogs_gtp2_ip_to_f_teid(
|
2020-08-13 00:31:22 +00:00
|
|
|
&ul_tunnel->remote_ip, &pgw_s5u_teid, &len);
|
|
|
|
gtp_rsp->bearer_contexts.s5_s8_u_pgw_f_teid.presence = 1;
|
|
|
|
gtp_rsp->bearer_contexts.s5_s8_u_pgw_f_teid.data = &pgw_s5u_teid;
|
|
|
|
gtp_rsp->bearer_contexts.s5_s8_u_pgw_f_teid.len = len;
|
|
|
|
|
2022-04-12 22:07:39 +00:00
|
|
|
recv_message->h.type = OGS_GTP2_CREATE_BEARER_RESPONSE_TYPE;
|
2020-08-13 00:31:22 +00:00
|
|
|
recv_message->h.teid = sess->pgw_s5c_teid;
|
|
|
|
|
2022-04-12 22:07:39 +00:00
|
|
|
pkbuf = ogs_gtp2_build_msg(recv_message);
|
2020-08-13 00:31:22 +00:00
|
|
|
ogs_expect_or_return(pkbuf);
|
|
|
|
|
|
|
|
rv = ogs_gtp_xact_update_tx(s5c_xact, &recv_message->h, pkbuf);
|
|
|
|
ogs_expect_or_return(rv == OGS_OK);
|
|
|
|
|
|
|
|
rv = ogs_gtp_xact_commit(s5c_xact);
|
|
|
|
ogs_expect(rv == OGS_OK);
|
|
|
|
|
|
|
|
} else if (flags & OGS_PFCP_MODIFY_INDIRECT) {
|
|
|
|
s11_xact = pfcp_xact->assoc_xact;
|
|
|
|
ogs_assert(s11_xact);
|
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
ogs_pfcp_xact_commit(pfcp_xact);
|
2020-08-13 00:31:22 +00:00
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
ogs_assert(flags & OGS_PFCP_MODIFY_SESSION);
|
2022-05-12 13:52:36 +00:00
|
|
|
if (SGWC_SESSION_SYNC_DONE(sgwc_ue,
|
2022-04-29 12:28:16 +00:00
|
|
|
OGS_PFCP_SESSION_MODIFICATION_REQUEST_TYPE, flags)) {
|
2020-08-13 00:31:22 +00:00
|
|
|
|
|
|
|
sgwc_tunnel_t *tunnel = NULL;
|
|
|
|
|
2022-04-12 22:07:39 +00:00
|
|
|
ogs_gtp2_create_indirect_data_forwarding_tunnel_request_t
|
2020-08-13 00:31:22 +00:00
|
|
|
*gtp_req = NULL;
|
2022-04-12 22:07:39 +00:00
|
|
|
ogs_gtp2_create_indirect_data_forwarding_tunnel_response_t
|
2020-08-13 00:31:22 +00:00
|
|
|
*gtp_rsp = NULL;
|
|
|
|
|
2022-04-12 22:07:39 +00:00
|
|
|
ogs_gtp2_f_teid_t rsp_dl_teid[OGS_GTP2_MAX_INDIRECT_TUNNEL];
|
|
|
|
ogs_gtp2_f_teid_t rsp_ul_teid[OGS_GTP2_MAX_INDIRECT_TUNNEL];
|
2020-08-13 00:31:22 +00:00
|
|
|
|
2020-10-21 00:00:02 +00:00
|
|
|
ogs_assert(recv_message);
|
2020-08-13 00:31:22 +00:00
|
|
|
gtp_req = &recv_message->
|
|
|
|
create_indirect_data_forwarding_tunnel_request;
|
|
|
|
ogs_assert(gtp_req);
|
|
|
|
gtp_rsp = &send_message.
|
|
|
|
create_indirect_data_forwarding_tunnel_response;
|
|
|
|
ogs_assert(gtp_rsp);
|
|
|
|
|
2022-04-12 22:07:39 +00:00
|
|
|
memset(&send_message, 0, sizeof(ogs_gtp2_message_t));
|
2020-08-13 00:31:22 +00:00
|
|
|
|
|
|
|
memset(&cause, 0, sizeof(cause));
|
2022-04-12 22:07:39 +00:00
|
|
|
cause.value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED;
|
2020-08-13 00:31:22 +00:00
|
|
|
|
|
|
|
gtp_rsp->cause.presence = 1;
|
|
|
|
gtp_rsp->cause.data = &cause;
|
|
|
|
gtp_rsp->cause.len = sizeof(cause);
|
|
|
|
|
|
|
|
for (i = 0; gtp_req->bearer_contexts[i].presence; i++) {
|
|
|
|
ogs_assert(gtp_req->
|
|
|
|
bearer_contexts[i].eps_bearer_id.presence);
|
|
|
|
bearer = sgwc_bearer_find_by_ue_ebi(sgwc_ue,
|
|
|
|
gtp_req->bearer_contexts[i].eps_bearer_id.u8);
|
|
|
|
ogs_assert(bearer);
|
|
|
|
|
|
|
|
ogs_list_for_each(&bearer->tunnel_list, tunnel) {
|
|
|
|
if (tunnel->interface_type ==
|
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
|
|
|
|
|
|
|
memset(&rsp_dl_teid[i],
|
2022-04-12 22:07:39 +00:00
|
|
|
0, sizeof(ogs_gtp2_f_teid_t));
|
2020-08-13 00:31:22 +00:00
|
|
|
rsp_dl_teid[i].interface_type =
|
|
|
|
tunnel->interface_type;
|
|
|
|
rsp_dl_teid[i].teid = htobe32(tunnel->local_teid);
|
2020-10-26 02:43:53 +00:00
|
|
|
ogs_assert(
|
|
|
|
tunnel->local_addr || tunnel->local_addr6);
|
2022-04-12 22:07:39 +00:00
|
|
|
rv = ogs_gtp2_sockaddr_to_f_teid(
|
2020-08-13 00:31:22 +00:00
|
|
|
tunnel->local_addr, tunnel->local_addr6,
|
|
|
|
&rsp_dl_teid[i], &len);
|
2021-06-06 13:35:46 +00:00
|
|
|
ogs_assert(rv == OGS_OK);
|
2020-08-13 00:31:22 +00:00
|
|
|
gtp_rsp->bearer_contexts[i].
|
|
|
|
s4_u_sgsn_f_teid.presence = 1;
|
|
|
|
gtp_rsp->bearer_contexts[i].
|
|
|
|
s4_u_sgsn_f_teid.data = &rsp_dl_teid[i];
|
|
|
|
gtp_rsp->bearer_contexts[i].
|
|
|
|
s4_u_sgsn_f_teid.len = len;
|
|
|
|
|
|
|
|
} else if (tunnel->interface_type ==
|
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
|
|
|
|
|
|
|
memset(&rsp_ul_teid[i],
|
2022-04-12 22:07:39 +00:00
|
|
|
0, sizeof(ogs_gtp2_f_teid_t));
|
2020-08-13 00:31:22 +00:00
|
|
|
rsp_ul_teid[i].teid = htobe32(tunnel->local_teid);
|
|
|
|
rsp_ul_teid[i].interface_type =
|
|
|
|
tunnel->interface_type;
|
2020-10-26 02:43:53 +00:00
|
|
|
ogs_assert(
|
|
|
|
tunnel->local_addr || tunnel->local_addr6);
|
2022-04-12 22:07:39 +00:00
|
|
|
rv = ogs_gtp2_sockaddr_to_f_teid(
|
2020-08-13 00:31:22 +00:00
|
|
|
tunnel->local_addr, tunnel->local_addr6,
|
|
|
|
&rsp_ul_teid[i], &len);
|
2021-06-06 13:35:46 +00:00
|
|
|
ogs_assert(rv == OGS_OK);
|
2020-08-13 00:31:22 +00:00
|
|
|
gtp_rsp->bearer_contexts[i].
|
|
|
|
s2b_u_epdg_f_teid_5.presence = 1;
|
|
|
|
gtp_rsp->bearer_contexts[i].
|
|
|
|
s2b_u_epdg_f_teid_5.data = &rsp_ul_teid[i];
|
|
|
|
gtp_rsp->bearer_contexts[i].
|
|
|
|
s2b_u_epdg_f_teid_5.len = len;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (gtp_rsp->bearer_contexts[i].
|
|
|
|
s4_u_sgsn_f_teid.presence ||
|
|
|
|
gtp_rsp->bearer_contexts[i].
|
|
|
|
s2b_u_epdg_f_teid_5.presence) {
|
|
|
|
|
|
|
|
gtp_rsp->bearer_contexts[i].presence = 1;
|
|
|
|
gtp_rsp->bearer_contexts[i].eps_bearer_id.presence = 1;
|
|
|
|
gtp_rsp->bearer_contexts[i].eps_bearer_id.u8 =
|
|
|
|
bearer->ebi;
|
|
|
|
|
|
|
|
gtp_rsp->bearer_contexts[i].cause.presence = 1;
|
|
|
|
gtp_rsp->bearer_contexts[i].cause.data = &cause;
|
|
|
|
gtp_rsp->bearer_contexts[i].cause.len = sizeof(cause);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
send_message.h.type =
|
2022-04-12 22:07:39 +00:00
|
|
|
OGS_GTP2_CREATE_INDIRECT_DATA_FORWARDING_TUNNEL_RESPONSE_TYPE;
|
2020-08-13 00:31:22 +00:00
|
|
|
send_message.h.teid = sgwc_ue->mme_s11_teid;
|
|
|
|
|
2022-04-12 22:07:39 +00:00
|
|
|
pkbuf = ogs_gtp2_build_msg(&send_message);
|
2020-08-13 00:31:22 +00:00
|
|
|
ogs_expect_or_return(pkbuf);
|
|
|
|
|
|
|
|
rv = ogs_gtp_xact_update_tx(s11_xact, &send_message.h, pkbuf);
|
|
|
|
ogs_expect_or_return(rv == OGS_OK);
|
|
|
|
|
|
|
|
rv = ogs_gtp_xact_commit(s11_xact);
|
|
|
|
ogs_expect(rv == OGS_OK);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
ogs_fatal("Invalid modify_flags[0x%llx]", (long long)flags);
|
|
|
|
ogs_assert_if_reached();
|
|
|
|
}
|
|
|
|
|
|
|
|
} else if (flags & OGS_PFCP_MODIFY_ACTIVATE) {
|
2022-05-15 14:35:41 +00:00
|
|
|
OGS_LIST(bearer_to_modify_list);
|
|
|
|
|
2020-08-13 00:31:22 +00:00
|
|
|
s11_xact = pfcp_xact->assoc_xact;
|
|
|
|
ogs_assert(s11_xact);
|
|
|
|
|
2022-05-15 14:35:41 +00:00
|
|
|
ogs_list_copy(&bearer_to_modify_list,
|
|
|
|
&pfcp_xact->bearer_to_modify_list);
|
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
ogs_pfcp_xact_commit(pfcp_xact);
|
|
|
|
|
2022-05-12 13:52:36 +00:00
|
|
|
ogs_assert(flags & OGS_PFCP_MODIFY_SESSION);
|
2020-08-13 00:31:22 +00:00
|
|
|
if (flags & OGS_PFCP_MODIFY_UL_ONLY) {
|
2022-04-12 22:07:39 +00:00
|
|
|
ogs_gtp2_create_session_response_t *gtp_rsp = NULL;
|
|
|
|
ogs_gtp2_f_teid_t sgw_s11_teid;
|
2022-05-12 13:52:36 +00:00
|
|
|
ogs_gtp2_f_teid_t sgw_s1u_teid[OGS_BEARER_PER_UE];
|
|
|
|
int sgw_s1u_len[OGS_BEARER_PER_UE];
|
2020-08-13 00:31:22 +00:00
|
|
|
|
2020-10-21 00:00:02 +00:00
|
|
|
ogs_assert(recv_message);
|
2020-08-13 00:31:22 +00:00
|
|
|
gtp_rsp = &recv_message->create_session_response;
|
|
|
|
ogs_assert(gtp_rsp);
|
|
|
|
|
|
|
|
/* Send Control Plane(UL) : SGW-S11 */
|
2022-04-12 22:07:39 +00:00
|
|
|
memset(&sgw_s11_teid, 0, sizeof(ogs_gtp2_f_teid_t));
|
|
|
|
sgw_s11_teid.interface_type = OGS_GTP2_F_TEID_S11_S4_SGW_GTP_C;
|
2020-08-13 00:31:22 +00:00
|
|
|
sgw_s11_teid.teid = htobe32(sgwc_ue->sgw_s11_teid);
|
2022-04-12 22:07:39 +00:00
|
|
|
rv = ogs_gtp2_sockaddr_to_f_teid(
|
2021-03-15 01:01:55 +00:00
|
|
|
ogs_gtp_self()->gtpc_addr, ogs_gtp_self()->gtpc_addr6,
|
2020-08-13 00:31:22 +00:00
|
|
|
&sgw_s11_teid, &len);
|
2021-06-06 13:35:46 +00:00
|
|
|
ogs_assert(rv == OGS_OK);
|
2020-08-13 00:31:22 +00:00
|
|
|
gtp_rsp->sender_f_teid_for_control_plane.presence = 1;
|
|
|
|
gtp_rsp->sender_f_teid_for_control_plane.data = &sgw_s11_teid;
|
|
|
|
gtp_rsp->sender_f_teid_for_control_plane.len = len;
|
|
|
|
|
|
|
|
/* Send Data Plane(UL) : SGW-S1U */
|
2022-05-12 13:52:36 +00:00
|
|
|
i = 0;
|
2022-05-15 14:35:41 +00:00
|
|
|
ogs_list_for_each_entry(
|
|
|
|
&bearer_to_modify_list, bearer, to_modify_node) {
|
2022-05-12 13:52:36 +00:00
|
|
|
ogs_assert(i < OGS_BEARER_PER_UE);
|
|
|
|
|
|
|
|
ul_tunnel = sgwc_ul_tunnel_in_bearer(bearer);
|
|
|
|
ogs_assert(ul_tunnel);
|
|
|
|
|
|
|
|
memset(&sgw_s1u_teid[i], 0, sizeof(ogs_gtp2_f_teid_t));
|
|
|
|
sgw_s1u_teid[i].interface_type = ul_tunnel->interface_type;
|
|
|
|
sgw_s1u_teid[i].teid = htobe32(ul_tunnel->local_teid);
|
|
|
|
ogs_assert(ul_tunnel->local_addr || ul_tunnel->local_addr6);
|
|
|
|
rv = ogs_gtp2_sockaddr_to_f_teid(
|
|
|
|
ul_tunnel->local_addr, ul_tunnel->local_addr6,
|
|
|
|
&sgw_s1u_teid[i], &sgw_s1u_len[i]);
|
|
|
|
ogs_assert(rv == OGS_OK);
|
|
|
|
gtp_rsp->bearer_contexts_created[i].s1_u_enodeb_f_teid.
|
|
|
|
presence = 1;
|
|
|
|
gtp_rsp->bearer_contexts_created[i].s1_u_enodeb_f_teid.
|
|
|
|
data = &sgw_s1u_teid[i];
|
|
|
|
gtp_rsp->bearer_contexts_created[i].s1_u_enodeb_f_teid.
|
|
|
|
len = sgw_s1u_len[i];
|
|
|
|
|
|
|
|
i++;
|
|
|
|
}
|
2020-08-13 00:31:22 +00:00
|
|
|
|
2022-04-12 22:07:39 +00:00
|
|
|
recv_message->h.type = OGS_GTP2_CREATE_SESSION_RESPONSE_TYPE;
|
2020-08-13 00:31:22 +00:00
|
|
|
recv_message->h.teid = sgwc_ue->mme_s11_teid;
|
|
|
|
|
2022-04-12 22:07:39 +00:00
|
|
|
pkbuf = ogs_gtp2_build_msg(recv_message);
|
2020-08-13 00:31:22 +00:00
|
|
|
ogs_expect_or_return(pkbuf);
|
|
|
|
|
|
|
|
rv = ogs_gtp_xact_update_tx(s11_xact, &recv_message->h, pkbuf);
|
|
|
|
ogs_expect_or_return(rv == OGS_OK);
|
|
|
|
|
|
|
|
rv = ogs_gtp_xact_commit(s11_xact);
|
|
|
|
ogs_expect(rv == OGS_OK);
|
|
|
|
|
|
|
|
} else if (flags & OGS_PFCP_MODIFY_DL_ONLY) {
|
2022-05-12 13:52:36 +00:00
|
|
|
if (SGWC_SESSION_SYNC_DONE(sgwc_ue,
|
2022-04-29 12:28:16 +00:00
|
|
|
OGS_PFCP_SESSION_MODIFICATION_REQUEST_TYPE, flags)) {
|
|
|
|
ogs_gtp2_modify_bearer_request_t *gtp_req = NULL;
|
|
|
|
ogs_gtp2_modify_bearer_response_t *gtp_rsp = NULL;
|
2020-08-13 00:31:22 +00:00
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
ogs_gtp2_indication_t *indication = NULL;
|
2021-06-21 13:36:38 +00:00
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
ogs_assert(recv_message);
|
|
|
|
gtp_req = &recv_message->modify_bearer_request;
|
|
|
|
ogs_assert(gtp_req);
|
2020-08-13 00:31:22 +00:00
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
if (gtp_req->indication_flags.presence &&
|
|
|
|
gtp_req->indication_flags.data &&
|
|
|
|
gtp_req->indication_flags.len) {
|
|
|
|
indication = gtp_req->indication_flags.data;
|
|
|
|
}
|
2021-06-21 13:36:38 +00:00
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
if (indication && indication->handover_indication) {
|
|
|
|
recv_message->h.type = OGS_GTP2_MODIFY_BEARER_REQUEST_TYPE;
|
|
|
|
recv_message->h.teid = sess->pgw_s5c_teid;
|
2021-06-21 13:36:38 +00:00
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
pkbuf = ogs_gtp2_build_msg(recv_message);
|
|
|
|
ogs_expect_or_return(pkbuf);
|
2020-08-13 00:31:22 +00:00
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
ogs_assert(sess->gnode);
|
|
|
|
s5c_xact = ogs_gtp_xact_local_create(
|
|
|
|
sess->gnode, &recv_message->h, pkbuf,
|
|
|
|
sess_timeout, sess);
|
|
|
|
ogs_expect_or_return(s5c_xact);
|
2020-08-13 00:31:22 +00:00
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
ogs_gtp_xact_associate(s11_xact, s5c_xact);
|
2020-08-13 00:31:22 +00:00
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
rv = ogs_gtp_xact_commit(s5c_xact);
|
|
|
|
ogs_expect(rv == OGS_OK);
|
2021-06-21 13:36:38 +00:00
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
} else {
|
|
|
|
gtp_rsp = &send_message.modify_bearer_response;
|
|
|
|
ogs_assert(gtp_rsp);
|
2021-06-21 13:36:38 +00:00
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
memset(&send_message, 0, sizeof(ogs_gtp2_message_t));
|
2021-06-21 13:36:38 +00:00
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
memset(&cause, 0, sizeof(cause));
|
|
|
|
cause.value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED;
|
2021-06-21 13:36:38 +00:00
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
gtp_rsp->cause.presence = 1;
|
|
|
|
gtp_rsp->cause.data = &cause;
|
|
|
|
gtp_rsp->cause.len = sizeof(cause);
|
2020-08-13 00:31:22 +00:00
|
|
|
|
|
|
|
/* Copy Bearer-Contexts-Modified from Modify-Bearer-Request
|
|
|
|
*
|
2022-05-12 13:52:36 +00:00
|
|
|
* TS 29.274 Table 7.2.8-2
|
2020-08-13 00:31:22 +00:00
|
|
|
* NOTE 1: The SGW shall not change its F-TEID for a given interface
|
|
|
|
* during the Handover, Service Request, E-UTRAN Initial Attach,
|
|
|
|
* UE Requested PDN connectivity and PDP Context Activation procedures.
|
|
|
|
* The SGW F-TEID shall be same for S1-U, S4-U and S12. During Handover
|
|
|
|
* and Service Request the target eNodeB/RNC/SGSN may use a different
|
|
|
|
* IP type than the one used by the source eNodeB/RNC/SGSN.
|
|
|
|
* In order to support such a scenario, the SGW F-TEID should contain
|
|
|
|
* both an IPv4 address and an IPv6 address
|
|
|
|
* (see also subclause 8.22 "F-TEID").
|
|
|
|
*/
|
2022-04-29 12:28:16 +00:00
|
|
|
for (i = 0; i < OGS_BEARER_PER_UE; i++) {
|
|
|
|
if (gtp_req->bearer_contexts_to_be_modified[i].
|
|
|
|
presence == 0)
|
|
|
|
break;
|
|
|
|
if (gtp_req->bearer_contexts_to_be_modified[i].
|
|
|
|
eps_bearer_id.presence == 0)
|
|
|
|
break;
|
|
|
|
if (gtp_req->bearer_contexts_to_be_modified[i].
|
|
|
|
s1_u_enodeb_f_teid.presence == 0)
|
|
|
|
break;
|
|
|
|
|
|
|
|
gtp_rsp->bearer_contexts_modified[i].presence = 1;
|
|
|
|
gtp_rsp->bearer_contexts_modified[i].eps_bearer_id.
|
|
|
|
presence = 1;
|
|
|
|
gtp_rsp->bearer_contexts_modified[i].eps_bearer_id.u8 =
|
|
|
|
gtp_req->bearer_contexts_to_be_modified[i].
|
|
|
|
eps_bearer_id.u8;
|
|
|
|
gtp_rsp->bearer_contexts_modified[i].
|
|
|
|
s1_u_enodeb_f_teid.presence = 1;
|
|
|
|
gtp_rsp->bearer_contexts_modified[i].
|
|
|
|
s1_u_enodeb_f_teid.data =
|
|
|
|
gtp_req->bearer_contexts_to_be_modified[i].
|
|
|
|
s1_u_enodeb_f_teid.data;
|
|
|
|
gtp_rsp->bearer_contexts_modified[i].
|
|
|
|
s1_u_enodeb_f_teid.len =
|
|
|
|
gtp_req->bearer_contexts_to_be_modified[i].
|
|
|
|
s1_u_enodeb_f_teid.len;
|
|
|
|
|
|
|
|
gtp_rsp->bearer_contexts_modified[i].cause.presence = 1;
|
|
|
|
gtp_rsp->bearer_contexts_modified[i].cause.len =
|
|
|
|
sizeof(cause);
|
|
|
|
gtp_rsp->bearer_contexts_modified[i].cause.data =
|
|
|
|
&cause;
|
|
|
|
}
|
2020-08-13 00:31:22 +00:00
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
send_message.h.type = OGS_GTP2_MODIFY_BEARER_RESPONSE_TYPE;
|
|
|
|
send_message.h.teid = sgwc_ue->mme_s11_teid;
|
2020-08-13 00:31:22 +00:00
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
pkbuf = ogs_gtp2_build_msg(&send_message);
|
|
|
|
ogs_expect_or_return(pkbuf);
|
2021-06-21 13:36:38 +00:00
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
rv = ogs_gtp_xact_update_tx(
|
|
|
|
s11_xact, &send_message.h, pkbuf);
|
|
|
|
ogs_expect_or_return(rv == OGS_OK);
|
|
|
|
|
|
|
|
rv = ogs_gtp_xact_commit(s11_xact);
|
|
|
|
ogs_expect(rv == OGS_OK);
|
|
|
|
}
|
2021-06-21 13:36:38 +00:00
|
|
|
}
|
2020-08-13 00:31:22 +00:00
|
|
|
} else {
|
|
|
|
ogs_fatal("Invalid modify_flags[0x%llx]", (long long)flags);
|
|
|
|
ogs_assert_if_reached();
|
|
|
|
}
|
2022-04-29 12:28:16 +00:00
|
|
|
} else if (flags & OGS_PFCP_MODIFY_DEACTIVATE) {
|
|
|
|
if (flags & OGS_PFCP_MODIFY_ERROR_INDICATION) {
|
|
|
|
/* It's faked method for receiving `bearer` context */
|
|
|
|
bearer = pfcp_xact->assoc_xact;
|
|
|
|
ogs_assert(bearer);
|
2020-08-13 00:31:22 +00:00
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
ogs_pfcp_xact_commit(pfcp_xact);
|
2020-08-13 00:31:22 +00:00
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
ogs_assert(flags & OGS_PFCP_MODIFY_SESSION);
|
2022-05-12 13:52:36 +00:00
|
|
|
if (SGWC_SESSION_SYNC_DONE(sgwc_ue,
|
2022-04-29 12:28:16 +00:00
|
|
|
OGS_PFCP_SESSION_MODIFICATION_REQUEST_TYPE, flags)) {
|
2021-05-16 03:22:10 +00:00
|
|
|
ogs_assert(OGS_OK ==
|
|
|
|
sgwc_gtp_send_downlink_data_notification(
|
2022-04-12 22:07:39 +00:00
|
|
|
OGS_GTP2_CAUSE_ERROR_INDICATION_RECEIVED, bearer));
|
2022-04-29 12:28:16 +00:00
|
|
|
}
|
2020-08-13 00:31:22 +00:00
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
} else {
|
|
|
|
s11_xact = pfcp_xact->assoc_xact;
|
|
|
|
ogs_assert(s11_xact);
|
2020-08-13 00:31:22 +00:00
|
|
|
|
2022-04-29 12:28:16 +00:00
|
|
|
ogs_pfcp_xact_commit(pfcp_xact);
|
|
|
|
|
|
|
|
ogs_assert(flags & OGS_PFCP_MODIFY_SESSION);
|
2022-05-12 13:52:36 +00:00
|
|
|
if (SGWC_SESSION_SYNC_DONE(sgwc_ue,
|
2022-04-29 12:28:16 +00:00
|
|
|
OGS_PFCP_SESSION_MODIFICATION_REQUEST_TYPE, flags)) {
|
|
|
|
|
|
|
|
ogs_gtp2_release_access_bearers_response_t *gtp_rsp = NULL;
|
2020-08-13 00:31:22 +00:00
|
|
|
|
2020-10-21 00:00:02 +00:00
|
|
|
gtp_rsp = &send_message.release_access_bearers_response;
|
|
|
|
ogs_assert(gtp_rsp);
|
2020-08-13 00:31:22 +00:00
|
|
|
|
2022-04-12 22:07:39 +00:00
|
|
|
memset(&send_message, 0, sizeof(ogs_gtp2_message_t));
|
2020-08-13 00:31:22 +00:00
|
|
|
|
2020-10-21 00:00:02 +00:00
|
|
|
memset(&cause, 0, sizeof(cause));
|
2022-04-12 22:07:39 +00:00
|
|
|
cause.value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED;
|
2020-08-13 00:31:22 +00:00
|
|
|
|
2020-10-21 00:00:02 +00:00
|
|
|
gtp_rsp->cause.presence = 1;
|
|
|
|
gtp_rsp->cause.data = &cause;
|
|
|
|
gtp_rsp->cause.len = sizeof(cause);
|
2020-08-13 00:31:22 +00:00
|
|
|
|
2020-10-21 00:00:02 +00:00
|
|
|
send_message.h.type =
|
2022-04-12 22:07:39 +00:00
|
|
|
OGS_GTP2_RELEASE_ACCESS_BEARERS_RESPONSE_TYPE;
|
2020-10-21 00:00:02 +00:00
|
|
|
send_message.h.teid = sgwc_ue->mme_s11_teid;
|
|
|
|
|
2022-04-12 22:07:39 +00:00
|
|
|
pkbuf = ogs_gtp2_build_msg(&send_message);
|
2020-10-21 00:00:02 +00:00
|
|
|
ogs_expect_or_return(pkbuf);
|
|
|
|
|
|
|
|
rv = ogs_gtp_xact_update_tx(s11_xact, &send_message.h, pkbuf);
|
|
|
|
ogs_expect_or_return(rv == OGS_OK);
|
|
|
|
|
|
|
|
rv = ogs_gtp_xact_commit(s11_xact);
|
|
|
|
ogs_expect(rv == OGS_OK);
|
|
|
|
}
|
2020-08-13 00:31:22 +00:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
ogs_fatal("Invalid modify_flags[0x%llx]", (long long)flags);
|
|
|
|
ogs_assert_if_reached();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void sgwc_sxa_handle_session_deletion_response(
|
|
|
|
sgwc_sess_t *sess, ogs_pfcp_xact_t *pfcp_xact,
|
2022-04-12 22:07:39 +00:00
|
|
|
ogs_gtp2_message_t *gtp_message,
|
2020-08-13 00:31:22 +00:00
|
|
|
ogs_pfcp_session_deletion_response_t *pfcp_rsp)
|
|
|
|
{
|
|
|
|
int rv;
|
|
|
|
uint8_t cause_value = 0;
|
2021-06-21 13:36:38 +00:00
|
|
|
uint32_t teid = 0;
|
2020-08-13 00:31:22 +00:00
|
|
|
|
|
|
|
sgwc_ue_t *sgwc_ue = NULL;
|
|
|
|
|
2021-06-21 13:36:38 +00:00
|
|
|
ogs_gtp_xact_t *gtp_xact = NULL;
|
2020-08-13 00:31:22 +00:00
|
|
|
ogs_pkbuf_t *pkbuf = NULL;
|
|
|
|
|
2021-03-31 10:59:57 +00:00
|
|
|
ogs_debug("Session Deletion Response");
|
|
|
|
|
2020-08-13 00:31:22 +00:00
|
|
|
ogs_assert(pfcp_xact);
|
|
|
|
ogs_assert(pfcp_rsp);
|
|
|
|
|
2022-04-12 22:07:39 +00:00
|
|
|
cause_value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED;
|
2020-08-13 00:31:22 +00:00
|
|
|
|
2022-06-30 00:11:38 +00:00
|
|
|
if (!sess) {
|
|
|
|
ogs_warn("No Context");
|
|
|
|
cause_value = OGS_GTP2_CAUSE_CONTEXT_NOT_FOUND;
|
|
|
|
}
|
|
|
|
|
2020-08-13 00:31:22 +00:00
|
|
|
if (pfcp_rsp->cause.presence) {
|
|
|
|
if (pfcp_rsp->cause.u8 != OGS_PFCP_CAUSE_REQUEST_ACCEPTED) {
|
|
|
|
ogs_warn("PFCP Cause[%d] : Not Accepted", pfcp_rsp->cause.u8);
|
|
|
|
cause_value = gtp_cause_from_pfcp(pfcp_rsp->cause.u8);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
ogs_error("No Cause");
|
2022-04-12 22:07:39 +00:00
|
|
|
cause_value = OGS_GTP2_CAUSE_MANDATORY_IE_MISSING;
|
2020-08-13 00:31:22 +00:00
|
|
|
}
|
|
|
|
|
2021-06-21 13:36:38 +00:00
|
|
|
gtp_xact = pfcp_xact->assoc_xact;
|
2020-11-07 22:27:12 +00:00
|
|
|
|
2021-06-21 13:36:38 +00:00
|
|
|
ogs_pfcp_xact_commit(pfcp_xact);
|
|
|
|
|
2021-11-28 07:42:47 +00:00
|
|
|
if (!gtp_message) {
|
|
|
|
ogs_error("No GTP Message");
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
2022-05-12 13:52:36 +00:00
|
|
|
if (gtp_message->h.type == OGS_GTP2_DELETE_SESSION_REQUEST_TYPE) {
|
|
|
|
/*
|
|
|
|
* X2-based Handover with SGW change
|
|
|
|
* 1. MME sends Delete Session Request to SGW-C
|
|
|
|
* 2. SGW-C sends Delete Session Response to MME.
|
|
|
|
*/
|
|
|
|
gtp_message->h.type = OGS_GTP2_DELETE_SESSION_RESPONSE_TYPE;
|
|
|
|
}
|
|
|
|
|
2021-06-21 13:36:38 +00:00
|
|
|
switch (gtp_message->h.type) {
|
2022-04-12 22:07:39 +00:00
|
|
|
case OGS_GTP2_DELETE_SESSION_RESPONSE_TYPE:
|
2021-06-21 13:36:38 +00:00
|
|
|
/*
|
|
|
|
* 1. MME sends Delete Session Request to SGW/SMF.
|
|
|
|
* 2. SMF sends Delete Session Response to SGW/MME.
|
|
|
|
*/
|
2020-08-13 00:31:22 +00:00
|
|
|
if (sess) sgwc_ue = sess->sgwc_ue;
|
2021-06-21 13:36:38 +00:00
|
|
|
teid = sgwc_ue ? sgwc_ue->mme_s11_teid : 0;
|
|
|
|
break;
|
2022-04-12 22:07:39 +00:00
|
|
|
case OGS_GTP2_DELETE_BEARER_RESPONSE_TYPE:
|
2021-06-21 13:36:38 +00:00
|
|
|
/*
|
|
|
|
* 1. SMF sends Delete Bearer Request(DEFAULT BEARER) to SGW/MME.
|
|
|
|
* 2. MME sends Delete Bearer Response to SGW/SMF.
|
|
|
|
*
|
|
|
|
* OR
|
|
|
|
*
|
|
|
|
* 1. SMF sends Delete Bearer Request(DEFAULT BEARER) to ePDG.
|
|
|
|
* 2. ePDG sends Delete Bearer Response(DEFAULT BEARER) to SMF.
|
|
|
|
*
|
|
|
|
* Note that the following messages are not processed here.
|
|
|
|
* - Bearer Resource Command
|
|
|
|
* - Delete Bearer Request/Response with DEDICATED BEARER.
|
|
|
|
*/
|
|
|
|
teid = sess ? sess->pgw_s5c_teid : 0;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
ogs_fatal("Unknown GTP message type [%d]", gtp_message->h.type);
|
|
|
|
ogs_assert_if_reached();
|
|
|
|
}
|
|
|
|
|
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 (gtp_xact) {
|
2020-11-07 22:27:12 +00:00
|
|
|
ogs_gtp_send_error_message(
|
2021-06-21 13:36:38 +00:00
|
|
|
gtp_xact, teid, gtp_message->h.type, cause_value);
|
2020-11-07 22:27:12 +00:00
|
|
|
}
|
2020-08-13 00:31:22 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
ogs_assert(sess);
|
|
|
|
sgwc_ue = sess->sgwc_ue;
|
|
|
|
ogs_assert(sgwc_ue);
|
|
|
|
|
2021-06-21 13:36:38 +00:00
|
|
|
if (gtp_xact) {
|
|
|
|
/*
|
2022-04-12 22:07:39 +00:00
|
|
|
* If gtp_message->h.type == OGS_GTP2_DELETE_SESSION_RESPONSE_TYPE
|
2021-06-21 13:36:38 +00:00
|
|
|
* Then gtp_xact is S11-XACT
|
|
|
|
*
|
2022-04-12 22:07:39 +00:00
|
|
|
* If gtp_message->h.type == OGS_GTP2_DELETE_BEARER_RESPONSE_TYPE
|
2021-06-21 13:36:38 +00:00
|
|
|
* Then gtp_xact is S5C-XACT
|
|
|
|
*/
|
|
|
|
gtp_message->h.teid = teid;
|
2020-08-13 00:31:22 +00:00
|
|
|
|
2022-04-12 22:07:39 +00:00
|
|
|
pkbuf = ogs_gtp2_build_msg(gtp_message);
|
2020-11-07 22:27:12 +00:00
|
|
|
ogs_expect_or_return(pkbuf);
|
2020-08-13 00:31:22 +00:00
|
|
|
|
2021-06-21 13:36:38 +00:00
|
|
|
rv = ogs_gtp_xact_update_tx(gtp_xact, >p_message->h, pkbuf);
|
2020-11-07 22:27:12 +00:00
|
|
|
ogs_expect_or_return(rv == OGS_OK);
|
2020-08-13 00:31:22 +00:00
|
|
|
|
2021-06-21 13:36:38 +00:00
|
|
|
rv = ogs_gtp_xact_commit(gtp_xact);
|
2020-11-07 22:27:12 +00:00
|
|
|
ogs_expect(rv == OGS_OK);
|
|
|
|
}
|
2020-08-13 00:31:22 +00:00
|
|
|
|
2021-11-28 07:42:47 +00:00
|
|
|
cleanup:
|
2020-08-13 00:31:22 +00:00
|
|
|
sgwc_sess_remove(sess);
|
|
|
|
}
|
|
|
|
|
|
|
|
void sgwc_sxa_handle_session_report_request(
|
|
|
|
sgwc_sess_t *sess, ogs_pfcp_xact_t *pfcp_xact,
|
|
|
|
ogs_pfcp_session_report_request_t *pfcp_req)
|
|
|
|
{
|
2020-09-07 02:41:12 +00:00
|
|
|
sgwc_ue_t *sgwc_ue = NULL;
|
2020-08-13 00:31:22 +00:00
|
|
|
sgwc_bearer_t *bearer = NULL;
|
2020-08-29 14:53:02 +00:00
|
|
|
sgwc_tunnel_t *tunnel = NULL;
|
2020-08-13 00:31:22 +00:00
|
|
|
|
|
|
|
ogs_pfcp_report_type_t report_type;
|
|
|
|
uint8_t cause_value = 0;
|
|
|
|
uint16_t pdr_id = 0;
|
|
|
|
|
2021-03-31 10:59:57 +00:00
|
|
|
ogs_debug("Session Report Request");
|
|
|
|
|
2020-08-13 00:31:22 +00:00
|
|
|
ogs_assert(pfcp_xact);
|
|
|
|
ogs_assert(pfcp_req);
|
|
|
|
|
2022-04-12 22:07:39 +00:00
|
|
|
cause_value = OGS_GTP2_CAUSE_REQUEST_ACCEPTED;
|
2020-08-13 00:31:22 +00:00
|
|
|
|
2022-06-30 00:11:38 +00:00
|
|
|
if (!sess) {
|
|
|
|
ogs_warn("No Context");
|
|
|
|
cause_value = OGS_PFCP_CAUSE_SESSION_CONTEXT_NOT_FOUND;
|
|
|
|
}
|
|
|
|
|
2020-08-13 00:31:22 +00:00
|
|
|
if (pfcp_req->report_type.presence == 0) {
|
|
|
|
ogs_error("No Report Type");
|
2022-04-12 22:07:39 +00:00
|
|
|
cause_value = OGS_GTP2_CAUSE_MANDATORY_IE_MISSING;
|
2020-08-13 00:31:22 +00:00
|
|
|
}
|
|
|
|
|
2022-04-12 22:07:39 +00:00
|
|
|
if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) {
|
2020-08-13 00:31:22 +00:00
|
|
|
ogs_pfcp_send_error_message(pfcp_xact, 0,
|
|
|
|
OGS_PFCP_SESSION_REPORT_RESPONSE_TYPE,
|
|
|
|
cause_value, 0);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
ogs_assert(sess);
|
2020-09-07 02:41:12 +00:00
|
|
|
sgwc_ue = sess->sgwc_ue;
|
|
|
|
ogs_assert(sgwc_ue);
|
2020-08-13 00:31:22 +00:00
|
|
|
|
2020-10-21 00:00:02 +00:00
|
|
|
if (!sgwc_ue->gnode) {
|
|
|
|
ogs_error("No SGWC-UE GTP Node");
|
|
|
|
ogs_pfcp_send_error_message(pfcp_xact, sess ? sess->sgwu_sxa_seid : 0,
|
|
|
|
OGS_PFCP_SESSION_REPORT_RESPONSE_TYPE,
|
|
|
|
OGS_PFCP_CAUSE_SESSION_CONTEXT_NOT_FOUND, 0);
|
|
|
|
return;
|
|
|
|
}
|
2020-08-13 00:31:22 +00:00
|
|
|
|
2021-05-16 03:22:10 +00:00
|
|
|
ogs_assert(OGS_OK ==
|
|
|
|
sgwc_pfcp_send_session_report_response(
|
|
|
|
pfcp_xact, sess, OGS_PFCP_CAUSE_REQUEST_ACCEPTED));
|
2020-08-13 00:31:22 +00:00
|
|
|
|
2020-10-21 00:00:02 +00:00
|
|
|
report_type.value = pfcp_req->report_type.u8;
|
|
|
|
|
|
|
|
if (report_type.downlink_data_report) {
|
|
|
|
if (pfcp_req->downlink_data_report.presence == 0) {
|
|
|
|
ogs_error("No Downlink Data Report");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (pfcp_req->downlink_data_report.pdr_id.presence == 0) {
|
|
|
|
ogs_error("No PDR-ID");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
pdr_id = pfcp_req->downlink_data_report.pdr_id.u16;
|
|
|
|
|
|
|
|
ogs_list_for_each(&sess->bearer_list, bearer) {
|
|
|
|
ogs_list_for_each(&bearer->tunnel_list, tunnel) {
|
|
|
|
ogs_assert(tunnel->pdr);
|
|
|
|
if (tunnel->pdr->id == pdr_id) {
|
2021-05-16 03:22:10 +00:00
|
|
|
ogs_assert(OGS_OK ==
|
|
|
|
sgwc_gtp_send_downlink_data_notification(
|
2022-04-12 22:07:39 +00:00
|
|
|
OGS_GTP2_CAUSE_UNDEFINED_VALUE, bearer));
|
2020-10-21 00:00:02 +00:00
|
|
|
return;
|
2020-08-29 14:53:02 +00:00
|
|
|
}
|
2020-08-13 00:31:22 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-10-21 00:00:02 +00:00
|
|
|
ogs_error("Cannot find the PDR-ID[%d]", pdr_id);
|
|
|
|
|
|
|
|
} else if (report_type.error_indication_report) {
|
|
|
|
bearer = sgwc_bearer_find_by_error_indication_report(
|
|
|
|
sess, &pfcp_req->error_indication_report);
|
|
|
|
|
|
|
|
if (!bearer) return;
|
2020-08-13 00:31:22 +00:00
|
|
|
|
2020-10-21 00:00:02 +00:00
|
|
|
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(sess,
|
2021-05-16 03:22:10 +00:00
|
|
|
/* We only use the `assoc_xact` parameter temporarily here
|
|
|
|
* to pass the `bearer` context. */
|
2020-10-21 00:00:02 +00:00
|
|
|
(ogs_gtp_xact_t *)bearer,
|
|
|
|
NULL,
|
|
|
|
OGS_PFCP_MODIFY_DL_ONLY|OGS_PFCP_MODIFY_DEACTIVATE|
|
2021-05-16 03:22:10 +00:00
|
|
|
OGS_PFCP_MODIFY_ERROR_INDICATION));
|
2020-10-21 00:00:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
} else {
|
|
|
|
ogs_error("Not supported Report Type[%d]", report_type.value);
|
|
|
|
}
|
2020-08-13 00:31:22 +00:00
|
|
|
}
|