Skip to content

Commit e0974e0

Browse files
authored
Merge pull request #203 from DBGR18/fix/906
Handle and propagate SM Context initialization errors
2 parents 2232d29 + 6de2fdf commit e0974e0

10 files changed

Lines changed: 117 additions & 40 deletions

File tree

internal/context/context.go

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -123,10 +123,9 @@ func AllocateLocalSEID() uint64 {
123123
return atomic.AddUint64(&smfContext.LocalSEIDCount, 1)
124124
}
125125

126-
func InitSmfContext(config *factory.Config) {
126+
func InitSmfContext(config *factory.Config) error {
127127
if config == nil {
128-
logger.CtxLog.Error("Config is nil")
129-
return
128+
return fmt.Errorf("config is nil")
130129
}
131130

132131
logger.CtxLog.Infof("smfconfig Info: Version[%s] Description[%s]", config.Info.Version, config.Info.Description)
@@ -137,8 +136,7 @@ func InitSmfContext(config *factory.Config) {
137136

138137
sbi := configuration.Sbi
139138
if sbi == nil {
140-
logger.CtxLog.Errorln("Configuration needs \"sbi\" value")
141-
return
139+
return fmt.Errorf("configuration needs \"sbi\" value")
142140
} else {
143141
smfContext.URIScheme = models.UriScheme(sbi.Scheme)
144142
smfContext.RegisterIPv4 = factory.SmfSbiDefaultIPv4 // default localhost
@@ -242,7 +240,11 @@ func InitSmfContext(config *factory.Config) {
242240

243241
smfContext.SupportedPDUSessionType = "IPv4"
244242

245-
smfContext.UserPlaneInformation = NewUserPlaneInformation(&configuration.UserPlaneInformation)
243+
userPlaneInformation, err := NewUserPlaneInformation(&configuration.UserPlaneInformation)
244+
if err != nil {
245+
return fmt.Errorf("initialize user plane information failed: %w", err)
246+
}
247+
smfContext.UserPlaneInformation = userPlaneInformation
246248

247249
smfContext.ChargingIDGenerator = idgenerator.NewGenerator(1, math.MaxUint32)
248250

@@ -253,6 +255,8 @@ func InitSmfContext(config *factory.Config) {
253255
TeidGenerator = idgenerator.NewGenerator(1, math.MaxUint32)
254256

255257
smfContext.Ues = InitSmfUeData()
258+
259+
return nil
256260
}
257261

258262
func InitSMFUERouting(routingConfig *factory.RoutingConfig) {

internal/context/sm_context_policy_test.go

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,9 @@ var testConfig = factory.Config{
111111
}
112112

113113
func initConfig() {
114-
smf_context.InitSmfContext(&testConfig)
114+
if err := smf_context.InitSmfContext(&testConfig); err != nil {
115+
panic(err)
116+
}
115117
factory.SmfConfig = &testConfig
116118
}
117119

@@ -655,7 +657,9 @@ func TestApplyPccRules(t *testing.T) {
655657
}
656658

657659
smfContext := smf_context.GetSelf()
658-
smfContext.UserPlaneInformation = smf_context.NewUserPlaneInformation(&userPlaneConfig)
660+
userPlaneInformation, err := smf_context.NewUserPlaneInformation(&userPlaneConfig)
661+
require.NoError(t, err)
662+
smfContext.UserPlaneInformation = userPlaneInformation
659663
for _, n := range smfContext.UserPlaneInformation.UPFs {
660664
n.UPF.AssociationContext = context.Background()
661665
}
@@ -713,7 +717,7 @@ func TestApplyPccRules(t *testing.T) {
713717
Downlink: "1 Gbps",
714718
},
715719
}
716-
err := smctx.AllocUeIP()
720+
err = smctx.AllocUeIP()
717721
require.NoError(t, err)
718722
err = smctx.SelectDefaultDataPath()
719723
require.NoError(t, err)

internal/context/ue_datapath_test.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@ var config = configuration
1616

1717
func TestNewUEPreConfigPaths(t *testing.T) {
1818
smfContext := context.GetSelf()
19-
smfContext.UserPlaneInformation = context.NewUserPlaneInformation(config)
19+
userPlaneInformation, err := context.NewUserPlaneInformation(config)
20+
require.NoError(t, err)
21+
smfContext.UserPlaneInformation = userPlaneInformation
2022
fmt.Println("Start")
2123
testcases := []struct {
2224
name string
@@ -150,8 +152,8 @@ func TestNewUEPreConfigPaths(t *testing.T) {
150152

151153
for _, tc := range testcases {
152154
t.Run(tc.name, func(t *testing.T) {
153-
retUePreConfigPaths, err := context.NewUEPreConfigPaths(tc.inPaths)
154-
require.Nil(t, err)
155+
retUePreConfigPaths, preConfigErr := context.NewUEPreConfigPaths(tc.inPaths)
156+
require.Nil(t, preConfigErr)
155157
require.NotNil(t, retUePreConfigPaths.PathIDGenerator)
156158
for pathIndex, path := range tc.inPaths {
157159
retDataPath := retUePreConfigPaths.DataPathPool[int64(pathIndex+1)]

internal/context/user_plane_information.go

Lines changed: 72 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package context
22

33
import (
44
"errors"
5+
"fmt"
56
"math/rand"
67
"net"
78
"reflect"
@@ -80,7 +81,7 @@ func AllocateUPFID() {
8081
}
8182

8283
// NewUserPlaneInformation process the configuration then returns a new instance of UserPlaneInformation
83-
func NewUserPlaneInformation(upTopology *factory.UserPlaneInformation) *UserPlaneInformation {
84+
func NewUserPlaneInformation(upTopology *factory.UserPlaneInformation) (*UserPlaneInformation, error) {
8485
nodePool := make(map[string]*UPNode)
8586
upfPool := make(map[string]*UPNode)
8687
anPool := make(map[string]*UPNode)
@@ -142,7 +143,7 @@ func NewUserPlaneInformation(upTopology *factory.UserPlaneInformation) *UserPlan
142143
for _, pool := range dnnInfoConfig.Pools {
143144
ueIPPool := NewUEIPPool(pool)
144145
if ueIPPool == nil {
145-
logger.InitLog.Fatalf("invalid pools value: %+v", pool)
146+
return nil, fmt.Errorf("invalid pools value: %+v", pool)
146147
} else {
147148
ueIPPools = append(ueIPPools, ueIPPool)
148149
allUEIPPools = append(allUEIPPools, ueIPPool)
@@ -151,13 +152,13 @@ func NewUserPlaneInformation(upTopology *factory.UserPlaneInformation) *UserPlan
151152
for _, staticPool := range dnnInfoConfig.StaticPools {
152153
staticUeIPPool := NewUEIPPool(staticPool)
153154
if staticUeIPPool == nil {
154-
logger.InitLog.Fatalf("invalid pools value: %+v", staticPool)
155+
return nil, fmt.Errorf("invalid pools value: %+v", staticPool)
155156
} else {
156157
staticUeIPPools = append(staticUeIPPools, staticUeIPPool)
157158
for _, dynamicUePool := range ueIPPools {
158159
if dynamicUePool.ueSubNet.Contains(staticUeIPPool.ueSubNet.IP) {
159160
if err := dynamicUePool.Exclude(staticUeIPPool); err != nil {
160-
logger.InitLog.Fatalf("exclude static Pool[%s] failed: %v",
161+
return nil, fmt.Errorf("exclude static Pool[%s] failed: %v",
161162
staticUeIPPool.ueSubNet, err)
162163
}
163164
}
@@ -200,7 +201,7 @@ func NewUserPlaneInformation(upTopology *factory.UserPlaneInformation) *UserPlan
200201
}
201202

202203
if isOverlap(allUEIPPools) {
203-
logger.InitLog.Fatalf("overlap cidr value between UPFs")
204+
return nil, fmt.Errorf("overlap cidr value between UPFs")
204205
}
205206

206207
for _, link := range upTopology.Links {
@@ -229,7 +230,7 @@ func NewUserPlaneInformation(upTopology *factory.UserPlaneInformation) *UserPlan
229230
DefaultUserPlanePathToUPF: make(map[string]map[string][]*UPNode),
230231
}
231232

232-
return userplaneInformation
233+
return userplaneInformation, nil
233234
}
234235

235236
func (upi *UserPlaneInformation) UpNodesToConfiguration() map[string]*factory.UPNode {
@@ -358,13 +359,51 @@ func (upi *UserPlaneInformation) LinksToConfiguration() []*factory.UPLink {
358359
return links
359360
}
360361

361-
func (upi *UserPlaneInformation) UpNodesFromConfiguration(upTopology *factory.UserPlaneInformation) {
362+
func (upi *UserPlaneInformation) UpNodesFromConfiguration(upTopology *factory.UserPlaneInformation) error {
363+
candidateUPNodes := make(map[string]*UPNode, len(upi.UPNodes))
364+
for name, node := range upi.UPNodes {
365+
candidateUPNodes[name] = node
366+
}
367+
368+
candidateUPFs := make(map[string]*UPNode, len(upi.UPFs))
369+
for name, node := range upi.UPFs {
370+
candidateUPFs[name] = node
371+
}
372+
373+
candidateAccessNetwork := make(map[string]*UPNode, len(upi.AccessNetwork))
374+
for name, node := range upi.AccessNetwork {
375+
candidateAccessNetwork[name] = node
376+
}
377+
378+
candidateUPFsID := make(map[string]string, len(upi.UPFsID))
379+
for name, id := range upi.UPFsID {
380+
candidateUPFsID[name] = id
381+
}
382+
383+
candidateUPFsIPtoID := make(map[string]string, len(upi.UPFsIPtoID))
384+
for ip, id := range upi.UPFsIPtoID {
385+
candidateUPFsIPtoID[ip] = id
386+
}
387+
388+
candidateUPFIPToName := make(map[string]string, len(upi.UPFIPToName))
389+
for ip, name := range upi.UPFIPToName {
390+
candidateUPFIPToName[ip] = name
391+
}
392+
393+
createdUPFs := make([]*UPF, 0)
394+
cleanupCreatedUPFs := func() {
395+
for _, upf := range createdUPFs {
396+
upfPool.Delete(upf.UUID())
397+
}
398+
}
399+
362400
for name, node := range upTopology.UPNodes {
363-
if _, ok := upi.UPNodes[name]; ok {
401+
if _, ok := candidateUPNodes[name]; ok {
364402
logger.InitLog.Warningf("Node [%s] already exists in SMF.\n", name)
365403
continue
366404
}
367405
upNode := new(UPNode)
406+
upNode.Name = name
368407
upNode.Type = UPNodeType(node.Type)
369408
switch upNode.Type {
370409
case UPNODE_UPF:
@@ -397,6 +436,7 @@ func (upi *UserPlaneInformation) UpNodesFromConfiguration(upTopology *factory.Us
397436
}
398437

399438
upNode.UPF = NewUPF(&upNode.NodeID, node.InterfaceUpfInfoList)
439+
createdUPFs = append(createdUPFs, upNode.UPF)
400440
snssaiInfos := make([]*SnssaiUPFInfo, 0)
401441
for _, snssaiInfoConfig := range node.SNssaiInfos {
402442
snssaiInfo := &SnssaiUPFInfo{
@@ -413,21 +453,24 @@ func (upi *UserPlaneInformation) UpNodesFromConfiguration(upTopology *factory.Us
413453
for _, pool := range dnnInfoConfig.Pools {
414454
ueIPPool := NewUEIPPool(pool)
415455
if ueIPPool == nil {
416-
logger.InitLog.Fatalf("invalid pools value: %+v", pool)
456+
cleanupCreatedUPFs()
457+
return fmt.Errorf("invalid pools value: %+v", pool)
417458
} else {
418459
ueIPPools = append(ueIPPools, ueIPPool)
419460
}
420461
}
421462
for _, pool := range dnnInfoConfig.StaticPools {
422463
ueIPPool := NewUEIPPool(pool)
423464
if ueIPPool == nil {
424-
logger.InitLog.Fatalf("invalid pools value: %+v", pool)
465+
cleanupCreatedUPFs()
466+
return fmt.Errorf("invalid pools value: %+v", pool)
425467
} else {
426468
staticUeIPPools = append(staticUeIPPools, ueIPPool)
427469
for _, dynamicUePool := range ueIPPools {
428470
if dynamicUePool.ueSubNet.Contains(ueIPPool.ueSubNet.IP) {
429471
if err := dynamicUePool.Exclude(ueIPPool); err != nil {
430-
logger.InitLog.Fatalf("exclude static Pool[%s] failed: %v",
472+
cleanupCreatedUPFs()
473+
return fmt.Errorf("exclude static Pool[%s] failed: %v",
431474
ueIPPool.ueSubNet, err)
432475
}
433476
}
@@ -445,39 +488,49 @@ func (upi *UserPlaneInformation) UpNodesFromConfiguration(upTopology *factory.Us
445488
snssaiInfos = append(snssaiInfos, snssaiInfo)
446489
}
447490
upNode.UPF.SNssaiInfos = snssaiInfos
448-
upi.UPFs[name] = upNode
491+
candidateUPFs[name] = upNode
449492

450493
// AllocateUPFID
451494
upfid := upNode.UPF.UUID()
452495
upfip := upNode.NodeID.ResolveNodeIdToIp().String()
453-
upi.UPFsID[name] = upfid
454-
upi.UPFsIPtoID[upfip] = upfid
496+
candidateUPFsID[name] = upfid
497+
candidateUPFsIPtoID[upfip] = upfid
455498

456499
case UPNODE_AN:
457500
upNode.ANIP = net.ParseIP(node.ANIP)
458-
upi.AccessNetwork[name] = upNode
501+
candidateAccessNetwork[name] = upNode
459502
default:
460503
logger.InitLog.Warningf("invalid UPNodeType: %s\n", upNode.Type)
461504
}
462505

463-
upi.UPNodes[name] = upNode
506+
candidateUPNodes[name] = upNode
464507

465508
ipStr := upNode.NodeID.ResolveNodeIdToIp().String()
466-
upi.UPFIPToName[ipStr] = name
509+
candidateUPFIPToName[ipStr] = name
467510
}
468511

469512
// overlap UE IP pool validation
470513
allUEIPPools := []*UeIPPool{}
471-
for _, upf := range upi.UPFs {
514+
for _, upf := range candidateUPFs {
472515
for _, snssaiInfo := range upf.UPF.SNssaiInfos {
473516
for _, dnn := range snssaiInfo.DnnList {
474517
allUEIPPools = append(allUEIPPools, dnn.UeIPPools...)
475518
}
476519
}
477520
}
478521
if isOverlap(allUEIPPools) {
479-
logger.InitLog.Fatalf("overlap cidr value between UPFs")
522+
cleanupCreatedUPFs()
523+
return fmt.Errorf("overlap cidr value between UPFs")
480524
}
525+
526+
upi.UPNodes = candidateUPNodes
527+
upi.UPFs = candidateUPFs
528+
upi.AccessNetwork = candidateAccessNetwork
529+
upi.UPFsID = candidateUPFsID
530+
upi.UPFsIPtoID = candidateUPFsIPtoID
531+
upi.UPFIPToName = candidateUPFIPToName
532+
533+
return nil
481534
}
482535

483536
func (upi *UserPlaneInformation) LinksFromConfiguration(upTopology *factory.UserPlaneInformation) {

internal/context/user_plane_information_test.go

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,8 @@ var configuration = &factory.UserPlaneInformation{
150150
}
151151

152152
func TestNewUserPlaneInformation(t *testing.T) {
153-
userplaneInformation := smf_context.NewUserPlaneInformation(configuration)
153+
userplaneInformation, err := smf_context.NewUserPlaneInformation(configuration)
154+
require.NoError(t, err)
154155

155156
require.NotNil(t, userplaneInformation.AccessNetwork["GNodeB"])
156157

@@ -249,7 +250,8 @@ func TestGenerateDefaultPath(t *testing.T) {
249250
},
250251
}
251252

252-
userplaneInformation := smf_context.NewUserPlaneInformation(&config1)
253+
userplaneInformation, err := smf_context.NewUserPlaneInformation(&config1)
254+
require.NoError(t, err)
253255
for _, tc := range testCases {
254256
t.Run(tc.name, func(t *testing.T) {
255257
pathExist := userplaneInformation.GenerateDefaultPath(tc.param)
@@ -268,7 +270,8 @@ func TestSelectUPFAndAllocUEIP(t *testing.T) {
268270
expectedIPPool = append(expectedIPPool, net.ParseIP(fmt.Sprintf("10.60.0.%d", i)).To4())
269271
}
270272

271-
userplaneInformation := smf_context.NewUserPlaneInformation(configuration)
273+
userplaneInformation, err := smf_context.NewUserPlaneInformation(configuration)
274+
require.NoError(t, err)
272275
for _, upf := range userplaneInformation.UPFs {
273276
upf.UPF.AssociationContext = context.Background()
274277
}
@@ -485,7 +488,8 @@ var testCasesOfGetUEIPPool = []struct {
485488
}
486489

487490
func TestGetUEIPPool(t *testing.T) {
488-
userplaneInformation := smf_context.NewUserPlaneInformation(configForIPPoolAllocate)
491+
userplaneInformation, err := smf_context.NewUserPlaneInformation(configForIPPoolAllocate)
492+
require.NoError(t, err)
489493
for _, upf := range userplaneInformation.UPFs {
490494
upf.UPF.AssociationContext = context.Background()
491495
}

internal/pfcp/message/build_test.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,9 @@ var testNodeID = &pfcpType.NodeID{
3737
}
3838

3939
func initSmfContext() {
40-
context.InitSmfContext(&testConfig)
40+
if err := context.InitSmfContext(&testConfig); err != nil {
41+
panic(err)
42+
}
4143
}
4244

4345
func initRuleList() ([]*context.PDR, []*context.FAR, []*context.BAR,

internal/sbi/api_upi.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,11 @@ func (s *Server) PostUpNodesLinks(c *gin.Context) {
6969
return
7070
}
7171

72-
upi.UpNodesFromConfiguration(&json)
72+
if err := upi.UpNodesFromConfiguration(&json); err != nil {
73+
c.Set(sbi.IN_PB_DETAILS_CTX_STR, http.StatusText(int(http.StatusBadRequest)))
74+
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
75+
return
76+
}
7377
upi.LinksFromConfiguration(&json)
7478

7579
for _, upf := range upi.UPFs {

internal/sbi/consumer/pcf_service_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ var testConfig = factory.Config{
3131
}
3232

3333
func TestSendSMPolicyAssociationUpdateByUERequestModification(t *testing.T) {
34-
smf_context.InitSmfContext(&testConfig)
34+
require.NoError(t, smf_context.InitSmfContext(&testConfig))
3535

3636
testCases := []struct {
3737
name string

internal/sbi/processor/pdu_session_test.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,9 @@ var testConfig = factory.Config{
119119
}
120120

121121
func initConfig() {
122-
smf_context.InitSmfContext(&testConfig)
122+
if err := smf_context.InitSmfContext(&testConfig); err != nil {
123+
panic(err)
124+
}
123125
factory.SmfConfig = &testConfig
124126
}
125127

0 commit comments

Comments
 (0)