diff --git a/openair2/COMMON/e1ap_messages_def.h b/openair2/COMMON/e1ap_messages_def.h
index ee3b1e45dfa3403412491913a93305479c56957d..70533f8add61a270294fc845fb7a84536b4a3863 100644
--- a/openair2/COMMON/e1ap_messages_def.h
+++ b/openair2/COMMON/e1ap_messages_def.h
@@ -29,3 +29,5 @@ MESSAGE_DEF(E1AP_BEARER_CONTEXT_SETUP_REQ , MESSAGE_PRIORITY_MED , e1ap_bearer_s
 
 MESSAGE_DEF(E1AP_BEARER_CONTEXT_SETUP_RESP , MESSAGE_PRIORITY_MED , e1ap_bearer_setup_resp_t , e1ap_bearer_setup_resp)
 
+MESSAGE_DEF(E1AP_BEARER_CONTEXT_MODIFICATION_REQ , MESSAGE_PRIORITY_MED , e1ap_bearer_setup_req_t , e1ap_bearer_mod_req)
+
diff --git a/openair2/COMMON/e1ap_messages_types.h b/openair2/COMMON/e1ap_messages_types.h
index ae76103321548f57064418f61f15656cd973e4f5..81542cb9e5c0445c745a43e9678287c955c74fbc 100644
--- a/openair2/COMMON/e1ap_messages_types.h
+++ b/openair2/COMMON/e1ap_messages_types.h
@@ -36,10 +36,11 @@
 #define E1AP_MAX_NUM_DRBS 4
 #define E1AP_MAX_NUM_UP_PARAM 4
 
-#define E1AP_SETUP_REQ(mSGpTR)                     (mSGpTR)->ittiMsg.e1ap_setup_req
-#define E1AP_SETUP_RESP(mSGpTR)                    (mSGpTR)->ittiMsg.e1ap_setup_resp
-#define E1AP_BEARER_CONTEXT_SETUP_REQ(mSGpTR)      (mSGpTR)->ittiMsg.e1ap_bearer_setup_req
-#define E1AP_BEARER_CONTEXT_SETUP_RESP(mSGpTR)     (mSGpTR)->ittiMsg.e1ap_bearer_setup_resp
+#define E1AP_SETUP_REQ(mSGpTR)                            (mSGpTR)->ittiMsg.e1ap_setup_req
+#define E1AP_SETUP_RESP(mSGpTR)                           (mSGpTR)->ittiMsg.e1ap_setup_resp
+#define E1AP_BEARER_CONTEXT_SETUP_REQ(mSGpTR)             (mSGpTR)->ittiMsg.e1ap_bearer_setup_req
+#define E1AP_BEARER_CONTEXT_SETUP_RESP(mSGpTR)            (mSGpTR)->ittiMsg.e1ap_bearer_setup_resp
+#define E1AP_BEARER_CONTEXT_MODIFICATION_REQ(mSGpTR)      (mSGpTR)->ittiMsg.e1ap_bearer_setup_req
 
 typedef f1ap_net_ip_address_t e1ap_net_ip_address_t;
 
@@ -112,6 +113,8 @@ typedef struct DRB_nGRAN_to_setup_s {
   long discardTimer;
   long reorderingTimer;
   long rLC_Mode;
+  in_addr_t tlAddress;
+  int teId;
   int numCellGroups;
   cell_group_t cellGroupList[E1AP_MAX_NUM_CELL_GROUPS];
   int numQosFlow2Setup;
@@ -136,6 +139,7 @@ typedef struct pdu_session_to_setup_s {
 
 typedef struct e1ap_bearer_setup_req_s {
   uint64_t gNB_cu_cp_ue_id;
+  rnti_t   rnti;
   uint64_t cipheringAlgorithm;
   uint64_t integrityProtectionAlgorithm;
   char     encryptionKey[128];
diff --git a/openair2/COMMON/gtpv1_u_messages_types.h b/openair2/COMMON/gtpv1_u_messages_types.h
index 6367699bfd8a7efd92ce77eacc6e27dd1d05f446..26e509b2e71d5eafe13bd784ccbc349f32dc8d90 100644
--- a/openair2/COMMON/gtpv1_u_messages_types.h
+++ b/openair2/COMMON/gtpv1_u_messages_types.h
@@ -186,6 +186,7 @@ typedef struct gtpv1u_gnb_create_tunnel_resp_s {
   int                    num_tunnels;
   teid_t                 gnb_NGu_teid[NR_GTPV1U_MAX_BEARERS_PER_UE];  ///< Tunnel Endpoint Identifier
   pdusessionid_t         pdusession_id[NR_GTPV1U_MAX_BEARERS_PER_UE];
+  int                    bearer_id[NR_GTPV1U_MAX_BEARERS_PER_UE];
   transport_layer_addr_t gnb_addr;
 } gtpv1u_gnb_create_tunnel_resp_t;
 typedef struct gtpv1u_gnb_delete_tunnel_req_s {
diff --git a/openair2/E1AP/e1ap.c b/openair2/E1AP/e1ap.c
index 910afb3653c07e668797c05a68274cbb60e44b61..d366902b81a33df0e06a810dfc9a855c81d5a19e 100644
--- a/openair2/E1AP/e1ap.c
+++ b/openair2/E1AP/e1ap.c
@@ -1086,7 +1086,8 @@ int e1apCUCP_handle_BEARER_CONTEXT_SETUP_FAILURE(instance_t instance,
   BEARER CONTEXT MODIFICATION REQUEST
 */
 
-int e1apCUCP_send_BEARER_CONTEXT_MODIFICATION_REQUEST(instance_t instance) {
+int e1apCUCP_send_BEARER_CONTEXT_MODIFICATION_REQUEST(instance_t instance,
+                                                      e1ap_bearer_setup_req_t *req) {
   AssertFatal(false,"Not implemented yet\n");
   return -1;
 }
@@ -1373,6 +1374,11 @@ void *E1AP_CUCP_task(void *arg) {
         e1apCUCP_send_BEARER_CONTEXT_SETUP_REQUEST(myInstance, &E1AP_BEARER_CONTEXT_SETUP_REQ(msg));
         break;
 
+      case E1AP_BEARER_CONTEXT_MODIFICATION_REQ:
+        LOG_I(E1AP, "CUCP Task Received E1AP_BEARER_CONTEXT_MODIFICATION_REQ\n");
+        e1apCUCP_send_BEARER_CONTEXT_MODIFICATION_REQUEST(myInstance, &E1AP_BEARER_CONTEXT_SETUP_REQ(msg));
+        break;
+
       default:
         LOG_E(E1AP, "Unknown message received in TASK_CUCP_E1\n");
         break;
diff --git a/openair2/E1AP/e1ap.h b/openair2/E1AP/e1ap.h
index 965aa17acdc65923a695d650186959bc25c51f9a..6aa6f9918476833e09e101eb679f176e17a26ad6 100644
--- a/openair2/E1AP/e1ap.h
+++ b/openair2/E1AP/e1ap.h
@@ -30,38 +30,8 @@
 #include "openair2/COMMON/e1ap_messages_types.h"
 #include "openair3/UTILS/conversions.h"
 #include "openair2/F1AP/f1ap_common.h"
+#include "openair2/E1AP/e1ap_common.h"
 
-#include <E1AP_Cause.h>
-#include <E1AP_InitiatingMessage.h>
-#include <E1AP_E1AP-PDU.h>
-#include <E1AP_ProtocolIE-Field.h>
-#include <E1AP_SupportedPLMNs-Item.h>
-#include <E1AP_SuccessfulOutcome.h>
-#include <E1AP_ProtocolIE-Field.h>
-#include <E1AP_UnsuccessfulOutcome.h>
-#include <E1AP_GNB-CU-UP-E1SetupFailure.h>
-#include <E1AP_GNB-CU-UP-ConfigurationUpdate.h>
-#include <E1AP_GNB-CU-UP-TNLA-To-Remove-Item.h>
-#include <E1AP_CP-TNL-Information.h>
-#include <E1AP_UP-Parameters-Item.h>
-#include <E1AP_UP-TNL-Information.h>
-#include <E1AP_PDU-Session-Resource-Setup-Item.h>
-#include <E1AP_DRB-Setup-Item-EUTRAN.h>
-#include <E1AP_DRB-Setup-Item-NG-RAN.h>
-#include <E1AP_QoS-Flow-QoS-Parameter-Item.h>
-#include <E1AP_QoS-Flow-Item.h>
-#include <E1AP_DRB-Failed-List-NG-RAN.h>
-#include <E1AP_DRB-Failed-Item-NG-RAN.h>
-#include <E1AP_BearerContextSetupResponse.h>
-#include <E1AP_BearerContextSetupRequest.h>
-#include <E1AP_DRB-To-Setup-Item-EUTRAN.h>
-#include <E1AP_DRB-To-Setup-Item-NG-RAN.h>
-#include <E1AP_Cell-Group-Information-Item.h>
-#include <E1AP_PDU-Session-Resource-To-Setup-Item.h>
-#include <E1AP_GTPTunnel.h>
-#include <E1AP_Non-Dynamic5QIDescriptor.h>
-#include <E1AP_Dynamic5QIDescriptor.h>
-#include <E1AP_T-ReorderingTimer.h>
 #endif
 
 
diff --git a/openair2/E1AP/e1ap_common.c b/openair2/E1AP/e1ap_common.c
index 8b995bc12f631790295b6bd34bc0ea1f76c4f9db..bc0a6d58df92fcf984450b1909b583edc8c0dca6 100644
--- a/openair2/E1AP/e1ap_common.c
+++ b/openair2/E1AP/e1ap_common.c
@@ -51,6 +51,7 @@ void createE1inst(E1_t type, instance_t instance, e1ap_setup_req_t *req) {
   if (type == CPtype) {
     AssertFatal(e1ap_cp_inst[instance] == NULL, "Double call to E1 CP instance %d\n", (int)instance);
     e1ap_cp_inst[instance] = (e1ap_upcp_inst_t *) calloc(1, sizeof(e1ap_upcp_inst_t));
+    memcpy(&e1ap_cp_inst[instance]->setupReq, req, sizeof(e1ap_setup_req_t));
   } else if (type == UPtype) {
     AssertFatal(e1ap_up_inst[instance] == NULL, "Double call to E1 UP instance %d\n", (int)instance);
     e1ap_up_inst[instance] = (e1ap_upcp_inst_t *) calloc(1, sizeof(e1ap_upcp_inst_t));
diff --git a/openair2/E1AP/e1ap_common.h b/openair2/E1AP/e1ap_common.h
index 90d41e2699202376bf02915f13772d0bef375e19..26e632913f8b04af7ce78a73a1158c84bce8ff2f 100644
--- a/openair2/E1AP/e1ap_common.h
+++ b/openair2/E1AP/e1ap_common.h
@@ -25,6 +25,39 @@
 #define E1AP_COMMON_H_
 #include "openair2/E1AP/e1ap_default_values.h"
 #include "openair2/COMMON/e1ap_messages_types.h"
+
+#include <E1AP_Cause.h>
+#include <E1AP_InitiatingMessage.h>
+#include <E1AP_E1AP-PDU.h>
+#include <E1AP_ProtocolIE-Field.h>
+#include <E1AP_SupportedPLMNs-Item.h>
+#include <E1AP_SuccessfulOutcome.h>
+#include <E1AP_ProtocolIE-Field.h>
+#include <E1AP_UnsuccessfulOutcome.h>
+#include <E1AP_GNB-CU-UP-E1SetupFailure.h>
+#include <E1AP_GNB-CU-UP-ConfigurationUpdate.h>
+#include <E1AP_GNB-CU-UP-TNLA-To-Remove-Item.h>
+#include <E1AP_CP-TNL-Information.h>
+#include <E1AP_UP-Parameters-Item.h>
+#include <E1AP_UP-TNL-Information.h>
+#include <E1AP_PDU-Session-Resource-Setup-Item.h>
+#include <E1AP_DRB-Setup-Item-EUTRAN.h>
+#include <E1AP_DRB-Setup-Item-NG-RAN.h>
+#include <E1AP_QoS-Flow-QoS-Parameter-Item.h>
+#include <E1AP_QoS-Flow-Item.h>
+#include <E1AP_DRB-Failed-List-NG-RAN.h>
+#include <E1AP_DRB-Failed-Item-NG-RAN.h>
+#include <E1AP_BearerContextSetupResponse.h>
+#include <E1AP_BearerContextSetupRequest.h>
+#include <E1AP_DRB-To-Setup-Item-EUTRAN.h>
+#include <E1AP_DRB-To-Setup-Item-NG-RAN.h>
+#include <E1AP_Cell-Group-Information-Item.h>
+#include <E1AP_PDU-Session-Resource-To-Setup-Item.h>
+#include <E1AP_GTPTunnel.h>
+#include <E1AP_Non-Dynamic5QIDescriptor.h>
+#include <E1AP_Dynamic5QIDescriptor.h>
+#include <E1AP_T-ReorderingTimer.h>
+
 int e1ap_decode_pdu(E1AP_E1AP_PDU_t *pdu, const uint8_t *const buffer, uint32_t length);
 
 e1ap_upcp_inst_t *getCxtE1(E1_t type, instance_t instance);
diff --git a/openair2/F1AP/f1ap_cu_ue_context_management.c b/openair2/F1AP/f1ap_cu_ue_context_management.c
index 0b058233b52108cab4f3bbf82d02ef2f8fb79b70..54034d42f32f28c0995eb7e9286ada8d1602b723 100644
--- a/openair2/F1AP/f1ap_cu_ue_context_management.c
+++ b/openair2/F1AP/f1ap_cu_ue_context_management.c
@@ -700,10 +700,15 @@ 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,
+      transport_layer_addr_t addr;
+      int sz=sizeof(drb_p->up_dl_tnl[0].tl_address);
+      memcpy(addr.buffer, &drb_p->up_dl_tnl[0].tl_address, sz);
+      addr.length = sz*8;
+      GtpuUpdateTunnelOutgoingPair(getCxt(CUtype, instance)->gtpInst,
                                    f1ap_ue_context_setup_resp->rnti,
                                    (ebi_t)drbs_setup_item_p->dRBID,
-                                   drb_p->up_dl_tnl[0].teid);
+                                   drb_p->up_dl_tnl[0].teid,
+                                   addr);
     }
   }
 
@@ -1691,10 +1696,6 @@ 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,
-                     f1ap_ue_context_modification_resp->rnti,
-                     (ebi_t)drbs_setupmod_item_p->dRBID,
-                     drb_p->up_dl_tnl[0].teid);
       }
     }
     // SRBs_FailedToBeSetupMod_List
diff --git a/openair2/RRC/NR/nr_rrc_defs.h b/openair2/RRC/NR/nr_rrc_defs.h
index fdd23348517fc6563fb30c91483d1b70f79c799e..a9b0dfb36129b4406419edd45e6f669d88447e7a 100644
--- a/openair2/RRC/NR/nr_rrc_defs.h
+++ b/openair2/RRC/NR/nr_rrc_defs.h
@@ -468,11 +468,13 @@ typedef struct {
 } nr_security_configuration_t;
 
 typedef void (*nr_e1_bearer_cxt_msg_transfer_func_t)(e1ap_bearer_setup_req_t *req, instance_t instance);
+typedef void (*nr_e1_ue_cxt_mod_msg_transfer_func_t)(MessageDef *msg, instance_t instance);
 
 typedef struct nr_mac_rrc_dl_if_s {
   /* TODO add other message types as necessary */
   dl_rrc_message_transfer_func_t dl_rrc_message_transfer;
   nr_e1_bearer_cxt_msg_transfer_func_t nr_e1_bearer_cxt_msg_transfer;
+  nr_e1_ue_cxt_mod_msg_transfer_func_t nr_e1_ue_cxt_mod_msg_transfer;
 } nr_mac_rrc_dl_if_t;
 
 //---NR---(completely change)---------------------
diff --git a/openair2/RRC/NR/nr_rrc_proto.h b/openair2/RRC/NR/nr_rrc_proto.h
index 0eb21358319469ed39dfe50313594f7281b16870..25223f118a240f912510b61ea41f1e6b1507a552 100644
--- a/openair2/RRC/NR/nr_rrc_proto.h
+++ b/openair2/RRC/NR/nr_rrc_proto.h
@@ -225,3 +225,9 @@ void bearer_context_setup_direct(e1ap_bearer_setup_req_t *req,
 void bearer_context_setup_e1ap(e1ap_bearer_setup_req_t *req,
                                  instance_t instance);
 
+void ue_cxt_mod_send_e1ap(MessageDef *msg,
+                          instance_t instance);
+
+void ue_cxt_mod_direct(MessageDef *msg,
+                       instance_t instance);
+
diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c
index 26f7835513f00e5bdfca328176bb23a648405207..4a406bfc8a5bf0ada2a537fbad2996691e88e2c8 100755
--- a/openair2/RRC/NR/rrc_gNB.c
+++ b/openair2/RRC/NR/rrc_gNB.c
@@ -102,6 +102,7 @@
 #include "LAYER2/nr_rlc/nr_rlc_oai_api.h"
 #include "openair2/LAYER2/nr_pdcp/nr_pdcp_e1_api.h"
 #include "openair2/F1AP/f1ap_common.h"
+#include "openair2/E1AP/e1ap_common.h"
 
 #include "BIT_STRING.h"
 #include "assertions.h"
@@ -202,24 +203,23 @@ static void rrc_gNB_mac_rrc_init(gNB_RRC_INST *rrc)
 {
   switch (rrc->node_type) {
     case ngran_gNB_CUCP:
-      rrc->cu_if.nr_e1_bearer_cxt_msg_transfer = bearer_context_setup_e1ap;
+      rrc->mac_rrc.nr_e1_bearer_cxt_msg_transfer = bearer_context_setup_e1ap;
+      rrc->mac_rrc.nr_e1_ue_cxt_mod_msg_transfer = ue_cxt_mod_send_e1ap;
       break;
     case ngran_gNB_CUUP:
       // CUUP should not have a RRC instance but we let it for now
       break;
     case ngran_gNB_CU:
+    case ngran_gNB:
       mac_rrc_dl_f1ap_init(&rrc->mac_rrc);
       rrc->mac_rrc.nr_e1_bearer_cxt_msg_transfer = bearer_context_setup_direct;
+      rrc->mac_rrc.nr_e1_ue_cxt_mod_msg_transfer = ue_cxt_mod_direct;
       break;
     case ngran_gNB_DU:
       /* silently drop this, as we currently still need the RRC at the DU. As
        * soon as this is not the case anymore, we can add the AssertFatal() */
       //AssertFatal(1==0,"nothing to do for DU\n");
       break;
-    case ngran_gNB:
-      mac_rrc_dl_direct_init(&rrc->mac_rrc);
-      rrc->mac_rrc.nr_e1_bearer_cxt_msg_transfer = bearer_context_setup_direct;
-      break;
     default:
       AssertFatal(0 == 1, "Unknown node type %d\n", rrc->node_type);
       break;
@@ -3596,9 +3596,49 @@ static void rrc_CU_process_ue_context_setup_response(MessageDef *msg_p, const ch
 
 }
 
+static void update_UL_UP_tunnel_info(e1ap_bearer_setup_req_t *req, instance_t instance, ue_id_t ue_id) {
+  for (int i=0; i < req->numPDUSessions; i++) {
+    for (int j=0; j < req->pduSession[i].numDRB2Setup; j++) {
+      DRB_nGRAN_to_setup_t *drb_p = req->pduSession[i].DRBnGRanList + j;
+
+      transport_layer_addr_t newRemoteAddr;
+      newRemoteAddr.length = 32; // IPv4
+      memcpy(newRemoteAddr.buffer,
+             &drb_p->tlAddress,
+             sizeof(in_addr_t));
+
+      GtpuUpdateTunnelOutgoingPair(instance,
+                                   ue_id,
+                                   (ebi_t)drb_p->id,
+                                   drb_p->teId,
+                                   newRemoteAddr);
+    }
+  }
+}
+
+void rrc_CUUP_process_bearer_context_mod_req(e1ap_bearer_setup_req_t *req, instance_t instance) {
+  update_UL_UP_tunnel_info(req, instance, req->gNB_cu_cp_ue_id);
+  // TODO: send bearer cxt mod response
+}
+
+void ue_cxt_mod_send_e1ap(MessageDef *msg, instance_t instance) {
+  int module_id = 0;
+  itti_send_msg_to_task(TASK_CUCP_E1, module_id, msg);
+}
+
+void ue_cxt_mod_direct(MessageDef *msg, instance_t instance) {
+  e1ap_bearer_setup_req_t *req = &E1AP_BEARER_CONTEXT_SETUP_REQ(msg);
+  instance_t gtpInst = getCxt(CUtype, instance)->gtpInst;
+
+  update_UL_UP_tunnel_info(req, gtpInst, req->rnti);
+
+  int result = itti_free (ITTI_MSG_ORIGIN_ID(msg), msg);
+  AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
+}
+
 static void rrc_CU_process_ue_context_modification_response(MessageDef *msg_p, const char *msg_name, instance_t instance){
 
-  f1ap_ue_context_setup_t * resp=&F1AP_UE_CONTEXT_SETUP_RESP(msg_p);
+  f1ap_ue_context_setup_t *resp=&F1AP_UE_CONTEXT_SETUP_RESP(msg_p);
   protocol_ctxt_t ctxt = {
     .rnti = resp->rnti,
     .module_id = instance,
@@ -3606,8 +3646,30 @@ static void rrc_CU_process_ue_context_modification_response(MessageDef *msg_p, c
     .enb_flag  = 1,
     .eNB_index = instance
   };
+
   gNB_RRC_INST *rrc = RC.nrrrc[ctxt.module_id];
   struct rrc_gNB_ue_context_s *ue_context_p = rrc_gNB_get_ue_context(rrc, ctxt.rnti);
+
+  MessageDef *msg_e1 = itti_alloc_new_message(TASK_CUCP_E1, instance, E1AP_BEARER_CONTEXT_MODIFICATION_REQ);
+  e1ap_bearer_setup_req_t *req = &E1AP_BEARER_CONTEXT_SETUP_REQ(msg_e1);
+  req->numPDUSessions = ue_context_p->ue_context.nb_of_pdusessions;
+  req->gNB_cu_cp_ue_id = ue_context_p->ue_context.gNB_ue_ngap_id;
+  req->rnti = ue_context_p->ue_context.rnti;
+  for (int i=0; i < req->numPDUSessions; i++) {
+    req->pduSession[i].numDRB2Setup = resp->drbs_to_be_setup_length;
+    for (int j=0; j < resp->drbs_to_be_setup_length; j++) {
+      f1ap_drb_to_be_setup_t *drb_f1 = resp->drbs_to_be_setup + j;
+      DRB_nGRAN_to_setup_t *drb_e1 = req->pduSession[i].DRBnGRanList + j;
+
+      drb_e1->id = drb_f1->drb_id;
+      drb_e1->tlAddress = drb_f1->up_dl_tnl[0].tl_address;
+      drb_e1->teId = drb_f1->up_dl_tnl[0].teid;
+    }
+  }
+
+  // send the F1 response message up to update F1-U tunnel info
+  rrc->cu_if.nr_e1_ue_cxt_mod_msg_transfer(msg_e1, instance);
+
   NR_CellGroupConfig_t *cellGroupConfig = NULL;
 
   if(resp->du_to_cu_rrc_information->cellGroupConfig!=NULL){
@@ -4007,33 +4069,35 @@ void fill_DRB_configList_e1(NR_DRB_ToAddModList_t *DRB_configList, pdu_session_t
   }
 }
 
-int drb_config_gtpu_create_e1(e1ap_bearer_setup_req_t *req,
-                              gtpv1u_gnb_create_tunnel_req_t  *create_tunnel_req,
-                              gtpv1u_gnb_create_tunnel_resp_t *create_tunnel_resp,
-                              instance_t instance) {
+int drb_config_N3gtpu_create_e1(e1ap_bearer_setup_req_t *req,
+                                gtpv1u_gnb_create_tunnel_resp_t *create_tunnel_resp,
+                                instance_t instance) {
+
+  gtpv1u_gnb_create_tunnel_req_t create_tunnel_req={0};
 
   NR_DRB_ToAddModList_t DRB_configList = {0};
   for (int i=0; i < req->numPDUSessions; i++) {
     pdu_session_to_setup_t *pdu = &req->pduSession[i];
-    create_tunnel_req->pdusession_id[i] = pdu->sessionId;
-    create_tunnel_req->incoming_rb_id[i] = pdu->DRBnGRanList[0].id; // taking only the first DRB. TODO:change this
-    memcpy(&create_tunnel_req->dst_addr[i].buffer,
+    create_tunnel_req.pdusession_id[i] = pdu->sessionId;
+    create_tunnel_req.incoming_rb_id[i] = pdu->DRBnGRanList[0].id; // taking only the first DRB. TODO:change this
+    memcpy(&create_tunnel_req.dst_addr[i].buffer,
            &pdu->tlAddress,
            sizeof(uint8_t)*4);
-    create_tunnel_req->dst_addr[i].length = 32; // 8bits * 4bytes
-    create_tunnel_req->outgoing_teid[i] = pdu->teId;
+    create_tunnel_req.dst_addr[i].length = 32; // 8bits * 4bytes
+    create_tunnel_req.outgoing_teid[i] = pdu->teId;
     fill_DRB_configList_e1(&DRB_configList, pdu);
   }
-  create_tunnel_req->num_tunnels = req->numPDUSessions;
-  create_tunnel_req->ue_id = (req->gNB_cu_cp_ue_id & 0xFFFF);
+  create_tunnel_req.num_tunnels = req->numPDUSessions;
+  create_tunnel_req.ue_id = (req->gNB_cu_cp_ue_id & 0xFFFF);
 
+  // Create N3 tunnel
   int ret = gtpv1u_create_ngu_tunnel(
                                  instance,
-                                 create_tunnel_req,
+                                 &create_tunnel_req,
                                  create_tunnel_resp);
   if (ret != 0) {
     LOG_E(NR_RRC,"rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ : gtpv1u_create_ngu_tunnel failed,start to release UE id %ld\n",
-          create_tunnel_req->ue_id);
+          create_tunnel_req.ue_id);
     return ret;
   }
 
@@ -4050,7 +4114,7 @@ int drb_config_gtpu_create_e1(e1ap_bearer_setup_req_t *req,
                         &kUPint);
 
   nr_pdcp_e1_add_drbs(false,
-                      create_tunnel_req->ue_id,
+                      create_tunnel_req.ue_id,
                       &DRB_configList,
                       (req->integrityProtectionAlgorithm << 4) | req->cipheringAlgorithm,
                       kUPenc,
@@ -4060,46 +4124,61 @@ int drb_config_gtpu_create_e1(e1ap_bearer_setup_req_t *req,
 
 void gNB_CU_create_up_ul_tunnel(e1ap_bearer_setup_resp_t *resp,
                                 e1ap_bearer_setup_req_t *req,
-                                instance_t instance,
-                                ue_id_t ue_id) {
+                                instance_t gtpInst,
+                                ue_id_t ue_id,
+                                int remote_port,
+                                in_addr_t my_addr) {
 
+  resp->numPDUSessions = req->numPDUSessions;
+  transport_layer_addr_t dummy_address = {0};
+  dummy_address.length = 32; // IPv4
   for (int i=0; i < req->numPDUSessions; i++) {
-    pdu_session_to_setup_t *pdu = req->pduSession + i;
-
-    transport_layer_addr_t addr;
-    int size = sizeof(pdu->tlAddress_dl);
-    memcpy(addr.buffer,
-           &pdu->tlAddress_dl,
-           size);
-    addr.length = size * 8;
-
-    resp->pduSession[i].tlAddress = pdu->tlAddress;
-    resp->pduSession[i].teId = newGtpuCreateTunnel(getCxt(CUtype, instance)->gtpInst,
-                                                   ue_id,
-                                                   pdu->DRBnGRanList[0].id,
-                                                   pdu->DRBnGRanList[0].id,
-                                                   0xFFFF, // We will set the right value from DU answer
-                                                   -1, // no qfi
-                                                   addr,
-                                                   pdu->tl_port_dl,
-                                                   cu_f1u_data_req,
-                                                   NULL);
+    resp->pduSession[i].numDRBSetup = req->pduSession[i].numDRB2Setup;
+    for (int j=0; j < req->pduSession[i].numDRB2Setup; j++) {
+      DRB_nGRAN_to_setup_t *drb2Setup = req->pduSession[i].DRBnGRanList + j;
+      DRB_nGRAN_setup_t *drbSetup = resp->pduSession[i].DRBnGRanList + j;
+
+      drbSetup->numUpParam = 1;
+      drbSetup->UpParamList[0].tlAddress = my_addr;
+      drbSetup->UpParamList[0].teId = newGtpuCreateTunnel(gtpInst,
+                                                          ue_id,
+                                                          drb2Setup->id,
+                                                          drb2Setup->id,
+                                                          0xFFFF, // We will set the right value from DU answer
+                                                          -1, // no qfi
+                                                          dummy_address, // We will set the right value from DU answer
+                                                          remote_port,
+                                                          cu_f1u_data_req,
+                                                          NULL);
+      drbSetup->id = drb2Setup->id;
+
+      drbSetup->numQosFlowSetup = drb2Setup->numQosFlow2Setup;
+      for (int k=0; k < drbSetup->numQosFlowSetup; k++) {
+        drbSetup->qosFlows[k].id = drb2Setup->qosFlows[k].id;
+      }
+    }
   }
 }
 
 void rrc_gNB_process_e1_bearer_context_setup_req(e1ap_bearer_setup_req_t *req, instance_t instance) {
 
-  gtpv1u_gnb_create_tunnel_req_t  create_tunnel_req={0};
-  gtpv1u_gnb_create_tunnel_resp_t create_tunnel_resp={0};
+  protocol_ctxt_t ctxt={0};
+  PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, 0, GNB_FLAG_YES, req->gNB_cu_cp_ue_id, 0, 0, 0);
+  gtpv1u_gnb_create_tunnel_resp_t create_tunnel_resp_N3={0};
 
   // GTP tunnel for UL
-  drb_config_gtpu_create_e1(req, &create_tunnel_req, &create_tunnel_resp, instance);
+  drb_config_N3gtpu_create_e1(req, &create_tunnel_resp_N3, instance);
 
   MessageDef *message_p;
   message_p = itti_alloc_new_message (TASK_RRC_GNB, instance, E1AP_BEARER_CONTEXT_SETUP_RESP);
   e1ap_bearer_setup_resp_t *resp = &E1AP_BEARER_CONTEXT_SETUP_RESP(message_p);
 
-  gNB_CU_create_up_ul_tunnel(resp, req, instance, req->gNB_cu_cp_ue_id);
+  int remote_port = RC.nrrrc[ctxt.module_id]->eth_params_s.remote_portd;
+  in_addr_t my_addr;
+  memcpy(&my_addr,
+         &getCxtE1(UPtype, instance)->setupReq.CUUP_e1_ip_address.ipv4_address,
+         sizeof(my_addr));
+  gNB_CU_create_up_ul_tunnel(resp, req, instance, req->gNB_cu_cp_ue_id, remote_port, my_addr);
 
   resp->gNB_cu_cp_ue_id = req->gNB_cu_cp_ue_id;
   resp->numPDUSessions = req->numPDUSessions;
@@ -4109,30 +4188,11 @@ void rrc_gNB_process_e1_bearer_context_setup_req(e1ap_bearer_setup_req_t *req, i
 
     pduSetup->id = pdu2Setup->sessionId;
     memcpy(&pduSetup->tlAddress,
-           &create_tunnel_resp.gnb_addr.buffer,
+           &create_tunnel_resp_N3.gnb_addr.buffer,
            sizeof(in_addr_t));
-    pduSetup->teId = create_tunnel_resp.gnb_NGu_teid[i];
+    pduSetup->teId = create_tunnel_resp_N3.gnb_NGu_teid[i];
     pduSetup->numDRBSetup = pdu2Setup->numDRB2Setup;
 
-    for (int j=0; j < pdu2Setup->numDRB2Setup; j++) {
-      DRB_nGRAN_setup_t    *drbSetup  = pduSetup->DRBnGRanList + j;
-      DRB_nGRAN_to_setup_t *drb2Setup = pdu2Setup->DRBnGRanList + j;
-
-      drbSetup->id = drb2Setup->id;
-
-      /* TODO: Set dummy values for UP Parameters for now */
-      drbSetup->numUpParam = 1;
-      for (int k=0; k < drbSetup->numUpParam; k++) {
-        drbSetup->UpParamList[k].tlAddress = 0;
-        drbSetup->UpParamList[k].teId      = 0;
-      }
-
-      drbSetup->numQosFlowSetup = drb2Setup->numQosFlow2Setup;
-      for (int k=0; k < drbSetup->numQosFlowSetup; k++) {
-        drbSetup->qosFlows[k].id = drb2Setup->qosFlows[k].id;
-      }
-    }
-
     // At this point we don't have a way to know the DRBs that failed to setup
     // We assume all DRBs to setup have are setup successfully so we always send successful outcome in response
     // TODO: Modify nr_pdcp_add_drbs() to return DRB list that failed to setup to support E1AP
@@ -4143,8 +4203,7 @@ void rrc_gNB_process_e1_bearer_context_setup_req(e1ap_bearer_setup_req_t *req, i
 }
 
 void prepare_and_send_ue_context_modification_f1(rrc_gNB_ue_context_t *ue_context_p,
-                                                 e1ap_bearer_setup_resp_t *e1ap_resp,
-                                                 e1ap_bearer_setup_req_t *e1ap_req) {
+                                                 e1ap_bearer_setup_resp_t *e1ap_resp) {
 
   /*Generate a UE context modification request message towards the DU to instruct the DU
    *for SRB2 and DRB configuration and get the updates on master cell group config from the DU*/
@@ -4169,19 +4228,16 @@ void prepare_and_send_ue_context_modification_f1(rrc_gNB_ue_context_t *ue_contex
   SRBs[0].lcid = 2;
 
   /*Instruction towards the DU for DRB configuration and tunnel creation*/
-  req->drbs_to_be_setup_length = e1ap_req->numPDUSessions;
+  req->drbs_to_be_setup_length = e1ap_resp->pduSession[0].numDRBSetup;
   req->drbs_to_be_setup = malloc(1*sizeof(f1ap_drb_to_be_setup_t)*req->drbs_to_be_setup_length);
-  for (int i=0; i < e1ap_req->numPDUSessions; i++) {
+  for (int i=0; i < e1ap_resp->pduSession[0].numDRBSetup; i++) {
     f1ap_drb_to_be_setup_t *DRBs =  req->drbs_to_be_setup + i;
-    DRBs[i].drb_id = e1ap_req->pduSession[i].DRBnGRanList[0].id;
+    DRBs[i].drb_id = e1ap_resp->pduSession[0].DRBnGRanList[i].id;
     DRBs[i].rlc_mode = RLC_MODE_AM;
-    DRBs[i].up_ul_tnl[0].tl_address = e1ap_req->pduSession[i].tlAddress;
-    DRBs[i].up_ul_tnl[0].port = e1ap_req->pduSession[i].tl_port;
-    DRBs[i].up_ul_tnl[0].teid = e1ap_resp->pduSession[i].teId;
+    DRBs[i].up_ul_tnl[0].tl_address = e1ap_resp->pduSession[0].DRBnGRanList[i].UpParamList[0].tlAddress;
+    DRBs[i].up_ul_tnl[0].port = RC.nrrrc[ctxt.module_id]->eth_params_s.my_portd;
+    DRBs[i].up_ul_tnl[0].teid = e1ap_resp->pduSession[0].DRBnGRanList[i].UpParamList[0].teId;
     DRBs[i].up_ul_tnl_length = 1;
-    DRBs[i].up_dl_tnl[0].tl_address = e1ap_req->pduSession[i].tlAddress_dl;
-    DRBs[i].up_dl_tnl[0].port = e1ap_req->pduSession[i].tl_port_dl;
-    DRBs[i].up_dl_tnl_length = 1;
   }
 
   itti_send_msg_to_task (TASK_CU_F1, ctxt.module_id, message_p);
@@ -4189,8 +4245,7 @@ void prepare_and_send_ue_context_modification_f1(rrc_gNB_ue_context_t *ue_contex
 
 void bearer_context_setup_direct(e1ap_bearer_setup_req_t *req, instance_t instance) {
 
-  uint16_t ue_initial_id = 0; // Making an invalid UE initial ID
-  rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_from_ngap_ids(instance, ue_initial_id, req->gNB_cu_cp_ue_id);
+  rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(RC.nrrrc[GNB_INSTANCE_TO_MODULE_ID(instance)], req->rnti);
   protocol_ctxt_t ctxt = {0};
   PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, 0, GNB_FLAG_YES, ue_context_p->ue_context.rnti, 0, 0, 0);
 
@@ -4205,22 +4260,16 @@ void bearer_context_setup_direct(e1ap_bearer_setup_req_t *req, instance_t instan
                                    instance);
   if (ret < 0) AssertFatal(false, "Unable to configure DRB or to create GTP Tunnel\n");
 
-  if(!NODE_IS_CU(RC.nrrrc[ctxt.module_id]->node_type)){
+  if(!NODE_IS_CU(RC.nrrrc[ctxt.module_id]->node_type)) {
     rrc_gNB_generate_dedicatedRRCReconfiguration(&ctxt, ue_context_p, NULL);
   } else {
-    for (int i=0; i < req->numPDUSessions; i++) {
-      pdu_session_to_setup_t *pdu = req->pduSession + i;
-
-      pdu->tlAddress    = inet_addr(RC.nrrrc[ctxt.module_id]->eth_params_s.my_addr);
-      pdu->tl_port       = RC.nrrrc[ctxt.module_id]->eth_params_s.my_portd;
-      pdu->tlAddress_dl = inet_addr(RC.nrrrc[ctxt.module_id]->eth_params_s.remote_addr);
-      pdu->tl_port_dl    = RC.nrrrc[ctxt.module_id]->eth_params_s.remote_portd;
-    }
-
     e1ap_bearer_setup_resp_t resp; // Used to store teids
-    gNB_CU_create_up_ul_tunnel(&resp, req, instance, ue_context_p->ue_context.rnti);
+    int remote_port = RC.nrrrc[ctxt.module_id]->eth_params_s.remote_portd;
+    in_addr_t my_addr = inet_addr(RC.nrrrc[ctxt.module_id]->eth_params_s.my_addr);
+    instance_t gtpInst = getCxt(CUtype, instance)->gtpInst;
+    gNB_CU_create_up_ul_tunnel(&resp, req, gtpInst, ue_context_p->ue_context.rnti, remote_port, my_addr);
 
-    prepare_and_send_ue_context_modification_f1(ue_context_p, &resp, req);
+    prepare_and_send_ue_context_modification_f1(ue_context_p, &resp);
   }
   // call the code that sends UE context modification message to DU
 }
@@ -4229,17 +4278,12 @@ void bearer_context_setup_e1ap(e1ap_bearer_setup_req_t *req, instance_t instance
 
   // create ITTI msg and send to CUCP E1 task to send via SCTP
   // then in CUUP the function rrc_gNB_process_e1_bearer_context_setup_req
-  uint16_t ue_initial_id = 0; // Making an invalid UE initial ID
-  rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_from_ngap_ids(instance, ue_initial_id, req->gNB_cu_cp_ue_id);
-  protocol_ctxt_t ctxt = {0};
-  PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, 0, GNB_FLAG_YES, ue_context_p->ue_context.rnti, 0, 0, 0);
-
-  MessageDef *msg_p = itti_alloc_new_message(TASK_CUCP_E1, 0, E1AP_BEARER_CONTEXT_SETUP_REQ);
+  MessageDef *msg_p = itti_alloc_new_message(TASK_CUCP_E1, instance, E1AP_BEARER_CONTEXT_SETUP_REQ);
   e1ap_bearer_setup_req_t *bearer_req = &E1AP_BEARER_CONTEXT_SETUP_REQ(msg_p);
   memcpy(bearer_req, req, sizeof(e1ap_bearer_setup_req_t));
   free(req);
 
-  itti_send_msg_to_task (TASK_CUCP_E1, ctxt.module_id, msg_p);
+  itti_send_msg_to_task (TASK_CUCP_E1, instance, msg_p);
 
 }
 
@@ -4267,20 +4311,7 @@ void rrc_gNB_process_e1_bearer_context_setup_resp(e1ap_bearer_setup_resp_t *resp
   ue_context_p->ue_context.setup_pdu_sessions += resp->numPDUSessions;
 
   // TODO: SV: combine e1ap_bearer_setup_req_t and e1ap_bearer_setup_resp_t and minimize assignments
-  e1ap_bearer_setup_req_t req;
-  req.numPDUSessions = resp->numPDUSessions;
-  for (int i=0; i < resp->numPDUSessions; i++) {
-    pdu_session_to_setup_t *pdu = req.pduSession + i;
-
-    pdu->DRBnGRanList[0].id = resp->pduSession[i].DRBnGRanList[0].id;
-
-    pdu->tlAddress    = inet_addr(RC.nrrrc[ctxt.module_id]->eth_params_s.my_addr);
-    pdu->tl_port       = RC.nrrrc[ctxt.module_id]->eth_params_s.my_portd;
-    pdu->tlAddress_dl = inet_addr(RC.nrrrc[ctxt.module_id]->eth_params_s.remote_addr);
-    pdu->tl_port_dl    = RC.nrrrc[ctxt.module_id]->eth_params_s.remote_portd;
-
-  }
-  prepare_and_send_ue_context_modification_f1(ue_context_p, resp, &req);
+  prepare_and_send_ue_context_modification_f1(ue_context_p, resp);
 }
 
 ///---------------------------------------------------------------------------------------------------------------///
diff --git a/openair2/RRC/NR/rrc_gNB_NGAP.c b/openair2/RRC/NR/rrc_gNB_NGAP.c
index dac634c6ed07b4b6f7320279fa01f43ad1c6ea30..49dfc84c597bb1688a5c0a97e423c2de3c84a253 100644
--- a/openair2/RRC/NR/rrc_gNB_NGAP.c
+++ b/openair2/RRC/NR/rrc_gNB_NGAP.c
@@ -497,12 +497,14 @@ rrc_gNB_process_NGAP_INITIAL_CONTEXT_SETUP_REQ(
       return (-1);
     } else {
       PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, GNB_FLAG_YES, ue_context_p->ue_context.rnti, 0, 0);
+      gNB_RRC_INST *rrc = RC.nrrrc[ctxt.module_id];
       ue_context_p->ue_context.gNB_ue_ngap_id = NGAP_INITIAL_CONTEXT_SETUP_REQ (msg_p).gNB_ue_ngap_id;
       ue_context_p->ue_context.amf_ue_ngap_id = NGAP_INITIAL_CONTEXT_SETUP_REQ (msg_p).amf_ue_ngap_id;
       ue_context_p->ue_context.nas_pdu_flag = NGAP_INITIAL_CONTEXT_SETUP_REQ (msg_p).nas_pdu_flag;
 
       uint8_t nb_pdusessions_tosetup = NGAP_INITIAL_CONTEXT_SETUP_REQ (msg_p).nb_of_pdusessions;
       if (nb_pdusessions_tosetup != 0) {
+        AssertFatal(rrc->node_type != ngran_gNB_CUCP, "PDU sessions in Initial context setup request not handled by E1 yet\n");
         gtpv1u_gnb_create_tunnel_req_t  create_tunnel_req={0};
         for (int i = 0; i < NR_NB_RB_MAX - 3; i++) {
           if(ue_context_p->ue_context.pduSession[i].status >= PDU_SESSION_STATUS_DONE)
@@ -992,6 +994,7 @@ rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ(
   e1ap_bearer_setup_req_t *bearer_req = calloc(1, sizeof(e1ap_bearer_setup_req_t));
 
   bearer_req->gNB_cu_cp_ue_id = gNB_ue_ngap_id;
+  bearer_req->rnti = ue_context_p->ue_context.rnti;
   bearer_req->cipheringAlgorithm = ue_context_p->ue_context.ciphering_algorithm;
   memcpy(bearer_req->encryptionKey, ue_context_p->ue_context.kgnb, sizeof(ue_context_p->ue_context.kgnb));
   bearer_req->integrityProtectionAlgorithm = ue_context_p->ue_context.integrity_algorithm;
diff --git a/openair3/ocp-gtpu/gtp_itf.cpp b/openair3/ocp-gtpu/gtp_itf.cpp
index a13f2b4d0c23268758f4335c4f798a1236ce276c..4d7cca38175e535239ea9f7a6a4fe33fba8e5d7e 100644
--- a/openair3/ocp-gtpu/gtp_itf.cpp
+++ b/openair3/ocp-gtpu/gtp_itf.cpp
@@ -546,7 +546,11 @@ 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 GtpuUpdateTunnelOutgoingPair(instance_t instance,
+                                  ue_id_t ue_id,
+                                  ebi_t bearer_id,
+                                  teid_t newOutgoingTeid,
+                                  transport_layer_addr_t newRemoteAddr) {
   pthread_mutex_lock(&globGtp.gtp_lock);
   getInstRetVoid(compatInst(instance));
   getRntiRetVoid(inst, ue_id);
@@ -560,7 +564,36 @@ void GtpuUpdateTunnelOutgoingTeid(instance_t instance, ue_id_t ue_id, ebi_t bear
   }
 
   ptr2->second.teid_outgoing = newOutgoingTeid;
-  LOG_I(GTPU, "[%ld] Tunnel Outgoing TEID updated to %x \n", instance, ptr2->second.teid_outgoing);
+
+  int addrs_length_in_bytes = newRemoteAddr.length / 8;
+
+  switch (addrs_length_in_bytes) {
+    case 4:
+      memcpy(&ptr2->second.outgoing_ip_addr,newRemoteAddr.buffer,4);
+      break;
+
+    case 16:
+      memcpy(ptr2->second.outgoing_ip6_addr.s6_addr,newRemoteAddr.buffer,
+             16);
+      break;
+
+    case 20:
+      memcpy(&ptr2->second.outgoing_ip_addr,newRemoteAddr.buffer,4);
+      memcpy(ptr2->second.outgoing_ip6_addr.s6_addr,
+             newRemoteAddr.buffer+4,
+             16);
+
+    default:
+      AssertFatal(false, "SGW Address size impossible");
+  }
+
+  char ip4[INET_ADDRSTRLEN];
+  char ip6[INET6_ADDRSTRLEN];
+  LOG_I(GTPU, "[%ld] Tunnel Outgoing TEID updated to %x, remote IPv4 to: %s, IPv6 to: %s\n",
+        instance,
+        ptr2->second.teid_outgoing,
+        inet_ntop(AF_INET,(void *)&ptr2->second.outgoing_ip_addr, ip4,INET_ADDRSTRLEN ),
+        inet_ntop(AF_INET6,(void *)ptr2->second.outgoing_ip6_addr.s6_addr, ip6, INET6_ADDRSTRLEN));
   pthread_mutex_unlock(&globGtp.gtp_lock);
   return;
 }
@@ -619,7 +652,7 @@ teid_t newGtpuCreateTunnel(instance_t instance,
 
     case 20:
       memcpy(&tmp->outgoing_ip_addr,remoteAddr.buffer,4);
-      memcpy(&tmp->outgoing_ip6_addr.s6_addr,
+      memcpy(tmp->outgoing_ip6_addr.s6_addr,
              remoteAddr.buffer+4,
              16);
 
diff --git a/openair3/ocp-gtpu/gtp_itf.h b/openair3/ocp-gtpu/gtp_itf.h
index 3e06ef0786bd5baa21c628a5677d36a47d55c515..aa22a1990f689e1f9e5dc7aac2a5b9a98b25e33e 100644
--- a/openair3/ocp-gtpu/gtp_itf.h
+++ b/openair3/ocp-gtpu/gtp_itf.h
@@ -91,7 +91,13 @@ extern "C" {
                              int port,
                              gtpCallback callBack,
                              gtpCallbackSDAP callBackSDAP);
-  void GtpuUpdateTunnelOutgoingTeid(instance_t instance, ue_id_t ue_id, ebi_t bearer_id, teid_t newOutgoingTeid);
+
+  void GtpuUpdateTunnelOutgoingPair(instance_t instance,
+                                    ue_id_t ue_id,
+                                    ebi_t bearer_id,
+                                    teid_t newOutgoingTeid,
+                                    transport_layer_addr_t newRemoteAddr);
+
   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);
   instance_t gtpv1Init(openAddr_t context);