mirror of
				https://github.com/open5gs/open5gs.git
				synced 2025-11-04 14:03:21 +00:00 
			
		
		
		
	Fix the crash when number of flow > 8 (#1108)
This commit is contained in:
		@@ -32,6 +32,9 @@ extern "C" {
 | 
			
		||||
#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 */
 | 
			
		||||
 | 
			
		||||
/* Num of Flow per Bearer or PCC Rule or PDR */
 | 
			
		||||
#define OGS_MAX_NUM_OF_FLOW             8
 | 
			
		||||
 | 
			
		||||
/* Num of PacketFilter per Bearer(GTP) or QoS(NAS-5GS) */
 | 
			
		||||
#define OGS_MAX_NUM_OF_PACKET_FILTER    16
 | 
			
		||||
 | 
			
		||||
@@ -336,8 +339,6 @@ typedef struct ogs_pcc_rule_s {
 | 
			
		||||
    char *id;   /* 5GC */
 | 
			
		||||
    char *name; /* EPC */
 | 
			
		||||
 | 
			
		||||
/* Num of Flow per PCC Rule */
 | 
			
		||||
#define OGS_MAX_NUM_OF_FLOW                     8
 | 
			
		||||
    ogs_flow_t flow[OGS_MAX_NUM_OF_FLOW];
 | 
			
		||||
    int num_of_flow;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -238,7 +238,7 @@ ogs_pkbuf_t *ogs_pfcp_up_build_association_setup_response(uint8_t type,
 | 
			
		||||
static struct {
 | 
			
		||||
    ogs_pfcp_f_teid_t f_teid;
 | 
			
		||||
    char dnn[OGS_MAX_DNN_LEN];
 | 
			
		||||
    char *sdf_filter[OGS_PFCP_MAX_NUM_OF_RULE];
 | 
			
		||||
    char *sdf_filter[OGS_MAX_NUM_OF_FLOW];
 | 
			
		||||
} pdrbuf[OGS_MAX_NUM_OF_PDR];
 | 
			
		||||
 | 
			
		||||
void ogs_pfcp_pdrbuf_init(void)
 | 
			
		||||
@@ -250,7 +250,7 @@ void ogs_pfcp_pdrbuf_clear(void)
 | 
			
		||||
{
 | 
			
		||||
    int i, j;
 | 
			
		||||
    for (i = 0; i < OGS_MAX_NUM_OF_PDR; i++) {
 | 
			
		||||
        for (j = 0; j < OGS_PFCP_MAX_NUM_OF_RULE; j++) {
 | 
			
		||||
        for (j = 0; j < OGS_MAX_NUM_OF_FLOW; j++) {
 | 
			
		||||
            if (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_far_t *far = NULL;
 | 
			
		||||
    ogs_pfcp_sdf_filter_t pfcp_sdf_filter[OGS_PFCP_MAX_NUM_OF_RULE];
 | 
			
		||||
    ogs_pfcp_sdf_filter_t pfcp_sdf_filter[OGS_MAX_NUM_OF_FLOW];
 | 
			
		||||
    int j = 0;
 | 
			
		||||
    int len = 0;
 | 
			
		||||
 | 
			
		||||
@@ -293,6 +293,7 @@ void ogs_pfcp_build_create_pdr(
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    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++) {
 | 
			
		||||
        pfcp_sdf_filter[j].fd = 1;
 | 
			
		||||
        pfcp_sdf_filter[j].flow_description_len =
 | 
			
		||||
@@ -376,7 +377,7 @@ void ogs_pfcp_build_created_pdr(
 | 
			
		||||
void ogs_pfcp_build_update_pdr(
 | 
			
		||||
    ogs_pfcp_tlv_update_pdr_t *message, int i, ogs_pfcp_pdr_t *pdr)
 | 
			
		||||
{
 | 
			
		||||
    ogs_pfcp_sdf_filter_t pfcp_sdf_filter[OGS_PFCP_MAX_NUM_OF_RULE];
 | 
			
		||||
    ogs_pfcp_sdf_filter_t pfcp_sdf_filter[OGS_MAX_NUM_OF_FLOW];
 | 
			
		||||
    int j = 0;
 | 
			
		||||
    int len = 0;
 | 
			
		||||
 | 
			
		||||
@@ -399,6 +400,7 @@ void ogs_pfcp_build_update_pdr(
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    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++) {
 | 
			
		||||
        pfcp_sdf_filter[j].fd = 1;
 | 
			
		||||
        pfcp_sdf_filter[j].flow_description_len =
 | 
			
		||||
 
 | 
			
		||||
@@ -79,7 +79,7 @@ void ogs_pfcp_context_init(void)
 | 
			
		||||
            ogs_app()->pool.sess * OGS_MAX_NUM_OF_BAR);
 | 
			
		||||
 | 
			
		||||
    ogs_pool_init(&ogs_pfcp_rule_pool,
 | 
			
		||||
            ogs_app()->pool.sess * OGS_PFCP_MAX_NUM_OF_RULE);
 | 
			
		||||
            ogs_app()->pool.sess * OGS_MAX_NUM_OF_PDR * OGS_MAX_NUM_OF_FLOW);
 | 
			
		||||
 | 
			
		||||
    ogs_pool_init(&ogs_pfcp_dev_pool, OGS_MAX_NUM_OF_DEV);
 | 
			
		||||
    ogs_pool_init(&ogs_pfcp_subnet_pool, OGS_MAX_NUM_OF_SUBNET);
 | 
			
		||||
 
 | 
			
		||||
@@ -173,8 +173,7 @@ typedef struct ogs_pfcp_pdr_s {
 | 
			
		||||
    ogs_pfcp_qer_t          *qer;
 | 
			
		||||
 | 
			
		||||
    int                     num_of_flow;
 | 
			
		||||
#define OGS_PFCP_MAX_NUM_OF_RULE  8   /* Num of Rule per Session */
 | 
			
		||||
    char                    *flow_description[OGS_PFCP_MAX_NUM_OF_RULE];
 | 
			
		||||
    char                    *flow_description[OGS_MAX_NUM_OF_FLOW];
 | 
			
		||||
 | 
			
		||||
    ogs_list_t              rule_list;      /* Rule List */
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -313,7 +313,7 @@ ogs_pfcp_pdr_t *ogs_pfcp_handle_create_pdr(ogs_pfcp_sess_t *sess,
 | 
			
		||||
 | 
			
		||||
    ogs_pfcp_rule_remove_all(pdr);
 | 
			
		||||
 | 
			
		||||
    for (i = 0; i < OGS_PFCP_MAX_NUM_OF_RULE; i++) {
 | 
			
		||||
    for (i = 0; i < OGS_MAX_NUM_OF_FLOW; i++) {
 | 
			
		||||
        ogs_pfcp_sdf_filter_t sdf_filter;
 | 
			
		||||
        ogs_pfcp_rule_t *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);
 | 
			
		||||
 | 
			
		||||
        for (i = 0; i < OGS_PFCP_MAX_NUM_OF_RULE; i++) {
 | 
			
		||||
        for (i = 0; i < OGS_MAX_NUM_OF_FLOW; i++) {
 | 
			
		||||
            ogs_pfcp_sdf_filter_t sdf_filter;
 | 
			
		||||
            ogs_pfcp_rule_t *rule = NULL;
 | 
			
		||||
            ogs_pfcp_rule_t *oppsite_direction_rule = NULL;
 | 
			
		||||
 
 | 
			
		||||
@@ -374,7 +374,7 @@ bool ogs_sbi_nnrf_handle_nf_profile(ogs_sbi_nf_instance_t *nf_instance,
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        OpenAPI_list_for_each(AllowedNfTypeList, node2) {
 | 
			
		||||
            OpenAPI_nf_type_e AllowedNfType = (OpenAPI_nf_type_e)node2->data;
 | 
			
		||||
            OpenAPI_nf_type_e AllowedNfType = (uintptr_t)node2->data;
 | 
			
		||||
 | 
			
		||||
            if (!AllowedNfType) continue;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -59,7 +59,7 @@ void smf_context_init(void)
 | 
			
		||||
    ogs_pool_init(&smf_sess_pool, ogs_app()->pool.sess);
 | 
			
		||||
    ogs_pool_init(&smf_bearer_pool, ogs_app()->pool.bearer);
 | 
			
		||||
 | 
			
		||||
    ogs_pool_init(&smf_pf_pool, ogs_app()->pool.bearer * MAX_NUM_OF_PF);
 | 
			
		||||
    ogs_pool_init(&smf_pf_pool, ogs_app()->pool.bearer * OGS_MAX_NUM_OF_FLOW);
 | 
			
		||||
 | 
			
		||||
    self.supi_hash = ogs_hash_make();
 | 
			
		||||
    ogs_assert(self.supi_hash);
 | 
			
		||||
@@ -2143,14 +2143,14 @@ smf_pf_t *smf_pf_add(smf_bearer_t *bearer)
 | 
			
		||||
    ogs_assert(pf->identifier_node);
 | 
			
		||||
 | 
			
		||||
    pf->identifier = *(pf->identifier_node);
 | 
			
		||||
    ogs_assert(pf->identifier > 0 && pf->identifier <= MAX_NUM_OF_PF);
 | 
			
		||||
    ogs_assert(pf->identifier > 0 && pf->identifier <= OGS_MAX_NUM_OF_FLOW);
 | 
			
		||||
 | 
			
		||||
    ogs_pool_alloc(&sess->pf_precedence_pool, &pf->precedence_node);
 | 
			
		||||
    ogs_assert(pf->precedence_node);
 | 
			
		||||
 | 
			
		||||
    pf->precedence = *(pf->precedence_node);
 | 
			
		||||
    ogs_assert(pf->precedence > 0 && pf->precedence <=
 | 
			
		||||
            (OGS_MAX_NUM_OF_BEARER * MAX_NUM_OF_PF));
 | 
			
		||||
            (OGS_MAX_NUM_OF_BEARER * OGS_MAX_NUM_OF_FLOW));
 | 
			
		||||
 | 
			
		||||
    pf->bearer = bearer;
 | 
			
		||||
 | 
			
		||||
@@ -2427,9 +2427,9 @@ void smf_pf_identifier_pool_init(smf_bearer_t *bearer)
 | 
			
		||||
 | 
			
		||||
    ogs_assert(bearer);
 | 
			
		||||
 | 
			
		||||
    ogs_index_init(&bearer->pf_identifier_pool, MAX_NUM_OF_PF);
 | 
			
		||||
    ogs_index_init(&bearer->pf_identifier_pool, OGS_MAX_NUM_OF_FLOW);
 | 
			
		||||
 | 
			
		||||
    for (i = 1; i <= MAX_NUM_OF_PF; i++) {
 | 
			
		||||
    for (i = 1; i <= OGS_MAX_NUM_OF_FLOW; i++) {
 | 
			
		||||
        bearer->pf_identifier_pool.array[i-1] = i;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -2448,9 +2448,9 @@ void smf_pf_precedence_pool_init(smf_sess_t *sess)
 | 
			
		||||
    ogs_assert(sess);
 | 
			
		||||
 | 
			
		||||
    ogs_index_init(&sess->pf_precedence_pool,
 | 
			
		||||
            OGS_MAX_NUM_OF_BEARER * MAX_NUM_OF_PF);
 | 
			
		||||
            OGS_MAX_NUM_OF_BEARER * OGS_MAX_NUM_OF_FLOW);
 | 
			
		||||
 | 
			
		||||
    for (i = 1; i <= OGS_MAX_NUM_OF_BEARER * MAX_NUM_OF_PF; i++) {
 | 
			
		||||
    for (i = 1; i <= OGS_MAX_NUM_OF_BEARER * OGS_MAX_NUM_OF_FLOW; i++) {
 | 
			
		||||
        sess->pf_precedence_pool.array[i-1] = i;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -177,8 +177,6 @@ typedef struct smf_bearer_s {
 | 
			
		||||
 | 
			
		||||
    OGS_POOL(pf_identifier_pool, uint8_t);
 | 
			
		||||
 | 
			
		||||
#define MAX_NUM_OF_PF 16            /* Num of PacketFilter per Bearer */
 | 
			
		||||
 | 
			
		||||
    /* Packet Filter List */
 | 
			
		||||
    ogs_list_t      pf_list;
 | 
			
		||||
    ogs_list_t      pf_to_add_list;
 | 
			
		||||
 
 | 
			
		||||
@@ -880,21 +880,19 @@ static void smf_gx_cca_cb(void *data, struct msg **msg)
 | 
			
		||||
                ogs_assert(ret == 0);
 | 
			
		||||
                switch (hdr->avp_code) {
 | 
			
		||||
                case OGS_DIAM_GX_AVP_CODE_CHARGING_RULE_DEFINITION:
 | 
			
		||||
                    if (gx_message->session_data.num_of_pcc_rule <
 | 
			
		||||
                            OGS_MAX_NUM_OF_PCC_RULE) {
 | 
			
		||||
                        pcc_rule = &gx_message->session_data.pcc_rule
 | 
			
		||||
                                [gx_message->session_data.num_of_pcc_rule];
 | 
			
		||||
 | 
			
		||||
                    rv = decode_pcc_rule_definition(pcc_rule, avpch1, &error);
 | 
			
		||||
                        rv = decode_pcc_rule_definition(
 | 
			
		||||
                                pcc_rule, avpch1, &error);
 | 
			
		||||
                        ogs_assert(rv == OGS_OK);
 | 
			
		||||
 | 
			
		||||
                        pcc_rule->type = OGS_PCC_RULE_TYPE_INSTALL;
 | 
			
		||||
                        gx_message->session_data.num_of_pcc_rule++;
 | 
			
		||||
 | 
			
		||||
                    /* Check for maximum number of flow rules per bearer */
 | 
			
		||||
                    bearer = smf_bearer_find_by_pcc_rule_name(
 | 
			
		||||
                            sess_data->sess, pcc_rule->name);
 | 
			
		||||
                    if (bearer &&
 | 
			
		||||
                            ((ogs_list_count(&bearer->pf_list) +
 | 
			
		||||
                                pcc_rule->num_of_flow) > MAX_NUM_OF_PF)) {
 | 
			
		||||
                    } else {
 | 
			
		||||
                        ogs_error("Overflow: Number of PCCRule");
 | 
			
		||||
                        error++;
 | 
			
		||||
                    }
 | 
			
		||||
                    break;
 | 
			
		||||
@@ -1081,6 +1079,8 @@ static int smf_gx_rar_cb( struct msg **msg, struct avp *avp,
 | 
			
		||||
                ogs_assert(ret == 0);
 | 
			
		||||
                switch(hdr->avp_code) {
 | 
			
		||||
                case OGS_DIAM_GX_AVP_CODE_CHARGING_RULE_DEFINITION:
 | 
			
		||||
                    if (gx_message->session_data.num_of_pcc_rule <
 | 
			
		||||
                            OGS_MAX_NUM_OF_PCC_RULE) {
 | 
			
		||||
                        pcc_rule = &gx_message->session_data.pcc_rule
 | 
			
		||||
                                [gx_message->session_data.num_of_pcc_rule];
 | 
			
		||||
 | 
			
		||||
@@ -1089,15 +1089,8 @@ static int smf_gx_rar_cb( struct msg **msg, struct avp *avp,
 | 
			
		||||
 | 
			
		||||
                        pcc_rule->type = OGS_PCC_RULE_TYPE_INSTALL;
 | 
			
		||||
                        gx_message->session_data.num_of_pcc_rule++;
 | 
			
		||||
 | 
			
		||||
                    /* Check for maximum number of flow rules per bearer */
 | 
			
		||||
                    bearer = smf_bearer_find_by_pcc_rule_name(
 | 
			
		||||
                            sess_data->sess, pcc_rule->name);
 | 
			
		||||
                    if (bearer &&
 | 
			
		||||
                            ((ogs_list_count(&bearer->pf_list) +
 | 
			
		||||
                                pcc_rule->num_of_flow) > MAX_NUM_OF_PF)) {
 | 
			
		||||
                        result_code = ER_DIAMETER_UNABLE_TO_COMPLY;
 | 
			
		||||
                        goto out;
 | 
			
		||||
                    } else {
 | 
			
		||||
                        ogs_error("Overflow: Number of PCCRule");
 | 
			
		||||
                    }
 | 
			
		||||
                    break;
 | 
			
		||||
                default:
 | 
			
		||||
@@ -1115,14 +1108,20 @@ static int smf_gx_rar_cb( struct msg **msg, struct avp *avp,
 | 
			
		||||
                ogs_assert(ret == 0);
 | 
			
		||||
                switch (hdr->avp_code) {
 | 
			
		||||
                case OGS_DIAM_GX_AVP_CODE_CHARGING_RULE_NAME:
 | 
			
		||||
                    if (gx_message->session_data.num_of_pcc_rule <
 | 
			
		||||
                            OGS_MAX_NUM_OF_PCC_RULE) {
 | 
			
		||||
                        pcc_rule = &gx_message->session_data.pcc_rule
 | 
			
		||||
                                [gx_message->session_data.num_of_pcc_rule];
 | 
			
		||||
 | 
			
		||||
                    pcc_rule->name = ogs_strdup((char*)hdr->avp_value->os.data);
 | 
			
		||||
                        pcc_rule->name = ogs_strdup(
 | 
			
		||||
                                (char*)hdr->avp_value->os.data);
 | 
			
		||||
                        ogs_assert(pcc_rule->name);
 | 
			
		||||
 | 
			
		||||
                        pcc_rule->type = OGS_PCC_RULE_TYPE_REMOVE;
 | 
			
		||||
                        gx_message->session_data.num_of_pcc_rule++;
 | 
			
		||||
                    } else {
 | 
			
		||||
                        ogs_error("Overflow: Number of PCCRule");
 | 
			
		||||
                    }
 | 
			
		||||
                    break;
 | 
			
		||||
                default:
 | 
			
		||||
                    ogs_error("Not supported(%d)", hdr->avp_code);
 | 
			
		||||
@@ -1286,6 +1285,7 @@ static int decode_pcc_rule_definition(
 | 
			
		||||
            ogs_assert(pcc_rule->name);
 | 
			
		||||
            break;
 | 
			
		||||
        case OGS_DIAM_GX_AVP_CODE_FLOW_INFORMATION:
 | 
			
		||||
            if (pcc_rule->num_of_flow < OGS_MAX_NUM_OF_FLOW) {
 | 
			
		||||
                flow = &pcc_rule->flow[pcc_rule->num_of_flow];
 | 
			
		||||
 | 
			
		||||
                ret = fd_avp_search_avp(
 | 
			
		||||
@@ -1311,6 +1311,10 @@ static int decode_pcc_rule_definition(
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                pcc_rule->num_of_flow++;
 | 
			
		||||
            } else {
 | 
			
		||||
                ogs_error("Overflow: Num of Flow");
 | 
			
		||||
                error++;
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
        case OGS_DIAM_GX_AVP_CODE_FLOW_STATUS:
 | 
			
		||||
            pcc_rule->flow_status = hdr->avp_value->i32;
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user