mirror of
https://github.com/open5gs/open5gs.git
synced 2025-10-23 07:41:57 +00:00
[HR] V-UPF: preserve PSC on N2 indirect (Access->Access) without QER (#2194)
Home-Routed roaming: during Xn/N2 handover the source gNB may forward remaining DL data to the core using UL PDU Session Information (PSC). On the V-UPF the PSC was lost on the indirect path because OHR+OHC removed the incoming GTP-U header (and its extensions) and we did not recreate PSC when no QER/QFI was provisioned by the V-SMF. This change makes the V-UPF rebuild a DL PSC for the target gNB even when QER is absent, limited to the Access->Access indirect path (source gNB -> V-UPF -> target gNB). Why this is needed in HR: - In HR deployments the V-SMF typically does not provision QER/QFI for the temporary indirect path. Without recreating PSC from recvhdr, the extension header disappears after OHR+OHC and the target gNB cannot see the QFI during handover buffering/forwarding.
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
---
|
||||
title: "v2.7.6 - Bug fixed"
|
||||
date: 2025-03-30 22:05:00 +0900
|
||||
date: 2025-07-19 22:05:00 +0900
|
||||
categories:
|
||||
- Release
|
||||
tags:
|
||||
|
@@ -303,6 +303,39 @@ bool ogs_pfcp_up_handle_pdr(
|
||||
sendhdr.pdu_type =
|
||||
OGS_GTP2_EXTENSION_HEADER_PDU_TYPE_DL_PDU_SESSION_INFORMATION;
|
||||
sendhdr.qos_flow_identifier = pdr->qer->qfi;
|
||||
} else if (pdr->src_if == OGS_PFCP_INTERFACE_ACCESS &&
|
||||
far->dst_if == OGS_PFCP_INTERFACE_ACCESS &&
|
||||
recvhdr->qos_flow_identifier) {
|
||||
/*
|
||||
* HR Indirect Forwarding (source gNB -> V-UPF -> target gNB)
|
||||
*
|
||||
* Context:
|
||||
* - Home-Routed roaming: the V-UPF is controlled by the V-SMF, which
|
||||
* typically does not provision QER/QFI for the indirect path.
|
||||
* - During Xn/N2 handover the source gNB may forward remaining DL data
|
||||
* to the core using UL PDU Session Information (PSC PDU type = UL).
|
||||
*
|
||||
* Goal:
|
||||
* - Preserve the PDU Session Container across the V-UPF hop and deliver
|
||||
* it to the target gNB with PDU type = DL while keeping the same QFI.
|
||||
*
|
||||
* What we do here:
|
||||
* - If this PDR has no QER/QFI and the path is Access->Access, derive
|
||||
* PSC fields from the received header (recvhdr).
|
||||
* - Force sendhdr.pdu_type = DL PDU Session Information.
|
||||
* - Copy recvhdr->qos_flow_identifier into sendhdr.qos_flow_identifier.
|
||||
* - The encapsulation routine will build a fresh GTP-U header and
|
||||
* generate the PSC extension from sendhdr fields. This converts UL
|
||||
* PSC to DL PSC and preserves the QFI for the target gNB.
|
||||
*
|
||||
* Why this is needed in HR:
|
||||
* - With OHR+OHC, the incoming GTP-U (extensions included) is removed
|
||||
* and a new one is created. Without recreating PSC from sendhdr.*, the
|
||||
* extension header would be lost when QER is absent on the V-UPF.
|
||||
*/
|
||||
sendhdr.pdu_type =
|
||||
OGS_GTP2_EXTENSION_HEADER_PDU_TYPE_DL_PDU_SESSION_INFORMATION;
|
||||
sendhdr.qos_flow_identifier = recvhdr->qos_flow_identifier;
|
||||
}
|
||||
|
||||
if (recvhdr) {
|
||||
@@ -962,6 +995,14 @@ ogs_pfcp_pdr_t *ogs_pfcp_handle_update_pdr(ogs_pfcp_sess_t *sess,
|
||||
}
|
||||
}
|
||||
|
||||
if (message->outer_header_removal.presence) {
|
||||
pdr->outer_header_removal_len =
|
||||
ogs_min(message->outer_header_removal.len,
|
||||
sizeof(pdr->outer_header_removal));
|
||||
memcpy(&pdr->outer_header_removal, message->outer_header_removal.data,
|
||||
pdr->outer_header_removal_len);
|
||||
}
|
||||
|
||||
return pdr;
|
||||
}
|
||||
|
||||
|
@@ -198,6 +198,14 @@ void sgwu_sxa_handle_session_modification_request(
|
||||
if (cause_value != OGS_PFCP_CAUSE_REQUEST_ACCEPTED)
|
||||
goto cleanup;
|
||||
|
||||
for (i = 0; i < OGS_MAX_NUM_OF_PDR; i++) {
|
||||
if (ogs_pfcp_handle_update_pdr(&sess->pfcp, &req->update_pdr[i],
|
||||
&cause_value, &offending_ie_value) == NULL)
|
||||
break;
|
||||
}
|
||||
if (cause_value != OGS_PFCP_CAUSE_REQUEST_ACCEPTED)
|
||||
goto cleanup;
|
||||
|
||||
for (i = 0; i < OGS_MAX_NUM_OF_PDR; i++) {
|
||||
if (ogs_pfcp_handle_remove_pdr(&sess->pfcp, &req->remove_pdr[i],
|
||||
&cause_value, &offending_ie_value) == false)
|
||||
|
Reference in New Issue
Block a user