[SMF] Setup Gy session when creating UE session over S2b interface

So far the Gy session creation triggered by S2b interface (ePDG) was not
implemented. Fix it.
This commit is contained in:
Pau Espin 2024-02-26 12:21:59 +01:00 committed by Sukchan Lee
parent 4aaac999f7
commit 32de75b1a5
5 changed files with 60 additions and 14 deletions

View File

@ -1,4 +1,4 @@
/*
/* 3GPP TS 29.273 section 9
* Copyright (C) 2019 by Sukchan Lee <acetcom@gmail.com>
*
* This file is part of Open5GS.
@ -35,7 +35,8 @@ extern struct dict_object *ogs_diam_s6b_application;
extern struct dict_object *ogs_diam_s6b_mip6_feature_vector;
typedef struct ogs_diam_s6b_message_s {
#define OGS_DIAM_S6B_CMD_SESSION_TERMINATION 1
#define OGS_DIAM_S6B_CMD_AUTHENTICATION_AUTHORIZATION 1
#define OGS_DIAM_S6B_CMD_SESSION_TERMINATION 2
uint16_t cmd_code;
uint32_t result_code;
uint32_t *err;

View File

@ -228,6 +228,8 @@ typedef struct smf_sess_s {
uint32_t gx_cca_init_err; /* Gx CCA RXed error code */
bool gy_ccr_init_in_flight; /* Waiting for Gy CCA */
uint32_t gy_cca_init_err; /* Gy CCA RXed error code */
bool s6b_aar_in_flight; /* Waiting for S6B AAR */
uint32_t s6b_aaa_err; /* S6B AAA RXed error code */
bool gx_ccr_term_in_flight; /* Waiting for Gx CCA */
uint32_t gx_cca_term_err; /* Gx CCA RXed error code */
bool gy_ccr_term_in_flight; /* Waiting for Gy CCA */

View File

