[SMF] Send PDU Session Establish Accept to serving AMF

In case there are multiple AMF registered to NRF, SMF would pick only
the first AMF from the list.
In the case of sending PDU Session Establishment Accept from SMF to
AMF, this would mean a high chance of failure since the AMF might
be different than the original requester, and would not know about a
particular UE.

Modify SMF to use ServingNfId field from original request
SmContextCreateData from AMF to determine to which AMF should it send
PDU Session Establishment Accept message.
This commit is contained in:
Bostjan Meglic 2022-07-20 12:01:52 +00:00 committed by Sukchan Lee
parent 9a958d7af8
commit 7e6568d800
7 changed files with 113 additions and 7 deletions

View File

@ -1658,6 +1658,8 @@ void smf_sess_remove(smf_sess_t *sess)
if (sess->pcf_id)
ogs_free(sess->pcf_id);
if (sess->serving_nf_id)
ogs_free(sess->serving_nf_id);
/* Free SBI object memory */
ogs_sbi_object_free(&sess->sbi);

View File

@ -300,6 +300,9 @@ typedef struct smf_sess_s {
/* PCF ID */
char *pcf_id;
/* Serving NF (AMF) Id */
char *serving_nf_id;
/* Integrity protection maximum data rate */
struct {
uint8_t mbr_dl;

View File

@ -346,3 +346,76 @@ void smf_nnrf_handle_nf_discover(
ogs_assert(true == smf_sbi_send(nf_instance, xact));
}
}
void smf_nnrf_handle_nf_profile_retrieve(
ogs_sbi_xact_t *xact, ogs_sbi_message_t *recvmsg)
{
ogs_sbi_object_t *sbi_object = NULL;
ogs_sbi_nf_instance_t *nf_instance = NULL;
OpenAPI_nf_profile_t *NFProfile = NULL;
bool handled;
ogs_assert(xact);
sbi_object = xact->sbi_object;
ogs_assert(sbi_object);
ogs_assert(recvmsg);
NFProfile = recvmsg->NFProfile;
if (!NFProfile) {
ogs_error("No NFProfile");
return;
}
nf_instance = ogs_sbi_nf_instance_find(NFProfile->nf_instance_id);
if (!nf_instance) {
nf_instance = ogs_sbi_nf_instance_add();
ogs_assert(nf_instance);
ogs_sbi_nf_instance_set_id(nf_instance, NFProfile->nf_instance_id);
smf_nf_fsm_init(nf_instance);
ogs_info("[%s] (NF-discover) NF registered", nf_instance->id);
} else {
nf_instance->reference_count++;
OGS_FSM_TRAN(&nf_instance->sm, smf_nf_state_registered);
ogs_fsm_dispatch(&nf_instance->sm, NULL);
ogs_warn("[%s] (NF-discover) NF has already been added",
NFProfile->nf_instance_id);
}
if (NF_INSTANCE_IS_OTHERS(nf_instance->id)) {
smf_sess_t *sess = NULL;
handled = ogs_sbi_nnrf_handle_nf_profile(
nf_instance, NFProfile, NULL, NULL);
if (!handled) {
ogs_error("ogs_sbi_nnrf_handle_nf_profile() failed [%s]",
nf_instance->id);
SMF_NF_INSTANCE_CLEAR("NRF-discover", nf_instance);
return;
}
handled = ogs_sbi_client_associate(nf_instance);
if (!handled) {
ogs_error("[%s] Cannot assciate NF EndPoint", nf_instance->id);
SMF_NF_INSTANCE_CLEAR("NRF-discover", nf_instance);
return;
}
sess = (smf_sess_t *)sbi_object;
ogs_assert(sess);
smf_sess_select_nf(sess, nf_instance->nf_type);
ogs_info("[%s] (NF-discover) NF Profile updated", nf_instance->id);
}
if (!nf_instance) {
ogs_error("(NF discover) No [%s]",
OpenAPI_nf_type_ToString(xact->target_nf_type));
} else {
ogs_assert(true == smf_sbi_send(nf_instance, xact));
}
}

View File

@ -36,6 +36,8 @@ bool smf_nnrf_handle_nf_status_notify(
void smf_nnrf_handle_nf_discover(
ogs_sbi_xact_t *xact, ogs_sbi_message_t *recvmsg);
void smf_nnrf_handle_nf_profile_retrieve(
ogs_sbi_xact_t *xact, ogs_sbi_message_t *recvmsg);
#ifdef __cplusplus
}

View File

@ -197,6 +197,12 @@ bool smf_nsmf_handle_create_sm_context(
ogs_assert(sess->pcf_id);
}
if (SmContextCreateData->serving_nf_id) {
if (sess->serving_nf_id) ogs_free(sess->serving_nf_id);
sess->serving_nf_id = ogs_strdup(SmContextCreateData->serving_nf_id);
ogs_assert(sess->serving_nf_id);
}
/*
* NOTE : The pkbuf created in the SBI message will be removed
* from ogs_sbi_message_free().

View File

@ -200,8 +200,13 @@ void smf_namf_comm_send_n1_n2_message_transfer(
xact->state = param->state;
ogs_sbi_discover_and_send(xact,
(ogs_fsm_handler_t)smf_nf_state_registered, client_cb);
if (ogs_sbi_discover_by_nf_instanceid_and_send(xact,
(ogs_fsm_handler_t)smf_nf_state_registered, client_cb,
sess->serving_nf_id) != true)
{
ogs_error("smf_namf_comm_send_n1_n2_message_transfer() failed");
ogs_sbi_xact_remove(xact);
}
}
void smf_sbi_send_sm_context_create_error(

View File

@ -658,12 +658,27 @@ void smf_state_operational(ogs_fsm_t *s, smf_event_t *e)
SWITCH(sbi_message.h.resource.component[0])
CASE(OGS_SBI_RESOURCE_NAME_NF_INSTANCES)
nf_instance = e->sbi.data;
ogs_assert(nf_instance);
ogs_assert(OGS_FSM_STATE(&nf_instance->sm));
e->sbi.message = &sbi_message;
ogs_fsm_dispatch(&nf_instance->sm, e);
SWITCH(sbi_message.h.method)
CASE(OGS_SBI_HTTP_METHOD_GET)
sbi_xact = e->sbi.data;
ogs_assert(sbi_xact);
if (sbi_message.res_status == OGS_SBI_HTTP_STATUS_OK)
smf_nnrf_handle_nf_profile_retrieve(
sbi_xact, &sbi_message);
else
ogs_error("HTTP response error [%d]",
sbi_message.res_status);
break;
DEFAULT
nf_instance = e->sbi.data;
ogs_assert(nf_instance);
ogs_assert(OGS_FSM_STATE(&nf_instance->sm));
e->sbi.message = &sbi_message;
ogs_fsm_dispatch(&nf_instance->sm, e);
END
break;
CASE(OGS_SBI_RESOURCE_NAME_SUBSCRIPTIONS)