From e65cb0cf42f66f88fee68d329306296a8199befb Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 21 Mar 2024 08:04:32 +0100 Subject: [PATCH] Introduce additional option to bind on separate IFs for F1-C/U in DU After the last commit, it is not possible to bind on separate interfaces for F1-C and F1-U. In other words, it is for instance not possible to have the F1-C on one subnet on one physical interface, and F1-U on another subnet on another physical interface. This commit introduces a second option MACRLCs.[0].local_n_address_f1u to allow to bind F1-U on an alternative address; if it is not specified, the interface of F1-C is reused. The above only works for the DU; no corresponding option exists for the CU. For the CU, use separate CU-CP and CU-UP. Use it in the CI. --- .../5g_rfsimulator_e1/docker-compose.yaml | 9 ++++--- doc/F1-design.md | 26 +++++++++++++------ openair2/COMMON/f1ap_messages_types.h | 3 ++- openair2/F1AP/f1ap_du_task.c | 4 +-- openair2/F1AP/f1ap_du_ue_context_management.c | 2 +- openair2/GNB_APP/MACRLC_nr_paramdef.h | 4 +++ openair2/GNB_APP/gnb_config.c | 5 +++- openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_f1ap.c | 24 ++++++++--------- openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h | 2 ++ 9 files changed, 50 insertions(+), 29 deletions(-) diff --git a/ci-scripts/yaml_files/5g_rfsimulator_e1/docker-compose.yaml b/ci-scripts/yaml_files/5g_rfsimulator_e1/docker-compose.yaml index 3e73e60a27..a6fa3bd715 100644 --- a/ci-scripts/yaml_files/5g_rfsimulator_e1/docker-compose.yaml +++ b/ci-scripts/yaml_files/5g_rfsimulator_e1/docker-compose.yaml @@ -187,8 +187,9 @@ services: container_name: rfsim5g-oai-du environment: USE_ADDITIONAL_OPTIONS: --sa --rfsim --log_config.global_log_options level,nocolor,time - --MACRLCs.[0].local_n_address 192.168.73.3 + --MACRLCs.[0].local_n_address 192.168.72.3 --MACRLCs.[0].remote_n_address 192.168.72.2 + --MACRLCs.[0].local_n_address_f1u 192.168.73.3 ASAN_OPTIONS: detect_leaks=0 depends_on: - oai-cucp @@ -217,8 +218,9 @@ services: --gNBs.[0].gNB_DU_ID 0xe01 --gNBs.[0].nr_cellid 87654321 --gNBs.[0].servingCellConfigCommon.[0].physCellId 1 - --MACRLCs.[0].local_n_address 192.168.74.3 --MACRLCs.[0].remote_n_address 192.168.72.2 + --MACRLCs.[0].local_n_address 192.168.72.4 + --MACRLCs.[0].local_n_address_f1u 192.168.74.3 ASAN_OPTIONS: detect_leaks=0 depends_on: - oai-cucp @@ -247,8 +249,9 @@ services: --gNBs.[0].gNB_DU_ID 0xe02 --gNBs.[0].nr_cellid 11111111 --gNBs.[0].servingCellConfigCommon.[0].physCellId 2 - --MACRLCs.[0].local_n_address 192.168.76.3 --MACRLCs.[0].remote_n_address 192.168.72.2 + --MACRLCs.[0].local_n_address 192.168.72.5 + --MACRLCs.[0].local_n_address_f1u 192.168.76.3 ASAN_OPTIONS: detect_leaks=0 depends_on: - oai-cucp diff --git a/doc/F1-design.md b/doc/F1-design.md index 115ad916d2..a4e6882ab9 100644 --- a/doc/F1-design.md +++ b/doc/F1-design.md @@ -124,11 +124,12 @@ gNB, are, in order: (`tr_s_preference`), it is a CU. 3. It is a (monolithic) gNB. -## Local network deployment of F1 +## F1 IP configuration for Local network deployment of F1 -For a local deployment, you should update the following fields. -We assume that the CU will bind on `192.168.70.129` towards the core, -`127.0.0.3` towards the DU, and the DU `127.0.0.4` towards the CU. +The following paragraphs explain the IP configuration for F1 in the OAI config +files on the example of a a local deployment. We assume that the CU will bind +on `192.168.70.129` towards the core, `127.0.0.3` towards the DU, and the DU +`127.0.0.4` towards the CU. In the CU file: - Update the `gNBs.[0].amf_ip_address` and `gNBs.[0].NETWORK_INTERFACES` @@ -138,8 +139,8 @@ In the CU file: - `gNBs.[0].NETWORK_INTERFACES.GNB_IPV4_ADDRESS_FOR_NG_AMF 192.168.70.129` - `gNBs.[0].NETWORK_INTERFACES.GNB_IPV4_ADDRESS_FOR_NGU 192.168.70.132` - Set `gNBs.[0].tr_s_preference` (transport south-bound) to `f1` -- Update the `gNBs.[0].local_s_address` (CU-local south address) for the F1-C - south-bound interface: `127.0.0.3` +- Update the `gNBs.[0].local_s_address` (CU-local south address) for the + F1-C/SCTP and F1-U/GTP/UDP south-bound interfaces: `127.0.0.3` - Note: the `gNBs.[0].remote_s_address` (CU-remote/DU south address) is ignored, but we recommend to put `0.0.0.0` ("any") - Ports should match the ones in the DU config, but for simplicity and @@ -152,14 +153,23 @@ In the CU file: In the DU file: - Set `MACRLCs.[0].tr_n_preference` to `f1` - Update `MACRLCs.[0].local_n_address` (local north-bound address of the DU) to - `127.0.0.4`. This IP address is used to bind the GTP socket (F1-U user plane - traffic). + `127.0.0.4`. This IP address is used to bind the F1-C/SCTP and F1-U/GTP/UDP + socket. +- If you need to bind to different addresses for F1-C and F1-U, there is a + second option `MACRLCs.[0].local_n_address_f1u` which is used to bind + F1-U/GTP/UDP instead; F1-C/SCTP will still bind to the address in + `MACRLCs.[0].local_n_address`. - Update `MACRLCs.[].remote_n_address` (remote north-bound address of the CU) to `127.0.0.3`. This IP address is used as the CU destination IP address for F1AP communication. Note: all `local_*_if_name` parameters are ignored. +Note 2: at the DU, you can bind to different interfaces for F1-C and F1-U with +the options `MACRLCs.[0].local_n_address` and +`MACRLCs.[0].local_n_address_f1u`, respectively. Note that this is not foreseen +for the CU; in the case of the CU, please use separate CU-UP and CU-CP. + ## Configuration of multiple DUs Upon F1 Setup Request of a new DU, the CU cross-checks that diff --git a/openair2/COMMON/f1ap_messages_types.h b/openair2/COMMON/f1ap_messages_types.h index c5ffe0f738..f99f4ce250 100644 --- a/openair2/COMMON/f1ap_messages_types.h +++ b/openair2/COMMON/f1ap_messages_types.h @@ -78,7 +78,8 @@ typedef net_ip_address_t f1ap_net_ip_address_t; typedef struct f1ap_net_config_t { f1ap_net_ip_address_t CU_f1_ip_address; - f1ap_net_ip_address_t DU_f1_ip_address; + f1ap_net_ip_address_t DU_f1c_ip_address; + char *DU_f1u_ip_address; uint16_t CUport; uint16_t DUport; } f1ap_net_config_t; diff --git a/openair2/F1AP/f1ap_du_task.c b/openair2/F1AP/f1ap_du_task.c index f8416d3550..1783e9d909 100644 --- a/openair2/F1AP/f1ap_du_task.c +++ b/openair2/F1AP/f1ap_du_task.c @@ -43,7 +43,7 @@ instance_t DUuniqInstance=0; static instance_t du_create_gtpu_instance_to_cu(const f1ap_net_config_t *nc) { openAddr_t tmp = {0}; - strncpy(tmp.originHost, nc->DU_f1_ip_address.ipv4_address, sizeof(tmp.originHost) - 1); + strncpy(tmp.originHost, nc->DU_f1u_ip_address, sizeof(tmp.originHost) - 1); strncpy(tmp.destinationHost, nc->CU_f1_ip_address.ipv4_address, sizeof(tmp.destinationHost) - 1); sprintf(tmp.originService, "%d", nc->DUport); sprintf(tmp.destinationService, "%d", nc->CUport); @@ -65,7 +65,7 @@ void du_task_send_sctp_association_req(instance_t instance, f1ap_net_config_t *n // remote memcpy(&sctp_new_association_req_p->remote_address, &nc->CU_f1_ip_address, sizeof(nc->CU_f1_ip_address)); // local - memcpy(&sctp_new_association_req_p->local_address, &nc->DU_f1_ip_address, sizeof(nc->DU_f1_ip_address)); + memcpy(&sctp_new_association_req_p->local_address, &nc->DU_f1c_ip_address, sizeof(nc->DU_f1c_ip_address)); // du_f1ap_register_to_sctp itti_send_msg_to_task(TASK_SCTP, instance, message_p); } diff --git a/openair2/F1AP/f1ap_du_ue_context_management.c b/openair2/F1AP/f1ap_du_ue_context_management.c index 3715c0ae5d..4d7be74a49 100644 --- a/openair2/F1AP/f1ap_du_ue_context_management.c +++ b/openair2/F1AP/f1ap_du_ue_context_management.c @@ -1189,7 +1189,7 @@ int DU_send_UE_CONTEXT_MODIFICATION_RESPONSE(sctp_assoc_t assoc_id, f1ap_ue_cont asn1cCalloc(dLUPTNLInformation_ToBeSetup_Item->dLUPTNLInformation.choice.gTPTunnel, gTPTunnel); /* transportLayerAddress */ struct sockaddr_in addr= {0}; - inet_pton(AF_INET, getCxt(0)->net_config.DU_f1_ip_address.ipv4_address, &addr.sin_addr.s_addr); + inet_pton(AF_INET, getCxt(0)->net_config.DU_f1u_ip_address, &addr.sin_addr.s_addr); TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(addr.sin_addr.s_addr, &gTPTunnel->transportLayerAddress); /* gTP_TEID */ INT32_TO_OCTET_STRING(resp->drbs_to_be_modified[i].up_dl_tnl[j].teid, &gTPTunnel->gTP_TEID); diff --git a/openair2/GNB_APP/MACRLC_nr_paramdef.h b/openair2/GNB_APP/MACRLC_nr_paramdef.h index f33cbf5327..cff2280532 100644 --- a/openair2/GNB_APP/MACRLC_nr_paramdef.h +++ b/openair2/GNB_APP/MACRLC_nr_paramdef.h @@ -41,6 +41,7 @@ #define CONFIG_STRING_MACRLC_TRANSPORT_N_PREFERENCE "tr_n_preference" #define CONFIG_STRING_MACRLC_LOCAL_N_IF_NAME "local_n_if_name" #define CONFIG_STRING_MACRLC_LOCAL_N_ADDRESS "local_n_address" +#define CONFIG_STRING_MACRLC_LOCAL_N_ADDRESS_F1U "local_n_address_f1u" #define CONFIG_STRING_MACRLC_REMOTE_N_ADDRESS "remote_n_address" #define CONFIG_STRING_MACRLC_LOCAL_N_PORTC "local_n_portc" #define CONFIG_STRING_MACRLC_REMOTE_N_PORTC "remote_n_portc" @@ -125,6 +126,7 @@ {CONFIG_STRING_MACRLC_MIN_GRANT_PRB, HLP_MACRLC_MIN_GRANT_PRB, 0, .u8ptr=NULL, .defintval=5, TYPE_UINT8, 0}, \ {CONFIG_STRING_MACRLC_MIN_GRANT_MCS, HLP_MACRLC_MIN_GRANT_MCS, 0, .u8ptr=NULL, .defintval=9, TYPE_UINT8, 0}, \ {CONFIG_STRING_MACRLC_IDENTITY_PM, HLP_MACRLC_IDENTITY_PM, PARAMFLAG_BOOL, .u8ptr=NULL, .defintval=0, TYPE_UINT8, 0}, \ + {CONFIG_STRING_MACRLC_LOCAL_N_ADDRESS_F1U, NULL, 0, .strptr=NULL, .defstrval=NULL, TYPE_STRING, 0}, \ } // clang-format off @@ -162,6 +164,7 @@ #define MACRLC_MIN_GRANT_PRB_IDX 31 #define MACRLC_MIN_GRANT_MCS_IDX 32 #define MACRLC_IDENTITY_PM_IDX 33 +#define MACRLC_LOCAL_N_ADDRESS_F1U_IDX 34 #define MACRLCPARAMS_CHECK { \ { .s5 = { NULL } }, \ @@ -198,6 +201,7 @@ { .s5 = { NULL } }, \ { .s5 = { NULL } }, \ { .s2 = { NULL } }, \ + { .s5 = { NULL } }, \ } /*---------------------------------------------------------------------------------------------------------------------------------------------------------*/ diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c index b8a64558d3..73c21c323f 100644 --- a/openair2/GNB_APP/gnb_config.c +++ b/openair2/GNB_APP/gnb_config.c @@ -1279,7 +1279,10 @@ void RCconfig_nr_macrlc(configmodule_interface_t *cfg) || strcmp(*(MacRLC_ParamList.paramarray[j][MACRLC_TRANSPORT_N_PREFERENCE_IDX].strptr), "cudu") == 0) { printf("Configuring F1 interfaces for MACRLC\n"); RC.nrmac[j]->eth_params_n.local_if_name = strdup(*(MacRLC_ParamList.paramarray[j][MACRLC_LOCAL_N_IF_NAME_IDX].strptr)); - RC.nrmac[j]->eth_params_n.my_addr = strdup(*(MacRLC_ParamList.paramarray[j][MACRLC_LOCAL_N_ADDRESS_IDX].strptr)); + char **f1caddr = MacRLC_ParamList.paramarray[j][MACRLC_LOCAL_N_ADDRESS_IDX].strptr; + RC.nrmac[j]->eth_params_n.my_addr = strdup(*f1caddr); + char **f1uaddr = MacRLC_ParamList.paramarray[j][MACRLC_LOCAL_N_ADDRESS_F1U_IDX].strptr; + RC.nrmac[j]->f1u_addr = f1uaddr != NULL ? strdup(*f1uaddr) : strdup(*f1caddr); RC.nrmac[j]->eth_params_n.remote_addr = strdup(*(MacRLC_ParamList.paramarray[j][MACRLC_REMOTE_N_ADDRESS_IDX].strptr)); RC.nrmac[j]->eth_params_n.my_portc = *(MacRLC_ParamList.paramarray[j][MACRLC_LOCAL_N_PORTC_IDX].iptr); RC.nrmac[j]->eth_params_n.remote_portc = *(MacRLC_ParamList.paramarray[j][MACRLC_REMOTE_N_PORTC_IDX].iptr); diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_f1ap.c b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_f1ap.c index fea829f61e..0ec4aabc24 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_f1ap.c +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_ul_f1ap.c @@ -29,7 +29,7 @@ #include "mac_rrc_ul.h" -static f1ap_net_config_t read_DU_IP_config(const eth_params_t* f1_params) +static f1ap_net_config_t read_DU_IP_config(const eth_params_t* f1_params, const char *f1u_ip_addr) { f1ap_net_config_t nc = {0}; @@ -37,19 +37,17 @@ static f1ap_net_config_t read_DU_IP_config(const eth_params_t* f1_params) nc.CU_f1_ip_address.ipv4 = 1; strcpy(nc.CU_f1_ip_address.ipv4_address, f1_params->remote_addr); nc.CUport = f1_params->remote_portd; - LOG_I(GNB_APP, - "FIAP: CU_ip4_address in DU %p, strlen %d\n", - nc.CU_f1_ip_address.ipv4_address, - (int)strlen(f1_params->remote_addr)); - nc.DU_f1_ip_address.ipv6 = 0; - nc.DU_f1_ip_address.ipv4 = 1; - strcpy(nc.DU_f1_ip_address.ipv4_address, f1_params->my_addr); + nc.DU_f1c_ip_address.ipv6 = 0; + nc.DU_f1c_ip_address.ipv4 = 1; + strcpy(nc.DU_f1c_ip_address.ipv4_address, f1_params->my_addr); + nc.DU_f1u_ip_address = strdup(f1u_ip_addr); nc.DUport = f1_params->my_portd; - LOG_I(GNB_APP, - "FIAP: DU_ip4_address in DU %p, strlen %ld\n", - nc.DU_f1_ip_address.ipv4_address, - strlen(f1_params->my_addr)); + LOG_I(F1AP, + "F1-C DU IPaddr %s, connect to F1-C CU %s, binding GTP to %s\n", + nc.DU_f1c_ip_address.ipv4_address, + nc.CU_f1_ip_address.ipv4_address, + nc.DU_f1u_ip_address); // sctp_in_streams/sctp_out_streams are given by SCTP layer return nc; @@ -95,7 +93,7 @@ static void f1_setup_request_f1ap(const f1ap_setup_req_t *req) } memcpy(f1ap_setup->rrc_ver, req->rrc_ver, sizeof(req->rrc_ver)); - F1AP_DU_REGISTER_REQ(msg).net_config = read_DU_IP_config(&RC.nrmac[0]->eth_params_n); + F1AP_DU_REGISTER_REQ(msg).net_config = read_DU_IP_config(&RC.nrmac[0]->eth_params_n, RC.nrmac[0]->f1u_addr); itti_send_msg_to_task(TASK_DU_F1, 0, msg); } diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h index e162ecbff5..398372e85b 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h @@ -723,6 +723,8 @@ typedef struct f1_config_t { typedef struct gNB_MAC_INST_s { /// Ethernet parameters for northbound midhaul interface eth_params_t eth_params_n; + /// address for F1U to bind, ports in eth_params_n + char *f1u_addr; /// Ethernet parameters for fronthaul interface eth_params_t eth_params_s; /// Module