diff --git a/src/sgwu/context.c b/src/sgwu/context.c index 62b4796b7..6f83150ce 100644 --- a/src/sgwu/context.c +++ b/src/sgwu/context.c @@ -44,8 +44,10 @@ void sgwu_context_init(void) ogs_list_init(&self.sess_list); ogs_pool_init(&sgwu_sess_pool, ogs_app()->pool.sess); - self.sess_hash = ogs_hash_make(); - ogs_assert(self.sess_hash); + self.seid_hash = ogs_hash_make(); + ogs_assert(self.seid_hash); + self.f_seid_hash = ogs_hash_make(); + ogs_assert(self.f_seid_hash); context_initialized = 1; } @@ -56,8 +58,10 @@ void sgwu_context_final(void) sgwu_sess_remove_all(); - ogs_assert(self.sess_hash); - ogs_hash_destroy(self.sess_hash); + ogs_assert(self.seid_hash); + ogs_hash_destroy(self.seid_hash); + ogs_assert(self.f_seid_hash); + ogs_hash_destroy(self.f_seid_hash); ogs_pool_final(&sgwu_sess_pool); @@ -137,12 +141,21 @@ sgwu_sess_t *sgwu_sess_add(ogs_pfcp_f_seid_t *cp_f_seid) ogs_assert(sess->index > 0 && sess->index <= ogs_app()->pool.sess); sess->sgwu_sxa_seid = sess->index; - sess->sgwc_sxa_seid = cp_f_seid->seid; - ogs_hash_set(self.sess_hash, &sess->sgwc_sxa_seid, - sizeof(sess->sgwc_sxa_seid), sess); + + /* Since F-SEID is composed of ogs_ip_t and uint64-seid, + * all these values must be put into the structure-sgwc_sxa_f_eid + * before creating hash */ + sess->sgwc_sxa_f_seid.seid = cp_f_seid->seid; + ogs_assert(OGS_OK == + ogs_pfcp_f_seid_to_ip(cp_f_seid, &sess->sgwc_sxa_f_seid.ip)); + + ogs_hash_set(self.f_seid_hash, &sess->sgwc_sxa_f_seid, + sizeof(sess->sgwc_sxa_f_seid), sess); + ogs_hash_set(self.seid_hash, &sess->sgwc_sxa_f_seid.seid, + sizeof(sess->sgwc_sxa_f_seid.seid), sess); ogs_info("UE F-SEID[CP:0x%lx UP:0x%lx]", - (long)sess->sgwu_sxa_seid, (long)sess->sgwc_sxa_seid); + (long)sess->sgwu_sxa_seid, (long)sess->sgwc_sxa_f_seid.seid); ogs_list_add(&self.sess_list, sess); @@ -159,8 +172,10 @@ int sgwu_sess_remove(sgwu_sess_t *sess) ogs_list_remove(&self.sess_list, sess); ogs_pfcp_sess_clear(&sess->pfcp); - ogs_hash_set(self.sess_hash, &sess->sgwc_sxa_seid, - sizeof(sess->sgwc_sxa_seid), NULL); + ogs_hash_set(self.seid_hash, &sess->sgwc_sxa_f_seid.seid, + sizeof(sess->sgwc_sxa_f_seid.seid), NULL); + ogs_hash_set(self.f_seid_hash, &sess->sgwc_sxa_f_seid, + sizeof(sess->sgwc_sxa_f_seid), NULL); ogs_pfcp_pool_final(&sess->pfcp); @@ -186,12 +201,26 @@ sgwu_sess_t *sgwu_sess_find(uint32_t index) return ogs_pool_find(&sgwu_sess_pool, index); } -sgwu_sess_t *sgwu_sess_find_by_cp_seid(uint64_t seid) +sgwu_sess_t *sgwu_sess_find_by_sgwc_sxa_seid(uint64_t seid) { - return (sgwu_sess_t *)ogs_hash_get(self.sess_hash, &seid, sizeof(seid)); + return (sgwu_sess_t *)ogs_hash_get(self.seid_hash, &seid, sizeof(seid)); } -sgwu_sess_t *sgwu_sess_find_by_up_seid(uint64_t seid) +sgwu_sess_t *sgwu_sess_find_by_sgwc_sxa_f_seid(ogs_pfcp_f_seid_t *f_seid) +{ + struct { + uint64_t seid; + ogs_ip_t ip; + } key; + + ogs_assert(f_seid); + ogs_assert(OGS_OK == ogs_pfcp_f_seid_to_ip(f_seid, &key.ip)); + key.seid = f_seid->seid; + + return (sgwu_sess_t *)ogs_hash_get(self.f_seid_hash, &key, sizeof(key)); +} + +sgwu_sess_t *sgwu_sess_find_by_sgwu_sxa_seid(uint64_t seid) { return sgwu_sess_find(seid); } @@ -212,7 +241,7 @@ sgwu_sess_t *sgwu_sess_add_by_message(ogs_pfcp_message_t *message) } f_seid->seid = be64toh(f_seid->seid); - sess = sgwu_sess_find_by_cp_seid(f_seid->seid); + sess = sgwu_sess_find_by_sgwc_sxa_f_seid(f_seid); if (!sess) { sess = sgwu_sess_add(f_seid); if (!sess) return NULL; diff --git a/src/sgwu/context.h b/src/sgwu/context.h index 5fd36fc3c..723adc71b 100644 --- a/src/sgwu/context.h +++ b/src/sgwu/context.h @@ -37,7 +37,9 @@ extern int __sgwu_log_domain; #define OGS_LOG_DOMAIN __sgwu_log_domain typedef struct sgwu_context_s { - ogs_hash_t *sess_hash; /* hash table (F-SEID) */ + ogs_hash_t *seid_hash; /* hash table (SEID) */ + ogs_hash_t *f_seid_hash; /* hash table (F-SEID) */ + ogs_list_t sess_list; } sgwu_context_t; @@ -49,7 +51,10 @@ typedef struct sgwu_sess_s { ogs_pfcp_sess_t pfcp; uint64_t sgwu_sxa_seid; /* SGW-U SEID is dervied from INDEX */ - uint64_t sgwc_sxa_seid; /* SGW-C SEID is received from Peer */ + struct { + uint64_t seid; + ogs_ip_t ip; + } sgwc_sxa_f_seid; /* SGW-C SEID is received from Peer */ ogs_pfcp_node_t *pfcp_node; } sgwu_sess_t; @@ -66,8 +71,9 @@ sgwu_sess_t *sgwu_sess_add(ogs_pfcp_f_seid_t *f_seid); int sgwu_sess_remove(sgwu_sess_t *sess); void sgwu_sess_remove_all(void); sgwu_sess_t *sgwu_sess_find(uint32_t index); -sgwu_sess_t *sgwu_sess_find_by_cp_seid(uint64_t seid); -sgwu_sess_t *sgwu_sess_find_by_up_seid(uint64_t seid); +sgwu_sess_t *sgwu_sess_find_by_sgwc_sxa_seid(uint64_t seid); +sgwu_sess_t *sgwu_sess_find_by_sgwc_sxa_f_seid(ogs_pfcp_f_seid_t *f_seid); +sgwu_sess_t *sgwu_sess_find_by_sgwu_sxa_seid(uint64_t seid); #ifdef __cplusplus } diff --git a/src/sgwu/pfcp-path.c b/src/sgwu/pfcp-path.c index 4feb127d2..4ed17d9f0 100644 --- a/src/sgwu/pfcp-path.c +++ b/src/sgwu/pfcp-path.c @@ -174,7 +174,7 @@ int sgwu_pfcp_send_session_establishment_response( memset(&h, 0, sizeof(ogs_pfcp_header_t)); h.type = OGS_PFCP_SESSION_ESTABLISHMENT_RESPONSE_TYPE; - h.seid = sess->sgwc_sxa_seid; + h.seid = sess->sgwc_sxa_f_seid.seid; sxabuf = sgwu_sxa_build_session_establishment_response( h.type, sess, created_pdr, num_of_created_pdr); @@ -202,7 +202,7 @@ int sgwu_pfcp_send_session_modification_response( memset(&h, 0, sizeof(ogs_pfcp_header_t)); h.type = OGS_PFCP_SESSION_MODIFICATION_RESPONSE_TYPE; - h.seid = sess->sgwc_sxa_seid; + h.seid = sess->sgwc_sxa_f_seid.seid; sxabuf = sgwu_sxa_build_session_modification_response( h.type, sess, created_pdr, num_of_created_pdr); @@ -228,7 +228,7 @@ int sgwu_pfcp_send_session_deletion_response(ogs_pfcp_xact_t *xact, memset(&h, 0, sizeof(ogs_pfcp_header_t)); h.type = OGS_PFCP_SESSION_DELETION_RESPONSE_TYPE; - h.seid = sess->sgwc_sxa_seid; + h.seid = sess->sgwc_sxa_f_seid.seid; sxabuf = sgwu_sxa_build_session_deletion_response(h.type, sess); ogs_expect_or_return_val(sxabuf, OGS_ERROR); @@ -272,7 +272,7 @@ int sgwu_pfcp_send_session_report_request( memset(&h, 0, sizeof(ogs_pfcp_header_t)); h.type = OGS_PFCP_SESSION_REPORT_REQUEST_TYPE; - h.seid = sess->sgwc_sxa_seid; + h.seid = sess->sgwc_sxa_f_seid.seid; xact = ogs_pfcp_xact_local_create(sess->pfcp_node, sess_timeout, sess); ogs_expect_or_return_val(xact, OGS_ERROR); diff --git a/src/sgwu/pfcp-sm.c b/src/sgwu/pfcp-sm.c index 5eb64079a..c7513acef 100644 --- a/src/sgwu/pfcp-sm.c +++ b/src/sgwu/pfcp-sm.c @@ -180,7 +180,7 @@ void sgwu_pfcp_state_associated(ogs_fsm_t *s, sgwu_event_t *e) ogs_assert(xact); if (message->h.seid_presence && message->h.seid != 0) - sess = sgwu_sess_find_by_up_seid(message->h.seid); + sess = sgwu_sess_find_by_sgwu_sxa_seid(message->h.seid); switch (message->h.type) { case OGS_PFCP_HEARTBEAT_REQUEST_TYPE: diff --git a/src/smf/binding.c b/src/smf/binding.c index 9637831ef..7c49695a9 100644 --- a/src/smf/binding.c +++ b/src/smf/binding.c @@ -47,7 +47,7 @@ static void gtp_bearer_timeout(ogs_gtp_xact_t *xact, void *data) break; } ogs_assert(OGS_OK == - smf_epc_pfcp_send_bearer_modification_request( + smf_epc_pfcp_send_one_bearer_modification_request( bearer, NULL, OGS_PFCP_MODIFY_REMOVE, OGS_NAS_PROCEDURE_TRANSACTION_IDENTITY_UNASSIGNED, OGS_GTP2_CAUSE_UNDEFINED_VALUE)); @@ -325,7 +325,7 @@ void smf_bearer_binding(smf_sess_t *sess) smf_bearer_qos_update(bearer); ogs_assert(OGS_OK == - smf_epc_pfcp_send_bearer_modification_request( + smf_epc_pfcp_send_one_bearer_modification_request( bearer, NULL, OGS_PFCP_MODIFY_CREATE, OGS_NAS_PROCEDURE_TRANSACTION_IDENTITY_UNASSIGNED, OGS_GTP2_CAUSE_UNDEFINED_VALUE)); @@ -383,7 +383,7 @@ void smf_bearer_binding(smf_sess_t *sess) * forwarding downlink packets for the affected bearer(s). */ ogs_assert(OGS_OK == - smf_epc_pfcp_send_bearer_modification_request( + smf_epc_pfcp_send_one_bearer_modification_request( bearer, NULL, OGS_PFCP_MODIFY_DL_ONLY|OGS_PFCP_MODIFY_DEACTIVATE, OGS_NAS_PROCEDURE_TRANSACTION_IDENTITY_UNASSIGNED, @@ -665,7 +665,7 @@ void smf_qos_flow_binding(smf_sess_t *sess) if (ogs_list_count(&sess->qos_flow_to_modify_list)) { ogs_assert(OGS_OK == - smf_5gc_pfcp_send_session_modification_request( + smf_5gc_pfcp_send_qos_flow_list_modification_request( sess, NULL, pfcp_flags, 0)); } } diff --git a/src/smf/gn-handler.c b/src/smf/gn-handler.c index fea5bef85..b89929421 100644 --- a/src/smf/gn-handler.c +++ b/src/smf/gn-handler.c @@ -413,7 +413,7 @@ void smf_gn_handle_update_pdp_context_request( } } - rv = smf_epc_pfcp_send_pdr_modification_request(sess, xact, NULL, + rv = smf_epc_pfcp_send_all_pdr_modification_request(sess, xact, NULL, OGS_PFCP_MODIFY_DL_ONLY|OGS_PFCP_MODIFY_ACTIVATE, OGS_NAS_PROCEDURE_TRANSACTION_IDENTITY_UNASSIGNED, OGS_GTP1_CAUSE_REACTIACTION_REQUESTED); diff --git a/src/smf/gsm-handler.c b/src/smf/gsm-handler.c index a91f9304d..30d148605 100644 --- a/src/smf/gsm-handler.c +++ b/src/smf/gsm-handler.c @@ -520,7 +520,7 @@ int gsm_handle_pdu_session_modification_request( } ogs_assert(OGS_OK == - smf_5gc_pfcp_send_session_modification_request( + smf_5gc_pfcp_send_qos_flow_list_modification_request( sess, stream, OGS_PFCP_MODIFY_UE_REQUESTED|pfcp_flags, 0)); diff --git a/src/smf/gtp-path.c b/src/smf/gtp-path.c index b2d8bcc74..102454927 100644 --- a/src/smf/gtp-path.c +++ b/src/smf/gtp-path.c @@ -705,7 +705,7 @@ static void bearer_timeout(ogs_gtp_xact_t *xact, void *data) } ogs_assert(OGS_OK == - smf_epc_pfcp_send_bearer_modification_request( + smf_epc_pfcp_send_one_bearer_modification_request( bearer, NULL, OGS_PFCP_MODIFY_REMOVE, OGS_NAS_PROCEDURE_TRANSACTION_IDENTITY_UNASSIGNED, OGS_GTP2_CAUSE_UNDEFINED_VALUE)); diff --git a/src/smf/gy-handler.c b/src/smf/gy-handler.c index e8a703802..af8b463a2 100644 --- a/src/smf/gy-handler.c +++ b/src/smf/gy-handler.c @@ -174,7 +174,7 @@ void smf_gy_handle_cca_update_request( /* Send PFCP Session Modification Request if we need to update the params. */ if (modify_flags) { modify_flags |= OGS_PFCP_MODIFY_URR|OGS_PFCP_MODIFY_UL_ONLY; - rv = smf_epc_pfcp_send_pdr_modification_request( + rv = smf_epc_pfcp_send_all_pdr_modification_request( sess, pfcp_xact, NULL, modify_flags, OGS_NAS_PROCEDURE_TRANSACTION_IDENTITY_UNASSIGNED, OGS_GTP1_CAUSE_REACTIACTION_REQUESTED); diff --git a/src/smf/n4-handler.c b/src/smf/n4-handler.c index 5fef8a3f1..0aa4d6643 100644 --- a/src/smf/n4-handler.c +++ b/src/smf/n4-handler.c @@ -265,7 +265,7 @@ void smf_5gc_n4_handle_session_modification_response( stream = xact->assoc_stream; if (flags & OGS_PFCP_MODIFY_SESSION) { - /* If smf_5gc_pfcp_send_pdr_modification_request() is called */ + /* If smf_5gc_pfcp_send_all_pdr_modification_request() is called */ } else { /* If smf_5gc_pfcp_send_qos_flow_modification_request() is called */ @@ -390,7 +390,7 @@ void smf_5gc_n4_handle_session_modification_response( if (smf_sess_have_indirect_data_forwarding(sess) == true) { ogs_assert(OGS_OK == - smf_5gc_pfcp_send_pdr_modification_request( + smf_5gc_pfcp_send_all_pdr_modification_request( sess, stream, OGS_PFCP_MODIFY_INDIRECT|OGS_PFCP_MODIFY_REMOVE, ogs_app()->time.handover.duration)); @@ -444,7 +444,7 @@ void smf_5gc_n4_handle_session_modification_response( smf_sess_create_indirect_data_forwarding(sess); ogs_assert(OGS_OK == - smf_5gc_pfcp_send_pdr_modification_request( + smf_5gc_pfcp_send_all_pdr_modification_request( sess, stream, OGS_PFCP_MODIFY_INDIRECT|OGS_PFCP_MODIFY_CREATE, 0)); @@ -1219,7 +1219,7 @@ void smf_n4_handle_session_report_request( if (error_indication_session) { ogs_assert(OGS_OK == - smf_5gc_pfcp_send_pdr_modification_request( + smf_5gc_pfcp_send_all_pdr_modification_request( error_indication_session, NULL, OGS_PFCP_MODIFY_DL_ONLY|OGS_PFCP_MODIFY_DEACTIVATE| OGS_PFCP_MODIFY_ERROR_INDICATION, diff --git a/src/smf/ngap-handler.c b/src/smf/ngap-handler.c index 0f2f1ff9e..f96ce849c 100644 --- a/src/smf/ngap-handler.c +++ b/src/smf/ngap-handler.c @@ -147,7 +147,7 @@ int ngap_handle_pdu_session_resource_setup_response_transfer( if (far_update) { ogs_assert(OGS_OK == - smf_5gc_pfcp_send_pdr_modification_request( + smf_5gc_pfcp_send_all_pdr_modification_request( sess, stream, OGS_PFCP_MODIFY_DL_ONLY|OGS_PFCP_MODIFY_ACTIVATE, 0)); } else { @@ -247,7 +247,7 @@ int ngap_handle_pdu_session_resource_setup_unsuccessful_transfer( */ ogs_assert(OGS_OK == - smf_5gc_pfcp_send_pdr_modification_request( + smf_5gc_pfcp_send_all_pdr_modification_request( sess, stream, OGS_PFCP_MODIFY_DL_ONLY|OGS_PFCP_MODIFY_DEACTIVATE, 0)); @@ -345,7 +345,7 @@ int ngap_handle_pdu_session_resource_modify_response_transfer( } ogs_assert(OGS_OK == - smf_5gc_pfcp_send_session_modification_request( + smf_5gc_pfcp_send_qos_flow_list_modification_request( sess, stream, OGS_PFCP_MODIFY_DL_ONLY|OGS_PFCP_MODIFY_ACTIVATE, 0)); @@ -474,7 +474,7 @@ int ngap_handle_path_switch_request_transfer( if (far_update) { ogs_assert(OGS_OK == - smf_5gc_pfcp_send_pdr_modification_request( + smf_5gc_pfcp_send_all_pdr_modification_request( sess, stream, OGS_PFCP_MODIFY_DL_ONLY|OGS_PFCP_MODIFY_ACTIVATE| OGS_PFCP_MODIFY_XN_HANDOVER|OGS_PFCP_MODIFY_END_MARKER, @@ -683,7 +683,7 @@ int ngap_handle_handover_request_ack( ogs_error("It will be automatically removed"); ogs_assert(OGS_OK == - smf_5gc_pfcp_send_pdr_modification_request( + smf_5gc_pfcp_send_all_pdr_modification_request( sess, stream, OGS_PFCP_MODIFY_INDIRECT| /* @@ -705,7 +705,7 @@ int ngap_handle_handover_request_ack( smf_sess_create_indirect_data_forwarding(sess); ogs_assert(OGS_OK == - smf_5gc_pfcp_send_pdr_modification_request( + smf_5gc_pfcp_send_all_pdr_modification_request( sess, stream, OGS_PFCP_MODIFY_INDIRECT|OGS_PFCP_MODIFY_CREATE, 0)); diff --git a/src/smf/nsmf-handler.c b/src/smf/nsmf-handler.c index 44d1eba99..d47f0ea0b 100644 --- a/src/smf/nsmf-handler.c +++ b/src/smf/nsmf-handler.c @@ -370,7 +370,7 @@ bool smf_nsmf_handle_update_sm_context( sess, stream, OpenAPI_up_cnx_state_DEACTIVATED); } else { ogs_assert(OGS_OK == - smf_5gc_pfcp_send_pdr_modification_request( + smf_5gc_pfcp_send_all_pdr_modification_request( sess, stream, OGS_PFCP_MODIFY_DL_ONLY|OGS_PFCP_MODIFY_DEACTIVATE, 0)); } @@ -506,7 +506,7 @@ bool smf_nsmf_handle_update_sm_context( if (far_update) { ogs_assert(OGS_OK == - smf_5gc_pfcp_send_pdr_modification_request( + smf_5gc_pfcp_send_all_pdr_modification_request( sess, stream, OGS_PFCP_MODIFY_DL_ONLY|OGS_PFCP_MODIFY_ACTIVATE| OGS_PFCP_MODIFY_N2_HANDOVER|OGS_PFCP_MODIFY_END_MARKER, @@ -539,7 +539,7 @@ bool smf_nsmf_handle_update_sm_context( if (smf_sess_have_indirect_data_forwarding(sess) == true) { ogs_assert(OGS_OK == - smf_5gc_pfcp_send_pdr_modification_request( + smf_5gc_pfcp_send_all_pdr_modification_request( sess, stream, OGS_PFCP_MODIFY_INDIRECT|OGS_PFCP_MODIFY_REMOVE| OGS_PFCP_MODIFY_HANDOVER_CANCEL, diff --git a/src/smf/pfcp-path.c b/src/smf/pfcp-path.c index 39513dd99..b306dd0da 100644 --- a/src/smf/pfcp-path.c +++ b/src/smf/pfcp-path.c @@ -321,29 +321,7 @@ int smf_5gc_pfcp_send_session_establishment_request( return rv; } -int smf_5gc_pfcp_send_session_modification_request( - smf_sess_t *sess, ogs_sbi_stream_t *stream, - uint64_t flags, ogs_time_t duration) -{ - int rv; - ogs_pfcp_xact_t *xact = NULL; - - ogs_assert(sess); - - xact = ogs_pfcp_xact_local_create(sess->pfcp_node, sess_5gc_timeout, sess); - ogs_expect_or_return_val(xact, OGS_ERROR); - - xact->assoc_stream = stream; - xact->modify_flags = flags | OGS_PFCP_MODIFY_SESSION; - - rv = smf_pfcp_send_modify_list( - sess, smf_n4_build_qos_flow_to_modify_list, xact, duration); - ogs_expect(rv == OGS_OK); - - return rv; -} - -int smf_5gc_pfcp_send_pdr_modification_request( +int smf_5gc_pfcp_send_all_pdr_modification_request( smf_sess_t *sess, ogs_sbi_stream_t *stream, uint64_t flags, ogs_time_t duration) { @@ -372,6 +350,28 @@ int smf_5gc_pfcp_send_pdr_modification_request( return rv; } +int smf_5gc_pfcp_send_qos_flow_list_modification_request( + smf_sess_t *sess, ogs_sbi_stream_t *stream, + uint64_t flags, ogs_time_t duration) +{ + int rv; + ogs_pfcp_xact_t *xact = NULL; + + ogs_assert(sess); + + xact = ogs_pfcp_xact_local_create(sess->pfcp_node, sess_5gc_timeout, sess); + ogs_expect_or_return_val(xact, OGS_ERROR); + + xact->assoc_stream = stream; + xact->modify_flags = flags | OGS_PFCP_MODIFY_SESSION; + + rv = smf_pfcp_send_modify_list( + sess, smf_n4_build_qos_flow_to_modify_list, xact, duration); + ogs_expect(rv == OGS_OK); + + return rv; +} + int smf_5gc_pfcp_send_session_deletion_request( smf_sess_t *sess, ogs_sbi_stream_t *stream, int trigger) { @@ -437,68 +437,7 @@ int smf_epc_pfcp_send_session_establishment_request( return rv; } -int smf_epc_pfcp_send_session_modification_request( - smf_sess_t *sess, void *gtp_xact, - uint64_t flags, uint8_t gtp_pti, uint8_t gtp_cause, - ogs_time_t duration) -{ - int rv; - ogs_pfcp_xact_t *xact = NULL; - - ogs_assert(sess); - - xact = ogs_pfcp_xact_local_create( - sess->pfcp_node, sess_epc_timeout, sess); - ogs_expect_or_return_val(xact, OGS_ERROR); - - xact->epc = true; /* EPC PFCP transaction */ - xact->assoc_xact = gtp_xact; - xact->modify_flags = flags | OGS_PFCP_MODIFY_SESSION; - - xact->gtp_pti = gtp_pti; - xact->gtp_cause = gtp_cause; - - rv = smf_pfcp_send_modify_list( - sess, smf_n4_build_qos_flow_to_modify_list, xact, duration); - ogs_expect(rv == OGS_OK); - - return rv; -} - -int smf_epc_pfcp_send_bearer_modification_request( - smf_bearer_t *bearer, void *gtp_xact, - uint64_t flags, uint8_t gtp_pti, uint8_t gtp_cause) -{ - int rv; - ogs_pfcp_xact_t *xact = NULL; - smf_sess_t *sess = NULL; - - ogs_assert(bearer); - sess = bearer->sess; - ogs_assert(sess); - - xact = ogs_pfcp_xact_local_create( - sess->pfcp_node, bearer_epc_timeout, bearer); - ogs_expect_or_return_val(xact, OGS_ERROR); - - xact->epc = true; /* EPC PFCP transaction */ - xact->assoc_xact = gtp_xact; - xact->modify_flags = flags; - - xact->gtp_pti = gtp_pti; - xact->gtp_cause = gtp_cause; - - ogs_list_init(&sess->qos_flow_to_modify_list); - ogs_list_add(&sess->qos_flow_to_modify_list, &bearer->to_modify_node); - - rv = smf_pfcp_send_modify_list( - sess, smf_n4_build_qos_flow_to_modify_list, xact, 0); - ogs_expect(rv == OGS_OK); - - return rv; -} - -int smf_epc_pfcp_send_pdr_modification_request( +int smf_epc_pfcp_send_all_pdr_modification_request( smf_sess_t *sess, void *gtp_xact, ogs_pkbuf_t *gtpbuf, uint64_t flags, uint8_t gtp_pti, uint8_t gtp_cause) { @@ -533,6 +472,39 @@ int smf_epc_pfcp_send_pdr_modification_request( return rv; } +int smf_epc_pfcp_send_one_bearer_modification_request( + smf_bearer_t *bearer, void *gtp_xact, + uint64_t flags, uint8_t gtp_pti, uint8_t gtp_cause) +{ + int rv; + ogs_pfcp_xact_t *xact = NULL; + smf_sess_t *sess = NULL; + + ogs_assert(bearer); + sess = bearer->sess; + ogs_assert(sess); + + xact = ogs_pfcp_xact_local_create( + sess->pfcp_node, bearer_epc_timeout, bearer); + ogs_expect_or_return_val(xact, OGS_ERROR); + + xact->epc = true; /* EPC PFCP transaction */ + xact->assoc_xact = gtp_xact; + xact->modify_flags = flags; + + xact->gtp_pti = gtp_pti; + xact->gtp_cause = gtp_cause; + + ogs_list_init(&sess->qos_flow_to_modify_list); + ogs_list_add(&sess->qos_flow_to_modify_list, &bearer->to_modify_node); + + rv = smf_pfcp_send_modify_list( + sess, smf_n4_build_qos_flow_to_modify_list, xact, 0); + ogs_expect(rv == OGS_OK); + + return rv; +} + int smf_epc_pfcp_send_session_deletion_request( smf_sess_t *sess, void *gtp_xact) { @@ -607,7 +579,7 @@ int smf_epc_pfcp_send_deactivation(smf_sess_t *sess, uint8_t gtp_cause) ogs_list_first(&wlan_sess->bearer_list), OGS_ERROR); /* Deactivate WLAN Session */ - rv = smf_epc_pfcp_send_pdr_modification_request( + rv = smf_epc_pfcp_send_all_pdr_modification_request( wlan_sess, NULL, NULL, OGS_PFCP_MODIFY_DL_ONLY|OGS_PFCP_MODIFY_DEACTIVATE, OGS_NAS_PROCEDURE_TRANSACTION_IDENTITY_UNASSIGNED, @@ -624,7 +596,7 @@ int smf_epc_pfcp_send_deactivation(smf_sess_t *sess, uint8_t gtp_cause) ogs_list_first(&eutran_sess->bearer_list), OGS_ERROR); /* Deactivate EUTRAN Session */ - rv = smf_epc_pfcp_send_pdr_modification_request( + rv = smf_epc_pfcp_send_all_pdr_modification_request( eutran_sess, NULL, NULL, OGS_PFCP_MODIFY_DL_ONLY|OGS_PFCP_MODIFY_DEACTIVATE, OGS_NAS_PROCEDURE_TRANSACTION_IDENTITY_UNASSIGNED, diff --git a/src/smf/pfcp-path.h b/src/smf/pfcp-path.h index 37f8efeb5..2f023555d 100644 --- a/src/smf/pfcp-path.h +++ b/src/smf/pfcp-path.h @@ -37,10 +37,10 @@ int smf_pfcp_send_modify_list( int smf_5gc_pfcp_send_session_establishment_request( smf_sess_t *sess, ogs_sbi_stream_t *stream); -int smf_5gc_pfcp_send_session_modification_request( +int smf_5gc_pfcp_send_all_pdr_modification_request( smf_sess_t *sess, ogs_sbi_stream_t *stream, uint64_t flags, ogs_time_t duration); -int smf_5gc_pfcp_send_pdr_modification_request( +int smf_5gc_pfcp_send_qos_flow_list_modification_request( smf_sess_t *sess, ogs_sbi_stream_t *stream, uint64_t flags, ogs_time_t duration); int smf_5gc_pfcp_send_session_deletion_request( @@ -48,16 +48,12 @@ int smf_5gc_pfcp_send_session_deletion_request( int smf_epc_pfcp_send_session_establishment_request( smf_sess_t *sess, void *gtp_xact); -int smf_epc_pfcp_send_session_modification_request( - smf_sess_t *sess, void *gtp_xact, - uint64_t flags, uint8_t gtp_pti, uint8_t gtp_cause, - ogs_time_t duration); -int smf_epc_pfcp_send_bearer_modification_request( - smf_bearer_t *bearer, void *gtp_xact, - uint64_t flags, uint8_t gtp_pti, uint8_t gtp_cause); -int smf_epc_pfcp_send_pdr_modification_request( +int smf_epc_pfcp_send_all_pdr_modification_request( smf_sess_t *sess, void *gtp_xact, ogs_pkbuf_t *gtpbuf, uint64_t flags, uint8_t gtp_pti, uint8_t gtp_cause); +int smf_epc_pfcp_send_one_bearer_modification_request( + smf_bearer_t *bearer, void *gtp_xact, + uint64_t flags, uint8_t gtp_pti, uint8_t gtp_cause); int smf_epc_pfcp_send_session_deletion_request( smf_sess_t *sess, void *gtp_xact); diff --git a/src/smf/s5c-handler.c b/src/smf/s5c-handler.c index cbce269e4..066b8ef28 100644 --- a/src/smf/s5c-handler.c +++ b/src/smf/s5c-handler.c @@ -621,7 +621,7 @@ void smf_s5c_handle_create_bearer_response( if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) { ogs_assert(OGS_OK == - smf_epc_pfcp_send_bearer_modification_request( + smf_epc_pfcp_send_one_bearer_modification_request( bearer, NULL, OGS_PFCP_MODIFY_REMOVE, OGS_NAS_PROCEDURE_TRANSACTION_IDENTITY_UNASSIGNED, OGS_GTP2_CAUSE_UNDEFINED_VALUE)); @@ -678,7 +678,7 @@ void smf_s5c_handle_create_bearer_response( if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) { ogs_assert(OGS_OK == - smf_epc_pfcp_send_bearer_modification_request( + smf_epc_pfcp_send_one_bearer_modification_request( bearer, NULL, OGS_PFCP_MODIFY_REMOVE, OGS_NAS_PROCEDURE_TRANSACTION_IDENTITY_UNASSIGNED, OGS_GTP2_CAUSE_UNDEFINED_VALUE)); @@ -696,7 +696,7 @@ void smf_s5c_handle_create_bearer_response( if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) { ogs_error("GTP Failed [Bearer-CAUSE:%d]", cause_value); ogs_assert(OGS_OK == - smf_epc_pfcp_send_bearer_modification_request( + smf_epc_pfcp_send_one_bearer_modification_request( bearer, NULL, OGS_PFCP_MODIFY_REMOVE, OGS_NAS_PROCEDURE_TRANSACTION_IDENTITY_UNASSIGNED, OGS_GTP2_CAUSE_UNDEFINED_VALUE)); @@ -709,7 +709,7 @@ void smf_s5c_handle_create_bearer_response( if (cause_value != OGS_GTP2_CAUSE_REQUEST_ACCEPTED) { ogs_error("GTP Failed [CAUSE:%d]", cause_value); ogs_assert(OGS_OK == - smf_epc_pfcp_send_bearer_modification_request( + smf_epc_pfcp_send_one_bearer_modification_request( bearer, NULL, OGS_PFCP_MODIFY_REMOVE, OGS_NAS_PROCEDURE_TRANSACTION_IDENTITY_UNASSIGNED, OGS_GTP2_CAUSE_UNDEFINED_VALUE)); @@ -753,7 +753,7 @@ void smf_s5c_handle_create_bearer_response( dl_far->outer_header_creation.teid = bearer->sgw_s5u_teid; ogs_assert(OGS_OK == - smf_epc_pfcp_send_bearer_modification_request( + smf_epc_pfcp_send_one_bearer_modification_request( bearer, NULL, OGS_PFCP_MODIFY_ACTIVATE, OGS_NAS_PROCEDURE_TRANSACTION_IDENTITY_UNASSIGNED, OGS_GTP2_CAUSE_UNDEFINED_VALUE)); @@ -872,7 +872,7 @@ void smf_s5c_handle_update_bearer_response( if (pfcp_flags) ogs_assert(OGS_OK == - smf_epc_pfcp_send_bearer_modification_request( + smf_epc_pfcp_send_one_bearer_modification_request( bearer, NULL, pfcp_flags, OGS_NAS_PROCEDURE_TRANSACTION_IDENTITY_UNASSIGNED, OGS_GTP2_CAUSE_UNDEFINED_VALUE)); @@ -990,7 +990,7 @@ bool smf_s5c_handle_delete_bearer_response( sess->sgw_s5c_teid, sess->smf_n4_teid); ogs_assert(OGS_OK == - smf_epc_pfcp_send_bearer_modification_request( + smf_epc_pfcp_send_one_bearer_modification_request( bearer, NULL, OGS_PFCP_MODIFY_REMOVE, OGS_NAS_PROCEDURE_TRANSACTION_IDENTITY_UNASSIGNED, OGS_GTP2_CAUSE_UNDEFINED_VALUE)); @@ -1372,7 +1372,7 @@ void smf_s5c_handle_bearer_resource_command( * forwarding downlink packets for the affected bearer(s). */ ogs_assert(OGS_OK == - smf_epc_pfcp_send_bearer_modification_request( + smf_epc_pfcp_send_one_bearer_modification_request( bearer, xact, OGS_PFCP_MODIFY_DL_ONLY|OGS_PFCP_MODIFY_DEACTIVATE, cmd->procedure_transaction_id.u8, diff --git a/src/upf/context.c b/src/upf/context.c index e74590429..192559631 100644 --- a/src/upf/context.c +++ b/src/upf/context.c @@ -48,8 +48,10 @@ void upf_context_init(void) ogs_list_init(&self.sess_list); ogs_pool_init(&upf_sess_pool, ogs_app()->pool.sess); - self.sess_hash = ogs_hash_make(); - ogs_assert(self.sess_hash); + self.seid_hash = ogs_hash_make(); + ogs_assert(self.seid_hash); + self.f_seid_hash = ogs_hash_make(); + ogs_assert(self.f_seid_hash); self.ipv4_hash = ogs_hash_make(); ogs_assert(self.ipv4_hash); self.ipv6_hash = ogs_hash_make(); @@ -64,8 +66,10 @@ void upf_context_final(void) upf_sess_remove_all(); - ogs_assert(self.sess_hash); - ogs_hash_destroy(self.sess_hash); + ogs_assert(self.seid_hash); + ogs_hash_destroy(self.seid_hash); + ogs_assert(self.f_seid_hash); + ogs_hash_destroy(self.f_seid_hash); ogs_assert(self.ipv4_hash); ogs_hash_destroy(self.ipv4_hash); ogs_assert(self.ipv6_hash); @@ -155,9 +159,18 @@ upf_sess_t *upf_sess_add(ogs_pfcp_f_seid_t *cp_f_seid) ogs_assert(sess->index > 0 && sess->index <= ogs_app()->pool.sess); sess->upf_n4_seid = sess->index; - sess->smf_n4_seid = cp_f_seid->seid; - ogs_hash_set(self.sess_hash, &sess->smf_n4_seid, - sizeof(sess->smf_n4_seid), sess); + + /* Since F-SEID is composed of ogs_ip_t and uint64-seid, + * all these values must be put into the structure-smf_n4_f_seid + * before creating hash */ + sess->smf_n4_f_seid.seid = cp_f_seid->seid; + ogs_assert(OGS_OK == + ogs_pfcp_f_seid_to_ip(cp_f_seid, &sess->smf_n4_f_seid.ip)); + + ogs_hash_set(self.f_seid_hash, &sess->smf_n4_f_seid, + sizeof(sess->smf_n4_f_seid), sess); + ogs_hash_set(self.seid_hash, &sess->smf_n4_f_seid.seid, + sizeof(sess->smf_n4_f_seid.seid), sess); ogs_list_add(&self.sess_list, sess); @@ -176,8 +189,10 @@ int upf_sess_remove(upf_sess_t *sess) ogs_list_remove(&self.sess_list, sess); ogs_pfcp_sess_clear(&sess->pfcp); - ogs_hash_set(self.sess_hash, &sess->smf_n4_seid, - sizeof(sess->smf_n4_seid), NULL); + ogs_hash_set(self.seid_hash, &sess->smf_n4_f_seid.seid, + sizeof(sess->smf_n4_f_seid.seid), NULL); + ogs_hash_set(self.f_seid_hash, &sess->smf_n4_f_seid, + sizeof(sess->smf_n4_f_seid), NULL); if (sess->ipv4) { ogs_hash_set(self.ipv4_hash, sess->ipv4->addr, OGS_IPV4_LEN, NULL); @@ -213,12 +228,26 @@ upf_sess_t *upf_sess_find(uint32_t index) return ogs_pool_find(&upf_sess_pool, index); } -upf_sess_t *upf_sess_find_by_cp_seid(uint64_t seid) +upf_sess_t *upf_sess_find_by_smf_n4_seid(uint64_t seid) { - return (upf_sess_t *)ogs_hash_get(self.sess_hash, &seid, sizeof(seid)); + return (upf_sess_t *)ogs_hash_get(self.seid_hash, &seid, sizeof(seid)); } -upf_sess_t *upf_sess_find_by_up_seid(uint64_t seid) +upf_sess_t *upf_sess_find_by_smf_n4_f_seid(ogs_pfcp_f_seid_t *f_seid) +{ + struct { + uint64_t seid; + ogs_ip_t ip; + } key; + + ogs_assert(f_seid); + ogs_assert(OGS_OK == ogs_pfcp_f_seid_to_ip(f_seid, &key.ip)); + key.seid = f_seid->seid; + + return (upf_sess_t *)ogs_hash_get(self.f_seid_hash, &key, sizeof(key)); +} + +upf_sess_t *upf_sess_find_by_upf_n4_seid(uint64_t seid) { return upf_sess_find(seid); } @@ -252,7 +281,7 @@ upf_sess_t *upf_sess_add_by_message(ogs_pfcp_message_t *message) } f_seid->seid = be64toh(f_seid->seid); - sess = upf_sess_find_by_cp_seid(f_seid->seid); + sess = upf_sess_find_by_smf_n4_f_seid(f_seid); if (!sess) { sess = upf_sess_add(f_seid); if (!sess) return NULL; @@ -366,7 +395,7 @@ uint8_t upf_sess_set_ue_ip(upf_sess_t *sess, ogs_info("UE F-SEID[CP:0x%lx UP:0x%lx] " "APN[%s] PDN-Type[%d] IPv4[%s] IPv6[%s]", - (long)sess->upf_n4_seid, (long)sess->smf_n4_seid, + (long)sess->upf_n4_seid, (long)sess->smf_n4_f_seid.seid, pdr->dnn, session_type, sess->ipv4 ? OGS_INET_NTOP(&sess->ipv4->addr, buf1) : "", sess->ipv6 ? OGS_INET6_NTOP(&sess->ipv6->addr, buf2) : ""); diff --git a/src/upf/context.h b/src/upf/context.h index 5f5da3741..dba0b155c 100644 --- a/src/upf/context.h +++ b/src/upf/context.h @@ -45,7 +45,8 @@ extern int __upf_log_domain; #define OGS_LOG_DOMAIN __upf_log_domain typedef struct upf_context_s { - ogs_hash_t *sess_hash; /* hash table (F-SEID) */ + ogs_hash_t *seid_hash; /* hash table (SEID) */ + ogs_hash_t *f_seid_hash; /* hash table (F-SEID) */ ogs_hash_t *ipv4_hash; /* hash table (IPv4 Address) */ ogs_hash_t *ipv6_hash; /* hash table (IPv6 Address) */ @@ -86,7 +87,10 @@ typedef struct upf_sess_s { ogs_pfcp_sess_t pfcp; uint64_t upf_n4_seid; /* UPF SEID is dervied from INDEX */ - uint64_t smf_n4_seid; /* SMF SEID is received from Peer */ + struct { + uint64_t seid; + ogs_ip_t ip; + } smf_n4_f_seid; /* SMF SEID is received from Peer */ /* APN Configuration */ ogs_pfcp_ue_ip_t *ipv4; @@ -111,8 +115,9 @@ upf_sess_t *upf_sess_add(ogs_pfcp_f_seid_t *f_seid); int upf_sess_remove(upf_sess_t *sess); void upf_sess_remove_all(void); upf_sess_t *upf_sess_find(uint32_t index); -upf_sess_t *upf_sess_find_by_cp_seid(uint64_t seid); -upf_sess_t *upf_sess_find_by_up_seid(uint64_t seid); +upf_sess_t *upf_sess_find_by_smf_n4_seid(uint64_t seid); +upf_sess_t *upf_sess_find_by_smf_n4_f_seid(ogs_pfcp_f_seid_t *f_seid); +upf_sess_t *upf_sess_find_by_upf_n4_seid(uint64_t seid); upf_sess_t *upf_sess_find_by_ipv4(uint32_t addr); upf_sess_t *upf_sess_find_by_ipv6(uint32_t *addr6); diff --git a/src/upf/n4-handler.c b/src/upf/n4-handler.c index b2de3bc61..327c13789 100644 --- a/src/upf/n4-handler.c +++ b/src/upf/n4-handler.c @@ -197,7 +197,7 @@ void upf_n4_handle_session_establishment_request( cleanup: ogs_pfcp_sess_clear(&sess->pfcp); - ogs_pfcp_send_error_message(xact, sess ? sess->smf_n4_seid : 0, + ogs_pfcp_send_error_message(xact, sess ? sess->smf_n4_f_seid.seid : 0, OGS_PFCP_SESSION_ESTABLISHMENT_RESPONSE_TYPE, cause_value, offending_ie_value); } @@ -432,7 +432,7 @@ void upf_n4_handle_session_modification_request( cleanup: ogs_pfcp_sess_clear(&sess->pfcp); - ogs_pfcp_send_error_message(xact, sess ? sess->smf_n4_seid : 0, + ogs_pfcp_send_error_message(xact, sess ? sess->smf_n4_f_seid.seid : 0, OGS_PFCP_SESSION_MODIFICATION_RESPONSE_TYPE, cause_value, offending_ie_value); } diff --git a/src/upf/pfcp-path.c b/src/upf/pfcp-path.c index 29bed3af4..184164534 100644 --- a/src/upf/pfcp-path.c +++ b/src/upf/pfcp-path.c @@ -177,7 +177,7 @@ int upf_pfcp_send_session_establishment_response( memset(&h, 0, sizeof(ogs_pfcp_header_t)); h.type = OGS_PFCP_SESSION_ESTABLISHMENT_RESPONSE_TYPE; - h.seid = sess->smf_n4_seid; + h.seid = sess->smf_n4_f_seid.seid; n4buf = upf_n4_build_session_establishment_response( h.type, sess, created_pdr, num_of_created_pdr); @@ -205,7 +205,7 @@ int upf_pfcp_send_session_modification_response( memset(&h, 0, sizeof(ogs_pfcp_header_t)); h.type = OGS_PFCP_SESSION_MODIFICATION_RESPONSE_TYPE; - h.seid = sess->smf_n4_seid; + h.seid = sess->smf_n4_f_seid.seid; n4buf = upf_n4_build_session_modification_response( h.type, sess, created_pdr, num_of_created_pdr); @@ -231,7 +231,7 @@ int upf_pfcp_send_session_deletion_response(ogs_pfcp_xact_t *xact, memset(&h, 0, sizeof(ogs_pfcp_header_t)); h.type = OGS_PFCP_SESSION_DELETION_RESPONSE_TYPE; - h.seid = sess->smf_n4_seid; + h.seid = sess->smf_n4_f_seid.seid; n4buf = upf_n4_build_session_deletion_response(h.type, sess); ogs_expect_or_return_val(n4buf, OGS_ERROR); @@ -275,7 +275,7 @@ int upf_pfcp_send_session_report_request( memset(&h, 0, sizeof(ogs_pfcp_header_t)); h.type = OGS_PFCP_SESSION_REPORT_REQUEST_TYPE; - h.seid = sess->smf_n4_seid; + h.seid = sess->smf_n4_f_seid.seid; xact = ogs_pfcp_xact_local_create(sess->pfcp_node, sess_timeout, sess); ogs_expect_or_return_val(xact, OGS_ERROR); diff --git a/src/upf/pfcp-sm.c b/src/upf/pfcp-sm.c index 82eeb05ad..6f890d392 100644 --- a/src/upf/pfcp-sm.c +++ b/src/upf/pfcp-sm.c @@ -185,7 +185,7 @@ void upf_pfcp_state_associated(ogs_fsm_t *s, upf_event_t *e) ogs_assert(xact); if (message->h.seid_presence && message->h.seid != 0) - sess = upf_sess_find_by_up_seid(message->h.seid); + sess = upf_sess_find_by_upf_n4_seid(message->h.seid); switch (message->h.type) { case OGS_PFCP_HEARTBEAT_REQUEST_TYPE: