diff --git a/openair-cn/UTILS/HASHTABLE/hashtable.c b/openair-cn/UTILS/HASHTABLE/hashtable.c
index 85207852df3df48e7f7b833107ec3efa25c3a7aa..73b73a540cf9a9342c192920379875584c9a86ac 100755
--- a/openair-cn/UTILS/HASHTABLE/hashtable.c
+++ b/openair-cn/UTILS/HASHTABLE/hashtable.c
@@ -8,7 +8,7 @@
 
 
 //-------------------------------------------------------------------------------------------------------------------------------
-char* hashtble_rc_code2string(hashtbl_rc_t rcP)
+char* hashtable_rc_code2string(hashtable_rc_t rcP)
 //-------------------------------------------------------------------------------------------------------------------------------
 {
     switch (rcP) {
@@ -17,220 +17,226 @@ char* hashtble_rc_code2string(hashtbl_rc_t rcP)
     case HASH_TABLE_KEY_NOT_EXISTS:          return "HASH_TABLE_KEY_NOT_EXISTS";break;
     case HASH_TABLE_KEY_ALREADY_EXISTS:      return "HASH_TABLE_KEY_ALREADY_EXISTS";break;
     case HASH_TABLE_BAD_PARAMETER_HASHTABLE: return "HASH_TABLE_BAD_PARAMETER_HASHTABLE";break;
-    default:                                 return "UNKNOWN hashtbl_rc_t";
-
+    default:                                 return "UNKNOWN hashtable_rc_t";
     }
-
 }
+//-------------------------------------------------------------------------------------------------------------------------------
+/*
+ * free int function
+ * hash_free_int_func() is used when this hashtable is used to store int values as data (pointer = value).
+ */
+
+void hash_free_int_func(void* memoryP){}
+
 //-------------------------------------------------------------------------------------------------------------------------------
 /*
  * Default hash function
- * def_hashfunc() is the default used by hashtbl_create() when the user didn't specify one.
+ * def_hashfunc() is the default used by hashtable_create() when the user didn't specify one.
  * This is a simple/naive hash function which adds the key's ASCII char values. It will probably generate lots of collisions on large hash tables.
  */
 
 static hash_size_t def_hashfunc(const uint64_t keyP)
 {
-	return (hash_size_t)keyP;
+    return (hash_size_t)keyP;
 }
 
 //-------------------------------------------------------------------------------------------------------------------------------
 /*
  * Initialisation
- * hashtbl_create() sets up the initial structure of the hash table. The user specified size will be allocated and initialized to NULL.
+ * hashtable_create() sets up the initial structure of the hash table. The user specified size will be allocated and initialized to NULL.
  * The user can also specify a hash function. If the hashfunc argument is NULL, a default hash function is used.
- * If an error occurred, NULL is returned. All other values in the returned hash_table_t pointer should be released with hashtbl_destroy().
+ * If an error occurred, NULL is returned. All other values in the returned hash_table_t pointer should be released with hashtable_destroy().
  */
-hash_table_t *hashtbl_create(hash_size_t sizeP, hash_size_t (*hashfuncP)(const uint64_t ), void (*freefuncP)(void*))
+hash_table_t *hashtable_create(hash_size_t sizeP, hash_size_t (*hashfuncP)(const uint64_t ), void (*freefuncP)(void*))
 {
-	hash_table_t *hashtbl;
+    hash_table_t *hashtbl;
 
-	if(!(hashtbl=malloc(sizeof(hash_table_t)))) return NULL;
+    if(!(hashtbl=malloc(sizeof(hash_table_t)))) return NULL;
 
-	if(!(hashtbl->nodes=calloc(sizeP, sizeof(hash_node_t*)))) {
-		free(hashtbl);
-		return NULL;
-	}
+    if(!(hashtbl->nodes=calloc(sizeP, sizeof(hash_node_t*)))) {
+        free(hashtbl);
+        return NULL;
+    }
 
-	hashtbl->size=sizeP;
+    hashtbl->size=sizeP;
 
-	if(hashfuncP) hashtbl->hashfunc=hashfuncP;
-	else hashtbl->hashfunc=def_hashfunc;
+    if(hashfuncP) hashtbl->hashfunc=hashfuncP;
+    else hashtbl->hashfunc=def_hashfunc;
 
-	if(freefuncP) hashtbl->freefunc=freefuncP;
-	else hashtbl->freefunc=free;
+    if(freefuncP) hashtbl->freefunc=freefuncP;
+    else hashtbl->freefunc=free;
 
-	return hashtbl;
+    return hashtbl;
 }
 //-------------------------------------------------------------------------------------------------------------------------------
 /*
  * Cleanup
- * The hashtbl_destroy() walks through the linked lists for each possible hash value, and releases the elements. It also releases the nodes array and the hash_table_t.
+ * The hashtable_destroy() walks through the linked lists for each possible hash value, and releases the elements. It also releases the nodes array and the hash_table_t.
  */
-hashtbl_rc_t hashtbl_destroy(hash_table_t *hashtblP)
+hashtable_rc_t hashtable_destroy(hash_table_t *hashtblP)
 {
-	hash_size_t n;
-	hash_node_t *node, *oldnode;
-
-	if (hashtblP == NULL) {
-		return HASH_TABLE_BAD_PARAMETER_HASHTABLE;
-	}
-
-	for(n=0; n<hashtblP->size; ++n) {
-		node=hashtblP->nodes[n];
-		while(node) {
-			oldnode=node;
-			node=node->next;
-			if (oldnode->data) {
-				hashtblP->freefunc(oldnode->data);
-			}
-			free(oldnode);
-		}
-	}
-	free(hashtblP->nodes);
-	free(hashtblP);
-	return HASH_TABLE_OK;
+    hash_size_t n;
+    hash_node_t *node, *oldnode;
+
+    if (hashtblP == NULL) {
+        return HASH_TABLE_BAD_PARAMETER_HASHTABLE;
+    }
+
+    for(n=0; n<hashtblP->size; ++n) {
+        node=hashtblP->nodes[n];
+        while(node) {
+            oldnode=node;
+            node=node->next;
+            if (oldnode->data) {
+                hashtblP->freefunc(oldnode->data);
+            }
+            free(oldnode);
+        }
+    }
+    free(hashtblP->nodes);
+    free(hashtblP);
+    return HASH_TABLE_OK;
 }
 //-------------------------------------------------------------------------------------------------------------------------------
-hashtbl_rc_t hashtbl_is_key_exists (hash_table_t *hashtblP, const uint64_t keyP)
+hashtable_rc_t hashtable_is_key_exists (hash_table_t *hashtblP, const uint64_t keyP)
 //-------------------------------------------------------------------------------------------------------------------------------
 {
-	hash_node_t *node;
-	hash_size_t  hash;
-
-	if (hashtblP == NULL) {
-		return HASH_TABLE_BAD_PARAMETER_HASHTABLE;
-	}
-
-	hash=hashtblP->hashfunc(keyP)%hashtblP->size;
-	node=hashtblP->nodes[hash];
-	while(node) {
-		if(node->key == keyP) {
-			return HASH_TABLE_OK;
-		}
-		node=node->next;
-	}
-	return HASH_TABLE_KEY_NOT_EXISTS;
+    hash_node_t *node;
+    hash_size_t  hash;
+
+    if (hashtblP == NULL) {
+        return HASH_TABLE_BAD_PARAMETER_HASHTABLE;
+    }
+
+    hash=hashtblP->hashfunc(keyP)%hashtblP->size;
+    node=hashtblP->nodes[hash];
+    while(node) {
+        if(node->key == keyP) {
+            return HASH_TABLE_OK;
+        }
+        node=node->next;
+    }
+    return HASH_TABLE_KEY_NOT_EXISTS;
 }
 //-------------------------------------------------------------------------------------------------------------------------------
-hashtbl_rc_t hashtbl_apply_funct_on_elements (hash_table_t *hashtblP, void functP(uint64_t keyP, void* dataP, void* parameterP), void* parameterP)
+hashtable_rc_t hashtable_apply_funct_on_elements (hash_table_t *hashtblP, void functP(uint64_t keyP, void* dataP, void* parameterP), void* parameterP)
 //-------------------------------------------------------------------------------------------------------------------------------
 {
-	hash_node_t  *node         = NULL;
-	unsigned int  i            = 0;
-	unsigned int  num_elements = 0;
-	if (hashtblP == NULL) {
-		return HASH_TABLE_BAD_PARAMETER_HASHTABLE;
-	}
-	while ((num_elements < hashtblP->num_elements) && (i < hashtblP->size)) {
-		if (hashtblP->nodes[i] != NULL) {
-			node=hashtblP->nodes[i];
-			while(node) {
-				num_elements += 1;
-				functP(node->key, node->data, parameterP);
-				node=node->next;
-			}
-		}
-		i += 1;
-	}
-	return HASH_TABLE_OK;
+    hash_node_t  *node         = NULL;
+    unsigned int  i            = 0;
+    unsigned int  num_elements = 0;
+    if (hashtblP == NULL) {
+        return HASH_TABLE_BAD_PARAMETER_HASHTABLE;
+    }
+    while ((num_elements < hashtblP->num_elements) && (i < hashtblP->size)) {
+        if (hashtblP->nodes[i] != NULL) {
+            node=hashtblP->nodes[i];
+            while(node) {
+                num_elements += 1;
+                functP(node->key, node->data, parameterP);
+                node=node->next;
+            }
+        }
+        i += 1;
+    }
+    return HASH_TABLE_OK;
 }
 //-------------------------------------------------------------------------------------------------------------------------------
 /*
  * Adding a new element
  * To make sure the hash value is not bigger than size, the result of the user provided hash function is used modulo size.
  */
