From af07cc75ec0d1b245d4620c69d3a20ea01f57cf2 Mon Sep 17 00:00:00 2001 From: Flander Bojan Date: Wed, 1 Feb 2023 08:28:57 +0000 Subject: [PATCH] Support for UPF HA - release/establish new PDU session --- src/amf/namf-handler.c | 5 +---- src/smf/context.h | 1 + src/smf/gsm-sm.c | 33 ++++++++++++++++++++++++++++++--- src/smf/pfcp-sm.c | 25 +++++++++++++++++++++++++ 4 files changed, 57 insertions(+), 7 deletions(-) diff --git a/src/amf/namf-handler.c b/src/amf/namf-handler.c index 36ed9089a..1b062e48d 100644 --- a/src/amf/namf-handler.c +++ b/src/amf/namf-handler.c @@ -377,9 +377,6 @@ int amf_namf_comm_handle_n1_n2_message_transfer( return OGS_ERROR; } - if (n1buf) - ogs_pkbuf_free(n1buf); - if (CM_IDLE(amf_ue)) { if (n2buf) ogs_pkbuf_free(n2buf); @@ -394,7 +391,7 @@ int amf_namf_comm_handle_n1_n2_message_transfer( } } else if (CM_CONNECTED(amf_ue)) { - r = nas_send_pdu_session_release_command(sess, NULL, n2buf); + r = nas_send_pdu_session_release_command(sess, n1buf, n2buf); ogs_expect(r == OGS_OK); ogs_assert(r != OGS_ERROR); } else { diff --git a/src/smf/context.h b/src/smf/context.h index 95143c519..9fbd98b8e 100644 --- a/src/smf/context.h +++ b/src/smf/context.h @@ -371,6 +371,7 @@ typedef struct smf_sess_s { #define SMF_NGAP_STATE_DELETE_TRIGGER_UE_REQUESTED 1 #define SMF_NGAP_STATE_DELETE_TRIGGER_PCF_INITIATED 2 #define SMF_NGAP_STATE_ERROR_INDICATION_RECEIVED_FROM_5G_AN 3 +#define SMF_NGAP_STATE_DELETE_TRIGGER_SMF_INITIATED 4 struct { int pdu_session_resource_release; } ngap_state; diff --git a/src/smf/gsm-sm.c b/src/smf/gsm-sm.c index 3fee8d941..73993910d 100644 --- a/src/smf/gsm-sm.c +++ b/src/smf/gsm-sm.c @@ -749,6 +749,8 @@ void smf_gsm_state_operational(ogs_fsm_t *s, smf_event_t *e) uint8_t gtp1_cause, gtp2_cause; bool release; + int state = 0; + ogs_assert(s); ogs_assert(e); @@ -861,6 +863,7 @@ void smf_gsm_state_operational(ogs_fsm_t *s, smf_event_t *e) SWITCH(sbi_message->h.service.name) CASE(OGS_SBI_SERVICE_NAME_NPCF_SMPOLICYCONTROL) stream = e->h.sbi.data; + state = e->h.sbi.state; SWITCH(sbi_message->h.resource.component[0]) CASE(OGS_SBI_RESOURCE_NAME_SM_POLICIES) @@ -897,8 +900,31 @@ void smf_gsm_state_operational(ogs_fsm_t *s, smf_event_t *e) break; } - OGS_FSM_TRAN(&sess->sm, - &smf_gsm_state_wait_pfcp_deletion); + if (state == OGS_PFCP_DELETE_TRIGGER_SMF_INITIATED) { + OGS_FSM_TRAN(&sess->sm, smf_gsm_state_wait_5gc_n1_n2_release); + + smf_n1_n2_message_transfer_param_t param; + + memset(¶m, 0, sizeof(param)); + param.state = SMF_NETWORK_REQUESTED_PDU_SESSION_RELEASE; + sess->pti = OGS_NAS_PROCEDURE_TRANSACTION_IDENTITY_UNASSIGNED; + param.n1smbuf = gsm_build_pdu_session_release_command( + sess, OGS_5GSM_CAUSE_REACTIVATION_REQUESTED); + ogs_assert(param.n1smbuf); + + param.n2smbuf = + ngap_build_pdu_session_resource_release_command_transfer( + sess, SMF_NGAP_STATE_DELETE_TRIGGER_SMF_INITIATED, + NGAP_Cause_PR_nas, NGAP_CauseNas_normal_release); + ogs_assert(param.n2smbuf); + + param.skip_ind = false; + + smf_namf_comm_send_n1_n2_message_transfer(sess, ¶m); + } else { + OGS_FSM_TRAN(&sess->sm, + &smf_gsm_state_wait_pfcp_deletion); + } break; DEFAULT @@ -1517,7 +1543,8 @@ void smf_gsm_state_wait_5gc_n1_n2_release(ogs_fsm_t *s, smf_event_t *e) } else if ( ngap_state == SMF_NGAP_STATE_DELETE_TRIGGER_UE_REQUESTED || - ngap_state == SMF_NGAP_STATE_DELETE_TRIGGER_PCF_INITIATED) { + ngap_state == SMF_NGAP_STATE_DELETE_TRIGGER_PCF_INITIATED || + ngap_state == SMF_NGAP_STATE_DELETE_TRIGGER_SMF_INITIATED) { ogs_assert(true == ogs_sbi_send_http_status_no_content(stream)); diff --git a/src/smf/pfcp-sm.c b/src/smf/pfcp-sm.c index 643bafff6..59a2421fc 100644 --- a/src/smf/pfcp-sm.c +++ b/src/smf/pfcp-sm.c @@ -315,6 +315,31 @@ void smf_pfcp_state_associated(ogs_fsm_t *s, smf_event_t *e) } break; case SMF_EVT_N4_NO_HEARTBEAT: + node = e->pfcp_node; + ogs_assert(node); + + smf_ue_t *smf_ue = NULL, *next = NULL;; + + ogs_list_for_each_safe(&smf_self()->smf_ue_list, next, smf_ue) { + smf_sess_t *sess = NULL, *next = NULL;; + ogs_assert(smf_ue); + + ogs_list_for_each_safe(&smf_ue->sess_list, next, sess) { + ogs_assert(sess); + + if (node == sess->pfcp_node) { + smf_npcf_smpolicycontrol_param_t param; + + memset(¶m, 0, sizeof(param)); + ogs_assert(true == + smf_sbi_discover_and_send( + OGS_SBI_SERVICE_TYPE_NPCF_SMPOLICYCONTROL, NULL, + smf_npcf_smpolicycontrol_build_delete, + sess, NULL, OGS_PFCP_DELETE_TRIGGER_SMF_INITIATED, ¶m)); + } + } + } + ogs_warn("No Heartbeat from UPF [%s]:%d", OGS_ADDR(addr, buf), OGS_PORT(addr)); OGS_FSM_TRAN(s, smf_pfcp_state_will_associate);