From e13c962d24c0f66a6ae5d39db6d7b3bec206bff0 Mon Sep 17 00:00:00 2001
From: "yoshio.inoue" <yoshio.inoue@jp.fujitsu.com>
Date: Fri, 2 Nov 2018 16:54:19 +0900
Subject: [PATCH] Fixed bug that u-plane is not transferred with multiple UEs

---
 openair2/LAYER2/PDCP_v10.1.0/pdcp.c      | 14 ++++++++++--
 openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c | 15 +++++++++++--
 openair2/NETWORK_DRIVER/UE_IP/common.c   | 11 +++++++++-
 openair2/NETWORK_DRIVER/UE_IP/device.c   | 10 ++++-----
 openair3/NAS/UE/ESM/esm_ebr_context.c    | 28 +++++++++++++++++++++---
 targets/RT/USER/lte-uesoftmodem.c        | 12 ++++++++--
 6 files changed, 75 insertions(+), 15 deletions(-)

diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c
index b16b7ad062..0112fe10ef 100755
--- a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c
+++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c
@@ -64,7 +64,9 @@
 #endif
 
 extern int otg_enabled;
-
+#if defined(ENABLE_USE_MME)
+extern uint8_t nfapi_mode;
+#endif
 #include "common/ran_context.h"
 extern RAN_CONTEXT_t RC;
 hash_table_t  *pdcp_coll_p = NULL;
@@ -796,7 +798,15 @@ pdcp_data_ind(
          * for the UE compiled in noS1 mode, we need 0
          * TODO: be sure of this
          */
-        ((pdcp_data_ind_header_t*) new_sdu_p->data)->inst  = 1;
+        if (nfapi_mode == 3) {
+#ifdef UESIM_EXPANSION
+          ((pdcp_data_ind_header_t*) new_sdu_p->data)->inst  = 1;
+#else
+          ((pdcp_data_ind_header_t*) new_sdu_p->data)->inst  = ctxt_pP->module_id + 1;
+#endif
+        } else {
+          ((pdcp_data_ind_header_t*) new_sdu_p->data)->inst  = 1;
+        }
 #endif
       } else {
         ((pdcp_data_ind_header_t*) new_sdu_p->data)->rb_id = rb_id + (ctxt_pP->module_id * maxDRB);
diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c
index 3b0283525e..0a49c7d94c 100755
--- a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c
+++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c
@@ -82,10 +82,13 @@ extern struct msghdr nas_msg_tx;
 extern struct msghdr nas_msg_rx;
 
 unsigned char pdcp_read_state_g = 0;
+extern uint8_t nfapi_mode;
+#ifdef UESIM_EXPANSION
+extern uint16_t inst_pdcp_list[NUMBER_OF_UE_MAX];
+#endif
 #endif
 
 extern Packet_OTG_List_t *otg_pdcp_buffer;
-extern uint8_t nfapi_mode;
 #if defined(LINK_ENB_PDCP_TO_GTPV1U)
 #  include "gtpv1u_eNB_task.h"
 #  include "gtpv1u_eNB_defs.h"
@@ -931,7 +934,15 @@ int pdcp_fifo_read_input_sdus (const protocol_ctxt_t* const  ctxt_pP)
             rab_id      = pdcp_read_header_g.rb_id % maxDRB;
             ctxt.rnti          = pdcp_eNB_UE_instance_to_rnti[pdcp_read_header_g.rb_id / maxDRB];
           } else {
-            ctxt.module_id = 0;
+            if (nfapi_mode == 3) {
+#ifdef UESIM_EXPANSION
+              ctxt.module_id = inst_pdcp_list[pdcp_read_header_g.inst];
+#else
+              ctxt.module_id = pdcp_read_header_g.inst - 1;
+#endif
+            } else {
+              ctxt.module_id = 0;
+            }
             rab_id      = pdcp_read_header_g.rb_id % maxDRB;
             ctxt.rnti          = pdcp_UE_UE_module_id_to_rnti[ctxt.module_id];
           }
