From 551aee172a0fd0916c666d8bbe9e54491d2335db Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Mon, 9 Jan 2023 10:56:59 +0100 Subject: [PATCH] bugfix CU/DU: use correct IP address for GTP-U Not only the teid is received from the DU but also the IP address. We have to use it too. Also, don't connect the UDP socket. The parameter remote_s_address in the configuration file must not be used, at least not for gtp-u because the IP address is received from the DU (plus for later, for multiple DUs, it won't work at all). --- openair2/F1AP/f1ap_cu_task.c | 8 ++--- openair2/F1AP/f1ap_cu_ue_context_management.c | 30 ++++++++----------- openair3/ocp-gtpu/gtp_itf.cpp | 5 ++-- openair3/ocp-gtpu/gtp_itf.h | 9 +++--- 4 files changed, 24 insertions(+), 28 deletions(-) diff --git a/openair2/F1AP/f1ap_cu_task.c b/openair2/F1AP/f1ap_cu_task.c index b2d2c872d1..b4e0c1ad2a 100644 --- a/openair2/F1AP/f1ap_cu_task.c +++ b/openair2/F1AP/f1ap_cu_task.c @@ -41,12 +41,10 @@ //Fixme: Uniq dirty DU instance, by global var, datamodel need better management instance_t CUuniqInstance=0; -static instance_t cu_task_create_gtpu_instance_to_du(eth_params_t *IPaddrs) { +static instance_t cu_task_create_gtpu_instance(eth_params_t *IPaddrs) { openAddr_t tmp= {0}; strncpy(tmp.originHost, IPaddrs->my_addr, sizeof(tmp.originHost)-1); - strncpy(tmp.destinationHost, IPaddrs->remote_addr, sizeof(tmp.destinationHost)-1); - sprintf(tmp.originService, "%d", IPaddrs->my_portd); - sprintf(tmp.destinationService, "%d", IPaddrs->remote_portd); + sprintf(tmp.originService, "%d", IPaddrs->my_portd); return gtpv1Init(tmp); } @@ -59,7 +57,7 @@ static void cu_task_handle_sctp_association_ind(instance_t instance, sctp_new_as f1ap_cu_data->sctp_in_streams = sctp_new_association_ind->in_streams; f1ap_cu_data->sctp_out_streams = sctp_new_association_ind->out_streams; f1ap_cu_data->default_sctp_stream_id = 0; - getCxt(CUtype, instance)->gtpInst=cu_task_create_gtpu_instance_to_du(IPaddrs); + getCxt(CUtype, instance)->gtpInst=cu_task_create_gtpu_instance(IPaddrs); AssertFatal(getCxt(CUtype, instance)->gtpInst>0,"Failed to create CU F1-U UDP listener"); // Fixme: fully inconsistent instances management // dirty global var is a bad fix diff --git a/openair2/F1AP/f1ap_cu_ue_context_management.c b/openair2/F1AP/f1ap_cu_ue_context_management.c index b8f1d7d84e..41898d77c7 100644 --- a/openair2/F1AP/f1ap_cu_ue_context_management.c +++ b/openair2/F1AP/f1ap_cu_ue_context_management.c @@ -510,18 +510,15 @@ int CU_send_UE_CONTEXT_SETUP_REQUEST(instance_t instance, /* 12.1.3 uLUPTNLInformation_ToBeSetup_List */ for (int j = 0; j < f1ap_ue_context_setup_req->drbs_to_be_setup[i].up_ul_tnl_length; j++) { - /*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*/ - transport_layer_addr_t addr; - int sz=sizeof(f1ap_ue_context_setup_req->drbs_to_be_setup[i].up_dl_tnl[0].tl_address); - memcpy(addr.buffer,&f1ap_ue_context_setup_req->drbs_to_be_setup[i].up_dl_tnl[0].tl_address, sz); - addr.length = sz*8; + /* Use a dummy address and teid for the outgoing GTP-U tunnel (DU) which will be updated once we get the UE context setup response from the DU */ + transport_layer_addr_t addr = { length: 32, buffer: { 0 } }; f1ap_ue_context_setup_req->drbs_to_be_setup[i].up_ul_tnl[j].teid = newGtpuCreateTunnel(getCxt(CUtype, instance)->gtpInst, f1ap_ue_context_setup_req->rnti, f1ap_ue_context_setup_req->drbs_to_be_setup[i].drb_id, f1ap_ue_context_setup_req->drbs_to_be_setup[i].drb_id, 0xFFFF, // We will set the right value from DU answer -1, // no qfi - addr, + addr, // We will set the right value from DU answer f1ap_ue_context_setup_req->drbs_to_be_setup[i].up_dl_tnl[0].port, cu_f1u_data_req, NULL); @@ -700,10 +697,11 @@ int CU_handle_UE_CONTEXT_SETUP_RESPONSE(instance_t instance, F1AP_GTPTunnel_t *dl_up_tnl0 = dl_up_tnl_info_p->dLUPTNLInformation.choice.gTPTunnel; BIT_STRING_TO_TRANSPORT_LAYER_ADDRESS_IPv4(&dl_up_tnl0->transportLayerAddress, drb_p->up_dl_tnl[0].tl_address); OCTET_STRING_TO_INT32(&dl_up_tnl0->gTP_TEID, drb_p->up_dl_tnl[0].teid); - GtpuUpdateTunnelOutgoingTeid(getCxt(CUtype, instance)->gtpInst, - f1ap_ue_context_setup_resp->rnti, - (ebi_t)drbs_setup_item_p->dRBID, - drb_p->up_dl_tnl[0].teid); + GtpuUpdateTunnelOutgoingAddressAndTeid(getCxt(CUtype, instance)->gtpInst, + f1ap_ue_context_setup_resp->rnti, + (ebi_t)drbs_setup_item_p->dRBID, + drb_p->up_dl_tnl[0].tl_address, + drb_p->up_dl_tnl[0].teid); } } @@ -1478,11 +1476,8 @@ int CU_send_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance, f1ap_ue_context /* 12.1.3 uLUPTNLInformation_ToBeSetup_List */ for (int j = 0; j < f1ap_ue_context_modification_req->drbs_to_be_setup[i].up_ul_tnl_length; j++) { - /*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*/ - transport_layer_addr_t addr; - int sz=sizeof(f1ap_ue_context_modification_req->drbs_to_be_setup[i].up_dl_tnl[0].tl_address); - memcpy(addr.buffer,&f1ap_ue_context_modification_req->drbs_to_be_setup[i].up_dl_tnl[0].tl_address, sz); - addr.length = sz*8; + /* Use a dummy address and teid for the outgoing GTP-U tunnel (DU) which will be updated once we get the UE context modification response from the DU */ + transport_layer_addr_t addr = { length: 32, buffer: { 0 } }; f1ap_ue_context_modification_req->drbs_to_be_setup[i].up_ul_tnl[j].teid = newGtpuCreateTunnel(getCxt(CUtype, instance)->gtpInst, f1ap_ue_context_modification_req->rnti, @@ -1490,7 +1485,7 @@ int CU_send_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance, f1ap_ue_context f1ap_ue_context_modification_req->drbs_to_be_setup[i].drb_id, 0xFFFF, // We will set the right value from DU answer -1, // no qfi - addr, + addr, // We will set the right value from DU answer f1ap_ue_context_modification_req->drbs_to_be_setup[i].up_dl_tnl[0].port, cu_f1u_data_req, NULL); @@ -1702,9 +1697,10 @@ int CU_handle_UE_CONTEXT_MODIFICATION_RESPONSE(instance_t instance, F1AP_GTPTunnel_t *dl_up_tnl0 = dl_up_tnl_info_p->dLUPTNLInformation.choice.gTPTunnel; BIT_STRING_TO_TRANSPORT_LAYER_ADDRESS_IPv4(&dl_up_tnl0->transportLayerAddress, drb_p->up_dl_tnl[0].tl_address); OCTET_STRING_TO_INT32(&dl_up_tnl0->gTP_TEID, drb_p->up_dl_tnl[0].teid); - GtpuUpdateTunnelOutgoingTeid(getCxt(CUtype, instance)->gtpInst, + GtpuUpdateTunnelOutgoingAddressAndTeid(getCxt(CUtype, instance)->gtpInst, f1ap_ue_context_modification_resp->rnti, (ebi_t)drbs_setupmod_item_p->dRBID, + drb_p->up_dl_tnl[0].tl_address, drb_p->up_dl_tnl[0].teid); } } diff --git a/openair3/ocp-gtpu/gtp_itf.cpp b/openair3/ocp-gtpu/gtp_itf.cpp index 5a2a7fd591..8045e7f635 100644 --- a/openair3/ocp-gtpu/gtp_itf.cpp +++ b/openair3/ocp-gtpu/gtp_itf.cpp @@ -552,7 +552,7 @@ instance_t gtpv1Init(openAddr_t context) { return id; } -void GtpuUpdateTunnelOutgoingTeid(instance_t instance, ue_id_t ue_id, ebi_t bearer_id, teid_t newOutgoingTeid) { +void GtpuUpdateTunnelOutgoingAddressAndTeid(instance_t instance, ue_id_t ue_id, ebi_t bearer_id, in_addr_t newOutgoingAddr, teid_t newOutgoingTeid) { pthread_mutex_lock(&globGtp.gtp_lock); getInstRetVoid(compatInst(instance)); getUeRetVoid(inst, ue_id); @@ -565,8 +565,9 @@ void GtpuUpdateTunnelOutgoingTeid(instance_t instance, ue_id_t ue_id, ebi_t bear return; } + ptr2->second.outgoing_ip_addr = newOutgoingAddr; ptr2->second.teid_outgoing = newOutgoingTeid; - LOG_I(GTPU, "[%ld] Tunnel Outgoing TEID updated to %x \n", instance, ptr2->second.teid_outgoing); + LOG_I(GTPU, "[%ld] Tunnel Outgoing TEID updated to %x and address to %x\n", instance, ptr2->second.teid_outgoing, ptr2->second.outgoing_ip_addr); pthread_mutex_unlock(&globGtp.gtp_lock); return; } diff --git a/openair3/ocp-gtpu/gtp_itf.h b/openair3/ocp-gtpu/gtp_itf.h index 00736fc672..86d719c200 100644 --- a/openair3/ocp-gtpu/gtp_itf.h +++ b/openair3/ocp-gtpu/gtp_itf.h @@ -92,10 +92,11 @@ extern "C" { gtpCallback callBack, gtpCallbackSDAP callBackSDAP); - void GtpuUpdateTunnelOutgoingTeid(instance_t instance, - ue_id_t ue_id, - ebi_t bearer_id, - teid_t newOutgoingTeid); + void GtpuUpdateTunnelOutgoingAddressAndTeid(instance_t instance, + ue_id_t ue_id, + ebi_t bearer_id, + in_addr_t newOutgoingAddr, + teid_t newOutgoingTeid); int newGtpuDeleteAllTunnels(instance_t instance, ue_id_t ue_id); int newGtpuDeleteTunnels(instance_t instance, ue_id_t ue_id, int nbTunnels, pdusessionid_t *pdusession_id);