diff --git a/lib/pfcp/build.c b/lib/pfcp/build.c index d9470ff4c..723153f38 100644 --- a/lib/pfcp/build.c +++ b/lib/pfcp/build.c @@ -446,6 +446,7 @@ void ogs_pfcp_build_update_pdr( static struct { ogs_pfcp_outer_header_creation_t outer_header_creation; + char dnn[OGS_MAX_DNN_LEN+1]; } farbuf[OGS_MAX_NUM_OF_FAR]; void ogs_pfcp_build_create_far( @@ -471,6 +472,14 @@ void ogs_pfcp_build_create_far( message->forwarding_parameters.destination_interface.u8 = far->dst_if; + if (far->dnn) { + message->forwarding_parameters.network_instance.presence = 1; + message->forwarding_parameters.network_instance.len = + ogs_fqdn_build(farbuf[i].dnn, far->dnn, strlen(far->dnn)); + message->forwarding_parameters.network_instance.data = + farbuf[i].dnn; + } + if (far->outer_header_creation_len) { memcpy(&farbuf[i].outer_header_creation, &far->outer_header_creation, far->outer_header_creation_len); @@ -534,6 +543,14 @@ void ogs_pfcp_build_update_far_activate( message->update_forwarding_parameters. destination_interface.u8 = far->dst_if; + if (far->dnn) { + message->update_forwarding_parameters.network_instance.presence = 1; + message->update_forwarding_parameters.network_instance.len = + ogs_fqdn_build(farbuf[i].dnn, far->dnn, strlen(far->dnn)); + message->update_forwarding_parameters.network_instance.data = + farbuf[i].dnn; + } + if (far->outer_header_creation_len || far->smreq_flags.value) { if (far->outer_header_creation_len) { diff --git a/lib/pfcp/context.c b/lib/pfcp/context.c index 553478d9f..921cbb95f 100644 --- a/lib/pfcp/context.c +++ b/lib/pfcp/context.c @@ -1222,6 +1222,9 @@ void ogs_pfcp_far_remove(ogs_pfcp_far_t *far) ogs_hash_set(self.far_f_teid_hash, &far->hash.f_teid.key, far->hash.f_teid.len, NULL); + if (far->dnn) + ogs_free(far->dnn); + for (i = 0; i < far->num_of_buffered_packet; i++) ogs_pkbuf_free(far->buffered_packet[i]); diff --git a/lib/pfcp/context.h b/lib/pfcp/context.h index b2b8a8533..0ecb95279 100644 --- a/lib/pfcp/context.h +++ b/lib/pfcp/context.h @@ -208,6 +208,11 @@ typedef struct ogs_pfcp_far_s { } teid; } hash; + union { + char *apn; + char *dnn; + }; + uint8_t *id_node; /* Pool-Node for ID */ ogs_pfcp_far_id_t id; ogs_pfcp_apply_action_t apply_action; diff --git a/lib/pfcp/handler.c b/lib/pfcp/handler.c index cd5ebf1da..5507d2a67 100644 --- a/lib/pfcp/handler.c +++ b/lib/pfcp/handler.c @@ -808,12 +808,29 @@ ogs_pfcp_far_t *ogs_pfcp_handle_create_far(ogs_pfcp_sess_t *sess, far->dst_if = 0; memset(&far->outer_header_creation, 0, sizeof(far->outer_header_creation)); + if (far->dnn) { + ogs_free(far->dnn); + far->dnn = NULL; + } + if (message->forwarding_parameters.presence) { if (message->forwarding_parameters.destination_interface.presence) { far->dst_if = message->forwarding_parameters.destination_interface.u8; } + if (message->forwarding_parameters.network_instance.presence) { + char dnn[OGS_MAX_DNN_LEN+1]; + + ogs_assert(0 < ogs_fqdn_parse(dnn, + message->forwarding_parameters.network_instance.data, + ogs_min(message->forwarding_parameters.network_instance.len, + OGS_MAX_DNN_LEN))); + + far->dnn = ogs_strdup(dnn); + ogs_assert(far->dnn); + } + if (message->forwarding_parameters.outer_header_creation.presence) { ogs_pfcp_tlv_outer_header_creation_t *outer_header_creation = &message->forwarding_parameters.outer_header_creation; @@ -906,6 +923,20 @@ ogs_pfcp_far_t *ogs_pfcp_handle_update_far(ogs_pfcp_sess_t *sess, message->update_forwarding_parameters.destination_interface.u8; } + if (message->update_forwarding_parameters.network_instance.presence) { + char dnn[OGS_MAX_DNN_LEN+1]; + + ogs_assert(0 < ogs_fqdn_parse(dnn, + message->update_forwarding_parameters.network_instance.data, + ogs_min(message->update_forwarding_parameters. + network_instance.len, OGS_MAX_DNN_LEN))); + + if (far->dnn) + ogs_free(far->dnn); + far->dnn = ogs_strdup(dnn); + ogs_assert(far->dnn); + } + if (message->update_forwarding_parameters. outer_header_creation.presence) { ogs_pfcp_tlv_outer_header_creation_t *outer_header_creation = diff --git a/src/sgwc/context.c b/src/sgwc/context.c index d21c8b313..079a6a0ab 100644 --- a/src/sgwc/context.c +++ b/src/sgwc/context.c @@ -702,16 +702,20 @@ sgwc_tunnel_t *sgwc_tunnel_add( pdr = ogs_pfcp_pdr_add(&sess->pfcp); ogs_assert(pdr); - pdr->src_if = src_if; - if (sess->session.name) { - pdr->apn = ogs_strdup(sess->session.name); - ogs_assert(pdr->apn); - } + ogs_assert(sess->session.name); + pdr->apn = ogs_strdup(sess->session.name); + ogs_assert(pdr->apn); + + pdr->src_if = src_if; far = ogs_pfcp_far_add(&sess->pfcp); ogs_assert(far); + ogs_assert(sess->session.name); + far->apn = ogs_strdup(sess->session.name); + ogs_assert(far->apn); + far->dst_if = dst_if; ogs_pfcp_pdr_associate_far(pdr, far); diff --git a/src/smf/context.c b/src/smf/context.c index f11d3e5ec..aecd79e7c 100644 --- a/src/smf/context.c +++ b/src/smf/context.c @@ -1822,23 +1822,21 @@ smf_bearer_t *smf_qos_flow_add(smf_sess_t *sess) ogs_assert(dl_pdr); qos_flow->dl_pdr = dl_pdr; - dl_pdr->src_if = OGS_PFCP_INTERFACE_CORE; + ogs_assert(sess->session.name); + dl_pdr->apn = ogs_strdup(sess->session.name); + ogs_assert(dl_pdr->apn); - if (sess->session.name) { - dl_pdr->apn = ogs_strdup(sess->session.name); - ogs_assert(dl_pdr->apn); - } + dl_pdr->src_if = OGS_PFCP_INTERFACE_CORE; ul_pdr = ogs_pfcp_pdr_add(&sess->pfcp); ogs_assert(ul_pdr); qos_flow->ul_pdr = ul_pdr; - ul_pdr->src_if = OGS_PFCP_INTERFACE_ACCESS; + ogs_assert(sess->session.name); + ul_pdr->apn = ogs_strdup(sess->session.name); + ogs_assert(ul_pdr->apn); - if (sess->session.name) { - ul_pdr->apn = ogs_strdup(sess->session.name); - ogs_assert(ul_pdr->apn); - } + ul_pdr->src_if = OGS_PFCP_INTERFACE_ACCESS; ul_pdr->outer_header_removal_len = 2; if (sess->session.session_type == OGS_PDU_SESSION_TYPE_IPV4) { @@ -1860,6 +1858,10 @@ smf_bearer_t *smf_qos_flow_add(smf_sess_t *sess) ogs_assert(dl_far); qos_flow->dl_far = dl_far; + ogs_assert(sess->session.name); + dl_far->apn = ogs_strdup(sess->session.name); + ogs_assert(dl_far->apn); + dl_far->dst_if = OGS_PFCP_INTERFACE_ACCESS; ogs_pfcp_pdr_associate_far(dl_pdr, dl_far); @@ -1871,6 +1873,10 @@ smf_bearer_t *smf_qos_flow_add(smf_sess_t *sess) ogs_assert(ul_far); qos_flow->ul_far = ul_far; + ogs_assert(sess->session.name); + ul_far->apn = ogs_strdup(sess->session.name); + ogs_assert(ul_far->apn); + ul_far->dst_if = OGS_PFCP_INTERFACE_CORE; ogs_pfcp_pdr_associate_far(ul_pdr, ul_far); @@ -1925,6 +1931,10 @@ void smf_sess_create_indirect_data_forwarding(smf_sess_t *sess) pdr = ogs_pfcp_pdr_add(&sess->pfcp); ogs_assert(pdr); + ogs_assert(sess->session.name); + pdr->apn = ogs_strdup(sess->session.name); + ogs_assert(pdr->apn); + pdr->src_if = OGS_PFCP_INTERFACE_ACCESS; pdr->outer_header_removal_len = 1; @@ -1943,6 +1953,10 @@ void smf_sess_create_indirect_data_forwarding(smf_sess_t *sess) far = ogs_pfcp_far_add(&sess->pfcp); ogs_assert(far); + ogs_assert(sess->session.name); + far->apn = ogs_strdup(sess->session.name); + ogs_assert(far->apn); + far->dst_if = OGS_PFCP_INTERFACE_ACCESS; ogs_pfcp_pdr_associate_far(pdr, far); @@ -2224,22 +2238,22 @@ smf_bearer_t *smf_bearer_add(smf_sess_t *sess) ogs_assert(dl_pdr); bearer->dl_pdr = dl_pdr; - dl_pdr->src_if = OGS_PFCP_INTERFACE_CORE; - ogs_assert(sess->session.name); dl_pdr->apn = ogs_strdup(sess->session.name); ogs_assert(dl_pdr->apn); + dl_pdr->src_if = OGS_PFCP_INTERFACE_CORE; + ul_pdr = ogs_pfcp_pdr_add(&sess->pfcp); ogs_assert(ul_pdr); bearer->ul_pdr = ul_pdr; - ul_pdr->src_if = OGS_PFCP_INTERFACE_ACCESS; - ogs_assert(sess->session.name); ul_pdr->apn = ogs_strdup(sess->session.name); ogs_assert(ul_pdr->apn); + ul_pdr->src_if = OGS_PFCP_INTERFACE_ACCESS; + ul_pdr->outer_header_removal_len = 1; if (sess->session.session_type == OGS_PDU_SESSION_TYPE_IPV4) { ul_pdr->outer_header_removal.description = @@ -2258,6 +2272,10 @@ smf_bearer_t *smf_bearer_add(smf_sess_t *sess) ogs_assert(dl_far); bearer->dl_far = dl_far; + ogs_assert(sess->session.name); + dl_far->apn = ogs_strdup(sess->session.name); + ogs_assert(dl_far->apn); + dl_far->dst_if = OGS_PFCP_INTERFACE_ACCESS; ogs_pfcp_pdr_associate_far(dl_pdr, dl_far); @@ -2269,6 +2287,10 @@ smf_bearer_t *smf_bearer_add(smf_sess_t *sess) ogs_assert(ul_far); bearer->ul_far = ul_far; + ogs_assert(sess->session.name); + ul_far->apn = ogs_strdup(sess->session.name); + ogs_assert(ul_far->apn); + ul_far->dst_if = OGS_PFCP_INTERFACE_CORE; ogs_pfcp_pdr_associate_far(ul_pdr, ul_far);