Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: request UPF to allocate F-TEID #334

Merged
merged 19 commits into from
Nov 28, 2024
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.7.1-dev
2.0.0
8 changes: 0 additions & 8 deletions context/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ const (
var smfContext SMFContext

type DrsmCtxts struct {
TeidPool drsm.DrsmInterface
SeidPool drsm.DrsmInterface
UeIpPool drsm.DrsmInterface
}
Expand Down Expand Up @@ -436,13 +435,6 @@ func (smfCtxt *SMFContext) InitDrsm() error {
return err
}

// for local FTEID
if drsmCtxt, err := drsm.InitDRSM("fteid", podId, db, opt); err == nil {
smfCtxt.DrsmCtxts.TeidPool = drsmCtxt
} else {
return err
}

// for IP-Addr
// TODO, use UPF based allocation for now

Expand Down
112 changes: 11 additions & 101 deletions context/datapath.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import (
"strconv"

"github.com/omec-project/openapi/models"
"github.com/omec-project/smf/factory"
"github.com/omec-project/smf/logger"
"github.com/omec-project/smf/qos"
"github.com/omec-project/smf/util"
Expand Down Expand Up @@ -154,23 +153,6 @@ func (node *DataPathNode) ActivateUpLinkTunnel(smContext *SMContext) error {
return err
}

var teid uint32
var teidErr error

if factory.SmfConfig.Configuration.EnableDbStore {
var tmp int32
tmp, teidErr = smfContext.DrsmCtxts.TeidPool.AllocateInt32ID()
teid = uint32(tmp)
} else {
teid, teidErr = destUPF.GenerateTEID()
}
if teidErr != nil {
logger.CtxLog.Errorf("generate uplink TEID fail: %s", teidErr)
return teidErr
} else {
node.UpLinkTunnel.TEID = teid
thakurajayL marked this conversation as resolved.
Show resolved Hide resolved
}

return nil
}

Expand Down Expand Up @@ -213,24 +195,6 @@ func (node *DataPathNode) ActivateDownLinkTunnel(smContext *SMContext) error {
return err
}

// Generate TEID for Tunnel
var teid uint32
var teidErr error

if factory.SmfConfig.Configuration.EnableDbStore {
var tmp int32
tmp, teidErr = smfContext.DrsmCtxts.TeidPool.AllocateInt32ID()
teid = uint32(tmp)
} else {
teid, teidErr = destUPF.GenerateTEID()
}
if teidErr != nil {
logger.CtxLog.Errorf("generate downlink TEID fail: %s", teidErr)
return teidErr
} else {
node.DownLinkTunnel.TEID = teid
}

return nil
}

Expand Down Expand Up @@ -274,17 +238,6 @@ func (node *DataPathNode) DeactivateUpLinkTunnel(smContext *SMContext) {
}
}
}

teid := node.DownLinkTunnel.TEID
var err error
if factory.SmfConfig.Configuration.EnableDbStore {
err = smfContext.DrsmCtxts.TeidPool.ReleaseInt32ID(int32(teid))
} else {
node.UPF.teidGenerator.FreeID(int64(teid))
}
if err != nil {
logger.CtxLog.Errorln("deactivated UpLinkTunnel", err)
}
node.DownLinkTunnel = &GTPTunnel{}
}

Expand Down Expand Up @@ -328,17 +281,6 @@ func (node *DataPathNode) DeactivateDownLinkTunnel(smContext *SMContext) {
}
}
}

teid := node.DownLinkTunnel.TEID
var err error
if factory.SmfConfig.Configuration.EnableDbStore {
err = smfContext.DrsmCtxts.TeidPool.ReleaseInt32ID(int32(teid))
} else {
node.UPF.teidGenerator.FreeID(int64(teid))
}
if err != nil {
logger.CtxLog.Errorln("deactivated DownLinkTunnel", err)
}
node.DownLinkTunnel = &GTPTunnel{}
}

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

