mirror of
https://github.com/open5gs/open5gs.git
synced 2025-10-25 00:53:52 +00:00
[NRF] Implemented PLMN list update handling in nrf_nnrf_handle_nf_update (#3566)
- Added functionality to parse and validate the plmnList JSON array during a PATCH request. - Updated the nf_instance structure with new PLMN data from the request. - Ensured robust error handling for invalid PLMN entries and excessive PLMN counts. - Responded with appropriate HTTP status codes for success and error scenarios.
This commit is contained in:
@@ -1205,6 +1205,35 @@ void ogs_sbi_free_plmn_list(OpenAPI_list_t *PlmnList)
|
|||||||
OpenAPI_list_free(PlmnList);
|
OpenAPI_list_free(PlmnList);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compares an ogs_plmn_id_t structure with an OpenAPI_plmn_id_t structure.
|
||||||
|
*
|
||||||
|
* @param plmn_list The PLMN-ID in ogs_plmn_id_t format.
|
||||||
|
* @param PlmnList The PLMN-ID in OpenAPI_plmn_id_t format.
|
||||||
|
* @return true if the PLMN-IDs are equal; otherwise, false.
|
||||||
|
*/
|
||||||
|
bool ogs_sbi_compare_plmn_list(
|
||||||
|
ogs_plmn_id_t *plmn_id, OpenAPI_plmn_id_t *PlmnId)
|
||||||
|
{
|
||||||
|
ogs_plmn_id_t temp_plmn_id;
|
||||||
|
|
||||||
|
ogs_assert(plmn_id);
|
||||||
|
ogs_assert(PlmnId);
|
||||||
|
ogs_assert(PlmnId->mcc);
|
||||||
|
ogs_assert(PlmnId->mnc);
|
||||||
|
|
||||||
|
/* Convert OpenAPI_plmn_id_t to ogs_plmn_id_t */
|
||||||
|
ogs_sbi_parse_plmn_id(&temp_plmn_id, PlmnId);
|
||||||
|
|
||||||
|
/* Compare MCC and MNC values */
|
||||||
|
if (ogs_plmn_id_mcc(plmn_id) == ogs_plmn_id_mcc(&temp_plmn_id) &&
|
||||||
|
ogs_plmn_id_mnc(plmn_id) == ogs_plmn_id_mnc(&temp_plmn_id)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
OpenAPI_plmn_id_nid_t *ogs_sbi_build_plmn_id_nid(ogs_plmn_id_t *plmn_id)
|
OpenAPI_plmn_id_nid_t *ogs_sbi_build_plmn_id_nid(ogs_plmn_id_t *plmn_id)
|
||||||
{
|
{
|
||||||
OpenAPI_plmn_id_nid_t *PlmnIdNid = NULL;
|
OpenAPI_plmn_id_nid_t *PlmnIdNid = NULL;
|
||||||
|
|||||||
@@ -98,6 +98,8 @@ OpenAPI_list_t *ogs_sbi_build_plmn_list(
|
|||||||
int ogs_sbi_parse_plmn_list(
|
int ogs_sbi_parse_plmn_list(
|
||||||
ogs_plmn_id_t *plmn_list, OpenAPI_list_t *PlmnList);
|
ogs_plmn_id_t *plmn_list, OpenAPI_list_t *PlmnList);
|
||||||
void ogs_sbi_free_plmn_list(OpenAPI_list_t *PlmnList);
|
void ogs_sbi_free_plmn_list(OpenAPI_list_t *PlmnList);
|
||||||
|
bool ogs_sbi_compare_plmn_list(
|
||||||
|
ogs_plmn_id_t *plmn_id, OpenAPI_plmn_id_t *PlmnId);
|
||||||
|
|
||||||
OpenAPI_plmn_id_nid_t *ogs_sbi_build_plmn_id_nid(ogs_plmn_id_t *plmn_id);
|
OpenAPI_plmn_id_nid_t *ogs_sbi_build_plmn_id_nid(ogs_plmn_id_t *plmn_id);
|
||||||
bool ogs_sbi_parse_plmn_id_nid(
|
bool ogs_sbi_parse_plmn_id_nid(
|
||||||
|
|||||||
@@ -150,6 +150,7 @@ extern "C" {
|
|||||||
|
|
||||||
#define OGS_SBI_PATCH_PATH_NF_STATUS "/nfStatus"
|
#define OGS_SBI_PATCH_PATH_NF_STATUS "/nfStatus"
|
||||||
#define OGS_SBI_PATCH_PATH_LOAD "/load"
|
#define OGS_SBI_PATCH_PATH_LOAD "/load"
|
||||||
|
#define OGS_SBI_PATCH_PATH_PLMN_LIST "/plmnList"
|
||||||
#define OGS_SBI_PATCH_PATH_VALIDITY_TIME "/validityTime"
|
#define OGS_SBI_PATCH_PATH_VALIDITY_TIME "/validityTime"
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2019-2023 by Sukchan Lee <acetcom@gmail.com>
|
* Copyright (C) 2019-2024 by Sukchan Lee <acetcom@gmail.com>
|
||||||
*
|
*
|
||||||
* This file is part of Open5GS.
|
* This file is part of Open5GS.
|
||||||
*
|
*
|
||||||
@@ -25,6 +25,15 @@ static int discover_handler(
|
|||||||
static void handle_nf_discover_search_result(
|
static void handle_nf_discover_search_result(
|
||||||
OpenAPI_search_result_t *SearchResult);
|
OpenAPI_search_result_t *SearchResult);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles NF registration in NRF. Validates the PLMN-ID against configured
|
||||||
|
* serving PLMN-IDs and registers the NF instance if valid.
|
||||||
|
*
|
||||||
|
* @param nf_instance The NF instance being registered.
|
||||||
|
* @param stream The SBI stream for communication.
|
||||||
|
* @param recvmsg The received SBI message.
|
||||||
|
* @return true if registration is successful; otherwise, false.
|
||||||
|
*/
|
||||||
bool nrf_nnrf_handle_nf_register(ogs_sbi_nf_instance_t *nf_instance,
|
bool nrf_nnrf_handle_nf_register(ogs_sbi_nf_instance_t *nf_instance,
|
||||||
ogs_sbi_stream_t *stream, ogs_sbi_message_t *recvmsg)
|
ogs_sbi_stream_t *stream, ogs_sbi_message_t *recvmsg)
|
||||||
{
|
{
|
||||||
@@ -33,6 +42,10 @@ bool nrf_nnrf_handle_nf_register(ogs_sbi_nf_instance_t *nf_instance,
|
|||||||
|
|
||||||
OpenAPI_nf_profile_t *NFProfile = NULL;
|
OpenAPI_nf_profile_t *NFProfile = NULL;
|
||||||
|
|
||||||
|
OpenAPI_lnode_t *node = NULL;
|
||||||
|
bool plmn_valid = false;
|
||||||
|
int i;
|
||||||
|
|
||||||
ogs_assert(nf_instance);
|
ogs_assert(nf_instance);
|
||||||
ogs_assert(stream);
|
ogs_assert(stream);
|
||||||
ogs_assert(recvmsg);
|
ogs_assert(recvmsg);
|
||||||
@@ -73,6 +86,41 @@ bool nrf_nnrf_handle_nf_register(ogs_sbi_nf_instance_t *nf_instance,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Validate the PLMN-ID against configured serving PLMN-IDs */
|
||||||
|
if (NFProfile->plmn_list) {
|
||||||
|
/* Set PLMN status to invalid */
|
||||||
|
plmn_valid = false;
|
||||||
|
|
||||||
|
if (ogs_local_conf()->num_of_serving_plmn_id > 0 && NFProfile->plmn_list) {
|
||||||
|
OpenAPI_list_for_each(NFProfile->plmn_list, node) {
|
||||||
|
OpenAPI_plmn_id_t *PlmnId = node->data;
|
||||||
|
if (PlmnId == NULL) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
for (i = 0; i < ogs_local_conf()->num_of_serving_plmn_id; i++) {
|
||||||
|
if (ogs_sbi_compare_plmn_list(
|
||||||
|
&ogs_local_conf()->serving_plmn_id[i],
|
||||||
|
PlmnId) == true) {
|
||||||
|
plmn_valid = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (plmn_valid) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Reject the registration if PLMN-ID is invalid */
|
||||||
|
if (!plmn_valid) {
|
||||||
|
ogs_error("PLMN-ID in NFProfile is not allowed");
|
||||||
|
ogs_assert(true == ogs_sbi_server_send_error(
|
||||||
|
stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST, recvmsg,
|
||||||
|
"PLMN-ID not allowed", NULL, NULL));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ogs_nnrf_nfm_handle_nf_profile(nf_instance, NFProfile);
|
ogs_nnrf_nfm_handle_nf_profile(nf_instance, NFProfile);
|
||||||
|
|
||||||
ogs_sbi_client_associate(nf_instance);
|
ogs_sbi_client_associate(nf_instance);
|
||||||
@@ -146,7 +194,6 @@ bool nrf_nnrf_handle_nf_register(ogs_sbi_nf_instance_t *nf_instance,
|
|||||||
if (ogs_local_conf()->num_of_serving_plmn_id &&
|
if (ogs_local_conf()->num_of_serving_plmn_id &&
|
||||||
NFProfile->plmn_list == NULL) {
|
NFProfile->plmn_list == NULL) {
|
||||||
OpenAPI_list_t *PlmnIdList = NULL;
|
OpenAPI_list_t *PlmnIdList = NULL;
|
||||||
int i;
|
|
||||||
|
|
||||||
PlmnIdList = OpenAPI_list_create();
|
PlmnIdList = OpenAPI_list_create();
|
||||||
ogs_assert(PlmnIdList);
|
ogs_assert(PlmnIdList);
|
||||||
@@ -208,6 +255,10 @@ bool nrf_nnrf_handle_nf_update(ogs_sbi_nf_instance_t *nf_instance,
|
|||||||
ogs_assert(stream);
|
ogs_assert(stream);
|
||||||
ogs_assert(recvmsg);
|
ogs_assert(recvmsg);
|
||||||
|
|
||||||
|
cJSON *plmn_array = NULL, *plmn_item = NULL;
|
||||||
|
bool plmn_valid = false;
|
||||||
|
int i;
|
||||||
|
|
||||||
SWITCH(recvmsg->h.method)
|
SWITCH(recvmsg->h.method)
|
||||||
CASE(OGS_SBI_HTTP_METHOD_PUT)
|
CASE(OGS_SBI_HTTP_METHOD_PUT)
|
||||||
return nrf_nnrf_handle_nf_register(
|
return nrf_nnrf_handle_nf_register(
|
||||||
@@ -224,14 +275,14 @@ bool nrf_nnrf_handle_nf_update(ogs_sbi_nf_instance_t *nf_instance,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Iterate through the PatchItemList */
|
||||||
OpenAPI_list_for_each(PatchItemList, node) {
|
OpenAPI_list_for_each(PatchItemList, node) {
|
||||||
OpenAPI_patch_item_t *patch_item = node->data;
|
OpenAPI_patch_item_t *patch_item = node->data;
|
||||||
if (!patch_item) {
|
if (!patch_item) {
|
||||||
ogs_error("No PatchItem");
|
ogs_error("No PatchItem");
|
||||||
ogs_assert(true ==
|
ogs_assert(true == ogs_sbi_server_send_error(
|
||||||
ogs_sbi_server_send_error(stream,
|
stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST, recvmsg,
|
||||||
OGS_SBI_HTTP_STATUS_BAD_REQUEST,
|
"No PatchItem", NULL, NULL));
|
||||||
recvmsg, "No PatchItem", NULL, NULL));
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -246,6 +297,102 @@ bool nrf_nnrf_handle_nf_update(ogs_sbi_nf_instance_t *nf_instance,
|
|||||||
break;
|
break;
|
||||||
CASE(OGS_SBI_PATCH_PATH_LOAD)
|
CASE(OGS_SBI_PATCH_PATH_LOAD)
|
||||||
break;
|
break;
|
||||||
|
CASE(OGS_SBI_PATCH_PATH_PLMN_LIST)
|
||||||
|
/* Ensure the value is not null and is a valid JSON array */
|
||||||
|
if (patch_item->value && patch_item->value->json) {
|
||||||
|
/* Set PLMN status to invalid */
|
||||||
|
plmn_valid = false;
|
||||||
|
|
||||||
|
plmn_array = patch_item->value->json;
|
||||||
|
if (!cJSON_IsArray(plmn_array)) {
|
||||||
|
ogs_error("Value for /plmnList is not a JSON array");
|
||||||
|
ogs_assert(true == ogs_sbi_server_send_error(
|
||||||
|
stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST, recvmsg,
|
||||||
|
"Invalid value for /plmnList", NULL, NULL));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Clear existing PLMN data in nf_instance */
|
||||||
|
memset(nf_instance->plmn_id, 0,
|
||||||
|
sizeof(nf_instance->plmn_id));
|
||||||
|
nf_instance->num_of_plmn_id = 0;
|
||||||
|
|
||||||
|
/* Iterate through the JSON array of PLMN IDs */
|
||||||
|
cJSON_ArrayForEach(plmn_item, plmn_array) {
|
||||||
|
OpenAPI_plmn_id_t plmn_id;
|
||||||
|
memset(&plmn_id, 0, sizeof(plmn_id));
|
||||||
|
|
||||||
|
if (nf_instance->num_of_plmn_id >=
|
||||||
|
OGS_ARRAY_SIZE(nf_instance->plmn_id)) {
|
||||||
|
ogs_error("Exceeded maximum number of PLMN IDs");
|
||||||
|
ogs_assert(true == ogs_sbi_server_send_error(
|
||||||
|
stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST,
|
||||||
|
recvmsg,
|
||||||
|
"Too many PLMN IDs", NULL, NULL));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Parse the PLMN item */
|
||||||
|
plmn_id.mcc = cJSON_GetObjectItem(plmn_item, "mcc")
|
||||||
|
? cJSON_GetStringValue(
|
||||||
|
cJSON_GetObjectItem(
|
||||||
|
plmn_item, "mcc"))
|
||||||
|
: NULL;
|
||||||
|
plmn_id.mnc = cJSON_GetObjectItem(plmn_item, "mnc")
|
||||||
|
? cJSON_GetStringValue(
|
||||||
|
cJSON_GetObjectItem(
|
||||||
|
plmn_item, "mnc"))
|
||||||
|
: NULL;
|
||||||
|
|
||||||
|
if (!plmn_id.mcc || !plmn_id.mnc) {
|
||||||
|
ogs_error(
|
||||||
|
"Invalid PLMN item in /plmnList update");
|
||||||
|
ogs_assert(true ==
|
||||||
|
ogs_sbi_server_send_error(
|
||||||
|
stream,
|
||||||
|
OGS_SBI_HTTP_STATUS_BAD_REQUEST,
|
||||||
|
recvmsg,
|
||||||
|
"Invalid PLMN item", NULL,
|
||||||
|
NULL));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Convert OpenAPI_plmn_id_t to ogs_plmn_id_t
|
||||||
|
* and store in nf_instance
|
||||||
|
*/
|
||||||
|
ogs_sbi_parse_plmn_id(
|
||||||
|
&nf_instance->
|
||||||
|
plmn_id[nf_instance->num_of_plmn_id],
|
||||||
|
&plmn_id);
|
||||||
|
nf_instance->num_of_plmn_id++;
|
||||||
|
|
||||||
|
/* Compare with the serving PLMN list */
|
||||||
|
for (i = 0;
|
||||||
|
i < ogs_local_conf()->num_of_serving_plmn_id;
|
||||||
|
i++) {
|
||||||
|
if (ogs_sbi_compare_plmn_list(
|
||||||
|
&ogs_local_conf()->serving_plmn_id[i],
|
||||||
|
&plmn_id) == true) {
|
||||||
|
plmn_valid = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (plmn_valid) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Reject the update if PLMN-ID is invalid */
|
||||||
|
if (!plmn_valid) {
|
||||||
|
ogs_error("PLMN-ID in NFProfile update is not allowed");
|
||||||
|
ogs_assert(true == ogs_sbi_server_send_error(
|
||||||
|
stream, OGS_SBI_HTTP_STATUS_BAD_REQUEST, recvmsg,
|
||||||
|
"PLMN-ID not allowed", NULL, NULL));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
DEFAULT
|
DEFAULT
|
||||||
ogs_error("Unknown PatchItem.Path [%s]", patch_item->path);
|
ogs_error("Unknown PatchItem.Path [%s]", patch_item->path);
|
||||||
END
|
END
|
||||||
|
|||||||
Reference in New Issue
Block a user