open5gs/lib/gtp/xact.c

1177 lines
36 KiB
C
Raw Normal View History

2019-04-27 14:54:30 +00:00
/*
* Copyright (C) 2019 by Sukchan Lee <acetcom@gmail.com>
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
* Copyright (C) 2022 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
* Copyright (C) 2023-2024 by Sukchan Lee <acetcom@gmail.com>
2019-04-27 14:54:30 +00:00
*
* This file is part of Open5GS.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
2017-03-26 15:48:33 +00:00
2019-09-13 12:07:47 +00:00
#include "ogs-gtp.h"
2020-07-27 01:02:40 +00:00
#include "ogs-app.h"
2017-04-01 14:28:22 +00:00
2017-08-31 01:48:14 +00:00
typedef enum {
GTP_XACT_UNKNOWN_STAGE,
GTP_XACT_INITIAL_STAGE,
GTP_XACT_INTERMEDIATE_STAGE,
GTP_XACT_FINAL_STAGE,
2019-09-13 12:07:47 +00:00
} ogs_gtp_xact_stage_t;
2017-04-03 11:50:20 +00:00
2019-09-13 12:07:47 +00:00
static int ogs_gtp_xact_initialized = 0;
2019-04-27 14:54:30 +00:00
static uint32_t g_xact_id = 0;
2017-08-31 05:03:00 +00:00
2019-09-13 12:07:47 +00:00
static OGS_POOL(pool, ogs_gtp_xact_t);
2017-03-26 15:48:33 +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
static ogs_gtp_xact_t *ogs_gtp_xact_remote_create(ogs_gtp_node_t *gnode, uint8_t gtp_version, uint32_t sqn);
static ogs_gtp_xact_stage_t ogs_gtp2_xact_get_stage(uint8_t type, uint32_t xid);
static ogs_gtp_xact_stage_t ogs_gtp1_xact_get_stage(uint8_t type, uint32_t xid);
2019-09-13 12:07:47 +00:00
static int ogs_gtp_xact_delete(ogs_gtp_xact_t *xact);
static int ogs_gtp_xact_update_rx(ogs_gtp_xact_t *xact, uint8_t type);
2017-08-31 01:48:14 +00:00
2019-04-27 14:54:30 +00:00
static void response_timeout(void *data);
static void holding_timeout(void *data);
int ogs_gtp_xact_init(void)
2017-03-26 15:48:33 +00:00
{
2019-09-13 12:07:47 +00:00
ogs_assert(ogs_gtp_xact_initialized == 0);
2017-08-31 05:03:00 +00:00
ogs_pool_init(&pool, ogs_app()->pool.xact);
2017-03-26 15:48:33 +00:00
2017-08-31 05:03:00 +00:00
g_xact_id = 0;
2017-03-26 15:48:33 +00:00
2019-09-13 12:07:47 +00:00
ogs_gtp_xact_initialized = 1;
2017-08-31 05:03:00 +00:00
2019-04-27 14:54:30 +00:00
return OGS_OK;
2017-03-26 15:48:33 +00:00
}
void ogs_gtp_xact_final(void)
2017-03-26 15:48:33 +00:00
{
2019-09-13 12:07:47 +00:00
ogs_assert(ogs_gtp_xact_initialized == 1);
2017-08-31 05:03:00 +00:00
2019-04-27 14:54:30 +00:00
ogs_pool_final(&pool);
2017-03-26 15:48:33 +00:00
2019-09-13 12:07:47 +00:00
ogs_gtp_xact_initialized = 0;
2017-08-31 03:06:11 +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
ogs_gtp_xact_t *ogs_gtp1_xact_local_create(ogs_gtp_node_t *gnode,
ogs_gtp1_header_t *hdesc, ogs_pkbuf_t *pkbuf,
void (*cb)(ogs_gtp_xact_t *xact, void *data), void *data)
{
int rv;
char buf[OGS_ADDRSTRLEN];
ogs_gtp_xact_t *xact = NULL;
ogs_assert(gnode);
ogs_assert(hdesc);
ogs_pool_alloc(&pool, &xact);
ogs_assert(xact);
memset(xact, 0, sizeof *xact);
xact->index = ogs_pool_index(&pool, xact);
xact->gtp_version = 1;
xact->org = OGS_GTP_LOCAL_ORIGINATOR;
xact->xid = OGS_NEXT_ID(g_xact_id,
OGS_GTP1_MIN_XACT_ID, OGS_GTP1_MAX_XACT_ID);
xact->gnode = gnode;
xact->cb = cb;
xact->data = data;
/* 7.6 "The T3-RESPONSE timer shall be started when a signalling request
* message (for which a response has been defined) is sent." */
if (hdesc->type != OGS_GTP1_RAN_INFORMATION_RELAY_TYPE) {
xact->tm_response = ogs_timer_add(
ogs_app()->timer_mgr, response_timeout, xact);
ogs_assert(xact->tm_response);
xact->response_rcount =
ogs_local_conf()->time.message.gtp.n3_response_rcount;
}
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
xact->tm_holding = ogs_timer_add(
ogs_app()->timer_mgr, holding_timeout, xact);
ogs_assert(xact->tm_holding);
xact->holding_rcount = ogs_local_conf()->time.message.gtp.n3_holding_rcount;
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_list_add(&xact->gnode->local_list, 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
rv = ogs_gtp1_xact_update_tx(xact, hdesc, pkbuf);
if (rv != OGS_OK) {
ogs_error("ogs_gtp_xact_update_tx(rv=%d) failed", (int)rv);
ogs_gtp_xact_delete(xact);
return NULL;
}
ogs_debug("[%d] LOCAL Create peer [%s]:%d",
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
xact->xid,
OGS_ADDR(&gnode->addr, buf),
OGS_PORT(&gnode->addr));
return xact;
}
ogs_gtp_xact_t *ogs_gtp_xact_local_create(ogs_gtp_node_t *gnode,
ogs_gtp2_header_t *hdesc, ogs_pkbuf_t *pkbuf,
void (*cb)(ogs_gtp_xact_t *xact, void *data), void *data)
2017-03-26 15:48:33 +00:00
{
2019-04-27 14:54:30 +00:00
int rv;
char buf[OGS_ADDRSTRLEN];
2019-09-13 12:07:47 +00:00
ogs_gtp_xact_t *xact = NULL;
2017-03-27 10:12:45 +00:00
2019-04-27 14:54:30 +00:00
ogs_assert(gnode);
ogs_assert(hdesc);
2017-03-27 10:12:45 +00:00
2019-04-27 14:54:30 +00:00
ogs_pool_alloc(&pool, &xact);
ogs_assert(xact);
memset(xact, 0, sizeof *xact);
xact->index = ogs_pool_index(&pool, xact);
2017-03-30 00:06:56 +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
xact->gtp_version = 2;
2019-09-13 12:07:47 +00:00
xact->org = OGS_GTP_LOCAL_ORIGINATOR;
xact->xid = OGS_NEXT_ID(g_xact_id,
OGS_GTP_MIN_XACT_ID, OGS_GTP_CMD_XACT_ID);
if (hdesc->type == OGS_GTP2_MODIFY_BEARER_COMMAND_TYPE ||
hdesc->type == OGS_GTP2_DELETE_BEARER_COMMAND_TYPE ||
hdesc->type == OGS_GTP2_BEARER_RESOURCE_COMMAND_TYPE) {
xact->xid |= OGS_GTP_CMD_XACT_ID;
}
2017-03-28 07:35:57 +00:00
xact->gnode = gnode;
xact->cb = cb;
xact->data = data;
2017-03-27 10:12:45 +00:00
xact->tm_response = ogs_timer_add(
ogs_app()->timer_mgr, response_timeout, xact);
2019-04-27 14:54:30 +00:00
ogs_assert(xact->tm_response);
xact->response_rcount =
ogs_local_conf()->time.message.gtp.n3_response_rcount,
2017-08-31 11:48:15 +00:00
xact->tm_holding = ogs_timer_add(
ogs_app()->timer_mgr, holding_timeout, xact);
2019-04-27 14:54:30 +00:00
ogs_assert(xact->tm_holding);
xact->holding_rcount = ogs_local_conf()->time.message.gtp.n3_holding_rcount,
2017-08-31 11:48:15 +00:00
ogs_list_add(&xact->gnode->local_list, xact);
2017-03-27 10:12:45 +00:00
2019-09-13 12:07:47 +00:00
rv = ogs_gtp_xact_update_tx(xact, hdesc, pkbuf);
2019-11-30 07:45:09 +00:00
if (rv != OGS_OK) {
ogs_error("ogs_gtp_xact_update_tx(rv=%d) failed", (int)rv);
2019-11-30 07:45:09 +00:00
ogs_gtp_xact_delete(xact);
return NULL;
}
2017-09-01 00:36:55 +00:00
ogs_debug("[%d] LOCAL Create peer [%s]:%d",
2017-08-01 01:16:06 +00:00
xact->xid,
2020-04-26 19:36:05 +00:00
OGS_ADDR(&gnode->addr, buf),
OGS_PORT(&gnode->addr));
2017-03-30 14:27:26 +00:00
2017-03-28 07:35:57 +00:00
return xact;
2017-03-26 15:48:33 +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
static ogs_gtp_xact_t *ogs_gtp_xact_remote_create(ogs_gtp_node_t *gnode, uint8_t gtp_version, uint32_t sqn)
2017-03-26 15:48:33 +00:00
{
2019-04-27 14:54:30 +00:00
char buf[OGS_ADDRSTRLEN];
2019-09-13 12:07:47 +00:00
ogs_gtp_xact_t *xact = NULL;
2017-07-31 13:35:25 +00:00
2019-04-27 14:54:30 +00:00
ogs_assert(gnode);
2017-04-03 14:40:22 +00:00
2019-04-27 14:54:30 +00:00
ogs_pool_alloc(&pool, &xact);
ogs_assert(xact);
memset(xact, 0, sizeof *xact);
xact->index = ogs_pool_index(&pool, xact);
2017-04-03 14:40:22 +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
xact->gtp_version = gtp_version;
2019-09-13 12:07:47 +00:00
xact->org = OGS_GTP_REMOTE_ORIGINATOR;
xact->xid = (gtp_version == 1) ?
OGS_GTP1_SQN_TO_XID(sqn) : OGS_GTP2_SQN_TO_XID(sqn);
2017-08-31 03:06:11 +00:00
xact->gnode = gnode;
2017-04-03 14:40:22 +00:00
xact->tm_response = ogs_timer_add(
ogs_app()->timer_mgr, response_timeout, xact);
2019-04-27 14:54:30 +00:00
ogs_assert(xact->tm_response);
xact->response_rcount =
ogs_local_conf()->time.message.gtp.n3_response_rcount,
2017-08-31 11:48:15 +00:00
xact->tm_holding = ogs_timer_add(
ogs_app()->timer_mgr, holding_timeout, xact);
2019-04-27 14:54:30 +00:00
ogs_assert(xact->tm_holding);
xact->holding_rcount = ogs_local_conf()->time.message.gtp.n3_holding_rcount,
2017-04-03 14:40:22 +00:00
ogs_list_add(&xact->gnode->remote_list, xact);
2017-04-03 13:46:19 +00:00
ogs_debug("[%d] REMOTE Create peer [%s]:%d",
2017-08-31 03:06:11 +00:00
xact->xid,
2020-04-26 19:36:05 +00:00
OGS_ADDR(&gnode->addr, buf),
OGS_PORT(&gnode->addr));
2017-04-03 13:46:19 +00:00
2017-08-31 03:06:11 +00:00
return xact;
2017-04-03 13:46:19 +00:00
}
2020-11-07 22:27:12 +00:00
ogs_gtp_xact_t *ogs_gtp_xact_cycle(ogs_gtp_xact_t *xact)
{
return ogs_pool_cycle(&pool, xact);
}
2019-09-13 12:07:47 +00:00
void ogs_gtp_xact_delete_all(ogs_gtp_node_t *gnode)
2017-04-11 13:44:57 +00:00
{
2019-09-13 12:07:47 +00:00
ogs_gtp_xact_t *xact = NULL, *next_xact = NULL;
2019-04-27 14:54:30 +00:00
ogs_list_for_each_safe(&gnode->local_list, next_xact, xact)
2019-09-13 12:07:47 +00:00
ogs_gtp_xact_delete(xact);
2019-04-27 14:54:30 +00:00
ogs_list_for_each_safe(&gnode->remote_list, next_xact, xact)
2019-09-13 12:07:47 +00:00
ogs_gtp_xact_delete(xact);
2017-04-11 13:44:57 +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
int ogs_gtp1_xact_update_tx(ogs_gtp_xact_t *xact,
ogs_gtp1_header_t *hdesc, ogs_pkbuf_t *pkbuf)
{
char buf[OGS_ADDRSTRLEN];
ogs_gtp_xact_stage_t stage;
ogs_gtp1_header_t *h = NULL;
int gtp_hlen = 0;
ogs_assert(xact);
ogs_assert(xact->gnode);
ogs_assert(hdesc);
ogs_assert(pkbuf);
ogs_debug("[%d] %s UPD TX-%d peer [%s]:%d",
xact->xid,
xact->org == OGS_GTP_LOCAL_ORIGINATOR ? "LOCAL " : "REMOTE",
hdesc->type,
OGS_ADDR(&xact->gnode->addr, buf),
OGS_PORT(&xact->gnode->addr));
stage = ogs_gtp1_xact_get_stage(hdesc->type, xact->xid);
if (xact->org == OGS_GTP_LOCAL_ORIGINATOR) {
switch (stage) {
case GTP_XACT_INITIAL_STAGE:
if (xact->step != 0) {
ogs_error("invalid step[%d]", xact->step);
ogs_pkbuf_free(pkbuf);
return OGS_ERROR;
}
break;
case GTP_XACT_INTERMEDIATE_STAGE:
ogs_expect(0);
ogs_pkbuf_free(pkbuf);
return OGS_ERROR;
case GTP_XACT_FINAL_STAGE:
if (xact->step != 2 && xact->step != 3) {
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_error("invalid step[%d]", xact->step);
ogs_pkbuf_free(pkbuf);
return OGS_ERROR;
}
break;
default:
ogs_assert_if_reached();
break;
}
} else if (xact->org == OGS_GTP_REMOTE_ORIGINATOR) {
switch (stage) {
case GTP_XACT_INITIAL_STAGE:
ogs_expect(0);
ogs_pkbuf_free(pkbuf);
return OGS_ERROR;
case GTP_XACT_INTERMEDIATE_STAGE:
case GTP_XACT_FINAL_STAGE:
if (xact->step != 1) {
ogs_error("invalid step[%d]", xact->step);
ogs_pkbuf_free(pkbuf);
return OGS_ERROR;
}
break;
default:
ogs_error("invalid stage[%d]", stage);
ogs_pkbuf_free(pkbuf);
return OGS_ERROR;
}
} else {
ogs_error("invalid org[%d]", xact->org);
ogs_pkbuf_free(pkbuf);
return OGS_ERROR;
}
gtp_hlen = OGS_GTPV1C_HEADER_LEN;
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_pkbuf_push(pkbuf, gtp_hlen);
h = (ogs_gtp1_header_t *)pkbuf->data;
memset(h, 0, gtp_hlen);
h->version = 1;
h->type = hdesc->type;
h->pt = 1; /* GTP */
h->teid = htobe32(hdesc->teid);
h->s = 1;
h->sqn = OGS_GTP1_XID_TO_SQN(xact->xid);
h->length = htobe16(pkbuf->len - 8);
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
/* Save Message type and packet of this step */
xact->seq[xact->step].type = h->type;
xact->seq[xact->step].pkbuf = pkbuf;
/* Step */
xact->step++;
return OGS_OK;
}
2019-09-13 12:07:47 +00:00
int ogs_gtp_xact_update_tx(ogs_gtp_xact_t *xact,
ogs_gtp2_header_t *hdesc, ogs_pkbuf_t *pkbuf)
2017-03-26 15:48:33 +00:00
{
2019-04-27 14:54:30 +00:00
char buf[OGS_ADDRSTRLEN];
2019-09-13 12:07:47 +00:00
ogs_gtp_xact_stage_t stage;
ogs_gtp2_header_t *h = NULL;
int gtp_hlen = 0;
2019-04-27 14:54:30 +00:00
ogs_assert(xact);
ogs_assert(xact->gnode);
ogs_assert(hdesc);
ogs_assert(pkbuf);
2017-03-29 14:19:31 +00:00
2019-04-27 14:54:30 +00:00
ogs_debug("[%d] %s UPD TX-%d peer [%s]:%d",
2017-08-01 01:16:06 +00:00
xact->xid,
2019-09-13 12:07:47 +00:00
xact->org == OGS_GTP_LOCAL_ORIGINATOR ? "LOCAL " : "REMOTE",
2017-09-01 04:51:31 +00:00
hdesc->type,
2020-04-26 19:36:05 +00:00
OGS_ADDR(&xact->gnode->addr, buf),
OGS_PORT(&xact->gnode->addr));
2017-04-01 14:13:15 +00:00
stage = ogs_gtp2_xact_get_stage(hdesc->type, xact->xid);
2019-09-13 12:07:47 +00:00
if (xact->org == OGS_GTP_LOCAL_ORIGINATOR) {
2019-07-20 06:20:52 +00:00
switch (stage) {
case GTP_XACT_INITIAL_STAGE:
2019-11-30 07:45:09 +00:00
if (xact->step != 0) {
ogs_error("invalid step[%d]", xact->step);
ogs_pkbuf_free(pkbuf);
return OGS_ERROR;
}
2019-07-20 06:20:52 +00:00
break;
case GTP_XACT_INTERMEDIATE_STAGE:
2019-11-30 07:45:09 +00:00
ogs_expect(0);
ogs_pkbuf_free(pkbuf);
return OGS_ERROR;
2019-07-20 06:20:52 +00:00
case GTP_XACT_FINAL_STAGE:
2019-11-30 07:45:09 +00:00
if (xact->step != 2) {
ogs_error("invalid step[%d]", xact->step);
ogs_pkbuf_free(pkbuf);
return OGS_ERROR;
}
2019-07-20 06:20:52 +00:00
break;
default:
ogs_assert_if_reached();
break;
2017-08-31 11:48:15 +00:00
}
2019-09-13 12:07:47 +00:00
} else if (xact->org == OGS_GTP_REMOTE_ORIGINATOR) {
2019-07-20 06:20:52 +00:00
switch (stage) {
case GTP_XACT_INITIAL_STAGE:
2019-11-30 07:45:09 +00:00
ogs_expect(0);
ogs_pkbuf_free(pkbuf);
return OGS_ERROR;
2019-07-20 06:20:52 +00:00
case GTP_XACT_INTERMEDIATE_STAGE:
case GTP_XACT_FINAL_STAGE:
2019-11-30 07:45:09 +00:00
if (xact->step != 1) {
ogs_error("invalid step[%d]", xact->step);
ogs_pkbuf_free(pkbuf);
return OGS_ERROR;
}
2019-07-20 06:20:52 +00:00
break;
default:
2019-11-30 07:45:09 +00:00
ogs_error("invalid stage[%d]", stage);
ogs_pkbuf_free(pkbuf);
return OGS_ERROR;
2017-08-31 11:48:15 +00:00
}
2019-11-30 07:45:09 +00:00
} else {
ogs_error("invalid org[%d]", xact->org);
ogs_pkbuf_free(pkbuf);
return OGS_ERROR;
}
2017-08-31 11:48:15 +00:00
if (hdesc->teid_presence) {
gtp_hlen = OGS_GTPV2C_HEADER_LEN;
} else {
gtp_hlen = OGS_GTPV2C_HEADER_LEN - OGS_GTP2_TEID_LEN;
}
ogs_pkbuf_push(pkbuf, gtp_hlen);
h = (ogs_gtp2_header_t *)pkbuf->data;
memset(h, 0, gtp_hlen);
2017-04-03 05:18:25 +00:00
h->version = 2;
2017-09-01 04:51:31 +00:00
h->type = hdesc->type;
if (hdesc->teid_presence) {
h->teid_presence = OGS_GTP2_TEID_PRESENCE;
h->teid = htobe32(hdesc->teid);
h->sqn = OGS_GTP2_XID_TO_SQN(xact->xid);
} else {
h->teid_presence = OGS_GTP2_TEID_NO_PRESENCE;
h->sqn_only = OGS_GTP2_XID_TO_SQN(xact->xid);
}
h->length = htobe16(pkbuf->len - 4);
2017-04-03 05:18:25 +00:00
2017-08-31 11:48:15 +00:00
/* Save Message type and packet of this step */
xact->seq[xact->step].type = h->type;
xact->seq[xact->step].pkbuf = pkbuf;
2017-04-01 14:13:15 +00:00
2017-08-31 11:48:15 +00:00
/* Step */
xact->step++;
2017-04-03 14:12:59 +00:00
2019-04-27 14:54:30 +00:00
return OGS_OK;
2017-08-31 05:03:00 +00:00
}
2017-04-03 05:18:25 +00:00
static int ogs_gtp_xact_update_rx(ogs_gtp_xact_t *xact, uint8_t type)
2017-08-31 05:03:00 +00:00
{
2019-04-27 14:54:30 +00:00
char buf[OGS_ADDRSTRLEN];
2019-09-13 12:07:47 +00:00
ogs_gtp_xact_stage_t stage;
2017-08-31 05:03:00 +00:00
2019-04-27 14:54:30 +00:00
ogs_debug("[%d] %s UPD RX-%d peer [%s]:%d",
2017-08-31 05:03:00 +00:00
xact->xid,
2019-09-13 12:07:47 +00:00
xact->org == OGS_GTP_LOCAL_ORIGINATOR ? "LOCAL " : "REMOTE",
2017-08-31 15:29:56 +00:00
type,
2020-04-26 19:36:05 +00:00
OGS_ADDR(&xact->gnode->addr, buf),
OGS_PORT(&xact->gnode->addr));
2017-08-31 05:03:00 +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 (xact->gtp_version == 1)
stage = ogs_gtp1_xact_get_stage(type, xact->xid);
else
stage = ogs_gtp2_xact_get_stage(type, xact->xid);
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
2019-09-13 12:07:47 +00:00
if (xact->org == OGS_GTP_LOCAL_ORIGINATOR) {
2019-07-20 06:20:52 +00:00
switch (stage) {
case GTP_XACT_INITIAL_STAGE:
2019-11-30 07:45:09 +00:00
ogs_expect(0);
return OGS_ERROR;
2019-07-20 06:20:52 +00:00
case GTP_XACT_INTERMEDIATE_STAGE:
if (xact->seq[1].type == type) {
ogs_pkbuf_t *pkbuf = NULL;
2019-11-30 07:45:09 +00:00
if (xact->step != 2 && xact->step != 3) {
ogs_error("invalid step[%d]", xact->step);
ogs_pkbuf_free(pkbuf);
return OGS_ERROR;
}
2019-07-20 06:20:52 +00:00
pkbuf = xact->seq[2].pkbuf;
if (pkbuf) {
if (xact->tm_holding)
2020-07-27 01:02:40 +00:00
ogs_timer_start(xact->tm_holding,
ogs_local_conf()->time.message.
2020-07-27 01:02:40 +00:00
gtp.t3_holding_duration);
2019-07-20 06:20:52 +00:00
ogs_warn("[%d] %s Request Duplicated. Retransmit!"
" for step %d type %d peer [%s]:%d",
xact->xid,
2019-09-13 12:07:47 +00:00
xact->org == OGS_GTP_LOCAL_ORIGINATOR ?
2019-07-20 06:20:52 +00:00
"LOCAL " : "REMOTE",
xact->step, type,
2020-04-26 19:36:05 +00:00
OGS_ADDR(&xact->gnode->addr,
2019-07-20 06:20:52 +00:00
buf),
2020-04-26 19:36:05 +00:00
OGS_PORT(&xact->gnode->addr));
2023-02-16 21:55:22 +00:00
ogs_expect(OGS_OK == ogs_gtp_sendto(xact->gnode, pkbuf));
2019-07-20 06:20:52 +00:00
} else {
ogs_warn("[%d] %s Request Duplicated. Discard!"
" for step %d type %d peer [%s]:%d",
xact->xid,
2019-09-13 12:07:47 +00:00
xact->org == OGS_GTP_LOCAL_ORIGINATOR ?
2019-07-20 06:20:52 +00:00
"LOCAL " : "REMOTE",
xact->step, type,
2020-04-26 19:36:05 +00:00
OGS_ADDR(&xact->gnode->addr,
2019-07-20 06:20:52 +00:00
buf),
2020-04-26 19:36:05 +00:00
OGS_PORT(&xact->gnode->addr));
2017-08-31 11:48:15 +00:00
}
2019-07-20 06:20:52 +00:00
return OGS_RETRY;
}
2019-11-30 07:45:09 +00:00
if (xact->step != 1) {
ogs_error("invalid step[%d]", xact->step);
return OGS_ERROR;
}
2017-08-31 11:48:15 +00:00
2019-07-20 06:20:52 +00:00
if (xact->tm_holding)
2020-07-27 01:02:40 +00:00
ogs_timer_start(xact->tm_holding,
ogs_local_conf()->time.message.gtp.t3_holding_duration);
2017-08-31 11:48:15 +00:00
2019-07-20 06:20:52 +00:00
break;
2017-08-31 11:48:15 +00:00
2019-07-20 06:20:52 +00:00
case GTP_XACT_FINAL_STAGE:
2019-11-30 07:45:09 +00:00
if (xact->step != 1) {
ogs_error("invalid step[%d]", xact->step);
return OGS_ERROR;
}
2019-07-20 06:20:52 +00:00
break;
2017-08-31 11:48:15 +00:00
2019-07-20 06:20:52 +00:00
default:
2019-11-30 07:45:09 +00:00
ogs_error("invalid stage[%d]", stage);
return OGS_ERROR;
2017-08-31 05:03:00 +00:00
}
2019-09-13 12:07:47 +00:00
} else if (xact->org == OGS_GTP_REMOTE_ORIGINATOR) {
2019-07-20 06:20:52 +00:00
switch (stage) {
case GTP_XACT_INITIAL_STAGE:
if (xact->seq[0].type == type) {
ogs_pkbuf_t *pkbuf = NULL;
2019-11-30 07:45:09 +00:00
if (xact->step != 1 && xact->step != 2) {
ogs_error("invalid step[%d]", xact->step);
return OGS_ERROR;
}
2019-07-20 06:20:52 +00:00
pkbuf = xact->seq[1].pkbuf;
if (pkbuf) {
if (xact->tm_holding)
2020-07-27 01:02:40 +00:00
ogs_timer_start(xact->tm_holding,
ogs_local_conf()->time.message.
2020-07-27 01:02:40 +00:00
gtp.t3_holding_duration);
2019-07-20 06:20:52 +00:00
ogs_warn("[%d] %s Request Duplicated. Retransmit!"
" for step %d type %d peer [%s]:%d",
xact->xid,
2019-09-13 12:07:47 +00:00
xact->org == OGS_GTP_LOCAL_ORIGINATOR ?
2019-07-20 06:20:52 +00:00
"LOCAL " : "REMOTE",
xact->step, type,
2020-04-26 19:36:05 +00:00
OGS_ADDR(&xact->gnode->addr,
2019-07-20 06:20:52 +00:00
buf),
2020-04-26 19:36:05 +00:00
OGS_PORT(&xact->gnode->addr));
2023-02-16 21:55:22 +00:00
ogs_expect(OGS_OK == ogs_gtp_sendto(xact->gnode, pkbuf));
2019-07-20 06:20:52 +00:00
} else {
ogs_warn("[%d] %s Request Duplicated. Discard!"
" for step %d type %d peer [%s]:%d",
xact->xid,
2019-09-13 12:07:47 +00:00
xact->org == OGS_GTP_LOCAL_ORIGINATOR ?
2019-07-20 06:20:52 +00:00
"LOCAL " : "REMOTE",
xact->step, type,
2020-04-26 19:36:05 +00:00
OGS_ADDR(&xact->gnode->addr,
2019-07-20 06:20:52 +00:00
buf),
2020-04-26 19:36:05 +00:00
OGS_PORT(&xact->gnode->addr));
2017-08-31 11:48:15 +00:00
}
2019-07-20 06:20:52 +00:00
return OGS_RETRY;
}
2019-11-30 07:45:09 +00:00
if (xact->step != 0) {
ogs_error("invalid step[%d]", xact->step);
return OGS_ERROR;
}
2019-07-20 06:20:52 +00:00
if (xact->tm_holding)
2020-07-27 01:02:40 +00:00
ogs_timer_start(xact->tm_holding,
ogs_local_conf()->time.message.gtp.t3_holding_duration);
2017-08-31 11:48:15 +00:00
2019-07-20 06:20:52 +00:00
break;
2017-08-31 11:48:15 +00:00
2019-07-20 06:20:52 +00:00
case GTP_XACT_INTERMEDIATE_STAGE:
2019-11-30 07:45:09 +00:00
ogs_expect(0);
return OGS_ERROR;
2017-08-31 11:48:15 +00:00
2019-07-20 06:20:52 +00:00
case GTP_XACT_FINAL_STAGE:
2019-11-30 07:45:09 +00:00
if (xact->step != 2) {
ogs_error("invalid step[%d]", xact->step);
return OGS_ERROR;
}
2017-08-31 11:48:15 +00:00
2019-07-20 06:20:52 +00:00
/* continue */
break;
2017-08-31 11:48:15 +00:00
2019-07-20 06:20:52 +00:00
default:
2019-11-30 07:45:09 +00:00
ogs_error("invalid stage[%d]", stage);
return OGS_ERROR;
2017-08-31 05:03:00 +00:00
}
2019-11-30 07:45:09 +00:00
} else {
ogs_error("invalid org[%d]", xact->org);
return OGS_ERROR;
}
2017-08-31 05:03:00 +00:00
2017-08-31 15:29:56 +00:00
if (xact->tm_response)
2019-04-27 14:54:30 +00:00
ogs_timer_stop(xact->tm_response);
2017-08-31 15:29:56 +00:00
2017-08-31 11:48:15 +00:00
/* Save Message type of this step */
xact->seq[xact->step].type = type;
/* Step */
xact->step++;
2017-08-31 05:03:00 +00:00
2019-04-27 14:54:30 +00:00
return OGS_OK;
2017-08-31 05:03:00 +00:00
}
2019-09-13 12:07:47 +00:00
int ogs_gtp_xact_commit(ogs_gtp_xact_t *xact)
2017-08-31 05:03:00 +00:00
{
2019-04-27 14:54:30 +00:00
char buf[OGS_ADDRSTRLEN];
2017-08-31 15:29:56 +00:00
2019-04-27 14:54:30 +00:00
uint8_t type;
ogs_pkbuf_t *pkbuf = NULL;
2019-09-13 12:07:47 +00:00
ogs_gtp_xact_stage_t stage;
2019-04-27 14:54:30 +00:00
ogs_assert(xact);
ogs_assert(xact->gnode);
2017-08-31 05:03:00 +00:00
2019-04-27 14:54:30 +00:00
ogs_debug("[%d] %s Commit peer [%s]:%d",
2017-08-31 05:03:00 +00:00
xact->xid,
2019-09-13 12:07:47 +00:00
xact->org == OGS_GTP_LOCAL_ORIGINATOR ? "LOCAL " : "REMOTE",
2020-04-26 19:36:05 +00:00
OGS_ADDR(&xact->gnode->addr, buf),
OGS_PORT(&xact->gnode->addr));
2017-08-31 05:03:00 +00:00
2017-08-31 15:29:56 +00:00
type = xact->seq[xact->step-1].type;
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 (xact->gtp_version == 1)
stage = ogs_gtp1_xact_get_stage(type, xact->xid);
else
stage = ogs_gtp2_xact_get_stage(type, xact->xid);
2017-08-31 15:29:56 +00:00
2019-09-13 12:07:47 +00:00
if (xact->org == OGS_GTP_LOCAL_ORIGINATOR) {
2019-07-20 06:20:52 +00:00
switch (stage) {
case GTP_XACT_INITIAL_STAGE:
2019-11-30 07:45:09 +00:00
if (xact->step != 1) {
ogs_error("invalid step[%d]", xact->step);
ogs_gtp_xact_delete(xact);
return OGS_ERROR;
}
2017-08-31 15:29:56 +00:00
2019-07-20 06:20:52 +00:00
if (xact->tm_response)
2020-07-27 01:02:40 +00:00
ogs_timer_start(xact->tm_response,
ogs_local_conf()->time.message.gtp.
t3_response_duration);
2017-08-31 15:29:56 +00:00
2019-07-20 06:20:52 +00:00
break;
2017-08-31 15:29:56 +00:00
2019-07-20 06:20:52 +00:00
case GTP_XACT_INTERMEDIATE_STAGE:
if (xact->step != 2) {
ogs_error("invalid step[%d]", xact->step);
ogs_gtp_xact_delete(xact);
return OGS_ERROR;
}
return OGS_OK;
2017-08-31 15:29:56 +00:00
2019-07-20 06:20:52 +00:00
case GTP_XACT_FINAL_STAGE:
2019-11-30 07:45:09 +00:00
if (xact->step != 2 && xact->step != 3) {
ogs_error("invalid step[%d]", xact->step);
ogs_gtp_xact_delete(xact);
return OGS_ERROR;
}
2019-07-20 06:20:52 +00:00
if (xact->step == 2) {
2019-09-13 12:07:47 +00:00
ogs_gtp_xact_delete(xact);
2019-07-20 06:20:52 +00:00
return OGS_OK;
}
2017-08-31 15:29:56 +00:00
2019-07-20 06:20:52 +00:00
break;
2017-08-31 15:29:56 +00:00
2019-07-20 06:20:52 +00:00
default:
2019-11-30 07:45:09 +00:00
ogs_error("invalid stage[%d]", stage);
ogs_gtp_xact_delete(xact);
return OGS_ERROR;
2017-08-31 05:03:00 +00:00
}
2019-09-13 12:07:47 +00:00
} else if (xact->org == OGS_GTP_REMOTE_ORIGINATOR) {
2019-07-20 06:20:52 +00:00
switch (stage) {
case GTP_XACT_INITIAL_STAGE:
2019-11-30 07:45:09 +00:00
ogs_expect(0);
ogs_gtp_xact_delete(xact);
return OGS_ERROR;
2019-07-20 06:20:52 +00:00
case GTP_XACT_INTERMEDIATE_STAGE:
2019-11-30 07:45:09 +00:00
if (xact->step != 2) {
ogs_error("invalid step[%d]", xact->step);
ogs_gtp_xact_delete(xact);
return OGS_ERROR;
}
2019-07-20 06:20:52 +00:00
if (xact->tm_response)
2020-07-27 01:02:40 +00:00
ogs_timer_start(xact->tm_response,
ogs_local_conf()->time.message.gtp.
t3_response_duration);
2019-07-20 06:20:52 +00:00
break;
case GTP_XACT_FINAL_STAGE:
2019-11-30 07:45:09 +00:00
if (xact->step != 2 && xact->step != 3) {
ogs_error("invalid step[%d]", xact->step);
ogs_gtp_xact_delete(xact);
return OGS_ERROR;
}
2019-07-20 06:20:52 +00:00
if (xact->step == 3) {
2019-09-13 12:07:47 +00:00
ogs_gtp_xact_delete(xact);
2019-07-20 06:20:52 +00:00
return OGS_OK;
}
2017-08-31 15:29:56 +00:00
2019-07-20 06:20:52 +00:00
break;
2017-08-31 15:29:56 +00:00
2019-07-20 06:20:52 +00:00
default:
2019-11-30 07:45:09 +00:00
ogs_error("invalid stage[%d]", stage);
ogs_gtp_xact_delete(xact);
return OGS_ERROR;
2017-08-31 15:29:56 +00:00
}
2019-11-30 07:45:09 +00:00
} else {
ogs_error("invalid org[%d]", xact->org);
ogs_gtp_xact_delete(xact);
return OGS_ERROR;
}
2017-08-31 05:03:00 +00:00
2017-08-31 11:48:15 +00:00
pkbuf = xact->seq[xact->step-1].pkbuf;
2019-04-27 14:54:30 +00:00
ogs_assert(pkbuf);
2017-08-31 11:48:15 +00:00
2023-02-16 21:55:22 +00:00
ogs_expect(OGS_OK == ogs_gtp_sendto(xact->gnode, pkbuf));
2017-08-31 05:03:00 +00:00
return OGS_OK;
2017-04-01 14:13:15 +00:00
}
2017-03-30 15:15:13 +00:00
2019-04-27 14:54:30 +00:00
static void response_timeout(void *data)
2017-04-01 14:13:15 +00:00
{
2019-04-27 14:54:30 +00:00
char buf[OGS_ADDRSTRLEN];
2019-09-13 12:07:47 +00:00
ogs_gtp_xact_t *xact = data;
2019-04-27 14:54:30 +00:00
ogs_assert(xact);
ogs_assert(xact->gnode);
2017-04-01 14:13:15 +00:00
2019-04-27 14:54:30 +00:00
ogs_debug("[%d] %s Response Timeout "
"for step %d type %d peer [%s]:%d",
xact->xid,
2019-09-13 12:07:47 +00:00
xact->org == OGS_GTP_LOCAL_ORIGINATOR ? "LOCAL " : "REMOTE",
2019-04-27 14:54:30 +00:00
xact->step, xact->seq[xact->step-1].type,
2020-04-26 19:36:05 +00:00
OGS_ADDR(&xact->gnode->addr, buf),
OGS_PORT(&xact->gnode->addr));
2017-08-31 15:29:56 +00:00
2019-07-20 06:20:52 +00:00
if (--xact->response_rcount > 0) {
2019-04-27 14:54:30 +00:00
ogs_pkbuf_t *pkbuf = NULL;
2017-08-31 11:48:15 +00:00
2019-04-27 14:54:30 +00:00
if (xact->tm_response)
2020-07-27 01:02:40 +00:00
ogs_timer_start(xact->tm_response,
ogs_local_conf()->time.message.gtp.t3_response_duration);
2017-08-31 11:48:15 +00:00
2019-04-27 14:54:30 +00:00
pkbuf = xact->seq[xact->step-1].pkbuf;
ogs_assert(pkbuf);
2017-04-01 14:28:22 +00:00
2023-02-16 21:55:22 +00:00
ogs_expect(OGS_OK == ogs_gtp_sendto(xact->gnode, pkbuf));
2019-07-20 06:20:52 +00:00
} else {
2019-04-27 14:54:30 +00:00
ogs_warn("[%d] %s No Reponse. Give up! "
"for step %d type %d peer [%s]:%d",
2017-08-31 15:29:56 +00:00
xact->xid,
2019-09-13 12:07:47 +00:00
xact->org == OGS_GTP_LOCAL_ORIGINATOR ? "LOCAL " : "REMOTE",
2017-09-04 11:06:54 +00:00
xact->step, xact->seq[xact->step-1].type,
2020-04-26 19:36:05 +00:00
OGS_ADDR(&xact->gnode->addr, buf),
OGS_PORT(&xact->gnode->addr));
if (xact->cb)
xact->cb(xact, xact->data);
2019-09-13 12:07:47 +00:00
ogs_gtp_xact_delete(xact);
2017-04-03 04:06:56 +00:00
}
2017-03-26 15:48:33 +00:00
}
2019-04-27 14:54:30 +00:00
static void holding_timeout(void *data)
{
char buf[OGS_ADDRSTRLEN];
2019-09-13 12:07:47 +00:00
ogs_gtp_xact_t *xact = data;
2019-04-27 14:54:30 +00:00
ogs_assert(xact);
ogs_assert(xact->gnode);
ogs_debug("[%d] %s Holding Timeout "
"for step %d type %d peer [%s]:%d",
xact->xid,
2019-09-13 12:07:47 +00:00
xact->org == OGS_GTP_LOCAL_ORIGINATOR ? "LOCAL " : "REMOTE",
2019-04-27 14:54:30 +00:00
xact->step, xact->seq[xact->step-1].type,
2020-04-26 19:36:05 +00:00
OGS_ADDR(&xact->gnode->addr, buf),
OGS_PORT(&xact->gnode->addr));
2019-04-27 14:54:30 +00:00
2019-07-20 06:20:52 +00:00
if (--xact->holding_rcount > 0) {
2019-04-27 14:54:30 +00:00
if (xact->tm_holding)
2020-07-27 01:02:40 +00:00
ogs_timer_start(xact->tm_holding,
ogs_local_conf()->time.message.gtp.t3_holding_duration);
2019-07-20 06:20:52 +00:00
} else {
2019-04-27 14:54:30 +00:00
ogs_debug("[%d] %s Delete Transaction "
"for step %d type %d peer [%s]:%d",
xact->xid,
2019-09-13 12:07:47 +00:00
xact->org == OGS_GTP_LOCAL_ORIGINATOR ? "LOCAL " : "REMOTE",
2019-04-27 14:54:30 +00:00
xact->step, xact->seq[xact->step-1].type,
2020-04-26 19:36:05 +00:00
OGS_ADDR(&xact->gnode->addr, buf),
OGS_PORT(&xact->gnode->addr));
2019-09-13 12:07:47 +00:00
ogs_gtp_xact_delete(xact);
2019-04-27 14:54:30 +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
int ogs_gtp1_xact_receive(
ogs_gtp_node_t *gnode, ogs_gtp1_header_t *h, ogs_gtp_xact_t **xact)
{
int rv;
char buf[OGS_ADDRSTRLEN];
uint8_t type;
uint32_t sqn, xid;
ogs_gtp_xact_stage_t stage;
ogs_list_t *list = NULL;
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_xact_t *new = NULL;
ogs_assert(gnode);
ogs_assert(h);
type = h->type;
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 (!h->s) {
ogs_error("ogs_gtp_xact_update_rx() failed, pkt has no SQN");
return OGS_ERROR;
}
sqn = h->sqn;
xid = OGS_GTP1_SQN_TO_XID(sqn);
stage = ogs_gtp1_xact_get_stage(type, xid);
switch (stage) {
case GTP_XACT_INITIAL_STAGE:
list = &gnode->remote_list;
break;
case GTP_XACT_INTERMEDIATE_STAGE:
list = &gnode->local_list;
break;
case GTP_XACT_FINAL_STAGE:
/* For types which are replies to replies, the xact is never locally
* created during transmit, but actually during rx of the initial req, hence
* it is never placed in the local_list, but in the remote_list. */
if (type == OGS_GTP1_SGSN_CONTEXT_ACKNOWLEDGE_TYPE)
list = &gnode->remote_list;
else
list = &gnode->local_list;
break;
default:
ogs_error("[%d] Unexpected type %u from GTPv1 peer [%s]:%d",
xid, type, OGS_ADDR(&gnode->addr, buf), OGS_PORT(&gnode->addr));
return OGS_ERROR;
}
ogs_assert(list);
ogs_list_for_each(list, new) {
if (new->gtp_version == 1 && new->xid == xid) {
ogs_debug("[%d] %s Find GTPv%u peer [%s]:%d",
new->xid,
new->org == OGS_GTP_LOCAL_ORIGINATOR ? "LOCAL " : "REMOTE",
new->gtp_version,
OGS_ADDR(&gnode->addr, buf),
OGS_PORT(&gnode->addr));
break;
}
}
if (!new) {
ogs_debug("[%d] Cannot find xact type %u from GTPv1 peer [%s]:%d",
xid, type, OGS_ADDR(&gnode->addr, buf), OGS_PORT(&gnode->addr));
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
new = ogs_gtp_xact_remote_create(gnode, 1, sqn);
}
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_assert(new);
ogs_debug("[%d] %s Receive peer [%s]:%d",
new->xid,
new->org == OGS_GTP_LOCAL_ORIGINATOR ? "LOCAL " : "REMOTE",
OGS_ADDR(&gnode->addr, buf),
OGS_PORT(&gnode->addr));
rv = ogs_gtp_xact_update_rx(new, type);
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 (rv == OGS_ERROR) {
ogs_error("ogs_gtp_xact_update_rx() failed");
ogs_gtp_xact_delete(new);
return rv;
} else if (rv == OGS_RETRY) {
return rv;
}
*xact = new;
return rv;
}
2019-04-27 14:54:30 +00:00
2019-09-13 12:07:47 +00:00
int ogs_gtp_xact_receive(
ogs_gtp_node_t *gnode, ogs_gtp2_header_t *h, ogs_gtp_xact_t **xact)
2017-03-29 14:19:31 +00:00
{
2019-04-27 14:54:30 +00:00
int rv;
char buf[OGS_ADDRSTRLEN];
uint8_t type;
uint32_t sqn, xid;
ogs_gtp_xact_stage_t stage;
ogs_list_t *list = NULL;
2019-09-13 12:07:47 +00:00
ogs_gtp_xact_t *new = NULL;
2017-03-29 14:19:31 +00:00
2019-04-27 14:54:30 +00:00
ogs_assert(gnode);
ogs_assert(h);
2017-03-30 14:27:26 +00:00
type = h->type;
if (h->teid_presence) sqn = h->sqn;
else sqn = h->sqn_only;
xid = OGS_GTP2_SQN_TO_XID(sqn);
stage = ogs_gtp2_xact_get_stage(type, xid);
switch (stage) {
case GTP_XACT_INITIAL_STAGE:
list = &gnode->remote_list;
break;
case GTP_XACT_INTERMEDIATE_STAGE:
list = &gnode->local_list;
break;
case GTP_XACT_FINAL_STAGE:
if (xid & OGS_GTP_CMD_XACT_ID) {
if (type == OGS_GTP2_MODIFY_BEARER_FAILURE_INDICATION_TYPE ||
type == OGS_GTP2_DELETE_BEARER_FAILURE_INDICATION_TYPE ||
type == OGS_GTP2_BEARER_RESOURCE_FAILURE_INDICATION_TYPE) {
list = &gnode->local_list;
} else {
list = &gnode->remote_list;
}
} else {
list = &gnode->local_list;
}
break;
default:
ogs_error("[%d] Unexpected type %u from GTPv2 peer [%s]:%d",
xid, type, OGS_ADDR(&gnode->addr, buf), OGS_PORT(&gnode->addr));
return OGS_ERROR;
}
ogs_assert(list);
ogs_list_for_each(list, new) {
if (new->gtp_version == 2 && new->xid == xid) {
ogs_debug("[%d] %s Find GTPv%u peer [%s]:%d",
new->xid,
new->org == OGS_GTP_LOCAL_ORIGINATOR ? "LOCAL " : "REMOTE",
new->gtp_version,
OGS_ADDR(&gnode->addr, buf),
OGS_PORT(&gnode->addr));
break;
}
}
if (!new) {
ogs_debug("[%d] Cannot find xact type %u from GTPv2 peer [%s]:%d",
xid, type, OGS_ADDR(&gnode->addr, buf), OGS_PORT(&gnode->addr));
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
new = ogs_gtp_xact_remote_create(gnode, 2, sqn);
}
2019-04-27 14:54:30 +00:00
ogs_assert(new);
2017-04-03 06:48:43 +00:00
2019-04-27 14:54:30 +00:00
ogs_debug("[%d] %s Receive peer [%s]:%d",
2017-08-01 01:16:06 +00:00
new->xid,
2019-09-13 12:07:47 +00:00
new->org == OGS_GTP_LOCAL_ORIGINATOR ? "LOCAL " : "REMOTE",
2020-04-26 19:36:05 +00:00
OGS_ADDR(&gnode->addr, buf),
OGS_PORT(&gnode->addr));
2017-04-03 13:46:19 +00:00
rv = ogs_gtp_xact_update_rx(new, type);
if (rv == OGS_ERROR) {
2019-11-30 07:45:09 +00:00
ogs_error("ogs_gtp_xact_update_rx() failed");
ogs_gtp_xact_delete(new);
2017-08-31 05:03:00 +00:00
return rv;
} else if (rv == OGS_RETRY) {
return rv;
2017-04-03 06:48:43 +00:00
}
2017-03-29 14:19:31 +00:00
2017-04-06 03:13:38 +00:00
*xact = new;
return rv;
2017-04-03 13:46:19 +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
static ogs_gtp_xact_stage_t ogs_gtp1_xact_get_stage(uint8_t type, uint32_t xid)
{
ogs_gtp_xact_stage_t stage = GTP_XACT_UNKNOWN_STAGE;
switch (type) {
case OGS_GTP1_ECHO_REQUEST_TYPE:
case OGS_GTP1_NODE_ALIVE_REQUEST_TYPE:
case OGS_GTP1_REDIRECTION_REQUEST_TYPE:
case OGS_GTP1_CREATE_PDP_CONTEXT_REQUEST_TYPE:
case OGS_GTP1_UPDATE_PDP_CONTEXT_REQUEST_TYPE:
case OGS_GTP1_DELETE_PDP_CONTEXT_REQUEST_TYPE:
case OGS_GTP1_INITIATE_PDP_CONTEXT_ACTIVATION_REQUEST_TYPE:
case OGS_GTP1_PDU_NOTIFICATION_REQUEST_TYPE:
case OGS_GTP1_PDU_NOTIFICATION_REJECT_REQUEST_TYPE:
case OGS_GTP1_SEND_ROUTEING_INFORMATION_FOR_GPRS_REQUEST_TYPE:
case OGS_GTP1_FAILURE_REPORT_REQUEST_TYPE:
case OGS_GTP1_NOTE_MS_GPRS_PRESENT_REQUEST_TYPE:
case OGS_GTP1_IDENTIFICATION_REQUEST_TYPE:
case OGS_GTP1_SGSN_CONTEXT_REQUEST_TYPE:
case OGS_GTP1_FORWARD_RELOCATION_REQUEST_TYPE:
case OGS_GTP1_RELOCATION_CANCEL_REQUEST_TYPE:
case OGS_GTP1_UE_REGISTRATION_QUERY_REQUEST_TYPE:
case OGS_GTP1_RAN_INFORMATION_RELAY_TYPE:
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
stage = GTP_XACT_INITIAL_STAGE;
break;
case OGS_GTP1_SGSN_CONTEXT_RESPONSE_TYPE:
stage = GTP_XACT_INTERMEDIATE_STAGE;
break;
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
case OGS_GTP1_ECHO_RESPONSE_TYPE:
case OGS_GTP1_NODE_ALIVE_RESPONSE_TYPE:
case OGS_GTP1_REDIRECTION_RESPONSE_TYPE:
case OGS_GTP1_CREATE_PDP_CONTEXT_RESPONSE_TYPE:
case OGS_GTP1_UPDATE_PDP_CONTEXT_RESPONSE_TYPE:
case OGS_GTP1_DELETE_PDP_CONTEXT_RESPONSE_TYPE:
case OGS_GTP1_INITIATE_PDP_CONTEXT_ACTIVATION_RESPONSE_TYPE:
case OGS_GTP1_PDU_NOTIFICATION_RESPONSE_TYPE:
case OGS_GTP1_PDU_NOTIFICATION_REJECT_RESPONSE_TYPE:
case OGS_GTP1_SEND_ROUTEING_INFORMATION_FOR_GPRS_RESPONSE_TYPE:
case OGS_GTP1_FAILURE_REPORT_RESPONSE_TYPE:
case OGS_GTP1_NOTE_MS_GPRS_PRESENT_RESPONSE_TYPE:
case OGS_GTP1_IDENTIFICATION_RESPONSE_TYPE:
case OGS_GTP1_SGSN_CONTEXT_ACKNOWLEDGE_TYPE:
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
case OGS_GTP1_FORWARD_RELOCATION_RESPONSE_TYPE:
case OGS_GTP1_RELOCATION_CANCEL_RESPONSE_TYPE:
case OGS_GTP1_UE_REGISTRATION_QUERY_RESPONSE_TYPE:
stage = GTP_XACT_FINAL_STAGE;
break;
default:
ogs_error("Not implemented GTPv1 Message Type(%d)", type);
break;
}
return stage;
}
/* TS 29.274 Table 6.1-1 */
static ogs_gtp_xact_stage_t ogs_gtp2_xact_get_stage(uint8_t type, uint32_t xid)
2017-08-31 01:48:14 +00:00
{
2019-09-13 12:07:47 +00:00
ogs_gtp_xact_stage_t stage = GTP_XACT_UNKNOWN_STAGE;
2017-08-31 01:48:14 +00:00
2019-07-20 06:20:52 +00:00
switch (type) {
case OGS_GTP2_ECHO_REQUEST_TYPE:
case OGS_GTP2_CREATE_SESSION_REQUEST_TYPE:
case OGS_GTP2_MODIFY_BEARER_REQUEST_TYPE:
case OGS_GTP2_DELETE_SESSION_REQUEST_TYPE:
case OGS_GTP2_CHANGE_NOTIFICATION_REQUEST_TYPE:
case OGS_GTP2_REMOTE_UE_REPORT_NOTIFICATION_TYPE:
case OGS_GTP2_MODIFY_BEARER_COMMAND_TYPE:
case OGS_GTP2_DELETE_BEARER_COMMAND_TYPE:
case OGS_GTP2_BEARER_RESOURCE_COMMAND_TYPE:
case OGS_GTP2_TRACE_SESSION_ACTIVATION_TYPE:
case OGS_GTP2_TRACE_SESSION_DEACTIVATION_TYPE:
case OGS_GTP2_STOP_PAGING_INDICATION_TYPE:
case OGS_GTP2_DELETE_PDN_CONNECTION_SET_REQUEST_TYPE:
case OGS_GTP2_PGW_DOWNLINK_TRIGGERING_NOTIFICATION_TYPE:
case OGS_GTP2_CREATE_FORWARDING_TUNNEL_REQUEST_TYPE:
case OGS_GTP2_SUSPEND_NOTIFICATION_TYPE:
case OGS_GTP2_RESUME_NOTIFICATION_TYPE:
case OGS_GTP2_CREATE_INDIRECT_DATA_FORWARDING_TUNNEL_REQUEST_TYPE:
case OGS_GTP2_DELETE_INDIRECT_DATA_FORWARDING_TUNNEL_REQUEST_TYPE:
case OGS_GTP2_RELEASE_ACCESS_BEARERS_REQUEST_TYPE:
case OGS_GTP2_DOWNLINK_DATA_NOTIFICATION_TYPE:
case OGS_GTP2_PGW_RESTART_NOTIFICATION_TYPE:
case OGS_GTP2_UPDATE_PDN_CONNECTION_SET_REQUEST_TYPE:
case OGS_GTP2_MODIFY_ACCESS_BEARERS_REQUEST_TYPE:
2019-07-20 06:20:52 +00:00
stage = GTP_XACT_INITIAL_STAGE;
break;
case OGS_GTP2_CREATE_BEARER_REQUEST_TYPE:
case OGS_GTP2_UPDATE_BEARER_REQUEST_TYPE:
case OGS_GTP2_DELETE_BEARER_REQUEST_TYPE:
if (xid & OGS_GTP_CMD_XACT_ID)
2019-07-20 06:20:52 +00:00
stage = GTP_XACT_INTERMEDIATE_STAGE;
else
2017-08-31 01:48:14 +00:00
stage = GTP_XACT_INITIAL_STAGE;
2019-07-20 06:20:52 +00:00
break;
case OGS_GTP2_ECHO_RESPONSE_TYPE:
case OGS_GTP2_VERSION_NOT_SUPPORTED_INDICATION_TYPE:
case OGS_GTP2_CREATE_SESSION_RESPONSE_TYPE:
case OGS_GTP2_MODIFY_BEARER_RESPONSE_TYPE:
case OGS_GTP2_DELETE_SESSION_RESPONSE_TYPE:
case OGS_GTP2_CHANGE_NOTIFICATION_RESPONSE_TYPE:
case OGS_GTP2_REMOTE_UE_REPORT_ACKNOWLEDGE_TYPE:
case OGS_GTP2_MODIFY_BEARER_FAILURE_INDICATION_TYPE:
case OGS_GTP2_DELETE_BEARER_FAILURE_INDICATION_TYPE:
case OGS_GTP2_BEARER_RESOURCE_FAILURE_INDICATION_TYPE:
case OGS_GTP2_DOWNLINK_DATA_NOTIFICATION_FAILURE_INDICATION_TYPE:
case OGS_GTP2_CREATE_BEARER_RESPONSE_TYPE:
case OGS_GTP2_UPDATE_BEARER_RESPONSE_TYPE:
case OGS_GTP2_DELETE_BEARER_RESPONSE_TYPE:
case OGS_GTP2_DELETE_PDN_CONNECTION_SET_RESPONSE_TYPE:
case OGS_GTP2_PGW_DOWNLINK_TRIGGERING_ACKNOWLEDGE_TYPE:
case OGS_GTP2_CREATE_FORWARDING_TUNNEL_RESPONSE_TYPE:
case OGS_GTP2_SUSPEND_ACKNOWLEDGE_TYPE:
case OGS_GTP2_RESUME_ACKNOWLEDGE_TYPE:
case OGS_GTP2_CREATE_INDIRECT_DATA_FORWARDING_TUNNEL_RESPONSE_TYPE:
case OGS_GTP2_DELETE_INDIRECT_DATA_FORWARDING_TUNNEL_RESPONSE_TYPE:
case OGS_GTP2_RELEASE_ACCESS_BEARERS_RESPONSE_TYPE:
case OGS_GTP2_DOWNLINK_DATA_NOTIFICATION_ACKNOWLEDGE_TYPE:
case OGS_GTP2_PGW_RESTART_NOTIFICATION_ACKNOWLEDGE_TYPE:
case OGS_GTP2_UPDATE_PDN_CONNECTION_SET_RESPONSE_TYPE:
case OGS_GTP2_MODIFY_ACCESS_BEARERS_RESPONSE_TYPE:
2019-07-20 06:20:52 +00:00
stage = GTP_XACT_FINAL_STAGE;
break;
default:
ogs_error("Not implemented GTPv2 Message Type(%d)", type);
break;
2017-08-31 01:48:14 +00:00
}
return stage;
}
2017-08-31 03:06:11 +00:00
2019-09-13 12:07:47 +00:00
void ogs_gtp_xact_associate(ogs_gtp_xact_t *xact1, ogs_gtp_xact_t *xact2)
2017-08-31 03:06:11 +00:00
{
2019-04-27 14:54:30 +00:00
ogs_assert(xact1);
ogs_assert(xact2);
2017-08-31 03:06:11 +00:00
2019-04-27 14:54:30 +00:00
ogs_assert(xact1->assoc_xact == NULL);
ogs_assert(xact2->assoc_xact == NULL);
2017-08-31 03:06:11 +00:00
xact1->assoc_xact = xact2;
xact2->assoc_xact = xact1;
}
2019-09-13 12:07:47 +00:00
void ogs_gtp_xact_deassociate(ogs_gtp_xact_t *xact1, ogs_gtp_xact_t *xact2)
2017-08-31 03:06:11 +00:00
{
2019-04-27 14:54:30 +00:00
ogs_assert(xact1);
ogs_assert(xact2);
2017-08-31 03:06:11 +00:00
2019-04-27 14:54:30 +00:00
ogs_assert(xact1->assoc_xact != NULL);
ogs_assert(xact2->assoc_xact != NULL);
2017-08-31 03:06:11 +00:00
xact1->assoc_xact = NULL;
xact2->assoc_xact = NULL;
}
2019-09-13 12:07:47 +00:00
static int ogs_gtp_xact_delete(ogs_gtp_xact_t *xact)
2017-08-31 05:03:00 +00:00
{
2019-04-27 14:54:30 +00:00
char buf[OGS_ADDRSTRLEN];
2017-08-31 05:03:00 +00:00
2019-04-27 14:54:30 +00:00
ogs_assert(xact);
ogs_assert(xact->gnode);
2017-08-31 05:03:00 +00:00
2019-04-27 14:54:30 +00:00
ogs_debug("[%d] %s Delete peer [%s]:%d",
2017-08-31 05:03:00 +00:00
xact->xid,
2019-09-13 12:07:47 +00:00
xact->org == OGS_GTP_LOCAL_ORIGINATOR ? "LOCAL " : "REMOTE",
2020-04-26 19:36:05 +00:00
OGS_ADDR(&xact->gnode->addr, buf),
OGS_PORT(&xact->gnode->addr));
2017-08-31 05:03:00 +00:00
2017-08-31 11:48:15 +00:00
if (xact->seq[0].pkbuf)
2019-04-27 14:54:30 +00:00
ogs_pkbuf_free(xact->seq[0].pkbuf);
2017-08-31 11:48:15 +00:00
if (xact->seq[1].pkbuf)
2019-04-27 14:54:30 +00:00
ogs_pkbuf_free(xact->seq[1].pkbuf);
2017-08-31 11:48:15 +00:00
if (xact->seq[2].pkbuf)
2019-04-27 14:54:30 +00:00
ogs_pkbuf_free(xact->seq[2].pkbuf);
2017-08-31 11:48:15 +00:00
if (xact->tm_response)
2019-04-27 14:54:30 +00:00
ogs_timer_delete(xact->tm_response);
2017-09-04 11:06:54 +00:00
if (xact->tm_holding)
2019-04-27 14:54:30 +00:00
ogs_timer_delete(xact->tm_holding);
2017-08-31 05:03:00 +00:00
if (xact->assoc_xact)
2019-09-13 12:07:47 +00:00
ogs_gtp_xact_deassociate(xact, xact->assoc_xact);
2017-08-31 05:03:00 +00:00
2019-09-13 12:07:47 +00:00
ogs_list_remove(xact->org == OGS_GTP_LOCAL_ORIGINATOR ?
2019-04-27 14:54:30 +00:00
&xact->gnode->local_list : &xact->gnode->remote_list, xact);
ogs_pool_free(&pool, xact);
2017-08-31 05:03:00 +00:00
2019-04-27 14:54:30 +00:00
return OGS_OK;
2017-08-31 05:03:00 +00:00
}