diff --git a/src/amf/context.h b/src/amf/context.h index 03e830196..1f41ab8f3 100644 --- a/src/amf/context.h +++ b/src/amf/context.h @@ -130,6 +130,7 @@ typedef struct amf_gnb_s { ogs_fsm_t sm; /* A state machine */ uint32_t gnb_id; /* gNB_ID received from gNB */ + ogs_plmn_id_t plmn_id; /* gNB PLMN-ID received from gNB */ ogs_sctp_sock_t sctp; /* SCTP socket */ struct { diff --git a/src/amf/ngap-handler.c b/src/amf/ngap-handler.c index d809566e1..814900258 100644 --- a/src/amf/ngap-handler.c +++ b/src/amf/ngap-handler.c @@ -22,6 +22,36 @@ #include "sbi-path.h" #include "nas-path.h" +static bool maximum_number_of_gnbs_is_reached(void) +{ + amf_gnb_t *gnb = NULL, *next_gnb = NULL; + int number_of_gnbs_online = 0; + + ogs_list_for_each_safe(&amf_self()->gnb_list, next_gnb, gnb) { + if (gnb->state.ng_setup_success) { + number_of_gnbs_online++; + } + } + + return number_of_gnbs_online >= ogs_app()->max.peer; +} + +static bool gnb_plmn_id_is_foreign(amf_gnb_t *gnb) +{ + int i, j; + + for (i = 0; i < gnb->num_of_supported_ta_list; i++) { + for (j = 0; j < gnb->supported_ta_list[i].num_of_bplmn_list; j++) { + if (memcmp(&gnb->plmn_id, + &gnb->supported_ta_list[i].bplmn_list[j].plmn_id, + OGS_PLMN_ID_LEN) == 0) + return false; + } + } + + return true; +} + static bool served_tai_is_found(amf_gnb_t *gnb) { int i, j; @@ -83,20 +113,6 @@ static bool s_nssai_is_found(amf_gnb_t *gnb) return false; } -static bool maximum_number_of_gnbs_is_reached(void) -{ - amf_gnb_t *gnb = NULL, *next_gnb = NULL; - int number_of_gnbs_online = 0; - - ogs_list_for_each_safe(&amf_self()->gnb_list, next_gnb, gnb) { - if (gnb->state.ng_setup_success) { - number_of_gnbs_online++; - } - } - - return number_of_gnbs_online >= ogs_app()->max.peer; -} - void ngap_handle_ng_setup_request(amf_gnb_t *gnb, ogs_ngap_message_t *message) { char buf[OGS_ADDRSTRLEN]; @@ -178,6 +194,11 @@ void ngap_handle_ng_setup_request(amf_gnb_t *gnb, ogs_ngap_message_t *message) ogs_ngap_GNB_ID_to_uint32(&globalGNB_ID->gNB_ID, &gnb_id); ogs_debug(" IP[%s] GNB_ID[0x%x]", OGS_ADDR(gnb->sctp.addr, buf), gnb_id); + memcpy(&gnb->plmn_id, + globalGNB_ID->pLMNIdentity.buf, sizeof(gnb->plmn_id)); + ogs_debug(" PLMN_ID[MCC:%d MNC:%d]", + ogs_plmn_id_mcc(&gnb->plmn_id), ogs_plmn_id_mnc(&gnb->plmn_id)); + if (PagingDRX) ogs_debug(" PagingDRX[%ld]", *PagingDRX); @@ -297,6 +318,18 @@ void ngap_handle_ng_setup_request(amf_gnb_t *gnb, ogs_ngap_message_t *message) return; } + if (gnb_plmn_id_is_foreign(gnb)) { + ogs_warn("NG-Setup failure:"); + ogs_warn(" globalGNB_ID PLMN-ID is foreign"); + group = NGAP_Cause_PR_protocol; + cause = NGAP_CauseProtocol_message_not_compatible_with_receiver_state; + + r = ngap_send_ng_setup_failure(gnb, group, cause); + ogs_expect(r == OGS_OK); + ogs_assert(r != OGS_ERROR); + return; + } + if (gnb->num_of_supported_ta_list == 0) { ogs_warn("NG-Setup failure:"); ogs_warn(" No supported TA exist in NG-Setup request"); diff --git a/src/mme/mme-context.h b/src/mme/mme-context.h index bf975f77d..3c0da394b 100644 --- a/src/mme/mme-context.h +++ b/src/mme/mme-context.h @@ -277,6 +277,7 @@ typedef struct mme_enb_s { ogs_fsm_t sm; /* A state machine */ uint32_t enb_id; /* eNB_ID received from eNB */ + ogs_plmn_id_t plmn_id; /* eNB PLMN-ID received from eNB */ ogs_sctp_sock_t sctp; /* SCTP socket */ struct { diff --git a/src/mme/s1ap-handler.c b/src/mme/s1ap-handler.c index 13f84d5c5..225b99896 100644 --- a/src/mme/s1ap-handler.c +++ b/src/mme/s1ap-handler.c @@ -34,6 +34,33 @@ #include "mme-path.h" #include "mme-sm.h" +static bool maximum_number_of_enbs_is_reached(void) +{ + mme_enb_t *enb = NULL, *next_enb = NULL; + int number_of_enbs_online = 0; + + ogs_list_for_each_safe(&mme_self()->enb_list, next_enb, enb) { + if (enb->state.s1_setup_success) { + number_of_enbs_online++; + } + } + + return number_of_enbs_online >= ogs_app()->max.peer; +} + +static bool enb_plmn_id_is_foreign(mme_enb_t *enb) +{ + int i; + + for (i = 0; i < enb->num_of_supported_ta_list; i++) { + if (memcmp(&enb->plmn_id, &enb->supported_ta_list[i].plmn_id, + OGS_PLMN_ID_LEN) == 0) + return false; + } + + return true; +} + static bool served_tai_is_found(mme_enb_t *enb) { int i; @@ -51,20 +78,6 @@ static bool served_tai_is_found(mme_enb_t *enb) return false; } -static bool maximum_number_of_enbs_is_reached(void) -{ - mme_enb_t *enb = NULL, *next_enb = NULL; - int number_of_enbs_online = 0; - - ogs_list_for_each_safe(&mme_self()->enb_list, next_enb, enb) { - if (enb->state.s1_setup_success) { - number_of_enbs_online++; - } - } - - return number_of_enbs_online >= ogs_app()->max.peer; -} - void s1ap_handle_s1_setup_request(mme_enb_t *enb, ogs_s1ap_message_t *message) { char buf[OGS_ADDRSTRLEN]; @@ -110,17 +123,41 @@ void s1ap_handle_s1_setup_request(mme_enb_t *enb, ogs_s1ap_message_t *message) } } - ogs_assert(Global_ENB_ID); + if (!Global_ENB_ID) { + ogs_error("No Global_ENB_ID"); + group = S1AP_Cause_PR_misc; + cause = S1AP_CauseProtocol_semantic_error; + + r = s1ap_send_s1_setup_failure(enb, group, cause); + ogs_expect(r == OGS_OK); + ogs_assert(r != OGS_ERROR); + return; + } + + if (!SupportedTAs) { + ogs_error("No SupportedTAs"); + group = S1AP_Cause_PR_misc; + cause = S1AP_CauseProtocol_semantic_error; + + r = s1ap_send_s1_setup_failure(enb, group, cause); + ogs_expect(r == OGS_OK); + ogs_assert(r != OGS_ERROR); + return; + } ogs_s1ap_ENB_ID_to_uint32(&Global_ENB_ID->eNB_ID, &enb_id); ogs_debug(" IP[%s] ENB_ID[%d]", OGS_ADDR(enb->sctp.addr, buf), enb_id); + mme_enb_set_enb_id(enb, enb_id); + + memcpy(&enb->plmn_id, + Global_ENB_ID->pLMNidentity.buf, sizeof(enb->plmn_id)); + ogs_debug(" PLMN_ID[MCC:%d MNC:%d]", + ogs_plmn_id_mcc(&enb->plmn_id), ogs_plmn_id_mnc(&enb->plmn_id)); + if (PagingDRX) ogs_debug(" PagingDRX[%ld]", *PagingDRX); - mme_enb_set_enb_id(enb, enb_id); - - ogs_assert(SupportedTAs); /* Parse Supported TA */ enb->num_of_supported_ta_list = 0; for (i = 0; i < SupportedTAs->list.count; i++) { @@ -169,11 +206,11 @@ void s1ap_handle_s1_setup_request(mme_enb_t *enb, ogs_s1ap_message_t *message) return; } - if (enb->num_of_supported_ta_list == 0) { + if (enb_plmn_id_is_foreign(enb)) { ogs_warn("S1-Setup failure:"); - ogs_warn(" No supported TA exist in S1-Setup request"); + ogs_warn(" Global-ENB-ID PLMN-ID is foreign"); group = S1AP_Cause_PR_misc; - cause = S1AP_CauseMisc_unspecified; + cause = S1AP_CauseProtocol_semantic_error; r = s1ap_send_s1_setup_failure(enb, group, cause); ogs_expect(r == OGS_OK);