open5gs/src/smf/n4-handler.c

1359 lines
48 KiB
C
Raw Normal View History

2020-04-26 19:36:05 +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 "context.h"
#include "timer.h"
#include "s5c-build.h"
2020-04-26 19:36:05 +00:00
#include "pfcp-path.h"
#include "gtp-path.h"
#include "n4-handler.h"
2021-01-01 02:07:08 +00:00
#include "binding.h"
2020-06-17 05:22:28 +00:00
#include "sbi-path.h"
2021-01-01 02:07:08 +00:00
#include "ngap-path.h"
2020-04-26 19:36:05 +00:00
uint8_t gtp_cause_from_pfcp(uint8_t pfcp_cause, uint8_t gtp_version)
2020-04-26 19:36:05 +00:00
{
Introduce Gn interface (GTPv1C) Support to PGW (#1351) * [CORE] tlv: Store mode in ogs_tlv_t This allows specifying the format of the IE for each individual IE, hence allowing messages containing IEs formatted in different ways. This is needed in order to support parsing GTPv1-C, since messages contain IEs with different structure (TLV vs TV). Hence, this is a preparation patch to add support for parsing TVs in ogs-tlv.c/.h. * [CORE] tlv: Support parsing msg with both TLV and TV in it IEs of type TV are sometimes used in GTPv1-C. Current tlv parser/builder doesn't provide with ways to parse messages which contain TV formatted IEs. This patch adds the relevant types and ways to encode/decode them. Furthermore, the current parser/builder allows parsing/building messages containing the exact same format in all its IEs. A new parser function is added which allows parsing messages of different types (TV, TLV) mixed in the same message. In order to be able to do so, it uses the general msg_mode passed to it in order to know the general TLV format (in essence, the length of the Tag field, and also the length of the Length field if applicable each IE). Looking up the instance in the TLV description is left undone and hadcoded to 0, since the only user so far requiring this API is GTPv1-C, which has no instances. * [CORE] tlv: Support repeated tag+instance parsing TLV message In GTPv2C, repeated IEs (same tag) are easily differentiated by the Instance byte, which provides info to match different decoded structures. In GTPv1C though, there's no Instance byte, and we still encounter repeated IEs (like GSN Address in Create PDP Context Request). Hence, the TLV decoder needs to be updated to track count of IEs found (identified by tag+instance, where instance is always 0 in GTPv1C) and get the proper description index + offset into the decoded structure. * [GTP]: Move GTPv2-C specifics to its own libgtp subdir This will allow adding GTPv1-C code by the side. Most GTPv2 code is left in this patch as "gtp" instead of renaming it to "gtp2" in order to avoid massive changes. It can be done at a later stage if wanted. * [GTP] Support generating GTPv1-C messages * [SMF] Add Gn interface support This patch introduces GTPv1C support to open5gs-smfd. With it, open5gs-becomes a GGSN too, where SGSN can connect to, hence supporting GERAN and UTRAN networks.
2022-02-18 13:23:45 +00:00
switch (gtp_version) {
case 1:
switch (pfcp_cause) {
case OGS_PFCP_CAUSE_REQUEST_ACCEPTED:
return OGS_GTP1_CAUSE_REQUEST_ACCEPTED;
case OGS_PFCP_CAUSE_REQUEST_REJECTED:
return OGS_GTP1_CAUSE_REJ_MS_NOT_GPRS_RESPONDING;
case OGS_PFCP_CAUSE_SESSION_CONTEXT_NOT_FOUND:
return OGS_GTP1_CAUSE_CONTEXT_NOT_FOUND;
case OGS_PFCP_CAUSE_MANDATORY_IE_MISSING:
case OGS_PFCP_CAUSE_CONDITIONAL_IE_MISSING:
return OGS_GTP1_CAUSE_MANDATORY_IE_MISSING;
case OGS_PFCP_CAUSE_INVALID_LENGTH:
return OGS_GTP1_CAUSE_INVALID_MESSAGE_FORMAT;
case OGS_PFCP_CAUSE_MANDATORY_IE_INCORRECT:
return OGS_GTP1_CAUSE_MANDATORY_IE_INCORRECT;
case OGS_PFCP_CAUSE_INVALID_FORWARDING_POLICY:
case OGS_PFCP_CAUSE_INVALID_F_TEID_ALLOCATION_OPTION:
return OGS_GTP1_CAUSE_INVALID_MESSAGE_FORMAT;
case OGS_PFCP_CAUSE_NO_ESTABLISHED_PFCP_ASSOCIATION:
return OGS_GTP1_CAUSE_NO_RESOURCES_AVAILABLE;
case OGS_PFCP_CAUSE_RULE_CREATION_MODIFICATION_FAILURE:
return OGS_GTP1_CAUSE_SEMANTIC_ERR_TFT_OPERATION;
case OGS_PFCP_CAUSE_PFCP_ENTITY_IN_CONGESTION:
return OGS_GTP1_CAUSE_APN_CONGESTION;
case OGS_PFCP_CAUSE_NO_RESOURCES_AVAILABLE:
return OGS_GTP1_CAUSE_NO_RESOURCES_AVAILABLE;
case OGS_PFCP_CAUSE_SERVICE_NOT_SUPPORTED:
return OGS_GTP1_CAUSE_SERVICE_NOT_SUPPORTED;
case OGS_PFCP_CAUSE_SYSTEM_FAILURE:
return OGS_GTP1_CAUSE_SYSTEM_FAILURE;
case OGS_PFCP_CAUSE_ALL_DYNAMIC_ADDRESS_ARE_OCCUPIED:
return OGS_GTP1_CAUSE_ALL_DYNAMIC_PDP_ADDRS_OCCUPIED;
default:
return OGS_GTP1_CAUSE_SYSTEM_FAILURE;
}
break;
case 2:
switch (pfcp_cause) {
case OGS_PFCP_CAUSE_REQUEST_ACCEPTED:
return OGS_GTP_CAUSE_REQUEST_ACCEPTED;
case OGS_PFCP_CAUSE_REQUEST_REJECTED:
return OGS_GTP_CAUSE_REQUEST_REJECTED_REASON_NOT_SPECIFIED;
case OGS_PFCP_CAUSE_SESSION_CONTEXT_NOT_FOUND:
return OGS_GTP_CAUSE_CONTEXT_NOT_FOUND;
case OGS_PFCP_CAUSE_MANDATORY_IE_MISSING:
return OGS_GTP_CAUSE_MANDATORY_IE_MISSING;
case OGS_PFCP_CAUSE_CONDITIONAL_IE_MISSING:
return OGS_GTP_CAUSE_CONDITIONAL_IE_MISSING;
case OGS_PFCP_CAUSE_INVALID_LENGTH:
return OGS_GTP_CAUSE_INVALID_LENGTH;
case OGS_PFCP_CAUSE_MANDATORY_IE_INCORRECT:
return OGS_GTP_CAUSE_MANDATORY_IE_INCORRECT;
case OGS_PFCP_CAUSE_INVALID_FORWARDING_POLICY:
case OGS_PFCP_CAUSE_INVALID_F_TEID_ALLOCATION_OPTION:
return OGS_GTP_CAUSE_INVALID_MESSAGE_FORMAT;
case OGS_PFCP_CAUSE_NO_ESTABLISHED_PFCP_ASSOCIATION:
return OGS_GTP_CAUSE_REMOTE_PEER_NOT_RESPONDING;
case OGS_PFCP_CAUSE_RULE_CREATION_MODIFICATION_FAILURE:
return OGS_GTP_CAUSE_SEMANTIC_ERROR_IN_THE_TFT_OPERATION;
case OGS_PFCP_CAUSE_PFCP_ENTITY_IN_CONGESTION:
return OGS_GTP_CAUSE_GTP_C_ENTITY_CONGESTION;
case OGS_PFCP_CAUSE_NO_RESOURCES_AVAILABLE:
return OGS_GTP_CAUSE_NO_RESOURCES_AVAILABLE;
case OGS_PFCP_CAUSE_SERVICE_NOT_SUPPORTED:
return OGS_GTP_CAUSE_SERVICE_NOT_SUPPORTED;
case OGS_PFCP_CAUSE_SYSTEM_FAILURE:
return OGS_GTP_CAUSE_SYSTEM_FAILURE;
case OGS_PFCP_CAUSE_ALL_DYNAMIC_ADDRESS_ARE_OCCUPIED:
return OGS_GTP_CAUSE_ALL_DYNAMIC_ADDRESSES_ARE_OCCUPIED;
default:
return OGS_GTP_CAUSE_SYSTEM_FAILURE;
}
break;
2020-04-26 19:36:05 +00:00
}
return OGS_GTP_CAUSE_SYSTEM_FAILURE;
}
2021-01-18 16:48:35 +00:00
2020-07-04 03:14:48 +00:00
static int sbi_status_from_pfcp(uint8_t pfcp_cause)
{
switch (pfcp_cause) {
case OGS_PFCP_CAUSE_REQUEST_ACCEPTED:
return OGS_SBI_HTTP_STATUS_OK;
case OGS_PFCP_CAUSE_REQUEST_REJECTED:
return OGS_SBI_HTTP_STATUS_FORBIDDEN;
case OGS_PFCP_CAUSE_SESSION_CONTEXT_NOT_FOUND:
return OGS_SBI_HTTP_STATUS_NOT_FOUND;
case OGS_PFCP_CAUSE_MANDATORY_IE_MISSING:
case OGS_PFCP_CAUSE_CONDITIONAL_IE_MISSING:
case OGS_PFCP_CAUSE_INVALID_LENGTH:
case OGS_PFCP_CAUSE_MANDATORY_IE_INCORRECT:
case OGS_PFCP_CAUSE_INVALID_FORWARDING_POLICY:
case OGS_PFCP_CAUSE_INVALID_F_TEID_ALLOCATION_OPTION:
case OGS_PFCP_CAUSE_RULE_CREATION_MODIFICATION_FAILURE:
case OGS_PFCP_CAUSE_PFCP_ENTITY_IN_CONGESTION:
case OGS_PFCP_CAUSE_NO_RESOURCES_AVAILABLE:
return OGS_SBI_HTTP_STATUS_BAD_REQUEST;
case OGS_PFCP_CAUSE_NO_ESTABLISHED_PFCP_ASSOCIATION:
return OGS_SBI_HTTP_STATUS_GATEWAY_TIMEOUT;
case OGS_PFCP_CAUSE_SERVICE_NOT_SUPPORTED:
return OGS_SBI_HTTP_STATUS_SERVICE_UNAVAILABLE;
case OGS_PFCP_CAUSE_SYSTEM_FAILURE:
return OGS_SBI_HTTP_STATUS_INTERNAL_SERVER_ERROR;
default:
return OGS_SBI_HTTP_STATUS_INTERNAL_SERVER_ERROR;
}
return OGS_SBI_HTTP_STATUS_INTERNAL_SERVER_ERROR;
}
2020-04-26 19:36:05 +00:00
2020-06-17 05:22:28 +00:00
void smf_5gc_n4_handle_session_establishment_response(
smf_sess_t *sess, ogs_pfcp_xact_t *xact,
ogs_pfcp_session_establishment_response_t *rsp)
{
int i;
2021-01-18 16:48:35 +00:00
smf_n1_n2_message_transfer_param_t param;
ogs_sbi_stream_t *stream = NULL;
uint8_t pfcp_cause_value = OGS_PFCP_CAUSE_REQUEST_ACCEPTED;
uint8_t offending_ie_value = 0;
2020-06-17 05:22:28 +00:00
ogs_pfcp_f_seid_t *up_f_seid = NULL;
ogs_assert(xact);
ogs_assert(rsp);
ogs_debug("Session Establishment Response [5gc]");
stream = xact->assoc_stream;
ogs_assert(stream);
2020-06-17 05:22:28 +00:00
ogs_pfcp_xact_commit(xact);
2020-07-04 03:14:48 +00:00
if (!sess) {
ogs_warn("No Context");
return;
}
2020-06-17 05:22:28 +00:00
if (rsp->up_f_seid.presence == 0) {
ogs_error("No UP F-SEID");
return;
}
if (rsp->created_pdr[0].presence == 0) {
ogs_error("No Created PDR");
return;
}
2020-06-17 05:22:28 +00:00
if (rsp->cause.presence) {
if (rsp->cause.u8 != OGS_PFCP_CAUSE_REQUEST_ACCEPTED) {
2020-07-04 03:14:48 +00:00
ogs_error("PFCP Cause [%d] : Not Accepted", rsp->cause.u8);
2020-06-17 05:22:28 +00:00
return;
}
} else {
ogs_error("No Cause");
return;
}
2020-07-04 03:14:48 +00:00
ogs_assert(sess);
pfcp_cause_value = OGS_PFCP_CAUSE_REQUEST_ACCEPTED;
for (i = 0; i < OGS_MAX_NUM_OF_PDR; i++) {
ogs_pfcp_pdr_t *pdr = NULL;
2021-03-15 01:01:55 +00:00
ogs_pfcp_far_t *far = NULL;
pdr = ogs_pfcp_handle_created_pdr(
&sess->pfcp, &rsp->created_pdr[i],
&pfcp_cause_value, &offending_ie_value);
if (!pdr)
break;
2021-03-15 01:01:55 +00:00
far = pdr->far;
ogs_assert(far);
if (pdr->src_if == OGS_PFCP_INTERFACE_ACCESS) {
if (far->dst_if == OGS_PFCP_INTERFACE_CP_FUNCTION)
ogs_pfcp_far_teid_hash_set(far);
ogs_assert(sess->pfcp_node);
if (sess->pfcp_node->up_function_features.ftup &&
pdr->f_teid_len) {
if (sess->upf_n3_addr)
ogs_freeaddrinfo(sess->upf_n3_addr);
if (sess->upf_n3_addr6)
ogs_freeaddrinfo(sess->upf_n3_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
&sess->upf_n3_addr, &sess->upf_n3_addr6));
2021-03-15 01:01:55 +00:00
sess->upf_n3_teid = pdr->f_teid.teid;
}
} else 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));
}
}
if (pfcp_cause_value != OGS_PFCP_CAUSE_REQUEST_ACCEPTED) {
ogs_error("PFCP Cause [%d] : Not Accepted", pfcp_cause_value);
return;
}
if (sess->upf_n3_addr == NULL && sess->upf_n3_addr6 == NULL) {
ogs_error("No UP F-TEID");
return;
}
2020-06-17 05:22:28 +00:00
/* UP F-SEID */
up_f_seid = rsp->up_f_seid.data;
ogs_assert(up_f_seid);
sess->upf_n4_seid = be64toh(up_f_seid->seid);
2021-01-18 16:48:35 +00:00
memset(&param, 0, sizeof(param));
param.state = SMF_UE_REQUESTED_PDU_SESSION_ESTABLISHMENT;
param.n1smbuf = gsm_build_pdu_session_establishment_accept(sess);
ogs_assert(param.n1smbuf);
param.n2smbuf = ngap_build_pdu_session_resource_setup_request_transfer(
2021-01-28 19:23:54 +00:00
sess);
2021-01-18 16:48:35 +00:00
ogs_assert(param.n2smbuf);
2020-06-17 05:22:28 +00:00
2021-01-18 16:48:35 +00:00
smf_namf_comm_send_n1_n2_message_transfer(sess, &param);
2020-06-17 05:22:28 +00:00
}
void smf_5gc_n4_handle_session_modification_response(
smf_sess_t *sess, ogs_pfcp_xact_t *xact,
ogs_pfcp_session_modification_response_t *rsp)
{
2020-07-04 03:14:48 +00:00
int status = 0;
uint64_t flags = 0;
ogs_sbi_stream_t *stream = NULL;
2021-01-01 02:07:08 +00:00
smf_bearer_t *qos_flow = NULL;
2020-06-17 05:22:28 +00:00
ogs_assert(xact);
ogs_assert(rsp);
ogs_debug("Session Modification Response [5gc]");
flags = xact->modify_flags;
ogs_assert(flags);
2020-06-17 05:22:28 +00:00
2021-01-01 02:07:08 +00:00
/* 'stream' could be NULL in smf_qos_flow_binding() */
stream = xact->assoc_stream;
if (flags & OGS_PFCP_MODIFY_SESSION) {
/* If smf_5gc_pfcp_send_session_modification_request() is called */
} else {
/* If smf_5gc_pfcp_send_qos_flow_modification_request() is called */
qos_flow = xact->data;
ogs_assert(qos_flow);
}
2021-01-01 02:07:08 +00:00
2020-06-17 05:22:28 +00:00
ogs_pfcp_xact_commit(xact);
2020-07-04 03:14:48 +00:00
status = OGS_SBI_HTTP_STATUS_OK;
if (!sess) {
ogs_warn("No Context");
status = OGS_SBI_HTTP_STATUS_NOT_FOUND;
}
2020-06-17 05:22:28 +00:00
if (rsp->cause.presence) {
if (rsp->cause.u8 != OGS_PFCP_CAUSE_REQUEST_ACCEPTED) {
2020-07-04 03:14:48 +00:00
ogs_warn("PFCP Cause [%d] : Not Accepted", rsp->cause.u8);
status = sbi_status_from_pfcp(rsp->cause.u8);
2020-06-17 05:22:28 +00:00
}
} else {
ogs_error("No Cause");
2020-07-04 03:14:48 +00:00
status = OGS_SBI_HTTP_STATUS_BAD_REQUEST;
}
if (status == OGS_SBI_HTTP_STATUS_OK) {
int i;
uint8_t pfcp_cause_value = OGS_PFCP_CAUSE_REQUEST_ACCEPTED;
uint8_t offending_ie_value = 0;
ogs_assert(sess);
for (i = 0; i < OGS_MAX_NUM_OF_PDR; i++) {
ogs_pfcp_pdr_t *pdr = NULL;
2021-03-15 01:01:55 +00:00
ogs_pfcp_far_t *far = NULL;
pdr = ogs_pfcp_handle_created_pdr(
&sess->pfcp, &rsp->created_pdr[i],
&pfcp_cause_value, &offending_ie_value);
if (!pdr)
break;
2021-03-15 01:01:55 +00:00
far = pdr->far;
ogs_assert(far);
if (pdr->src_if == OGS_PFCP_INTERFACE_ACCESS) {
if (far->dst_if == OGS_PFCP_INTERFACE_CP_FUNCTION)
ogs_pfcp_far_teid_hash_set(far);
ogs_assert(sess->pfcp_node);
if (sess->pfcp_node->up_function_features.ftup &&
pdr->f_teid_len) {
if (far->dst_if == OGS_PFCP_INTERFACE_CORE) {
if (sess->upf_n3_addr)
ogs_freeaddrinfo(sess->upf_n3_addr);
if (sess->upf_n3_addr6)
ogs_freeaddrinfo(sess->upf_n3_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
&sess->upf_n3_addr, &sess->upf_n3_addr6));
2021-03-15 01:01:55 +00:00
sess->upf_n3_teid = pdr->f_teid.teid;
} else if (far->dst_if == OGS_PFCP_INTERFACE_ACCESS) {
if (sess->handover.upf_dl_addr)
ogs_freeaddrinfo(sess->handover.upf_dl_addr);
if (sess->handover.upf_dl_addr6)
ogs_freeaddrinfo(sess->handover.upf_dl_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,
&sess->handover.upf_dl_addr,
2021-06-06 13:35:46 +00:00
&sess->handover.upf_dl_addr6));
2021-03-15 01:01:55 +00:00
sess->handover.upf_dl_teid = pdr->f_teid.teid;
}
}
2021-03-15 01:01:55 +00:00
} else 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));
}
}
status = sbi_status_from_pfcp(pfcp_cause_value);
}
2020-07-04 03:14:48 +00:00
if (status != OGS_SBI_HTTP_STATUS_OK) {
char *strerror = ogs_msprintf(
"PFCP Cause [%d] : Not Accepted", rsp->cause.u8);
2021-01-01 02:07:08 +00:00
if (stream)
smf_sbi_send_sm_context_update_error(
stream, status, strerror, NULL, NULL, NULL);
ogs_error("%s", strerror);
2020-07-04 03:14:48 +00:00
ogs_free(strerror);
2020-06-17 05:22:28 +00:00
return;
}
2020-07-04 03:14:48 +00:00
ogs_assert(sess);
if (sess->upf_n3_addr == NULL && sess->upf_n3_addr6 == NULL) {
2021-01-01 02:07:08 +00:00
if (stream)
smf_sbi_send_sm_context_update_error(
stream, status, "No UP F_TEID", NULL, NULL, NULL);
return;
}
2020-08-13 00:31:22 +00:00
if (flags & OGS_PFCP_MODIFY_ACTIVATE) {
2021-01-28 19:23:54 +00:00
if (flags & OGS_PFCP_MODIFY_XN_HANDOVER) {
2021-01-03 05:50:59 +00:00
ogs_pkbuf_t *n2smbuf =
ngap_build_path_switch_request_ack_transfer(sess);
ogs_assert(n2smbuf);
2021-01-18 16:48:35 +00:00
smf_sbi_send_sm_context_updated_data_n2smbuf(sess, stream,
2021-01-03 05:50:59 +00:00
OpenAPI_n2_sm_info_type_PATH_SWITCH_REQ_ACK, n2smbuf);
2021-01-28 19:23:54 +00:00
} else if (flags & OGS_PFCP_MODIFY_N2_HANDOVER) {
if (smf_sess_have_indirect_data_forwarding(sess) == true) {
ogs_assert(OGS_OK ==
smf_5gc_pfcp_send_session_modification_request(
sess, stream,
OGS_PFCP_MODIFY_INDIRECT|OGS_PFCP_MODIFY_REMOVE,
ogs_app()->time.handover.duration));
}
2021-01-28 19:23:54 +00:00
smf_sbi_send_sm_context_updated_data_ho_state(
sess, stream, OpenAPI_ho_state_COMPLETED);
2021-01-18 16:48:35 +00:00
} else {
sess->paging.ue_requested_pdu_session_establishment_done = true;
2021-06-06 13:35:46 +00:00
ogs_assert(true == ogs_sbi_send_http_status_no_content(stream));
2021-01-03 05:50:59 +00:00
}
2020-06-17 05:22:28 +00:00
2020-08-13 00:31:22 +00:00
} else if (flags & OGS_PFCP_MODIFY_DEACTIVATE) {
2021-01-18 16:48:35 +00:00
if (flags & OGS_PFCP_MODIFY_ERROR_INDICATION) {
smf_n1_n2_message_transfer_param_t param;
memset(&param, 0, sizeof(param));
param.state = SMF_ERROR_INDICATON_RECEIVED_FROM_5G_AN;
param.n2smbuf =
ngap_build_pdu_session_resource_release_command_transfer(
sess, SMF_NGAP_STATE_ERROR_INDICATION_RECEIVED_FROM_5G_AN,
NGAP_Cause_PR_nas, NGAP_CauseNas_normal_release);
ogs_assert(param.n2smbuf);
param.skip_ind = true;
smf_namf_comm_send_n1_n2_message_transfer(sess, &param);
} else {
smf_sbi_send_sm_context_updated_data_up_cnx_state(
sess, stream, OpenAPI_up_cnx_state_DEACTIVATED);
}
/*
* 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) {
* }
*/
} else if (flags & OGS_PFCP_MODIFY_REMOVE) {
if (flags & OGS_PFCP_MODIFY_INDIRECT) {
smf_sess_delete_indirect_data_forwarding(sess);
/*
* OGS_PFCP_MODIFY_CREATE remains.
* So now we do some extra work to create an indirect tunnel.
*/
if (flags & OGS_PFCP_MODIFY_CREATE) {
smf_sess_create_indirect_data_forwarding(sess);
ogs_assert(OGS_OK ==
smf_5gc_pfcp_send_session_modification_request(
sess, stream,
OGS_PFCP_MODIFY_INDIRECT|OGS_PFCP_MODIFY_CREATE,
0));
} else if (flags & OGS_PFCP_MODIFY_HANDOVER_CANCEL) {
smf_sbi_send_sm_context_updated_data_ho_state(
sess, stream, OpenAPI_ho_state_CANCELLED);
}
2021-11-14 12:07:56 +00:00
} else if (flags & OGS_PFCP_MODIFY_NETWORK_REQUESTED) {
smf_n1_n2_message_transfer_param_t param;
ogs_assert(qos_flow);
2021-11-14 12:07:56 +00:00
memset(&param, 0, sizeof(param));
param.state = SMF_NETWORK_REQUESTED_QOS_FLOW_MODIFICATION;
param.n1smbuf = gsm_build_qos_flow_modification_command(
qos_flow,
OGS_NAS_PROCEDURE_TRANSACTION_IDENTITY_UNASSIGNED,
OGS_NAS_QOS_CODE_DELETE_EXISTING_QOS_RULE,
OGS_NAS_DELETE_NEW_QOS_FLOW_DESCRIPTION);
ogs_assert(param.n1smbuf);
param.n2smbuf =
ngap_build_qos_flow_resource_release_request_transfer(
qos_flow,
NGAP_Cause_PR_nas, NGAP_CauseNas_normal_release);
ogs_assert(param.n2smbuf);
smf_namf_comm_send_n1_n2_message_transfer(sess, &param);
smf_bearer_remove(qos_flow);
} else if (flags & OGS_PFCP_MODIFY_UE_REQUESTED) {
ogs_pkbuf_t *n1smbuf = NULL, *n2smbuf = NULL;
ogs_assert(stream);
ogs_assert(qos_flow);
2021-11-14 12:07:56 +00:00
n1smbuf = gsm_build_qos_flow_modification_command(
qos_flow, sess->pti,
OGS_NAS_QOS_CODE_DELETE_EXISTING_QOS_RULE,
OGS_NAS_DELETE_NEW_QOS_FLOW_DESCRIPTION);
ogs_assert(n1smbuf);
n2smbuf = ngap_build_qos_flow_resource_release_request_transfer(
qos_flow,
NGAP_Cause_PR_nas, NGAP_CauseNas_normal_release);
ogs_assert(n2smbuf);
smf_sbi_send_sm_context_updated_data_n1_n2_message(sess, stream,
n1smbuf, OpenAPI_n2_sm_info_type_PDU_RES_MOD_REQ, n2smbuf);
smf_bearer_remove(qos_flow);
} else {
ogs_fatal("Unknown flags [0x%llx]", (long long)flags);
ogs_assert_if_reached();
}
2021-01-01 02:07:08 +00:00
} else if (flags & OGS_PFCP_MODIFY_CREATE) {
if (flags & OGS_PFCP_MODIFY_INDIRECT) {
ogs_pkbuf_t *n2smbuf = ngap_build_handover_command_transfer(sess);
ogs_assert(n2smbuf);
smf_sbi_send_sm_context_updated_data(
sess, stream, 0, OpenAPI_ho_state_PREPARED,
NULL, OpenAPI_n2_sm_info_type_HANDOVER_CMD, n2smbuf);
2021-11-14 12:07:56 +00:00
} else if (flags & OGS_PFCP_MODIFY_NETWORK_REQUESTED) {
smf_n1_n2_message_transfer_param_t param;
2021-01-01 02:07:08 +00:00
ogs_assert(qos_flow);
memset(&param, 0, sizeof(param));
param.state = SMF_NETWORK_REQUESTED_QOS_FLOW_MODIFICATION;
2021-11-14 12:07:56 +00:00
param.n1smbuf = gsm_build_qos_flow_modification_command(
qos_flow,
OGS_NAS_PROCEDURE_TRANSACTION_IDENTITY_UNASSIGNED,
OGS_NAS_QOS_CODE_CREATE_NEW_QOS_RULE,
OGS_NAS_CREATE_NEW_QOS_FLOW_DESCRIPTION);
ogs_assert(param.n1smbuf);
param.n2smbuf =
ngap_build_qos_flow_resource_modify_request_transfer(
qos_flow, true);
ogs_assert(param.n2smbuf);
smf_namf_comm_send_n1_n2_message_transfer(sess, &param);
} else {
ogs_fatal("Unknown flags [0x%llx]", (long long)flags);
ogs_assert_if_reached();
}
} else if (flags &
(OGS_PFCP_MODIFY_TFT_NEW|OGS_PFCP_MODIFY_TFT_ADD|
OGS_PFCP_MODIFY_TFT_REPLACE|OGS_PFCP_MODIFY_TFT_DELETE|
OGS_PFCP_MODIFY_QOS_MODIFY)) {
smf_n1_n2_message_transfer_param_t param;
uint8_t qos_rule_code = 0;
uint8_t qos_flow_description_code = 0;
if (flags & OGS_PFCP_MODIFY_TFT_NEW) {
qos_rule_code = OGS_NAS_QOS_CODE_CREATE_NEW_QOS_RULE;
} else if (flags & OGS_PFCP_MODIFY_TFT_ADD) {
qos_rule_code = OGS_NAS_QOS_CODE_MODIFY_EXISTING_QOS_RULE_AND_ADD_PACKET_FILTERS;
} else if (flags & OGS_PFCP_MODIFY_TFT_REPLACE) {
qos_rule_code = OGS_NAS_QOS_CODE_MODIFY_EXISTING_QOS_RULE_AND_REPLACE_PACKET_FILTERS;
} else if (flags & OGS_PFCP_MODIFY_TFT_DELETE) {
qos_rule_code = OGS_NAS_QOS_CODE_MODIFY_EXISTING_QOS_RULE_AND_DELETE_PACKET_FILTERS;
}
if (flags & OGS_PFCP_MODIFY_QOS_CREATE) {
ogs_assert_if_reached();
} else if (flags & OGS_PFCP_MODIFY_QOS_MODIFY) {
qos_flow_description_code = OGS_NAS_MODIFY_NEW_QOS_FLOW_DESCRIPTION;
} else if (flags & OGS_PFCP_MODIFY_QOS_DELETE) {
ogs_assert_if_reached();
}
if (flags & OGS_PFCP_MODIFY_NETWORK_REQUESTED) {
ogs_assert(qos_flow);
2021-11-14 12:07:56 +00:00
memset(&param, 0, sizeof(param));
param.state = SMF_NETWORK_REQUESTED_QOS_FLOW_MODIFICATION;
param.n1smbuf = gsm_build_qos_flow_modification_command(
qos_flow,
OGS_NAS_PROCEDURE_TRANSACTION_IDENTITY_UNASSIGNED,
qos_rule_code, qos_flow_description_code);
ogs_assert(param.n1smbuf);
param.n2smbuf =
2021-11-14 12:07:56 +00:00
ngap_build_qos_flow_resource_modify_request_transfer(
qos_flow,
(flags & OGS_PFCP_MODIFY_QOS_MODIFY) ? true : false);
ogs_assert(param.n2smbuf);
2021-01-01 02:07:08 +00:00
smf_namf_comm_send_n1_n2_message_transfer(sess, &param);
2021-11-14 12:07:56 +00:00
} else if (flags & OGS_PFCP_MODIFY_UE_REQUESTED) {
ogs_pkbuf_t *n1smbuf = NULL, *n2smbuf = NULL;
ogs_assert(stream);
ogs_assert(qos_flow);
2021-11-14 12:07:56 +00:00
n1smbuf = gsm_build_qos_flow_modification_command(
qos_flow, sess->pti,
qos_rule_code, qos_flow_description_code);
ogs_assert(n1smbuf);
n2smbuf = ngap_build_qos_flow_resource_modify_request_transfer(
qos_flow,
(flags & OGS_PFCP_MODIFY_QOS_MODIFY) ? true : false);
ogs_assert(n2smbuf);
smf_sbi_send_sm_context_updated_data_n1_n2_message(sess, stream,
n1smbuf, OpenAPI_n2_sm_info_type_PDU_RES_MOD_REQ, n2smbuf);
} else {
ogs_fatal("Unknown flags [0x%llx]", (long long)flags);
ogs_assert_if_reached();
}
}
2020-06-17 05:22:28 +00:00
}
void smf_5gc_n4_handle_session_deletion_response(
smf_sess_t *sess, ogs_pfcp_xact_t *xact,
ogs_pfcp_session_deletion_response_t *rsp)
{
2020-07-04 03:14:48 +00:00
int status = 0;
2020-07-02 05:50:23 +00:00
int trigger;
ogs_sbi_stream_t *stream = NULL;
2020-06-22 03:07:14 +00:00
ogs_sbi_message_t sendmsg;
ogs_sbi_response_t *response = NULL;
2020-07-04 03:14:48 +00:00
ogs_assert(xact);
2020-06-22 03:07:14 +00:00
ogs_assert(rsp);
ogs_debug("Session Deletion Response [5gc]");
stream = xact->assoc_stream;
trigger = xact->delete_trigger;
2020-07-02 05:50:23 +00:00
ogs_assert(trigger);
2020-06-22 03:07:14 +00:00
ogs_pfcp_xact_commit(xact);
2020-07-04 03:14:48 +00:00
status = OGS_SBI_HTTP_STATUS_OK;
if (!sess) {
ogs_warn("No Context");
status = OGS_SBI_HTTP_STATUS_NOT_FOUND;
}
2020-06-22 03:07:14 +00:00
if (rsp->cause.presence) {
if (rsp->cause.u8 != OGS_PFCP_CAUSE_REQUEST_ACCEPTED) {
2020-07-04 03:14:48 +00:00
ogs_warn("PFCP Cause [%d] : Not Accepted", rsp->cause.u8);
status = sbi_status_from_pfcp(rsp->cause.u8);
2020-06-22 03:07:14 +00:00
}
} else {
ogs_error("No Cause");
2020-07-04 03:14:48 +00:00
status = OGS_SBI_HTTP_STATUS_BAD_REQUEST;
}
if (status != OGS_SBI_HTTP_STATUS_OK) {
char *strerror = ogs_msprintf(
"PFCP Cause [%d] : Not Accepted", rsp->cause.u8);
2021-11-14 12:07:56 +00:00
if (trigger == OGS_PFCP_DELETE_TRIGGER_UE_REQUESTED ||
trigger == OGS_PFCP_DELETE_TRIGGER_AMF_UPDATE_SM_CONTEXT) {
ogs_assert(stream);
smf_sbi_send_sm_context_update_error(
stream, status, strerror, NULL, NULL, NULL);
2021-11-14 12:07:56 +00:00
} else if (trigger == OGS_PFCP_DELETE_TRIGGER_AMF_RELEASE_SM_CONTEXT) {
ogs_assert(stream);
ogs_assert(true ==
ogs_sbi_server_send_error(
stream, status, NULL, strerror, NULL));
} else if (trigger == OGS_PFCP_DELETE_TRIGGER_PCF_INITIATED) {
/* No stream - Nothing */
} else {
ogs_fatal("Unknown trigger [%d]", trigger);
ogs_assert_if_reached();
}
ogs_error("%s", strerror);
2020-07-04 03:14:48 +00:00
ogs_free(strerror);
2020-06-22 03:07:14 +00:00
return;
}
2020-07-04 03:14:48 +00:00
ogs_assert(sess);
2020-08-13 00:31:22 +00:00
if (trigger == OGS_PFCP_DELETE_TRIGGER_UE_REQUESTED) {
2021-01-18 16:48:35 +00:00
ogs_pkbuf_t *n1smbuf = NULL, *n2smbuf = NULL;
2020-07-02 05:50:23 +00:00
2021-01-18 16:48:35 +00:00
n1smbuf = gsm_build_pdu_session_release_command(
sess, OGS_5GSM_CAUSE_REGULAR_DEACTIVATION);
ogs_assert(n1smbuf);
2020-06-22 03:07:14 +00:00
2021-01-18 16:48:35 +00:00
n2smbuf = ngap_build_pdu_session_resource_release_command_transfer(
sess, SMF_NGAP_STATE_DELETE_TRIGGER_UE_REQUESTED,
NGAP_Cause_PR_nas, NGAP_CauseNas_normal_release);
ogs_assert(n2smbuf);
2021-11-14 12:07:56 +00:00
ogs_assert(stream);
2021-01-18 16:48:35 +00:00
smf_sbi_send_sm_context_updated_data_n1_n2_message(sess, stream,
n1smbuf, OpenAPI_n2_sm_info_type_PDU_RES_REL_CMD, n2smbuf);
2021-11-14 12:07:56 +00:00
} else if (trigger == OGS_PFCP_DELETE_TRIGGER_AMF_UPDATE_SM_CONTEXT ||
trigger == OGS_PFCP_DELETE_TRIGGER_AMF_RELEASE_SM_CONTEXT) {
2020-07-02 05:50:23 +00:00
memset(&sendmsg, 0, sizeof(sendmsg));
response = ogs_sbi_build_response(
&sendmsg, OGS_SBI_HTTP_STATUS_NO_CONTENT);
ogs_assert(response);
2021-11-14 12:07:56 +00:00
ogs_assert(stream);
2021-06-06 13:35:46 +00:00
ogs_assert(true == ogs_sbi_server_send_response(stream, response));
2020-06-22 03:07:14 +00:00
2020-07-02 05:50:23 +00:00
SMF_SESS_CLEAR(sess);
2021-11-14 12:07:56 +00:00
} else if (trigger == OGS_PFCP_DELETE_TRIGGER_PCF_INITIATED) {
smf_n1_n2_message_transfer_param_t param;
memset(&param, 0, sizeof(param));
param.state = SMF_NETWORK_REQUESTED_PDU_SESSION_RELEASE;
param.n2smbuf =
ngap_build_pdu_session_resource_release_command_transfer(
sess, SMF_NGAP_STATE_DELETE_TRIGGER_PCF_INITIATED,
NGAP_Cause_PR_nas, NGAP_CauseNas_normal_release);
ogs_assert(param.n2smbuf);
param.skip_ind = true;
smf_namf_comm_send_n1_n2_message_transfer(sess, &param);
} else {
ogs_fatal("Unknown trigger [%d]", trigger);
ogs_assert_if_reached();
2020-07-02 05:50:23 +00:00
}
2020-06-17 05:22:28 +00:00
}
void smf_epc_n4_handle_session_establishment_response(
2020-04-26 19:36:05 +00:00
smf_sess_t *sess, ogs_pfcp_xact_t *xact,
ogs_pfcp_session_establishment_response_t *rsp)
{
uint8_t cause_value = 0;
Introduce Gn interface (GTPv1C) Support to PGW (#1351) * [CORE] tlv: Store mode in ogs_tlv_t This allows specifying the format of the IE for each individual IE, hence allowing messages containing IEs formatted in different ways. This is needed in order to support parsing GTPv1-C, since messages contain IEs with different structure (TLV vs TV). Hence, this is a preparation patch to add support for parsing TVs in ogs-tlv.c/.h. * [CORE] tlv: Support parsing msg with both TLV and TV in it IEs of type TV are sometimes used in GTPv1-C. Current tlv parser/builder doesn't provide with ways to parse messages which contain TV formatted IEs. This patch adds the relevant types and ways to encode/decode them. Furthermore, the current parser/builder allows parsing/building messages containing the exact same format in all its IEs. A new parser function is added which allows parsing messages of different types (TV, TLV) mixed in the same message. In order to be able to do so, it uses the general msg_mode passed to it in order to know the general TLV format (in essence, the length of the Tag field, and also the length of the Length field if applicable each IE). Looking up the instance in the TLV description is left undone and hadcoded to 0, since the only user so far requiring this API is GTPv1-C, which has no instances. * [CORE] tlv: Support repeated tag+instance parsing TLV message In GTPv2C, repeated IEs (same tag) are easily differentiated by the Instance byte, which provides info to match different decoded structures. In GTPv1C though, there's no Instance byte, and we still encounter repeated IEs (like GSN Address in Create PDP Context Request). Hence, the TLV decoder needs to be updated to track count of IEs found (identified by tag+instance, where instance is always 0 in GTPv1C) and get the proper description index + offset into the decoded structure. * [GTP]: Move GTPv2-C specifics to its own libgtp subdir This will allow adding GTPv1-C code by the side. Most GTPv2 code is left in this patch as "gtp" instead of renaming it to "gtp2" in order to avoid massive changes. It can be done at a later stage if wanted. * [GTP] Support generating GTPv1-C messages * [SMF] Add Gn interface support This patch introduces GTPv1C support to open5gs-smfd. With it, open5gs-becomes a GGSN too, where SGSN can connect to, hence supporting GERAN and UTRAN networks.
2022-02-18 13:23:45 +00:00
uint8_t resp_type = 0;
smf_bearer_t *bearer = NULL;
2020-04-26 19:36:05 +00:00
ogs_gtp_xact_t *gtp_xact = NULL;
2020-04-26 19:36:05 +00:00
ogs_pfcp_f_seid_t *up_f_seid = NULL;
ogs_assert(xact);
ogs_assert(rsp);
ogs_debug("Session Establishment Response [epc]");
2020-04-26 19:36:05 +00:00
gtp_xact = xact->assoc_xact;
ogs_assert(gtp_xact);
ogs_pfcp_xact_commit(xact);
Introduce Gn interface (GTPv1C) Support to PGW (#1351) * [CORE] tlv: Store mode in ogs_tlv_t This allows specifying the format of the IE for each individual IE, hence allowing messages containing IEs formatted in different ways. This is needed in order to support parsing GTPv1-C, since messages contain IEs with different structure (TLV vs TV). Hence, this is a preparation patch to add support for parsing TVs in ogs-tlv.c/.h. * [CORE] tlv: Support parsing msg with both TLV and TV in it IEs of type TV are sometimes used in GTPv1-C. Current tlv parser/builder doesn't provide with ways to parse messages which contain TV formatted IEs. This patch adds the relevant types and ways to encode/decode them. Furthermore, the current parser/builder allows parsing/building messages containing the exact same format in all its IEs. A new parser function is added which allows parsing messages of different types (TV, TLV) mixed in the same message. In order to be able to do so, it uses the general msg_mode passed to it in order to know the general TLV format (in essence, the length of the Tag field, and also the length of the Length field if applicable each IE). Looking up the instance in the TLV description is left undone and hadcoded to 0, since the only user so far requiring this API is GTPv1-C, which has no instances. * [CORE] tlv: Support repeated tag+instance parsing TLV message In GTPv2C, repeated IEs (same tag) are easily differentiated by the Instance byte, which provides info to match different decoded structures. In GTPv1C though, there's no Instance byte, and we still encounter repeated IEs (like GSN Address in Create PDP Context Request). Hence, the TLV decoder needs to be updated to track count of IEs found (identified by tag+instance, where instance is always 0 in GTPv1C) and get the proper description index + offset into the decoded structure. * [GTP]: Move GTPv2-C specifics to its own libgtp subdir This will allow adding GTPv1-C code by the side. Most GTPv2 code is left in this patch as "gtp" instead of renaming it to "gtp2" in order to avoid massive changes. It can be done at a later stage if wanted. * [GTP] Support generating GTPv1-C messages * [SMF] Add Gn interface support This patch introduces GTPv1C support to open5gs-smfd. With it, open5gs-becomes a GGSN too, where SGSN can connect to, hence supporting GERAN and UTRAN networks.
2022-02-18 13:23:45 +00:00
if (gtp_xact->gtp_version == 1) {
cause_value = OGS_GTP1_CAUSE_REQUEST_ACCEPTED;
resp_type = OGS_GTP1_CREATE_PDP_CONTEXT_RESPONSE_TYPE;
} else {
cause_value = OGS_GTP_CAUSE_REQUEST_ACCEPTED;
resp_type = OGS_GTP_CREATE_SESSION_RESPONSE_TYPE;
}
2020-04-26 19:36:05 +00:00
if (!sess) {
ogs_warn("No Context");
Introduce Gn interface (GTPv1C) Support to PGW (#1351) * [CORE] tlv: Store mode in ogs_tlv_t This allows specifying the format of the IE for each individual IE, hence allowing messages containing IEs formatted in different ways. This is needed in order to support parsing GTPv1-C, since messages contain IEs with different structure (TLV vs TV). Hence, this is a preparation patch to add support for parsing TVs in ogs-tlv.c/.h. * [CORE] tlv: Support parsing msg with both TLV and TV in it IEs of type TV are sometimes used in GTPv1-C. Current tlv parser/builder doesn't provide with ways to parse messages which contain TV formatted IEs. This patch adds the relevant types and ways to encode/decode them. Furthermore, the current parser/builder allows parsing/building messages containing the exact same format in all its IEs. A new parser function is added which allows parsing messages of different types (TV, TLV) mixed in the same message. In order to be able to do so, it uses the general msg_mode passed to it in order to know the general TLV format (in essence, the length of the Tag field, and also the length of the Length field if applicable each IE). Looking up the instance in the TLV description is left undone and hadcoded to 0, since the only user so far requiring this API is GTPv1-C, which has no instances. * [CORE] tlv: Support repeated tag+instance parsing TLV message In GTPv2C, repeated IEs (same tag) are easily differentiated by the Instance byte, which provides info to match different decoded structures. In GTPv1C though, there's no Instance byte, and we still encounter repeated IEs (like GSN Address in Create PDP Context Request). Hence, the TLV decoder needs to be updated to track count of IEs found (identified by tag+instance, where instance is always 0 in GTPv1C) and get the proper description index + offset into the decoded structure. * [GTP]: Move GTPv2-C specifics to its own libgtp subdir This will allow adding GTPv1-C code by the side. Most GTPv2 code is left in this patch as "gtp" instead of renaming it to "gtp2" in order to avoid massive changes. It can be done at a later stage if wanted. * [GTP] Support generating GTPv1-C messages * [SMF] Add Gn interface support This patch introduces GTPv1C support to open5gs-smfd. With it, open5gs-becomes a GGSN too, where SGSN can connect to, hence supporting GERAN and UTRAN networks.
2022-02-18 13:23:45 +00:00
cause_value = (gtp_xact->gtp_version == 1) ?
OGS_GTP1_CAUSE_CONTEXT_NOT_FOUND :
OGS_GTP_CAUSE_CONTEXT_NOT_FOUND;
2020-04-26 19:36:05 +00:00
}
if (rsp->up_f_seid.presence == 0) {
ogs_error("No UP F-SEID");
Introduce Gn interface (GTPv1C) Support to PGW (#1351) * [CORE] tlv: Store mode in ogs_tlv_t This allows specifying the format of the IE for each individual IE, hence allowing messages containing IEs formatted in different ways. This is needed in order to support parsing GTPv1-C, since messages contain IEs with different structure (TLV vs TV). Hence, this is a preparation patch to add support for parsing TVs in ogs-tlv.c/.h. * [CORE] tlv: Support parsing msg with both TLV and TV in it IEs of type TV are sometimes used in GTPv1-C. Current tlv parser/builder doesn't provide with ways to parse messages which contain TV formatted IEs. This patch adds the relevant types and ways to encode/decode them. Furthermore, the current parser/builder allows parsing/building messages containing the exact same format in all its IEs. A new parser function is added which allows parsing messages of different types (TV, TLV) mixed in the same message. In order to be able to do so, it uses the general msg_mode passed to it in order to know the general TLV format (in essence, the length of the Tag field, and also the length of the Length field if applicable each IE). Looking up the instance in the TLV description is left undone and hadcoded to 0, since the only user so far requiring this API is GTPv1-C, which has no instances. * [CORE] tlv: Support repeated tag+instance parsing TLV message In GTPv2C, repeated IEs (same tag) are easily differentiated by the Instance byte, which provides info to match different decoded structures. In GTPv1C though, there's no Instance byte, and we still encounter repeated IEs (like GSN Address in Create PDP Context Request). Hence, the TLV decoder needs to be updated to track count of IEs found (identified by tag+instance, where instance is always 0 in GTPv1C) and get the proper description index + offset into the decoded structure. * [GTP]: Move GTPv2-C specifics to its own libgtp subdir This will allow adding GTPv1-C code by the side. Most GTPv2 code is left in this patch as "gtp" instead of renaming it to "gtp2" in order to avoid massive changes. It can be done at a later stage if wanted. * [GTP] Support generating GTPv1-C messages * [SMF] Add Gn interface support This patch introduces GTPv1C support to open5gs-smfd. With it, open5gs-becomes a GGSN too, where SGSN can connect to, hence supporting GERAN and UTRAN networks.
2022-02-18 13:23:45 +00:00
cause_value = (gtp_xact->gtp_version == 1) ?
OGS_GTP1_CAUSE_MANDATORY_IE_MISSING :
OGS_GTP_CAUSE_MANDATORY_IE_MISSING;
2020-04-26 19:36:05 +00:00
}
if (rsp->created_pdr[0].presence == 0) {
ogs_error("No Created PDR");
Introduce Gn interface (GTPv1C) Support to PGW (#1351) * [CORE] tlv: Store mode in ogs_tlv_t This allows specifying the format of the IE for each individual IE, hence allowing messages containing IEs formatted in different ways. This is needed in order to support parsing GTPv1-C, since messages contain IEs with different structure (TLV vs TV). Hence, this is a preparation patch to add support for parsing TVs in ogs-tlv.c/.h. * [CORE] tlv: Support parsing msg with both TLV and TV in it IEs of type TV are sometimes used in GTPv1-C. Current tlv parser/builder doesn't provide with ways to parse messages which contain TV formatted IEs. This patch adds the relevant types and ways to encode/decode them. Furthermore, the current parser/builder allows parsing/building messages containing the exact same format in all its IEs. A new parser function is added which allows parsing messages of different types (TV, TLV) mixed in the same message. In order to be able to do so, it uses the general msg_mode passed to it in order to know the general TLV format (in essence, the length of the Tag field, and also the length of the Length field if applicable each IE). Looking up the instance in the TLV description is left undone and hadcoded to 0, since the only user so far requiring this API is GTPv1-C, which has no instances. * [CORE] tlv: Support repeated tag+instance parsing TLV message In GTPv2C, repeated IEs (same tag) are easily differentiated by the Instance byte, which provides info to match different decoded structures. In GTPv1C though, there's no Instance byte, and we still encounter repeated IEs (like GSN Address in Create PDP Context Request). Hence, the TLV decoder needs to be updated to track count of IEs found (identified by tag+instance, where instance is always 0 in GTPv1C) and get the proper description index + offset into the decoded structure. * [GTP]: Move GTPv2-C specifics to its own libgtp subdir This will allow adding GTPv1-C code by the side. Most GTPv2 code is left in this patch as "gtp" instead of renaming it to "gtp2" in order to avoid massive changes. It can be done at a later stage if wanted. * [GTP] Support generating GTPv1-C messages * [SMF] Add Gn interface support This patch introduces GTPv1C support to open5gs-smfd. With it, open5gs-becomes a GGSN too, where SGSN can connect to, hence supporting GERAN and UTRAN networks.
2022-02-18 13:23:45 +00:00
cause_value = (gtp_xact->gtp_version == 1) ?
OGS_GTP1_CAUSE_MANDATORY_IE_MISSING :
OGS_GTP_CAUSE_MANDATORY_IE_MISSING;
}
2020-04-26 19:36:05 +00:00
if (rsp->cause.presence) {
if (rsp->cause.u8 != OGS_PFCP_CAUSE_REQUEST_ACCEPTED) {
2020-07-04 03:14:48 +00:00
ogs_warn("PFCP Cause [%d] : Not Accepted", rsp->cause.u8);
Introduce Gn interface (GTPv1C) Support to PGW (#1351) * [CORE] tlv: Store mode in ogs_tlv_t This allows specifying the format of the IE for each individual IE, hence allowing messages containing IEs formatted in different ways. This is needed in order to support parsing GTPv1-C, since messages contain IEs with different structure (TLV vs TV). Hence, this is a preparation patch to add support for parsing TVs in ogs-tlv.c/.h. * [CORE] tlv: Support parsing msg with both TLV and TV in it IEs of type TV are sometimes used in GTPv1-C. Current tlv parser/builder doesn't provide with ways to parse messages which contain TV formatted IEs. This patch adds the relevant types and ways to encode/decode them. Furthermore, the current parser/builder allows parsing/building messages containing the exact same format in all its IEs. A new parser function is added which allows parsing messages of different types (TV, TLV) mixed in the same message. In order to be able to do so, it uses the general msg_mode passed to it in order to know the general TLV format (in essence, the length of the Tag field, and also the length of the Length field if applicable each IE). Looking up the instance in the TLV description is left undone and hadcoded to 0, since the only user so far requiring this API is GTPv1-C, which has no instances. * [CORE] tlv: Support repeated tag+instance parsing TLV message In GTPv2C, repeated IEs (same tag) are easily differentiated by the Instance byte, which provides info to match different decoded structures. In GTPv1C though, there's no Instance byte, and we still encounter repeated IEs (like GSN Address in Create PDP Context Request). Hence, the TLV decoder needs to be updated to track count of IEs found (identified by tag+instance, where instance is always 0 in GTPv1C) and get the proper description index + offset into the decoded structure. * [GTP]: Move GTPv2-C specifics to its own libgtp subdir This will allow adding GTPv1-C code by the side. Most GTPv2 code is left in this patch as "gtp" instead of renaming it to "gtp2" in order to avoid massive changes. It can be done at a later stage if wanted. * [GTP] Support generating GTPv1-C messages * [SMF] Add Gn interface support This patch introduces GTPv1C support to open5gs-smfd. With it, open5gs-becomes a GGSN too, where SGSN can connect to, hence supporting GERAN and UTRAN networks.
2022-02-18 13:23:45 +00:00
cause_value = gtp_cause_from_pfcp(rsp->cause.u8, gtp_xact->gtp_version);
2020-04-26 19:36:05 +00:00
}
} else {
ogs_error("No Cause");
Introduce Gn interface (GTPv1C) Support to PGW (#1351) * [CORE] tlv: Store mode in ogs_tlv_t This allows specifying the format of the IE for each individual IE, hence allowing messages containing IEs formatted in different ways. This is needed in order to support parsing GTPv1-C, since messages contain IEs with different structure (TLV vs TV). Hence, this is a preparation patch to add support for parsing TVs in ogs-tlv.c/.h. * [CORE] tlv: Support parsing msg with both TLV and TV in it IEs of type TV are sometimes used in GTPv1-C. Current tlv parser/builder doesn't provide with ways to parse messages which contain TV formatted IEs. This patch adds the relevant types and ways to encode/decode them. Furthermore, the current parser/builder allows parsing/building messages containing the exact same format in all its IEs. A new parser function is added which allows parsing messages of different types (TV, TLV) mixed in the same message. In order to be able to do so, it uses the general msg_mode passed to it in order to know the general TLV format (in essence, the length of the Tag field, and also the length of the Length field if applicable each IE). Looking up the instance in the TLV description is left undone and hadcoded to 0, since the only user so far requiring this API is GTPv1-C, which has no instances. * [CORE] tlv: Support repeated tag+instance parsing TLV message In GTPv2C, repeated IEs (same tag) are easily differentiated by the Instance byte, which provides info to match different decoded structures. In GTPv1C though, there's no Instance byte, and we still encounter repeated IEs (like GSN Address in Create PDP Context Request). Hence, the TLV decoder needs to be updated to track count of IEs found (identified by tag+instance, where instance is always 0 in GTPv1C) and get the proper description index + offset into the decoded structure. * [GTP]: Move GTPv2-C specifics to its own libgtp subdir This will allow adding GTPv1-C code by the side. Most GTPv2 code is left in this patch as "gtp" instead of renaming it to "gtp2" in order to avoid massive changes. It can be done at a later stage if wanted. * [GTP] Support generating GTPv1-C messages * [SMF] Add Gn interface support This patch introduces GTPv1C support to open5gs-smfd. With it, open5gs-becomes a GGSN too, where SGSN can connect to, hence supporting GERAN and UTRAN networks.
2022-02-18 13:23:45 +00:00
cause_value = (gtp_xact->gtp_version == 1) ?
OGS_GTP1_CAUSE_MANDATORY_IE_MISSING :
OGS_GTP_CAUSE_MANDATORY_IE_MISSING;
2020-04-26 19:36:05 +00:00
}
Introduce Gn interface (GTPv1C) Support to PGW (#1351) * [CORE] tlv: Store mode in ogs_tlv_t This allows specifying the format of the IE for each individual IE, hence allowing messages containing IEs formatted in different ways. This is needed in order to support parsing GTPv1-C, since messages contain IEs with different structure (TLV vs TV). Hence, this is a preparation patch to add support for parsing TVs in ogs-tlv.c/.h. * [CORE] tlv: Support parsing msg with both TLV and TV in it IEs of type TV are sometimes used in GTPv1-C. Current tlv parser/builder doesn't provide with ways to parse messages which contain TV formatted IEs. This patch adds the relevant types and ways to encode/decode them. Furthermore, the current parser/builder allows parsing/building messages containing the exact same format in all its IEs. A new parser function is added which allows parsing messages of different types (TV, TLV) mixed in the same message. In order to be able to do so, it uses the general msg_mode passed to it in order to know the general TLV format (in essence, the length of the Tag field, and also the length of the Length field if applicable each IE). Looking up the instance in the TLV description is left undone and hadcoded to 0, since the only user so far requiring this API is GTPv1-C, which has no instances. * [CORE] tlv: Support repeated tag+instance parsing TLV message In GTPv2C, repeated IEs (same tag) are easily differentiated by the Instance byte, which provides info to match different decoded structures. In GTPv1C though, there's no Instance byte, and we still encounter repeated IEs (like GSN Address in Create PDP Context Request). Hence, the TLV decoder needs to be updated to track count of IEs found (identified by tag+instance, where instance is always 0 in GTPv1C) and get the proper description index + offset into the decoded structure. * [GTP]: Move GTPv2-C specifics to its own libgtp subdir This will allow adding GTPv1-C code by the side. Most GTPv2 code is left in this patch as "gtp" instead of renaming it to "gtp2" in order to avoid massive changes. It can be done at a later stage if wanted. * [GTP] Support generating GTPv1-C messages * [SMF] Add Gn interface support This patch introduces GTPv1C support to open5gs-smfd. With it, open5gs-becomes a GGSN too, where SGSN can connect to, hence supporting GERAN and UTRAN networks.
2022-02-18 13:23:45 +00:00
if ((gtp_xact->gtp_version == 1 && cause_value == OGS_GTP1_CAUSE_REQUEST_ACCEPTED) ||
(gtp_xact->gtp_version == 2 && cause_value == OGS_GTP_CAUSE_REQUEST_ACCEPTED)) {
int i;
uint8_t pfcp_cause_value = OGS_PFCP_CAUSE_REQUEST_ACCEPTED;
uint8_t offending_ie_value = 0;
ogs_assert(sess);
for (i = 0; i < OGS_MAX_NUM_OF_PDR; i++) {
ogs_pfcp_pdr_t *pdr = NULL;
2021-03-15 01:01:55 +00:00
ogs_pfcp_far_t *far = NULL;
pdr = ogs_pfcp_handle_created_pdr(
&sess->pfcp, &rsp->created_pdr[i],
&pfcp_cause_value, &offending_ie_value);
if (!pdr)
break;
2021-03-15 01:01:55 +00:00
far = pdr->far;
ogs_assert(far);
if (pdr->src_if == OGS_PFCP_INTERFACE_ACCESS) {
smf_bearer_t *pdr_bearer = NULL;
2021-03-15 01:01:55 +00:00
if (far->dst_if == OGS_PFCP_INTERFACE_CP_FUNCTION)
ogs_pfcp_far_teid_hash_set(far);
pdr_bearer = smf_bearer_find_by_pdr_id(sess, pdr->id);
if (pdr_bearer) {
2021-03-15 01:01:55 +00:00
ogs_assert(sess->pfcp_node);
if (sess->pfcp_node->up_function_features.ftup &&
pdr->f_teid_len) {
if (pdr_bearer->pgw_s5u_addr)
ogs_freeaddrinfo(pdr_bearer->pgw_s5u_addr);
if (pdr_bearer->pgw_s5u_addr)
ogs_freeaddrinfo(pdr_bearer->pgw_s5u_addr6);
2021-03-15 01:01:55 +00:00
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,
&pdr_bearer->pgw_s5u_addr,
&pdr_bearer->pgw_s5u_addr6));
pdr_bearer->pgw_s5u_teid = pdr->f_teid.teid;
2021-03-15 01:01:55 +00:00
}
}
} else 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));
}
}
Introduce Gn interface (GTPv1C) Support to PGW (#1351) * [CORE] tlv: Store mode in ogs_tlv_t This allows specifying the format of the IE for each individual IE, hence allowing messages containing IEs formatted in different ways. This is needed in order to support parsing GTPv1-C, since messages contain IEs with different structure (TLV vs TV). Hence, this is a preparation patch to add support for parsing TVs in ogs-tlv.c/.h. * [CORE] tlv: Support parsing msg with both TLV and TV in it IEs of type TV are sometimes used in GTPv1-C. Current tlv parser/builder doesn't provide with ways to parse messages which contain TV formatted IEs. This patch adds the relevant types and ways to encode/decode them. Furthermore, the current parser/builder allows parsing/building messages containing the exact same format in all its IEs. A new parser function is added which allows parsing messages of different types (TV, TLV) mixed in the same message. In order to be able to do so, it uses the general msg_mode passed to it in order to know the general TLV format (in essence, the length of the Tag field, and also the length of the Length field if applicable each IE). Looking up the instance in the TLV description is left undone and hadcoded to 0, since the only user so far requiring this API is GTPv1-C, which has no instances. * [CORE] tlv: Support repeated tag+instance parsing TLV message In GTPv2C, repeated IEs (same tag) are easily differentiated by the Instance byte, which provides info to match different decoded structures. In GTPv1C though, there's no Instance byte, and we still encounter repeated IEs (like GSN Address in Create PDP Context Request). Hence, the TLV decoder needs to be updated to track count of IEs found (identified by tag+instance, where instance is always 0 in GTPv1C) and get the proper description index + offset into the decoded structure. * [GTP]: Move GTPv2-C specifics to its own libgtp subdir This will allow adding GTPv1-C code by the side. Most GTPv2 code is left in this patch as "gtp" instead of renaming it to "gtp2" in order to avoid massive changes. It can be done at a later stage if wanted. * [GTP] Support generating GTPv1-C messages * [SMF] Add Gn interface support This patch introduces GTPv1C support to open5gs-smfd. With it, open5gs-becomes a GGSN too, where SGSN can connect to, hence supporting GERAN and UTRAN networks.
2022-02-18 13:23:45 +00:00
cause_value = gtp_cause_from_pfcp(pfcp_cause_value, gtp_xact->gtp_version);
}
Introduce Gn interface (GTPv1C) Support to PGW (#1351) * [CORE] tlv: Store mode in ogs_tlv_t This allows specifying the format of the IE for each individual IE, hence allowing messages containing IEs formatted in different ways. This is needed in order to support parsing GTPv1-C, since messages contain IEs with different structure (TLV vs TV). Hence, this is a preparation patch to add support for parsing TVs in ogs-tlv.c/.h. * [CORE] tlv: Support parsing msg with both TLV and TV in it IEs of type TV are sometimes used in GTPv1-C. Current tlv parser/builder doesn't provide with ways to parse messages which contain TV formatted IEs. This patch adds the relevant types and ways to encode/decode them. Furthermore, the current parser/builder allows parsing/building messages containing the exact same format in all its IEs. A new parser function is added which allows parsing messages of different types (TV, TLV) mixed in the same message. In order to be able to do so, it uses the general msg_mode passed to it in order to know the general TLV format (in essence, the length of the Tag field, and also the length of the Length field if applicable each IE). Looking up the instance in the TLV description is left undone and hadcoded to 0, since the only user so far requiring this API is GTPv1-C, which has no instances. * [CORE] tlv: Support repeated tag+instance parsing TLV message In GTPv2C, repeated IEs (same tag) are easily differentiated by the Instance byte, which provides info to match different decoded structures. In GTPv1C though, there's no Instance byte, and we still encounter repeated IEs (like GSN Address in Create PDP Context Request). Hence, the TLV decoder needs to be updated to track count of IEs found (identified by tag+instance, where instance is always 0 in GTPv1C) and get the proper description index + offset into the decoded structure. * [GTP]: Move GTPv2-C specifics to its own libgtp subdir This will allow adding GTPv1-C code by the side. Most GTPv2 code is left in this patch as "gtp" instead of renaming it to "gtp2" in order to avoid massive changes. It can be done at a later stage if wanted. * [GTP] Support generating GTPv1-C messages * [SMF] Add Gn interface support This patch introduces GTPv1C support to open5gs-smfd. With it, open5gs-becomes a GGSN too, where SGSN can connect to, hence supporting GERAN and UTRAN networks.
2022-02-18 13:23:45 +00:00
if ((gtp_xact->gtp_version == 1 && cause_value != OGS_GTP1_CAUSE_REQUEST_ACCEPTED) ||
(gtp_xact->gtp_version == 2 && cause_value != OGS_GTP_CAUSE_REQUEST_ACCEPTED)) {
2020-04-26 19:36:05 +00:00
ogs_gtp_send_error_message(gtp_xact, sess ? sess->sgw_s5c_teid : 0,
Introduce Gn interface (GTPv1C) Support to PGW (#1351) * [CORE] tlv: Store mode in ogs_tlv_t This allows specifying the format of the IE for each individual IE, hence allowing messages containing IEs formatted in different ways. This is needed in order to support parsing GTPv1-C, since messages contain IEs with different structure (TLV vs TV). Hence, this is a preparation patch to add support for parsing TVs in ogs-tlv.c/.h. * [CORE] tlv: Support parsing msg with both TLV and TV in it IEs of type TV are sometimes used in GTPv1-C. Current tlv parser/builder doesn't provide with ways to parse messages which contain TV formatted IEs. This patch adds the relevant types and ways to encode/decode them. Furthermore, the current parser/builder allows parsing/building messages containing the exact same format in all its IEs. A new parser function is added which allows parsing messages of different types (TV, TLV) mixed in the same message. In order to be able to do so, it uses the general msg_mode passed to it in order to know the general TLV format (in essence, the length of the Tag field, and also the length of the Length field if applicable each IE). Looking up the instance in the TLV description is left undone and hadcoded to 0, since the only user so far requiring this API is GTPv1-C, which has no instances. * [CORE] tlv: Support repeated tag+instance parsing TLV message In GTPv2C, repeated IEs (same tag) are easily differentiated by the Instance byte, which provides info to match different decoded structures. In GTPv1C though, there's no Instance byte, and we still encounter repeated IEs (like GSN Address in Create PDP Context Request). Hence, the TLV decoder needs to be updated to track count of IEs found (identified by tag+instance, where instance is always 0 in GTPv1C) and get the proper description index + offset into the decoded structure. * [GTP]: Move GTPv2-C specifics to its own libgtp subdir This will allow adding GTPv1-C code by the side. Most GTPv2 code is left in this patch as "gtp" instead of renaming it to "gtp2" in order to avoid massive changes. It can be done at a later stage if wanted. * [GTP] Support generating GTPv1-C messages * [SMF] Add Gn interface support This patch introduces GTPv1C support to open5gs-smfd. With it, open5gs-becomes a GGSN too, where SGSN can connect to, hence supporting GERAN and UTRAN networks.
2022-02-18 13:23:45 +00:00
resp_type, cause_value);
2020-04-26 19:36:05 +00:00
return;
}
ogs_assert(sess);
bearer = smf_default_bearer_in_sess(sess);
ogs_assert(bearer);
if (bearer->pgw_s5u_addr == NULL && bearer->pgw_s5u_addr6 == NULL) {
ogs_error("No UP F-TEID");
ogs_gtp_send_error_message(gtp_xact, sess ? sess->sgw_s5c_teid : 0,
Introduce Gn interface (GTPv1C) Support to PGW (#1351) * [CORE] tlv: Store mode in ogs_tlv_t This allows specifying the format of the IE for each individual IE, hence allowing messages containing IEs formatted in different ways. This is needed in order to support parsing GTPv1-C, since messages contain IEs with different structure (TLV vs TV). Hence, this is a preparation patch to add support for parsing TVs in ogs-tlv.c/.h. * [CORE] tlv: Support parsing msg with both TLV and TV in it IEs of type TV are sometimes used in GTPv1-C. Current tlv parser/builder doesn't provide with ways to parse messages which contain TV formatted IEs. This patch adds the relevant types and ways to encode/decode them. Furthermore, the current parser/builder allows parsing/building messages containing the exact same format in all its IEs. A new parser function is added which allows parsing messages of different types (TV, TLV) mixed in the same message. In order to be able to do so, it uses the general msg_mode passed to it in order to know the general TLV format (in essence, the length of the Tag field, and also the length of the Length field if applicable each IE). Looking up the instance in the TLV description is left undone and hadcoded to 0, since the only user so far requiring this API is GTPv1-C, which has no instances. * [CORE] tlv: Support repeated tag+instance parsing TLV message In GTPv2C, repeated IEs (same tag) are easily differentiated by the Instance byte, which provides info to match different decoded structures. In GTPv1C though, there's no Instance byte, and we still encounter repeated IEs (like GSN Address in Create PDP Context Request). Hence, the TLV decoder needs to be updated to track count of IEs found (identified by tag+instance, where instance is always 0 in GTPv1C) and get the proper description index + offset into the decoded structure. * [GTP]: Move GTPv2-C specifics to its own libgtp subdir This will allow adding GTPv1-C code by the side. Most GTPv2 code is left in this patch as "gtp" instead of renaming it to "gtp2" in order to avoid massive changes. It can be done at a later stage if wanted. * [GTP] Support generating GTPv1-C messages * [SMF] Add Gn interface support This patch introduces GTPv1C support to open5gs-smfd. With it, open5gs-becomes a GGSN too, where SGSN can connect to, hence supporting GERAN and UTRAN networks.
2022-02-18 13:23:45 +00:00
resp_type,
(gtp_xact->gtp_version == 1) ?
OGS_GTP1_CAUSE_CONTEXT_NOT_FOUND : OGS_GTP_CAUSE_GRE_KEY_NOT_FOUND);
return;
}
2020-04-26 19:36:05 +00:00
/* UP F-SEID */
up_f_seid = rsp->up_f_seid.data;
ogs_assert(up_f_seid);
sess->upf_n4_seid = be64toh(up_f_seid->seid);
Introduce Gn interface (GTPv1C) Support to PGW (#1351) * [CORE] tlv: Store mode in ogs_tlv_t This allows specifying the format of the IE for each individual IE, hence allowing messages containing IEs formatted in different ways. This is needed in order to support parsing GTPv1-C, since messages contain IEs with different structure (TLV vs TV). Hence, this is a preparation patch to add support for parsing TVs in ogs-tlv.c/.h. * [CORE] tlv: Support parsing msg with both TLV and TV in it IEs of type TV are sometimes used in GTPv1-C. Current tlv parser/builder doesn't provide with ways to parse messages which contain TV formatted IEs. This patch adds the relevant types and ways to encode/decode them. Furthermore, the current parser/builder allows parsing/building messages containing the exact same format in all its IEs. A new parser function is added which allows parsing messages of different types (TV, TLV) mixed in the same message. In order to be able to do so, it uses the general msg_mode passed to it in order to know the general TLV format (in essence, the length of the Tag field, and also the length of the Length field if applicable each IE). Looking up the instance in the TLV description is left undone and hadcoded to 0, since the only user so far requiring this API is GTPv1-C, which has no instances. * [CORE] tlv: Support repeated tag+instance parsing TLV message In GTPv2C, repeated IEs (same tag) are easily differentiated by the Instance byte, which provides info to match different decoded structures. In GTPv1C though, there's no Instance byte, and we still encounter repeated IEs (like GSN Address in Create PDP Context Request). Hence, the TLV decoder needs to be updated to track count of IEs found (identified by tag+instance, where instance is always 0 in GTPv1C) and get the proper description index + offset into the decoded structure. * [GTP]: Move GTPv2-C specifics to its own libgtp subdir This will allow adding GTPv1-C code by the side. Most GTPv2 code is left in this patch as "gtp" instead of renaming it to "gtp2" in order to avoid massive changes. It can be done at a later stage if wanted. * [GTP] Support generating GTPv1-C messages * [SMF] Add Gn interface support This patch introduces GTPv1C support to open5gs-smfd. With it, open5gs-becomes a GGSN too, where SGSN can connect to, hence supporting GERAN and UTRAN networks.
2022-02-18 13:23:45 +00:00
switch (gtp_xact->gtp_version) {
case 1:
ogs_assert(OGS_OK == smf_gtp1_send_create_pdp_context_response(sess, gtp_xact));
break;
case 2:
ogs_assert(OGS_OK == smf_gtp_send_create_session_response(sess, gtp_xact));
break;
}
2021-06-21 13:36:38 +00:00
if (sess->gtp_rat_type == OGS_GTP_RAT_TYPE_WLAN) {
/*
* TS23.214
* 6.3.1.7 Procedures with modification of bearer
* p50
* 2. ...
* For "PGW/MME initiated bearer deactivation procedure",
* PGW-C shall indicate PGW-U to stop counting and stop
* forwarding downlink packets for the affected bearer(s).
*/
2021-06-21 13:36:38 +00:00
smf_ue_t *smf_ue = NULL;
smf_sess_t *eutran_sess = NULL;
smf_ue = sess->smf_ue;
ogs_assert(smf_ue);
eutran_sess = smf_sess_find_by_apn(
smf_ue, sess->session.name, OGS_GTP_RAT_TYPE_EUTRAN);
2021-06-21 13:36:38 +00:00
if (eutran_sess) {
ogs_assert(OGS_OK ==
smf_epc_pfcp_send_session_modification_request(
eutran_sess, NULL,
OGS_PFCP_MODIFY_DL_ONLY|OGS_PFCP_MODIFY_DEACTIVATE,
2021-06-21 13:36:38 +00:00
OGS_NAS_PROCEDURE_TRANSACTION_IDENTITY_UNASSIGNED,
OGS_GTP_CAUSE_RAT_CHANGED_FROM_3GPP_TO_NON_3GPP));
}
}
2020-04-26 19:36:05 +00:00
smf_bearer_binding(sess);
}
2020-06-17 05:22:28 +00:00
void smf_epc_n4_handle_session_modification_response(
2020-04-26 19:36:05 +00:00
smf_sess_t *sess, ogs_pfcp_xact_t *xact,
ogs_pfcp_session_modification_response_t *rsp)
{
int i;
2020-04-26 19:36:05 +00:00
smf_bearer_t *bearer = NULL;
ogs_gtp_xact_t *gtp_xact = NULL;
uint8_t gtp_pti = OGS_NAS_PROCEDURE_TRANSACTION_IDENTITY_UNASSIGNED;
uint8_t gtp_cause = OGS_GTP_CAUSE_UNDEFINED_VALUE;
2020-08-13 00:31:22 +00:00
uint64_t flags = 0;
2020-04-26 19:36:05 +00:00
uint8_t pfcp_cause_value = OGS_PFCP_CAUSE_REQUEST_ACCEPTED;
uint8_t offending_ie_value = 0;
2020-04-26 19:36:05 +00:00
ogs_assert(xact);
ogs_assert(rsp);
ogs_debug("Session Modification Response [epc]");
if (flags & OGS_PFCP_MODIFY_SESSION) {
/* If smf_epc_pfcp_send_session_modification_request() is called */
} else {
/* If smf_epc_pfcp_send_bearer_modification_request() is called */
bearer = xact->data;
ogs_assert(bearer);
}
2020-08-13 00:31:22 +00:00
flags = xact->modify_flags;
ogs_assert(flags);
2020-04-26 19:36:05 +00:00
gtp_xact = xact->assoc_xact;
gtp_pti = xact->gtp_pti;
gtp_cause = xact->gtp_cause;
2020-04-26 19:36:05 +00:00
ogs_pfcp_xact_commit(xact);
if (!sess) {
ogs_error("No Context");
return;
}
if (rsp->cause.presence) {
if (rsp->cause.u8 != OGS_PFCP_CAUSE_REQUEST_ACCEPTED) {
ogs_error("PFCP Cause [%d] : Not Accepted", rsp->cause.u8);
return;
}
} else {
ogs_error("No Cause");
return;
}
ogs_assert(sess);
pfcp_cause_value = OGS_PFCP_CAUSE_REQUEST_ACCEPTED;
for (i = 0; i < OGS_MAX_NUM_OF_PDR; i++) {
ogs_pfcp_pdr_t *pdr = NULL;
2021-03-15 01:01:55 +00:00
ogs_pfcp_far_t *far = NULL;
pdr = ogs_pfcp_handle_created_pdr(
&sess->pfcp, &rsp->created_pdr[i],
&pfcp_cause_value, &offending_ie_value);
if (!pdr)
break;
2021-03-15 01:01:55 +00:00
far = pdr->far;
ogs_assert(far);
if (pdr->src_if == OGS_PFCP_INTERFACE_ACCESS) {
smf_bearer_t *pdr_bearer = NULL;
2021-03-15 01:01:55 +00:00
if (far->dst_if == OGS_PFCP_INTERFACE_CP_FUNCTION)
ogs_pfcp_far_teid_hash_set(far);
pdr_bearer = smf_bearer_find_by_pdr_id(sess, pdr->id);
if (pdr_bearer) {
ogs_assert(sess->pfcp_node);
if (sess->pfcp_node->up_function_features.ftup &&
pdr->f_teid_len) {
if (pdr_bearer->pgw_s5u_addr)
ogs_freeaddrinfo(pdr_bearer->pgw_s5u_addr);
if (pdr_bearer->pgw_s5u_addr)
ogs_freeaddrinfo(pdr_bearer->pgw_s5u_addr6);
ogs_assert(OGS_OK ==
ogs_pfcp_f_teid_to_sockaddr(
&pdr->f_teid, pdr->f_teid_len,
&pdr_bearer->pgw_s5u_addr,
&pdr_bearer->pgw_s5u_addr6));
pdr_bearer->pgw_s5u_teid = pdr->f_teid.teid;
}
2021-03-15 01:01:55 +00:00
}
} else 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));
}
}
if (pfcp_cause_value != OGS_PFCP_CAUSE_REQUEST_ACCEPTED) {
ogs_error("PFCP Cause [%d] : Not Accepted", pfcp_cause_value);
return;
}
if (flags & OGS_PFCP_MODIFY_REMOVE) {
ogs_assert(bearer);
2020-04-26 19:36:05 +00:00
smf_bearer_remove(bearer);
} else if (flags & OGS_PFCP_MODIFY_CREATE) {
ogs_assert(bearer);
2021-06-06 13:35:46 +00:00
ogs_assert(OGS_OK == smf_gtp_send_create_bearer_request(bearer));
} else if (flags & OGS_PFCP_MODIFY_DEACTIVATE) {
/*
* TS23.214
* 6.3.1.7 Procedures with modification of bearer
* p50
* 2. ...
* For "PGW/MME initiated bearer deactivation procedure",
* PGW-C shall indicate PGW-U to stop counting and stop
* forwarding downlink packets for the affected bearer(s).
*/
if (gtp_xact) {
/*
* 1. MME sends Bearer Resource Command to SGW/SMF.
* 2. SMF sends Delete Bearer Request(DEDICATED BEARER) to SGW/MME
* 3. MME sends Delete Bearer Response(DEDICATED BEARER) to SGW/SMF
*/
ogs_gtp_header_t h;
ogs_pkbuf_t *pkbuf = NULL;
int rv;
ogs_assert(bearer);
memset(&h, 0, sizeof(ogs_gtp_header_t));
h.teid = sess->sgw_s5c_teid;
h.type = OGS_GTP_DELETE_BEARER_REQUEST_TYPE;
pkbuf = smf_s5c_build_delete_bearer_request(
h.type, bearer, gtp_pti, gtp_cause);
ogs_expect_or_return(pkbuf);
rv = ogs_gtp_xact_update_tx(gtp_xact, &h, pkbuf);
ogs_expect_or_return(rv == OGS_OK);
/* IMPORTANT:
*
* When initiaited by Bearer Resource Command,
* there must be bearer context in the Transaction.
* Otherwise, the bearer context cannot be found
* in GTP response message.
*
* For example,
* 1. MME sends Bearer Resource Command to SGW-C, SMF.
* 2. SMF sends Update/Delete Bearer Request to the SGW-C, MME.
* 3. MME sends Update/Delete Bearer Response to thw SGW-C, SMF.
*
* On number 3 step, if MME sends Response without Bearer Context,
* we need a way to find Bearer context.
*
* To do this, I saved Bearer Context in Transaction Context.
*/
gtp_xact->data = bearer;
rv = ogs_gtp_xact_commit(gtp_xact);
ogs_expect(rv == OGS_OK);
} else {
if (flags & OGS_PFCP_MODIFY_SESSION) {
/*
* 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.
*/
smf_bearer_t *linked_bearer =
ogs_list_first(&sess->bearer_list);
ogs_assert(linked_bearer);
ogs_assert(OGS_OK ==
smf_gtp_send_delete_bearer_request(
linked_bearer, gtp_pti, gtp_cause));
} else {
/*
* 1. SMF sends Delete Bearer Request(DEDICATED BEARER) to SGW/MME.
* 2. MME sends Delete Bearer Response(DEDICATED BEARER) to SGW/SMF.
*/
ogs_assert(bearer);
ogs_assert(OGS_OK ==
smf_gtp_send_delete_bearer_request(
bearer,
OGS_NAS_PROCEDURE_TRANSACTION_IDENTITY_UNASSIGNED,
gtp_cause));
}
}
} else if (flags & OGS_PFCP_MODIFY_ACTIVATE) {
if (gtp_xact) {
/* SMF send Update PDP Context Response (GTPv1C) to SGSN */
if (gtp_xact->gtp_version == 1) {
bearer = gtp_xact->data;
smf_gtp1_send_update_pdp_context_response(bearer, gtp_xact);
} else {
/* TODO: SMF send Modify Bearer Response (GTPv2C) to SGWC */
}
} else {
/* Nothing */
}
}
2020-04-26 19:36:05 +00:00
}
2020-06-17 05:22:28 +00:00
void smf_epc_n4_handle_session_deletion_response(
2020-04-26 19:36:05 +00:00
smf_sess_t *sess, ogs_pfcp_xact_t *xact,
ogs_pfcp_session_deletion_response_t *rsp)
{
uint8_t cause_value = 0;
Introduce Gn interface (GTPv1C) Support to PGW (#1351) * [CORE] tlv: Store mode in ogs_tlv_t This allows specifying the format of the IE for each individual IE, hence allowing messages containing IEs formatted in different ways. This is needed in order to support parsing GTPv1-C, since messages contain IEs with different structure (TLV vs TV). Hence, this is a preparation patch to add support for parsing TVs in ogs-tlv.c/.h. * [CORE] tlv: Support parsing msg with both TLV and TV in it IEs of type TV are sometimes used in GTPv1-C. Current tlv parser/builder doesn't provide with ways to parse messages which contain TV formatted IEs. This patch adds the relevant types and ways to encode/decode them. Furthermore, the current parser/builder allows parsing/building messages containing the exact same format in all its IEs. A new parser function is added which allows parsing messages of different types (TV, TLV) mixed in the same message. In order to be able to do so, it uses the general msg_mode passed to it in order to know the general TLV format (in essence, the length of the Tag field, and also the length of the Length field if applicable each IE). Looking up the instance in the TLV description is left undone and hadcoded to 0, since the only user so far requiring this API is GTPv1-C, which has no instances. * [CORE] tlv: Support repeated tag+instance parsing TLV message In GTPv2C, repeated IEs (same tag) are easily differentiated by the Instance byte, which provides info to match different decoded structures. In GTPv1C though, there's no Instance byte, and we still encounter repeated IEs (like GSN Address in Create PDP Context Request). Hence, the TLV decoder needs to be updated to track count of IEs found (identified by tag+instance, where instance is always 0 in GTPv1C) and get the proper description index + offset into the decoded structure. * [GTP]: Move GTPv2-C specifics to its own libgtp subdir This will allow adding GTPv1-C code by the side. Most GTPv2 code is left in this patch as "gtp" instead of renaming it to "gtp2" in order to avoid massive changes. It can be done at a later stage if wanted. * [GTP] Support generating GTPv1-C messages * [SMF] Add Gn interface support This patch introduces GTPv1C support to open5gs-smfd. With it, open5gs-becomes a GGSN too, where SGSN can connect to, hence supporting GERAN and UTRAN networks.
2022-02-18 13:23:45 +00:00
uint8_t resp_type = 0;
2020-04-26 19:36:05 +00:00
ogs_gtp_xact_t *gtp_xact = NULL;
ogs_assert(xact);
ogs_assert(rsp);
ogs_debug("Session Deletion Response [epc]");
2020-04-26 19:36:05 +00:00
gtp_xact = xact->assoc_xact;
ogs_pfcp_xact_commit(xact);
Introduce Gn interface (GTPv1C) Support to PGW (#1351) * [CORE] tlv: Store mode in ogs_tlv_t This allows specifying the format of the IE for each individual IE, hence allowing messages containing IEs formatted in different ways. This is needed in order to support parsing GTPv1-C, since messages contain IEs with different structure (TLV vs TV). Hence, this is a preparation patch to add support for parsing TVs in ogs-tlv.c/.h. * [CORE] tlv: Support parsing msg with both TLV and TV in it IEs of type TV are sometimes used in GTPv1-C. Current tlv parser/builder doesn't provide with ways to parse messages which contain TV formatted IEs. This patch adds the relevant types and ways to encode/decode them. Furthermore, the current parser/builder allows parsing/building messages containing the exact same format in all its IEs. A new parser function is added which allows parsing messages of different types (TV, TLV) mixed in the same message. In order to be able to do so, it uses the general msg_mode passed to it in order to know the general TLV format (in essence, the length of the Tag field, and also the length of the Length field if applicable each IE). Looking up the instance in the TLV description is left undone and hadcoded to 0, since the only user so far requiring this API is GTPv1-C, which has no instances. * [CORE] tlv: Support repeated tag+instance parsing TLV message In GTPv2C, repeated IEs (same tag) are easily differentiated by the Instance byte, which provides info to match different decoded structures. In GTPv1C though, there's no Instance byte, and we still encounter repeated IEs (like GSN Address in Create PDP Context Request). Hence, the TLV decoder needs to be updated to track count of IEs found (identified by tag+instance, where instance is always 0 in GTPv1C) and get the proper description index + offset into the decoded structure. * [GTP]: Move GTPv2-C specifics to its own libgtp subdir This will allow adding GTPv1-C code by the side. Most GTPv2 code is left in this patch as "gtp" instead of renaming it to "gtp2" in order to avoid massive changes. It can be done at a later stage if wanted. * [GTP] Support generating GTPv1-C messages * [SMF] Add Gn interface support This patch introduces GTPv1C support to open5gs-smfd. With it, open5gs-becomes a GGSN too, where SGSN can connect to, hence supporting GERAN and UTRAN networks.
2022-02-18 13:23:45 +00:00
/* If !gtp_xact, set it to whatever valid, nothing is sent in the end anyway */
uint8_t gtp_version = gtp_xact ? gtp_xact->gtp_version : 2;
if (gtp_version == 1) {
resp_type = OGS_GTP1_DELETE_PDP_CONTEXT_RESPONSE_TYPE;
cause_value = OGS_GTP1_CAUSE_REQUEST_ACCEPTED;
} else {
resp_type = OGS_GTP_DELETE_SESSION_RESPONSE_TYPE;
cause_value = OGS_GTP_CAUSE_REQUEST_ACCEPTED;
}
2020-04-26 19:36:05 +00:00
if (!sess) {
ogs_warn("No Context");
Introduce Gn interface (GTPv1C) Support to PGW (#1351) * [CORE] tlv: Store mode in ogs_tlv_t This allows specifying the format of the IE for each individual IE, hence allowing messages containing IEs formatted in different ways. This is needed in order to support parsing GTPv1-C, since messages contain IEs with different structure (TLV vs TV). Hence, this is a preparation patch to add support for parsing TVs in ogs-tlv.c/.h. * [CORE] tlv: Support parsing msg with both TLV and TV in it IEs of type TV are sometimes used in GTPv1-C. Current tlv parser/builder doesn't provide with ways to parse messages which contain TV formatted IEs. This patch adds the relevant types and ways to encode/decode them. Furthermore, the current parser/builder allows parsing/building messages containing the exact same format in all its IEs. A new parser function is added which allows parsing messages of different types (TV, TLV) mixed in the same message. In order to be able to do so, it uses the general msg_mode passed to it in order to know the general TLV format (in essence, the length of the Tag field, and also the length of the Length field if applicable each IE). Looking up the instance in the TLV description is left undone and hadcoded to 0, since the only user so far requiring this API is GTPv1-C, which has no instances. * [CORE] tlv: Support repeated tag+instance parsing TLV message In GTPv2C, repeated IEs (same tag) are easily differentiated by the Instance byte, which provides info to match different decoded structures. In GTPv1C though, there's no Instance byte, and we still encounter repeated IEs (like GSN Address in Create PDP Context Request). Hence, the TLV decoder needs to be updated to track count of IEs found (identified by tag+instance, where instance is always 0 in GTPv1C) and get the proper description index + offset into the decoded structure. * [GTP]: Move GTPv2-C specifics to its own libgtp subdir This will allow adding GTPv1-C code by the side. Most GTPv2 code is left in this patch as "gtp" instead of renaming it to "gtp2" in order to avoid massive changes. It can be done at a later stage if wanted. * [GTP] Support generating GTPv1-C messages * [SMF] Add Gn interface support This patch introduces GTPv1C support to open5gs-smfd. With it, open5gs-becomes a GGSN too, where SGSN can connect to, hence supporting GERAN and UTRAN networks.
2022-02-18 13:23:45 +00:00
cause_value = (gtp_version == 1) ?
OGS_GTP1_CAUSE_NON_EXISTENT :
Introduce Gn interface (GTPv1C) Support to PGW (#1351) * [CORE] tlv: Store mode in ogs_tlv_t This allows specifying the format of the IE for each individual IE, hence allowing messages containing IEs formatted in different ways. This is needed in order to support parsing GTPv1-C, since messages contain IEs with different structure (TLV vs TV). Hence, this is a preparation patch to add support for parsing TVs in ogs-tlv.c/.h. * [CORE] tlv: Support parsing msg with both TLV and TV in it IEs of type TV are sometimes used in GTPv1-C. Current tlv parser/builder doesn't provide with ways to parse messages which contain TV formatted IEs. This patch adds the relevant types and ways to encode/decode them. Furthermore, the current parser/builder allows parsing/building messages containing the exact same format in all its IEs. A new parser function is added which allows parsing messages of different types (TV, TLV) mixed in the same message. In order to be able to do so, it uses the general msg_mode passed to it in order to know the general TLV format (in essence, the length of the Tag field, and also the length of the Length field if applicable each IE). Looking up the instance in the TLV description is left undone and hadcoded to 0, since the only user so far requiring this API is GTPv1-C, which has no instances. * [CORE] tlv: Support repeated tag+instance parsing TLV message In GTPv2C, repeated IEs (same tag) are easily differentiated by the Instance byte, which provides info to match different decoded structures. In GTPv1C though, there's no Instance byte, and we still encounter repeated IEs (like GSN Address in Create PDP Context Request). Hence, the TLV decoder needs to be updated to track count of IEs found (identified by tag+instance, where instance is always 0 in GTPv1C) and get the proper description index + offset into the decoded structure. * [GTP]: Move GTPv2-C specifics to its own libgtp subdir This will allow adding GTPv1-C code by the side. Most GTPv2 code is left in this patch as "gtp" instead of renaming it to "gtp2" in order to avoid massive changes. It can be done at a later stage if wanted. * [GTP] Support generating GTPv1-C messages * [SMF] Add Gn interface support This patch introduces GTPv1C support to open5gs-smfd. With it, open5gs-becomes a GGSN too, where SGSN can connect to, hence supporting GERAN and UTRAN networks.
2022-02-18 13:23:45 +00:00
OGS_GTP_CAUSE_CONTEXT_NOT_FOUND;
2020-04-26 19:36:05 +00:00
}
if (rsp->cause.presence) {
if (rsp->cause.u8 != OGS_PFCP_CAUSE_REQUEST_ACCEPTED) {
2020-07-04 03:14:48 +00:00
ogs_warn("PFCP Cause[%d] : Not Accepted", rsp->cause.u8);
Introduce Gn interface (GTPv1C) Support to PGW (#1351) * [CORE] tlv: Store mode in ogs_tlv_t This allows specifying the format of the IE for each individual IE, hence allowing messages containing IEs formatted in different ways. This is needed in order to support parsing GTPv1-C, since messages contain IEs with different structure (TLV vs TV). Hence, this is a preparation patch to add support for parsing TVs in ogs-tlv.c/.h. * [CORE] tlv: Support parsing msg with both TLV and TV in it IEs of type TV are sometimes used in GTPv1-C. Current tlv parser/builder doesn't provide with ways to parse messages which contain TV formatted IEs. This patch adds the relevant types and ways to encode/decode them. Furthermore, the current parser/builder allows parsing/building messages containing the exact same format in all its IEs. A new parser function is added which allows parsing messages of different types (TV, TLV) mixed in the same message. In order to be able to do so, it uses the general msg_mode passed to it in order to know the general TLV format (in essence, the length of the Tag field, and also the length of the Length field if applicable each IE). Looking up the instance in the TLV description is left undone and hadcoded to 0, since the only user so far requiring this API is GTPv1-C, which has no instances. * [CORE] tlv: Support repeated tag+instance parsing TLV message In GTPv2C, repeated IEs (same tag) are easily differentiated by the Instance byte, which provides info to match different decoded structures. In GTPv1C though, there's no Instance byte, and we still encounter repeated IEs (like GSN Address in Create PDP Context Request). Hence, the TLV decoder needs to be updated to track count of IEs found (identified by tag+instance, where instance is always 0 in GTPv1C) and get the proper description index + offset into the decoded structure. * [GTP]: Move GTPv2-C specifics to its own libgtp subdir This will allow adding GTPv1-C code by the side. Most GTPv2 code is left in this patch as "gtp" instead of renaming it to "gtp2" in order to avoid massive changes. It can be done at a later stage if wanted. * [GTP] Support generating GTPv1-C messages * [SMF] Add Gn interface support This patch introduces GTPv1C support to open5gs-smfd. With it, open5gs-becomes a GGSN too, where SGSN can connect to, hence supporting GERAN and UTRAN networks.
2022-02-18 13:23:45 +00:00
cause_value = gtp_cause_from_pfcp(rsp->cause.u8, gtp_version);
2020-04-26 19:36:05 +00:00
}
} else {
ogs_error("No Cause");
Introduce Gn interface (GTPv1C) Support to PGW (#1351) * [CORE] tlv: Store mode in ogs_tlv_t This allows specifying the format of the IE for each individual IE, hence allowing messages containing IEs formatted in different ways. This is needed in order to support parsing GTPv1-C, since messages contain IEs with different structure (TLV vs TV). Hence, this is a preparation patch to add support for parsing TVs in ogs-tlv.c/.h. * [CORE] tlv: Support parsing msg with both TLV and TV in it IEs of type TV are sometimes used in GTPv1-C. Current tlv parser/builder doesn't provide with ways to parse messages which contain TV formatted IEs. This patch adds the relevant types and ways to encode/decode them. Furthermore, the current parser/builder allows parsing/building messages containing the exact same format in all its IEs. A new parser function is added which allows parsing messages of different types (TV, TLV) mixed in the same message. In order to be able to do so, it uses the general msg_mode passed to it in order to know the general TLV format (in essence, the length of the Tag field, and also the length of the Length field if applicable each IE). Looking up the instance in the TLV description is left undone and hadcoded to 0, since the only user so far requiring this API is GTPv1-C, which has no instances. * [CORE] tlv: Support repeated tag+instance parsing TLV message In GTPv2C, repeated IEs (same tag) are easily differentiated by the Instance byte, which provides info to match different decoded structures. In GTPv1C though, there's no Instance byte, and we still encounter repeated IEs (like GSN Address in Create PDP Context Request). Hence, the TLV decoder needs to be updated to track count of IEs found (identified by tag+instance, where instance is always 0 in GTPv1C) and get the proper description index + offset into the decoded structure. * [GTP]: Move GTPv2-C specifics to its own libgtp subdir This will allow adding GTPv1-C code by the side. Most GTPv2 code is left in this patch as "gtp" instead of renaming it to "gtp2" in order to avoid massive changes. It can be done at a later stage if wanted. * [GTP] Support generating GTPv1-C messages * [SMF] Add Gn interface support This patch introduces GTPv1C support to open5gs-smfd. With it, open5gs-becomes a GGSN too, where SGSN can connect to, hence supporting GERAN and UTRAN networks.
2022-02-18 13:23:45 +00:00
cause_value = (gtp_xact->gtp_version == 1) ?
OGS_GTP1_CAUSE_MANDATORY_IE_MISSING :
OGS_GTP_CAUSE_MANDATORY_IE_MISSING;
2020-04-26 19:36:05 +00:00
}
Introduce Gn interface (GTPv1C) Support to PGW (#1351) * [CORE] tlv: Store mode in ogs_tlv_t This allows specifying the format of the IE for each individual IE, hence allowing messages containing IEs formatted in different ways. This is needed in order to support parsing GTPv1-C, since messages contain IEs with different structure (TLV vs TV). Hence, this is a preparation patch to add support for parsing TVs in ogs-tlv.c/.h. * [CORE] tlv: Support parsing msg with both TLV and TV in it IEs of type TV are sometimes used in GTPv1-C. Current tlv parser/builder doesn't provide with ways to parse messages which contain TV formatted IEs. This patch adds the relevant types and ways to encode/decode them. Furthermore, the current parser/builder allows parsing/building messages containing the exact same format in all its IEs. A new parser function is added which allows parsing messages of different types (TV, TLV) mixed in the same message. In order to be able to do so, it uses the general msg_mode passed to it in order to know the general TLV format (in essence, the length of the Tag field, and also the length of the Length field if applicable each IE). Looking up the instance in the TLV description is left undone and hadcoded to 0, since the only user so far requiring this API is GTPv1-C, which has no instances. * [CORE] tlv: Support repeated tag+instance parsing TLV message In GTPv2C, repeated IEs (same tag) are easily differentiated by the Instance byte, which provides info to match different decoded structures. In GTPv1C though, there's no Instance byte, and we still encounter repeated IEs (like GSN Address in Create PDP Context Request). Hence, the TLV decoder needs to be updated to track count of IEs found (identified by tag+instance, where instance is always 0 in GTPv1C) and get the proper description index + offset into the decoded structure. * [GTP]: Move GTPv2-C specifics to its own libgtp subdir This will allow adding GTPv1-C code by the side. Most GTPv2 code is left in this patch as "gtp" instead of renaming it to "gtp2" in order to avoid massive changes. It can be done at a later stage if wanted. * [GTP] Support generating GTPv1-C messages * [SMF] Add Gn interface support This patch introduces GTPv1C support to open5gs-smfd. With it, open5gs-becomes a GGSN too, where SGSN can connect to, hence supporting GERAN and UTRAN networks.
2022-02-18 13:23:45 +00:00
if (gtp_xact &&
((gtp_version == 1 && cause_value != OGS_GTP1_CAUSE_REQUEST_ACCEPTED) ||
(gtp_version == 2 && cause_value != OGS_GTP_CAUSE_REQUEST_ACCEPTED))) {
ogs_gtp_send_error_message(gtp_xact, sess->sgw_s5c_teid, resp_type,
cause_value);
2020-04-26 19:36:05 +00:00
return;
}
ogs_assert(sess);
2021-06-21 13:36:38 +00:00
if (gtp_xact) {
/*
* 1. MME sends Delete Session Request to SGW/SMF.
* 2. SMF sends Delete Session Response to SGW/MME.
*/
Introduce Gn interface (GTPv1C) Support to PGW (#1351) * [CORE] tlv: Store mode in ogs_tlv_t This allows specifying the format of the IE for each individual IE, hence allowing messages containing IEs formatted in different ways. This is needed in order to support parsing GTPv1-C, since messages contain IEs with different structure (TLV vs TV). Hence, this is a preparation patch to add support for parsing TVs in ogs-tlv.c/.h. * [CORE] tlv: Support parsing msg with both TLV and TV in it IEs of type TV are sometimes used in GTPv1-C. Current tlv parser/builder doesn't provide with ways to parse messages which contain TV formatted IEs. This patch adds the relevant types and ways to encode/decode them. Furthermore, the current parser/builder allows parsing/building messages containing the exact same format in all its IEs. A new parser function is added which allows parsing messages of different types (TV, TLV) mixed in the same message. In order to be able to do so, it uses the general msg_mode passed to it in order to know the general TLV format (in essence, the length of the Tag field, and also the length of the Length field if applicable each IE). Looking up the instance in the TLV description is left undone and hadcoded to 0, since the only user so far requiring this API is GTPv1-C, which has no instances. * [CORE] tlv: Support repeated tag+instance parsing TLV message In GTPv2C, repeated IEs (same tag) are easily differentiated by the Instance byte, which provides info to match different decoded structures. In GTPv1C though, there's no Instance byte, and we still encounter repeated IEs (like GSN Address in Create PDP Context Request). Hence, the TLV decoder needs to be updated to track count of IEs found (identified by tag+instance, where instance is always 0 in GTPv1C) and get the proper description index + offset into the decoded structure. * [GTP]: Move GTPv2-C specifics to its own libgtp subdir This will allow adding GTPv1-C code by the side. Most GTPv2 code is left in this patch as "gtp" instead of renaming it to "gtp2" in order to avoid massive changes. It can be done at a later stage if wanted. * [GTP] Support generating GTPv1-C messages * [SMF] Add Gn interface support This patch introduces GTPv1C support to open5gs-smfd. With it, open5gs-becomes a GGSN too, where SGSN can connect to, hence supporting GERAN and UTRAN networks.
2022-02-18 13:23:45 +00:00
switch (gtp_version) {
case 1:
ogs_assert(OGS_OK == smf_gtp1_send_delete_pdp_context_response(sess, gtp_xact));
break;
case 2:
ogs_assert(OGS_OK == smf_gtp_send_delete_session_response(sess, gtp_xact));
break;
}
2021-06-21 13:36:38 +00:00
} else {
/*
* 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.
*/
}
2020-04-26 19:36:05 +00:00
SMF_SESS_CLEAR(sess);
2020-04-26 19:36:05 +00:00
}
2021-01-18 16:48:35 +00:00
void smf_n4_handle_session_report_request(
smf_sess_t *sess, ogs_pfcp_xact_t *pfcp_xact,
ogs_pfcp_session_report_request_t *pfcp_req)
{
smf_bearer_t *qos_flow = NULL;
ogs_pfcp_pdr_t *pdr = NULL;
ogs_pfcp_report_type_t report_type;
uint8_t cause_value = 0;
uint16_t pdr_id = 0;
ogs_assert(pfcp_xact);
ogs_assert(pfcp_req);
ogs_debug("Session Report Request");
2021-01-18 16:48:35 +00:00
cause_value = OGS_GTP_CAUSE_REQUEST_ACCEPTED;
if (!sess) {
ogs_warn("No Context");
cause_value = OGS_PFCP_CAUSE_SESSION_CONTEXT_NOT_FOUND;
}
if (pfcp_req->report_type.presence == 0) {
ogs_error("No Report Type");
cause_value = OGS_GTP_CAUSE_MANDATORY_IE_MISSING;
}
if (cause_value != OGS_GTP_CAUSE_REQUEST_ACCEPTED) {
ogs_pfcp_send_error_message(pfcp_xact, 0,
OGS_PFCP_SESSION_REPORT_RESPONSE_TYPE,
cause_value, 0);
return;
}
ogs_assert(sess);
report_type.value = pfcp_req->report_type.u8;
if (report_type.downlink_data_report) {
ogs_pfcp_downlink_data_service_information_t *info = NULL;
uint8_t paging_policy_indication_value = 0;
uint8_t qfi = 0;
if (pfcp_req->downlink_data_report.presence) {
if (pfcp_req->downlink_data_report.
downlink_data_service_information.presence) {
info = pfcp_req->downlink_data_report.
downlink_data_service_information.data;
if (info) {
if (info->qfii && info->ppi) {
paging_policy_indication_value =
info->paging_policy_indication_value;
qfi = info->qfi;
} else if (info->qfii) {
qfi = info->qfi;
} else if (info->ppi) {
paging_policy_indication_value =
info->paging_policy_indication_value;
} else {
ogs_error("Invalid Downlink Data Service Information");
}
if (paging_policy_indication_value) {
ogs_warn("Not implement - "
"Paging Policy Indication Value");
ogs_pfcp_send_error_message(pfcp_xact, 0,
OGS_PFCP_SESSION_REPORT_RESPONSE_TYPE,
OGS_GTP_CAUSE_SERVICE_NOT_SUPPORTED, 0);
return;
}
if (qfi) {
qos_flow = smf_qos_flow_find_by_qfi(sess, qfi);
if (!qos_flow)
ogs_error("Cannot find the QoS Flow[%d]", qfi);
}
} else {
ogs_error("No Info");
}
}
if (pfcp_req->downlink_data_report.pdr_id.presence) {
pdr = ogs_pfcp_pdr_find(&sess->pfcp,
pfcp_req->downlink_data_report.pdr_id.u16);
if (!pdr)
ogs_error("Cannot find the PDR-ID[%d]", pdr_id);
} else {
ogs_error("No PDR-ID");
}
} else {
ogs_error("No Downlink Data Report");
}
if (!pdr || !qos_flow) {
ogs_error("No Context [%p:%p]", pdr, qos_flow);
ogs_pfcp_send_error_message(pfcp_xact, 0,
OGS_PFCP_SESSION_REPORT_RESPONSE_TYPE,
cause_value, 0);
return;
2021-01-18 16:48:35 +00:00
}
ogs_assert(OGS_OK ==
smf_pfcp_send_session_report_response(
pfcp_xact, sess, OGS_PFCP_CAUSE_REQUEST_ACCEPTED));
2021-01-18 16:48:35 +00:00
if (sess->paging.ue_requested_pdu_session_establishment_done == true) {
smf_n1_n2_message_transfer_param_t param;
memset(&param, 0, sizeof(param));
param.state = SMF_NETWORK_TRIGGERED_SERVICE_REQUEST;
param.n2smbuf =
ngap_build_pdu_session_resource_setup_request_transfer(sess);
2021-01-18 16:48:35 +00:00
ogs_assert(param.n2smbuf);
param.n1n2_failure_txf_notif_uri = true;
smf_namf_comm_send_n1_n2_message_transfer(sess, &param);
}
} else if (report_type.error_indication_report) {
smf_ue_t *smf_ue = sess->smf_ue;
smf_sess_t *error_indication_session = NULL;
ogs_assert(smf_ue);
ogs_assert(OGS_OK ==
smf_pfcp_send_session_report_response(
pfcp_xact, sess, OGS_PFCP_CAUSE_REQUEST_ACCEPTED));
2021-01-18 16:48:35 +00:00
error_indication_session = smf_sess_find_by_error_indication_report(
smf_ue, &pfcp_req->error_indication_report);
if (!error_indication_session) return;
ogs_assert(OGS_OK ==
smf_5gc_pfcp_send_session_modification_request(
2021-01-18 16:48:35 +00:00
error_indication_session, NULL,
OGS_PFCP_MODIFY_DL_ONLY|OGS_PFCP_MODIFY_DEACTIVATE|
OGS_PFCP_MODIFY_ERROR_INDICATION,
0));
2021-01-18 16:48:35 +00:00
} else {
ogs_error("Not supported Report Type[%d]", report_type.value);
ogs_assert(OGS_OK ==
smf_pfcp_send_session_report_response(
pfcp_xact, sess, OGS_PFCP_CAUSE_SYSTEM_FAILURE));
2021-01-18 16:48:35 +00:00
}
}