Jump through topic

Modify the packet parameters with “Security Mode Command”

Modify the packet parameters with “Initial Context Setup Request”

Original log from core

image
image
image
image

1. Modify the packet parameters with “Authentication request”

After modification in image

Make problem : imported not use

image

  • Detached this two module.
    image
  • Then compile again and it's successful.
  • Then run core, gnb and UE again.

Core error

  1. image
    image
  2. Make(compiler) problem(Need to add one more parameter to the function)
    (Screenshot gone)

Solution

  • Modification in image

After modification in image

image

Solution
image

UE error

image

  • It is related to CN, after CN errors are fixed, it can access the network.

2. Remove “AUSF”

File editting to ignore this NF

nano /home/ubuntu/free5gc/run.sh
nano /home/ubuntu/free5gc/Makefile
  • run.sh
    image
  • Makefile
    image
  • Then complile it again, we can see the error messages on 5gc log, it is a important clue to find where to modify in source code.

    image

After modification in image

  • Need to detached the including function.
    image

Solution
image

Problem
image

  • It looks the same as I met in lll testing process.
  • And it it not related to MongoDB because in lll testing I thought that the error message included the mongodb part, but it only related to UPF problem.

Solution

  • forcekill and make agaiin and again, then it runs successfully.

After compiling

Core (From NG setup)

image

  • We can search the error message in VScode, and find it is in send.go

UE (Past screenshot)

B1cxXfnGa

After modification in image

  • Test successfully, see the testing result.

3. Remove "NSSF"

File editting

Record the log before accessing UE

  • We can see if there is defference between this and the orignal clean 5GC.

image
image
image
image

  • The NSSF part in original log disappear, see below is the original one.

image

The error messages after ignore NSSF

AMF can't select NSSF

Past note

unnamed

error1.png

error_gnb 1.png

AMF can not select an NSSF by NRF.png

Core side

image
image
image

  • Repeat that AMF can not select an NSSF Instance by NRF[Error: AMF can not select an NSSF by NRF]

UE side

image

  • After a while, it keep trying retransmitting PDU session establishment request, and when it attempts 5 time it will abort the SM procedure.

Error fixing process

  1. Use ctrl+shift+F to find the keyword in the whole folder, here we can see there are two places which may print out this error messages.
    image
  2. In this line image, we can see it is printed from GMM(GPRS Mobility Management, LINK1, LINK2), so first we modify the handler.go which is in the GMM folder.
