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