forked from acouzens/open5gs
[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
This commit is contained in:
parent
5f37777280
commit
d469809192
|
@ -417,6 +417,41 @@ sbi:
|
|||
# s_nssai:
|
||||
# - sst: 1
|
||||
#
|
||||
#
|
||||
# <Access Control>
|
||||
#
|
||||
# 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
|
||||
#
|
||||
#
|
||||
# <Network Name>
|
||||
#
|
||||
# amf:
|
||||
|
|
|
@ -269,6 +269,41 @@ logger:
|
|||
# mnc: 09
|
||||
# tac: [70, 80]
|
||||
#
|
||||
#
|
||||
# <Access Control>
|
||||
#
|
||||
# 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
|
||||
#
|
||||
#
|
||||
# <Network Name>
|
||||
# mme:
|
||||
# network_name:
|
||||
|
|
|
@ -125,30 +125,6 @@ smf:
|
|||
- identity: pcrf.localdomain
|
||||
addr: 127.0.0.9
|
||||
|
||||
#
|
||||
# <For Indirect Communication with Delegated Discovery>
|
||||
#
|
||||
# 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
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2019-2022 by Sukchan Lee <acetcom@gmail.com>
|
||||
* Copyright (C) 2019-2023 by Sukchan Lee <acetcom@gmail.com>
|
||||
*
|
||||
* 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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2019,2020 by Sukchan Lee <acetcom@gmail.com>
|
||||
* Copyright (C) 2019-2023 by Sukchan Lee <acetcom@gmail.com>
|
||||
*
|
||||
* 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;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2019 by Sukchan Lee <acetcom@gmail.com>
|
||||
* Copyright (C) 2019-2023 by Sukchan Lee <acetcom@gmail.com>
|
||||
*
|
||||
* 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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue