diff --git a/openair-cn/SGW-LITE/Makefile.am b/openair-cn/SGW-LITE/Makefile.am index 9b469f9e93d24f253c6ecf0be0b1a690711f1680..80a0815f49a9634b9e77009f0af66fdeff837187 100644 --- a/openair-cn/SGW-LITE/Makefile.am +++ b/openair-cn/SGW-LITE/Makefile.am @@ -12,11 +12,12 @@ AM_CFLAGS = @ADD_CFLAGS@ \ -I$(top_srcdir)/UTILS/HASHTABLE noinst_LTLIBRARIES = libsgw_lite.la -libsgw_lite_la_LDFLAGS = -all-static +libsgw_lite_la_LDFLAGS = -all-static -lconfig -libsgw_lite_la_SOURCES= \ - s11_causes.c s11_causes.h \ - sgw_lite_task.c \ - sgw_lite_handlers.c sgw_lite_handlers.h \ +libsgw_lite_la_SOURCES= \ + spgw_config.c spgw_config.h \ + s11_causes.c s11_causes.h \ + sgw_lite_task.c \ + sgw_lite_handlers.c sgw_lite_handlers.h \ sgw_lite_context_manager.c sgw_lite_context_manager.h \ - sgw_lite.h + sgw_lite.h sgw_lite_defs.h sgw_lite_ie_defs.h diff --git a/openair-cn/SGW-LITE/s11_causes.c b/openair-cn/SGW-LITE/s11_causes.c index 21476f764c1e09a97098550cac0c95d2417bff0f..e06e3008cf924bf1d9cdba331c2524106e6d0aa5 100644 --- a/openair-cn/SGW-LITE/s11_causes.c +++ b/openair-cn/SGW-LITE/s11_causes.c @@ -27,6 +27,8 @@ 06410 Biot FRANCE *******************************************************************************/ +#define SGW_LITE +#define S11_CAUSES_C #include <stdio.h> #include <stdlib.h> diff --git a/openair-cn/SGW-LITE/sgw_lite.h b/openair-cn/SGW-LITE/sgw_lite.h index 76d71c7a6f51019af0d4cc9649c8123f4c980ce5..c50a7ccc9562006e5286356663372f04d80212bc 100755 --- a/openair-cn/SGW-LITE/sgw_lite.h +++ b/openair-cn/SGW-LITE/sgw_lite.h @@ -59,5 +59,19 @@ typedef struct sgw_app_s{ } sgw_app_t; +typedef struct ipv4_address_s { + +}ipv4_address_t; +typedef struct ipv6_address_s { + +}ipv6_address_t; + +typedef struct pgw_app_s{ + STAILQ_HEAD(free_ipv4_addresses_head_s, ipv4_address_s) free_ipv4_addresses_head; + STAILQ_HEAD(free_ipv6_addresses_head_s, ipv6_address_s) free_ipv6_addresses_head; + STAILQ_HEAD(allocated_ipv4_addresses_head_s, ipv4_address_s) allocated_ipv4_addresses_head; + STAILQ_HEAD(allocated_ipv6_addresses_head_s, ipv6_address_s) allocated_ipv6_addresses_head; +} pgw_app_t; + #endif diff --git a/openair-cn/SGW-LITE/sgw_lite_context_manager.c b/openair-cn/SGW-LITE/sgw_lite_context_manager.c index 091788806de629c3498410526570d65fdd963075..f6a4c9c22112449e10977019a7ef41eeb35d95a3 100644 --- a/openair-cn/SGW-LITE/sgw_lite_context_manager.c +++ b/openair-cn/SGW-LITE/sgw_lite_context_manager.c @@ -27,6 +27,8 @@ 06410 Biot FRANCE *******************************************************************************/ +#define SGW_LITE +#define SGW_LITE_CONTEXT_MANAGER_C #include <stdio.h> #include <stdlib.h> @@ -65,7 +67,7 @@ void sgw_lite_display_s11teid2mme_mappings(void) SPGW_APP_DEBUG("+--------------------------------------+\n"); SPGW_APP_DEBUG("| MME <--- S11 TE ID MAPPINGS ---> SGW |\n"); SPGW_APP_DEBUG("+--------------------------------------+\n"); - hashtbl_apply_funct_on_elements(sgw_app.s11teid2mme_hashtable, sgw_lite_display_s11teid2mme_mapping, NULL); + hashtable_apply_funct_on_elements(sgw_app.s11teid2mme_hashtable, sgw_lite_display_s11teid2mme_mapping, NULL); SPGW_APP_DEBUG("+--------------------------------------+\n"); } //----------------------------------------------------------------------------- @@ -91,7 +93,7 @@ static void sgw_lite_display_s11_bearer_context_information(uint64_t keyP, void //----------------------------------------------------------------------------- { s_plus_p_gw_eps_bearer_context_information_t * sp_context_information= NULL; - hashtbl_rc_t hash_rc; + hashtable_rc_t hash_rc; if (dataP != NULL) { sp_context_information = (s_plus_p_gw_eps_bearer_context_information_t *)dataP; @@ -111,7 +113,7 @@ static void sgw_lite_display_s11_bearer_context_information(uint64_t keyP, void SPGW_APP_DEBUG("|\t\t\tdefault_bearer: %u\n", sp_context_information->sgw_eps_bearer_context_information.pdn_connection.default_bearer); SPGW_APP_DEBUG("|\t\t\teps_bearers:\n"); - hash_rc = hashtbl_apply_funct_on_elements(sp_context_information->sgw_eps_bearer_context_information.pdn_connection.sgw_eps_bearers, + hash_rc = hashtable_apply_funct_on_elements(sp_context_information->sgw_eps_bearer_context_information.pdn_connection.sgw_eps_bearers, sgw_lite_display_pdn_connection_sgw_eps_bearers, NULL); if (hash_rc != HASH_TABLE_OK) { @@ -131,7 +133,7 @@ void sgw_lite_display_s11_bearer_context_information_mapping(void) SPGW_APP_DEBUG("+-----------------------------------------+\n"); SPGW_APP_DEBUG("| S11 BEARER CONTEXT INFORMATION MAPPINGS |\n"); SPGW_APP_DEBUG("+-----------------------------------------+\n"); - hashtbl_apply_funct_on_elements(sgw_app.s11_bearer_context_information_hashtable, sgw_lite_display_s11_bearer_context_information, NULL); + hashtable_apply_funct_on_elements(sgw_app.s11_bearer_context_information_hashtable, sgw_lite_display_s11_bearer_context_information, NULL); SPGW_APP_DEBUG("+--------------------------------------+\n"); } //----------------------------------------------------------------------------- @@ -140,7 +142,7 @@ void pgw_lite_cm_free_apn(pgw_apn_t *apnP) { if (apnP != NULL) { if (apnP->pdn_connections != NULL) { - obj_hashtbl_destroy(apnP->pdn_connections); + obj_hashtable_destroy(apnP->pdn_connections); } } } @@ -175,7 +177,7 @@ mme_sgw_tunnel_t *sgw_lite_cm_create_s11_tunnel(Teid_t remote_teid, Teid_t local /* Trying to insert the new tunnel into the tree. * If collision_p is not NULL (0), it means tunnel is already present. */ - hashtbl_insert(sgw_app.s11teid2mme_hashtable, local_teid, new_tunnel); + hashtable_insert(sgw_app.s11teid2mme_hashtable, local_teid, new_tunnel); return new_tunnel; } @@ -186,7 +188,7 @@ int sgw_lite_cm_remove_s11_tunnel(Teid_t local_teid) { int temp; - temp = hashtbl_remove(sgw_app.s11teid2mme_hashtable, local_teid); + temp = hashtable_remove(sgw_app.s11teid2mme_hashtable, local_teid); return temp; } @@ -223,7 +225,7 @@ sgw_pdn_connection_t * sgw_lite_cm_create_pdn_connection(void) } memset(pdn_connection, 0, sizeof(sgw_pdn_connection_t)); - pdn_connection->sgw_eps_bearers = hashtbl_create(12, NULL, NULL); + pdn_connection->sgw_eps_bearers = hashtable_create(12, NULL, NULL); if ( pdn_connection->sgw_eps_bearers == NULL) { SPGW_APP_ERROR("Failed to create eps bearers collection object\n"); free(pdn_connection); @@ -238,7 +240,7 @@ void sgw_lite_cm_free_pdn_connection(sgw_pdn_connection_t *pdn_connectionP) { if (pdn_connectionP != NULL) { if (pdn_connectionP->sgw_eps_bearers != NULL) { - hashtbl_destroy(pdn_connectionP->sgw_eps_bearers); + hashtable_destroy(pdn_connectionP->sgw_eps_bearers); } } } @@ -250,14 +252,14 @@ void sgw_lite_cm_free_s_plus_p_gw_eps_bearer_context_information(s_plus_p_gw_eps return; } /*if (contextP->sgw_eps_bearer_context_information.pdn_connections != NULL) { - obj_hashtbl_destroy(contextP->sgw_eps_bearer_context_information.pdn_connections); + obj_hashtable_destroy(contextP->sgw_eps_bearer_context_information.pdn_connections); }*/ if (contextP->sgw_eps_bearer_context_information.pdn_connection.sgw_eps_bearers != NULL) { - hashtbl_destroy(contextP->sgw_eps_bearer_context_information.pdn_connection.sgw_eps_bearers); + hashtable_destroy(contextP->sgw_eps_bearer_context_information.pdn_connection.sgw_eps_bearers); } if (contextP->pgw_eps_bearer_context_information.apns != NULL) { - obj_hashtbl_destroy(contextP->pgw_eps_bearer_context_information.apns); + obj_hashtable_destroy(contextP->pgw_eps_bearer_context_information.apns); } free(contextP); } @@ -278,7 +280,7 @@ s_plus_p_gw_eps_bearer_context_information_t * sgw_lite_cm_create_bearer_context memset(new_bearer_context_information, 0, sizeof(s_plus_p_gw_eps_bearer_context_information_t)); SPGW_APP_DEBUG("sgw_lite_cm_create_bearer_context_information_in_collection %d\n", teid); - /*new_bearer_context_information->sgw_eps_bearer_context_information.pdn_connections = obj_hashtbl_create(32, NULL, NULL, sgw_lite_cm_free_pdn_connection); + /*new_bearer_context_information->sgw_eps_bearer_context_information.pdn_connections = obj_hashtable_create(32, NULL, NULL, sgw_lite_cm_free_pdn_connection); if ( new_bearer_context_information->sgw_eps_bearer_context_information.pdn_connections == NULL) { SPGW_APP_ERROR("Failed to create PDN connections collection object entry for EPS bearer teid %u \n", teid); @@ -286,7 +288,7 @@ s_plus_p_gw_eps_bearer_context_information_t * sgw_lite_cm_create_bearer_context return NULL; }*/ - new_bearer_context_information->pgw_eps_bearer_context_information.apns = obj_hashtbl_create(32, NULL, NULL, pgw_lite_cm_free_apn); + new_bearer_context_information->pgw_eps_bearer_context_information.apns = obj_hashtable_create(32, NULL, NULL, pgw_lite_cm_free_apn); if ( new_bearer_context_information->pgw_eps_bearer_context_information.apns == NULL) { SPGW_APP_ERROR("Failed to create APN collection object entry for EPS bearer S11 teid %u \n", teid); @@ -297,7 +299,7 @@ s_plus_p_gw_eps_bearer_context_information_t * sgw_lite_cm_create_bearer_context /* Trying to insert the new tunnel into the tree. * If collision_p is not NULL (0), it means tunnel is already present. */ - hashtbl_insert(sgw_app.s11_bearer_context_information_hashtable, teid, new_bearer_context_information); + hashtable_insert(sgw_app.s11_bearer_context_information_hashtable, teid, new_bearer_context_information); SPGW_APP_DEBUG("Added new s_plus_p_gw_eps_bearer_context_information_t in s11_bearer_context_information_hashtable key teid %u\n", teid); return new_bearer_context_information; @@ -305,7 +307,7 @@ s_plus_p_gw_eps_bearer_context_information_t * sgw_lite_cm_create_bearer_context int sgw_lite_cm_remove_bearer_context_information(Teid_t teid) { int temp; - temp = hashtbl_remove(sgw_app.s11_bearer_context_information_hashtable, teid); + temp = hashtable_remove(sgw_app.s11_bearer_context_information_hashtable, teid); return temp; } @@ -316,7 +318,7 @@ sgw_eps_bearer_entry_t * sgw_lite_cm_create_eps_bearer_entry_in_collection(hash_ //----------------------------------------------------------------------------- { sgw_eps_bearer_entry_t *new_eps_bearer_entry; - hashtbl_rc_t hash_rc = HASH_TABLE_OK; + hashtable_rc_t hash_rc = HASH_TABLE_OK; if (eps_bearersP == NULL) { SPGW_APP_ERROR("Failed to create EPS bearer entry for EPS bearer id %u. reason eps bearer hashtable is NULL \n", eps_bearer_idP); @@ -333,10 +335,10 @@ sgw_eps_bearer_entry_t * sgw_lite_cm_create_eps_bearer_entry_in_collection(hash_ new_eps_bearer_entry->eps_bearer_id = eps_bearer_idP; - hash_rc = hashtbl_insert(eps_bearersP, eps_bearer_idP, new_eps_bearer_entry); - SPGW_APP_DEBUG("Inserted new EPS bearer entry for EPS bearer id %u status %s\n", eps_bearer_idP, hashtble_rc_code2string(hash_rc)); + hash_rc = hashtable_insert(eps_bearersP, eps_bearer_idP, new_eps_bearer_entry); + SPGW_APP_DEBUG("Inserted new EPS bearer entry for EPS bearer id %u status %s\n", eps_bearer_idP, hashtable_rc_code2string(hash_rc)); - hash_rc = hashtbl_apply_funct_on_elements(eps_bearersP, + hash_rc = hashtable_apply_funct_on_elements(eps_bearersP, sgw_lite_display_pdn_connection_sgw_eps_bearers, NULL); if (hash_rc != HASH_TABLE_OK) { @@ -358,7 +360,7 @@ int sgw_lite_cm_remove_eps_bearer_entry(hash_table_t *eps_bearersP, ebi_t eps_be if (eps_bearersP == NULL) { return -1; } - temp = hashtbl_remove(eps_bearersP, eps_bearer_idP); + temp = hashtable_remove(eps_bearersP, eps_bearer_idP); return temp; } diff --git a/openair-cn/SGW-LITE/sgw_lite_defs.h b/openair-cn/SGW-LITE/sgw_lite_defs.h index ca0da471055ea1ef268bf297c231f17652b70c47..a1a582af4c08410e0273ea95c270cbc14f0d5a1b 100644 --- a/openair-cn/SGW-LITE/sgw_lite_defs.h +++ b/openair-cn/SGW-LITE/sgw_lite_defs.h @@ -44,6 +44,6 @@ while(0) #endif -int sgw_lite_init(const mme_config_t *mme_config); +int sgw_lite_init(char* config_file_name_pP); #endif /* SGW_LITE_DEFS_H_ */ diff --git a/openair-cn/SGW-LITE/sgw_lite_handlers.c b/openair-cn/SGW-LITE/sgw_lite_handlers.c index 7f34223d62f5fe5da01a95d05ce7911770913bc7..586d09e295c0490961f07abef4e8d8135b15073a 100644 --- a/openair-cn/SGW-LITE/sgw_lite_handlers.c +++ b/openair-cn/SGW-LITE/sgw_lite_handlers.c @@ -27,6 +27,8 @@ 06410 Biot FRANCE *******************************************************************************/ +#define SGW_LITE +#define SGW_LITE_HANDLERS_C #include <stdio.h> #include <stdlib.h> @@ -118,7 +120,7 @@ int sgw_lite_handle_create_session_request(SgwCreateSessionRequest *session_req_ return -1; }*/ memset(&s_plus_p_gw_eps_bearer_context_information->sgw_eps_bearer_context_information.pdn_connection, 0, sizeof(sgw_pdn_connection_t)); - s_plus_p_gw_eps_bearer_context_information->sgw_eps_bearer_context_information.pdn_connection.sgw_eps_bearers = hashtbl_create(12, NULL, NULL); + s_plus_p_gw_eps_bearer_context_information->sgw_eps_bearer_context_information.pdn_connection.sgw_eps_bearers = hashtable_create(12, NULL, NULL); if ( s_plus_p_gw_eps_bearer_context_information->sgw_eps_bearer_context_information.pdn_connection.sgw_eps_bearers == NULL) { SPGW_APP_ERROR("Failed to create eps bearers collection object\n"); DevMessage("Failed to create eps bearers collection object\n"); @@ -132,7 +134,7 @@ int sgw_lite_handle_create_session_request(SgwCreateSessionRequest *session_req_ } s_plus_p_gw_eps_bearer_context_information->sgw_eps_bearer_context_information.pdn_connection.default_bearer = session_req_p->bearer_to_create.eps_bearer_id; - //obj_hashtbl_insert(s_plus_p_gw_eps_bearer_context_information->sgw_eps_bearer_context_information.pdn_connections, pdn_connection->apn_in_use, strlen(pdn_connection->apn_in_use), pdn_connection); + //obj_hashtable_insert(s_plus_p_gw_eps_bearer_context_information->sgw_eps_bearer_context_information.pdn_connections, pdn_connection->apn_in_use, strlen(pdn_connection->apn_in_use), pdn_connection); //-------------------------------------- // EPS bearer entry //-------------------------------------- @@ -190,11 +192,11 @@ int sgw_lite_handle_sgi_endpoint_created(SGICreateEndpointResp *resp_p) SgwCreateSessionResponse *create_session_response_p = NULL; s_plus_p_gw_eps_bearer_context_information_t *new_bearer_context_information_p = NULL; MessageDef *message_p = NULL; - hashtbl_rc_t hash_rc; + hashtable_rc_t hash_rc; SPGW_APP_DEBUG("Rx SGI_CREATE_ENDPOINT_RESPONSE,Context: S11 teid %u, SGW S1U teid %u EPS bearer id %u\n", resp_p->context_teid, resp_p->sgw_S1u_teid, resp_p->eps_bearer_id); - hash_rc = hashtbl_get(sgw_app.s11_bearer_context_information_hashtable, resp_p->context_teid, (void**)&new_bearer_context_information_p); + hash_rc = hashtable_get(sgw_app.s11_bearer_context_information_hashtable, resp_p->context_teid, (void**)&new_bearer_context_information_p); #if defined(ENABLE_STANDALONE_EPC) to_task = TASK_MME_APP; @@ -261,7 +263,7 @@ int sgw_lite_handle_gtpv1uCreateTunnelResp(Gtpv1uCreateTunnelResp *endpoint_crea SGICreateEndpointReq *sgi_create_endpoint_req_p = NULL; MessageDef *message_p = NULL; sgw_eps_bearer_entry_t *eps_bearer_entry_p = NULL; - hashtbl_rc_t hash_rc; + hashtable_rc_t hash_rc; #if defined(ENABLE_STANDALONE_EPC) to_task = TASK_MME_APP; @@ -274,10 +276,10 @@ int sgw_lite_handle_gtpv1uCreateTunnelResp(Gtpv1uCreateTunnelResp *endpoint_crea endpoint_created_p->S1u_teid, endpoint_created_p->eps_bearer_id, endpoint_created_p->status); - hash_rc = hashtbl_get(sgw_app.s11_bearer_context_information_hashtable, endpoint_created_p->context_teid, (void**)&new_bearer_context_information_p); + hash_rc = hashtable_get(sgw_app.s11_bearer_context_information_hashtable, endpoint_created_p->context_teid, (void**)&new_bearer_context_information_p); if (hash_rc == HASH_TABLE_OK) { - hash_rc = hashtbl_get (new_bearer_context_information_p->sgw_eps_bearer_context_information.pdn_connection.sgw_eps_bearers, endpoint_created_p->eps_bearer_id, (void**)&eps_bearer_entry_p); + hash_rc = hashtable_get (new_bearer_context_information_p->sgw_eps_bearer_context_information.pdn_connection.sgw_eps_bearers, endpoint_created_p->eps_bearer_id, (void**)&eps_bearer_entry_p); DevAssert(hash_rc == HASH_TABLE_OK); @@ -321,7 +323,7 @@ int sgw_lite_handle_gtpv1uUpdateTunnelResp(Gtpv1uUpdateTunnelResp *endpoint_upda s_plus_p_gw_eps_bearer_context_information_t *new_bearer_context_information_p = NULL; MessageDef *message_p = NULL; sgw_eps_bearer_entry_t *eps_bearer_entry_p = NULL; - hashtbl_rc_t hash_rc; + hashtable_rc_t hash_rc; task_id_t to_task; #if defined(ENABLE_STANDALONE_EPC) @@ -338,10 +340,10 @@ int sgw_lite_handle_gtpv1uUpdateTunnelResp(Gtpv1uUpdateTunnelResp *endpoint_upda endpoint_updated_p->status); - hash_rc = hashtbl_get(sgw_app.s11_bearer_context_information_hashtable, endpoint_updated_p->context_teid, (void**)&new_bearer_context_information_p); + hash_rc = hashtable_get(sgw_app.s11_bearer_context_information_hashtable, endpoint_updated_p->context_teid, (void**)&new_bearer_context_information_p); if (hash_rc == HASH_TABLE_OK) { - hash_rc = hashtbl_get (new_bearer_context_information_p->sgw_eps_bearer_context_information.pdn_connection.sgw_eps_bearers, endpoint_updated_p->eps_bearer_id, (void**)&eps_bearer_entry_p); + hash_rc = hashtable_get (new_bearer_context_information_p->sgw_eps_bearer_context_information.pdn_connection.sgw_eps_bearers, endpoint_updated_p->eps_bearer_id, (void**)&eps_bearer_entry_p); if ((hash_rc == HASH_TABLE_KEY_NOT_EXISTS) || (hash_rc == HASH_TABLE_BAD_PARAMETER_HASHTABLE)) { SPGW_APP_DEBUG("Sending SGW_MODIFY_BEARER_RESPONSE trxn %p bearer %u CONTEXT_NOT_FOUND (sgw_eps_bearers)\n", @@ -404,7 +406,7 @@ int sgw_lite_handle_sgi_endpoint_updated(SGIUpdateEndpointResp *resp_p) s_plus_p_gw_eps_bearer_context_information_t *new_bearer_context_information_p = NULL; MessageDef *message_p = NULL; sgw_eps_bearer_entry_t *eps_bearer_entry_p = NULL; - hashtbl_rc_t hash_rc; + hashtable_rc_t hash_rc; task_id_t to_task; #if defined(ENABLE_STANDALONE_EPC) @@ -427,11 +429,11 @@ int sgw_lite_handle_sgi_endpoint_updated(SGIUpdateEndpointResp *resp_p) modify_response_p = &message_p->ittiMsg.sgwModifyBearerResponse; memset(modify_response_p, 0, sizeof(SgwModifyBearerResponse)); - hash_rc = hashtbl_get(sgw_app.s11_bearer_context_information_hashtable, resp_p->context_teid, (void**)&new_bearer_context_information_p); + hash_rc = hashtable_get(sgw_app.s11_bearer_context_information_hashtable, resp_p->context_teid, (void**)&new_bearer_context_information_p); if (hash_rc == HASH_TABLE_OK) { - hash_rc = hashtbl_get (new_bearer_context_information_p->sgw_eps_bearer_context_information.pdn_connection.sgw_eps_bearers, + hash_rc = hashtable_get (new_bearer_context_information_p->sgw_eps_bearer_context_information.pdn_connection.sgw_eps_bearers, resp_p->eps_bearer_id, (void**)&eps_bearer_entry_p); @@ -478,7 +480,7 @@ int sgw_lite_handle_modify_bearer_request(SgwModifyBearerRequest *modify_bearer_ s_plus_p_gw_eps_bearer_context_information_t *new_bearer_context_information_p = NULL; MessageDef *message_p = NULL; sgw_eps_bearer_entry_t *eps_bearer_entry_p = NULL; - hashtbl_rc_t hash_rc; + hashtable_rc_t hash_rc; task_id_t to_task; #if defined(ENABLE_STANDALONE_EPC) @@ -494,14 +496,14 @@ int sgw_lite_handle_modify_bearer_request(SgwModifyBearerRequest *modify_bearer_ sgw_lite_display_s11teid2mme_mappings(); sgw_lite_display_s11_bearer_context_information_mapping(); - hash_rc = hashtbl_get(sgw_app.s11_bearer_context_information_hashtable, modify_bearer_p->teid, (void**)&new_bearer_context_information_p); + hash_rc = hashtable_get(sgw_app.s11_bearer_context_information_hashtable, modify_bearer_p->teid, (void**)&new_bearer_context_information_p); if (hash_rc == HASH_TABLE_OK) { new_bearer_context_information_p->sgw_eps_bearer_context_information.pdn_connection.default_bearer = modify_bearer_p->bearer_context_to_modify.eps_bearer_id; new_bearer_context_information_p->sgw_eps_bearer_context_information.trxn = modify_bearer_p->trxn; - hash_rc = hashtbl_is_key_exists (new_bearer_context_information_p->sgw_eps_bearer_context_information.pdn_connection.sgw_eps_bearers, modify_bearer_p->bearer_context_to_modify.eps_bearer_id); + hash_rc = hashtable_is_key_exists (new_bearer_context_information_p->sgw_eps_bearer_context_information.pdn_connection.sgw_eps_bearers, modify_bearer_p->bearer_context_to_modify.eps_bearer_id); if (hash_rc == HASH_TABLE_KEY_NOT_EXISTS) { message_p = itti_alloc_new_message(TASK_SPGW_APP, SGW_MODIFY_BEARER_RESPONSE); @@ -518,7 +520,7 @@ int sgw_lite_handle_modify_bearer_request(SgwModifyBearerRequest *modify_bearer_ return itti_send_msg_to_task(to_task, INSTANCE_DEFAULT, message_p); } else if (hash_rc == HASH_TABLE_OK) { // TO DO - hash_rc = hashtbl_get (new_bearer_context_information_p->sgw_eps_bearer_context_information.pdn_connection.sgw_eps_bearers, modify_bearer_p->bearer_context_to_modify.eps_bearer_id, (void**)&eps_bearer_entry_p); + hash_rc = hashtable_get (new_bearer_context_information_p->sgw_eps_bearer_context_information.pdn_connection.sgw_eps_bearers, modify_bearer_p->bearer_context_to_modify.eps_bearer_id, (void**)&eps_bearer_entry_p); FTEID_T_2_IP_ADDRESS_T( (&modify_bearer_p->bearer_context_to_modify.s1_eNB_fteid) , (&eps_bearer_entry_p->enb_ip_address_for_S1u) ); eps_bearer_entry_p->enb_teid_for_S1u = modify_bearer_p->bearer_context_to_modify.s1_eNB_fteid.teid; @@ -562,7 +564,7 @@ int sgw_lite_handle_modify_bearer_request(SgwModifyBearerRequest *modify_bearer_ int sgw_lite_handle_delete_session_request(SgwDeleteSessionRequest *delete_session_req_p) { task_id_t to_task; - hashtbl_rc_t hash_rc; + hashtable_rc_t hash_rc; SgwDeleteSessionResponse *delete_session_resp_p; MessageDef *message_p = NULL; @@ -587,7 +589,7 @@ int sgw_lite_handle_delete_session_request(SgwDeleteSessionRequest *delete_sessi "should be forwarded to P-GW entity\n"); } - hash_rc = hashtbl_get(sgw_app.s11_bearer_context_information_hashtable, + hash_rc = hashtable_get(sgw_app.s11_bearer_context_information_hashtable, delete_session_req_p->teid, (void**)&ctx_p); diff --git a/openair-cn/SGW-LITE/sgw_lite_task.c b/openair-cn/SGW-LITE/sgw_lite_task.c index 840a5942f3d6b2a21163a3d013b223a24a48b265..6d1353d93ab8fb73d2b640e9b1f03c04c8e4fcb8 100644 --- a/openair-cn/SGW-LITE/sgw_lite_task.c +++ b/openair-cn/SGW-LITE/sgw_lite_task.c @@ -27,6 +27,8 @@ 06410 Biot FRANCE *******************************************************************************/ +#define SGW_LITE +#define SGW_LITE_TASK_C #include <stdio.h> #include <stdlib.h> @@ -40,8 +42,11 @@ #include "sgw_lite_handlers.h" #include "sgw_lite.h" #include "hashtable.h" +#include "spgw_config.h" -sgw_app_t sgw_app; +spgw_config_t spgw_config; +sgw_app_t sgw_app; +pgw_app_t pgw_app; static void *sgw_lite_intertask_interface(void *args_p) { @@ -105,44 +110,46 @@ static void *sgw_lite_intertask_interface(void *args_p) return NULL; } -int sgw_lite_init(const mme_config_t *mme_config_p) +int sgw_lite_init(char* config_file_name_pP) { - SPGW_APP_DEBUG("Initializing SPGW-APP task interface\n"); - if (itti_create_task(TASK_SPGW_APP, - &sgw_lite_intertask_interface, NULL) < 0) { - perror("pthread_create"); - SPGW_APP_DEBUG("Initializing SPGW-APP task interface: ERROR\n"); - return -1; - } + spgw_config_init(config_file_name_pP, &spgw_config); - sgw_app.s11teid2mme_hashtable = hashtbl_create (8192, NULL, NULL); + sgw_app.s11teid2mme_hashtable = hashtable_create (8192, NULL, NULL); if (sgw_app.s11teid2mme_hashtable == NULL) { - perror("hashtbl_create"); + perror("hashtable_create"); SPGW_APP_DEBUG("Initializing SPGW-APP task interface: ERROR\n"); return -1; } - sgw_app.s1uteid2enb_hashtable = hashtbl_create (8192, NULL, NULL); + sgw_app.s1uteid2enb_hashtable = hashtable_create (8192, NULL, NULL); if (sgw_app.s1uteid2enb_hashtable == NULL) { - perror("hashtbl_create"); + perror("hashtable_create"); SPGW_APP_DEBUG("Initializing SPGW-APP task interface: ERROR\n"); return -1; } - sgw_app.s11_bearer_context_information_hashtable = hashtbl_create (8192, NULL, sgw_lite_cm_free_s_plus_p_gw_eps_bearer_context_information); + sgw_app.s11_bearer_context_information_hashtable = hashtable_create (8192, NULL, sgw_lite_cm_free_s_plus_p_gw_eps_bearer_context_information); if (sgw_app.s11_bearer_context_information_hashtable == NULL) { - perror("hashtbl_create"); + perror("hashtable_create"); SPGW_APP_DEBUG("Initializing SPGW-APP task interface: ERROR\n"); return -1; } - sgw_app.sgw_interface_name_for_S1u_S12_S4_up = mme_config_p->ipv4.sgw_interface_name_for_S1u_S12_S4_up; - sgw_app.sgw_ip_address_for_S1u_S12_S4_up = mme_config_p->ipv4.sgw_ip_address_for_S1u_S12_S4_up; - sgw_app.sgw_interface_name_for_S11_S4 = mme_config_p->ipv4.sgw_interface_name_for_S11; - sgw_app.sgw_ip_address_for_S11_S4 = mme_config_p->ipv4.sgw_ip_address_for_S11; - //sgw_app.sgw_ip_address_for_S5_S8_cp = mme_config_p->ipv4.sgw_ip_address_for_S5_S8_cp; - sgw_app.sgw_ip_address_for_S5_S8_up = mme_config_p->ipv4.sgw_ip_address_for_S5_S8_up; + sgw_app.sgw_interface_name_for_S1u_S12_S4_up = spgw_config.sgw_config.ipv4.sgw_interface_name_for_S1u_S12_S4_up; + sgw_app.sgw_ip_address_for_S1u_S12_S4_up = spgw_config.sgw_config.ipv4.sgw_ipv4_address_for_S1u_S12_S4_up; + sgw_app.sgw_interface_name_for_S11_S4 = spgw_config.sgw_config.ipv4.sgw_interface_name_for_S11; + sgw_app.sgw_ip_address_for_S11_S4 = spgw_config.sgw_config.ipv4.sgw_ipv4_address_for_S11; + //sgw_app.sgw_ip_address_for_S5_S8_cp = spgw_config.sgw_config.ipv4.sgw_ip_address_for_S5_S8_cp; + sgw_app.sgw_ip_address_for_S5_S8_up = spgw_config.sgw_config.ipv4.sgw_ipv4_address_for_S5_S8_up; + + SPGW_APP_DEBUG("Initializing SPGW-APP task interface\n"); + if (itti_create_task(TASK_SPGW_APP, + &sgw_lite_intertask_interface, NULL) < 0) { + perror("pthread_create"); + SPGW_APP_DEBUG("Initializing SPGW-APP task interface: ERROR\n"); + return -1; + } SPGW_APP_DEBUG("Initializing SPGW-APP task interface: DONE\n"); return 0; diff --git a/openair-cn/SGW-LITE/spgw_config.c b/openair-cn/SGW-LITE/spgw_config.c new file mode 100755 index 0000000000000000000000000000000000000000..67d4f5068768900cb5ae6243df4f72c70cdd6ebf --- /dev/null +++ b/openair-cn/SGW-LITE/spgw_config.c @@ -0,0 +1,385 @@ +/******************************************************************************* + + Eurecom OpenAirInterface + Copyright(c) 1999 - 2014 Eurecom + + This program is free software; you can redistribute it and/or modify it + under the terms and conditions of the GNU General Public License, + version 2, as published by the Free Software Foundation. + + This program is distributed in the hope it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along with + this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + + The full GNU General Public License is included in this distribution in + the file called "COPYING". + + Contact Information + Openair Admin: openair_admin@eurecom.fr + Openair Tech : openair_tech@eurecom.fr + Forums : http://forums.eurecom.fr/openairinterface + Address : EURECOM, Campus SophiaTech, 450 Route des Chappes + 06410 Biot FRANCE + + *******************************************************************************/ +#define SGW_LITE +#define SPGW_CONFIG_C + +#include <string.h> +#include <libconfig.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <sys/types.h> +#include <stdlib.h> +#include <unistd.h> +#include <netdb.h> + +#include "log.h" +#include "assertions.h" +#include "spgw_config.h" +#include "sgw_lite_defs.h" +#include "intertask_interface.h" + +#define NIPADDR(addr) \ + (uint8_t)(addr & 0x000000FF), \ + (uint8_t)((addr & 0x0000FF00) >> 8), \ + (uint8_t)((addr & 0x00FF0000) >> 16), \ + (uint8_t)((addr & 0xFF000000) >> 24) + +#define HIPADDR(addr) \ + (uint8_t)((addr & 0xFF000000) >> 24),\ + (uint8_t)((addr & 0x00FF0000) >> 16),\ + (uint8_t)((addr & 0x0000FF00) >> 8), \ + (uint8_t)(addr & 0x000000FF) + +#define NIP6ADDR(addr) \ + ntohs((addr)->s6_addr16[0]), \ + ntohs((addr)->s6_addr16[1]), \ + ntohs((addr)->s6_addr16[2]), \ + ntohs((addr)->s6_addr16[3]), \ + ntohs((addr)->s6_addr16[4]), \ + ntohs((addr)->s6_addr16[5]), \ + ntohs((addr)->s6_addr16[6]), \ + ntohs((addr)->s6_addr16[7]) + +#define IN6_ARE_ADDR_MASKED_EQUAL(a,b,m) \ + (((((__const uint32_t *) (a))[0] & (((__const uint32_t *) (m))[0])) == (((__const uint32_t *) (b))[0] & (((__const uint32_t *) (m))[0]))) \ + && ((((__const uint32_t *) (a))[1] & (((__const uint32_t *) (m))[1])) == (((__const uint32_t *) (b))[1] & (((__const uint32_t *) (m))[1]))) \ + && ((((__const uint32_t *) (a))[2] & (((__const uint32_t *) (m))[2])) == (((__const uint32_t *) (b))[2] & (((__const uint32_t *) (m))[2]))) \ + && ((((__const uint32_t *) (a))[3] & (((__const uint32_t *) (m))[3])) == (((__const uint32_t *) (b))[3] & (((__const uint32_t *) (m))[3])))) + +void trim(char* srcP, int sizeP) +{ + if(srcP == NULL) + return; + + const char* current = srcP; + unsigned int i = 0; + while((*current) != '\0' && (i < (sizeP-1))) + { + if((*current != ' ') && (*current != '\t')) { + srcP[i++] = *current; + } + ++current; + } + srcP[i] = '\0'; +} + +void sgw_ipv6_mask_in6_addr( struct in6_addr *addr6_pP, int maskP) { + int addr8_idx; + + addr8_idx = maskP / 8; + maskP = maskP % 8; + + if (maskP > 0) { + addr6_pP->s6_addr[addr8_idx] = addr6_pP->s6_addr[addr8_idx] & (0xFF << (8 - maskP)); + addr8_idx += 1; + } + while (addr8_idx < 16) { + addr6_pP->s6_addr[addr8_idx++] = 0; + } +} +/*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; + config_setting_t *setting_sgw = NULL; + char *sgw_interface_name_for_S1u_S12_S4_up = NULL; + char *sgw_ipv4_address_for_S1u_S12_S4_up = NULL; + char *sgw_interface_name_for_S5_S8_up = NULL; + char *sgw_ipv4_address_for_S5_S8_up = NULL; + char *sgw_interface_name_for_S11 = NULL; + char *sgw_ipv4_address_for_S11 = NULL; + + config_setting_t *setting_pgw = NULL; + config_setting_t *subsetting = NULL; + config_setting_t *sub2setting = NULL; + char *pgw_interface_name_for_S5_S8 = NULL; + char *pgw_ipv4_address_for_S5_S8 = NULL; + char *pgw_interface_name_for_SGI = NULL; + char *pgw_ipv4_address_for_SGI = NULL; + + char *delimiters=NULL; + char *saveptr1= NULL; + char *astring = NULL; + char *atoken = NULL; + char *atoken2 = NULL; + char *address = NULL; + char *cidr = NULL; + char *mask = NULL; + int num = 0; + int i = 0; + int jh, jn; + unsigned char buf_in6_addr[sizeof(struct in6_addr)]; + struct in6_addr addr6_start; + struct in6_addr addr6_mask; + int prefix_mask; + uint64_t counter64; + unsigned char buf_in_addr[sizeof(struct in_addr)]; + struct in_addr addr_start; + struct in_addr addr_end; + + + memset((char*)config_pP, 0 , sizeof(spgw_config_t)); + + config_init(&cfg); + + if(lib_config_file_name_pP != NULL) + { + /* Read the file. If there is an error, report it and exit. */ + if(! config_read_file(&cfg, lib_config_file_name_pP)) + { + SPGW_APP_ERROR("%s:%d - %s\n", lib_config_file_name_pP, config_error_line(&cfg), config_error_text(&cfg)); + config_destroy(&cfg); + AssertFatal (1 == 0, "Failed to parse eNB configuration file %s!\n", lib_config_file_name_pP); + } + } + else + { + SPGW_APP_ERROR("No SP-GW configuration file provided!\n"); + config_destroy(&cfg); + AssertFatal (0, "No SP-GW configuration file provided!\n"); + } + + setting_sgw = config_lookup(&cfg, SGW_CONFIG_STRING_SGW_CONFIG); + if(setting_sgw != NULL) { + subsetting = config_setting_get_member (setting_sgw, SGW_CONFIG_STRING_NETWORK_INTERFACES_CONFIG); + if(subsetting != NULL) { + if( ( + config_setting_lookup_string( subsetting, SGW_CONFIG_STRING_SGW_INTERFACE_NAME_FOR_S1U_S12_S4_UP, (const char **)&sgw_interface_name_for_S1u_S12_S4_up) + && config_setting_lookup_string( subsetting, SGW_CONFIG_STRING_SGW_IPV4_ADDRESS_FOR_S1U_S12_S4_UP, (const char **)&sgw_ipv4_address_for_S1u_S12_S4_up) + && config_setting_lookup_string( subsetting, SGW_CONFIG_STRING_SGW_INTERFACE_NAME_FOR_S5_S8_UP, (const char **)&sgw_interface_name_for_S5_S8_up) + && config_setting_lookup_string( subsetting, SGW_CONFIG_STRING_SGW_IPV4_ADDRESS_FOR_S5_S8_UP, (const char **)&sgw_ipv4_address_for_S5_S8_up) + && config_setting_lookup_string( subsetting, SGW_CONFIG_STRING_SGW_INTERFACE_NAME_FOR_S11, (const char **)&sgw_interface_name_for_S11) + && config_setting_lookup_string( subsetting, SGW_CONFIG_STRING_SGW_IPV4_ADDRESS_FOR_S11, (const char **)&sgw_ipv4_address_for_S11) + ) + ) { + config_pP->sgw_config.ipv4.sgw_interface_name_for_S1u_S12_S4_up = strdup(sgw_interface_name_for_S1u_S12_S4_up); + cidr = strdup(sgw_ipv4_address_for_S1u_S12_S4_up); + address = strtok(cidr, "/"); + mask = strtok(NULL, "/"); + IPV4_STR_ADDR_TO_INT_NWBO ( address, config_pP->sgw_config.ipv4.sgw_ipv4_address_for_S1u_S12_S4_up, "BAD IP ADDRESS FORMAT FOR S1u_S12_S4 !\n" ) + config_pP->sgw_config.ipv4.sgw_ip_netmask_for_S1u_S12_S4_up = atoi(mask); + free(cidr); + + config_pP->sgw_config.ipv4.sgw_interface_name_for_S5_S8_up = strdup(sgw_interface_name_for_S5_S8_up); + cidr = strdup(sgw_ipv4_address_for_S5_S8_up); + address = strtok(cidr, "/"); + mask = strtok(NULL, "/"); + IPV4_STR_ADDR_TO_INT_NWBO ( address, config_pP->sgw_config.ipv4.sgw_ipv4_address_for_S5_S8_up, "BAD IP ADDRESS FORMAT FOR S5_S8 !\n" ) + config_pP->sgw_config.ipv4.sgw_ip_netmask_for_S5_S8_up = atoi(mask); + free(cidr); + + config_pP->sgw_config.ipv4.sgw_interface_name_for_S11 = strdup(sgw_interface_name_for_S11); + cidr = strdup(sgw_ipv4_address_for_S11); + address = strtok(cidr, "/"); + mask = strtok(NULL, "/"); + IPV4_STR_ADDR_TO_INT_NWBO ( address, config_pP->sgw_config.ipv4.sgw_ipv4_address_for_S11, "BAD IP ADDRESS FORMAT FOR S11 !\n" ) + config_pP->sgw_config.ipv4.sgw_ip_netmask_for_S11 = atoi(mask); + free(cidr); + } + } + } + + setting_pgw = config_lookup(&cfg, PGW_CONFIG_STRING_PGW_CONFIG); + if(setting_pgw != NULL) + { + subsetting = config_setting_get_member (setting_pgw, SGW_CONFIG_STRING_NETWORK_INTERFACES_CONFIG); + if(subsetting != NULL) { + if( ( + config_setting_lookup_string(subsetting, + PGW_CONFIG_STRING_PGW_INTERFACE_NAME_FOR_S5_S8, + (const char **)&pgw_interface_name_for_S5_S8) + && config_setting_lookup_string(subsetting, + PGW_CONFIG_STRING_PGW_IPV4_ADDRESS_FOR_S5_S8, + (const char **)&pgw_ipv4_address_for_S5_S8) + && config_setting_lookup_string(subsetting, + PGW_CONFIG_STRING_PGW_INTERFACE_NAME_FOR_SGI, + (const char **)&pgw_interface_name_for_SGI) + && config_setting_lookup_string(subsetting, + PGW_CONFIG_STRING_PGW_IPV4_ADDR_FOR_SGI, + (const char **)&pgw_ipv4_address_for_SGI) + ) + ) { + config_pP->pgw_config.ipv4.pgw_interface_name_for_S5_S8 = strdup(pgw_interface_name_for_S5_S8); + cidr = strdup(pgw_ipv4_address_for_S5_S8); + address = strtok(cidr, "/"); + mask = strtok(NULL, "/"); + IPV4_STR_ADDR_TO_INT_NWBO ( address, config_pP->pgw_config.ipv4.pgw_ipv4_address_for_S5_S8, "BAD IP ADDRESS FORMAT FOR S5_S8 !\n" ) + config_pP->pgw_config.ipv4.pgw_ip_netmask_for_S5_S8 = atoi(mask); + free(cidr); + + config_pP->pgw_config.ipv4.pgw_interface_name_for_SGI = strdup(pgw_interface_name_for_SGI); + cidr = strdup(pgw_ipv4_address_for_SGI); + address = strtok(cidr, "/"); + mask = strtok(NULL, "/"); + IPV4_STR_ADDR_TO_INT_NWBO ( address, config_pP->pgw_config.ipv4.pgw_ipv4_address_for_SGI, "BAD IP ADDRESS FORMAT FOR SGI !\n" ) + config_pP->pgw_config.ipv4.pgw_ip_netmask_for_SGI = atoi(mask); + free(cidr); + } + } + subsetting = config_setting_get_member (setting_pgw, PGW_CONFIG_STRING_IP_ADDRESS_POOL); + if(subsetting != NULL) { + sub2setting = config_setting_get_member (subsetting, PGW_CONFIG_STRING_IPV4_ADDRESS_LIST); + if(sub2setting != NULL) { + num = config_setting_length(sub2setting); + for (i = 0; i < num; i++) { + astring = config_setting_get_string_elem(sub2setting,i); + if (astring != NULL) { + trim(astring, strlen(astring)+1); + if (inet_pton(AF_INET, astring, buf_in_addr) < 1) { + // failure, test if there is a range specified in the string + atoken = strtok(astring, PGW_CONFIG_STRING_IP_ADDRESS_RANGE_DELIMITERS); + if (inet_pton(AF_INET, astring, buf_in_addr) == 1) { + memcpy (&addr_start, buf_in_addr, sizeof(struct in_addr)); + // valid address + atoken2 = strtok(NULL, PGW_CONFIG_STRING_IP_ADDRESS_RANGE_DELIMITERS); + if (inet_pton(AF_INET, atoken2, buf_in_addr) == 1) { + memcpy (&addr_end, buf_in_addr, sizeof(struct in_addr)); + // valid address + for (jh = ntohl(addr_start.s_addr); jh <= ntohl(addr_end.s_addr); jh++) { + DevAssert(PGW_MAX_ALLOCATED_PDN_ADDRESSES > config_pP->pgw_config.pool_pdn_addresses.num_ipv4_addresses); + jn = htonl(jh); + if (IN_CLASSA(addr_start.s_addr)) { + if ((jh & 0xFF) && (jh & 0xFF) != 0xFF) { + config_pP->pgw_config.pool_pdn_addresses.ipv4_addresses[config_pP->pgw_config.pool_pdn_addresses.num_ipv4_addresses++].s_addr = jn; + } + } else if (IN_CLASSB(addr_start.s_addr)) { + if ((jh & 0xFF) && (jh & 0xFF) != 0xFF) { + config_pP->pgw_config.pool_pdn_addresses.ipv4_addresses[config_pP->pgw_config.pool_pdn_addresses.num_ipv4_addresses++].s_addr = jn; + } + } else if (IN_CLASSC(addr_start.s_addr)) { + if ((jh & 0xFF) && (jh & 0xFF) != 0xFF) { + config_pP->pgw_config.pool_pdn_addresses.ipv4_addresses[config_pP->pgw_config.pool_pdn_addresses.num_ipv4_addresses++].s_addr = jn; + } + } else { + printf("ERROR ON ADDRESS CLASS %d.%d.%d.%d\n", NIPADDR(jn)); + } + } + } + } + } else { + DevAssert(PGW_MAX_ALLOCATED_PDN_ADDRESSES > config_pP->pgw_config.pool_pdn_addresses.num_ipv4_addresses); + memcpy (&addr_start, buf_in_addr, sizeof(struct in_addr)); + config_pP->pgw_config.pool_pdn_addresses.ipv4_addresses[config_pP->pgw_config.pool_pdn_addresses.num_ipv4_addresses++].s_addr = addr_start.s_addr; + } + } + } + } + sub2setting = config_setting_get_member (subsetting, PGW_CONFIG_STRING_IPV6_ADDRESS_LIST); + if(sub2setting != NULL) { + num = config_setting_length(sub2setting); + for (i = 0; i < num; i++) { + astring = config_setting_get_string_elem(sub2setting,i); + if (astring != NULL) { + trim(astring, strlen(astring)+1); + if (inet_pton(AF_INET6, astring, buf_in6_addr) < 1) { + // failure, test if there is a range specified in the string + atoken = strtok(astring, PGW_CONFIG_STRING_IPV6_PREFIX_DELIMITER); + if (inet_pton(AF_INET6, astring, buf_in6_addr) == 1) { + atoken2 = strtok(NULL, PGW_CONFIG_STRING_IPV6_PREFIX_DELIMITER); + prefix_mask = atoi(atoken2); + // arbitrary values + DevAssert((prefix_mask < 128) && (prefix_mask >= 64)); + + memcpy (&addr6_start, buf_in6_addr, sizeof(struct in6_addr)); + memcpy (&addr6_mask, buf_in6_addr, sizeof(struct in6_addr)); + sgw_ipv6_mask_in6_addr(&addr6_mask, prefix_mask); + + if (memcmp(&addr6_start, &addr6_mask, sizeof(struct in6_addr)) != 0) { + AssertFatal(0, "BAD IPV6 ADDR CONFIG/MASK PAIRING %s/%d\n", astring, prefix_mask); + } + + counter64 = 0xFFFFFFFFFFFFFFFF >> prefix_mask; // address Prefix_mask/0..0 not valid + do { + addr6_start.s6_addr32[3] = addr6_start.s6_addr32[3] + htonl(1); + if (addr6_start.s6_addr32[3] == 0) { + addr6_start.s6_addr32[2] = addr6_start.s6_addr32[2] + htonl(1); + if (addr6_start.s6_addr32[2] == 0) { + // should not happen since mask is no less than 64 + addr6_start.s6_addr32[1] = addr6_start.s6_addr32[1] + htonl(1); + if (addr6_start.s6_addr32[1] == 0) { + addr6_start.s6_addr32[0] = addr6_start.s6_addr32[0] + htonl(1); + } + } + } + memcpy (&config_pP->pgw_config.pool_pdn_addresses.ipv6_addresses[config_pP->pgw_config.pool_pdn_addresses.num_ipv6_addresses++], + &addr6_start, + sizeof(struct in6_addr)); + counter64 = counter64 - 1; + } while (counter64 > 0); + } + } else { + DevAssert(PGW_MAX_ALLOCATED_PDN_ADDRESSES > config_pP->pgw_config.pool_pdn_addresses.num_ipv6_addresses); + memcpy (&config_pP->pgw_config.pool_pdn_addresses.ipv6_addresses[config_pP->pgw_config.pool_pdn_addresses.num_ipv6_addresses++], + buf_in6_addr, + sizeof(struct in6_addr)); + } + } + } + } } + } + return 0; +} diff --git a/openair-cn/SGW-LITE/spgw_config.h b/openair-cn/SGW-LITE/spgw_config.h new file mode 100755 index 0000000000000000000000000000000000000000..aec8e5aa0d2b2dad2ee18fe4fe383238a480b3d4 --- /dev/null +++ b/openair-cn/SGW-LITE/spgw_config.h @@ -0,0 +1,120 @@ +/******************************************************************************* + + Eurecom OpenAirInterface + Copyright(c) 1999 - 2014 Eurecom + + This program is free software; you can redistribute it and/or modify it + under the terms and conditions of the GNU General Public License, + version 2, as published by the Free Software Foundation. + + This program is distributed in the hope it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along with + this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + + The full GNU General Public License is included in this distribution in + the file called "COPYING". + + Contact Information + Openair Admin: openair_admin@eurecom.fr + Openair Tech : openair_tech@eurecom.fr + Forums : http://forums.eurecom.fr/openairinterface + Address : EURECOM, Campus SophiaTech, 450 Route des Chappes + 06410 Biot FRANCE + +*******************************************************************************/ + +#ifndef SPGW_CONFIG_H_ +#define SPGW_CONFIG_H_ +#include <sys/socket.h> // inet_aton +#include <netinet/in.h> // inet_aton +#include <arpa/inet.h> // inet_aton + + + +#define SGW_CONFIG_STRING_SGW_CONFIG "S-GW" +#define SGW_CONFIG_STRING_NETWORK_INTERFACES_CONFIG "NETWORK_INTERFACES" +#define SGW_CONFIG_STRING_SGW_INTERFACE_NAME_FOR_S1U_S12_S4_UP "SGW_INTERFACE_NAME_FOR_S1U_S12_S4_UP" +#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_INTERFACE_NAME_FOR_S5_S8_UP "SGW_INTERFACE_NAME_FOR_S5_S8_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 PGW_CONFIG_STRING_PGW_CONFIG "P-GW" +#define PGW_CONFIG_STRING_NETWORK_INTERFACES_CONFIG "NETWORK_INTERFACES" +#define PGW_CONFIG_STRING_PGW_INTERFACE_NAME_FOR_S5_S8 "PGW_INTERFACE_NAME_FOR_S5_S8" +#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_ADDR_FOR_SGI" + +#define PGW_CONFIG_STRING_IP_ADDRESS_POOL "IP_ADDRESS_POOL" +#define PGW_CONFIG_STRING_IPV4_ADDRESS_LIST "IPV4_LIST" +#define PGW_CONFIG_STRING_IPV6_ADDRESS_LIST "IPV6_LIST" +#define PGW_CONFIG_STRING_IP_ADDRESS_RANGE_DELIMITERS " -<>" +#define PGW_CONFIG_STRING_IPV6_PREFIX_DELIMITER " /" + + +#define IPV4_STR_ADDR_TO_INT_NWBO(AdDr_StR,NwBo,MeSsAgE ) do {\ + struct in_addr inp;\ + if ( inet_aton(AdDr_StR, &inp ) < 0 ) {\ + AssertFatal (0, MeSsAgE);\ + } else {\ + NwBo = inp.s_addr;\ + }\ + } while (0); + +typedef struct sgw_config_s { + struct { + char *sgw_interface_name_for_S1u_S12_S4_up; + uint32_t sgw_ipv4_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_ipv4_address_for_S5_S8_up; + int sgw_ip_netmask_for_S5_S8_up; + + char *sgw_interface_name_for_S11; + uint32_t sgw_ipv4_address_for_S11; + int sgw_ip_netmask_for_S11; + } ipv4; +} sgw_config_t; + +// may be more +#define PGW_MAX_ALLOCATED_PDN_ADDRESSES 1024 + +typedef struct pgw_config_s { + struct { + char *pgw_interface_name_for_S5_S8; + uint32_t pgw_ipv4_address_for_S5_S8; + int pgw_ip_netmask_for_S5_S8; + + char *pgw_interface_name_for_SGI; + uint32_t pgw_ipv4_address_for_SGI; + int pgw_ip_netmask_for_SGI; + } ipv4; + + struct { + int num_ipv4_addresses; + struct in_addr ipv4_addresses[PGW_MAX_ALLOCATED_PDN_ADDRESSES]; + int num_ipv6_addresses; + struct in6_addr ipv6_addresses[PGW_MAX_ALLOCATED_PDN_ADDRESSES]; + } pool_pdn_addresses; +} pgw_config_t; + +typedef struct spgw_config_s { + sgw_config_t sgw_config; + pgw_config_t pgw_config; +}spgw_config_t; + +#ifndef SGW_LITE +extern spgw_config_t spgw_config; +#endif + +int spgw_config_init(char* lib_config_file_name_pP, spgw_config_t* config_pP); + +#endif /* ENB_CONFIG_H_ */