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

refactor: introduce UPNode as common interface for UPF and gNB nodes #120

Open
wants to merge 15 commits into
base: main
Choose a base branch
from
Open
23 changes: 5 additions & 18 deletions internal/context/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -176,26 +176,13 @@ func InitSmfContext(config *factory.Config) {
smfContext.ListenAddr = pfcp.ListenAddr
smfContext.ExternalAddr = pfcp.ExternalAddr

if ip := net.ParseIP(pfcp.NodeID); ip == nil {
smfContext.CPNodeID = pfcpType.NodeID{
NodeIdType: pfcpType.NodeIdTypeFqdn,
FQDN: pfcp.NodeID,
}
} else {
ipv4 := ip.To4()
if ipv4 != nil {
smfContext.CPNodeID = pfcpType.NodeID{
NodeIdType: pfcpType.NodeIdTypeIpv4Address,
IP: ipv4,
}
} else {
smfContext.CPNodeID = pfcpType.NodeID{
NodeIdType: pfcpType.NodeIdTypeIpv6Address,
IP: ip,
}
}
nodeID, err := ConfigToNodeID(pfcp.NodeID)
if err != nil {
logger.InitLog.Fatalf("[InitSmfContext] cannot parse PFCP NodeID from config: %+v", err)
}

smfContext.CPNodeID = nodeID

smfContext.PfcpHeartbeatInterval = pfcp.HeartbeatInterval
var multipleOfInterval time.Duration = 5
if pfcp.AssocFailAlertInterval == 0 {
Expand Down
46 changes: 19 additions & 27 deletions internal/context/datapath.go
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ func (node *DataPathNode) ActivateUpLinkTunnel(smContext *SMContext) error {

destUPF := node.UPF
if node.UpLinkTunnel.PDR, err = destUPF.AddPDR(); err != nil {
logger.CtxLog.Errorln("In ActivateUpLinkTunnel UPF IP: ", node.UPF.NodeID.ResolveNodeIdToIp().String())
logger.CtxLog.Errorln("In ActivateUpLinkTunnel UPF IP: ", node.GetNodeIP())
logger.CtxLog.Errorln("Allocate PDR Error: ", err)
return fmt.Errorf("Add PDR failed: %s", err)
}
Expand All @@ -159,7 +159,7 @@ func (node *DataPathNode) ActivateDownLinkTunnel(smContext *SMContext) error {

destUPF := node.UPF
if node.DownLinkTunnel.PDR, err = destUPF.AddPDR(); err != nil {
logger.CtxLog.Errorln("In ActivateDownLinkTunnel UPF IP: ", node.UPF.NodeID.ResolveNodeIdToIp().String())
logger.CtxLog.Errorln("In ActivateDownLinkTunnel UPF IP: ", node.GetNodeIP())
logger.CtxLog.Errorln("Allocate PDR Error: ", err)
return fmt.Errorf("Add PDR failed: %s", err)
}
Expand Down Expand Up @@ -244,20 +244,12 @@ func (node *DataPathNode) DeactivateDownLinkTunnel(smContext *SMContext) {
}
}

func (node *DataPathNode) GetUPFID() (id string, err error) {
node_ip := node.GetNodeIP()
var exist bool

if id, exist = smfContext.UserPlaneInformation.UPFsIPtoID[node_ip]; !exist {
err = fmt.Errorf("UPNode IP %s doesn't exist in smfcfg.yaml", node_ip)
return "", err
}

return id, nil
func (node *DataPathNode) GetUPFID() uuid.UUID {
return node.UPF.GetID()
}

func (node *DataPathNode) GetNodeIP() (ip string) {
ip = node.UPF.NodeID.ResolveNodeIdToIp().String()
ip = node.UPF.GetNodeIDString()
return
}

Expand Down Expand Up @@ -319,17 +311,17 @@ func (dataPath *DataPath) String() string {
for curDPNode := firstDPNode; curDPNode != nil; curDPNode = curDPNode.Next() {
str += strconv.Itoa(index) + "th Node in the Path\n"
str += "Current UPF IP: " + curDPNode.GetNodeIP() + "\n"
str += "Current UPF ID: " + curDPNode.UPF.GetUPFID() + "\n"
str += "Current UPF ID: " + curDPNode.UPF.GetID().String() + "\n"
if curDPNode.Prev() != nil {
str += "Previous UPF IP: " + curDPNode.Prev().GetNodeIP() + "\n"
str += "Previous UPF ID: " + curDPNode.Prev().UPF.GetUPFID() + "\n"
str += "Previous UPF ID: " + curDPNode.Prev().UPF.GetID().String() + "\n"
} else {
str += "Previous UPF IP: None\n"
}

if curDPNode.Next() != nil {
str += "Next UPF IP: " + curDPNode.Next().GetNodeIP() + "\n"
str += "Next UPF ID: " + curDPNode.Next().UPF.GetUPFID() + "\n"
str += "Next UPF ID: " + curDPNode.Next().UPF.GetID().String() + "\n"
} else {
str += "Next UPF IP: None\n"
}
Expand All @@ -340,8 +332,8 @@ func (dataPath *DataPath) String() string {
return str
}

func getUrrIdKey(uuid string, urrId uint32) string {
return uuid + ":" + strconv.Itoa(int(urrId))
func getUrrIdKey(uuid uuid.UUID, urrId uint32) string {
return uuid.String() + ":" + strconv.Itoa(int(urrId))
}

func GetUpfIdFromUrrIdKey(urrIdKey string) string {
Expand All @@ -352,7 +344,7 @@ func (node DataPathNode) addUrrToNode(smContext *SMContext, urrId uint32, isMeas
var urr *URR
var ok bool
var err error
currentUUID := node.UPF.UUID()
currentUUID := node.UPF.GetID()
id := getUrrIdKey(currentUUID, urrId)

if urr, ok = smContext.UrrUpfMap[id]; !ok {
Expand Down Expand Up @@ -412,7 +404,7 @@ func (dataPath *DataPath) ActivateTunnelAndPDR(smContext *SMContext, precedence
logger.PduSessLog.Traceln(dataPath.String())
// Activate Tunnels
for node := firstDPNode; node != nil; node = node.Next() {
logger.PduSessLog.Traceln("Current DP Node IP: ", node.UPF.NodeID.ResolveNodeIdToIp().String())
logger.PduSessLog.Traceln("Current DP Node IP: ", node.GetNodeIP())
if err := node.ActivateUpLinkTunnel(smContext); err != nil {
logger.CtxLog.Warnln(err)
return
Expand All @@ -438,7 +430,7 @@ func (dataPath *DataPath) ActivateTunnelAndPDR(smContext *SMContext, precedence
for curDataPathNode := firstDPNode; curDataPathNode != nil; curDataPathNode = curDataPathNode.Next() {
var defaultQER *QER
var ambrQER *QER
currentUUID := curDataPathNode.UPF.uuid
currentUUID := curDataPathNode.UPF.GetID()
if qerId, okCurrentId := smContext.AMBRQerMap[currentUUID]; !okCurrentId {
if newQER, err := curDataPathNode.UPF.AddQER(); err != nil {
logger.PduSessLog.Errorln("new QER failed")
Expand Down Expand Up @@ -644,7 +636,7 @@ func (dataPath *DataPath) ActivateTunnelAndPDR(smContext *SMContext, precedence

DLFAR := DLPDR.FAR

logger.PduSessLog.Traceln("Current DP Node IP: ", curDataPathNode.UPF.NodeID.ResolveNodeIdToIp().String())
logger.PduSessLog.Traceln("Current DP Node IP: ", curDataPathNode.GetNodeIP())
logger.PduSessLog.Traceln("Before DLPDR OuterHeaderCreation")
if nextDLDest := curDataPathNode.Prev(); nextDLDest != nil {
logger.PduSessLog.Traceln("In DLPDR OuterHeaderCreation")
Expand Down Expand Up @@ -768,7 +760,7 @@ func (p *DataPath) AddChargingRules(smContext *SMContext, chgLevel ChargingLevel
chgInfo := &ChargingInfo{
RatingGroup: chgData.RatingGroup,
ChargingLevel: chgLevel,
UpfId: node.UPF.UUID(),
UpfId: node.UPF.GetID().String(),
}

urrId, err := smContext.UrrIDGenerator.Allocate()
Expand All @@ -777,7 +769,7 @@ func (p *DataPath) AddChargingRules(smContext *SMContext, chgLevel ChargingLevel
return
}

currentUUID := node.UPF.UUID()
currentUUID := node.UPF.GetID()
id := getUrrIdKey(currentUUID, uint32(urrId))

if oldURR, ok := smContext.UrrUpfMap[id]; !ok {
Expand Down Expand Up @@ -820,7 +812,7 @@ func (p *DataPath) AddChargingRules(smContext *SMContext, chgLevel ChargingLevel
if !isUrrExist(node.UpLinkTunnel.PDR.URR, urr) {
node.UpLinkTunnel.PDR.AppendURRs([]*URR{urr})
// nolint
nodeId, _ := node.GetUPFID()
nodeId := node.GetUPFID()
logger.PduSessLog.Tracef("UpLinkTunnel add URR for node %s %+v",
nodeId, node.UpLinkTunnel.PDR)
}
Expand All @@ -829,7 +821,7 @@ func (p *DataPath) AddChargingRules(smContext *SMContext, chgLevel ChargingLevel
if !isUrrExist(node.DownLinkTunnel.PDR.URR, urr) {
node.DownLinkTunnel.PDR.AppendURRs([]*URR{urr})
// nolint
nodeId, _ := node.GetUPFID()
nodeId := node.GetUPFID()
logger.PduSessLog.Tracef("DownLinkTunnel add URR for node %s %+v",
nodeId, node.UpLinkTunnel.PDR)
}
Expand All @@ -847,7 +839,7 @@ func (p *DataPath) AddQoS(smContext *SMContext, qfi uint8, qos *models.QosData)
for node := p.FirstDPNode; node != nil; node = node.Next() {
var qer *QER

currentUUID := node.UPF.GetUUID()
currentUUID := node.UPF.GetID()
id := getQosIdKey(currentUUID, qfi)

if qerId, ok := smContext.QerUpfMap[id]; !ok {
Expand Down
97 changes: 97 additions & 0 deletions internal/context/gnb.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
package context

import (
"fmt"
"net"

"github.com/google/uuid"

"github.com/free5gc/pfcp/pfcpType"
"github.com/free5gc/smf/internal/logger"
)

// embeds the UPNode struct ("inheritance")
// implements UPNodeInterface
type GNB struct {
UPNode
ANIP net.IP
}

func (gNB *GNB) GetName() string {
return gNB.Name
}

func (gNB *GNB) GetID() uuid.UUID {
return gNB.ID
}

func (gNB *GNB) GetType() UPNodeType {
return gNB.Type
}

func (gNB *GNB) GetDnn() string {
return gNB.Dnn
}

func (gNB *GNB) String() string {
str := "gNB {\n"
prefix := " "
str += prefix + fmt.Sprintf("Name: %s\n", gNB.Name)
str += prefix + fmt.Sprintf("ANIP: %s\n", gNB.ANIP)
str += prefix + fmt.Sprintf("ID: %s\n", gNB.ID)
str += prefix + fmt.Sprintf("NodeID: %s\n", gNB.GetNodeIDString())
str += prefix + fmt.Sprintf("Dnn: %s\n", gNB.Dnn)
str += prefix + fmt.Sprintln("Links:")
for _, link := range gNB.Links {
str += prefix + fmt.Sprintf("-- %s: %s\n", link.GetName(), link.GetNodeIDString())
}
str += "}"
return str
}

func (gNB *GNB) GetNodeIDString() string {
switch gNB.NodeID.NodeIdType {
case pfcpType.NodeIdTypeIpv4Address, pfcpType.NodeIdTypeIpv6Address:
return gNB.NodeID.IP.String()
case pfcpType.NodeIdTypeFqdn:
return gNB.NodeID.FQDN
default:
logger.CtxLog.Errorf("nodeID has unknown type %d", gNB.NodeID.NodeIdType)
return ""
}
}

func (gNB *GNB) GetNodeID() pfcpType.NodeID {
return gNB.NodeID
}

func (gNB *GNB) GetLinks() UPPath {
return gNB.Links
}

func (gNB *GNB) AddLink(link UPNodeInterface) bool {
for _, existingLink := range gNB.Links {
if link.GetName() == existingLink.GetName() {
logger.CfgLog.Warningf("UPLink [%s] <=> [%s] already exists, skip\n", existingLink.GetName(), link.GetName())
return false
}
}
gNB.Links = append(gNB.Links, link)
return true
}

func (gNB *GNB) RemoveLink(link UPNodeInterface) bool {
for i, existingLink := range gNB.Links {
if link.GetName() == existingLink.GetName() && existingLink.GetNodeIDString() == link.GetNodeIDString() {
logger.CfgLog.Warningf("Remove UPLink [%s] <=> [%s]\n", existingLink.GetName(), link.GetName())
gNB.Links = append(gNB.Links[:i], gNB.Links[i+1:]...)
return true
}
}
return false
}

func (gNB *GNB) RemoveLinkByIndex(index int) bool {
gNB.Links[index] = gNB.Links[len(gNB.Links)-1]
return true
}
2 changes: 1 addition & 1 deletion internal/context/pfcp_reports.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ func (smContext *SMContext) HandleReports(
) {
var usageReport UsageReport
upf := RetrieveUPFNodeByNodeID(nodeId)
upfId := upf.UUID()
upfId := upf.GetID()

for _, report := range usageReportRequest {
usageReport.UrrId = report.URRID.UrrIdValue
Expand Down
10 changes: 5 additions & 5 deletions internal/context/sm_context.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ type EventExposureNotification struct {

type UsageReport struct {
UrrId uint32
UpfId string
UpfId uuid.UUID

TotalVolume uint64
UplinkVolume uint64
Expand Down Expand Up @@ -160,7 +160,7 @@ type SMContext struct {
SmStatusNotifyUri string

Tunnel *UPTunnel
SelectedUPF *UPNode
SelectedUPF *UPF
BPManager *BPManager
// NodeID(string form) to PFCP Session Context
PFCPContext map[string]*PFCPSessionContext
Expand Down Expand Up @@ -476,13 +476,13 @@ func (smContext *SMContext) GetNodeIDByLocalSEID(seid uint64) pfcpType.NodeID {

func (smContext *SMContext) AllocateLocalSEIDForUPPath(path UPPath) {
for _, upNode := range path {
NodeIDtoIP := upNode.NodeID.ResolveNodeIdToIp().String()
NodeIDtoIP := upNode.GetNodeIDString()
if _, exist := smContext.PFCPContext[NodeIDtoIP]; !exist {
allocatedSEID := AllocateLocalSEID()

smContext.PFCPContext[NodeIDtoIP] = &PFCPSessionContext{
PDRs: make(map[uint16]*PDR),
NodeID: upNode.NodeID,
NodeID: upNode.GetNodeID(),
LocalSEID: allocatedSEID,
}

Expand All @@ -494,7 +494,7 @@ func (smContext *SMContext) AllocateLocalSEIDForUPPath(path UPPath) {
func (smContext *SMContext) AllocateLocalSEIDForDataPath(dataPath *DataPath) {
logger.PduSessLog.Traceln("In AllocateLocalSEIDForDataPath")
for node := dataPath.FirstDPNode; node != nil; node = node.Next() {
NodeIDtoIP := node.UPF.NodeID.ResolveNodeIdToIp().String()
NodeIDtoIP := node.GetNodeIP()
logger.PduSessLog.Traceln("NodeIDtoIP: ", NodeIDtoIP)
if _, exist := smContext.PFCPContext[NodeIDtoIP]; !exist {
allocatedSEID := AllocateLocalSEID()
Expand Down
9 changes: 4 additions & 5 deletions internal/context/sm_context_policy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@ import (
var userPlaneConfig = factory.UserPlaneInformation{
UPNodes: map[string]*factory.UPNode{
"GNodeB": {
Type: "AN",
Type: "AN",
NodeID: "192.168.1.1",
},
"UPF1": {
Type: "UPF",
NodeID: "10.4.0.11",
Addr: "10.4.0.11",
SNssaiInfos: []*factory.SnssaiUpfInfoItem{
{
SNssai: &models.Snssai{
Expand Down Expand Up @@ -53,7 +53,6 @@ var userPlaneConfig = factory.UserPlaneInformation{
"UPF2": {
Type: "UPF",
NodeID: "10.4.0.12",
Addr: "10.4.0.12",
SNssaiInfos: []*factory.SnssaiUpfInfoItem{
{
SNssai: &models.Snssai{
Expand Down Expand Up @@ -96,7 +95,7 @@ var userPlaneConfig = factory.UserPlaneInformation{
var testConfig = factory.Config{
Info: &factory.Info{
Version: "1.0.0",
Description: "SMF procdeure test configuration",
Description: "SMF procedure test configuration",
},
Configuration: &factory.Configuration{
Sbi: &factory.Sbi{
Expand Down Expand Up @@ -622,7 +621,7 @@ func TestApplyPccRules(t *testing.T) {
smfContext := context.GetSelf()
smfContext.UserPlaneInformation = context.NewUserPlaneInformation(&userPlaneConfig)
for _, n := range smfContext.UserPlaneInformation.UPFs {
n.UPF.UPFStatus = context.AssociatedSetUpSuccess
n.UPFStatus = context.AssociatedSetUpSuccess
}

smctx := context.NewSMContext("imsi-208930000000002", 10)
Expand Down
Loading
Loading