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.
This commit is contained in:
committed by
Robert Schmidt
parent
46e27ba445
commit
7340abc6f4
@@ -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);
|
||||
|
||||
|
||||
+17
-69
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user