From d4698091928682885ad6d53424071581aa7f0a6a Mon Sep 17 00:00:00 2001 From: Sukchan Lee Date: Sat, 25 Mar 2023 09:18:20 +0900 Subject: [PATCH] [AMF/MME] PLMN access control These mechanisms are described in the GSMA roaming guidelines. Chapters called Access Control. For 4g: https://www.gsma.com/newsroom/wp-content/uploads//IR.88-v21.0.pdf For 5g: https://www.gsma.com/newsroom/wp-content/uploads//NG.113-v6.0.pdf --- configs/open5gs/amf.yaml.in | 35 +++++++++++++++ configs/open5gs/mme.yaml.in | 35 +++++++++++++++ configs/sample.yaml.in | 24 ---------- lib/proto/types.h | 3 +- src/amf/context.c | 81 ++++++++++++++++++++++++++++++++- src/amf/context.h | 8 ++++ src/amf/gmm-handler.c | 56 ++++++++++++++++++++++- src/mme/emm-handler.c | 89 ++++++++++++++++++++++++++++++++++++- src/mme/mme-context.c | 84 ++++++++++++++++++++++++++++++++-- src/mme/mme-context.h | 8 ++++ 10 files changed, 390 insertions(+), 33 deletions(-) diff --git a/configs/open5gs/amf.yaml.in b/configs/open5gs/amf.yaml.in index e694dc573..b022552db 100644 --- a/configs/open5gs/amf.yaml.in +++ b/configs/open5gs/amf.yaml.in @@ -417,6 +417,41 @@ sbi: # s_nssai: # - sst: 1 # +# +# +# +# If access_control is not specified, then all networks are allowed +# If access_control is defined, +# no other networks are allowed other than matching plmn_id. +# +# default_reject_cause may be used to overwrite the default error cause #11 +# for non matching plmn_id +# +# for matching plmn_id with reject_cause defined, +# the AMF rejects access with the reject_cause error cause +# +# for matching plmn_id without reject_cause defined, +# the AMF accepts the PLMN traffic +# +# o The example below only accepts 002/02 and 999/70 PLMNs. +# 001/01 is rejected with cause 15, +# and the rest of the PLMNs are rejected with default cause 13. +# +# amf: +# access_control: +# - default_reject_cause: 13 +# - plmn_id: +# reject_cause: 15 +# mcc: 001 +# mnc: 01 +# - plmn_id: +# mcc: 002 +# mnc: 02 +# - plmn_id: +# mcc: 999 +# mnc: 70 +# +# # # # amf: diff --git a/configs/open5gs/mme.yaml.in b/configs/open5gs/mme.yaml.in index 96aaac05d..1fb245923 100644 --- a/configs/open5gs/mme.yaml.in +++ b/configs/open5gs/mme.yaml.in @@ -269,6 +269,41 @@ logger: # mnc: 09 # tac: [70, 80] # +# +# +# +# If access_control is not specified, then all networks are allowed +# If access_control is defined, +# no other networks are allowed other than matching plmn_id. +# +# default_reject_cause may be used to overwrite the default error cause #11 +# for non matching plmn_id +# +# for matching plmn_id with reject_cause defined, +# the MME rejects access with the reject_cause error cause +# +# for matching plmn_id without reject_cause defined, +# the MME accepts the PLMN traffic +# +# o The example below only accepts 002/02 and 999/70 PLMNs. +# 001/01 is rejected with cause 15, +# and the rest of the PLMNs are rejected with default cause 13. +# +# mme: +# access_control: +# - default_reject_cause: 13 +# - plmn_id: +# reject_cause: 15 +# mcc: 001 +# mnc: 01 +# - plmn_id: +# mcc: 002 +# mnc: 02 +# - plmn_id: +# mcc: 999 +# mnc: 70 +# +# # # mme: # network_name: diff --git a/configs/sample.yaml.in b/configs/sample.yaml.in index 14345bd51..47a3c1fd6 100644 --- a/configs/sample.yaml.in +++ b/configs/sample.yaml.in @@ -125,30 +125,6 @@ smf: - identity: pcrf.localdomain addr: 127.0.0.9 -# -# -# -# o (Default) If you do not set Delegated Discovery as shown below, -# -# sbi: -# - addr: 127.0.0.5 -# port: 7777 -# -# - Use SCP if SCP avaiable. Otherwise NRF is used. -# => App fails if both NRF and SCP are unavailable. -# -# sbi: -# - addr: 127.0.0.5 -# port: 7777 -# discovery: -# delegated: auto -# -# o To use SCP always => App fails if no SCP available. -# delegated: yes -# -# o Don't use SCP server => App fails if no NRF available. -# delegated: no -# amf: sbi: - addr: 127.0.0.5 diff --git a/lib/proto/types.h b/lib/proto/types.h index 3a30c1d33..b05626a2a 100644 --- a/lib/proto/types.h +++ b/lib/proto/types.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019-2022 by Sukchan Lee + * Copyright (C) 2019-2023 by Sukchan Lee * * This file is part of Open5GS. * @@ -84,6 +84,7 @@ extern "C" { #define OGS_MAX_NUM_OF_SERVED_GUAMI 8 #define OGS_MAX_NUM_OF_SERVED_TAI OGS_MAX_NUM_OF_TAI +#define OGS_MAX_NUM_OF_ACCESS_CONTROL 8 #define OGS_MAX_NUM_OF_ALGORITHM 8 #define OGS_MAX_NUM_OF_BPLMN 6 diff --git a/src/amf/context.c b/src/amf/context.c index 990cb784c..45aeaba08 100644 --- a/src/amf/context.c +++ b/src/amf/context.c @@ -755,6 +755,81 @@ int amf_context_parse_config(void) } } while (ogs_yaml_iter_type(&plmn_support_array) == YAML_SEQUENCE_NODE); + } else if (!strcmp(amf_key, "access_control")) { + ogs_yaml_iter_t access_control_array, access_control_iter; + ogs_yaml_iter_recurse(&amf_iter, &access_control_array); + do { + ogs_assert(self.num_of_access_control < + OGS_MAX_NUM_OF_ACCESS_CONTROL); + + if (ogs_yaml_iter_type(&access_control_array) == + YAML_MAPPING_NODE) { + memcpy(&access_control_iter, &access_control_array, + sizeof(ogs_yaml_iter_t)); + } else if (ogs_yaml_iter_type(&access_control_array) == + YAML_SEQUENCE_NODE) { + if (!ogs_yaml_iter_next(&access_control_array)) + break; + ogs_yaml_iter_recurse(&access_control_array, + &access_control_iter); + } else if (ogs_yaml_iter_type(&access_control_array) == + YAML_SCALAR_NODE) { + break; + } else + ogs_assert_if_reached(); + + while (ogs_yaml_iter_next(&access_control_iter)) { + const char *mnc = NULL, *mcc = NULL; + int reject_cause = 0; + const char *access_control_key = + ogs_yaml_iter_key(&access_control_iter); + ogs_assert(access_control_key); + if (!strcmp(access_control_key, + "default_reject_cause")) { + const char *v = ogs_yaml_iter_value( + &access_control_iter); + if (v) self.default_reject_cause = atoi(v); + } else if (!strcmp(access_control_key, "plmn_id")) { + ogs_yaml_iter_t plmn_id_iter; + + ogs_yaml_iter_recurse(&access_control_iter, + &plmn_id_iter); + while (ogs_yaml_iter_next(&plmn_id_iter)) { + const char *plmn_id_key = + ogs_yaml_iter_key(&plmn_id_iter); + ogs_assert(plmn_id_key); + if (!strcmp(plmn_id_key, "reject_cause")) { + const char *v = ogs_yaml_iter_value( + &plmn_id_iter); + if (v) reject_cause = atoi(v); + } else if (!strcmp(plmn_id_key, "mcc")) { + mcc = ogs_yaml_iter_value( + &plmn_id_iter); + } else if (!strcmp(plmn_id_key, "mnc")) { + mnc = ogs_yaml_iter_value( + &plmn_id_iter); + } + } + + if (mcc && mnc) { + ogs_plmn_id_build( + &self.access_control[ + self.num_of_access_control]. + plmn_id, + atoi(mcc), atoi(mnc), strlen(mnc)); + if (reject_cause) + self.access_control[ + self.num_of_access_control]. + reject_cause = reject_cause; + self.num_of_access_control++; + } + } else + ogs_warn("unknown key `%s`", + access_control_key); + } + + } while (ogs_yaml_iter_type(&access_control_array) == + YAML_SEQUENCE_NODE); } else if (!strcmp(amf_key, "security")) { ogs_yaml_iter_t security_iter; ogs_yaml_iter_recurse(&amf_iter, &security_iter); @@ -847,7 +922,8 @@ int amf_context_parse_config(void) } while ( ogs_yaml_iter_type(&ciphering_order_iter) == YAML_SEQUENCE_NODE); - } + } else + ogs_warn("unknown key `%s`", security_key); } } else if (!strcmp(amf_key, "network_name")) { ogs_yaml_iter_t network_name_iter; @@ -891,7 +967,8 @@ int amf_context_parse_config(void) network_short_name->length = size*2+1; network_short_name->coding_scheme = 1; network_short_name->ext = 1; - } + } else + ogs_warn("unknown key `%s`", network_name_key); } } else if (!strcmp(amf_key, "amf_name")) { self.amf_name = ogs_yaml_iter_value(&amf_iter); diff --git a/src/amf/context.h b/src/amf/context.h index e126ce167..a4203842f 100644 --- a/src/amf/context.h +++ b/src/amf/context.h @@ -66,6 +66,14 @@ typedef struct amf_context_s { ogs_s_nssai_t s_nssai[OGS_MAX_NUM_OF_SLICE]; } plmn_support[OGS_MAX_NUM_OF_PLMN]; + /* Access Control */ + int default_reject_cause; + int num_of_access_control; + struct { + int reject_cause; + ogs_plmn_id_t plmn_id; + } access_control[OGS_MAX_NUM_OF_ACCESS_CONTROL]; + /* defined in 'nas_ies.h' * #define NAS_SECURITY_ALGORITHMS_EIA0 0 * #define NAS_SECURITY_ALGORITHMS_128_EEA1 1 diff --git a/src/amf/gmm-handler.c b/src/amf/gmm-handler.c index 0f06d5062..9f03822e8 100644 --- a/src/amf/gmm-handler.c +++ b/src/amf/gmm-handler.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019,2020 by Sukchan Lee + * Copyright (C) 2019-2023 by Sukchan Lee * * This file is part of Open5GS. * @@ -32,11 +32,14 @@ static ogs_nas_5gmm_cause_t gmm_handle_nas_message_container( amf_ue_t *amf_ue, uint8_t message_type, ogs_nas_message_container_t *nas_message_container); +static uint8_t gmm_cause_from_access_control(ogs_plmn_id_t *plmn_id); + ogs_nas_5gmm_cause_t gmm_handle_registration_request(amf_ue_t *amf_ue, ogs_nas_security_header_type_t h, NGAP_ProcedureCode_t ngap_code, ogs_nas_5gs_registration_request_t *registration_request) { int served_tai_index = 0; + uint8_t gmm_cause; ran_ue_t *ran_ue = NULL; ogs_nas_5gs_registration_type_t *registration_type = NULL; @@ -281,6 +284,18 @@ ogs_nas_5gmm_cause_t gmm_handle_registration_request(amf_ue_t *amf_ue, memcpy(&amf_ue->nr_cgi, &ran_ue->saved.nr_cgi, sizeof(ogs_nr_cgi_t)); amf_ue->ue_location_timestamp = ogs_time_now(); + /* Check PLMN-ID access control */ + gmm_cause = gmm_cause_from_access_control(&amf_ue->nr_tai.plmn_id); + if (gmm_cause != OGS_5GMM_CAUSE_REQUEST_ACCEPTED) { + ogs_error("Rejected by PLMN-ID(in TAI) access control"); + return gmm_cause; + } + gmm_cause = gmm_cause_from_access_control(&amf_ue->nr_cgi.plmn_id); + if (gmm_cause != OGS_5GMM_CAUSE_REQUEST_ACCEPTED) { + ogs_error("Rejected by PLMN-ID(in CGI) access control"); + return gmm_cause; + } + /* Check TAI */ served_tai_index = amf_find_served_tai(&amf_ue->nr_tai); if (served_tai_index < 0) { @@ -511,6 +526,7 @@ ogs_nas_5gmm_cause_t gmm_handle_service_request(amf_ue_t *amf_ue, ogs_nas_5gs_service_request_t *service_request) { int served_tai_index = 0; + uint8_t gmm_cause; ran_ue_t *ran_ue = NULL; ogs_nas_key_set_identifier_t *ngksi = NULL; @@ -605,6 +621,18 @@ ogs_nas_5gmm_cause_t gmm_handle_service_request(amf_ue_t *amf_ue, memcpy(&amf_ue->nr_cgi, &ran_ue->saved.nr_cgi, sizeof(ogs_nr_cgi_t)); amf_ue->ue_location_timestamp = ogs_time_now(); + /* Check PLMN-ID access control */ + gmm_cause = gmm_cause_from_access_control(&amf_ue->nr_tai.plmn_id); + if (gmm_cause != OGS_5GMM_CAUSE_REQUEST_ACCEPTED) { + ogs_error("Rejected by PLMN-ID(in TAI) access control"); + return gmm_cause; + } + gmm_cause = gmm_cause_from_access_control(&amf_ue->nr_cgi.plmn_id); + if (gmm_cause != OGS_5GMM_CAUSE_REQUEST_ACCEPTED) { + ogs_error("Rejected by PLMN-ID(in CGI) access control"); + return gmm_cause; + } + /* Check TAI */ served_tai_index = amf_find_served_tai(&amf_ue->nr_tai); if (served_tai_index < 0) { @@ -1411,3 +1439,29 @@ static ogs_nas_5gmm_cause_t gmm_handle_nas_message_container( ogs_pkbuf_free(nasbuf); return gmm_cause; } + +static uint8_t gmm_cause_from_access_control(ogs_plmn_id_t *plmn_id) +{ + int i; + + ogs_assert(plmn_id); + + /* No Access Control */ + if (amf_self()->num_of_access_control == 0) + return OGS_5GMM_CAUSE_REQUEST_ACCEPTED; + + for (i = 0; i < amf_self()->num_of_access_control; i++) { + if (memcmp(&amf_self()->access_control[i].plmn_id, + plmn_id, OGS_PLMN_ID_LEN) == 0) { + if (amf_self()->access_control[i].reject_cause) + return amf_self()->access_control[i].reject_cause; + else + return OGS_5GMM_CAUSE_REQUEST_ACCEPTED; + } + } + + if (amf_self()->default_reject_cause) + return amf_self()->default_reject_cause; + + return OGS_5GMM_CAUSE_PLMN_NOT_ALLOWED; +} diff --git a/src/mme/emm-handler.c b/src/mme/emm-handler.c index 87e0b701d..2739885c2 100644 --- a/src/mme/emm-handler.c +++ b/src/mme/emm-handler.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 by Sukchan Lee + * Copyright (C) 2019-2023 by Sukchan Lee * * This file is part of Open5GS. * @@ -32,10 +32,13 @@ #undef OGS_LOG_DOMAIN #define OGS_LOG_DOMAIN __emm_log_domain +static uint8_t emm_cause_from_access_control(ogs_plmn_id_t *plmn_id); + int emm_handle_attach_request(mme_ue_t *mme_ue, ogs_nas_eps_attach_request_t *attach_request, ogs_pkbuf_t *pkbuf) { int r; + uint8_t emm_cause; int served_tai_index = 0; ogs_nas_eps_mobile_identity_guti_t *eps_mobile_identity_guti = NULL; @@ -132,6 +135,26 @@ int emm_handle_attach_request(mme_ue_t *mme_ue, memcpy(&mme_ue->e_cgi, &enb_ue->saved.e_cgi, sizeof(ogs_e_cgi_t)); mme_ue->ue_location_timestamp = ogs_time_now(); + /* Check PLMN-ID access control */ + emm_cause = emm_cause_from_access_control(&mme_ue->tai.plmn_id); + if (emm_cause != OGS_NAS_EMM_CAUSE_REQUEST_ACCEPTED) { + ogs_error("Rejected by PLMN-ID(in TAI) access control"); + r = nas_eps_send_attach_reject(mme_ue, + emm_cause, OGS_NAS_ESM_CAUSE_PROTOCOL_ERROR_UNSPECIFIED); + ogs_expect(r == OGS_OK); + ogs_assert(r != OGS_ERROR); + return OGS_ERROR; + } + emm_cause = emm_cause_from_access_control(&mme_ue->e_cgi.plmn_id); + if (emm_cause != OGS_NAS_EMM_CAUSE_REQUEST_ACCEPTED) { + ogs_error("Rejected by PLMN-ID(in CGI) access control"); + r = nas_eps_send_attach_reject(mme_ue, + emm_cause, OGS_NAS_ESM_CAUSE_PROTOCOL_ERROR_UNSPECIFIED); + ogs_expect(r == OGS_OK); + ogs_assert(r != OGS_ERROR); + return OGS_ERROR; + } + /* Check TAI */ served_tai_index = mme_find_served_tai(&mme_ue->tai); if (served_tai_index < 0) { @@ -504,6 +527,7 @@ int emm_handle_tau_request(mme_ue_t *mme_ue, { int r; int served_tai_index = 0; + uint8_t emm_cause; ogs_nas_eps_mobile_identity_guti_t *eps_mobile_identity_guti = NULL; ogs_nas_eps_guti_t nas_guti; @@ -570,6 +594,24 @@ int emm_handle_tau_request(mme_ue_t *mme_ue, memcpy(&mme_ue->e_cgi, &enb_ue->saved.e_cgi, sizeof(ogs_e_cgi_t)); mme_ue->ue_location_timestamp = ogs_time_now(); + /* Check PLMN-ID access control */ + emm_cause = emm_cause_from_access_control(&mme_ue->tai.plmn_id); + if (emm_cause != OGS_NAS_EMM_CAUSE_REQUEST_ACCEPTED) { + ogs_error("Rejected by PLMN-ID(in TAI) access control"); + r = nas_eps_send_tau_reject(mme_ue, emm_cause); + ogs_expect(r == OGS_OK); + ogs_assert(r != OGS_ERROR); + return OGS_ERROR; + } + emm_cause = emm_cause_from_access_control(&mme_ue->e_cgi.plmn_id); + if (emm_cause != OGS_NAS_EMM_CAUSE_REQUEST_ACCEPTED) { + ogs_error("Rejected by PLMN-ID(in CGI) access control"); + r = nas_eps_send_tau_reject(mme_ue, emm_cause); + ogs_expect(r == OGS_OK); + ogs_assert(r != OGS_ERROR); + return OGS_ERROR; + } + /* Check TAI */ served_tai_index = mme_find_served_tai(&mme_ue->tai); if (served_tai_index < 0) { @@ -644,6 +686,7 @@ int emm_handle_extended_service_request(mme_ue_t *mme_ue, { int r; int served_tai_index = 0; + uint8_t emm_cause; ogs_nas_service_type_t *service_type = &extended_service_request->service_type; @@ -690,6 +733,24 @@ int emm_handle_extended_service_request(mme_ue_t *mme_ue, memcpy(&mme_ue->e_cgi, &enb_ue->saved.e_cgi, sizeof(ogs_e_cgi_t)); mme_ue->ue_location_timestamp = ogs_time_now(); + /* Check PLMN-ID access control */ + emm_cause = emm_cause_from_access_control(&mme_ue->tai.plmn_id); + if (emm_cause != OGS_NAS_EMM_CAUSE_REQUEST_ACCEPTED) { + ogs_error("Rejected by PLMN-ID(in TAI) access control"); + r = nas_eps_send_tau_reject(mme_ue, emm_cause); + ogs_expect(r == OGS_OK); + ogs_assert(r != OGS_ERROR); + return OGS_ERROR; + } + emm_cause = emm_cause_from_access_control(&mme_ue->e_cgi.plmn_id); + if (emm_cause != OGS_NAS_EMM_CAUSE_REQUEST_ACCEPTED) { + ogs_error("Rejected by PLMN-ID(in CGI) access control"); + r = nas_eps_send_tau_reject(mme_ue, emm_cause); + ogs_expect(r == OGS_OK); + ogs_assert(r != OGS_ERROR); + return OGS_ERROR; + } + /* Check TAI */ served_tai_index = mme_find_served_tai(&mme_ue->tai); if (served_tai_index < 0) { @@ -767,3 +828,29 @@ int emm_handle_security_mode_complete(mme_ue_t *mme_ue, return OGS_OK; } + +static uint8_t emm_cause_from_access_control(ogs_plmn_id_t *plmn_id) +{ + int i; + + ogs_assert(plmn_id); + + /* No Access Control */ + if (mme_self()->num_of_access_control == 0) + return OGS_NAS_EMM_CAUSE_REQUEST_ACCEPTED; + + for (i = 0; i < mme_self()->num_of_access_control; i++) { + if (memcmp(&mme_self()->access_control[i].plmn_id, + plmn_id, OGS_PLMN_ID_LEN) == 0) { + if (mme_self()->access_control[i].reject_cause) + return mme_self()->access_control[i].reject_cause; + else + return OGS_NAS_EMM_CAUSE_REQUEST_ACCEPTED; + } + } + + if (mme_self()->default_reject_cause) + return mme_self()->default_reject_cause; + + return OGS_NAS_EMM_CAUSE_PLMN_NOT_ALLOWED; +} diff --git a/src/mme/mme-context.c b/src/mme/mme-context.c index 889fa8b01..9471ad41b 100644 --- a/src/mme/mme-context.c +++ b/src/mme/mme-context.c @@ -626,8 +626,7 @@ int mme_context_parse_config() const char *plmn_id_key = ogs_yaml_iter_key(&plmn_id_iter); ogs_assert(plmn_id_key); - if (!strcmp(plmn_id_key, "mcc")) - { + if (!strcmp(plmn_id_key, "mcc")) { mcc = ogs_yaml_iter_value( &plmn_id_iter); } else if (!strcmp( @@ -910,6 +909,81 @@ int mme_context_parse_config() if (list2->num || num_of_list1 || num_of_list0) { self.num_of_served_tai++; } + } else if (!strcmp(mme_key, "access_control")) { + ogs_yaml_iter_t access_control_array, access_control_iter; + ogs_yaml_iter_recurse(&mme_iter, &access_control_array); + do { + ogs_assert(self.num_of_access_control < + OGS_MAX_NUM_OF_ACCESS_CONTROL); + + if (ogs_yaml_iter_type(&access_control_array) == + YAML_MAPPING_NODE) { + memcpy(&access_control_iter, &access_control_array, + sizeof(ogs_yaml_iter_t)); + } else if (ogs_yaml_iter_type(&access_control_array) == + YAML_SEQUENCE_NODE) { + if (!ogs_yaml_iter_next(&access_control_array)) + break; + ogs_yaml_iter_recurse(&access_control_array, + &access_control_iter); + } else if (ogs_yaml_iter_type(&access_control_array) == + YAML_SCALAR_NODE) { + break; + } else + ogs_assert_if_reached(); + + while (ogs_yaml_iter_next(&access_control_iter)) { + const char *mnc = NULL, *mcc = NULL; + int reject_cause = 0; + const char *access_control_key = + ogs_yaml_iter_key(&access_control_iter); + ogs_assert(access_control_key); + if (!strcmp(access_control_key, + "default_reject_cause")) { + const char *v = ogs_yaml_iter_value( + &access_control_iter); + if (v) self.default_reject_cause = atoi(v); + } else if (!strcmp(access_control_key, "plmn_id")) { + ogs_yaml_iter_t plmn_id_iter; + + ogs_yaml_iter_recurse(&access_control_iter, + &plmn_id_iter); + while (ogs_yaml_iter_next(&plmn_id_iter)) { + const char *plmn_id_key = + ogs_yaml_iter_key(&plmn_id_iter); + ogs_assert(plmn_id_key); + if (!strcmp(plmn_id_key, "reject_cause")) { + const char *v = ogs_yaml_iter_value( + &plmn_id_iter); + if (v) reject_cause = atoi(v); + } else if (!strcmp(plmn_id_key, "mcc")) { + mcc = ogs_yaml_iter_value( + &plmn_id_iter); + } else if (!strcmp(plmn_id_key, "mnc")) { + mnc = ogs_yaml_iter_value( + &plmn_id_iter); + } + } + + if (mcc && mnc) { + ogs_plmn_id_build( + &self.access_control[ + self.num_of_access_control]. + plmn_id, + atoi(mcc), atoi(mnc), strlen(mnc)); + if (reject_cause) + self.access_control[ + self.num_of_access_control]. + reject_cause = reject_cause; + self.num_of_access_control++; + } + } else + ogs_warn("unknown key `%s`", + access_control_key); + } + + } while (ogs_yaml_iter_type(&access_control_array) == + YAML_SEQUENCE_NODE); } else if (!strcmp(mme_key, "security")) { ogs_yaml_iter_t security_iter; ogs_yaml_iter_recurse(&mme_iter, &security_iter); @@ -1002,7 +1076,8 @@ int mme_context_parse_config() } while ( ogs_yaml_iter_type(&ciphering_order_iter) == YAML_SEQUENCE_NODE); - } + } else + ogs_warn("unknown key `%s`", security_key); } } else if (!strcmp(mme_key, "network_name")) { ogs_yaml_iter_t network_name_iter; @@ -1046,7 +1121,8 @@ int mme_context_parse_config() network_short_name->length = size*2+1; network_short_name->coding_scheme = 1; network_short_name->ext = 1; - } + } else + ogs_warn("unknown key `%s`", network_name_key); } } else if (!strcmp(mme_key, "sgsap")) { ogs_yaml_iter_t sgsap_array, sgsap_iter; diff --git a/src/mme/mme-context.h b/src/mme/mme-context.h index 3961dea16..9c705939f 100644 --- a/src/mme/mme-context.h +++ b/src/mme/mme-context.h @@ -109,6 +109,14 @@ typedef struct mme_context_s { ogs_eps_tai2_list_t list2; } served_tai[OGS_MAX_NUM_OF_SERVED_TAI]; + /* Access Control */ + int default_reject_cause; + int num_of_access_control; + struct { + int reject_cause; + ogs_plmn_id_t plmn_id; + } access_control[OGS_MAX_NUM_OF_ACCESS_CONTROL]; + /* defined in 'nas_ies.h' * #define NAS_SECURITY_ALGORITHMS_EIA0 0 * #define NAS_SECURITY_ALGORITHMS_128_EEA1 1