From aa50e9da8276e6f22de267c314c4c24b20f06d32 Mon Sep 17 00:00:00 2001 From: roy19991013 <80-ChienAn@users.noreply.gitlab.nems.cs.nctu.edu.tw> Date: Sun, 14 May 2023 19:58:52 -0700 Subject: [PATCH 01/32] support converged charging --- internal/context/charging.go | 32 ++ internal/context/context.go | 14 + internal/context/datapath.go | 103 +++++- internal/context/pcc_rule.go | 22 ++ internal/context/pfcp_reports.go | 95 ++++++ internal/context/pfcp_rules.go | 18 ++ internal/context/sm_context.go | 75 +++++ internal/context/sm_context_policy.go | 75 ++++- internal/context/upf.go | 10 +- internal/logger/logger.go | 2 + internal/pfcp/handler/handler.go | 53 +--- internal/pfcp/message/build.go | 88 ++++++ internal/sbi/callback/api_default.go | 36 +++ internal/sbi/callback/routers.go | 6 + internal/sbi/consumer/converged_charging.go | 105 +++++++ internal/sbi/producer/callback.go | 53 ++++ internal/sbi/producer/charging_trigger.go | 328 ++++++++++++++++++++ internal/sbi/producer/datapath.go | 31 +- internal/sbi/producer/pdu_session.go | 32 +- internal/sbi/producer/ulcl_procedure.go | 22 +- pkg/factory/config.go | 1 + 21 files changed, 1139 insertions(+), 62 deletions(-) create mode 100644 internal/context/charging.go create mode 100644 internal/context/pfcp_reports.go create mode 100644 internal/sbi/consumer/converged_charging.go create mode 100644 internal/sbi/producer/charging_trigger.go diff --git a/internal/context/charging.go b/internal/context/charging.go new file mode 100644 index 00000000..8e1e840e --- /dev/null +++ b/internal/context/charging.go @@ -0,0 +1,32 @@ +package context + +import ( + "github.com/free5gc/openapi/models" +) + +type ChargingLevel uint8 + +// For a rating group that is pud session charging level, all volume in a pdu session will be charged +// For a rating group that is flow charging level (or Rating group level (32.255)), only volume in a flow will be charged +const ( + PduSessionCharging ChargingLevel = iota + FlowCharging +) + +type RequestType uint8 + +// For each charging event, it will have a corresponding charging request type, see 32.255 Table 5.2.1.4.1 +const ( + CHARGING_INIT RequestType = iota + CHARGING_UPDATE + CHARGING_RELEASE +) + +type ChargingInfo struct { + ChargingMethod models.QuotaManagementIndicator + VolumeLimitExpiryTimer *Timer + EventLimitExpiryTimer *Timer + ChargingLevel ChargingLevel + RatingGroup int32 + UpfId string +} diff --git a/internal/context/context.go b/internal/context/context.go index 6d98e63a..a3770e04 100644 --- a/internal/context/context.go +++ b/internal/context/context.go @@ -3,6 +3,7 @@ package context import ( "context" "fmt" + "math" "net" "os" "sync/atomic" @@ -17,6 +18,7 @@ import ( "github.com/free5gc/pfcp/pfcpType" "github.com/free5gc/smf/internal/logger" "github.com/free5gc/smf/pkg/factory" + "github.com/free5gc/util/idgenerator" ) func Init() { @@ -70,6 +72,16 @@ type SMFContext struct { UEPreConfigPathPool map[string]*UEPreConfigPaths UEDefaultPathPool map[string]*UEDefaultPaths LocalSEIDCount uint64 + + // Each pdu session should have a unique charging id + ChargingIDGenerator *idgenerator.IDGenerator +} + +func GenerateChargingID() int32 { + if id, err := smfContext.ChargingIDGenerator.Allocate(); err == nil { + return int32(id) + } + return 0 } func ResolveIP(host string) net.IP { @@ -231,6 +243,8 @@ func InitSmfContext(config *factory.Config) { smfContext.UserPlaneInformation = NewUserPlaneInformation(&configuration.UserPlaneInformation) + smfContext.ChargingIDGenerator = idgenerator.NewGenerator(1, math.MaxUint32) + SetupNFProfile(config) smfContext.Locality = configuration.Locality diff --git a/internal/context/datapath.go b/internal/context/datapath.go index de75c44c..f46d28d1 100644 --- a/internal/context/datapath.go +++ b/internal/context/datapath.go @@ -3,6 +3,7 @@ package context import ( "fmt" "strconv" + "strings" "github.com/google/uuid" @@ -345,6 +346,10 @@ func getUrrIdKey(uuid string, urrId uint32) string { return uuid + ":" + strconv.Itoa(int(urrId)) } +func GetUpfIdFromUrrIdKey(urrIdKey string) string { + return strings.Split(urrIdKey, ":")[0] +} + func (node DataPathNode) addUrrToNode(smContext *SMContext, urrId uint32, isMeasurePkt, isMeasureBeforeQos bool) { var urr *URR var ok bool @@ -360,7 +365,6 @@ func (node DataPathNode) addUrrToNode(smContext *SMContext, urrId uint32, isMeas logger.PduSessLog.Errorln("new URR failed") return } - smContext.UrrUpfMap[id] = urr } if urr != nil { @@ -422,7 +426,7 @@ func (dataPath *DataPath) ActivateTunnelAndPDR(smContext *SMContext, precedence // Note: This should be after Activate Tunnels if smContext.UrrReportTime != 0 || smContext.UrrReportThreshold != 0 { dataPath.addUrrToPath(smContext) - logger.PduSessLog.Warn("Create URR") + logger.PduSessLog.Trace("Create URR") } else { logger.PduSessLog.Warn("No Create URR") } @@ -712,6 +716,101 @@ func (p *DataPath) RemovePDR() { } } +func (p *DataPath) GetChargingUrr(smContext *SMContext) []*URR { + var chargingUrrs []*URR + var urrs []*URR + + for node := p.FirstDPNode; node != nil; node = node.Next() { + // Charging rules only apply to anchor UPF + if node.IsAnchorUPF() { + if node.UpLinkTunnel != nil && node.UpLinkTunnel.PDR != nil { + urrs = node.UpLinkTunnel.PDR.URR + } else if node.DownLinkTunnel != nil && node.DownLinkTunnel.PDR != nil { + urrs = node.UpLinkTunnel.PDR.URR + } + + for _, urr := range urrs { + if smContext.ChargingInfo[urr.URRID] != nil { + chargingUrrs = append(chargingUrrs, urr) + } + } + } + } + + return chargingUrrs +} + +func (p *DataPath) AddChargingRules(smContext *SMContext, chgLevel ChargingLevel, chgData *models.ChargingData) { + if chgData == nil { + return + } + + for node := p.FirstDPNode; node != nil; node = node.Next() { + // Charging rules only apply to anchor UPF + if node.IsAnchorUPF() { + var urr *URR + chgInfo := &ChargingInfo{ + RatingGroup: chgData.RatingGroup, + ChargingLevel: chgLevel, + UpfId: node.UPF.UUID(), + } + + urrId, err := smContext.UrrIDGenerator.Allocate() + if err != nil { + logger.PduSessLog.Errorln("Generate URR Id failed") + return + } + + currentUUID := node.UPF.UUID() + id := getUrrIdKey(currentUUID, uint32(urrId)) + + if oldURR, ok := smContext.UrrUpfMap[id]; !ok { + // For online charging, the charging trigger "Start of the Service data flow" are needed. + // Therefore, the START reporting trigger in the urr are needed to detect the Start of the SDF + if chgData.Online { + if newURR, err := node.UPF.AddURR(uint32(urrId), + NewMeasureInformation(false, false), + SetStartofSDFTrigger()); err != nil { + logger.PduSessLog.Errorln("new URR failed") + return + } else { + urr = newURR + } + + chgInfo.ChargingMethod = models.QuotaManagementIndicator_ONLINE_CHARGING + } else if chgData.Offline { + // For offline charging, URR only need to report based on the volume threshold + if newURR, err := node.UPF.AddURR(uint32(urrId), + NewMeasureInformation(false, false), + NewVolumeThreshold(smContext.UrrReportThreshold)); err != nil { + logger.PduSessLog.Errorln("new URR failed") + return + } else { + urr = newURR + } + + chgInfo.ChargingMethod = models.QuotaManagementIndicator_OFFLINE_CHARGING + } + smContext.UrrUpfMap[id] = urr + } else { + urr = oldURR + } + + if urr != nil { + logger.PduSessLog.Tracef("Successfully add URR %d for Rating group %d", urr.URRID, chgData.RatingGroup) + + smContext.ChargingInfo[urr.URRID] = chgInfo + if node.UpLinkTunnel != nil && node.UpLinkTunnel.PDR != nil { + node.UpLinkTunnel.PDR.URR = append(node.UpLinkTunnel.PDR.URR, urr) + } + if node.DownLinkTunnel != nil && node.DownLinkTunnel.PDR != nil { + node.DownLinkTunnel.PDR.URR = append(node.DownLinkTunnel.PDR.URR, urr) + } + } + } + } +} + func (p *DataPath) AddQoS(smContext *SMContext, qfi uint8, qos *models.QosData) { // QFI = 1 -> default QFI if qos == nil && qfi != 1 { diff --git a/internal/context/pcc_rule.go b/internal/context/pcc_rule.go index 12f33171..42990dc3 100644 --- a/internal/context/pcc_rule.go +++ b/internal/context/pcc_rule.go @@ -41,6 +41,14 @@ func (r *PCCRule) FlowDescription() string { return "" } +func (r *PCCRule) RefChgDataID() string { + if len(r.RefChgData) > 0 { + // now 1 pcc rule only maps to 1 Charging data + return r.RefChgData[0] + } + return "" +} + func (r *PCCRule) RefQosDataID() string { if len(r.RefQosData) > 0 { // now 1 pcc rule only maps to 1 QoS data @@ -61,6 +69,20 @@ func (r *PCCRule) RefTcDataID() string { return "" } +func (r *PCCRule) IdentifyChargingLevel() (ChargingLevel, error) { + dlIPFilterRule, err := flowdesc.Decode(r.FlowDescription()) + if err != nil { + return 0, err + } + // For pcc that are applicable for all datapath, it's charging level will be Pdu based + if dlIPFilterRule.Src == "any" && dlIPFilterRule.Dst == "assigned" { + return PduSessionCharging, nil + } else { + // For pcc that have applicable for all datapath fpr a datapath, it's charging level will be flow based + return FlowCharging, nil + } +} + func (r *PCCRule) UpdateDataPathFlowDescription(dlFlowDesc string) error { if r.Datapath == nil { return fmt.Errorf("pcc[%s]: no data path", r.PccRuleId) diff --git a/internal/context/pfcp_reports.go b/internal/context/pfcp_reports.go new file mode 100644 index 00000000..5567b373 --- /dev/null +++ b/internal/context/pfcp_reports.go @@ -0,0 +1,95 @@ +package context + +import ( + "github.com/free5gc/openapi/models" + "github.com/free5gc/pfcp" + "github.com/free5gc/pfcp/pfcpType" + "github.com/free5gc/smf/internal/logger" +) + +func (smContext *SMContext) HandleReports( + UsageReportReport []*pfcp.UsageReportPFCPSessionReportRequest, + UsageReportModification []*pfcp.UsageReportPFCPSessionModificationResponse, + UsageReportDeletion []*pfcp.UsageReportPFCPSessionDeletionResponse, + nodeId pfcpType.NodeID, reportTpye models.TriggerType, +) { + var usageReport UsageReport + upf := RetrieveUPFNodeByNodeID(nodeId) + upfId := upf.UUID() + + for _, report := range UsageReportReport { + usageReport.UrrId = report.URRID.UrrIdValue + usageReport.UpfId = upfId + usageReport.TotalVolume = report.VolumeMeasurement.TotalVolume + usageReport.UplinkVolume = report.VolumeMeasurement.UplinkVolume + usageReport.DownlinkVolume = report.VolumeMeasurement.DownlinkVolume + usageReport.TotalPktNum = report.VolumeMeasurement.TotalPktNum + usageReport.UplinkPktNum = report.VolumeMeasurement.UplinkPktNum + usageReport.DownlinkPktNum = report.VolumeMeasurement.DownlinkPktNum + usageReport.ReportTpye = identityTriggerType(report.UsageReportTrigger) + + if reportTpye != "" { + usageReport.ReportTpye = reportTpye + } + + smContext.UrrReports = append(smContext.UrrReports, usageReport) + } + for _, report := range UsageReportModification { + usageReport.UrrId = report.URRID.UrrIdValue + usageReport.UpfId = upfId + usageReport.TotalVolume = report.VolumeMeasurement.TotalVolume + usageReport.UplinkVolume = report.VolumeMeasurement.UplinkVolume + usageReport.DownlinkVolume = report.VolumeMeasurement.DownlinkVolume + usageReport.TotalPktNum = report.VolumeMeasurement.TotalPktNum + usageReport.UplinkPktNum = report.VolumeMeasurement.UplinkPktNum + usageReport.DownlinkPktNum = report.VolumeMeasurement.DownlinkPktNum + usageReport.ReportTpye = identityTriggerType(report.UsageReportTrigger) + + if reportTpye != "" { + usageReport.ReportTpye = reportTpye + } + + smContext.UrrReports = append(smContext.UrrReports, usageReport) + } + for _, report := range UsageReportDeletion { + usageReport.UrrId = report.URRID.UrrIdValue + usageReport.UpfId = upfId + usageReport.TotalVolume = report.VolumeMeasurement.TotalVolume + usageReport.UplinkVolume = report.VolumeMeasurement.UplinkVolume + usageReport.DownlinkVolume = report.VolumeMeasurement.DownlinkVolume + usageReport.TotalPktNum = report.VolumeMeasurement.TotalPktNum + usageReport.UplinkPktNum = report.VolumeMeasurement.UplinkPktNum + usageReport.DownlinkPktNum = report.VolumeMeasurement.DownlinkPktNum + usageReport.ReportTpye = identityTriggerType(report.UsageReportTrigger) + + if reportTpye != "" { + usageReport.ReportTpye = reportTpye + } + + smContext.UrrReports = append(smContext.UrrReports, usageReport) + } +} + +func identityTriggerType(usarTrigger *pfcpType.UsageReportTrigger) models.TriggerType { + var trigger models.TriggerType + + if usarTrigger.Volth { + trigger = models.TriggerType_QUOTA_THRESHOLD + } else if usarTrigger.Volqu { + trigger = models.TriggerType_QUOTA_EXHAUSTED + } else if usarTrigger.Quvti { + trigger = models.TriggerType_VALIDITY_TIME + } else if usarTrigger.Start { + trigger = models.TriggerType_START_OF_SERVICE_DATA_FLOW + } else if usarTrigger.Immer { + logger.PduSessLog.Trace("Reports Query by SMF, trigger should be filled later") + return "" + } else if usarTrigger.Termr { + trigger = models.TriggerType_FINAL + } else { + logger.PduSessLog.Trace("Report is not a charging trigger") + return "" + } + + return trigger +} diff --git a/internal/context/pfcp_rules.go b/internal/context/pfcp_rules.go index ca4ef3c0..9db42f31 100644 --- a/internal/context/pfcp_rules.go +++ b/internal/context/pfcp_rules.go @@ -11,6 +11,7 @@ const ( RULE_CREATE RuleState = 1 RULE_UPDATE RuleState = 2 RULE_REMOVE RuleState = 3 + RULE_QUERY RuleState = 4 ) type RuleState uint8 @@ -44,8 +45,10 @@ type URR struct { MeasureMethod string // vol or time ReportingTrigger pfcpType.ReportingTriggers MeasurementPeriod time.Duration + QuotaValidityTime time.Time MeasurementInformation pfcpType.MeasurementInformation VolumeThreshold uint64 + VolumeQuota uint64 State RuleState } @@ -60,16 +63,31 @@ func NewMeasureInformation(isMeasurePkt, isMeasureBeforeQos bool) UrrOpt { func NewMeasurementPeriod(time time.Duration) UrrOpt { return func(urr *URR) { + urr.ReportingTrigger.Perio = true urr.MeasurementPeriod = time } } func NewVolumeThreshold(threshold uint64) UrrOpt { return func(urr *URR) { + urr.ReportingTrigger.Volth = true urr.VolumeThreshold = threshold } } +func NewVolumeQuota(quota uint64) UrrOpt { + return func(urr *URR) { + urr.ReportingTrigger.Volqu = true + urr.VolumeQuota = quota + } +} + +func SetStartofSDFTrigger() UrrOpt { + return func(urr *URR) { + urr.ReportingTrigger.Start = true + } +} + func MeasureInformation(isMeasurePkt, isMeasureBeforeQos bool) pfcpType.MeasurementInformation { var measureInformation pfcpType.MeasurementInformation measureInformation.Mnop = isMeasurePkt diff --git a/internal/context/sm_context.go b/internal/context/sm_context.go index 4774cb24..74df2c62 100644 --- a/internal/context/sm_context.go +++ b/internal/context/sm_context.go @@ -20,6 +20,7 @@ import ( "github.com/free5gc/ngap/ngapType" "github.com/free5gc/openapi" "github.com/free5gc/openapi/Namf_Communication" + "github.com/free5gc/openapi/Nchf_ConvergedCharging" "github.com/free5gc/openapi/Nnrf_NFDiscovery" "github.com/free5gc/openapi/Npcf_SMPolicyControl" "github.com/free5gc/openapi/models" @@ -100,6 +101,7 @@ type EventExposureNotification struct { type UsageReport struct { UrrId uint32 + UpfId string TotalVolume uint64 UplinkVolume uint64 @@ -154,9 +156,11 @@ type SMContext struct { // Client SMPolicyClient *Npcf_SMPolicyControl.APIClient CommunicationClient *Namf_Communication.APIClient + ChargingClient *Nchf_ConvergedCharging.APIClient AMFProfile models.NfProfile SelectedPCFProfile models.NfProfile + SelectedCHFProfile models.NfProfile SmStatusNotifyUri string Tunnel *UPTunnel @@ -172,6 +176,7 @@ type SMContext struct { PCCRules map[string]*PCCRule SessionRules map[string]*SessionRule TrafficControlDatas map[string]*TrafficControlData + ChargingData map[string]*models.ChargingData QosDatas map[string]*models.QosData UpPathChgEarlyNotification map[string]*EventExposureNotification // Key: Uri+NotifId @@ -199,6 +204,18 @@ type SMContext struct { UrrReportThreshold uint64 UrrReports []UsageReport + // Charging Related + ChargingDataRef string + // Each PDU session has a unique charging id + ChargingID int32 + RequestedUnit int32 + // key = urrid + // All urr can map to a rating group + // However, a rating group may map to more than one urr + // e.g. In UL CL case, the rating group for recoreding PDU Session volume may map to two URR + // one is for PSA 1, the other is for PSA 2. + // Note: the premise is that urrid in a pdu session is unique, urr in same or different upf cannot have the same urrid + ChargingInfo map[uint32]*ChargingInfo // NAS Pti uint8 EstAcceptCause5gSMValue uint8 @@ -281,11 +298,15 @@ func NewSMContext(id string, pduSessID int32) *SMContext { smContext.GenerateUrrId() smContext.UrrUpfMap = make(map[string]*URR) + smContext.ChargingInfo = make(map[uint32]*ChargingInfo) + smContext.ChargingID = GenerateChargingID() + if factory.SmfConfig.Configuration != nil { smContext.UrrReportTime = time.Duration(factory.SmfConfig.Configuration.UrrPeriod) * time.Second smContext.UrrReportThreshold = factory.SmfConfig.Configuration.UrrThreshold logger.CtxLog.Infof("UrrPeriod: %v", smContext.UrrReportTime) logger.CtxLog.Infof("UrrThreshold: %d", smContext.UrrReportThreshold) + smContext.RequestedUnit = factory.SmfConfig.Configuration.RequestedUnit } return smContext @@ -408,6 +429,52 @@ func (smContext *SMContext) PDUAddressToNAS() ([12]byte, uint8) { return addr, addrLen } +// CHFSelection will select CHF for this SM Context +func (smContext *SMContext) CHFSelection() error { + // Send NFDiscovery for find CHF + localVarOptionals := Nnrf_NFDiscovery.SearchNFInstancesParamOpts{ + // Supi: optional.NewString(smContext.Supi), + } + + rep, res, err := GetSelf(). + NFDiscoveryClient. + NFInstancesStoreApi. + SearchNFInstances(context.TODO(), models.NfType_CHF, models.NfType_SMF, &localVarOptionals) + if err != nil { + return err + } + defer func() { + if rspCloseErr := res.Body.Close(); rspCloseErr != nil { + logger.PduSessLog.Errorf("SmfEventExposureNotification response body cannot close: %+v", rspCloseErr) + } + }() + + if res != nil { + if status := res.StatusCode; status != http.StatusOK { + apiError := err.(openapi.GenericOpenAPIError) + problemDetails := apiError.Model().(models.ProblemDetails) + + logger.CtxLog.Warningf("NFDiscovery SMF return status: %d\n", status) + logger.CtxLog.Warningf("Detail: %v\n", problemDetails.Title) + } + } + + // Select CHF from available CHF + + smContext.SelectedCHFProfile = rep.NfInstances[0] + + // Create Converged Charging Client for this SM Context + for _, service := range *smContext.SelectedCHFProfile.NfServices { + if service.ServiceName == models.ServiceName_NCHF_CONVERGEDCHARGING { + ConvergedChargingConf := Nchf_ConvergedCharging.NewConfiguration() + ConvergedChargingConf.SetBasePath(service.ApiPrefix) + smContext.ChargingClient = Nchf_ConvergedCharging.NewAPIClient(ConvergedChargingConf) + } + } + + return nil +} + // PCFSelection will select PCF for this SM Context func (smContext *SMContext) PCFSelection() error { // Send NFDiscovery for find PCF @@ -595,6 +662,7 @@ func (c *SMContext) SelectDefaultDataPath() error { func (c *SMContext) CreatePccRuleDataPath(pccRule *PCCRule, tcData *TrafficControlData, qosData *models.QosData, + chgData *models.ChargingData, ) error { var targetRoute models.RouteToLocation if tcData != nil && len(tcData.RouteToLocs) > 0 { @@ -618,6 +686,13 @@ func (c *SMContext) CreatePccRuleDataPath(pccRule *PCCRule, c.Tunnel.AddDataPath(createdDataPath) pccRule.Datapath = createdDataPath pccRule.AddDataPathForwardingParameters(c, &targetRoute) + + if chgLevel, err := pccRule.IdentifyChargingLevel(); err != nil { + c.Log.Warnf("fail to identify charging level[%+v] for pcc rule[%s]", err, pccRule.PccRuleId) + } else { + pccRule.Datapath.AddChargingRules(c, chgLevel, chgData) + } + pccRule.Datapath.AddQoS(c, pccRule.QFI, qosData) c.AddQosFlow(pccRule.QFI, qosData) return nil diff --git a/internal/context/sm_context_policy.go b/internal/context/sm_context_policy.go index 4df99329..82147da5 100644 --- a/internal/context/sm_context_policy.go +++ b/internal/context/sm_context_policy.go @@ -68,6 +68,42 @@ func (c *SMContext) RemoveQosFlow(qfi uint8) { delete(c.AdditonalQosFlows, qfi) } +// For urr that created for Pdu session level charging, it show be applied to all data path +func (c *SMContext) addPduLevelChargingRuleToFlow(pccRules map[string]*PCCRule) { + var pduLevelChargingUrrs []*URR + var pccIdsForPduSession []string + + for id, pcc := range pccRules { + if chargingLevel, err := pcc.IdentifyChargingLevel(); err != nil { + continue + } else if chargingLevel == PduSessionCharging { + pccIdsForPduSession = append(pccIdsForPduSession, id) + } + } + + for _, pduPccid := range pccIdsForPduSession { + pduPcc := pccRules[pduPccid] + pduLevelChargingUrrs = pduPcc.Datapath.GetChargingUrr(c) + } + + for _, flowPcc := range pccRules { + if chgLevel, err := flowPcc.IdentifyChargingLevel(); err != nil { + continue + } else if chgLevel == FlowCharging { + for node := flowPcc.Datapath.FirstDPNode; node != nil; node = node.Next() { + if node.IsAnchorUPF() { + if node.UpLinkTunnel != nil && node.UpLinkTunnel.PDR != nil { + node.UpLinkTunnel.PDR.URR = append(node.UpLinkTunnel.PDR.URR, pduLevelChargingUrrs...) + } + if node.DownLinkTunnel != nil && node.DownLinkTunnel.PDR != nil { + node.DownLinkTunnel.PDR.URR = append(node.DownLinkTunnel.PDR.URR, pduLevelChargingUrrs...) + } + } + } + } + } +} + func (c *SMContext) ApplyPccRules( decision *models.SmPolicyDecision, ) error { @@ -78,7 +114,7 @@ func (c *SMContext) ApplyPccRules( finalPccRules := make(map[string]*PCCRule) finalTcDatas := make(map[string]*TrafficControlData) finalQosDatas := make(map[string]*models.QosData) - + finalChgDatas := make(map[string]*models.ChargingData) // Handle QoSData for id, qos := range decision.QosDecs { if qos == nil { @@ -106,12 +142,15 @@ func (c *SMContext) ApplyPccRules( tgtTcID := tgtPcc.RefTcDataID() _, tgtTcData = c.getSrcTgtTcData(decision.TraffContDecs, tgtTcID) + tgtChgID := tgtPcc.RefChgDataID() + _, tgtChgData := c.getSrcTgtChgData(decision.ChgDecs, tgtChgID) + tgtQosID := tgtPcc.RefQosDataID() _, tgtQosData := c.getSrcTgtQosData(decision.QosDecs, tgtQosID) tgtPcc.SetQFI(c.AssignQFI(tgtQosID)) // Create Data path for targetPccRule - if err := c.CreatePccRuleDataPath(tgtPcc, tgtTcData, tgtQosData); err != nil { + if err := c.CreatePccRuleDataPath(tgtPcc, tgtTcData, tgtQosData, tgtChgData); err != nil { return err } if srcPcc != nil { @@ -145,15 +184,19 @@ func (c *SMContext) ApplyPccRules( tcID := pcc.RefTcDataID() srcTcData, tgtTcData := c.getSrcTgtTcData(decision.TraffContDecs, tcID) + chgID := pcc.RefChgDataID() + srcChgData, tgtChgData := c.getSrcTgtChgData(decision.ChgDecs, chgID) + qosID := pcc.RefQosDataID() srcQosData, tgtQosData := c.getSrcTgtQosData(decision.QosDecs, qosID) if !reflect.DeepEqual(srcTcData, tgtTcData) || - !reflect.DeepEqual(srcQosData, tgtQosData) { + !reflect.DeepEqual(srcQosData, tgtQosData) || + !reflect.DeepEqual(srcChgData, tgtChgData) { // Remove old Data path c.PreRemoveDataPath(pcc.Datapath) // Create new Data path - if err := c.CreatePccRuleDataPath(pcc, tgtTcData, tgtQosData); err != nil { + if err := c.CreatePccRuleDataPath(pcc, tgtTcData, tgtQosData, tgtChgData); err != nil { return err } if err := checkUpPathChgEvent(c, srcTcData, tgtTcData); err != nil { @@ -167,11 +210,18 @@ func (c *SMContext) ApplyPccRules( if qosID != "" { finalQosDatas[qosID] = tgtQosData } + if chgID != "" { + finalChgDatas[chgID] = tgtChgData + } } + // For PCC rule that is for Pdu session level charging, add the created session rules to all other flow + // so that all volume in the Pdu session could be recorded and charged for the Pdu session + c.addPduLevelChargingRuleToFlow(finalPccRules) c.PCCRules = finalPccRules c.TrafficControlDatas = finalTcDatas c.QosDatas = finalQosDatas + c.ChargingData = finalChgDatas return nil } @@ -192,6 +242,23 @@ func (c *SMContext) getSrcTgtTcData( return srcTcData, tgtTcData } +func (c *SMContext) getSrcTgtChgData( + decisionChgDecs map[string]*models.ChargingData, + chgID string, +) (*models.ChargingData, *models.ChargingData) { + if chgID == "" { + return nil, nil + } + + srcChgData := c.ChargingData[chgID] + tgtChgData := decisionChgDecs[chgID] + if tgtChgData == nil { + // no TcData in decision, use source TcData as target TcData + tgtChgData = srcChgData + } + return srcChgData, tgtChgData +} + func (c *SMContext) getSrcTgtQosData( decisionQosDecs map[string]*models.QosData, qosID string, diff --git a/internal/context/upf.go b/internal/context/upf.go index 8b11f475..ead327ac 100644 --- a/internal/context/upf.go +++ b/internal/context/upf.go @@ -109,6 +109,14 @@ type UPFInterfaceInfo struct { EndpointFQDN string } +func GetUpfById(uuid string) *UPF { + upf, ok := upfPool.Load(uuid) + if ok { + return upf.(*UPF) + } + return nil +} + // NewUPFInterfaceInfo parse the InterfaceUpfInfoItem to generate UPFInterfaceInfo func NewUPFInterfaceInfo(i *factory.InterfaceUpfInfoItem) *UPFInterfaceInfo { interfaceInfo := new(UPFInterfaceInfo) @@ -542,8 +550,6 @@ func (upf *UPF) AddURR(urrId uint32, opts ...UrrOpt) (*URR, error) { urr := new(URR) urr.MeasureMethod = MesureMethodVol urr.MeasurementInformation = MeasureInformation(true, false) - urr.ReportingTrigger.Perio = true - urr.ReportingTrigger.Volth = true for _, opt := range opts { opt(urr) diff --git a/internal/logger/logger.go b/internal/logger/logger.go index 81936e74..ca2ef96f 100644 --- a/internal/logger/logger.go +++ b/internal/logger/logger.go @@ -23,6 +23,7 @@ var ( GsmLog *logrus.Entry PfcpLog *logrus.Entry PduSessLog *logrus.Entry + ChargingLog *logrus.Entry ) func init() { @@ -42,4 +43,5 @@ func init() { GsmLog = NfLog.WithField(logger_util.FieldCategory, "GSM") PfcpLog = NfLog.WithField(logger_util.FieldCategory, "PFCP") PduSessLog = NfLog.WithField(logger_util.FieldCategory, "PduSess") + ChargingLog = NfLog.WithField(logger_util.FieldCategory, "Charging") } diff --git a/internal/pfcp/handler/handler.go b/internal/pfcp/handler/handler.go index 926f8025..b048f0dd 100644 --- a/internal/pfcp/handler/handler.go +++ b/internal/pfcp/handler/handler.go @@ -11,6 +11,7 @@ import ( smf_context "github.com/free5gc/smf/internal/context" "github.com/free5gc/smf/internal/logger" pfcp_message "github.com/free5gc/smf/internal/pfcp/message" + "github.com/free5gc/smf/internal/sbi/producer" ) func HandlePfcpHeartbeatRequest(msg *pfcpUdp.Message) { @@ -190,54 +191,16 @@ func HandlePfcpSessionReportRequest(msg *pfcpUdp.Message) { } if req.ReportType.Usar && req.UsageReport != nil { - HandleReports(req.UsageReport, nil, nil, smContext, upfNodeID) + smContext.HandleReports(req.UsageReport, nil, nil, upfNodeID, "") + // After recieving the Usage Report, it should send charging request to the CHF + // and update the URR with the quota or other charging information according to + // the charging response + go func() { + producer.ReportUsageAndUpdateQuota(smContext) + }() } // TS 23.502 4.2.3.3 2b. Send Data Notification Ack, SMF->UPF cause.CauseValue = pfcpType.CauseRequestAccepted pfcp_message.SendPfcpSessionReportResponse(msg.RemoteAddr, cause, seqFromUPF, remoteSEID) } - -func HandleReports( - UsageReportReport []*pfcp.UsageReportPFCPSessionReportRequest, - UsageReportModification []*pfcp.UsageReportPFCPSessionModificationResponse, - UsageReportDeletion []*pfcp.UsageReportPFCPSessionDeletionResponse, - smContext *smf_context.SMContext, - nodeId pfcpType.NodeID, -) { - var usageReport smf_context.UsageReport - - for _, report := range UsageReportReport { - usageReport.UrrId = report.URRID.UrrIdValue - usageReport.TotalVolume = report.VolumeMeasurement.TotalVolume - usageReport.UplinkVolume = report.VolumeMeasurement.UplinkVolume - usageReport.DownlinkVolume = report.VolumeMeasurement.DownlinkVolume - usageReport.TotalPktNum = report.VolumeMeasurement.TotalPktNum - usageReport.UplinkPktNum = report.VolumeMeasurement.UplinkPktNum - usageReport.DownlinkPktNum = report.VolumeMeasurement.DownlinkPktNum - - smContext.UrrReports = append(smContext.UrrReports, usageReport) - } - for _, report := range UsageReportModification { - usageReport.UrrId = report.URRID.UrrIdValue - usageReport.TotalVolume = report.VolumeMeasurement.TotalVolume - usageReport.UplinkVolume = report.VolumeMeasurement.UplinkVolume - usageReport.DownlinkVolume = report.VolumeMeasurement.DownlinkVolume - usageReport.TotalPktNum = report.VolumeMeasurement.TotalPktNum - usageReport.UplinkPktNum = report.VolumeMeasurement.UplinkPktNum - usageReport.DownlinkPktNum = report.VolumeMeasurement.DownlinkPktNum - - smContext.UrrReports = append(smContext.UrrReports, usageReport) - } - for _, report := range UsageReportDeletion { - usageReport.UrrId = report.URRID.UrrIdValue - usageReport.TotalVolume = report.VolumeMeasurement.TotalVolume - usageReport.UplinkVolume = report.VolumeMeasurement.UplinkVolume - usageReport.DownlinkVolume = report.VolumeMeasurement.DownlinkVolume - usageReport.TotalPktNum = report.VolumeMeasurement.TotalPktNum - usageReport.UplinkPktNum = report.VolumeMeasurement.UplinkPktNum - usageReport.DownlinkPktNum = report.VolumeMeasurement.DownlinkPktNum - - smContext.UrrReports = append(smContext.UrrReports, usageReport) - } -} diff --git a/internal/pfcp/message/build.go b/internal/pfcp/message/build.go index 73313ce6..7a688628 100644 --- a/internal/pfcp/message/build.go +++ b/internal/pfcp/message/build.go @@ -200,6 +200,12 @@ func urrToCreateURR(urr *context.URR) *pfcp.CreateURR { MeasurementPeriod: uint32(urr.MeasurementPeriod / time.Second), } } + if !urr.QuotaValidityTime.IsZero() { + createURR.QuotaValidityTime = &pfcpType.QuotaValidityTime{ + QuotaValidityTime: uint32(urr.QuotaValidityTime.Sub(time.Date(1900, time.January, 1, 0, 0, 0, 0, time.UTC)) / 1000000000), + } + } + if urr.VolumeThreshold != 0 { createURR.VolumeThreshold = &pfcpType.VolumeThreshold{ Dlvol: true, @@ -208,6 +214,17 @@ func urrToCreateURR(urr *context.URR) *pfcp.CreateURR { UplinkVolume: urr.VolumeThreshold, } } + if urr.VolumeQuota != 0 { + createURR.VolumeQuota = &pfcpType.VolumeQuota{ + Tovol: true, + Dlvol: true, + Ulvol: true, + TotalVolume: urr.VolumeQuota, + DownlinkVolume: urr.VolumeQuota, + UplinkVolume: urr.VolumeQuota, + } + } + createURR.MeasurementInformation = &urr.MeasurementInformation return createURR @@ -249,6 +266,14 @@ func pdrToUpdatePDR(pdr *context.PDR) *pfcp.UpdatePDR { FarIdValue: pdr.FAR.FARID, } + for _, urr := range pdr.URR { + if urr != nil { + updatePDR.URRID = append(updatePDR.URRID, &pfcpType.URRID{ + UrrIdValue: urr.URRID, + }) + } + } + return updatePDR } @@ -290,6 +315,54 @@ func farToUpdateFAR(far *context.FAR) *pfcp.UpdateFAR { return updateFAR } +func urrToUpdateURR(urr *context.URR) *pfcp.UpdateURR { + updateURR := new(pfcp.UpdateURR) + + updateURR.URRID = &pfcpType.URRID{ + UrrIdValue: urr.URRID, + } + updateURR.MeasurementMethod = &pfcpType.MeasurementMethod{} + switch urr.MeasureMethod { + case context.MesureMethodVol: + updateURR.MeasurementMethod.Volum = true + case context.MesureMethodTime: + updateURR.MeasurementMethod.Durat = true + } + updateURR.ReportingTriggers = &urr.ReportingTrigger + if urr.MeasurementPeriod != 0 { + updateURR.MeasurementPeriod = &pfcpType.MeasurementPeriod{ + MeasurementPeriod: uint32(urr.MeasurementPeriod / time.Second), + } + } + if urr.QuotaValidityTime.IsZero() { + updateURR.QuotaValidityTime = &pfcpType.QuotaValidityTime{ + QuotaValidityTime: uint32(urr.QuotaValidityTime.Sub(time.Date(1900, time.January, 1, 0, 0, 0, 0, time.UTC)) / 1000000000), + } + } + + if urr.VolumeThreshold != 0 { + updateURR.VolumeThreshold = &pfcpType.VolumeThreshold{ + Dlvol: true, + Ulvol: true, + DownlinkVolume: urr.VolumeThreshold, + UplinkVolume: urr.VolumeThreshold, + } + } + if urr.VolumeQuota != 0 { + updateURR.VolumeQuota = &pfcpType.VolumeQuota{ + Tovol: true, + Dlvol: true, + Ulvol: true, + TotalVolume: urr.VolumeQuota, + DownlinkVolume: urr.VolumeQuota, + UplinkVolume: urr.VolumeQuota, + } + } + updateURR.MeasurementInformation = &urr.MeasurementInformation + + return updateURR +} + func BuildPfcpSessionEstablishmentRequest( upNodeID pfcpType.NodeID, upN4Addr string, @@ -427,6 +500,7 @@ func BuildPfcpSessionModificationRequest( msg.UpdatePDR = make([]*pfcp.UpdatePDR, 0, 2) msg.UpdateFAR = make([]*pfcp.UpdateFAR, 0, 2) + msg.UpdateURR = make([]*pfcp.UpdateURR, 0, 12) nodeIDtoIP := upNodeID.ResolveNodeIdToIp().String() @@ -490,6 +564,20 @@ func BuildPfcpSessionModificationRequest( switch urr.State { case context.RULE_INITIAL: msg.CreateURR = append(msg.CreateURR, urrToCreateURR(urr)) + case context.RULE_UPDATE: + msg.UpdateURR = append(msg.UpdateURR, urrToUpdateURR(urr)) + case context.RULE_REMOVE: + msg.RemoveURR = append(msg.RemoveURR, &pfcp.RemoveURR{ + URRID: &pfcpType.URRID{ + UrrIdValue: urr.URRID, + }, + }) + case context.RULE_QUERY: + msg.QueryURR = append(msg.QueryURR, &pfcp.QueryURR{ + URRID: &pfcpType.URRID{ + UrrIdValue: urr.URRID, + }, + }) } urr.State = context.RULE_CREATE } diff --git a/internal/sbi/callback/api_default.go b/internal/sbi/callback/api_default.go index 3fea413f..4e168e6e 100644 --- a/internal/sbi/callback/api_default.go +++ b/internal/sbi/callback/api_default.go @@ -11,6 +11,7 @@ package callback import ( "net/http" + "strings" "github.com/gin-gonic/gin" @@ -60,3 +61,38 @@ func HTTPSmPolicyUpdateNotification(c *gin.Context) { func SmPolicyControlTerminationRequestNotification(c *gin.Context) { c.JSON(http.StatusOK, gin.H{}) } + +func HTTPChargingNotification(c *gin.Context) { + var req models.ChargingNotifyRequest + + requestBody, err := c.GetRawData() + if err != nil { + logger.PduSessLog.Errorln("GetRawData failed") + } + + err = openapi.Deserialize(&req, requestBody, "application/json") + if err != nil { + logger.PduSessLog.Errorln("Deserialize request failed") + } + + reqWrapper := httpwrapper.NewRequest(c.Request, req) + reqWrapper.Params["notifyUri"] = c.Params.ByName("notifyUri") + smContextRef := strings.Split(reqWrapper.Params["notifyUri"], "_")[1] + + HTTPResponse := producer.HandleChargingNotification(reqWrapper.Body.(models.ChargingNotifyRequest), smContextRef) + + for key, val := range HTTPResponse.Header { + c.Header(key, val[0]) + } + + resBody, err := openapi.Serialize(HTTPResponse.Body, "application/json") + if err != nil { + logger.PduSessLog.Errorln("Serialize failed") + } + + _, err = c.Writer.Write(resBody) + if err != nil { + logger.PduSessLog.Errorln("Write failed") + } + c.Status(HTTPResponse.Status) +} diff --git a/internal/sbi/callback/routers.go b/internal/sbi/callback/routers.go index 745391f2..4d318d32 100644 --- a/internal/sbi/callback/routers.go +++ b/internal/sbi/callback/routers.go @@ -70,4 +70,10 @@ var routes = Routes{ "/sm-policies/:smContextRef/terminate", SmPolicyControlTerminationRequestNotification, }, + { + "ChargingNotification", + "POST", + "/:notifyUri", + HTTPChargingNotification, + }, } diff --git a/internal/sbi/consumer/converged_charging.go b/internal/sbi/consumer/converged_charging.go new file mode 100644 index 00000000..fa374b49 --- /dev/null +++ b/internal/sbi/consumer/converged_charging.go @@ -0,0 +1,105 @@ +package consumer + +import ( + "context" + "fmt" + "net/http" + "strings" + "time" + + "github.com/free5gc/nas/nasConvert" + "github.com/free5gc/openapi" + "github.com/free5gc/openapi/models" + smf_context "github.com/free5gc/smf/internal/context" + "github.com/free5gc/smf/internal/logger" +) + +func buildConvergedChargingRequest(smContext *smf_context.SMContext, multipleUnitUsage []models.MultipleUnitUsage) *models.ChargingDataRequest { + var triggers []models.Trigger + + smfSelf := smf_context.GetSelf() + date := time.Now() + + for _, unitUsage := range multipleUnitUsage { + for _, usedUnit := range unitUsage.UsedUnitContainer { + triggers = append(triggers, usedUnit.Triggers...) + } + } + + req := &models.ChargingDataRequest{ + ChargingId: smContext.ChargingID, + SubscriberIdentifier: smContext.Supi, + NfConsumerIdentification: &models.NfIdentification{ + NodeFunctionality: models.NodeFunctionality_SMF, + NFName: smfSelf.Name, + // not sure if NFIPv4Address is RegisterIPv4 or BindingIPv4 + NFIPv4Address: smfSelf.RegisterIPv4, + }, + InvocationTimeStamp: &date, + Triggers: triggers, + PDUSessionChargingInformation: &models.PduSessionChargingInformation{ + ChargingId: smContext.ChargingID, + UserInformation: &models.UserInformation{ + ServedGPSI: smContext.Gpsi, + ServedPEI: smContext.Pei, + }, + PduSessionInformation: &models.PduSessionInformation{ + PduSessionID: smContext.PDUSessionID, + NetworkSlicingInfo: &models.NetworkSlicingInfo{ + SNSSAI: smContext.SNssai, + }, + + PduType: nasConvert.PDUSessionTypeToModels(smContext.SelectedPDUSessionType), + ServingNetworkFunctionID: &models.ServingNetworkFunctionId{ + ServingNetworkFunctionInformation: &models.NfIdentification{ + NodeFunctionality: models.NodeFunctionality_AMF, + }, + }, + DnnId: smContext.Dnn, + }, + }, + NotifyUri: fmt.Sprintf("%s://%s:%d/nsmf-callback/notify_%s", + smf_context.GetSelf().URIScheme, + smf_context.GetSelf().RegisterIPv4, + smf_context.GetSelf().SBIPort, + smContext.Ref, + ), + MultipleUnitUsage: multipleUnitUsage, + } + + return req +} + +func SendConvergedChargingRequest(smContext *smf_context.SMContext, requestType smf_context.RequestType, multipleUnitUsage []models.MultipleUnitUsage) (*models.ChargingDataResponse, *models.ProblemDetails, error) { + logger.ChargingLog.Info("Handle SendConvergedChargingRequest") + + req := buildConvergedChargingRequest(smContext, multipleUnitUsage) + + var rsp models.ChargingDataResponse + var httpResponse *http.Response + var err error + + //select the appropriate converged charging service based on trigger type + switch requestType { + case smf_context.CHARGING_INIT: + rsp, httpResponse, err = smContext.ChargingClient.DefaultApi.ChargingdataPost(context.Background(), *req) + chargingDataRef := strings.Split(httpResponse.Header.Get("Location"), "/") + smContext.ChargingDataRef = chargingDataRef[len(chargingDataRef)-1] + case smf_context.CHARGING_UPDATE: + rsp, httpResponse, err = smContext.ChargingClient.DefaultApi.ChargingdataChargingDataRefUpdatePost(context.Background(), smContext.ChargingDataRef, *req) + case smf_context.CHARGING_RELEASE: + httpResponse, err = smContext.ChargingClient.DefaultApi.ChargingdataChargingDataRefReleasePost(context.Background(), smContext.ChargingDataRef, *req) + } + + if err == nil { + return &rsp, nil, nil + } else if httpResponse != nil { + if httpResponse.Status != err.Error() { + return nil, nil, err + } + problem := err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails) + return nil, &problem, nil + } else { + return nil, nil, openapi.ReportError("server no response") + } +} diff --git a/internal/sbi/producer/callback.go b/internal/sbi/producer/callback.go index 38067c27..fbb86b1b 100644 --- a/internal/sbi/producer/callback.go +++ b/internal/sbi/producer/callback.go @@ -2,6 +2,7 @@ package producer import ( "context" + "fmt" "net/http" "github.com/free5gc/openapi/Nsmf_EventExposure" @@ -11,6 +12,58 @@ import ( "github.com/free5gc/util/httpwrapper" ) +func HandleChargingNotification(chargingNotifyRequest models.ChargingNotifyRequest, smContextRef string) *httpwrapper.Response { + logger.ChargingLog.Info("Handle Charging Notification") + + problemDetails := chargingNotificationProcedure(chargingNotifyRequest, smContextRef) + if problemDetails != nil { + return httpwrapper.NewResponse(int(problemDetails.Status), nil, problemDetails) + } else { + return httpwrapper.NewResponse(http.StatusNoContent, nil, nil) + } +} + +// While recieve Charging Notification from CHF, SMF will send Charging Information to CHF and update UPF +func chargingNotificationProcedure(req models.ChargingNotifyRequest, smContextRef string) *models.ProblemDetails { + if smContext := smf_context.GetSMContextByRef(smContextRef); smContext != nil { + go func() { + upfUrrMap := make(map[string][]*smf_context.URR) + + for _, reauthorizeDetail := range req.ReauthorizationDetails { + rg := reauthorizeDetail.RatingGroup + logger.ChargingLog.Infof("Force update charging information for rating group %d", rg) + + for _, urr := range smContext.UrrUpfMap { + chgInfo := smContext.ChargingInfo[urr.URRID] + if chgInfo.RatingGroup == rg || + chgInfo.ChargingLevel == smf_context.PduSessionCharging { + logger.ChargingLog.Tracef("Query URR (%d) for Rating Group (%d)", urr.URRID, rg) + + upfId := smContext.ChargingInfo[urr.URRID].UpfId + upfUrrMap[upfId] = append(upfUrrMap[upfId], urr) + } + } + + } + + for upfId, urrList := range upfUrrMap { + upf := smf_context.GetUpfById(upfId) + QueryReport(smContext, upf, urrList, models.TriggerType_FORCED_REAUTHORISATION) + } + + ReportUsageAndUpdateQuota(smContext) + }() + } else { + problemDetails := &models.ProblemDetails{ + Status: http.StatusNotFound, + Cause: "CONTEXT_NOT_FOUND", + Detail: fmt.Sprintf("SM Context [%s] Not Found ", smContextRef), + } + return problemDetails + } + + return nil +} func HandleSMPolicyUpdateNotify(smContextRef string, request models.SmPolicyNotification) *httpwrapper.Response { logger.PduSessLog.Infoln("In HandleSMPolicyUpdateNotify") decision := request.SmPolicyDecision diff --git a/internal/sbi/producer/charging_trigger.go b/internal/sbi/producer/charging_trigger.go new file mode 100644 index 00000000..c9c7c9e1 --- /dev/null +++ b/internal/sbi/producer/charging_trigger.go @@ -0,0 +1,328 @@ +package producer + +import ( + "strings" + "time" + + "github.com/free5gc/openapi/models" + "github.com/free5gc/pfcp" + "github.com/free5gc/pfcp/pfcpType" + smf_context "github.com/free5gc/smf/internal/context" + "github.com/free5gc/smf/internal/logger" + pfcp_message "github.com/free5gc/smf/internal/pfcp/message" + "github.com/free5gc/smf/internal/sbi/consumer" +) + +func CreateChargingSession(smContext *smf_context.SMContext) { + _, problemDetails, err := consumer.SendConvergedChargingRequest(smContext, smf_context.CHARGING_INIT, nil) + if problemDetails != nil { + logger.ChargingLog.Errorf("Send Charging Data Request[Init] Failed Problem[%+v]", problemDetails) + } else if err != nil { + logger.ChargingLog.Errorf("Send Charging Data Request[Init] Error[%+v]", err) + } else { + logger.ChargingLog.Infof("Send Charging Data Request[Init] successfully") + } +} + +func UpdateChargingSession(smContext *smf_context.SMContext, urrList []*smf_context.URR, trigger models.Trigger) { + var multipleUnitUsage []models.MultipleUnitUsage + + for _, urr := range urrList { + if chgInfo := smContext.ChargingInfo[urr.URRID]; chgInfo != nil { + + rg := chgInfo.RatingGroup + logger.PduSessLog.Tracef("Recieve Usage Report from URR[%d], correspopnding Rating Group[%d], ChargingMethod %v", urr.URRID, rg, chgInfo.ChargingMethod) + triggerTime := time.Now() + + uu := models.UsedUnitContainer{ + QuotaManagementIndicator: chgInfo.ChargingMethod, + Triggers: []models.Trigger{trigger}, + TriggerTimestamp: &triggerTime, + } + + muu := models.MultipleUnitUsage{ + RatingGroup: rg, + UPFID: chgInfo.UpfId, + UsedUnitContainer: []models.UsedUnitContainer{uu}, + } + + multipleUnitUsage = append(multipleUnitUsage, muu) + } + } + + _, problemDetails, err := consumer.SendConvergedChargingRequest(smContext, smf_context.CHARGING_UPDATE, multipleUnitUsage) + if problemDetails != nil { + logger.ChargingLog.Errorf("Send Charging Data Request[Init] Failed Problem[%+v]", problemDetails) + } else if err != nil { + logger.ChargingLog.Errorf("Send Charging Data Request[Init] Error[%+v]", err) + } else { + logger.ChargingLog.Infof("Send Charging Data Request[Init] successfully") + } +} + +func ReleaseChargingSession(smContext *smf_context.SMContext) { + multipleUnitUsage := buildMultiUnitUsageFromUsageReport(smContext) + + _, problemDetails, err := consumer.SendConvergedChargingRequest(smContext, smf_context.CHARGING_RELEASE, multipleUnitUsage) + if problemDetails != nil { + logger.ChargingLog.Errorf("Send Charging Data Request[Termination] Failed Problem[%+v]", problemDetails) + } else if err != nil { + logger.ChargingLog.Errorf("Send Charging Data Request[Termination] Error[%+v]", err) + } else { + logger.ChargingLog.Infof("Send Charging Data Request[Termination] successfully") + } +} + +// Report usage report to the CHF and update the URR with the charging information in the charging response +func ReportUsageAndUpdateQuota(smContext *smf_context.SMContext) { + multipleUnitUsage := buildMultiUnitUsageFromUsageReport(smContext) + + if len(multipleUnitUsage) != 0 { + rsp, problemDetails, err := consumer.SendConvergedChargingRequest(smContext, smf_context.CHARGING_UPDATE, multipleUnitUsage) + + if problemDetails != nil { + logger.ChargingLog.Errorf("Send Charging Data Request[Update] Failed Problem[%+v]", problemDetails) + } else if err != nil { + logger.ChargingLog.Errorf("Send Charging Data Request[Update] Error[%+v]", err) + } else { + var pfcpResponseStatus smf_context.PFCPSessionResponseStatus + + upfUrrMap := make(map[string][]*smf_context.URR) + + logger.ChargingLog.Infof("Send Charging Data Request[Update] successfully") + smContext.SetState(smf_context.PFCPModification) + + updateGrantedQuota(smContext, rsp.MultipleUnitInformation) + // Usually only the anchor UPF need to be updated + for _, urr := range smContext.UrrUpfMap { + upfId := smContext.ChargingInfo[urr.URRID].UpfId + + if urr.State == smf_context.RULE_UPDATE { + upfUrrMap[upfId] = append(upfUrrMap[upfId], urr) + } + } + + if len(upfUrrMap) == 0 { + logger.ChargingLog.Infof("Do not have urr that need to update charging information") + return + } + + for upfId, urrList := range upfUrrMap { + upf := smf_context.GetUpfById(upfId) + rcvMsg, err := pfcp_message.SendPfcpSessionModificationRequest( + upf, smContext, nil, nil, nil, nil, urrList) + if err != nil { + logger.PduSessLog.Warnf("Sending PFCP Session Modification Request to AN UPF error: %+v", err) + pfcpResponseStatus = smf_context.SessionUpdateFailed + } + + logger.PduSessLog.Infoln("Received PFCP Session Modification Response") + pfcpResponseStatus = smf_context.SessionUpdateSuccess + + rsp := rcvMsg.PfcpMessage.Body.(pfcp.PFCPSessionModificationResponse) + if rsp.Cause == nil || rsp.Cause.CauseValue != pfcpType.CauseRequestAccepted { + logger.PduSessLog.Warn("Received PFCP Session Modification Not Accepted Response from AN UPF") + pfcpResponseStatus = smf_context.SessionUpdateFailed + } + + switch pfcpResponseStatus { + case smf_context.SessionUpdateSuccess: + logger.PfcpLog.Traceln("In case SessionUpdateSuccess") + smContext.SetState(smf_context.Active) + case smf_context.SessionUpdateFailed: + logger.PfcpLog.Traceln("In case SessionUpdateFailed") + smContext.SetState(smf_context.Active) + } + } + } + } else { + logger.ChargingLog.Infof("No report need to be charged") + } +} + +func getUpfIdFromKey(key string) string { + upfIdUrridStr := strings.Split(key, ":") + return upfIdUrridStr[0] +} + +func buildMultiUnitUsageFromUsageReport(smContext *smf_context.SMContext) []models.MultipleUnitUsage { + var ratingGroupUnitUsagesMap map[int32]models.MultipleUnitUsage + var multipleUnitUsage []models.MultipleUnitUsage + + ratingGroupUnitUsagesMap = make(map[int32]models.MultipleUnitUsage) + for _, ur := range smContext.UrrReports { + if ur.ReportTpye != "" { + var triggers []models.Trigger + + chgInfo := smContext.ChargingInfo[ur.UrrId] + + if chgInfo.ChargingLevel == smf_context.FlowCharging && ur.ReportTpye == models.TriggerType_VOLUME_LIMIT { + triggers = []models.Trigger{ + { + TriggerType: ur.ReportTpye, + TriggerCategory: models.TriggerCategory_DEFERRED_REPORT, + }, + } + } else { + triggers = []models.Trigger{ + { + TriggerType: ur.ReportTpye, + TriggerCategory: models.TriggerCategory_IMMEDIATE_REPORT, + }, + } + } + + rg := chgInfo.RatingGroup + logger.PduSessLog.Tracef("Recieve Usage Report from URR[%d], correspopnding Rating Group[%d], ChargingMethod %v", ur.UrrId, rg, chgInfo.ChargingMethod) + triggerTime := time.Now() + + uu := models.UsedUnitContainer{ + QuotaManagementIndicator: chgInfo.ChargingMethod, + Triggers: triggers, + TriggerTimestamp: &triggerTime, + DownlinkVolume: int32(ur.DownlinkVolume), + UplinkVolume: int32(ur.UplinkVolume), + TotalVolume: int32(ur.TotalVolume), + } + if unitUsage, ok := ratingGroupUnitUsagesMap[rg]; !ok { + ratingGroupUnitUsagesMap[rg] = models.MultipleUnitUsage{ + RatingGroup: rg, + UPFID: ur.UpfId, + UsedUnitContainer: []models.UsedUnitContainer{uu}, + RequestedUnit: &models.RequestedUnit{ + TotalVolume: smContext.RequestedUnit, + DownlinkVolume: smContext.RequestedUnit, + UplinkVolume: smContext.RequestedUnit, + }, + } + } else { + unitUsage.UsedUnitContainer = append(unitUsage.UsedUnitContainer, uu) + ratingGroupUnitUsagesMap[rg] = unitUsage + } + } else { + logger.PduSessLog.Tracef("Report for urr (%d) will not be charged", ur.UrrId) + } + } + + smContext.UrrReports = []smf_context.UsageReport{} + + for _, unitUsage := range ratingGroupUnitUsagesMap { + multipleUnitUsage = append(multipleUnitUsage, unitUsage) + } + + return multipleUnitUsage +} + +func getUrrByRg(smContext *smf_context.SMContext, upfId string, rg int32) *smf_context.URR { + for _, urr := range smContext.UrrUpfMap { + if smContext.ChargingInfo[urr.URRID] != nil && + smContext.ChargingInfo[urr.URRID].RatingGroup == rg && + smContext.ChargingInfo[urr.URRID].UpfId == upfId { + return urr + } + } + + return nil +} + +// Udate the urr by the charging information renewed by chf +func updateGrantedQuota(smContext *smf_context.SMContext, multipleUnitInformation []models.MultipleUnitInformation) { + for _, ui := range multipleUnitInformation { + trigger := pfcpType.ReportingTriggers{} + + rg := ui.RatingGroup + upfId := ui.UPFID + + if urr := getUrrByRg(smContext, upfId, rg); urr != nil { + urr.State = smf_context.RULE_UPDATE + chgInfo := smContext.ChargingInfo[urr.URRID] + + for _, t := range ui.Triggers { + switch t.TriggerType { + case models.TriggerType_VOLUME_LIMIT: + // According to 32.255, the for the trigger "Expirt of datavolume limit" have tow reporting level + // In the Pdu sesion level, the report should be "Immediate report", that is this report should send to CHF immediately + // In the Rating Group level, the report should be "Defferd report", that is this report should send to CHF when the in the next charging request triggereed + // by charging trigger that belongs to the type of immediate report + + // TODO: Currently CHF cannot identify the report level since it only knows the rating group, so the both charging level of "Expirt of datavolume limit" + // will be included in the report, and the report type will be determined by the SMF + switch chgInfo.ChargingLevel { + case smf_context.PduSessionCharging: + if t.TriggerCategory == models.TriggerCategory_IMMEDIATE_REPORT { + smContext.Log.Infof("Add Volume Limit Expiry Timer for Pdu session, it's rating group is [%d]", rg) + + chgInfo.VolumeLimitExpiryTimer = smf_context.NewTimer(time.Duration(t.VolumeLimit)*time.Second, 1, func(expireTimes int32) { + urrList := []*smf_context.URR{urr} + upf := smf_context.GetUpfById(ui.UPFID) + QueryReport(smContext, upf, urrList, models.TriggerType_VOLUME_LIMIT) + ReportUsageAndUpdateQuota(smContext) + }, func() { + smContext.Log.Tracef("Volume Limit Expiry for Pdu session, it's rating group is [%d]", rg) + chgInfo.VolumeLimitExpiryTimer.Stop() + chgInfo.VolumeLimitExpiryTimer = nil + }) + } + case smf_context.FlowCharging: + if t.TriggerCategory == models.TriggerCategory_DEFERRED_REPORT { + smContext.Log.Infof("Add Volume Limit Expiry Timer for rating group [%d] ", rg) + + chgInfo.VolumeLimitExpiryTimer = smf_context.NewTimer(time.Duration(t.VolumeLimit)*time.Second, 1, func(expireTimes int32) { + urrList := []*smf_context.URR{urr} + upf := smf_context.GetUpfById(ui.UPFID) + QueryReport(smContext, upf, urrList, models.TriggerType_VOLUME_LIMIT) + }, func() { + smContext.Log.Tracef("Volume Limit Expiry for rating group [%d]", rg) + chgInfo.VolumeLimitExpiryTimer.Stop() + chgInfo.VolumeLimitExpiryTimer = nil + }) + } + } + case models.TriggerType_MAX_NUMBER_OF_CHANGES_IN_CHARGING_CONDITIONS: + switch chgInfo.ChargingLevel { + case smf_context.PduSessionCharging: + chgInfo.EventLimitExpiryTimer = smf_context.NewTimer(time.Duration(t.EventLimit)*time.Second, 1, func(expireTimes int32) { + urrList := []*smf_context.URR{urr} + upf := smf_context.GetUpfById(ui.UPFID) + QueryReport(smContext, upf, urrList, models.TriggerType_VOLUME_LIMIT) + ReportUsageAndUpdateQuota(smContext) + }, func() { + smContext.Log.Tracef("Event Limit Expiry Timer is triggered") + chgInfo.EventLimitExpiryTimer = nil + }) + default: + smContext.Log.Tracef("MAX_NUMBER_OF_CHANGES_IN_CHARGING_CONDITIONS should only be applied to PDU session level charging") + } + case models.TriggerType_QUOTA_THRESHOLD: + if ui.VolumeQuotaThreshold != 0 { + trigger.Volth = true + urr.VolumeThreshold = uint64(ui.VolumeQuotaThreshold) + } + // The difference between the quota validity time and the volume limit is that the validity time is counted by the UPF, + // the volume limit is counted by the SMF + case models.TriggerType_VALIDITY_TIME: + if ui.ValidityTime != 0 { + urr.ReportingTrigger.Quvti = true + urr.QuotaValidityTime = time.Now().Add(time.Second * time.Duration(ui.ValidityTime)) + } + case models.TriggerType_QUOTA_EXHAUSTED: + if chgInfo.ChargingMethod == models.QuotaManagementIndicator_ONLINE_CHARGING { + if ui.GrantedUnit != nil { + trigger.Volqu = true + urr.VolumeQuota = uint64(ui.GrantedUnit.TotalVolume) + } else { + // No granted quota, so set the urr.VolumeQuota to 0, upf should stop send traffic + logger.ChargingLog.Warnf("No granted quota") + trigger.Volqu = true + urr.VolumeQuota = 0 + } + } + } + } + + urr.ReportingTrigger = trigger + } else { + logger.PduSessLog.Warnf("Do not find charging Information for rating group[%d]\n", rg) + } + } +} diff --git a/internal/sbi/producer/datapath.go b/internal/sbi/producer/datapath.go index 4604cab6..14051e0f 100644 --- a/internal/sbi/producer/datapath.go +++ b/internal/sbi/producer/datapath.go @@ -11,7 +11,6 @@ import ( "github.com/free5gc/pfcp/pfcpUdp" smf_context "github.com/free5gc/smf/internal/context" "github.com/free5gc/smf/internal/logger" - "github.com/free5gc/smf/internal/pfcp/handler" pfcp_message "github.com/free5gc/smf/internal/pfcp/message" ) @@ -90,7 +89,7 @@ func ActivateUPFSession( if !exist || sessionContext.RemoteSEID == 0 { go establishPfcpSession(smContext, pfcp, resChan) } else { - go modifyExistingPfcpSession(smContext, pfcp, resChan) + go modifyExistingPfcpSession(smContext, pfcp, resChan, "") } } @@ -98,6 +97,29 @@ func ActivateUPFSession( close(resChan) } +func QueryReport(smContext *smf_context.SMContext, upf *smf_context.UPF, urrs []*smf_context.URR, reportResaon models.TriggerType) { + smContext.SMLock.Lock() + defer smContext.SMLock.Unlock() + + for _, urr := range urrs { + urr.State = smf_context.RULE_QUERY + } + + pfcpState := &PFCPState{ + upf: upf, + urrList: urrs, + } + + resChan := make(chan SendPfcpResult) + go modifyExistingPfcpSession(smContext, pfcpState, resChan, reportResaon) + pfcpResult := <-resChan + + if pfcpResult.Err != nil { + logger.PduSessLog.Error("Query URR Report by PFCP Session Mod Request fail: %+v", pfcpResult.Err) + return + } +} + func establishPfcpSession(smContext *smf_context.SMContext, state *PFCPState, resCh chan<- SendPfcpResult, @@ -141,6 +163,7 @@ func modifyExistingPfcpSession( smContext *smf_context.SMContext, state *PFCPState, resCh chan<- SendPfcpResult, + reportResaon models.TriggerType, ) { logger.PduSessLog.Infoln("Sending PFCP Session Modification Request") @@ -166,7 +189,7 @@ func modifyExistingPfcpSession( if rsp.UsageReport != nil { SEID := rcvMsg.PfcpMessage.Header.SEID upfNodeID := smContext.GetNodeIDByLocalSEID(SEID) - handler.HandleReports(nil, rsp.UsageReport, nil, smContext, upfNodeID) + smContext.HandleReports(nil, rsp.UsageReport, nil, upfNodeID, reportResaon) } } else { resCh <- SendPfcpResult{ @@ -414,7 +437,7 @@ func deletePfcpSession(upf *smf_context.UPF, ctx *smf_context.SMContext, resCh c if rsp.UsageReport != nil { SEID := rcvMsg.PfcpMessage.Header.SEID upfNodeID := ctx.GetNodeIDByLocalSEID(SEID) - handler.HandleReports(nil, nil, rsp.UsageReport, ctx, upfNodeID) + ctx.HandleReports(nil, nil, rsp.UsageReport, upfNodeID, "") } } else { logger.PduSessLog.Warn("Received PFCP Session Deletion Not Accepted Response") diff --git a/internal/sbi/producer/pdu_session.go b/internal/sbi/producer/pdu_session.go index 086b097c..cacd0aeb 100644 --- a/internal/sbi/producer/pdu_session.go +++ b/internal/sbi/producer/pdu_session.go @@ -183,6 +183,15 @@ func HandlePDUSessionSMContextCreate(isDone <-chan struct{}, } smContext.SMPolicyID = smPolicyID + // PDU session create is a charging event + logger.PduSessLog.Infof("CHF Selection for SMContext SUPI[%s] PDUSessionID[%d]\n", + smContext.Supi, smContext.PDUSessionID) + if err := smContext.CHFSelection(); err != nil { + logger.PduSessLog.Errorln("chf selection error:", err) + } + + CreateChargingSession(smContext) + // Update SessionRule from decision if err := smContext.ApplySessionRules(smPolicyDecision); err != nil { smContext.Log.Errorf("PDUSessionSMContextCreate err: %v", err) @@ -432,6 +441,26 @@ func HandlePDUSessionSMContextUpdate(smContextRef string, body models.UpdateSmCo smContext.SetState(smf_context.ModificationPending) response.JsonData.UpCnxState = models.UpCnxState_DEACTIVATED smContext.UpCnxState = body.JsonData.UpCnxState + // UE location change is a charging event + // TODO: This is not tested yet + if smContext.UeLocation != body.JsonData.UeLocation { + var urrList []*smf_context.URR + + // All rating group related to this Pdu session should send charging request + for _, dataPath := range tunnel.DataPathPool { + if dataPath.Activated { + for curDataPathNode := dataPath.FirstDPNode; curDataPathNode != nil; curDataPathNode = curDataPathNode.Next() { + if curDataPathNode.IsANUPF() { + urrList = append(urrList, curDataPathNode.UpLinkTunnel.PDR.URR...) + QueryReport(smContext, curDataPathNode.UPF, urrList, models.TriggerType_USER_LOCATION_CHANGE) + } + } + } + } + + ReportUsageAndUpdateQuota(smContext) + } + smContext.UeLocation = body.JsonData.UeLocation // Set FAR and An, N3 Release Info @@ -863,7 +892,6 @@ func HandlePDUSessionSMContextRelease(smContextRef string, body models.ReleaseSm smContext.SetState(smf_context.PFCPModification) } pfcpResponseStatus := releaseSession(smContext) - var httpResponse *httpwrapper.Response switch pfcpResponseStatus { @@ -981,6 +1009,8 @@ func HandlePDUSessionSMContextLocalRelease(smContext *smf_context.SMContext, cre } func releaseSession(smContext *smf_context.SMContext) smf_context.PFCPSessionResponseStatus { + ReleaseChargingSession(smContext) + smContext.SetState(smf_context.PFCPModification) for _, res := range ReleaseTunnel(smContext) { diff --git a/internal/sbi/producer/ulcl_procedure.go b/internal/sbi/producer/ulcl_procedure.go index 71883e52..7a2e0aed 100644 --- a/internal/sbi/producer/ulcl_procedure.go +++ b/internal/sbi/producer/ulcl_procedure.go @@ -4,6 +4,7 @@ import ( "net" "reflect" + "github.com/free5gc/openapi/models" "github.com/free5gc/pfcp/pfcpType" "github.com/free5gc/pfcp/pfcpUdp" "github.com/free5gc/smf/internal/context" @@ -77,6 +78,19 @@ func EstablishPSA2(smContext *context.SMContext) { qerList := upLinkPDR.QER urrList := upLinkPDR.URR + chgUrrList := []*context.URR{} + for _, urr := range urrList { + if urr.ReportingTrigger.Start { + chgUrrList = append(chgUrrList, urr) + } + } + + // According to 32.255 5.2.2.7, Addition of additional PDU Session Anchor is a charging event + UpdateChargingSession(smContext, chgUrrList, models.Trigger{ + TriggerType: models.TriggerType_ADDITION_OF_UPF, + TriggerCategory: models.TriggerCategory_IMMEDIATE_REPORT, + }) + lastNode := node.Prev() if lastNode != nil && !reflect.DeepEqual(lastNode.UPF.NodeID, ulcl.NodeID) { @@ -100,7 +114,7 @@ func EstablishPSA2(smContext *context.SMContext) { if !exist || sessionContext.RemoteSEID == 0 { go establishPfcpSession(smContext, pfcpState, resChan) } else { - go modifyExistingPfcpSession(smContext, pfcpState, resChan) + go modifyExistingPfcpSession(smContext, pfcpState, resChan, "") } } else { if reflect.DeepEqual(node.UPF.NodeID, ulcl.NodeID) { @@ -170,7 +184,7 @@ func EstablishULCL(smContext *context.SMContext) { curDPNodeIP := ulcl.NodeID.ResolveNodeIdToIp().String() pendingUPFs = append(pendingUPFs, curDPNodeIP) - go modifyExistingPfcpSession(smContext, pfcpState, resChan) + go modifyExistingPfcpSession(smContext, pfcpState, resChan, "") break } } @@ -215,7 +229,7 @@ func UpdatePSA2DownLink(smContext *context.SMContext) { curDPNodeIP := node.UPF.NodeID.ResolveNodeIdToIp().String() pendingUPFs = append(pendingUPFs, curDPNodeIP) - go modifyExistingPfcpSession(smContext, pfcpState, resChan) + go modifyExistingPfcpSession(smContext, pfcpState, resChan, "") logger.PfcpLog.Info("[SMF] Update PSA2 downlink msg has been send") break } @@ -327,7 +341,7 @@ func UpdateRANAndIUPFUpLink(smContext *context.SMContext) { curDPNodeIP := curDPNode.UPF.NodeID.ResolveNodeIdToIp().String() pendingUPFs = append(pendingUPFs, curDPNodeIP) - go modifyExistingPfcpSession(smContext, pfcpState, resChan) + go modifyExistingPfcpSession(smContext, pfcpState, resChan, "") } } diff --git a/pkg/factory/config.go b/pkg/factory/config.go index b701cc4f..767e5a64 100644 --- a/pkg/factory/config.go +++ b/pkg/factory/config.go @@ -89,6 +89,7 @@ type Configuration struct { T3591 *TimerValue `yaml:"t3591" valid:"required"` T3592 *TimerValue `yaml:"t3592" valid:"required"` NwInstFqdnEncoding bool `yaml:"nwInstFqdnEncoding" valid:"type(bool),optional"` + RequestedUnit int32 `yaml:"requestedUnit,omitempty" valid:"optional"` } type Logger struct { From 8908ad583fafb18ba35968f8d5f913ddee8493de Mon Sep 17 00:00:00 2001 From: roy19991013 <80-ChienAn@users.noreply.gitlab.nems.cs.nctu.edu.tw> Date: Thu, 18 May 2023 23:29:59 -0700 Subject: [PATCH 02/32] flow status --- go.mod | 4 +++ go.sum | 3 -- internal/context/datapath.go | 55 ++++++++++++++++++++++++---------- internal/context/sm_context.go | 5 ++++ 4 files changed, 49 insertions(+), 18 deletions(-) diff --git a/go.mod b/go.mod index ecc1aa80..2f554142 100644 --- a/go.mod +++ b/go.mod @@ -66,3 +66,7 @@ require ( google.golang.org/protobuf v1.30.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) + +replace github.com/free5gc/openapi => /home/free5gc/openapi + +replace github.com/free5gc/pfcp => /home/free5gc/pfcp diff --git a/go.sum b/go.sum index 8c595740..871eed33 100644 --- a/go.sum +++ b/go.sum @@ -322,7 +322,6 @@ golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81R golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= @@ -373,7 +372,6 @@ golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -395,7 +393,6 @@ golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3 golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= diff --git a/internal/context/datapath.go b/internal/context/datapath.go index f46d28d1..2f970d6d 100644 --- a/internal/context/datapath.go +++ b/internal/context/datapath.go @@ -65,6 +65,7 @@ type DataPath struct { GBRFlow bool Destination Destination HasBranchingPoint bool + Flowstatus models.FlowStatus // Data Path Double Link List FirstDPNode *DataPathNode } @@ -386,7 +387,9 @@ func (datapath *DataPath) addUrrToPath(smContext *SMContext) { for curDataPathNode := datapath.FirstDPNode; curDataPathNode != nil; curDataPathNode = curDataPathNode.Next() { var MBQEUrrId uint32 var MAQEUrrId uint32 - + // If more than two data path will use the same UPF + // It may cause urr be created multiple times + // There may be some mechanism to make sure that existed URR should not be create again if curDataPathNode.IsANUPF() { if curDataPathNode.Next() == nil { MBQEUrrId = smContext.UrrIdMap[N3N6_MBEQ_URR] @@ -534,12 +537,24 @@ func (dataPath *DataPath) ActivateTunnelAndPDR(smContext *SMContext, precedence } ULFAR := ULPDR.FAR - ULFAR.ApplyAction = pfcpType.ApplyAction{ - Buff: false, - Drop: false, - Dupl: false, - Forw: true, - Nocp: false, + // If the flow is disable, the tunnel and the session rules will not be created + if dataPath.Flowstatus != models.FlowStatus_DISABLED && + dataPath.Flowstatus != models.FlowStatus_ENABLED_DOWNLINK { + ULFAR.ApplyAction = pfcpType.ApplyAction{ + Buff: false, + Drop: false, + Dupl: false, + Forw: true, + Nocp: false, + } + } else { + ULFAR.ApplyAction = pfcpType.ApplyAction{ + Buff: false, + Drop: true, + Dupl: false, + Forw: false, + Nocp: false, + } } ULFAR.ForwardingParameters = &ForwardingParameters{ DestinationInterface: pfcpType.DestinationInterface{ @@ -637,15 +652,25 @@ func (dataPath *DataPath) ActivateTunnelAndPDR(smContext *SMContext, precedence if nextDLDest := curDataPathNode.Prev(); nextDLDest != nil { logger.PduSessLog.Traceln("In DLPDR OuterHeaderCreation") nextDLTunnel := nextDLDest.DownLinkTunnel - - DLFAR.ApplyAction = pfcpType.ApplyAction{ - Buff: false, - Drop: false, - Dupl: false, - Forw: true, - Nocp: false, + // If the flow is disable, the tunnel and the session rules will not be created + if dataPath.Flowstatus != models.FlowStatus_DISABLED && + dataPath.Flowstatus != models.FlowStatus_ENABLED_UPLINK { + DLFAR.ApplyAction = pfcpType.ApplyAction{ + Buff: false, + Drop: false, + Dupl: false, + Forw: true, + Nocp: false, + } + } else { + DLFAR.ApplyAction = pfcpType.ApplyAction{ + Buff: false, + Drop: true, + Dupl: false, + Forw: false, + Nocp: false, + } } - iface = nextDLDest.UPF.GetInterface(models.UpInterfaceType_N9, smContext.Dnn) if upIP, err := iface.IP(smContext.SelectedPDUSessionType); err != nil { diff --git a/internal/context/sm_context.go b/internal/context/sm_context.go index 74df2c62..4d62232a 100644 --- a/internal/context/sm_context.go +++ b/internal/context/sm_context.go @@ -215,6 +215,7 @@ type SMContext struct { // e.g. In UL CL case, the rating group for recoreding PDU Session volume may map to two URR // one is for PSA 1, the other is for PSA 2. // Note: the premise is that urrid in a pdu session is unique, urr in same or different upf cannot have the same urrid + // TODO: curerrently have not tested the case where multiple urr share the same rating group ChargingInfo map[uint32]*ChargingInfo // NAS Pti uint8 @@ -681,6 +682,10 @@ func (c *SMContext) CreatePccRuleDataPath(pccRule *PCCRule, if createdDataPath == nil { return fmt.Errorf("fail to create data path for pcc rule[%s]", pccRule.PccRuleId) } + if tcData != nil { + createdDataPath.Flowstatus = tcData.FlowStatus + } + createdDataPath.GBRFlow = isGBRFlow(qosData) createdDataPath.ActivateTunnelAndPDR(c, uint32(pccRule.Precedence)) c.Tunnel.AddDataPath(createdDataPath) From fbf1c63b48e66c2cd9f8ebd1bfe9bb21ccb34050 Mon Sep 17 00:00:00 2001 From: roy19991013 <80-ChienAn@users.noreply.gitlab.nems.cs.nctu.edu.tw> Date: Mon, 22 May 2023 23:47:57 -0700 Subject: [PATCH 03/32] add pdu level charging urr to default data path --- internal/context/sm_context_policy.go | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/internal/context/sm_context_policy.go b/internal/context/sm_context_policy.go index 82147da5..e17ca82e 100644 --- a/internal/context/sm_context_policy.go +++ b/internal/context/sm_context_policy.go @@ -102,6 +102,18 @@ func (c *SMContext) addPduLevelChargingRuleToFlow(pccRules map[string]*PCCRule) } } } + + defaultPath := c.Tunnel.DataPathPool.GetDefaultPath() + for node := defaultPath.FirstDPNode; node != nil; node = node.Next() { + if node.IsAnchorUPF() { + if node.UpLinkTunnel != nil && node.UpLinkTunnel.PDR != nil { + node.UpLinkTunnel.PDR.URR = append(node.UpLinkTunnel.PDR.URR, pduLevelChargingUrrs...) + } + if node.DownLinkTunnel != nil && node.DownLinkTunnel.PDR != nil { + node.DownLinkTunnel.PDR.URR = append(node.DownLinkTunnel.PDR.URR, pduLevelChargingUrrs...) + } + } + } } func (c *SMContext) ApplyPccRules( From d236f2b21853119ec313648599c709c096ca8daf Mon Sep 17 00:00:00 2001 From: roy19991013 <80-ChienAn@users.noreply.gitlab.nems.cs.nctu.edu.tw> Date: Mon, 22 May 2023 23:48:27 -0700 Subject: [PATCH 04/32] fix: only onlince charging need to request unit --- internal/sbi/producer/charging_trigger.go | 29 +++++++++++++++++++---- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/internal/sbi/producer/charging_trigger.go b/internal/sbi/producer/charging_trigger.go index c9c7c9e1..f3121889 100644 --- a/internal/sbi/producer/charging_trigger.go +++ b/internal/sbi/producer/charging_trigger.go @@ -185,15 +185,24 @@ func buildMultiUnitUsageFromUsageReport(smContext *smf_context.SMContext) []mode TotalVolume: int32(ur.TotalVolume), } if unitUsage, ok := ratingGroupUnitUsagesMap[rg]; !ok { + requestUnit := &models.RequestedUnit{} + + // Only online charging should request unit + // offline charging is only for recording usage + switch chgInfo.ChargingMethod { + case models.QuotaManagementIndicator_ONLINE_CHARGING: + requestUnit = &models.RequestedUnit{ + TotalVolume: smContext.RequestedUnit, + DownlinkVolume: smContext.RequestedUnit, + UplinkVolume: smContext.RequestedUnit, + } + } + ratingGroupUnitUsagesMap[rg] = models.MultipleUnitUsage{ RatingGroup: rg, UPFID: ur.UpfId, UsedUnitContainer: []models.UsedUnitContainer{uu}, - RequestedUnit: &models.RequestedUnit{ - TotalVolume: smContext.RequestedUnit, - DownlinkVolume: smContext.RequestedUnit, - UplinkVolume: smContext.RequestedUnit, - }, + RequestedUnit: requestUnit, } } else { unitUsage.UsedUnitContainer = append(unitUsage.UsedUnitContainer, uu) @@ -252,6 +261,11 @@ func updateGrantedQuota(smContext *smf_context.SMContext, multipleUnitInformatio if t.TriggerCategory == models.TriggerCategory_IMMEDIATE_REPORT { smContext.Log.Infof("Add Volume Limit Expiry Timer for Pdu session, it's rating group is [%d]", rg) + if chgInfo.VolumeLimitExpiryTimer != nil { + chgInfo.VolumeLimitExpiryTimer.Stop() + chgInfo.VolumeLimitExpiryTimer = nil + } + chgInfo.VolumeLimitExpiryTimer = smf_context.NewTimer(time.Duration(t.VolumeLimit)*time.Second, 1, func(expireTimes int32) { urrList := []*smf_context.URR{urr} upf := smf_context.GetUpfById(ui.UPFID) @@ -267,6 +281,11 @@ func updateGrantedQuota(smContext *smf_context.SMContext, multipleUnitInformatio if t.TriggerCategory == models.TriggerCategory_DEFERRED_REPORT { smContext.Log.Infof("Add Volume Limit Expiry Timer for rating group [%d] ", rg) + if chgInfo.VolumeLimitExpiryTimer != nil { + chgInfo.VolumeLimitExpiryTimer.Stop() + chgInfo.VolumeLimitExpiryTimer = nil + } + chgInfo.VolumeLimitExpiryTimer = smf_context.NewTimer(time.Duration(t.VolumeLimit)*time.Second, 1, func(expireTimes int32) { urrList := []*smf_context.URR{urr} upf := smf_context.GetUpfById(ui.UPFID) From 4b3a277fa0ba66511800c8ea84f4e62bab3415e6 Mon Sep 17 00:00:00 2001 From: roy19991013 <80-ChienAn@users.noreply.gitlab.nems.cs.nctu.edu.tw> Date: Mon, 22 May 2023 23:48:51 -0700 Subject: [PATCH 05/32] fix: release charging session in all pdu session release case --- internal/sbi/producer/pdu_session.go | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/internal/sbi/producer/pdu_session.go b/internal/sbi/producer/pdu_session.go index cacd0aeb..8fb3e2c2 100644 --- a/internal/sbi/producer/pdu_session.go +++ b/internal/sbi/producer/pdu_session.go @@ -785,6 +785,8 @@ func HandlePDUSessionSMContextUpdate(smContextRef string, body models.UpdateSmCo } case smf_context.SessionReleaseSuccess: + ReleaseChargingSession(smContext) + smContext.Log.Traceln("In case SessionReleaseSuccess") smContext.SetState(smf_context.InActivePending) httpResponse = &httpwrapper.Response{ @@ -892,10 +894,13 @@ func HandlePDUSessionSMContextRelease(smContextRef string, body models.ReleaseSm smContext.SetState(smf_context.PFCPModification) } pfcpResponseStatus := releaseSession(smContext) + var httpResponse *httpwrapper.Response switch pfcpResponseStatus { case smf_context.SessionReleaseSuccess: + ReleaseChargingSession(smContext) + smContext.Log.Traceln("In case SessionReleaseSuccess") smContext.SetState(smf_context.InActive) httpResponse = &httpwrapper.Response{ @@ -979,6 +984,8 @@ func HandlePDUSessionSMContextLocalRelease(smContext *smf_context.SMContext, cre switch pfcpResponseStatus { case smf_context.SessionReleaseSuccess: + ReleaseChargingSession(smContext) + logger.CtxLog.Traceln("In case SessionReleaseSuccess") smContext.SetState(smf_context.InActivePending) if createData.SmContextStatusUri != smContext.SmStatusNotifyUri { @@ -1009,7 +1016,6 @@ func HandlePDUSessionSMContextLocalRelease(smContext *smf_context.SMContext, cre } func releaseSession(smContext *smf_context.SMContext) smf_context.PFCPSessionResponseStatus { - ReleaseChargingSession(smContext) smContext.SetState(smf_context.PFCPModification) From 29b6f398d70f591a0fdf9e7e5a54bd7075abc0e3 Mon Sep 17 00:00:00 2001 From: roy19991013 <80-ChienAn@users.noreply.gitlab.nems.cs.nctu.edu.tw> Date: Tue, 23 May 2023 23:20:34 -0700 Subject: [PATCH 06/32] fix: don't send charging request for non-charging urr --- internal/sbi/producer/charging_trigger.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/internal/sbi/producer/charging_trigger.go b/internal/sbi/producer/charging_trigger.go index f3121889..e37ba66c 100644 --- a/internal/sbi/producer/charging_trigger.go +++ b/internal/sbi/producer/charging_trigger.go @@ -155,6 +155,10 @@ func buildMultiUnitUsageFromUsageReport(smContext *smf_context.SMContext) []mode var triggers []models.Trigger chgInfo := smContext.ChargingInfo[ur.UrrId] + if chgInfo == nil { + logger.PduSessLog.Tracef("URR %d is not for charging", ur.UrrId) + continue + } if chgInfo.ChargingLevel == smf_context.FlowCharging && ur.ReportTpye == models.TriggerType_VOLUME_LIMIT { triggers = []models.Trigger{ From c56f0f85ea36564511cd48d2671c7162b09039e8 Mon Sep 17 00:00:00 2001 From: roy19991013 <80-ChienAn@users.noreply.gitlab.nems.cs.nctu.edu.tw> Date: Thu, 25 May 2023 03:14:07 -0700 Subject: [PATCH 07/32] rm untested code --- internal/context/datapath.go | 51 +++++++++++----------------------- internal/context/sm_context.go | 3 -- 2 files changed, 16 insertions(+), 38 deletions(-) diff --git a/internal/context/datapath.go b/internal/context/datapath.go index 2f970d6d..4e0b6538 100644 --- a/internal/context/datapath.go +++ b/internal/context/datapath.go @@ -65,7 +65,6 @@ type DataPath struct { GBRFlow bool Destination Destination HasBranchingPoint bool - Flowstatus models.FlowStatus // Data Path Double Link List FirstDPNode *DataPathNode } @@ -538,24 +537,15 @@ func (dataPath *DataPath) ActivateTunnelAndPDR(smContext *SMContext, precedence ULFAR := ULPDR.FAR // If the flow is disable, the tunnel and the session rules will not be created - if dataPath.Flowstatus != models.FlowStatus_DISABLED && - dataPath.Flowstatus != models.FlowStatus_ENABLED_DOWNLINK { - ULFAR.ApplyAction = pfcpType.ApplyAction{ - Buff: false, - Drop: false, - Dupl: false, - Forw: true, - Nocp: false, - } - } else { - ULFAR.ApplyAction = pfcpType.ApplyAction{ - Buff: false, - Drop: true, - Dupl: false, - Forw: false, - Nocp: false, - } + + ULFAR.ApplyAction = pfcpType.ApplyAction{ + Buff: false, + Drop: false, + Dupl: false, + Forw: true, + Nocp: false, } + ULFAR.ForwardingParameters = &ForwardingParameters{ DestinationInterface: pfcpType.DestinationInterface{ InterfaceValue: pfcpType.DestinationInterfaceCore, @@ -653,24 +643,15 @@ func (dataPath *DataPath) ActivateTunnelAndPDR(smContext *SMContext, precedence logger.PduSessLog.Traceln("In DLPDR OuterHeaderCreation") nextDLTunnel := nextDLDest.DownLinkTunnel // If the flow is disable, the tunnel and the session rules will not be created - if dataPath.Flowstatus != models.FlowStatus_DISABLED && - dataPath.Flowstatus != models.FlowStatus_ENABLED_UPLINK { - DLFAR.ApplyAction = pfcpType.ApplyAction{ - Buff: false, - Drop: false, - Dupl: false, - Forw: true, - Nocp: false, - } - } else { - DLFAR.ApplyAction = pfcpType.ApplyAction{ - Buff: false, - Drop: true, - Dupl: false, - Forw: false, - Nocp: false, - } + + DLFAR.ApplyAction = pfcpType.ApplyAction{ + Buff: false, + Drop: false, + Dupl: false, + Forw: true, + Nocp: false, } + iface = nextDLDest.UPF.GetInterface(models.UpInterfaceType_N9, smContext.Dnn) if upIP, err := iface.IP(smContext.SelectedPDUSessionType); err != nil { diff --git a/internal/context/sm_context.go b/internal/context/sm_context.go index 4d62232a..1b75fc09 100644 --- a/internal/context/sm_context.go +++ b/internal/context/sm_context.go @@ -682,9 +682,6 @@ func (c *SMContext) CreatePccRuleDataPath(pccRule *PCCRule, if createdDataPath == nil { return fmt.Errorf("fail to create data path for pcc rule[%s]", pccRule.PccRuleId) } - if tcData != nil { - createdDataPath.Flowstatus = tcData.FlowStatus - } createdDataPath.GBRFlow = isGBRFlow(qosData) createdDataPath.ActivateTunnelAndPDR(c, uint32(pccRule.Precedence)) From a2748901378e122fdee65005778ea68201a11927 Mon Sep 17 00:00:00 2001 From: Tim Liu Date: Fri, 11 Aug 2023 08:17:30 +0000 Subject: [PATCH 08/32] update openapi/pfcp hash --- go.mod | 4 ---- go.sum | 3 +++ internal/sbi/producer/datapath.go | 2 +- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/go.mod b/go.mod index 2f554142..ecc1aa80 100644 --- a/go.mod +++ b/go.mod @@ -66,7 +66,3 @@ require ( google.golang.org/protobuf v1.30.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) - -replace github.com/free5gc/openapi => /home/free5gc/openapi - -replace github.com/free5gc/pfcp => /home/free5gc/pfcp diff --git a/go.sum b/go.sum index 871eed33..8c595740 100644 --- a/go.sum +++ b/go.sum @@ -322,6 +322,7 @@ golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81R golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= @@ -372,6 +373,7 @@ golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -393,6 +395,7 @@ golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3 golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= diff --git a/internal/sbi/producer/datapath.go b/internal/sbi/producer/datapath.go index 14051e0f..f1701433 100644 --- a/internal/sbi/producer/datapath.go +++ b/internal/sbi/producer/datapath.go @@ -115,7 +115,7 @@ func QueryReport(smContext *smf_context.SMContext, upf *smf_context.UPF, urrs [] pfcpResult := <-resChan if pfcpResult.Err != nil { - logger.PduSessLog.Error("Query URR Report by PFCP Session Mod Request fail: %+v", pfcpResult.Err) + logger.PduSessLog.Errorf("Query URR Report by PFCP Session Mod Request fail: %v", pfcpResult.Err) return } } From 5831ddc18a4e8934a5a685dd4d36d323585ebfa4 Mon Sep 17 00:00:00 2001 From: Ian Chen Date: Wed, 6 Sep 2023 14:40:51 +0800 Subject: [PATCH 09/32] add nil & error checking --- go.mod | 6 +++--- internal/context/charging.go | 3 ++- internal/sbi/producer/charging_trigger.go | 4 ++++ internal/sbi/producer/pdu_session.go | 5 ++--- 4 files changed, 11 insertions(+), 7 deletions(-) diff --git a/go.mod b/go.mod index ecc1aa80..09bec28b 100644 --- a/go.mod +++ b/go.mod @@ -10,9 +10,9 @@ require ( github.com/free5gc/nas v1.1.0 github.com/free5gc/ngap v1.0.6 github.com/free5gc/openapi v1.0.7-0.20230802173229-2b3ded4db293 - github.com/free5gc/pfcp v1.0.6 - github.com/free5gc/util v1.0.5-0.20231001095115-433858e5be94 - github.com/gin-gonic/gin v1.9.1 + github.com/free5gc/pfcp v1.0.7-0.20230629010245-1c089bfc34f7 + github.com/free5gc/util v1.0.5-0.20230511064842-2e120956883b + github.com/gin-gonic/gin v1.9.0 github.com/google/uuid v1.3.0 github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 github.com/pkg/errors v0.9.1 diff --git a/internal/context/charging.go b/internal/context/charging.go index 8e1e840e..57d76bce 100644 --- a/internal/context/charging.go +++ b/internal/context/charging.go @@ -7,7 +7,8 @@ import ( type ChargingLevel uint8 // For a rating group that is pud session charging level, all volume in a pdu session will be charged -// For a rating group that is flow charging level (or Rating group level (32.255)), only volume in a flow will be charged +// For a rating group that is flow charging level (or Rating group level (32.255)), +// only volume in a flow will be charged const ( PduSessionCharging ChargingLevel = iota FlowCharging diff --git a/internal/sbi/producer/charging_trigger.go b/internal/sbi/producer/charging_trigger.go index e37ba66c..c992cb50 100644 --- a/internal/sbi/producer/charging_trigger.go +++ b/internal/sbi/producer/charging_trigger.go @@ -109,6 +109,10 @@ func ReportUsageAndUpdateQuota(smContext *smf_context.SMContext) { for upfId, urrList := range upfUrrMap { upf := smf_context.GetUpfById(upfId) + if upf == nil { + logger.PduSessLog.Warnf("Cound not find upf %s", upfId) + continue + } rcvMsg, err := pfcp_message.SendPfcpSessionModificationRequest( upf, smContext, nil, nil, nil, nil, urrList) if err != nil { diff --git a/internal/sbi/producer/pdu_session.go b/internal/sbi/producer/pdu_session.go index 8fb3e2c2..b2eccaa6 100644 --- a/internal/sbi/producer/pdu_session.go +++ b/internal/sbi/producer/pdu_session.go @@ -188,10 +188,10 @@ func HandlePDUSessionSMContextCreate(isDone <-chan struct{}, smContext.Supi, smContext.PDUSessionID) if err := smContext.CHFSelection(); err != nil { logger.PduSessLog.Errorln("chf selection error:", err) + } else { + CreateChargingSession(smContext) } - CreateChargingSession(smContext) - // Update SessionRule from decision if err := smContext.ApplySessionRules(smPolicyDecision); err != nil { smContext.Log.Errorf("PDUSessionSMContextCreate err: %v", err) @@ -1016,7 +1016,6 @@ func HandlePDUSessionSMContextLocalRelease(smContext *smf_context.SMContext, cre } func releaseSession(smContext *smf_context.SMContext) smf_context.PFCPSessionResponseStatus { - smContext.SetState(smf_context.PFCPModification) for _, res := range ReleaseTunnel(smContext) { From 9ed1ebf6171a08aa20fd16ec15739b41bb434f09 Mon Sep 17 00:00:00 2001 From: Ian Chen Date: Wed, 6 Sep 2023 14:57:53 +0800 Subject: [PATCH 10/32] update go.sum --- go.mod | 3 +++ go.sum | 41 ++++++++++++++++++++++++++++++++--------- 2 files changed, 35 insertions(+), 9 deletions(-) diff --git a/go.mod b/go.mod index 09bec28b..6c4dcd19 100644 --- a/go.mod +++ b/go.mod @@ -43,6 +43,7 @@ require ( github.com/json-iterator/go v1.1.12 // indirect github.com/jtolds/gls v4.20.0+incompatible // indirect github.com/klauspost/cpuid/v2 v2.2.4 // indirect + github.com/kr/pretty v0.3.0 // indirect github.com/leodido/go-urn v1.2.4 // indirect github.com/mattn/go-isatty v0.0.19 // indirect github.com/mitchellh/mapstructure v1.4.2 // indirect @@ -50,6 +51,7 @@ require ( github.com/modern-go/reflect2 v1.0.2 // indirect github.com/pelletier/go-toml/v2 v2.0.8 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/rogpeppe/go-internal v1.8.0 // indirect github.com/russross/blackfriday/v2 v2.0.1 // indirect github.com/shurcooL/sanitized_anchor_name v1.0.0 // indirect github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d // indirect @@ -64,5 +66,6 @@ require ( golang.org/x/text v0.9.0 // indirect google.golang.org/appengine v1.6.6 // indirect google.golang.org/protobuf v1.30.0 // indirect + gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 8c595740..dd5e192b 100644 --- a/go.sum +++ b/go.sum @@ -41,6 +41,7 @@ github.com/antonfisher/nested-logrus-formatter v1.3.1/go.mod h1:6WTfyWFkBc9+zyBa github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d h1:Byv0BzEl3/e6D5CLfI0j/7hiIEtvGVFPCZ7Ei2oq8iQ= github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM= +github.com/bytedance/sonic v1.8.0/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U= github.com/bytedance/sonic v1.9.1 h1:6iJ6NqdoxCDr6mbY8h18oSO+cShGSMRGCEo7F2h0x8s= github.com/bytedance/sonic v1.9.1/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= @@ -54,6 +55,7 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDk github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d h1:U+s90UTSYgptZMwQh2aRr3LuazLJIa+Pg3Kc1ylSYVY= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -72,18 +74,18 @@ github.com/free5gc/openapi v1.0.4/go.mod h1:KRCnnp0GeK0Bl4gnrX79cQAidKXNENf8VRdG github.com/free5gc/openapi v1.0.6/go.mod h1:iw/N0E+FlX44EEx24IBi2EdZW8v+bkj3ETWPGnlK9DI= github.com/free5gc/openapi v1.0.7-0.20230802173229-2b3ded4db293 h1:BSIvKCYu7646sE8J9R1L8v2R435otUik3wOFN33csfs= github.com/free5gc/openapi v1.0.7-0.20230802173229-2b3ded4db293/go.mod h1:iw/N0E+FlX44EEx24IBi2EdZW8v+bkj3ETWPGnlK9DI= -github.com/free5gc/pfcp v1.0.6 h1:dKEVyZWozF1G+yk1JXw/1ggtIRI0v362say/Q6VDZTE= -github.com/free5gc/pfcp v1.0.6/go.mod h1:WzpW7Zxhx5WONMumNKRWbPn7pl/iTYp2FqRLNiOWUjs= +github.com/free5gc/pfcp v1.0.7-0.20230629010245-1c089bfc34f7 h1:oE9n4qhoaHkriyp7+vElXggBChs321YIYOe/Y4iPqbg= +github.com/free5gc/pfcp v1.0.7-0.20230629010245-1c089bfc34f7/go.mod h1:WzpW7Zxhx5WONMumNKRWbPn7pl/iTYp2FqRLNiOWUjs= github.com/free5gc/tlv v1.0.2-0.20230131124215-8b6ebd69bf93 h1:QPSSI5zw4goiIfxem9doVyMqTO8iKLQ536pzpET5Y+Q= github.com/free5gc/tlv v1.0.2-0.20230131124215-8b6ebd69bf93/go.mod h1:KbbQJIgGaA2jIwnTJgJ/lE3JSDEp3898S6c4TEq0Vyg= -github.com/free5gc/util v1.0.5-0.20231001095115-433858e5be94 h1:tNylIqH/m5Kq+3KuC+jjXGl06Y6EmM8yq61ZUgNrPBY= -github.com/free5gc/util v1.0.5-0.20231001095115-433858e5be94/go.mod h1:aMszJZbCkcg5xaGgzya+55jz+OPMsJqPLq5Z3fWDFPE= +github.com/free5gc/util v1.0.5-0.20230511064842-2e120956883b h1:XMw3j+4AEXLeL/uyiZ7/qYE1X7Ul05RTwWBhzxCLi+0= +github.com/free5gc/util v1.0.5-0.20230511064842-2e120956883b/go.mod h1:l2Jrml4vojDomW5jdDJhIS60KdbrE9uPYhyAq/7OnF4= github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU= github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA= github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= -github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg= -github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU= +github.com/gin-gonic/gin v1.9.0 h1:OjyFBKICoexlu99ctXNR2gg+c5pKrKMuyjgARg9qeY8= +github.com/gin-gonic/gin v1.9.0/go.mod h1:W1Me9+hsUSyj3CePGrd1/QrKJMSJ1Tu/0hFEH89961k= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= @@ -93,9 +95,11 @@ github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/o github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= +github.com/go-playground/validator/v10 v10.11.2/go.mod h1:NieE624vt4SCTJtD87arVLvdmjPAeV8BQlHtMnw9D7s= github.com/go-playground/validator/v10 v10.14.0 h1:vgvQWe3XCz3gIeFDm/HnTIbj6UGmg/+t63MyGU2n5js= github.com/go-playground/validator/v10 v10.14.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/goccy/go-json v0.10.0/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/golang-jwt/jwt v3.2.1+incompatible h1:73Z+4BJcrTC+KczS6WvTPvRGOp1WmfEP4Q1lOd9Z/+c= @@ -173,13 +177,18 @@ github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47e github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.2.4 h1:acbojRNwl3o09bUq+yDCtZFc1aiwaAAxtcn8YkZXnvk= github.com/klauspost/cpuid/v2 v2.2.4/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= -github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= +github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY= github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q= github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4= +github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= @@ -195,14 +204,19 @@ github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwd github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc= github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32 h1:W6apQkHrMkS0Muv8G/TipAy/FJl/rCYT0+EuS8+Z0z4= github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32/go.mod h1:9wM+0iRr9ahx58uYLpLIr5fm8diHn0JbqRycJi6w0Ms= +github.com/pelletier/go-toml/v2 v2.0.6/go.mod h1:eumQOmlWiOPt5WriQQqoM5y18pDHwha2N+QD+EUNTek= github.com/pelletier/go-toml/v2 v2.0.8 h1:0ctb6s9mE31h0/lhu+J6OPmVeDxJn+kYnJc2jZR9tGQ= github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNcZljzZR9VXg+4= +github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= +github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8= +github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo= @@ -232,6 +246,7 @@ github.com/tim-ywliu/nested-logrus-formatter v1.3.2 h1:jugNJ2/CNCI79SxOJCOhwUHeN github.com/tim-ywliu/nested-logrus-formatter v1.3.2/go.mod h1:oGPmcxZB65j9Wo7mCnQKSrKEJtVDqyjD666SGmyStXI= github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= +github.com/ugorji/go/codec v1.2.9/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU= github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= github.com/urfave/cli v1.22.5 h1:lNq9sAHXK2qfdI8W+GRItjCEkI+2oR4d+MEHy1CKXoU= @@ -260,6 +275,7 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201216223049-8b5274cf687f/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.5.0/go.mod h1:NK/OQwhpMQP3MwtdjgLlYHnH9ebylxKWv3e0fK+mkQU= golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g= golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= @@ -324,6 +340,7 @@ golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81R golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= @@ -378,7 +395,9 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU= @@ -386,6 +405,7 @@ golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= @@ -398,6 +418,7 @@ golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= +golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= @@ -529,11 +550,13 @@ google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpAD google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/h2non/gock.v1 v1.1.2 h1:jBbHXgGBK/AoPVfJh5x4r/WxIrElvbLel8TCZkkZJoY= gopkg.in/h2non/gock.v1 v1.1.2/go.mod h1:n7UGz/ckNChHiK05rDoiC4MYSunEC/lyaUm2WWaDva0= From 33fc34d763e1fdbe885fcd7e0a30019ec918889a Mon Sep 17 00:00:00 2001 From: Ian Chen Date: Wed, 6 Sep 2023 15:11:37 +0800 Subject: [PATCH 11/32] add more error checking --- internal/context/sm_context.go | 8 ++++---- internal/context/sm_context_policy.go | 9 ++------- internal/sbi/producer/callback.go | 4 ++++ internal/sbi/producer/charging_trigger.go | 16 +++++++++++----- 4 files changed, 21 insertions(+), 16 deletions(-) diff --git a/internal/context/sm_context.go b/internal/context/sm_context.go index 1b75fc09..c1ceddfc 100644 --- a/internal/context/sm_context.go +++ b/internal/context/sm_context.go @@ -437,7 +437,7 @@ func (smContext *SMContext) CHFSelection() error { // Supi: optional.NewString(smContext.Supi), } - rep, res, err := GetSelf(). + rsp, res, err := GetSelf(). NFDiscoveryClient. NFInstancesStoreApi. SearchNFInstances(context.TODO(), models.NfType_CHF, models.NfType_SMF, &localVarOptionals) @@ -462,7 +462,7 @@ func (smContext *SMContext) CHFSelection() error { // Select CHF from available CHF - smContext.SelectedCHFProfile = rep.NfInstances[0] + smContext.SelectedCHFProfile = rsp.NfInstances[0] // Create Converged Charging Client for this SM Context for _, service := range *smContext.SelectedCHFProfile.NfServices { @@ -485,7 +485,7 @@ func (smContext *SMContext) PCFSelection() error { localVarOptionals.PreferredLocality = optional.NewString(GetSelf().Locality) } - rep, res, err := GetSelf(). + rsp, res, err := GetSelf(). NFDiscoveryClient. NFInstancesStoreApi. SearchNFInstances(context.TODO(), models.NfType_PCF, models.NfType_SMF, &localVarOptionals) @@ -510,7 +510,7 @@ func (smContext *SMContext) PCFSelection() error { // Select PCF from available PCF - smContext.SelectedPCFProfile = rep.NfInstances[0] + smContext.SelectedPCFProfile = rsp.NfInstances[0] // Create SMPolicyControl Client for this SM Context for _, service := range *smContext.SelectedPCFProfile.NfServices { diff --git a/internal/context/sm_context_policy.go b/internal/context/sm_context_policy.go index e17ca82e..ffc373ff 100644 --- a/internal/context/sm_context_policy.go +++ b/internal/context/sm_context_policy.go @@ -71,21 +71,16 @@ func (c *SMContext) RemoveQosFlow(qfi uint8) { // For urr that created for Pdu session level charging, it show be applied to all data path func (c *SMContext) addPduLevelChargingRuleToFlow(pccRules map[string]*PCCRule) { var pduLevelChargingUrrs []*URR - var pccIdsForPduSession []string for id, pcc := range pccRules { if chargingLevel, err := pcc.IdentifyChargingLevel(); err != nil { continue } else if chargingLevel == PduSessionCharging { - pccIdsForPduSession = append(pccIdsForPduSession, id) + pduPcc := pccRules[id] + pduLevelChargingUrrs = pduPcc.Datapath.GetChargingUrr(c) } } - for _, pduPccid := range pccIdsForPduSession { - pduPcc := pccRules[pduPccid] - pduLevelChargingUrrs = pduPcc.Datapath.GetChargingUrr(c) - } - for _, flowPcc := range pccRules { if chgLevel, err := flowPcc.IdentifyChargingLevel(); err != nil { continue diff --git a/internal/sbi/producer/callback.go b/internal/sbi/producer/callback.go index fbb86b1b..ea733060 100644 --- a/internal/sbi/producer/callback.go +++ b/internal/sbi/producer/callback.go @@ -48,6 +48,10 @@ func chargingNotificationProcedure(req models.ChargingNotifyRequest, smContextRe for upfId, urrList := range upfUrrMap { upf := smf_context.GetUpfById(upfId) + if upf == nil { + logger.ChargingLog.Warnf("Cound not find upf %s", upfId) + continue + } QueryReport(smContext, upf, urrList, models.TriggerType_FORCED_REAUTHORISATION) } diff --git a/internal/sbi/producer/charging_trigger.go b/internal/sbi/producer/charging_trigger.go index c992cb50..e7ef742f 100644 --- a/internal/sbi/producer/charging_trigger.go +++ b/internal/sbi/producer/charging_trigger.go @@ -277,8 +277,10 @@ func updateGrantedQuota(smContext *smf_context.SMContext, multipleUnitInformatio chgInfo.VolumeLimitExpiryTimer = smf_context.NewTimer(time.Duration(t.VolumeLimit)*time.Second, 1, func(expireTimes int32) { urrList := []*smf_context.URR{urr} upf := smf_context.GetUpfById(ui.UPFID) - QueryReport(smContext, upf, urrList, models.TriggerType_VOLUME_LIMIT) - ReportUsageAndUpdateQuota(smContext) + if upf != nil { + QueryReport(smContext, upf, urrList, models.TriggerType_VOLUME_LIMIT) + ReportUsageAndUpdateQuota(smContext) + } }, func() { smContext.Log.Tracef("Volume Limit Expiry for Pdu session, it's rating group is [%d]", rg) chgInfo.VolumeLimitExpiryTimer.Stop() @@ -297,7 +299,9 @@ func updateGrantedQuota(smContext *smf_context.SMContext, multipleUnitInformatio chgInfo.VolumeLimitExpiryTimer = smf_context.NewTimer(time.Duration(t.VolumeLimit)*time.Second, 1, func(expireTimes int32) { urrList := []*smf_context.URR{urr} upf := smf_context.GetUpfById(ui.UPFID) - QueryReport(smContext, upf, urrList, models.TriggerType_VOLUME_LIMIT) + if upf != nil { + QueryReport(smContext, upf, urrList, models.TriggerType_VOLUME_LIMIT) + } }, func() { smContext.Log.Tracef("Volume Limit Expiry for rating group [%d]", rg) chgInfo.VolumeLimitExpiryTimer.Stop() @@ -311,8 +315,10 @@ func updateGrantedQuota(smContext *smf_context.SMContext, multipleUnitInformatio chgInfo.EventLimitExpiryTimer = smf_context.NewTimer(time.Duration(t.EventLimit)*time.Second, 1, func(expireTimes int32) { urrList := []*smf_context.URR{urr} upf := smf_context.GetUpfById(ui.UPFID) - QueryReport(smContext, upf, urrList, models.TriggerType_VOLUME_LIMIT) - ReportUsageAndUpdateQuota(smContext) + if upf != nil { + QueryReport(smContext, upf, urrList, models.TriggerType_VOLUME_LIMIT) + ReportUsageAndUpdateQuota(smContext) + } }, func() { smContext.Log.Tracef("Event Limit Expiry Timer is triggered") chgInfo.EventLimitExpiryTimer = nil From 79b83f36bb065867079422ddb52a617a52939b6c Mon Sep 17 00:00:00 2001 From: Ian Chen Date: Wed, 6 Sep 2023 15:15:14 +0800 Subject: [PATCH 12/32] fix test fail --- internal/context/sm_context_policy_test.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/internal/context/sm_context_policy_test.go b/internal/context/sm_context_policy_test.go index a04030d3..a43d3f64 100644 --- a/internal/context/sm_context_policy_test.go +++ b/internal/context/sm_context_policy_test.go @@ -98,11 +98,18 @@ var testConfig = factory.Config{ Description: "SMF procdeure test configuration", }, Configuration: &factory.Configuration{ + Sbi: &factory.Sbi{ + Scheme: "http", + RegisterIPv4: "127.0.0.1", + BindingIPv4: "127.0.0.1", + Port: 8000, + }, UserPlaneInformation: userPlaneConfig, }, } func initConfig() { + InitSmfContext(&testConfig) factory.SmfConfig = &testConfig } From 0ec5749586d64ef6840f2a3373b9d469d80fb874 Mon Sep 17 00:00:00 2001 From: Ian Chen Date: Wed, 6 Sep 2023 15:38:26 +0800 Subject: [PATCH 13/32] fix ci error --- internal/context/charging.go | 2 +- internal/pfcp/handler/handler.go | 2 +- internal/pfcp/message/build.go | 6 +- internal/pfcp/message/send.go | 8 +- internal/sbi/consumer/converged_charging.go | 22 +++- internal/sbi/producer/callback.go | 8 +- internal/sbi/producer/charging_trigger.go | 118 +++++++++++--------- internal/sbi/producer/datapath.go | 4 +- internal/sbi/producer/pdu_session.go | 2 - 9 files changed, 98 insertions(+), 74 deletions(-) diff --git a/internal/context/charging.go b/internal/context/charging.go index 57d76bce..7ff4c75b 100644 --- a/internal/context/charging.go +++ b/internal/context/charging.go @@ -7,7 +7,7 @@ import ( type ChargingLevel uint8 // For a rating group that is pud session charging level, all volume in a pdu session will be charged -// For a rating group that is flow charging level (or Rating group level (32.255)), +// For a rating group that is flow charging level (or Rating group level (32.255)), // only volume in a flow will be charged const ( PduSessionCharging ChargingLevel = iota diff --git a/internal/pfcp/handler/handler.go b/internal/pfcp/handler/handler.go index b048f0dd..a8ecf2b1 100644 --- a/internal/pfcp/handler/handler.go +++ b/internal/pfcp/handler/handler.go @@ -192,7 +192,7 @@ func HandlePfcpSessionReportRequest(msg *pfcpUdp.Message) { if req.ReportType.Usar && req.UsageReport != nil { smContext.HandleReports(req.UsageReport, nil, nil, upfNodeID, "") - // After recieving the Usage Report, it should send charging request to the CHF + // After receiving the Usage Report, it should send charging request to the CHF // and update the URR with the quota or other charging information according to // the charging response go func() { diff --git a/internal/pfcp/message/build.go b/internal/pfcp/message/build.go index 7a688628..c8760d44 100644 --- a/internal/pfcp/message/build.go +++ b/internal/pfcp/message/build.go @@ -202,7 +202,8 @@ func urrToCreateURR(urr *context.URR) *pfcp.CreateURR { } if !urr.QuotaValidityTime.IsZero() { createURR.QuotaValidityTime = &pfcpType.QuotaValidityTime{ - QuotaValidityTime: uint32(urr.QuotaValidityTime.Sub(time.Date(1900, time.January, 1, 0, 0, 0, 0, time.UTC)) / 1000000000), + QuotaValidityTime: uint32(urr.QuotaValidityTime.Sub( + time.Date(1900, time.January, 1, 0, 0, 0, 0, time.UTC)) / 1000000000), } } @@ -336,7 +337,8 @@ func urrToUpdateURR(urr *context.URR) *pfcp.UpdateURR { } if urr.QuotaValidityTime.IsZero() { updateURR.QuotaValidityTime = &pfcpType.QuotaValidityTime{ - QuotaValidityTime: uint32(urr.QuotaValidityTime.Sub(time.Date(1900, time.January, 1, 0, 0, 0, 0, time.UTC)) / 1000000000), + QuotaValidityTime: uint32(urr.QuotaValidityTime.Sub( + time.Date(1900, time.January, 1, 0, 0, 0, 0, time.UTC)) / 1000000000), } } diff --git a/internal/pfcp/message/send.go b/internal/pfcp/message/send.go index c891cf35..c92a5fad 100644 --- a/internal/pfcp/message/send.go +++ b/internal/pfcp/message/send.go @@ -78,7 +78,7 @@ func SendPfcpAssociationReleaseRequest(upNodeID pfcpType.NodeID) (resMsg *pfcpUd pfcpMsg, err := BuildPfcpAssociationReleaseRequest() if err != nil { logger.PfcpLog.Errorf("Build PFCP Association Release Request failed: %v", err) - return + return nil, err } message := &pfcp.Message{ @@ -148,7 +148,7 @@ func SendPfcpSessionEstablishmentRequest( ctx, pdrList, farList, barList, qerList, urrList) if err != nil { logger.PfcpLog.Errorf("Build PFCP Session Establishment Request failed: %v", err) - return + return nil, err } message := &pfcp.Message{ @@ -231,7 +231,7 @@ func SendPfcpSessionModificationRequest( ctx, pdrList, farList, barList, qerList, urrList) if err != nil { logger.PfcpLog.Errorf("Build PFCP Session Modification Request failed: %v", err) - return + return nil, err } seqNum := getSeqNumber() @@ -305,7 +305,7 @@ func SendPfcpSessionDeletionRequest(upf *context.UPF, ctx *context.SMContext) (r pfcpMsg, err := BuildPfcpSessionDeletionRequest() if err != nil { logger.PfcpLog.Errorf("Build PFCP Session Deletion Request failed: %v", err) - return + return nil, err } seqNum := getSeqNumber() remoteSEID := ctx.PFCPContext[nodeIDtoIP.String()].RemoteSEID diff --git a/internal/sbi/consumer/converged_charging.go b/internal/sbi/consumer/converged_charging.go index fa374b49..e7980823 100644 --- a/internal/sbi/consumer/converged_charging.go +++ b/internal/sbi/consumer/converged_charging.go @@ -14,7 +14,9 @@ import ( "github.com/free5gc/smf/internal/logger" ) -func buildConvergedChargingRequest(smContext *smf_context.SMContext, multipleUnitUsage []models.MultipleUnitUsage) *models.ChargingDataRequest { +func buildConvergedChargingRequest(smContext *smf_context.SMContext, + multipleUnitUsage []models.MultipleUnitUsage, +) *models.ChargingDataRequest { var triggers []models.Trigger smfSelf := smf_context.GetSelf() @@ -70,7 +72,9 @@ func buildConvergedChargingRequest(smContext *smf_context.SMContext, multipleUni return req } -func SendConvergedChargingRequest(smContext *smf_context.SMContext, requestType smf_context.RequestType, multipleUnitUsage []models.MultipleUnitUsage) (*models.ChargingDataResponse, *models.ProblemDetails, error) { +func SendConvergedChargingRequest(smContext *smf_context.SMContext, requestType smf_context.RequestType, + multipleUnitUsage []models.MultipleUnitUsage, +) (*models.ChargingDataResponse, *models.ProblemDetails, error) { logger.ChargingLog.Info("Handle SendConvergedChargingRequest") req := buildConvergedChargingRequest(smContext, multipleUnitUsage) @@ -79,18 +83,26 @@ func SendConvergedChargingRequest(smContext *smf_context.SMContext, requestType var httpResponse *http.Response var err error - //select the appropriate converged charging service based on trigger type + // select the appropriate converged charging service based on trigger type switch requestType { case smf_context.CHARGING_INIT: rsp, httpResponse, err = smContext.ChargingClient.DefaultApi.ChargingdataPost(context.Background(), *req) chargingDataRef := strings.Split(httpResponse.Header.Get("Location"), "/") smContext.ChargingDataRef = chargingDataRef[len(chargingDataRef)-1] case smf_context.CHARGING_UPDATE: - rsp, httpResponse, err = smContext.ChargingClient.DefaultApi.ChargingdataChargingDataRefUpdatePost(context.Background(), smContext.ChargingDataRef, *req) + rsp, httpResponse, err = smContext.ChargingClient.DefaultApi.ChargingdataChargingDataRefUpdatePost( + context.Background(), smContext.ChargingDataRef, *req) case smf_context.CHARGING_RELEASE: - httpResponse, err = smContext.ChargingClient.DefaultApi.ChargingdataChargingDataRefReleasePost(context.Background(), smContext.ChargingDataRef, *req) + httpResponse, err = smContext.ChargingClient.DefaultApi.ChargingdataChargingDataRefReleasePost(context.Background(), + smContext.ChargingDataRef, *req) } + defer func() { + if resCloseErr := httpResponse.Body.Close(); resCloseErr != nil { + logger.ChargingLog.Errorf("RegisterNFInstance response body cannot close: %+v", resCloseErr) + } + }() + if err == nil { return &rsp, nil, nil } else if httpResponse != nil { diff --git a/internal/sbi/producer/callback.go b/internal/sbi/producer/callback.go index ea733060..a6f26125 100644 --- a/internal/sbi/producer/callback.go +++ b/internal/sbi/producer/callback.go @@ -12,7 +12,9 @@ import ( "github.com/free5gc/util/httpwrapper" ) -func HandleChargingNotification(chargingNotifyRequest models.ChargingNotifyRequest, smContextRef string) *httpwrapper.Response { +func HandleChargingNotification(chargingNotifyRequest models.ChargingNotifyRequest, + smContextRef string, +) *httpwrapper.Response { logger.ChargingLog.Info("Handle Charging Notification") problemDetails := chargingNotificationProcedure(chargingNotifyRequest, smContextRef) @@ -23,7 +25,7 @@ func HandleChargingNotification(chargingNotifyRequest models.ChargingNotifyReque } } -// While recieve Charging Notification from CHF, SMF will send Charging Information to CHF and update UPF +// While receive Charging Notification from CHF, SMF will send Charging Information to CHF and update UPF func chargingNotificationProcedure(req models.ChargingNotifyRequest, smContextRef string) *models.ProblemDetails { if smContext := smf_context.GetSMContextByRef(smContextRef); smContext != nil { go func() { @@ -43,7 +45,6 @@ func chargingNotificationProcedure(req models.ChargingNotifyRequest, smContextRe upfUrrMap[upfId] = append(upfUrrMap[upfId], urr) } } - } for upfId, urrList := range upfUrrMap { @@ -68,6 +69,7 @@ func chargingNotificationProcedure(req models.ChargingNotifyRequest, smContextRe return nil } + func HandleSMPolicyUpdateNotify(smContextRef string, request models.SmPolicyNotification) *httpwrapper.Response { logger.PduSessLog.Infoln("In HandleSMPolicyUpdateNotify") decision := request.SmPolicyDecision diff --git a/internal/sbi/producer/charging_trigger.go b/internal/sbi/producer/charging_trigger.go index e7ef742f..efea30bb 100644 --- a/internal/sbi/producer/charging_trigger.go +++ b/internal/sbi/producer/charging_trigger.go @@ -1,7 +1,6 @@ package producer import ( - "strings" "time" "github.com/free5gc/openapi/models" @@ -29,9 +28,9 @@ func UpdateChargingSession(smContext *smf_context.SMContext, urrList []*smf_cont for _, urr := range urrList { if chgInfo := smContext.ChargingInfo[urr.URRID]; chgInfo != nil { - rg := chgInfo.RatingGroup - logger.PduSessLog.Tracef("Recieve Usage Report from URR[%d], correspopnding Rating Group[%d], ChargingMethod %v", urr.URRID, rg, chgInfo.ChargingMethod) + logger.PduSessLog.Tracef("Receive Usage Report from URR[%d], correspopnding Rating Group[%d], ChargingMethod %v", + urr.URRID, rg, chgInfo.ChargingMethod) triggerTime := time.Now() uu := models.UsedUnitContainer{ @@ -50,7 +49,8 @@ func UpdateChargingSession(smContext *smf_context.SMContext, urrList []*smf_cont } } - _, problemDetails, err := consumer.SendConvergedChargingRequest(smContext, smf_context.CHARGING_UPDATE, multipleUnitUsage) + _, problemDetails, err := consumer.SendConvergedChargingRequest(smContext, + smf_context.CHARGING_UPDATE, multipleUnitUsage) if problemDetails != nil { logger.ChargingLog.Errorf("Send Charging Data Request[Init] Failed Problem[%+v]", problemDetails) } else if err != nil { @@ -63,7 +63,8 @@ func UpdateChargingSession(smContext *smf_context.SMContext, urrList []*smf_cont func ReleaseChargingSession(smContext *smf_context.SMContext) { multipleUnitUsage := buildMultiUnitUsageFromUsageReport(smContext) - _, problemDetails, err := consumer.SendConvergedChargingRequest(smContext, smf_context.CHARGING_RELEASE, multipleUnitUsage) + _, problemDetails, err := consumer.SendConvergedChargingRequest(smContext, + smf_context.CHARGING_RELEASE, multipleUnitUsage) if problemDetails != nil { logger.ChargingLog.Errorf("Send Charging Data Request[Termination] Failed Problem[%+v]", problemDetails) } else if err != nil { @@ -78,7 +79,8 @@ func ReportUsageAndUpdateQuota(smContext *smf_context.SMContext) { multipleUnitUsage := buildMultiUnitUsageFromUsageReport(smContext) if len(multipleUnitUsage) != 0 { - rsp, problemDetails, err := consumer.SendConvergedChargingRequest(smContext, smf_context.CHARGING_UPDATE, multipleUnitUsage) + rsp, problemDetails, err := consumer.SendConvergedChargingRequest(smContext, + smf_context.CHARGING_UPDATE, multipleUnitUsage) if problemDetails != nil { logger.ChargingLog.Errorf("Send Charging Data Request[Update] Failed Problem[%+v]", problemDetails) @@ -118,11 +120,11 @@ func ReportUsageAndUpdateQuota(smContext *smf_context.SMContext) { if err != nil { logger.PduSessLog.Warnf("Sending PFCP Session Modification Request to AN UPF error: %+v", err) pfcpResponseStatus = smf_context.SessionUpdateFailed + } else { + logger.PduSessLog.Infoln("Received PFCP Session Modification Response") + pfcpResponseStatus = smf_context.SessionUpdateSuccess } - logger.PduSessLog.Infoln("Received PFCP Session Modification Response") - pfcpResponseStatus = smf_context.SessionUpdateSuccess - rsp := rcvMsg.PfcpMessage.Body.(pfcp.PFCPSessionModificationResponse) if rsp.Cause == nil || rsp.Cause.CauseValue != pfcpType.CauseRequestAccepted { logger.PduSessLog.Warn("Received PFCP Session Modification Not Accepted Response from AN UPF") @@ -144,11 +146,6 @@ func ReportUsageAndUpdateQuota(smContext *smf_context.SMContext) { } } -func getUpfIdFromKey(key string) string { - upfIdUrridStr := strings.Split(key, ":") - return upfIdUrridStr[0] -} - func buildMultiUnitUsageFromUsageReport(smContext *smf_context.SMContext) []models.MultipleUnitUsage { var ratingGroupUnitUsagesMap map[int32]models.MultipleUnitUsage var multipleUnitUsage []models.MultipleUnitUsage @@ -181,7 +178,8 @@ func buildMultiUnitUsageFromUsageReport(smContext *smf_context.SMContext) []mode } rg := chgInfo.RatingGroup - logger.PduSessLog.Tracef("Recieve Usage Report from URR[%d], correspopnding Rating Group[%d], ChargingMethod %v", ur.UrrId, rg, chgInfo.ChargingMethod) + logger.PduSessLog.Tracef("Receive Usage Report from URR[%d], correspopnding Rating Group[%d], ChargingMethod %v", + ur.UrrId, rg, chgInfo.ChargingMethod) triggerTime := time.Now() uu := models.UsedUnitContainer{ @@ -258,12 +256,15 @@ func updateGrantedQuota(smContext *smf_context.SMContext, multipleUnitInformatio switch t.TriggerType { case models.TriggerType_VOLUME_LIMIT: // According to 32.255, the for the trigger "Expirt of datavolume limit" have tow reporting level - // In the Pdu sesion level, the report should be "Immediate report", that is this report should send to CHF immediately - // In the Rating Group level, the report should be "Defferd report", that is this report should send to CHF when the in the next charging request triggereed + // In the Pdu sesion level, the report should be "Immediate report", + // that is this report should send to CHF immediately + // In the Rating Group level, the report should be "Defferd report", that is this report should send to CHF + // when the in the next charging request triggereed // by charging trigger that belongs to the type of immediate report - // TODO: Currently CHF cannot identify the report level since it only knows the rating group, so the both charging level of "Expirt of datavolume limit" - // will be included in the report, and the report type will be determined by the SMF + // TODO: Currently CHF cannot identify the report level since it only knows the rating group, + // so the both charging level of "Expirt of datavolume limit" + // will be included in the report, and the report type will be determined by the SMF switch chgInfo.ChargingLevel { case smf_context.PduSessionCharging: if t.TriggerCategory == models.TriggerCategory_IMMEDIATE_REPORT { @@ -274,18 +275,20 @@ func updateGrantedQuota(smContext *smf_context.SMContext, multipleUnitInformatio chgInfo.VolumeLimitExpiryTimer = nil } - chgInfo.VolumeLimitExpiryTimer = smf_context.NewTimer(time.Duration(t.VolumeLimit)*time.Second, 1, func(expireTimes int32) { - urrList := []*smf_context.URR{urr} - upf := smf_context.GetUpfById(ui.UPFID) - if upf != nil { - QueryReport(smContext, upf, urrList, models.TriggerType_VOLUME_LIMIT) - ReportUsageAndUpdateQuota(smContext) - } - }, func() { - smContext.Log.Tracef("Volume Limit Expiry for Pdu session, it's rating group is [%d]", rg) - chgInfo.VolumeLimitExpiryTimer.Stop() - chgInfo.VolumeLimitExpiryTimer = nil - }) + chgInfo.VolumeLimitExpiryTimer = smf_context.NewTimer(time.Duration(t.VolumeLimit)*time.Second, 1, + func(expireTimes int32) { + urrList := []*smf_context.URR{urr} + upf := smf_context.GetUpfById(ui.UPFID) + if upf != nil { + QueryReport(smContext, upf, urrList, models.TriggerType_VOLUME_LIMIT) + ReportUsageAndUpdateQuota(smContext) + } + }, + func() { + smContext.Log.Tracef("Volume Limit Expiry for Pdu session, it's rating group is [%d]", rg) + chgInfo.VolumeLimitExpiryTimer.Stop() + chgInfo.VolumeLimitExpiryTimer = nil + }) } case smf_context.FlowCharging: if t.TriggerCategory == models.TriggerCategory_DEFERRED_REPORT { @@ -296,43 +299,48 @@ func updateGrantedQuota(smContext *smf_context.SMContext, multipleUnitInformatio chgInfo.VolumeLimitExpiryTimer = nil } - chgInfo.VolumeLimitExpiryTimer = smf_context.NewTimer(time.Duration(t.VolumeLimit)*time.Second, 1, func(expireTimes int32) { + chgInfo.VolumeLimitExpiryTimer = smf_context.NewTimer(time.Duration(t.VolumeLimit)*time.Second, 1, + func(expireTimes int32) { + urrList := []*smf_context.URR{urr} + upf := smf_context.GetUpfById(ui.UPFID) + if upf != nil { + QueryReport(smContext, upf, urrList, models.TriggerType_VOLUME_LIMIT) + } + }, + func() { + smContext.Log.Tracef("Volume Limit Expiry for rating group [%d]", rg) + chgInfo.VolumeLimitExpiryTimer.Stop() + chgInfo.VolumeLimitExpiryTimer = nil + }) + } + } + case models.TriggerType_MAX_NUMBER_OF_CHANGES_IN_CHARGING_CONDITIONS: + switch chgInfo.ChargingLevel { + case smf_context.PduSessionCharging: + chgInfo.EventLimitExpiryTimer = smf_context.NewTimer(time.Duration(t.EventLimit)*time.Second, 1, + func(expireTimes int32) { urrList := []*smf_context.URR{urr} upf := smf_context.GetUpfById(ui.UPFID) if upf != nil { QueryReport(smContext, upf, urrList, models.TriggerType_VOLUME_LIMIT) + ReportUsageAndUpdateQuota(smContext) } - }, func() { - smContext.Log.Tracef("Volume Limit Expiry for rating group [%d]", rg) - chgInfo.VolumeLimitExpiryTimer.Stop() - chgInfo.VolumeLimitExpiryTimer = nil + }, + func() { + smContext.Log.Tracef("Event Limit Expiry Timer is triggered") + chgInfo.EventLimitExpiryTimer = nil }) - } - } - case models.TriggerType_MAX_NUMBER_OF_CHANGES_IN_CHARGING_CONDITIONS: - switch chgInfo.ChargingLevel { - case smf_context.PduSessionCharging: - chgInfo.EventLimitExpiryTimer = smf_context.NewTimer(time.Duration(t.EventLimit)*time.Second, 1, func(expireTimes int32) { - urrList := []*smf_context.URR{urr} - upf := smf_context.GetUpfById(ui.UPFID) - if upf != nil { - QueryReport(smContext, upf, urrList, models.TriggerType_VOLUME_LIMIT) - ReportUsageAndUpdateQuota(smContext) - } - }, func() { - smContext.Log.Tracef("Event Limit Expiry Timer is triggered") - chgInfo.EventLimitExpiryTimer = nil - }) default: - smContext.Log.Tracef("MAX_NUMBER_OF_CHANGES_IN_CHARGING_CONDITIONS should only be applied to PDU session level charging") + smContext.Log.Tracef("MAX_NUMBER_OF_CHANGES_IN_CHARGING_CONDITIONS" + + "should only be applied to PDU session level charging") } case models.TriggerType_QUOTA_THRESHOLD: if ui.VolumeQuotaThreshold != 0 { trigger.Volth = true urr.VolumeThreshold = uint64(ui.VolumeQuotaThreshold) } - // The difference between the quota validity time and the volume limit is that the validity time is counted by the UPF, - // the volume limit is counted by the SMF + // The difference between the quota validity time and the volume limit is + // that the validity time is counted by the UPF, the volume limit is counted by the SMF case models.TriggerType_VALIDITY_TIME: if ui.ValidityTime != 0 { urr.ReportingTrigger.Quvti = true diff --git a/internal/sbi/producer/datapath.go b/internal/sbi/producer/datapath.go index f1701433..b46994c8 100644 --- a/internal/sbi/producer/datapath.go +++ b/internal/sbi/producer/datapath.go @@ -97,7 +97,9 @@ func ActivateUPFSession( close(resChan) } -func QueryReport(smContext *smf_context.SMContext, upf *smf_context.UPF, urrs []*smf_context.URR, reportResaon models.TriggerType) { +func QueryReport(smContext *smf_context.SMContext, upf *smf_context.UPF, + urrs []*smf_context.URR, reportResaon models.TriggerType, +) { smContext.SMLock.Lock() defer smContext.SMLock.Unlock() diff --git a/internal/sbi/producer/pdu_session.go b/internal/sbi/producer/pdu_session.go index b2eccaa6..db11e34b 100644 --- a/internal/sbi/producer/pdu_session.go +++ b/internal/sbi/producer/pdu_session.go @@ -444,8 +444,6 @@ func HandlePDUSessionSMContextUpdate(smContextRef string, body models.UpdateSmCo // UE location change is a charging event // TODO: This is not tested yet if smContext.UeLocation != body.JsonData.UeLocation { - var urrList []*smf_context.URR - // All rating group related to this Pdu session should send charging request for _, dataPath := range tunnel.DataPathPool { if dataPath.Activated { From f67ffe7051a8130f76b0e8b8bd2ad8dd67d810a7 Mon Sep 17 00:00:00 2001 From: Ian Chen Date: Tue, 19 Sep 2023 18:48:28 +0800 Subject: [PATCH 14/32] add comment for addPduLevelChargingRuleToFlow() --- internal/context/sm_context_policy.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/internal/context/sm_context_policy.go b/internal/context/sm_context_policy.go index ffc373ff..86db6986 100644 --- a/internal/context/sm_context_policy.go +++ b/internal/context/sm_context_policy.go @@ -72,12 +72,14 @@ func (c *SMContext) RemoveQosFlow(qfi uint8) { func (c *SMContext) addPduLevelChargingRuleToFlow(pccRules map[string]*PCCRule) { var pduLevelChargingUrrs []*URR + // First, select charging URRs from pcc rule, which charging level is PDU Session level for id, pcc := range pccRules { if chargingLevel, err := pcc.IdentifyChargingLevel(); err != nil { continue } else if chargingLevel == PduSessionCharging { pduPcc := pccRules[id] pduLevelChargingUrrs = pduPcc.Datapath.GetChargingUrr(c) + break } } @@ -87,6 +89,7 @@ func (c *SMContext) addPduLevelChargingRuleToFlow(pccRules map[string]*PCCRule) } else if chgLevel == FlowCharging { for node := flowPcc.Datapath.FirstDPNode; node != nil; node = node.Next() { if node.IsAnchorUPF() { + // only the traffic on the PSA UPF will be charged if node.UpLinkTunnel != nil && node.UpLinkTunnel.PDR != nil { node.UpLinkTunnel.PDR.URR = append(node.UpLinkTunnel.PDR.URR, pduLevelChargingUrrs...) } From 467694c26846cefe86dc6e43e38b7fce4746f5ed Mon Sep 17 00:00:00 2001 From: Ian Chen Date: Wed, 20 Sep 2023 15:02:21 +0800 Subject: [PATCH 15/32] add comment & fix potential synchronization issues --- internal/context/datapath.go | 6 ++- internal/context/pfcp_reports.go | 4 +- internal/context/pfcp_rules.go | 2 +- internal/context/sm_context.go | 2 + internal/context/sm_context_policy.go | 6 +-- internal/pfcp/handler/handler.go | 6 +-- internal/sbi/producer/callback.go | 50 +++++++++++------------ internal/sbi/producer/charging_trigger.go | 6 +++ internal/sbi/producer/datapath.go | 3 -- internal/sbi/producer/pdu_session.go | 2 +- 10 files changed, 44 insertions(+), 43 deletions(-) diff --git a/internal/context/datapath.go b/internal/context/datapath.go index 4e0b6538..62e81d27 100644 --- a/internal/context/datapath.go +++ b/internal/context/datapath.go @@ -728,11 +728,13 @@ func (p *DataPath) GetChargingUrr(smContext *SMContext) []*URR { for node := p.FirstDPNode; node != nil; node = node.Next() { // Charging rules only apply to anchor UPF + // Note: ULPDR and DLPDR share the same URR but have different FAR + // See AddChargingRules() for more details if node.IsAnchorUPF() { if node.UpLinkTunnel != nil && node.UpLinkTunnel.PDR != nil { urrs = node.UpLinkTunnel.PDR.URR } else if node.DownLinkTunnel != nil && node.DownLinkTunnel.PDR != nil { - urrs = node.UpLinkTunnel.PDR.URR + urrs = node.DownLinkTunnel.PDR.URR } for _, urr := range urrs { @@ -776,7 +778,7 @@ func (p *DataPath) AddChargingRules(smContext *SMContext, chgLevel ChargingLevel if chgData.Online { if newURR, err := node.UPF.AddURR(uint32(urrId), NewMeasureInformation(false, false), - SetStartofSDFTrigger()); err != nil { + SetStartOfSDFTrigger()); err != nil { logger.PduSessLog.Errorln("new URR failed") return } else { diff --git a/internal/context/pfcp_reports.go b/internal/context/pfcp_reports.go index 5567b373..14bc737d 100644 --- a/internal/context/pfcp_reports.go +++ b/internal/context/pfcp_reports.go @@ -8,7 +8,7 @@ import ( ) func (smContext *SMContext) HandleReports( - UsageReportReport []*pfcp.UsageReportPFCPSessionReportRequest, + UsageReportRequest []*pfcp.UsageReportPFCPSessionReportRequest, UsageReportModification []*pfcp.UsageReportPFCPSessionModificationResponse, UsageReportDeletion []*pfcp.UsageReportPFCPSessionDeletionResponse, nodeId pfcpType.NodeID, reportTpye models.TriggerType, @@ -17,7 +17,7 @@ func (smContext *SMContext) HandleReports( upf := RetrieveUPFNodeByNodeID(nodeId) upfId := upf.UUID() - for _, report := range UsageReportReport { + for _, report := range UsageReportRequest { usageReport.UrrId = report.URRID.UrrIdValue usageReport.UpfId = upfId usageReport.TotalVolume = report.VolumeMeasurement.TotalVolume diff --git a/internal/context/pfcp_rules.go b/internal/context/pfcp_rules.go index 9db42f31..a473fd4a 100644 --- a/internal/context/pfcp_rules.go +++ b/internal/context/pfcp_rules.go @@ -82,7 +82,7 @@ func NewVolumeQuota(quota uint64) UrrOpt { } } -func SetStartofSDFTrigger() UrrOpt { +func SetStartOfSDFTrigger() UrrOpt { return func(urr *URR) { urr.ReportingTrigger.Start = true } diff --git a/internal/context/sm_context.go b/internal/context/sm_context.go index c1ceddfc..ef387ab0 100644 --- a/internal/context/sm_context.go +++ b/internal/context/sm_context.go @@ -202,6 +202,8 @@ type SMContext struct { UrrUpfMap map[string]*URR UrrReportTime time.Duration UrrReportThreshold uint64 + // Cache the usage reports, sent from UPF + // Those information will be included in CDR. UrrReports []UsageReport // Charging Related diff --git a/internal/context/sm_context_policy.go b/internal/context/sm_context_policy.go index 86db6986..d5e5500d 100644 --- a/internal/context/sm_context_policy.go +++ b/internal/context/sm_context_policy.go @@ -182,7 +182,7 @@ func (c *SMContext) ApplyPccRules( finalQosDatas[tgtQosID] = tgtQosData } } - if err := checkUpPathChgEvent(c, srcTcData, tgtTcData); err != nil { + if err := checkUpPathChangeEvt(c, srcTcData, tgtTcData); err != nil { c.Log.Warnf("Check UpPathChgEvent err: %v", err) } // Remove handled pcc rule @@ -209,7 +209,7 @@ func (c *SMContext) ApplyPccRules( if err := c.CreatePccRuleDataPath(pcc, tgtTcData, tgtQosData, tgtChgData); err != nil { return err } - if err := checkUpPathChgEvent(c, srcTcData, tgtTcData); err != nil { + if err := checkUpPathChangeEvt(c, srcTcData, tgtTcData); err != nil { c.Log.Warnf("Check UpPathChgEvent err: %v", err) } } @@ -343,7 +343,7 @@ func applyFlowInfoOrPFD(pcc *PCCRule) error { return nil } -func checkUpPathChgEvent(c *SMContext, +func checkUpPathChangeEvt(c *SMContext, srcTcData, tgtTcData *TrafficControlData, ) error { var srcRoute, tgtRoute models.RouteToLocation diff --git a/internal/pfcp/handler/handler.go b/internal/pfcp/handler/handler.go index a8ecf2b1..ca8f8734 100644 --- a/internal/pfcp/handler/handler.go +++ b/internal/pfcp/handler/handler.go @@ -193,11 +193,9 @@ func HandlePfcpSessionReportRequest(msg *pfcpUdp.Message) { if req.ReportType.Usar && req.UsageReport != nil { smContext.HandleReports(req.UsageReport, nil, nil, upfNodeID, "") // After receiving the Usage Report, it should send charging request to the CHF - // and update the URR with the quota or other charging information according to + // and update the URR with the quota or other charging information according to // the charging response - go func() { - producer.ReportUsageAndUpdateQuota(smContext) - }() + producer.ReportUsageAndUpdateQuota(smContext) } // TS 23.502 4.2.3.3 2b. Send Data Notification Ack, SMF->UPF diff --git a/internal/sbi/producer/callback.go b/internal/sbi/producer/callback.go index a6f26125..18adc46f 100644 --- a/internal/sbi/producer/callback.go +++ b/internal/sbi/producer/callback.go @@ -26,38 +26,34 @@ func HandleChargingNotification(chargingNotifyRequest models.ChargingNotifyReque } // While receive Charging Notification from CHF, SMF will send Charging Information to CHF and update UPF +// The Charging Notification will be sent when CHF found the changes of the quota file. func chargingNotificationProcedure(req models.ChargingNotifyRequest, smContextRef string) *models.ProblemDetails { if smContext := smf_context.GetSMContextByRef(smContextRef); smContext != nil { - go func() { - upfUrrMap := make(map[string][]*smf_context.URR) - - for _, reauthorizeDetail := range req.ReauthorizationDetails { - rg := reauthorizeDetail.RatingGroup - logger.ChargingLog.Infof("Force update charging information for rating group %d", rg) - - for _, urr := range smContext.UrrUpfMap { - chgInfo := smContext.ChargingInfo[urr.URRID] - if chgInfo.RatingGroup == rg || - chgInfo.ChargingLevel == smf_context.PduSessionCharging { - logger.ChargingLog.Tracef("Query URR (%d) for Rating Group (%d)", urr.URRID, rg) - - upfId := smContext.ChargingInfo[urr.URRID].UpfId - upfUrrMap[upfId] = append(upfUrrMap[upfId], urr) - } + smContext.SMLock.Lock() + defer smContext.SMLock.Unlock() + upfUrrMap := make(map[string][]*smf_context.URR) + for _, reauthorizeDetail := range req.ReauthorizationDetails { + rg := reauthorizeDetail.RatingGroup + logger.ChargingLog.Infof("Force update charging information for rating group %d", rg) + for _, urr := range smContext.UrrUpfMap { + chgInfo := smContext.ChargingInfo[urr.URRID] + if chgInfo.RatingGroup == rg || + chgInfo.ChargingLevel == smf_context.PduSessionCharging { + logger.ChargingLog.Tracef("Query URR (%d) for Rating Group (%d)", urr.URRID, rg) + upfId := smContext.ChargingInfo[urr.URRID].UpfId + upfUrrMap[upfId] = append(upfUrrMap[upfId], urr) } } - - for upfId, urrList := range upfUrrMap { - upf := smf_context.GetUpfById(upfId) - if upf == nil { - logger.ChargingLog.Warnf("Cound not find upf %s", upfId) - continue - } - QueryReport(smContext, upf, urrList, models.TriggerType_FORCED_REAUTHORISATION) + } + for upfId, urrList := range upfUrrMap { + upf := smf_context.GetUpfById(upfId) + if upf == nil { + logger.ChargingLog.Warnf("Cound not find upf %s", upfId) + continue } - - ReportUsageAndUpdateQuota(smContext) - }() + QueryReport(smContext, upf, urrList, models.TriggerType_FORCED_REAUTHORISATION) + } + ReportUsageAndUpdateQuota(smContext) } else { problemDetails := &models.ProblemDetails{ Status: http.StatusNotFound, diff --git a/internal/sbi/producer/charging_trigger.go b/internal/sbi/producer/charging_trigger.go index efea30bb..6db28957 100644 --- a/internal/sbi/producer/charging_trigger.go +++ b/internal/sbi/producer/charging_trigger.go @@ -277,6 +277,8 @@ func updateGrantedQuota(smContext *smf_context.SMContext, multipleUnitInformatio chgInfo.VolumeLimitExpiryTimer = smf_context.NewTimer(time.Duration(t.VolumeLimit)*time.Second, 1, func(expireTimes int32) { + smContext.SMLock.Lock() + defer smContext.SMLock.Unlock() urrList := []*smf_context.URR{urr} upf := smf_context.GetUpfById(ui.UPFID) if upf != nil { @@ -301,6 +303,8 @@ func updateGrantedQuota(smContext *smf_context.SMContext, multipleUnitInformatio chgInfo.VolumeLimitExpiryTimer = smf_context.NewTimer(time.Duration(t.VolumeLimit)*time.Second, 1, func(expireTimes int32) { + smContext.SMLock.Lock() + defer smContext.SMLock.Unlock() urrList := []*smf_context.URR{urr} upf := smf_context.GetUpfById(ui.UPFID) if upf != nil { @@ -319,6 +323,8 @@ func updateGrantedQuota(smContext *smf_context.SMContext, multipleUnitInformatio case smf_context.PduSessionCharging: chgInfo.EventLimitExpiryTimer = smf_context.NewTimer(time.Duration(t.EventLimit)*time.Second, 1, func(expireTimes int32) { + smContext.SMLock.Lock() + defer smContext.SMLock.Unlock() urrList := []*smf_context.URR{urr} upf := smf_context.GetUpfById(ui.UPFID) if upf != nil { diff --git a/internal/sbi/producer/datapath.go b/internal/sbi/producer/datapath.go index b46994c8..85041e54 100644 --- a/internal/sbi/producer/datapath.go +++ b/internal/sbi/producer/datapath.go @@ -100,9 +100,6 @@ func ActivateUPFSession( func QueryReport(smContext *smf_context.SMContext, upf *smf_context.UPF, urrs []*smf_context.URR, reportResaon models.TriggerType, ) { - smContext.SMLock.Lock() - defer smContext.SMLock.Unlock() - for _, urr := range urrs { urr.State = smf_context.RULE_QUERY } diff --git a/internal/sbi/producer/pdu_session.go b/internal/sbi/producer/pdu_session.go index db11e34b..5a021a57 100644 --- a/internal/sbi/producer/pdu_session.go +++ b/internal/sbi/producer/pdu_session.go @@ -441,7 +441,7 @@ func HandlePDUSessionSMContextUpdate(smContextRef string, body models.UpdateSmCo smContext.SetState(smf_context.ModificationPending) response.JsonData.UpCnxState = models.UpCnxState_DEACTIVATED smContext.UpCnxState = body.JsonData.UpCnxState - // UE location change is a charging event + // UE location change is a charging event // TODO: This is not tested yet if smContext.UeLocation != body.JsonData.UeLocation { // All rating group related to this Pdu session should send charging request From eb77066143bef3170ddbc30d276817770a872e64 Mon Sep 17 00:00:00 2001 From: ianchen0119 Date: Wed, 20 Sep 2023 07:11:07 +0000 Subject: [PATCH 16/32] fix typo & linter error --- internal/context/pcc_rule.go | 6 ++++-- internal/context/sm_context.go | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/internal/context/pcc_rule.go b/internal/context/pcc_rule.go index 42990dc3..320f5d55 100644 --- a/internal/context/pcc_rule.go +++ b/internal/context/pcc_rule.go @@ -74,11 +74,13 @@ func (r *PCCRule) IdentifyChargingLevel() (ChargingLevel, error) { if err != nil { return 0, err } - // For pcc that are applicable for all datapath, it's charging level will be Pdu based + // For the PCC rule that are applicable for all datapath, + // it's charging level will be PDU-based if dlIPFilterRule.Src == "any" && dlIPFilterRule.Dst == "assigned" { return PduSessionCharging, nil } else { - // For pcc that have applicable for all datapath fpr a datapath, it's charging level will be flow based + // For the PCC rule that is applicable for all datapath for a datapath, + // it's charging level will be flow-based return FlowCharging, nil } } diff --git a/internal/context/sm_context.go b/internal/context/sm_context.go index ef387ab0..b1d18f9e 100644 --- a/internal/context/sm_context.go +++ b/internal/context/sm_context.go @@ -204,7 +204,7 @@ type SMContext struct { UrrReportThreshold uint64 // Cache the usage reports, sent from UPF // Those information will be included in CDR. - UrrReports []UsageReport + UrrReports []UsageReport // Charging Related ChargingDataRef string From c373a131d796fa73cb9bdcbe23056869424445c2 Mon Sep 17 00:00:00 2001 From: brianchennn Date: Tue, 10 Oct 2023 05:40:55 +0000 Subject: [PATCH 17/32] handle assigned when IP in ipFilterRule is assigned --- internal/context/pcc_rule.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/context/pcc_rule.go b/internal/context/pcc_rule.go index 320f5d55..30c000ae 100644 --- a/internal/context/pcc_rule.go +++ b/internal/context/pcc_rule.go @@ -219,7 +219,7 @@ func createNasPacketFilter( } } - if ipFilterRule.Dst != "any" { + if ipFilterRule.Dst != "any" && ipFilterRule.Dst != "assigned" { _, ipNet, err := net.ParseCIDR(ipFilterRule.Dst) if err != nil { return nil, fmt.Errorf("parse IP fail: %s", err) @@ -242,7 +242,7 @@ func createNasPacketFilter( } } - if ipFilterRule.Src != "any" { + if ipFilterRule.Src != "any" && ipFilterRule.Src != "assigned" { _, ipNet, err := net.ParseCIDR(ipFilterRule.Src) if err != nil { return nil, fmt.Errorf("parse IP fail: %s", err) From 62c70bc1cf6039a1f3c60741d6ecc390b4ff479d Mon Sep 17 00:00:00 2001 From: brianchennn Date: Fri, 13 Oct 2023 08:59:23 +0000 Subject: [PATCH 18/32] fix typo --- internal/context/sm_context_policy.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/context/sm_context_policy.go b/internal/context/sm_context_policy.go index d5e5500d..5538abff 100644 --- a/internal/context/sm_context_policy.go +++ b/internal/context/sm_context_policy.go @@ -68,7 +68,7 @@ func (c *SMContext) RemoveQosFlow(qfi uint8) { delete(c.AdditonalQosFlows, qfi) } -// For urr that created for Pdu session level charging, it show be applied to all data path +// For urr that created for Pdu session level charging, it shall be applied to all data path func (c *SMContext) addPduLevelChargingRuleToFlow(pccRules map[string]*PCCRule) { var pduLevelChargingUrrs []*URR From 51bbb8783426cfbba2344c081f63acc52f198e38 Mon Sep 17 00:00:00 2001 From: Ian Chen Date: Wed, 25 Oct 2023 15:04:45 +0800 Subject: [PATCH 19/32] fix typo & set default value of RequestedUnit --- internal/context/sm_context.go | 6 +++++- internal/sbi/producer/charging_trigger.go | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/internal/context/sm_context.go b/internal/context/sm_context.go index b1d18f9e..313121be 100644 --- a/internal/context/sm_context.go +++ b/internal/context/sm_context.go @@ -309,7 +309,11 @@ func NewSMContext(id string, pduSessID int32) *SMContext { smContext.UrrReportThreshold = factory.SmfConfig.Configuration.UrrThreshold logger.CtxLog.Infof("UrrPeriod: %v", smContext.UrrReportTime) logger.CtxLog.Infof("UrrThreshold: %d", smContext.UrrReportThreshold) - smContext.RequestedUnit = factory.SmfConfig.Configuration.RequestedUnit + if factory.SmfConfig.Configuration.RequestedUnit { + smContext.RequestedUnit = factory.SmfConfig.Configuration.RequestedUnit + } else { + smContext.RequestedUnit = 1000 + } } return smContext diff --git a/internal/sbi/producer/charging_trigger.go b/internal/sbi/producer/charging_trigger.go index 6db28957..922aaf5b 100644 --- a/internal/sbi/producer/charging_trigger.go +++ b/internal/sbi/producer/charging_trigger.go @@ -255,7 +255,7 @@ func updateGrantedQuota(smContext *smf_context.SMContext, multipleUnitInformatio for _, t := range ui.Triggers { switch t.TriggerType { case models.TriggerType_VOLUME_LIMIT: - // According to 32.255, the for the trigger "Expirt of datavolume limit" have tow reporting level + // According to 32.255, the for the trigger "Expirt of datavolume limit" have two reporting level // In the Pdu sesion level, the report should be "Immediate report", // that is this report should send to CHF immediately // In the Rating Group level, the report should be "Defferd report", that is this report should send to CHF From 53f3d626ecb27b60b5587601be782c5f8678695c Mon Sep 17 00:00:00 2001 From: Ian Chen Date: Wed, 25 Oct 2023 15:08:49 +0800 Subject: [PATCH 20/32] fix NewSMContext --- internal/context/sm_context.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/context/sm_context.go b/internal/context/sm_context.go index 313121be..ba8f065c 100644 --- a/internal/context/sm_context.go +++ b/internal/context/sm_context.go @@ -309,7 +309,7 @@ func NewSMContext(id string, pduSessID int32) *SMContext { smContext.UrrReportThreshold = factory.SmfConfig.Configuration.UrrThreshold logger.CtxLog.Infof("UrrPeriod: %v", smContext.UrrReportTime) logger.CtxLog.Infof("UrrThreshold: %d", smContext.UrrReportThreshold) - if factory.SmfConfig.Configuration.RequestedUnit { + if factory.SmfConfig.Configuration.RequestedUnit != 0 { smContext.RequestedUnit = factory.SmfConfig.Configuration.RequestedUnit } else { smContext.RequestedUnit = 1000 From 96d8b7d0083f7ff1f6e6e881728ea52a144e9c3e Mon Sep 17 00:00:00 2001 From: brianchennn Date: Thu, 23 Nov 2023 05:55:47 +0000 Subject: [PATCH 21/32] fix: remove SwapSrcAndDst() --- internal/context/pcc_rule.go | 1 - 1 file changed, 1 deletion(-) diff --git a/internal/context/pcc_rule.go b/internal/context/pcc_rule.go index 30c000ae..0617f340 100644 --- a/internal/context/pcc_rule.go +++ b/internal/context/pcc_rule.go @@ -107,7 +107,6 @@ func getUplinkFlowDescription(dlFlowDesc string) string { return "" } - ulIPFilterRule.SwapSrcAndDst() ulFlowDesc, err := flowdesc.Encode(ulIPFilterRule) if err != nil { return "" From fe96cf23c4fcb34f90d68ca197dc789ab0e7b1a7 Mon Sep 17 00:00:00 2001 From: brianchennn Date: Thu, 23 Nov 2023 07:06:17 +0000 Subject: [PATCH 22/32] fix: UL, DL flow description should be same --- internal/context/pcc_rule.go | 25 +++++-------------------- 1 file changed, 5 insertions(+), 20 deletions(-) diff --git a/internal/context/pcc_rule.go b/internal/context/pcc_rule.go index 0617f340..c63b47ab 100644 --- a/internal/context/pcc_rule.go +++ b/internal/context/pcc_rule.go @@ -93,25 +93,10 @@ func (r *PCCRule) UpdateDataPathFlowDescription(dlFlowDesc string) error { if dlFlowDesc == "" { return fmt.Errorf("pcc[%s]: no flow description", r.PccRuleId) } - ulFlowDesc := getUplinkFlowDescription(dlFlowDesc) - if ulFlowDesc == "" { - return fmt.Errorf("pcc[%s]: uplink flow description parsing error", r.PccRuleId) - } - r.Datapath.UpdateFlowDescription(ulFlowDesc, dlFlowDesc) - return nil -} -func getUplinkFlowDescription(dlFlowDesc string) string { - ulIPFilterRule, err := flowdesc.Decode(dlFlowDesc) - if err != nil { - return "" - } - - ulFlowDesc, err := flowdesc.Encode(ulIPFilterRule) - if err != nil { - return "" - } - return ulFlowDesc + ulFlowDesc := dlFlowDesc + r.Datapath.UpdateFlowDescription(ulFlowDesc, dlFlowDesc) // UL, DL flow description should be same + return nil } func (r *PCCRule) AddDataPathForwardingParameters(c *SMContext, @@ -218,7 +203,7 @@ func createNasPacketFilter( } } - if ipFilterRule.Dst != "any" && ipFilterRule.Dst != "assigned" { + if ipFilterRule.Dst != "assigned" { _, ipNet, err := net.ParseCIDR(ipFilterRule.Dst) if err != nil { return nil, fmt.Errorf("parse IP fail: %s", err) @@ -241,7 +226,7 @@ func createNasPacketFilter( } } - if ipFilterRule.Src != "any" && ipFilterRule.Src != "assigned" { + if ipFilterRule.Src != "any" { _, ipNet, err := net.ParseCIDR(ipFilterRule.Src) if err != nil { return nil, fmt.Errorf("parse IP fail: %s", err) From e6d08d28eab65aadea02427ceb5886e6f7278d10 Mon Sep 17 00:00:00 2001 From: brianchennn Date: Fri, 24 Nov 2023 07:13:36 +0000 Subject: [PATCH 23/32] remove SMF's default data path to reduce redundant PDRs --- internal/context/datapath.go | 8 ++++++++ internal/context/pcc_rule.go | 9 +++++++-- internal/context/sm_context.go | 25 ++++++++++++++++++++----- internal/context/sm_context_policy.go | 6 ++++++ internal/sbi/producer/pdu_session.go | 10 ++++++---- 5 files changed, 47 insertions(+), 11 deletions(-) diff --git a/internal/context/datapath.go b/internal/context/datapath.go index 62e81d27..e21c1853 100644 --- a/internal/context/datapath.go +++ b/internal/context/datapath.go @@ -307,6 +307,14 @@ func (dataPathPool DataPathPool) GetDefaultPath() *DataPath { return nil } +func (dataPathPool DataPathPool) ResetDefaultPath() error { + for _, path := range dataPathPool { + path.IsDefaultPath = false + } + + return nil +} + func (dataPath *DataPath) String() string { firstDPNode := dataPath.FirstDPNode diff --git a/internal/context/pcc_rule.go b/internal/context/pcc_rule.go index c63b47ab..0c40cf92 100644 --- a/internal/context/pcc_rule.go +++ b/internal/context/pcc_rule.go @@ -121,8 +121,13 @@ func (r *PCCRule) AddDataPathForwardingParameters(c *SMContext, return } } - r.Datapath.AddForwardingParameters(routeProf.ForwardingPolicyID, - c.Tunnel.DataPathPool.GetDefaultPath().FirstDPNode.GetUpLinkPDR().PDI.LocalFTeid.Teid) + if c.Tunnel.DataPathPool.GetDefaultPath() == nil { + logger.CtxLog.Infoln("No Default Data Path") + } else { + r.Datapath.AddForwardingParameters(routeProf.ForwardingPolicyID, + c.Tunnel.DataPathPool.GetDefaultPath().FirstDPNode.GetUpLinkPDR().PDI.LocalFTeid.Teid) + } + } func (r *PCCRule) BuildNasQoSRule(smCtx *SMContext, diff --git a/internal/context/sm_context.go b/internal/context/sm_context.go index ba8f065c..5d507480 100644 --- a/internal/context/sm_context.go +++ b/internal/context/sm_context.go @@ -634,6 +634,7 @@ func (c *SMContext) AllocUeIP() error { return nil } +// This function create a data path to be default data path. func (c *SMContext) SelectDefaultDataPath() error { if c.SelectionParam == nil || c.SelectedUPF == nil { return fmt.Errorf("SelectDefaultDataPath err: SelectionParam or SelectedUPF is nil") @@ -646,10 +647,10 @@ func (c *SMContext) SelectDefaultDataPath() error { c.Tunnel.DataPathPool = uePreConfigPaths.DataPathPool c.Tunnel.PathIDGenerator = uePreConfigPaths.PathIDGenerator defaultPath = c.Tunnel.DataPathPool.GetDefaultPath() - } else { - // UE has no pre-config path. + } else if c.Tunnel.DataPathPool.GetDefaultPath() == nil { + // UE has no pre-config path and default path // Use default route - c.Log.Infof("Has no pre-config route") + c.Log.Infof("Has no pre-config route. Has no default path") defaultUPPath := GetUserPlaneInformation().GetDefaultUserPlanePathByDNNAndUPF( c.SelectionParam, c.SelectedUPF) defaultPath = GenerateDataPath(defaultUPPath) @@ -657,13 +658,20 @@ func (c *SMContext) SelectDefaultDataPath() error { defaultPath.IsDefaultPath = true c.Tunnel.AddDataPath(defaultPath) } + } else { + c.Log.Infof("Has no pre-config route. Has default path") + defaultPath = c.Tunnel.DataPathPool.GetDefaultPath() } if defaultPath == nil { - return fmt.Errorf("Data Path not found, Selection Parameter: %s", + return fmt.Errorf("data path not found, Selection Parameter: %s", c.SelectionParam.String()) } - defaultPath.ActivateTunnelAndPDR(c, DefaultPrecedence) + + if !defaultPath.Activated { + defaultPath.ActivateTunnelAndPDR(c, DefaultPrecedence) + } + return nil } @@ -689,6 +697,13 @@ func (c *SMContext) CreatePccRuleDataPath(pccRule *PCCRule, return fmt.Errorf("fail to create data path for pcc rule[%s]", pccRule.PccRuleId) } + // Try to use a default pcc rule as default data path + if c.Tunnel.DataPathPool.GetDefaultPath() == nil && + pccRule.Precedence == 255 && + pccRule.FlowInfos[0].FlowDescription == "permit out ip from any to assigned" { + createdDataPath.IsDefaultPath = true + } + createdDataPath.GBRFlow = isGBRFlow(qosData) createdDataPath.ActivateTunnelAndPDR(c, uint32(pccRule.Precedence)) c.Tunnel.AddDataPath(createdDataPath) diff --git a/internal/context/sm_context_policy.go b/internal/context/sm_context_policy.go index 5538abff..6ea2cd86 100644 --- a/internal/context/sm_context_policy.go +++ b/internal/context/sm_context_policy.go @@ -5,6 +5,7 @@ import ( "reflect" "github.com/free5gc/openapi/models" + "github.com/free5gc/smf/internal/logger" "github.com/free5gc/smf/pkg/factory" ) @@ -102,6 +103,11 @@ func (c *SMContext) addPduLevelChargingRuleToFlow(pccRules map[string]*PCCRule) } defaultPath := c.Tunnel.DataPathPool.GetDefaultPath() + if defaultPath == nil { + logger.CtxLog.Errorln("No default data path") + return + } + for node := defaultPath.FirstDPNode; node != nil; node = node.Next() { if node.IsAnchorUPF() { if node.UpLinkTunnel != nil && node.UpLinkTunnel.PDR != nil { diff --git a/internal/sbi/producer/pdu_session.go b/internal/sbi/producer/pdu_session.go index 5a021a57..7dc7924c 100644 --- a/internal/sbi/producer/pdu_session.go +++ b/internal/sbi/producer/pdu_session.go @@ -200,6 +200,12 @@ func HandlePDUSessionSMContextCreate(isDone <-chan struct{}, &Nsmf_PDUSession.SubscriptionDenied) } + // If PCF prepares default Pcc Rule, SMF do not need to create defaultDataPath. + if err := smContext.ApplyPccRules(smPolicyDecision); err != nil { + smContext.Log.Errorf("apply sm policy decision error: %+v", err) + } + + // SelectDefaultDataPath() will create a default data path if default data path is not found. if err := smContext.SelectDefaultDataPath(); err != nil { smContext.SetState(smf_context.InActive) smContext.Log.Errorf("PDUSessionSMContextCreate err: %v", err) @@ -208,10 +214,6 @@ func HandlePDUSessionSMContextCreate(isDone <-chan struct{}, &Nsmf_PDUSession.InsufficientResourceSliceDnn) } - if err := smContext.ApplyPccRules(smPolicyDecision); err != nil { - smContext.Log.Errorf("apply sm policy decision error: %+v", err) - } - // generate goroutine to handle PFCP and // reply PDUSessionSMContextCreate rsp immediately needUnlock = false From 89bfa6108bec37eaef3a1ab55ad64837e76bc27b Mon Sep 17 00:00:00 2001 From: brianchennn Date: Fri, 24 Nov 2023 08:22:09 +0000 Subject: [PATCH 24/32] fix: testcase's ip.dst should not be any --- internal/context/pcc_rule.go | 1 - internal/sbi/producer/gsm_handler_test.go | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/internal/context/pcc_rule.go b/internal/context/pcc_rule.go index 0c40cf92..1afd5a31 100644 --- a/internal/context/pcc_rule.go +++ b/internal/context/pcc_rule.go @@ -127,7 +127,6 @@ func (r *PCCRule) AddDataPathForwardingParameters(c *SMContext, r.Datapath.AddForwardingParameters(routeProf.ForwardingPolicyID, c.Tunnel.DataPathPool.GetDefaultPath().FirstDPNode.GetUpLinkPDR().PDI.LocalFTeid.Teid) } - } func (r *PCCRule) BuildNasQoSRule(smCtx *SMContext, diff --git a/internal/sbi/producer/gsm_handler_test.go b/internal/sbi/producer/gsm_handler_test.go index df977d68..61f6391b 100644 --- a/internal/sbi/producer/gsm_handler_test.go +++ b/internal/sbi/producer/gsm_handler_test.go @@ -30,7 +30,7 @@ func TestBuildNASPacketFilterFromPacketFilterInfo(t *testing.T) { }, flowInfo: models.FlowInformation{ FlowDirection: models.FlowDirectionRm_BIDIRECTIONAL, - FlowDescription: "permit out ip from any to any", + FlowDescription: "permit out ip from any to assigned", }, }, { From 0cdbfa62d8fc20b0bf15587b012175c78636b2cd Mon Sep 17 00:00:00 2001 From: brianchennn Date: Fri, 24 Nov 2023 08:26:38 +0000 Subject: [PATCH 25/32] style: fix naked return --- internal/context/user_plane_information.go | 10 ++++------ internal/sbi/consumer/nnrf.go | 2 +- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/internal/context/user_plane_information.go b/internal/context/user_plane_information.go index 2ccabe19..712d76f1 100644 --- a/internal/context/user_plane_information.go +++ b/internal/context/user_plane_information.go @@ -748,7 +748,7 @@ func getPathBetween(cur *UPNode, dest *UPNode, visited map[*UPNode]bool, path = make([]*UPNode, 0) path = append(path, cur) pathExist = true - return + return path, pathExist } selectedSNssai := selection.SNssai @@ -760,16 +760,14 @@ func getPathBetween(cur *UPNode, dest *UPNode, visited map[*UPNode]bool, continue } - path_tail, path_exist := getPathBetween(node, dest, visited, selection) + path_tail, pathExist := getPathBetween(node, dest, visited, selection) - if path_exist { + if pathExist { path = make([]*UPNode, 0) path = append(path, cur) - path = append(path, path_tail...) - pathExist = true - return + return path, pathExist } } } diff --git a/internal/sbi/consumer/nnrf.go b/internal/sbi/consumer/nnrf.go index 484fd03b..5e3d8162 100644 --- a/internal/sbi/consumer/nnrf.go +++ b/internal/sbi/consumer/nnrf.go @@ -184,7 +184,7 @@ func SendNFDiscoveryPCF() (problemDetails *models.ProblemDetails, err error) { logger.ConsumerLog.Warnln("handler returned wrong status code ", httpResp.Status) if httpResp.Status != localErr.Error() { err = localErr - return + return problemDetails, err } problem := localErr.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails) problemDetails = &problem From 05b05de0d4903ae187e71420a14a94a550c7ad6a Mon Sep 17 00:00:00 2001 From: brianchennn Date: Mon, 27 Nov 2023 05:44:18 +0000 Subject: [PATCH 26/32] update util's hash --- go.mod | 12 ++++---- go.sum | 86 ++++++++-------------------------------------------------- 2 files changed, 18 insertions(+), 80 deletions(-) diff --git a/go.mod b/go.mod index 6c4dcd19..8a385a31 100644 --- a/go.mod +++ b/go.mod @@ -11,8 +11,8 @@ require ( github.com/free5gc/ngap v1.0.6 github.com/free5gc/openapi v1.0.7-0.20230802173229-2b3ded4db293 github.com/free5gc/pfcp v1.0.7-0.20230629010245-1c089bfc34f7 - github.com/free5gc/util v1.0.5-0.20230511064842-2e120956883b - github.com/gin-gonic/gin v1.9.0 + github.com/free5gc/util v1.0.5-0.20231012123940-85f4557167be + github.com/gin-gonic/gin v1.9.1 github.com/google/uuid v1.3.0 github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 github.com/pkg/errors v0.9.1 @@ -59,11 +59,11 @@ require ( github.com/twitchyliquid64/golang-asm v0.15.1 // indirect github.com/ugorji/go/codec v1.2.11 // indirect golang.org/x/arch v0.3.0 // indirect - golang.org/x/crypto v0.9.0 // indirect - golang.org/x/net v0.10.0 // indirect + golang.org/x/crypto v0.14.0 // indirect + golang.org/x/net v0.17.0 // indirect golang.org/x/oauth2 v0.0.0-20210810183815-faf39c7919d5 // indirect - golang.org/x/sys v0.8.0 // indirect - golang.org/x/text v0.9.0 // indirect + golang.org/x/sys v0.13.0 // indirect + golang.org/x/text v0.13.0 // indirect google.golang.org/appengine v1.6.6 // indirect google.golang.org/protobuf v1.30.0 // indirect gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect diff --git a/go.sum b/go.sum index dd5e192b..32ad6827 100644 --- a/go.sum +++ b/go.sum @@ -33,7 +33,6 @@ cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9 dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= -github.com/aead/cmac v0.0.0-20160719120800-7af84192f0b1/go.mod h1:nuudZmJhzWtx2212z+pkuy7B6nkBqa+xwNXZHL1j8cg= github.com/antihax/optional v1.0.0 h1:xK2lYat7ZLaVVcIuj82J8kIro4V6kDe0AUDFboUCwcg= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/antonfisher/nested-logrus-formatter v1.3.1 h1:NFJIr+pzwv5QLHTPyKz9UMEoHck02Q9L0FP13b/xSbQ= @@ -41,7 +40,6 @@ github.com/antonfisher/nested-logrus-formatter v1.3.1/go.mod h1:6WTfyWFkBc9+zyBa github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d h1:Byv0BzEl3/e6D5CLfI0j/7hiIEtvGVFPCZ7Ei2oq8iQ= github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM= -github.com/bytedance/sonic v1.8.0/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U= github.com/bytedance/sonic v1.9.1 h1:6iJ6NqdoxCDr6mbY8h18oSO+cShGSMRGCEo7F2h0x8s= github.com/bytedance/sonic v1.9.1/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= @@ -63,7 +61,6 @@ github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymF github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/evanphx/json-patch v0.5.2/go.mod h1:ZWS5hhDbVDyob71nXKNL0+PWn6ToqBHMikGIFbs31qQ= github.com/free5gc/aper v1.0.4 h1:Ufbf5lzbXBOhSdUSaIdAhFMOjggsX4p6eWMrpzrrD60= github.com/free5gc/aper v1.0.4/go.mod h1:3K/m47BIPR2xhBkuHD1unp2LnArVtt3iTI4De0bCqpI= github.com/free5gc/nas v1.1.0 h1:8mIncMWG0L9BA+3oMlrYocfZ6qE+P7jZ1oe/tnXLWAs= @@ -71,35 +68,30 @@ github.com/free5gc/nas v1.1.0/go.mod h1:fjWwpyp7/wOyL72HTkjvIe9YTCfGyZosjITsI5sX github.com/free5gc/ngap v1.0.6 h1:f9sKqHMNrFZVo9Kp8hAyrCXSoI8l746N5O+DFn7vKHA= github.com/free5gc/ngap v1.0.6/go.mod h1:TG1kwwU/EyIlJ3bxY591rdxpD5ZeYnLZTzoWjcfvrBM= github.com/free5gc/openapi v1.0.4/go.mod h1:KRCnnp0GeK0Bl4gnrX79cQAidKXNENf8VRdG0y9R0Fc= -github.com/free5gc/openapi v1.0.6/go.mod h1:iw/N0E+FlX44EEx24IBi2EdZW8v+bkj3ETWPGnlK9DI= github.com/free5gc/openapi v1.0.7-0.20230802173229-2b3ded4db293 h1:BSIvKCYu7646sE8J9R1L8v2R435otUik3wOFN33csfs= github.com/free5gc/openapi v1.0.7-0.20230802173229-2b3ded4db293/go.mod h1:iw/N0E+FlX44EEx24IBi2EdZW8v+bkj3ETWPGnlK9DI= github.com/free5gc/pfcp v1.0.7-0.20230629010245-1c089bfc34f7 h1:oE9n4qhoaHkriyp7+vElXggBChs321YIYOe/Y4iPqbg= github.com/free5gc/pfcp v1.0.7-0.20230629010245-1c089bfc34f7/go.mod h1:WzpW7Zxhx5WONMumNKRWbPn7pl/iTYp2FqRLNiOWUjs= github.com/free5gc/tlv v1.0.2-0.20230131124215-8b6ebd69bf93 h1:QPSSI5zw4goiIfxem9doVyMqTO8iKLQ536pzpET5Y+Q= github.com/free5gc/tlv v1.0.2-0.20230131124215-8b6ebd69bf93/go.mod h1:KbbQJIgGaA2jIwnTJgJ/lE3JSDEp3898S6c4TEq0Vyg= -github.com/free5gc/util v1.0.5-0.20230511064842-2e120956883b h1:XMw3j+4AEXLeL/uyiZ7/qYE1X7Ul05RTwWBhzxCLi+0= -github.com/free5gc/util v1.0.5-0.20230511064842-2e120956883b/go.mod h1:l2Jrml4vojDomW5jdDJhIS60KdbrE9uPYhyAq/7OnF4= +github.com/free5gc/util v1.0.5-0.20231012123940-85f4557167be h1:SglM1KIL+bR50hPzbvxVwNW44+yHR2tq9nTpLra75UE= +github.com/free5gc/util v1.0.5-0.20231012123940-85f4557167be/go.mod h1:d+79g84a3YHhzvjJ2IhurrBOavOA8xWIQ/GCywPXqQk= github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU= github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA= github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= -github.com/gin-gonic/gin v1.9.0 h1:OjyFBKICoexlu99ctXNR2gg+c5pKrKMuyjgARg9qeY8= -github.com/gin-gonic/gin v1.9.0/go.mod h1:W1Me9+hsUSyj3CePGrd1/QrKJMSJ1Tu/0hFEH89961k= +github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg= +github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= -github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= -github.com/go-playground/validator/v10 v10.11.2/go.mod h1:NieE624vt4SCTJtD87arVLvdmjPAeV8BQlHtMnw9D7s= github.com/go-playground/validator/v10 v10.14.0 h1:vgvQWe3XCz3gIeFDm/HnTIbj6UGmg/+t63MyGU2n5js= github.com/go-playground/validator/v10 v10.14.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU= -github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/goccy/go-json v0.10.0/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/golang-jwt/jwt v3.2.1+incompatible h1:73Z+4BJcrTC+KczS6WvTPvRGOp1WmfEP4Q1lOd9Z/+c= @@ -130,7 +122,6 @@ github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QD github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0 h1:LUVKkCeviFUMKqHa4tXIIij/lbhnMbP7Fn5wKdKkRh4= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= @@ -140,7 +131,6 @@ github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= @@ -165,7 +155,6 @@ github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542/go.mod h1:Ow0tF8D4Kplb github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= @@ -173,7 +162,6 @@ github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/X github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.2.4 h1:acbojRNwl3o09bUq+yDCtZFc1aiwaAAxtcn8YkZXnvk= github.com/klauspost/cpuid/v2 v2.2.4/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= @@ -185,10 +173,8 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY= github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q= github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4= -github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= @@ -201,10 +187,8 @@ github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9G github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw= github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= -github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc= github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32 h1:W6apQkHrMkS0Muv8G/TipAy/FJl/rCYT0+EuS8+Z0z4= github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32/go.mod h1:9wM+0iRr9ahx58uYLpLIr5fm8diHn0JbqRycJi6w0Ms= -github.com/pelletier/go-toml/v2 v2.0.6/go.mod h1:eumQOmlWiOPt5WriQQqoM5y18pDHwha2N+QD+EUNTek= github.com/pelletier/go-toml/v2 v2.0.8 h1:0ctb6s9mE31h0/lhu+J6OPmVeDxJn+kYnJc2jZR9tGQ= github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNcZljzZR9VXg+4= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= @@ -233,7 +217,6 @@ github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpE github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= @@ -241,25 +224,17 @@ github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.3 h1:RP3t2pwF7cMEbC1dqtB6poj3niw/9gnV4Cjg5oW5gtY= github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= github.com/tim-ywliu/nested-logrus-formatter v1.3.2 h1:jugNJ2/CNCI79SxOJCOhwUHeN3O7/7/bj+ZRGOFlCSw= github.com/tim-ywliu/nested-logrus-formatter v1.3.2/go.mod h1:oGPmcxZB65j9Wo7mCnQKSrKEJtVDqyjD666SGmyStXI= github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= -github.com/ugorji/go/codec v1.2.9/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU= github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= github.com/urfave/cli v1.22.5 h1:lNq9sAHXK2qfdI8W+GRItjCEkI+2oR4d+MEHy1CKXoU= github.com/urfave/cli v1.22.5/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= -github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= -github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs= -github.com/xdg-go/stringprep v1.0.2/go.mod h1:8F9zXuvzgwmyT5DUm4GUfZGDdT3W+LCvS6+da4O5kxM= -github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -go.mongodb.org/mongo-driver v1.8.4/go.mod h1:0sQWfOeY63QTntERDJJ/0SuKK0T1uVSgKCuAROlKEPY= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= @@ -273,12 +248,8 @@ golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20201216223049-8b5274cf687f/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= -golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.5.0/go.mod h1:NK/OQwhpMQP3MwtdjgLlYHnH9ebylxKWv3e0fK+mkQU= -golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= -golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g= -golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= +golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc= +golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -309,8 +280,6 @@ golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzB golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -337,15 +306,9 @@ golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/ golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= -golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= -golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M= -golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= +golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -361,8 +324,6 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -391,38 +352,19 @@ golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU= -golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= +golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= +golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ= -golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= -golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= -golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= -golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= -golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= +golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -436,7 +378,6 @@ golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3 golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190531172133-b3315ee88b7d/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= @@ -468,8 +409,6 @@ golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roY golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -550,7 +489,6 @@ google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpAD google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= From 4788fdf1c86d336321ac0bc0ab1d476e8d344a12 Mon Sep 17 00:00:00 2001 From: brianchennn Date: Tue, 28 Nov 2023 05:23:02 +0000 Subject: [PATCH 27/32] fix: duplicated URRs in PDR --- internal/context/datapath.go | 13 +++++++++---- internal/context/pfcp_rules.go | 17 +++++++++++++++++ internal/context/sm_context_policy.go | 8 ++++---- 3 files changed, 30 insertions(+), 8 deletions(-) diff --git a/internal/context/datapath.go b/internal/context/datapath.go index e21c1853..23f471fd 100644 --- a/internal/context/datapath.go +++ b/internal/context/datapath.go @@ -377,10 +377,10 @@ func (node DataPathNode) addUrrToNode(smContext *SMContext, urrId uint32, isMeas if urr != nil { if node.UpLinkTunnel != nil && node.UpLinkTunnel.PDR != nil { - node.UpLinkTunnel.PDR.URR = append(node.UpLinkTunnel.PDR.URR, urr) + node.UpLinkTunnel.PDR.AppendURRs([]*URR{urr}) } if node.DownLinkTunnel != nil && node.DownLinkTunnel.PDR != nil { - node.DownLinkTunnel.PDR.URR = append(node.DownLinkTunnel.PDR.URR, urr) + node.DownLinkTunnel.PDR.AppendURRs([]*URR{urr}) } } } @@ -409,6 +409,7 @@ func (datapath *DataPath) addUrrToPath(smContext *SMContext) { MBQEUrrId = smContext.UrrIdMap[N9N6_MBEQ_URR] MAQEUrrId = smContext.UrrIdMap[N9N6_MAEQ_URR] } + curDataPathNode.addUrrToNode(smContext, MBQEUrrId, true, true) curDataPathNode.addUrrToNode(smContext, MAQEUrrId, true, false) } @@ -817,10 +818,14 @@ func (p *DataPath) AddChargingRules(smContext *SMContext, chgLevel ChargingLevel smContext.ChargingInfo[urr.URRID] = chgInfo if node.UpLinkTunnel != nil && node.UpLinkTunnel.PDR != nil { - node.UpLinkTunnel.PDR.URR = append(node.UpLinkTunnel.PDR.URR, urr) + if !isUrrExist(node.UpLinkTunnel.PDR.URR, urr) { + node.UpLinkTunnel.PDR.AppendURRs([]*URR{urr}) + } } if node.DownLinkTunnel != nil && node.DownLinkTunnel.PDR != nil { - node.DownLinkTunnel.PDR.URR = append(node.DownLinkTunnel.PDR.URR, urr) + if !isUrrExist(node.DownLinkTunnel.PDR.URR, urr) { + node.DownLinkTunnel.PDR.AppendURRs([]*URR{urr}) + } } } } diff --git a/internal/context/pfcp_rules.go b/internal/context/pfcp_rules.go index a473fd4a..6344ad27 100644 --- a/internal/context/pfcp_rules.go +++ b/internal/context/pfcp_rules.go @@ -95,6 +95,23 @@ func MeasureInformation(isMeasurePkt, isMeasureBeforeQos bool) pfcpType.Measurem return measureInformation } +func (pdr *PDR) AppendURRs(urrs []*URR) { + for _, urr := range urrs { + if !isUrrExist(pdr.URR, urr) { + pdr.URR = append(pdr.URR, urr) + } + } +} + +func isUrrExist(URRs []*URR, urr *URR) bool { // check if urr is in URRs list + for _, URR := range URRs { + if urr.URRID == URR.URRID { + return true + } + } + return false +} + // Packet Detection. 7.5.2.2-2 type PDI struct { SourceInterface pfcpType.SourceInterface diff --git a/internal/context/sm_context_policy.go b/internal/context/sm_context_policy.go index 6ea2cd86..8361ee68 100644 --- a/internal/context/sm_context_policy.go +++ b/internal/context/sm_context_policy.go @@ -92,10 +92,10 @@ func (c *SMContext) addPduLevelChargingRuleToFlow(pccRules map[string]*PCCRule) if node.IsAnchorUPF() { // only the traffic on the PSA UPF will be charged if node.UpLinkTunnel != nil && node.UpLinkTunnel.PDR != nil { - node.UpLinkTunnel.PDR.URR = append(node.UpLinkTunnel.PDR.URR, pduLevelChargingUrrs...) + node.UpLinkTunnel.PDR.AppendURRs(pduLevelChargingUrrs) } if node.DownLinkTunnel != nil && node.DownLinkTunnel.PDR != nil { - node.DownLinkTunnel.PDR.URR = append(node.DownLinkTunnel.PDR.URR, pduLevelChargingUrrs...) + node.DownLinkTunnel.PDR.AppendURRs(pduLevelChargingUrrs) } } } @@ -111,10 +111,10 @@ func (c *SMContext) addPduLevelChargingRuleToFlow(pccRules map[string]*PCCRule) for node := defaultPath.FirstDPNode; node != nil; node = node.Next() { if node.IsAnchorUPF() { if node.UpLinkTunnel != nil && node.UpLinkTunnel.PDR != nil { - node.UpLinkTunnel.PDR.URR = append(node.UpLinkTunnel.PDR.URR, pduLevelChargingUrrs...) + node.UpLinkTunnel.PDR.AppendURRs(pduLevelChargingUrrs) } if node.DownLinkTunnel != nil && node.DownLinkTunnel.PDR != nil { - node.DownLinkTunnel.PDR.URR = append(node.DownLinkTunnel.PDR.URR, pduLevelChargingUrrs...) + node.DownLinkTunnel.PDR.AppendURRs(pduLevelChargingUrrs) } } } From 349408525c734de50b6158993f6194a913c8eaa5 Mon Sep 17 00:00:00 2001 From: brianchennn Date: Fri, 1 Dec 2023 05:53:11 +0000 Subject: [PATCH 28/32] fix: Volume Threshold IE should be added to PFCP Session Modification Request Update URR to prevent the flow rule be blocked --- internal/pfcp/message/build.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/internal/pfcp/message/build.go b/internal/pfcp/message/build.go index c8760d44..8ddbbb78 100644 --- a/internal/pfcp/message/build.go +++ b/internal/pfcp/message/build.go @@ -346,6 +346,8 @@ func urrToUpdateURR(urr *context.URR) *pfcp.UpdateURR { updateURR.VolumeThreshold = &pfcpType.VolumeThreshold{ Dlvol: true, Ulvol: true, + Tovol: true, + TotalVolume: urr.VolumeThreshold, DownlinkVolume: urr.VolumeThreshold, UplinkVolume: urr.VolumeThreshold, } From a9f0c3aef2622ecf61d9ddadab6495a63112c047 Mon Sep 17 00:00:00 2001 From: brianchennn Date: Thu, 7 Dec 2023 07:58:22 +0000 Subject: [PATCH 29/32] remove SMContext.UrrIDGenerator --- go.sum | 55 ++++++++++++++++++++++- internal/context/datapath.go | 39 +++++++++++++++- internal/context/sm_context.go | 47 ++++++++++--------- internal/sbi/producer/charging_trigger.go | 2 +- 4 files changed, 115 insertions(+), 28 deletions(-) diff --git a/go.sum b/go.sum index 32ad6827..3a4bd712 100644 --- a/go.sum +++ b/go.sum @@ -33,6 +33,7 @@ cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9 dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/aead/cmac v0.0.0-20160719120800-7af84192f0b1/go.mod h1:nuudZmJhzWtx2212z+pkuy7B6nkBqa+xwNXZHL1j8cg= github.com/antihax/optional v1.0.0 h1:xK2lYat7ZLaVVcIuj82J8kIro4V6kDe0AUDFboUCwcg= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/antonfisher/nested-logrus-formatter v1.3.1 h1:NFJIr+pzwv5QLHTPyKz9UMEoHck02Q9L0FP13b/xSbQ= @@ -61,6 +62,7 @@ github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymF github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/evanphx/json-patch v0.5.2/go.mod h1:ZWS5hhDbVDyob71nXKNL0+PWn6ToqBHMikGIFbs31qQ= github.com/free5gc/aper v1.0.4 h1:Ufbf5lzbXBOhSdUSaIdAhFMOjggsX4p6eWMrpzrrD60= github.com/free5gc/aper v1.0.4/go.mod h1:3K/m47BIPR2xhBkuHD1unp2LnArVtt3iTI4De0bCqpI= github.com/free5gc/nas v1.1.0 h1:8mIncMWG0L9BA+3oMlrYocfZ6qE+P7jZ1oe/tnXLWAs= @@ -68,14 +70,13 @@ github.com/free5gc/nas v1.1.0/go.mod h1:fjWwpyp7/wOyL72HTkjvIe9YTCfGyZosjITsI5sX github.com/free5gc/ngap v1.0.6 h1:f9sKqHMNrFZVo9Kp8hAyrCXSoI8l746N5O+DFn7vKHA= github.com/free5gc/ngap v1.0.6/go.mod h1:TG1kwwU/EyIlJ3bxY591rdxpD5ZeYnLZTzoWjcfvrBM= github.com/free5gc/openapi v1.0.4/go.mod h1:KRCnnp0GeK0Bl4gnrX79cQAidKXNENf8VRdG0y9R0Fc= +github.com/free5gc/openapi v1.0.6/go.mod h1:iw/N0E+FlX44EEx24IBi2EdZW8v+bkj3ETWPGnlK9DI= github.com/free5gc/openapi v1.0.7-0.20230802173229-2b3ded4db293 h1:BSIvKCYu7646sE8J9R1L8v2R435otUik3wOFN33csfs= github.com/free5gc/openapi v1.0.7-0.20230802173229-2b3ded4db293/go.mod h1:iw/N0E+FlX44EEx24IBi2EdZW8v+bkj3ETWPGnlK9DI= github.com/free5gc/pfcp v1.0.7-0.20230629010245-1c089bfc34f7 h1:oE9n4qhoaHkriyp7+vElXggBChs321YIYOe/Y4iPqbg= github.com/free5gc/pfcp v1.0.7-0.20230629010245-1c089bfc34f7/go.mod h1:WzpW7Zxhx5WONMumNKRWbPn7pl/iTYp2FqRLNiOWUjs= github.com/free5gc/tlv v1.0.2-0.20230131124215-8b6ebd69bf93 h1:QPSSI5zw4goiIfxem9doVyMqTO8iKLQ536pzpET5Y+Q= github.com/free5gc/tlv v1.0.2-0.20230131124215-8b6ebd69bf93/go.mod h1:KbbQJIgGaA2jIwnTJgJ/lE3JSDEp3898S6c4TEq0Vyg= -github.com/free5gc/util v1.0.5-0.20231012123940-85f4557167be h1:SglM1KIL+bR50hPzbvxVwNW44+yHR2tq9nTpLra75UE= -github.com/free5gc/util v1.0.5-0.20231012123940-85f4557167be/go.mod h1:d+79g84a3YHhzvjJ2IhurrBOavOA8xWIQ/GCywPXqQk= github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU= github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA= github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= @@ -86,12 +87,14 @@ github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9 github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= +github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= github.com/go-playground/validator/v10 v10.14.0 h1:vgvQWe3XCz3gIeFDm/HnTIbj6UGmg/+t63MyGU2n5js= github.com/go-playground/validator/v10 v10.14.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/golang-jwt/jwt v3.2.1+incompatible h1:73Z+4BJcrTC+KczS6WvTPvRGOp1WmfEP4Q1lOd9Z/+c= @@ -122,6 +125,7 @@ github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QD github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0 h1:LUVKkCeviFUMKqHa4tXIIij/lbhnMbP7Fn5wKdKkRh4= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= @@ -131,6 +135,7 @@ github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= @@ -155,6 +160,7 @@ github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542/go.mod h1:Ow0tF8D4Kplb github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= @@ -162,6 +168,7 @@ github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/X github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.2.4 h1:acbojRNwl3o09bUq+yDCtZFc1aiwaAAxtcn8YkZXnvk= github.com/klauspost/cpuid/v2 v2.2.4/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= @@ -187,6 +194,7 @@ github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9G github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw= github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= +github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc= github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32 h1:W6apQkHrMkS0Muv8G/TipAy/FJl/rCYT0+EuS8+Z0z4= github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32/go.mod h1:9wM+0iRr9ahx58uYLpLIr5fm8diHn0JbqRycJi6w0Ms= github.com/pelletier/go-toml/v2 v2.0.8 h1:0ctb6s9mE31h0/lhu+J6OPmVeDxJn+kYnJc2jZR9tGQ= @@ -217,6 +225,7 @@ github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpE github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= @@ -224,6 +233,7 @@ github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.3 h1:RP3t2pwF7cMEbC1dqtB6poj3niw/9gnV4Cjg5oW5gtY= github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= github.com/tim-ywliu/nested-logrus-formatter v1.3.2 h1:jugNJ2/CNCI79SxOJCOhwUHeN3O7/7/bj+ZRGOFlCSw= github.com/tim-ywliu/nested-logrus-formatter v1.3.2/go.mod h1:oGPmcxZB65j9Wo7mCnQKSrKEJtVDqyjD666SGmyStXI= github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= @@ -232,9 +242,15 @@ github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4d github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= github.com/urfave/cli v1.22.5 h1:lNq9sAHXK2qfdI8W+GRItjCEkI+2oR4d+MEHy1CKXoU= github.com/urfave/cli v1.22.5/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= +github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= +github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs= +github.com/xdg-go/stringprep v1.0.2/go.mod h1:8F9zXuvzgwmyT5DUm4GUfZGDdT3W+LCvS6+da4O5kxM= +github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +go.mongodb.org/mongo-driver v1.8.4/go.mod h1:0sQWfOeY63QTntERDJJ/0SuKK0T1uVSgKCuAROlKEPY= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= @@ -248,6 +264,10 @@ golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20201216223049-8b5274cf687f/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= +golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc= golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -280,6 +300,8 @@ golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzB golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -306,7 +328,13 @@ golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/ golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -324,6 +352,8 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -352,17 +382,35 @@ golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= +golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -378,6 +426,7 @@ golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3 golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190531172133-b3315ee88b7d/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= @@ -409,6 +458,8 @@ golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roY golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/internal/context/datapath.go b/internal/context/datapath.go index 23f471fd..3e930d2f 100644 --- a/internal/context/datapath.go +++ b/internal/context/datapath.go @@ -772,7 +772,44 @@ func (p *DataPath) AddChargingRules(smContext *SMContext, chgLevel ChargingLevel UpfId: node.UPF.UUID(), } - urrId, err := smContext.UrrIDGenerator.Allocate() + if smContext.UrrIdMap[N3N6_MBEQ_URR] == 0 { + if id, err := node.UPF.urrIDGenerator.Allocate(); err == nil { + smContext.UrrIdMap[N3N6_MBEQ_URR] = uint32(id) + } + } + + if smContext.UrrIdMap[N3N6_MAEQ_URR] == 0 { + if id, err := node.UPF.urrIDGenerator.Allocate(); err == nil { + smContext.UrrIdMap[N3N6_MAEQ_URR] = uint32(id) + } + } + + if smContext.UrrIdMap[N9N6_MBEQ_URR] == 0 { + if id, err := node.UPF.urrIDGenerator.Allocate(); err == nil { + smContext.UrrIdMap[N9N6_MBEQ_URR] = uint32(id) + } + } + + if smContext.UrrIdMap[N9N6_MAEQ_URR] == 0 { + if id, err := node.UPF.urrIDGenerator.Allocate(); err == nil { + smContext.UrrIdMap[N9N6_MAEQ_URR] = uint32(id) + } + } + + if smContext.UrrIdMap[N3N9_MBEQ_URR] == 0 { + if id, err := node.UPF.urrIDGenerator.Allocate(); err == nil { + smContext.UrrIdMap[N3N9_MBEQ_URR] = uint32(id) + } + } + + if smContext.UrrIdMap[N3N9_MAEQ_URR] == 0 { + if id, err := node.UPF.urrIDGenerator.Allocate(); err == nil { + smContext.UrrIdMap[N3N9_MAEQ_URR] = uint32(id) + } + } + + urrId, err := node.UPF.urrIDGenerator.Allocate() + logger.CtxLog.Warnln("urrId:", urrId) if err != nil { logger.PduSessLog.Errorln("Generate URR Id failed") return diff --git a/internal/context/sm_context.go b/internal/context/sm_context.go index 5d507480..73b5df0c 100644 --- a/internal/context/sm_context.go +++ b/internal/context/sm_context.go @@ -3,7 +3,6 @@ package context import ( "context" "fmt" - "math" "net" "net/http" "strings" @@ -197,7 +196,7 @@ type SMContext struct { AdditonalQosFlows map[uint8]*QoSFlow // Key: qfi // URR - UrrIDGenerator *idgenerator.IDGenerator + // UrrIDGenerator *idgenerator.IDGenerator // should be deprecated UrrIdMap map[UrrType]uint32 UrrUpfMap map[string]*URR UrrReportTime time.Duration @@ -296,9 +295,9 @@ func NewSMContext(id string, pduSessID int32) *SMContext { smContext.AMBRQerMap = make(map[uuid.UUID]uint32) smContext.QerUpfMap = make(map[string]uint32) smContext.AdditonalQosFlows = make(map[uint8]*QoSFlow) - smContext.UrrIDGenerator = idgenerator.NewGenerator(1, math.MaxUint32) + // smContext.UrrIDGenerator = idgenerator.NewGenerator(1, math.MaxUint32) smContext.UrrIdMap = make(map[UrrType]uint32) - smContext.GenerateUrrId() + // smContext.GenerateUrrId() smContext.UrrUpfMap = make(map[string]*URR) smContext.ChargingInfo = make(map[uint32]*ChargingInfo) @@ -375,26 +374,26 @@ func GetSMContextBySEID(SEID uint64) *SMContext { return nil } -func (smContext *SMContext) GenerateUrrId() { - if id, err := smContext.UrrIDGenerator.Allocate(); err == nil { - smContext.UrrIdMap[N3N6_MBEQ_URR] = uint32(id) - } - if id, err := smContext.UrrIDGenerator.Allocate(); err == nil { - smContext.UrrIdMap[N3N6_MAEQ_URR] = uint32(id) - } - if id, err := smContext.UrrIDGenerator.Allocate(); err == nil { - smContext.UrrIdMap[N9N6_MBEQ_URR] = uint32(id) - } - if id, err := smContext.UrrIDGenerator.Allocate(); err == nil { - smContext.UrrIdMap[N9N6_MAEQ_URR] = uint32(id) - } - if id, err := smContext.UrrIDGenerator.Allocate(); err == nil { - smContext.UrrIdMap[N3N9_MBEQ_URR] = uint32(id) - } - if id, err := smContext.UrrIDGenerator.Allocate(); err == nil { - smContext.UrrIdMap[N3N9_MAEQ_URR] = uint32(id) - } -} +// func (smContext *SMContext) GenerateUrrId() { +// if id, err := smContext.UrrIDGenerator.Allocate(); err == nil { +// smContext.UrrIdMap[N3N6_MBEQ_URR] = uint32(id) +// } +// if id, err := smContext.UrrIDGenerator.Allocate(); err == nil { +// smContext.UrrIdMap[N3N6_MAEQ_URR] = uint32(id) +// } +// if id, err := smContext.UrrIDGenerator.Allocate(); err == nil { +// smContext.UrrIdMap[N9N6_MBEQ_URR] = uint32(id) +// } +// if id, err := smContext.UrrIDGenerator.Allocate(); err == nil { +// smContext.UrrIdMap[N9N6_MAEQ_URR] = uint32(id) +// } +// if id, err := smContext.UrrIDGenerator.Allocate(); err == nil { +// smContext.UrrIdMap[N3N9_MBEQ_URR] = uint32(id) +// } +// if id, err := smContext.UrrIDGenerator.Allocate(); err == nil { +// smContext.UrrIdMap[N3N9_MAEQ_URR] = uint32(id) +// } +// } func (smContext *SMContext) BuildCreatedData() *models.SmContextCreatedData { return &models.SmContextCreatedData{ diff --git a/internal/sbi/producer/charging_trigger.go b/internal/sbi/producer/charging_trigger.go index 922aaf5b..775dc056 100644 --- a/internal/sbi/producer/charging_trigger.go +++ b/internal/sbi/producer/charging_trigger.go @@ -240,7 +240,7 @@ func getUrrByRg(smContext *smf_context.SMContext, upfId string, rg int32) *smf_c return nil } -// Udate the urr by the charging information renewed by chf +// Update the urr by the charging information renewed by chf func updateGrantedQuota(smContext *smf_context.SMContext, multipleUnitInformation []models.MultipleUnitInformation) { for _, ui := range multipleUnitInformation { trigger := pfcpType.ReportingTriggers{} From 55743dabe1bdcb7dbdf32354fda3078250db1866 Mon Sep 17 00:00:00 2001 From: brianchennn Date: Thu, 7 Dec 2023 08:17:09 +0000 Subject: [PATCH 30/32] fix: MBQE, MAQE's URR --- go.sum | 2 + internal/context/datapath.go | 70 +++++++++++++++++----------------- internal/context/sm_context.go | 35 ++++------------- 3 files changed, 45 insertions(+), 62 deletions(-) diff --git a/go.sum b/go.sum index 3a4bd712..450b3373 100644 --- a/go.sum +++ b/go.sum @@ -77,6 +77,8 @@ github.com/free5gc/pfcp v1.0.7-0.20230629010245-1c089bfc34f7 h1:oE9n4qhoaHkriyp7 github.com/free5gc/pfcp v1.0.7-0.20230629010245-1c089bfc34f7/go.mod h1:WzpW7Zxhx5WONMumNKRWbPn7pl/iTYp2FqRLNiOWUjs= github.com/free5gc/tlv v1.0.2-0.20230131124215-8b6ebd69bf93 h1:QPSSI5zw4goiIfxem9doVyMqTO8iKLQ536pzpET5Y+Q= github.com/free5gc/tlv v1.0.2-0.20230131124215-8b6ebd69bf93/go.mod h1:KbbQJIgGaA2jIwnTJgJ/lE3JSDEp3898S6c4TEq0Vyg= +github.com/free5gc/util v1.0.5-0.20231012123940-85f4557167be h1:SglM1KIL+bR50hPzbvxVwNW44+yHR2tq9nTpLra75UE= +github.com/free5gc/util v1.0.5-0.20231012123940-85f4557167be/go.mod h1:d+79g84a3YHhzvjJ2IhurrBOavOA8xWIQ/GCywPXqQk= github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU= github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA= github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= diff --git a/internal/context/datapath.go b/internal/context/datapath.go index 3e930d2f..1cf532d3 100644 --- a/internal/context/datapath.go +++ b/internal/context/datapath.go @@ -399,15 +399,15 @@ func (datapath *DataPath) addUrrToPath(smContext *SMContext) { // There may be some mechanism to make sure that existed URR should not be create again if curDataPathNode.IsANUPF() { if curDataPathNode.Next() == nil { - MBQEUrrId = smContext.UrrIdMap[N3N6_MBEQ_URR] - MAQEUrrId = smContext.UrrIdMap[N3N6_MAEQ_URR] + MBQEUrrId = smContext.UrrIdMap[N3N6_MBQE_URR] + MAQEUrrId = smContext.UrrIdMap[N3N6_MAQE_URR] } else { - MBQEUrrId = smContext.UrrIdMap[N3N9_MBEQ_URR] - MAQEUrrId = smContext.UrrIdMap[N3N9_MAEQ_URR] + MBQEUrrId = smContext.UrrIdMap[N3N9_MBQE_URR] + MAQEUrrId = smContext.UrrIdMap[N3N9_MAQE_URR] } } else { - MBQEUrrId = smContext.UrrIdMap[N9N6_MBEQ_URR] - MAQEUrrId = smContext.UrrIdMap[N9N6_MAEQ_URR] + MBQEUrrId = smContext.UrrIdMap[N9N6_MBQE_URR] + MAQEUrrId = smContext.UrrIdMap[N9N6_MAQE_URR] } curDataPathNode.addUrrToNode(smContext, MBQEUrrId, true, true) @@ -772,39 +772,29 @@ func (p *DataPath) AddChargingRules(smContext *SMContext, chgLevel ChargingLevel UpfId: node.UPF.UUID(), } - if smContext.UrrIdMap[N3N6_MBEQ_URR] == 0 { - if id, err := node.UPF.urrIDGenerator.Allocate(); err == nil { - smContext.UrrIdMap[N3N6_MBEQ_URR] = uint32(id) - } - } - - if smContext.UrrIdMap[N3N6_MAEQ_URR] == 0 { - if id, err := node.UPF.urrIDGenerator.Allocate(); err == nil { - smContext.UrrIdMap[N3N6_MAEQ_URR] = uint32(id) - } - } - - if smContext.UrrIdMap[N9N6_MBEQ_URR] == 0 { - if id, err := node.UPF.urrIDGenerator.Allocate(); err == nil { - smContext.UrrIdMap[N9N6_MBEQ_URR] = uint32(id) + if node.Prev() == nil { + if smContext.UrrIdMap[N3N6_MBQE_URR] == 0 { + if id, err := node.UPF.urrIDGenerator.Allocate(); err == nil { + smContext.UrrIdMap[N3N6_MBQE_URR] = uint32(id) + } } - } - if smContext.UrrIdMap[N9N6_MAEQ_URR] == 0 { - if id, err := node.UPF.urrIDGenerator.Allocate(); err == nil { - smContext.UrrIdMap[N9N6_MAEQ_URR] = uint32(id) + if smContext.UrrIdMap[N3N6_MAQE_URR] == 0 { + if id, err := node.UPF.urrIDGenerator.Allocate(); err == nil { + smContext.UrrIdMap[N3N6_MAQE_URR] = uint32(id) + } } - } - - if smContext.UrrIdMap[N3N9_MBEQ_URR] == 0 { - if id, err := node.UPF.urrIDGenerator.Allocate(); err == nil { - smContext.UrrIdMap[N3N9_MBEQ_URR] = uint32(id) + } else { + if smContext.UrrIdMap[N9N6_MBQE_URR] == 0 { + if id, err := node.UPF.urrIDGenerator.Allocate(); err == nil { + smContext.UrrIdMap[N9N6_MBQE_URR] = uint32(id) + } } - } - if smContext.UrrIdMap[N3N9_MAEQ_URR] == 0 { - if id, err := node.UPF.urrIDGenerator.Allocate(); err == nil { - smContext.UrrIdMap[N3N9_MAEQ_URR] = uint32(id) + if smContext.UrrIdMap[N9N6_MAQE_URR] == 0 { + if id, err := node.UPF.urrIDGenerator.Allocate(); err == nil { + smContext.UrrIdMap[N9N6_MAQE_URR] = uint32(id) + } } } @@ -865,6 +855,18 @@ func (p *DataPath) AddChargingRules(smContext *SMContext, chgLevel ChargingLevel } } } + } else { + if smContext.UrrIdMap[N3N9_MBQE_URR] == 0 { + if id, err := node.UPF.urrIDGenerator.Allocate(); err == nil { + smContext.UrrIdMap[N3N9_MBQE_URR] = uint32(id) + } + } + + if smContext.UrrIdMap[N3N9_MAQE_URR] == 0 { + if id, err := node.UPF.urrIDGenerator.Allocate(); err == nil { + smContext.UrrIdMap[N3N9_MAQE_URR] = uint32(id) + } + } } } } diff --git a/internal/context/sm_context.go b/internal/context/sm_context.go index 73b5df0c..696a79d7 100644 --- a/internal/context/sm_context.go +++ b/internal/context/sm_context.go @@ -46,17 +46,17 @@ const ( type UrrType int const ( - N3N6_MBEQ_URR UrrType = iota - N3N6_MAEQ_URR - N3N9_MBEQ_URR - N3N9_MAEQ_URR - N9N6_MBEQ_URR - N9N6_MAEQ_URR + N3N6_MBQE_URR UrrType = iota + N3N6_MAQE_URR + N3N9_MBQE_URR + N3N9_MAQE_URR + N9N6_MBQE_URR + N9N6_MAQE_URR NOT_FOUND_URR ) func (t UrrType) String() string { - urrTypeList := []string{"N3N6_MBEQ", "N3N6_MAEQ", "N3N9_MBEQ", "N3N9_MAEQ", "N9N6_MBEQ", "N9N6_MAEQ"} + urrTypeList := []string{"N3N6_MBQE", "N3N6_MAQE", "N3N9_MBQE", "N3N9_MAQE", "N9N6_MBQE", "N9N6_MAQE"} return urrTypeList[t] } @@ -374,27 +374,6 @@ func GetSMContextBySEID(SEID uint64) *SMContext { return nil } -// func (smContext *SMContext) GenerateUrrId() { -// if id, err := smContext.UrrIDGenerator.Allocate(); err == nil { -// smContext.UrrIdMap[N3N6_MBEQ_URR] = uint32(id) -// } -// if id, err := smContext.UrrIDGenerator.Allocate(); err == nil { -// smContext.UrrIdMap[N3N6_MAEQ_URR] = uint32(id) -// } -// if id, err := smContext.UrrIDGenerator.Allocate(); err == nil { -// smContext.UrrIdMap[N9N6_MBEQ_URR] = uint32(id) -// } -// if id, err := smContext.UrrIDGenerator.Allocate(); err == nil { -// smContext.UrrIdMap[N9N6_MAEQ_URR] = uint32(id) -// } -// if id, err := smContext.UrrIDGenerator.Allocate(); err == nil { -// smContext.UrrIdMap[N3N9_MBEQ_URR] = uint32(id) -// } -// if id, err := smContext.UrrIDGenerator.Allocate(); err == nil { -// smContext.UrrIdMap[N3N9_MAEQ_URR] = uint32(id) -// } -// } - func (smContext *SMContext) BuildCreatedData() *models.SmContextCreatedData { return &models.SmContextCreatedData{ SNssai: smContext.SNssai, From ce7b0ced2b549ae376d5397a57f304c9a33c156d Mon Sep 17 00:00:00 2001 From: brianchennn Date: Thu, 7 Dec 2023 09:05:59 +0000 Subject: [PATCH 31/32] comment out these variable: N3N6, N3N9, N9N6 --- internal/context/datapath.go | 64 +++++++--------------------------- internal/context/sm_context.go | 34 +++++++++--------- 2 files changed, 29 insertions(+), 69 deletions(-) diff --git a/internal/context/datapath.go b/internal/context/datapath.go index 1cf532d3..de868fb1 100644 --- a/internal/context/datapath.go +++ b/internal/context/datapath.go @@ -392,26 +392,25 @@ func (datapath *DataPath) addUrrToPath(smContext *SMContext) { } for curDataPathNode := datapath.FirstDPNode; curDataPathNode != nil; curDataPathNode = curDataPathNode.Next() { - var MBQEUrrId uint32 - var MAQEUrrId uint32 + var MBQEUrrId int64 + var MAQEUrrId int64 + var err error // If more than two data path will use the same UPF // It may cause urr be created multiple times // There may be some mechanism to make sure that existed URR should not be create again if curDataPathNode.IsANUPF() { - if curDataPathNode.Next() == nil { - MBQEUrrId = smContext.UrrIdMap[N3N6_MBQE_URR] - MAQEUrrId = smContext.UrrIdMap[N3N6_MAQE_URR] - } else { - MBQEUrrId = smContext.UrrIdMap[N3N9_MBQE_URR] - MAQEUrrId = smContext.UrrIdMap[N3N9_MAQE_URR] + MBQEUrrId, err = curDataPathNode.UPF.urrIDGenerator.Allocate() + if err != nil { + logger.CtxLog.Warnf("MBQE URR ID allocate error: %v\n", err) + } + MAQEUrrId, err = curDataPathNode.UPF.urrIDGenerator.Allocate() + if err != nil { + logger.CtxLog.Warnf("MAQE URR ID allocate error: %v\n", err) } - } else { - MBQEUrrId = smContext.UrrIdMap[N9N6_MBQE_URR] - MAQEUrrId = smContext.UrrIdMap[N9N6_MAQE_URR] } - curDataPathNode.addUrrToNode(smContext, MBQEUrrId, true, true) - curDataPathNode.addUrrToNode(smContext, MAQEUrrId, true, false) + curDataPathNode.addUrrToNode(smContext, uint32(MBQEUrrId), true, true) + curDataPathNode.addUrrToNode(smContext, uint32(MAQEUrrId), true, false) } } @@ -772,34 +771,7 @@ func (p *DataPath) AddChargingRules(smContext *SMContext, chgLevel ChargingLevel UpfId: node.UPF.UUID(), } - if node.Prev() == nil { - if smContext.UrrIdMap[N3N6_MBQE_URR] == 0 { - if id, err := node.UPF.urrIDGenerator.Allocate(); err == nil { - smContext.UrrIdMap[N3N6_MBQE_URR] = uint32(id) - } - } - - if smContext.UrrIdMap[N3N6_MAQE_URR] == 0 { - if id, err := node.UPF.urrIDGenerator.Allocate(); err == nil { - smContext.UrrIdMap[N3N6_MAQE_URR] = uint32(id) - } - } - } else { - if smContext.UrrIdMap[N9N6_MBQE_URR] == 0 { - if id, err := node.UPF.urrIDGenerator.Allocate(); err == nil { - smContext.UrrIdMap[N9N6_MBQE_URR] = uint32(id) - } - } - - if smContext.UrrIdMap[N9N6_MAQE_URR] == 0 { - if id, err := node.UPF.urrIDGenerator.Allocate(); err == nil { - smContext.UrrIdMap[N9N6_MAQE_URR] = uint32(id) - } - } - } - urrId, err := node.UPF.urrIDGenerator.Allocate() - logger.CtxLog.Warnln("urrId:", urrId) if err != nil { logger.PduSessLog.Errorln("Generate URR Id failed") return @@ -855,18 +827,6 @@ func (p *DataPath) AddChargingRules(smContext *SMContext, chgLevel ChargingLevel } } } - } else { - if smContext.UrrIdMap[N3N9_MBQE_URR] == 0 { - if id, err := node.UPF.urrIDGenerator.Allocate(); err == nil { - smContext.UrrIdMap[N3N9_MBQE_URR] = uint32(id) - } - } - - if smContext.UrrIdMap[N3N9_MAQE_URR] == 0 { - if id, err := node.UPF.urrIDGenerator.Allocate(); err == nil { - smContext.UrrIdMap[N3N9_MAQE_URR] = uint32(id) - } - } } } } diff --git a/internal/context/sm_context.go b/internal/context/sm_context.go index 696a79d7..401bdfa1 100644 --- a/internal/context/sm_context.go +++ b/internal/context/sm_context.go @@ -45,15 +45,15 @@ const ( type UrrType int -const ( - N3N6_MBQE_URR UrrType = iota - N3N6_MAQE_URR - N3N9_MBQE_URR - N3N9_MAQE_URR - N9N6_MBQE_URR - N9N6_MAQE_URR - NOT_FOUND_URR -) +// const ( +// N3N6_MBQE_URR UrrType = iota +// N3N6_MAQE_URR +// N3N9_MBQE_URR +// N3N9_MAQE_URR +// N9N6_MBQE_URR +// N9N6_MAQE_URR +// NOT_FOUND_URR +// ) func (t UrrType) String() string { urrTypeList := []string{"N3N6_MBQE", "N3N6_MAQE", "N3N9_MBQE", "N3N9_MAQE", "N9N6_MBQE", "N9N6_MAQE"} @@ -881,14 +881,14 @@ func (smContext *SMContext) IsAllowedPDUSessionType(requestedPDUSessionType uint return nil } -func (smContext *SMContext) GetUrrTypeById(urrId uint32) (UrrType, error) { - for urrType, id := range smContext.UrrIdMap { - if id == urrId { - return urrType, nil - } - } - return NOT_FOUND_URR, fmt.Errorf("Urr type not found ") -} +// func (smContext *SMContext) GetUrrTypeById(urrId uint32) (UrrType, error) { +// for urrType, id := range smContext.UrrIdMap { +// if id == urrId { +// return urrType, nil +// } +// } +// return NOT_FOUND_URR, fmt.Errorf("Urr type not found ") +// } func (smContext *SMContext) StopT3591() { if smContext.T3591 != nil { From c8f767d5dc627dfa56b0788835591cd5e2e0ef3d Mon Sep 17 00:00:00 2001 From: brianchennn Date: Tue, 12 Dec 2023 10:53:31 +0000 Subject: [PATCH 32/32] remove FlowDescription judgement --- internal/context/sm_context.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/internal/context/sm_context.go b/internal/context/sm_context.go index 401bdfa1..9325b9e0 100644 --- a/internal/context/sm_context.go +++ b/internal/context/sm_context.go @@ -677,8 +677,7 @@ func (c *SMContext) CreatePccRuleDataPath(pccRule *PCCRule, // Try to use a default pcc rule as default data path if c.Tunnel.DataPathPool.GetDefaultPath() == nil && - pccRule.Precedence == 255 && - pccRule.FlowInfos[0].FlowDescription == "permit out ip from any to assigned" { + pccRule.Precedence == 255 { createdDataPath.IsDefaultPath = true }