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 committed Jan 24, 2024
1 parent 1ab26c6 commit 9c07511
Show file tree
Hide file tree
Showing 7 changed files with 175 additions and 29 deletions.
64 changes: 55 additions & 9 deletions src/sgwc/pfcp-path.c
Original file line number Diff line number Diff line change
Expand Up @@ -168,25 +168,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 @@ -427,6 +427,8 @@ typedef struct smf_sess_s {
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
67 changes: 65 additions & 2 deletions src/smf/gsm-sm.c
Original file line number Diff line number Diff line change
Expand Up @@ -720,8 +720,26 @@ void smf_gsm_state_wait_pfcp_establishment(ogs_fsm_t *s, smf_event_t *e)
case SMF_EVT_N4_TIMER:
switch (e->h.timer_id) {
case SMF_TIMER_PFCP_NO_ESTABLISHMENT_RESPONSE:
OGS_FSM_TRAN(s, smf_gsm_state_5gc_n1_n2_reject);
ogs_error("PFCP timeout waiting for Session Establishment Response");

if (sess->timeout_xact->epc) {
ogs_gtp_xact_t *gtp_xact = (ogs_gtp_xact_t *) sess->timeout_xact->assoc_xact;
uint8_t gtp_cause = OGS_GTP1_CAUSE_NETWORK_FAILURE;

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);
} else {
OGS_FSM_TRAN(s, smf_gsm_state_5gc_n1_n2_reject);
}
break;

default:
ogs_error("Unknown timer[%s:%d]",
ogs_timer_get_name(e->h.timer_id), e->h.timer_id);
Expand Down Expand Up @@ -1267,8 +1285,25 @@ void smf_gsm_state_operational(ogs_fsm_t *s, smf_event_t *e)
case SMF_EVT_N4_TIMER:
switch (e->h.timer_id) {
case SMF_TIMER_PFCP_NO_ESTABLISHMENT_RESPONSE:
OGS_FSM_TRAN(s, smf_gsm_state_5gc_n1_n2_reject);
ogs_error("PFCP timeout waiting for Session Establishment Response");

if (timeout_xact->epc) {
ogs_gtp_xact_t *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);
} else {
OGS_FSM_TRAN(s, smf_gsm_state_5gc_n1_n2_reject);
}
break;

default:
ogs_error("Unknown timer[%s:%d]",
ogs_timer_get_name(e->h.timer_id), e->h.timer_id);
Expand Down Expand Up @@ -1440,6 +1475,34 @@ 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_N4_TIMER:
switch(e->h.timer_id) {
case SMF_TIMER_PFCP_NO_DELETION_RESPONSE:
ogs_error("PFCP timeout waiting for Session Deletion Response");

if (sess->timeout_xact->epc) {
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);
} else {
ogs_error("5GC Session Deletion timeout not written");
}
break;

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

Expand Down
32 changes: 14 additions & 18 deletions src/smf/pfcp-path.c
Original file line number Diff line number Diff line change
Expand Up @@ -216,8 +216,6 @@ static void sess_5gc_timeout(ogs_pfcp_xact_t *xact, void *data)
uint8_t type;
int trigger;
char *strerror = NULL;
smf_event_t *e = NULL;
int rv;

ogs_assert(xact);
ogs_assert(data);
Expand All @@ -226,25 +224,15 @@ static void sess_5gc_timeout(ogs_pfcp_xact_t *xact, void *data)
ogs_assert(sess);
smf_ue = sess->smf_ue;
ogs_assert(smf_ue);

sess->timeout_xact = xact;

stream = xact->assoc_stream;
type = xact->seq[0].type;

switch (type) {
case OGS_PFCP_SESSION_ESTABLISHMENT_REQUEST_TYPE:
ogs_warn("No PFCP session establishment response");

e = smf_event_new(SMF_EVT_N4_TIMER);
ogs_assert(e);
e->sess = sess;
e->h.timer_id = SMF_TIMER_PFCP_NO_ESTABLISHMENT_RESPONSE;
e->pfcp_node = sess->pfcp_node;

rv = ogs_queue_push(ogs_app()->queue, e);
if (rv != OGS_OK) {
ogs_error("ogs_queue_push() failed:%d", (int)rv);
ogs_event_free(e);
}
smf_timeout_pfcp_no_establishment_response(data);
break;
case OGS_PFCP_SESSION_MODIFICATION_REQUEST_TYPE:
strerror = ogs_msprintf("[%s:%d] No PFCP session modification response",
Expand Down Expand Up @@ -299,19 +287,26 @@ 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_establishment_response(data);
break;
case OGS_PFCP_SESSION_MODIFICATION_REQUEST_TYPE:
ogs_error("No PFCP session modification response");
ogs_warn("No PFCP session modification response");
smf_timeout_pfcp_no_modification_response(data);
break;
case OGS_PFCP_SESSION_DELETION_REQUEST_TYPE:
ogs_error("No PFCP session deletion response");
ogs_warn("No PFCP session deletion response");
smf_timeout_pfcp_no_deletion_response(data);
break;
default:
ogs_error("Not implemented [type:%d]", type);
Expand All @@ -328,7 +323,8 @@ 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");
ogs_warn("No PFCP session modification response");
smf_timeout_pfcp_no_modification_response(data);
break;
default:
ogs_error("Not implemented [type:%d]", type);
Expand Down
4 changes: 4 additions & 0 deletions src/smf/pfcp-sm.c
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,8 @@ void smf_pfcp_state_will_associate(ogs_fsm_t *s, smf_event_t *e)
ogs_pfcp_cp_send_association_setup_request(node, node_timeout);
break;
case SMF_TIMER_PFCP_NO_ESTABLISHMENT_RESPONSE:
case SMF_TIMER_PFCP_NO_DELETION_RESPONSE:
case SMF_TIMER_PFCP_NO_MODIFICATION_RESPONSE:
sess = e->sess;
sess = smf_sess_cycle(sess);
if (!sess) {
Expand Down Expand Up @@ -402,6 +404,8 @@ void smf_pfcp_state_associated(ogs_fsm_t *s, smf_event_t *e)
ogs_pfcp_send_heartbeat_request(node, node_timeout));
break;
case SMF_TIMER_PFCP_NO_ESTABLISHMENT_RESPONSE:
case SMF_TIMER_PFCP_NO_DELETION_RESPONSE:
case SMF_TIMER_PFCP_NO_MODIFICATION_RESPONSE:
sess = e->sess;
sess = smf_sess_cycle(sess);
if (!sess) {
Expand Down
29 changes: 29 additions & 0 deletions src/smf/timer.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ const char *smf_timer_get_name(int timer_id)
return "SMF_TIMER_PFCP_NO_HEARTBEAT";
case SMF_TIMER_PFCP_NO_ESTABLISHMENT_RESPONSE:
return "SMF_TIMER_PFCP_NO_ESTABLISHMENT_RESPONSE";
case SMF_TIMER_PFCP_NO_DELETION_RESPONSE:
return "SMF_TIMER_PFCP_NO_DELETION_RESPONSE";
case SMF_TIMER_PFCP_NO_MODIFICATION_RESPONSE:
return "SMF_TIMER_PFCP_NO_MODIFICATION_RESPONSE";
default:
break;
}
Expand Down Expand Up @@ -78,6 +82,16 @@ static void timer_send_event(int timer_id, void *data)
e->gtp_xact = old_e->gtp_xact;
break;

case SMF_TIMER_PFCP_NO_ESTABLISHMENT_RESPONSE:
case SMF_TIMER_PFCP_NO_DELETION_RESPONSE:
case SMF_TIMER_PFCP_NO_MODIFICATION_RESPONSE:
e = smf_event_new(SMF_EVT_N4_TIMER);
ogs_assert(e);
e->h.timer_id = timer_id;
e->sess = data;
e->pfcp_node = e->sess->pfcp_node;
break;

default:
ogs_fatal("Unknown timer id[%d]", timer_id);
ogs_assert_if_reached();
Expand Down Expand Up @@ -110,4 +124,19 @@ void smf_timer_gx_no_cca(void *data)
void smf_timer_gy_no_cca(void *data)
{
timer_send_event(SMF_TIMER_GY_CCA, data);
}

void smf_timeout_pfcp_no_establishment_response(void *data)
{
timer_send_event(SMF_TIMER_PFCP_NO_ESTABLISHMENT_RESPONSE, data);
}

void smf_timeout_pfcp_no_deletion_response(void *data)
{
timer_send_event(SMF_TIMER_PFCP_NO_DELETION_RESPONSE, data);
}

void smf_timeout_pfcp_no_modification_response(void *data)
{
timer_send_event(SMF_TIMER_PFCP_NO_MODIFICATION_RESPONSE, data);
}
6 changes: 6 additions & 0 deletions src/smf/timer.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ typedef enum {
SMF_TIMER_PFCP_ASSOCIATION,
SMF_TIMER_PFCP_NO_HEARTBEAT,
SMF_TIMER_PFCP_NO_ESTABLISHMENT_RESPONSE,
SMF_TIMER_PFCP_NO_DELETION_RESPONSE,
SMF_TIMER_PFCP_NO_MODIFICATION_RESPONSE,
SMF_TIMER_GX_CCA,
SMF_TIMER_GY_CCA,

Expand All @@ -47,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_establishment_response(void *data);
void smf_timeout_pfcp_no_deletion_response(void *data);
void smf_timeout_pfcp_no_modification_response(void *data);

#ifdef __cplusplus
}
#endif
Expand Down

0 comments on commit 9c07511

Please sign in to comment.