diff --git a/openair2/ENB_APP/flexran_agent_common_internal.c b/openair2/ENB_APP/flexran_agent_common_internal.c
index e3fac4594b9c0976961b2890c05842b7721f3c1c..416f13f24168cda24ab978cc58e7560fb48d3182 100644
--- a/openair2/ENB_APP/flexran_agent_common_internal.c
+++ b/openair2/ENB_APP/flexran_agent_common_internal.c
@@ -32,45 +32,37 @@
 #include "flexran_agent_common_internal.h"
 #include "flexran_agent_mac_internal.h"
 
-/* the following is needed to soft-restart the lte-softmodem */
+/* needed to soft-restart the lte-softmodem */
 #include "targets/RT/USER/lte-softmodem.h"
-#include "assertions.h"
-#include "enb_app.h"
 
-#if 0
 void handle_reconfiguration(mid_t mod_id)
 {
-  /* NOTE: this function might be extended by using stop_modem()
-   * to halt the modem so that it can later be resumed */
-  int do_restart = 0;
-
-  pthread_mutex_lock(&mutex_node_ctrl);
-  if (ENB_NORMAL_OPERATION != node_control_state) {
-    node_control_state = ENB_NORMAL_OPERATION;
-    pthread_cond_broadcast(&cond_node_ctrl);
-  } else {
-    do_restart = 1;
+  struct timespec start, end;
+  clock_gettime(CLOCK_MONOTONIC, &start);
+
+  if (stop_L1L2(mod_id) < 0) {
+    LOG_E(ENB_APP, "can not stop lte-softmodem, aborting restart\n");
+    return;
+  }
+
+  /* TODO wait state could be here IF IT IS NOT EXECUTED BY THE FLEXRAN THREAD */
+
+  if (restart_L1L2(mod_id) < 0) {
+    LOG_F(ENB_APP, "can not restart, killing lte-softmodem\n");
+    itti_terminate_tasks(TASK_PHY_ENB);
+    return;
   }
-  pthread_mutex_unlock(&mutex_node_ctrl);
-
-  if (do_restart) {
-    clock_t start_ms = 1000 * clock();
-    /* operator || enforces sequence points */
-    if (stop_L1L2(mod_id) < 0 || restart_L1L2(mod_id) < 0) {
-      LOG_E(ENB_APP, "could not restart, killing lte-softmodem\n");
-      /* shutdown the whole lte-softmodem */
-      itti_terminate_tasks(TASK_PHY_ENB);
-      return;
-    }
-    enb_app_start_phy_rrc(mod_id, mod_id+1);
-    MessageDef *msg_p = itti_alloc_new_message(TASK_ENB_APP, INITIALIZE_MESSAGE);
-    itti_send_msg_to_task(TASK_L2L1, INSTANCE_DEFAULT, msg_p);
 
-    int diff_ms = (1000 * clock() - start_ms) / CLOCKS_PER_SEC;
-    LOG_I(ENB_APP, "lte-softmodem restart succeeded in %d ms\n", diff_ms);
+  clock_gettime(CLOCK_MONOTONIC, &end);
+  end.tv_sec -= start.tv_sec;
+  if (end.tv_nsec >= start.tv_nsec) {
+    end.tv_nsec -= start.tv_nsec;
+  } else {
+    end.tv_sec -= 1;
+    end.tv_nsec = end.tv_nsec - start.tv_nsec + 1000000000;
   }
+  LOG_I(ENB_APP, "lte-softmodem restart succeeded in %ld.%ld s\n", end.tv_sec, end.tv_nsec / 1000000);
 }
-#endif
 
 int apply_reconfiguration_policy(mid_t mod_id, const char *policy, size_t policy_length) {
 
@@ -111,8 +103,7 @@ int apply_reconfiguration_policy(mid_t mod_id, const char *policy, size_t policy
 	if (parse_enb_id(mod_id, &parser) == -1) {
 	  goto error;
 	} else { // succeful parse and setting 
-          /* TODO implement */
-          //handle_reconfiguration(mod_id);
+          handle_reconfiguration(mod_id);
 	}
       } else if (strcmp((char *) event.data.scalar.value, "mac") == 0) {
 	LOG_D(ENB_APP, "This is intended for the mac system\n");
@@ -265,9 +256,9 @@ int parse_enb_config_parameters(mid_t mod_id, yaml_parser_t *parser) {
       } else if (strcmp((char *) event.data.scalar.value, "ul_freq_offset") == 0) {
         if (!yaml_parser_parse(parser, &event))
           goto error;
-	flexran_agent_set_operating_ul_freq(mod_id,
-					    0,
-					    strtol((char *) event.data.scalar.value, &endptr, 10));
+        flexran_agent_set_operating_ul_freq(mod_id,
+                                            0,
+                                            strtol((char *) event.data.scalar.value, &endptr, 10));
         LOG_I(ENB_APP, "Setting ul_freq_offset to %s\n", event.data.scalar.value);
       } else if (strcmp((char *) event.data.scalar.value, "bandwidth") == 0) {
         if (!yaml_parser_parse(parser, &event))
@@ -296,8 +287,6 @@ int parse_enb_config_parameters(mid_t mod_id, yaml_parser_t *parser) {
     yaml_event_delete(&event);
   }
 
-  /* TODO: reflect in RAN API */
-
   return 0;
   
  error:
diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c
index 181150c672a26e743a4e6cd499458cb8ea2b0a0d..c8db435d4672aaf4646b8e7c660bab9cb9ff09cd 100644
--- a/targets/RT/USER/lte-softmodem.c
+++ b/targets/RT/USER/lte-softmodem.c
@@ -872,11 +872,11 @@ void wait_eNBs(void) {
   printf("eNB L1 are configured\n");
 }
 
-#if defined(ENABLE_ITTI) && defined(FLEXRAN_AGENT_SB_IF)
+#if defined(ENABLE_ITTI)
 /*
  * helper function to terminate a certain ITTI task
  */
-void terminate_task(task_id_t task_id, mid_t mod_id)
+void terminate_task(task_id_t task_id, module_id_t mod_id)
 {
   LOG_I(ENB_APP, "sending TERMINATE_MESSAGE to task %s (%d)\n", itti_get_task_name(task_id), task_id);
   MessageDef *msg;
@@ -884,70 +884,71 @@ void terminate_task(task_id_t task_id, mid_t mod_id)
   itti_send_msg_to_task (task_id, ENB_MODULE_ID_TO_INSTANCE(mod_id), msg);
 }
 
-#if 0
-int stop_L1L2(int enb_id)
+int stop_L1L2(module_id_t enb_id)
 {
-  int CC_id;
-
   LOG_W(ENB_APP, "stopping lte-softmodem\n");
   oai_exit = 1;
 
-  /* stop trx devices */
-  for(CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
-    if (PHY_vars_eNB_g[0][CC_id]->rfdevice.trx_stop_func) {
-        LOG_I(ENB_APP, "stopping PHY_vars_eNB_g[0][%d]->rfdevice (via trx_stop_func())\n", CC_id);
-        PHY_vars_eNB_g[0][CC_id]->rfdevice.trx_stop_func(&PHY_vars_eNB_g[0][CC_id]->rfdevice);
+  if (!RC.ru) {
+    LOG_F(ENB_APP, "no RU configured\n");
+    return -1;
+  }
+
+  /* stop trx devices, multiple carrier currently not supported by RU */
+  if (RC.ru[enb_id]) {
+    if (RC.ru[enb_id]->rfdevice.trx_stop_func) {
+      RC.ru[enb_id]->rfdevice.trx_stop_func(&RC.ru[enb_id]->rfdevice);
+      LOG_I(ENB_APP, "turned off RU rfdevice\n");
+    } else {
+      LOG_W(ENB_APP, "can not turn off rfdevice due to missing trx_stop_func callback, proceding anyway!\n");
     }
-    if (PHY_vars_eNB_g[0][CC_id]->ifdevice.trx_stop_func) {
-        LOG_I(ENB_APP, "stopping PHY_vars_eNB_g[0][%d]->ifdevice (via trx_stop_func())\n", CC_id);
-        PHY_vars_eNB_g[0][CC_id]->ifdevice.trx_stop_func(&PHY_vars_eNB_g[0][CC_id]->ifdevice);
+    if (RC.ru[enb_id]->ifdevice.trx_stop_func) {
+      RC.ru[enb_id]->ifdevice.trx_stop_func(&RC.ru[enb_id]->ifdevice);
+      LOG_I(ENB_APP, "turned off RU ifdevice\n");
+    } else {
+      LOG_W(ENB_APP, "can not turn off ifdevice due to missing trx_stop_func callback, proceding anyway!\n");
     }
+  } else {
+    LOG_W(ENB_APP, "no RU found for index %d\n", enb_id);
+    return -1;
   }
 
   /* these tasks need to pick up new configuration */
   terminate_task(TASK_RRC_ENB, enb_id);
   terminate_task(TASK_L2L1, enb_id);
-  LOG_W(ENB_APP, "calling kill_eNB_proc() for instance %d\n", enb_id);
+  LOG_I(ENB_APP, "calling kill_eNB_proc() for instance %d\n", enb_id);
   kill_eNB_proc(enb_id);
+  LOG_I(ENB_APP, "calling kill_RU_proc() for instance %d\n", enb_id);
+  kill_RU_proc(enb_id);
   oai_exit = 0;
   return 0;
 }
 
 /*
- * Restart the lte-softmodem.
- * This function checks whether we are in ENB_NORMAL_OPERATION (defined by
- * FlexRAN). If yes, first stop L1/L2/L3, then resume.
+ * Restart the lte-softmodem after it has been soft-stopped with stop_L1L2()
  */
-int restart_L1L2(int enb_id)
+int restart_L1L2(module_id_t enb_id)
 {
-  int i, aa, CC_id;
-  /* needed for fill_PHY_vars_eNB_g(), defined locally in main();
-   * abstraction flag is needed too, but defined both globally and in main () */
-  uint8_t beta_ACK = 0, beta_RI = 0, beta_CQI = 2;
-  /* needed for macphy_init() */
-  int eMBMS_active = 0;
+  RU_t *ru = RC.ru[enb_id];
+  int cc_id;
+  MessageDef *msg_p = NULL;
 
   LOG_W(ENB_APP, "restarting lte-softmodem\n");
 
   /* block threads */
   sync_var = -1;
 
-  reconfigure_enb_params(enb_id);     /* set frame parameters from configuration */
-
-  /* PHY_vars_eNB_g will be filled by init_lte_eNB(), so free and
-   * let the data structure be filled again */
-  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
-    free(PHY_vars_eNB_g[0][CC_id]);
-    fill_PHY_vars_eNB_g(abstraction_flag, beta_ACK, beta_RI, beta_CQI);
+  for (cc_id = 0; cc_id < RC.nb_L1_CC[enb_id]; cc_id++) {
+    RC.eNB[enb_id][cc_id]->configured = 0;
   }
 
-  dump_frame_parms(frame_parms[0]);
-  init_openair0();
 
-  /* give MAC interface current cell information, the rest is the same.
-   * For more info, check l2_init(). Then, initialize it (cf. line 1904). */
-  mac_xface->frame_parms = frame_parms[0];
-  mac_xface->macphy_init(eMBMS_active,(uecap_xer_in==1)?uecap_xer:NULL,0,0);
+  /* TODO undo malloc_IF4p5_buffer() */
+  RC.ru_mask |= (1 << ru->idx);
+  /* copy the changed frame parameters to the RU */
+  /* TODO this should be done for all RUs associated to this eNB */
+  memcpy(&ru->frame_parms, &RC.eNB[enb_id][0]->frame_parms, sizeof(LTE_DL_FRAME_PARMS));
+  set_function_spec_param(RC.ru[enb_id]);
 
   LOG_I(ENB_APP, "attempting to create ITTI tasks\n");
   if (itti_create_task (TASK_RRC_ENB, rrc_enb_task, NULL) < 0) {
@@ -963,28 +964,26 @@ int restart_L1L2(int enb_id)
     LOG_I(PDCP, "Re-created task for L2L1 successfully\n");
   }
 
+  /* pass a reconfiguration request which will configure everything down to
+   * RC.eNB[i][j]->frame_parms, too */
+  msg_p = itti_alloc_new_message(TASK_ENB_APP, RRC_CONFIGURATION_REQ);
+  RRC_CONFIGURATION_REQ(msg_p) = RC.rrc[enb_id]->configuration;
+  itti_send_msg_to_task(TASK_RRC_ENB, ENB_MODULE_ID_TO_INSTANCE(enb_id), msg_p);
+
   /* TODO XForms here */
 
-  printf("Initializing eNB threads\n");
-  init_eNB(node_function, node_timing, 1, eth_params, single_thread_flag, wait_for_sync);
-  for(CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
-      PHY_vars_eNB_g[0][CC_id]->rf_map.card=0;
-      PHY_vars_eNB_g[0][CC_id]->rf_map.chain=CC_id+chain_offset;
-  }
+  /* TODO check for memory leaks */
+  /* TODO wait_eNBs() would wait for phy_config_request()? */
+  //init_eNB(single_thread_flag,wait_for_sync);
+  wait_eNBs();
+  init_RU_proc(ru);
+  ru->rf_map.card = 0;
+  ru->rf_map.chain = 0; /* CC_id + chain_offset;*/
+  wait_RUs();
+  init_eNB_afterRU();
 
-  mlockall(MCL_CURRENT | MCL_FUTURE);
-
-  printf("Setting eNB buffer to all-RX\n");
-  // Set LSBs for antenna switch (ExpressMIMO)
-  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
-    PHY_vars_eNB_g[0][CC_id]->hw_timing_advance = 0;
-    for (i=0; i<frame_parms[CC_id]->samples_per_tti*10; i++)
-      for (aa=0; aa<frame_parms[CC_id]->nb_antennas_tx; aa++)
-        PHY_vars_eNB_g[0][CC_id]->common_vars.txdata[0][aa][i] = 0x00010001;
-  }
 
   printf("Sending sync to all threads\n");
-
   pthread_mutex_lock(&sync_mutex);
   sync_var=0;
   pthread_cond_broadcast(&sync_cond);
@@ -993,7 +992,6 @@ int restart_L1L2(int enb_id)
   return 0;
 }
 #endif
-#endif
 
 int main( int argc, char **argv )
 {
diff --git a/targets/RT/USER/lte-softmodem.h b/targets/RT/USER/lte-softmodem.h
index c1d63eef4c39e90565363efbfaeef5b71d0ec7c8..c6f8d8d54c12157b586399192c0c057fd614f877 100644
--- a/targets/RT/USER/lte-softmodem.h
+++ b/targets/RT/USER/lte-softmodem.h
@@ -268,8 +268,8 @@ PHY_VARS_UE* init_ue_vars(LTE_DL_FRAME_PARMS *frame_parms,
                           uint8_t abstraction_flag);
 void init_eNB_afterRU(void);
 
-extern int stop_L1L2(int enb_id);
-extern int restart_L1L2(int enb_id);
+extern int stop_L1L2(module_id_t enb_id);
+extern int restart_L1L2(module_id_t enb_id);
 
 #ifdef FLEXRAN_AGENT_SB_IF
 #include "flexran_agent.h" // for locking