Skip to content

Commit

Permalink
feat(smf): notify UPF to send endMarker when handover (#58)
Browse files Browse the repository at this point in the history
  • Loading branch information
tim-ywliu authored Jun 28, 2022
1 parent f0d0531 commit c005646
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 80 deletions.
72 changes: 12 additions & 60 deletions internal/context/ngap_handler.go
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
package context

import (
"bytes"
"encoding/binary"
"errors"
"fmt"

"github.com/free5gc/aper"
"github.com/free5gc/ngap/ngapType"
"github.com/free5gc/openapi/models"
"github.com/free5gc/pfcp/pfcpType"
"github.com/free5gc/smf/internal/logger"
)

Expand All @@ -29,25 +26,11 @@ func HandlePDUSessionResourceSetupResponseTransfer(b []byte, ctx *SMContext) (er
return errors.New("resourceSetupResponseTransfer.QosFlowPerTNLInformation.UPTransportLayerInformation.Present")
}

gtpTunnel := QosFlowPerTNLInformation.UPTransportLayerInformation.GTPTunnel
GTPTunnel := QosFlowPerTNLInformation.UPTransportLayerInformation.GTPTunnel

teid := binary.BigEndian.Uint32(gtpTunnel.GTPTEID.Value)

ctx.Tunnel.ANInformation.IPAddress = gtpTunnel.TransportLayerAddress.Value.Bytes
ctx.Tunnel.ANInformation.TEID = teid

for _, dataPath := range ctx.Tunnel.DataPathPool {
if dataPath.Activated {
ANUPF := dataPath.FirstDPNode
DLPDR := ANUPF.DownLinkTunnel.PDR

DLPDR.FAR.ForwardingParameters.OuterHeaderCreation = new(pfcpType.OuterHeaderCreation)
dlOuterHeaderCreation := DLPDR.FAR.ForwardingParameters.OuterHeaderCreation
dlOuterHeaderCreation.OuterHeaderCreationDescription = pfcpType.OuterHeaderCreationGtpUUdpIpv4
dlOuterHeaderCreation.Teid = teid
dlOuterHeaderCreation.Ipv4Address = ctx.Tunnel.ANInformation.IPAddress.To4()
}
}
ctx.Tunnel.UpdateANInformation(
GTPTunnel.TransportLayerAddress.Value.Bytes,
binary.BigEndian.Uint32(GTPTunnel.GTPTEID.Value))

ctx.UpCnxState = models.UpCnxState_ACTIVATED
return nil
Expand Down Expand Up @@ -99,26 +82,11 @@ func HandlePathSwitchRequestTransfer(b []byte, ctx *SMContext) error {
return errors.New("pathSwitchRequestTransfer.DLNGUUPTNLInformation.Present")
}

gtpTunnel := pathSwitchRequestTransfer.DLNGUUPTNLInformation.GTPTunnel

teid := binary.BigEndian.Uint32(gtpTunnel.GTPTEID.Value)

ctx.Tunnel.ANInformation.IPAddress = gtpTunnel.TransportLayerAddress.Value.Bytes
ctx.Tunnel.ANInformation.TEID = teid
GTPTunnel := pathSwitchRequestTransfer.DLNGUUPTNLInformation.GTPTunnel

for _, dataPath := range ctx.Tunnel.DataPathPool {
if dataPath.Activated {
ANUPF := dataPath.FirstDPNode
DLPDR := ANUPF.DownLinkTunnel.PDR

DLPDR.FAR.ForwardingParameters.OuterHeaderCreation = new(pfcpType.OuterHeaderCreation)
dlOuterHeaderCreation := DLPDR.FAR.ForwardingParameters.OuterHeaderCreation
dlOuterHeaderCreation.OuterHeaderCreationDescription = pfcpType.OuterHeaderCreationGtpUUdpIpv4
dlOuterHeaderCreation.Teid = teid
dlOuterHeaderCreation.Ipv4Address = ctx.Tunnel.ANInformation.IPAddress.To4()
DLPDR.FAR.State = RULE_UPDATE
}
}
ctx.Tunnel.UpdateANInformation(
GTPTunnel.TransportLayerAddress.Value.Bytes,
binary.BigEndian.Uint32(GTPTunnel.GTPTEID.Value))

ctx.UpSecurityFromPathSwitchRequestSameAsLocalStored = true

Expand Down Expand Up @@ -189,28 +157,12 @@ func HandleHandoverRequestAcknowledgeTransfer(b []byte, ctx *SMContext) (err err
if err != nil {
return err
}
DLNGUUPTNLInformation := handoverRequestAcknowledgeTransfer.DLNGUUPTNLInformation
GTPTunnel := DLNGUUPTNLInformation.GTPTunnel
TEIDReader := bytes.NewBuffer(GTPTunnel.GTPTEID.Value)

teid, err := binary.ReadUvarint(TEIDReader)
if err != nil {
return fmt.Errorf("Parse TEID error %s", err.Error())
}
DLNGUUPGTPTunnel := handoverRequestAcknowledgeTransfer.DLNGUUPTNLInformation.GTPTunnel

for _, dataPath := range ctx.Tunnel.DataPathPool {
if dataPath.Activated {
ANUPF := dataPath.FirstDPNode
DLPDR := ANUPF.DownLinkTunnel.PDR

DLPDR.FAR.ForwardingParameters.OuterHeaderCreation = new(pfcpType.OuterHeaderCreation)
dlOuterHeaderCreation := DLPDR.FAR.ForwardingParameters.OuterHeaderCreation
dlOuterHeaderCreation.OuterHeaderCreationDescription = pfcpType.OuterHeaderCreationGtpUUdpIpv4
dlOuterHeaderCreation.Teid = uint32(teid)
dlOuterHeaderCreation.Ipv4Address = GTPTunnel.TransportLayerAddress.Value.Bytes
DLPDR.FAR.State = RULE_UPDATE
}
}
ctx.Tunnel.UpdateANInformation(
DLNGUUPGTPTunnel.TransportLayerAddress.Value.Bytes,
binary.BigEndian.Uint32(DLNGUUPGTPTunnel.GTPTEID.Value))

return nil
}
1 change: 1 addition & 0 deletions internal/context/pfcp_rules.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ type ForwardingParameters struct {
NetworkInstance *pfcpType.NetworkInstance
OuterHeaderCreation *pfcpType.OuterHeaderCreation
ForwardingPolicyID string
SendEndMarker bool
}

// Buffering Action Rule 7.5.2.6-1
Expand Down
24 changes: 24 additions & 0 deletions internal/context/upf.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,30 @@ type UPTunnel struct {
}
}

