From 160490483ab2b323c71e5fd7079bfbb832d9f014 Mon Sep 17 00:00:00 2001 From: Sukchan Lee Date: Mon, 7 Sep 2020 22:02:45 -0400 Subject: [PATCH] Fix the many UEs issues [#551] --- README.md | 2 +- docs/_posts/2020-09-07-release-v2.0.2.md | 2 +- lib/pfcp/context.c | 124 ++++++++++++++++++----- lib/pfcp/context.h | 18 +++- src/amf/context.h | 3 +- src/mme/mme-context.h | 3 +- src/mme/mme-s11-handler.c | 2 +- src/mme/mme-sm.c | 4 +- src/mme/nas-path.c | 5 +- src/mme/s1ap-handler.c | 108 +++++++++++++------- src/mme/s1ap-path.c | 22 ++++ src/mme/s1ap-path.h | 2 + src/smf/context.c | 44 +++++++- src/smf/context.h | 7 +- 14 files changed, 265 insertions(+), 81 deletions(-) diff --git a/README.md b/README.md index a94d58454..debdf7727 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ If you find Open5GS useful for work, please consider supporting this Open Source project by [Becoming a sponsor](https://github.com/sponsors/acetcom). To manage the funding transactions transparently, you can donate through [OpenCollective](https://opencollective.com/open5gs). -#### Thank you to our sponsors! +#### Thanks to sponsors! diff --git a/docs/_posts/2020-09-07-release-v2.0.2.md b/docs/_posts/2020-09-07-release-v2.0.2.md index fbb79d29b..5e5eeb017 100644 --- a/docs/_posts/2020-09-07-release-v2.0.2.md +++ b/docs/_posts/2020-09-07-release-v2.0.2.md @@ -1,5 +1,5 @@ --- -title: "v2.0.2 - Hotfix for many UEs +title: "v2.0.2 - Hotfix for many UEs" date: 2020-09-08 12:35:00 -0400 categories: - Release diff --git a/lib/pfcp/context.c b/lib/pfcp/context.c index b7978e495..e80c6127b 100644 --- a/lib/pfcp/context.c +++ b/lib/pfcp/context.c @@ -26,6 +26,11 @@ static OGS_POOL(ogs_pfcp_node_pool, ogs_pfcp_node_t); static OGS_POOL(ogs_pfcp_gtpu_resource_pool, ogs_pfcp_gtpu_resource_t); static OGS_POOL(ogs_pfcp_sess_pool, ogs_pfcp_sess_t); +static OGS_POOL(ogs_pfcp_pdr_pool, ogs_pfcp_pdr_t); +static OGS_POOL(ogs_pfcp_far_pool, ogs_pfcp_far_t); +static OGS_POOL(ogs_pfcp_urr_pool, ogs_pfcp_urr_t); +static OGS_POOL(ogs_pfcp_qer_pool, ogs_pfcp_qer_t); +static OGS_POOL(ogs_pfcp_bar_pool, ogs_pfcp_bar_t); static OGS_POOL(ogs_pfcp_dev_pool, ogs_pfcp_dev_t); static OGS_POOL(ogs_pfcp_subnet_pool, ogs_pfcp_subnet_t); @@ -67,6 +72,17 @@ void ogs_pfcp_context_init(int num_of_gtpu_resource) ogs_pool_init(&ogs_pfcp_sess_pool, ogs_app()->pool.sess); + ogs_pool_init(&ogs_pfcp_pdr_pool, + ogs_app()->pool.sess * OGS_MAX_NUM_OF_PDR); + ogs_pool_init(&ogs_pfcp_far_pool, + ogs_app()->pool.sess * OGS_MAX_NUM_OF_FAR); + ogs_pool_init(&ogs_pfcp_urr_pool, + ogs_app()->pool.sess * OGS_MAX_NUM_OF_URR); + ogs_pool_init(&ogs_pfcp_qer_pool, + ogs_app()->pool.sess * OGS_MAX_NUM_OF_QER); + ogs_pool_init(&ogs_pfcp_bar_pool, + ogs_app()->pool.sess * OGS_MAX_NUM_OF_BAR); + ogs_pool_init(&ogs_pfcp_rule_pool, ogs_app()->pool.sess * OGS_MAX_NUM_OF_RULE); @@ -95,6 +111,11 @@ void ogs_pfcp_context_final(void) ogs_pool_final(&ogs_pfcp_rule_pool); ogs_pool_final(&ogs_pfcp_sess_pool); + ogs_pool_final(&ogs_pfcp_pdr_pool); + ogs_pool_final(&ogs_pfcp_far_pool); + ogs_pool_final(&ogs_pfcp_urr_pool); + ogs_pool_final(&ogs_pfcp_qer_pool); + ogs_pool_final(&ogs_pfcp_bar_pool); ogs_pfcp_node_remove_all(&self.peer_list); ogs_pfcp_gtpu_resource_remove_all(&self.gtpu_resource_list); @@ -791,11 +812,14 @@ ogs_pfcp_pdr_t *ogs_pfcp_pdr_add(ogs_pfcp_sess_t *sess) ogs_assert(sess); - ogs_pool_alloc(&sess->pdr_pool, &pdr); + ogs_pool_alloc(&ogs_pfcp_pdr_pool, &pdr); ogs_assert(pdr); memset(pdr, 0, sizeof *pdr); - pdr->index = ogs_pool_index(&sess->pdr_pool, pdr); + ogs_pool_alloc(&sess->pdr_id_pool, &pdr->id_node); + ogs_assert(pdr->id_node); + + pdr->index = *(pdr->id_node); ogs_assert(pdr->index > 0 && pdr->index <= OGS_MAX_NUM_OF_PDR); pdr->sess = sess; @@ -912,7 +936,10 @@ void ogs_pfcp_pdr_remove(ogs_pfcp_pdr_t *pdr) if (pdr->dnn) ogs_free(pdr->dnn); - ogs_pool_free(&pdr->sess->pdr_pool, pdr); + if (pdr->id_node) + ogs_pool_free(&pdr->sess->pdr_id_pool, pdr->id_node); + + ogs_pool_free(&ogs_pfcp_pdr_pool, pdr); } void ogs_pfcp_pdr_remove_all(ogs_pfcp_sess_t *sess) @@ -930,11 +957,14 @@ ogs_pfcp_far_t *ogs_pfcp_far_add(ogs_pfcp_sess_t *sess) ogs_assert(sess); - ogs_pool_alloc(&sess->far_pool, &far); + ogs_pool_alloc(&ogs_pfcp_far_pool, &far); ogs_assert(far); memset(far, 0, sizeof *far); - far->index = ogs_pool_index(&sess->far_pool, far); + ogs_pool_alloc(&sess->far_id_pool, &far->id_node); + ogs_assert(far->id_node); + + far->index = *(far->id_node); ogs_assert(far->index > 0 && far->index <= OGS_MAX_NUM_OF_FAR); far->apply_action = OGS_PFCP_APPLY_ACTION_FORW; @@ -988,7 +1018,11 @@ void ogs_pfcp_far_remove(ogs_pfcp_far_t *far) ogs_pkbuf_free(far->buffered_packet[i]); ogs_list_remove(&sess->far_list, far); - ogs_pool_free(&sess->far_pool, far); + + if (far->id_node) + ogs_pool_free(&far->sess->far_id_pool, far->id_node); + + ogs_pool_free(&ogs_pfcp_far_pool, far); } void ogs_pfcp_far_remove_all(ogs_pfcp_sess_t *sess) @@ -1007,11 +1041,14 @@ ogs_pfcp_urr_t *ogs_pfcp_urr_add(ogs_pfcp_sess_t *sess) ogs_assert(sess); - ogs_pool_alloc(&sess->urr_pool, &urr); + ogs_pool_alloc(&ogs_pfcp_urr_pool, &urr); ogs_assert(urr); memset(urr, 0, sizeof *urr); - urr->index = ogs_pool_index(&sess->urr_pool, urr); + ogs_pool_alloc(&sess->urr_id_pool, &urr->id_node); + ogs_assert(urr->id_node); + + urr->index = *(urr->id_node); ogs_assert(urr->index > 0 && urr->index <= OGS_MAX_NUM_OF_URR); urr->sess = sess; @@ -1059,7 +1096,11 @@ void ogs_pfcp_urr_remove(ogs_pfcp_urr_t *urr) ogs_assert(sess); ogs_list_remove(&sess->urr_list, urr); - ogs_pool_free(&sess->urr_pool, urr); + + if (urr->id_node) + ogs_pool_free(&urr->sess->urr_id_pool, urr->id_node); + + ogs_pool_free(&ogs_pfcp_urr_pool, urr); } void ogs_pfcp_urr_remove_all(ogs_pfcp_sess_t *sess) @@ -1078,11 +1119,14 @@ ogs_pfcp_qer_t *ogs_pfcp_qer_add(ogs_pfcp_sess_t *sess) ogs_assert(sess); - ogs_pool_alloc(&sess->qer_pool, &qer); + ogs_pool_alloc(&ogs_pfcp_qer_pool, &qer); ogs_assert(qer); memset(qer, 0, sizeof *qer); - qer->index = ogs_pool_index(&sess->qer_pool, qer); + ogs_pool_alloc(&sess->qer_id_pool, &qer->id_node); + ogs_assert(qer->id_node); + + qer->index = *(qer->id_node); ogs_assert(qer->index > 0 && qer->index <= OGS_MAX_NUM_OF_QER); qer->sess = sess; @@ -1130,7 +1174,11 @@ void ogs_pfcp_qer_remove(ogs_pfcp_qer_t *qer) ogs_assert(sess); ogs_list_remove(&sess->qer_list, qer); - ogs_pool_free(&sess->qer_pool, qer); + + if (qer->id_node) + ogs_pool_free(&qer->sess->qer_id_pool, qer->id_node); + + ogs_pool_free(&ogs_pfcp_qer_pool, qer); } void ogs_pfcp_qer_remove_all(ogs_pfcp_sess_t *sess) @@ -1150,10 +1198,13 @@ ogs_pfcp_bar_t *ogs_pfcp_bar_new(ogs_pfcp_sess_t *sess) ogs_assert(sess); ogs_assert(sess->bar == NULL); /* Only One BAR is supported */ - ogs_pool_alloc(&sess->bar_pool, &bar); + ogs_pool_alloc(&ogs_pfcp_bar_pool, &bar); ogs_assert(bar); memset(bar, 0, sizeof *bar); + ogs_pool_alloc(&sess->bar_id_pool, &bar->id_node); + ogs_assert(bar->id_node); + bar->sess = sess; sess->bar = bar; @@ -1171,7 +1222,10 @@ void ogs_pfcp_bar_delete(ogs_pfcp_bar_t *bar) bar->sess = NULL; sess->bar = NULL; - ogs_pool_free(&sess->bar_pool, bar); + if (bar->id_node) + ogs_pool_free(&bar->sess->bar_id_pool, bar->id_node); + + ogs_pool_free(&ogs_pfcp_bar_pool, bar); } ogs_pfcp_rule_t *ogs_pfcp_rule_add(ogs_pfcp_pdr_t *pdr) @@ -1505,17 +1559,39 @@ ogs_pfcp_subnet_t *ogs_pfcp_find_subnet(int family, const char *apn) void ogs_pfcp_pool_init(ogs_pfcp_sess_t *sess) { - ogs_index_init(&sess->pdr_pool, OGS_MAX_NUM_OF_PDR); - ogs_index_init(&sess->far_pool, OGS_MAX_NUM_OF_FAR); - ogs_index_init(&sess->urr_pool, OGS_MAX_NUM_OF_URR); - ogs_index_init(&sess->qer_pool, OGS_MAX_NUM_OF_QER); - ogs_index_init(&sess->bar_pool, OGS_MAX_NUM_OF_BAR); + int i; + + ogs_assert(sess); + + ogs_index_init(&sess->pdr_id_pool, OGS_MAX_NUM_OF_PDR); + ogs_index_init(&sess->far_id_pool, OGS_MAX_NUM_OF_FAR); + ogs_index_init(&sess->urr_id_pool, OGS_MAX_NUM_OF_URR); + ogs_index_init(&sess->qer_id_pool, OGS_MAX_NUM_OF_QER); + ogs_index_init(&sess->bar_id_pool, OGS_MAX_NUM_OF_BAR); + + for (i = 1; i <= OGS_MAX_NUM_OF_PDR; i++) { + sess->pdr_id_pool.array[i-1] = i; + } + for (i = 1; i <= OGS_MAX_NUM_OF_FAR; i++) { + sess->far_id_pool.array[i-1] = i; + } + for (i = 1; i <= OGS_MAX_NUM_OF_URR; i++) { + sess->urr_id_pool.array[i-1] = i; + } + for (i = 1; i <= OGS_MAX_NUM_OF_QER; i++) { + sess->qer_id_pool.array[i-1] = i; + } + for (i = 1; i <= OGS_MAX_NUM_OF_BAR; i++) { + sess->bar_id_pool.array[i-1] = i; + } } void ogs_pfcp_pool_final(ogs_pfcp_sess_t *sess) { - ogs_index_final(&sess->pdr_pool); - ogs_index_final(&sess->far_pool); - ogs_index_final(&sess->urr_pool); - ogs_index_final(&sess->qer_pool); - ogs_index_final(&sess->bar_pool); + ogs_assert(sess); + + ogs_index_final(&sess->pdr_id_pool); + ogs_index_final(&sess->far_id_pool); + ogs_index_final(&sess->urr_id_pool); + ogs_index_final(&sess->qer_id_pool); + ogs_index_final(&sess->bar_id_pool); } diff --git a/lib/pfcp/context.h b/lib/pfcp/context.h index 6ef7b1da1..3666c3f97 100644 --- a/lib/pfcp/context.h +++ b/lib/pfcp/context.h @@ -116,6 +116,7 @@ typedef struct ogs_pfcp_pdr_s { uint64_t hashkey; + uint8_t *id_node; /* Pool-Node for ID */ ogs_pfcp_pdr_id_t id; ogs_pfcp_precedence_t precedence; ogs_pfcp_interface_t src_if; @@ -152,6 +153,7 @@ typedef struct ogs_pfcp_far_s { ogs_lnode_t lnode; uint32_t index; + uint8_t *id_node; /* Pool-Node for ID */ ogs_pfcp_far_id_t id; ogs_pfcp_apply_action_t apply_action; ogs_pfcp_interface_t dst_if; @@ -182,6 +184,7 @@ typedef struct ogs_pfcp_urr_s { ogs_lnode_t lnode; uint32_t index; + uint8_t *id_node; /* Pool-Node for ID */ ogs_pfcp_urr_id_t id; ogs_pfcp_sess_t *sess; @@ -191,6 +194,7 @@ typedef struct ogs_pfcp_qer_s { ogs_lnode_t lnode; uint32_t index; + uint8_t *id_node; /* Pool-Node for ID */ ogs_pfcp_qer_id_t id; ogs_pfcp_gate_status_t gate_status; @@ -203,6 +207,10 @@ typedef struct ogs_pfcp_qer_s { } ogs_pfcp_qer_t; typedef struct ogs_pfcp_bar_s { + ogs_lnode_t lnode; + uint32_t index; + + uint8_t *id_node; /* Pool-Node for ID */ ogs_pfcp_bar_id_t id; ogs_pfcp_sess_t *sess; @@ -215,11 +223,11 @@ typedef struct ogs_pfcp_sess_s { ogs_list_t qer_list; /* QER List */ ogs_pfcp_bar_t *bar; /* BAR Item */ - OGS_POOL(pdr_pool, ogs_pfcp_pdr_t); - OGS_POOL(far_pool, ogs_pfcp_far_t); - OGS_POOL(urr_pool, ogs_pfcp_urr_t); - OGS_POOL(qer_pool, ogs_pfcp_qer_t); - OGS_POOL(bar_pool, ogs_pfcp_bar_t); + OGS_POOL(pdr_id_pool, uint8_t); + OGS_POOL(far_id_pool, uint8_t); + OGS_POOL(urr_id_pool, uint8_t); + OGS_POOL(qer_id_pool, uint8_t); + OGS_POOL(bar_id_pool, uint8_t); /* Related Context */ ogs_pfcp_pdr_t *default_pdr; /* Used by UPF */ diff --git a/src/amf/context.h b/src/amf/context.h index 1b0bf79b7..8ea8b2dae 100644 --- a/src/amf/context.h +++ b/src/amf/context.h @@ -343,7 +343,8 @@ struct amf_ue_s { #define CM_CONNECTED(__aMF) \ ((__aMF) && ((__aMF)->ran_ue != NULL)) -#define CM_IDLE(__aMF) (!ECM_CONNECTED(__aMF)) +#define CM_IDLE(__aMF) \ + ((__aMF) && ((__aMF)->ran_ue == NULL)) /* NG UE context */ ran_ue_t *ran_ue; diff --git a/src/mme/mme-context.h b/src/mme/mme-context.h index e55fb18f7..87c8df582 100644 --- a/src/mme/mme-context.h +++ b/src/mme/mme-context.h @@ -406,7 +406,8 @@ struct mme_ue_s { #define ECM_CONNECTED(__mME) \ ((__mME) && ((__mME)->enb_ue != NULL)) -#define ECM_IDLE(__mME) (!ECM_CONNECTED(__mME)) +#define ECM_IDLE(__mME) \ + ((__mME) && ((__mME)->enb_ue == NULL)) /* S1 UE context */ enb_ue_t *enb_ue; diff --git a/src/mme/mme-s11-handler.c b/src/mme/mme-s11-handler.c index ad610458b..1b72e7a63 100644 --- a/src/mme/mme-s11-handler.c +++ b/src/mme/mme-s11-handler.c @@ -723,7 +723,7 @@ void mme_s11_handle_downlink_data_notification( cause.value = OGS_GTP_CAUSE_REQUEST_ACCEPTED; if (!mme_ue) { - ogs_warn("No Context"); + ogs_warn("OGS_GTP_CAUSE_CONTEXT_NOT_FOUND"); cause.value = OGS_GTP_CAUSE_CONTEXT_NOT_FOUND; } diff --git a/src/mme/mme-sm.c b/src/mme/mme-sm.c index 18c52ea9e..b136aa331 100644 --- a/src/mme/mme-sm.c +++ b/src/mme/mme-sm.c @@ -604,9 +604,9 @@ void mme_state_operational(ogs_fsm_t *s, mme_event_t *e) case OGS_GTP_DOWNLINK_DATA_NOTIFICATION_TYPE: if (!mme_ue) { if (gtp_message.h.teid_presence) - ogs_warn("TEID[%d]", gtp_message.h.teid); + ogs_warn("No Context : TEID[%d]", gtp_message.h.teid); else - ogs_warn("No TEID presence"); + ogs_warn("No Context : No TEID"); } mme_s11_handle_downlink_data_notification( xact, mme_ue, >p_message.downlink_data_notification); diff --git a/src/mme/nas-path.c b/src/mme/nas-path.c index ab063f0d7..d8af0f2d0 100644 --- a/src/mme/nas-path.c +++ b/src/mme/nas-path.c @@ -111,7 +111,10 @@ void nas_eps_send_attach_accept(mme_ue_t *mme_ue) ogs_assert(mme_bearer_next(bearer) == NULL); esmbuf = esm_build_activate_default_bearer_context_request(sess); - ogs_expect_or_return(esmbuf); + if (!esmbuf) { + ogs_error("esm_build_activate_default_bearer_context_request() failed"); + return; + } emmbuf = emm_build_attach_accept(mme_ue, esmbuf); ogs_expect_or_return(emmbuf); diff --git a/src/mme/s1ap-handler.c b/src/mme/s1ap-handler.c index babd52454..de8261884 100644 --- a/src/mme/s1ap-handler.c +++ b/src/mme/s1ap-handler.c @@ -494,52 +494,84 @@ void s1ap_handle_initial_context_setup_response( } } - ogs_debug(" IP[%s] ENB_ID[%d]", - OGS_ADDR(enb->addr, buf), enb->enb_id); + ogs_debug(" IP[%s] ENB_ID[%d]", OGS_ADDR(enb->addr, buf), enb->enb_id); - ogs_assert(ENB_UE_S1AP_ID); + if (!ENB_UE_S1AP_ID) { + ogs_error("No ENB_UE_S1AP_ID"); + s1ap_send_error_indication(enb, + NULL, ENB_UE_S1AP_ID, + S1AP_Cause_PR_protocol, S1AP_CauseProtocol_semantic_error); + return; + } enb_ue = enb_ue_find_by_enb_ue_s1ap_id(enb, *ENB_UE_S1AP_ID); - ogs_expect_or_return(enb_ue); - mme_ue = enb_ue->mme_ue; - ogs_assert(mme_ue); + if (!enb_ue) { + ogs_error("No eNB UE Context : ENB_UE_S1AP_ID[%lld]", + (long long)*ENB_UE_S1AP_ID); + s1ap_send_error_indication(enb, + NULL, ENB_UE_S1AP_ID, + S1AP_Cause_PR_radioNetwork, + S1AP_CauseRadioNetwork_unknown_enb_ue_s1ap_id); + return; + } ogs_debug(" ENB_UE_S1AP_ID[%d] MME_UE_S1AP_ID[%d]", enb_ue->enb_ue_s1ap_id, enb_ue->mme_ue_s1ap_id); - ogs_assert(E_RABSetupListCtxtSURes); - for (i = 0; i < E_RABSetupListCtxtSURes->list.count; i++) { - S1AP_E_RABSetupItemCtxtSUResIEs_t *ie2 = NULL; - S1AP_E_RABSetupItemCtxtSURes_t *e_rab = NULL; + mme_ue = enb_ue->mme_ue; + ogs_assert(mme_ue); - mme_bearer_t *bearer = NULL; + if (E_RABSetupListCtxtSURes) { + for (i = 0; i < E_RABSetupListCtxtSURes->list.count; i++) { + S1AP_E_RABSetupItemCtxtSUResIEs_t *ie2 = NULL; + S1AP_E_RABSetupItemCtxtSURes_t *e_rab = NULL; - ie2 = (S1AP_E_RABSetupItemCtxtSUResIEs_t *) - E_RABSetupListCtxtSURes->list.array[i]; - ogs_assert(ie2); + mme_bearer_t *bearer = NULL; - e_rab = &ie2->value.choice.E_RABSetupItemCtxtSURes; - ogs_assert(e_rab); - - bearer = mme_bearer_find_by_ue_ebi(mme_ue, e_rab->e_RAB_ID); - ogs_assert(bearer); - memcpy(&bearer->enb_s1u_teid, e_rab->gTP_TEID.buf, - sizeof(bearer->enb_s1u_teid)); - bearer->enb_s1u_teid = ntohl(bearer->enb_s1u_teid); - rv = ogs_asn_BIT_STRING_to_ip( - &e_rab->transportLayerAddress, &bearer->enb_s1u_ip); - ogs_assert(rv == OGS_OK); - - ogs_debug(" EBI[%d] ENB-S1U-TEID[%d]", - bearer->ebi, bearer->enb_s1u_teid); - - if (OGS_FSM_CHECK(&bearer->sm, esm_state_active)) { - ogs_debug(" NAS_EPS Type[%d]", mme_ue->nas_eps.type); - int uli_presence = 0; - if (mme_ue->nas_eps.type != MME_EPS_TYPE_ATTACH_REQUEST) { - ogs_debug(" ### ULI PRESENT ###"); - uli_presence = 1; + ie2 = (S1AP_E_RABSetupItemCtxtSUResIEs_t *) + E_RABSetupListCtxtSURes->list.array[i]; + if (!ie2) { + ogs_error("No S1AP_E_RABSetupItemCtxtSUResIEs_t"); + s1ap_send_error_indication2(mme_ue, + S1AP_Cause_PR_protocol, S1AP_CauseProtocol_semantic_error); + return; + } + + e_rab = &ie2->value.choice.E_RABSetupItemCtxtSURes; + if (!e_rab) { + ogs_error("No E_RABSetupItemCtxtSURes"); + s1ap_send_error_indication2(mme_ue, + S1AP_Cause_PR_protocol, S1AP_CauseProtocol_semantic_error); + return; + } + + bearer = mme_bearer_find_by_ue_ebi(mme_ue, e_rab->e_RAB_ID); + if (!bearer) { + ogs_error("Invalid e_RAB_ID[%lld]", (long long)e_rab->e_RAB_ID); + s1ap_send_error_indication2(mme_ue, + S1AP_Cause_PR_radioNetwork, + S1AP_CauseRadioNetwork_unknown_E_RAB_ID); + return; + } + + memcpy(&bearer->enb_s1u_teid, e_rab->gTP_TEID.buf, + sizeof(bearer->enb_s1u_teid)); + bearer->enb_s1u_teid = ntohl(bearer->enb_s1u_teid); + rv = ogs_asn_BIT_STRING_to_ip( + &e_rab->transportLayerAddress, &bearer->enb_s1u_ip); + ogs_assert(rv == OGS_OK); + + ogs_debug(" EBI[%d] ENB-S1U-TEID[%d]", + bearer->ebi, bearer->enb_s1u_teid); + + if (OGS_FSM_CHECK(&bearer->sm, esm_state_active)) { + ogs_debug(" NAS_EPS Type[%d]", mme_ue->nas_eps.type); + int uli_presence = 0; + if (mme_ue->nas_eps.type != MME_EPS_TYPE_ATTACH_REQUEST) { + ogs_debug(" ### ULI PRESENT ###"); + uli_presence = 1; + } + mme_gtp_send_modify_bearer_request(bearer, uli_presence); } - mme_gtp_send_modify_bearer_request(bearer, uli_presence); } } @@ -894,7 +926,7 @@ void s1ap_handle_ue_context_release_request( if (!enb_ue) { ogs_warn("No ENB UE Context : MME_UE_S1AP_ID[%d]", (int)*MME_UE_S1AP_ID); - s1ap_send_error_indication(enb, + s1ap_send_error_indication(enb, MME_UE_S1AP_ID, ENB_UE_S1AP_ID, S1AP_Cause_PR_radioNetwork, S1AP_CauseRadioNetwork_unknown_mme_ue_s1ap_id); @@ -970,7 +1002,7 @@ void s1ap_handle_ue_context_release_complete( if (!enb_ue) { ogs_warn("No ENB UE Context : MME_UE_S1AP_ID[%d]", (int)*MME_UE_S1AP_ID); - s1ap_send_error_indication(enb, + s1ap_send_error_indication(enb, MME_UE_S1AP_ID, NULL, S1AP_Cause_PR_radioNetwork, S1AP_CauseRadioNetwork_unknown_mme_ue_s1ap_id); diff --git a/src/mme/s1ap-path.c b/src/mme/s1ap-path.c index 6522f4882..733e88103 100644 --- a/src/mme/s1ap-path.c +++ b/src/mme/s1ap-path.c @@ -519,6 +519,28 @@ void s1ap_send_error_indication( ogs_expect(rv == OGS_OK); } +void s1ap_send_error_indication2( + mme_ue_t *mme_ue, S1AP_Cause_PR group, long cause) +{ + mme_enb_t *enb; + enb_ue_t *enb_ue; + + S1AP_MME_UE_S1AP_ID_t mme_ue_s1ap_id; + S1AP_ENB_UE_S1AP_ID_t enb_ue_s1ap_id; + + ogs_assert(mme_ue); + enb_ue = mme_ue->enb_ue; + ogs_expect_or_return(enb_ue); + enb = enb_ue->enb; + ogs_expect_or_return(enb); + + mme_ue_s1ap_id = enb_ue->mme_ue_s1ap_id, + enb_ue_s1ap_id = enb_ue->enb_ue_s1ap_id, + + s1ap_send_error_indication( + enb, &mme_ue_s1ap_id, &enb_ue_s1ap_id, group, cause); +} + void s1ap_send_s1_reset_ack( mme_enb_t *enb, S1AP_UE_associatedLogicalS1_ConnectionListRes_t *partOfS1_Interface) diff --git a/src/mme/s1ap-path.h b/src/mme/s1ap-path.h index 872f16aec..cfc10f1cc 100644 --- a/src/mme/s1ap-path.h +++ b/src/mme/s1ap-path.h @@ -91,6 +91,8 @@ void s1ap_send_error_indication( S1AP_MME_UE_S1AP_ID_t *mme_ue_s1ap_id, S1AP_ENB_UE_S1AP_ID_t *enb_ue_s1ap_id, S1AP_Cause_PR group, long cause); +void s1ap_send_error_indication2( + mme_ue_t *mme_ue, S1AP_Cause_PR group, long cause); void s1ap_send_s1_reset_ack( mme_enb_t *enb, S1AP_UE_associatedLogicalS1_ConnectionListRes_t *partOfS1_Interface); diff --git a/src/smf/context.c b/src/smf/context.c index 3fc9d1c9a..ebd3bb544 100644 --- a/src/smf/context.c +++ b/src/smf/context.c @@ -29,6 +29,8 @@ static OGS_POOL(smf_ue_pool, smf_ue_t); static OGS_POOL(smf_sess_pool, smf_sess_t); static OGS_POOL(smf_bearer_pool, smf_bearer_t); +static OGS_POOL(smf_pf_pool, smf_pf_t); + static int context_initialized = 0; static int num_of_smf_sess = 0; @@ -67,6 +69,8 @@ void smf_context_init(void) ogs_pool_init(&smf_sess_pool, ogs_app()->pool.sess); ogs_pool_init(&smf_bearer_pool, ogs_app()->pool.bearer); + ogs_pool_init(&smf_pf_pool, ogs_app()->pool.bearer * OGS_MAX_NUM_OF_PF); + self.supi_hash = ogs_hash_make(); self.imsi_hash = ogs_hash_make(); self.ipv4_hash = ogs_hash_make(); @@ -94,6 +98,8 @@ void smf_context_final(void) ogs_pool_final(&smf_bearer_pool); ogs_pool_final(&smf_sess_pool); + ogs_pool_final(&smf_pf_pool); + ogs_gtp_node_remove_all(&self.sgw_s5c_list); ogs_gtp_node_final(); @@ -1234,7 +1240,7 @@ smf_bearer_t *smf_bearer_add(smf_sess_t *sess) ogs_assert(bearer); memset(bearer, 0, sizeof *bearer); - ogs_index_init(&bearer->pf_pool, OGS_MAX_NUM_OF_PF); + smf_pf_identifier_pool_init(bearer); bearer->index = ogs_pool_index(&smf_bearer_pool, bearer); ogs_assert(bearer->index > 0 && bearer->index <= @@ -1351,7 +1357,7 @@ int smf_bearer_remove(smf_bearer_t *bearer) smf_pf_remove_all(bearer); - ogs_index_final(&bearer->pf_pool); + smf_pf_identifier_pool_final(bearer); if (bearer->qfi_node) ogs_pool_free(&bearer->sess->qfi_pool, bearer->qfi_node); @@ -1490,11 +1496,14 @@ smf_pf_t *smf_pf_add(smf_bearer_t *bearer, uint32_t precedence) ogs_assert(bearer); - ogs_pool_alloc(&bearer->pf_pool, &pf); + ogs_pool_alloc(&smf_pf_pool, &pf); ogs_assert(pf); memset(pf, 0, sizeof *pf); - pf->index = ogs_pool_index(&bearer->pf_pool, pf); + ogs_pool_alloc(&bearer->pf_identifier_pool, &pf->identifier_node); + ogs_assert(pf->identifier_node); + + pf->index = *(pf->identifier_node); ogs_assert(pf->index > 0 && pf->index <= OGS_MAX_NUM_OF_PF); pf->identifier = pf->index; @@ -1514,7 +1523,10 @@ int smf_pf_remove(smf_pf_t *pf) if (pf->flow_description) ogs_free(pf->flow_description); - ogs_pool_free(&pf->bearer->pf_pool, pf); + if (pf->identifier_node) + ogs_pool_free(&pf->bearer->pf_identifier_pool, pf->identifier_node); + + ogs_pool_free(&smf_pf_pool, pf); return OGS_OK; } @@ -1731,9 +1743,31 @@ void smf_qfi_pool_init(smf_sess_t *sess) void smf_qfi_pool_final(smf_sess_t *sess) { + ogs_assert(sess); + ogs_index_final(&sess->qfi_pool); } +void smf_pf_identifier_pool_init(smf_bearer_t *bearer) +{ + int i; + + ogs_assert(bearer); + + ogs_index_init(&bearer->pf_identifier_pool, OGS_MAX_NUM_OF_PF); + + for (i = 1; i <= OGS_MAX_NUM_OF_PF; i++) { + bearer->pf_identifier_pool.array[i-1] = i; + } +} + +void smf_pf_identifier_pool_final(smf_bearer_t *bearer) +{ + ogs_assert(bearer); + + ogs_index_final(&bearer->pf_identifier_pool); +} + static void stats_add_smf_session(void) { num_of_smf_sess = num_of_smf_sess + 1; diff --git a/src/smf/context.h b/src/smf/context.h index 4c6f5e705..b4832e01b 100644 --- a/src/smf/context.h +++ b/src/smf/context.h @@ -142,6 +142,8 @@ ED3(uint8_t spare:2;, uint8_t direction:2;, uint8_t identifier:4;) + uint8_t *identifier_node; /* Pool-Node for Identifier */ + ogs_ipfw_rule_t ipfw_rule; char *flow_description; @@ -172,7 +174,7 @@ typedef struct smf_bearer_s { char *name; /* PCC Rule Name */ ogs_qos_t qos; /* QoS Infomration */ - OGS_POOL(pf_pool, smf_pf_t); + OGS_POOL(pf_identifier_pool, uint8_t); /* Packet Filter Identifier Generator(1~15) */ uint8_t pf_identifier; @@ -350,6 +352,9 @@ int smf_pco_build(uint8_t *pco_buf, uint8_t *buffer, int length); void smf_qfi_pool_init(smf_sess_t *sess); void smf_qfi_pool_final(smf_sess_t *sess); +void smf_pf_identifier_pool_init(smf_bearer_t *bearer); +void smf_pf_identifier_pool_final(smf_bearer_t *bearer); + #ifdef __cplusplus } #endif