Skip to content

Commit ec30f3e

Browse files
authored
feat: request UPF to allocate F-TEID (#334)
* feat: request upf to allocate f-teid Signed-off-by: Guillaume Belanger <[email protected]> * fix: also implement for downlink pdr Signed-off-by: Guillaume Belanger <[email protected]> * fix: set fteid with downlink tunnel Signed-off-by: Guillaume Belanger <[email protected]> * fix: write f-teid to proper variable Signed-off-by: Guillaume Belanger <[email protected]> * chore: add unit tests Signed-off-by: Guillaume Belanger <[email protected]> * chore: add copyright info Signed-off-by: Guillaume Belanger <[email protected]> * chore: bump version Signed-off-by: Guillaume Belanger <[email protected]> * chore: use different ports to avoid conflicts Signed-off-by: Guillaume Belanger <[email protected]> * chore: re-add newline to version file Signed-off-by: Guillaume Belanger <[email protected]> * feat: store upf generated f-teid when using pfcp adapter Signed-off-by: Guillaume Belanger <[email protected]> * chore: bump go version to v1.23 Signed-off-by: Guillaume Belanger <[email protected]> * chore: add missing lock statement Signed-off-by: Guillaume Belanger <[email protected]> * chore: defer mutex unlock right away Signed-off-by: Guillaume Belanger <[email protected]> --------- Signed-off-by: Guillaume Belanger <[email protected]>
1 parent 7cc3adb commit ec30f3e

File tree

10 files changed

+356
-552
lines changed

10 files changed

+356
-552
lines changed

VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
1.7.1-dev
1+
2.0.0

context/context.go

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@ const (
3737
var smfContext SMFContext
3838

3939
type DrsmCtxts struct {
40-
TeidPool drsm.DrsmInterface
4140
SeidPool drsm.DrsmInterface
4241
UeIpPool drsm.DrsmInterface
4342
}
@@ -436,13 +435,6 @@ func (smfCtxt *SMFContext) InitDrsm() error {
436435
return err
437436
}
438437

439-
// for local FTEID
440-
if drsmCtxt, err := drsm.InitDRSM("fteid", podId, db, opt); err == nil {
441-
smfCtxt.DrsmCtxts.TeidPool = drsmCtxt
442-
} else {
443-
return err
444-
}
445-
446438
// for IP-Addr
447439
// TODO, use UPF based allocation for now
448440

context/datapath.go

Lines changed: 10 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import (
1212
"strconv"
1313

1414
"github.com/omec-project/openapi/models"
15-
"github.com/omec-project/smf/factory"
1615
"github.com/omec-project/smf/logger"
1716
"github.com/omec-project/smf/qos"
1817
"github.com/omec-project/smf/util"
@@ -154,23 +153,6 @@ func (node *DataPathNode) ActivateUpLinkTunnel(smContext *SMContext) error {
154153
return err
155154
}
156155

157-
var teid uint32
158-
var teidErr error
159-
160-
if factory.SmfConfig.Configuration.EnableDbStore {
161-
var tmp int32
162-
tmp, teidErr = smfContext.DrsmCtxts.TeidPool.AllocateInt32ID()
163-
teid = uint32(tmp)
164-
} else {
165-
teid, teidErr = destUPF.GenerateTEID()
166-
}
167-
if teidErr != nil {
168-
logger.CtxLog.Errorf("generate uplink TEID fail: %s", teidErr)
169-
return teidErr
170-
} else {
171-
node.UpLinkTunnel.TEID = teid
172-
}
173-
174156
return nil
175157
}
176158

@@ -213,24 +195,6 @@ func (node *DataPathNode) ActivateDownLinkTunnel(smContext *SMContext) error {
213195
return err
214196
}
215197

216-
// Generate TEID for Tunnel
217-
var teid uint32
218-
var teidErr error
219-
220-
if factory.SmfConfig.Configuration.EnableDbStore {
221-
var tmp int32
222-
tmp, teidErr = smfContext.DrsmCtxts.TeidPool.AllocateInt32ID()
223-
teid = uint32(tmp)
224-
} else {
225-
teid, teidErr = destUPF.GenerateTEID()
226-
}
227-
if teidErr != nil {
228-
logger.CtxLog.Errorf("generate downlink TEID fail: %s", teidErr)
229-
return teidErr
230-
} else {
231-
node.DownLinkTunnel.TEID = teid
232-
}
233-
234198
return nil
235199
}
236200

@@ -274,17 +238,6 @@ func (node *DataPathNode) DeactivateUpLinkTunnel(smContext *SMContext) {
274238
}
275239
}
276240
}
277-
278-
teid := node.DownLinkTunnel.TEID
279-
var err error
280-
if factory.SmfConfig.Configuration.EnableDbStore {
281-
err = smfContext.DrsmCtxts.TeidPool.ReleaseInt32ID(int32(teid))
282-
} else {
283-
node.UPF.teidGenerator.FreeID(int64(teid))
284-
}
285-
if err != nil {
286-
logger.CtxLog.Errorln("deactivated UpLinkTunnel", err)
287-
}
288241
node.DownLinkTunnel = &GTPTunnel{}
289242
}
290243

