From b56c33479eefd01704bb02f17341d3010e788093 Mon Sep 17 00:00:00 2001 From: Gaber Stare Date: Mon, 12 Dec 2022 10:41:08 +0000 Subject: [PATCH] Add NF load to NRF Heartbeat The current load percentage of the NF Service Consumer is provided in the payload body of the PATCH request when periodically contacting the NRF (heart-beat). AMF: ratio between currently connected ran_ue and maximum number of them SMF: ratio between current PDU sessions and maximum available PCF: ratio between current AM+SM policy associations and maximum available or ratio between currently connected UEs and maximum number of them (the load which is higher) AUSF, UDM: ratio between currently connected UE and maximum number of them BSF: ratio between current sessions and maximum available NSSF: ratio between currently used NSIs and maximum number of them NRF currently doesn't determine that the NF Profile has changed. --- lib/sbi/nnrf-build.c | 31 ++++++++++++++++++++++--------- src/amf/amf-sm.c | 2 ++ src/amf/context.c | 7 +++++++ src/amf/context.h | 1 + src/ausf/ausf-sm.c | 2 ++ src/ausf/context.c | 7 +++++++ src/ausf/context.h | 1 + src/bsf/bsf-sm.c | 2 ++ src/bsf/context.c | 7 +++++++ src/bsf/context.h | 1 + src/nssf/context.c | 7 +++++++ src/nssf/context.h | 1 + src/nssf/nssf-sm.c | 2 ++ src/pcf/context.c | 15 +++++++++++++++ src/pcf/context.h | 1 + src/pcf/pcf-sm.c | 2 ++ src/smf/context.c | 7 +++++++ src/smf/context.h | 1 + src/smf/smf-sm.c | 2 ++ src/udm/context.c | 7 +++++++ src/udm/context.h | 1 + src/udm/udm-sm.c | 2 ++ 22 files changed, 100 insertions(+), 9 deletions(-) diff --git a/lib/sbi/nnrf-build.c b/lib/sbi/nnrf-build.c index 4b218576c..951f673d6 100644 --- a/lib/sbi/nnrf-build.c +++ b/lib/sbi/nnrf-build.c @@ -1217,7 +1217,8 @@ ogs_sbi_request_t *ogs_nnrf_nfm_build_update(void) ogs_sbi_request_t *request = NULL; OpenAPI_list_t *PatchItemList; - OpenAPI_patch_item_t item; + OpenAPI_patch_item_t StatusItem; + OpenAPI_patch_item_t LoadItem; nf_instance = ogs_sbi_self()->nf_instance; ogs_assert(nf_instance); @@ -1239,17 +1240,28 @@ ogs_sbi_request_t *ogs_nnrf_nfm_build_update(void) goto end; } - memset(&item, 0, sizeof(item)); - item.op = OpenAPI_patch_operation_replace; - item.path = (char *)"/nfStatus"; - item.value = OpenAPI_any_type_create_string( + memset(&StatusItem, 0, sizeof(StatusItem)); + StatusItem.op = OpenAPI_patch_operation_replace; + StatusItem.path = (char *)"/nfStatus"; + StatusItem.value = OpenAPI_any_type_create_string( OpenAPI_nf_status_ToString(OpenAPI_nf_status_REGISTERED)); - if (!item.value) { - ogs_error("No item.value"); + if (!StatusItem.value) { + ogs_error("No status item.value"); goto end; } - OpenAPI_list_add(PatchItemList, &item); + OpenAPI_list_add(PatchItemList, &StatusItem); + + memset(&LoadItem, 0, sizeof(LoadItem)); + LoadItem.op = OpenAPI_patch_operation_replace; + LoadItem.path = (char *)"/load"; + LoadItem.value = OpenAPI_any_type_create_number(ogs_sbi_self()->nf_instance->load); + if (!LoadItem.value) { + ogs_error("No load item.value"); + goto end; + } + + OpenAPI_list_add(PatchItemList, &LoadItem); message.PatchItemList = PatchItemList; @@ -1258,7 +1270,8 @@ ogs_sbi_request_t *ogs_nnrf_nfm_build_update(void) end: OpenAPI_list_free(PatchItemList); - OpenAPI_any_type_free(item.value); + OpenAPI_any_type_free(StatusItem.value); + OpenAPI_any_type_free(LoadItem.value); return request; } diff --git a/src/amf/amf-sm.c b/src/amf/amf-sm.c index 57c455c48..83f447863 100644 --- a/src/amf/amf-sm.c +++ b/src/amf/amf-sm.c @@ -567,6 +567,8 @@ void amf_state_operational(ogs_fsm_t *s, amf_event_t *e) ogs_assert(nf_instance); ogs_assert(OGS_FSM_STATE(&nf_instance->sm)); + ogs_sbi_self()->nf_instance->load = get_ran_ue_load(); + ogs_fsm_dispatch(&nf_instance->sm, e); if (OGS_FSM_CHECK(&nf_instance->sm, ogs_sbi_nf_state_exception)) ogs_error("[%s:%s] State machine exception [%d]", diff --git a/src/amf/context.c b/src/amf/context.c index 4e579f0bd..6aaa4520a 100644 --- a/src/amf/context.c +++ b/src/amf/context.c @@ -2313,6 +2313,13 @@ static void stats_remove_ran_ue(void) ogs_info("[Removed] Number of gNB-UEs is now %d", num_of_ran_ue); } +int get_ran_ue_load() +{ + return (((ogs_pool_size(&ran_ue_pool) - + ogs_pool_avail(&ran_ue_pool)) * 100) / + ogs_pool_size(&ran_ue_pool)); +} + static void stats_add_amf_session(void) { amf_metrics_inst_global_inc(AMF_METR_GLOB_GAUGE_AMF_SESS); diff --git a/src/amf/context.h b/src/amf/context.h index 476377390..f18c05b5a 100644 --- a/src/amf/context.h +++ b/src/amf/context.h @@ -793,6 +793,7 @@ void amf_clear_subscribed_info(amf_ue_t *amf_ue); bool amf_update_allowed_nssai(amf_ue_t *amf_ue); bool amf_ue_is_rat_restricted(amf_ue_t *amf_ue); +int get_ran_ue_load(void); #ifdef __cplusplus } diff --git a/src/ausf/ausf-sm.c b/src/ausf/ausf-sm.c index db60a23fc..81efab228 100644 --- a/src/ausf/ausf-sm.c +++ b/src/ausf/ausf-sm.c @@ -332,6 +332,8 @@ void ausf_state_operational(ogs_fsm_t *s, ausf_event_t *e) ogs_assert(nf_instance); ogs_assert(OGS_FSM_STATE(&nf_instance->sm)); + ogs_sbi_self()->nf_instance->load = get_ue_load(); + ogs_fsm_dispatch(&nf_instance->sm, e); if (OGS_FSM_CHECK(&nf_instance->sm, ogs_sbi_nf_state_exception)) ogs_error("[%s:%s] State machine exception [%d]", diff --git a/src/ausf/context.c b/src/ausf/context.c index 153e327e1..c925d0fc0 100644 --- a/src/ausf/context.c +++ b/src/ausf/context.c @@ -224,3 +224,10 @@ ausf_ue_t *ausf_ue_cycle(ausf_ue_t *ausf_ue) { return ogs_pool_cycle(&ausf_ue_pool, ausf_ue); } + +int get_ue_load() +{ + return (((ogs_pool_size(&ausf_ue_pool) - + ogs_pool_avail(&ausf_ue_pool)) * 100) / + ogs_pool_size(&ausf_ue_pool)); +} diff --git a/src/ausf/context.h b/src/ausf/context.h index cb38789c7..6da3a06c3 100644 --- a/src/ausf/context.h +++ b/src/ausf/context.h @@ -77,6 +77,7 @@ ausf_ue_t *ausf_ue_find_by_suci_or_supi(char *suci_or_supi); ausf_ue_t *ausf_ue_find_by_ctx_id(char *ctx_id); ausf_ue_t *ausf_ue_cycle(ausf_ue_t *ausf_ue); +int get_ue_load(void); #ifdef __cplusplus } diff --git a/src/bsf/bsf-sm.c b/src/bsf/bsf-sm.c index 60a4843dd..9689a11cb 100644 --- a/src/bsf/bsf-sm.c +++ b/src/bsf/bsf-sm.c @@ -316,6 +316,8 @@ void bsf_state_operational(ogs_fsm_t *s, bsf_event_t *e) ogs_assert(nf_instance); ogs_assert(OGS_FSM_STATE(&nf_instance->sm)); + ogs_sbi_self()->nf_instance->load = get_sess_load(); + ogs_fsm_dispatch(&nf_instance->sm, e); if (OGS_FSM_CHECK(&nf_instance->sm, ogs_sbi_nf_state_exception)) ogs_error("[%s:%s] State machine exception [%d]", diff --git a/src/bsf/context.c b/src/bsf/context.c index 3fd57a9f4..8add69993 100644 --- a/src/bsf/context.c +++ b/src/bsf/context.c @@ -322,3 +322,10 @@ bsf_sess_t *bsf_sess_find_by_ipv6prefix(char *ipv6prefix_string) return ogs_hash_get(self.ipv6prefix_hash, &ipv6prefix, (ipv6prefix.len >> 3) + 1); } + +int get_sess_load() +{ + return (((ogs_pool_size(&bsf_sess_pool) - + ogs_pool_avail(&bsf_sess_pool)) * 100) / + ogs_pool_size(&bsf_sess_pool)); +} diff --git a/src/bsf/context.h b/src/bsf/context.h index 963b5ddbb..a7de9b001 100644 --- a/src/bsf/context.h +++ b/src/bsf/context.h @@ -95,6 +95,7 @@ bsf_sess_t *bsf_sess_find_by_snssai_and_dnn(ogs_s_nssai_t *s_nssai, char *dnn); bsf_sess_t *bsf_sess_find_by_binding_id(char *binding_id); bsf_sess_t *bsf_sess_find_by_ipv4addr(char *ipv4addr_string); bsf_sess_t *bsf_sess_find_by_ipv6prefix(char *ipv6prefix_string); +int get_sess_load(void); #ifdef __cplusplus } diff --git a/src/nssf/context.c b/src/nssf/context.c index 5e16df74c..084410608 100644 --- a/src/nssf/context.c +++ b/src/nssf/context.c @@ -346,3 +346,10 @@ char *nssf_nsi_nrf_uri(nssf_nsi_t *nsi) return ogs_uridup(ogs_app_tls_server_enabled() == true, nsi->addr, &h); } + +int get_nsi_load() +{ + return (((ogs_pool_size(&nssf_nsi_pool) - + ogs_pool_avail(&nssf_nsi_pool)) * 100) / + ogs_pool_size(&nssf_nsi_pool)); +} diff --git a/src/nssf/context.h b/src/nssf/context.h index a1d90d62b..45457cdbf 100644 --- a/src/nssf/context.h +++ b/src/nssf/context.h @@ -60,6 +60,7 @@ void nssf_nsi_remove_all(void); nssf_nsi_t *nssf_nsi_find_by_s_nssai(ogs_s_nssai_t *s_nssai); char *nssf_nsi_nrf_uri(nssf_nsi_t *nsi); +int get_nsi_load(void); #ifdef __cplusplus } diff --git a/src/nssf/nssf-sm.c b/src/nssf/nssf-sm.c index 0d997c82f..81a05aef3 100644 --- a/src/nssf/nssf-sm.c +++ b/src/nssf/nssf-sm.c @@ -232,6 +232,8 @@ void nssf_state_operational(ogs_fsm_t *s, nssf_event_t *e) ogs_assert(nf_instance); ogs_assert(OGS_FSM_STATE(&nf_instance->sm)); + ogs_sbi_self()->nf_instance->load = get_nsi_load(); + ogs_fsm_dispatch(&nf_instance->sm, e); if (OGS_FSM_CHECK(&nf_instance->sm, ogs_sbi_nf_state_exception)) ogs_error("[%s:%s] State machine exception [%d]", diff --git a/src/pcf/context.c b/src/pcf/context.c index c65a80e12..3efcc13ce 100644 --- a/src/pcf/context.c +++ b/src/pcf/context.c @@ -572,3 +572,18 @@ pcf_app_t *pcf_app_find_by_app_session_id(char *app_session_id) ogs_assert(app_session_id); return pcf_app_find(atoll(app_session_id)); } + +int get_pcf_load() +{ + if (ogs_pool_avail(&pcf_ue_pool) / ogs_pool_size(&pcf_ue_pool) < + ogs_pool_avail(&pcf_sess_pool) / + ogs_pool_avail(&pcf_sess_pool)) { + return (((ogs_pool_size(&pcf_ue_pool) - + ogs_pool_avail(&pcf_ue_pool)) * 100) / + ogs_pool_size(&pcf_ue_pool)); + } else { + return (((ogs_pool_size(&pcf_sess_pool) - + ogs_pool_avail(&pcf_sess_pool)) * 100) / + ogs_pool_size(&pcf_sess_pool)); + } +} diff --git a/src/pcf/context.h b/src/pcf/context.h index 7ac41e27f..cc92a0c40 100644 --- a/src/pcf/context.h +++ b/src/pcf/context.h @@ -171,6 +171,7 @@ int pcf_app_remove(pcf_app_t *app); void pcf_app_remove_all(pcf_sess_t *sess); pcf_app_t *pcf_app_find(uint32_t index); pcf_app_t *pcf_app_find_by_app_session_id(char *app_session_id); +int get_pcf_load(void); #ifdef __cplusplus } diff --git a/src/pcf/pcf-sm.c b/src/pcf/pcf-sm.c index 8586baa58..7ed547e07 100644 --- a/src/pcf/pcf-sm.c +++ b/src/pcf/pcf-sm.c @@ -562,6 +562,8 @@ void pcf_state_operational(ogs_fsm_t *s, pcf_event_t *e) ogs_assert(nf_instance); ogs_assert(OGS_FSM_STATE(&nf_instance->sm)); + ogs_sbi_self()->nf_instance->load = get_pcf_load(); + ogs_fsm_dispatch(&nf_instance->sm, e); if (OGS_FSM_CHECK(&nf_instance->sm, ogs_sbi_nf_state_exception)) ogs_error("[%s:%s] State machine exception [%d]", diff --git a/src/smf/context.c b/src/smf/context.c index 60bd34e32..f6d99426f 100644 --- a/src/smf/context.c +++ b/src/smf/context.c @@ -3103,6 +3103,13 @@ static void stats_remove_smf_session(smf_sess_t *sess) ogs_info("[Removed] Number of SMF-Sessions is now %d", num_of_smf_sess); } +int get_sess_load() +{ + return (((ogs_pool_size(&smf_sess_pool) - + ogs_pool_avail(&smf_sess_pool)) * 100) / + ogs_pool_size(&smf_sess_pool)); +} + int smf_integrity_protection_indication_value2enum(const char *value) { ogs_assert(value); diff --git a/src/smf/context.h b/src/smf/context.h index c74269bc6..2256c093e 100644 --- a/src/smf/context.h +++ b/src/smf/context.h @@ -525,6 +525,7 @@ int smf_maximum_integrity_protected_data_rate_uplink_value2enum( const char *value); int smf_maximum_integrity_protected_data_rate_downlink_value2enum( const char *value); +int get_sess_load(void); #ifdef __cplusplus } diff --git a/src/smf/smf-sm.c b/src/smf/smf-sm.c index 54638ab53..3b0258320 100644 --- a/src/smf/smf-sm.c +++ b/src/smf/smf-sm.c @@ -806,6 +806,8 @@ void smf_state_operational(ogs_fsm_t *s, smf_event_t *e) ogs_assert(nf_instance); ogs_assert(OGS_FSM_STATE(&nf_instance->sm)); + ogs_sbi_self()->nf_instance->load = get_sess_load(); + ogs_fsm_dispatch(&nf_instance->sm, e); if (OGS_FSM_CHECK(&nf_instance->sm, ogs_sbi_nf_state_exception)) ogs_error("[%s:%s] State machine exception [%d]", diff --git a/src/udm/context.c b/src/udm/context.c index 6707c4bd9..7b9dcf62e 100644 --- a/src/udm/context.c +++ b/src/udm/context.c @@ -233,3 +233,10 @@ udm_ue_t *udm_ue_cycle(udm_ue_t *udm_ue) { return ogs_pool_cycle(&udm_ue_pool, udm_ue); } + +int get_ue_load() +{ + return (((ogs_pool_size(&udm_ue_pool) - + ogs_pool_avail(&udm_ue_pool)) * 100) / + ogs_pool_size(&udm_ue_pool)); +} diff --git a/src/udm/context.h b/src/udm/context.h index 96ee2b858..451971f62 100644 --- a/src/udm/context.h +++ b/src/udm/context.h @@ -87,6 +87,7 @@ udm_ue_t *udm_ue_find_by_suci_or_supi(char *suci_or_supi); udm_ue_t *udm_ue_find_by_ctx_id(char *ctx_id); udm_ue_t *udm_ue_cycle(udm_ue_t *udm_ue); +int get_ue_load(void); #ifdef __cplusplus } diff --git a/src/udm/udm-sm.c b/src/udm/udm-sm.c index a73cba26c..371e21db7 100644 --- a/src/udm/udm-sm.c +++ b/src/udm/udm-sm.c @@ -373,6 +373,8 @@ void udm_state_operational(ogs_fsm_t *s, udm_event_t *e) ogs_assert(nf_instance); ogs_assert(OGS_FSM_STATE(&nf_instance->sm)); + ogs_sbi_self()->nf_instance->load = get_ue_load(); + ogs_fsm_dispatch(&nf_instance->sm, e); if (OGS_FSM_CHECK(&nf_instance->sm, ogs_sbi_nf_state_exception)) ogs_error("[%s:%s] State machine exception [%d]",