From 7340abc6f4e6649ff0de7b1a720cd0f724301dde Mon Sep 17 00:00:00 2001 From: Giulio Carota Date: Fri, 1 Mar 2024 14:39:10 +0100 Subject: [PATCH] Refactor Security Mode Command procedure: send in RRC DL transfer Previously, the CU sent the Security Mode Command as part of a UE context setup request. This was done "because it was possible", not because there was an inherent need to do this. However the LiteOn DU does not like this, as it expects to also have a DRB in the UE context setup request procedure, which is not always the case. Hence, send the Security Mode Command in a normal DL RRC msg transfer over F1. As of this commit, there is not UE context Setup Request (so it might not work with all DUs), but the OAI DU is cool and does not care, so RFsim still works. This also aligns the CU's behavior with O-RAN.WG5.C.1-v11. Finally, as of this commit, we do not trigger a UE context setup request, so we cannot handle PDU sessions inside the initial UE context setup request at the same time as the security mode command (which was done previously before reaching this point). This will be fixed in a later commit. --- openair2/RRC/NR/nr_rrc_proto.h | 8 +--- openair2/RRC/NR/rrc_gNB.c | 86 +++++++--------------------------- openair2/RRC/NR/rrc_gNB_NGAP.c | 9 ++-- 3 files changed, 23 insertions(+), 80 deletions(-) diff --git a/openair2/RRC/NR/nr_rrc_proto.h b/openair2/RRC/NR/nr_rrc_proto.h index 990c714bda..0bb66d314e 100644 --- a/openair2/RRC/NR/nr_rrc_proto.h +++ b/openair2/RRC/NR/nr_rrc_proto.h @@ -80,13 +80,7 @@ int generate_CG_Config(gNB_RRC_INST *rrc, int parse_CG_ConfigInfo(gNB_RRC_INST *rrc, NR_CG_ConfigInfo_t *CG_ConfigInfo, x2ap_ENDC_sgnb_addition_req_t *m); -void -rrc_gNB_generate_SecurityModeCommand( - const protocol_ctxt_t *const ctxt_pP, - rrc_gNB_ue_context_t *const ue_context_pP, - int n_drbs, - const f1ap_drb_to_be_setup_t *drbs -); +void rrc_gNB_generate_SecurityModeCommand(const protocol_ctxt_t *const ctxt_pP, rrc_gNB_ue_context_t *const ue_context_pP); unsigned int rrc_gNB_get_next_transaction_identifier(module_id_t gnb_mod_idP); diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index ae49f9000b..18d4fb6db5 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -2105,11 +2105,9 @@ void rrc_gNB_process_e1_bearer_context_setup_resp(e1ap_bearer_setup_resp_t *resp } if (!UE->as_security_active) { - /* no AS security active, need to send UE context setup req with security - * command (and the bearers) */ + /* no AS security active, need to activate security before data*/ protocol_ctxt_t ctxt = {.rntiMaybeUEid = UE->rrc_ue_id}; - rrc_gNB_generate_SecurityModeCommand(&ctxt, ue_context_p, nb_drb, drbs); - return; + rrc_gNB_generate_SecurityModeCommand(&ctxt, ue_context_p); } /* Gather UE capability if present */ @@ -2470,81 +2468,31 @@ void *rrc_gnb_task(void *args_p) { } } -typedef struct deliver_ue_ctxt_setup_data_t { - gNB_RRC_INST *rrc; - f1ap_ue_context_setup_t *setup_req; - sctp_assoc_t assoc_id; -} deliver_ue_ctxt_setup_data_t; -static void rrc_deliver_ue_ctxt_setup_req(void *deliver_pdu_data, ue_id_t ue_id, int srb_id, char *buf, int size, int sdu_id) -{ - DevAssert(deliver_pdu_data != NULL); - deliver_ue_ctxt_setup_data_t *data = deliver_pdu_data; - data->setup_req->rrc_container = (uint8_t*)buf; - data->setup_req->rrc_container_length = size; - data->rrc->mac_rrc.ue_context_setup_request(data->assoc_id, data->setup_req); -} - //----------------------------------------------------------------------------- -void -rrc_gNB_generate_SecurityModeCommand( - const protocol_ctxt_t *const ctxt_pP, - rrc_gNB_ue_context_t *const ue_context_pP, - int n_drbs, - const f1ap_drb_to_be_setup_t *drbs -) +void rrc_gNB_generate_SecurityModeCommand(const protocol_ctxt_t *const ctxt_pP, rrc_gNB_ue_context_t *const ue_context_pP) //----------------------------------------------------------------------------- { - uint8_t buffer[100]; - uint8_t size; + uint8_t buffer[100]; + uint8_t size; gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context; AssertFatal(!ue_p->as_security_active, "logic error: security already active\n"); - T(T_ENB_RRC_SECURITY_MODE_COMMAND, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rntiMaybeUEid)); + T(T_ENB_RRC_SECURITY_MODE_COMMAND, + T_INT(ctxt_pP->module_id), + T_INT(ctxt_pP->frame), + T_INT(ctxt_pP->subframe), + T_INT(ctxt_pP->rntiMaybeUEid)); NR_IntegrityProtAlgorithm_t integrity_algorithm = (NR_IntegrityProtAlgorithm_t)ue_p->integrity_algorithm; - size = do_NR_SecurityModeCommand(ctxt_pP, buffer, rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id), ue_p->ciphering_algorithm, integrity_algorithm); - LOG_DUMPMSG(NR_RRC,DEBUG_RRC,(char *)buffer,size,"[MSG] RRC Security Mode Command\n"); + size = do_NR_SecurityModeCommand(ctxt_pP, + buffer, + rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id), + ue_p->ciphering_algorithm, + integrity_algorithm); + LOG_DUMPMSG(NR_RRC, DEBUG_RRC, (char *)buffer, size, "[MSG] RRC Security Mode Command\n"); LOG_I(NR_RRC, "UE %u Logical Channel DL-DCCH, Generate SecurityModeCommand (bytes %d)\n", ue_p->rrc_ue_id, size); gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id]; - AssertFatal(!NODE_IS_DU(rrc->node_type), "illegal node type DU!\n"); - - cu_to_du_rrc_information_t cu2du = {0}; - cu_to_du_rrc_information_t *cu2du_p = NULL; - if (ue_p->ue_cap_buffer.len > 0 && ue_p->ue_cap_buffer.buf != NULL) { - cu2du_p = &cu2du; - cu2du.uE_CapabilityRAT_ContainerList = ue_p->ue_cap_buffer.buf; - cu2du.uE_CapabilityRAT_ContainerList_length = ue_p->ue_cap_buffer.len; - } - - int nb_srb = 0; - f1ap_srb_to_be_setup_t srb_buf[1] = {0}; - f1ap_srb_to_be_setup_t *srbs = 0; - if (n_drbs > 0) { - nb_srb = 1; - srb_buf[0].srb_id = 2; - srb_buf[0].lcid = 2; - srbs = srb_buf; - } - - /* the callback will fill the UE context setup request and forward it */ - f1_ue_data_t ue_data = cu_get_f1_ue_data(ue_p->rrc_ue_id); - RETURN_IF_INVALID_ASSOC_ID(ue_data); - f1ap_ue_context_setup_t ue_context_setup_req = { - .gNB_CU_ue_id = ue_p->rrc_ue_id, - .gNB_DU_ue_id = ue_data.secondary_ue, - .plmn.mcc = rrc->configuration.mcc[0], - .plmn.mnc = rrc->configuration.mnc[0], - .plmn.mnc_digit_length = rrc->configuration.mnc_digit_length[0], - .nr_cellid = rrc->nr_cellid, - .servCellId = 0, /* TODO: correct value? */ - .srbs_to_be_setup_length = nb_srb, - .srbs_to_be_setup = srbs, - .drbs_to_be_setup_length = n_drbs, - .drbs_to_be_setup = (f1ap_drb_to_be_setup_t *) drbs, - .cu_to_du_rrc_information = cu2du_p, - }; - deliver_ue_ctxt_setup_data_t data = {.rrc = rrc, .setup_req = &ue_context_setup_req, .assoc_id = ue_data.du_assoc_id }; - nr_pdcp_data_req_srb(ctxt_pP->rntiMaybeUEid, DCCH, rrc_gNB_mui++, size, buffer, rrc_deliver_ue_ctxt_setup_req, &data); + nr_rrc_transfer_protected_rrc_message(rrc, ue_p, DCCH, buffer, size); } void diff --git a/openair2/RRC/NR/rrc_gNB_NGAP.c b/openair2/RRC/NR/rrc_gNB_NGAP.c index e198ab0748..7c44bd90f6 100644 --- a/openair2/RRC/NR/rrc_gNB_NGAP.c +++ b/openair2/RRC/NR/rrc_gNB_NGAP.c @@ -494,9 +494,10 @@ int rrc_gNB_process_NGAP_INITIAL_CONTEXT_SETUP_REQ(MessageDef *msg_p, instance_t nr_rrc_pdcp_config_security(&ctxt, ue_context_p, 0); uint8_t nb_pdusessions_tosetup = req->nb_of_pdusessions; - /* if there are PDU sessions to setup, first send them to the CU-UP, then - * send the UE Context setup with Security commend. Else go to the security - * command directly. */ + /* if there are PDU sessions to setup, first send them to the CU-UP. + * Once the E1 bearer are activated, the CUCP will trigger the context + * setup. */ + AssertFatal(nb_pdusessions_tosetup == 0, "no UE context setup request, so can't setup PDU sessions\n"); if (nb_pdusessions_tosetup > 0) { trigger_bearer_setup(RC.nrrrc[instance], UE, @@ -504,7 +505,7 @@ int rrc_gNB_process_NGAP_INITIAL_CONTEXT_SETUP_REQ(MessageDef *msg_p, instance_t req->pdusession_param, /*req->ueAggMaxBitRateDownlink*/ 0); } else { - rrc_gNB_generate_SecurityModeCommand(&ctxt, ue_context_p, 0, NULL); + rrc_gNB_generate_SecurityModeCommand(&ctxt, ue_context_p); } return 0;