Refactor tunnel endpoint struct members in pdu_session_t

Motivation:
Clarify the role of GTP tunnel endpoint IDs in PDU session handling. Previously,
the struct members (gNB_teid_N3, UPF_teid_N3, etc.) were confusingly named and
duplicated with separate transport-layer address fields.
This refactoring replaces these with explicit n3_incoming and n3_outgoing members using
gtpu_tunnel_t. This aligns with GTP conventions: "incoming TEID" refers to the
TEID received from the remote peer (UPF on N3), while "outgoing TEID" is the
TEID sent by the local entity (NG-RAN on N3) to the remote peer.

Benefits:
* Improves readability and clarity of the code
* Reduces redundant struct members, i.e. remove UPF_teid_N3, UPF_addr_N3
* Aligns naming with 3GPP conventions for transport layer tunnels

Changes:
* Replace gtp_addr_N3, gNB_teid_N3, gtp_teid, upf_addr with n3_incoming and n3_outgoing
* Update all related code to use the new struct members
* Aligns naming with 3GPP conventions for transport layer tunnels
This commit is contained in:
Guido Casati
2025-06-18 10:52:15 +02:00
parent b86ae96c66
commit 4ec498c996
4 changed files with 19 additions and 27 deletions
+4 -9
View File
@@ -249,15 +249,10 @@ typedef struct pdusession_s {
pdusession_level_qos_parameter_t qos[QOSFLOW_MAX_VALUE];
/* The transport layer address for the IP packets */
pdu_session_type_t pdu_session_type;
transport_layer_addr_t upf_addr;
/* Outgoing (UL) NG-U Tunnel Endpoint Identifier (S-GW/UPF) */
uint32_t gtp_teid;
/* Incoming (DL) NG-U Tunnel Endpoint Identifier (S-GW/UPF) */
uint32_t gNB_teid_N3;
transport_layer_addr_t gNB_addr_N3;
/* Incoming (DL) NG-U Tunnel Endpoint Identifier (S-GW/UPF) */
uint32_t UPF_teid_N3;
transport_layer_addr_t UPF_addr_N3;
// NG-RAN endpoint of the NG-U (N3) transport bearer
gtpu_tunnel_t n3_outgoing;
// UPF endpoint of the NG-U (N3) transport bearer
gtpu_tunnel_t n3_incoming;
nssai_t nssai;
} pdusession_t;
@@ -65,8 +65,8 @@ bool read_gtp_sm(void * data)
int nb_pdu_session = ue_context_p->ue_context.nb_of_pdusessions;
if (nb_pdu_session > 0) {
int nb_pdu_idx = nb_pdu_session - 1;
gtp->msg.ngut[i].teidgnb = ue_context_p->ue_context.pduSession[nb_pdu_idx].param.gNB_teid_N3;
gtp->msg.ngut[i].teidupf = ue_context_p->ue_context.pduSession[nb_pdu_idx].param.UPF_teid_N3;
gtp->msg.ngut[i].teidgnb = ue_context_p->ue_context.pduSession[nb_pdu_idx].param.n3_outgoing.teid;
gtp->msg.ngut[i].teidupf = ue_context_p->ue_context.pduSession[nb_pdu_idx].param.n3_incoming.teid;
// TODO: one PDU session has multiple QoS Flow
int nb_qos_flow = ue_context_p->ue_context.pduSession[nb_pdu_idx].param.nb_qos;
if (nb_qos_flow > 0) {
+3 -3
View File
@@ -2449,9 +2449,9 @@ void rrc_gNB_process_e1_bearer_context_setup_resp(e1ap_bearer_setup_resp_t *resp
LOG_W(RRC, "E1: received setup for PDU session %ld, but has not been requested\n", e1_pdu->id);
continue;
}
rrc_pdu->param.gNB_teid_N3 = e1_pdu->tl_info.teId;
memcpy(&rrc_pdu->param.gNB_addr_N3.buffer, &e1_pdu->tl_info.tlAddress, sizeof(uint8_t) * 4);
rrc_pdu->param.gNB_addr_N3.length = sizeof(in_addr_t);
rrc_pdu->param.n3_outgoing.teid = e1_pdu->tl_info.teId;
memcpy(&rrc_pdu->param.n3_outgoing.addr.buffer, &e1_pdu->tl_info.tlAddress, sizeof(uint8_t) * 4);
rrc_pdu->param.n3_outgoing.addr.length = sizeof(in_addr_t);
// save the tunnel address for the DRBs
for (int i = 0; i < e1_pdu->numDRBSetup; i++) {
+10 -13
View File
@@ -283,12 +283,11 @@ static int decodePDUSessionResourceSetup(pdusession_t *session)
NGAP_GTPTunnel_t *gTPTunnel_p = pdusessionTransfer_ies->value.choice.UPTransportLayerInformation.choice.gTPTunnel;
/* Set the transport layer address */
memcpy(session->upf_addr.buffer, gTPTunnel_p->transportLayerAddress.buf, gTPTunnel_p->transportLayerAddress.size);
session->upf_addr.length = gTPTunnel_p->transportLayerAddress.size * 8 - gTPTunnel_p->transportLayerAddress.bits_unused;
memcpy(session->n3_incoming.addr.buffer, gTPTunnel_p->transportLayerAddress.buf, gTPTunnel_p->transportLayerAddress.size);
session->n3_incoming.addr.length = gTPTunnel_p->transportLayerAddress.size * 8 - gTPTunnel_p->transportLayerAddress.bits_unused;
/* GTP tunnel endpoint ID */
OCTET_STRING_TO_INT32(&gTPTunnel_p->gTP_TEID, session->gtp_teid);
OCTET_STRING_TO_INT32(&gTPTunnel_p->gTP_TEID, session->n3_incoming.teid);
}
break;
@@ -386,8 +385,8 @@ bool trigger_bearer_setup(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, int n, pdusession
: SECURITY_NOT_NEEDED;
sec->confidentialityProtectionIndication = rrc->security.do_drb_ciphering ? SECURITY_REQUIRED
: SECURITY_NOT_NEEDED;
pdu->UP_TL_information.teId = session->gtp_teid;
memcpy(&pdu->UP_TL_information.tlAddress, session->upf_addr.buffer, sizeof(in_addr_t));
pdu->UP_TL_information.teId = session->n3_incoming.teid;
memcpy(&pdu->UP_TL_information.tlAddress, session->n3_incoming.addr.buffer, sizeof(in_addr_t));
/* we assume for the moment one DRB per PDU session. Activate the bearer,
* and configure in RRC. */
@@ -582,9 +581,9 @@ void rrc_gNB_send_NGAP_INITIAL_CONTEXT_SETUP_RESP(gNB_RRC_INST *rrc, gNB_RRC_UE_
if (session->status == PDU_SESSION_STATUS_DONE) {
pdu_sessions_done++;
resp->pdusessions[pdusession].pdusession_id = session->param.pdusession_id;
resp->pdusessions[pdusession].gtp_teid = session->param.gNB_teid_N3;
resp->pdusessions[pdusession].gtp_teid = session->param.n3_outgoing.teid;
memcpy(resp->pdusessions[pdusession].gNB_addr.buffer,
session->param.gNB_addr_N3.buffer,
session->param.n3_outgoing.addr.buffer,
sizeof(resp->pdusessions[pdusession].gNB_addr.buffer));
resp->pdusessions[pdusession].gNB_addr.length = 4; // Fixme: IPv4 hard coded here
resp->pdusessions[pdusession].nb_of_qos_flow = session->param.nb_qos;
@@ -777,10 +776,10 @@ void rrc_gNB_send_NGAP_PDUSESSION_SETUP_RESP(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE
pdusession_setup_t *tmp = &resp->pdusessions[pdu_sessions_done];
tmp->pdusession_id = session->param.pdusession_id;
tmp->nb_of_qos_flow = session->param.nb_qos;
tmp->gtp_teid = session->param.gNB_teid_N3;
tmp->gtp_teid = session->param.n3_outgoing.teid;
tmp->pdu_session_type = session->param.pdu_session_type;
tmp->gNB_addr.length = session->param.gNB_addr_N3.length;
memcpy(tmp->gNB_addr.buffer, session->param.gNB_addr_N3.buffer, tmp->gNB_addr.length);
tmp->gNB_addr.length = session->param.n3_outgoing.addr.length;
memcpy(tmp->gNB_addr.buffer, session->param.n3_outgoing.addr.buffer, tmp->gNB_addr.length);
for (int qos_flow_index = 0; qos_flow_index < tmp->nb_of_qos_flow; qos_flow_index++) {
tmp->associated_qos_flows[qos_flow_index].qfi = session->param.qos[qos_flow_index].qfi;
tmp->associated_qos_flows[qos_flow_index].qos_flow_mapping_ind = QOSFLOW_MAPPING_INDICATION_DL;
@@ -1091,8 +1090,6 @@ int rrc_gNB_process_NGAP_PDUSESSION_MODIFY_REQ(MessageDef *msg_p, instance_t ins
}
// Save new pdu session parameters, qos, upf addr, teid
decodePDUSessionResourceModify(&sess->param, UE->pduSession[i].param.pdusessionTransfer);
sess->param.UPF_addr_N3 = sessMod->upf_addr;
sess->param.UPF_teid_N3 = sessMod->gtp_teid;
}
}