diff --git a/lib/pfcp/build.c b/lib/pfcp/build.c index 723153f38d..ccc1f4e0dc 100644 --- a/lib/pfcp/build.c +++ b/lib/pfcp/build.c @@ -235,6 +235,63 @@ ogs_pkbuf_t *ogs_pfcp_up_build_association_setup_response(uint8_t type, return ogs_pfcp_build_msg(&pfcp_message); } +ogs_pkbuf_t *ogs_pfcp_cp_build_session_set_deletion_request(uint8_t type) +{ + ogs_pfcp_message_t pfcp_message; + ogs_pfcp_session_set_deletion_request_t *req = NULL; + + ogs_pfcp_node_id_t node_id; + int node_id_len = 0, rv; + + ogs_debug("Session Set Deletion Request"); + + req = &pfcp_message.pfcp_session_set_deletion_request; + memset(&pfcp_message, 0, sizeof(ogs_pfcp_message_t)); + + rv = ogs_pfcp_sockaddr_to_node_id( + ogs_pfcp_self()->pfcp_addr, ogs_pfcp_self()->pfcp_addr6, + ogs_app()->parameter.prefer_ipv4, + &node_id, &node_id_len); + ogs_expect_or_return_val(rv == OGS_OK, NULL); + req->node_id.presence = 1; + req->node_id.data = &node_id; + req->node_id.len = node_id_len; + + pfcp_message.h.type = type; + return ogs_pfcp_build_msg(&pfcp_message); +} + +ogs_pkbuf_t *ogs_pfcp_up_build_session_set_deletion_response(uint8_t type, uint8_t cause) +{ + ogs_pfcp_message_t pfcp_message; + ogs_pfcp_session_set_deletion_response_t *rsp = NULL; + + ogs_pfcp_node_id_t node_id; + int node_id_len = 0, rv; + + ogs_debug("Session Set Deletion Response"); + + rsp = &pfcp_message.pfcp_session_set_deletion_response; + memset(&pfcp_message, 0, sizeof(ogs_pfcp_message_t)); + + // node id + rv = ogs_pfcp_sockaddr_to_node_id( + ogs_pfcp_self()->pfcp_addr, ogs_pfcp_self()->pfcp_addr6, + ogs_app()->parameter.prefer_ipv4, + &node_id, &node_id_len); + ogs_expect_or_return_val(rv == OGS_OK, NULL); + rsp->node_id.presence = 1; + rsp->node_id.data = &node_id; + rsp->node_id.len = node_id_len; + + // cause + rsp->cause.presence = 1; + rsp->cause.u8 = cause; + + pfcp_message.h.type = type; + return ogs_pfcp_build_msg(&pfcp_message); +} + static struct { ogs_pfcp_f_teid_t f_teid; char dnn[OGS_MAX_DNN_LEN+1]; diff --git a/lib/pfcp/build.h b/lib/pfcp/build.h index eb83f2f61d..887842b1e2 100644 --- a/lib/pfcp/build.h +++ b/lib/pfcp/build.h @@ -35,6 +35,10 @@ ogs_pkbuf_t *ogs_pfcp_up_build_association_setup_request(uint8_t type); ogs_pkbuf_t *ogs_pfcp_up_build_association_setup_response(uint8_t type, uint8_t cause); +ogs_pkbuf_t *ogs_pfcp_cp_build_session_set_deletion_request(uint8_t type); +ogs_pkbuf_t *ogs_pfcp_up_build_session_set_deletion_response(uint8_t type, + uint8_t cause); + void ogs_pfcp_pdrbuf_init(void); void ogs_pfcp_pdrbuf_clear(void); diff --git a/lib/pfcp/path.c b/lib/pfcp/path.c index 5969a71077..dfcab6db02 100644 --- a/lib/pfcp/path.c +++ b/lib/pfcp/path.c @@ -235,6 +235,60 @@ int ogs_pfcp_cp_send_association_setup_response(ogs_pfcp_xact_t *xact, return rv; } +int ogs_pfcp_cp_send_session_set_deletion_request(ogs_pfcp_node_t *node, + void (*cb)(ogs_pfcp_xact_t *xact, void *data)) +{ + int rv; + ogs_pkbuf_t *pkbuf = NULL; + ogs_pfcp_header_t h; + ogs_pfcp_xact_t *xact = NULL; + + ogs_assert(node); + + memset(&h, 0, sizeof(ogs_pfcp_header_t)); + h.type = OGS_PFCP_SESSION_SET_DELETION_REQUEST_TYPE; + h.seid = 0; + + xact = ogs_pfcp_xact_local_create(node, cb, node); + ogs_expect_or_return_val(xact, OGS_ERROR); + + pkbuf = ogs_pfcp_cp_build_session_set_deletion_request(h.type); + ogs_expect_or_return_val(pkbuf, OGS_ERROR); + + rv = ogs_pfcp_xact_update_tx(xact, &h, pkbuf); + ogs_expect_or_return_val(rv == OGS_OK, OGS_ERROR); + + rv = ogs_pfcp_xact_commit(xact); + ogs_expect(rv == OGS_OK); + + return rv; +} + +int ogs_pfcp_up_send_session_set_deletion_response(ogs_pfcp_xact_t *xact, + uint8_t cause) +{ + int rv; + ogs_pkbuf_t *pkbuf = NULL; + ogs_pfcp_header_t h; + + ogs_assert(xact); + + memset(&h, 0, sizeof(ogs_pfcp_header_t)); + h.type = OGS_PFCP_SESSION_SET_DELETION_RESPONSE_TYPE; + h.seid = 0; + + pkbuf = ogs_pfcp_up_build_session_set_deletion_response(h.type, cause); + ogs_expect_or_return_val(pkbuf, OGS_ERROR); + + rv = ogs_pfcp_xact_update_tx(xact, &h, pkbuf); + ogs_expect_or_return_val(rv == OGS_OK, OGS_ERROR); + + rv = ogs_pfcp_xact_commit(xact); + ogs_expect(rv == OGS_OK); + + return rv; +} + int ogs_pfcp_up_send_association_setup_request(ogs_pfcp_node_t *node, void (*cb)(ogs_pfcp_xact_t *xact, void *data)) { diff --git a/lib/pfcp/path.h b/lib/pfcp/path.h index 689175c26b..3a061fa257 100644 --- a/lib/pfcp/path.h +++ b/lib/pfcp/path.h @@ -73,6 +73,11 @@ int ogs_pfcp_cp_send_association_setup_request(ogs_pfcp_node_t *node, int ogs_pfcp_cp_send_association_setup_response(ogs_pfcp_xact_t *xact, uint8_t cause); +int ogs_pfcp_cp_send_session_set_deletion_request(ogs_pfcp_node_t *node, + void (*cb)(ogs_pfcp_xact_t *xact, void *data)); +int ogs_pfcp_up_send_session_set_deletion_response(ogs_pfcp_xact_t *xact, + uint8_t cause); + int ogs_pfcp_up_send_association_setup_request(ogs_pfcp_node_t *node, void (*cb)(ogs_pfcp_xact_t *xact, void *data)); int ogs_pfcp_up_send_association_setup_response(ogs_pfcp_xact_t *xact, diff --git a/lib/pfcp/xact.c b/lib/pfcp/xact.c index c04631f804..634d0c97e9 100644 --- a/lib/pfcp/xact.c +++ b/lib/pfcp/xact.c @@ -728,6 +728,7 @@ static ogs_pfcp_xact_stage_t ogs_pfcp_xact_get_stage(uint8_t type, uint32_t xid) case OGS_PFCP_SESSION_ESTABLISHMENT_REQUEST_TYPE: case OGS_PFCP_SESSION_MODIFICATION_REQUEST_TYPE: case OGS_PFCP_SESSION_DELETION_REQUEST_TYPE: + case OGS_PFCP_SESSION_SET_DELETION_REQUEST_TYPE: case OGS_PFCP_SESSION_REPORT_REQUEST_TYPE: stage = PFCP_XACT_INITIAL_STAGE; break; @@ -739,6 +740,7 @@ static ogs_pfcp_xact_stage_t ogs_pfcp_xact_get_stage(uint8_t type, uint32_t xid) case OGS_PFCP_SESSION_ESTABLISHMENT_RESPONSE_TYPE: case OGS_PFCP_SESSION_MODIFICATION_RESPONSE_TYPE: case OGS_PFCP_SESSION_DELETION_RESPONSE_TYPE: + case OGS_PFCP_SESSION_SET_DELETION_RESPONSE_TYPE: case OGS_PFCP_SESSION_REPORT_RESPONSE_TYPE: stage = PFCP_XACT_FINAL_STAGE; break; diff --git a/src/sgwc/pfcp-sm.c b/src/sgwc/pfcp-sm.c index c12465d7c5..d888600739 100644 --- a/src/sgwc/pfcp-sm.c +++ b/src/sgwc/pfcp-sm.c @@ -239,6 +239,11 @@ void sgwc_pfcp_state_associated(ogs_fsm_t *s, sgwc_event_t *e) &message->pfcp_session_deletion_response); break; + case OGS_PFCP_SESSION_SET_DELETION_RESPONSE_TYPE: + sgwc_sxa_handle_session_set_deletion_response( + xact, &message->pfcp_session_set_deletion_response); + break; + case OGS_PFCP_SESSION_REPORT_REQUEST_TYPE: if (!message->h.seid_presence) ogs_error("No SEID"); diff --git a/src/sgwc/sxa-handler.c b/src/sgwc/sxa-handler.c index 59c61c7ddc..cc854670fe 100644 --- a/src/sgwc/sxa-handler.c +++ b/src/sgwc/sxa-handler.c @@ -1311,6 +1311,20 @@ void sgwc_sxa_handle_session_deletion_response( sgwc_sess_remove(sess); } +void sgwc_sxa_handle_session_set_deletion_response( + ogs_pfcp_xact_t *pfcp_xact, + ogs_pfcp_session_set_deletion_response_t *pfcp_rsp) +{ + ogs_debug("Session Set Deletion Response"); + + ogs_assert(pfcp_xact); + ogs_assert(pfcp_rsp); + + ogs_pfcp_xact_commit(pfcp_xact); + + return; +} + void sgwc_sxa_handle_session_report_request( sgwc_sess_t *sess, ogs_pfcp_xact_t *pfcp_xact, ogs_pfcp_session_report_request_t *pfcp_req) diff --git a/src/sgwc/sxa-handler.h b/src/sgwc/sxa-handler.h index 045f6bcf31..a4dd4bb4d3 100644 --- a/src/sgwc/sxa-handler.h +++ b/src/sgwc/sxa-handler.h @@ -38,6 +38,9 @@ void sgwc_sxa_handle_session_deletion_response( sgwc_sess_t *sess, ogs_pfcp_xact_t *pfcp_xact, ogs_gtp2_message_t *gtp_message, ogs_pfcp_session_deletion_response_t *pfcp_rsp); +void sgwc_sxa_handle_session_set_deletion_response( + ogs_pfcp_xact_t *pfcp_xact, + ogs_pfcp_session_set_deletion_response_t *pfcp_rsp); void sgwc_sxa_handle_session_report_request( sgwc_sess_t *sess, ogs_pfcp_xact_t *pfcp_xact, ogs_pfcp_session_report_request_t *pfcp_req); diff --git a/src/sgwu/pfcp-sm.c b/src/sgwu/pfcp-sm.c index 7d8d7cb065..5b8128ab36 100644 --- a/src/sgwu/pfcp-sm.c +++ b/src/sgwu/pfcp-sm.c @@ -225,6 +225,10 @@ void sgwu_pfcp_state_associated(ogs_fsm_t *s, sgwu_event_t *e) sgwu_sxa_handle_session_report_response( sess, xact, &message->pfcp_session_report_response); break; + case OGS_PFCP_SESSION_SET_DELETION_REQUEST_TYPE: + sgwu_sxa_handle_session_set_deletion_request( + node, xact, &message->pfcp_session_set_deletion_request); + break; default: ogs_error("Not implemented PFCP message type[%d]", message->h.type); diff --git a/src/sgwu/sxa-handler.c b/src/sgwu/sxa-handler.c index b000626d64..b4d5112a39 100644 --- a/src/sgwu/sxa-handler.c +++ b/src/sgwu/sxa-handler.c @@ -410,6 +410,26 @@ void sgwu_sxa_handle_session_deletion_request( sgwu_sess_remove(sess); } +void sgwu_sxa_handle_session_set_deletion_request( + ogs_pfcp_node_t *node, ogs_pfcp_xact_t *xact, + ogs_pfcp_session_set_deletion_request_t *req) +{ + sgwu_sess_t *sess = NULL, *next = NULL;; + ogs_assert(node); + ogs_assert(xact); + ogs_assert(req); + + ogs_debug("Session Set Deletion Request"); + + ogs_list_for_each_safe(&sgwu_self()->sess_list, next, sess) { + if (sess->pfcp_node == node) { + sgwu_sess_remove(sess); + } + } + + ogs_pfcp_up_send_session_set_deletion_response(xact, OGS_PFCP_CAUSE_REQUEST_ACCEPTED); +} + void sgwu_sxa_handle_session_report_response( sgwu_sess_t *sess, ogs_pfcp_xact_t *xact, ogs_pfcp_session_report_response_t *rsp) diff --git a/src/sgwu/sxa-handler.h b/src/sgwu/sxa-handler.h index 5ceec47eb9..c864b9fc37 100644 --- a/src/sgwu/sxa-handler.h +++ b/src/sgwu/sxa-handler.h @@ -35,6 +35,9 @@ void sgwu_sxa_handle_session_modification_request( void sgwu_sxa_handle_session_deletion_request( sgwu_sess_t *sess, ogs_pfcp_xact_t *xact, ogs_pfcp_session_deletion_request_t *req); +void sgwu_sxa_handle_session_set_deletion_request( + ogs_pfcp_node_t *node, ogs_pfcp_xact_t *xact, + ogs_pfcp_session_set_deletion_request_t *req); void sgwu_sxa_handle_session_report_response( sgwu_sess_t *sess, ogs_pfcp_xact_t *xact, diff --git a/src/smf/n4-handler.c b/src/smf/n4-handler.c index 96d9fd468e..7302ff5e43 100644 --- a/src/smf/n4-handler.c +++ b/src/smf/n4-handler.c @@ -1099,6 +1099,19 @@ uint8_t smf_epc_n4_handle_session_deletion_response( return OGS_PFCP_CAUSE_REQUEST_ACCEPTED; } +void smf_epc_n4_handle_session_set_deletion_response( + ogs_pfcp_xact_t *xact, ogs_pfcp_session_set_deletion_response_t *rsp) +{ + ogs_debug("Session Set Deletion Response"); + + ogs_assert(xact); + ogs_assert(rsp); + + ogs_pfcp_xact_commit(xact); + + return; +} + void smf_n4_handle_session_report_request( smf_sess_t *sess, ogs_pfcp_xact_t *pfcp_xact, ogs_pfcp_session_report_request_t *pfcp_req) diff --git a/src/smf/n4-handler.h b/src/smf/n4-handler.h index 76a257d129..cc23636c79 100644 --- a/src/smf/n4-handler.h +++ b/src/smf/n4-handler.h @@ -46,6 +46,8 @@ void smf_epc_n4_handle_session_modification_response( uint8_t smf_epc_n4_handle_session_deletion_response( smf_sess_t *sess, ogs_pfcp_xact_t *xact, ogs_pfcp_session_deletion_response_t *rsp); +void smf_epc_n4_handle_session_set_deletion_response( + ogs_pfcp_xact_t *xact, ogs_pfcp_session_set_deletion_response_t *rsp); void smf_n4_handle_session_report_request( smf_sess_t *sess, ogs_pfcp_xact_t *pfcp_xact, diff --git a/src/smf/pfcp-sm.c b/src/smf/pfcp-sm.c index de2fdd4a1d..d609406507 100644 --- a/src/smf/pfcp-sm.c +++ b/src/smf/pfcp-sm.c @@ -275,6 +275,11 @@ void smf_pfcp_state_associated(ogs_fsm_t *s, smf_event_t *e) ogs_fsm_dispatch(&sess->sm, e); break; + case OGS_PFCP_SESSION_SET_DELETION_RESPONSE_TYPE: + smf_epc_n4_handle_session_set_deletion_response( + xact, &message->pfcp_session_set_deletion_response); + break; + case OGS_PFCP_SESSION_REPORT_REQUEST_TYPE: if (!message->h.seid_presence) ogs_error("No SEID"); diff --git a/src/upf/n4-handler.c b/src/upf/n4-handler.c index cbfe63c4fc..e34669f1ba 100644 --- a/src/upf/n4-handler.c +++ b/src/upf/n4-handler.c @@ -471,6 +471,26 @@ void upf_n4_handle_session_deletion_request( upf_sess_remove(sess); } +void upf_n4_handle_session_set_deletion_request( + ogs_pfcp_node_t *node, ogs_pfcp_xact_t *xact, + ogs_pfcp_session_set_deletion_request_t *req) +{ + upf_sess_t *sess = NULL, *next = NULL;; + ogs_assert(node); + ogs_assert(xact); + ogs_assert(req); + + ogs_debug("Session Set Deletion Request"); + + ogs_list_for_each_safe(&upf_self()->sess_list, next, sess) { + if (sess->pfcp_node == node) { + upf_sess_remove(sess); + } + } + + ogs_pfcp_up_send_session_set_deletion_response(xact, OGS_PFCP_CAUSE_REQUEST_ACCEPTED); +} + void upf_n4_handle_session_report_response( upf_sess_t *sess, ogs_pfcp_xact_t *xact, ogs_pfcp_session_report_response_t *rsp) diff --git a/src/upf/n4-handler.h b/src/upf/n4-handler.h index 09a46b404d..5386ad3a65 100644 --- a/src/upf/n4-handler.h +++ b/src/upf/n4-handler.h @@ -35,6 +35,9 @@ void upf_n4_handle_session_modification_request( void upf_n4_handle_session_deletion_request( upf_sess_t *sess, ogs_pfcp_xact_t *xact, ogs_pfcp_session_deletion_request_t *req); +void upf_n4_handle_session_set_deletion_request( + ogs_pfcp_node_t *node, ogs_pfcp_xact_t *xact, + ogs_pfcp_session_set_deletion_request_t *req); void upf_n4_handle_session_report_response( upf_sess_t *sess, ogs_pfcp_xact_t *xact, diff --git a/src/upf/pfcp-sm.c b/src/upf/pfcp-sm.c index c4c3e10fe5..dcf71b59f3 100644 --- a/src/upf/pfcp-sm.c +++ b/src/upf/pfcp-sm.c @@ -226,6 +226,10 @@ void upf_pfcp_state_associated(ogs_fsm_t *s, upf_event_t *e) upf_n4_handle_session_deletion_request( sess, xact, &message->pfcp_session_deletion_request); break; + case OGS_PFCP_SESSION_SET_DELETION_REQUEST_TYPE: + upf_n4_handle_session_set_deletion_request( + node, xact, &message->pfcp_session_set_deletion_request); + break; case OGS_PFCP_SESSION_REPORT_RESPONSE_TYPE: upf_n4_handle_session_report_response( sess, xact, &message->pfcp_session_report_response);