-hashtbl_rc_t hashtbl_insert(hash_table_t *hashtblP, const uint64_t keyP, void *dataP)
+hashtable_rc_t hashtable_insert(hash_table_t *hashtblP, const uint64_t keyP, void *dataP)
 {
-	hash_node_t *node;
-	hash_size_t hash;
-	if (hashtblP == NULL) {
-		return HASH_TABLE_BAD_PARAMETER_HASHTABLE;
-	}
-	hash=hashtblP->hashfunc(keyP)%hashtblP->size;
-
-	node=hashtblP->nodes[hash];
-	while(node) {
-		if(node->key == keyP) {
-			if (node->data) {
-				hashtblP->freefunc(node->data);
-			}
-			node->data=dataP;
-			return HASH_TABLE_INSERT_OVERWRITTEN_DATA;
-		}
-		node=node->next;
-	}
-	if(!(node=malloc(sizeof(hash_node_t)))) return -1;
-	node->key=keyP;
-	node->data=dataP;
-	if (hashtblP->nodes[hash]) {
-	    node->next=hashtblP->nodes[hash];
-	} else {
-		node->next = NULL;
-	}
-	hashtblP->nodes[hash]=node;
-	hashtblP->num_elements += 1;
-	return HASH_TABLE_OK;
+    hash_node_t *node;
+    hash_size_t hash;
+    if (hashtblP == NULL) {
+        return HASH_TABLE_BAD_PARAMETER_HASHTABLE;
+    }
+    hash=hashtblP->hashfunc(keyP)%hashtblP->size;
+
+    node=hashtblP->nodes[hash];
+    while(node) {
+        if(node->key == keyP) {
+            if (node->data) {
+                hashtblP->freefunc(node->data);
+            }
+            node->data=dataP;
+            return HASH_TABLE_INSERT_OVERWRITTEN_DATA;
+        }
+        node=node->next;
+    }
+    if(!(node=malloc(sizeof(hash_node_t)))) return -1;
+    node->key=keyP;
+    node->data=dataP;
+    if (hashtblP->nodes[hash]) {
+        node->next=hashtblP->nodes[hash];
+    } else {
+        node->next = NULL;
+    }
+    hashtblP->nodes[hash]=node;
+    hashtblP->num_elements += 1;
+    return HASH_TABLE_OK;
 }
 //-------------------------------------------------------------------------------------------------------------------------------
 /*
  * To remove an element from the hash table, we just search for it in the linked list for that hash value,
  * and remove it if it is found. If it was not found, it is an error and -1 is returned.
  */
-hashtbl_rc_t hashtbl_remove(hash_table_t *hashtblP, const uint64_t keyP)
+hashtable_rc_t hashtable_remove(hash_table_t *hashtblP, const uint64_t keyP)
 {
-	hash_node_t *node, *prevnode=NULL;
-	hash_size_t  hash;
-
-	if (hashtblP == NULL) {
-		return HASH_TABLE_BAD_PARAMETER_HASHTABLE;
-	}
-	hash=hashtblP->hashfunc(keyP)%hashtblP->size;
-	node=hashtblP->nodes[hash];
-	while(node) {
-		if(node->key != keyP) {
-			if(prevnode) prevnode->next=node->next;
-			else hashtblP->nodes[hash]=node->next;
-			if (node->data) {
-				hashtblP->freefunc(node->data);
-			}
-			free(node);
-			hashtblP->num_elements -= 1;
-			return HASH_TABLE_OK;
-		}
-		prevnode=node;
-		node=node->next;
-	}
-	return HASH_TABLE_KEY_NOT_EXISTS;
+    hash_node_t *node, *prevnode=NULL;
+    hash_size_t  hash;
+
+    if (hashtblP == NULL) {
+        return HASH_TABLE_BAD_PARAMETER_HASHTABLE;
+    }
+    hash=hashtblP->hashfunc(keyP)%hashtblP->size;
+    node=hashtblP->nodes[hash];
+    while(node) {
+        if(node->key != keyP) {
+            if(prevnode) prevnode->next=node->next;
+            else hashtblP->nodes[hash]=node->next;
+            if (node->data) {
+                hashtblP->freefunc(node->data);
+            }
+            free(node);
+            hashtblP->num_elements -= 1;
+            return HASH_TABLE_OK;
+        }
+        prevnode=node;
+        node=node->next;
+    }
+    return HASH_TABLE_KEY_NOT_EXISTS;
 }
 //-------------------------------------------------------------------------------------------------------------------------------
 /*
  * Searching for an element is easy. We just search through the linked list for the corresponding hash value.
  * NULL is returned if we didn't find it.
  */
-hashtbl_rc_t hashtbl_get(hash_table_t *hashtblP, const uint64_t keyP, void** dataP)
+hashtable_rc_t hashtable_get(hash_table_t *hashtblP, const uint64_t keyP, void** dataP)
 {
-	hash_node_t *node;
-	hash_size_t  hash;
-
-	if (hashtblP == NULL) {
-		*dataP = NULL;
-		return HASH_TABLE_BAD_PARAMETER_HASHTABLE;
-	}
-	hash=hashtblP->hashfunc(keyP)%hashtblP->size;
-/*	fprintf(stderr, "hashtbl_get() key=%s, hash=%d\n", key, hash);*/
-
-	node=hashtblP->nodes[hash];
-
-	while(node) {
-		if(node->key == keyP) {
-			*dataP = node->data;
-			return HASH_TABLE_OK;
-		}
-		node=node->next;
-	}
-	*dataP = NULL;
-	return HASH_TABLE_KEY_NOT_EXISTS;
+    hash_node_t *node;
+    hash_size_t  hash;
+
+    if (hashtblP == NULL) {
+        *dataP = NULL;
+        return HASH_TABLE_BAD_PARAMETER_HASHTABLE;
+    }
+    hash=hashtblP->hashfunc(keyP)%hashtblP->size;
+/*  fprintf(stderr, "hashtable_get() key=%s, hash=%d\n", key, hash);*/
+
+    node=hashtblP->nodes[hash];
+
+    while(node) {
+        if(node->key == keyP) {
+            *dataP = node->data;
+            return HASH_TABLE_OK;
+        }
+        node=node->next;
+    }
+    *dataP = NULL;
+    return HASH_TABLE_KEY_NOT_EXISTS;
 }
 //-------------------------------------------------------------------------------------------------------------------------------
 /*
@@ -240,40 +246,40 @@ hashtbl_rc_t hashtbl_get(hash_table_t *hashtblP, const uint64_t keyP, void** dat
  * If the number of elements are reduced, the hash table will waste memory. That is why we provide a function for resizing the table.
  * Resizing a hash table is not as easy as a realloc(). All hash values must be recalculated and each element must be inserted into its new position.
  * We create a temporary hash_table_t object (newtbl) to be used while building the new hashes.
- * This allows us to reuse hashtbl_insert() and hashtbl_remove(), when moving the elements to the new table.
+ * This allows us to reuse hashtable_insert() and hashtable_remove(), when moving the elements to the new table.
  * After that, we can just free the old table and copy the elements from newtbl to hashtbl.
  */
 
-hashtbl_rc_t hashtbl_resize(hash_table_t *hashtblP, hash_size_t sizeP)
+hashtable_rc_t hashtable_resize(hash_table_t *hashtblP, hash_size_t sizeP)
 {
-	hash_table_t       newtbl;
-	hash_size_t        n;
-	hash_node_t       *node,*next;
+    hash_table_t       newtbl;
+    hash_size_t        n;
+    hash_node_t       *node,*next;
 
-	if (hashtblP == NULL) {
-		return HASH_TABLE_BAD_PARAMETER_HASHTABLE;
-	}
+    if (hashtblP == NULL) {
+        return HASH_TABLE_BAD_PARAMETER_HASHTABLE;
+    }
 
-	newtbl.size     = sizeP;
-	newtbl.hashfunc = hashtblP->hashfunc;
+    newtbl.size     = sizeP;
+    newtbl.hashfunc = hashtblP->hashfunc;
 
-	if(!(newtbl.nodes=calloc(sizeP, sizeof(hash_node_t*)))) return -1;
+    if(!(newtbl.nodes=calloc(sizeP, sizeof(hash_node_t*)))) return -1;
 
-	for(n=0; n<hashtblP->size; ++n) {
-		for(node=hashtblP->nodes[n]; node; node=next) {
-			next = node->next;
-			hashtbl_insert(&newtbl, node->key, node->data);
-			// Lionel GAUTHIER: BAD CODE TO BE REWRITTEN
-			hashtbl_remove(hashtblP, node->key);
+    for(n=0; n<hashtblP->size; ++n) {
+        for(node=hashtblP->nodes[n]; node; node=next) {
+            next = node->next;
+            hashtable_insert(&newtbl, node->key, node->data);
+            // Lionel GAUTHIER: BAD CODE TO BE REWRITTEN
+            hashtable_remove(hashtblP, node->key);
 
-		}
-	}
+        }
+    }
 
-	free(hashtblP->nodes);
-	hashtblP->size=newtbl.size;
-	hashtblP->nodes=newtbl.nodes;
+    free(hashtblP->nodes);
+    hashtblP->size=newtbl.size;
+    hashtblP->nodes=newtbl.nodes;
 
-	return HASH_TABLE_OK;
+    return HASH_TABLE_OK;
 }
 
 
diff --git a/openair-cn/UTILS/HASHTABLE/hashtable.h b/openair-cn/UTILS/HASHTABLE/hashtable.h
index 0c5d8ed4e00adeaedf01ed22afc151333015e429..fb59bac4ec6696ac3a99313e6270428eb7b3c52a 100755
--- a/openair-cn/UTILS/HASHTABLE/hashtable.h
+++ b/openair-cn/UTILS/HASHTABLE/hashtable.h
@@ -1,44 +1,46 @@
-#ifndef _HASH_TABLE_H_
-#define _HASH_TABLE_H_
+#ifndef _UTILS_COLLECTION_HASH_TABLE_H_
+#define _UTILS_COLLECTION_HASH_TABLE_H_
 #include<stdlib.h>
 #include <stdint.h>
 #include <stddef.h>
 
 typedef size_t hash_size_t;
 
