diff --git a/openair2/COMMON/e1ap_messages_types.h b/openair2/COMMON/e1ap_messages_types.h
index 81542cb9e5c0445c745a43e9678287c955c74fbc..891e05882364c30c00a6e1b388a0780beab2652f 100644
--- a/openair2/COMMON/e1ap_messages_types.h
+++ b/openair2/COMMON/e1ap_messages_types.h
@@ -35,6 +35,8 @@
 #define E1AP_MAX_NUM_DRBS 4
 #define E1AP_MAX_NUM_DRBS 4
 #define E1AP_MAX_NUM_UP_PARAM 4
+#define E1AP_GTP_INST_N3 10
+#define E1AP_GTP_INST_F1U 11
 
 #define E1AP_SETUP_REQ(mSGpTR)                            (mSGpTR)->ittiMsg.e1ap_setup_req
 #define E1AP_SETUP_RESP(mSGpTR)                           (mSGpTR)->ittiMsg.e1ap_setup_resp
@@ -75,6 +77,12 @@ typedef struct cell_group_s {
   long id;
 } cell_group_t;
 
+typedef struct up_params_s {
+  in_addr_t tlAddress;
+  long teId;
+  int cell_group_id;
+} up_params_t;
+
 typedef struct drb_to_setup_s {
   long drbId;
   long pDCP_SN_Size_UL;
@@ -115,6 +123,8 @@ typedef struct DRB_nGRAN_to_setup_s {
   long rLC_Mode;
   in_addr_t tlAddress;
   int teId;
+  int numDlUpParam;
+  up_params_t DlUpParamList[E1AP_MAX_NUM_UP_PARAM];
   int numCellGroups;
   cell_group_t cellGroupList[E1AP_MAX_NUM_CELL_GROUPS];
   int numQosFlow2Setup;
@@ -135,10 +145,13 @@ typedef struct pdu_session_to_setup_s {
   int tl_port_dl;
   long numDRB2Setup;
   DRB_nGRAN_to_setup_t DRBnGRanList[E1AP_MAX_NUM_NGRAN_DRB];
+  long numDRB2Modify;
+  DRB_nGRAN_to_setup_t DRBnGRanModList[E1AP_MAX_NUM_NGRAN_DRB];
 } pdu_session_to_setup_t;
 
 typedef struct e1ap_bearer_setup_req_s {
   uint64_t gNB_cu_cp_ue_id;
+  uint64_t gNB_cu_up_ue_id;
   rnti_t   rnti;
   uint64_t cipheringAlgorithm;
   uint64_t integrityProtectionAlgorithm;
@@ -151,13 +164,10 @@ typedef struct e1ap_bearer_setup_req_s {
   drb_to_setup_t DRBList[E1AP_MAX_NUM_DRBS];
   int numPDUSessions;
   pdu_session_to_setup_t pduSession[E1AP_MAX_NUM_PDU_SESSIONS];
+  int numPDUSessionsMod;
+  pdu_session_to_setup_t pduSessionMod[E1AP_MAX_NUM_PDU_SESSIONS];
 } e1ap_bearer_setup_req_t;
 
-typedef struct up_params_s {
-  in_addr_t tlAddress;
-  long teId;
-} up_params_t;
-
 typedef struct drb_setup_s {
   int drbId;
   in_addr_t tlAddress;
@@ -205,6 +215,8 @@ typedef struct e1ap_bearer_setup_resp_s {
 
 typedef struct e1ap_upcp_inst_s {
   uint32_t                assoc_id;
+  instance_t              gtpInstN3;
+  instance_t              gtpInstF1U;
   e1ap_setup_req_t        setupReq;
   e1ap_bearer_setup_req_t bearerSetupReq;
   e1ap_bearer_setup_resp_t bearerSetupResp;
diff --git a/openair2/E1AP/e1ap.c b/openair2/E1AP/e1ap.c
index d366902b81a33df0e06a810dfc9a855c81d5a19e..40d89101287df642a279fb416a969f5ed504c6b7 100644
--- a/openair2/E1AP/e1ap.c
+++ b/openair2/E1AP/e1ap.c
@@ -40,7 +40,7 @@ e1ap_message_processing_t e1ap_message_processing[E1AP_NUM_MSG_HANDLERS][3] = {
   { 0, 0, 0 }, /* gNBCUCPConfigurationUpdate */
   { 0, 0, 0 }, /* E1Release */
   { e1apCUUP_handle_BEARER_CONTEXT_SETUP_REQUEST, e1apCUCP_handle_BEARER_CONTEXT_SETUP_RESPONSE, e1apCUCP_handle_BEARER_CONTEXT_SETUP_FAILURE }, /* bearerContextSetup */
-  { 0, 0, 0 }, /* bearerContextModification */
+  { e1apCUUP_handle_BEARER_CONTEXT_MODIFICATION_REQUEST, 0, 0 }, /* bearerContextModification */
   { 0, 0, 0 }, /* bearerContextModificationRequired */
   { 0, 0, 0 }, /* bearerContextRelease */
   { 0, 0, 0 }, /* bearerContextReleaseRequired */
@@ -1048,7 +1048,7 @@ int e1apCUCP_handle_BEARER_CONTEXT_SETUP_RESPONSE(instance_t instance,
             AssertFatal(pdu->nG_DL_UP_TNL_Information.present == E1AP_UP_TNL_Information_PR_gTPTunnel,
                         "pdu->nG_DL_UP_TNL_Information.present != E1AP_UP_TNL_Information_PR_gTPTunnel\n");
             BIT_STRING_TO_TRANSPORT_LAYER_ADDRESS_IPv4(&pdu->nG_DL_UP_TNL_Information.choice.gTPTunnel->transportLayerAddress,
-                                                  pduSetup->tlAddress);
+                                                       pduSetup->tlAddress);
             OCTET_STRING_TO_INT32(&pdu->nG_DL_UP_TNL_Information.choice.gTPTunnel->gTP_TEID,
                                   pduSetup->teId);
           }
@@ -1059,6 +1059,24 @@ int e1apCUCP_handle_BEARER_CONTEXT_SETUP_RESPONSE(instance_t instance,
             E1AP_DRB_Setup_Item_NG_RAN_t *drb = pdu->dRB_Setup_List_NG_RAN.list.array[j];
 
             drbSetup->id = drb->dRB_ID;
+
+            drbSetup->numUpParam = drb->uL_UP_Transport_Parameters.list.count;
+            for (int k=0; k < drb->uL_UP_Transport_Parameters.list.count; k++) {
+              up_params_t *UL_UP_param = drbSetup->UpParamList + k;
+              E1AP_UP_Parameters_Item_t *in_UL_UP_param = drb->uL_UP_Transport_Parameters.list.array[k];
+
+              AssertFatal(in_UL_UP_param->uP_TNL_Information.present == E1AP_UP_TNL_Information_PR_gTPTunnel,
+                          "in_UL_UP_param->uP_TNL_Information.present != E1AP_UP_TNL_Information_PR_gTPTunnel\n");
+              E1AP_GTPTunnel_t *gTPTunnel = in_UL_UP_param->uP_TNL_Information.choice.gTPTunnel;
+              if (gTPTunnel) {
+                BIT_STRING_TO_TRANSPORT_LAYER_ADDRESS_IPv4(&gTPTunnel->transportLayerAddress,
+                                                           UL_UP_param->tlAddress);
+                OCTET_STRING_TO_INT32(&gTPTunnel->gTP_TEID,
+                                      UL_UP_param->teId);
+              } else {
+                AssertFatal(false, "gTPTunnel information in required\n");
+              }
+            }
           }
         }
         break;
@@ -1087,9 +1105,76 @@ int e1apCUCP_handle_BEARER_CONTEXT_SETUP_FAILURE(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;
+                                                      e1ap_bearer_setup_req_t *bearerCxt) {
+  E1AP_E1AP_PDU_t pdu = {0};
+  /* Create */
+  /* 0. pdu Type */
+  e1ap_setup_req_t *setup = &getCxtE1(CPtype, instance)->setupReq;
+  if (!setup) {
+    LOG_E(E1AP, "got send_BEARER_CONTEXT_MODIFICATION_REQUEST on not established instance (%ld)\n", instance);
+    return -1;
+  }
+
+  pdu.present = E1AP_E1AP_PDU_PR_initiatingMessage;
+  asn1cCalloc(pdu.choice.initiatingMessage, msg);
+  msg->procedureCode = E1AP_ProcedureCode_id_bearerContextModification;
+  msg->criticality   = E1AP_Criticality_reject;
+  msg->value.present = E1AP_InitiatingMessage__value_PR_BearerContextModificationRequest;
+  E1AP_BearerContextModificationRequest_t *out = &pdu.choice.initiatingMessage->value.choice.BearerContextModificationRequest;
+  /* mandatory */
+  /* c1. gNB-CU-CP UE E1AP ID */
+  asn1cSequenceAdd(out->protocolIEs.list, E1AP_BearerContextModificationRequestIEs_t, ieC1);
+  ieC1->id                         = E1AP_ProtocolIE_ID_id_gNB_CU_CP_UE_E1AP_ID;
+  ieC1->criticality                = E1AP_Criticality_reject;
+  ieC1->value.present              = E1AP_BearerContextModificationRequestIEs__value_PR_GNB_CU_CP_UE_E1AP_ID;
+  ieC1->value.choice.GNB_CU_CP_UE_E1AP_ID = bearerCxt->gNB_cu_cp_ue_id;
+  /* mandatory */
+  /* c2. gNB-CU-UP UE E1AP ID */
+  asn1cSequenceAdd(out->protocolIEs.list, E1AP_BearerContextModificationRequestIEs_t, ieC2);
+  ieC2->id                         = E1AP_ProtocolIE_ID_id_gNB_CU_UP_UE_E1AP_ID;
+  ieC2->criticality                = E1AP_Criticality_reject;
+  ieC2->value.present              = E1AP_BearerContextModificationRequestIEs__value_PR_GNB_CU_UP_UE_E1AP_ID;
+  ieC2->value.choice.GNB_CU_UP_UE_E1AP_ID = bearerCxt->gNB_cu_cp_ue_id;
+  /* optional */
+  /*  */
+  asn1cSequenceAdd(out->protocolIEs.list, E1AP_BearerContextModificationRequestIEs_t, ieC3);
+  ieC3->id            = E1AP_ProtocolIE_ID_id_System_BearerContextModificationRequest;
+  ieC3->criticality   = E1AP_Criticality_reject;
+  ieC3->value.present = E1AP_BearerContextModificationRequestIEs__value_PR_System_BearerContextModificationRequest;
+  ieC3->value.choice.System_BearerContextModificationRequest.present = E1AP_System_BearerContextModificationRequest_PR_nG_RAN_BearerContextModificationRequest;
+  E1AP_ProtocolIE_Container_4932P26_t *msgNGRAN_list = calloc(1, sizeof(E1AP_ProtocolIE_Container_4932P26_t));
+  ieC3->value.choice.System_BearerContextModificationRequest.choice.nG_RAN_BearerContextModificationRequest = (struct E1AP_ProtocolIE_Container *) msgNGRAN_list;
+  asn1cSequenceAdd(msgNGRAN_list->list, E1AP_NG_RAN_BearerContextModificationRequest_t, msgNGRAN);
+  msgNGRAN->id = E1AP_ProtocolIE_ID_id_PDU_Session_Resource_To_Modify_List;
+  msgNGRAN->criticality = E1AP_Criticality_reject;
+  msgNGRAN->value.present = E1AP_NG_RAN_BearerContextModificationRequest__value_PR_PDU_Session_Resource_To_Modify_List;
+  E1AP_PDU_Session_Resource_To_Modify_List_t *pdu2Setup = &msgNGRAN->value.choice.PDU_Session_Resource_To_Modify_List;
+  for(pdu_session_to_setup_t *i=bearerCxt->pduSessionMod; i < bearerCxt->pduSessionMod+bearerCxt->numPDUSessionsMod; i++) {
+    asn1cSequenceAdd(pdu2Setup->list, E1AP_PDU_Session_Resource_To_Modify_Item_t, ieC3_1);
+    ieC3_1->pDU_Session_ID = i->sessionId;
+
+    for (DRB_nGRAN_to_setup_t *j=i->DRBnGRanModList; j < i->DRBnGRanModList+i->numDRB2Modify; j++) {
+      asn1cCalloc(ieC3_1->dRB_To_Modify_List_NG_RAN, drb2Mod_List);
+      asn1cSequenceAdd(drb2Mod_List->list, E1AP_DRB_To_Modify_Item_NG_RAN_t, drb2Mod);
+      drb2Mod->dRB_ID = j->id;
+
+      if (j->numDlUpParam > 0) {
+        asn1cCalloc(drb2Mod->dL_UP_Parameters, DL_UP_Param_List);
+        for (up_params_t *k=j->DlUpParamList; k < j->DlUpParamList+j->numDlUpParam; k++) {
+          asn1cSequenceAdd(DL_UP_Param_List->list, E1AP_UP_Parameters_Item_t, DL_UP_Param);
+          DL_UP_Param->uP_TNL_Information.present = E1AP_UP_TNL_Information_PR_gTPTunnel;
+          asn1cCalloc(DL_UP_Param->uP_TNL_Information.choice.gTPTunnel, gTPTunnel);
+          TRANSPORT_LAYER_ADDRESS_IPv4_TO_BIT_STRING(k->tlAddress, &gTPTunnel->transportLayerAddress);
+          INT32_TO_OCTET_STRING(k->teId, &gTPTunnel->gTP_TEID);
+
+          DL_UP_Param->cell_Group_ID = k->cell_group_id;
+        }
+      }
+    }
+  }
+
+  e1ap_encode_send(CPtype, instance, &pdu, 0, __func__);
+  return 0;
 }
 
 int e1apCUUP_send_BEARER_CONTEXT_MODIFICATION_RESPONSE(instance_t instance) {
@@ -1103,11 +1188,115 @@ int e1apCUUP_send_BEARER_CONTEXT_MODIFICATION_FAILURE(instance_t instance) {
 }
 
 int e1apCUUP_handle_BEARER_CONTEXT_MODIFICATION_REQUEST(instance_t instance,
-                                                        uint32_t assoc_id,
-                                                        uint32_t stream,
                                                         E1AP_E1AP_PDU_t *pdu) {
-  AssertFatal(false,"Not implemented yet\n");
-  return -1;
+  e1ap_upcp_inst_t *e1_inst = getCxtE1(UPtype, instance);
+  if (!e1_inst) {
+    LOG_E(E1AP, "got BEARER_CONTEXT_MODIFICATION_REQUEST on not established instance (%ld)\n", instance);
+    return -1;
+  }
+  
+  DevAssert(pdu != NULL);
+  AssertFatal(pdu->present == E1AP_E1AP_PDU_PR_initiatingMessage,
+              "pdu->present != E1AP_E1AP_PDU_PR_initiatingMessage\n");
+  AssertFatal(pdu->choice.initiatingMessage->procedureCode == E1AP_ProcedureCode_id_bearerContextModification,
+              "procedureCode != E1AP_ProcedureCode_id_bearerContextModification\n");
+  AssertFatal(pdu->choice.initiatingMessage->criticality == E1AP_Criticality_reject,
+              "criticality != E1AP_Criticality_reject\n");
+  AssertFatal(pdu->choice.initiatingMessage->value.present == E1AP_InitiatingMessage__value_PR_BearerContextModificationRequest,
+              "initiatingMessage->value.present != E1AP_InitiatingMessage__value_PR_BearerContextModificationRequest\n");
+
+  E1AP_BearerContextModificationRequest_t *in = &pdu->choice.initiatingMessage->value.choice.BearerContextModificationRequest;
+  E1AP_BearerContextModificationRequestIEs_t *ie;
+
+  MessageDef *msg = itti_alloc_new_message(TASK_CUUP_E1, 0, E1AP_BEARER_CONTEXT_MODIFICATION_REQ);
+
+  e1ap_bearer_setup_req_t *bearerCxt = &E1AP_BEARER_CONTEXT_SETUP_REQ(msg);
+  LOG_I(E1AP, "Bearer context setup number of IEs %d\n", in->protocolIEs.list.count);
+
+  for (int i=0; i < in->protocolIEs.list.count; i++) {
+    ie = in->protocolIEs.list.array[i];
+
+    switch(ie->id) {
+      case E1AP_ProtocolIE_ID_id_gNB_CU_CP_UE_E1AP_ID:
+        AssertFatal(ie->criticality == E1AP_Criticality_reject,
+                    "ie->criticality != E1AP_Criticality_reject\n");
+        AssertFatal(ie->value.present == E1AP_BearerContextModificationRequestIEs__value_PR_GNB_CU_CP_UE_E1AP_ID,
+                    "ie->value.present != E1AP_BearerContextModificationRequestIEs__value_PR_GNB_CU_CP_UE_E1AP_ID\n");
+        bearerCxt->gNB_cu_cp_ue_id = ie->value.choice.GNB_CU_CP_UE_E1AP_ID;
+        break;
+
+      case E1AP_ProtocolIE_ID_id_gNB_CU_UP_UE_E1AP_ID:
+        AssertFatal(ie->criticality == E1AP_Criticality_reject,
+                    "ie->criticality != E1AP_Criticality_reject\n");
+        AssertFatal(ie->value.present == E1AP_BearerContextModificationRequestIEs__value_PR_GNB_CU_UP_UE_E1AP_ID,
+                    "ie->value.present != E1AP_BearerContextModificationRequestIEs__value_PR_GNB_CU_UP_UE_E1AP_ID\n");
+        bearerCxt->gNB_cu_up_ue_id = ie->value.choice.GNB_CU_UP_UE_E1AP_ID;
+        break;
+
+      case E1AP_ProtocolIE_ID_id_System_BearerContextModificationRequest:
+        AssertFatal(ie->criticality == E1AP_Criticality_reject,
+                    "ie->criticality != E1AP_Criticality_reject\n");
+        AssertFatal(ie->value.present == E1AP_BearerContextModificationRequestIEs__value_PR_System_BearerContextModificationRequest,
+                    "ie->value.present != E1AP_BearerContextModificationRequestIEs__value_PR_System_BearerContextModificationRequest\n");
+        AssertFatal(ie->value.choice.System_BearerContextModificationRequest.present ==
+                    E1AP_System_BearerContextModificationRequest_PR_nG_RAN_BearerContextModificationRequest,
+                    "ie->value.choice.System_BearerContextSetupRequest.present !="
+                    "E1AP_System_BearerContextModificationRequest_PR_nG_RAN_BearerContextModificationRequest\n");
+        AssertFatal(ie->value.choice.System_BearerContextModificationRequest.choice.nG_RAN_BearerContextModificationRequest,
+                    "nG_RAN_BearerContextModificationRequest is NULL\n");
+        E1AP_ProtocolIE_Container_4932P26_t *msgNGRAN_list = (E1AP_ProtocolIE_Container_4932P26_t *) ie->value.choice.System_BearerContextModificationRequest.choice.nG_RAN_BearerContextModificationRequest;
+        E1AP_NG_RAN_BearerContextModificationRequest_t *msgNGRAN = msgNGRAN_list->list.array[0];
+        AssertFatal(msgNGRAN_list->list.count == 1, "nG_RAN_BearerContextModificationRequest supports only 1 count for now\n");
+        AssertFatal(msgNGRAN->id == E1AP_ProtocolIE_ID_id_PDU_Session_Resource_To_Modify_List,
+                    "msgNGRAN->id (%ld) != E1AP_ProtocolIE_ID_id_PDU_Session_Resource_To_Modify_List\n", msgNGRAN->id);
+        AssertFatal(msgNGRAN->value.present =
+                    E1AP_NG_RAN_BearerContextModificationRequest__value_PR_PDU_Session_Resource_To_Modify_List,
+                    "msgNGRAN->value.present != E1AP_NG_RAN_BearerContextModificationRequest__value_PR_PDU_Session_Resource_To_Modify_List\n");
+
+        E1AP_PDU_Session_Resource_To_Modify_List_t *pdu2ModList = &msgNGRAN->value.choice.PDU_Session_Resource_To_Modify_List;
+        bearerCxt->numPDUSessionsMod = pdu2ModList->list.count;
+        for (int i=0; i < pdu2ModList->list.count; i++) {
+          pdu_session_to_setup_t *pdu = bearerCxt->pduSessionMod + i;
+          E1AP_PDU_Session_Resource_To_Modify_Item_t *pdu2Mod = pdu2ModList->list.array[i];
+
+          pdu->sessionId = pdu2Mod->pDU_Session_ID;
+
+          E1AP_DRB_To_Modify_List_NG_RAN_t *drb2ModList = pdu2Mod->dRB_To_Modify_List_NG_RAN;
+          pdu->numDRB2Modify = drb2ModList->list.count;
+          for (int j=0; j < drb2ModList->list.count; j++) {
+            DRB_nGRAN_to_setup_t *drb = pdu->DRBnGRanModList + j;
+            E1AP_DRB_To_Modify_Item_NG_RAN_t *drb2Mod = drb2ModList->list.array[j];
+
+            drb->id = drb2Mod->dRB_ID;
+
+            E1AP_UP_Parameters_t *dl_up_paramList = drb2Mod->dL_UP_Parameters;
+            drb->numDlUpParam = dl_up_paramList->list.count;
+            for (int k=0; k < dl_up_paramList->list.count; k++) {
+              up_params_t *dl_up_param = drb->DlUpParamList + k;
+              E1AP_UP_Parameters_Item_t *dl_up_param_in = dl_up_paramList->list.array[k]; 
+              if (dl_up_param_in->uP_TNL_Information.choice.gTPTunnel) { // Optional IE
+                AssertFatal(dl_up_param_in->uP_TNL_Information.present = E1AP_UP_TNL_Information_PR_gTPTunnel,
+                            "dl_up_param_in->uP_TNL_Information.present != E1AP_UP_TNL_Information_PR_gTPTunnel\n");
+                BIT_STRING_TO_TRANSPORT_LAYER_ADDRESS_IPv4(&dl_up_param_in->uP_TNL_Information.choice.gTPTunnel->transportLayerAddress,
+                                                           dl_up_param->tlAddress);
+                OCTET_STRING_TO_INT32(&dl_up_param_in->uP_TNL_Information.choice.gTPTunnel->gTP_TEID, dl_up_param->teId);
+              } else {
+                AssertFatal(false, "gTPTunnel IE is missing. It is mandatory at this point\n");
+              }
+              dl_up_param->cell_group_id = dl_up_param_in->cell_Group_ID;
+            }
+          }
+        }
+        break;
+
+      default:
+        LOG_E(E1AP, "Handle for this IE is not implemented (or) invalid IE detected\n");
+        break;
+    }
+  }
+
+  itti_send_msg_to_task(TASK_RRC_GNB, instance, msg);
+  return 0;
 }
 
 int e1apCUCP_handle_BEARER_CONTEXT_MODIFICATION_RESPONSE(instance_t instance,
diff --git a/openair2/E1AP/e1ap.h b/openair2/E1AP/e1ap.h
index 6aa6f9918476833e09e101eb679f176e17a26ad6..5467f98b8fdd74ab34c3b32c0c4d8cc000251663 100644
--- a/openair2/E1AP/e1ap.h
+++ b/openair2/E1AP/e1ap.h
@@ -53,6 +53,9 @@ int e1apCUCP_handle_BEARER_CONTEXT_SETUP_RESPONSE(instance_t instance,
 int e1apCUCP_handle_BEARER_CONTEXT_SETUP_FAILURE(instance_t instance,
                                                  E1AP_E1AP_PDU_t *pdu);
 
+int e1apCUUP_handle_BEARER_CONTEXT_MODIFICATION_REQUEST(instance_t instance,
+                                                        E1AP_E1AP_PDU_t *pdu);
+
 void *E1AP_CUUP_task(void *arg);
 
 void *E1AP_CUCP_task(void *arg);
diff --git a/openair2/E1AP/e1ap_common.c b/openair2/E1AP/e1ap_common.c
index bc0a6d58df92fcf984450b1909b583edc8c0dca6..fc77a22c53a3084f18f3f6372a87481586751a92 100644
--- a/openair2/E1AP/e1ap_common.c
+++ b/openair2/E1AP/e1ap_common.c
@@ -51,11 +51,12 @@ 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));
     memcpy(&e1ap_up_inst[instance]->setupReq, req, sizeof(e1ap_setup_req_t));
+    e1ap_up_inst[instance]->gtpInstN3 = E1AP_GTP_INST_N3;
+    e1ap_up_inst[instance]->gtpInstF1U = E1AP_GTP_INST_F1U;
   } else {
     AssertFatal(false, "Unknown CU type\n");
   }
@@ -121,6 +122,9 @@ int e1ap_decode_initiating_message(E1AP_E1AP_PDU_t *pdu) {
     case E1AP_ProcedureCode_id_bearerContextSetup:
       break;
 
+    case E1AP_ProcedureCode_id_bearerContextModification:
+      break;
+
     default:
       LOG_E(E1AP, "Unsupported procedure code (%d) for initiating message\n",
             (int)pdu->choice.initiatingMessage->procedureCode);
diff --git a/openair2/E1AP/e1ap_common.h b/openair2/E1AP/e1ap_common.h
index 26e632913f8b04af7ce78a73a1158c84bce8ff2f..46d6524a7a41a5f7b61eb37981aa8f2ac4b951e7 100644
--- a/openair2/E1AP/e1ap_common.h
+++ b/openair2/E1AP/e1ap_common.h
@@ -53,6 +53,10 @@
 #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_PDU-Session-Resource-To-Modify-List.h>
+#include <E1AP_PDU-Session-Resource-To-Modify-Item.h>
+#include <E1AP_DRB-To-Modify-List-NG-RAN.h>
+#include <E1AP_DRB-To-Modify-Item-NG-RAN.h>
 #include <E1AP_GTPTunnel.h>
 #include <E1AP_Non-Dynamic5QIDescriptor.h>
 #include <E1AP_Dynamic5QIDescriptor.h>
diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c
index 4a406bfc8a5bf0ada2a537fbad2996691e88e2c8..b2c2d3a7aa8be7432853e5afc83beb9f9c7a8028 100755
--- a/openair2/RRC/NR/rrc_gNB.c
+++ b/openair2/RRC/NR/rrc_gNB.c
@@ -3597,27 +3597,28 @@ 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;
+  for (int i=0; i < req->numPDUSessionsMod; i++) {
+    for (int j=0; j < req->pduSessionMod[i].numDRB2Modify; j++) {
+      DRB_nGRAN_to_setup_t *drb_p = req->pduSessionMod[i].DRBnGRanModList + j;
 
       transport_layer_addr_t newRemoteAddr;
       newRemoteAddr.length = 32; // IPv4
       memcpy(newRemoteAddr.buffer,
-             &drb_p->tlAddress,
+             &drb_p->DlUpParamList[0].tlAddress,
              sizeof(in_addr_t));
 
       GtpuUpdateTunnelOutgoingPair(instance,
                                    ue_id,
                                    (ebi_t)drb_p->id,
-                                   drb_p->teId,
+                                   drb_p->DlUpParamList[0].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);
+  instance_t gtpInst = getCxtE1(UPtype, instance)->gtpInstF1U;
+  update_UL_UP_tunnel_info(req, gtpInst, req->gNB_cu_cp_ue_id);
   // TODO: send bearer cxt mod response
 }
 
@@ -3652,18 +3653,19 @@ static void rrc_CU_process_ue_context_modification_response(MessageDef *msg_p, c
 
   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->numPDUSessionsMod = 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 i=0; i < req->numPDUSessionsMod; i++) {
+    req->pduSessionMod[i].numDRB2Modify = 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_nGRAN_to_setup_t *drb_e1 = req->pduSessionMod[i].DRBnGRanModList + 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;
+      drb_e1->numDlUpParam = drb_f1->up_dl_tnl_length;
+      drb_e1->DlUpParamList[0].tlAddress = drb_f1->up_dl_tnl[0].tl_address;
+      drb_e1->DlUpParamList[0].teId = drb_f1->up_dl_tnl[0].teid;
     }
   }
 
@@ -4167,7 +4169,8 @@ void rrc_gNB_process_e1_bearer_context_setup_req(e1ap_bearer_setup_req_t *req, i
   gtpv1u_gnb_create_tunnel_resp_t create_tunnel_resp_N3={0};
 
   // GTP tunnel for UL
-  drb_config_N3gtpu_create_e1(req, &create_tunnel_resp_N3, instance);
+  instance_t gtpInst = getCxtE1(UPtype, instance)->gtpInstN3;
+  drb_config_N3gtpu_create_e1(req, &create_tunnel_resp_N3, gtpInst);
 
   MessageDef *message_p;
   message_p = itti_alloc_new_message (TASK_RRC_GNB, instance, E1AP_BEARER_CONTEXT_SETUP_RESP);
@@ -4175,10 +4178,12 @@ void rrc_gNB_process_e1_bearer_context_setup_req(e1ap_bearer_setup_req_t *req, i
 
   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);
+  inet_pton(AF_INET,
+            getCxtE1(UPtype, instance)->setupReq.CUUP_e1_ip_address.ipv4_address,
+            &my_addr);
+
+  gtpInst = getCxtE1(UPtype, instance)->gtpInstF1U;
+  gNB_CU_create_up_ul_tunnel(resp, req, gtpInst, 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;
@@ -4278,6 +4283,11 @@ 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
+  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);
+
+  fill_DRB_configList(&ctxt, ue_context_p);
   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));
@@ -4487,6 +4497,11 @@ void *rrc_gnb_task(void *args_p) {
         rrc_gNB_process_e1_bearer_context_setup_resp(&E1AP_BEARER_CONTEXT_SETUP_RESP(msg_p), instance);
         break;
 
+      case E1AP_BEARER_CONTEXT_MODIFICATION_REQ:
+        LOG_I(NR_RRC, "Received E1AP_BEARER_CONTEXT_MODIFICATION_REQ for instance %d\n", (int)instance);
+        rrc_CUUP_process_bearer_context_mod_req(&E1AP_BEARER_CONTEXT_SETUP_REQ(msg_p), instance);
+        break;
+
       default:
         LOG_E(NR_RRC, "[gNB %ld] Received unexpected message %s\n", instance, msg_name_p);
         break;