if needSliceSelection { if ue.NssfUri == "" { for { err := consumer.SearchNssfNSSelectionInstance(ue, amfSelf.NrfUri, models.NfType_NSSF, models.NfType_AMF, nil) if err != nil { //ue.GmmLog.Errorf("AMF can not select an NSSF Instance by NRF[Error: %+v]", err) //time.Sleep(2 * time.Second) } else { break } } }
  • After modifying and compiling, the error message is still the same, so we should modify the sm_context.go.
  1. If I directly ignore the error printing and time sleep lines, the error message is gone, but it will enter a infinite loop to look for NSSF.
    image
  2. Then I add some messages printed to see the log sequence running in the code, and try to break the for loop after TEST04.
  • image
func SelectSmf( ue *amf_context.AmfUe, anType models.AccessType, pduSessionID int32, snssai models.Snssai, dnn string, ) (*amf_context.SmContext, uint8, error) { var ( smfID string smfUri string ) ue.GmmLog.Infof("Select SMF [snssai: %+v, dnn: %+v]", snssai, dnn) nrfUri := ue.ServingAMF().NrfUri // default NRF URI is pre-configured by AMF ue.GmmLog.Errorf("/////////////////TEST01////////////////") nsiInformation := ue.GetNsiInformationFromSnssai(anType, snssai) ue.GmmLog.Errorf("/////////////////TEST02////////////////") if nsiInformation == nil { if ue.NssfUri == "" { // TODO: Set a timeout of NSSF Selection or will starvation here for { ue.GmmLog.Errorf("/////////////////TEST03////////////////") if err := SearchNssfNSSelectionInstance(ue, nrfUri, models.NfType_NSSF, models.NfType_AMF, nil); err != nil { ue.GmmLog.Errorf("/////////////////TEST04////////////////") //ue.GmmLog.Errorf("AMF can not select an NSSF Instance by NRF[Error: %+v]", err) //time.Sleep(2 * time.Second) break } else { break } } } response, problemDetails, err := NSSelectionGetForPduSession(ue, snssai) if err != nil { err = fmt.Errorf("NSSelection Get Error[%+v]", err) return nil, nasMessage.Cause5GMMPayloadWasNotForwarded, err } else if problemDetails != nil { err = fmt.Errorf("NSSelection Get Failed Problem[%+v]", problemDetails) return nil, nasMessage.Cause5GMMPayloadWasNotForwarded, err } nsiInformation = response.NsiInformation } . . .
  • image
func SendSearchNFInstances(nrfUri string, targetNfType, requestNfType models.NfType, param *Nnrf_NFDiscovery.SearchNFInstancesParamOpts, ) (models.SearchResult, error) { // Set client and set url fmt.Println("////TEST A////") configuration := Nnrf_NFDiscovery.NewConfiguration() fmt.Println("////TEST B////") configuration.SetBasePath(nrfUri) client := Nnrf_NFDiscovery.NewAPIClient(configuration) fmt.Println("////TEST C////") result, res, err := client.NFInstancesStoreApi.SearchNFInstances(context.TODO(), targetNfType, requestNfType, param) // 從這行印出 Handle NFDiscoveryRequest 和 200 GET,然後就到下面return回去了。 fmt.Println("////TEST D////") if res != nil && res.StatusCode == http.StatusTemporaryRedirect { err = fmt.Errorf("Temporary Redirect For Non NRF Consumer") } if res == nil || res.Body == nil { return result, err } defer func() { if res != nil { if bodyCloseErr := res.Body.Close(); bodyCloseErr != nil { err = fmt.Errorf("SearchNFInstances' response body cannot close: %+w", bodyCloseErr) } } }() return result, err }
  1. The result is like below.
    image
    • Although it breaks successfully, it gets in another error which go back to resend DL NAS Transport.
    • Then enters another infinite loop which still want to find SMF based on snssai.

Select SMD failed: NSSelection Get Error[NSSF No Response]

  • From 5.

Error fixing process

  • Originally I thought that the error message is from here, where is below the ignored two lines.
    image
  • But when searching the prefix of this lineimage, it actually starts from func CreatePDUSession in image
func CreatePDUSession(ulNasTransport *nasMessage.ULNASTransport, ue *context.AmfUe, anType models.AccessType, pduSessionID int32, smMessage []uint8, ) (setNewSmContext bool, err error) { var ( snssai models.Snssai dnn string ) // A) AMF shall select an SMF // If the S-NSSAI IE is not included and the user's subscription context obtained from UDM. AMF shall // select a default snssai if ulNasTransport.SNSSAI != nil { snssai = nasConvert.SnssaiToModels(ulNasTransport.SNSSAI) } else { if allowedNssai, ok := ue.AllowedNssai[anType]; ok { snssai = *allowedNssai[0].AllowedSnssai } else { return false, errors.New("Ue doesn't have allowedNssai") } } if ulNasTransport.DNN != nil { dnn = ulNasTransport.DNN.GetDNN() } else { // if user's subscription context obtained from UDM does not contain the default DNN for the, // S-NSSAI, the AMF shall use a locally configured DNN as the DNN dnn = ue.ServingAMF().SupportDnnLists[0] if ue.SmfSelectionData != nil { snssaiStr := util.SnssaiModelsToHex(snssai) if snssaiInfo, ok := ue.SmfSelectionData.SubscribedSnssaiInfos[snssaiStr]; ok { for _, dnnInfo := range snssaiInfo.DnnInfos { if dnnInfo.DefaultDnnIndicator { dnn = dnnInfo.Dnn } } } } } if newSmContext, cause, err := consumer.SelectSmf(ue, anType, pduSessionID, snssai, dnn); err != nil { ue.GmmLog.Errorf("Select SMF failed: %+v", err) gmm_message.SendDLNASTransport(ue.RanUe[anType], nasMessage.PayloadContainerTypeN1SMInfo, smMessage, pduSessionID, cause, nil, 0) } else { _, smContextRef, errResponse, problemDetail, err := consumer.SendCreateSmContextRequest( ue, newSmContext, nil, smMessage) if err != nil { ue.GmmLog.Errorf("CreateSmContextRequest Error: %+v", err) return false, nil } else if problemDetail != nil { // TODO: error handling return false, fmt.Errorf("Failed to Create smContext[pduSessionID: %d], Error[%v]", pduSessionID, problemDetail) } else if errResponse != nil { ue.GmmLog.Warnf("PDU Session Establishment Request is rejected by SMF[pduSessionId:%d]", pduSessionID) gmm_message.SendDLNASTransport(ue.RanUe[anType], nasMessage.PayloadContainerTypeN1SMInfo, errResponse.BinaryDataN1SmMessage, pduSessionID, 0, nil, 0) } else { newSmContext.SetSmContextRef(smContextRef) newSmContext.SetUserLocation(deepcopy.Copy(ue.Location).(models.UserLocation)) ue.StoreSmContext(pduSessionID, newSmContext) ue.GmmLog.Infof("create smContext[pduSessionID: %d] Success", pduSessionID) // TODO: handle response(response N2SmInfo to RAN if exists) return true, nil } } return false, nil }
  • It is kinda complicated, so I draw the clall flow :
    unnamed
  1. Until here, I may have two ways to solve it :
    • Keep ingoring the lines produce the error messages.
      1. First I try to skip the SendDLNASTransport process, let it continue to next else function.
        image but it turns out
        image
        or modify like this
        image but it need the parameters passed from SelectSMF
        image
      2. Then I turn to sm_context.go to see if I can ignore the error parameter(err) which will be returned to handler.go.
      3. I add some text before each return line in func SelectSmf, and result is that it returns at here :
        image
        in the first if function,
        image
        and it actually means that the prefix of the image is from CreatePDUSession but afterpart(suffix) is printed here before return back(return01), so if I ignore this image,
        the log looks like this
        image,
        which is different from this
        image.
      4. Then I scroll down to see the rest code of the func SelectSmf after return01, and find that maybe I can try to ignore the whole if function, because it seems that it doesnt really need it, if I remove it, the error will also not be put in err parameter.
    • Try to modify the code, let SMF stop to find NSSF or give AMF a fixed value snssai to select SMF.
      1. So in the last method, we cannot just ignore the error meassage lines to jump through this process.
      2. Like the point 4. up there, I try to ingore the whole nsiInformation checking function, the result put in below part.

Solution

  1. Continued to say, because the if function I modified seems to be useless for afterpart in SelectSmf :
. . . smContext := amf_context.NewSmContext(pduSessionID) smContext.SetSnssai(snssai) smContext.SetDnn(dnn) smContext.SetAccessType(anType) if nsiInformation == nil { ue.GmmLog.Warnf("nsiInformation is still nil, use default NRF[%s]", nrfUri) } else { smContext.SetNsInstance(nsiInformation.NsiId) nrfApiUri, err := url.Parse(nsiInformation.NrfId) if err != nil { ue.GmmLog.Errorf("Parse NRF URI error, use default NRF[%s]", nrfUri) } else { nrfUri = fmt.Sprintf("%s://%s", nrfApiUri.Scheme, nrfApiUri.Host) } } param := Nnrf_NFDiscovery.SearchNFInstancesParamOpts{ ServiceNames: optional.NewInterface([]models.ServiceName{models.ServiceName_NSMF_PDUSESSION}), Dnn: optional.NewString(dnn), Snssais: optional.NewInterface(openapi.MarshToJsonString([]models.Snssai{snssai})), } if ue.PlmnId.Mcc != "" { param.TargetPlmnList = optional.NewInterface(openapi.MarshToJsonString(ue.PlmnId)) } if amf_context.GetSelf().Locality != "" { param.PreferredLocality = optional.NewString(amf_context.GetSelf().Locality) } ue.GmmLog.Debugf("Search SMF from NRF[%s]", nrfUri) result, err := SendSearchNFInstances(nrfUri, models.NfType_SMF, models.NfType_AMF, &param) if err != nil { ue.GmmLog.Errorf("////return03////") return nil, nasMessage.Cause5GMMPayloadWasNotForwarded, err } if len(result.NfInstances) == 0 { err = fmt.Errorf("DNN[%s] is not supported or not subscribed in the slice[Snssai: %+v]", dnn, snssai) ue.GmmLog.Errorf("////return04////") return nil, nasMessage.Cause5GMMDNNNotSupportedOrNotSubscribedInTheSlice, err } // select the first SMF, TODO: select base on other info for _, nfProfile := range result.NfInstances { smfUri = util.SearchNFServiceUri(nfProfile, models.ServiceName_NSMF_PDUSESSION, models.NfServiceStatus_REGISTERED) if smfUri != "" { break } } smContext.SetSmfID(smfID) smContext.SetSmfUri(smfUri) ue.GmmLog.Errorf("////return05////") return smContext, 0, nil }
  1. I try to do this, not just ingore the lines produce the error messages, but stop the NSSelection error production :
    image
  2. And it works, the PDUSession is builded successfully, though there is a warning message, see the testing result.

4. Remove "PCF"

File editting

Record the log before accessing UE

  • You can see PCF log dispear, and check the difference with the last part "Remove NSSF"

image
image
image
image

The error logs after ignoring PCF and acessing the UE

1. AMF can not select an PCF by NRF

Core side
image
image
image

gnb side

  • Repeated messages
    image

UE side

  • Repeated messages
    image

Error fixing process

  1. Search in the folder
    image
    • In handler.go, the logs is from this function, and you can check it start from printing out Handle InitialRegistration by see the log up there(Core side).
func HandleInitialRegistration(ue *context.AmfUe, anType models.AccessType) error { ue.GmmLog.Infoln("Handle InitialRegistration") amfSelf := context.GetSelf() // update Kgnb/Kn3iwf ue.UpdateSecurityContext(anType) // Registration with AMF re-allocation (TS 23.502 4.2.2.2.3) if len(ue.SubscribedNssai) == 0 { getSubscribedNssai(ue) } if err := handleRequestedNssai(ue, anType); err != nil { return err } if ue.RegistrationRequest.Capability5GMM != nil { ue.Capability5GMM = *ue.RegistrationRequest.Capability5GMM } else { gmm_message.SendRegistrationReject(ue.RanUe[anType], nasMessage.Cause5GMMProtocolErrorUnspecified, "") return fmt.Errorf("Capability5GMM is nil") } storeLastVisitedRegisteredTAI(ue, ue.RegistrationRequest.LastVisitedRegisteredTAI) if ue.RegistrationRequest.MICOIndication != nil { ue.GmmLog.Warnf("Receive MICO Indication[RAAI: %d], Not Supported", ue.RegistrationRequest.MICOIndication.GetRAAI()) } // TODO: Negotiate DRX value if need (TS 23.501 5.4.5) negotiateDRXParameters(ue, ue.RegistrationRequest.RequestedDRXParameters) // TODO (step 10 optional): send Namf_Communication_RegistrationCompleteNotify to old AMF if need if ue.ServingAmfChanged { // If the AMF has changed the new AMF notifies the old AMF that the registration of the UE in the new AMF is completed req := models.UeRegStatusUpdateReqData{ TransferStatus: models.UeContextTransferStatus_TRANSFERRED, } // TODO: based on locol policy, decide if need to change serving PCF for UE regStatusTransferComplete, problemDetails, err := consumer.RegistrationStatusUpdate(ue, req) if problemDetails != nil { ue.GmmLog.Errorf("Registration Status Update Failed Problem[%+v]", problemDetails) } else if err != nil { ue.GmmLog.Errorf("Registration Status Update Error[%+v]", err) } else { if regStatusTransferComplete { ue.GmmLog.Infof("Registration Status Transfer complete") } } } if len(ue.Pei) == 0 { gmm_message.SendIdentityRequest(ue.RanUe[anType], anType, nasMessage.MobileIdentity5GSTypeImei) return nil } // TODO (step 12 optional): the new AMF initiates ME identity check by invoking the // N5g-eir_EquipmentIdentityCheck_Get service operation if ue.ServingAmfChanged || ue.State[models.AccessType_NON_3_GPP_ACCESS].Is(context.Registered) || !ue.ContextValid { if err := communicateWithUDM(ue, anType); err != nil { ue.GmmLog.Errorf("communicateWithUDM error: %v", err) gmm_message.SendRegistrationReject(ue.RanUe[anType], nasMessage.Cause5GMMPLMNNotAllowed, "") return errors.Wrap(err, "communicateWithUDM failed") } } param := Nnrf_NFDiscovery.SearchNFInstancesParamOpts{ Supi: optional.NewString(ue.Supi), } if amfSelf.Locality != "" { param.PreferredLocality = optional.NewString(amfSelf.Locality) } for { resp, err := consumer.SendSearchNFInstances(amfSelf.NrfUri, models.NfType_PCF, models.NfType_AMF, &param) if err != nil { ue.GmmLog.Error("AMF can not select an PCF by NRF") } else { // select the first PCF, TODO: select base on other info var pcfUri string for _, nfProfile := range resp.NfInstances { pcfUri = util.SearchNFServiceUri(nfProfile, models.ServiceName_NPCF_AM_POLICY_CONTROL, models.NfServiceStatus_REGISTERED) if pcfUri != "" { ue.PcfId = nfProfile.NfInstanceId break } } if ue.PcfUri = pcfUri; ue.PcfUri == "" { ue.GmmLog.Error("AMF can not select an PCF by NRF") } else { break } } time.Sleep(500 * time.Millisecond) // sleep a while when search NF Instance fail } problemDetails, err := consumer.AMPolicyControlCreate(ue, anType) if problemDetails != nil { ue.GmmLog.Errorf("AM Policy Control Create Failed Problem[%+v]", problemDetails) } else if err != nil { ue.GmmLog.Errorf("AM Policy Control Create Error[%+v]", err) } // Service Area Restriction are applicable only to 3GPP access if anType == models.AccessType__3_GPP_ACCESS { if ue.AmPolicyAssociation != nil && ue.AmPolicyAssociation.ServAreaRes != nil { servAreaRes := ue.AmPolicyAssociation.ServAreaRes if servAreaRes.RestrictionType == models.RestrictionType_ALLOWED_AREAS { numOfallowedTAs := 0 for _, area := range servAreaRes.Areas { numOfallowedTAs += len(area.Tacs) } // if numOfallowedTAs < int(servAreaRes.MaxNumOfTAs) { // TODO: based on AMF Policy, assign additional allowed area for UE, // and the upper limit is servAreaRes.MaxNumOfTAs (TS 29.507 4.2.2.3) // } } } } // TODO (step 18 optional): // If the AMF has changed and the old AMF has indicated an existing NGAP UE association towards a N3IWF, the new AMF // creates an NGAP UE association towards the N3IWF to which the UE is connectedsend N2 AMF mobility request to N3IWF // if anType == models.AccessType_NON_3_GPP_ACCESS && ue.ServingAmfChanged { // TODO: send N2 AMF Mobility Request // } amfSelf.AllocateRegistrationArea(ue, anType) ue.GmmLog.Debugf("Use original GUTI[%s]", ue.Guti) assignLadnInfo(ue, anType) amfSelf.AddAmfUeToUePool(ue, ue.Supi) ue.T3502Value = amfSelf.T3502Value if anType == models.AccessType__3_GPP_ACCESS { ue.T3512Value = amfSelf.T3512Value } else { ue.Non3gppDeregTimerValue = amfSelf.Non3gppDeregTimerValue } gmm_message.SendRegistrationAccept(ue, anType, nil, nil, nil, nil, nil) return nil }
  1. Try to break after error
    • After first error printing message, it still enter infinite loop, so the error is not printed here.
      image
    • So it is actually printed from here.
      image
  2. And it turns out to be panic error.
    • Core side
      image
    • Repeated UE side
      image
  3. But sometimes it will print out another kind of panic error.
    • Core side
      image
      image
    • Repeated UE side
      image
  • Here the 4. should be the right way to print out the message, because when we close core, gnb, ue completely, and restart all of them, they always look like 4.
  • But if we dont stop gnb and ue, just restart the core, then also restart the gnb, and ue can connect again which doesnt need to stop and restart, you will see in the message
    image
    will be printed out in the core side, then when ue connect to core again, the error in 3. will happen.
  • The panic error means some of pointer parameters have an error address or value, which is also met in NSSF removing(in SMF selection), so I guess that if we dont stop the ue, the reconnected ue will cause the authentication parameter error in restarted 5GC.
    • So when we meet panic error, we may accidentally comment out some parameter which is using in the process of ignoring error printing line.
    • In the past experence, the panic error is hard to solve, because we may need to redefine the parameter or give some value to it
      • If we derectly comment out the patameter, other function need it.
      • If we dont comment out it, the function returning process need the parameter which we want to comment out, like the err parameter.
      • For example, response is needed for other function, err is needed for access the returned value, but we want to comment out err.
        image
  1. But in here, we can see the panic error is after another error message image which is happened after image, so we can deal with it first and see if the panic error disapears.

2. AM Policy Control Create Error[server no response]

  • From 5.

Error fixing process

  1. You can see this error is from here.
    • And when you check other parts of func HandleInitialRegistration, you can see the only part has relation with PCF is this part, but I need to study more about PolicyControl to know what kind of relation it is.
. . . for { resp, err := consumer.SendSearchNFInstances(amfSelf.NrfUri, models.NfType_PCF, models.NfType_AMF, &param) if err != nil { ue.GmmLog.Error("AMF can not select an PCF by NRF") //break } else { // select the first PCF, TODO: select base on other info var pcfUri string for _, nfProfile := range resp.NfInstances { pcfUri = util.SearchNFServiceUri(nfProfile, models.ServiceName_NPCF_AM_POLICY_CONTROL, models.NfServiceStatus_REGISTERED) if pcfUri != "" { ue.PcfId = nfProfile.NfInstanceId break } } if ue.PcfUri = pcfUri; ue.PcfUri == "" { ue.GmmLog.Error("AMF can not select an PCF by NRF") break } else { break } } time.Sleep(500 * time.Millisecond) // sleep a while when search NF Instance fail } problemDetails, err := consumer.AMPolicyControlCreate(ue, anType) if problemDetails != nil { ue.GmmLog.Errorf("AM Policy Control Create Failed Problem[%+v]", problemDetails) } else if err != nil { ue.GmmLog.Errorf("AM Policy Control Create Error[%+v]", err) } . . .
  1. I think there are some ways to comment out the PCF related part in initial registration.
    1. Remove the function SendSearchNFInstances to stop the production of err.
      • The function SendSearchNFInstances is like a global variable in free5gc, other part of code will call it to find NF.
      • There will has an error about resp because it is used at below code.
    2. Break the for loop after error printing line(this line can be commented out or it will be printed out as usual)
      • It seems to be OK, it successfully jump to next part and will not cause some implicit errors that will not be seen in logs, because the original error is trigered by PCF's uri is blank, and the blank PCFuri will not cause other problem, it is just because PCF is removed.
      • If this is OK, maybe we dont need to comment out the whole for loop, but if the err parameter is used in afterpart and the value stored in it caused another problem, we should do this or other modification(In the code, after this part, err will not be used.)
    3. Remove the function AMPolicyControlCreate
      • It seems to be ok because the parameters problemDetails and err is only used in here.
    4. But I just comment out this part
      image
  2. As 7-2 says, I also comment it out,
    image
    and the result is like below, the error message are gone, but the panic error still exists.
    image
  3. As stated above, now I just need to try figuring out how to solve this out.
    • The panic error happended after I break the for loop, and it is printed after Send Initial Context Setup Request, which is produced here :
      1. In the end of func HandleInitialRegistration, it callsimage
      2. The func SendRegistrationAccept is in
        image
        , which will print out this before Send Initial Context Setup Request
        image
        image
      3. And func SendRegistrationAccept calls this function
        image
        , which is in here and will print out this
        image
        image
    • So there might have some parameters needed in the process of Send Registration Accept and Send Initial Context Setup Request, like below is one of the ue info but not be written in because the printed error and break.
      image
  4. Originally I think the panic may have relation with commenting out some kind of parameter needed in consumer.AMPolicyControlCreate
    • (Uncertain) But compare to the panic error screenshot attached above, we can say there is no difference between this(after commenting out) and that(before commenting out).
    • So we might still turn to 9. for the answar.

3. [FATA][AMF][Ngap] panic: runtime error: invalid memory address or nil pointer dereference

  • From 10.

Error fixing process

  1. Continue from 9.
    • After doing this, it still has panic.
      image
  2. And I think the reason is in the parameters passed from HandleInitialRegistration to SendRegistrationAccept and to SendInitialContextSetupRequest.
    image
    image
  3. So I add some lines of fmt.println. to see the value passing process. If you has an error which says no import "fmt", you need to add this.
    image
    In this process, we need to repeat compiling core and change the line of print to see where the panic happens.
    1. First in image, wa can see the printed info before passing to SendRegistrationAccept :
      image
    2. Then in image, the info can be printed out after BuildRegistrationAccept and before the if lines :
      image
    3. Then in the SendInitialContextSetupRequest of image, I add these lines so I can check where the panic is from, here the HERE3 is printed and HERE4 is not printed, which means the panic is from BuildInitialContextSetupRequest.
      image
  4. In this function, there are so many if functions, about 300 lines, so I just repeat printing to see which one is the last one run before panic error.
    image
    image
    And result is here, wa can see +++++ is printed, and ===== is not printed.
    image
  5. The log is like below, because the value of ue is printed in original type, I dont know how to modify it.
    image
  6. Here just try to fix the PcfId, but it change nothing.
    image
  7. Keep tracing, we can dig more deep in BuildIEMobilityRestrictionList.
    image
    And it is in image, in the function I just try this if line first because it relates to PolicyAssociation, then the line of 55555 is not printed, so I want to print the ServAreaRes parameter, but it is not printed too, so the panic reason is in the parameter.
    image
  8. Here we can see the log stops at 33333.
    image
    At the same time, when checking the log of panic error, we can see it has already printed out the start of error
    image
    and the end of the error,
    image
    so next time we can follow this.
  9. Next step, I find where is AmPolicyAssociation and ServAreaRes. One is in type AmfUe struct of this file
    image,
    the other one is in
    image.
  10. If I derectly comment out here.
    image
    I will get another panic error.

4. [ERRO][SMF][GIN] panic: runtime error: index out of range [0] with length 0

  • from 20.

Core side

  • It skip the policy part of AMF and it seems entering the part of SMF but get panic error and repeat it.

image
image
image

gnb side
image
UE side
image

Error fixing process

  1. image This line just disappears if I directly comment out in the code, so I didnt touch it.
  2. image Then I search this information to find where the panic error happend, and it is in here. image
    When I want to print the value of rep.NfInstances[0], it turns out this, the error happenning place move to line 444.
    image
  3. Test in original full CN, the value of this structure is image
    • Because I use logger.CtxLog.Warningf() to print it, it can be more conspicuous in many logs.
    • Because I use %v, the printed values is not only the first element, it print out all values in the struc.
    • Using %+v can print in detailed including the parameter name.
      image
  4. And I use the original value of NfInstance Id to write into it.
    image
    But the result stay the same.
    image
    I guess it may need all value of struc, so I do this to write the parameter if it has value in original CN.
    image
    But the result stay the same.
    image

image
image

image
image
image
image

5. PDU Session Establishment Request is rejected by SMF

  • From 25.
    Core side
    image
    image
    gnb side
    image
    UE side
    image

Error fixing process

  1. Only reserve these two lines.
    image
    image
    And dont comment out here.
    image
    • Result stay the same
  2. Original values which printed in free5gc_v3.3_01(full core).
    image
    image
    image
    image
  3. Dont comment out these lines and replace the apiprefix, I want to recover the policy in SMF.
    image
    image
    • It is hard to specify the NfServices, so i didnt use original parameter service.ApiPrefix
    • Result stay the same
  • It use this kind of url to use the reference from github of openapi, in detail.
    image
    image

6. Combine PCF to SMF to recover the policy creating process

  • From 28.

Because the log result has already on the stage of SMcontext and PDUsession creaing, so if I keep commenting out something, it may influence the whole process.

6-1. Investiigation in original core

  1. Compare to the modified core side(get the 504 error and release the IP of UE), the highlighted part in the picture(original core), maybe we can recover it through moving the removed function of PCF to SMF.
    image
    • If I searh the first message([PCF][SMpolicy] Handle CreateSmPolicy) in code directly, I can find this kind of sequence :
      smpolicy.go <== api_default.go <== routers.go
      (HandleCreateSmPolicyRequest <== HTTPSmPoliciesPost <== var routes = Routes)
      image
      image
      image
  2. Print some numbers to seperate them so that I can know the breakpoints, then can know how and where to call router.go.
    image
    image
    image
    image
    image
    • Call between 1 and 2, which is by consumer.SendSMPolicyAssociationCreate(smContext).
  3. Keep tracing to sm_policy.go in sbi/consumer of SMF, we can find it calls the API producer in PCF through router.go between 2-6 and 2-7, which produce the messages in the log.
    image
    image
    image
  4. About the detailed situation of openAPI call flow, see here.
  5. Keep finding where the logs between 2-6 and 2-7, we can find that they are all in the func createSMPolicyProcedure which is in the same SMF calling file (smpolicy.go).
    Here are the sources of each line :
    1. image
      image
    2. image
      image
    3. image
      image
    4. image
      image
    5. image
      image
    6. image
      image

6-2.

  1. Before moving the function between 2-6~2-7, I find that I miss some clues :
    • In modifed core, it send 504 error after PDUAdress allocated.
      image
    • But in original core, it will send 200 for finding PCF successfully after PDUAdress allocated.
      image
      • And if I just move the part I investigated in 6-1, although it is truely the lacked policy part in SMF, I may still have error because of skipping this difference before 1 and some value printed by me.
    • The difference here is also caused by the lack of PCF I guess.
  2. The releasing part after api 504.
    image
    image
    image

v3.3_PCF_v0.3 & v3.3_Full_PCF_v0.1

Select a repo