Skip to content

Commit

Permalink
[smf][sgwc] hook-up pfcp timeout functions (#71)
Browse files Browse the repository at this point in the history
  • Loading branch information
spencersevilla authored and Spencer Sevilla committed Feb 8, 2023
1 parent b57e3a1 commit c1cbcf8
Show file tree
Hide file tree
Showing 8 changed files with 155 additions and 14 deletions.
64 changes: 55 additions & 9 deletions src/sgwc/pfcp-path.c
Original file line number Diff line number Diff line change
Expand Up @@ -160,25 +160,71 @@ void sgwc_pfcp_close(void)
ogs_socknode_remove_all(&ogs_pfcp_self()->pfcp_list6);
}

static void sess_timeout(ogs_pfcp_xact_t *xact, void *data)
static void sess_timeout(ogs_pfcp_xact_t *pfcp_xact, void *data)
{
uint8_t type;
uint8_t pfcp_type;

ogs_assert(xact);
type = xact->seq[0].type;
uint8_t gtp_cause;
uint8_t gtp_type;
ogs_gtp_xact_t * s11_xact = NULL;
sgwc_sess_t *sess = data;
sgwc_ue_t *sgwc_ue = NULL;

switch (type) {
ogs_assert(pfcp_xact);
ogs_assert(sess);

s11_xact = pfcp_xact->assoc_xact;
ogs_assert(s11_xact);

switch (s11_xact->gtp_version) {
case 1:
gtp_cause = OGS_GTP1_CAUSE_NETWORK_FAILURE;
break;
case 2:
gtp_cause = OGS_GTP2_CAUSE_REMOTE_PEER_NOT_RESPONDING;
break;
}

sgwc_ue = sess->sgwc_ue;

pfcp_type = pfcp_xact->seq[0].type;
switch (pfcp_type) {
case OGS_PFCP_SESSION_ESTABLISHMENT_REQUEST_TYPE:
ogs_error("No PFCP session establishment response");
ogs_error("Timeout: No PFCP session establishment response");
ogs_gtp_send_error_message(
s11_xact, sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
OGS_GTP2_CREATE_SESSION_RESPONSE_TYPE, gtp_cause);
break;
case OGS_PFCP_SESSION_MODIFICATION_REQUEST_TYPE:
ogs_error("No PFCP session modification response");
ogs_error("Timeout: No PFCP session modification response");

// multiple gtp message-types are translated to pfcp session mod request
switch (s11_xact->seq[0].type) {
case OGS_GTP2_MODIFY_BEARER_REQUEST_TYPE:
gtp_type = OGS_GTP2_MODIFY_BEARER_RESPONSE_TYPE;
break;
case OGS_GTP2_RELEASE_ACCESS_BEARERS_REQUEST_TYPE:
gtp_type = OGS_GTP2_RELEASE_ACCESS_BEARERS_RESPONSE_TYPE;
break;
default:
ogs_error("GTP request type not implemented: %d", s11_xact->seq[0].type);
gtp_type = OGS_GTP2_MODIFY_BEARER_RESPONSE_TYPE;
break;
}

ogs_gtp_send_error_message(
s11_xact, sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
gtp_type, gtp_cause);
break;
case OGS_PFCP_SESSION_DELETION_REQUEST_TYPE:
ogs_error("No PFCP session deletion response");
ogs_error("Timeout: No PFCP session deletion response");
ogs_gtp_send_error_message(
s11_xact, sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
OGS_GTP2_DELETE_SESSION_RESPONSE_TYPE, gtp_cause);
sgwc_sess_remove(sess);
break;
default:
ogs_error("Not implemented [type:%d]", type);
ogs_error("PFCP request type not implemented [type:%d]", pfcp_type);
break;
}
}
Expand Down
2 changes: 2 additions & 0 deletions src/smf/context.h
Original file line number Diff line number Diff line change
Expand Up @@ -412,6 +412,8 @@ typedef struct smf_sess_s {
ogs_gtp_node_t *gnode;
ogs_pfcp_node_t *pfcp_node;
bool pfcp_established;

ogs_pfcp_xact_t *timeout_xact;

ogs_timer_t *timer_gx_cca;
ogs_timer_t *timer_gy_cca;
Expand Down
3 changes: 2 additions & 1 deletion src/smf/event.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@ typedef enum {
SMF_EVT_GX_MESSAGE,
SMF_EVT_GY_MESSAGE,
SMF_EVT_DIAMETER_TIMER,

SMF_EVT_PFCP_TIMEOUT,

SMF_EVT_N4_MESSAGE,
SMF_EVT_N4_TIMER,
SMF_EVT_N4_NO_HEARTBEAT,
Expand Down
49 changes: 49 additions & 0 deletions src/smf/gsm-sm.c
Original file line number Diff line number Diff line change
Expand Up @@ -691,6 +691,8 @@ void smf_gsm_state_wait_pfcp_establishment(ogs_fsm_t *s, smf_event_t *e)
ogs_pfcp_message_t *pfcp_message = NULL;
int rv;

ogs_gtp_xact_t *gtp_xact = NULL;

ogs_assert(s);
ogs_assert(e);

Expand Down Expand Up @@ -779,6 +781,29 @@ void smf_gsm_state_wait_pfcp_establishment(ogs_fsm_t *s, smf_event_t *e)
ogs_error("cannot handle PFCP message type[%d]",
pfcp_message->h.type);
}
break;

case SMF_EVT_PFCP_TIMEOUT:
switch(e->h.timer_id) {
case SMF_TIMEOUT_PFCP_SER:
ogs_error("PFCP timeout waiting for Session Establishment Response");

gtp_xact = (ogs_gtp_xact_t *) sess->timeout_xact->assoc_xact;

switch (gtp_xact->gtp_version) {
case 1:
gtp_cause = OGS_GTP1_CAUSE_NETWORK_FAILURE;
break;
case 2:
gtp_cause = OGS_GTP2_CAUSE_REMOTE_PEER_NOT_RESPONDING;
break;
}
send_gtp_create_err_msg(sess, gtp_xact, gtp_cause);
break;

default:
ogs_error("Unknown SMF_EVT_PFCP_TIMEOUT timer id [%d]", e->h.timer_id);
}
}
}

