From c003096176022f9a1bb32fc60551ff7267a2fb37 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 12 Jan 2026 17:36:41 +0100 Subject: [PATCH 1/6] Always send release request at RRC It might happen that the RRC does not know the AMF UE NGAP ID, yet. Even in that case, we should forward the release request to the NGAP module, which can either forward a message to the AMF, or reply back to release the UE. Reported-By: Jegor Zelenjak --- openair2/RRC/NR/rrc_gNB.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index 3b8476f9a4..2037e11085 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -2440,10 +2440,8 @@ static void rrc_CU_process_ue_context_release_request(MessageDef *msg_p, sctp_as gNB_RRC_INST *rrc = RC.nrrrc[instance]; rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(rrc, req->gNB_CU_ue_id); int srbid = 1; - // valid AMF UE NGAP ID range is 0..2^40-1 - if (!ue_context_p || ue_context_p->ue_context.amf_ue_ngap_id >= (1LL << 40)) { - const char *reason = !ue_context_p ? "could not find UE context" : "no AMF"; - LOG_W(RRC, "%s for CU UE ID %u: auto-generate release command\n", reason, req->gNB_CU_ue_id); + if (!ue_context_p) { + LOG_W(RRC, "could not find UE context for CU UE ID %u: auto-generate release command\n", req->gNB_CU_ue_id); uint8_t buffer[NR_RRC_BUF_SIZE] = {0}; int size = do_NR_RRCRelease(buffer, NR_RRC_BUF_SIZE, rrc_gNB_get_next_transaction_identifier(0)); RETURN_IF_INVALID_ASSOC_ID(assoc_id); From f1db9cb1580aaab9406bb8f82b3d880ccb7175c6 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 12 Jan 2026 17:47:55 +0100 Subject: [PATCH 2/6] Forward AMF UE NGAP ID to RRC on DL NAS Message In the Initial Context Setup message, the NGAP forwards the AMF UE ID, but not in the DL NAS Message, although 38.413 says, in $8.3.1.2 either > The NG-RAN node shall use the AMF UE NGAP ID IE and RAN UE NGAP ID IE > received in the INITIAL CONTEXT SETUP REQUEST message as identification > of the logical connection or in $8.6.2.2 > The NG-RAN node shall use the AMF UE NGAP ID IE and RAN UE NGAP ID IE > received in the DOWNLINK NAS TRANSPORT message as identification of the > logical connection So forward in both cases for harmonization. --- openair2/COMMON/ngap_messages_types.h | 2 ++ openair2/RRC/NR/rrc_gNB_NGAP.c | 1 + openair3/NGAP/ngap_gNB_itti_messaging.c | 3 ++- openair3/NGAP/ngap_gNB_itti_messaging.h | 6 +++++- openair3/NGAP/ngap_gNB_nas_procedures.c | 6 +++++- 5 files changed, 15 insertions(+), 3 deletions(-) diff --git a/openair2/COMMON/ngap_messages_types.h b/openair2/COMMON/ngap_messages_types.h index 3bfd2e20a2..0aad7b8598 100644 --- a/openair2/COMMON/ngap_messages_types.h +++ b/openair2/COMMON/ngap_messages_types.h @@ -737,6 +737,8 @@ typedef struct ngap_ue_ctxt_modification_resp_s { typedef struct ngap_downlink_nas_s { /* UE id for initial connection to NGAP */ uint32_t gNB_ue_ngap_id; + /* UE id at AMF */ + uint64_t amf_ue_ngap_id; /* NAS pdu */ byte_array_t nas_pdu; } ngap_downlink_nas_t; diff --git a/openair2/RRC/NR/rrc_gNB_NGAP.c b/openair2/RRC/NR/rrc_gNB_NGAP.c index 65991f714d..19bab47b67 100644 --- a/openair2/RRC/NR/rrc_gNB_NGAP.c +++ b/openair2/RRC/NR/rrc_gNB_NGAP.c @@ -717,6 +717,7 @@ int rrc_gNB_process_NGAP_DOWNLINK_NAS(MessageDef *msg_p, instance_t instance, mu } gNB_RRC_UE_t *UE = &ue_context_p->ue_context; + UE->amf_ue_ngap_id = req->amf_ue_ngap_id; UE->nas_pdu = req->nas_pdu; rrc_forward_ue_nas_message(rrc, UE); return 0; diff --git a/openair3/NGAP/ngap_gNB_itti_messaging.c b/openair3/NGAP/ngap_gNB_itti_messaging.c index b640f2e556..1e03192599 100644 --- a/openair3/NGAP/ngap_gNB_itti_messaging.c +++ b/openair3/NGAP/ngap_gNB_itti_messaging.c @@ -54,7 +54,7 @@ void ngap_gNB_itti_send_sctp_data_req(instance_t instance, itti_send_msg_to_task(TASK_SCTP, instance, message_p); } -void ngap_gNB_itti_send_nas_downlink_ind(instance_t instance, uint32_t gNB_ue_ngap_id, uint8_t *nas_pdu, uint32_t nas_pdu_length) +void ngap_gNB_itti_send_nas_downlink_ind(instance_t instance, uint32_t gNB_ue_ngap_id, uint64_t amf_ue_ngap_id, uint8_t *nas_pdu, uint32_t nas_pdu_length) { MessageDef *message_p; ngap_downlink_nas_t *ngap_downlink_nas; @@ -64,6 +64,7 @@ void ngap_gNB_itti_send_nas_downlink_ind(instance_t instance, uint32_t gNB_ue_ng ngap_downlink_nas = &message_p->ittiMsg.ngap_downlink_nas; ngap_downlink_nas->gNB_ue_ngap_id = gNB_ue_ngap_id; + ngap_downlink_nas->amf_ue_ngap_id = amf_ue_ngap_id; ngap_downlink_nas->nas_pdu = create_byte_array(nas_pdu_length, nas_pdu); itti_send_msg_to_task(TASK_RRC_GNB, instance, message_p); diff --git a/openair3/NGAP/ngap_gNB_itti_messaging.h b/openair3/NGAP/ngap_gNB_itti_messaging.h index 67054761e3..09ae4d6480 100644 --- a/openair3/NGAP/ngap_gNB_itti_messaging.h +++ b/openair3/NGAP/ngap_gNB_itti_messaging.h @@ -40,7 +40,11 @@ void ngap_gNB_itti_send_sctp_data_req(instance_t instance, uint32_t buffer_length, uint16_t stream); -void ngap_gNB_itti_send_nas_downlink_ind(instance_t instance, uint32_t gNB_ue_ngap_id, uint8_t *nas_pdu, uint32_t nas_pdu_length); +void ngap_gNB_itti_send_nas_downlink_ind(instance_t instance, + uint32_t gNB_ue_ngap_id, + uint64_t amf_ue_ngap_id, + uint8_t *nas_pdu, + uint32_t nas_pdu_length); void ngap_gNB_itti_send_sctp_close_association(instance_t instance, sctp_assoc_t assoc_id); diff --git a/openair3/NGAP/ngap_gNB_nas_procedures.c b/openair3/NGAP/ngap_gNB_nas_procedures.c index 2218155c61..7bf7753668 100644 --- a/openair3/NGAP/ngap_gNB_nas_procedures.c +++ b/openair3/NGAP/ngap_gNB_nas_procedures.c @@ -361,7 +361,11 @@ int ngap_gNB_handle_nas_downlink(sctp_assoc_t assoc_id, uint32_t stream, NGAP_NG NGAP_FIND_PROTOCOLIE_BY_ID(NGAP_DownlinkNASTransport_IEs_t, ie, container, NGAP_ProtocolIE_ID_id_NAS_PDU, true); /* Forward the NAS PDU to NR-RRC */ - ngap_gNB_itti_send_nas_downlink_ind(ngap_gNB_instance->instance, ue_desc_p->gNB_ue_ngap_id, ie->value.choice.NAS_PDU.buf, ie->value.choice.NAS_PDU.size); + ngap_gNB_itti_send_nas_downlink_ind(ngap_gNB_instance->instance, + ue_desc_p->gNB_ue_ngap_id, + ue_desc_p->amf_ue_ngap_id, + ie->value.choice.NAS_PDU.buf, + ie->value.choice.NAS_PDU.size); return 0; } From 89b3eb01324304451158be087e70afa68943a7d0 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 12 Jan 2026 18:29:56 +0100 Subject: [PATCH 3/6] NR MAC: warn on release for unknown UE --- openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c | 1 + 1 file changed, 1 insertion(+) diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c index 20b30cb074..c271824e75 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c @@ -888,6 +888,7 @@ void ue_context_release_command(const f1ap_ue_context_rel_cmd_t *cmd) UE = UE ? UE : find_ra_UE(&mac->UE_info, cmd->gNB_DU_ue_id); if (UE == NULL) { NR_SCHED_UNLOCK(&mac->sched_lock); + LOG_W(NR_MAC, "UE Context Release Command for unknown RNTI %04x/CU UE ID %d\n", cmd->gNB_DU_ue_id, cmd->gNB_CU_ue_id); f1ap_ue_context_rel_cplt_t complete = { .gNB_CU_ue_id = cmd->gNB_CU_ue_id, .gNB_DU_ue_id = cmd->gNB_DU_ue_id, From b60a37ebb8e186ef76b40857e030fa576e63de8f Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 12 Jan 2026 18:38:21 +0100 Subject: [PATCH 4/6] Log NGAP Initial Context Setup For debugging, it might notably be useful to see the AMF UE NGAP ID. Log it in the single Initial Context Setup message. --- openair3/NGAP/ngap_gNB_handlers.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/openair3/NGAP/ngap_gNB_handlers.c b/openair3/NGAP/ngap_gNB_handlers.c index a58c98508b..7a606468e5 100644 --- a/openair3/NGAP/ngap_gNB_handlers.c +++ b/openair3/NGAP/ngap_gNB_handlers.c @@ -849,6 +849,11 @@ static int ngap_gNB_handle_initial_context_request(sctp_assoc_t assoc_id, uint32 itti_send_msg_to_task(TASK_RRC_GNB, ue_desc_p->gNB_instance->instance, message_p); + NGAP_INFO("Initial Context Setup UE RAN ID %d UE AMF ID %ld: %d PDU session(s)\n", + msg->gNB_ue_ngap_id, + msg->amf_ue_ngap_id, + msg->nb_of_pdusessions); + return 0; } From d7a940baba02217067a64bdf0f0c7291b9bc36cb Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 12 Jan 2026 18:42:57 +0100 Subject: [PATCH 5/6] Log TEID in host order All over the GTP module, we use ntohl()/htonl() to convert between local and network order. It seems to have been forgotten here. --- openair3/ocp-gtpu/gtp_itf.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openair3/ocp-gtpu/gtp_itf.cpp b/openair3/ocp-gtpu/gtp_itf.cpp index ed15d48f80..6650439e81 100644 --- a/openair3/ocp-gtpu/gtp_itf.cpp +++ b/openair3/ocp-gtpu/gtp_itf.cpp @@ -1036,9 +1036,9 @@ static int Gtpv1uHandleError(int h, uint8_t *msgBuf, uint32_t msgBufLen, const s " TV id for GTP addr %u (should be 133)\n" " len for addr of UPF %u (should be IPv4 or IPv6 len)" " (TS 29.281 Sec 7.3.1 Error Handling not implemented)\n", - msg->h.teid, + ntohl(msg->h.teid), msg->teid_data_i, - msg->teid, + ntohl(msg->teid), msg->addr_data_i, msg->addr_len); int rc = GTPNOK; From 5fa624b2067c93be297e564b3f1cf5320c398047 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 12 Jan 2026 20:26:59 +0100 Subject: [PATCH 6/6] Move NGSetupResponse message to avoid confusion On NGSetupFailure, before moving, we might have [NGAP] Received NG setup failure for AMF... please check your parameters [NGAP] Received NGSetupResponse from AMF --- openair3/NGAP/ngap_gNB_handlers.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair3/NGAP/ngap_gNB_handlers.c b/openair3/NGAP/ngap_gNB_handlers.c index 7a606468e5..292ab1635d 100644 --- a/openair3/NGAP/ngap_gNB_handlers.c +++ b/openair3/NGAP/ngap_gNB_handlers.c @@ -84,7 +84,6 @@ void ngap_handle_ng_setup_message(ngap_gNB_amf_data_t *amf_desc_p, int sctp_shut } } } else { - LOG_A(NGAP, "Received NGSetupResponse from AMF\n"); /* Check that at least one setup message is pending */ DevCheck(amf_desc_p->ngap_gNB_instance->ngap_amf_pending_nb > 0, amf_desc_p->ngap_gNB_instance->instance, amf_desc_p->ngap_gNB_instance->ngap_amf_pending_nb, 0); @@ -314,6 +313,7 @@ static int ngap_gNB_handle_ng_setup_response(sctp_assoc_t assoc_id, uint32_t str amf_desc_p->state = NGAP_GNB_STATE_CONNECTED; amf_desc_p->ngap_gNB_instance->ngap_amf_associated_nb ++; ngap_handle_ng_setup_message(amf_desc_p, 0); + LOG_A(NGAP, "Received NGSetupResponse from AMF\n"); return 0; }