QFI is added

This commit is contained in:
Sukchan Lee 2020-07-17 23:29:45 -04:00
parent 4db0f80374
commit 9b3176ca4a
16 changed files with 221 additions and 105 deletions

View File

@ -81,6 +81,8 @@ extern "C" {
#define OGS_ACCESS_TYPE_NON_3GPP 2
#define OGS_ACCESS_TYPE_BOTH_3GPP_AND_NON_3GPP 3
#define OGS_MAX_QOS_FLOW_ID 63
/************************************
* PLMN_ID Structure */
#define OGS_MAX_NUM_OF_PLMN 6

View File

@ -28,10 +28,28 @@
extern "C" {
#endif
#define OGS_GTPV1U_EXTENSION_HEADER_LEN 4
#define OGS_GTP_MAX_INDIRECT_TUNNEL 8
#define OGS_GTPV1U_5GC_HEADER_LEN 16
/*
* 5GC GTP Header (16byte)
* o Flags(1byte) : 0x34
* o Message Type(1byte) : T-PDU (0xff)
* o Length(2byte) : 36
* o TEID(4byte) : 0x00000001
* o Next extension header type(4byte)
* - Sequence Number(2byte) : 0x0000
* - N PDU Number(1byte) : 0x00
* - PDU Session container(1byte) : (0x85)
* o Extension header(4byte)
* - Extension HEader Length(1byte) : 1
* - PDU Session Container(2byte)
* ; PDU Type : UL PDU SESSION INFORMATION (1)
* ; QoS Flow Identifier (QFI) : 1
* - Next extension header type : No more extension headers (0x00)
*/
#define OGS_GTPV1U_EXTENSION_HEADER_LEN 4
typedef struct ogs_gtp_extension_header_s {
#define OGS_GTP_EXTENSION_HEADER_TYPE_PDU_SESSION_CONTAINER 0x85
#define OGS_GTP_EXTENSION_HEADER_TYPE_NO_MORE_EXTENSION_HEADERS 0x0
@ -39,10 +57,12 @@ typedef struct ogs_gtp_extension_header_s {
uint8_t n_pdu_number;
uint8_t type;
uint8_t len;
#define OGS_GTP_EXTENSION_HEADER_PDU_TYPE_DL_PDU_SESSION_INFORMATION 0
#define OGS_GTP_EXTENSION_HEADER_PDU_TYPE_UL_PDU_SESSION_INFORMATION 1
ED2(uint8_t pdu_type:4;,
uint8_t spare1:4;);
ED2(uint8_t spare2:2;,
ED3(uint8_t paging_policy_presence:1;,
uint8_t reflective_qos_indicator:1;,
uint8_t qos_flow_identifier:6;);
uint8_t next_type;
} __attribute__ ((packed)) ogs_gtp_extension_header_t;

View File

@ -911,6 +911,7 @@ void ogs_pfcp_pdr_associate_far(ogs_pfcp_pdr_t *pdr, ogs_pfcp_far_t *far)
ogs_assert(far);
pdr->far = far;
far->pdr = pdr;
}
void ogs_pfcp_pdr_associate_urr(ogs_pfcp_pdr_t *pdr, ogs_pfcp_urr_t *urr)
{
@ -918,6 +919,7 @@ void ogs_pfcp_pdr_associate_urr(ogs_pfcp_pdr_t *pdr, ogs_pfcp_urr_t *urr)
ogs_assert(urr);
pdr->urr = urr;
urr->pdr = pdr;
}
void ogs_pfcp_pdr_associate_qer(ogs_pfcp_pdr_t *pdr, ogs_pfcp_qer_t *qer)
{
@ -925,6 +927,7 @@ void ogs_pfcp_pdr_associate_qer(ogs_pfcp_pdr_t *pdr, ogs_pfcp_qer_t *qer)
ogs_assert(qer);
pdr->qer = qer;
qer->pdr = pdr;
}
void ogs_pfcp_pdr_remove(ogs_pfcp_pdr_t *pdr)

View File

@ -149,6 +149,7 @@ typedef struct ogs_pfcp_far_s {
/* Related Context */
ogs_pfcp_sess_t *sess;
void *gnode;
ogs_pfcp_pdr_t *pdr;
} ogs_pfcp_far_t;
typedef struct ogs_pfcp_urr_s {
@ -156,6 +157,7 @@ typedef struct ogs_pfcp_urr_s {
ogs_pfcp_urr_id_t id;
ogs_pfcp_pdr_t *pdr;
ogs_pfcp_sess_t *sess;
} ogs_pfcp_urr_t;
@ -168,6 +170,9 @@ typedef struct ogs_pfcp_qer_s {
ogs_pfcp_bitrate_t mbr;
ogs_pfcp_bitrate_t gbr;
uint8_t qfi;
ogs_pfcp_pdr_t *pdr;
ogs_pfcp_sess_t *sess;
} ogs_pfcp_qer_t;

View File

@ -20,7 +20,7 @@
/*******************************************************************************
* This file had been created by pfcp-tlv.py script v0.1.0
* Please do not modify this file but regenerate it via script.
* Created on: 2020-04-22 22:57:07.588861 by acetcom
* Created on: 2020-07-17 20:36:05.513686 by acetcom
* from 29244-g10.docx
******************************************************************************/
@ -996,10 +996,10 @@ ogs_tlv_desc_t ogs_pfcp_tlv_desc_subsequent_time_quota =
ogs_tlv_desc_t ogs_pfcp_tlv_desc_rqi =
{
OGS_TLV_VAR_STR,
OGS_TLV_UINT8,
"RQI",
OGS_PFCP_RQI_TYPE,
0,
1,
0,
sizeof(ogs_pfcp_tlv_rqi_t),
{ NULL }
@ -1007,10 +1007,10 @@ ogs_tlv_desc_t ogs_pfcp_tlv_desc_rqi =
ogs_tlv_desc_t ogs_pfcp_tlv_desc_qfi =
{
OGS_TLV_VAR_STR,
OGS_TLV_UINT8,
"QFI",
OGS_PFCP_QFI_TYPE,
0,
1,
0,
sizeof(ogs_pfcp_tlv_qfi_t),
{ NULL }
@ -1315,10 +1315,10 @@ ogs_tlv_desc_t ogs_pfcp_tlv_desc_event_time_stamp =
ogs_tlv_desc_t ogs_pfcp_tlv_desc_averaging_window =
{
OGS_TLV_VAR_STR,
OGS_TLV_UINT32,
"Averaging Window",
OGS_PFCP_AVERAGING_WINDOW_TYPE,
0,
4,
0,
sizeof(ogs_pfcp_tlv_averaging_window_t),
{ NULL }
@ -1326,10 +1326,10 @@ ogs_tlv_desc_t ogs_pfcp_tlv_desc_averaging_window =
ogs_tlv_desc_t ogs_pfcp_tlv_desc_paging_policy_indicator =
{
OGS_TLV_VAR_STR,
OGS_TLV_UINT8,
"Paging Policy Indicator",
OGS_PFCP_PAGING_POLICY_INDICATOR_TYPE,
0,
1,
0,
sizeof(ogs_pfcp_tlv_paging_policy_indicator_t),
{ NULL }

View File

@ -20,7 +20,7 @@
/*******************************************************************************
* This file had been created by pfcp-tlv.py script v0.1.0
* Please do not modify this file but regenerate it via script.
* Created on: 2020-04-22 22:57:07.579730 by acetcom
* Created on: 2020-07-17 20:36:05.504399 by acetcom
* from 29244-g10.docx
******************************************************************************/
@ -569,8 +569,8 @@ typedef ogs_tlv_octet_t ogs_pfcp_tlv_multiplier_t;
typedef ogs_tlv_octet_t ogs_pfcp_tlv_aggregated_urr_id_t;
typedef ogs_tlv_octet_t ogs_pfcp_tlv_subsequent_volume_quota_t;
typedef ogs_tlv_octet_t ogs_pfcp_tlv_subsequent_time_quota_t;
typedef ogs_tlv_octet_t ogs_pfcp_tlv_rqi_t;
typedef ogs_tlv_octet_t ogs_pfcp_tlv_qfi_t;
typedef ogs_tlv_uint8_t ogs_pfcp_tlv_rqi_t;
typedef ogs_tlv_uint8_t ogs_pfcp_tlv_qfi_t;
typedef ogs_tlv_octet_t ogs_pfcp_tlv_query_urr_reference_t;
typedef ogs_tlv_octet_t ogs_pfcp_tlv_additional_usage_reports_information_t;
typedef ogs_tlv_octet_t ogs_pfcp_tlv_update_traffic_endpoint_t;
@ -598,8 +598,8 @@ typedef ogs_tlv_octet_t ogs_pfcp_tlv_framed_route_t;
typedef ogs_tlv_octet_t ogs_pfcp_tlv_framed_routing_t;
typedef ogs_tlv_octet_t ogs_pfcp_tlv_framed_ipv6_route_t;
typedef ogs_tlv_octet_t ogs_pfcp_tlv_event_time_stamp_t;
typedef ogs_tlv_octet_t ogs_pfcp_tlv_averaging_window_t;
typedef ogs_tlv_octet_t ogs_pfcp_tlv_paging_policy_indicator_t;
typedef ogs_tlv_uint32_t ogs_pfcp_tlv_averaging_window_t;
typedef ogs_tlv_uint8_t ogs_pfcp_tlv_paging_policy_indicator_t;
typedef ogs_tlv_octet_t ogs_pfcp_tlv_apn_dnn_t;
typedef ogs_tlv_octet_t ogs_pfcp_tlv__interface_type_t;
typedef ogs_tlv_octet_t ogs_pfcp_tlv_pfcpsrreq_flags_t;

View File

@ -423,6 +423,10 @@ type_list["Recovery Time Stamp"]["size"] = 4 # Type 96
type_list["FAR ID"]["size"] = 4 # Type 108
type_list["QER ID"]["size"] = 4 # Type 109
type_list["PDN Type"]["size"] = 1 # Type 113
type_list["RQI"]["size"] = 1 # Type 123
type_list["QFI"]["size"] = 1 # Type 124
type_list["Averaging Window"]["size"] = 4 # Type 157
type_list["Paging Policy Indicator"]["size"] = 1 # Type 158
f = open(outdir + 'message.h', 'w')
output_header_to_file(f)

View File

@ -753,7 +753,7 @@ smf_sess_t *smf_sess_add_by_apn(smf_ue_t *smf_ue, char *apn,
bearer = smf_bearer_add(sess);
ogs_assert(bearer);
bearer->ebi = ebi;
bearer->ebi = ebi; /* EPC only */
/* Default PDRs is set to lowest precedence(highest precedence value). */
ogs_list_for_each(&bearer->pfcp.pdr_list, pdr)
@ -864,62 +864,6 @@ smf_sess_t *smf_sess_add_by_gtp_message(ogs_gtp_message_t *message)
return sess;
}
void smf_sess_set_ue_ip(smf_sess_t *sess)
{
char buf1[OGS_ADDRSTRLEN];
char buf2[OGS_ADDRSTRLEN];
ogs_pfcp_subnet_t *subnet6 = NULL;
smf_ue_t *smf_ue = NULL;
ogs_assert(sess);
smf_ue = sess->smf_ue;
ogs_assert(smf_ue);
sess->pdn.paa.pdn_type = sess->pdn.pdn_type;
ogs_assert(sess->pdn.pdn_type);
if (sess->pdn.pdn_type == OGS_PDU_SESSION_TYPE_IPV4) {
sess->ipv4 = ogs_pfcp_ue_ip_alloc(
AF_INET, sess->pdn.apn, (uint8_t *)&sess->pdn.ue_ip.addr);
ogs_assert(sess->ipv4);
sess->pdn.paa.addr = sess->ipv4->addr[0];
ogs_hash_set(self.ipv4_hash, sess->ipv4->addr, OGS_IPV4_LEN, sess);
} else if (sess->pdn.pdn_type == OGS_PDU_SESSION_TYPE_IPV6) {
sess->ipv6 = ogs_pfcp_ue_ip_alloc(
AF_INET6, sess->pdn.apn, sess->pdn.ue_ip.addr6);
ogs_assert(sess->ipv6);
subnet6 = sess->ipv6->subnet;
ogs_assert(subnet6);
sess->pdn.paa.len = subnet6->prefixlen;
memcpy(sess->pdn.paa.addr6, sess->ipv6->addr, OGS_IPV6_LEN);
ogs_hash_set(self.ipv6_hash, sess->ipv6->addr, OGS_IPV6_LEN, sess);
} else if (sess->pdn.pdn_type == OGS_PDU_SESSION_TYPE_IPV4V6) {
sess->ipv4 = ogs_pfcp_ue_ip_alloc(
AF_INET, sess->pdn.apn, (uint8_t *)&sess->pdn.ue_ip.addr);
ogs_assert(sess->ipv4);
sess->ipv6 = ogs_pfcp_ue_ip_alloc(
AF_INET6, sess->pdn.apn, sess->pdn.ue_ip.addr6);
ogs_assert(sess->ipv6);
subnet6 = sess->ipv6->subnet;
ogs_assert(subnet6);
sess->pdn.paa.both.addr = sess->ipv4->addr[0];
sess->pdn.paa.both.len = subnet6->prefixlen;
memcpy(sess->pdn.paa.both.addr6, sess->ipv6->addr, OGS_IPV6_LEN);
ogs_hash_set(self.ipv4_hash, sess->ipv4->addr, OGS_IPV4_LEN, sess);
ogs_hash_set(self.ipv6_hash, sess->ipv6->addr, OGS_IPV6_LEN, sess);
} else
ogs_assert_if_reached();
ogs_info("UE SUPI:[%s] DNN:[%s] IPv4:[%s] IPv6:[%s]",
smf_ue->supi, sess->pdn.apn,
sess->ipv4 ? OGS_INET_NTOP(&sess->ipv4->addr, buf1) : "",
sess->ipv6 ? OGS_INET6_NTOP(&sess->ipv6->addr, buf2) : "");
}
smf_sess_t *smf_sess_add_by_psi(smf_ue_t *smf_ue, uint8_t psi)
{
ogs_debug("smf_sess_add_by_psi");
@ -980,6 +924,10 @@ smf_sess_t *smf_sess_add_by_psi(smf_ue_t *smf_ue, uint8_t psi)
bearer = smf_bearer_add(sess);
ogs_assert(bearer);
/* QFI is only used in 5GC */
bearer->qfi = OGS_NEXT_ID(
sess->qos_flow_identifier, 1, OGS_MAX_QOS_FLOW_ID+1);
/* Default PDRs is set to lowest precedence(highest precedence value). */
ogs_list_for_each(&bearer->pfcp.pdr_list, pdr)
pdr->precedence = 0xffffffff;

View File

@ -154,11 +154,13 @@ typedef struct smf_sess_s {
char *gx_sid; /* Gx Session ID */
ogs_pfcp_pdr_id_t pdr_id; /* ID Generator(1~MAX_NUM_OF_PDR) */
ogs_pfcp_far_id_t far_id; /* ID Generator(1~MAX_NUM_OF_FAR) */
ogs_pfcp_urr_id_t urr_id; /* ID Generator(1~MAX_NUM_OF_URR) */
ogs_pfcp_qer_id_t qer_id; /* ID Generator(1~MAX_NUM_OF_URR) */
ogs_pfcp_bar_id_t bar_id; /* ID Generator(1~MAX_NUM_OF_BAR) */
ogs_pfcp_pdr_id_t pdr_id; /* ID Generator(1~OGS_MAX_NUM_OF_PDR) */
ogs_pfcp_far_id_t far_id; /* ID Generator(1~OGS_MAX_NUM_OF_FAR) */
ogs_pfcp_urr_id_t urr_id; /* ID Generator(1~OGS_MAX_NUM_OF_URR) */
ogs_pfcp_qer_id_t qer_id; /* ID Generator(1~OGS_MAX_NUM_OF_URR) */
ogs_pfcp_bar_id_t bar_id; /* ID Generator(1~OGS_MAX_NUM_OF_BAR) */
uint8_t qos_flow_identifier; /* ID Generator(1~OGS_MAX_QOS_FLOW_ID) */
/* IMSI */
uint8_t imsi[OGS_MAX_IMSI_LEN];
@ -245,7 +247,9 @@ typedef struct smf_bearer_s {
ogs_pfcp_sess_t pfcp; /* PFCP session context */
uint8_t ebi;
uint8_t qfi; /* 5GC */
uint8_t ebi; /* EPC */
/*
* UPF-S5U-TEID = INDEX | TEID_RANGE
* INDEX = UPF-S5U-TEID & ~TEID_RANGE
@ -309,7 +313,6 @@ smf_sess_t *smf_sess_add_by_apn(smf_ue_t *smf_ue, char *apn,
smf_sess_t *smf_sess_add_by_sbi_message(ogs_sbi_message_t *message);
smf_sess_t *smf_sess_add_by_psi(smf_ue_t *smf_ue, uint8_t psi);
void smf_sess_set_ue_ip(smf_sess_t *sess);
void smf_sess_remove(smf_sess_t *sess);
void smf_sess_remove_all(smf_ue_t *smf_ue);

View File

@ -25,6 +25,7 @@
ogs_pkbuf_t *gsm_build_pdu_session_establishment_accept(smf_sess_t *sess)
{
ogs_pkbuf_t *pkbuf = NULL;
smf_bearer_t *bearer = NULL;
ogs_nas_5gs_message_t message;
ogs_nas_5gs_pdu_session_establishment_accept_t *
@ -72,6 +73,10 @@ ogs_pkbuf_t *gsm_build_pdu_session_establishment_accept(smf_sess_t *sess)
dnn = &pdu_session_establishment_accept->dnn;
ogs_assert(dnn);
ogs_assert(sess);
bearer = smf_default_bearer_in_sess(sess);
ogs_assert(bearer);
memset(&message, 0, sizeof(message));
message.gsm.h.extended_protocol_discriminator =
OGS_NAS_EXTENDED_PROTOCOL_DISCRIMINATOR_5GSM;
@ -96,7 +101,7 @@ ogs_pkbuf_t *gsm_build_pdu_session_establishment_accept(smf_sess_t *sess)
qos_rule[0].pf[0].component[0].type = OGS_PACKET_FILTER_MATCH_ALL;
qos_rule[0].precedence = 255; /* lowest precedence */
qos_rule[0].flow.segregation = 0;
qos_rule[0].flow.identifier = 1;
qos_rule[0].flow.identifier = bearer->qfi;
ogs_nas_build_qos_rules(authorized_qos_rules, qos_rule, 1);
@ -149,7 +154,7 @@ ogs_pkbuf_t *gsm_build_pdu_session_establishment_accept(smf_sess_t *sess)
/* QoS flow descriptions */
memset(&qos_flow_description, 0, sizeof(qos_flow_description));
qos_flow_description.identifier = 1;
qos_flow_description.identifier = bearer->qfi;
qos_flow_description.code = OGS_NAS_CREATE_NEW_QOS_FLOW_DESCRIPTION;
qos_flow_description.E = 1;
qos_flow_description.num_of_parameter = 1;

View File

@ -122,12 +122,7 @@ void smf_gsm_state_operational(ogs_fsm_t *s, smf_event_t *e)
ogs_sbi_server_send_error(session,
OGS_SBI_HTTP_STATUS_INTERNAL_SERVER_ERROR,
sbi_message, "HTTP response error", smf_ue->supi);
break;
}
smf_sess_set_ue_ip(sess);
smf_5gc_pfcp_send_session_establishment_request(sess);
break;
DEFAULT

View File

@ -304,6 +304,11 @@ static void build_create_qer(
&message->guaranteed_bitrate,
&qer->gbr, create_qer_buf[i].gbr, OGS_PFCP_BITRATE_LEN);
}
if (qer->qfi) {
message->qos_flow_identifier.presence = 1;
message->qos_flow_identifier.u8 = qer->qfi;
}
}
static void build_update_qer(

View File

@ -132,7 +132,7 @@ ogs_pkbuf_t *ngap_build_pdu_session_resource_setup_request_transfer(
qosCharacteristics->choice.nonDynamic5QI = nonDynamic5QI;
qosCharacteristics->present = NGAP_QosCharacteristics_PR_nonDynamic5QI;
*qosFlowIdentifier = 1;
*qosFlowIdentifier = bearer->qfi;
nonDynamic5QI->fiveQI = sess->pdn.qos.qci;

View File

@ -18,10 +18,20 @@
*/
#include "nudm-handler.h"
#include "pfcp-path.h"
bool smf_nudm_sdm_handle_get(smf_sess_t *sess, ogs_sbi_message_t *recvmsg)
{
char buf1[OGS_ADDRSTRLEN];
char buf2[OGS_ADDRSTRLEN];
smf_ue_t *smf_ue = NULL;
ogs_pfcp_subnet_t *subnet6 = NULL;
smf_bearer_t *bearer = NULL;
ogs_pfcp_pdr_t *pdr = NULL;
ogs_pfcp_qer_t *qer = NULL;
ogs_sbi_server_t *server = NULL;
ogs_sbi_session_t *session = NULL;
@ -236,5 +246,85 @@ bool smf_nudm_sdm_handle_get(smf_sess_t *sess, ogs_sbi_message_t *recvmsg)
ogs_free(sendmsg.http.location);
sess->pdn.paa.pdn_type = sess->pdn.pdn_type;
ogs_assert(sess->pdn.pdn_type);
if (sess->ipv4) {
ogs_hash_set(smf_self()->ipv4_hash,
sess->ipv4->addr, OGS_IPV4_LEN, NULL);
ogs_pfcp_ue_ip_free(sess->ipv4);
}
if (sess->ipv6) {
ogs_hash_set(smf_self()->ipv6_hash,
sess->ipv6->addr, OGS_IPV6_LEN, NULL);
ogs_pfcp_ue_ip_free(sess->ipv6);
}
if (sess->pdn.pdn_type == OGS_PDU_SESSION_TYPE_IPV4) {
sess->ipv4 = ogs_pfcp_ue_ip_alloc(
AF_INET, sess->pdn.apn, (uint8_t *)&sess->pdn.ue_ip.addr);
ogs_assert(sess->ipv4);
sess->pdn.paa.addr = sess->ipv4->addr[0];
ogs_hash_set(smf_self()->ipv4_hash,
sess->ipv4->addr, OGS_IPV4_LEN, sess);
} else if (sess->pdn.pdn_type == OGS_PDU_SESSION_TYPE_IPV6) {
sess->ipv6 = ogs_pfcp_ue_ip_alloc(
AF_INET6, sess->pdn.apn, sess->pdn.ue_ip.addr6);
ogs_assert(sess->ipv6);
subnet6 = sess->ipv6->subnet;
ogs_assert(subnet6);
sess->pdn.paa.len = subnet6->prefixlen;
memcpy(sess->pdn.paa.addr6, sess->ipv6->addr, OGS_IPV6_LEN);
ogs_hash_set(smf_self()->ipv6_hash,
sess->ipv6->addr, OGS_IPV6_LEN, sess);
} else if (sess->pdn.pdn_type == OGS_PDU_SESSION_TYPE_IPV4V6) {
sess->ipv4 = ogs_pfcp_ue_ip_alloc(
AF_INET, sess->pdn.apn, (uint8_t *)&sess->pdn.ue_ip.addr);
ogs_assert(sess->ipv4);
sess->ipv6 = ogs_pfcp_ue_ip_alloc(
AF_INET6, sess->pdn.apn, sess->pdn.ue_ip.addr6);
ogs_assert(sess->ipv6);
subnet6 = sess->ipv6->subnet;
ogs_assert(subnet6);
sess->pdn.paa.both.addr = sess->ipv4->addr[0];
sess->pdn.paa.both.len = subnet6->prefixlen;
memcpy(sess->pdn.paa.both.addr6, sess->ipv6->addr, OGS_IPV6_LEN);
ogs_hash_set(smf_self()->ipv4_hash,
sess->ipv4->addr, OGS_IPV4_LEN, sess);
ogs_hash_set(smf_self()->ipv6_hash,
sess->ipv6->addr, OGS_IPV6_LEN, sess);
} else
ogs_assert_if_reached();
ogs_info("UE SUPI:[%s] DNN:[%s] IPv4:[%s] IPv6:[%s]",
smf_ue->supi, sess->pdn.apn,
sess->ipv4 ? OGS_INET_NTOP(&sess->ipv4->addr, buf1) : "",
sess->ipv6 ? OGS_INET6_NTOP(&sess->ipv6->addr, buf2) : "");
bearer = smf_default_bearer_in_sess(sess);
ogs_assert(bearer);
/* Only 1 QER is used per bearer */
qer = ogs_list_first(&bearer->pfcp.qer_list);
if (!qer) {
qer = ogs_pfcp_qer_add(&bearer->pfcp);
ogs_assert(qer);
qer->id = OGS_NEXT_ID(sess->qer_id, 1, OGS_MAX_NUM_OF_QER+1);
}
qer->mbr.uplink = sess->pdn.ambr.uplink;
qer->mbr.downlink = sess->pdn.ambr.downlink;
qer->qfi = bearer->qfi;
ogs_list_for_each(&bearer->pfcp.pdr_list, pdr)
ogs_pfcp_pdr_associate_qer(pdr, qer);
smf_5gc_pfcp_send_session_establishment_request(sess);
return true;
}

View File

@ -55,8 +55,8 @@ static void _gtpv1_tun_recv_cb(short when, ogs_socket_t fd, void *data)
ogs_pfcp_pdr_t *pdr = NULL;
recvbuf = ogs_pkbuf_alloc(NULL, OGS_MAX_SDU_LEN);
ogs_pkbuf_reserve(recvbuf, OGS_GTPV1U_HEADER_LEN);
ogs_pkbuf_put(recvbuf, OGS_MAX_SDU_LEN-OGS_GTPV1U_HEADER_LEN);
ogs_pkbuf_reserve(recvbuf, OGS_GTPV1U_5GC_HEADER_LEN);
ogs_pkbuf_put(recvbuf, OGS_MAX_SDU_LEN-OGS_GTPV1U_5GC_HEADER_LEN);
n = ogs_read(fd, recvbuf->data, recvbuf->len);
if (n <= 0) {
@ -347,8 +347,12 @@ static void upf_gtp_send_to_gnb(ogs_pfcp_far_t *far, ogs_pkbuf_t *sendbuf)
char buf[OGS_ADDRSTRLEN];
int rv;
ogs_gtp_header_t *gtp_h = NULL;
ogs_gtp_extension_header_t *ext_h = NULL;
ogs_gtp_node_t *gnode = NULL;
ogs_pfcp_pdr_t *pdr = NULL;
ogs_pfcp_qer_t *qer = NULL;
ogs_assert(far);
if (far->dst_if != OGS_PFCP_INTERFACE_ACCESS) {
@ -361,19 +365,48 @@ static void upf_gtp_send_to_gnb(ogs_pfcp_far_t *far, ogs_pkbuf_t *sendbuf)
ogs_assert(gnode->sock);
ogs_assert(sendbuf);
pdr = far->pdr;
ogs_assert(pdr);
qer = pdr->qer;
/* Add GTP-U header */
ogs_assert(ogs_pkbuf_push(sendbuf, OGS_GTPV1U_HEADER_LEN));
gtp_h = (ogs_gtp_header_t *)sendbuf->data;
/* Bits 8 7 6 5 4 3 2 1
* +--+--+--+--+--+--+--+--+
* |version |PT| 1| E| S|PN|
* +--+--+--+--+--+--+--+--+
* 0 0 1 1 0 0 0 0
*/
gtp_h->flags = 0x30;
gtp_h->type = OGS_GTPU_MSGTYPE_GPDU;
gtp_h->length = htobe16(sendbuf->len - OGS_GTPV1U_HEADER_LEN);
gtp_h->teid = htobe32(far->outer_header_creation.teid);
if (qer && qer->qfi) {
ogs_assert(ogs_pkbuf_push(sendbuf, OGS_GTPV1U_5GC_HEADER_LEN));
gtp_h = (ogs_gtp_header_t *)sendbuf->data;
/* Bits 8 7 6 5 4 3 2 1
* +--+--+--+--+--+--+--+--+
* |version |PT| 1| E| S|PN|
* +--+--+--+--+--+--+--+--+
* 0 0 1 1 0 1 0 0
*/
gtp_h->flags = 0x34;
gtp_h->type = OGS_GTPU_MSGTYPE_GPDU;
gtp_h->length = htobe16(sendbuf->len - OGS_GTPV1U_HEADER_LEN);
gtp_h->teid = htobe32(far->outer_header_creation.teid);
ext_h = (ogs_gtp_extension_header_t *)(
sendbuf->data + OGS_GTPV1U_HEADER_LEN);
ext_h->type = OGS_GTP_EXTENSION_HEADER_TYPE_PDU_SESSION_CONTAINER;
ext_h->len = 1;
ext_h->pdu_type =
OGS_GTP_EXTENSION_HEADER_PDU_TYPE_DL_PDU_SESSION_INFORMATION;
ext_h->qos_flow_identifier = qer->qfi;
ext_h->next_type =
OGS_GTP_EXTENSION_HEADER_TYPE_NO_MORE_EXTENSION_HEADERS;
} else {
ogs_assert(ogs_pkbuf_push(sendbuf, OGS_GTPV1U_HEADER_LEN));
gtp_h = (ogs_gtp_header_t *)sendbuf->data;
/* Bits 8 7 6 5 4 3 2 1
* +--+--+--+--+--+--+--+--+
* |version |PT| 1| E| S|PN|
* +--+--+--+--+--+--+--+--+
* 0 0 1 1 0 0 0 0
*/
gtp_h->flags = 0x30;
gtp_h->type = OGS_GTPU_MSGTYPE_GPDU;
gtp_h->length = htobe16(sendbuf->len - OGS_GTPV1U_HEADER_LEN);
gtp_h->teid = htobe32(far->outer_header_creation.teid);
}
/* Send to gNB */
ogs_debug("SEND GPU-U to gNB[%s] : TEID[0x%x]",
@ -524,8 +557,8 @@ static int upf_gtp_send_router_advertisement(
dev = subnet->dev;
ogs_assert(dev);
pkbuf = ogs_pkbuf_alloc(NULL, OGS_GTPV1U_HEADER_LEN+200);
ogs_pkbuf_reserve(pkbuf, OGS_GTPV1U_HEADER_LEN);
pkbuf = ogs_pkbuf_alloc(NULL, OGS_GTPV1U_5GC_HEADER_LEN+200);
ogs_pkbuf_reserve(pkbuf, OGS_GTPV1U_5GC_HEADER_LEN);
ogs_pkbuf_put(pkbuf, 200);
pkbuf->len = sizeof *ip6_h + sizeof *advert_h + sizeof *prefix;
memset(pkbuf->data, 0, pkbuf->len);

View File

@ -471,6 +471,9 @@ static ogs_pfcp_qer_t *handle_create_qer(ogs_pfcp_sess_t *sess,
if (message->guaranteed_bitrate.presence)
ogs_pfcp_parse_bitrate(&qer->gbr, &message->guaranteed_bitrate);
if (message->qos_flow_identifier.presence)
qer->qfi = message->qos_flow_identifier.u8;
return qer;
}