From c3bc4f6359eaf53e8eed029331da00a339e292af Mon Sep 17 00:00:00 2001
From: Lionel Gauthier <lionel.gauthier@eurecom.fr>
Date: Fri, 28 Nov 2014 17:48:19 +0000
Subject: [PATCH] more parameters in config for S1U

git-svn-id: http://svn.eurecom.fr/openair4G/trunk@6119 818b1a75-f10b-46b9-bf7c-635c3b92a50f
---
 openair-cn/SGW-LITE/sgw_lite_handlers.c |   1 +
 openair-cn/SGW-LITE/spgw_config.c       | 150 +++++++++++++++---------
 openair-cn/SGW-LITE/spgw_config.h       |   9 ++
 3 files changed, 107 insertions(+), 53 deletions(-)

diff --git a/openair-cn/SGW-LITE/sgw_lite_handlers.c b/openair-cn/SGW-LITE/sgw_lite_handlers.c
index c9a9072580..f935b0e684 100644
--- a/openair-cn/SGW-LITE/sgw_lite_handlers.c
+++ b/openair-cn/SGW-LITE/sgw_lite_handlers.c
@@ -698,6 +698,7 @@ sgw_lite_handle_sgi_endpoint_updated(
             if (iptable_uplink_remove_gtpu == FALSE) {
                 ret = snprintf(cmd,
                         256,
+                        // no "-p udp --dport 2152" because of fragmented packets
                         "iptables -t raw -I PREROUTING -i %s -s %u.%u.%u.%u -d %u.%u.%u.%u -p udp --dport 2152 -j GTPURH --action remove",
                         sgw_app.sgw_interface_name_for_S1u_S12_S4_up,
                         eps_bearer_entry_p->enb_ip_address_for_S1u.address.ipv4_address[0],
diff --git a/openair-cn/SGW-LITE/spgw_config.c b/openair-cn/SGW-LITE/spgw_config.c
index e70c3da0e8..e1a805be96 100755
--- a/openair-cn/SGW-LITE/spgw_config.c
+++ b/openair-cn/SGW-LITE/spgw_config.c
@@ -51,6 +51,12 @@
 #include "sgw_lite_defs.h"
 #include "intertask_interface.h"
 
+#ifdef LIBCONFIG_LONG
+#define libconfig_int long
+#else
+#define libconfig_int int
+#endif
+
 #define NIPADDR(addr) \
         (uint8_t)(addr & 0x000000FF), \
         (uint8_t)((addr & 0x0000FF00) >> 8), \
@@ -124,44 +130,6 @@ sgw_ipv6_mask_in6_addr(
     }
 }
 
-
-/*int is_valid_ip_address(char *addr_pP, int ai_familyP , struct sockaddr *sock_addr_pP) {
-    struct addrinfo      hints;
-    struct addrinfo     *result, *rp;
-    int                  sfd, s;
-
-    if (addr_pP == NULL) {
-        SPGW_APP_ERROR("Bad parameter addr is NULL\n");
-        return 0;
-    }
-    if ((ai_familyP != AF_INET) && (ai_familyP != AF_INET6)) {
-        SPGW_APP_ERROR("Bad parameter ai_family:%d\n", ai_familyP);
-        return 0;
-    }
-    memset(&hints, 0, sizeof(struct addrinfo));
-    hints.ai_family    = ai_familyP;    //  AF_INET, AF_INET6
-    hints.ai_socktype  = 0;             // UDP or TCP
-    hints.ai_flags     = AI_PASSIVE;    // For wildcard IP address
-    hints.ai_protocol  = 0;             // Any protocol
-    hints.ai_canonname = NULL;
-    hints.ai_addr      = NULL;
-    hints.ai_next      = NULL;
-
-    s = getaddrinfo(NULL, addr_pP, &hints, &result);
-    if (s != 0) {
-        SPGW_APP_ERROR("getaddrinfo: %s\n", gai_strerror(s));
-        return 0;
-    }
-
-    for (rp = result; rp != NULL; rp = rp->ai_next) {
-        memcpy(sock_addr_pP, (char*)rp->ai_addr, rp->ai_addrlen);
-        printf ("Found sock addr length %d\n", rp->ai_addrlen);
-        freeaddrinfo(result);
-        return 1;
-    }
-    return 0;
-}*/
-
 int spgw_config_init(char* lib_config_file_name_pP, spgw_config_t* config_pP) {
 
   config_t          cfg;
@@ -172,6 +140,9 @@ int spgw_config_init(char* lib_config_file_name_pP, spgw_config_t* config_pP) {
   char             *sgw_ipv4_address_for_S5_S8_up        = NULL;
   char             *sgw_interface_name_for_S11           = NULL;
   char             *sgw_ipv4_address_for_S11             = NULL;
+  char             *sgw_drop_uplink_s1u_traffic          = NULL;
+  char             *sgw_drop_downlink_s1u_traffic        = NULL;
+  libconfig_int     sgw_interface_mtu_for_S1u_S12_S4_up  = 1500;
 
   config_setting_t *setting_pgw                  = NULL;
   config_setting_t *subsetting                   = NULL;
@@ -180,6 +151,7 @@ int spgw_config_init(char* lib_config_file_name_pP, spgw_config_t* config_pP) {
   char             *pgw_ipv4_address_for_S5_S8   = NULL;
   char             *pgw_interface_name_for_SGI   = NULL;
   char             *pgw_ipv4_address_for_SGI     = NULL;
+  char             *pgw_masquerade_SGI           = NULL;
   char             *pgw_default_dns_ipv4_address = NULL;
   char             *pgw_default_dns_sec_ipv4_address = NULL;
 
@@ -289,6 +261,50 @@ int spgw_config_init(char* lib_config_file_name_pP, spgw_config_t* config_pP) {
                       config_pP->sgw_config.ipv4.sgw_ip_netmask_for_S11,
                       config_pP->sgw_config.ipv4.sgw_interface_name_for_S11);
           }
+          // optional
+          if(config_setting_lookup_int(
+                  subsetting,
+                  SGW_CONFIG_STRING_SGW_INTERFACE_MTU_FOR_S1U_S12_S4_UP,
+                  &sgw_interface_mtu_for_S1u_S12_S4_up)
+            ) {
+                config_pP->sgw_config.sgw_interface_mtu_for_S1u_S12_S4_up = sgw_interface_mtu_for_S1u_S12_S4_up;
+                if (snprintf(system_cmd, 128,
+                        "ip link set dev %s mtu %u",
+                        config_pP->sgw_config.ipv4.sgw_interface_name_for_S1u_S12_S4_up,
+                        config_pP->sgw_config.sgw_interface_mtu_for_S1u_S12_S4_up) > 0) {
+                    SPGW_APP_INFO("Set S1U interface MTU: %s\n",system_cmd);
+                  system(system_cmd);
+                } else {
+                    SPGW_APP_ERROR("Set S1U interface MTU\n");
+                }
+          }
+      }
+      if(  (
+               config_setting_lookup_string( setting_sgw, SGW_CONFIG_STRING_SGW_DROP_UPLINK_S1U_TRAFFIC,
+                       (const char **)&sgw_drop_uplink_s1u_traffic)
+              && config_setting_lookup_string( setting_sgw, SGW_CONFIG_STRING_SGW_DROP_DOWNLINK_S1U_TRAFFIC,
+                      (const char **)&sgw_drop_downlink_s1u_traffic)
+            )
+        ) {
+          if (strcasecmp(sgw_drop_uplink_s1u_traffic, "yes") == 0) {
+              config_pP->sgw_config.sgw_drop_uplink_traffic=1;
+
+              if (snprintf(system_cmd, 128,
+                      "iptables -t raw -I PREROUTING  -i %s --protocol udp --destination-port 2152  -j DROP",
+                      config_pP->sgw_config.ipv4.sgw_interface_name_for_S1u_S12_S4_up) > 0) {
+                  SPGW_APP_INFO("Drop uplink traffic: %s\n",system_cmd);
+                system(system_cmd);
+              } else {
+                  SPGW_APP_ERROR("Drop uplink traffic\n");
+              }
+          } else {
+              config_pP->sgw_config.sgw_drop_uplink_traffic=0;
+          }
+          if (strcasecmp(sgw_drop_downlink_s1u_traffic, "yes") == 0) {
+              config_pP->sgw_config.sgw_drop_downlink_traffic=1;
+          } else {
+              config_pP->sgw_config.sgw_drop_downlink_traffic=0;
+          }
       }
   }
 
@@ -310,6 +326,9 @@ int spgw_config_init(char* lib_config_file_name_pP, spgw_config_t* config_pP) {
                   && config_setting_lookup_string(subsetting,
                           PGW_CONFIG_STRING_PGW_IPV4_ADDR_FOR_SGI,
                           (const char **)&pgw_ipv4_address_for_SGI)
+                  &&  config_setting_lookup_string(subsetting,
+                          PGW_CONFIG_STRING_PGW_MASQUERADE_SGI,
+                          (const char **)&pgw_masquerade_SGI)
                 )
             ) {
               config_pP->pgw_config.ipv4.pgw_interface_name_for_S5_S8 = strdup(pgw_interface_name_for_S5_S8);
@@ -321,9 +340,9 @@ int spgw_config_init(char* lib_config_file_name_pP, spgw_config_t* config_pP) {
               free(cidr);
               in_addr_var.s_addr = config_pP->pgw_config.ipv4.pgw_ipv4_address_for_S5_S8;
               SPGW_APP_INFO("Parsing configuration file found pgw_ipv4_address_for_S5_S8: %s/%d on %s\n",
-            		  inet_ntoa(in_addr_var),
-            		  config_pP->pgw_config.ipv4.pgw_ip_netmask_for_S5_S8,
-            		  config_pP->pgw_config.ipv4.pgw_interface_name_for_S5_S8);
+                      inet_ntoa(in_addr_var),
+                      config_pP->pgw_config.ipv4.pgw_ip_netmask_for_S5_S8,
+                      config_pP->pgw_config.ipv4.pgw_interface_name_for_S5_S8);
 
               config_pP->pgw_config.ipv4.pgw_interface_name_for_SGI = strdup(pgw_interface_name_for_SGI);
               cidr = strdup(pgw_ipv4_address_for_SGI);
@@ -334,9 +353,24 @@ int spgw_config_init(char* lib_config_file_name_pP, spgw_config_t* config_pP) {
               free(cidr);
               in_addr_var.s_addr = config_pP->pgw_config.ipv4.pgw_ipv4_address_for_SGI;
               SPGW_APP_INFO("Parsing configuration file found pgw_ipv4_address_for_SGI: %s/%d on %s\n",
-            		  inet_ntoa(in_addr_var),
-            		  config_pP->pgw_config.ipv4.pgw_ip_netmask_for_SGI,
-            		  config_pP->pgw_config.ipv4.pgw_interface_name_for_SGI);
+                      inet_ntoa(in_addr_var),
+                      config_pP->pgw_config.ipv4.pgw_ip_netmask_for_SGI,
+                      config_pP->pgw_config.ipv4.pgw_interface_name_for_SGI);
+
+              if (strcasecmp(pgw_masquerade_SGI, "yes") == 0) {
+                  config_pP->pgw_config.pgw_masquerade_SGI=1;
+                  if (snprintf(system_cmd, 128,
+                          "iptables -t nat -A POSTROUTING  -o %s  ! --protocol sctp -j MASQUERADE",
+                          config_pP->pgw_config.ipv4.pgw_interface_name_for_SGI) > 0) {
+                      SPGW_APP_INFO("Masquerade SGI: %s\n",system_cmd);
+                    system(system_cmd);
+                  } else {
+                      SPGW_APP_ERROR("Masquerade SGI\n");
+                  }
+              } else {
+                  config_pP->pgw_config.pgw_masquerade_SGI=0;
+                  SPGW_APP_INFO("No masquerading for SGI\n");
+              }
 
 #if defined (ENABLE_USE_GTPU_IN_KERNEL)
               if (snprintf(system_cmd, 128,
@@ -356,14 +390,6 @@ int spgw_config_init(char* lib_config_file_name_pP, spgw_config_t* config_pP) {
               } else {
                   SPGW_APP_ERROR("Restore mark\n");
               }
-              if (snprintf(system_cmd, 128,
-                      "iptables -t nat -A POSTROUTING  -o %s  ! --protocol sctp -j MASQUERADE",
-                      config_pP->pgw_config.ipv4.pgw_interface_name_for_SGI) > 0) {
-                  SPGW_APP_INFO("Masquerade SGI: %s\n",system_cmd);
-                  system(system_cmd);
-              } else {
-                  SPGW_APP_ERROR("Masquerade SGI\n");
-              }
 #endif
           } else {
               SPGW_APP_WARN("CONFIG P-GW / NETWORK INTERFACES parsing failed\n");
@@ -397,6 +423,25 @@ int spgw_config_init(char* lib_config_file_name_pP, spgw_config_t* config_pP) {
                               } else {
                                   SPGW_APP_ERROR("Add route: for %s\n", astring);
                               }
+
+                              if (config_pP->sgw_config.sgw_drop_downlink_traffic) {
+                                  if (snprintf(system_cmd, 128,
+                                          "iptables -t filter -I FORWARD  -d %s/%s  -j DROP",
+                                          astring, atoken2) > 0) {
+                                      SPGW_APP_INFO("Drop downlink traffic: %s\n",system_cmd);
+                                      system(system_cmd);
+                                  } else {
+                                      SPGW_APP_ERROR("Drop downlink traffic\n");
+                                  }
+                                  if (snprintf(system_cmd, 128,
+                                          "iptables -t filter -I OUTPUT  -d %s/%s  -j DROP",
+                                          astring, atoken2) > 0) {
+                                      SPGW_APP_INFO("Drop downlink traffic: %s\n",system_cmd);
+                                      system(system_cmd);
+                                  } else {
+                                      SPGW_APP_ERROR("Drop downlink traffic\n");
+                                  }
+                              }
 #endif
                               prefix_mask = atoi(atoken2);
                               if ((prefix_mask >= 2)&&(prefix_mask < 32)) {
@@ -496,7 +541,6 @@ int spgw_config_init(char* lib_config_file_name_pP, spgw_config_t* config_pP) {
               IPV4_STR_ADDR_TO_INT_NWBO ( pgw_default_dns_sec_ipv4_address, config_pP->pgw_config.ipv4.default_dns_sec_v4, "BAD IPv4 ADDRESS FORMAT FOR DEFAULT DNS SEC!\n" )
           }
       }
-
   } else {
       SPGW_APP_WARN("CONFIG P-GW not found\n");
   }
diff --git a/openair-cn/SGW-LITE/spgw_config.h b/openair-cn/SGW-LITE/spgw_config.h
index 1c5a461403..6d7c0e285a 100755
--- a/openair-cn/SGW-LITE/spgw_config.h
+++ b/openair-cn/SGW-LITE/spgw_config.h
@@ -47,9 +47,12 @@
 #define SGW_CONFIG_STRING_SGW_IPV4_ADDRESS_FOR_S1U_S12_S4_UP    "SGW_IPV4_ADDRESS_FOR_S1U_S12_S4_UP"
 #define SGW_CONFIG_STRING_SGW_PORT_FOR_S1U_S12_S4_UP            "SGW_IPV4_PORT_FOR_S1U_S12_S4_UP"
 #define SGW_CONFIG_STRING_SGW_INTERFACE_NAME_FOR_S5_S8_UP       "SGW_INTERFACE_NAME_FOR_S5_S8_UP"
+#define SGW_CONFIG_STRING_SGW_INTERFACE_MTU_FOR_S1U_S12_S4_UP   "SGW_INTERFACE_MTU_FOR_S1U_S12_S4_UP"
 #define SGW_CONFIG_STRING_SGW_IPV4_ADDRESS_FOR_S5_S8_UP         "SGW_IPV4_ADDRESS_FOR_S5_S8_UP"
 #define SGW_CONFIG_STRING_SGW_INTERFACE_NAME_FOR_S11            "SGW_INTERFACE_NAME_FOR_S11"
 #define SGW_CONFIG_STRING_SGW_IPV4_ADDRESS_FOR_S11              "SGW_IPV4_ADDRESS_FOR_S11"
+#define SGW_CONFIG_STRING_SGW_DROP_UPLINK_S1U_TRAFFIC           "SGW_DROP_UPLINK_S1U_TRAFFIC"
+#define SGW_CONFIG_STRING_SGW_DROP_DOWNLINK_S1U_TRAFFIC         "SGW_DROP_DOWNLINK_S1U_TRAFFIC"
 
 #define PGW_CONFIG_STRING_PGW_CONFIG                            "P-GW"
 #define PGW_CONFIG_STRING_NETWORK_INTERFACES_CONFIG             "NETWORK_INTERFACES"
@@ -57,6 +60,7 @@
 #define PGW_CONFIG_STRING_PGW_IPV4_ADDRESS_FOR_S5_S8            "PGW_IPV4_ADDRESS_FOR_S5_S8"
 #define PGW_CONFIG_STRING_PGW_INTERFACE_NAME_FOR_SGI            "PGW_INTERFACE_NAME_FOR_SGI"
 #define PGW_CONFIG_STRING_PGW_IPV4_ADDR_FOR_SGI                 "PGW_IPV4_ADDRESS_FOR_SGI"
+#define PGW_CONFIG_STRING_PGW_MASQUERADE_SGI                    "PGW_MASQUERADE_SGI"
 
 #define PGW_CONFIG_STRING_IP_ADDRESS_POOL                       "IP_ADDRESS_POOL"
 #define PGW_CONFIG_STRING_IPV4_ADDRESS_LIST                     "IPV4_LIST"
@@ -91,6 +95,10 @@ typedef struct sgw_config_s {
         uint32_t  sgw_ipv4_address_for_S11;
         int       sgw_ip_netmask_for_S11;
     } ipv4;
+    int sgw_interface_mtu_for_S1u_S12_S4_up;
+
+    uint8_t       sgw_drop_uplink_traffic;
+    uint8_t       sgw_drop_downlink_traffic;
 } sgw_config_t;
 
 // may be more
@@ -123,6 +131,7 @@ typedef struct pgw_config_s {
         uint32_t  default_dns_v4;    // NBO
         uint32_t  default_dns_sec_v4;// NBO
     } ipv4;
+    uint8_t   pgw_masquerade_SGI;
 
     STAILQ_HEAD(pgw_lite_ipv4_pool_head_s,      pgw_lite_conf_ipv4_list_elm_s) pgw_lite_ipv4_pool_list;
     STAILQ_HEAD(pgw_lite_ipv6_pool_head_s,      pgw_lite_conf_ipv6_list_elm_s) pgw_lite_ipv6_pool_list;
-- 
GitLab