forked from acouzens/open5gs
[UPF] Fixed bug when 2 PDRs with same TEID (#2003)
This commit is contained in:
parent
ce7b60dbb5
commit
0e0085c69f
|
@ -929,6 +929,20 @@ ogs_pfcp_object_t *ogs_pfcp_object_find_by_teid(uint32_t teid)
|
||||||
self.object_teid_hash, &teid, sizeof(teid));
|
self.object_teid_hash, &teid, sizeof(teid));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ogs_pfcp_object_count_by_teid(ogs_pfcp_sess_t *sess, uint32_t teid)
|
||||||
|
{
|
||||||
|
ogs_pfcp_pdr_t *pdr = NULL;
|
||||||
|
int count = 0;
|
||||||
|
|
||||||
|
ogs_assert(sess);
|
||||||
|
|
||||||
|
ogs_list_for_each(&sess->pdr_list, pdr) {
|
||||||
|
if (pdr->f_teid.teid == teid) count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
ogs_pfcp_pdr_t *ogs_pfcp_pdr_find_by_choose_id(
|
ogs_pfcp_pdr_t *ogs_pfcp_pdr_find_by_choose_id(
|
||||||
ogs_pfcp_sess_t *sess, uint8_t choose_id)
|
ogs_pfcp_sess_t *sess, uint8_t choose_id)
|
||||||
{
|
{
|
||||||
|
@ -997,9 +1011,21 @@ void ogs_pfcp_pdr_remove(ogs_pfcp_pdr_t *pdr)
|
||||||
|
|
||||||
ogs_pfcp_rule_remove_all(pdr);
|
ogs_pfcp_rule_remove_all(pdr);
|
||||||
|
|
||||||
if (pdr->hash.teid.len)
|
if (pdr->hash.teid.len) {
|
||||||
ogs_hash_set(self.object_teid_hash,
|
/*
|
||||||
&pdr->hash.teid.key, pdr->hash.teid.len, NULL);
|
* Issues #2003
|
||||||
|
*
|
||||||
|
* In 5G Core, two PDRs can use different QFIDs for the same TEID.
|
||||||
|
* So, before deleting a TEID, we should check if there is a PDR
|
||||||
|
* using the same TEID.
|
||||||
|
*
|
||||||
|
* Since this PDR has already been deleted with ogs_list_remove() above,
|
||||||
|
* if the current list has a TEID count of 0, there are no other PDRs.
|
||||||
|
*/
|
||||||
|
if (ogs_pfcp_object_count_by_teid(pdr->sess, pdr->f_teid.teid) == 0)
|
||||||
|
ogs_hash_set(self.object_teid_hash,
|
||||||
|
&pdr->hash.teid.key, pdr->hash.teid.len, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
if (pdr->dnn)
|
if (pdr->dnn)
|
||||||
ogs_free(pdr->dnn);
|
ogs_free(pdr->dnn);
|
||||||
|
|
|
@ -397,6 +397,7 @@ ogs_pfcp_pdr_t *ogs_pfcp_pdr_find_or_add(
|
||||||
void ogs_pfcp_object_teid_hash_set(
|
void ogs_pfcp_object_teid_hash_set(
|
||||||
ogs_pfcp_object_type_e type, ogs_pfcp_pdr_t *pdr);
|
ogs_pfcp_object_type_e type, ogs_pfcp_pdr_t *pdr);
|
||||||
ogs_pfcp_object_t *ogs_pfcp_object_find_by_teid(uint32_t teid);
|
ogs_pfcp_object_t *ogs_pfcp_object_find_by_teid(uint32_t teid);
|
||||||
|
int ogs_pfcp_object_count_by_teid(ogs_pfcp_sess_t *sess, uint32_t teid);
|
||||||
|
|
||||||
ogs_pfcp_pdr_t *ogs_pfcp_pdr_find_by_choose_id(
|
ogs_pfcp_pdr_t *ogs_pfcp_pdr_find_by_choose_id(
|
||||||
ogs_pfcp_sess_t *sess, uint8_t choose_id);
|
ogs_pfcp_sess_t *sess, uint8_t choose_id);
|
||||||
|
|
|
@ -418,6 +418,20 @@ static void test1_func(abts_case *tc, void *data)
|
||||||
/* Test Bearer Remove */
|
/* Test Bearer Remove */
|
||||||
test_bearer_remove(qos_flow);
|
test_bearer_remove(qos_flow);
|
||||||
|
|
||||||
|
/* Send GTP-U ICMP Packet */
|
||||||
|
qos_flow = test_qos_flow_find_by_qfi(sess, 1);
|
||||||
|
ogs_assert(qos_flow);
|
||||||
|
rv = test_gtpu_send_ping(gtpu, qos_flow, TEST_PING_IPV4);
|
||||||
|
ABTS_INT_EQUAL(tc, OGS_OK, rv);
|
||||||
|
|
||||||
|
/* Receive GTP-U ICMP Packet */
|
||||||
|
recvbuf = testgnb_gtpu_read(gtpu);
|
||||||
|
ABTS_PTR_NOTNULL(tc, recvbuf);
|
||||||
|
ogs_pkbuf_free(recvbuf);
|
||||||
|
|
||||||
|
/* Wait for PDU session resource modify complete */
|
||||||
|
ogs_msleep(100);
|
||||||
|
|
||||||
/* Send UEContextReleaseRequest */
|
/* Send UEContextReleaseRequest */
|
||||||
sendbuf = testngap_build_ue_context_release_request(test_ue,
|
sendbuf = testngap_build_ue_context_release_request(test_ue,
|
||||||
NGAP_Cause_PR_radioNetwork, NGAP_CauseRadioNetwork_user_inactivity,
|
NGAP_Cause_PR_radioNetwork, NGAP_CauseRadioNetwork_user_inactivity,
|
||||||
|
|
Loading…
Reference in New Issue