diff --git a/src/mme/mme-gtp-path.c b/src/mme/mme-gtp-path.c index 99d27f655..581799352 100644 --- a/src/mme/mme-gtp-path.c +++ b/src/mme/mme-gtp-path.c @@ -480,15 +480,37 @@ int mme_gtp_send_release_access_bearers_request(mme_ue_t *mme_ue, int action) void mme_gtp_send_release_all_ue_in_enb(mme_enb_t *enb, int action) { mme_ue_t *mme_ue = NULL; - enb_ue_t *enb_ue = NULL; + enb_ue_t *enb_ue = NULL, *next = NULL; - ogs_list_for_each(&enb->enb_ue_list, enb_ue) { + ogs_list_for_each_safe(&enb->enb_ue_list, next, enb_ue) { mme_ue = enb_ue->mme_ue; if (mme_ue) { + if (action == OGS_GTP_RELEASE_S1_CONTEXT_REMOVE_BY_LO_CONNREFUSED) { + /* + * https://github.com/open5gs/open5gs/pull/1497 + * + * 1. eNB, SGW-U and UPF go offline at the same time. + * 2. MME sends Release Access Bearer Request to SGW-C + * 3. SGW-C/SMF sends PFCP modification, + * but SGW-U/UPF does not respond. + * 4. MME does not receive Release Access Bearer Response. + * 5. timeout() + * 6. MME sends Delete Session Request to the SGW-C/SMF + * 7. No SGW-U/UPF, so timeout() + * 8. MME sends UEContextReleaseRequest enb_ue. + * 9. But there is no enb_ue, so MME crashed. + * + * To solve this situation, + * Execute enb_ue_unlink(mme_ue) and enb_ue_remove(enb_ue) + * before mme_gtp_send_release_access_bearers_request() + */ + enb_ue_unlink(mme_ue); + enb_ue_remove(enb_ue); + } + ogs_assert(OGS_OK == mme_gtp_send_release_access_bearers_request(mme_ue, action)); - } else { ogs_warn("mme_gtp_send_release_all_ue_in_enb()"); ogs_warn(" ENB_UE_S1AP_ID[%d] MME_UE_S1AP_ID[%d] Action[%d]", diff --git a/src/mme/mme-s11-handler.c b/src/mme/mme-s11-handler.c index 338adfb82..744757956 100644 --- a/src/mme/mme-s11-handler.c +++ b/src/mme/mme-s11-handler.c @@ -1152,16 +1152,10 @@ void mme_s11_handle_release_access_bearers_response( ogs_error("ENB-S1 Context has already been removed"); } } else if (action == OGS_GTP_RELEASE_S1_CONTEXT_REMOVE_BY_LO_CONNREFUSED) { - enb_ue = enb_ue_cycle(mme_ue->enb_ue); - - enb_ue_unlink(mme_ue); - - if (enb_ue) { - enb_ue_remove(enb_ue); - } else { - ogs_error("ENB-S1 Context has already been removed"); - } + /* enb_ue_unlink() and enb_ue_remove() has already been executed. + * So, there is no `enb_ue` context */ + } else if (action == OGS_GTP_RELEASE_S1_CONTEXT_REMOVE_BY_RESET_ALL) { /* * TS36.413 * 8.7.1.2.1 Reset Procedure Initiated from the MME @@ -1175,7 +1169,6 @@ void mme_s11_handle_release_access_bearers_response( * for new UE-associated logical S1-connections over the S1 interface, * the MME shall respond with the RESET ACKNOWLEDGE message. */ - } else if (action == OGS_GTP_RELEASE_S1_CONTEXT_REMOVE_BY_RESET_ALL) { enb_ue = enb_ue_cycle(mme_ue->enb_ue); enb_ue_unlink(mme_ue);