@@ -328,17 +281,6 @@ func (node *DataPathNode) DeactivateDownLinkTunnel(smContext *SMContext) {
328281
}
329282
}
330283
}
331-
332-
teid := node.DownLinkTunnel.TEID
333-
var err error
334-
if factory.SmfConfig.Configuration.EnableDbStore {
335-
err = smfContext.DrsmCtxts.TeidPool.ReleaseInt32ID(int32(teid))
336-
} else {
337-
node.UPF.teidGenerator.FreeID(int64(teid))
338-
}
339-
if err != nil {
340-
logger.CtxLog.Errorln("deactivated DownLinkTunnel", err)
341-
}
342284
node.DownLinkTunnel = &GTPTunnel{}
343285
}
344286

@@ -534,37 +476,19 @@ func (dpNode *DataPathNode) ActivateUpLinkPdr(smContext *SMContext, defQER *QER,
534476

535477
curULTunnel := dpNode.UpLinkTunnel
536478
for name, ULPDR := range curULTunnel.PDR {
537-
ULDestUPF := curULTunnel.DestEndPoint.UPF
538479
ULPDR.QER = append(ULPDR.QER, defQER)
539480

540481
// Set Default precedence
541482
if ULPDR.Precedence == 0 {
542483
ULPDR.Precedence = defPrecedence
543484
}
544485

545-
var iface *UPFInterfaceInfo
546-
if dpNode.IsANUPF() {
547-
iface = ULDestUPF.GetInterface(models.UpInterfaceType_N3, smContext.Dnn)
548-
} else {
549-
iface = ULDestUPF.GetInterface(models.UpInterfaceType_N9, smContext.Dnn)
486+
ULPDR.PDI.SourceInterface = SourceInterface{InterfaceValue: SourceInterfaceAccess}
487+
ULPDR.PDI.LocalFTeid = &FTEID{
488+
Ch: true,
550489
}
551-
552-
if upIP, err := iface.IP(smContext.SelectedPDUSessionType); err != nil {
553-
logger.CtxLog.Errorf("activate UpLink PDR[%v] failed %v", name, err)
554-
return err
555-
} else {
556-
ULPDR.PDI.SourceInterface = SourceInterface{InterfaceValue: SourceInterfaceAccess}
557-
ULPDR.PDI.LocalFTeid = &FTEID{
558-
V4: true,
559-
Ipv4Address: upIP,
560-
Teid: curULTunnel.TEID,
561-
}
562-
563-
ULPDR.PDI.UEIPAddress = &ueIpAddr
564-
565-
ULPDR.PDI.NetworkInstance = util_3gpp.Dnn(smContext.Dnn)
566-
}
567-
490+
ULPDR.PDI.UEIPAddress = &ueIpAddr
491+
ULPDR.PDI.NetworkInstance = util_3gpp.Dnn(smContext.Dnn)
568492
ULPDR.OuterHeaderRemoval = &OuterHeaderRemoval{
569493
OuterHeaderRemovalDescription: OuterHeaderRemovalGtpUUdpIpv4,
570494
}
@@ -591,7 +515,7 @@ func (dpNode *DataPathNode) ActivateUpLinkPdr(smContext *SMContext, defQER *QER,
591515

592516
if nextULDest := dpNode.Next(); nextULDest != nil {
593517
nextULTunnel := nextULDest.UpLinkTunnel
594-
iface = nextULTunnel.DestEndPoint.UPF.GetInterface(models.UpInterfaceType_N9, smContext.Dnn)
518+
iface := nextULTunnel.DestEndPoint.UPF.GetInterface(models.UpInterfaceType_N9, smContext.Dnn)
595519

596520
if upIP, err := iface.IP(smContext.SelectedPDUSessionType); err != nil {
597521
logger.CtxLog.Errorf("activate UpLink PDR[%v] failed %v", name, err)
@@ -624,36 +548,21 @@ func (dpNode *DataPathNode) ActivateDlLinkPdr(smContext *SMContext, defQER *QER,
624548

625549
for name, DLPDR := range curDLTunnel.PDR {
626550
logger.CtxLog.Infof("activate Downlink PDR[%v]:[%v]", name, DLPDR)
627-
DLDestUPF := curDLTunnel.DestEndPoint.UPF
628551
DLPDR.QER = append(DLPDR.QER, defQER)
629552

630553
if DLPDR.Precedence == 0 {
631554
DLPDR.Precedence = defPrecedence
632555
}
633556

634-
if dpNode.IsAnchorUPF() {
635-
DLPDR.PDI.UEIPAddress = &ueIpAddr
636-
} else {
557+
if !dpNode.IsAnchorUPF() {
637558
DLPDR.OuterHeaderRemoval = &OuterHeaderRemoval{
638559
OuterHeaderRemovalDescription: OuterHeaderRemovalGtpUUdpIpv4,
639560
}
640-
641-
iface = DLDestUPF.GetInterface(models.UpInterfaceType_N9, smContext.Dnn)
642-
if upIP, err := iface.IP(smContext.SelectedPDUSessionType); err != nil {
643-
logger.CtxLog.Errorf("activate Downlink PDR[%v] failed %v", name, err)
644-
return err
645-
} else {
646-
DLPDR.PDI.SourceInterface = SourceInterface{InterfaceValue: SourceInterfaceCore}
647-
DLPDR.PDI.LocalFTeid = &FTEID{
648-
V4: true,
649-
Ipv4Address: upIP,
650-
Teid: curDLTunnel.TEID,
651-
}
652-
653-
DLPDR.PDI.UEIPAddress = &ueIpAddr
654-
}
655561
}
656562

563+
DLPDR.PDI.SourceInterface = SourceInterface{InterfaceValue: SourceInterfaceCore}
564+
DLPDR.PDI.UEIPAddress = &ueIpAddr
565+
657566
DLFAR := DLPDR.FAR
658567

659568
logger.PduSessLog.Debugln("current DP Node IP:", dpNode.UPF.NodeID.ResolveNodeIdToIp().String())

context/datapath_test.go

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
// Copyright 2024 Canonical Ltd.
2+
//
3+
// SPDX-License-Identifier: Apache-2.0
4+
5+
package context_test
6+
7+
import (
8+
"net"
9+
"testing"
10+
11+
"github.com/omec-project/smf/context"
12+
)
13+
14+
func TestActivateUpLinkPdr(t *testing.T) {
15+
smContext := &context.SMContext{
16+
PDUAddress: &context.UeIpAddr{
17+
Ip: net.IPv4(192, 168, 1, 1),
18+
},
19+
Dnn: "internet",
20+
}
21+
22+
defQER := &context.QER{}
23+
24+
dpNode := &context.DataPathNode{
25+
UPF: &context.UPF{},
26+
UpLinkTunnel: &context.GTPTunnel{
27+
PDR: map[string]*context.PDR{
28+
"default": {
29+
Precedence: 0,
30+
FAR: &context.FAR{},
31+
},
32+
},
33+
},
34+
}
35+
36+
err := dpNode.ActivateUpLinkPdr(smContext, defQER, 10)
37+
if err != nil {
38+
t.Errorf("expected no error, got %v", err)
39+
}
40+
41+
pdr := dpNode.UpLinkTunnel.PDR["default"]
42+
if pdr == nil {
43+
t.Fatalf("expected pdr to be not nil")
44+
}
45+
46+
if pdr.PDI.SourceInterface.InterfaceValue != context.SourceInterfaceAccess {
47+
t.Errorf("expected SourceInterface to be %v, got %v", context.SourceInterfaceAccess, pdr.PDI.SourceInterface.InterfaceValue)
48+
}
49+
if pdr.PDI.LocalFTeid == nil {
50+
t.Errorf("expected pdr.PDI.LocalFTeid to be not nil")
51+
}
52+
if !pdr.PDI.LocalFTeid.Ch {
53+
t.Errorf("expected pdr.PDI.LocalFTeid.Ch to be true")
54+
}
55+
if pdr.PDI.UEIPAddress == nil {
56+
t.Errorf("expected pdr.PDI.UEIPAddress to be not nil")
57+
}
58+
if !pdr.PDI.UEIPAddress.V4 {
59+
t.Errorf("expected pdr.PDI.UEIPAddress.V4 to be true")
60+
}
61+
if !pdr.PDI.UEIPAddress.Ipv4Address.Equal(net.IP{192, 168, 1, 1}) {
62+
t.Errorf("expected pdr.PDI.UEIPAddress.Ipv4Address to be %v, got %v", net.IP{192, 168, 1, 1}, pdr.PDI.UEIPAddress.Ipv4Address)
63+
}
64+
if string(pdr.PDI.NetworkInstance) != "internet" {
65+
t.Errorf("expected pdr.PDI.NetworkInstance to be 'internet', got %v", string(pdr.PDI.NetworkInstance))
66+
}
67+
}
68+
69+
func TestActivateDlLinkPdr(t *testing.T) {
70+
smContext := &context.SMContext{
71+
PDUAddress: &context.UeIpAddr{
72+
Ip: net.IP{192, 168, 1, 1},
73+
},
74+
Dnn: "internet",
75+
Tunnel: &context.UPTunnel{
76+
ANInformation: struct {
77+
IPAddress net.IP
78+
TEID uint32
79+
}{
80+
IPAddress: net.IP{10, 0, 0, 1},
81+
TEID: 12345,
82+
},
83+
},
84+
}
85+
86+
defQER := &context.QER{}
87+
88+
dpNode := &context.DataPathNode{
89+
UPF: &context.UPF{},
90+
DownLinkTunnel: &context.GTPTunnel{
91+
PDR: map[string]*context.PDR{
92+
"default": {
93+
Precedence: 0,
94+
FAR: &context.FAR{},
95+
},
96+
},
97+
},
98+
}
99+
100+
dataPath := &context.DataPath{
101+
FirstDPNode: dpNode,
102+
}
103+
104+
err := dpNode.ActivateDlLinkPdr(smContext, defQER, 10, dataPath)
105+
if err != nil {
106+
t.Fatalf("expected no error, got %v", err)
107+
}
108+
109+
pdr := dpNode.DownLinkTunnel.PDR["default"]
110+
if pdr == nil {
111+
t.Fatalf("expected pdr to be not nil")
112+
}
113+
114+
if pdr.PDI.SourceInterface.InterfaceValue != context.SourceInterfaceCore {
115+
t.Errorf("expected SourceInterface to be %v, got %v", context.SourceInterfaceCore, pdr.PDI.SourceInterface.InterfaceValue)
116+
}
117+
if pdr.PDI.UEIPAddress == nil {
118+
t.Errorf("expected pdr.PDI.UEIPAddress to be not nil")
119+
}
120+
if !pdr.PDI.UEIPAddress.V4 {
121+
t.Errorf("expected pdr.PDI.UEIPAddress.V4 to be true")
122+
}
123+
if !pdr.PDI.UEIPAddress.Ipv4Address.Equal(net.IP{192, 168, 1, 1}) {
124+
t.Errorf("expected pdr.PDI.UEIPAddress.Ipv4Address to be %v, got %v", net.IP{192, 168, 1, 1}, pdr.PDI.UEIPAddress.Ipv4Address)
125+
}
126+
}

0 commit comments

Comments
 (0)