curULTunnel := dpNode.UpLinkTunnel
for name, ULPDR := range curULTunnel.PDR {
ULDestUPF := curULTunnel.DestEndPoint.UPF
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why this code is deleted?

ULPDR.QER = append(ULPDR.QER, defQER)

// Set Default precedence
if ULPDR.Precedence == 0 {
ULPDR.Precedence = defPrecedence
}

var iface *UPFInterfaceInfo
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What was motivation to delete this code?

Copy link
Contributor Author

@gruyaume gruyaume Nov 26, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This instance of iface was only used to get the user plane IP address and set the PDR F-TEID accordingly. Now that the F-TEID is set by the UPF, this is not needed anymore

Old code:

var iface *UPFInterfaceInfo
		if dpNode.IsANUPF() {
			iface = ULDestUPF.GetInterface(models.UpInterfaceType_N3, smContext.Dnn)
		} else {
			iface = ULDestUPF.GetInterface(models.UpInterfaceType_N9, smContext.Dnn)
		}

		if upIP, err := iface.IP(smContext.SelectedPDUSessionType); err != nil {
			logger.CtxLog.Errorf("activate UpLink PDR[%v] failed %v", name, err)
			return err
		} else {
			ULPDR.PDI.SourceInterface = SourceInterface{InterfaceValue: SourceInterfaceAccess}
			ULPDR.PDI.LocalFTeid = &FTEID{
				V4:          true,
				Ipv4Address: upIP,
				Teid:        curULTunnel.TEID,
			}

			ULPDR.PDI.UEIPAddress = &ueIpAddr

			ULPDR.PDI.NetworkInstance = util_3gpp.Dnn(smContext.Dnn)
		}

if dpNode.IsANUPF() {
iface = ULDestUPF.GetInterface(models.UpInterfaceType_N3, smContext.Dnn)
} else {
iface = ULDestUPF.GetInterface(models.UpInterfaceType_N9, smContext.Dnn)
ULPDR.PDI.SourceInterface = SourceInterface{InterfaceValue: SourceInterfaceAccess}
ULPDR.PDI.LocalFTeid = &FTEID{
Ch: true,
}

if upIP, err := iface.IP(smContext.SelectedPDUSessionType); err != nil {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we are removing code which supports iUPF

Copy link
Contributor Author

@gruyaume gruyaume Nov 26, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's iUPF?

The code you are referring to is not needed anymore as the F-TEID is generated by the UPF.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gruyaume, FYI, iUPF is the intermediate UPF (N3 and N9 interfaces)

logger.CtxLog.Errorf("activate UpLink PDR[%v] failed %v", name, err)
return err
} else {
ULPDR.PDI.SourceInterface = SourceInterface{InterfaceValue: SourceInterfaceAccess}
ULPDR.PDI.LocalFTeid = &FTEID{
V4: true,
Ipv4Address: upIP,
Teid: curULTunnel.TEID,
}

ULPDR.PDI.UEIPAddress = &ueIpAddr

ULPDR.PDI.NetworkInstance = util_3gpp.Dnn(smContext.Dnn)
}

ULPDR.PDI.UEIPAddress = &ueIpAddr
thakurajayL marked this conversation as resolved.
Show resolved Hide resolved
ULPDR.PDI.NetworkInstance = util_3gpp.Dnn(smContext.Dnn)
ULPDR.OuterHeaderRemoval = &OuterHeaderRemoval{
OuterHeaderRemovalDescription: OuterHeaderRemovalGtpUUdpIpv4,
}
Expand All @@ -591,7 +515,7 @@ func (dpNode *DataPathNode) ActivateUpLinkPdr(smContext *SMContext, defQER *QER,

if nextULDest := dpNode.Next(); nextULDest != nil {
nextULTunnel := nextULDest.UpLinkTunnel
iface = nextULTunnel.DestEndPoint.UPF.GetInterface(models.UpInterfaceType_N9, smContext.Dnn)
iface := nextULTunnel.DestEndPoint.UPF.GetInterface(models.UpInterfaceType_N9, smContext.Dnn)

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

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

if DLPDR.Precedence == 0 {
DLPDR.Precedence = defPrecedence
}

if dpNode.IsAnchorUPF() {
DLPDR.PDI.UEIPAddress = &ueIpAddr
} else {
if !dpNode.IsAnchorUPF() {
DLPDR.OuterHeaderRemoval = &OuterHeaderRemoval{
OuterHeaderRemovalDescription: OuterHeaderRemovalGtpUUdpIpv4,
}

iface = DLDestUPF.GetInterface(models.UpInterfaceType_N9, smContext.Dnn)
if upIP, err := iface.IP(smContext.SelectedPDUSessionType); err != nil {
logger.CtxLog.Errorf("activate Downlink PDR[%v] failed %v", name, err)
return err
} else {
DLPDR.PDI.SourceInterface = SourceInterface{InterfaceValue: SourceInterfaceCore}
DLPDR.PDI.LocalFTeid = &FTEID{
V4: true,
Ipv4Address: upIP,
Teid: curDLTunnel.TEID,
}

DLPDR.PDI.UEIPAddress = &ueIpAddr
}
}

DLPDR.PDI.SourceInterface = SourceInterface{InterfaceValue: SourceInterfaceCore}
DLPDR.PDI.UEIPAddress = &ueIpAddr
DLPDR.PDI.UEIPAddress = &ueIpAddr

DLFAR := DLPDR.FAR

logger.PduSessLog.Debugln("current DP Node IP:", dpNode.UPF.NodeID.ResolveNodeIdToIp().String())
Expand Down
126 changes: 126 additions & 0 deletions context/datapath_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
// Copyright 2024 Canonical Ltd.
gab-arrobo marked this conversation as resolved.
Show resolved Hide resolved
//
// SPDX-License-Identifier: Apache-2.0

package context_test

import (
"net"
"testing"

"github.com/omec-project/smf/context"
)

func TestActivateUpLinkPdr(t *testing.T) {
smContext := &context.SMContext{
PDUAddress: &context.UeIpAddr{
Ip: net.IPv4(192, 168, 1, 1),
},
Dnn: "internet",
}

defQER := &context.QER{}

dpNode := &context.DataPathNode{
UPF: &context.UPF{},
UpLinkTunnel: &context.GTPTunnel{
PDR: map[string]*context.PDR{
"default": {
Precedence: 0,
FAR: &context.FAR{},
},
},
},
}

err := dpNode.ActivateUpLinkPdr(smContext, defQER, 10)
if err != nil {
t.Errorf("expected no error, got %v", err)
}

pdr := dpNode.UpLinkTunnel.PDR["default"]
if pdr == nil {
t.Fatalf("expected pdr to be not nil")
}

if pdr.PDI.SourceInterface.InterfaceValue != context.SourceInterfaceAccess {
t.Errorf("expected SourceInterface to be %v, got %v", context.SourceInterfaceAccess, pdr.PDI.SourceInterface.InterfaceValue)
}
if pdr.PDI.LocalFTeid == nil {
t.Errorf("expected pdr.PDI.LocalFTeid to be not nil")
}
if !pdr.PDI.LocalFTeid.Ch {
t.Errorf("expected pdr.PDI.LocalFTeid.Ch to be true")
}
if pdr.PDI.UEIPAddress == nil {
t.Errorf("expected pdr.PDI.UEIPAddress to be not nil")
}
if !pdr.PDI.UEIPAddress.V4 {
t.Errorf("expected pdr.PDI.UEIPAddress.V4 to be true")
}
if !pdr.PDI.UEIPAddress.Ipv4Address.Equal(net.IP{192, 168, 1, 1}) {
t.Errorf("expected pdr.PDI.UEIPAddress.Ipv4Address to be %v, got %v", net.IP{192, 168, 1, 1}, pdr.PDI.UEIPAddress.Ipv4Address)
}
if string(pdr.PDI.NetworkInstance) != "internet" {
t.Errorf("expected pdr.PDI.NetworkInstance to be 'internet', got %v", string(pdr.PDI.NetworkInstance))
}
}

func TestActivateDlLinkPdr(t *testing.T) {
smContext := &context.SMContext{
PDUAddress: &context.UeIpAddr{
Ip: net.IP{192, 168, 1, 1},
},
Dnn: "internet",
Tunnel: &context.UPTunnel{
ANInformation: struct {
IPAddress net.IP
TEID uint32
}{
IPAddress: net.IP{10, 0, 0, 1},
TEID: 12345,
},
},
}

defQER := &context.QER{}

dpNode := &context.DataPathNode{
UPF: &context.UPF{},
DownLinkTunnel: &context.GTPTunnel{
PDR: map[string]*context.PDR{
"default": {
Precedence: 0,
FAR: &context.FAR{},
},
},
},
}

dataPath := &context.DataPath{
FirstDPNode: dpNode,
}

err := dpNode.ActivateDlLinkPdr(smContext, defQER, 10, dataPath)
if err != nil {
t.Fatalf("expected no error, got %v", err)
}

pdr := dpNode.DownLinkTunnel.PDR["default"]
if pdr == nil {
t.Fatalf("expected pdr to be not nil")
}

if pdr.PDI.SourceInterface.InterfaceValue != context.SourceInterfaceCore {
t.Errorf("expected SourceInterface to be %v, got %v", context.SourceInterfaceCore, pdr.PDI.SourceInterface.InterfaceValue)
}
if pdr.PDI.UEIPAddress == nil {
t.Errorf("expected pdr.PDI.UEIPAddress to be not nil")
}
if !pdr.PDI.UEIPAddress.V4 {
t.Errorf("expected pdr.PDI.UEIPAddress.V4 to be true")
}
if !pdr.PDI.UEIPAddress.Ipv4Address.Equal(net.IP{192, 168, 1, 1}) {
t.Errorf("expected pdr.PDI.UEIPAddress.Ipv4Address to be %v, got %v", net.IP{192, 168, 1, 1}, pdr.PDI.UEIPAddress.Ipv4Address)
}
}
Loading