-typedef enum hashtbl_return_code_e {
+typedef enum hashtable_return_code_e {
     HASH_TABLE_OK                      = 0,
     HASH_TABLE_INSERT_OVERWRITTEN_DATA = 1,
     HASH_TABLE_KEY_NOT_EXISTS          = 2,
     HASH_TABLE_KEY_ALREADY_EXISTS      = 3,
     HASH_TABLE_BAD_PARAMETER_HASHTABLE = 4,
+    HASH_TABLE_SYSTEM_ERROR            = 5,
     HASH_TABLE_CODE_MAX
-} hashtbl_rc_t;
+} hashtable_rc_t;
 
 
 typedef struct hash_node_s {
-	uint64_t            key;
-	void               *data;
-	struct hash_node_s *next;
+    uint64_t            key;
+    void               *data;
+    struct hash_node_s *next;
 } hash_node_t;
 
 typedef struct hash_table_s {
-	hash_size_t         size;
-	hash_size_t         num_elements;
-	struct hash_node_s **nodes;
-	hash_size_t       (*hashfunc)(const uint64_t);
-	void              (*freefunc)(void*);
+    hash_size_t         size;
+    hash_size_t         num_elements;
+    struct hash_node_s **nodes;
+    hash_size_t       (*hashfunc)(const uint64_t);
+    void              (*freefunc)(void*);
 } hash_table_t;
 
-char*         hashtble_rc_code2string(hashtbl_rc_t rcP);
-hash_table_t *hashtbl_create (hash_size_t   size, hash_size_t (*hashfunc)(const uint64_t ), void (*freefunc)(void*));
-hashtbl_rc_t  hashtbl_destroy(hash_table_t *hashtbl);
-hashtbl_rc_t  hashtbl_is_key_exists (hash_table_t *hashtbl, const uint64_t key);
-hashtbl_rc_t  hashtbl_apply_funct_on_elements (hash_table_t *hashtblP, void funct(uint64_t keyP, void* dataP, void* parameterP), void* parameterP);
-hashtbl_rc_t  hashtbl_insert (hash_table_t *hashtbl, const uint64_t key, void *data);
-hashtbl_rc_t  hashtbl_remove (hash_table_t *hashtbl, const uint64_t key);
-hashtbl_rc_t  hashtbl_get    (hash_table_t *hashtbl, const uint64_t key, void **dataP);
-hashtbl_rc_t  hashtbl_resize (hash_table_t *hashtbl, hash_size_t size);
+char*           hashtable_rc_code2string(hashtable_rc_t rcP);
+void            hash_free_int_func(void* memoryP);
+hash_table_t   *hashtable_create (hash_size_t   size, hash_size_t (*hashfunc)(const uint64_t ), void (*freefunc)(void*));
+hashtable_rc_t  hashtable_destroy(hash_table_t *hashtbl);
+hashtable_rc_t  hashtable_is_key_exists (hash_table_t *hashtbl, const uint64_t key);
+hashtable_rc_t  hashtable_apply_funct_on_elements (hash_table_t *hashtblP, void funct(uint64_t keyP, void* dataP, void* parameterP), void* parameterP);
+hashtable_rc_t  hashtable_insert (hash_table_t *hashtbl, const uint64_t key, void *data);
+hashtable_rc_t  hashtable_remove (hash_table_t *hashtbl, const uint64_t key);
+hashtable_rc_t  hashtable_get    (hash_table_t *hashtbl, const uint64_t key, void **dataP);
+hashtable_rc_t  hashtable_resize (hash_table_t *hashtbl, hash_size_t size);
 
 
 
diff --git a/openair-cn/UTILS/HASHTABLE/obj_hashtable.c b/openair-cn/UTILS/HASHTABLE/obj_hashtable.c
index b1a46ab6760136e889e40077e35f769609cb65c7..b2280144b73b7201b18f4d3de2c5a0eb6d7fc327 100755
--- a/openair-cn/UTILS/HASHTABLE/obj_hashtable.c
+++ b/openair-cn/UTILS/HASHTABLE/obj_hashtable.c
@@ -8,189 +8,221 @@
 //-------------------------------------------------------------------------------------------------------------------------------
 /*
  * Default hash function
- * def_hashfunc() is the default used by hashtbl_create() when the user didn't specify one.
+ * def_hashfunc() is the default used by hashtable_create() when the user didn't specify one.
  * This is a simple/naive hash function which adds the key's ASCII char values. It will probably generate lots of collisions on large hash tables.
  */
 
 static hash_size_t def_hashfunc(const void *keyP, int key_sizeP)
 {
-	hash_size_t hash=0;
+    hash_size_t hash=0;
 
-	while(key_sizeP) hash^=((unsigned char*)keyP)[key_sizeP --];
+    while(key_sizeP) hash^=((unsigned char*)keyP)[key_sizeP --];
 
-	return hash;
+    return hash;
 }
 
 //-------------------------------------------------------------------------------------------------------------------------------
 /*
  * Initialisation
- * hashtbl_create() sets up the initial structure of the hash table. The user specified size will be allocated and initialized to NULL.
+ * hashtable_create() sets up the initial structure of the hash table. The user specified size will be allocated and initialized to NULL.
  * The user can also specify a hash function. If the hashfunc argument is NULL, a default hash function is used.
- * If an error occurred, NULL is returned. All other values in the returned obj_hash_table_t pointer should be released with hashtbl_destroy().
+ * If an error occurred, NULL is returned. All other values in the returned obj_hash_table_t pointer should be released with hashtable_destroy().
  */
-obj_hash_table_t *obj_hashtbl_create(hash_size_t sizeP, hash_size_t (*hashfuncP)(const void*, int ), void (*freekeyfuncP)(void*), void (*freedatafuncP)(void*))
+obj_hash_table_t *obj_hashtable_create(hash_size_t sizeP, hash_size_t (*hashfuncP)(const void*, int ), void (*freekeyfuncP)(void*), void (*freedatafuncP)(void*))
 {
-	obj_hash_table_t *hashtbl;
+    obj_hash_table_t *hashtbl;
 
-	if(!(hashtbl=malloc(sizeof(obj_hash_table_t)))) return NULL;
+    if(!(hashtbl=malloc(sizeof(obj_hash_table_t)))) return NULL;
 
-	if(!(hashtbl->nodes=calloc(sizeP, sizeof(obj_hash_node_t*)))) {
-		free(hashtbl);
-		return NULL;
-	}
+    if(!(hashtbl->nodes=calloc(sizeP, sizeof(obj_hash_node_t*)))) {
+        free(hashtbl);
+        return NULL;
+    }
 
-	hashtbl->size=sizeP;
+    hashtbl->size=sizeP;
 
-	if(hashfuncP) hashtbl->hashfunc=hashfuncP;
-	else hashtbl->hashfunc=def_hashfunc;
+    if(hashfuncP) hashtbl->hashfunc=hashfuncP;
+    else hashtbl->hashfunc=def_hashfunc;
 
-	if(freekeyfuncP) hashtbl->freekeyfunc=freekeyfuncP;
-	else hashtbl->freekeyfunc=free;
+    if(freekeyfuncP) hashtbl->freekeyfunc=freekeyfuncP;
+    else hashtbl->freekeyfunc=free;
 
-	if(freedatafuncP) hashtbl->freedatafunc=freedatafuncP;
-	else hashtbl->freedatafunc=free;
+    if(freedatafuncP) hashtbl->freedatafunc=freedatafuncP;
+    else hashtbl->freedatafunc=free;
 
-	return hashtbl;
+    return hashtbl;
 }
 //-------------------------------------------------------------------------------------------------------------------------------
 /*
  * Cleanup
- * The hashtbl_destroy() walks through the linked lists for each possible hash value, and releases the elements. It also releases the nodes array and the obj_hash_table_t.
+ * The hashtable_destroy() walks through the linked lists for each possible hash value, and releases the elements. It also releases the nodes array and the obj_hash_table_t.
  */
-hashtbl_rc_t obj_hashtbl_destroy(obj_hash_table_t *hashtblP)
+hashtable_rc_t obj_hashtable_destroy(obj_hash_table_t *hashtblP)
 {
-	hash_size_t n;
-	obj_hash_node_t *node, *oldnode;
-
-	for(n=0; n<hashtblP->size; ++n) {
-		node=hashtblP->nodes[n];
-		while(node) {
-			oldnode=node;
-			node=node->next;
-			hashtblP->freekeyfunc(oldnode->key);
-			hashtblP->freedatafunc(oldnode->data);
-			free(oldnode);
-		}
-	}
-	free(hashtblP->nodes);
-	free(hashtblP);
-	return HASH_TABLE_OK;
+    hash_size_t n;
+    obj_hash_node_t *node, *oldnode;
+
+    for(n=0; n<hashtblP->size; ++n) {
+        node=hashtblP->nodes[n];
+        while(node) {
+            oldnode=node;
+            node=node->next;
+            hashtblP->freekeyfunc(oldnode->key);
+            hashtblP->freedatafunc(oldnode->data);
+            free(oldnode);
+        }
+    }
+    free(hashtblP->nodes);
+    free(hashtblP);
+    return HASH_TABLE_OK;
 }
 //-------------------------------------------------------------------------------------------------------------------------------
