From 45ca753b24ea8169d7d6dbb9fcc9040dde73adc5 Mon Sep 17 00:00:00 2001 From: Guido Casati Date: Fri, 12 Jan 2024 11:01:19 +0100 Subject: [PATCH] Handling E1 connection loss on CU-CP - it triggers the RRC callback after SCTP SHUTDOWN indication - CUUP entity cleanup at RRC level --- openair2/COMMON/e1ap_messages_def.h | 3 +++ openair2/COMMON/e1ap_messages_types.h | 7 +++++++ openair2/E1AP/e1ap.c | 10 ++++++++++ openair2/RRC/NR/nr_rrc_proto.h | 3 +++ openair2/RRC/NR/rrc_gNB.c | 4 ++++ openair2/RRC/NR/rrc_gNB_cuup.c | 25 +++++++++++++++++++++++++ 6 files changed, 52 insertions(+) diff --git a/openair2/COMMON/e1ap_messages_def.h b/openair2/COMMON/e1ap_messages_def.h index fd39731df1..7c81334e68 100644 --- a/openair2/COMMON/e1ap_messages_def.h +++ b/openair2/COMMON/e1ap_messages_def.h @@ -22,6 +22,9 @@ /* gNB_CUUP application layer -> E1AP messages */ MESSAGE_DEF(E1AP_REGISTER_REQ, MESSAGE_PRIORITY_MED, e1ap_register_req_t, e1ap_register_req) +/* E1AP -> RRC to inform about lost connection */ +MESSAGE_DEF(E1AP_LOST_CONNECTION, MESSAGE_PRIORITY_MED, e1ap_lost_connection_t, e1ap_lost_connection) + /* E1AP Interface Management Messages */ /* E1AP Setup Request: gNB-CU-UP -> gNB-CU-CP */ MESSAGE_DEF(E1AP_SETUP_REQ , MESSAGE_PRIORITY_MED , e1ap_setup_req_t , e1ap_setup_req) diff --git a/openair2/COMMON/e1ap_messages_types.h b/openair2/COMMON/e1ap_messages_types.h index 605441e5f7..43d63924e0 100644 --- a/openair2/COMMON/e1ap_messages_types.h +++ b/openair2/COMMON/e1ap_messages_types.h @@ -51,6 +51,7 @@ #define E1AP_BEARER_CONTEXT_MODIFICATION_RESP(mSGpTR) (mSGpTR)->ittiMsg.e1ap_bearer_modif_resp #define E1AP_BEARER_CONTEXT_RELEASE_CMD(mSGpTR) (mSGpTR)->ittiMsg.e1ap_bearer_release_cmd #define E1AP_BEARER_CONTEXT_RELEASE_CPLT(mSGpTR) (mSGpTR)->ittiMsg.e1ap_bearer_release_cplt +#define E1AP_LOST_CONNECTION(mSGpTR) (mSGpTR)->ittiMsg.e1ap_lost_connection typedef net_ip_address_t e1ap_net_ip_address_t; @@ -279,4 +280,10 @@ typedef struct e1ap_bearer_modif_resp_s { pdu_session_modif_t pduSessionMod[E1AP_MAX_NUM_PDU_SESSIONS]; } e1ap_bearer_modif_resp_t; +/* E1AP Connection Loss indication */ +typedef struct e1ap_lost_connection_t { + int dummy; +} e1ap_lost_connection_t; + + #endif /* E1AP_MESSAGES_TYPES_H */ diff --git a/openair2/E1AP/e1ap.c b/openair2/E1AP/e1ap.c index 662a3af6e1..6ceb6b8b6c 100644 --- a/openair2/E1AP/e1ap.c +++ b/openair2/E1AP/e1ap.c @@ -1774,6 +1774,16 @@ static void e1_task_handle_sctp_association_resp(E1_t type, instance_t instance, { DevAssert(sctp_new_association_resp != NULL); getCxtE1(instance)->sockState = sctp_new_association_resp->sctp_state; + + if (sctp_new_association_resp->sctp_state == SCTP_STATE_SHUTDOWN) { + LOG_I(E1AP, "Received SCTP shutdown for assoc_id %d, removing CUCP endpoint\n", sctp_new_association_resp->assoc_id); + /* inform RRC that the CU-UP is gone */ + MessageDef *message_p = itti_alloc_new_message(TASK_CUCP_E1, 0, E1AP_LOST_CONNECTION); + message_p->ittiMsgHeader.originInstance = sctp_new_association_resp->assoc_id; + itti_send_msg_to_task(TASK_RRC_GNB, instance, message_p); + return; + } + if (sctp_new_association_resp->sctp_state != SCTP_STATE_ESTABLISHED) { LOG_W(E1AP, "Received unsuccessful result for SCTP association (%u), instance %ld, cnx_id %u\n", sctp_new_association_resp->sctp_state, diff --git a/openair2/RRC/NR/nr_rrc_proto.h b/openair2/RRC/NR/nr_rrc_proto.h index a1342a33f9..45cb2d3439 100644 --- a/openair2/RRC/NR/nr_rrc_proto.h +++ b/openair2/RRC/NR/nr_rrc_proto.h @@ -129,6 +129,9 @@ sctp_assoc_t get_existing_cuup_for_ue(const gNB_RRC_INST *rrc, const gNB_RRC_UE_ sctp_assoc_t get_new_cuup_for_ue(const gNB_RRC_INST *rrc, const gNB_RRC_UE_t *ue, int sst, int sd); int rrc_gNB_process_e1_setup_req(sctp_assoc_t assoc_id, e1ap_setup_req_t *req); +/* Process indication of E1 connection loss on CU-CP */ +void rrc_gNB_process_e1_lost_connection(gNB_RRC_INST *rrc, e1ap_lost_connection_t *lc, sctp_assoc_t assoc_id); + void bearer_context_setup_direct(e1ap_bearer_setup_req_t *req, instance_t instance); diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index f6486c0032..6388665b74 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -2476,6 +2476,10 @@ void *rrc_gnb_task(void *args_p) { rrc_gNB_process_e1_bearer_context_release_cplt(&E1AP_BEARER_CONTEXT_RELEASE_CPLT(msg_p)); break; + case E1AP_LOST_CONNECTION: /* CUCP */ + rrc_gNB_process_e1_lost_connection(RC.nrrrc[0], &E1AP_LOST_CONNECTION(msg_p), msg_p->ittiMsgHeader.originInstance); + break; + case NGAP_PAGING_IND: rrc_gNB_process_PAGING_IND(msg_p, instance); break; diff --git a/openair2/RRC/NR/rrc_gNB_cuup.c b/openair2/RRC/NR/rrc_gNB_cuup.c index 4ed1886e75..9c4aa05dc0 100644 --- a/openair2/RRC/NR/rrc_gNB_cuup.c +++ b/openair2/RRC/NR/rrc_gNB_cuup.c @@ -189,3 +189,28 @@ int rrc_gNB_process_e1_setup_req(sctp_assoc_t assoc_id, e1ap_setup_req_t *req) return 0; } + +/** + * @brief RRC Processing of the indication of E1 connection loss on CU-CP +*/ +void rrc_gNB_process_e1_lost_connection(gNB_RRC_INST *rrc, e1ap_lost_connection_t *lc, sctp_assoc_t assoc_id) +{ + LOG_I(NR_RRC, "Received E1 connection loss indication on RRC\n"); + AssertFatal(assoc_id != 0, "illegal assoc_id == 0: should be -1 (monolithic) or >0 (split)\n"); + nr_rrc_cuup_container_t e = {.assoc_id = assoc_id}; + nr_rrc_cuup_container_t *cuup = RB_FIND(rrc_cuup_tree, &rrc->cuups, &e); + if (cuup == NULL) { + LOG_W(NR_RRC, "CU-UP for assoc_id %d not found!\n", assoc_id); + return; + } + if (cuup->setup_req != NULL) { + e1ap_setup_req_t *req = cuup->setup_req; + LOG_I(NR_RRC, "releasing CU-UP %s on assoc_id %d\n", req->gNB_cu_up_name, assoc_id); + free(cuup->setup_req); + } + nr_rrc_cuup_container_t *removed = RB_REMOVE(rrc_cuup_tree, &rrc->cuups, cuup); + // Free relevant CU-UP structures + free(cuup); + DevAssert(removed != NULL); + rrc->num_cuups--; +}