* [UPF/SGW-U] Optimizing data-path (#3306)
In ogs_pfcp_up_handle_pdr, there is a copy operation performed on recvbuf,
which can reduce the sending performance in the data path. Personally,
We believe that this copy operation can be eliminated.
Of course, if it is canceled, the recvbuf does not need to be released again
at the location where ogs_pfcp_up_handle_pdr is called. After testing,
it has indeed shown an improvement in performance of approximately 15-18%.
/*
sendbuf = ogs_pkbuf_copy(recvbuf);
if (!sendbuf) {
ogs_error("ogs_pkbuf_copy() failed");
return false;
}*/
sendbuf = recvbuf;</div>
* update it
UE attached to 4G cell, terminates 4G connection,
then attempts 5G cell attach with TAC update - fails connection
Setup a UE on a 4G cell. Also have a 5G cell available to the UE.
Next, disable the 4G cell. The 4G connection terminates normally.
The UE scans the network and finds the 5G cell.
At this time the UE sends a registration to the 5G cell.
Open5gs sent back a reject with reason "Semantically incorrect message".
Then the UE did not try to attach again and lost the call forever.
Compare this scenario with a different core that we tested this scenario on.
With a different core (other than open5gs) the core sent back a reject
also but with a reason "UE can't be derived by network".
Then the UE tried attach again and the 5G call was successful.
Although this was successful for the other core it could be suggested
that not rejecting at all is good behavior.
There is a workaround which is that the Samsung UE could be put into
airplane mode and taken out of airplane mode and at that point
the UE is able to attach to the 5G cell. But this is a lot of manual effort
on the user of the UE which could be avoided with a simple open5gs change.
Note: Issue only happens when registration request + tracking area update
occurs on 5G cell attach following LTE cell being disabled.
If only registration occurs without a tracking area update
(such as the first time system is up) then it is ok with no rejection.
To solve this issue, added Additional-GUTI to the ClearText Group.
On 4G only... when UE sent an inactivity UEContextReleaseRequest,
Open5GS sent back UEContextReleaseCommand **with cause=normal-release.
This, in turn, does not allow the Samsung UE to return to the low power state
in our testing of the scenario.
Comparing the behavior of open5gs to other cores that we have tested
the other cores are sending a ** cause=“Radio Network Layer Cause”:
User inactivity ** when the UE sends inactivity. And this is what allows
other cores to transition the UE to the low power state whereas
with open5gs the UE is not entering the low power state.
We've fixed to allow open5gs to come to the same level of compliance
in this area as to the other cores.
Update Bearer Request
Modify Bearer Context Request
Modify Bearer Context Accept
Update Bearer Response
In the process above, we incorrectly used the Timer
that the MME uses to wait for the eNB.
We used xact's holding timer, which continues to hold the transaction
for further exception handling even after sending the Update Bearer Response.
This timer should end exactly when the Update Bearer Response is sent
by the MME to the SGW-C. Therefore, we have added a new peer timer
in xact for this purpose.
We fixed an issue in #3302 where MME does not send Downlink Data Notification
Acknowledge to SGW-C in Error Indication situation.
However, it did not work properly when this occurred in conjunction
with releasing the bearer as shown below.
>>>Seesion-Termination in Diameter
>>>SMF sends E-RABReleaseCommand and
Deactivate EPS bearer request context
1. SGW-U received Error Indication
2. SGW-U sends PFCP Report Request to SGW-C
3. SGW-C sends PFCP Report Response to SGW-U
4. SGW-C sends Downlink Data Notification to MME (MME Connected with eNB)
>>> eNB sends E-RABReleaseCommand
>>> UE sends Deactivate EPS bearer context accept
5. MME sends UEContextReleaseCommand to the eNB
6. eNB sends UEContextReleaseComplete to the MME
7. MME sends S1-Paging to the eNB
8. eNB sends Service-Request to the MME
9. MME sends InitialContextSetupRequest to the eNB
10. eNB sends InitialContextSetupResponse to the MME
No bearer context, so cannot send Downlink Data Notification Acknowledge
So, we've fixed it as below.
>>>Seesion-Termination in Diameter
>>>SMF sends E-RABReleaseCommand and
Deactivate EPS bearer request context
1. SGW-U received Error Indication
2. SGW-U sends PFCP Report Request to SGW-C
3. SGW-C sends PFCP Report Response to SGW-U
4. SGW-C sends Downlink Data Notification to MME (MME Connected with eNB)
>>>>>>>> Since eNB Connected, we send Downlink Data Notification Acknowledge here.
>>> eNB sends E-RABReleaseCommand
>>> UE sends Deactivate EPS bearer context accept
5. MME sends UEContextReleaseCommand to the eNB
6. eNB sends UEContextReleaseComplete to the MME
7. MME sends S1-Paging to the eNB
8. eNB sends Service-Request to the MME
9. MME sends InitialContextSetupRequest to the eNB
10. eNB sends InitialContextSetupResponse to the MME
We've encountered an issue where Downlink Data Notification Acks are not sent
in the following situations.
1. SGW-U received Error Indication
2. SGW-U sends PFCP Report Request to SGW-C
3. SGW-C sends PFCP Report Response to SGW-U
4. SGW-C sends Downlink Data Notification to MME
(MME Connected with eNB)
5. MME sends UEContextReleaseCommand to the eNB
6. eNB sends UEContextReleaseComplete to the MME
7. MME sends S1-Paging to the eNB
8. eNB sends Service-Request to the MME
9. MME sends InitialContextSetupRequest to the eNB
10. eNB sends InitialContextSetupResponse to the MME
Here, MME needs to send Downlink Data Notification Acknowledge.
So, we've fixed it
I created ogs_sbi_xact_find_by_id() with a hash
to replace ogs_sbi_xact_cycle().
Modified to find the xact via xact->id
when making an HTTP request with the SBI client function
and waiting for the HTTP response.
Pool library has the following issues with XXX_cycle,
including mme_enb_cycle()/amf_ue_cycle()
```
INIT POOL(SIZE:5)
Alloc Node1
Alloc Node2
Alloc Node3
Alloc Node4
Alloc Node5
Free Node4
Free Node3
PoolCycle(Node4) is NULL (Freed...OK!)
PoolCycle(Node3) is NULL (Freed...OK!)
Alloc Node6
Alloc Node7
PoolCycle(Node4) is Not NULL (Freed...but NOK!)
PoolCycle(Node3) is Not NULL (Freed...but NOK!)
PoolCycle(Node6) is Not NULL (Allocated...OK!)
PoolCycle(Node7) is Not NULL (Allocated...OK!)
```
If we use ogs_poll_alloc() to create and allocate a node,
the correct behavior of calling ogs_pool_free() on this node
and then later calling ogs_pool_cycle() on this node must always return NULL.
However, the behavior of calling ogs_pool_cycle() on this node
in the future may return a “valid” pointer.
To solve the problem, we added hash id to the pool memory and
ogs_pool_find_by_id() function is added.
3GPP TS 23.003 Ch. 2.8.2.2.2 (Mapping in the UE) states "The P-TMSI
signature is sent intact to the MME."
So simply use the PTMSI signature from the TAU and pass it throught to the
SGSN Context Request.
The algorithms described in 3GPP TS 23.003 Ch. 2.8.2.1.2 an 2.8.2.2.2
are not directly the inverse of each other.
To send a SGSN Context Request (in 2G -> 4G mobility) the algorithm in
2.8.2.2.2 has to be done in reverse (like mentioned in 2.8.2.2.3 -
Mapping in the new MME).
When parsing an SGSN Context Request (for 4G -> 2G mobility) the reverse
of 2.8.2.1.2 (as described in 2.8.2.1.3) has to be used.
PTMSI signature handling is added in a separate commit.
When setting hashes, we typically delete and set hashes that are set to OLD.
A hash set to OLD should be deleted by setting it to NULL,
but here we're deleting it with a value of NEW.
Therefore, we modified it to delete the OLD gNB/eNB ID
instead of NEW by setting a NULL value to Hash as Key.
Consider the following situation.
```
1. SMF->SGW-C->MME: First Update Bearer Request
2. MME->UE: First Modify EPS bearer context request
3. SMF->SGW-C->MME: Second Update Bearer Request
4. MME->UE: Second Modify EPS bearer context request
5. UE->MME: First Modify EPS bearer context accept
6. MME->SGW-C->SMF: First Update Bearer Response
7. UE->MME: Second Modify EPS bearer context accept
8. MME->SGW-C->SMF: Second Update Bearer Response
```
Until now, only one GTP transaction was managed for one bearer.
Therefore, if the UE does not send an EPS Modify bearer accept to the MME,
and the SMF/SGW-C sends an Update Bearer Request to the MME,
The NEW update bearer request overwrites the OLD that was previously managed.
So we modified it to manage them simultaneously.
However, we don't know if this is the right way to implement it.
So if the SMF/SGW-C sends 5 MMEs of Update Bearer Request and
the UE sends only 3 MMEs of Modify EPS bearer context accept,
we have no way to associate it.
Therefore, it's implemented so that we just process them sequentially and
2 of them are just timeout.
When the second AMF, which is the transfer, runs later than the SMF,
there is no client information.
Fixed to pre-create the Client when the Resource URI is transferred.
Fixed to not change the session information stored in the DB
when transferring context from GERAN to EUTRAN.
Note that the Tracking Area Update Procedure differs
from the Attach Procedure in 5.3.2 in the point
at which HSS and ULR/ULA are performed.
3GPP TS 23.401
Ch 5.3.3 Tracking Area Update procedures
<Attach Procedure>
1. Security-mode complete
2. Update Location Request/Answer
3. Create Session Request/Response
<Tracking Area Update Procedure>
1. Security-mode complete
2. Create Session Request/Response
3. Update Location Request/Answer
When TAU creates a Create Session Request message,
there is no session type information in the Subscriber DB
that is received from HSS in the Update Location.
Therefore, TAU does not reflect the Session Type
but creates PDN Type by reflecting the information
in the Request Type as it is.
HTTP Location header field does not contain the "5g-aka-confirmation"
substring. Which means that when we try to delete the authentication
from AUSF, it fails.
/nausf-auth/v1/ue-authentications/1
vs
/nausf-auth/v1/ue-authentications/1/5g-aka-confirmation
IP assigned from SMF: session->paa
Static IP read from the Subscriber DB: session->ue_ip
When passing the PDP context information to the SGSN, we actually wanna
provide it with the IP address currently in use.
Try to fix the following error
"MME_Tests.ttcn:955 : no SGSN Context Response from MME"
MME_Tests.ttcn:1572 MME_Tests control part
MME_Tests.ttcn:1457 TC_ue_cell_reselect_eutran_to_geran testcase
If the UE continuously attempts to Attach while changing PDN Type,
it will cause the wrong IP to be assigned.
(e.g PDU-Type : IPv4v6 -> IPv4 -> IPv4v6)
This is because we use two variables at the same time,
one to read and store the Static IP from the Subscriber DB and
one to store the IP assigned from SMF, called session->paa.
When the UE attaches with PDN-Type set to IPv4v6,
MME saves the allocated IP in session->paa.
However, MME thinks it has been assigned a static IP based on the information
in session->paa, so changing the PDN-Type may result in the wrong IP
being assigned.
To solve this problem, I separated the variable(session->paa) that stores
the allocated IP received from SMF and the variable(session->ue_ip) that stores
the Static IP read from the Subscriber DB.
Therefore, the information read from the Subscriber DB
(session->session_type and session->ue_ip) should not be modified.
When using ogs_buffer_to_bcd(), an overflow occurs if the input buffer length
is larger than the output bcd size, causing a crash.
We adjusted the size of the input buffer length using ogs_min as follows.
```
sgwc_ue->imsi_len = ogs_min(imsi_len, OGS_MAX_IMSI_LEN);
memcpy(sgwc_ue->imsi, imsi, sgwc_ue->imsi_len);
ogs_buffer_to_bcd(sgwc_ue->imsi, sgwc_ue->imsi_len, sgwc_ue->imsi_bcd);
```
When we run the test, for example,
./tests/registration/registration simple-init,
wee get an INFO message like the one below.
```
05/17 14:24:03.933: [sbi] INFO: NF EndPoint(addr) setup [127.0.0.200:7777] (../lib/sbi/context.c:474)
```
When we run the code in Open5GS, the log level initially defaults to INFO.
However, for test code, we change the log level to ERROR
by automatically inserting the -e error option into argv.
The reason for this is to prevent WARNING and INFO messages
from appearing when the test code is run.
However, the log level to ERROR is changed at the bottom of
the initialize routine, which caused the above message
to be printed during testing.
To prevent this from being printed, I modified the code
to change that log level to ERROR a little earlier.