diff --git a/openair2/NETWORK_DRIVER/UE_IP/common.c b/openair2/NETWORK_DRIVER/UE_IP/common.c
index b21ca5f2dc..1b15ea8aed 100644
--- a/openair2/NETWORK_DRIVER/UE_IP/common.c
+++ b/openair2/NETWORK_DRIVER/UE_IP/common.c
@@ -304,7 +304,16 @@ ue_ip_common_ip2wireless(
     if (dst_addr) {
       printk("[UE_IP_DRV][%s] Dest %d.%d.%d.%d\n",__FUNCTION__, dst_addr[0],dst_addr[1],dst_addr[2],dst_addr[3]);
     }
-
+    // modify inst by IP address for the U-Plane of multiple UEs while L2 fapi simulator start
+#ifdef UESIM_EXPANSION
+    if ((src_addr[3] - 1)> instP) {
+        pdcph.inst = src_addr[3] - 1;
+        printk("[UE_IP_DRV] change INST from %d to %d\n",instP, pdcph.inst);
+        instP = src_addr[3] - 1;
+        priv_p=netdev_priv(ue_ip_dev[instP]);
+    }
+#endif
+    // modify inst by IP address for the U-Plane of multiple UEs while L2 fapi simulator end
     //get Ipv4 address and pass to PCDP header
     printk("[UE_IP_DRV] source Id: 0x%08x\n",pdcph.sourceL2Id );
     printk("[UE_IP_DRV] destinationL2Id Id: 0x%08x\n",pdcph.destinationL2Id );
diff --git a/openair2/NETWORK_DRIVER/UE_IP/device.c b/openair2/NETWORK_DRIVER/UE_IP/device.c
index 47c820fe77..e67f67d6e3 100644
--- a/openair2/NETWORK_DRIVER/UE_IP/device.c
+++ b/openair2/NETWORK_DRIVER/UE_IP/device.c
@@ -61,7 +61,7 @@ int ue_ip_find_inst(struct net_device *dev_pP)
   //---------------------------------------------------------------------------
   int i;
 
-  for (i=0; i<UE_IP_NB_INSTANCES_MAX; i++)
+  for (i=1; i<=UE_IP_NB_INSTANCES_MAX; i++)
     if (ue_ip_dev[i] == dev_pP) {
       return(i);
     }
@@ -194,7 +194,7 @@ void ue_ip_teardown(struct net_device *dev_pP)
     priv_p = netdev_priv(dev_pP);
     inst = ue_ip_find_inst(dev_pP);
 
-    if ((inst<0) || (inst>=UE_IP_NB_INSTANCES_MAX)) {
+    if ((inst<=0) || (inst>UE_IP_NB_INSTANCES_MAX)) {
       printk("[UE_IP_DRV][%s] ERROR, couldn't find instance\n", __FUNCTION__);
       return;
     }
@@ -243,7 +243,7 @@ int ue_ip_hard_start_xmit(struct sk_buff *skb_pP, struct net_device *dev_pP)
     return -1;
   }
 
-  if ((inst>=0) && (inst<UE_IP_NB_INSTANCES_MAX)) {
+  if ((inst>0) && (inst<=UE_IP_NB_INSTANCES_MAX)) {
 #ifdef OAI_DRV_OAI_DRV_DEBUG_DEVICE
     printk("[UE_IP_DRV][%s] inst %d,  begin\n", __FUNCTION__,inst);
 #endif
@@ -392,7 +392,7 @@ int init_module (void)
   // Initialize parameters shared with RRC
   printk("[UE_IP_DRV][%s] Starting OAI IP driver", __FUNCTION__);
 
-  for (inst=0; inst<UE_IP_NB_INSTANCES_MAX; inst++) {
+  for (inst=1; inst<=UE_IP_NB_INSTANCES_MAX; inst++) {
     printk("[UE_IP_DRV][%s] begin init instance %d\n", __FUNCTION__,inst);
     sprintf(devicename,"oip%d",inst);
 #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 17, 0)
@@ -434,7 +434,7 @@ void cleanup_module(void)
 
   printk("[UE_IP_DRV][CLEANUP] begin\n");
 
-  for (inst=0; inst<UE_IP_NB_INSTANCES_MAX; inst++) {
+  for (inst=1; inst<=UE_IP_NB_INSTANCES_MAX; inst++) {
 #ifdef OAI_DRV_DEBUG_DEVICE
     printk("[UE_IP_DRV][CLEANUP]  unregister and free net device instance %d\n",inst);
 #endif
diff --git a/openair3/NAS/UE/ESM/esm_ebr_context.c b/openair3/NAS/UE/ESM/esm_ebr_context.c
index 25d3bea6ea..3dddab5b74 100755
--- a/openair3/NAS/UE/ESM/esm_ebr_context.c
+++ b/openair3/NAS/UE/ESM/esm_ebr_context.c
@@ -57,7 +57,12 @@ Description Defines functions used to handle EPS bearer contexts.
 #include <sys/socket.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
-
+#ifdef PDCP_USE_NETLINK
+#ifdef UESIM_EXPANSION
+  #include "openairinterface5g_limits.h"
+  extern uint16_t inst_pdcp_list[NUMBER_OF_UE_MAX];
+#endif
+#endif
 extern uint8_t  nfapi_mode;
 
 /****************************************************************************/
@@ -277,15 +282,32 @@ int esm_ebr_context_create(
                 // this is for L2 FAPI simulator.
                 // change for multiple UE's like 256UEs.
                 // if it's made too many tables , OS may crush so we use one table.
+#ifdef PDCP_USE_NETLINK
+#ifdef UESIM_EXPANSION
+                uint16_t inst_nic = (pdn->ip_addr[3] & 0x000000FF) - 1;
                 res = sprintf(command_line,
                            "ifconfig oip%d %s netmask %s broadcast %s up && "
                            "ip rule add from %s/24 table %d && "
                            "ip rule add to %s/24 table %d && "
                            "ip route add default dev oip%d table %d",
-                           ueid+1, ipv4_addr, netmask, broadcast,
+                           inst_nic, ipv4_addr, netmask, broadcast,
                            ipv4_addr, 201,
                            ipv4_addr, 201,
-                           ueid+1, 201);
+                           inst_nic, 201);
+
+               inst_pdcp_list[inst_nic] = ueid;
+#else
+               res = sprintf(command_line,
+                          "ifconfig oip%d %s netmask %s broadcast %s up && "
+                          "ip rule add from %s/32 table %d && "
+                          "ip rule add to %s/32 table %d && "
+                          "ip route add default dev oip%d table %d",
+                          ueid + 1, ipv4_addr, netmask, broadcast,
+                          ipv4_addr, ueid + 201,
+                          ipv4_addr, ueid + 201,
+                          ueid + 1, ueid + 201);
+#endif
+#endif
              } else {
                res = sprintf(command_line,
                            "ifconfig oip%d %s netmask %s broadcast %s up && "
diff --git a/targets/RT/USER/lte-uesoftmodem.c b/targets/RT/USER/lte-uesoftmodem.c
index be8a30c1bd..9ae1ead95e 100755
--- a/targets/RT/USER/lte-uesoftmodem.c
+++ b/targets/RT/USER/lte-uesoftmodem.c
@@ -115,7 +115,11 @@ pthread_mutex_t nfapi_sync_mutex;
 int nfapi_sync_var=-1; //!< protected by mutex \ref nfapi_sync_mutex
 
 uint8_t nfapi_mode = 0;
-
+#ifdef PDCP_USE_NETLINK
+#ifdef UESIM_EXPANSION
+uint16_t inst_pdcp_list[NUMBER_OF_UE_MAX];
+#endif
+#endif
 uint16_t sf_ahead=2;
 int tddflag;
 char *emul_iface;
@@ -821,7 +825,11 @@ int main( int argc, char **argv )
   int CC_id;
   uint8_t  abstraction_flag=0;
   unsigned int start_msc=0;
-
+#ifdef PDCP_USE_NETLINK
+#ifdef UESIM_EXPANSION
+  memset(inst_pdcp_list, 0, sizeof(inst_pdcp_list));
+#endif
+#endif
   // Default value for the number of UEs. It will hold,
   // if not changed from the command line option --num-ues
   NB_UE_INST=1;
-- 
GitLab