Skip to content

Commit a6b6ee5

Browse files
authored
Guard stale UE release-complete during handover; harden RanUe attach (#704)
* Guard stale UE release-complete during handover; harden RanUe attach Signed-off-by: Arrobo, Gabriel <gabriel.arrobo@intel.com> * Address Copilot's comments Signed-off-by: Arrobo, Gabriel <gabriel.arrobo@intel.com> --------- Signed-off-by: Arrobo, Gabriel <gabriel.arrobo@intel.com>
1 parent 1553ac3 commit a6b6ee5

5 files changed

Lines changed: 374 additions & 24 deletions

File tree

context/amf_ue.go

Lines changed: 54 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// SPDX-FileCopyrightText: 2022-present Intel Corporation
1+
// Copyright (c) 2022-present Intel Corporation
22
// SPDX-FileCopyrightText: 2021 Open Networking Foundation <info@opennetworking.org>
33
// Copyright 2019 free5GC.org
44
//
@@ -468,6 +468,9 @@ func (ue *AmfUe) init() {
468468
}
469469

470470
func (ue *AmfUe) CmConnect(anType models.AccessType) bool {
471+
ue.Mutex.Lock()
472+
defer ue.Mutex.Unlock()
473+
471474
if _, ok := ue.RanUe[anType]; !ok {
472475
return false
473476
}
@@ -479,7 +482,14 @@ func (ue *AmfUe) CmIdle(anType models.AccessType) bool {
479482
}
480483

481484
func (ue *AmfUe) Remove() {
485+
ue.Mutex.Lock()
486+
ranUes := make([]*RanUe, 0, len(ue.RanUe))
482487
for _, ranUe := range ue.RanUe {
488+
ranUes = append(ranUes, ranUe)
489+
}
490+
ue.Mutex.Unlock()
491+
492+
for _, ranUe := range ranUes {
483493
if err := ranUe.Remove(); err != nil {
484494
logger.ContextLog.Errorf("Remove RanUe error: %v", err)
485495
}
@@ -502,23 +512,52 @@ func (ue *AmfUe) Remove() {
502512
}
503513

504514
func (ue *AmfUe) DetachRanUe(anType models.AccessType) {
515+
ue.Mutex.Lock()
516+
defer ue.Mutex.Unlock()
517+
505518
delete(ue.RanUe, anType)
506519
}
507520

521+
func (ue *AmfUe) GetRanUe(anType models.AccessType) *RanUe {
522+
ue.Mutex.Lock()
523+
defer ue.Mutex.Unlock()
524+
525+
return ue.RanUe[anType]
526+
}
527+
508528
func (ue *AmfUe) AttachRanUe(ranUe *RanUe) {
509529
/* detach any RanUe associated to it */
510-
oldRanUe := ue.RanUe[ranUe.Ran.AnType]
511-
ue.RanUe[ranUe.Ran.AnType] = ranUe
530+
anType := ranUe.Ran.AnType
531+
ue.Mutex.Lock()
532+
oldRanUe := ue.RanUe[anType]
533+
if oldRanUe == ranUe {
534+
ranUe.AmfUe = ue
535+
ue.Mutex.Unlock()
536+
ue.updateAttachedRanUeLogs(ranUe)
537+
return
538+
}
539+
ue.RanUe[anType] = ranUe
512540
ranUe.AmfUe = ue
541+
ue.Mutex.Unlock()
513542

514-
go func() {
515-
time.Sleep(time.Second * 2)
516-
if oldRanUe != nil {
517-
logger.ContextLog.Infof("detached UeContext from OldRanUe %v", oldRanUe.AmfUeNgapId)
518-
oldRanUe.AmfUe = nil
519-
}
520-
}()
543+
if oldRanUe != nil {
544+
go func(oldRanUe, newRanUe *RanUe, anType models.AccessType) {
545+
time.Sleep(time.Second * 2)
546+
547+
ue.Mutex.Lock()
548+
defer ue.Mutex.Unlock()
549+
550+
if oldRanUe.AmfUe == ue && ue.RanUe[anType] == newRanUe {
551+
logger.ContextLog.Infof("detached UeContext from OldRanUe %v", oldRanUe.AmfUeNgapId)
552+
oldRanUe.AmfUe = nil
553+
}
554+
}(oldRanUe, ranUe, anType)
555+
}
556+
557+
ue.updateAttachedRanUeLogs(ranUe)
558+
}
521559

560+
func (ue *AmfUe) updateAttachedRanUeLogs(ranUe *RanUe) {
522561
// set log information
523562
ue.NASLog = logger.NasLog.With(logger.FieldAmfUeNgapID, fmt.Sprintf("AMF_UE_NGAP_ID:%d", ranUe.AmfUeNgapId))
524563
ue.GmmLog = logger.GmmLog.With(logger.FieldAmfUeNgapID, fmt.Sprintf("AMF_UE_NGAP_ID:%d", ranUe.AmfUeNgapId))
@@ -1090,11 +1129,11 @@ func (ueContext *AmfUe) PublishUeCtxtInfo() {
10901129
kafkaSmCtxt.Guti = ueContext.Guti
10911130
kafkaSmCtxt.Tmsi = ueContext.Tmsi
10921131
kafkaSmCtxt.AmfIp = ueContext.AmfInstanceIp
1093-
if ueContext.RanUe != nil && ueContext.RanUe[models.ACCESSTYPE__3_GPP_ACCESS] != nil {
1094-
kafkaSmCtxt.AmfNgapId = ueContext.RanUe[models.ACCESSTYPE__3_GPP_ACCESS].AmfUeNgapId
1095-
kafkaSmCtxt.RanNgapId = ueContext.RanUe[models.ACCESSTYPE__3_GPP_ACCESS].RanUeNgapId
1096-
kafkaSmCtxt.GnbId = ueContext.RanUe[models.ACCESSTYPE__3_GPP_ACCESS].Ran.GnbId
1097-
kafkaSmCtxt.TacId = ueContext.RanUe[models.ACCESSTYPE__3_GPP_ACCESS].Tai.Tac
1132+
if ranUe := ueContext.GetRanUe(models.ACCESSTYPE__3_GPP_ACCESS); ranUe != nil {
1133+
kafkaSmCtxt.AmfNgapId = ranUe.AmfUeNgapId
1134+
kafkaSmCtxt.RanNgapId = ranUe.RanUeNgapId
1135+
kafkaSmCtxt.GnbId = ranUe.Ran.GnbId
1136+
kafkaSmCtxt.TacId = ranUe.Tai.Tac
10981137
}
10991138
kafkaSmCtxt.AmfSubState = string(ueContext.State[models.ACCESSTYPE__3_GPP_ACCESS].Current())
11001139
ueState := ueContext.GetCmInfo()

context/ran_ue.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,10 +95,14 @@ func (ranUe *RanUe) Remove() error {
9595
}
9696
if ranUe.AmfUe != nil {
9797
amfUe := ranUe.AmfUe
98+
amfUe.Mutex.Lock()
9899
if amfUe.RanUe[ran.AnType] == ranUe {
99-
ranUe.AmfUe.DetachRanUe(ran.AnType)
100+
delete(amfUe.RanUe, ran.AnType)
100101
}
101-
ranUe.DetachAmfUe()
102+
if ranUe.AmfUe == amfUe {
103+
ranUe.AmfUe = nil
104+
}
105+
amfUe.Mutex.Unlock()
102106
}
103107

104108
for index, ranUe1 := range ran.RanUeList {

nas/handler.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,9 +63,6 @@ func HandleNAS(ctx ctxt.Context, ue *context.RanUe, procedureCode int64, nasPdu
6363
}
6464
}
6565

66-
ue.AmfUe.Mutex.Lock()
67-
defer ue.AmfUe.Mutex.Unlock()
68-
6966
ue.Log.Infoln("Antype from new RanUe:", ue.Ran.AnType)
7067
// AnType is set in SetRanId function. This is called
7168
// when we handle NGSetup. In case of sctplb enabled,
@@ -76,12 +73,14 @@ func HandleNAS(ctx ctxt.Context, ue *context.RanUe, procedureCode int64, nasPdu
7673
}
7774
ue.AmfUe.AttachRanUe(ue)
7875

76+
ue.AmfUe.Mutex.Lock()
7977
if ue.AmfUe.EventChannel == nil {
8078
ue.AmfUe.EventChannel = ue.AmfUe.NewEventChannel()
8179
ue.AmfUe.EventChannel.UpdateNasHandler(DispatchMsg)
8280
go ue.AmfUe.EventChannel.Start(ctx)
8381
}
8482
ue.AmfUe.EventChannel.UpdateNasHandler(DispatchMsg)
83+
ue.AmfUe.Mutex.Unlock()
8584

8685
nasMsg := context.NasMsg{
8786
Context: ctx,

ngap/handler.go

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1030,7 +1030,18 @@ func HandleUEContextReleaseComplete(ctx ctxt.Context, ran *context.AmfRan, messa
10301030
ranUe.Ran = ran
10311031
amfUe := ranUe.AmfUe
10321032
if amfUe == nil {
1033-
ran.Log.Infof("Release UE Context : RanUe[AmfUeNgapId: %d]", ranUe.AmfUeNgapId)
1033+
ran.Log.Infof("release UE Context: RanUe[AmfUeNgapId: %d]", ranUe.AmfUeNgapId)
1034+
context.DetachSourceUeTargetUe(ranUe)
1035+
err := ranUe.Remove()
1036+
if err != nil {
1037+
ran.Log.Errorln(err.Error())
1038+
}
1039+
return
1040+
}
1041+
if currentRanUe := amfUe.GetRanUe(ran.AnType); currentRanUe != nil && currentRanUe != ranUe {
1042+
ran.Log.Infof("release UE Context for stale RanUe[AmfUeNgapId: %d]; keeping current RanUe[AmfUeNgapId: %d]",
1043+
ranUe.AmfUeNgapId, currentRanUe.AmfUeNgapId)
1044+
context.DetachSourceUeTargetUe(ranUe)
10341045
err := ranUe.Remove()
10351046
if err != nil {
10361047
ran.Log.Errorln(err.Error())
@@ -1665,7 +1676,9 @@ func HandleInitialUEMessage(ctx ctxt.Context, ran *context.AmfRan, message *ngap
16651676

16661677
if amfUe.CmConnect(ran.AnType) {
16671678
ranUe.Log.Debug("Implicit Deregistration")
1668-
ranUe.Log.Debugf("RanUeNgapID[%d]", amfUe.RanUe[ran.AnType].RanUeNgapId)
1679+
if currentRanUe := amfUe.GetRanUe(ran.AnType); currentRanUe != nil {
1680+
ranUe.Log.Debugf("RanUeNgapID[%d]", currentRanUe.RanUeNgapId)
1681+
}
16691682
amfUe.DetachRanUe(ran.AnType)
16701683
}
16711684
// TODO: stop Implicit Deregistration timer

0 commit comments

Comments
 (0)