Merge remote-tracking branch 'origin/gtp-e1-fix-errors-test' into integration_2025_w44 (!3725)

Handle GTP receiver errors, fix memory leaks, add CU-UP test

- Fix use-after-free bugs in GTP by properly stopping the receive thread(s)
- Fix a bug from !3519 (merged): QFI 0 is a valid QFI
- Fix multiple memory leaks in CU-UP, E1, CU-UP load tester, SCTP
- Add a (conservative) functional CU-UP test that verifies that the load tester
  and CU-UP work. Test only a low throughput, as it will run in parallel with
  other tests.
This commit is contained in:
Jaroslava Fiedlerova
2025-10-30 10:41:47 +01:00
13 changed files with 84 additions and 30 deletions
+5 -5
View File
@@ -125,8 +125,8 @@ static void e1_task_handle_sctp_data_ind(instance_t instance, sctp_data_ind_t *s
int e1ap_send_RESET(bool isCu, sctp_assoc_t assoc_id, E1AP_Reset_t *Reset)
{
AssertFatal(false, "Not implemented yet\n");
E1AP_E1AP_PDU_t pdu = {0};
return e1ap_encode_send(isCu, assoc_id, &pdu, 0, __func__);
E1AP_E1AP_PDU_t *pdu = calloc_or_fail(1, sizeof(*pdu));
return e1ap_encode_send(isCu, assoc_id, pdu, 0, __func__);
}
int e1ap_send_RESET_ACKNOWLEDGE(instance_t instance, E1AP_Reset_t *Reset)
@@ -304,9 +304,9 @@ static void fill_CONFIGURATION_UPDATE(E1AP_E1AP_PDU_t *pdu)
void e1apCUUP_send_CONFIGURATION_UPDATE(sctp_assoc_t assoc_id)
{
E1AP_E1AP_PDU_t pdu = {0};
fill_CONFIGURATION_UPDATE(&pdu);
e1ap_encode_send(UPtype, assoc_id, &pdu, 0, __func__);
E1AP_E1AP_PDU_t *pdu = calloc_or_fail(1, sizeof(*pdu));
fill_CONFIGURATION_UPDATE(pdu);
e1ap_encode_send(UPtype, assoc_id, pdu, 0, __func__);
}
int e1apCUCP_send_gNB_DU_CONFIGURATION_FAILURE(void)
+1 -1
View File
@@ -226,7 +226,7 @@ int e1ap_encode_send(E1_t type, sctp_assoc_t assoc_id, E1AP_E1AP_PDU_t *pdu, uin
void *buffer = NULL;
ssize_t encoded = aper_encode_to_new_buffer(&asn_DEF_E1AP_E1AP_PDU, 0, pdu, &buffer);
ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_E1AP_E1AP_PDU, pdu);
ASN_STRUCT_FREE(asn_DEF_E1AP_E1AP_PDU, pdu);
if (encoded < 0) {
LOG_E(E1AP, "%s: Failed to encode E1AP message\n", func);
+1 -1
View File
@@ -153,7 +153,7 @@ static void e1_add_bearers(const int ue_id, const NR_DRB_ToAddModList_t *addMod,
// get SDAP config
sdap_config_t sdap = nr_sdap_get_config(GNB_FLAG_YES, drb->cnAssociation->choice.sdap_Config, drb->drb_Identity);
// add SDAP entity
nr_sdap_addmod_entity(GNB_FLAG_YES, ue_id, sdap);
nr_sdap_addmod_entity(GNB_FLAG_YES, ue_id, &sdap);
// add PDCP entity
nr_pdcp_add_drb(GNB_FLAG_YES, ue_id, drb->pdcp_Config, &sdap, sp);
}
+1 -1
View File
@@ -177,7 +177,7 @@ static void rrc_nsa_add_drb(const int ue_id,
sdap.drb_id = drb->drb_Identity;
sdap.defaultDRB = true;
// add SDAP entity (terminated at gNB, since it's EPC)
nr_sdap_addmod_entity(GNB_FLAG_YES, ue_id, sdap);
nr_sdap_addmod_entity(GNB_FLAG_YES, ue_id, &sdap);
// add PDCP entity
nr_pdcp_add_drb(GNB_FLAG_YES, ue_id, drb->pdcp_Config, &sdap, sp);
}
+1 -1
View File
@@ -619,7 +619,7 @@ static void rrc_ue_add_bearer(const int ue_id, const NR_DRB_ToAddMod_t *drb, con
sdap = nr_sdap_get_config(GNB_FLAG_NO, drb->cnAssociation->choice.sdap_Config, drb->drb_Identity);
}
// add SDAP entity
nr_sdap_addmod_entity(GNB_FLAG_NO, ue_id, sdap);
nr_sdap_addmod_entity(GNB_FLAG_NO, ue_id, &sdap);
// add PDCP entity
nr_pdcp_add_drb(GNB_FLAG_NO, ue_id, drb->pdcp_Config, &sdap, sp);
}
+11 -11
View File
@@ -210,8 +210,8 @@ static void nr_sdap_rx_entity(nr_sdap_entity_t *entity,
{
/* The offset of the SDAP header, it might be 0 if has_sdap_rx is not true in the pdcp entity. */
int offset=0;
int qfi = buf[0] & 0x3F; // QFI is always the first 6 bits in the first octet
if (qfi <= 0 || qfi >= SDAP_MAX_QFI) {
uint8_t qfi = buf[0] & 0x3F; // QFI is always the first 6 bits in the first octet
if (qfi >= SDAP_MAX_QFI) {
LOG_E(SDAP, "Invalid QFI %d received in SDAP header\n", qfi);
return;
}
@@ -450,7 +450,7 @@ static void nr_sdap_add_qos_flows_to_drb(nr_sdap_entity_t *entity, const sdap_co
for (int i = 0; i < sdap->mappedQFIs2AddCount; i++) {
uint8_t qfi = sdap->mappedQFIs2Add[i];
LOG_D(SDAP, "Adding QFI to DRB mapping rules: %d mapped QFIs for DRB %d\n", sdap->mappedQFIs2AddCount, sdap->drb_id);
if (qfi < SDAP_MAX_QFI && qfi > SDAP_MAP_RULE_EMPTY && sdap->drb_id > 0 && sdap->drb_id <= MAX_DRBS_PER_UE) {
if (qfi < SDAP_MAX_QFI && sdap->drb_id > SDAP_MAP_RULE_EMPTY && sdap->drb_id <= MAX_DRBS_PER_UE) {
entity->qfi2drb_map_add(entity, qfi, sdap->drb_id, sdap->role);
} else {
LOG_E(SDAP, "Failed to add qfi2drb mapping: QFI=%d, DRB=%d\n", qfi, sdap->drb_id);
@@ -487,13 +487,13 @@ static void nr_sdap_qfi2drb_map_update(nr_sdap_entity_t *entity, const sdap_conf
* @param is_gnb, indicates whether it is for gNB or UE
* @param ue_id, UE ID
* @param sdap, SDAP configuration */
static void nr_sdap_add_entity(const int is_gnb, const ue_id_t ue_id, const sdap_config_t sdap)
static void nr_sdap_add_entity(const int is_gnb, const ue_id_t ue_id, const sdap_config_t *sdap)
{
nr_sdap_entity_t *sdap_entity = calloc_or_fail(1, sizeof(*sdap_entity));
// SDAP entity ids
sdap_entity->ue_id = ue_id;
sdap_entity->pdusession_id = sdap.pdusession_id;
sdap_entity->pdusession_id = sdap->pdusession_id;
sdap_entity->is_gnb = is_gnb;
// rx/tx entities
@@ -513,13 +513,13 @@ static void nr_sdap_add_entity(const int is_gnb, const ue_id_t ue_id, const sdap
sdap_entity->pdusession_sock = -1;
// set default DRB
if (sdap.defaultDRB) {
sdap_entity->default_drb = sdap.drb_id;
if (sdap->defaultDRB) {
sdap_entity->default_drb = sdap->drb_id;
LOG_I(SDAP, "Default DRB for the created SDAP entity: DRB %d \n", sdap_entity->default_drb);
}
// Add QoS flows to the DRB (initial configuration)
nr_sdap_add_qos_flows_to_drb(sdap_entity, &sdap);
nr_sdap_add_qos_flows_to_drb(sdap_entity, sdap);
// update SDAP entity list pointers
sdap_entity->next_entity = sdap_info.sdap_entity_llist;
@@ -533,11 +533,11 @@ static void nr_sdap_add_entity(const int is_gnb, const ue_id_t ue_id, const sdap
}
/** @brief Add or modify an SDAP entity if it already exists */
void nr_sdap_addmod_entity(const int is_gnb, const ue_id_t ue_id, const sdap_config_t sdap)
void nr_sdap_addmod_entity(const int is_gnb, const ue_id_t ue_id, const sdap_config_t *sdap)
{
nr_sdap_entity_t *sdap_entity = nr_sdap_get_entity(ue_id, sdap.pdusession_id);
nr_sdap_entity_t *sdap_entity = nr_sdap_get_entity(ue_id, sdap->pdusession_id);
if (sdap_entity) {
sdap_entity->qfi2drb_map_update(sdap_entity, &sdap);
sdap_entity->qfi2drb_map_update(sdap_entity, sdap);
} else {
nr_sdap_add_entity(is_gnb, ue_id, sdap);
}
+1 -1
View File
@@ -172,7 +172,7 @@ sdap_config_t nr_sdap_get_config(const int is_gnb, const NR_SDAP_Config_t *sdap_
void nr_sdap_release_drb(ue_id_t ue_id, int drb_id, int pdusession_id);
/** @brief Add or modify an SDAP entity based on whether it already exists */
void nr_sdap_addmod_entity(const int is_gnb, const ue_id_t ue_id, const sdap_config_t sdap);
void nr_sdap_addmod_entity(const int is_gnb, const ue_id_t ue_id, const sdap_config_t *sdap);
/**
* @brief Function to delete a single SDAP Entity based on the ue_id and pdusession_id.