From 4e667929b766f871eaedbd2d6c62ed625c81b331 Mon Sep 17 00:00:00 2001 From: matzakos Date: Tue, 31 Aug 2021 11:18:30 +0200 Subject: [PATCH] Add gtp-u tunnel creation at the CU side - Change some elements names inside create_tunnel structure so that they are more generic to capture both N3 and F1-U use cases --- openair2/COMMON/gtpv1_u_messages_types.h | 7 +++-- openair2/LAYER2/PDCP_v10.1.0/pdcp.h | 15 +++++++++++ openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c | 19 +++++++++++++ openair2/RRC/NR/nr_rrc_defs.h | 2 ++ openair2/RRC/NR/rrc_gNB.c | 33 +++++++++++++++++++---- openair2/RRC/NR/rrc_gNB_NGAP.c | 16 +++++------ openair3/GTPV1-U/gtpv1u_gNB.c | 24 ++++++++--------- openair3/ocp-gtpu/gtp_itf.cpp | 7 ++--- 8 files changed, 93 insertions(+), 30 deletions(-) diff --git a/openair2/COMMON/gtpv1_u_messages_types.h b/openair2/COMMON/gtpv1_u_messages_types.h index 3c82076510..1dff6b89cb 100644 --- a/openair2/COMMON/gtpv1_u_messages_types.h +++ b/openair2/COMMON/gtpv1_u_messages_types.h @@ -189,10 +189,13 @@ typedef struct { typedef struct gtpv1u_gnb_create_tunnel_req_s { rnti_t rnti; int num_tunnels; - teid_t upf_NGu_teid[NR_GTPV1U_MAX_BEARERS_PER_UE]; ///< Tunnel Endpoint Identifier + //teid_t upf_NGu_teid[NR_GTPV1U_MAX_BEARERS_PER_UE]; ///< Tunnel Endpoint Identifier + teid_t outgoing_teid[NR_GTPV1U_MAX_BEARERS_PER_UE]; pdusessionid_t pdusession_id[NR_GTPV1U_MAX_BEARERS_PER_UE]; ebi_t incoming_rb_id[NR_GTPV1U_MAX_BEARERS_PER_UE]; - transport_layer_addr_t upf_addr[NR_GTPV1U_MAX_BEARERS_PER_UE]; + //ebi_t outgoing_rb_id[NR_GTPV1U_MAX_BEARERS_PER_UE]; + //transport_layer_addr_t upf_addr[NR_GTPV1U_MAX_BEARERS_PER_UE]; + transport_layer_addr_t dst_addr[NR_GTPV1U_MAX_BEARERS_PER_UE]; } gtpv1u_gnb_create_tunnel_req_t; typedef struct gtpv1u_gnb_create_tunnel_resp_s { diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp.h b/openair2/LAYER2/PDCP_v10.1.0/pdcp.h index 0c3dd2f04f..94d19e9c01 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp.h +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp.h @@ -256,6 +256,21 @@ boolean_t pdcp_data_req( const uint32_t * destinationL2Id ); +boolean_t cu_f1u_data_req( + protocol_ctxt_t *ctxt_pP, + const srb_flag_t srb_flagP, + const rb_id_t rb_id, + const mui_t muiP, + const confirm_t confirmP, + const sdu_size_t sdu_buffer_size, + unsigned char *const sdu_buffer, + const pdcp_transmission_mode_t mode +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + ,const uint32_t *const sourceL2Id + ,const uint32_t *const destinationL2Id +#endif + ); + /*! \fn boolean_t pdcp_data_ind(const protocol_ctxt_t* const, srb_flag_t, MBMS_flag_t, rb_id_t, sdu_size_t, mem_block_t*, boolean_t) * \brief This functions handles data transfer indications coming from RLC * \param[in] ctxt_pP Running context. diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c index e62d79e23b..9f3f3370d4 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c @@ -1212,6 +1212,25 @@ static boolean_t pdcp_data_req_drb( return 1; } +boolean_t cu_f1u_data_req( + protocol_ctxt_t *ctxt_pP, + const srb_flag_t srb_flagP, + const rb_id_t rb_id, + const mui_t muiP, + const confirm_t confirmP, + const sdu_size_t sdu_buffer_size, + unsigned char *const sdu_buffer, + const pdcp_transmission_mode_t mode +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + ,const uint32_t *const sourceL2Id + ,const uint32_t *const destinationL2Id +#endif + ) +{ + LOG_E(PDCP, "Implementation is pending"); + return true; +} + boolean_t pdcp_data_req( protocol_ctxt_t *ctxt_pP, const srb_flag_t srb_flagP, diff --git a/openair2/RRC/NR/nr_rrc_defs.h b/openair2/RRC/NR/nr_rrc_defs.h index b92b5defe6..4f1f5783c7 100644 --- a/openair2/RRC/NR/nr_rrc_defs.h +++ b/openair2/RRC/NR/nr_rrc_defs.h @@ -367,6 +367,8 @@ typedef struct gNB_RRC_UE_s { transport_layer_addr_t gnb_gtp_addrs[S1AP_MAX_E_RAB]; rb_id_t gnb_gtp_ebi[S1AP_MAX_E_RAB]; rb_id_t gnb_gtp_psi[S1AP_MAX_E_RAB]; + //GTPV1 F1-U TUNNELS + uint32_t incoming_teid[S1AP_MAX_E_RAB]; uint32_t ul_failure_timer; uint32_t ue_release_timer; diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index 3793e59dbe..88ff49de3b 100755 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -1346,17 +1346,40 @@ rrc_gNB_process_RRCReconfigurationComplete( /*gtpv1u_gnb_create_tunnel_req_t create_tunnel_req; gtpv1u_gnb_create_tunnel_resp_t create_tunnel_resp; memset(&create_tunnel_req, 0, sizeof(gtpv1u_gnb_create_tunnel_req_t)); - create_tunnel_req.upf_NGu_teid[0] = 1;*/ + create_tunnel_req.outgoing_teid[0] = 1;*/ if(DRB_configList!=NULL){ + + gtpv1u_gnb_create_tunnel_req_t create_tunnel_req; + teid_t incoming_teid; MessageDef *message_p; message_p = itti_alloc_new_message (TASK_RRC_GNB, 0, F1AP_UE_CONTEXT_SETUP_REQ); F1AP_UE_CONTEXT_SETUP_REQ (message_p).drbs_to_be_setup = malloc(DRB_configList->list.count*sizeof(f1ap_drb_to_be_setup_t)); F1AP_UE_CONTEXT_SETUP_REQ (message_p).drbs_to_be_setup_length = DRB_configList->list.count; LOG_I(RRC, "Length of DRB list:%d, %d \n", DRB_configList->list.count, F1AP_UE_CONTEXT_SETUP_REQ (message_p).drbs_to_be_setup_length); for (int i = 0; i < DRB_configList->list.count; i++){ + memset(&create_tunnel_req, 0, sizeof(gtpv1u_gnb_create_tunnel_req_t)); + //Use a dummy teid for the outgoing GTP-U tunnel (DU) which will be updated once we get the UE context setup response from the DU + //create_tunnel_req.outgoing_teid[i] = 0xFFFF; + create_tunnel_req.outgoing_teid[i] = 0xFFFF; + create_tunnel_req.rnti = ue_context_pP->ue_context.rnti; + memcpy(create_tunnel_req.dst_addr[i].buffer,rrc->eth_params_s.remote_addr,4); + //create_tunnel_req.dst_addr[i].length = 32; + create_tunnel_req.dst_addr[i].length = 32; + create_tunnel_req.incoming_rb_id[i] = DRB_configList->list.array[i]->drb_Identity; + //create_tunnel_req.outgoing_rb_id[i] = DRB_configList->list.array[i]->drb_Identity; + + /* Here the callback function used as input is not the right one. Need to create a new one probably for F1-U, not sure + * if the kind of input parameters to the callback function are convenient though for gtp-u over F1-U.*/ + incoming_teid=newGtpuCreateTunnel(0, create_tunnel_req.rnti, + create_tunnel_req.incoming_rb_id[i], + create_tunnel_req.incoming_rb_id[i], + create_tunnel_req.outgoing_teid[i], + create_tunnel_req.dst_addr[i], 2152, + cu_f1u_data_req); + F1AP_UE_CONTEXT_SETUP_REQ (message_p).drbs_to_be_setup[i].drb_id = DRB_configList->list.array[i]->drb_Identity; F1AP_UE_CONTEXT_SETUP_REQ (message_p).drbs_to_be_setup[i].rlc_mode = RLC_MODE_AM; - F1AP_UE_CONTEXT_SETUP_REQ (message_p).drbs_to_be_setup[i].up_ul_tnl[0].gtp_teid = 1; + F1AP_UE_CONTEXT_SETUP_REQ (message_p).drbs_to_be_setup[i].up_ul_tnl[0].gtp_teid = incoming_teid; memcpy(&F1AP_UE_CONTEXT_SETUP_REQ (message_p).drbs_to_be_setup[i].up_ul_tnl[0].tl_address,rrc->eth_params_s.my_addr,4); F1AP_UE_CONTEXT_SETUP_REQ (message_p).drbs_to_be_setup[i].up_ul_tnl_length = 1; } @@ -1680,11 +1703,11 @@ rrc_gNB_process_RRCConnectionReestablishmentComplete( if (ue_context_pP->ue_context.pduSession[i].status == PDU_SESSION_STATUS_ESTABLISHED || ue_context_pP->ue_context.pduSession[i].status == PDU_SESSION_STATUS_DONE) { create_tunnel_req.pdusession_id[j] = ue_context_pP->ue_context.pduSession[i].param.pdusession_id; create_tunnel_req.incoming_rb_id[j] = i+1; - create_tunnel_req.upf_NGu_teid[j] = ue_context_pP->ue_context.pduSession[i].param.gtp_teid; - memcpy(create_tunnel_req.upf_addr[j].buffer, + create_tunnel_req.outgoing_teid[j] = ue_context_pP->ue_context.pduSession[i].param.gtp_teid; + memcpy(create_tunnel_req.dst_addr[j].buffer, ue_context_pP->ue_context.pduSession[i].param.upf_addr.buffer, sizeof(uint8_t)*20); - create_tunnel_req.upf_addr[j].length = ue_context_pP->ue_context.pduSession[i].param.upf_addr.length; + create_tunnel_req.dst_addr[j].length = ue_context_pP->ue_context.pduSession[i].param.upf_addr.length; j++; } } diff --git a/openair2/RRC/NR/rrc_gNB_NGAP.c b/openair2/RRC/NR/rrc_gNB_NGAP.c index 49145515a1..e8e5055cfe 100644 --- a/openair2/RRC/NR/rrc_gNB_NGAP.c +++ b/openair2/RRC/NR/rrc_gNB_NGAP.c @@ -541,14 +541,14 @@ rrc_gNB_process_NGAP_INITIAL_CONTEXT_SETUP_REQ( ue_context_p->ue_context.pduSession[i].param = NGAP_INITIAL_CONTEXT_SETUP_REQ (msg_p).pdusession_param[pdu_sessions_done]; create_tunnel_req.pdusession_id[pdu_sessions_done] = NGAP_INITIAL_CONTEXT_SETUP_REQ (msg_p).pdusession_param[pdu_sessions_done].pdusession_id; create_tunnel_req.incoming_rb_id[pdu_sessions_done] = i+1; - create_tunnel_req.upf_NGu_teid[pdu_sessions_done] = NGAP_INITIAL_CONTEXT_SETUP_REQ (msg_p).pdusession_param[pdu_sessions_done].gtp_teid; - create_tunnel_req.upf_addr[pdu_sessions_done].length = NGAP_INITIAL_CONTEXT_SETUP_REQ (msg_p).pdusession_param[pdu_sessions_done].upf_addr.length; - memcpy(create_tunnel_req.upf_addr[pdu_sessions_done].buffer, + create_tunnel_req.outgoing_teid[pdu_sessions_done] = NGAP_INITIAL_CONTEXT_SETUP_REQ (msg_p).pdusession_param[pdu_sessions_done].gtp_teid; + create_tunnel_req.dst_addr[pdu_sessions_done].length = NGAP_INITIAL_CONTEXT_SETUP_REQ (msg_p).pdusession_param[pdu_sessions_done].upf_addr.length; + memcpy(create_tunnel_req.dst_addr[pdu_sessions_done].buffer, NGAP_INITIAL_CONTEXT_SETUP_REQ (msg_p).pdusession_param[pdu_sessions_done].upf_addr.buffer, sizeof(uint8_t)*20); LOG_I(NR_RRC, "PDUSESSION SETUP: local index %d teid %u, pdusession id %d \n", i, - create_tunnel_req.upf_NGu_teid[pdu_sessions_done], + create_tunnel_req.outgoing_teid[pdu_sessions_done], create_tunnel_req.pdusession_id[pdu_sessions_done]); inde_list[pdu_sessions_done] = i; pdu_sessions_done++; @@ -1064,14 +1064,14 @@ rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ( ue_context_p->ue_context.pduSession[i].param = NGAP_PDUSESSION_SETUP_REQ(msg_p).pdusession_setup_params[pdu_sessions_done]; create_tunnel_req.pdusession_id[pdu_sessions_done] = NGAP_PDUSESSION_SETUP_REQ(msg_p).pdusession_setup_params[pdu_sessions_done].pdusession_id; create_tunnel_req.incoming_rb_id[pdu_sessions_done]= i+1; - create_tunnel_req.upf_NGu_teid[pdu_sessions_done] = NGAP_PDUSESSION_SETUP_REQ(msg_p).pdusession_setup_params[pdu_sessions_done].gtp_teid; - memcpy(create_tunnel_req.upf_addr[pdu_sessions_done].buffer, + create_tunnel_req.outgoing_teid[pdu_sessions_done] = NGAP_PDUSESSION_SETUP_REQ(msg_p).pdusession_setup_params[pdu_sessions_done].gtp_teid; + memcpy(create_tunnel_req.dst_addr[pdu_sessions_done].buffer, NGAP_PDUSESSION_SETUP_REQ(msg_p).pdusession_setup_params[pdu_sessions_done].upf_addr.buffer, sizeof(uint8_t)*20); - create_tunnel_req.upf_addr[pdu_sessions_done].length = NGAP_PDUSESSION_SETUP_REQ(msg_p).pdusession_setup_params[pdu_sessions_done].upf_addr.length; + create_tunnel_req.dst_addr[pdu_sessions_done].length = NGAP_PDUSESSION_SETUP_REQ(msg_p).pdusession_setup_params[pdu_sessions_done].upf_addr.length; LOG_I(NR_RRC,"NGAP PDUSESSION SETUP REQ: local index %d teid %u, pdusession id %d \n", i, - create_tunnel_req.upf_NGu_teid[pdu_sessions_done], + create_tunnel_req.outgoing_teid[pdu_sessions_done], create_tunnel_req.pdusession_id[pdu_sessions_done]); inde_list[pdu_sessions_done] = i; pdu_sessions_done++; diff --git a/openair3/GTPV1-U/gtpv1u_gNB.c b/openair3/GTPV1-U/gtpv1u_gNB.c index d3f26aeff1..ea6902f5be 100644 --- a/openair3/GTPV1-U/gtpv1u_gNB.c +++ b/openair3/GTPV1-U/gtpv1u_gNB.c @@ -528,7 +528,7 @@ gtpv1u_create_ngu_tunnel( MSC_AS_TIME_FMT" CREATE_TUNNEL_REQ RNTI %"PRIx16" inst %u ntuns %u psid %u upf-ngu teid %u", 0,0,create_tunnel_req_pP->rnti, instanceP, create_tunnel_req_pP->num_tunnels, create_tunnel_req_pP->pdusession_id[0], - create_tunnel_req_pP->upf_NGu_teid[0]); + create_tunnel_req_pP->outgoing_teid[0]); create_tunnel_resp_pP->rnti = create_tunnel_req_pP->rnti; create_tunnel_resp_pP->status = 0; create_tunnel_resp_pP->num_tunnels = 0; @@ -579,16 +579,16 @@ gtpv1u_create_ngu_tunnel( LOG_I(GTPU,"Configured GTPu address : %x\n",RC.nr_gtpv1u_data_g->gnb_ip_address_for_NGu_up); create_tunnel_resp_pP->gnb_addr.length = sizeof (in_addr_t); - addrs_length_in_bytes = create_tunnel_req_pP->upf_addr[i].length / 8; + addrs_length_in_bytes = create_tunnel_req_pP->dst_addr[i].length / 8; AssertFatal((addrs_length_in_bytes == 4) || (addrs_length_in_bytes == 16) || (addrs_length_in_bytes == 20), "Bad transport layer address length %d (bits) %d (bytes)", - create_tunnel_req_pP->upf_addr[i].length, addrs_length_in_bytes); + create_tunnel_req_pP->dst_addr[i].length, addrs_length_in_bytes); if ((addrs_length_in_bytes == 4) || (addrs_length_in_bytes == 20)) { - in_addr = *((in_addr_t *)create_tunnel_req_pP->upf_addr[i].buffer); + in_addr = *((in_addr_t *)create_tunnel_req_pP->dst_addr[i].buffer); ip_offset = 4; gtpv1u_ue_data_p->bearers[pdusession_id - GTPV1U_BEARER_OFFSET].upf_ip_addr = in_addr; } @@ -596,7 +596,7 @@ gtpv1u_create_ngu_tunnel( if ((addrs_length_in_bytes == 16) || (addrs_length_in_bytes == 20)) { memcpy(gtpv1u_ue_data_p->bearers[pdusession_id - GTPV1U_BEARER_OFFSET].upf_ip6_addr.s6_addr, - &create_tunnel_req_pP->upf_addr[i].buffer[ip_offset], + &create_tunnel_req_pP->dst_addr[i].buffer[ip_offset], 16); } @@ -861,7 +861,7 @@ static int gtpv1u_gnb_tunnel_data_req(gtpv1u_gnb_tunnel_data_req_t *gnb_tunnel_d hashtable_rc_t hash_rc = HASH_TABLE_KEY_NOT_EXISTS; nr_gtpv1u_ue_data_t *gtpv1u_ue_data_p = NULL; teid_t gnb_ngu_teid = 0; - teid_t upf_ngu_teid = 0; + teid_t outgoing_teid = 0; VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_GTPV1U_PROCESS_TUNNEL_DATA_REQ, VCD_FUNCTION_IN); data_req_p = gnb_tunnel_data_req; @@ -873,13 +873,13 @@ static int gtpv1u_gnb_tunnel_data_req(gtpv1u_gnb_tunnel_data_req_t *gnb_tunnel_d } else { if ((data_req_p->pdusession_id >= GTPV1U_BEARER_OFFSET) && (data_req_p->pdusession_id < max_val_NR_DRB_Identity)) { gnb_ngu_teid = gtpv1u_ue_data_p->bearers[data_req_p->pdusession_id - GTPV1U_BEARER_OFFSET].teid_gNB; - upf_ngu_teid = gtpv1u_ue_data_p->bearers[data_req_p->pdusession_id - GTPV1U_BEARER_OFFSET].teid_upf; + outgoing_teid = gtpv1u_ue_data_p->bearers[data_req_p->pdusession_id - GTPV1U_BEARER_OFFSET].teid_upf; stack_req.apiType = NW_GTPV1U_ULP_API_SEND_TPDU; - stack_req.apiInfo.sendtoInfo.teid = upf_ngu_teid; + stack_req.apiInfo.sendtoInfo.teid = outgoing_teid; stack_req.apiInfo.sendtoInfo.ipAddr = gtpv1u_ue_data_p->bearers[data_req_p->pdusession_id - GTPV1U_BEARER_OFFSET].upf_ip_addr; rc = nwGtpv1uGpduMsgNew( RC.nr_gtpv1u_data_g->gtpv1u_stack, - upf_ngu_teid, + outgoing_teid, NW_FALSE, RC.nr_gtpv1u_data_g->seq_num++, data_req_p->buffer, @@ -890,7 +890,7 @@ static int gtpv1u_gnb_tunnel_data_req(gtpv1u_gnb_tunnel_data_req_t *gnb_tunnel_d if (rc != NW_GTPV1U_OK) { LOG_E(GTPU, "nwGtpv1uGpduMsgNew failed: 0x%x\n", rc); MSC_LOG_EVENT(MSC_GTPU_GNB,"0 Failed send G-PDU ltid %u rtid %u size %u", - gnb_ngu_teid,upf_ngu_teid,data_req_p->length); + gnb_ngu_teid,outgoing_teid,data_req_p->length); (void)gnb_ngu_teid; /* avoid gcc warning "set but not used" */ } else { rc = nwGtpv1uProcessUlpReq(RC.nr_gtpv1u_data_g->gtpv1u_stack, &stack_req); @@ -898,7 +898,7 @@ static int gtpv1u_gnb_tunnel_data_req(gtpv1u_gnb_tunnel_data_req_t *gnb_tunnel_d if (rc != NW_GTPV1U_OK) { LOG_E(GTPU, "nwGtpv1uProcessUlpReq failed: 0x%x\n", rc); MSC_LOG_EVENT(MSC_GTPU_GNB,"0 Failed send G-PDU ltid %u rtid %u size %u", - gnb_ngu_teid,upf_ngu_teid,data_req_p->length); + gnb_ngu_teid,outgoing_teid,data_req_p->length); } else { MSC_LOG_TX_MESSAGE( MSC_GTPU_GNB, @@ -908,7 +908,7 @@ static int gtpv1u_gnb_tunnel_data_req(gtpv1u_gnb_tunnel_data_req_t *gnb_tunnel_d MSC_AS_TIME_FMT" G-PDU ltid %u rtid %u size %u", 0,0, gnb_ngu_teid, - upf_ngu_teid, + outgoing_teid, data_req_p->length); } diff --git a/openair3/ocp-gtpu/gtp_itf.cpp b/openair3/ocp-gtpu/gtp_itf.cpp index 25d3d7489d..7d039e15a9 100644 --- a/openair3/ocp-gtpu/gtp_itf.cpp +++ b/openair3/ocp-gtpu/gtp_itf.cpp @@ -404,6 +404,7 @@ teid_t newGtpuCreateTunnel(instance_t instance, rnti_t rnti, int incoming_bearer LOG_W(GTPU, "generated a random Teid that exists, re-generating (%x)\n",incoming_teid); incoming_teid=gtpv1uNewTeid(); }; + LOG_I (GTPU, "Allocated incoming teid: %d \n", incoming_teid); inst->te2ue_mapping[incoming_teid].rnti=rnti; @@ -524,14 +525,14 @@ int gtpv1u_create_ngu_tunnel( const instance_t instance, LOG_D(GTPU, "Start create tunnels for RNTI %x, num_tunnels %d, sgw_S1u_teid %x\n", create_tunnel_req->rnti, create_tunnel_req->num_tunnels, - create_tunnel_req->upf_NGu_teid[0]); + create_tunnel_req->outgoing_teid[0]); for (int i = 0; i < create_tunnel_req->num_tunnels; i++) { teid_t teid=newGtpuCreateTunnel(compatInst(instance), create_tunnel_req->rnti, create_tunnel_req->incoming_rb_id[i], create_tunnel_req->pdusession_id[i], - create_tunnel_req->upf_NGu_teid[i], - create_tunnel_req->upf_addr[i], 2152, + create_tunnel_req->outgoing_teid[i], + create_tunnel_req->dst_addr[i], 2152, pdcp_data_req); create_tunnel_resp->status=0; create_tunnel_resp->rnti=create_tunnel_req->rnti;