-hashtbl_rc_t obj_hashtbl_is_key_exists (obj_hash_table_t *hashtblP, void* keyP, int key_sizeP)
+hashtable_rc_t obj_hashtable_is_key_exists (obj_hash_table_t *hashtblP, void* keyP, int key_sizeP)
 //-------------------------------------------------------------------------------------------------------------------------------
 {
-	obj_hash_node_t *node;
-	hash_size_t      hash;
-
-	if (hashtblP == NULL) {
-		return HASH_TABLE_BAD_PARAMETER_HASHTABLE;
-	}
-	hash=hashtblP->hashfunc(keyP, key_sizeP)%hashtblP->size;
-	node=hashtblP->nodes[hash];
-	while(node) {
-		if(node->key == keyP) {
-			return HASH_TABLE_OK;
-		}
-		node=node->next;
-	}
-	return HASH_TABLE_KEY_NOT_EXISTS;
+    obj_hash_node_t *node;
+    hash_size_t      hash;
+
+    if (hashtblP == NULL) {
+        return HASH_TABLE_BAD_PARAMETER_HASHTABLE;
+    }
+    hash=hashtblP->hashfunc(keyP, key_sizeP)%hashtblP->size;
+    node=hashtblP->nodes[hash];
+    while(node) {
+        if(node->key == keyP) {
+            return HASH_TABLE_OK;
+        } else if (node->key_size == key_sizeP) {
+            if (memcmp(node->key, keyP, key_sizeP) == 0) {
+                return HASH_TABLE_OK;
+            }
+        }
+        node=node->next;
+    }
+    return HASH_TABLE_KEY_NOT_EXISTS;
 }
 //-------------------------------------------------------------------------------------------------------------------------------
 /*
  * Adding a new element
  * To make sure the hash value is not bigger than size, the result of the user provided hash function is used modulo size.
  */
-hashtbl_rc_t obj_hashtbl_insert(obj_hash_table_t *hashtblP, void* keyP, int key_sizeP, void *dataP)
+hashtable_rc_t obj_hashtable_insert(obj_hash_table_t *hashtblP, void* keyP, int key_sizeP, void *dataP)
 {
-	obj_hash_node_t *node;
-	hash_size_t      hash;
-
-	if (hashtblP == NULL) {
-		return HASH_TABLE_BAD_PARAMETER_HASHTABLE;
-	}
-	hash=hashtblP->hashfunc(keyP, key_sizeP)%hashtblP->size;
-	node=hashtblP->nodes[hash];
-	while(node) {
-		if(node->key == keyP) {
-			if (node->data) {
-				hashtblP->freedatafunc(node->data);
-			}
-			node->data=dataP;
-			// waste of memory here (keyP is lost) we should free it now
-			return HASH_TABLE_INSERT_OVERWRITTEN_DATA;
-		}
-		node=node->next;
-	}
-	if(!(node=malloc(sizeof(obj_hash_node_t)))) return -1;
-	node->key=keyP;
-	node->data=dataP;
-	if (hashtblP->nodes[hash]) {
-	    node->next=hashtblP->nodes[hash];
-	} else {
-		node->next = NULL;
-	}
-	hashtblP->nodes[hash]=node;
-	return HASH_TABLE_OK;
+    obj_hash_node_t *node;
+    hash_size_t      hash;
+
+    if (hashtblP == NULL) {
+        return HASH_TABLE_BAD_PARAMETER_HASHTABLE;
+    }
+    hash=hashtblP->hashfunc(keyP, key_sizeP)%hashtblP->size;
+    node=hashtblP->nodes[hash];
+    while(node) {
+        if(node->key == keyP) {
+            if (node->data) {
+                hashtblP->freedatafunc(node->data);
+            }
+            node->data=dataP;
+            // waste of memory here (keyP is lost) we should free it now
+            return HASH_TABLE_INSERT_OVERWRITTEN_DATA;
+        }
+        node=node->next;
+    }
+    if(!(node=malloc(sizeof(obj_hash_node_t)))) return -1;
+    node->key=keyP;
+    node->data=dataP;
+    if (hashtblP->nodes[hash]) {
+        node->next=hashtblP->nodes[hash];
+    } else {
+        node->next = NULL;
+    }
+    hashtblP->nodes[hash]=node;
+    return HASH_TABLE_OK;
 }
 //-------------------------------------------------------------------------------------------------------------------------------
 /*
  * To remove an element from the hash table, we just search for it in the linked list for that hash value,
  * and remove it if it is found. If it was not found, it is an error and -1 is returned.
  */
-hashtbl_rc_t obj_hashtbl_remove(obj_hash_table_t *hashtblP, const void* keyP, int key_sizeP)
+hashtable_rc_t obj_hashtable_remove(obj_hash_table_t *hashtblP, const void* keyP, int key_sizeP)
 {
-	obj_hash_node_t *node, *prevnode=NULL;
-	hash_size_t      hash;
-
-	if (hashtblP == NULL) {
-		return HASH_TABLE_BAD_PARAMETER_HASHTABLE;
-	}
-
-	hash=hashtblP->hashfunc(keyP, key_sizeP)%hashtblP->size;
-	node=hashtblP->nodes[hash];
-	while(node) {
-		if(node->key == keyP) {
-			if(prevnode) {
-				prevnode->next=node->next;
-			} else {
-				hashtblP->nodes[hash]=node->next;
-			}
-			hashtblP->freekeyfunc(node->key);
-			hashtblP->freedatafunc(node->data);
-			free(node);
-			return HASH_TABLE_OK;
-		}
-		prevnode=node;
-		node=node->next;
-	}
-	return HASH_TABLE_KEY_NOT_EXISTS;
+    obj_hash_node_t *node, *prevnode=NULL;
+    hash_size_t      hash;
+
+    if (hashtblP == NULL) {
+        return HASH_TABLE_BAD_PARAMETER_HASHTABLE;
+    }
+
+    hash=hashtblP->hashfunc(keyP, key_sizeP)%hashtblP->size;
+    node=hashtblP->nodes[hash];
+    while(node) {
+        if ((node->key == keyP) || ((node->key_size == key_sizeP) && (memcmp(node->key, keyP, key_sizeP) == 0))){
+            if(prevnode) {
+                prevnode->next=node->next;
+            } else {
+                hashtblP->nodes[hash]=node->next;
+            }
+            hashtblP->freekeyfunc(node->key);
+            hashtblP->freedatafunc(node->data);
+            free(node);
+            return HASH_TABLE_OK;
+        }
+        prevnode=node;
+        node=node->next;
+    }
+    return HASH_TABLE_KEY_NOT_EXISTS;
 }
 //-------------------------------------------------------------------------------------------------------------------------------
 /*
  * Searching for an element is easy. We just search through the linked list for the corresponding hash value.
  * NULL is returned if we didn't find it.
  */
-hashtbl_rc_t obj_hashtbl_get(obj_hash_table_t *hashtblP, const void* keyP, int key_sizeP, void** dataP)
+hashtable_rc_t obj_hashtable_get(obj_hash_table_t *hashtblP, const void* keyP, int key_sizeP, void** dataP)
+{
+    obj_hash_node_t *node;
+    hash_size_t      hash;
+
+    if (hashtblP == NULL) {
+        *dataP = NULL;
+        return HASH_TABLE_BAD_PARAMETER_HASHTABLE;
+    }
+    hash=hashtblP->hashfunc(keyP, key_sizeP)%hashtblP->size;
+    node=hashtblP->nodes[hash];
+    while(node) {
+        if(node->key == keyP) {
+            *dataP = node->data;
+            return HASH_TABLE_OK;
+        } else if (node->key_size == key_sizeP) {
+            if (memcmp(node->key, keyP, key_sizeP) == 0) {
+                *dataP = node->data;
+                return HASH_TABLE_OK;
+            }
+        }
+        node=node->next;
+    }
+    *dataP = NULL;
+    return HASH_TABLE_KEY_NOT_EXISTS;
+}
+//-------------------------------------------------------------------------------------------------------------------------------
+/*
+ * Function to return all keys of an object hash table
+ */
+hashtable_rc_t obj_hashtable_get_keys(obj_hash_table_t *hashtblP, void ** keysP, unsigned int *sizeP)
 {
-	obj_hash_node_t *node;
-	hash_size_t      hash;
-
-	if (hashtblP == NULL) {
-		*dataP = NULL;
-		return HASH_TABLE_BAD_PARAMETER_HASHTABLE;
-	}
-	hash=hashtblP->hashfunc(keyP, key_sizeP)%hashtblP->size;
-	node=hashtblP->nodes[hash];
-	while(node) {
-		if(node->key == keyP) {
-			*dataP = node->data;
-			return HASH_TABLE_OK;
-		}
-		node=node->next;
-	}
-	*dataP = NULL;
-	return HASH_TABLE_KEY_NOT_EXISTS;
+    size_t                 n     = 0;
+    obj_hash_node_t       *node  = NULL;
+    obj_hash_node_t       *next  = NULL;
+
+    *sizeP = 0;
+    keysP = calloc(hashtblP->num_elements, sizeof(void *));
+    if (keysP) {
+        for(n=0; n<hashtblP->size; ++n) {
+            for(node=hashtblP->nodes[n]; node; node=next) {
+                keysP[*sizeP++] = node->key;
+                next = node->next;
+            }
+        }
+        return HASH_TABLE_OK;
+    }
+    return HASH_TABLE_SYSTEM_ERROR;
 }
 //-------------------------------------------------------------------------------------------------------------------------------
 /*
@@ -200,38 +232,37 @@ hashtbl_rc_t obj_hashtbl_get(obj_hash_table_t *hashtblP, const void* keyP, int k
  * If the number of elements are reduced, the hash table will waste memory. That is why we provide a function for resizing the table.
  * Resizing a hash table is not as easy as a realloc(). All hash values must be recalculated and each element must be inserted into its new position.
  * We create a temporary obj_hash_table_t object (newtbl) to be used while building the new hashes.
- * This allows us to reuse hashtbl_insert() and hashtbl_remove(), when moving the elements to the new table.
+ * This allows us to reuse hashtable_insert() and hashtable_remove(), when moving the elements to the new table.
  * After that, we can just free the old table and copy the elements from newtbl to hashtbl.
  */
