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]; pdusession_level_qos_parameter_t qos[QOSFLOW_MAX_VALUE];
/* The transport layer address for the IP packets */ /* The transport layer address for the IP packets */
pdu_session_type_t pdu_session_type; pdu_session_type_t pdu_session_type;
transport_layer_addr_t upf_addr; // NG-RAN endpoint of the NG-U (N3) transport bearer
/* Outgoing (UL) NG-U Tunnel Endpoint Identifier (S-GW/UPF) */ gtpu_tunnel_t n3_outgoing;
uint32_t gtp_teid; // UPF endpoint of the NG-U (N3) transport bearer
/* Incoming (DL) NG-U Tunnel Endpoint Identifier (S-GW/UPF) */ gtpu_tunnel_t n3_incoming;
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;
nssai_t nssai; nssai_t nssai;
} pdusession_t; } pdusession_t;
@@ -65,8 +65,8 @@ bool read_gtp_sm(void * data)
int nb_pdu_session = ue_context_p->ue_context.nb_of_pdusessions; int nb_pdu_session = ue_context_p->ue_context.nb_of_pdusessions;
if (nb_pdu_session > 0) { if (nb_pdu_session > 0) {
int nb_pdu_idx = nb_pdu_session - 1; 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].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.UPF_teid_N3; 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 // TODO: one PDU session has multiple QoS Flow
int nb_qos_flow = ue_context_p->ue_context.pduSession[nb_pdu_idx].param.nb_qos; int nb_qos_flow = ue_context_p->ue_context.pduSession[nb_pdu_idx].param.nb_qos;
if (nb_qos_flow > 0) { 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); LOG_W(RRC, "E1: received setup for PDU session %ld, but has not been requested\n", e1_pdu->id);
continue; continue;
} }
rrc_pdu->param.gNB_teid_N3 = e1_pdu->tl_info.teId; rrc_pdu->param.n3_outgoing.teid = e1_pdu->tl_info.teId;
memcpy(&rrc_pdu->param.gNB_addr_N3.buffer, &e1_pdu->tl_info.tlAddress, sizeof(uint8_t) * 4); memcpy(&rrc_pdu->param.n3_outgoing.addr.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.addr.length = sizeof(in_addr_t);
// save the tunnel address for the DRBs // save the tunnel address for the DRBs
for (int i = 0; i < e1_pdu->numDRBSetup; i++) { 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; NGAP_GTPTunnel_t *gTPTunnel_p = pdusessionTransfer_ies->value.choice.UPTransportLayerInformation.choice.gTPTunnel;
/* Set the transport layer address */ /* Set the transport layer address */
memcpy(session->upf_addr.buffer, gTPTunnel_p->transportLayerAddress.buf, gTPTunnel_p->transportLayerAddress.size); 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;
session->upf_addr.length = gTPTunnel_p->transportLayerAddress.size * 8 - gTPTunnel_p->transportLayerAddress.bits_unused;
/* GTP tunnel endpoint ID */ /* 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; break;
@@ -386,8 +385,8 @@ bool trigger_bearer_setup(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, int n, pdusession
: SECURITY_NOT_NEEDED; : SECURITY_NOT_NEEDED;
sec->confidentialityProtectionIndication = rrc->security.do_drb_ciphering ? SECURITY_REQUIRED sec->confidentialityProtectionIndication = rrc->security.do_drb_ciphering ? SECURITY_REQUIRED
: SECURITY_NOT_NEEDED; : SECURITY_NOT_NEEDED;
pdu->UP_TL_information.teId = session->gtp_teid; pdu->UP_TL_information.teId = session->n3_incoming.teid;
memcpy(&pdu->UP_TL_information.tlAddress, session->upf_addr.buffer, sizeof(in_addr_t)); 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, /* we assume for the moment one DRB per PDU session. Activate the bearer,
* and configure in RRC. */ * 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) { if (session->status == PDU_SESSION_STATUS_DONE) {
pdu_sessions_done++; pdu_sessions_done++;
resp->pdusessions[pdusession].pdusession_id = session->param.pdusession_id; 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, 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)); sizeof(resp->pdusessions[pdusession].gNB_addr.buffer));
resp->pdusessions[pdusession].gNB_addr.length = 4; // Fixme: IPv4 hard coded here resp->pdusessions[pdusession].gNB_addr.length = 4; // Fixme: IPv4 hard coded here
resp->pdusessions[pdusession].nb_of_qos_flow = session->param.nb_qos; 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]; pdusession_setup_t *tmp = &resp->pdusessions[pdu_sessions_done];
tmp->pdusession_id = session->param.pdusession_id; tmp->pdusession_id = session->param.pdusession_id;
tmp->nb_of_qos_flow = session->param.nb_qos; 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->pdu_session_type = session->param.pdu_session_type;
tmp->gNB_addr.length = session->param.gNB_addr_N3.length; tmp->gNB_addr.length = session->param.n3_outgoing.addr.length;
memcpy(tmp->gNB_addr.buffer, session->param.gNB_addr_N3.buffer, tmp->gNB_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++) { 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].qfi = session->param.qos[qos_flow_index].qfi;
tmp->associated_qos_flows[qos_flow_index].qos_flow_mapping_ind = QOSFLOW_MAPPING_INDICATION_DL; 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 // Save new pdu session parameters, qos, upf addr, teid
decodePDUSessionResourceModify(&sess->param, UE->pduSession[i].param.pdusessionTransfer); decodePDUSessionResourceModify(&sess->param, UE->pduSession[i].param.pdusessionTransfer);
sess->param.UPF_addr_N3 = sessMod->upf_addr;
sess->param.UPF_teid_N3 = sessMod->gtp_teid;
} }
} }