From 79de674fd8f5154cc45ae5ad784ec5b18c1400b8 Mon Sep 17 00:00:00 2001 From: Sukchan Lee Date: Sat, 16 Apr 2022 14:08:56 +0900 Subject: [PATCH] [PFCP] F-TEID allocation by SMF (#1466) --- lib/core/ogs-3gpp-types.c | 8 ++++-- lib/core/ogs-3gpp-types.h | 2 +- lib/core/ogs-list.h | 5 ++++ lib/pfcp/build.c | 18 ++++++++---- lib/pfcp/build.h | 2 +- lib/pfcp/context.h | 2 ++ lib/pfcp/handler.c | 4 +-- lib/pfcp/xact.h | 2 ++ src/sgwc/context.c | 13 ++------- src/sgwc/pfcp-path.c | 14 ++++++++-- src/sgwc/sxa-build.c | 23 +++++++++++++--- src/sgwc/sxa-build.h | 6 ++-- src/sgwc/sxa-handler.c | 32 ++++++++++++---------- src/sgwu/gtp-path.c | 7 +---- src/sgwu/sxa-build.c | 16 +++++++---- src/smf/binding.c | 22 ++------------- src/smf/context.c | 42 ++++++++++++++++++++++------ src/smf/gx-handler.c | 17 ++++-------- src/smf/n4-build.c | 36 ++++++++++++++++++++---- src/smf/n4-build.h | 6 ++-- src/smf/n4-handler.c | 50 +++++++++++++++++++--------------- src/smf/ngap-build.c | 11 ++++---- src/smf/npcf-handler.c | 17 ++++-------- src/smf/pfcp-path.c | 28 ++++++++++++++++--- src/upf/gtp-path.c | 2 +- src/upf/n4-build.c | 16 +++++++---- src/upf/n4-handler.c | 13 +++++---- tests/app/app-init.c | 2 +- tests/volte/diameter-rx-path.c | 28 +++++++++---------- 29 files changed, 271 insertions(+), 173 deletions(-) diff --git a/lib/core/ogs-3gpp-types.c b/lib/core/ogs-3gpp-types.c index 6cfec3339..c974b90ea 100644 --- a/lib/core/ogs-3gpp-types.c +++ b/lib/core/ogs-3gpp-types.c @@ -465,11 +465,11 @@ int ogs_ip_to_sockaddr(ogs_ip_t *ip, uint16_t port, ogs_sockaddr_t **list) return OGS_OK; } -void ogs_sockaddr_to_ip( +int ogs_sockaddr_to_ip( ogs_sockaddr_t *addr, ogs_sockaddr_t *addr6, ogs_ip_t *ip) { - ogs_assert(ip); - ogs_assert(addr || addr6); + ogs_expect_or_return_val(ip, OGS_ERROR); + ogs_expect_or_return_val(addr || addr6, OGS_ERROR); memset(ip, 0, sizeof(ogs_ip_t)); @@ -489,6 +489,8 @@ void ogs_sockaddr_to_ip( memcpy(ip->addr6, addr6->sin6.sin6_addr.s6_addr, OGS_IPV6_LEN); } else ogs_assert_if_reached(); + + return OGS_OK; } char *ogs_ipv4_to_string(uint32_t addr) diff --git a/lib/core/ogs-3gpp-types.h b/lib/core/ogs-3gpp-types.h index 5a6c54631..f6f8ead6b 100644 --- a/lib/core/ogs-3gpp-types.h +++ b/lib/core/ogs-3gpp-types.h @@ -238,7 +238,7 @@ ED3(uint8_t ipv4:1;, } ogs_ip_t; int ogs_ip_to_sockaddr(ogs_ip_t *ip, uint16_t port, ogs_sockaddr_t **list); -void ogs_sockaddr_to_ip( +int ogs_sockaddr_to_ip( ogs_sockaddr_t *addr, ogs_sockaddr_t *addr6, ogs_ip_t *ip); char *ogs_ipv4_to_string(uint32_t addr); diff --git a/lib/core/ogs-list.h b/lib/core/ogs-list.h index 6d5a694b7..c21c843aa 100644 --- a/lib/core/ogs-list.h +++ b/lib/core/ogs-list.h @@ -42,6 +42,11 @@ typedef struct ogs_list_s ogs_lnode_t;; (list)->next = (NULL); \ } while (0) +#define ogs_list_copy(dst, src) do { \ + (dst)->prev = (src)->prev; \ + (dst)->next = (src)->next; \ +} while (0) + static ogs_inline void *ogs_list_first(const ogs_list_t *list) { return list->next; diff --git a/lib/pfcp/build.c b/lib/pfcp/build.c index 521941249..aa56508a3 100644 --- a/lib/pfcp/build.c +++ b/lib/pfcp/build.c @@ -351,17 +351,15 @@ void ogs_pfcp_build_create_pdr( } } -void ogs_pfcp_build_created_pdr( +bool ogs_pfcp_build_created_pdr( ogs_pfcp_tlv_created_pdr_t *message, int i, ogs_pfcp_pdr_t *pdr) { + bool pdr_presence = false; + ogs_assert(message); ogs_assert(pdr); - message->presence = 1; - message->pdr_id.presence = 1; - message->pdr_id.u16 = pdr->id; - if (ogs_pfcp_self()->up_function_features.ftup) { if (pdr->f_teid_len) { memcpy(&pdrbuf[i].f_teid, &pdr->f_teid, pdr->f_teid_len); @@ -370,8 +368,18 @@ void ogs_pfcp_build_created_pdr( message->local_f_teid.presence = 1; message->local_f_teid.data = &pdrbuf[i].f_teid; message->local_f_teid.len = pdr->f_teid_len; + + pdr_presence = true; } } + + if (pdr_presence == true) { + message->presence = 1; + message->pdr_id.presence = 1; + message->pdr_id.u16 = pdr->id; + } + + return pdr_presence; } void ogs_pfcp_build_update_pdr( diff --git a/lib/pfcp/build.h b/lib/pfcp/build.h index c2065cae9..eb83f2f61 100644 --- a/lib/pfcp/build.h +++ b/lib/pfcp/build.h @@ -40,7 +40,7 @@ void ogs_pfcp_pdrbuf_clear(void); void ogs_pfcp_build_create_pdr( ogs_pfcp_tlv_create_pdr_t *message, int i, ogs_pfcp_pdr_t *pdr); -void ogs_pfcp_build_created_pdr( +bool ogs_pfcp_build_created_pdr( ogs_pfcp_tlv_created_pdr_t *message, int i, ogs_pfcp_pdr_t *pdr); void ogs_pfcp_build_update_pdr( ogs_pfcp_tlv_update_pdr_t *message, int i, ogs_pfcp_pdr_t *pdr); diff --git a/lib/pfcp/context.h b/lib/pfcp/context.h index 84d9a3780..993de0ca7 100644 --- a/lib/pfcp/context.h +++ b/lib/pfcp/context.h @@ -137,6 +137,8 @@ typedef struct ogs_pfcp_pdr_s { ogs_pfcp_object_t obj; uint32_t index; + ogs_lnode_t to_create_node; + struct { struct { int len; diff --git a/lib/pfcp/handler.c b/lib/pfcp/handler.c index b4c71c117..ee86c81f5 100644 --- a/lib/pfcp/handler.c +++ b/lib/pfcp/handler.c @@ -85,7 +85,7 @@ bool ogs_pfcp_cp_handle_association_setup_request( ogs_sockaddr_t *addr = node->sa_list; ogs_assert(addr); - ogs_error("F-TEID allocation/release not supported with peer [%s]:%d", + ogs_warn("F-TEID allocation/release not supported with peer [%s]:%d", OGS_ADDR(addr, buf), OGS_PORT(addr)); } @@ -131,7 +131,7 @@ bool ogs_pfcp_cp_handle_association_setup_response( ogs_sockaddr_t *addr = node->sa_list; ogs_assert(addr); - ogs_error("F-TEID allocation/release not supported with peer [%s]:%d", + ogs_warn("F-TEID allocation/release not supported with peer [%s]:%d", OGS_ADDR(addr, buf), OGS_PORT(addr)); } diff --git a/lib/pfcp/xact.h b/lib/pfcp/xact.h index 4ba968f02..73595a483 100644 --- a/lib/pfcp/xact.h +++ b/lib/pfcp/xact.h @@ -112,6 +112,8 @@ typedef struct ogs_pfcp_xact_s { #define OGS_PFCP_DELETE_TRIGGER_AMF_RELEASE_SM_CONTEXT 5 #define OGS_PFCP_DELETE_TRIGGER_AMF_UPDATE_SM_CONTEXT 6 int delete_trigger; + + ogs_list_t pdr_to_create_list; } ogs_pfcp_xact_t; int ogs_pfcp_xact_init(void); diff --git a/src/sgwc/context.c b/src/sgwc/context.c index 2f77c45b0..088fae03b 100644 --- a/src/sgwc/context.c +++ b/src/sgwc/context.c @@ -698,14 +698,7 @@ sgwc_tunnel_t *sgwc_tunnel_add( pdr->f_teid.ch = 1; pdr->f_teid_len = 1; } else { - char buf[OGS_ADDRSTRLEN]; ogs_gtpu_resource_t *resource = NULL; - ogs_sockaddr_t *addr = sess->pfcp_node->sa_list; - ogs_assert(addr); - - ogs_error("F-TEID allocation/release not supported with peer [%s]:%d", - OGS_ADDR(addr, buf), OGS_PORT(addr)); - resource = ogs_pfcp_find_gtpu_resource( &sess->pfcp_node->gtpu_resource_list, sess->session.name, OGS_PFCP_INTERFACE_ACCESS); @@ -714,10 +707,10 @@ sgwc_tunnel_t *sgwc_tunnel_add( &tunnel->local_addr, &tunnel->local_addr6); if (resource->info.teidri) tunnel->local_teid = OGS_PFCP_GTPU_INDEX_TO_TEID( - tunnel->index, resource->info.teidri, + pdr->index, resource->info.teidri, resource->info.teid_range); else - tunnel->local_teid = tunnel->index; + tunnel->local_teid = pdr->index; } else { if (sess->pfcp_node->addr.ogs_sa_family == AF_INET) ogs_assert(OGS_OK == @@ -730,7 +723,7 @@ sgwc_tunnel_t *sgwc_tunnel_add( else ogs_assert_if_reached(); - tunnel->local_teid = tunnel->index; + tunnel->local_teid = pdr->index; } ogs_assert(OGS_OK == diff --git a/src/sgwc/pfcp-path.c b/src/sgwc/pfcp-path.c index 218281f4f..42c924332 100644 --- a/src/sgwc/pfcp-path.c +++ b/src/sgwc/pfcp-path.c @@ -243,13 +243,16 @@ int sgwc_pfcp_send_sess_modification_request( ogs_pfcp_header_t h; ogs_pfcp_xact_t *xact = NULL; + OGS_LIST(pdr_to_create_list); + ogs_assert(sess); memset(&h, 0, sizeof(ogs_pfcp_header_t)); h.type = OGS_PFCP_SESSION_MODIFICATION_REQUEST_TYPE; h.seid = sess->sgwu_sxa_seid; - sxabuf = sgwc_sxa_build_sess_modification_request(h.type, sess, flags); + sxabuf = sgwc_sxa_build_sess_modification_request( + h.type, sess, flags, &pdr_to_create_list); ogs_expect_or_return_val(sxabuf, OGS_ERROR); xact = ogs_pfcp_xact_local_create( @@ -262,6 +265,8 @@ int sgwc_pfcp_send_sess_modification_request( ogs_expect_or_return_val(xact->gtpbuf, OGS_ERROR); } + ogs_list_copy(&xact->pdr_to_create_list, &pdr_to_create_list); + rv = ogs_pfcp_xact_commit(xact); ogs_expect(rv == OGS_OK); @@ -278,6 +283,8 @@ int sgwc_pfcp_send_bearer_modification_request( ogs_pfcp_xact_t *xact = NULL; sgwc_sess_t *sess = NULL; + OGS_LIST(pdr_to_create_list); + ogs_assert(bearer); sess = bearer->sess; ogs_assert(sess); @@ -286,7 +293,8 @@ int sgwc_pfcp_send_bearer_modification_request( h.type = OGS_PFCP_SESSION_MODIFICATION_REQUEST_TYPE; h.seid = sess->sgwu_sxa_seid; - sxabuf = sgwc_sxa_build_bearer_modification_request(h.type, bearer, flags); + sxabuf = sgwc_sxa_build_bearer_modification_request( + h.type, bearer, flags, &pdr_to_create_list); ogs_expect_or_return_val(sxabuf, OGS_ERROR); xact = ogs_pfcp_xact_local_create( @@ -299,6 +307,8 @@ int sgwc_pfcp_send_bearer_modification_request( ogs_expect_or_return_val(xact->gtpbuf, OGS_ERROR); } + ogs_list_copy(&xact->pdr_to_create_list, &pdr_to_create_list); + rv = ogs_pfcp_xact_commit(xact); ogs_expect(rv == OGS_OK); diff --git a/src/sgwc/sxa-build.c b/src/sgwc/sxa-build.c index 7f6107c74..03858ecc9 100644 --- a/src/sgwc/sxa-build.c +++ b/src/sgwc/sxa-build.c @@ -106,7 +106,8 @@ ogs_pkbuf_t *sgwc_sxa_build_session_establishment_request( } ogs_pkbuf_t *sgwc_sxa_build_sess_modification_request( - uint8_t type, sgwc_sess_t *sess, uint64_t modify_flags) + uint8_t type, sgwc_sess_t *sess, uint64_t modify_flags, + ogs_list_t *pdr_to_create_list) { ogs_pfcp_message_t pfcp_message; ogs_pfcp_session_modification_request_t *req = NULL; @@ -129,6 +130,10 @@ ogs_pkbuf_t *sgwc_sxa_build_sess_modification_request( req = &pfcp_message.pfcp_session_modification_request; memset(&pfcp_message, 0, sizeof(ogs_pfcp_message_t)); + if (modify_flags & OGS_PFCP_MODIFY_CREATE) { + ogs_pfcp_pdrbuf_init(); + } + ogs_list_for_each(&sess->bearer_list, bearer) { ogs_list_for_each(&bearer->tunnel_list, tunnel) { if (((modify_flags & @@ -182,8 +187,11 @@ ogs_pkbuf_t *sgwc_sxa_build_sess_modification_request( ogs_pfcp_build_create_pdr( &req->create_pdr[num_of_create_pdr], num_of_create_pdr, pdr); - num_of_create_pdr++; + + ogs_assert(pdr_to_create_list); + ogs_list_add(pdr_to_create_list, + &pdr->to_create_node); } else ogs_assert_if_reached(); @@ -217,11 +225,16 @@ ogs_pkbuf_t *sgwc_sxa_build_sess_modification_request( pfcp_message.h.type = type; pkbuf = ogs_pfcp_build_msg(&pfcp_message); + if (modify_flags & OGS_PFCP_MODIFY_CREATE) { + ogs_pfcp_pdrbuf_clear(); + } + return pkbuf; } ogs_pkbuf_t *sgwc_sxa_build_bearer_modification_request( - uint8_t type, sgwc_bearer_t *bearer, uint64_t modify_flags) + uint8_t type, sgwc_bearer_t *bearer, uint64_t modify_flags, + ogs_list_t *pdr_to_create_list) { ogs_pfcp_message_t pfcp_message; ogs_pfcp_session_modification_request_t *req = NULL; @@ -302,8 +315,10 @@ ogs_pkbuf_t *sgwc_sxa_build_bearer_modification_request( ogs_pfcp_build_create_pdr( &req->create_pdr[num_of_create_pdr], num_of_create_pdr, pdr); - num_of_create_pdr++; + + ogs_assert(pdr_to_create_list); + ogs_list_add(pdr_to_create_list, &pdr->to_create_node); } else ogs_assert_if_reached(); diff --git a/src/sgwc/sxa-build.h b/src/sgwc/sxa-build.h index 7acf28aa4..6ef7e9965 100644 --- a/src/sgwc/sxa-build.h +++ b/src/sgwc/sxa-build.h @@ -29,9 +29,11 @@ extern "C" { ogs_pkbuf_t *sgwc_sxa_build_session_establishment_request( uint8_t type, sgwc_sess_t *sess); ogs_pkbuf_t *sgwc_sxa_build_sess_modification_request( - uint8_t type, sgwc_sess_t *sess, uint64_t modify_flags); + uint8_t type, sgwc_sess_t *sess, uint64_t modify_flags, + ogs_list_t *pdr_to_create_list); ogs_pkbuf_t *sgwc_sxa_build_bearer_modification_request( - uint8_t type, sgwc_bearer_t *bearer, uint64_t modify_flags); + uint8_t type, sgwc_bearer_t *bearer, uint64_t modify_flags, + ogs_list_t *pdr_to_create_list); ogs_pkbuf_t *sgwc_sxa_build_session_deletion_request( uint8_t type, sgwc_sess_t *sess); diff --git a/src/sgwc/sxa-handler.c b/src/sgwc/sxa-handler.c index 7b1123500..4728c103e 100644 --- a/src/sgwc/sxa-handler.c +++ b/src/sgwc/sxa-handler.c @@ -173,11 +173,6 @@ void sgwc_sxa_handle_session_establishment_response( cause_value = OGS_GTP2_CAUSE_MANDATORY_IE_MISSING; } - if (pfcp_rsp->created_pdr[0].presence == 0) { - ogs_error("No Created PDR"); - cause_value = OGS_GTP2_CAUSE_MANDATORY_IE_MISSING; - } - if (pfcp_rsp->cause.presence) { if (pfcp_rsp->cause.u8 != OGS_PFCP_CAUSE_REQUEST_ACCEPTED) { ogs_warn("PFCP Cause [%d] : Not Accepted", pfcp_rsp->cause.u8); @@ -194,19 +189,21 @@ void sgwc_sxa_handle_session_establishment_response( uint8_t pfcp_cause_value = OGS_PFCP_CAUSE_REQUEST_ACCEPTED; uint8_t offending_ie_value = 0; + sgwc_tunnel_t *tunnel = NULL; + ogs_pfcp_pdr_t *pdr = NULL; + ogs_pfcp_far_t *far = NULL; + ogs_assert(sess); for (i = 0; i < OGS_MAX_NUM_OF_PDR; i++) { - sgwc_tunnel_t *tunnel = NULL; - ogs_pfcp_pdr_t *pdr = NULL; - ogs_pfcp_far_t *far = NULL; - pdr = ogs_pfcp_handle_created_pdr( &sess->pfcp, &pfcp_rsp->created_pdr[i], &pfcp_cause_value, &offending_ie_value); if (!pdr) break; + } + ogs_list_for_each(&sess->pfcp.pdr_list, pdr) { far = pdr->far; ogs_assert(far); @@ -356,6 +353,8 @@ void sgwc_sxa_handle_session_modification_response( ogs_gtp2_cause_t cause; + OGS_LIST(pdr_to_create_list); + ogs_debug("Session Modification Response"); ogs_assert(pfcp_xact); @@ -409,19 +408,24 @@ void sgwc_sxa_handle_session_modification_response( uint8_t pfcp_cause_value = OGS_PFCP_CAUSE_REQUEST_ACCEPTED; uint8_t offending_ie_value = 0; - ogs_assert(sess); - for (i = 0; i < OGS_MAX_NUM_OF_PDR; i++) { - sgwc_tunnel_t *tunnel = NULL; - ogs_pfcp_pdr_t *pdr = NULL; - ogs_pfcp_far_t *far = NULL; + sgwc_tunnel_t *tunnel = NULL; + ogs_pfcp_pdr_t *pdr = NULL; + ogs_pfcp_far_t *far = NULL; + ogs_assert(sess); + + ogs_list_copy(&pdr_to_create_list, &pfcp_xact->pdr_to_create_list); + + for (i = 0; i < OGS_MAX_NUM_OF_PDR; i++) { pdr = ogs_pfcp_handle_created_pdr( &sess->pfcp, &pfcp_rsp->created_pdr[i], &pfcp_cause_value, &offending_ie_value); if (!pdr) break; + } + ogs_list_for_each_entry(&pdr_to_create_list, pdr, to_create_node) { far = pdr->far; ogs_assert(far); diff --git a/src/sgwu/gtp-path.c b/src/sgwu/gtp-path.c index b18e61ec7..1526ea7b0 100644 --- a/src/sgwu/gtp-path.c +++ b/src/sgwu/gtp-path.c @@ -104,7 +104,7 @@ static void _gtpv1_u_recv_cb(short when, ogs_socket_t fd, void *data) * Session Container should be the first Extension Header */ ogs_gtp2_extension_header_t *extension_header = - (ogs_gtp2_extension_header_t *)(pkbuf->data + OGS_GTPV1U_HEADER_LEN); + (ogs_gtp2_extension_header_t *)(pkbuf->data+OGS_GTPV1U_HEADER_LEN); ogs_assert(extension_header); if (extension_header->type == OGS_GTP2_EXTENSION_HEADER_TYPE_PDU_SESSION_CONTAINER) { @@ -181,11 +181,6 @@ static void _gtpv1_u_recv_cb(short when, ogs_socket_t fd, void *data) ogs_assert(pfcp_sess); ogs_list_for_each(&pfcp_sess->pdr_list, pdr) { - /* Check if Source Interface */ - if (pdr->src_if != OGS_PFCP_INTERFACE_ACCESS && - pdr->src_if != OGS_PFCP_INTERFACE_CP_FUNCTION) - continue; - /* Check if TEID */ if (teid != pdr->f_teid.teid) continue; diff --git a/src/sgwu/sxa-build.c b/src/sgwu/sxa-build.c index f26d16d83..964415026 100644 --- a/src/sgwu/sxa-build.c +++ b/src/sgwu/sxa-build.c @@ -26,7 +26,7 @@ ogs_pkbuf_t *sgwu_sxa_build_session_establishment_response(uint8_t type, ogs_pfcp_session_establishment_response_t *rsp = NULL; ogs_pkbuf_t *pkbuf = NULL; - int i = 0, rv; + int i = 0, j = 0, rv; ogs_pfcp_node_id_t node_id; ogs_pfcp_f_seid_t f_seid; @@ -64,8 +64,10 @@ ogs_pkbuf_t *sgwu_sxa_build_session_establishment_response(uint8_t type, ogs_pfcp_pdrbuf_init(); /* Created PDR */ - for (i = 0; i < num_of_created_pdr; i++) { - ogs_pfcp_build_created_pdr(&rsp->created_pdr[i], i, created_pdr[i]); + for (i = 0, j = 0; i < num_of_created_pdr; i++) { + bool pdr_presence = ogs_pfcp_build_created_pdr( + &rsp->created_pdr[j], i, created_pdr[i]); + if (pdr_presence == true) j++; } pfcp_message.h.type = type; @@ -83,7 +85,7 @@ ogs_pkbuf_t *sgwu_sxa_build_session_modification_response(uint8_t type, ogs_pfcp_session_modification_response_t *rsp = NULL; ogs_pkbuf_t *pkbuf = NULL; - int i = 0; + int i = 0, j = 0; ogs_debug("Session Modification Response"); @@ -97,8 +99,10 @@ ogs_pkbuf_t *sgwu_sxa_build_session_modification_response(uint8_t type, ogs_pfcp_pdrbuf_init(); /* Created PDR */ - for (i = 0; i < num_of_created_pdr; i++) { - ogs_pfcp_build_created_pdr(&rsp->created_pdr[i], i, created_pdr[i]); + for (i = 0, j = 0; i < num_of_created_pdr; i++) { + bool pdr_presence = ogs_pfcp_build_created_pdr( + &rsp->created_pdr[i], i, created_pdr[i]); + if (pdr_presence == true) j++; } pfcp_message.h.type = type; diff --git a/src/smf/binding.c b/src/smf/binding.c index 49465f628..196a7a752 100644 --- a/src/smf/binding.c +++ b/src/smf/binding.c @@ -171,15 +171,7 @@ void smf_bearer_binding(smf_sess_t *sess) ul_pdr->f_teid.ch = 1; ul_pdr->f_teid_len = 1; } else { - char buf[OGS_ADDRSTRLEN]; ogs_gtpu_resource_t *resource = NULL; - ogs_sockaddr_t *addr = sess->pfcp_node->sa_list; - ogs_assert(addr); - - ogs_error("F-TEID allocation/release not supported " - "with peer [%s]:%d", - OGS_ADDR(addr, buf), OGS_PORT(addr)); - resource = ogs_pfcp_find_gtpu_resource( &sess->pfcp_node->gtpu_resource_list, sess->session.name, OGS_PFCP_INTERFACE_ACCESS); @@ -189,10 +181,10 @@ void smf_bearer_binding(smf_sess_t *sess) &bearer->pgw_s5u_addr, &bearer->pgw_s5u_addr6); if (resource->info.teidri) bearer->pgw_s5u_teid = OGS_PFCP_GTPU_INDEX_TO_TEID( - bearer->index, resource->info.teidri, + ul_pdr->index, resource->info.teidri, resource->info.teid_range); else - bearer->pgw_s5u_teid = bearer->index; + bearer->pgw_s5u_teid = ul_pdr->index; } else { if (sess->pfcp_node->addr.ogs_sa_family == AF_INET) ogs_assert(OGS_OK == @@ -206,7 +198,7 @@ void smf_bearer_binding(smf_sess_t *sess) else ogs_assert_if_reached(); - bearer->pgw_s5u_teid = bearer->index; + bearer->pgw_s5u_teid = ul_pdr->index; } ogs_assert(OGS_OK == @@ -496,14 +488,6 @@ void smf_qos_flow_binding(smf_sess_t *sess) ul_pdr->f_teid.choose_id = OGS_PFCP_DEFAULT_CHOOSE_ID; ul_pdr->f_teid_len = 2; } else { - char buf[OGS_ADDRSTRLEN]; - ogs_sockaddr_t *addr = sess->pfcp_node->sa_list; - ogs_assert(addr); - - ogs_error("F-TEID allocation/release not supported " - "with peer [%s]:%d", - OGS_ADDR(addr, buf), OGS_PORT(addr)); - ogs_assert(OGS_OK == ogs_pfcp_sockaddr_to_f_teid( sess->upf_n3_addr, sess->upf_n3_addr6, diff --git a/src/smf/context.c b/src/smf/context.c index 4dcc9fce2..e3a4dffaf 100644 --- a/src/smf/context.c +++ b/src/smf/context.c @@ -1896,18 +1896,44 @@ void smf_sess_create_indirect_data_forwarding(smf_sess_t *sess) pdr->f_teid.choose_id = OGS_PFCP_INDIRECT_DATA_FORWARDING_CHOOSE_ID; pdr->f_teid_len = 2; } else { - char buf[OGS_ADDRSTRLEN]; - ogs_sockaddr_t *addr = sess->pfcp_node->sa_list; - ogs_assert(addr); + ogs_gtpu_resource_t *resource = NULL; + + if (sess->handover.upf_dl_addr) + ogs_freeaddrinfo(sess->handover.upf_dl_addr); + if (sess->handover.upf_dl_addr6) + ogs_freeaddrinfo(sess->handover.upf_dl_addr6); + + resource = ogs_pfcp_find_gtpu_resource( + &sess->pfcp_node->gtpu_resource_list, + sess->session.name, OGS_PFCP_INTERFACE_ACCESS); + + if (resource) { + ogs_user_plane_ip_resource_info_to_sockaddr(&resource->info, + &sess->handover.upf_dl_addr, &sess->handover.upf_dl_addr6); + if (resource->info.teidri) + sess->handover.upf_dl_teid = OGS_PFCP_GTPU_INDEX_TO_TEID( + pdr->index, resource->info.teidri, + resource->info.teid_range); + else + sess->handover.upf_dl_teid = pdr->index; + } else { + if (sess->pfcp_node->addr.ogs_sa_family == AF_INET) + ogs_assert(OGS_OK == ogs_copyaddrinfo( + &sess->handover.upf_dl_addr, &sess->pfcp_node->addr)); + else if (sess->pfcp_node->addr.ogs_sa_family == AF_INET6) + ogs_assert(OGS_OK == ogs_copyaddrinfo( + &sess->handover.upf_dl_addr6, &sess->pfcp_node->addr)); + else + ogs_assert_if_reached(); + + sess->handover.upf_dl_teid = pdr->index; + } - ogs_error("F-TEID allocation/release not supported " - "with peer [%s]:%d", - OGS_ADDR(addr, buf), OGS_PORT(addr)); ogs_assert(OGS_OK == ogs_pfcp_sockaddr_to_f_teid( - sess->upf_n3_addr, sess->upf_n3_addr6, + sess->handover.upf_dl_addr, sess->handover.upf_dl_addr6, &pdr->f_teid, &pdr->f_teid_len)); - pdr->f_teid.teid = sess->upf_n3_teid; + pdr->f_teid.teid = sess->handover.upf_dl_teid; } ogs_assert(OGS_OK == diff --git a/src/smf/gx-handler.c b/src/smf/gx-handler.c index ea36dc2b4..27bab4890 100644 --- a/src/smf/gx-handler.c +++ b/src/smf/gx-handler.c @@ -183,14 +183,7 @@ uint32_t smf_gx_handle_cca_initial_request( up2cp_pdr->f_teid.choose_id = OGS_PFCP_DEFAULT_CHOOSE_ID; up2cp_pdr->f_teid_len = 2; } else { - char buf[OGS_ADDRSTRLEN]; ogs_gtpu_resource_t *resource = NULL; - ogs_sockaddr_t *addr = sess->pfcp_node->sa_list; - ogs_assert(addr); - - ogs_error("F-TEID allocation/release not supported with peer [%s]:%d", - OGS_ADDR(addr, buf), OGS_PORT(addr)); - resource = ogs_pfcp_find_gtpu_resource( &sess->pfcp_node->gtpu_resource_list, sess->session.name, OGS_PFCP_INTERFACE_ACCESS); @@ -199,10 +192,10 @@ uint32_t smf_gx_handle_cca_initial_request( &bearer->pgw_s5u_addr, &bearer->pgw_s5u_addr6); if (resource->info.teidri) bearer->pgw_s5u_teid = OGS_PFCP_GTPU_INDEX_TO_TEID( - bearer->index, resource->info.teidri, + ul_pdr->index, resource->info.teidri, resource->info.teid_range); else - bearer->pgw_s5u_teid = bearer->index; + bearer->pgw_s5u_teid = ul_pdr->index; } else { if (sess->pfcp_node->addr.ogs_sa_family == AF_INET) ogs_assert(OGS_OK == @@ -215,7 +208,7 @@ uint32_t smf_gx_handle_cca_initial_request( else ogs_assert_if_reached(); - bearer->pgw_s5u_teid = bearer->index; + bearer->pgw_s5u_teid = ul_pdr->index; } ogs_assert(OGS_OK == @@ -226,9 +219,9 @@ uint32_t smf_gx_handle_cca_initial_request( ogs_assert(OGS_OK == ogs_pfcp_sockaddr_to_f_teid( - ogs_gtp_self()->gtpu_addr, ogs_gtp_self()->gtpu_addr6, + bearer->pgw_s5u_addr, bearer->pgw_s5u_addr6, &cp2up_pdr->f_teid, &cp2up_pdr->f_teid_len)); - cp2up_pdr->f_teid.teid = bearer->index; + cp2up_pdr->f_teid.teid = cp2up_pdr->index; ogs_assert(OGS_OK == ogs_pfcp_sockaddr_to_f_teid( diff --git a/src/smf/n4-build.c b/src/smf/n4-build.c index 9958adf82..0f4d1f087 100644 --- a/src/smf/n4-build.c +++ b/src/smf/n4-build.c @@ -111,7 +111,8 @@ ogs_pkbuf_t *smf_n4_build_session_establishment_request( } ogs_pkbuf_t *smf_n4_build_session_modification_request( - uint8_t type, smf_sess_t *sess, uint64_t modify_flags) + uint8_t type, smf_sess_t *sess, uint64_t modify_flags, + ogs_list_t *pdr_to_create_list) { ogs_pfcp_pdr_t *pdr = NULL; ogs_pfcp_urr_t *urr = NULL; @@ -134,6 +135,10 @@ ogs_pkbuf_t *smf_n4_build_session_modification_request( req = &pfcp_message.pfcp_session_modification_request; memset(&pfcp_message, 0, sizeof(ogs_pfcp_message_t)); + if (modify_flags & OGS_PFCP_MODIFY_CREATE) { + ogs_pfcp_pdrbuf_init(); + } + ogs_list_for_each(&sess->pfcp.pdr_list, pdr) { ogs_pfcp_far_t *far = pdr->far; ogs_assert(far); @@ -174,9 +179,11 @@ ogs_pkbuf_t *smf_n4_build_session_modification_request( ogs_pfcp_build_create_pdr( &req->create_pdr[num_of_create_pdr], num_of_create_pdr, pdr); - num_of_create_pdr++; + ogs_assert(pdr_to_create_list); + ogs_list_add(pdr_to_create_list, &pdr->to_create_node); + ogs_pfcp_build_create_far( &req->create_far[num_of_create_far], num_of_create_far, far); @@ -222,11 +229,16 @@ ogs_pkbuf_t *smf_n4_build_session_modification_request( pfcp_message.h.type = type; pkbuf = ogs_pfcp_build_msg(&pfcp_message); + if (modify_flags & OGS_PFCP_MODIFY_CREATE) { + ogs_pfcp_pdrbuf_clear(); + } + return pkbuf; } ogs_pkbuf_t *smf_n4_build_qos_flow_modification_request( - uint8_t type, smf_bearer_t *qos_flow, uint64_t modify_flags) + uint8_t type, smf_bearer_t *qos_flow, uint64_t modify_flags, + ogs_list_t *pdr_to_create_list) { ogs_pfcp_message_t pfcp_message; ogs_pfcp_session_modification_request_t *req = NULL; @@ -244,6 +256,14 @@ ogs_pkbuf_t *smf_n4_build_qos_flow_modification_request( req = &pfcp_message.pfcp_session_modification_request; memset(&pfcp_message, 0, sizeof(ogs_pfcp_message_t)); + if (modify_flags & + (OGS_PFCP_MODIFY_CREATE| + OGS_PFCP_MODIFY_TFT_NEW|OGS_PFCP_MODIFY_TFT_ADD| + OGS_PFCP_MODIFY_TFT_REPLACE|OGS_PFCP_MODIFY_TFT_DELETE| + OGS_PFCP_MODIFY_EPC_TFT_UPDATE)) { + ogs_pfcp_pdrbuf_init(); + } + if (modify_flags & OGS_PFCP_MODIFY_REMOVE) { /* Remove PDR */ i = 0; @@ -296,7 +316,6 @@ ogs_pkbuf_t *smf_n4_build_qos_flow_modification_request( } else { if (modify_flags & OGS_PFCP_MODIFY_CREATE) { - ogs_pfcp_pdrbuf_init(); /* Create PDR */ i = 0; @@ -304,11 +323,19 @@ ogs_pkbuf_t *smf_n4_build_qos_flow_modification_request( ogs_pfcp_build_create_pdr( &req->create_pdr[i], i, qos_flow->dl_pdr); i++; + + ogs_assert(pdr_to_create_list); + ogs_list_add(pdr_to_create_list, + &qos_flow->dl_pdr->to_create_node); } if (qos_flow->ul_pdr) { ogs_pfcp_build_create_pdr( &req->create_pdr[i], i, qos_flow->ul_pdr); i++; + + ogs_assert(pdr_to_create_list); + ogs_list_add(pdr_to_create_list, + &qos_flow->ul_pdr->to_create_node); } /* Create FAR */ @@ -336,7 +363,6 @@ ogs_pkbuf_t *smf_n4_build_qos_flow_modification_request( (OGS_PFCP_MODIFY_TFT_NEW|OGS_PFCP_MODIFY_TFT_ADD| OGS_PFCP_MODIFY_TFT_REPLACE|OGS_PFCP_MODIFY_TFT_DELETE| OGS_PFCP_MODIFY_EPC_TFT_UPDATE)) { - ogs_pfcp_pdrbuf_init(); /* Update PDR */ i = 0; diff --git a/src/smf/n4-build.h b/src/smf/n4-build.h index bb11599ab..b1dfd3de5 100644 --- a/src/smf/n4-build.h +++ b/src/smf/n4-build.h @@ -29,9 +29,11 @@ extern "C" { ogs_pkbuf_t *smf_n4_build_session_establishment_request( uint8_t type, smf_sess_t *sess); ogs_pkbuf_t *smf_n4_build_session_modification_request( - uint8_t type, smf_sess_t *sess, uint64_t modify_flags); + uint8_t type, smf_sess_t *sess, uint64_t modify_flags, + ogs_list_t *pdr_to_create_list); ogs_pkbuf_t *smf_n4_build_qos_flow_modification_request( - uint8_t type, smf_bearer_t *qos_flow, uint64_t modify_flags); + uint8_t type, smf_bearer_t *qos_flow, uint64_t modify_flags, + ogs_list_t *pdr_to_create_list); ogs_pkbuf_t *smf_n4_build_session_deletion_request( uint8_t type, smf_sess_t *sess); diff --git a/src/smf/n4-handler.c b/src/smf/n4-handler.c index 9c9fddac2..7d5510675 100644 --- a/src/smf/n4-handler.c +++ b/src/smf/n4-handler.c @@ -155,6 +155,9 @@ uint8_t smf_5gc_n4_handle_session_establishment_response( ogs_pfcp_f_seid_t *up_f_seid = NULL; + ogs_pfcp_pdr_t *pdr = NULL; + ogs_pfcp_far_t *far = NULL; + ogs_assert(sess); ogs_assert(xact); ogs_assert(rsp); @@ -171,11 +174,6 @@ uint8_t smf_5gc_n4_handle_session_establishment_response( cause_value = OGS_PFCP_CAUSE_MANDATORY_IE_MISSING; } - if (rsp->created_pdr[0].presence == 0) { - ogs_error("No Created PDR"); - cause_value = OGS_PFCP_CAUSE_MANDATORY_IE_MISSING; - } - if (rsp->cause.presence) { if (rsp->cause.u8 != OGS_PFCP_CAUSE_REQUEST_ACCEPTED) { ogs_error("PFCP Cause [%d] : Not Accepted", rsp->cause.u8); @@ -190,16 +188,15 @@ uint8_t smf_5gc_n4_handle_session_establishment_response( return cause_value; for (i = 0; i < OGS_MAX_NUM_OF_PDR; i++) { - ogs_pfcp_pdr_t *pdr = NULL; - ogs_pfcp_far_t *far = NULL; - pdr = ogs_pfcp_handle_created_pdr( &sess->pfcp, &rsp->created_pdr[i], &cause_value, &offending_ie_value); if (!pdr) break; + } + ogs_list_for_each(&sess->pfcp.pdr_list, pdr) { far = pdr->far; ogs_assert(far); @@ -253,6 +250,8 @@ void smf_5gc_n4_handle_session_modification_response( ogs_sbi_stream_t *stream = NULL; smf_bearer_t *qos_flow = NULL; + OGS_LIST(pdr_to_create_list); + ogs_assert(xact); ogs_assert(rsp); @@ -273,6 +272,8 @@ void smf_5gc_n4_handle_session_modification_response( ogs_assert(qos_flow); } + ogs_list_copy(&pdr_to_create_list, &xact->pdr_to_create_list); + ogs_pfcp_xact_commit(xact); status = OGS_SBI_HTTP_STATUS_OK; @@ -298,18 +299,20 @@ void smf_5gc_n4_handle_session_modification_response( uint8_t pfcp_cause_value = OGS_PFCP_CAUSE_REQUEST_ACCEPTED; uint8_t offending_ie_value = 0; + ogs_pfcp_pdr_t *pdr = NULL; + ogs_pfcp_far_t *far = NULL; + ogs_assert(sess); for (i = 0; i < OGS_MAX_NUM_OF_PDR; i++) { - ogs_pfcp_pdr_t *pdr = NULL; - ogs_pfcp_far_t *far = NULL; - pdr = ogs_pfcp_handle_created_pdr( &sess->pfcp, &rsp->created_pdr[i], &pfcp_cause_value, &offending_ie_value); if (!pdr) break; + } + ogs_list_for_each_entry(&pdr_to_create_list, pdr, to_create_node) { far = pdr->far; ogs_assert(far); @@ -739,11 +742,6 @@ uint8_t smf_epc_n4_handle_session_establishment_response( cause_value = OGS_PFCP_CAUSE_MANDATORY_IE_MISSING; } - if (rsp->created_pdr[0].presence == 0) { - ogs_error("No Created PDR"); - cause_value = OGS_PFCP_CAUSE_MANDATORY_IE_MISSING; - } - if (rsp->cause.presence) { if (rsp->cause.u8 != OGS_PFCP_CAUSE_REQUEST_ACCEPTED) { ogs_warn("PFCP Cause [%d] : Not Accepted", rsp->cause.u8); @@ -758,17 +756,19 @@ uint8_t smf_epc_n4_handle_session_establishment_response( int i; uint8_t offending_ie_value = 0; - for (i = 0; i < OGS_MAX_NUM_OF_PDR; i++) { - ogs_pfcp_pdr_t *pdr = NULL; - ogs_pfcp_far_t *far = NULL; + ogs_pfcp_pdr_t *pdr = NULL; + ogs_pfcp_far_t *far = NULL; + for (i = 0; i < OGS_MAX_NUM_OF_PDR; i++) { pdr = ogs_pfcp_handle_created_pdr( &sess->pfcp, &rsp->created_pdr[i], &cause_value, &offending_ie_value); if (!pdr) break; + } + ogs_list_for_each(&sess->pfcp.pdr_list, pdr) { far = pdr->far; ogs_assert(far); @@ -836,6 +836,11 @@ void smf_epc_n4_handle_session_modification_response( uint8_t pfcp_cause_value = OGS_PFCP_CAUSE_REQUEST_ACCEPTED; uint8_t offending_ie_value = 0; + ogs_pfcp_pdr_t *pdr = NULL; + ogs_pfcp_far_t *far = NULL; + + OGS_LIST(pdr_to_create_list); + ogs_assert(xact); ogs_assert(rsp); @@ -860,6 +865,8 @@ void smf_epc_n4_handle_session_modification_response( gtp_cause = xact->gtp_cause; } + ogs_list_copy(&pdr_to_create_list, &xact->pdr_to_create_list); + ogs_pfcp_xact_commit(xact); if (!sess) { @@ -881,16 +888,15 @@ void smf_epc_n4_handle_session_modification_response( pfcp_cause_value = OGS_PFCP_CAUSE_REQUEST_ACCEPTED; for (i = 0; i < OGS_MAX_NUM_OF_PDR; i++) { - ogs_pfcp_pdr_t *pdr = NULL; - ogs_pfcp_far_t *far = NULL; - pdr = ogs_pfcp_handle_created_pdr( &sess->pfcp, &rsp->created_pdr[i], &pfcp_cause_value, &offending_ie_value); if (!pdr) break; + } + ogs_list_for_each_entry(&pdr_to_create_list, pdr, to_create_node) { far = pdr->far; ogs_assert(far); diff --git a/src/smf/ngap-build.c b/src/smf/ngap-build.c index e15f05f04..27b02b98c 100644 --- a/src/smf/ngap-build.c +++ b/src/smf/ngap-build.c @@ -82,8 +82,8 @@ ogs_pkbuf_t *ngap_build_pdu_session_resource_setup_request_transfer( NGAP_UPTransportLayerInformation_PR_gTPTunnel; UPTransportLayerInformation->choice.gTPTunnel = gTPTunnel; - ogs_assert(sess->upf_n3_addr || sess->upf_n3_addr6); - ogs_sockaddr_to_ip(sess->upf_n3_addr, sess->upf_n3_addr6, &upf_n3_ip); + ogs_assert(OGS_OK == ogs_sockaddr_to_ip( + sess->upf_n3_addr, sess->upf_n3_addr6, &upf_n3_ip)); ogs_asn_ip_to_BIT_STRING(&upf_n3_ip, &gTPTunnel->transportLayerAddress); ogs_asn_uint32_to_OCTET_STRING(sess->upf_n3_teid, &gTPTunnel->gTP_TEID); @@ -378,7 +378,8 @@ ogs_pkbuf_t *ngap_build_path_switch_request_ack_transfer(smf_sess_t *sess) NGAP_UPTransportLayerInformation_PR_gTPTunnel; UPTransportLayerInformation->choice.gTPTunnel = gTPTunnel; - ogs_sockaddr_to_ip(sess->upf_n3_addr, sess->upf_n3_addr6, &upf_n3_ip); + ogs_assert(OGS_OK == ogs_sockaddr_to_ip( + sess->upf_n3_addr, sess->upf_n3_addr6, &upf_n3_ip)); ogs_asn_ip_to_BIT_STRING(&upf_n3_ip, &gTPTunnel->transportLayerAddress); ogs_asn_uint32_to_OCTET_STRING(sess->upf_n3_teid, &gTPTunnel->gTP_TEID); @@ -417,9 +418,9 @@ ogs_pkbuf_t *ngap_build_handover_command_transfer(smf_sess_t *sess) CALLOC(1, sizeof(*gTPTunnel)); ogs_assert(gTPTunnel); - ogs_sockaddr_to_ip( + ogs_assert(OGS_OK == ogs_sockaddr_to_ip( sess->handover.upf_dl_addr, sess->handover.upf_dl_addr6, - &upf_dl_ip); + &upf_dl_ip)); ogs_asn_ip_to_BIT_STRING(&upf_dl_ip, &gTPTunnel->transportLayerAddress); ogs_asn_uint32_to_OCTET_STRING( sess->handover.upf_dl_teid, &gTPTunnel->gTP_TEID); diff --git a/src/smf/npcf-handler.c b/src/smf/npcf-handler.c index 12d83bab3..7a7849724 100644 --- a/src/smf/npcf-handler.c +++ b/src/smf/npcf-handler.c @@ -520,14 +520,7 @@ bool smf_npcf_smpolicycontrol_handle_create( up2cp_pdr->f_teid.choose_id = OGS_PFCP_DEFAULT_CHOOSE_ID; up2cp_pdr->f_teid_len = 2; } else { - char buf[OGS_ADDRSTRLEN]; ogs_gtpu_resource_t *resource = NULL; - ogs_sockaddr_t *addr = sess->pfcp_node->sa_list; - ogs_assert(addr); - - ogs_error("F-TEID allocation/release not supported with peer [%s]:%d", - OGS_ADDR(addr, buf), OGS_PORT(addr)); - resource = ogs_pfcp_find_gtpu_resource( &sess->pfcp_node->gtpu_resource_list, sess->session.name, OGS_PFCP_INTERFACE_ACCESS); @@ -536,10 +529,10 @@ bool smf_npcf_smpolicycontrol_handle_create( &sess->upf_n3_addr, &sess->upf_n3_addr6); if (resource->info.teidri) sess->upf_n3_teid = OGS_PFCP_GTPU_INDEX_TO_TEID( - sess->index, resource->info.teidri, + ul_pdr->index, resource->info.teidri, resource->info.teid_range); else - sess->upf_n3_teid = sess->index; + sess->upf_n3_teid = ul_pdr->index; } else { if (sess->pfcp_node->addr.ogs_sa_family == AF_INET) ogs_assert(OGS_OK == @@ -552,7 +545,7 @@ bool smf_npcf_smpolicycontrol_handle_create( else ogs_assert_if_reached(); - sess->upf_n3_teid = sess->index; + sess->upf_n3_teid = ul_pdr->index; } ogs_assert(OGS_OK == @@ -563,9 +556,9 @@ bool smf_npcf_smpolicycontrol_handle_create( ogs_assert(OGS_OK == ogs_pfcp_sockaddr_to_f_teid( - ogs_gtp_self()->gtpu_addr, ogs_gtp_self()->gtpu_addr6, + sess->upf_n3_addr, sess->upf_n3_addr6, &cp2up_pdr->f_teid, &cp2up_pdr->f_teid_len)); - cp2up_pdr->f_teid.teid = sess->index; + cp2up_pdr->f_teid.teid = cp2up_pdr->index; ogs_assert(OGS_OK == ogs_pfcp_sockaddr_to_f_teid( diff --git a/src/smf/pfcp-path.c b/src/smf/pfcp-path.c index 413e9df47..b2c449f43 100644 --- a/src/smf/pfcp-path.c +++ b/src/smf/pfcp-path.c @@ -331,6 +331,8 @@ int smf_5gc_pfcp_send_session_modification_request( ogs_pkbuf_t *n4buf = NULL; ogs_pfcp_header_t h; ogs_pfcp_xact_t *xact = NULL; + + OGS_LIST(pdr_to_create_list); ogs_assert(sess); if ((flags & OGS_PFCP_MODIFY_ERROR_INDICATION) == 0) @@ -340,7 +342,8 @@ int smf_5gc_pfcp_send_session_modification_request( h.type = OGS_PFCP_SESSION_MODIFICATION_REQUEST_TYPE; h.seid = sess->upf_n4_seid; - n4buf = smf_n4_build_session_modification_request(h.type, sess, flags); + n4buf = smf_n4_build_session_modification_request( + h.type, sess, flags, &pdr_to_create_list); ogs_expect_or_return_val(n4buf, OGS_ERROR); xact = ogs_pfcp_xact_local_create( @@ -349,6 +352,8 @@ int smf_5gc_pfcp_send_session_modification_request( xact->assoc_stream = stream; xact->modify_flags = flags | OGS_PFCP_MODIFY_SESSION; + ogs_list_copy(&xact->pdr_to_create_list, &pdr_to_create_list); + if (duration) { ogs_pfcp_xact_delayed_commit(xact, duration); @@ -370,6 +375,8 @@ int smf_5gc_pfcp_send_qos_flow_modification_request(smf_bearer_t *qos_flow, ogs_pfcp_xact_t *xact = NULL; smf_sess_t *sess = NULL; + OGS_LIST(pdr_to_create_list); + ogs_assert(qos_flow); sess = qos_flow->sess; ogs_assert(sess); @@ -378,7 +385,8 @@ int smf_5gc_pfcp_send_qos_flow_modification_request(smf_bearer_t *qos_flow, h.type = OGS_PFCP_SESSION_MODIFICATION_REQUEST_TYPE; h.seid = sess->upf_n4_seid; - n4buf = smf_n4_build_qos_flow_modification_request(h.type, qos_flow, flags); + n4buf = smf_n4_build_qos_flow_modification_request( + h.type, qos_flow, flags, &pdr_to_create_list); ogs_expect_or_return_val(n4buf, OGS_ERROR); xact = ogs_pfcp_xact_local_create( @@ -388,6 +396,8 @@ int smf_5gc_pfcp_send_qos_flow_modification_request(smf_bearer_t *qos_flow, xact->assoc_stream = stream; xact->modify_flags = flags; + ogs_list_copy(&xact->pdr_to_create_list, &pdr_to_create_list); + rv = ogs_pfcp_xact_commit(xact); ogs_expect(rv == OGS_OK); @@ -463,13 +473,16 @@ int smf_epc_pfcp_send_session_modification_request( ogs_pfcp_header_t h; ogs_pfcp_xact_t *xact = NULL; + OGS_LIST(pdr_to_create_list); + ogs_assert(sess); memset(&h, 0, sizeof(ogs_pfcp_header_t)); h.type = OGS_PFCP_SESSION_MODIFICATION_REQUEST_TYPE; h.seid = sess->upf_n4_seid; - n4buf = smf_n4_build_session_modification_request(h.type, sess, flags); + n4buf = smf_n4_build_session_modification_request( + h.type, sess, flags, &pdr_to_create_list); ogs_expect_or_return_val(n4buf, OGS_ERROR); xact = ogs_pfcp_xact_local_create( @@ -483,6 +496,8 @@ int smf_epc_pfcp_send_session_modification_request( xact->gtp_pti = gtp_pti; xact->gtp_cause = gtp_cause; + ogs_list_copy(&xact->pdr_to_create_list, &pdr_to_create_list); + rv = ogs_pfcp_xact_commit(xact); ogs_expect(rv == OGS_OK); @@ -499,6 +514,8 @@ int smf_epc_pfcp_send_bearer_modification_request( ogs_pfcp_xact_t *xact = NULL; smf_sess_t *sess = NULL; + OGS_LIST(pdr_to_create_list); + ogs_assert(bearer); sess = bearer->sess; ogs_assert(sess); @@ -507,7 +524,8 @@ int smf_epc_pfcp_send_bearer_modification_request( h.type = OGS_PFCP_SESSION_MODIFICATION_REQUEST_TYPE; h.seid = sess->upf_n4_seid; - n4buf = smf_n4_build_qos_flow_modification_request(h.type, bearer, flags); + n4buf = smf_n4_build_qos_flow_modification_request( + h.type, bearer, flags, &pdr_to_create_list); ogs_expect_or_return_val(n4buf, OGS_ERROR); xact = ogs_pfcp_xact_local_create( @@ -521,6 +539,8 @@ int smf_epc_pfcp_send_bearer_modification_request( xact->gtp_pti = gtp_pti; xact->gtp_cause = gtp_cause; + ogs_list_copy(&xact->pdr_to_create_list, &pdr_to_create_list); + rv = ogs_pfcp_xact_commit(xact); ogs_expect(rv == OGS_OK); diff --git a/src/upf/gtp-path.c b/src/upf/gtp-path.c index de43e597e..7292d6175 100644 --- a/src/upf/gtp-path.c +++ b/src/upf/gtp-path.c @@ -289,7 +289,7 @@ static void _gtpv1_u_recv_cb(short when, ogs_socket_t fd, void *data) * Session Container should be the first Extension Header */ ogs_gtp2_extension_header_t *extension_header = - (ogs_gtp2_extension_header_t *)(pkbuf->data + OGS_GTPV1U_HEADER_LEN); + (ogs_gtp2_extension_header_t *)(pkbuf->data+OGS_GTPV1U_HEADER_LEN); ogs_assert(extension_header); if (extension_header->type == OGS_GTP2_EXTENSION_HEADER_TYPE_PDU_SESSION_CONTAINER) { diff --git a/src/upf/n4-build.c b/src/upf/n4-build.c index 7b847a5c9..a8d94935b 100644 --- a/src/upf/n4-build.c +++ b/src/upf/n4-build.c @@ -27,7 +27,7 @@ ogs_pkbuf_t *upf_n4_build_session_establishment_response(uint8_t type, ogs_pfcp_session_establishment_response_t *rsp = NULL; ogs_pkbuf_t *pkbuf = NULL; - int i = 0; + int i = 0, j = 0; ogs_pfcp_node_id_t node_id; ogs_pfcp_f_seid_t f_seid; @@ -63,8 +63,10 @@ ogs_pkbuf_t *upf_n4_build_session_establishment_response(uint8_t type, ogs_pfcp_pdrbuf_init(); /* Created PDR */ - for (i = 0; i < num_of_created_pdr; i++) { - ogs_pfcp_build_created_pdr(&rsp->created_pdr[i], i, created_pdr[i]); + for (i = 0, j = 0; i < num_of_created_pdr; i++) { + bool pdr_presence = ogs_pfcp_build_created_pdr( + &rsp->created_pdr[j], i, created_pdr[i]); + if (pdr_presence == true) j++; } pfcp_message.h.type = type; @@ -82,7 +84,7 @@ ogs_pkbuf_t *upf_n4_build_session_modification_response(uint8_t type, ogs_pfcp_session_modification_response_t *rsp = NULL; ogs_pkbuf_t *pkbuf = NULL; - int i = 0; + int i = 0, j = 0; ogs_debug("Session Modification Response"); @@ -96,8 +98,10 @@ ogs_pkbuf_t *upf_n4_build_session_modification_response(uint8_t type, ogs_pfcp_pdrbuf_init(); /* Created PDR */ - for (i = 0; i < num_of_created_pdr; i++) { - ogs_pfcp_build_created_pdr(&rsp->created_pdr[i], i, created_pdr[i]); + for (i = 0, j = 0; i < num_of_created_pdr; i++) { + bool pdr_presence = ogs_pfcp_build_created_pdr( + &rsp->created_pdr[j], i, created_pdr[i]); + if (pdr_presence == true) j++; } pfcp_message.h.type = type; diff --git a/src/upf/n4-handler.c b/src/upf/n4-handler.c index 67a6293f2..4451bd153 100644 --- a/src/upf/n4-handler.c +++ b/src/upf/n4-handler.c @@ -131,7 +131,7 @@ void upf_n4_handle_session_establishment_request( /* Setup UPF-N3-TEID & QFI Hash */ if (pdr->f_teid_len) { - ogs_pfcp_object_type_e type = OGS_PFCP_OBJ_PDR_TYPE; + ogs_pfcp_object_type_e type = OGS_PFCP_OBJ_SESS_TYPE; if (ogs_pfcp_self()->up_function_features.ftup && pdr->f_teid.ch) { @@ -139,19 +139,20 @@ void upf_n4_handle_session_establishment_request( ogs_pfcp_pdr_t *choosed_pdr = NULL; if (pdr->f_teid.chid) { - type = OGS_PFCP_OBJ_SESS_TYPE; - choosed_pdr = ogs_pfcp_pdr_find_by_choose_id( &sess->pfcp, pdr->f_teid.choose_id); if (!choosed_pdr) { pdr->chid = true; pdr->choose_id = pdr->f_teid.choose_id; } + } else { + type = OGS_PFCP_OBJ_PDR_TYPE; } if (choosed_pdr) { pdr->f_teid_len = choosed_pdr->f_teid_len; memcpy(&pdr->f_teid, &choosed_pdr->f_teid, pdr->f_teid_len); + } else { ogs_gtpu_resource_t *resource = NULL; resource = ogs_pfcp_find_gtpu_resource( @@ -363,7 +364,7 @@ void upf_n4_handle_session_modification_request( ogs_assert(pdr); if (pdr->f_teid_len) { - ogs_pfcp_object_type_e type = OGS_PFCP_OBJ_PDR_TYPE; + ogs_pfcp_object_type_e type = OGS_PFCP_OBJ_SESS_TYPE; if (ogs_pfcp_self()->up_function_features.ftup && pdr->f_teid.ch) { @@ -371,14 +372,14 @@ void upf_n4_handle_session_modification_request( ogs_pfcp_pdr_t *choosed_pdr = NULL; if (pdr->f_teid.chid) { - type = OGS_PFCP_OBJ_SESS_TYPE; - choosed_pdr = ogs_pfcp_pdr_find_by_choose_id( &sess->pfcp, pdr->f_teid.choose_id); if (!choosed_pdr) { pdr->chid = true; pdr->choose_id = pdr->f_teid.choose_id; } + } else { + type = OGS_PFCP_OBJ_PDR_TYPE; } if (choosed_pdr) { diff --git a/tests/app/app-init.c b/tests/app/app-init.c index 80bc07c47..12cd78712 100644 --- a/tests/app/app-init.c +++ b/tests/app/app-init.c @@ -95,7 +95,7 @@ int app_initialize(const char *const argv[]) * * Note that at least 4 seconds are needed if freeDiameter is running. */ - ogs_msleep(500); + ogs_msleep(5000); return OGS_OK;; } diff --git a/tests/volte/diameter-rx-path.c b/tests/volte/diameter-rx-path.c index a0513e5bb..fbdb77744 100644 --- a/tests/volte/diameter-rx-path.c +++ b/tests/volte/diameter-rx-path.c @@ -386,7 +386,7 @@ void test_rx_send_aar_audio(uint8_t **rx_sid, ret = fd_msg_avp_new(ogs_diam_rx_flow_description, 0, &avpch2); ogs_assert(ret == 0); #define TEST_OGS_DIAM_RX_FLOW_DESC1 \ - "permit out 17 from 172.20.166.84 to 10.45.0.2 20001" + "permit out icmp from any to assigned" val.os.data = (uint8_t *)TEST_OGS_DIAM_RX_FLOW_DESC1; val.os.len = strlen(TEST_OGS_DIAM_RX_FLOW_DESC1); ret = fd_msg_avp_setvalue (avpch2, &val); @@ -397,7 +397,7 @@ void test_rx_send_aar_audio(uint8_t **rx_sid, ret = fd_msg_avp_new(ogs_diam_rx_flow_description, 0, &avpch2); ogs_assert(ret == 0); #define TEST_OGS_DIAM_RX_FLOW_DESC2 \ - "permit in 17 from 10.45.0.2 to 172.20.166.84 20360" + "permit in icmp from assigned to any" val.os.data = (uint8_t *)TEST_OGS_DIAM_RX_FLOW_DESC2; val.os.len = strlen(TEST_OGS_DIAM_RX_FLOW_DESC2); ret = fd_msg_avp_setvalue (avpch2, &val); @@ -769,7 +769,7 @@ void test_rx_send_aar_video(uint8_t **rx_sid, test_sess_t *sess, int id_type) ret = fd_msg_avp_new(ogs_diam_rx_flow_description, 0, &avpch2); ogs_assert(ret == 0); #define TEST_OGS_DIAM_RX_FLOW_DESC5 \ - "permit out 17 from 45.45.0.5 50026 to 45.45.0.3 50022" + "permit out icmp from any to assigned" val.os.data = (uint8_t *)TEST_OGS_DIAM_RX_FLOW_DESC5; val.os.len = strlen(TEST_OGS_DIAM_RX_FLOW_DESC5); ret = fd_msg_avp_setvalue (avpch2, &val); @@ -780,7 +780,7 @@ void test_rx_send_aar_video(uint8_t **rx_sid, test_sess_t *sess, int id_type) ret = fd_msg_avp_new(ogs_diam_rx_flow_description, 0, &avpch2); ogs_assert(ret == 0); #define TEST_OGS_DIAM_RX_FLOW_DESC6 \ - "permit in 17 from 45.45.0.3 50022 to 45.45.0.5 50026" + "permit in icmp from assigned to any" val.os.data = (uint8_t *)TEST_OGS_DIAM_RX_FLOW_DESC6; val.os.len = strlen(TEST_OGS_DIAM_RX_FLOW_DESC6); ret = fd_msg_avp_setvalue (avpch2, &val); @@ -791,7 +791,7 @@ void test_rx_send_aar_video(uint8_t **rx_sid, test_sess_t *sess, int id_type) ret = fd_msg_avp_new(ogs_diam_rx_flow_description, 0, &avpch2); ogs_assert(ret == 0); #define TEST_OGS_DIAM_RX_FLOW_DESC7 \ - "permit out 17 from 45.45.0.5 50027 to 45.45.0.3 50023" + "permit out 17 from 10.45.0.5 50027 to 10.45.0.3 50023" val.os.data = (uint8_t *)TEST_OGS_DIAM_RX_FLOW_DESC7; val.os.len = strlen(TEST_OGS_DIAM_RX_FLOW_DESC7); ret = fd_msg_avp_setvalue (avpch2, &val); @@ -802,7 +802,7 @@ void test_rx_send_aar_video(uint8_t **rx_sid, test_sess_t *sess, int id_type) ret = fd_msg_avp_new(ogs_diam_rx_flow_description, 0, &avpch2); ogs_assert(ret == 0); #define TEST_OGS_DIAM_RX_FLOW_DESC8 \ - "permit in 17 from 45.45.0.3 50023 to 45.45.0.5 50027" + "permit in 17 from 10.45.0.3 50023 to 10.45.0.5 50027" val.os.data = (uint8_t *)TEST_OGS_DIAM_RX_FLOW_DESC8; val.os.len = strlen(TEST_OGS_DIAM_RX_FLOW_DESC8); ret = fd_msg_avp_setvalue (avpch2, &val); @@ -953,7 +953,7 @@ void test_rx_send_aar_video(uint8_t **rx_sid, test_sess_t *sess, int id_type) ret = fd_msg_avp_new(ogs_diam_rx_flow_description, 0, &avpch2); ogs_assert(ret == 0); #define TEST_OGS_DIAM_RX_FLOW_DESC9 \ - "permit out 17 from 45.45.0.5 60010 to 45.45.0.3 60010" + "permit out icmp from any to assigned" val.os.data = (uint8_t *)TEST_OGS_DIAM_RX_FLOW_DESC9; val.os.len = strlen(TEST_OGS_DIAM_RX_FLOW_DESC9); ret = fd_msg_avp_setvalue (avpch2, &val); @@ -964,7 +964,7 @@ void test_rx_send_aar_video(uint8_t **rx_sid, test_sess_t *sess, int id_type) ret = fd_msg_avp_new(ogs_diam_rx_flow_description, 0, &avpch2); ogs_assert(ret == 0); #define TEST_OGS_DIAM_RX_FLOW_DESC10 \ - "permit in 17 from 45.45.0.3 60010 to 45.45.0.5 60010" + "permit in icmp from assigned to any" val.os.data = (uint8_t *)TEST_OGS_DIAM_RX_FLOW_DESC10; val.os.len = strlen(TEST_OGS_DIAM_RX_FLOW_DESC10); ret = fd_msg_avp_setvalue (avpch2, &val); @@ -975,7 +975,7 @@ void test_rx_send_aar_video(uint8_t **rx_sid, test_sess_t *sess, int id_type) ret = fd_msg_avp_new(ogs_diam_rx_flow_description, 0, &avpch2); ogs_assert(ret == 0); #define TEST_OGS_DIAM_RX_FLOW_DESC11 \ - "permit out 17 from 45.45.0.5 60011 to 45.45.0.3 60011" + "permit out 17 from 10.45.0.5 60011 to 10.45.0.3 60011" val.os.data = (uint8_t *)TEST_OGS_DIAM_RX_FLOW_DESC11; val.os.len = strlen(TEST_OGS_DIAM_RX_FLOW_DESC11); ret = fd_msg_avp_setvalue (avpch2, &val); @@ -986,7 +986,7 @@ void test_rx_send_aar_video(uint8_t **rx_sid, test_sess_t *sess, int id_type) ret = fd_msg_avp_new(ogs_diam_rx_flow_description, 0, &avpch2); ogs_assert(ret == 0); #define TEST_OGS_DIAM_RX_FLOW_DESC12 \ - "permit in 17 from 45.45.0.3 60011 to 45.45.0.5 60011" + "permit in 17 from 10.45.0.3 60011 to 10.45.0.5 60011" val.os.data = (uint8_t *)TEST_OGS_DIAM_RX_FLOW_DESC12; val.os.len = strlen(TEST_OGS_DIAM_RX_FLOW_DESC12); ret = fd_msg_avp_setvalue (avpch2, &val); @@ -1419,7 +1419,7 @@ void test_rx_send_aar_ctrl(uint8_t **rx_sid, test_sess_t *sess, int id_type) ret = fd_msg_avp_new(ogs_diam_rx_flow_description, 0, &avpch2); ogs_assert(ret == 0); #define TEST_OGS_DIAM_RX_FLOW_DESC13 \ - "permit out ip from 172.30.0.144 43810 to 45.45.0.4 43810" + "permit out ip from 172.30.0.144 43810 to 10.45.0.4 43810" val.os.data = (uint8_t *)TEST_OGS_DIAM_RX_FLOW_DESC13; val.os.len = strlen(TEST_OGS_DIAM_RX_FLOW_DESC13); ret = fd_msg_avp_setvalue (avpch2, &val); @@ -1430,7 +1430,7 @@ void test_rx_send_aar_ctrl(uint8_t **rx_sid, test_sess_t *sess, int id_type) ret = fd_msg_avp_new(ogs_diam_rx_flow_description, 0, &avpch2); ogs_assert(ret == 0); #define TEST_OGS_DIAM_RX_FLOW_DESC14 \ - "permit in ip from 45.45.0.4 43810 to 172.30.0.144 43810" + "permit in ip from 10.45.0.4 43810 to 172.30.0.144 43810" val.os.data = (uint8_t *)TEST_OGS_DIAM_RX_FLOW_DESC14; val.os.len = strlen(TEST_OGS_DIAM_RX_FLOW_DESC14); ret = fd_msg_avp_setvalue (avpch2, &val); @@ -1441,7 +1441,7 @@ void test_rx_send_aar_ctrl(uint8_t **rx_sid, test_sess_t *sess, int id_type) ret = fd_msg_avp_new(ogs_diam_rx_flow_description, 0, &avpch2); ogs_assert(ret == 0); #define TEST_OGS_DIAM_RX_FLOW_DESC15 \ - "permit out ip from 172.30.0.144 43811 to 45.45.0.4 43811" + "permit out ip from 172.30.0.144 43811 to 10.45.0.4 43811" val.os.data = (uint8_t *)TEST_OGS_DIAM_RX_FLOW_DESC15; val.os.len = strlen(TEST_OGS_DIAM_RX_FLOW_DESC15); ret = fd_msg_avp_setvalue (avpch2, &val); @@ -1452,7 +1452,7 @@ void test_rx_send_aar_ctrl(uint8_t **rx_sid, test_sess_t *sess, int id_type) ret = fd_msg_avp_new(ogs_diam_rx_flow_description, 0, &avpch2); ogs_assert(ret == 0); #define TEST_OGS_DIAM_RX_FLOW_DESC16 \ - "permit in ip from 45.45.0.4 43811 to 172.30.0.144 43811" + "permit in ip from 10.45.0.4 43811 to 172.30.0.144 43811" val.os.data = (uint8_t *)TEST_OGS_DIAM_RX_FLOW_DESC16; val.os.len = strlen(TEST_OGS_DIAM_RX_FLOW_DESC16); ret = fd_msg_avp_setvalue (avpch2, &val);