Expand Down Expand Up @@ -1369,6 +1394,30 @@ void smf_gsm_state_wait_pfcp_deletion(ogs_fsm_t *s, smf_event_t *e)
ogs_error("cannot handle PFCP message type[%d]",
pfcp_message->h.type);
}
break;

case SMF_EVT_PFCP_TIMEOUT:
switch(e->h.timer_id) {
case SMF_TIMEOUT_PFCP_SDR:
ogs_error("PFCP timeout waiting for Session Deletion Response");

gtp_xact = (ogs_gtp_xact_t *) sess->timeout_xact->assoc_xact;

switch (gtp_xact->gtp_version) {
case 1:
gtp_cause = OGS_GTP1_CAUSE_NETWORK_FAILURE;
break;
case 2:
gtp_cause = OGS_GTP2_CAUSE_REMOTE_PEER_NOT_RESPONDING;
break;
}
send_gtp_delete_err_msg(sess, gtp_xact, gtp_cause);
break;

default:
ogs_error("Unknown SMF_EVT_PFCP_TIMEOUT timer id [%d]", e->h.timer_id);
}
break;
}
}

Expand Down
12 changes: 8 additions & 4 deletions src/smf/pfcp-path.c
Original file line number Diff line number Diff line change
Expand Up @@ -277,19 +277,23 @@ static void sess_5gc_timeout(ogs_pfcp_xact_t *xact, void *data)
static void sess_epc_timeout(ogs_pfcp_xact_t *xact, void *data)
{
uint8_t type;
smf_sess_t *sess;

ogs_assert(xact);
type = xact->seq[0].type;

sess = data;
sess->timeout_xact = xact;

switch (type) {
case OGS_PFCP_SESSION_ESTABLISHMENT_REQUEST_TYPE:
ogs_warn("No PFCP session establishment response");
smf_timeout_pfcp_no_ser(data);
break;
case OGS_PFCP_SESSION_MODIFICATION_REQUEST_TYPE:
ogs_error("No PFCP session modification response");
smf_timeout_pfcp_no_smr(data);
break;
case OGS_PFCP_SESSION_DELETION_REQUEST_TYPE:
ogs_error("No PFCP session deletion response");
smf_timeout_pfcp_no_sdr(data);
break;
default:
ogs_error("Not implemented [type:%d]", type);
Expand All @@ -306,7 +310,7 @@ static void bearer_epc_timeout(ogs_pfcp_xact_t *xact, void *data)

switch (type) {
case OGS_PFCP_SESSION_MODIFICATION_REQUEST_TYPE:
ogs_error("No PFCP session modification response");
smf_timeout_pfcp_no_smr(data);
break;
default:
ogs_error("Not implemented [type:%d]", type);
Expand Down
9 changes: 9 additions & 0 deletions src/smf/smf-sm.c
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,15 @@ void smf_state_operational(ogs_fsm_t *s, smf_event_t *e)
}
break;

case SMF_EVT_PFCP_TIMEOUT:
ogs_assert(e);
sess = e->sess;
if (sess) {
ogs_assert(OGS_FSM_STATE(&sess->sm));
ogs_fsm_dispatch(&sess->sm, e);
}
break;

case SMF_EVT_S6B_MESSAGE:
ogs_assert(e);
s6b_message = e->s6b_message;
Expand Down
23 changes: 23 additions & 0 deletions src/smf/timer.c
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,14 @@ static void timer_send_event(int timer_id, void *data)
e->gx_message = old_e->gx_message;
e->gtp_xact = old_e->gtp_xact;
break;
case SMF_TIMEOUT_PFCP_SER:
case SMF_TIMEOUT_PFCP_SDR:
case SMF_TIMEOUT_PFCP_SMR:
e = smf_event_new(SMF_EVT_PFCP_TIMEOUT);
ogs_assert(e);
e->h.timer_id = timer_id;
e->sess = data;
break;
default:
ogs_fatal("Unknown timer id[%d]", timer_id);
ogs_assert_if_reached();
Expand Down Expand Up @@ -105,3 +113,18 @@ void smf_timer_gy_no_cca(void *data)
{
timer_send_event(SMF_TIMER_GY_CCA, data);
}

void smf_timeout_pfcp_no_ser(void *data)
{
timer_send_event(SMF_TIMEOUT_PFCP_SER, data);
}

void smf_timeout_pfcp_no_sdr(void *data)
{
timer_send_event(SMF_TIMEOUT_PFCP_SDR, data);
}

void smf_timeout_pfcp_no_smr(void *data)
{
timer_send_event(SMF_TIMEOUT_PFCP_SMR, data);
}
7 changes: 7 additions & 0 deletions src/smf/timer.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ typedef enum {
SMF_TIMER_PFCP_NO_HEARTBEAT,
SMF_TIMER_GX_CCA,
SMF_TIMER_GY_CCA,
SMF_TIMEOUT_PFCP_SER,
SMF_TIMEOUT_PFCP_SDR,
SMF_TIMEOUT_PFCP_SMR,

MAX_NUM_OF_SMF_TIMER,

Expand All @@ -46,6 +49,10 @@ void smf_timer_pfcp_no_heartbeat(void *data);
void smf_timer_gx_no_cca(void *data);
void smf_timer_gy_no_cca(void *data);

void smf_timeout_pfcp_no_ser(void *data);
void smf_timeout_pfcp_no_sdr(void *data);
void smf_timeout_pfcp_no_smr(void *data);

#ifdef __cplusplus
}
#endif
Expand Down

0 comments on commit c1cbcf8

Please sign in to comment.