-hashtbl_rc_t obj_hashtbl_resize(obj_hash_table_t *hashtblP, hash_size_t sizeP)
+hashtable_rc_t obj_hashtable_resize(obj_hash_table_t *hashtblP, hash_size_t sizeP)
 {
-	obj_hash_table_t       newtbl;
-	hash_size_t        n;
-	obj_hash_node_t       *node,*next;
+    obj_hash_table_t       newtbl;
+    hash_size_t        n;
+    obj_hash_node_t       *node,*next;
 
-	if (hashtblP == NULL) {
-		return HASH_TABLE_BAD_PARAMETER_HASHTABLE;
-	}
+    if (hashtblP == NULL) {
+        return HASH_TABLE_BAD_PARAMETER_HASHTABLE;
+    }
 
-	newtbl.size     = sizeP;
-	newtbl.hashfunc = hashtblP->hashfunc;
+    newtbl.size     = sizeP;
+    newtbl.hashfunc = hashtblP->hashfunc;
 
-	if(!(newtbl.nodes=calloc(sizeP, sizeof(obj_hash_node_t*)))) return -1;
+    if(!(newtbl.nodes=calloc(sizeP, sizeof(obj_hash_node_t*)))) return HASH_TABLE_SYSTEM_ERROR;
 
-	for(n=0; n<hashtblP->size; ++n) {
-		for(node=hashtblP->nodes[n]; node; node=next) {
-			next = node->next;
-			obj_hashtbl_insert(&newtbl, node->key, node->key_size, node->data);
-			//WARNING  Lionel GAUTHIER: BAD CODE TO BE REWRITTEN
-			obj_hashtbl_remove(hashtblP, node->key, node->key_size);
-		}
-	}
+    for(n=0; n<hashtblP->size; ++n) {
+        for(node=hashtblP->nodes[n]; node; node=next) {
+            next = node->next;
+            obj_hashtable_insert(&newtbl, node->key, node->key_size, node->data);
+            obj_hashtable_remove(hashtblP, node->key, node->key_size);
+        }
+    }
 
-	free(hashtblP->nodes);
-	hashtblP->size=newtbl.size;
-	hashtblP->nodes=newtbl.nodes;
+    free(hashtblP->nodes);
+    hashtblP->size=newtbl.size;
+    hashtblP->nodes=newtbl.nodes;
 
-	return HASH_TABLE_OK;
+    return HASH_TABLE_OK;
 }
 
 
diff --git a/openair-cn/UTILS/HASHTABLE/obj_hashtable.h b/openair-cn/UTILS/HASHTABLE/obj_hashtable.h
index 45442edf41eae1b713cba00baec4ae08db730474..466f1a5b14b80e06f351da68ab0bdb806a484fe4 100755
--- a/openair-cn/UTILS/HASHTABLE/obj_hashtable.h
+++ b/openair-cn/UTILS/HASHTABLE/obj_hashtable.h
@@ -10,28 +10,29 @@ typedef size_t hash_size_t;
 
 
 typedef struct obj_hash_node_s {
-	int                 key_size;
-	void               *key;
-	void               *data;
-	struct obj_hash_node_s *next;
+    int                 key_size;
+    void               *key;
+    void               *data;
+    struct obj_hash_node_s *next;
 } obj_hash_node_t;
 
 typedef struct obj_hash_table_s {
-	hash_size_t         size;
-	hash_size_t         num_elements;
-	struct obj_hash_node_s **nodes;
-	hash_size_t       (*hashfunc)(const void*, int);
-	void              (*freekeyfunc)(void*);
-	void              (*freedatafunc)(void*);
+    hash_size_t         size;
+    hash_size_t         num_elements;
+    struct obj_hash_node_s **nodes;
+    hash_size_t       (*hashfunc)(const void*, int);
+    void              (*freekeyfunc)(void*);
+    void              (*freedatafunc)(void*);
 } obj_hash_table_t;
 
-obj_hash_table_t *obj_hashtbl_create (hash_size_t   size, hash_size_t (*hashfunc)(const void*, int ), void (*freekeyfunc)(void*), void (*freedatafunc)(void*));
-hashtbl_rc_t      obj_hashtbl_destroy(obj_hash_table_t *hashtblP);
-hashtbl_rc_t      obj_hashtbl_is_key_exists (obj_hash_table_t *hashtblP, void* keyP, int key_sizeP);
-hashtbl_rc_t      obj_hashtbl_insert (obj_hash_table_t *hashtblP,       void* keyP, int key_sizeP, void *dataP);
-hashtbl_rc_t      obj_hashtbl_remove (obj_hash_table_t *hashtblP, const void* keyP, int key_sizeP);
-hashtbl_rc_t      obj_hashtbl_get    (obj_hash_table_t *hashtblP, const void* keyP, int key_sizeP, void ** dataP);
-hashtbl_rc_t      obj_hashtbl_resize (obj_hash_table_t *hashtblP, hash_size_t sizeP);
+obj_hash_table_t   *obj_hashtable_create  (hash_size_t   size, hash_size_t (*hashfunc)(const void*, int ), void (*freekeyfunc)(void*), void (*freedatafunc)(void*));
+hashtable_rc_t      obj_hashtable_destroy (obj_hash_table_t *hashtblP);
+hashtable_rc_t      obj_hashtable_is_key_exists (obj_hash_table_t *hashtblP, void* keyP, int key_sizeP);
+hashtable_rc_t      obj_hashtable_insert  (obj_hash_table_t *hashtblP,       void* keyP, int key_sizeP, void *dataP);
+hashtable_rc_t      obj_hashtable_remove  (obj_hash_table_t *hashtblP, const void* keyP, int key_sizeP);
+hashtable_rc_t      obj_hashtable_get     (obj_hash_table_t *hashtblP, const void* keyP, int key_sizeP, void ** dataP);
+hashtable_rc_t      obj_hashtable_get_keys(obj_hash_table_t *hashtblP, void ** keysP, unsigned int *sizeP);
+hashtable_rc_t      obj_hashtable_resize  (obj_hash_table_t *hashtblP, hash_size_t sizeP);
 
 
 
diff --git a/openair-cn/UTILS/Makefile.am b/openair-cn/UTILS/Makefile.am
index 438034e52ed12d49ddc314b76be79450db51321f..c6337ee4f246910d7a5ae5972e725b46aec7b5a2 100644
--- a/openair-cn/UTILS/Makefile.am
+++ b/openair-cn/UTILS/Makefile.am
@@ -4,6 +4,7 @@ AM_CFLAGS = @ADD_CFLAGS@	\
 	-I$(top_srcdir)/COMMON	\
 	-I$(top_srcdir)/NAS/EURECOM-NAS/src/api/network	\
 	-I$(top_srcdir)/NAS/EURECOM-NAS/src/include \
+	-I$(top_srcdir)/SGW-LITE \
 	-I$(top_srcdir)/INTERTASK_INTERFACE
 
 AM_YFLAGS = -d
@@ -14,7 +15,6 @@ libutils_la_SOURCES = \
 	conversions.h	conversions.c	\
 	enum_string.h	enum_string.c	\
 	log.c log.h	\
-	mme_parser.y mme_scanner.l	\
 	mme_config.c mme_config.h	\
 	mme_default_values.h	\
 	queue.h	tree.h
diff --git a/openair-cn/UTILS/mme_config.c b/openair-cn/UTILS/mme_config.c
index 6bbb8d566f22f443931b929c6adb09f025ee9d8e..98b1a182a8aeaf48de6432bf5c68e0f2a9c79c54 100644
--- a/openair-cn/UTILS/mme_config.c
+++ b/openair-cn/UTILS/mme_config.c
@@ -38,16 +38,19 @@
 #include <unistd.h>
 #include <string.h>
 #include <errno.h>
+#include <libconfig.h>
 
 #include <arpa/inet.h> /* To provide inet_addr */
 
+#include "assertions.h"
 #include "mme_config.h"
+#include "spgw_config.h"
 #include "intertask_interface_conf.h"
 
 mme_config_t mme_config;
 
 static
