fix the SMF crash when num of flow > 8 (#1108)

This commit is contained in:
Sukchan Lee 2021-08-07 14:23:20 +09:00
parent e9dbe5a3d7
commit 68edcd6438
18 changed files with 134 additions and 51 deletions

View File

@ -32,11 +32,21 @@ extern "C" {
#define OGS_MAX_NUM_OF_BEARER 4 /* Num of Bearer per Session */ #define OGS_MAX_NUM_OF_BEARER 4 /* Num of Bearer per Session */
#define OGS_MAX_NUM_OF_PACKET_BUFFER 64 /* Num of PacketBuffer per UE */ #define OGS_MAX_NUM_OF_PACKET_BUFFER 64 /* Num of PacketBuffer per UE */
/* Num of Flow per Bearer or PCC Rule or PDR */ /*
#define OGS_MAX_NUM_OF_FLOW 8 * The array of TLV messages is limited to 8.
* So, Flow(PDI.SDF_Filter) in PDR is limited to 8.
/* Num of PacketFilter per Bearer(GTP) or QoS(NAS-5GS) */ *
#define OGS_MAX_NUM_OF_PACKET_FILTER 16 * However, the number of flow in bearer context seems to need more than 16.
*
* Therefore, the maximum number of flows of messages is defined as 8,
* and the maximum number of flows stored by the context is 16.
*/
#define OGS_MAX_NUM_OF_FLOW_IN_PDR 8
#define OGS_MAX_NUM_OF_FLOW_IN_GTP OGS_MAX_NUM_OF_FLOW_IN_PDR
#define OGS_MAX_NUM_OF_FLOW_IN_NAS OGS_MAX_NUM_OF_FLOW_IN_PDR
#define OGS_MAX_NUM_OF_FLOW_IN_PCC_RULE OGS_MAX_NUM_OF_FLOW_IN_PDR
#define OGS_MAX_NUM_OF_FLOW_IN_MEDIA_SUB_COMPONENT OGS_MAX_NUM_OF_FLOW_IN_PDR
#define OGS_MAX_NUM_OF_FLOW_IN_BEARER 16
#define OGS_MAX_NUM_OF_GTPU_RESOURCE 4 #define OGS_MAX_NUM_OF_GTPU_RESOURCE 4
@ -339,7 +349,7 @@ typedef struct ogs_pcc_rule_s {
char *id; /* 5GC */ char *id; /* 5GC */
char *name; /* EPC */ char *name; /* EPC */
ogs_flow_t flow[OGS_MAX_NUM_OF_FLOW]; ogs_flow_t flow[OGS_MAX_NUM_OF_FLOW_IN_PCC_RULE];
int num_of_flow; int num_of_flow;
int flow_status; int flow_status;
@ -627,7 +637,7 @@ void ogs_session_data_free(ogs_session_data_t *session_data);
typedef struct ogs_media_sub_component_s { typedef struct ogs_media_sub_component_s {
uint32_t flow_number; uint32_t flow_number;
uint32_t flow_usage; uint32_t flow_usage;
ogs_flow_t flow[OGS_MAX_NUM_OF_FLOW]; ogs_flow_t flow[OGS_MAX_NUM_OF_FLOW_IN_MEDIA_SUB_COMPONENT];
int num_of_flow; int num_of_flow;
} ogs_media_sub_component_t; } ogs_media_sub_component_t;

View File

@ -436,7 +436,8 @@ done:
while (bson_iter_next(&child7_iter)) { while (bson_iter_next(&child7_iter)) {
ogs_flow_t *flow = NULL; ogs_flow_t *flow = NULL;
ogs_assert(flow_index < OGS_MAX_NUM_OF_FLOW); ogs_assert(
flow_index < OGS_MAX_NUM_OF_FLOW_IN_PCC_RULE);
flow = &pcc_rule->flow[flow_index]; flow = &pcc_rule->flow[flow_index];
bson_iter_recurse(&child7_iter, &child8_iter); bson_iter_recurse(&child7_iter, &child8_iter);

View File

@ -302,7 +302,8 @@ int16_t ogs_gtp_parse_tft(ogs_gtp_tft_t *tft, ogs_tlv_octet_t *octet)
tft->code == OGS_GTP_TFT_CODE_DELETE_EXISTING_TFT) tft->code == OGS_GTP_TFT_CODE_DELETE_EXISTING_TFT)
return size; return size;
for (i = 0; i < tft->num_of_packet_filter; i++) { for (i = 0; i < tft->num_of_packet_filter &&
i < OGS_MAX_NUM_OF_FLOW_IN_GTP ; i++) {
ogs_assert(size+sizeof(tft->pf[i].flags) <= octet->len); ogs_assert(size+sizeof(tft->pf[i].flags) <= octet->len);
memcpy(&tft->pf[i].flags, (unsigned char *)octet->data+size, memcpy(&tft->pf[i].flags, (unsigned char *)octet->data+size,
sizeof(tft->pf[i].flags)); sizeof(tft->pf[i].flags));
@ -468,7 +469,8 @@ int16_t ogs_gtp_build_tft(
tft->code == OGS_GTP_TFT_CODE_DELETE_EXISTING_TFT) tft->code == OGS_GTP_TFT_CODE_DELETE_EXISTING_TFT)
return size; return size;
for (i = 0; i < target.num_of_packet_filter; i++) { for (i = 0; i < target.num_of_packet_filter &&
i < OGS_MAX_NUM_OF_FLOW_IN_GTP; i++) {
ogs_assert(size + sizeof(target.pf[i].flags) <= data_len); ogs_assert(size + sizeof(target.pf[i].flags) <= data_len);
memcpy((unsigned char *)octet->data + size, &target.pf[i].flags, memcpy((unsigned char *)octet->data + size, &target.pf[i].flags,
sizeof(target.pf[i].flags)); sizeof(target.pf[i].flags));

View File

@ -302,7 +302,7 @@ ED3(uint8_t code:3;,
}; };
uint8_t precedence; uint8_t precedence;
ogs_pf_content_t content; ogs_pf_content_t content;
} pf[OGS_MAX_NUM_OF_PACKET_FILTER]; } pf[OGS_MAX_NUM_OF_FLOW_IN_GTP];
} ogs_gtp_tft_t; } ogs_gtp_tft_t;
int16_t ogs_gtp_parse_tft(ogs_gtp_tft_t *tft, ogs_tlv_octet_t *octet); int16_t ogs_gtp_parse_tft(ogs_gtp_tft_t *tft, ogs_tlv_octet_t *octet);

View File

@ -484,7 +484,8 @@ int ogs_nas_build_qos_rules(ogs_nas_qos_rules_t *rules,
memcpy(buffer + length, &target.flags, sizeof(target.flags)); memcpy(buffer + length, &target.flags, sizeof(target.flags));
length += sizeof(target.flags); length += sizeof(target.flags);
for (j = 0; j < target.num_of_packet_filter; j++) { for (j = 0; j < target.num_of_packet_filter &&
j < OGS_MAX_NUM_OF_FLOW_IN_NAS; j++) {
ogs_assert(length + sizeof(target.pf[j].flags) <= ogs_assert(length + sizeof(target.pf[j].flags) <=
OGS_NAS_MAX_QOS_RULES_LEN); OGS_NAS_MAX_QOS_RULES_LEN);
memcpy(buffer + length, &target.pf[j].flags, memcpy(buffer + length, &target.pf[j].flags,

View File

@ -837,7 +837,7 @@ typedef struct ogs_nas_qos_rule_s {
uint8_t flags; uint8_t flags;
}; };
ogs_pf_content_t content; ogs_pf_content_t content;
} pf[OGS_MAX_NUM_OF_PACKET_FILTER]; } pf[OGS_MAX_NUM_OF_FLOW_IN_NAS];
uint8_t precedence; uint8_t precedence;
union { union {

View File

@ -238,7 +238,7 @@ ogs_pkbuf_t *ogs_pfcp_up_build_association_setup_response(uint8_t type,
static struct { static struct {
ogs_pfcp_f_teid_t f_teid; ogs_pfcp_f_teid_t f_teid;
char dnn[OGS_MAX_DNN_LEN]; char dnn[OGS_MAX_DNN_LEN];
char *sdf_filter[OGS_MAX_NUM_OF_FLOW]; char *sdf_filter[OGS_MAX_NUM_OF_FLOW_IN_PDR];
} pdrbuf[OGS_MAX_NUM_OF_PDR]; } pdrbuf[OGS_MAX_NUM_OF_PDR];
void ogs_pfcp_pdrbuf_init(void) void ogs_pfcp_pdrbuf_init(void)
@ -250,7 +250,7 @@ void ogs_pfcp_pdrbuf_clear(void)
{ {
int i, j; int i, j;
for (i = 0; i < OGS_MAX_NUM_OF_PDR; i++) { for (i = 0; i < OGS_MAX_NUM_OF_PDR; i++) {
for (j = 0; j < OGS_MAX_NUM_OF_FLOW; j++) { for (j = 0; j < OGS_MAX_NUM_OF_FLOW_IN_PDR; j++) {
if (pdrbuf[i].sdf_filter[j]) if (pdrbuf[i].sdf_filter[j])
ogs_free(pdrbuf[i].sdf_filter[j]); ogs_free(pdrbuf[i].sdf_filter[j]);
} }
@ -261,7 +261,7 @@ void ogs_pfcp_build_create_pdr(
ogs_pfcp_tlv_create_pdr_t *message, int i, ogs_pfcp_pdr_t *pdr) ogs_pfcp_tlv_create_pdr_t *message, int i, ogs_pfcp_pdr_t *pdr)
{ {
ogs_pfcp_far_t *far = NULL; ogs_pfcp_far_t *far = NULL;
ogs_pfcp_sdf_filter_t pfcp_sdf_filter[OGS_MAX_NUM_OF_FLOW]; ogs_pfcp_sdf_filter_t pfcp_sdf_filter[OGS_MAX_NUM_OF_FLOW_IN_PDR];
int j = 0; int j = 0;
int len = 0; int len = 0;
@ -293,8 +293,7 @@ void ogs_pfcp_build_create_pdr(
} }
memset(pfcp_sdf_filter, 0, sizeof(pfcp_sdf_filter)); memset(pfcp_sdf_filter, 0, sizeof(pfcp_sdf_filter));
ogs_assert(pdr->num_of_flow <= OGS_MAX_NUM_OF_FLOW); for (j = 0; j < pdr->num_of_flow && j < OGS_MAX_NUM_OF_FLOW_IN_PDR; j++) {
for (j = 0; j < pdr->num_of_flow; j++) {
pfcp_sdf_filter[j].fd = 1; pfcp_sdf_filter[j].fd = 1;
pfcp_sdf_filter[j].flow_description_len = pfcp_sdf_filter[j].flow_description_len =
strlen(pdr->flow_description[j]); strlen(pdr->flow_description[j]);
@ -377,7 +376,7 @@ void ogs_pfcp_build_created_pdr(
void ogs_pfcp_build_update_pdr( void ogs_pfcp_build_update_pdr(
ogs_pfcp_tlv_update_pdr_t *message, int i, ogs_pfcp_pdr_t *pdr) ogs_pfcp_tlv_update_pdr_t *message, int i, ogs_pfcp_pdr_t *pdr)
{ {
ogs_pfcp_sdf_filter_t pfcp_sdf_filter[OGS_MAX_NUM_OF_FLOW]; ogs_pfcp_sdf_filter_t pfcp_sdf_filter[OGS_MAX_NUM_OF_FLOW_IN_PDR];
int j = 0; int j = 0;
int len = 0; int len = 0;
@ -400,8 +399,7 @@ void ogs_pfcp_build_update_pdr(
} }
memset(pfcp_sdf_filter, 0, sizeof(pfcp_sdf_filter)); memset(pfcp_sdf_filter, 0, sizeof(pfcp_sdf_filter));
ogs_assert(pdr->num_of_flow <= OGS_MAX_NUM_OF_FLOW); for (j = 0; j < pdr->num_of_flow && j < OGS_MAX_NUM_OF_FLOW_IN_PDR; j++) {
for (j = 0; j < pdr->num_of_flow; j++) {
pfcp_sdf_filter[j].fd = 1; pfcp_sdf_filter[j].fd = 1;
pfcp_sdf_filter[j].flow_description_len = pfcp_sdf_filter[j].flow_description_len =
strlen(pdr->flow_description[j]); strlen(pdr->flow_description[j]);

View File

@ -79,7 +79,8 @@ void ogs_pfcp_context_init(void)
ogs_app()->pool.sess * OGS_MAX_NUM_OF_BAR); ogs_app()->pool.sess * OGS_MAX_NUM_OF_BAR);
ogs_pool_init(&ogs_pfcp_rule_pool, ogs_pool_init(&ogs_pfcp_rule_pool,
ogs_app()->pool.sess * OGS_MAX_NUM_OF_PDR * OGS_MAX_NUM_OF_FLOW); ogs_app()->pool.sess *
OGS_MAX_NUM_OF_PDR * OGS_MAX_NUM_OF_FLOW_IN_PDR);
ogs_pool_init(&ogs_pfcp_dev_pool, OGS_MAX_NUM_OF_DEV); ogs_pool_init(&ogs_pfcp_dev_pool, OGS_MAX_NUM_OF_DEV);
ogs_pool_init(&ogs_pfcp_subnet_pool, OGS_MAX_NUM_OF_SUBNET); ogs_pool_init(&ogs_pfcp_subnet_pool, OGS_MAX_NUM_OF_SUBNET);

View File

@ -173,7 +173,7 @@ typedef struct ogs_pfcp_pdr_s {
ogs_pfcp_qer_t *qer; ogs_pfcp_qer_t *qer;
int num_of_flow; int num_of_flow;
char *flow_description[OGS_MAX_NUM_OF_FLOW]; char *flow_description[OGS_MAX_NUM_OF_FLOW_IN_PDR];
ogs_list_t rule_list; /* Rule List */ ogs_list_t rule_list; /* Rule List */

View File

@ -313,7 +313,7 @@ ogs_pfcp_pdr_t *ogs_pfcp_handle_create_pdr(ogs_pfcp_sess_t *sess,
ogs_pfcp_rule_remove_all(pdr); ogs_pfcp_rule_remove_all(pdr);
for (i = 0; i < OGS_MAX_NUM_OF_FLOW; i++) { for (i = 0; i < OGS_MAX_NUM_OF_FLOW_IN_PDR; i++) {
ogs_pfcp_sdf_filter_t sdf_filter; ogs_pfcp_sdf_filter_t sdf_filter;
ogs_pfcp_rule_t *rule = NULL; ogs_pfcp_rule_t *rule = NULL;
ogs_pfcp_rule_t *oppsite_direction_rule = NULL; ogs_pfcp_rule_t *oppsite_direction_rule = NULL;
@ -558,7 +558,7 @@ ogs_pfcp_pdr_t *ogs_pfcp_handle_update_pdr(ogs_pfcp_sess_t *sess,
ogs_pfcp_rule_remove_all(pdr); ogs_pfcp_rule_remove_all(pdr);
for (i = 0; i < OGS_MAX_NUM_OF_FLOW; i++) { for (i = 0; i < OGS_MAX_NUM_OF_FLOW_IN_PDR; i++) {
ogs_pfcp_sdf_filter_t sdf_filter; ogs_pfcp_sdf_filter_t sdf_filter;
ogs_pfcp_rule_t *rule = NULL; ogs_pfcp_rule_t *rule = NULL;
ogs_pfcp_rule_t *oppsite_direction_rule = NULL; ogs_pfcp_rule_t *oppsite_direction_rule = NULL;

View File

@ -455,7 +455,11 @@ bool pcf_npcf_policyauthorization_handle_create(pcf_sess_t *sess,
fDescList = SubComponent->f_descs; fDescList = SubComponent->f_descs;
OpenAPI_list_for_each(fDescList, node3) { OpenAPI_list_for_each(fDescList, node3) {
ogs_flow_t *flow = &sub->flow[sub->num_of_flow]; ogs_flow_t *flow = NULL;
ogs_assert(sub->num_of_flow <
OGS_MAX_NUM_OF_FLOW_IN_MEDIA_SUB_COMPONENT);
flow = &sub->flow[sub->num_of_flow];
if (node3->data) { if (node3->data) {
flow->description = ogs_strdup(node3->data); flow->description = ogs_strdup(node3->data);
ogs_assert(flow->description); ogs_assert(flow->description);

View File

@ -1435,7 +1435,8 @@ static int matched_flow(ogs_pcc_rule_t *pcc_rule,
continue; continue;
} }
for (j = 0; j < sub->num_of_flow; j++) { for (j = 0; j < sub->num_of_flow &&
j < OGS_MAX_NUM_OF_FLOW_IN_MEDIA_SUB_COMPONENT; j++) {
ogs_flow_t gx_flow; ogs_flow_t gx_flow;
ogs_flow_t *rx_flow = &sub->flow[j]; ogs_flow_t *rx_flow = &sub->flow[j];
@ -1484,11 +1485,12 @@ static int install_flow(ogs_pcc_rule_t *pcc_rule,
} }
/* Copy Flow to PCC Rule */ /* Copy Flow to PCC Rule */
for (j = 0; j < sub->num_of_flow; j++) { for (j = 0; j < sub->num_of_flow &&
j < OGS_MAX_NUM_OF_FLOW_IN_MEDIA_SUB_COMPONENT; j++) {
ogs_flow_t *rx_flow = NULL; ogs_flow_t *rx_flow = NULL;
ogs_flow_t *gx_flow = NULL; ogs_flow_t *gx_flow = NULL;
if (pcc_rule->num_of_flow < OGS_MAX_NUM_OF_FLOW) { if (pcc_rule->num_of_flow < OGS_MAX_NUM_OF_FLOW_IN_PCC_RULE) {
rx_flow = &sub->flow[j]; rx_flow = &sub->flow[j];
gx_flow = &pcc_rule->flow[pcc_rule->num_of_flow]; gx_flow = &pcc_rule->flow[pcc_rule->num_of_flow];
@ -1530,7 +1532,8 @@ static int update_qos(ogs_pcc_rule_t *pcc_rule,
continue; continue;
} }
for (j = 0; j < sub->num_of_flow; j++) { for (j = 0; j < sub->num_of_flow &&
j < OGS_MAX_NUM_OF_FLOW_IN_MEDIA_SUB_COMPONENT; j++) {
ogs_flow_t gx_flow; ogs_flow_t gx_flow;
ogs_flow_t *rx_flow = &sub->flow[j]; ogs_flow_t *rx_flow = &sub->flow[j];

View File

@ -281,6 +281,8 @@ static int pcrf_rx_aar_cb( struct msg **msg, struct avp *avp,
hdr->avp_value->i32; hdr->avp_value->i32;
break; break;
case OGS_DIAM_RX_AVP_CODE_FLOW_DESCRIPTION: case OGS_DIAM_RX_AVP_CODE_FLOW_DESCRIPTION:
ogs_assert(sub->num_of_flow <
OGS_MAX_NUM_OF_FLOW_IN_MEDIA_SUB_COMPONENT);
flow = &sub->flow[sub->num_of_flow]; flow = &sub->flow[sub->num_of_flow];
/* IE (IPV4-local-addr field ) is not supported on /* IE (IPV4-local-addr field ) is not supported on

View File

@ -87,6 +87,7 @@ static void encode_traffic_flow_template(
if (tft_operation_code != OGS_GTP_TFT_CODE_DELETE_EXISTING_TFT && if (tft_operation_code != OGS_GTP_TFT_CODE_DELETE_EXISTING_TFT &&
tft_operation_code != OGS_GTP_TFT_CODE_NO_TFT_OPERATION) { tft_operation_code != OGS_GTP_TFT_CODE_NO_TFT_OPERATION) {
ogs_list_for_each_entry(&bearer->pf_to_add_list, pf, to_add_node) { ogs_list_for_each_entry(&bearer->pf_to_add_list, pf, to_add_node) {
ogs_assert(i < OGS_MAX_NUM_OF_FLOW_IN_GTP);
tft->pf[i].identifier = pf->identifier - 1; tft->pf[i].identifier = pf->identifier - 1;
/* Deletion of packet filters /* Deletion of packet filters
@ -270,6 +271,10 @@ void smf_bearer_binding(smf_sess_t *sess)
} }
pf = smf_pf_add(bearer); pf = smf_pf_add(bearer);
if (!pf) {
ogs_error("Overflow: PacketFilter in Bearer");
break;
}
ogs_assert(pf); ogs_assert(pf);
pf->direction = flow->direction; pf->direction = flow->direction;
@ -336,10 +341,15 @@ void smf_bearer_binding(smf_sess_t *sess)
ogs_gtp_tft_t tft; ogs_gtp_tft_t tft;
memset(&tft, 0, sizeof tft); memset(&tft, 0, sizeof tft);
if (pcc_rule->num_of_flow) if (pcc_rule->num_of_flow) {
if (ogs_list_count(&bearer->pf_to_add_list) == 0) {
ogs_error("No need to send 'Update Bearer Request'");
continue;
}
encode_traffic_flow_template( encode_traffic_flow_template(
&tft, bearer, &tft, bearer,
OGS_GTP_TFT_CODE_ADD_PACKET_FILTERS_TO_EXISTING_TFT); OGS_GTP_TFT_CODE_ADD_PACKET_FILTERS_TO_EXISTING_TFT);
}
memset(&h, 0, sizeof(ogs_gtp_header_t)); memset(&h, 0, sizeof(ogs_gtp_header_t));
h.type = OGS_GTP_UPDATE_BEARER_REQUEST_TYPE; h.type = OGS_GTP_UPDATE_BEARER_REQUEST_TYPE;

View File

@ -59,7 +59,8 @@ void smf_context_init(void)
ogs_pool_init(&smf_sess_pool, ogs_app()->pool.sess); ogs_pool_init(&smf_sess_pool, ogs_app()->pool.sess);
ogs_pool_init(&smf_bearer_pool, ogs_app()->pool.bearer); ogs_pool_init(&smf_bearer_pool, ogs_app()->pool.bearer);
ogs_pool_init(&smf_pf_pool, ogs_app()->pool.bearer * OGS_MAX_NUM_OF_FLOW); ogs_pool_init(&smf_pf_pool,
ogs_app()->pool.bearer * OGS_MAX_NUM_OF_FLOW_IN_BEARER);
self.supi_hash = ogs_hash_make(); self.supi_hash = ogs_hash_make();
ogs_assert(self.supi_hash); ogs_assert(self.supi_hash);
@ -2140,17 +2141,27 @@ smf_pf_t *smf_pf_add(smf_bearer_t *bearer)
memset(pf, 0, sizeof *pf); memset(pf, 0, sizeof *pf);
ogs_pool_alloc(&bearer->pf_identifier_pool, &pf->identifier_node); ogs_pool_alloc(&bearer->pf_identifier_pool, &pf->identifier_node);
ogs_assert(pf->identifier_node); if (!pf->identifier_node) {
ogs_error("smf_pf_add: Expectation `pf->identifier_node' failed");
ogs_pool_free(&smf_pf_pool, pf);
return NULL;
}
pf->identifier = *(pf->identifier_node); pf->identifier = *(pf->identifier_node);
ogs_assert(pf->identifier > 0 && pf->identifier <= OGS_MAX_NUM_OF_FLOW); ogs_assert(pf->identifier > 0 && pf->identifier <=
OGS_MAX_NUM_OF_FLOW_IN_BEARER);
ogs_pool_alloc(&sess->pf_precedence_pool, &pf->precedence_node); ogs_pool_alloc(&sess->pf_precedence_pool, &pf->precedence_node);
ogs_assert(pf->precedence_node); if (!pf->precedence_node) {
ogs_error("smf_pf_add: Expectation `pf->precedence_node' failed");
ogs_pool_free(&bearer->pf_identifier_pool, pf->identifier_node);
ogs_pool_free(&smf_pf_pool, pf);
return NULL;
}
pf->precedence = *(pf->precedence_node); pf->precedence = *(pf->precedence_node);
ogs_assert(pf->precedence > 0 && pf->precedence <= ogs_assert(pf->precedence > 0 && pf->precedence <=
(OGS_MAX_NUM_OF_BEARER * OGS_MAX_NUM_OF_FLOW)); (OGS_MAX_NUM_OF_BEARER * OGS_MAX_NUM_OF_FLOW_IN_BEARER));
pf->bearer = bearer; pf->bearer = bearer;
@ -2427,9 +2438,9 @@ void smf_pf_identifier_pool_init(smf_bearer_t *bearer)
ogs_assert(bearer); ogs_assert(bearer);
ogs_index_init(&bearer->pf_identifier_pool, OGS_MAX_NUM_OF_FLOW); ogs_index_init(&bearer->pf_identifier_pool, OGS_MAX_NUM_OF_FLOW_IN_BEARER);
for (i = 1; i <= OGS_MAX_NUM_OF_FLOW; i++) { for (i = 1; i <= OGS_MAX_NUM_OF_FLOW_IN_BEARER; i++) {
bearer->pf_identifier_pool.array[i-1] = i; bearer->pf_identifier_pool.array[i-1] = i;
} }
} }
@ -2448,9 +2459,10 @@ void smf_pf_precedence_pool_init(smf_sess_t *sess)
ogs_assert(sess); ogs_assert(sess);
ogs_index_init(&sess->pf_precedence_pool, ogs_index_init(&sess->pf_precedence_pool,
OGS_MAX_NUM_OF_BEARER * OGS_MAX_NUM_OF_FLOW); OGS_MAX_NUM_OF_BEARER * OGS_MAX_NUM_OF_FLOW_IN_BEARER);
for (i = 1; i <= OGS_MAX_NUM_OF_BEARER * OGS_MAX_NUM_OF_FLOW; i++) { for (i = 1; i <=
OGS_MAX_NUM_OF_BEARER * OGS_MAX_NUM_OF_FLOW_IN_BEARER; i++) {
sess->pf_precedence_pool.array[i-1] = i; sess->pf_precedence_pool.array[i-1] = i;
} }
} }

View File

@ -265,6 +265,7 @@ static void encode_qos_rule_packet_filter(
i = 0; i = 0;
ogs_list_for_each(&qos_flow->pf_list, pf) { ogs_list_for_each(&qos_flow->pf_list, pf) {
ogs_assert(i < OGS_MAX_NUM_OF_FLOW_IN_NAS);
qos_rule->pf[i].direction = pf->direction; qos_rule->pf[i].direction = pf->direction;
qos_rule->pf[i].identifier = pf->identifier; qos_rule->pf[i].identifier = pf->identifier;

View File

@ -626,7 +626,6 @@ static void smf_gx_cca_cb(void *data, struct msg **msg)
smf_event_t *e = NULL; smf_event_t *e = NULL;
ogs_gtp_xact_t *xact = NULL; ogs_gtp_xact_t *xact = NULL;
smf_sess_t *sess = NULL; smf_sess_t *sess = NULL;
ogs_pcc_rule_t *pcc_rule = NULL;
ogs_pkbuf_t *gxbuf = NULL; ogs_pkbuf_t *gxbuf = NULL;
ogs_diam_gx_message_t *gx_message = NULL; ogs_diam_gx_message_t *gx_message = NULL;
uint16_t gxbuf_len = 0; uint16_t gxbuf_len = 0;
@ -881,6 +880,10 @@ static void smf_gx_cca_cb(void *data, struct msg **msg)
case OGS_DIAM_GX_AVP_CODE_CHARGING_RULE_DEFINITION: case OGS_DIAM_GX_AVP_CODE_CHARGING_RULE_DEFINITION:
if (gx_message->session_data.num_of_pcc_rule < if (gx_message->session_data.num_of_pcc_rule <
OGS_MAX_NUM_OF_PCC_RULE) { OGS_MAX_NUM_OF_PCC_RULE) {
ogs_pcc_rule_t *pcc_rule = NULL;
smf_bearer_t *bearer = NULL;
int num_of_flow = 0;
pcc_rule = &gx_message->session_data.pcc_rule pcc_rule = &gx_message->session_data.pcc_rule
[gx_message->session_data.num_of_pcc_rule]; [gx_message->session_data.num_of_pcc_rule];
@ -888,8 +891,21 @@ static void smf_gx_cca_cb(void *data, struct msg **msg)
pcc_rule, avpch1, &error); pcc_rule, avpch1, &error);
ogs_assert(rv == OGS_OK); ogs_assert(rv == OGS_OK);
pcc_rule->type = OGS_PCC_RULE_TYPE_INSTALL; num_of_flow = pcc_rule->num_of_flow;
gx_message->session_data.num_of_pcc_rule++;
bearer = smf_bearer_find_by_pcc_rule_name(
sess, pcc_rule->name);
if (bearer)
num_of_flow += ogs_list_count(&bearer->pf_list);
if (num_of_flow < OGS_MAX_NUM_OF_FLOW_IN_BEARER) {
pcc_rule->type = OGS_PCC_RULE_TYPE_INSTALL;
gx_message->session_data.num_of_pcc_rule++;
} else {
ogs_error("Overflow : Num Of Flow %d", num_of_flow);
OGS_PCC_RULE_FREE(pcc_rule);
error++;
}
} else { } else {
ogs_error("Overflow: Number of PCCRule"); ogs_error("Overflow: Number of PCCRule");
error++; error++;
@ -1015,7 +1031,6 @@ static int smf_gx_rar_cb( struct msg **msg, struct avp *avp,
ogs_pkbuf_t *gxbuf = NULL; ogs_pkbuf_t *gxbuf = NULL;
smf_sess_t *sess = NULL; smf_sess_t *sess = NULL;
ogs_diam_gx_message_t *gx_message = NULL; ogs_diam_gx_message_t *gx_message = NULL;
ogs_pcc_rule_t *pcc_rule = NULL;
uint32_t result_code = OGS_DIAM_UNKNOWN_SESSION_ID; uint32_t result_code = OGS_DIAM_UNKNOWN_SESSION_ID;
int error = 0; int error = 0;
@ -1080,6 +1095,10 @@ static int smf_gx_rar_cb( struct msg **msg, struct avp *avp,
case OGS_DIAM_GX_AVP_CODE_CHARGING_RULE_DEFINITION: case OGS_DIAM_GX_AVP_CODE_CHARGING_RULE_DEFINITION:
if (gx_message->session_data.num_of_pcc_rule < if (gx_message->session_data.num_of_pcc_rule <
OGS_MAX_NUM_OF_PCC_RULE) { OGS_MAX_NUM_OF_PCC_RULE) {
ogs_pcc_rule_t *pcc_rule = NULL;
smf_bearer_t *bearer = NULL;
int num_of_flow = 0;
pcc_rule = &gx_message->session_data.pcc_rule pcc_rule = &gx_message->session_data.pcc_rule
[gx_message->session_data.num_of_pcc_rule]; [gx_message->session_data.num_of_pcc_rule];
@ -1089,12 +1108,27 @@ static int smf_gx_rar_cb( struct msg **msg, struct avp *avp,
if (error) { if (error) {
ogs_error("decode_pcc_rule_definition() failed"); ogs_error("decode_pcc_rule_definition() failed");
OGS_PCC_RULE_FREE(pcc_rule);
result_code = OGS_DIAM_GX_DIAMETER_PCC_RULE_EVENT; result_code = OGS_DIAM_GX_DIAMETER_PCC_RULE_EVENT;
goto out; goto out;
} }
pcc_rule->type = OGS_PCC_RULE_TYPE_INSTALL; num_of_flow = pcc_rule->num_of_flow;
gx_message->session_data.num_of_pcc_rule++;
bearer = smf_bearer_find_by_pcc_rule_name(
sess, pcc_rule->name);
if (bearer)
num_of_flow += ogs_list_count(&bearer->pf_list);
if (num_of_flow < OGS_MAX_NUM_OF_FLOW_IN_BEARER) {
pcc_rule->type = OGS_PCC_RULE_TYPE_INSTALL;
gx_message->session_data.num_of_pcc_rule++;
} else {
ogs_error("Overflow : Num Of Flow %d", num_of_flow);
OGS_PCC_RULE_FREE(pcc_rule);
result_code = OGS_DIAM_GX_DIAMETER_PCC_RULE_EVENT;
goto out;
}
} else { } else {
ogs_error("Overflow: Number of PCCRule"); ogs_error("Overflow: Number of PCCRule");
} }
@ -1116,7 +1150,8 @@ static int smf_gx_rar_cb( struct msg **msg, struct avp *avp,
case OGS_DIAM_GX_AVP_CODE_CHARGING_RULE_NAME: case OGS_DIAM_GX_AVP_CODE_CHARGING_RULE_NAME:
if (gx_message->session_data.num_of_pcc_rule < if (gx_message->session_data.num_of_pcc_rule <
OGS_MAX_NUM_OF_PCC_RULE) { OGS_MAX_NUM_OF_PCC_RULE) {
pcc_rule = &gx_message->session_data.pcc_rule ogs_pcc_rule_t *pcc_rule =
&gx_message->session_data.pcc_rule
[gx_message->session_data.num_of_pcc_rule]; [gx_message->session_data.num_of_pcc_rule];
pcc_rule->name = ogs_strdup( pcc_rule->name = ogs_strdup(
@ -1291,7 +1326,7 @@ static int decode_pcc_rule_definition(
ogs_assert(pcc_rule->name); ogs_assert(pcc_rule->name);
break; break;
case OGS_DIAM_GX_AVP_CODE_FLOW_INFORMATION: case OGS_DIAM_GX_AVP_CODE_FLOW_INFORMATION:
if (pcc_rule->num_of_flow < OGS_MAX_NUM_OF_FLOW) { if (pcc_rule->num_of_flow < OGS_MAX_NUM_OF_FLOW_IN_PCC_RULE) {
flow = &pcc_rule->flow[pcc_rule->num_of_flow]; flow = &pcc_rule->flow[pcc_rule->num_of_flow];
ret = fd_avp_search_avp( ret = fd_avp_search_avp(

View File

@ -999,7 +999,8 @@ void smf_s5c_handle_bearer_resource_command(
tft_delete = 1; tft_delete = 1;
} else if (tft.code == } else if (tft.code ==
OGS_GTP_TFT_CODE_REPLACE_PACKET_FILTERS_IN_EXISTING) { OGS_GTP_TFT_CODE_REPLACE_PACKET_FILTERS_IN_EXISTING) {
for (i = 0; i < tft.num_of_packet_filter; i++) { for (i = 0; i < tft.num_of_packet_filter &&
i < OGS_MAX_NUM_OF_FLOW_IN_GTP; i++) {
pf = smf_pf_find_by_id(bearer, tft.pf[i].identifier+1); pf = smf_pf_find_by_id(bearer, tft.pf[i].identifier+1);
if (pf) { if (pf) {
if (reconfigure_packet_filter(pf, &tft, i) < 0) { if (reconfigure_packet_filter(pf, &tft, i) < 0) {
@ -1064,7 +1065,8 @@ void smf_s5c_handle_bearer_resource_command(
if (tft.code == OGS_GTP_TFT_CODE_CREATE_NEW_TFT) if (tft.code == OGS_GTP_TFT_CODE_CREATE_NEW_TFT)
smf_pf_remove_all(bearer); smf_pf_remove_all(bearer);
for (i = 0; i < tft.num_of_packet_filter; i++) { for (i = 0; i < tft.num_of_packet_filter &&
i < OGS_MAX_NUM_OF_FLOW_IN_GTP; i++) {
pf = smf_pf_find_by_id(bearer, tft.pf[i].identifier+1); pf = smf_pf_find_by_id(bearer, tft.pf[i].identifier+1);
if (!pf) if (!pf)
pf = smf_pf_add(bearer); pf = smf_pf_add(bearer);
@ -1128,7 +1130,8 @@ void smf_s5c_handle_bearer_resource_command(
} }
} else if (tft.code == } else if (tft.code ==
OGS_GTP_TFT_CODE_DELETE_PACKET_FILTERS_FROM_EXISTING) { OGS_GTP_TFT_CODE_DELETE_PACKET_FILTERS_FROM_EXISTING) {
for (i = 0; i < tft.num_of_packet_filter; i++) { for (i = 0; i < tft.num_of_packet_filter &&
i <= OGS_MAX_NUM_OF_FLOW_IN_GTP; i++) {
pf = smf_pf_find_by_id(bearer, tft.pf[i].identifier+1); pf = smf_pf_find_by_id(bearer, tft.pf[i].identifier+1);
if (pf) if (pf)
smf_pf_remove(pf); smf_pf_remove(pf);