func (t *UPTunnel) UpdateANInformation(ip net.IP, teid uint32) {
t.ANInformation.IPAddress = ip
t.ANInformation.TEID = teid

for _, dataPath := range t.DataPathPool {
if dataPath.Activated {
ANUPF := dataPath.FirstDPNode
DLPDR := ANUPF.DownLinkTunnel.PDR

if DLPDR.FAR.ForwardingParameters.OuterHeaderCreation != nil {
// Old AN tunnel exists
DLPDR.FAR.ForwardingParameters.SendEndMarker = true
}

DLPDR.FAR.ForwardingParameters.OuterHeaderCreation = new(pfcpType.OuterHeaderCreation)
dlOuterHeaderCreation := DLPDR.FAR.ForwardingParameters.OuterHeaderCreation
dlOuterHeaderCreation.OuterHeaderCreationDescription = pfcpType.OuterHeaderCreationGtpUUdpIpv4
dlOuterHeaderCreation.Teid = t.ANInformation.TEID
dlOuterHeaderCreation.Ipv4Address = t.ANInformation.IPAddress.To4()
DLPDR.FAR.State = RULE_UPDATE
}
}
}

type UPFStatus int

const (
Expand Down
45 changes: 25 additions & 20 deletions internal/pfcp/message/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,16 +119,16 @@ func farToCreateFAR(far *context.FAR) *pfcp.CreateFAR {
}

if far.ForwardingParameters != nil {
createFAR.ForwardingParameters = new(pfcp.ForwardingParametersIEInFAR)
createFAR.ForwardingParameters.DestinationInterface = &far.ForwardingParameters.DestinationInterface
createFAR.ForwardingParameters.NetworkInstance = far.ForwardingParameters.NetworkInstance
createFAR.ForwardingParameters.OuterHeaderCreation = far.ForwardingParameters.OuterHeaderCreation
createFAR.ForwardingParameters = &pfcp.ForwardingParametersIEInFAR{
DestinationInterface: &far.ForwardingParameters.DestinationInterface,
NetworkInstance: far.ForwardingParameters.NetworkInstance,
OuterHeaderCreation: far.ForwardingParameters.OuterHeaderCreation,
}
if far.ForwardingParameters.ForwardingPolicyID != "" {
createFAR.ForwardingParameters.ForwardingPolicy = new(pfcpType.ForwardingPolicy)
createFAR.ForwardingParameters.ForwardingPolicy.ForwardingPolicyIdentifierLength =
uint8(len(far.ForwardingParameters.ForwardingPolicyID))
createFAR.ForwardingParameters.ForwardingPolicy.ForwardingPolicyIdentifier =
[]byte(far.ForwardingParameters.ForwardingPolicyID)
createFAR.ForwardingParameters.ForwardingPolicy = &pfcpType.ForwardingPolicy{
ForwardingPolicyIdentifierLength: uint8(len(far.ForwardingParameters.ForwardingPolicyID)),
ForwardingPolicyIdentifier: []byte(far.ForwardingParameters.ForwardingPolicyID),
}
}
}

Expand Down Expand Up @@ -220,16 +220,19 @@ func farToUpdateFAR(far *context.FAR) *pfcp.UpdateFAR {
updateFAR.ApplyAction.Drop = far.ApplyAction.Drop

if far.ForwardingParameters != nil {
updateFAR.UpdateForwardingParameters = new(pfcp.UpdateForwardingParametersIEInFAR)
updateFAR.UpdateForwardingParameters.DestinationInterface = &far.ForwardingParameters.DestinationInterface
updateFAR.UpdateForwardingParameters.NetworkInstance = far.ForwardingParameters.NetworkInstance
updateFAR.UpdateForwardingParameters.OuterHeaderCreation = far.ForwardingParameters.OuterHeaderCreation
updateFAR.UpdateForwardingParameters = &pfcp.UpdateForwardingParametersIEInFAR{
DestinationInterface: &far.ForwardingParameters.DestinationInterface,
NetworkInstance: far.ForwardingParameters.NetworkInstance,
OuterHeaderCreation: far.ForwardingParameters.OuterHeaderCreation,
PFCPSMReqFlags: &pfcpType.PFCPSMReqFlags{
Sndem: far.ForwardingParameters.SendEndMarker,
},
}
if far.ForwardingParameters.ForwardingPolicyID != "" {
updateFAR.UpdateForwardingParameters.ForwardingPolicy = new(pfcpType.ForwardingPolicy)
updateFAR.UpdateForwardingParameters.ForwardingPolicy.ForwardingPolicyIdentifierLength =
uint8(len(far.ForwardingParameters.ForwardingPolicyID))
updateFAR.UpdateForwardingParameters.ForwardingPolicy.ForwardingPolicyIdentifier =
[]byte(far.ForwardingParameters.ForwardingPolicyID)
updateFAR.UpdateForwardingParameters.ForwardingPolicy = &pfcpType.ForwardingPolicy{
ForwardingPolicyIdentifierLength: uint8(len(far.ForwardingParameters.ForwardingPolicyID)),
ForwardingPolicyIdentifier: []byte(far.ForwardingParameters.ForwardingPolicyID),
}
}
}

Expand All @@ -242,7 +245,8 @@ func BuildPfcpSessionEstablishmentRequest(
pdrList []*context.PDR,
farList []*context.FAR,
barList []*context.BAR,
qerList []*context.QER) (pfcp.PFCPSessionEstablishmentRequest, error) {
qerList []*context.QER,
) (pfcp.PFCPSessionEstablishmentRequest, error) {
msg := pfcp.PFCPSessionEstablishmentRequest{}

msg.NodeID = &context.SMF_Self().CPNodeID
Expand Down Expand Up @@ -351,7 +355,8 @@ func BuildPfcpSessionModificationRequest(
pdrList []*context.PDR,
farList []*context.FAR,
barList []*context.BAR,
qerList []*context.QER) (pfcp.PFCPSessionModificationRequest, error) {
qerList []*context.QER,
) (pfcp.PFCPSessionModificationRequest, error) {
msg := pfcp.PFCPSessionModificationRequest{}

msg.UpdatePDR = make([]*pfcp.UpdatePDR, 0, 2)
Expand Down

0 comments on commit c005646

Please sign in to comment.