Commit 7340abc6 authored by Giulio Carota's avatar Giulio Carota Committed by Robert Schmidt

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.
parent 46e27ba4
...@@ -80,13 +80,7 @@ int generate_CG_Config(gNB_RRC_INST *rrc, ...@@ -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); int parse_CG_ConfigInfo(gNB_RRC_INST *rrc, NR_CG_ConfigInfo_t *CG_ConfigInfo, x2ap_ENDC_sgnb_addition_req_t *m);
void void rrc_gNB_generate_SecurityModeCommand(const protocol_ctxt_t *const ctxt_pP, rrc_gNB_ue_context_t *const ue_context_pP);
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
);
unsigned int rrc_gNB_get_next_transaction_identifier(module_id_t gnb_mod_idP); unsigned int rrc_gNB_get_next_transaction_identifier(module_id_t gnb_mod_idP);
......
...@@ -2105,11 +2105,9 @@ void rrc_gNB_process_e1_bearer_context_setup_resp(e1ap_bearer_setup_resp_t *resp ...@@ -2105,11 +2105,9 @@ void rrc_gNB_process_e1_bearer_context_setup_resp(e1ap_bearer_setup_resp_t *resp
} }
if (!UE->as_security_active) { if (!UE->as_security_active) {
/* no AS security active, need to send UE context setup req with security /* no AS security active, need to activate security before data*/
* command (and the bearers) */
protocol_ctxt_t ctxt = {.rntiMaybeUEid = UE->rrc_ue_id}; protocol_ctxt_t ctxt = {.rntiMaybeUEid = UE->rrc_ue_id};
rrc_gNB_generate_SecurityModeCommand(&ctxt, ue_context_p, nb_drb, drbs); rrc_gNB_generate_SecurityModeCommand(&ctxt, ue_context_p);
return;
} }
/* Gather UE capability if present */ /* Gather UE capability if present */
...@@ -2470,28 +2468,8 @@ void *rrc_gnb_task(void *args_p) { ...@@ -2470,28 +2468,8 @@ 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 void rrc_gNB_generate_SecurityModeCommand(const protocol_ctxt_t *const ctxt_pP, rrc_gNB_ue_context_t *const ue_context_pP)
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
)
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
{ {
uint8_t buffer[100]; uint8_t buffer[100];
...@@ -2499,52 +2477,22 @@ rrc_gNB_generate_SecurityModeCommand( ...@@ -2499,52 +2477,22 @@ rrc_gNB_generate_SecurityModeCommand(
gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context; gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context;
AssertFatal(!ue_p->as_security_active, "logic error: security already active\n"); 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; 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); size = do_NR_SecurityModeCommand(ctxt_pP,
LOG_DUMPMSG(NR_RRC,DEBUG_RRC,(char *)buffer,size,"[MSG] RRC Security Mode Command\n"); 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); 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]; gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id];
AssertFatal(!NODE_IS_DU(rrc->node_type), "illegal node type DU!\n"); nr_rrc_transfer_protected_rrc_message(rrc, ue_p, DCCH, buffer, size);
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);
} }
void void
......
...@@ -494,9 +494,10 @@ int rrc_gNB_process_NGAP_INITIAL_CONTEXT_SETUP_REQ(MessageDef *msg_p, instance_t ...@@ -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); nr_rrc_pdcp_config_security(&ctxt, ue_context_p, 0);
uint8_t nb_pdusessions_tosetup = req->nb_of_pdusessions; uint8_t nb_pdusessions_tosetup = req->nb_of_pdusessions;
/* if there are PDU sessions to setup, first send them to the CU-UP, then /* if there are PDU sessions to setup, first send them to the CU-UP.
* send the UE Context setup with Security commend. Else go to the security * Once the E1 bearer are activated, the CUCP will trigger the context
* command directly. */ * setup. */
AssertFatal(nb_pdusessions_tosetup == 0, "no UE context setup request, so can't setup PDU sessions\n");
if (nb_pdusessions_tosetup > 0) { if (nb_pdusessions_tosetup > 0) {
trigger_bearer_setup(RC.nrrrc[instance], trigger_bearer_setup(RC.nrrrc[instance],
UE, UE,
...@@ -504,7 +505,7 @@ int rrc_gNB_process_NGAP_INITIAL_CONTEXT_SETUP_REQ(MessageDef *msg_p, instance_t ...@@ -504,7 +505,7 @@ int rrc_gNB_process_NGAP_INITIAL_CONTEXT_SETUP_REQ(MessageDef *msg_p, instance_t
req->pdusession_param, req->pdusession_param,
/*req->ueAggMaxBitRateDownlink*/ 0); /*req->ueAggMaxBitRateDownlink*/ 0);
} else { } else {
rrc_gNB_generate_SecurityModeCommand(&ctxt, ue_context_p, 0, NULL); rrc_gNB_generate_SecurityModeCommand(&ctxt, ue_context_p);
} }
return 0; return 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment