From 60c51a47041a0ecb6056857a379f535d64a53fce Mon Sep 17 00:00:00 2001 From: "akagi.mari" Date: Wed, 27 Jul 2022 00:01:21 +0000 Subject: [PATCH 1/5] Retry PFCP Association Setup --- internal/context/context.go | 20 +++++++++++++----- pkg/factory/config.go | 5 +++-- pkg/service/association.go | 42 +++++++++++++++++++++++++++++++++++++ pkg/service/init.go | 26 +++++++++-------------- 4 files changed, 70 insertions(+), 23 deletions(-) diff --git a/internal/context/context.go b/internal/context/context.go index d4c5e5c7..794db84f 100644 --- a/internal/context/context.go +++ b/internal/context/context.go @@ -1,10 +1,12 @@ package context import ( + "context" "fmt" "net" "os" "sync/atomic" + "time" "github.com/google/uuid" @@ -43,13 +45,15 @@ type SMFContext struct { SnssaiInfos []SnssaiSmfInfo - NrfUri string - NFManagementClient *Nnrf_NFManagement.APIClient - NFDiscoveryClient *Nnrf_NFDiscovery.APIClient - SubscriberDataManagementClient *Nudm_SubscriberDataManagement.APIClient - Locality string + NrfUri string + NFManagementClient *Nnrf_NFManagement.APIClient + NFDiscoveryClient *Nnrf_NFDiscovery.APIClient + SubscriberDataManagementClient *Nudm_SubscriberDataManagement.APIClient + Locality string + AssociationSetupFailedAlertInterval time.Duration UserPlaneInformation *UserPlaneInformation + PFCPCancelFunc context.CancelFunc // Now only "IPv4" supported // TODO: support "IPv6", "IPv4v6", "Ethernet" @@ -154,6 +158,12 @@ func InitSmfContext(config *factory.Config) { smfContext.CPNodeID.NodeIdType = pfcpType.NodeIdTypeIpv6Address smfContext.CPNodeID.IP = addr.IP } + + if pfcp.AssociationSetupFailedAlertInterval == 0 { + smfContext.AssociationSetupFailedAlertInterval = 5 * time.Minute + } else { + smfContext.AssociationSetupFailedAlertInterval = pfcp.AssociationSetupFailedAlertInterval + } } smfContext.SnssaiInfos = make([]SnssaiSmfInfo, 0, len(configuration.SNssaiInfo)) diff --git a/pkg/factory/config.go b/pkg/factory/config.go index 4f4c6a42..a1cda3dc 100644 --- a/pkg/factory/config.go +++ b/pkg/factory/config.go @@ -210,8 +210,9 @@ func (t *Tls) validate() (bool, error) { } type PFCP struct { - Addr string `yaml:"addr,omitempty" valid:"host,required"` - Port uint16 `yaml:"port,omitempty" valid:"port,optional"` + Addr string `yaml:"addr,omitempty" valid:"host,required"` + Port uint16 `yaml:"port,omitempty" valid:"port,optional"` + AssociationSetupFailedAlertInterval time.Duration `yaml:"associationSetupFailedAlertInterval,omitempty"` } func (p *PFCP) validate() (bool, error) { diff --git a/pkg/service/association.go b/pkg/service/association.go index e279c916..42dbae20 100644 --- a/pkg/service/association.go +++ b/pkg/service/association.go @@ -1,7 +1,9 @@ package service import ( + "context" "fmt" + "time" "github.com/free5gc/pfcp" "github.com/free5gc/pfcp/pfcpType" @@ -10,6 +12,46 @@ import ( "github.com/free5gc/smf/internal/pfcp/message" ) +func toBeAssociatedWithUPF(ctx context.Context, upf *smf_context.UPF) { + var upfStr string + if upf.NodeID.NodeIdType == pfcpType.NodeIdTypeFqdn { + upfStr = fmt.Sprintf("[%s](%s)", upf.NodeID.FQDN, upf.NodeID.ResolveNodeIdToIp().String()) + } else { + upfStr = fmt.Sprintf("[%s]", upf.NodeID.ResolveNodeIdToIp().String()) + } + ensureSetupPfcpAssociation(ctx, upf, upfStr) +} + +func isDone(ctx context.Context) bool { + select { + case <-ctx.Done(): + return true + default: + return false + } +} + +func ensureSetupPfcpAssociation(ctx context.Context, upf *smf_context.UPF, upfStr string) { + var alertTime time.Time + for { + alertInterval := smf_context.SMF_Self().AssociationSetupFailedAlertInterval + err := setupPfcpAssociation(upf, upfStr) + if err == nil { + return + } + now := time.Now() + if alertTime.IsZero() || now.After(alertTime.Add(alertInterval)) { + logger.AppLog.Errorf("Failed to setup an association with UPF%s, error:%+v", upfStr, err) + alertTime = now + } + + if isDone(ctx) { + logger.AppLog.Infof("Canceled association request to UPF%s", upfStr) + return + } + } +} + func setupPfcpAssociation(upf *smf_context.UPF, upfStr string) error { logger.AppLog.Infof("Sending PFCP Association Request to UPF%s", upfStr) diff --git a/pkg/service/init.go b/pkg/service/init.go index 02ef09db..a1c68b1f 100644 --- a/pkg/service/init.go +++ b/pkg/service/init.go @@ -1,6 +1,7 @@ package service import ( + "context" "fmt" "os" "os/signal" @@ -16,8 +17,7 @@ import ( ngapLogger "github.com/free5gc/ngap/logger" "github.com/free5gc/openapi/models" pfcpLogger "github.com/free5gc/pfcp/logger" - "github.com/free5gc/pfcp/pfcpType" - "github.com/free5gc/smf/internal/context" + smf_context "github.com/free5gc/smf/internal/context" "github.com/free5gc/smf/internal/logger" "github.com/free5gc/smf/internal/pfcp" "github.com/free5gc/smf/internal/pfcp/udp" @@ -222,10 +222,10 @@ func (smf *SMF) Start() { keyPath = sbi.Tls.Key } - context.InitSmfContext(&factory.SmfConfig) + smf_context.InitSmfContext(&factory.SmfConfig) // allocate id for each upf - context.AllocateUPFID() - context.InitSMFUERouting(&factory.UERoutingConfig) + smf_context.AllocateUPFID() + smf_context.InitSMFUERouting(&factory.UERoutingConfig) logger.InitLog.Infoln("Server started") router := logger_util.NewGinWithLogrus(logger.GinLog) @@ -266,21 +266,15 @@ func (smf *SMF) Start() { } udp.Run(pfcp.Dispatch) - for _, upf := range context.SMF_Self().UserPlaneInformation.UPFs { - var upfStr string - if upf.NodeID.NodeIdType == pfcpType.NodeIdTypeFqdn { - upfStr = fmt.Sprintf("[%s](%s)", upf.NodeID.FQDN, upf.NodeID.ResolveNodeIdToIp().String()) - } else { - upfStr = fmt.Sprintf("[%s]", upf.NodeID.IP.String()) - } - if err = setupPfcpAssociation(upf.UPF, upfStr); err != nil { - logger.AppLog.Errorf("Failed to setup an association with UPF%s, error:%+v", upfStr, err) - } + ctx, cancel := context.WithCancel(context.Background()) + smf_context.SMF_Self().PFCPCancelFunc = cancel + for _, upNode := range smf_context.SMF_Self().UserPlaneInformation.UPFs { + go toBeAssociatedWithUPF(ctx, upNode.UPF) } time.Sleep(1000 * time.Millisecond) - HTTPAddr := fmt.Sprintf("%s:%d", context.SMF_Self().BindingIPv4, context.SMF_Self().SBIPort) + HTTPAddr := fmt.Sprintf("%s:%d", smf_context.SMF_Self().BindingIPv4, smf_context.SMF_Self().SBIPort) server, err := httpwrapper.NewHttp2Server(HTTPAddr, smf.KeyLogPath, router) if server == nil { From db3ede1865d5234cb81e3bfde8633a829db2fe97 Mon Sep 17 00:00:00 2001 From: "akagi.mari" Date: Tue, 23 Aug 2022 05:43:33 +0000 Subject: [PATCH 2/5] add validation for associationSetupFailedAlertInterval --- internal/context/context.go | 4 ++-- pkg/factory/config.go | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/internal/context/context.go b/internal/context/context.go index 794db84f..2540b762 100644 --- a/internal/context/context.go +++ b/internal/context/context.go @@ -159,10 +159,10 @@ func InitSmfContext(config *factory.Config) { smfContext.CPNodeID.IP = addr.IP } - if pfcp.AssociationSetupFailedAlertInterval == 0 { + if pfcp.AlertInterval == 0 { smfContext.AssociationSetupFailedAlertInterval = 5 * time.Minute } else { - smfContext.AssociationSetupFailedAlertInterval = pfcp.AssociationSetupFailedAlertInterval + smfContext.AssociationSetupFailedAlertInterval = pfcp.AlertInterval } } diff --git a/pkg/factory/config.go b/pkg/factory/config.go index a1cda3dc..effae4e0 100644 --- a/pkg/factory/config.go +++ b/pkg/factory/config.go @@ -210,9 +210,9 @@ func (t *Tls) validate() (bool, error) { } type PFCP struct { - Addr string `yaml:"addr,omitempty" valid:"host,required"` - Port uint16 `yaml:"port,omitempty" valid:"port,optional"` - AssociationSetupFailedAlertInterval time.Duration `yaml:"associationSetupFailedAlertInterval,omitempty"` + Addr string `yaml:"addr,omitempty" valid:"host,required"` + Port uint16 `yaml:"port,omitempty" valid:"port,optional"` + AlertInterval time.Duration `yaml:"associationSetupFailedAlertInterval,omitempty" valid:"type(time.Duration),optional"` } func (p *PFCP) validate() (bool, error) { From 1f689b6c5328f9cbcc799297e15728665b627e21 Mon Sep 17 00:00:00 2001 From: "akagi.mari" Date: Mon, 29 Aug 2022 06:39:12 +0000 Subject: [PATCH 3/5] Update go.sum --- go.sum | 1 + 1 file changed, 1 insertion(+) diff --git a/go.sum b/go.sum index b76aa91d..4b7b72a8 100644 --- a/go.sum +++ b/go.sum @@ -62,6 +62,7 @@ github.com/free5gc/nas v1.0.7 h1:c+UXWENvJgTr/QZl50SyX+ZZzUdazGHHZ9ZGtnnwG5A= github.com/free5gc/nas v1.0.7/go.mod h1:qPj0gxFk81cH9zIkg4hm3ID0hkYofBlzZzcciBnJxwY= 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.5 h1:S25JqyrTgLwcH6pqZE6U448vv0RKg1CoH48AQ4Cj/d4= github.com/free5gc/openapi v1.0.5/go.mod h1:KRCnnp0GeK0Bl4gnrX79cQAidKXNENf8VRdG0y9R0Fc= github.com/free5gc/pfcp v1.0.4 h1:11ous/chOya/bG0bHAHHEUc7JUB2g6svABock8Ta2Zs= From ceb91c9eae10279c86e52db6c9655dc8e137a3da Mon Sep 17 00:00:00 2001 From: "akagi.mari" Date: Tue, 1 Nov 2022 04:56:37 +0000 Subject: [PATCH 4/5] add comment --- pkg/factory/config.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pkg/factory/config.go b/pkg/factory/config.go index effae4e0..288c55a3 100644 --- a/pkg/factory/config.go +++ b/pkg/factory/config.go @@ -210,8 +210,9 @@ func (t *Tls) validate() (bool, error) { } type PFCP struct { - Addr string `yaml:"addr,omitempty" valid:"host,required"` - Port uint16 `yaml:"port,omitempty" valid:"port,optional"` + Addr string `yaml:"addr,omitempty" valid:"host,required"` + Port uint16 `yaml:"port,omitempty" valid:"port,optional"` + // interval at which PFCP Association Setup error messages are output. AlertInterval time.Duration `yaml:"associationSetupFailedAlertInterval,omitempty" valid:"type(time.Duration),optional"` } From 1ae3f085b072bae5d346de3ffe6940c570a9408b Mon Sep 17 00:00:00 2001 From: "akagi.mari" Date: Tue, 8 Nov 2022 07:24:18 +0000 Subject: [PATCH 5/5] modify loop --- pkg/service/association.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/service/association.go b/pkg/service/association.go index 42dbae20..b4bac9f6 100644 --- a/pkg/service/association.go +++ b/pkg/service/association.go @@ -33,8 +33,8 @@ func isDone(ctx context.Context) bool { func ensureSetupPfcpAssociation(ctx context.Context, upf *smf_context.UPF, upfStr string) { var alertTime time.Time + alertInterval := smf_context.SMF_Self().AssociationSetupFailedAlertInterval for { - alertInterval := smf_context.SMF_Self().AssociationSetupFailedAlertInterval err := setupPfcpAssociation(upf, upfStr) if err == nil { return