-void config_init(mme_config_t *mme_config_p)
+void mme_config_init(mme_config_t *mme_config_p)
 {
     memset(mme_config_p, 0, sizeof(mme_config_t));
 
@@ -65,29 +68,15 @@ void config_init(mme_config_t *mme_config_p)
     mme_config_p->gtpv1u_config.port_number = GTPV1_U_PORT_NUMBER;
     mme_config_p->s1ap_config.port_number   = S1AP_PORT_NUMBER;
     /* IP configuration */
-    mme_config_p->ipv4.sgw_interface_name_for_S1u_S12_S4_up = DEFAULT_SGW_INTERFACE_NAME_FOR_S1U_S12_S4_UP;
     mme_config_p->ipv4.sgw_ip_address_for_S1u_S12_S4_up     = inet_addr(DEFAULT_SGW_IP_ADDRESS_FOR_S1U_S12_S4_UP);
-    mme_config_p->ipv4.sgw_ip_netmask_for_S1u_S12_S4_up     = DEFAULT_SGW_IP_NETMASK_FOR_S1U_S12_S4_UP;
-
-    mme_config_p->ipv4.sgw_interface_name_for_S5_S8_up      = DEFAULT_SGW_INTERFACE_NAME_FOR_S5_S8_UP;
-    mme_config_p->ipv4.sgw_ip_address_for_S5_S8_up          = inet_addr(DEFAULT_SGW_IP_ADDRESS_FOR_S5_S8_UP);
-    mme_config_p->ipv4.sgw_ip_netmask_for_S5_S8_up          = DEFAULT_SGW_IP_NETMASK_FOR_S5_S8_UP;
-
-    mme_config_p->ipv4.pgw_interface_name_for_SGI           = DEFAULT_PGW_INTERFACE_NAME_FOR_S5_S8;
-    mme_config_p->ipv4.pgw_ip_addr_for_SGI                  = inet_addr(DEFAULT_PGW_IP_ADDRESS_FOR_S5_S8);
-    mme_config_p->ipv4.pgw_ip_netmask_for_SGI               = DEFAULT_PGW_IP_NETMASK_FOR_S5_S8;
 
     mme_config_p->ipv4.mme_interface_name_for_S1_MME        = DEFAULT_MME_INTERFACE_NAME_FOR_S1_MME;
     mme_config_p->ipv4.mme_ip_address_for_S1_MME            = inet_addr(DEFAULT_MME_IP_ADDRESS_FOR_S1_MME);
-    mme_config_p->ipv4.mme_ip_netmask_for_S1_MME            = DEFAULT_MME_IP_NETMASK_FOR_S1_MME;
 
     mme_config_p->ipv4.mme_interface_name_for_S11           = DEFAULT_MME_INTERFACE_NAME_FOR_S11;
     mme_config_p->ipv4.mme_ip_address_for_S11               = inet_addr(DEFAULT_MME_IP_ADDRESS_FOR_S11);
-    mme_config_p->ipv4.mme_ip_netmask_for_S11               = DEFAULT_MME_IP_NETMASK_FOR_S11;
 
-    mme_config_p->ipv4.sgw_interface_name_for_S11           = DEFAULT_SGW_INTERFACE_NAME_FOR_S11;
     mme_config_p->ipv4.sgw_ip_address_for_S11               = inet_addr(DEFAULT_SGW_IP_ADDRESS_FOR_S11);
-    mme_config_p->ipv4.sgw_ip_netmask_for_S11               = DEFAULT_SGW_IP_NETMASK_FOR_S11;
 
     mme_config_p->s6a_config.conf_file    = S6A_CONF_FILE;
 
@@ -123,34 +112,231 @@ void config_init(mme_config_t *mme_config_p)
 
 static int config_parse_file(mme_config_t *mme_config_p)
 {
-    extern FILE *yyin;
-    int ret = -1;
-
-    if (mme_config_p == NULL)
-        return ret;
-    if (mme_config_p->config_file == NULL) {
-        fprintf(stderr, "No Configuration file given... Attempting default values\n");
-        return 0;
+    config_t          cfg;
+    config_setting_t *setting_mme = NULL;
+    config_setting_t *setting     = NULL;
+    config_setting_t *subsetting  = NULL;
+    config_setting_t *sub2setting = NULL;
+
+    long int         alongint;
+    int              i, num;
+    char             *astring = NULL;
+    char             *address = NULL;
+    char             *cidr    = NULL;
+
+    char             *sgw_ip_address_for_S1u_S12_S4_up = NULL;
+    char             *mme_interface_name_for_S1_MME    = NULL;
+    char             *mme_ip_address_for_S1_MME        = NULL;
+    char             *mme_interface_name_for_S11       = NULL;
+    char             *mme_ip_address_for_S11           = NULL;
+    char             *sgw_ip_address_for_S11           = NULL;
+
+    config_init(&cfg);
+
+    if(mme_config_p->config_file != NULL)
+    {
+        /* Read the file. If there is an error, report it and exit. */
+        if(! config_read_file(&cfg, mme_config_p->config_file))
+        {
+            fprintf(stdout, "ERROR: %s:%d - %s\n", mme_config_p->config_file, config_error_line(&cfg), config_error_text(&cfg));
+            config_destroy(&cfg);
+            AssertFatal (1 == 0, "Failed to parse MME configuration file %s!\n", mme_config_p->config_file);
+        }
     }
-
-    yyin = fopen(mme_config_p->config_file, "r");
-    if (!yyin) {
-        /* We failed to open the file */
-        fprintf(stderr, "Unable to open the configuration file: %s (%d:%s)\n",
-                mme_config_p->config_file, errno, strerror(errno));
-        return errno;
+    else
+    {
+        fprintf(stdout, "ERROR No MME configuration file provided!\n");
+        config_destroy(&cfg);
+        AssertFatal (0, "No MME configuration file provided!\n");
     }
 
-    /* Call the yacc parser */
-    ret = yyparse(mme_config_p);
+    setting_mme = config_lookup(&cfg, MME_CONFIG_STRING_MME_CONFIG);
+    if(setting_mme != NULL) {
+        // GENERAL MME SETTINGS
+        if(  (config_setting_lookup_string( setting_mme, MME_CONFIG_STRING_REALM, (const char **)&astring) )) {
+            mme_config_p->realm = strdup(astring);
+            mme_config_p->realm_length = strlen(mme_config_p->realm);
+        }
+        if(  (config_setting_lookup_int( setting_mme, MME_CONFIG_STRING_MAXENB, &alongint) )) {
+            mme_config_p->max_eNBs = (uint32_t)alongint;
+        }
+        if(  (config_setting_lookup_int( setting_mme, MME_CONFIG_STRING_MAXUE, &alongint) )) {
+            mme_config_p->max_ues = (uint32_t)alongint;
+        }
+        if(  (config_setting_lookup_int( setting_mme, MME_CONFIG_STRING_RELATIVE_CAPACITY, &alongint) )) {
+            mme_config_p->relative_capacity = (uint8_t)alongint;
+        }
+        if(  (config_setting_lookup_int( setting_mme, MME_CONFIG_STRING_STATISTIC_TIMER, &alongint) )) {
+            mme_config_p->mme_statistic_timer = (uint32_t)alongint;
+        }
+        if(  (config_setting_lookup_string( setting_mme, MME_CONFIG_STRING_EMERGENCY_ATTACH_SUPPORTED, (const char **)&astring) )) {
+            if (strcasecmp(astring , "yes") == 0)
+                mme_config_p->emergency_attach_supported = 1;
+            else
+                mme_config_p->emergency_attach_supported = 0;
+        }
+        if(  (config_setting_lookup_string( setting_mme, MME_CONFIG_STRING_UNAUTHENTICATED_IMSI_SUPPORTED, (const char **)&astring) )) {
+            if (strcasecmp(astring , "yes") == 0)
+                mme_config_p->unauthenticated_imsi_supported = 1;
+            else
+                mme_config_p->unauthenticated_imsi_supported = 0;
+        }
+
+        // ITTI SETTING
+        setting = config_setting_get_member (setting_mme, MME_CONFIG_STRING_INTERTASK_INTERFACE_CONFIG);
+        if (setting != NULL) {
+            if(  (config_setting_lookup_int( setting, MME_CONFIG_STRING_INTERTASK_INTERFACE_QUEUE_SIZE, &alongint) )) {
+                mme_config_p->itti_config.queue_size = (uint32_t)alongint;
+            }
+        }
+
+        // S6A SETTING
+        setting = config_setting_get_member (setting_mme, MME_CONFIG_STRING_S6A_CONFIG);
+        if (setting != NULL) {
+            if(  (config_setting_lookup_string( setting, MME_CONFIG_STRING_S6A_CONF_FILE_PATH, (const char **)&astring) )) {
+                if (astring != NULL)
+                    mme_config_p->s6a_config.conf_file = strdup(astring);
+            }
+        }
+
+        // SCTP SETTING
+        setting = config_setting_get_member (setting_mme, MME_CONFIG_STRING_SCTP_CONFIG);
+        if (setting != NULL) {
+            if(  (config_setting_lookup_int( setting, MME_CONFIG_STRING_SCTP_INSTREAMS, &alongint) )) {
+                mme_config_p->sctp_config.in_streams = (uint16_t)alongint;
+            }
+            if(  (config_setting_lookup_int( setting, MME_CONFIG_STRING_SCTP_OUTSTREAMS, &alongint) )) {
+                mme_config_p->sctp_config.out_streams = (uint16_t)alongint;
+            }
+        }
+
+        // S1AP SETTING
+        setting = config_setting_get_member (setting_mme, MME_CONFIG_STRING_S1AP_CONFIG);
+        if (setting != NULL) {
+            if(  (config_setting_lookup_int( setting, MME_CONFIG_STRING_S1AP_OUTCOME_TIMER, &alongint) )) {
+                mme_config_p->s1ap_config.outcome_drop_timer_sec = (uint8_t)alongint;
+            }
+            if(  (config_setting_lookup_int( setting, MME_CONFIG_STRING_SCTP_OUTSTREAMS, &alongint) )) {
+                mme_config_p->sctp_config.out_streams = (uint16_t)alongint;
+            }
+        }
+
+        // GUMMEI SETTING
+        setting = config_setting_get_member (setting_mme, MME_CONFIG_STRING_GUMMEI_CONFIG);
+        if (setting != NULL) {
+            subsetting = config_setting_get_member (setting, MME_CONFIG_STRING_MME_CODE);
+            if (subsetting != NULL) {
+                num     = config_setting_length(subsetting);
+                if (mme_config_p->gummei.nb_mmec != num) {
+                    if (mme_config_p->gummei.mmec != NULL) {
+                        free(mme_config_p->gummei.mmec);
+                    }
+                    mme_config_p->gummei.mmec = calloc(num, sizeof(*mme_config_p->gummei.mmec));
+                }
+                mme_config_p->gummei.nb_mmec = num;
+                for (i = 0; i < num; i++) {
+                    mme_config_p->gummei.mmec[i] = config_setting_get_int_elem(subsetting, i);
+                }
+            }
+
+            subsetting = config_setting_get_member (setting, MME_CONFIG_STRING_MME_GID);
+            if (subsetting != NULL) {
+                num     = config_setting_length(subsetting);
+                if (mme_config_p->gummei.nb_mme_gid != num) {
+                    if (mme_config_p->gummei.mme_gid != NULL) {
+                        free(mme_config_p->gummei.mme_gid);
+                    }
+                    mme_config_p->gummei.mme_gid = calloc(num, sizeof(*mme_config_p->gummei.mme_gid));
+                }
+                mme_config_p->gummei.nb_mme_gid = num;
+                for (i = 0; i < num; i++) {
+                    mme_config_p->gummei.mme_gid[i] = config_setting_get_int_elem(subsetting, i);
+                }
+            }
+
+            subsetting = config_setting_get_member (setting, MME_CONFIG_STRING_PLMN);
+            if (subsetting != NULL) {
+                num     = config_setting_length(subsetting);
+                if (mme_config_p->gummei.nb_plmns != num) {
+                    if (mme_config_p->gummei.plmn_mcc != NULL) free(mme_config_p->gummei.plmn_mcc);
+                    if (mme_config_p->gummei.plmn_mnc != NULL) free(mme_config_p->gummei.plmn_mnc);
+                    if (mme_config_p->gummei.plmn_tac != NULL) free(mme_config_p->gummei.plmn_tac);
+
+                    mme_config_p->gummei.plmn_mcc = calloc(num, sizeof(*mme_config_p->gummei.plmn_mcc));
+                    mme_config_p->gummei.plmn_mnc = calloc(num, sizeof(*mme_config_p->gummei.plmn_mnc));
+                    mme_config_p->gummei.plmn_tac = calloc(num, sizeof(*mme_config_p->gummei.plmn_tac));
+                }
+                mme_config_p->gummei.nb_plmns = num;
+                for (i = 0; i < num; i++) {
+                    sub2setting =  config_setting_get_elem(subsetting, i);
+                    if (sub2setting != NULL) {
+                        if(  (config_setting_lookup_int( sub2setting, MME_CONFIG_STRING_MCC, &alongint) )) {
+                            mme_config_p->gummei.plmn_mcc[i] = (uint16_t)alongint;
+                        }
+                        if(  (config_setting_lookup_int( sub2setting, MME_CONFIG_STRING_MNC, &alongint) )) {
+                            mme_config_p->gummei.plmn_mnc[i] = (uint16_t)alongint;
+                        }
+                        if(  (config_setting_lookup_int( sub2setting, MME_CONFIG_STRING_TAC, &alongint) )) {
+                            mme_config_p->gummei.plmn_tac[i] = (uint16_t)alongint;
+                        }
+                    }
+                }
+            }
+        }
 
-    /* Close the file descriptor */
-    if (fclose(yyin) != 0) {
-        fprintf(stderr, "Unable to close the configuration file: %s (%d:%s)\n",
-                mme_config_p->config_file, errno, strerror(errno));
-        return errno;
+        // NETWORK INTERFACE SETTING
+        setting = config_setting_get_member (setting_mme, MME_CONFIG_STRING_NETWORK_INTERFACES_CONFIG);
+        if(setting != NULL) {
+            if(  (
+                       config_setting_lookup_string( setting, MME_CONFIG_STRING_INTERFACE_NAME_FOR_S1_MME,
+                               (const char **)&mme_interface_name_for_S1_MME)
+                    && config_setting_lookup_string( setting, MME_CONFIG_STRING_IPV4_ADDRESS_FOR_S1_MME,
+                            (const char **)&mme_ip_address_for_S1_MME)
+                    && config_setting_lookup_string( setting, MME_CONFIG_STRING_INTERFACE_NAME_FOR_S11_MME,
+                            (const char **)&mme_interface_name_for_S11)
+                    && config_setting_lookup_string( setting, MME_CONFIG_STRING_IPV4_ADDRESS_FOR_S11_MME,
+                            (const char **)&mme_ip_address_for_S11)
+                  )
+              ) {
+                mme_config_p->ipv4.mme_interface_name_for_S1_MME = strdup(mme_interface_name_for_S1_MME);
+                cidr = strdup(mme_ip_address_for_S1_MME);
+                address = strtok(cidr, "/");
+                IPV4_STR_ADDR_TO_INT_NWBO ( address, mme_config_p->ipv4.mme_ip_address_for_S1_MME, "BAD IP ADDRESS FORMAT FOR MME S1_MME !\n" )
+                free(cidr);
+
+                mme_config_p->ipv4.mme_interface_name_for_S11 = strdup(mme_interface_name_for_S11);
+                cidr = strdup(mme_ip_address_for_S11);
+                address = strtok(cidr, "/");
+                IPV4_STR_ADDR_TO_INT_NWBO ( address, mme_config_p->ipv4.mme_ip_address_for_S11, "BAD IP ADDRESS FORMAT FOR MME S11 !\n" )
+                free(cidr);
+            }
+        }
+    }
+
+    setting = config_lookup(&cfg, SGW_CONFIG_STRING_SGW_CONFIG);
+    if(setting != NULL) {
+        subsetting = config_setting_get_member (setting, SGW_CONFIG_STRING_NETWORK_INTERFACES_CONFIG);
+        if(subsetting != NULL) {
+            if(  (
+                    config_setting_lookup_string( subsetting, SGW_CONFIG_STRING_SGW_IPV4_ADDRESS_FOR_S1U_S12_S4_UP,
+                            (const char **)&sgw_ip_address_for_S1u_S12_S4_up)
+                    && config_setting_lookup_string( subsetting, SGW_CONFIG_STRING_SGW_IPV4_ADDRESS_FOR_S11,
+                            (const char **)&sgw_ip_address_for_S11)
+                  )
+              ) {
+                cidr = strdup(sgw_ip_address_for_S1u_S12_S4_up);
+                address = strtok(cidr, "/");
+                IPV4_STR_ADDR_TO_INT_NWBO ( address, mme_config_p->ipv4.sgw_ip_address_for_S1u_S12_S4_up, "BAD IP ADDRESS FORMAT FOR SGW S1u_S12_S4 !\n" )
+                free(cidr);
+
+                cidr = strdup(sgw_ip_address_for_S11);
+                address = strtok(cidr, "/");
+                IPV4_STR_ADDR_TO_INT_NWBO ( address, mme_config_p->ipv4.sgw_ip_address_for_S11, "BAD IP ADDRESS FORMAT FOR SGW S11 !\n" )
+                free(cidr);
+            }
+        }
     }
-    return ret;
+    return 0;
 }
 
 #define DISPLAY_ARRAY(size, format, args...)                        \
@@ -178,7 +364,6 @@ static void config_display(mme_config_t *mme_config_p)
     fprintf(stdout, "- Max UEs ............: %u\n", mme_config_p->max_ues);
     fprintf(stdout, "- Emergency support ..: %s\n", mme_config_p->emergency_attach_supported == 0 ? "FALSE" : "TRUE");
     fprintf(stdout, "- Unauth IMSI support : %s\n", mme_config_p->unauthenticated_imsi_supported == 0 ? "FALSE" : "TRUE");
-    fprintf(stdout, "- Max UEs ............: %u\n", mme_config_p->max_ues);
     fprintf(stdout, "- Relative capa ......: %u\n\n", mme_config_p->relative_capacity);
     fprintf(stdout, "- Statistics timer ...: %u (seconds)\n\n", mme_config_p->mme_statistic_timer);
     fprintf(stdout, "- S1-U:\n");
@@ -186,26 +371,24 @@ static void config_display(mme_config_t *mme_config_p)
     fprintf(stdout, "- S1-MME:\n");
     fprintf(stdout, "    port number ......: %d\n", mme_config_p->s1ap_config.port_number);
     fprintf(stdout, "- IP:\n");
-    fprintf(stdout, "    s1-u iface .......: %s\n", mme_config_p->ipv4.sgw_interface_name_for_S1u_S12_S4_up);
-    fprintf(stdout, "    s1-u ip ..........: %s/%d\n",
-            inet_ntoa(*((struct in_addr *)&mme_config_p->ipv4.sgw_ip_address_for_S1u_S12_S4_up)),
-            mme_config_p->ipv4.sgw_ip_netmask_for_S1u_S12_S4_up);
-    fprintf(stdout, "    sgi iface ........: %s\n", mme_config_p->ipv4.pgw_interface_name_for_SGI);
-    fprintf(stdout, "    sgi ip ...........: %s/%d\n",
-            inet_ntoa(*((struct in_addr *)&mme_config_p->ipv4.pgw_ip_addr_for_SGI)),
-            mme_config_p->ipv4.pgw_ip_netmask_for_SGI);
+    //fprintf(stdout, "    s1-u iface .......: %s\n", mme_config_p->ipv4.sgw_interface_name_for_S1u_S12_S4_up);
+    //fprintf(stdout, "    s1-u ip ..........: %s/%d\n",
+    //        inet_ntoa(*((struct in_addr *)&mme_config_p->ipv4.sgw_ip_address_for_S1u_S12_S4_up)),
+    //        mme_config_p->ipv4.sgw_ip_netmask_for_S1u_S12_S4_up);
+    //fprintf(stdout, "    sgi iface ........: %s\n", mme_config_p->ipv4.pgw_interface_name_for_SGI);
+    //fprintf(stdout, "    sgi ip ...........: %s/%d\n",
+    //        inet_ntoa(*((struct in_addr *)&mme_config_p->ipv4.pgw_ip_addr_for_SGI)),
+    //        mme_config_p->ipv4.pgw_ip_netmask_for_SGI);
     fprintf(stdout, "    s1-MME iface .....: %s\n", mme_config_p->ipv4.mme_interface_name_for_S1_MME);
-    fprintf(stdout, "    s1-MME ip ........: %s/%d\n",
-            inet_ntoa(*((struct in_addr *)&mme_config_p->ipv4.mme_ip_address_for_S1_MME)),
-            mme_config_p->ipv4.mme_ip_netmask_for_S1_MME);
-    fprintf(stdout, "    s11 S-GW iface ...: %s\n", mme_config_p->ipv4.sgw_interface_name_for_S11);
-    fprintf(stdout, "    s11 S-GW ip ......: %s/%d\n",
-            inet_ntoa(*((struct in_addr *)&mme_config_p->ipv4.sgw_ip_address_for_S11)),
-            mme_config_p->ipv4.sgw_ip_netmask_for_S11);
+    fprintf(stdout, "    s1-MME ip ........: %s\n",
+            inet_ntoa(*((struct in_addr *)&mme_config_p->ipv4.mme_ip_address_for_S1_MME)));
+    //fprintf(stdout, "    s11 S-GW iface ...: %s\n", mme_config_p->ipv4.sgw_interface_name_for_S11);
+    //fprintf(stdout, "    s11 S-GW ip ......: %s/%d\n",
+    //        inet_ntoa(*((struct in_addr *)&mme_config_p->ipv4.sgw_ip_address_for_S11)),
+    //        mme_config_p->ipv4.sgw_ip_netmask_for_S11);
     fprintf(stdout, "    s11 MME iface ....: %s\n", mme_config_p->ipv4.mme_interface_name_for_S11);
-    fprintf(stdout, "    s11 S-GW ip ......: %s/%d\n",
-            inet_ntoa(*((struct in_addr *)&mme_config_p->ipv4.mme_ip_address_for_S11)),
-            mme_config_p->ipv4.mme_ip_netmask_for_S11);
+    fprintf(stdout, "    s11 S-GW ip ......: %s\n",
+            inet_ntoa(*((struct in_addr *)&mme_config_p->ipv4.mme_ip_address_for_S11)));
     fprintf(stdout, "- ITTI:\n");
     fprintf(stdout, "    queue size .......: %u (bytes)\n", mme_config_p->itti_config.queue_size);
     fprintf(stdout, "    log file .........: %s\n", mme_config_p->itti_config.log_file);
@@ -251,7 +434,7 @@ nwGtpv1uDisplayBanner(void);
 int config_parse_opt_line(int argc, char *argv[], mme_config_t *mme_config_p)
 {
     int c;
-    config_init(mme_config_p);
+    mme_config_init(mme_config_p);
     /* Parsing command line */
     while ((c = getopt (argc, argv, "c:hi:K:v:V")) != -1) {
         switch (c) {
@@ -265,15 +448,15 @@ int config_parse_opt_line(int argc, char *argv[], mme_config_t *mme_config_p)
                 memcpy(mme_config_p->config_file, optarg, config_file_len);
                 mme_config_p->config_file[config_file_len] = '\0';
             } break;
-            case 'i': {
+            /*case 'i': {
                 int interface_len = 0;
 
-                /* Copying provided interface name to use for ipv4 forwarding */
+                // Copying provided interface name to use for ipv4 forwarding
                 interface_len = strlen(optarg);
                 mme_config_p->ipv4.sgw_interface_name_for_S1u_S12_S4_up = calloc(interface_len + 1, sizeof(char));
                 memcpy(mme_config_p->ipv4.sgw_interface_name_for_S1u_S12_S4_up, optarg, interface_len);
                 mme_config_p->ipv4.sgw_interface_name_for_S1u_S12_S4_up[interface_len] = '\0';
-            } break;
+            } break;*/
             case 'v': {
                 mme_config_p->verbosity_level = atoi(optarg);
             } break;
diff --git a/openair-cn/UTILS/mme_config.h b/openair-cn/UTILS/mme_config.h
index 0dd5f3eaafc343264c66336b547d4864414dee30..06f0e75296db6f1f3309ba7fc3f72e65c309ed10 100644
--- a/openair-cn/UTILS/mme_config.h
+++ b/openair-cn/UTILS/mme_config.h
@@ -36,6 +36,44 @@
 #ifndef MME_CONFIG_H_
 #define MME_CONFIG_H_
 
+#define MME_CONFIG_STRING_MME_CONFIG                     "MME"
+#define MME_CONFIG_STRING_REALM                          "REALM"
+#define MME_CONFIG_STRING_MAXENB                         "MAXENB"
+#define MME_CONFIG_STRING_MAXUE                          "MAXUE"
+#define MME_CONFIG_STRING_RELATIVE_CAPACITY              "RELATIVE_CAPACITY"
+#define MME_CONFIG_STRING_STATISTIC_TIMER                "MME_STATISTIC_TIMER"
+#define MME_CONFIG_STRING_EMERGENCY_ATTACH_SUPPORTED     "EMERGENCY_ATTACH_SUPPORTED"
+#define MME_CONFIG_STRING_UNAUTHENTICATED_IMSI_SUPPORTED "UNAUTHENTICATED_IMSI_SUPPORTED"
+
+#define MME_CONFIG_STRING_INTERTASK_INTERFACE_CONFIG     "INTERTASK_INTERFACE"
+#define MME_CONFIG_STRING_INTERTASK_INTERFACE_QUEUE_SIZE "ITTI_QUEUE_SIZE"
+
+#define MME_CONFIG_STRING_S6A_CONFIG                     "S6A"
+#define MME_CONFIG_STRING_S6A_CONF_FILE_PATH             "S6A_CONF"
+
+#define MME_CONFIG_STRING_SCTP_CONFIG                    "SCTP"
+#define MME_CONFIG_STRING_SCTP_INSTREAMS                 "SCTP_INSTREAMS"
+#define MME_CONFIG_STRING_SCTP_OUTSTREAMS                "SCTP_OUTSTREAMS"
+
+
+#define MME_CONFIG_STRING_S1AP_CONFIG                    "S1AP"
+#define MME_CONFIG_STRING_S1AP_OUTCOME_TIMER             "S1AP_OUTCOME_TIMER"
+
+#define MME_CONFIG_STRING_GUMMEI_CONFIG                  "GUMMEI"
+#define MME_CONFIG_STRING_MME_CODE                       "MME_CODE"
+#define MME_CONFIG_STRING_MME_GID                        "MME_GID"
+#define MME_CONFIG_STRING_PLMN                           "PLMN"
+#define MME_CONFIG_STRING_MCC                            "MCC"
+#define MME_CONFIG_STRING_MNC                            "MNC"
+#define MME_CONFIG_STRING_TAC                            "TAC"
+
+#define MME_CONFIG_STRING_NETWORK_INTERFACES_CONFIG      "NETWORK_INTERFACES"
+#define MME_CONFIG_STRING_INTERFACE_NAME_FOR_S1_MME      "MME_INTERFACE_NAME_FOR_S1_MME"
+#define MME_CONFIG_STRING_IPV4_ADDRESS_FOR_S1_MME        "MME_IPV4_ADDRESS_FOR_S1_MME"
+#define MME_CONFIG_STRING_INTERFACE_NAME_FOR_S11_MME     "MME_INTERFACE_NAME_FOR_S11_MME"
+#define MME_CONFIG_STRING_IPV4_ADDRESS_FOR_S11_MME       "MME_IPV4_ADDRESS_FOR_S11_MME"
+
+
 typedef struct mme_config_s {
     /* Reader/writer lock for this configuration */
     pthread_rwlock_t rw_lock;
@@ -81,33 +119,15 @@ typedef struct mme_config_s {
         uint8_t  outcome_drop_timer_sec;
     } s1ap_config;
     struct {
-        char     *sgw_interface_name_for_S1u_S12_S4_up;
         uint32_t  sgw_ip_address_for_S1u_S12_S4_up;
-        int       sgw_ip_netmask_for_S1u_S12_S4_up;
-
-        char     *sgw_interface_name_for_S5_S8_up;
-        uint32_t  sgw_ip_address_for_S5_S8_up;
-        int       sgw_ip_netmask_for_S5_S8_up;
-
-        char     *pgw_interface_name_for_S5_S8;
-        uint32_t  pgw_ip_address_for_S5_S8;
-        int       pgw_ip_netmask_for_S5_S8;
-
-        char     *pgw_interface_name_for_SGI;
-        uint32_t  pgw_ip_addr_for_SGI;
-        int       pgw_ip_netmask_for_SGI;
 
         char     *mme_interface_name_for_S1_MME;
         uint32_t  mme_ip_address_for_S1_MME;
-        int       mme_ip_netmask_for_S1_MME;
 
         char     *mme_interface_name_for_S11;
         uint32_t  mme_ip_address_for_S11;
-        int       mme_ip_netmask_for_S11;
 
-        char     *sgw_interface_name_for_S11;
         uint32_t  sgw_ip_address_for_S11;
-        int       sgw_ip_netmask_for_S11;
     } ipv4;
     struct {
         char *conf_file;
@@ -126,6 +146,6 @@ int config_parse_opt_line(int argc, char *argv[], mme_config_t *mme_config);
 #define config_write_lock(mMEcONFIG) pthread_rwlock_wrlock(&(mMEcONFIG)->rw_lock)
 #define config_unlock(mMEcONFIG)     pthread_rwlock_unlock(&(mMEcONFIG)->rw_lock)
 
-int yyparse(struct mme_config_s *mme_config_p);
+//int yyparse(struct mme_config_s *mme_config_p);
 
 #endif /* MME_CONFIG_H_ */
diff --git a/openair-cn/UTILS/mme_default_values.h b/openair-cn/UTILS/mme_default_values.h
index 0be05d168322c30b4f63468aec1498abac5e1689..9a70d9376a974be1cb0b8ef1e324b1c7d175dc83 100644
--- a/openair-cn/UTILS/mme_default_values.h
+++ b/openair-cn/UTILS/mme_default_values.h
@@ -93,9 +93,13 @@
  *        |           |cpenb0+------------------+cpmme0|           |
  *        |           +------+   |bridge|       +------+           |
  *        |           |upenb0+-------+  |              |           |
- *        +-----------+------+   |   |  |              +-----------+
- *                               +---|--+                    |
- *                                   |                 +-----------+
+ *        +-----------+------+   |   |  |              +-+------+--+
+ *                               +---|--+                |s11mme|
+ *                                   |                   +---+--+
+ *                                   |                 VLAN3 | (optional)
+ *                                   |                   +---+--+
+ *                                   |                   |s11sgw|
+ *                                   |                 +-+------+--+
  *                                   |                 |  S+P-GW   |
  *                                   |  VLAN2   +------+           +--------+
  *                                   +----------+upsgw0|           |pgwsgi0 +
@@ -132,7 +136,5 @@
 #define DEFAULT_MME_IP_ADDRESS_FOR_S1_MME             ("192.168.11.1")   ///< MME control plane IP address
 #define DEFAULT_MME_IP_NETMASK_FOR_S1_MME             24;
 
-#define IPV4_UP_UE_SUBNET      ("10.2.0.0")
-
 
 #endif /* MME_DEFAULT_VALUES_H_ */