@ -182,8 +182,10 @@ void smf_gsm_state_initial(ogs_fsm_t *s, smf_event_t *e)
switch (e->h.id) {
case OGS_FSM_ENTRY_SIG:
/* reset state: */
sess->sm_data.s6b_aar_in_flight = false;
sess->sm_data.gx_ccr_init_in_flight = false;
sess->sm_data.gy_ccr_init_in_flight = false;
sess->sm_data.s6b_aaa_err = ER_DIAMETER_SUCCESS;
sess->sm_data.gx_cca_init_err = ER_DIAMETER_SUCCESS;
sess->sm_data.gy_cca_init_err = ER_DIAMETER_SUCCESS;
break;
@ -229,7 +231,9 @@ void smf_gsm_state_initial(ogs_fsm_t *s, smf_event_t *e)
break;
case OGS_GTP2_RAT_TYPE_WLAN:
smf_s6b_send_aar(sess, e->gtp_xact);
sess->sm_data.s6b_aar_in_flight = true;
OGS_FSM_TRAN(s, smf_gsm_state_wait_epc_auth_initial);
/* Gx/Gy Init Req is done after s6b AAR + AAA */
break;
default:
ogs_error("Unknown RAT Type [%d]", sess->gtp_rat_type);
@ -327,6 +331,7 @@ void smf_gsm_state_wait_epc_auth_initial(ogs_fsm_t *s, smf_event_t *e)
{
smf_sess_t *sess = NULL;
ogs_diam_s6b_message_t *s6b_message = NULL;
ogs_diam_gy_message_t *gy_message = NULL;
ogs_diam_gx_message_t *gx_message = NULL;
uint32_t diam_err;
@ -340,6 +345,22 @@ void smf_gsm_state_wait_epc_auth_initial(ogs_fsm_t *s, smf_event_t *e)
ogs_assert(sess);
switch (e->h.id) {
case SMF_EVT_S6B_MESSAGE:
s6b_message = e->s6b_message;
ogs_assert(s6b_message);
switch(s6b_message->cmd_code) {
case OGS_DIAM_S6B_CMD_AUTHENTICATION_AUTHORIZATION:
sess->sm_data.s6b_aar_in_flight = false;
sess->sm_data.s6b_aaa_err = s6b_message->result_code;
if (s6b_message->result_code == ER_DIAMETER_SUCCESS) {
send_ccr_init_req_gx_gy(sess, e);
return;
}
goto test_can_proceed;
}
break;
case SMF_EVT_GX_MESSAGE:
gx_message = e->gx_message;
ogs_assert(gx_message);
@ -382,9 +403,12 @@ void smf_gsm_state_wait_epc_auth_initial(ogs_fsm_t *s, smf_event_t *e)
test_can_proceed:
/* First wait for both Gx and Gy requests to be done: */
if (!sess->sm_data.gx_ccr_init_in_flight &&
if (!sess->sm_data.s6b_aar_in_flight &&
!sess->sm_data.gx_ccr_init_in_flight &&
!sess->sm_data.gy_ccr_init_in_flight) {
diam_err = ER_DIAMETER_SUCCESS;
if (sess->sm_data.s6b_aaa_err != ER_DIAMETER_SUCCESS)
diam_err = sess->sm_data.s6b_aaa_err;
if (sess->sm_data.gx_cca_init_err != ER_DIAMETER_SUCCESS)
diam_err = sess->sm_data.gx_cca_init_err;
if (sess->sm_data.gy_cca_init_err != ER_DIAMETER_SUCCESS)

View File

@ -1,4 +1,4 @@
/*
/* 3GPP TS 29.273 section 9
* Copyright (C) 2019 by Sukchan Lee <acetcom@gmail.com>
*
* This file is part of Open5GS.
@ -344,11 +344,11 @@ static void smf_s6b_aaa_cb(void *data, struct msg **msg)
unsigned long dur;
int error = 0;
int new;
int result_code = 0;
int exp_result_code = 0;
smf_sess_t *sess = NULL;
ogs_gtp_xact_t *xact = NULL;
smf_event_t *e = NULL;
ogs_diam_s6b_message_t *s6b_message = NULL;
ogs_debug("[AA-Answer]");
@ -374,15 +374,20 @@ static void smf_s6b_aaa_cb(void *data, struct msg **msg)
xact = sess_data->xact;
ogs_assert(xact);
s6b_message = ogs_calloc(1, sizeof(ogs_diam_s6b_message_t));
ogs_assert(s6b_message);
/* Set Session Termination Command */
s6b_message->cmd_code = OGS_DIAM_S6B_CMD_AUTHENTICATION_AUTHORIZATION;
/* Value of Result Code */
ret = fd_msg_search_avp(*msg, ogs_diam_result_code, &avp);
ogs_assert(ret == 0);
if (avp) {
ret = fd_msg_avp_hdr(avp, &hdr);
ogs_assert(ret == 0);
result_code = hdr->avp_value->i32;
if (result_code != ER_DIAMETER_SUCCESS) {
ogs_error("Result Code: %d", result_code);
s6b_message->result_code = hdr->avp_value->i32;
if (s6b_message->result_code != ER_DIAMETER_SUCCESS) {
ogs_error("Result Code: %d", s6b_message->result_code);
error++;
}
} else {
@ -397,8 +402,8 @@ static void smf_s6b_aaa_cb(void *data, struct msg **msg)
if (avpch1) {
ret = fd_msg_avp_hdr(avpch1, &hdr);
ogs_assert(ret == 0);
exp_result_code = hdr->avp_value->i32;
ogs_error("Experimental Result Code: %d", exp_result_code);
s6b_message->result_code = hdr->avp_value->i32;
ogs_error("Experimental Result Code: %d", s6b_message->result_code);
}
} else {
ogs_error("no Result-Code");
@ -431,9 +436,22 @@ static void smf_s6b_aaa_cb(void *data, struct msg **msg)
error++;
}
if (!error) {
smf_gx_send_ccr(sess, xact,
OGS_DIAM_GX_CC_REQUEST_TYPE_INITIAL_REQUEST);
e = smf_event_new(SMF_EVT_S6B_MESSAGE);
ogs_assert(e);
if (error && s6b_message->result_code == ER_DIAMETER_SUCCESS)
s6b_message->result_code = error;
e->sess = sess;
e->gtp_xact = xact;
e->s6b_message = s6b_message;
ret = ogs_queue_push(ogs_app()->queue, e);
if (ret != OGS_OK) {
ogs_error("ogs_queue_push() failed:%d", (int)ret);
ogs_free(s6b_message);
ogs_event_free(e);
} else {
ogs_pollset_notify(ogs_app()->pollset);
}
/* Free the message */

View File

@ -365,6 +365,7 @@ void smf_state_operational(ogs_fsm_t *s, smf_event_t *e)
ogs_assert(sess);
switch(s6b_message->cmd_code) {
case OGS_DIAM_S6B_CMD_AUTHENTICATION_AUTHORIZATION:
case OGS_DIAM_S6B_CMD_SESSION_TERMINATION:
ogs_fsm_dispatch(&sess->sm, e);
break;