forked from acouzens/open5gs
Now, F-TEID is allocated in the UP function.
This commit is contained in:
parent
aa81bb2c89
commit
a470131489
|
@ -341,6 +341,29 @@ void ogs_pfcp_build_create_pdr(
|
|||
}
|
||||
}
|
||||
|
||||
void ogs_pfcp_build_created_pdr(
|
||||
ogs_pfcp_tlv_created_pdr_t *message, int i, ogs_pfcp_pdr_t *pdr)
|
||||
{
|
||||
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);
|
||||
pdrbuf[i].f_teid.teid = htobe32(pdr->f_teid.teid);
|
||||
|
||||
message->local_f_teid.presence = 1;
|
||||
message->local_f_teid.data = &pdrbuf[i].f_teid;
|
||||
message->local_f_teid.len = pdr->f_teid_len;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ogs_pfcp_build_update_pdr(
|
||||
ogs_pfcp_tlv_update_pdr_t *message, int i, ogs_pfcp_pdr_t *pdr)
|
||||
{
|
||||
|
|
|
@ -40,6 +40,8 @@ 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(
|
||||
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);
|
||||
|
||||
|
|
|
@ -835,11 +835,15 @@ ogs_pfcp_pdr_t *ogs_pfcp_pdr_add(ogs_pfcp_sess_t *sess)
|
|||
ogs_assert(pdr);
|
||||
memset(pdr, 0, sizeof *pdr);
|
||||
|
||||
pdr->index = ogs_pool_index(&ogs_pfcp_pdr_pool, pdr);
|
||||
ogs_assert(pdr->index > 0 &&
|
||||
pdr->index <= ogs_app()->pool.sess * OGS_MAX_NUM_OF_PDR);
|
||||
|
||||
ogs_pool_alloc(&sess->pdr_id_pool, &pdr->id_node);
|
||||
ogs_assert(pdr->id_node);
|
||||
|
||||
pdr->index = *(pdr->id_node);
|
||||
ogs_assert(pdr->index > 0 && pdr->index <= OGS_MAX_NUM_OF_PDR);
|
||||
pdr->id = *(pdr->id_node);
|
||||
ogs_assert(pdr->id > 0 && pdr->id <= OGS_MAX_NUM_OF_PDR);
|
||||
|
||||
pdr->sess = sess;
|
||||
ogs_list_add(&sess->pdr_list, pdr);
|
||||
|
@ -983,8 +987,8 @@ ogs_pfcp_far_t *ogs_pfcp_far_add(ogs_pfcp_sess_t *sess)
|
|||
ogs_pool_alloc(&sess->far_id_pool, &far->id_node);
|
||||
ogs_assert(far->id_node);
|
||||
|
||||
far->index = *(far->id_node);
|
||||
ogs_assert(far->index > 0 && far->index <= OGS_MAX_NUM_OF_FAR);
|
||||
far->id = *(far->id_node);
|
||||
ogs_assert(far->id > 0 && far->id <= OGS_MAX_NUM_OF_FAR);
|
||||
|
||||
far->apply_action = OGS_PFCP_APPLY_ACTION_FORW;
|
||||
|
||||
|
@ -1172,8 +1176,8 @@ ogs_pfcp_urr_t *ogs_pfcp_urr_add(ogs_pfcp_sess_t *sess)
|
|||
ogs_pool_alloc(&sess->urr_id_pool, &urr->id_node);
|
||||
ogs_assert(urr->id_node);
|
||||
|
||||
urr->index = *(urr->id_node);
|
||||
ogs_assert(urr->index > 0 && urr->index <= OGS_MAX_NUM_OF_URR);
|
||||
urr->id = *(urr->id_node);
|
||||
ogs_assert(urr->id > 0 && urr->id <= OGS_MAX_NUM_OF_URR);
|
||||
|
||||
urr->sess = sess;
|
||||
ogs_list_add(&sess->urr_list, urr);
|
||||
|
@ -1250,8 +1254,8 @@ ogs_pfcp_qer_t *ogs_pfcp_qer_add(ogs_pfcp_sess_t *sess)
|
|||
ogs_pool_alloc(&sess->qer_id_pool, &qer->id_node);
|
||||
ogs_assert(qer->id_node);
|
||||
|
||||
qer->index = *(qer->id_node);
|
||||
ogs_assert(qer->index > 0 && qer->index <= OGS_MAX_NUM_OF_QER);
|
||||
qer->id = *(qer->id_node);
|
||||
ogs_assert(qer->id > 0 && qer->id <= OGS_MAX_NUM_OF_QER);
|
||||
|
||||
qer->sess = sess;
|
||||
ogs_list_add(&sess->qer_list, qer);
|
||||
|
|
|
@ -99,6 +99,9 @@ typedef struct ogs_pfcp_node_s {
|
|||
uint8_t rr_enable;
|
||||
|
||||
ogs_list_t gtpu_resource_list; /* User Plane IP Resource Information */
|
||||
|
||||
ogs_pfcp_up_function_features_t up_function_features;
|
||||
int up_function_features_len;
|
||||
} ogs_pfcp_node_t;
|
||||
|
||||
typedef struct ogs_pfcp_gtpu_resource_s {
|
||||
|
@ -160,7 +163,6 @@ typedef struct ogs_pfcp_far_hashkey_s {
|
|||
|
||||
typedef struct ogs_pfcp_far_s {
|
||||
ogs_lnode_t lnode;
|
||||
uint32_t index;
|
||||
|
||||
int hashkey_len;
|
||||
ogs_pfcp_far_hashkey_t hashkey;
|
||||
|
@ -184,7 +186,6 @@ typedef struct ogs_pfcp_far_s {
|
|||
|
||||
typedef struct ogs_pfcp_urr_s {
|
||||
ogs_lnode_t lnode;
|
||||
uint32_t index;
|
||||
|
||||
uint8_t *id_node; /* Pool-Node for ID */
|
||||
ogs_pfcp_urr_id_t id;
|
||||
|
@ -194,7 +195,6 @@ typedef struct ogs_pfcp_urr_s {
|
|||
|
||||
typedef struct ogs_pfcp_qer_s {
|
||||
ogs_lnode_t lnode;
|
||||
uint32_t index;
|
||||
|
||||
uint8_t *id_node; /* Pool-Node for ID */
|
||||
ogs_pfcp_qer_id_t id;
|
||||
|
@ -210,7 +210,6 @@ typedef struct ogs_pfcp_qer_s {
|
|||
|
||||
typedef struct ogs_pfcp_bar_s {
|
||||
ogs_lnode_t lnode;
|
||||
uint32_t index;
|
||||
|
||||
uint8_t *id_node; /* Pool-Node for ID */
|
||||
ogs_pfcp_bar_id_t id;
|
||||
|
|
|
@ -206,6 +206,43 @@ int ogs_pfcp_sockaddr_to_f_teid(
|
|||
return OGS_OK;
|
||||
}
|
||||
|
||||
int ogs_pfcp_f_teid_to_sockaddr(
|
||||
ogs_pfcp_f_teid_t *f_teid, int f_teid_len,
|
||||
ogs_sockaddr_t **addr, ogs_sockaddr_t **addr6)
|
||||
{
|
||||
ogs_assert(addr && addr6);
|
||||
ogs_assert(f_teid);
|
||||
ogs_assert(f_teid_len);
|
||||
|
||||
*addr = NULL;
|
||||
*addr6 = NULL;
|
||||
|
||||
if (f_teid->ipv4 && f_teid->ipv6) {
|
||||
*addr = ogs_calloc(1, sizeof(**addr));
|
||||
ogs_assert(*addr);
|
||||
(*addr)->sin.sin_addr.s_addr = f_teid->both.addr;
|
||||
(*addr)->ogs_sa_family = AF_INET;
|
||||
|
||||
*addr6 = ogs_calloc(1, sizeof(**addr6));
|
||||
ogs_assert(*addr6);
|
||||
memcpy((*addr6)->sin6.sin6_addr.s6_addr,
|
||||
f_teid->both.addr6, OGS_IPV6_LEN);
|
||||
(*addr6)->ogs_sa_family = AF_INET6;
|
||||
} else if (f_teid->ipv4) {
|
||||
*addr = ogs_calloc(1, sizeof(**addr));
|
||||
ogs_assert(*addr);
|
||||
(*addr)->sin.sin_addr.s_addr = f_teid->addr;
|
||||
(*addr)->ogs_sa_family = AF_INET;
|
||||
} else if (f_teid->ipv6) {
|
||||
*addr6 = ogs_calloc(1, sizeof(**addr6));
|
||||
ogs_assert(*addr6);
|
||||
memcpy((*addr6)->sin6.sin6_addr.s6_addr, f_teid->addr6, OGS_IPV6_LEN);
|
||||
(*addr6)->ogs_sa_family = AF_INET6;
|
||||
}
|
||||
|
||||
return OGS_OK;
|
||||
}
|
||||
|
||||
int ogs_pfcp_sockaddr_to_user_plane_ip_resource_info(
|
||||
ogs_sockaddr_t *addr, ogs_sockaddr_t *addr6,
|
||||
ogs_pfcp_user_plane_ip_resource_info_t *info)
|
||||
|
@ -237,12 +274,14 @@ int ogs_pfcp_user_plane_ip_resource_info_to_sockaddr(
|
|||
|
||||
if (info->v4) {
|
||||
*addr = ogs_calloc(1, sizeof(**addr));
|
||||
ogs_assert(*addr);
|
||||
(*addr)->sin.sin_addr.s_addr = info->addr;
|
||||
(*addr)->ogs_sa_family = AF_INET;
|
||||
}
|
||||
|
||||
if (info->v6) {
|
||||
*addr6 = ogs_calloc(1, sizeof(**addr6));
|
||||
ogs_assert(*addr6);
|
||||
memcpy((*addr6)->sin6.sin6_addr.s6_addr, info->addr6, OGS_IPV6_LEN);
|
||||
(*addr6)->ogs_sa_family = AF_INET6;
|
||||
}
|
||||
|
|
|
@ -41,6 +41,9 @@ int ogs_pfcp_f_seid_to_ip(ogs_pfcp_f_seid_t *f_seid, ogs_ip_t *ip);
|
|||
|
||||
int ogs_pfcp_sockaddr_to_f_teid(
|
||||
ogs_sockaddr_t *a, ogs_sockaddr_t *b, ogs_pfcp_f_teid_t *f_teid, int *len);
|
||||
int ogs_pfcp_f_teid_to_sockaddr(
|
||||
ogs_pfcp_f_teid_t *f_teid, int f_teid_len,
|
||||
ogs_sockaddr_t **addr, ogs_sockaddr_t **addr6);
|
||||
|
||||
int ogs_pfcp_sockaddr_to_user_plane_ip_resource_info(
|
||||
ogs_sockaddr_t *addr, ogs_sockaddr_t *addr6,
|
||||
|
|
|
@ -67,11 +67,9 @@ void ogs_pfcp_cp_handle_association_setup_request(
|
|||
|
||||
if (req->up_function_features.presence) {
|
||||
if (req->up_function_features.data && req->up_function_features.len) {
|
||||
ogs_pfcp_self()->up_function_features_len =
|
||||
req->up_function_features.len;
|
||||
memcpy(&ogs_pfcp_self()->up_function_features,
|
||||
req->up_function_features.data,
|
||||
ogs_pfcp_self()->up_function_features_len);
|
||||
node->up_function_features_len = req->up_function_features.len;
|
||||
memcpy(&node->up_function_features, req->up_function_features.data,
|
||||
node->up_function_features_len);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -104,11 +102,9 @@ void ogs_pfcp_cp_handle_association_setup_response(
|
|||
|
||||
if (rsp->up_function_features.presence) {
|
||||
if (rsp->up_function_features.data && rsp->up_function_features.len) {
|
||||
ogs_pfcp_self()->up_function_features_len =
|
||||
rsp->up_function_features.len;
|
||||
memcpy(&ogs_pfcp_self()->up_function_features,
|
||||
rsp->up_function_features.data,
|
||||
ogs_pfcp_self()->up_function_features_len);
|
||||
node->up_function_features_len = rsp->up_function_features.len;
|
||||
memcpy(&node->up_function_features, rsp->up_function_features.data,
|
||||
node->up_function_features_len);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -401,6 +397,42 @@ ogs_pfcp_pdr_t *ogs_pfcp_handle_create_pdr(ogs_pfcp_sess_t *sess,
|
|||
return pdr;
|
||||
}
|
||||
|
||||
ogs_pfcp_pdr_t *ogs_pfcp_handle_created_pdr(ogs_pfcp_sess_t *sess,
|
||||
ogs_pfcp_tlv_created_pdr_t *message,
|
||||
uint8_t *cause_value, uint8_t *offending_ie_value)
|
||||
{
|
||||
ogs_pfcp_pdr_t *pdr = NULL;
|
||||
|
||||
ogs_assert(sess);
|
||||
ogs_assert(message);
|
||||
|
||||
if (message->presence == 0)
|
||||
return NULL;
|
||||
|
||||
if (message->pdr_id.presence == 0) {
|
||||
ogs_error("No PDR-ID");
|
||||
*cause_value = OGS_PFCP_CAUSE_MANDATORY_IE_MISSING;
|
||||
*offending_ie_value = OGS_PFCP_PDR_ID_TYPE;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pdr = ogs_pfcp_pdr_find(sess, message->pdr_id.u16);
|
||||
if (!pdr) {
|
||||
ogs_error("Cannot find PDR-ID[%d] in PDR", message->pdr_id.u16);
|
||||
*cause_value = OGS_PFCP_CAUSE_MANDATORY_IE_INCORRECT;
|
||||
*offending_ie_value = OGS_PFCP_PDR_ID_TYPE;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (message->local_f_teid.presence) {
|
||||
pdr->f_teid_len = message->local_f_teid.len;
|
||||
memcpy(&pdr->f_teid, message->local_f_teid.data, pdr->f_teid_len);
|
||||
pdr->f_teid.teid = be32toh(pdr->f_teid.teid);
|
||||
}
|
||||
|
||||
return pdr;
|
||||
}
|
||||
|
||||
ogs_pfcp_pdr_t *ogs_pfcp_handle_update_pdr(ogs_pfcp_sess_t *sess,
|
||||
ogs_pfcp_tlv_update_pdr_t *message,
|
||||
uint8_t *cause_value, uint8_t *offending_ie_value)
|
||||
|
|
|
@ -54,6 +54,9 @@ void ogs_pfcp_up_handle_error_indication(
|
|||
ogs_pfcp_pdr_t *ogs_pfcp_handle_create_pdr(ogs_pfcp_sess_t *sess,
|
||||
ogs_pfcp_tlv_create_pdr_t *message,
|
||||
uint8_t *cause_value, uint8_t *offending_ie_value);
|
||||
ogs_pfcp_pdr_t *ogs_pfcp_handle_created_pdr(ogs_pfcp_sess_t *sess,
|
||||
ogs_pfcp_tlv_created_pdr_t *message,
|
||||
uint8_t *cause_value, uint8_t *offending_ie_value);
|
||||
ogs_pfcp_pdr_t *ogs_pfcp_handle_update_pdr(ogs_pfcp_sess_t *sess,
|
||||
ogs_pfcp_tlv_update_pdr_t *message,
|
||||
uint8_t *cause_value, uint8_t *offending_ie_value);
|
||||
|
|
|
@ -435,13 +435,60 @@ ED3(uint8_t spare:6;,
|
|||
};
|
||||
} __attribute__ ((packed)) ogs_pfcp_f_seid_t;
|
||||
|
||||
/*
|
||||
* 8.2.3 F-TEID
|
||||
*
|
||||
* The following flags are coded within Octet 5:
|
||||
*
|
||||
* - Bit 1 – V4: If this bit is set to "1" and the CH bit is not set,
|
||||
* then the IPv4 address field shall be present,
|
||||
* otherwise the IPv4 address field shall not be present.
|
||||
* - Bit 2 – V6: If this bit is set to "1" and the CH bit is not set,
|
||||
* then the IPv6 address field shall be present,
|
||||
* otherwise the IPv6 address field shall not be present.
|
||||
* - Bit 3 – CH (CHOOSE): If this bit is set to "1", then the TEID,
|
||||
* IPv4 address and IPv6 address fields shall not be present and
|
||||
* the UP function shall assign an F-TEID with an IP4 or an IPv6 address
|
||||
* if the V4 or V6 bit is set respectively. This bit shall only be set
|
||||
* by the CP function.
|
||||
* - Bit 4 – CHID (CHOOSE ID): If this bit is set to "1",
|
||||
* then the UP function shall assign the same F-TEID to the PDRs requested
|
||||
* to be created in a PFCP Session Establishment Request or
|
||||
* PFCP Session Modification Request with the same CHOOSE ID value.
|
||||
* This bit may only be set to "1" if the CH bit it set to "1".
|
||||
* This bit shall only be set by the CP function.
|
||||
* - Bit 5 to 8: Spare, for future use and set to 0.
|
||||
*
|
||||
* At least one of the V4 and V6 flags shall be set to "1", and
|
||||
* both may be set to "1" for both scenarios:
|
||||
*
|
||||
* - when the CP function is allocating F-TEID, i.e. both IPv4 address field
|
||||
* and IPv6 address field may be present;
|
||||
* - or when the UP function is requested to allocate the F-TEID,
|
||||
* i.e. when CHOOSE bit is set to "1", and the IPv4 address and
|
||||
* IPv6 address fields are not present.
|
||||
*
|
||||
* Octet 6 to 9 (TEID) shall be present and shall contain a GTP-U TEID,
|
||||
* if the CH bit in octet 5 is not set. When the TEID is present,
|
||||
* if both IPv4 and IPv6 addresses are present in the F-TEID IE,
|
||||
* then the TEID value shall be shared by both addresses.
|
||||
*
|
||||
* Octets "m to (m+3)" and/or "p to (p+15)"(IPv4 address / IPv6 address fields),
|
||||
* if present, it shall contain the respective IP address values.
|
||||
*
|
||||
* Octet q shall be present and shall contain a binary integer value
|
||||
* if the CHID bit in octet 5 is set to "1".
|
||||
*/
|
||||
typedef struct ogs_pfcp_f_teid_s {
|
||||
ED5(uint8_t spare:4;,
|
||||
uint8_t chid:1;,
|
||||
uint8_t ch:1;,
|
||||
uint8_t ipv6:1;,
|
||||
uint8_t ipv4:1;)
|
||||
uint32_t teid;
|
||||
union {
|
||||
uint32_t teid;
|
||||
uint8_t choose_id;
|
||||
};
|
||||
union {
|
||||
union {
|
||||
uint32_t addr;
|
||||
|
@ -451,7 +498,6 @@ ED5(uint8_t spare:4;,
|
|||
uint8_t addr6[OGS_IPV6_LEN];
|
||||
} both;
|
||||
};
|
||||
uint8_t choose_id;
|
||||
};
|
||||
} __attribute__ ((packed)) ogs_pfcp_f_teid_t;
|
||||
|
||||
|
|
|
@ -126,7 +126,7 @@ void mme_s11_handle_create_session_response(
|
|||
}
|
||||
|
||||
if (cause_value != OGS_GTP_CAUSE_REQUEST_ACCEPTED) {
|
||||
if (SESSION_CONTEXT_IN_ATTACH(sess)) {
|
||||
if (sess && SESSION_CONTEXT_IN_ATTACH(sess)) {
|
||||
ogs_error("[%s] Attach reject", mme_ue->imsi_bcd);
|
||||
nas_eps_send_attach_reject(mme_ue,
|
||||
EMM_CAUSE_NETWORK_FAILURE, ESM_CAUSE_NETWORK_FAILURE);
|
||||
|
|
|
@ -646,11 +646,6 @@ void sgwc_bearer_remove_all(sgwc_sess_t *sess)
|
|||
sgwc_bearer_remove(bearer);
|
||||
}
|
||||
|
||||
sgwc_bearer_t *sgwc_bearer_find_by_sgwc_s5u_teid(uint32_t sgwc_s5u_teid)
|
||||
{
|
||||
return ogs_pool_find(&sgwc_bearer_pool, sgwc_s5u_teid);
|
||||
}
|
||||
|
||||
sgwc_bearer_t *sgwc_bearer_find_by_sess_ebi(sgwc_sess_t *sess, uint8_t ebi)
|
||||
{
|
||||
sgwc_bearer_t *bearer = NULL;
|
||||
|
@ -797,7 +792,6 @@ sgwc_tunnel_t *sgwc_tunnel_add(
|
|||
|
||||
pdr = ogs_pfcp_pdr_add(&sess->pfcp);
|
||||
ogs_assert(pdr);
|
||||
pdr->id = pdr->index;
|
||||
pdr->src_if = src_if;
|
||||
|
||||
if (strlen(sess->pdn.apn))
|
||||
|
@ -818,40 +812,43 @@ sgwc_tunnel_t *sgwc_tunnel_add(
|
|||
|
||||
far = ogs_pfcp_far_add(&sess->pfcp);
|
||||
ogs_assert(far);
|
||||
far->id = far->index;
|
||||
far->dst_if = dst_if;
|
||||
ogs_pfcp_pdr_associate_far(pdr, far);
|
||||
|
||||
ogs_assert(sess->pfcp_node);
|
||||
resource = ogs_pfcp_gtpu_resource_find(
|
||||
&sess->pfcp_node->gtpu_resource_list,
|
||||
sess->pdn.apn, OGS_PFCP_INTERFACE_ACCESS);
|
||||
if (resource) {
|
||||
ogs_pfcp_user_plane_ip_resource_info_to_sockaddr(&resource->info,
|
||||
&tunnel->local_addr, &tunnel->local_addr6);
|
||||
ogs_assert(tunnel->local_addr || tunnel->local_addr6);
|
||||
if (resource->info.teidri)
|
||||
tunnel->local_teid = OGS_PFCP_GTPU_INDEX_TO_TEID(
|
||||
tunnel->index, resource->info.teidri,
|
||||
resource->info.teid_range);
|
||||
else
|
||||
tunnel->local_teid = tunnel->index;
|
||||
if (sess->pfcp_node->up_function_features.ftup) {
|
||||
pdr->f_teid.ch = 1;
|
||||
pdr->f_teid_len = 1;
|
||||
} else {
|
||||
if (sess->pfcp_node->addr.ogs_sa_family == AF_INET)
|
||||
ogs_copyaddrinfo(&tunnel->local_addr, &sess->pfcp_node->addr);
|
||||
else if (sess->pfcp_node->addr.ogs_sa_family == AF_INET6)
|
||||
ogs_copyaddrinfo(&tunnel->local_addr6, &sess->pfcp_node->addr);
|
||||
else
|
||||
ogs_assert_if_reached();
|
||||
resource = ogs_pfcp_gtpu_resource_find(
|
||||
&sess->pfcp_node->gtpu_resource_list,
|
||||
sess->pdn.apn, OGS_PFCP_INTERFACE_ACCESS);
|
||||
if (resource) {
|
||||
ogs_pfcp_user_plane_ip_resource_info_to_sockaddr(&resource->info,
|
||||
&tunnel->local_addr, &tunnel->local_addr6);
|
||||
if (resource->info.teidri)
|
||||
tunnel->local_teid = OGS_PFCP_GTPU_INDEX_TO_TEID(
|
||||
tunnel->index, resource->info.teidri,
|
||||
resource->info.teid_range);
|
||||
else
|
||||
tunnel->local_teid = tunnel->index;
|
||||
} else {
|
||||
if (sess->pfcp_node->addr.ogs_sa_family == AF_INET)
|
||||
ogs_copyaddrinfo(&tunnel->local_addr, &sess->pfcp_node->addr);
|
||||
else if (sess->pfcp_node->addr.ogs_sa_family == AF_INET6)
|
||||
ogs_copyaddrinfo(&tunnel->local_addr6, &sess->pfcp_node->addr);
|
||||
else
|
||||
ogs_assert_if_reached();
|
||||
|
||||
tunnel->local_teid = tunnel->index;
|
||||
}
|
||||
|
||||
ogs_assert(tunnel->local_addr || tunnel->local_addr6);
|
||||
|
||||
tunnel->local_teid = tunnel->index;
|
||||
ogs_pfcp_sockaddr_to_f_teid(tunnel->local_addr, tunnel->local_addr6,
|
||||
&pdr->f_teid, &pdr->f_teid_len);
|
||||
pdr->f_teid.teid = tunnel->local_teid;
|
||||
}
|
||||
|
||||
ogs_pfcp_sockaddr_to_f_teid(tunnel->local_addr, tunnel->local_addr6,
|
||||
&pdr->f_teid, &pdr->f_teid_len);
|
||||
pdr->f_teid.teid = tunnel->local_teid;
|
||||
|
||||
tunnel->pdr = pdr;
|
||||
tunnel->far = far;
|
||||
|
||||
|
@ -891,9 +888,23 @@ void sgwc_tunnel_remove_all(sgwc_bearer_t *bearer)
|
|||
sgwc_tunnel_remove(tunnel);
|
||||
}
|
||||
|
||||
sgwc_tunnel_t *sgwc_tunnel_find_by_teid(uint32_t teid)
|
||||
sgwc_tunnel_t *sgwc_tunnel_find_by_teid(sgwc_ue_t *sgwc_ue, uint32_t teid)
|
||||
{
|
||||
return ogs_pool_find(&sgwc_tunnel_pool, teid);
|
||||
sgwc_sess_t *sess = NULL;
|
||||
sgwc_bearer_t *bearer = NULL;
|
||||
sgwc_tunnel_t *tunnel = NULL;
|
||||
|
||||
ogs_assert(sgwc_ue);
|
||||
|
||||
ogs_list_for_each(&sgwc_ue->sess_list, sess) {
|
||||
ogs_list_for_each(&sess->bearer_list, bearer) {
|
||||
ogs_list_for_each(&bearer->tunnel_list, tunnel) {
|
||||
if (tunnel->local_teid == teid) return tunnel;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sgwc_tunnel_t *sgwc_tunnel_find_by_interface_type(
|
||||
|
@ -909,6 +920,28 @@ sgwc_tunnel_t *sgwc_tunnel_find_by_interface_type(
|
|||
return NULL;
|
||||
}
|
||||
|
||||
sgwc_tunnel_t *sgwc_tunnel_find_by_pdr_id(
|
||||
sgwc_sess_t *sess, ogs_pfcp_pdr_id_t pdr_id)
|
||||
{
|
||||
sgwc_bearer_t *bearer = NULL;
|
||||
sgwc_tunnel_t *tunnel = NULL;
|
||||
|
||||
ogs_pfcp_pdr_t *pdr = NULL;
|
||||
|
||||
ogs_assert(sess);
|
||||
|
||||
ogs_list_for_each(&sess->bearer_list, bearer) {
|
||||
ogs_list_for_each(&bearer->tunnel_list, tunnel) {
|
||||
pdr = tunnel->pdr;
|
||||
ogs_assert(pdr);
|
||||
|
||||
if (pdr->id == pdr_id) return tunnel;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sgwc_tunnel_t *sgwc_dl_tunnel_in_bearer(sgwc_bearer_t *bearer)
|
||||
{
|
||||
ogs_assert(bearer);
|
||||
|
|
|
@ -179,8 +179,6 @@ sgwc_sess_t *sgwc_sess_find_by_ebi(sgwc_ue_t *sgwc_ue, uint8_t ebi);
|
|||
sgwc_bearer_t *sgwc_bearer_add(sgwc_sess_t *sess);
|
||||
int sgwc_bearer_remove(sgwc_bearer_t *bearer);
|
||||
void sgwc_bearer_remove_all(sgwc_sess_t *sess);
|
||||
sgwc_bearer_t *sgwc_bearer_find_by_sgwc_s5u_teid(
|
||||
uint32_t sgwc_s5u_teid);
|
||||
sgwc_bearer_t *sgwc_bearer_find_by_sess_ebi(
|
||||
sgwc_sess_t *sess, uint8_t ebi);
|
||||
sgwc_bearer_t *sgwc_bearer_find_by_ue_ebi(
|
||||
|
@ -194,9 +192,11 @@ sgwc_tunnel_t *sgwc_tunnel_add(
|
|||
sgwc_bearer_t *bearer, uint8_t interface_type);
|
||||
int sgwc_tunnel_remove(sgwc_tunnel_t *tunnel);
|
||||
void sgwc_tunnel_remove_all(sgwc_bearer_t *bearer);
|
||||
sgwc_tunnel_t *sgwc_tunnel_find_by_teid(uint32_t teid);
|
||||
sgwc_tunnel_t *sgwc_tunnel_find_by_teid(sgwc_ue_t *sgwc_ue, uint32_t teid);
|
||||
sgwc_tunnel_t *sgwc_tunnel_find_by_interface_type(
|
||||
sgwc_bearer_t *bearer, uint8_t interface_type);
|
||||
sgwc_tunnel_t *sgwc_tunnel_find_by_pdr_id(
|
||||
sgwc_sess_t *sess, ogs_pfcp_pdr_id_t pdr_id);
|
||||
sgwc_tunnel_t *sgwc_dl_tunnel_in_bearer(sgwc_bearer_t *bearer);
|
||||
sgwc_tunnel_t *sgwc_ul_tunnel_in_bearer(sgwc_bearer_t *bearer);
|
||||
|
||||
|
|
|
@ -235,6 +235,7 @@ void sgwc_s11_handle_modify_bearer_request(
|
|||
uint16_t decoded;
|
||||
uint64_t flags = 0;
|
||||
|
||||
sgwc_sess_t *sess = NULL;
|
||||
sgwc_bearer_t *bearer = NULL;
|
||||
sgwc_tunnel_t *dl_tunnel = NULL;
|
||||
ogs_pfcp_far_t *far = NULL;
|
||||
|
@ -291,6 +292,10 @@ void sgwc_s11_handle_modify_bearer_request(
|
|||
return;
|
||||
}
|
||||
|
||||
ogs_assert(bearer);
|
||||
sess = bearer->sess;
|
||||
ogs_assert(sess);
|
||||
|
||||
dl_tunnel = sgwc_dl_tunnel_in_bearer(bearer);
|
||||
ogs_assert(dl_tunnel);
|
||||
|
||||
|
@ -332,8 +337,10 @@ void sgwc_s11_handle_modify_bearer_request(
|
|||
if (memcmp(&dl_tunnel->remote_ip, &zero_ip, sizeof(ogs_ip_t)) != 0 &&
|
||||
memcmp(&dl_tunnel->remote_ip, &remote_ip, sizeof(ogs_ip_t)) != 0) {
|
||||
|
||||
ogs_assert(sess->pfcp_node);
|
||||
|
||||
/* eNB IP is changed during handover */
|
||||
if (ogs_pfcp_self()->up_function_features.empu) {
|
||||
if (sess->pfcp_node->up_function_features.empu) {
|
||||
flags |= OGS_PFCP_MODIFY_END_MARKER;
|
||||
} else {
|
||||
ogs_error("SGW-U does not support End Marker");
|
||||
|
@ -519,12 +526,14 @@ void sgwc_s11_handle_create_bearer_response(
|
|||
return;
|
||||
}
|
||||
|
||||
ogs_assert(sgwc_ue);
|
||||
|
||||
/* Correlate with SGW-S1U-TEID */
|
||||
sgw_s1u_teid = rsp->bearer_contexts.s4_u_sgsn_f_teid.data;
|
||||
ogs_assert(sgw_s1u_teid);
|
||||
|
||||
/* Find the Tunnel by SGW-S1U-TEID */
|
||||
ul_tunnel = sgwc_tunnel_find_by_teid(be32toh(sgw_s1u_teid->teid));
|
||||
ul_tunnel = sgwc_tunnel_find_by_teid(sgwc_ue, be32toh(sgw_s1u_teid->teid));
|
||||
ogs_assert(ul_tunnel);
|
||||
bearer = ul_tunnel->bearer;
|
||||
ogs_assert(bearer);
|
||||
|
|
|
@ -84,6 +84,7 @@ void sgwc_sxa_handle_session_establishment_response(
|
|||
{
|
||||
int rv, len = 0;
|
||||
uint8_t cause_value = 0;
|
||||
|
||||
ogs_pfcp_f_seid_t *up_f_seid = NULL;
|
||||
|
||||
ogs_gtp_f_teid_t sgw_s5c_teid, sgw_s5u_teid;
|
||||
|
@ -123,6 +124,11 @@ void sgwc_sxa_handle_session_establishment_response(
|
|||
cause_value = OGS_GTP_CAUSE_MANDATORY_IE_MISSING;
|
||||
}
|
||||
|
||||
if (pfcp_rsp->created_pdr[0].presence == 0) {
|
||||
ogs_error("No Created PDR");
|
||||
cause_value = OGS_GTP_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);
|
||||
|
@ -133,6 +139,48 @@ void sgwc_sxa_handle_session_establishment_response(
|
|||
cause_value = OGS_GTP_CAUSE_MANDATORY_IE_MISSING;
|
||||
}
|
||||
|
||||
if (cause_value == OGS_GTP_CAUSE_REQUEST_ACCEPTED) {
|
||||
int i;
|
||||
|
||||
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;
|
||||
|
||||
pdr = ogs_pfcp_handle_created_pdr(
|
||||
&sess->pfcp, &pfcp_rsp->created_pdr[i],
|
||||
&pfcp_cause_value, &offending_ie_value);
|
||||
|
||||
if (!pdr)
|
||||
break;
|
||||
|
||||
tunnel = sgwc_tunnel_find_by_pdr_id(sess, pdr->id);
|
||||
if (!tunnel) {
|
||||
pfcp_cause_value = OGS_PFCP_CAUSE_SESSION_CONTEXT_NOT_FOUND;
|
||||
break;
|
||||
}
|
||||
|
||||
ogs_assert(sess->pfcp_node);
|
||||
if (sess->pfcp_node->up_function_features.ftup &&
|
||||
pdr->f_teid_len) {
|
||||
if (tunnel->local_addr)
|
||||
ogs_freeaddrinfo(tunnel->local_addr);
|
||||
if (tunnel->local_addr6)
|
||||
ogs_freeaddrinfo(tunnel->local_addr6);
|
||||
|
||||
ogs_pfcp_f_teid_to_sockaddr(
|
||||
&pdr->f_teid, pdr->f_teid_len,
|
||||
&tunnel->local_addr, &tunnel->local_addr6);
|
||||
tunnel->local_teid = pdr->f_teid.teid;
|
||||
}
|
||||
}
|
||||
|
||||
cause_value = gtp_cause_from_pfcp(pfcp_cause_value);
|
||||
}
|
||||
|
||||
if (cause_value != OGS_GTP_CAUSE_REQUEST_ACCEPTED) {
|
||||
if (sess) sgwc_ue = sess->sgwc_ue;
|
||||
ogs_gtp_send_error_message(
|
||||
|
@ -148,6 +196,15 @@ void sgwc_sxa_handle_session_establishment_response(
|
|||
dl_tunnel = sgwc_dl_tunnel_in_bearer(bearer);
|
||||
ogs_assert(dl_tunnel);
|
||||
|
||||
if (dl_tunnel->local_addr == NULL && dl_tunnel->local_addr6 == NULL) {
|
||||
ogs_error("No UP F-TEID");
|
||||
ogs_gtp_send_error_message(
|
||||
s11_xact, sgwc_ue ? sgwc_ue->mme_s11_teid : 0,
|
||||
OGS_GTP_CREATE_SESSION_RESPONSE_TYPE,
|
||||
OGS_GTP_CAUSE_GRE_KEY_NOT_FOUND);
|
||||
return;
|
||||
}
|
||||
|
||||
/* UP F-SEID */
|
||||
up_f_seid = pfcp_rsp->up_f_seid.data;
|
||||
ogs_assert(up_f_seid);
|
||||
|
@ -195,6 +252,7 @@ void sgwc_sxa_handle_session_establishment_response(
|
|||
memset(&sgw_s5u_teid, 0, sizeof(ogs_gtp_f_teid_t));
|
||||
sgw_s5u_teid.teid = htobe32(dl_tunnel->local_teid);
|
||||
sgw_s5u_teid.interface_type = dl_tunnel->interface_type;
|
||||
ogs_assert(dl_tunnel->local_addr || dl_tunnel->local_addr6);
|
||||
rv = ogs_gtp_sockaddr_to_f_teid(
|
||||
dl_tunnel->local_addr, dl_tunnel->local_addr6, &sgw_s5u_teid, &len);
|
||||
ogs_assert(rv == OGS_OK);
|
||||
|
@ -265,6 +323,46 @@ void sgwc_sxa_handle_session_modification_response(
|
|||
cause_value = OGS_GTP_CAUSE_MANDATORY_IE_MISSING;
|
||||
}
|
||||
|
||||
if (cause_value == OGS_GTP_CAUSE_REQUEST_ACCEPTED) {
|
||||
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;
|
||||
|
||||
pdr = ogs_pfcp_handle_created_pdr(
|
||||
&sess->pfcp, &pfcp_rsp->created_pdr[i],
|
||||
&pfcp_cause_value, &offending_ie_value);
|
||||
|
||||
if (!pdr)
|
||||
break;
|
||||
|
||||
tunnel = sgwc_tunnel_find_by_pdr_id(sess, pdr->id);
|
||||
if (!tunnel) {
|
||||
pfcp_cause_value = OGS_PFCP_CAUSE_SESSION_CONTEXT_NOT_FOUND;
|
||||
break;
|
||||
}
|
||||
|
||||
ogs_assert(sess->pfcp_node);
|
||||
if (sess->pfcp_node->up_function_features.ftup &&
|
||||
pdr->f_teid_len) {
|
||||
if (tunnel->local_addr)
|
||||
ogs_freeaddrinfo(tunnel->local_addr);
|
||||
if (tunnel->local_addr6)
|
||||
ogs_freeaddrinfo(tunnel->local_addr6);
|
||||
|
||||
ogs_pfcp_f_teid_to_sockaddr(
|
||||
&pdr->f_teid, pdr->f_teid_len,
|
||||
&tunnel->local_addr, &tunnel->local_addr6);
|
||||
tunnel->local_teid = pdr->f_teid.teid;
|
||||
}
|
||||
}
|
||||
|
||||
cause_value = gtp_cause_from_pfcp(pfcp_cause_value);
|
||||
}
|
||||
|
||||
if (cause_value != OGS_GTP_CAUSE_REQUEST_ACCEPTED) {
|
||||
if (sess) sgwc_ue = sess->sgwc_ue;
|
||||
if (flags & OGS_PFCP_MODIFY_CREATE) {
|
||||
|
@ -353,6 +451,7 @@ void sgwc_sxa_handle_session_modification_response(
|
|||
memset(&sgw_s1u_teid, 0, sizeof(ogs_gtp_f_teid_t));
|
||||
sgw_s1u_teid.interface_type = ul_tunnel->interface_type;
|
||||
sgw_s1u_teid.teid = htobe32(ul_tunnel->local_teid);
|
||||
ogs_assert(ul_tunnel->local_addr || ul_tunnel->local_addr6);
|
||||
rv = ogs_gtp_sockaddr_to_f_teid(
|
||||
ul_tunnel->local_addr, ul_tunnel->local_addr6,
|
||||
&sgw_s1u_teid, &len);
|
||||
|
@ -398,6 +497,7 @@ void sgwc_sxa_handle_session_modification_response(
|
|||
memset(&sgw_s5u_teid, 0, sizeof(ogs_gtp_f_teid_t));
|
||||
sgw_s5u_teid.interface_type = OGS_GTP_F_TEID_S5_S8_SGW_GTP_U;
|
||||
sgw_s5u_teid.teid = htobe32(dl_tunnel->local_teid);
|
||||
ogs_assert(dl_tunnel->local_addr || dl_tunnel->local_addr6);
|
||||
rv = ogs_gtp_sockaddr_to_f_teid(
|
||||
dl_tunnel->local_addr, dl_tunnel->local_addr6,
|
||||
&sgw_s5u_teid, &len);
|
||||
|
@ -485,6 +585,8 @@ void sgwc_sxa_handle_session_modification_response(
|
|||
rsp_dl_teid[i].interface_type =
|
||||
tunnel->interface_type;
|
||||
rsp_dl_teid[i].teid = htobe32(tunnel->local_teid);
|
||||
ogs_assert(
|
||||
tunnel->local_addr || tunnel->local_addr6);
|
||||
rv = ogs_gtp_sockaddr_to_f_teid(
|
||||
tunnel->local_addr, tunnel->local_addr6,
|
||||
&rsp_dl_teid[i], &len);
|
||||
|
@ -504,6 +606,8 @@ void sgwc_sxa_handle_session_modification_response(
|
|||
rsp_ul_teid[i].teid = htobe32(tunnel->local_teid);
|
||||
rsp_ul_teid[i].interface_type =
|
||||
tunnel->interface_type;
|
||||
ogs_assert(
|
||||
tunnel->local_addr || tunnel->local_addr6);
|
||||
rv = ogs_gtp_sockaddr_to_f_teid(
|
||||
tunnel->local_addr, tunnel->local_addr6,
|
||||
&rsp_ul_teid[i], &len);
|
||||
|
@ -663,6 +767,7 @@ void sgwc_sxa_handle_session_modification_response(
|
|||
memset(&sgw_s1u_teid, 0, sizeof(ogs_gtp_f_teid_t));
|
||||
sgw_s1u_teid.interface_type = ul_tunnel->interface_type;
|
||||
sgw_s1u_teid.teid = htobe32(ul_tunnel->local_teid);
|
||||
ogs_assert(ul_tunnel->local_addr || ul_tunnel->local_addr6);
|
||||
rv = ogs_gtp_sockaddr_to_f_teid(
|
||||
ul_tunnel->local_addr, ul_tunnel->local_addr6,
|
||||
&sgw_s1u_teid, &len);
|
||||
|
|
|
@ -24,6 +24,7 @@ ogs_pkbuf_t *sgwu_sxa_build_session_establishment_response(uint8_t type,
|
|||
{
|
||||
ogs_pfcp_message_t pfcp_message;
|
||||
ogs_pfcp_session_establishment_response_t *rsp = NULL;
|
||||
ogs_pkbuf_t *pkbuf = NULL;
|
||||
|
||||
int i = 0;
|
||||
|
||||
|
@ -58,18 +59,19 @@ ogs_pkbuf_t *sgwu_sxa_build_session_establishment_response(uint8_t type,
|
|||
rsp->up_f_seid.data = &f_seid;
|
||||
rsp->up_f_seid.len = len;
|
||||
|
||||
ogs_pfcp_pdrbuf_init();
|
||||
|
||||
/* Created PDR */
|
||||
for (i = 0; i < num_of_created_pdr; i++) {
|
||||
ogs_pfcp_tlv_created_pdr_t *message = &rsp->created_pdr[i];
|
||||
ogs_assert(message);
|
||||
|
||||
message->presence = 1;
|
||||
message->pdr_id.presence = 1;
|
||||
message->pdr_id.u16 = created_pdr[i]->id;
|
||||
ogs_pfcp_build_created_pdr(&rsp->created_pdr[i], i, created_pdr[i]);
|
||||
}
|
||||
|
||||
pfcp_message.h.type = type;
|
||||
return ogs_pfcp_build_msg(&pfcp_message);
|
||||
pkbuf = ogs_pfcp_build_msg(&pfcp_message);
|
||||
|
||||
ogs_pfcp_pdrbuf_clear();
|
||||
|
||||
return pkbuf;
|
||||
}
|
||||
|
||||
ogs_pkbuf_t *sgwu_sxa_build_session_modification_response(uint8_t type,
|
||||
|
@ -77,6 +79,7 @@ ogs_pkbuf_t *sgwu_sxa_build_session_modification_response(uint8_t type,
|
|||
{
|
||||
ogs_pfcp_message_t pfcp_message;
|
||||
ogs_pfcp_session_modification_response_t *rsp = NULL;
|
||||
ogs_pkbuf_t *pkbuf = NULL;
|
||||
|
||||
int i = 0;
|
||||
|
||||
|
@ -89,18 +92,19 @@ ogs_pkbuf_t *sgwu_sxa_build_session_modification_response(uint8_t type,
|
|||
rsp->cause.presence = 1;
|
||||
rsp->cause.u8 = OGS_PFCP_CAUSE_REQUEST_ACCEPTED;
|
||||
|
||||
ogs_pfcp_pdrbuf_init();
|
||||
|
||||
/* Created PDR */
|
||||
for (i = 0; i < num_of_created_pdr; i++) {
|
||||
ogs_pfcp_tlv_created_pdr_t *message = &rsp->created_pdr[i];
|
||||
ogs_assert(message);
|
||||
|
||||
message->presence = 1;
|
||||
message->pdr_id.presence = 1;
|
||||
message->pdr_id.u16 = created_pdr[i]->id;
|
||||
ogs_pfcp_build_created_pdr(&rsp->created_pdr[i], i, created_pdr[i]);
|
||||
}
|
||||
|
||||
pfcp_message.h.type = type;
|
||||
return ogs_pfcp_build_msg(&pfcp_message);
|
||||
pkbuf = ogs_pfcp_build_msg(&pfcp_message);
|
||||
|
||||
ogs_pfcp_pdrbuf_clear();
|
||||
|
||||
return pkbuf;
|
||||
}
|
||||
|
||||
ogs_pkbuf_t *sgwu_sxa_build_session_deletion_response(uint8_t type,
|
||||
|
|
|
@ -115,8 +115,40 @@ void sgwu_sxa_handle_session_establishment_request(
|
|||
pdr = created_pdr[i];
|
||||
ogs_assert(pdr);
|
||||
|
||||
if (pdr->f_teid_len)
|
||||
if (pdr->f_teid_len) {
|
||||
if (ogs_pfcp_self()->up_function_features.ftup &&
|
||||
pdr->f_teid.ch) {
|
||||
ogs_pfcp_gtpu_resource_t *resource = NULL;
|
||||
resource = ogs_pfcp_gtpu_resource_find(
|
||||
&ogs_pfcp_self()->gtpu_resource_list,
|
||||
sess->pdn.apn, OGS_PFCP_INTERFACE_ACCESS);
|
||||
if (resource) {
|
||||
ogs_pfcp_user_plane_ip_resource_info_to_f_teid(
|
||||
&resource->info, &pdr->f_teid, &pdr->f_teid_len);
|
||||
if (resource->info.teidri)
|
||||
pdr->f_teid.teid = OGS_PFCP_GTPU_INDEX_TO_TEID(
|
||||
pdr->index, resource->info.teidri,
|
||||
resource->info.teid_range);
|
||||
else
|
||||
pdr->f_teid.teid = pdr->index;
|
||||
} else {
|
||||
ogs_sockaddr_t *addr = NULL, *addr6 = NULL;
|
||||
|
||||
if (sgwu_self()->gtpu_sock)
|
||||
addr = &sgwu_self()->gtpu_sock->local_addr;
|
||||
if (sgwu_self()->gtpu_sock6)
|
||||
addr6 = &sgwu_self()->gtpu_sock6->local_addr;
|
||||
|
||||
ogs_assert(addr || addr6);
|
||||
ogs_pfcp_sockaddr_to_f_teid(
|
||||
addr, addr6, &pdr->f_teid, &pdr->f_teid_len);
|
||||
|
||||
pdr->f_teid.teid = pdr->index;
|
||||
}
|
||||
}
|
||||
|
||||
ogs_pfcp_pdr_hash_set(pdr);
|
||||
}
|
||||
}
|
||||
|
||||
/* Send Buffered Packet to gNB */
|
||||
|
@ -257,8 +289,40 @@ void sgwu_sxa_handle_session_modification_request(
|
|||
pdr = created_pdr[i];
|
||||
ogs_assert(pdr);
|
||||
|
||||
if (pdr->f_teid_len)
|
||||
if (pdr->f_teid_len) {
|
||||
if (ogs_pfcp_self()->up_function_features.ftup &&
|
||||
pdr->f_teid.ch) {
|
||||
ogs_pfcp_gtpu_resource_t *resource = NULL;
|
||||
resource = ogs_pfcp_gtpu_resource_find(
|
||||
&ogs_pfcp_self()->gtpu_resource_list,
|
||||
sess->pdn.apn, OGS_PFCP_INTERFACE_ACCESS);
|
||||
if (resource) {
|
||||
ogs_pfcp_user_plane_ip_resource_info_to_f_teid(
|
||||
&resource->info, &pdr->f_teid, &pdr->f_teid_len);
|
||||
if (resource->info.teidri)
|
||||
pdr->f_teid.teid = OGS_PFCP_GTPU_INDEX_TO_TEID(
|
||||
pdr->index, resource->info.teidri,
|
||||
resource->info.teid_range);
|
||||
else
|
||||
pdr->f_teid.teid = pdr->index;
|
||||
} else {
|
||||
ogs_sockaddr_t *addr = NULL, *addr6 = NULL;
|
||||
|
||||
if (sgwu_self()->gtpu_sock)
|
||||
addr = &sgwu_self()->gtpu_sock->local_addr;
|
||||
if (sgwu_self()->gtpu_sock6)
|
||||
addr6 = &sgwu_self()->gtpu_sock6->local_addr;
|
||||
|
||||
ogs_assert(addr || addr6);
|
||||
ogs_pfcp_sockaddr_to_f_teid(
|
||||
addr, addr6, &pdr->f_teid, &pdr->f_teid_len);
|
||||
|
||||
pdr->f_teid.teid = pdr->index;
|
||||
}
|
||||
}
|
||||
|
||||
ogs_pfcp_pdr_hash_set(pdr);
|
||||
}
|
||||
}
|
||||
|
||||
/* Send Buffered Packet to gNB */
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
#include "bearer-binding.h"
|
||||
#include "s5c-build.h"
|
||||
#include "pfcp-path.h"
|
||||
|
||||
#include "ipfw/ipfw2.h"
|
||||
|
||||
|
@ -203,7 +204,6 @@ void smf_bearer_binding(smf_sess_t *sess)
|
|||
ogs_pcc_rule_t *pcc_rule = &sess->pcc_rule[i];
|
||||
int bearer_created = 0;
|
||||
int qos_presence = 0;
|
||||
ogs_gtp_tft_t tft;
|
||||
|
||||
ogs_assert(pcc_rule);
|
||||
if (pcc_rule->name == NULL) {
|
||||
|
@ -334,28 +334,40 @@ void smf_bearer_binding(smf_sess_t *sess)
|
|||
}
|
||||
}
|
||||
|
||||
memset(&tft, 0, sizeof tft);
|
||||
if (pcc_rule->num_of_flow)
|
||||
encode_traffic_flow_template(&tft, bearer);
|
||||
|
||||
memset(&h, 0, sizeof(ogs_gtp_header_t));
|
||||
if (bearer_created == 1) {
|
||||
h.type = OGS_GTP_CREATE_BEARER_REQUEST_TYPE;
|
||||
h.teid = sess->sgw_s5c_teid;
|
||||
/* Setup QER */
|
||||
if (bearer->qos.mbr.downlink || bearer->qos.mbr.uplink ||
|
||||
bearer->qos.gbr.downlink || bearer->qos.gbr.uplink) {
|
||||
ogs_pfcp_qer_t *qer = NULL;
|
||||
|
||||
/* TFT is mandatory in
|
||||
* activate dedicated EPS bearer context request */
|
||||
ogs_assert(pcc_rule->num_of_flow);
|
||||
/* Only 1 QER is used per bearer */
|
||||
qer = bearer->qer;
|
||||
if (!qer) {
|
||||
qer = ogs_pfcp_qer_add(&sess->pfcp);
|
||||
ogs_assert(qer);
|
||||
bearer->qer = qer;
|
||||
}
|
||||
|
||||
pkbuf = smf_s5c_build_create_bearer_request(
|
||||
h.type, bearer, pcc_rule->num_of_flow ? &tft : NULL);
|
||||
ogs_expect_or_return(pkbuf);
|
||||
ogs_pfcp_pdr_associate_qer(bearer->dl_pdr, qer);
|
||||
ogs_pfcp_pdr_associate_qer(bearer->ul_pdr, qer);
|
||||
|
||||
xact = ogs_gtp_xact_local_create(
|
||||
sess->gnode, &h, pkbuf, timeout, sess);
|
||||
ogs_expect_or_return(xact);
|
||||
qer->mbr.uplink = bearer->qos.mbr.uplink;
|
||||
qer->mbr.downlink = bearer->qos.mbr.downlink;
|
||||
qer->gbr.uplink = bearer->qos.gbr.uplink;
|
||||
qer->gbr.downlink = bearer->qos.gbr.downlink;
|
||||
}
|
||||
|
||||
smf_epc_pfcp_send_bearer_modification_request(
|
||||
bearer, OGS_PFCP_MODIFY_CREATE);
|
||||
|
||||
} else {
|
||||
ogs_gtp_tft_t tft;
|
||||
|
||||
memset(&tft, 0, sizeof tft);
|
||||
if (pcc_rule->num_of_flow)
|
||||
encode_traffic_flow_template(&tft, bearer);
|
||||
|
||||
memset(&h, 0, sizeof(ogs_gtp_header_t));
|
||||
h.type = OGS_GTP_UPDATE_BEARER_REQUEST_TYPE;
|
||||
h.teid = sess->sgw_s5c_teid;
|
||||
|
||||
|
@ -373,10 +385,10 @@ void smf_bearer_binding(smf_sess_t *sess)
|
|||
xact->update_flags |= OGS_GTP_MODIFY_TFT_UPDATE;
|
||||
if (qos_presence)
|
||||
xact->update_flags |= OGS_GTP_MODIFY_QOS_UPDATE;
|
||||
}
|
||||
|
||||
rv = ogs_gtp_xact_commit(xact);
|
||||
ogs_expect(rv == OGS_OK);
|
||||
rv = ogs_gtp_xact_commit(xact);
|
||||
ogs_expect(rv == OGS_OK);
|
||||
}
|
||||
|
||||
} else if (pcc_rule->type == OGS_PCC_RULE_TYPE_REMOVE) {
|
||||
bearer = smf_bearer_find_by_name(sess, pcc_rule->name);
|
||||
|
@ -407,3 +419,34 @@ void smf_bearer_binding(smf_sess_t *sess)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
void smf_gtp_send_create_bearer_request(smf_bearer_t *bearer)
|
||||
{
|
||||
int rv;
|
||||
|
||||
smf_sess_t *sess = NULL;
|
||||
ogs_gtp_xact_t *xact = NULL;
|
||||
|
||||
ogs_gtp_header_t h;
|
||||
ogs_pkbuf_t *pkbuf = NULL;
|
||||
ogs_gtp_tft_t tft;
|
||||
|
||||
ogs_assert(bearer);
|
||||
sess = bearer->sess;
|
||||
ogs_assert(sess);
|
||||
|
||||
h.type = OGS_GTP_CREATE_BEARER_REQUEST_TYPE;
|
||||
h.teid = sess->sgw_s5c_teid;
|
||||
|
||||
memset(&tft, 0, sizeof tft);
|
||||
encode_traffic_flow_template(&tft, bearer);
|
||||
|
||||
pkbuf = smf_s5c_build_create_bearer_request(h.type, bearer, &tft);
|
||||
ogs_expect_or_return(pkbuf);
|
||||
|
||||
xact = ogs_gtp_xact_local_create(sess->gnode, &h, pkbuf, timeout, sess);
|
||||
ogs_expect_or_return(xact);
|
||||
|
||||
rv = ogs_gtp_xact_commit(xact);
|
||||
ogs_expect(rv == OGS_OK);
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
void smf_bearer_binding(smf_sess_t *sess);
|
||||
void smf_gtp_send_create_bearer_request(smf_bearer_t *bearer);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -1176,7 +1176,6 @@ smf_bearer_t *smf_qos_flow_add(smf_sess_t *sess)
|
|||
|
||||
dl_pdr = ogs_pfcp_pdr_add(&sess->pfcp);
|
||||
ogs_assert(dl_pdr);
|
||||
dl_pdr->id = dl_pdr->index;
|
||||
qos_flow->dl_pdr = dl_pdr;
|
||||
|
||||
dl_pdr->src_if = OGS_PFCP_INTERFACE_CORE;
|
||||
|
@ -1186,7 +1185,6 @@ smf_bearer_t *smf_qos_flow_add(smf_sess_t *sess)
|
|||
|
||||
ul_pdr = ogs_pfcp_pdr_add(&sess->pfcp);
|
||||
ogs_assert(ul_pdr);
|
||||
ul_pdr->id = ul_pdr->index;
|
||||
qos_flow->ul_pdr = ul_pdr;
|
||||
|
||||
ul_pdr->src_if = OGS_PFCP_INTERFACE_ACCESS;
|
||||
|
@ -1209,7 +1207,6 @@ smf_bearer_t *smf_qos_flow_add(smf_sess_t *sess)
|
|||
|
||||
dl_far = ogs_pfcp_far_add(&sess->pfcp);
|
||||
ogs_assert(dl_far);
|
||||
dl_far->id = dl_far->index;
|
||||
qos_flow->dl_far = dl_far;
|
||||
|
||||
dl_far->dst_if = OGS_PFCP_INTERFACE_ACCESS;
|
||||
|
@ -1217,7 +1214,6 @@ smf_bearer_t *smf_qos_flow_add(smf_sess_t *sess)
|
|||
|
||||
ul_far = ogs_pfcp_far_add(&sess->pfcp);
|
||||
ogs_assert(ul_far);
|
||||
ul_far->id = ul_far->index;
|
||||
qos_flow->ul_far = ul_far;
|
||||
|
||||
ul_far->dst_if = OGS_PFCP_INTERFACE_CORE;
|
||||
|
@ -1225,7 +1221,6 @@ smf_bearer_t *smf_qos_flow_add(smf_sess_t *sess)
|
|||
|
||||
qer = ogs_pfcp_qer_add(&sess->pfcp);
|
||||
ogs_assert(qer);
|
||||
qer->id = qer->index;
|
||||
qos_flow->qer = qer;
|
||||
|
||||
ogs_pfcp_pdr_associate_qer(dl_pdr, qer);
|
||||
|
@ -1283,7 +1278,6 @@ smf_bearer_t *smf_bearer_add(smf_sess_t *sess)
|
|||
|
||||
dl_pdr = ogs_pfcp_pdr_add(&sess->pfcp);
|
||||
ogs_assert(dl_pdr);
|
||||
dl_pdr->id = dl_pdr->index;
|
||||
bearer->dl_pdr = dl_pdr;
|
||||
|
||||
dl_pdr->src_if = OGS_PFCP_INTERFACE_CORE;
|
||||
|
@ -1293,7 +1287,6 @@ smf_bearer_t *smf_bearer_add(smf_sess_t *sess)
|
|||
|
||||
ul_pdr = ogs_pfcp_pdr_add(&sess->pfcp);
|
||||
ogs_assert(ul_pdr);
|
||||
ul_pdr->id = ul_pdr->index;
|
||||
bearer->ul_pdr = ul_pdr;
|
||||
|
||||
ul_pdr->src_if = OGS_PFCP_INTERFACE_ACCESS;
|
||||
|
@ -1316,7 +1309,6 @@ smf_bearer_t *smf_bearer_add(smf_sess_t *sess)
|
|||
|
||||
dl_far = ogs_pfcp_far_add(&sess->pfcp);
|
||||
ogs_assert(dl_far);
|
||||
dl_far->id = dl_far->index;
|
||||
bearer->dl_far = dl_far;
|
||||
|
||||
dl_far->dst_if = OGS_PFCP_INTERFACE_ACCESS;
|
||||
|
@ -1324,42 +1316,46 @@ smf_bearer_t *smf_bearer_add(smf_sess_t *sess)
|
|||
|
||||
ul_far = ogs_pfcp_far_add(&sess->pfcp);
|
||||
ogs_assert(ul_far);
|
||||
ul_far->id = ul_far->index;
|
||||
bearer->ul_far = ul_far;
|
||||
|
||||
ul_far->dst_if = OGS_PFCP_INTERFACE_CORE;
|
||||
ogs_pfcp_pdr_associate_far(ul_pdr, ul_far);
|
||||
|
||||
ogs_assert(sess->pfcp_node);
|
||||
resource = ogs_pfcp_gtpu_resource_find(
|
||||
&sess->pfcp_node->gtpu_resource_list,
|
||||
sess->pdn.apn, OGS_PFCP_INTERFACE_ACCESS);
|
||||
if (resource) {
|
||||
ogs_pfcp_user_plane_ip_resource_info_to_sockaddr(&resource->info,
|
||||
&bearer->pgw_s5u_addr, &bearer->pgw_s5u_addr6);
|
||||
ogs_assert(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,
|
||||
resource->info.teid_range);
|
||||
else
|
||||
bearer->pgw_s5u_teid = bearer->index;
|
||||
if (sess->pfcp_node->up_function_features.ftup) {
|
||||
ul_pdr->f_teid.ch = 1;
|
||||
ul_pdr->f_teid_len = 1;
|
||||
} else {
|
||||
if (sess->pfcp_node->addr.ogs_sa_family == AF_INET)
|
||||
ogs_copyaddrinfo(&bearer->pgw_s5u_addr, &sess->pfcp_node->addr);
|
||||
else if (sess->pfcp_node->addr.ogs_sa_family == AF_INET6)
|
||||
ogs_copyaddrinfo(&bearer->pgw_s5u_addr6, &sess->pfcp_node->addr);
|
||||
else
|
||||
ogs_assert_if_reached();
|
||||
resource = ogs_pfcp_gtpu_resource_find(
|
||||
&sess->pfcp_node->gtpu_resource_list,
|
||||
sess->pdn.apn, OGS_PFCP_INTERFACE_ACCESS);
|
||||
if (resource) {
|
||||
ogs_pfcp_user_plane_ip_resource_info_to_sockaddr(&resource->info,
|
||||
&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,
|
||||
resource->info.teid_range);
|
||||
else
|
||||
bearer->pgw_s5u_teid = bearer->index;
|
||||
} else {
|
||||
if (sess->pfcp_node->addr.ogs_sa_family == AF_INET)
|
||||
ogs_copyaddrinfo(&bearer->pgw_s5u_addr, &sess->pfcp_node->addr);
|
||||
else if (sess->pfcp_node->addr.ogs_sa_family == AF_INET6)
|
||||
ogs_copyaddrinfo(
|
||||
&bearer->pgw_s5u_addr6, &sess->pfcp_node->addr);
|
||||
else
|
||||
ogs_assert_if_reached();
|
||||
|
||||
bearer->pgw_s5u_teid = bearer->index;
|
||||
}
|
||||
|
||||
ogs_assert(bearer->pgw_s5u_addr || bearer->pgw_s5u_addr6);
|
||||
|
||||
bearer->pgw_s5u_teid = bearer->index;
|
||||
ogs_pfcp_sockaddr_to_f_teid(bearer->pgw_s5u_addr, bearer->pgw_s5u_addr6,
|
||||
&ul_pdr->f_teid, &ul_pdr->f_teid_len);
|
||||
ul_pdr->f_teid.teid = bearer->pgw_s5u_teid;
|
||||
}
|
||||
|
||||
ogs_pfcp_sockaddr_to_f_teid(bearer->pgw_s5u_addr, bearer->pgw_s5u_addr6,
|
||||
&ul_pdr->f_teid, &ul_pdr->f_teid_len);
|
||||
ul_pdr->f_teid.teid = bearer->pgw_s5u_teid;
|
||||
|
||||
bearer->sess = sess;
|
||||
|
||||
ogs_list_add(&sess->bearer_list, bearer);
|
||||
|
@ -1415,9 +1411,19 @@ smf_bearer_t *smf_bearer_find(uint32_t index)
|
|||
return ogs_pool_find(&smf_bearer_pool, index);
|
||||
}
|
||||
|
||||
smf_bearer_t *smf_bearer_find_by_pgw_s5u_teid(uint32_t pgw_s5u_teid)
|
||||
smf_bearer_t *smf_bearer_find_by_pgw_s5u_teid(
|
||||
smf_sess_t *sess, uint32_t pgw_s5u_teid)
|
||||
{
|
||||
return smf_bearer_find(pgw_s5u_teid);
|
||||
smf_bearer_t *bearer = NULL;
|
||||
|
||||
ogs_assert(sess);
|
||||
|
||||
ogs_list_for_each(&sess->bearer_list, bearer) {
|
||||
if (bearer->pgw_s5u_teid == pgw_s5u_teid)
|
||||
return bearer;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
smf_bearer_t *smf_bearer_find_by_ebi(smf_sess_t *sess, uint8_t ebi)
|
||||
|
@ -1426,15 +1432,12 @@ smf_bearer_t *smf_bearer_find_by_ebi(smf_sess_t *sess, uint8_t ebi)
|
|||
|
||||
ogs_assert(sess);
|
||||
|
||||
bearer = smf_bearer_first(sess);
|
||||
while (bearer) {
|
||||
ogs_list_for_each(&sess->bearer_list, bearer) {
|
||||
if (bearer->ebi == ebi)
|
||||
break;
|
||||
|
||||
bearer = smf_bearer_next(bearer);
|
||||
return bearer;
|
||||
}
|
||||
|
||||
return bearer;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
smf_bearer_t *smf_bearer_find_by_name(smf_sess_t *sess, char *name)
|
||||
|
@ -1444,12 +1447,9 @@ smf_bearer_t *smf_bearer_find_by_name(smf_sess_t *sess, char *name)
|
|||
ogs_assert(sess);
|
||||
ogs_assert(name);
|
||||
|
||||
bearer = smf_bearer_first(sess);
|
||||
while (bearer) {
|
||||
ogs_list_for_each(&sess->bearer_list, bearer) {
|
||||
if (bearer->name && strcmp(bearer->name, name) == 0)
|
||||
return bearer;
|
||||
|
||||
bearer = smf_bearer_next(bearer);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
@ -1493,6 +1493,29 @@ smf_bearer_t *smf_bearer_find_by_qci_arp(smf_sess_t *sess,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
smf_bearer_t *smf_bearer_find_by_pdr_id(
|
||||
smf_sess_t *sess, ogs_pfcp_pdr_id_t pdr_id)
|
||||
{
|
||||
smf_bearer_t *bearer = NULL;
|
||||
|
||||
ogs_assert(sess);
|
||||
|
||||
ogs_list_for_each(&sess->bearer_list, bearer) {
|
||||
ogs_pfcp_pdr_t *dl_pdr = NULL;
|
||||
ogs_pfcp_pdr_t *ul_pdr = NULL;
|
||||
|
||||
dl_pdr = bearer->dl_pdr;
|
||||
ogs_assert(dl_pdr);
|
||||
ul_pdr = bearer->ul_pdr;
|
||||
ogs_assert(ul_pdr);
|
||||
|
||||
if (dl_pdr->id == pdr_id || ul_pdr->id == pdr_id)
|
||||
return bearer;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
smf_bearer_t *smf_default_bearer_in_sess(smf_sess_t *sess)
|
||||
{
|
||||
return smf_bearer_first(sess);
|
||||
|
|
|
@ -327,7 +327,8 @@ smf_bearer_t *smf_bearer_add(smf_sess_t *sess);
|
|||
int smf_bearer_remove(smf_bearer_t *bearer);
|
||||
void smf_bearer_remove_all(smf_sess_t *sess);
|
||||
smf_bearer_t *smf_bearer_find(uint32_t index);
|
||||
smf_bearer_t *smf_bearer_find_by_pgw_s5u_teid(uint32_t pgw_s5u_teid);
|
||||
smf_bearer_t *smf_bearer_find_by_pgw_s5u_teid(
|
||||
smf_sess_t *sess, uint32_t pgw_s5u_teid);
|
||||
smf_bearer_t *smf_bearer_find_by_ebi(smf_sess_t *sess, uint8_t ebi);
|
||||
smf_bearer_t *smf_bearer_find_by_name(smf_sess_t *sess, char *name);
|
||||
smf_bearer_t *smf_bearer_find_by_qci_arp(smf_sess_t *sess,
|
||||
|
@ -335,6 +336,8 @@ smf_bearer_t *smf_bearer_find_by_qci_arp(smf_sess_t *sess,
|
|||
uint8_t priority_level,
|
||||
uint8_t pre_emption_capability,
|
||||
uint8_t pre_emption_vulnerability);
|
||||
smf_bearer_t *smf_bearer_find_by_pdr_id(
|
||||
smf_sess_t *sess, ogs_pfcp_pdr_id_t pdr_id);
|
||||
smf_bearer_t *smf_default_bearer_in_sess(smf_sess_t *sess);
|
||||
bool smf_bearer_is_default(smf_bearer_t *bearer);
|
||||
smf_bearer_t *smf_bearer_first(smf_sess_t *sess);
|
||||
|
|
|
@ -124,7 +124,6 @@ void smf_gx_handle_cca_initial_request(
|
|||
if (!qer) {
|
||||
qer = ogs_pfcp_qer_add(&sess->pfcp);
|
||||
ogs_assert(qer);
|
||||
qer->id = qer->index;
|
||||
bearer->qer = qer;
|
||||
}
|
||||
|
||||
|
|
|
@ -99,8 +99,13 @@ void smf_5gc_n4_handle_session_establishment_response(
|
|||
smf_sess_t *sess, ogs_pfcp_xact_t *xact,
|
||||
ogs_pfcp_session_establishment_response_t *rsp)
|
||||
{
|
||||
int i;
|
||||
|
||||
ogs_sbi_session_t *session = NULL;
|
||||
|
||||
uint8_t pfcp_cause_value = OGS_PFCP_CAUSE_REQUEST_ACCEPTED;
|
||||
uint8_t offending_ie_value = 0;
|
||||
|
||||
ogs_pfcp_f_seid_t *up_f_seid = NULL;
|
||||
|
||||
ogs_assert(xact);
|
||||
|
@ -121,6 +126,11 @@ void smf_5gc_n4_handle_session_establishment_response(
|
|||
return;
|
||||
}
|
||||
|
||||
if (rsp->created_pdr[0].presence == 0) {
|
||||
ogs_error("No Created PDR");
|
||||
return;
|
||||
}
|
||||
|
||||
if (rsp->cause.presence) {
|
||||
if (rsp->cause.u8 != OGS_PFCP_CAUSE_REQUEST_ACCEPTED) {
|
||||
ogs_error("PFCP Cause [%d] : Not Accepted", rsp->cause.u8);
|
||||
|
@ -133,6 +143,42 @@ void smf_5gc_n4_handle_session_establishment_response(
|
|||
|
||||
ogs_assert(sess);
|
||||
|
||||
pfcp_cause_value = OGS_PFCP_CAUSE_REQUEST_ACCEPTED;
|
||||
for (i = 0; i < OGS_MAX_NUM_OF_PDR; i++) {
|
||||
ogs_pfcp_pdr_t *pdr = NULL;
|
||||
|
||||
pdr = ogs_pfcp_handle_created_pdr(
|
||||
&sess->pfcp, &rsp->created_pdr[i],
|
||||
&pfcp_cause_value, &offending_ie_value);
|
||||
|
||||
if (!pdr)
|
||||
break;
|
||||
|
||||
ogs_assert(sess->pfcp_node);
|
||||
if (sess->pfcp_node->up_function_features.ftup &&
|
||||
pdr->f_teid_len) {
|
||||
if (sess->upf_n3_addr)
|
||||
ogs_freeaddrinfo(sess->upf_n3_addr);
|
||||
if (sess->upf_n3_addr6)
|
||||
ogs_freeaddrinfo(sess->upf_n3_addr6);
|
||||
|
||||
ogs_pfcp_f_teid_to_sockaddr(
|
||||
&pdr->f_teid, pdr->f_teid_len,
|
||||
&sess->upf_n3_addr, &sess->upf_n3_addr6);
|
||||
sess->upf_n3_teid = pdr->f_teid.teid;
|
||||
}
|
||||
}
|
||||
|
||||
if (pfcp_cause_value != OGS_PFCP_CAUSE_REQUEST_ACCEPTED) {
|
||||
ogs_error("PFCP Cause [%d] : Not Accepted", pfcp_cause_value);
|
||||
return;
|
||||
}
|
||||
|
||||
if (sess->upf_n3_addr == NULL && sess->upf_n3_addr6 == NULL) {
|
||||
ogs_error("No UP F-TEID");
|
||||
return;
|
||||
}
|
||||
|
||||
/* UP F-SEID */
|
||||
up_f_seid = rsp->up_f_seid.data;
|
||||
ogs_assert(up_f_seid);
|
||||
|
@ -181,6 +227,41 @@ void smf_5gc_n4_handle_session_modification_response(
|
|||
status = OGS_SBI_HTTP_STATUS_BAD_REQUEST;
|
||||
}
|
||||
|
||||
if (status == OGS_SBI_HTTP_STATUS_OK) {
|
||||
int i;
|
||||
|
||||
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++) {
|
||||
ogs_pfcp_pdr_t *pdr = NULL;
|
||||
|
||||
pdr = ogs_pfcp_handle_created_pdr(
|
||||
&sess->pfcp, &rsp->created_pdr[i],
|
||||
&pfcp_cause_value, &offending_ie_value);
|
||||
|
||||
if (!pdr)
|
||||
break;
|
||||
|
||||
ogs_assert(sess->pfcp_node);
|
||||
if (sess->pfcp_node->up_function_features.ftup &&
|
||||
pdr->f_teid_len) {
|
||||
if (sess->upf_n3_addr)
|
||||
ogs_freeaddrinfo(sess->upf_n3_addr);
|
||||
if (sess->upf_n3_addr6)
|
||||
ogs_freeaddrinfo(sess->upf_n3_addr6);
|
||||
|
||||
ogs_pfcp_f_teid_to_sockaddr(
|
||||
&pdr->f_teid, pdr->f_teid_len,
|
||||
&sess->upf_n3_addr, &sess->upf_n3_addr6);
|
||||
sess->upf_n3_teid = pdr->f_teid.teid;
|
||||
}
|
||||
}
|
||||
|
||||
status = sbi_status_from_pfcp(pfcp_cause_value);
|
||||
}
|
||||
|
||||
if (status != OGS_SBI_HTTP_STATUS_OK) {
|
||||
char *strerror = ogs_msprintf(
|
||||
"PFCP Cause [%d] : Not Accepted", rsp->cause.u8);
|
||||
|
@ -192,6 +273,12 @@ void smf_5gc_n4_handle_session_modification_response(
|
|||
|
||||
ogs_assert(sess);
|
||||
|
||||
if (sess->upf_n3_addr == NULL && sess->upf_n3_addr6 == NULL) {
|
||||
smf_sbi_send_sm_context_update_error(session, status, "No UP F_TEID",
|
||||
NULL, NULL, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
if (flags & OGS_PFCP_MODIFY_ACTIVATE) {
|
||||
/* ACTIVATED Is NOT Inlcuded in RESPONSE */
|
||||
smf_sbi_send_sm_context_updated_data(sess, session, 0);
|
||||
|
@ -274,7 +361,10 @@ void smf_epc_n4_handle_session_establishment_response(
|
|||
ogs_pfcp_session_establishment_response_t *rsp)
|
||||
{
|
||||
uint8_t cause_value = 0;
|
||||
|
||||
smf_bearer_t *bearer = NULL;
|
||||
ogs_gtp_xact_t *gtp_xact = NULL;
|
||||
|
||||
ogs_pfcp_f_seid_t *up_f_seid = NULL;
|
||||
|
||||
ogs_assert(xact);
|
||||
|
@ -297,6 +387,11 @@ void smf_epc_n4_handle_session_establishment_response(
|
|||
cause_value = OGS_GTP_CAUSE_MANDATORY_IE_MISSING;
|
||||
}
|
||||
|
||||
if (rsp->created_pdr[0].presence == 0) {
|
||||
ogs_error("No Created PDR");
|
||||
cause_value = OGS_GTP_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);
|
||||
|
@ -307,6 +402,47 @@ void smf_epc_n4_handle_session_establishment_response(
|
|||
cause_value = OGS_GTP_CAUSE_MANDATORY_IE_MISSING;
|
||||
}
|
||||
|
||||
if (cause_value == OGS_GTP_CAUSE_REQUEST_ACCEPTED) {
|
||||
int i;
|
||||
|
||||
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++) {
|
||||
ogs_pfcp_pdr_t *pdr = NULL;
|
||||
|
||||
pdr = ogs_pfcp_handle_created_pdr(
|
||||
&sess->pfcp, &rsp->created_pdr[i],
|
||||
&pfcp_cause_value, &offending_ie_value);
|
||||
|
||||
if (!pdr)
|
||||
break;
|
||||
|
||||
bearer = smf_bearer_find_by_pdr_id(sess, pdr->id);
|
||||
if (!bearer) {
|
||||
pfcp_cause_value = OGS_PFCP_CAUSE_SESSION_CONTEXT_NOT_FOUND;
|
||||
break;
|
||||
}
|
||||
|
||||
ogs_assert(sess->pfcp_node);
|
||||
if (sess->pfcp_node->up_function_features.ftup &&
|
||||
pdr->f_teid_len) {
|
||||
if (bearer->pgw_s5u_addr)
|
||||
ogs_freeaddrinfo(bearer->pgw_s5u_addr);
|
||||
if (bearer->pgw_s5u_addr)
|
||||
ogs_freeaddrinfo(bearer->pgw_s5u_addr6);
|
||||
|
||||
ogs_pfcp_f_teid_to_sockaddr(
|
||||
&pdr->f_teid, pdr->f_teid_len,
|
||||
&bearer->pgw_s5u_addr, &bearer->pgw_s5u_addr6);
|
||||
bearer->pgw_s5u_teid = pdr->f_teid.teid;
|
||||
}
|
||||
}
|
||||
|
||||
cause_value = gtp_cause_from_pfcp(pfcp_cause_value);
|
||||
}
|
||||
|
||||
if (cause_value != OGS_GTP_CAUSE_REQUEST_ACCEPTED) {
|
||||
ogs_gtp_send_error_message(gtp_xact, sess ? sess->sgw_s5c_teid : 0,
|
||||
OGS_GTP_CREATE_SESSION_RESPONSE_TYPE, cause_value);
|
||||
|
@ -314,6 +450,16 @@ void smf_epc_n4_handle_session_establishment_response(
|
|||
}
|
||||
|
||||
ogs_assert(sess);
|
||||
bearer = smf_default_bearer_in_sess(sess);
|
||||
ogs_assert(bearer);
|
||||
|
||||
if (bearer->pgw_s5u_addr == NULL && bearer->pgw_s5u_addr6 == NULL) {
|
||||
ogs_error("No UP F-TEID");
|
||||
ogs_gtp_send_error_message(gtp_xact, sess ? sess->sgw_s5c_teid : 0,
|
||||
OGS_GTP_CREATE_SESSION_RESPONSE_TYPE,
|
||||
OGS_GTP_CAUSE_GRE_KEY_NOT_FOUND);
|
||||
return;
|
||||
}
|
||||
|
||||
/* UP F-SEID */
|
||||
up_f_seid = rsp->up_f_seid.data;
|
||||
|
@ -329,9 +475,14 @@ void smf_epc_n4_handle_session_modification_response(
|
|||
smf_sess_t *sess, ogs_pfcp_xact_t *xact,
|
||||
ogs_pfcp_session_modification_response_t *rsp)
|
||||
{
|
||||
int i;
|
||||
|
||||
smf_bearer_t *bearer = NULL;
|
||||
uint64_t flags = 0;
|
||||
|
||||
uint8_t pfcp_cause_value = OGS_PFCP_CAUSE_REQUEST_ACCEPTED;
|
||||
uint8_t offending_ie_value = 0;
|
||||
|
||||
ogs_assert(xact);
|
||||
ogs_assert(rsp);
|
||||
|
||||
|
@ -342,8 +493,63 @@ void smf_epc_n4_handle_session_modification_response(
|
|||
|
||||
ogs_pfcp_xact_commit(xact);
|
||||
|
||||
if (flags & OGS_PFCP_MODIFY_REMOVE)
|
||||
if (!sess) {
|
||||
ogs_error("No Context");
|
||||
return;
|
||||
}
|
||||
|
||||
if (rsp->cause.presence) {
|
||||
if (rsp->cause.u8 != OGS_PFCP_CAUSE_REQUEST_ACCEPTED) {
|
||||
ogs_error("PFCP Cause [%d] : Not Accepted", rsp->cause.u8);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
ogs_error("No Cause");
|
||||
return;
|
||||
}
|
||||
|
||||
ogs_assert(sess);
|
||||
|
||||
pfcp_cause_value = OGS_PFCP_CAUSE_REQUEST_ACCEPTED;
|
||||
for (i = 0; i < OGS_MAX_NUM_OF_PDR; i++) {
|
||||
ogs_pfcp_pdr_t *pdr = NULL;
|
||||
|
||||
pdr = ogs_pfcp_handle_created_pdr(
|
||||
&sess->pfcp, &rsp->created_pdr[i],
|
||||
&pfcp_cause_value, &offending_ie_value);
|
||||
|
||||
if (!pdr)
|
||||
break;
|
||||
|
||||
ogs_assert(sess->pfcp_node);
|
||||
if (sess->pfcp_node->up_function_features.ftup &&
|
||||
pdr->f_teid_len) {
|
||||
if (bearer->pgw_s5u_addr)
|
||||
ogs_freeaddrinfo(bearer->pgw_s5u_addr);
|
||||
if (bearer->pgw_s5u_addr)
|
||||
ogs_freeaddrinfo(bearer->pgw_s5u_addr6);
|
||||
|
||||
ogs_pfcp_f_teid_to_sockaddr(
|
||||
&pdr->f_teid, pdr->f_teid_len,
|
||||
&bearer->pgw_s5u_addr, &bearer->pgw_s5u_addr6);
|
||||
bearer->pgw_s5u_teid = pdr->f_teid.teid;
|
||||
}
|
||||
}
|
||||
|
||||
if (pfcp_cause_value != OGS_PFCP_CAUSE_REQUEST_ACCEPTED) {
|
||||
ogs_error("PFCP Cause [%d] : Not Accepted", pfcp_cause_value);
|
||||
return;
|
||||
}
|
||||
|
||||
if (flags & OGS_PFCP_MODIFY_CREATE) {
|
||||
smf_gtp_send_create_bearer_request(bearer);
|
||||
|
||||
} else if (flags & OGS_PFCP_MODIFY_REMOVE) {
|
||||
smf_bearer_remove(bearer);
|
||||
|
||||
} else if (flags & OGS_PFCP_MODIFY_ACTIVATE) {
|
||||
/* Nothing */
|
||||
}
|
||||
}
|
||||
|
||||
void smf_epc_n4_handle_session_deletion_response(
|
||||
|
|
|
@ -79,6 +79,7 @@ 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_asn_ip_to_BIT_STRING(&upf_n3_ip, &gTPTunnel->transportLayerAddress);
|
||||
ogs_asn_uint32_to_OCTET_STRING(sess->upf_n3_teid, &gTPTunnel->gTP_TEID);
|
||||
|
|
|
@ -235,45 +235,6 @@ bool smf_nudm_sdm_handle_get(smf_sess_t *sess, ogs_sbi_session_t *session,
|
|||
return false;
|
||||
}
|
||||
|
||||
/* Setup GTP-U Tunnel */
|
||||
resource = ogs_pfcp_gtpu_resource_find(
|
||||
&sess->pfcp_node->gtpu_resource_list,
|
||||
sess->pdn.dnn, OGS_PFCP_INTERFACE_ACCESS);
|
||||
if (resource) {
|
||||
ogs_pfcp_user_plane_ip_resource_info_to_sockaddr(&resource->info,
|
||||
&sess->upf_n3_addr, &sess->upf_n3_addr6);
|
||||
ogs_assert(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,
|
||||
resource->info.teid_range);
|
||||
else
|
||||
sess->upf_n3_teid = sess->index;
|
||||
} else {
|
||||
if (sess->pfcp_node->addr.ogs_sa_family == AF_INET)
|
||||
ogs_copyaddrinfo(&sess->upf_n3_addr, &sess->pfcp_node->addr);
|
||||
else if (sess->pfcp_node->addr.ogs_sa_family == AF_INET6)
|
||||
ogs_copyaddrinfo(&sess->upf_n3_addr6, &sess->pfcp_node->addr);
|
||||
else
|
||||
ogs_assert_if_reached();
|
||||
ogs_assert(sess->upf_n3_addr || sess->upf_n3_addr6);
|
||||
|
||||
sess->upf_n3_teid = sess->index;
|
||||
}
|
||||
|
||||
ogs_debug("UPF TEID:[0x%x], IPv4:[%s] IPv6:[%s]",
|
||||
sess->upf_n3_teid,
|
||||
sess->upf_n3_addr ? OGS_ADDR(sess->upf_n3_addr, buf1) : "",
|
||||
sess->upf_n3_addr6 ? OGS_ADDR(sess->upf_n3_addr6, buf2) : "");
|
||||
|
||||
/* UE IP Address */
|
||||
smf_sess_set_ue_ip(sess);
|
||||
|
||||
ogs_info("UE SUPI:[%s] DNN:[%s] IPv4:[%s] IPv6:[%s]",
|
||||
smf_ue->supi, sess->pdn.dnn,
|
||||
sess->ipv4 ? OGS_INET_NTOP(&sess->ipv4->addr, buf1) : "",
|
||||
sess->ipv6 ? OGS_INET6_NTOP(&sess->ipv6->addr, buf2) : "");
|
||||
|
||||
/*********************************************************************
|
||||
* Send HTTP_STATUS_CREATED(/nsmf-pdusession/v1/sm-context) to the AMF
|
||||
*********************************************************************/
|
||||
|
@ -299,7 +260,6 @@ bool smf_nudm_sdm_handle_get(smf_sess_t *sess, ogs_sbi_session_t *session,
|
|||
|
||||
ogs_free(sendmsg.http.location);
|
||||
|
||||
|
||||
/*********************************************************************
|
||||
* Send PFCP Session Establiashment Request to the UPF
|
||||
*********************************************************************/
|
||||
|
@ -324,14 +284,50 @@ bool smf_nudm_sdm_handle_get(smf_sess_t *sess, ogs_sbi_session_t *session,
|
|||
ogs_assert(ul_pdr);
|
||||
|
||||
/* Set UE IP Address to the Default DL PDR */
|
||||
smf_sess_set_ue_ip(sess);
|
||||
|
||||
ogs_pfcp_paa_to_ue_ip_addr(&sess->pdn.paa,
|
||||
&dl_pdr->ue_ip_addr, &dl_pdr->ue_ip_addr_len);
|
||||
dl_pdr->ue_ip_addr.sd = OGS_PFCP_UE_IP_DST;
|
||||
|
||||
ogs_info("UE SUPI:[%s] DNN:[%s] IPv4:[%s] IPv6:[%s]",
|
||||
smf_ue->supi, sess->pdn.dnn,
|
||||
sess->ipv4 ? OGS_INET_NTOP(&sess->ipv4->addr, buf1) : "",
|
||||
sess->ipv6 ? OGS_INET6_NTOP(&sess->ipv6->addr, buf2) : "");
|
||||
|
||||
/* Set UPF-N3 TEID & ADDR to the Default UL PDR */
|
||||
ogs_pfcp_sockaddr_to_f_teid(sess->upf_n3_addr, sess->upf_n3_addr6,
|
||||
&ul_pdr->f_teid, &ul_pdr->f_teid_len);
|
||||
ul_pdr->f_teid.teid = sess->upf_n3_teid;
|
||||
if (sess->pfcp_node->up_function_features.ftup) {
|
||||
ul_pdr->f_teid.ch = 1;
|
||||
ul_pdr->f_teid_len = 1;
|
||||
} else {
|
||||
resource = ogs_pfcp_gtpu_resource_find(
|
||||
&sess->pfcp_node->gtpu_resource_list,
|
||||
sess->pdn.dnn, OGS_PFCP_INTERFACE_ACCESS);
|
||||
if (resource) {
|
||||
ogs_pfcp_user_plane_ip_resource_info_to_sockaddr(&resource->info,
|
||||
&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,
|
||||
resource->info.teid_range);
|
||||
else
|
||||
sess->upf_n3_teid = sess->index;
|
||||
} else {
|
||||
if (sess->pfcp_node->addr.ogs_sa_family == AF_INET)
|
||||
ogs_copyaddrinfo(&sess->upf_n3_addr, &sess->pfcp_node->addr);
|
||||
else if (sess->pfcp_node->addr.ogs_sa_family == AF_INET6)
|
||||
ogs_copyaddrinfo(&sess->upf_n3_addr6, &sess->pfcp_node->addr);
|
||||
else
|
||||
ogs_assert_if_reached();
|
||||
|
||||
sess->upf_n3_teid = sess->index;
|
||||
}
|
||||
|
||||
ogs_assert(sess->upf_n3_addr || sess->upf_n3_addr6);
|
||||
ogs_pfcp_sockaddr_to_f_teid(sess->upf_n3_addr, sess->upf_n3_addr6,
|
||||
&ul_pdr->f_teid, &ul_pdr->f_teid_len);
|
||||
ul_pdr->f_teid.teid = sess->upf_n3_teid;
|
||||
}
|
||||
|
||||
/* Default PDRs is set to lowest precedence(highest precedence value) */
|
||||
dl_pdr->precedence = 0xffffffff;
|
||||
|
|
|
@ -143,6 +143,7 @@ ogs_pkbuf_t *smf_s5c_build_create_session_response(
|
|||
memset(&pgw_s5u_teid, 0, sizeof(ogs_gtp_f_teid_t));
|
||||
pgw_s5u_teid.interface_type = OGS_GTP_F_TEID_S5_S8_PGW_GTP_U;
|
||||
pgw_s5u_teid.teid = htobe32(bearer->pgw_s5u_teid);
|
||||
ogs_assert(bearer->pgw_s5u_addr || bearer->pgw_s5u_addr6);
|
||||
rv = ogs_gtp_sockaddr_to_f_teid(
|
||||
bearer->pgw_s5u_addr, bearer->pgw_s5u_addr6, &pgw_s5u_teid, &len);
|
||||
ogs_assert(rv == OGS_OK);
|
||||
|
@ -238,6 +239,7 @@ ogs_pkbuf_t *smf_s5c_build_create_bearer_request(
|
|||
memset(&pgw_s5u_teid, 0, sizeof(ogs_gtp_f_teid_t));
|
||||
pgw_s5u_teid.interface_type = OGS_GTP_F_TEID_S5_S8_PGW_GTP_U;
|
||||
pgw_s5u_teid.teid = htobe32(bearer->pgw_s5u_teid);
|
||||
ogs_assert(bearer->pgw_s5u_addr || bearer->pgw_s5u_addr6);
|
||||
rv = ogs_gtp_sockaddr_to_f_teid(
|
||||
bearer->pgw_s5u_addr, bearer->pgw_s5u_addr6, &pgw_s5u_teid, &len);
|
||||
ogs_assert(rv == OGS_OK);
|
||||
|
|
|
@ -323,11 +323,11 @@ void smf_s5c_handle_create_bearer_response(
|
|||
|
||||
/* Correlate with PGW-S5U-TEID */
|
||||
pgw_s5u_teid = rsp->bearer_contexts.s5_s8_u_pgw_f_teid.data;
|
||||
ogs_assert(pgw_s5u_teid);
|
||||
ogs_expect_or_return(pgw_s5u_teid);
|
||||
|
||||
/* Find the Bearer by PGW-S5U-TEID */
|
||||
bearer = smf_bearer_find_by_pgw_s5u_teid(be32toh(pgw_s5u_teid->teid));
|
||||
ogs_assert(bearer);
|
||||
bearer = smf_bearer_find_by_pgw_s5u_teid(sess, be32toh(pgw_s5u_teid->teid));
|
||||
ogs_expect_or_return(bearer);
|
||||
|
||||
/* Set EBI */
|
||||
bearer->ebi = rsp->bearer_contexts.eps_bearer_id.u8;
|
||||
|
@ -350,31 +350,8 @@ void smf_s5c_handle_create_bearer_response(
|
|||
&dl_far->outer_header_creation, &dl_far->outer_header_creation_len);
|
||||
dl_far->outer_header_creation.teid = bearer->sgw_s5u_teid;
|
||||
|
||||
/* Setup QER */
|
||||
if (bearer->qos.mbr.downlink || bearer->qos.mbr.uplink ||
|
||||
bearer->qos.gbr.downlink || bearer->qos.gbr.uplink) {
|
||||
ogs_pfcp_qer_t *qer = NULL;
|
||||
|
||||
/* Only 1 QER is used per bearer */
|
||||
qer = bearer->qer;
|
||||
if (!qer) {
|
||||
qer = ogs_pfcp_qer_add(&sess->pfcp);
|
||||
ogs_assert(qer);
|
||||
qer->id = qer->index;
|
||||
bearer->qer = qer;
|
||||
}
|
||||
|
||||
ogs_pfcp_pdr_associate_qer(bearer->dl_pdr, qer);
|
||||
ogs_pfcp_pdr_associate_qer(bearer->ul_pdr, qer);
|
||||
|
||||
qer->mbr.uplink = bearer->qos.mbr.uplink;
|
||||
qer->mbr.downlink = bearer->qos.mbr.downlink;
|
||||
qer->gbr.uplink = bearer->qos.gbr.uplink;
|
||||
qer->gbr.downlink = bearer->qos.gbr.downlink;
|
||||
}
|
||||
|
||||
smf_epc_pfcp_send_bearer_modification_request(
|
||||
bearer, OGS_PFCP_MODIFY_CREATE);
|
||||
bearer, OGS_PFCP_MODIFY_ACTIVATE);
|
||||
}
|
||||
|
||||
void smf_s5c_handle_update_bearer_response(
|
||||
|
@ -425,7 +402,7 @@ void smf_s5c_handle_update_bearer_response(
|
|||
|
||||
bearer = smf_bearer_find_by_ebi(
|
||||
sess, rsp->bearer_contexts.eps_bearer_id.u8);
|
||||
ogs_assert(bearer);
|
||||
ogs_expect_or_return(bearer);
|
||||
|
||||
ogs_debug("[SMF] Update Bearer Response : SGW[0x%x] --> SMF[0x%x]",
|
||||
sess->sgw_s5c_teid, sess->smf_n4_teid);
|
||||
|
@ -523,7 +500,7 @@ void smf_s5c_handle_delete_bearer_response(
|
|||
|
||||
bearer = smf_bearer_find_by_ebi(
|
||||
sess, rsp->bearer_contexts.eps_bearer_id.u8);
|
||||
ogs_assert(bearer);
|
||||
ogs_expect_or_return(bearer);
|
||||
|
||||
ogs_debug("[SMF] Delete Bearer Response : SGW[0x%x] --> SMF[0x%x]",
|
||||
sess->sgw_s5c_teid, sess->smf_n4_teid);
|
||||
|
|
|
@ -25,6 +25,7 @@ ogs_pkbuf_t *upf_n4_build_session_establishment_response(uint8_t type,
|
|||
{
|
||||
ogs_pfcp_message_t pfcp_message;
|
||||
ogs_pfcp_session_establishment_response_t *rsp = NULL;
|
||||
ogs_pkbuf_t *pkbuf = NULL;
|
||||
|
||||
int i = 0;
|
||||
|
||||
|
@ -59,18 +60,19 @@ ogs_pkbuf_t *upf_n4_build_session_establishment_response(uint8_t type,
|
|||
rsp->up_f_seid.data = &f_seid;
|
||||
rsp->up_f_seid.len = len;
|
||||
|
||||
ogs_pfcp_pdrbuf_init();
|
||||
|
||||
/* Created PDR */
|
||||
for (i = 0; i < num_of_created_pdr; i++) {
|
||||
ogs_pfcp_tlv_created_pdr_t *message = &rsp->created_pdr[i];
|
||||
ogs_assert(message);
|
||||
|
||||
message->presence = 1;
|
||||
message->pdr_id.presence = 1;
|
||||
message->pdr_id.u16 = created_pdr[i]->id;
|
||||
ogs_pfcp_build_created_pdr(&rsp->created_pdr[i], i, created_pdr[i]);
|
||||
}
|
||||
|
||||
pfcp_message.h.type = type;
|
||||
return ogs_pfcp_build_msg(&pfcp_message);
|
||||
pkbuf = ogs_pfcp_build_msg(&pfcp_message);
|
||||
|
||||
ogs_pfcp_pdrbuf_clear();
|
||||
|
||||
return pkbuf;
|
||||
}
|
||||
|
||||
ogs_pkbuf_t *upf_n4_build_session_modification_response(uint8_t type,
|
||||
|
@ -78,6 +80,7 @@ ogs_pkbuf_t *upf_n4_build_session_modification_response(uint8_t type,
|
|||
{
|
||||
ogs_pfcp_message_t pfcp_message;
|
||||
ogs_pfcp_session_modification_response_t *rsp = NULL;
|
||||
ogs_pkbuf_t *pkbuf = NULL;
|
||||
|
||||
int i = 0;
|
||||
|
||||
|
@ -90,18 +93,19 @@ ogs_pkbuf_t *upf_n4_build_session_modification_response(uint8_t type,
|
|||
rsp->cause.presence = 1;
|
||||
rsp->cause.u8 = OGS_PFCP_CAUSE_REQUEST_ACCEPTED;
|
||||
|
||||
ogs_pfcp_pdrbuf_init();
|
||||
|
||||
/* Created PDR */
|
||||
for (i = 0; i < num_of_created_pdr; i++) {
|
||||
ogs_pfcp_tlv_created_pdr_t *message = &rsp->created_pdr[i];
|
||||
ogs_assert(message);
|
||||
|
||||
message->presence = 1;
|
||||
message->pdr_id.presence = 1;
|
||||
message->pdr_id.u16 = created_pdr[i]->id;
|
||||
ogs_pfcp_build_created_pdr(&rsp->created_pdr[i], i, created_pdr[i]);
|
||||
}
|
||||
|
||||
pfcp_message.h.type = type;
|
||||
return ogs_pfcp_build_msg(&pfcp_message);
|
||||
pkbuf = ogs_pfcp_build_msg(&pfcp_message);
|
||||
|
||||
ogs_pfcp_pdrbuf_clear();
|
||||
|
||||
return pkbuf;
|
||||
}
|
||||
|
||||
ogs_pkbuf_t *upf_n4_build_session_deletion_response(uint8_t type,
|
||||
|
|
|
@ -117,8 +117,40 @@ void upf_n4_handle_session_establishment_request(
|
|||
ogs_assert(pdr);
|
||||
|
||||
if (pdr->src_if == OGS_PFCP_INTERFACE_ACCESS) { /* Uplink */
|
||||
if (pdr->f_teid_len)
|
||||
if (pdr->f_teid_len) {
|
||||
if (ogs_pfcp_self()->up_function_features.ftup &&
|
||||
pdr->f_teid.ch) {
|
||||
ogs_pfcp_gtpu_resource_t *resource = NULL;
|
||||
resource = ogs_pfcp_gtpu_resource_find(
|
||||
&ogs_pfcp_self()->gtpu_resource_list,
|
||||
sess->pdn.apn, OGS_PFCP_INTERFACE_ACCESS);
|
||||
if (resource) {
|
||||
ogs_pfcp_user_plane_ip_resource_info_to_f_teid(
|
||||
&resource->info, &pdr->f_teid, &pdr->f_teid_len);
|
||||
if (resource->info.teidri)
|
||||
pdr->f_teid.teid = OGS_PFCP_GTPU_INDEX_TO_TEID(
|
||||
pdr->index, resource->info.teidri,
|
||||
resource->info.teid_range);
|
||||
else
|
||||
pdr->f_teid.teid = pdr->index;
|
||||
} else {
|
||||
ogs_sockaddr_t *addr = NULL, *addr6 = NULL;
|
||||
|
||||
if (upf_self()->gtpu_sock)
|
||||
addr = &upf_self()->gtpu_sock->local_addr;
|
||||
if (upf_self()->gtpu_sock6)
|
||||
addr6 = &upf_self()->gtpu_sock6->local_addr;
|
||||
|
||||
ogs_assert(addr || addr6);
|
||||
ogs_pfcp_sockaddr_to_f_teid(
|
||||
addr, addr6, &pdr->f_teid, &pdr->f_teid_len);
|
||||
|
||||
pdr->f_teid.teid = pdr->index;
|
||||
}
|
||||
}
|
||||
|
||||
ogs_pfcp_pdr_hash_set(pdr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -269,8 +301,40 @@ void upf_n4_handle_session_modification_request(
|
|||
ogs_assert(pdr);
|
||||
|
||||
if (pdr->src_if == OGS_PFCP_INTERFACE_ACCESS) { /* Uplink */
|
||||
if (pdr->f_teid_len)
|
||||
if (pdr->f_teid_len) {
|
||||
if (ogs_pfcp_self()->up_function_features.ftup &&
|
||||
pdr->f_teid.ch) {
|
||||
ogs_pfcp_gtpu_resource_t *resource = NULL;
|
||||
resource = ogs_pfcp_gtpu_resource_find(
|
||||
&ogs_pfcp_self()->gtpu_resource_list,
|
||||
sess->pdn.apn, OGS_PFCP_INTERFACE_ACCESS);
|
||||
if (resource) {
|
||||
ogs_pfcp_user_plane_ip_resource_info_to_f_teid(
|
||||
&resource->info, &pdr->f_teid, &pdr->f_teid_len);
|
||||
if (resource->info.teidri)
|
||||
pdr->f_teid.teid = OGS_PFCP_GTPU_INDEX_TO_TEID(
|
||||
pdr->index, resource->info.teidri,
|
||||
resource->info.teid_range);
|
||||
else
|
||||
pdr->f_teid.teid = pdr->index;
|
||||
} else {
|
||||
ogs_sockaddr_t *addr = NULL, *addr6 = NULL;
|
||||
|
||||
if (upf_self()->gtpu_sock)
|
||||
addr = &upf_self()->gtpu_sock->local_addr;
|
||||
if (upf_self()->gtpu_sock6)
|
||||
addr6 = &upf_self()->gtpu_sock6->local_addr;
|
||||
|
||||
ogs_assert(addr || addr6);
|
||||
ogs_pfcp_sockaddr_to_f_teid(
|
||||
addr, addr6, &pdr->f_teid, &pdr->f_teid_len);
|
||||
|
||||
pdr->f_teid.teid = pdr->index;
|
||||
}
|
||||
}
|
||||
|
||||
ogs_pfcp_pdr_hash_set(pdr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue