Skip to content

Commit

Permalink
Add new types FARUpdate and FARMapUpdate to handle correctly the …
Browse files Browse the repository at this point in the history
…update of Forwarding Parameters
  • Loading branch information
louisroyer committed Jan 13, 2025
1 parent 4d6f571 commit c34ba22
Show file tree
Hide file tree
Showing 10 changed files with 225 additions and 95 deletions.
4 changes: 1 addition & 3 deletions pfcp/api/far_interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,7 @@ type FARID = uint32
type FARInterface interface {
ID() (FARID, error)
ApplyAction() *ie.IE
SetApplyAction(*ie.IE) error
ForwardingParameters() (*ie.IE, error)
SetForwardingParameters(*ie.IE) error
NewCreateFAR() *ie.IE
NewUpdateFAR() *ie.IE
Update(FARUpdateInterface) error
}
5 changes: 2 additions & 3 deletions pfcp/api/far_map_interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,11 @@ import (
type FARMapInterface interface {
Get(key FARID) (FARInterface, error)
Add(far FARInterface) error
Update(far FARInterface) error
Update(far FARUpdateInterface) error
Remove(key FARID) error
SimulateAdd(far FARInterface) error
SimulateUpdate(far FARInterface) error
SimulateUpdate(far FARUpdateInterface) error
SimulateRemove(key FARID) error
Foreach(func(FARInterface) error) error
IntoCreateFAR() []*ie.IE
IntoUpdateFAR() []*ie.IE
}
14 changes: 14 additions & 0 deletions pfcp/api/far_map_update_interface.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// Copyright Louis Royer and the NextMN contributors. All rights reserved.
// Use of this source code is governed by a MIT-style license that can be
// found in the LICENSE file.
// SPDX-License-Identifier: MIT

package api

import "github.com/wmnsk/go-pfcp/ie"

type FARMapUpdateInterface interface {
Add(far FARUpdateInterface) error
IntoUpdateFAR() []*ie.IE
Foreach(f func(FARUpdateInterface) error) error
}
15 changes: 15 additions & 0 deletions pfcp/api/far_update_interface.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Copyright Louis Royer and the NextMN contributors. All rights reserved.
// Use of this source code is governed by a MIT-style license that can be
// found in the LICENSE file.
// SPDX-License-Identifier: MIT

package api

import "github.com/wmnsk/go-pfcp/ie"

type FARUpdateInterface interface {
ID() (FARID, error)
ApplyAction() *ie.IE
UpdateForwardingParameters() *ie.IE
NewUpdateFAR() *ie.IE
}
2 changes: 1 addition & 1 deletion pfcp/api/session_interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ type PFCPSessionInterface interface {
GetSortedPDRIDs() []PDRID
GetPDR(pdrid PDRID) (PDRInterface, error)
GetFAR(farid FARID) (FARInterface, error)
AddUpdatePDRsFARs(createpdrs PDRMapInterface, createfars FARMapInterface, updatepdr PDRMapInterface, updatefars FARMapInterface) error
AddUpdatePDRsFARs(createpdrs PDRMapInterface, createfars FARMapInterface, updatepdr PDRMapInterface, updatefars FARMapUpdateInterface) error
// SetRemoteFSEID(FSEID *ie.IE)
Setup() error
ForeachUnsortedPDR(f func(pdr PDRInterface) error) error
Expand Down
57 changes: 40 additions & 17 deletions pfcp/far.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,6 @@ func (far *FAR) ApplyAction() *ie.IE {
return far.applyAction
}

func (far *FAR) SetApplyAction(aa *ie.IE) error {
far.applyAction = aa
return nil
}

func (far *FAR) ForwardingParameters() (*ie.IE, error) {
// This IE shall be present when the Apply Action requests
// the packets to be forwarded. It may be present otherwise.
Expand All @@ -48,11 +43,6 @@ func (far *FAR) ForwardingParameters() (*ie.IE, error) {

}

func (far *FAR) SetForwardingParameters(fp *ie.IE) error {
far.forwardingParameters = fp
return nil
}

func (far *FAR) NewCreateFAR() *ie.IE {
ies := make([]*ie.IE, 0)
ies = append(ies, far.id)
Expand All @@ -63,12 +53,45 @@ func (far *FAR) NewCreateFAR() *ie.IE {
return ie.NewCreateFAR(ies...)
}

func (far *FAR) NewUpdateFAR() *ie.IE {
ies := make([]*ie.IE, 0)
ies = append(ies, far.id)
ies = append(ies, far.applyAction)
if far.forwardingParameters != nil {
ies = append(ies, far.forwardingParameters)
func (far *FAR) Update(farUpdate api.FARUpdateInterface) error {
// Check FARID
farUpdateId, err := farUpdate.ID()
if err != nil {
return err
}
farId, err := far.ID()
if err != nil {
return err
}
if farId != farUpdateId {
return fmt.Errorf("Wrong FAR ID")
}

// Update ApplyAction
if aa := farUpdate.ApplyAction(); aa != nil {
far.applyAction = aa
}
return ie.NewUpdateFAR(ies...)

// Update Forwarding Parameters
ForwParam := make([]*ie.IE, 0)
if fp := farUpdate.UpdateForwardingParameters(); fp != nil {
if di, err := fp.DestinationInterface(); err == nil {
ForwParam = append(ForwParam, ie.NewDestinationInterface(di))
} else if diorg, err := far.forwardingParameters.DestinationInterface(); err == nil {
ForwParam = append(ForwParam, ie.NewDestinationInterface(diorg))
}
if ni, err := fp.NetworkInstance(); err == nil {
ForwParam = append(ForwParam, ie.NewNetworkInstance(ni))
} else if niorg, err := far.forwardingParameters.NetworkInstance(); err == nil {
ForwParam = append(ForwParam, ie.NewNetworkInstance(niorg))
}
if ohc, err := fp.OuterHeaderCreation(); err == nil {
ForwParam = append(ForwParam, ie.NewOuterHeaderCreation(ohc.OuterHeaderCreationDescription, ohc.TEID, ohc.IPv4Address.String(), ohc.IPv6Address.String(), ohc.PortNumber, ohc.CTag, ohc.STag))
} else if ohcorg, err := far.forwardingParameters.OuterHeaderCreation(); err == nil {
ForwParam = append(ForwParam, ie.NewOuterHeaderCreation(ohcorg.OuterHeaderCreationDescription, ohcorg.TEID, ohcorg.IPv4Address.String(), ohcorg.IPv6Address.String(), ohcorg.PortNumber, ohcorg.CTag, ohcorg.STag))
}
far.forwardingParameters = ie.NewForwardingParameters(ForwParam...)
}

return nil
}
73 changes: 5 additions & 68 deletions pfcp/far_map.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,41 +68,25 @@ func (m *FARMap) SimulateAdd(far api.FARInterface) error {
return nil
}

func (m *FARMap) Update(far api.FARInterface) error {
func (m *FARMap) Update(farUpdate api.FARUpdateInterface) error {
logrus.Trace("Inside farmap.Update()")
// only present fields are replaced
id, err := far.ID()
id, err := farUpdate.ID()
if err != nil {
return err
}
m.mu.Lock()
defer m.mu.Unlock()
if _, exists := m.farmap[id]; !exists {
if far, exists := m.farmap[id]; !exists {
logrus.WithFields(logrus.Fields{"far-id": id, "current_map": m.farmap}).Trace("Updating FAR: this FAR id does not exist")
return fmt.Errorf("FAR %d does not exist.", id)
} else {
logrus.WithFields(logrus.Fields{"far-id": id}).Trace("Updating FAR")
if far.ApplyAction() != nil {
m.farmap[id].SetApplyAction(far.ApplyAction())
logrus.WithFields(logrus.Fields{"far-id": id}).Trace("Updating FAR Apply Action")
}
// XXX: update fields in forwarding parameters instead of replacing
if fp, err := far.ForwardingParameters(); err == nil {
if fp == nil {
logrus.Warn("Removing forwarding parameters. aborting")
return nil
}
m.farmap[id].SetForwardingParameters(fp)
logrus.WithFields(logrus.Fields{"far-id": id}).Trace("Updating FAR Forwarding Parameters")
} else {
logrus.WithFields(logrus.Fields{"far-id": id}).Trace("Updating FAR but not Forwarding Parameters")
}

return nil
return far.Update(farUpdate)
}
}

func (m *FARMap) SimulateUpdate(far api.FARInterface) error {
func (m *FARMap) SimulateUpdate(far api.FARUpdateInterface) error {
logrus.Trace("Inside farmap.SimulateUpdate()")
id, err := far.ID()
if err != nil {
Expand Down Expand Up @@ -202,39 +186,6 @@ func NewFARMap(fars []*ie.IE) (farmap *FARMap, err error, cause uint8, offending

}

func NewFARMapUpdate(fars []*ie.IE) (*FARMap, error, uint8, uint16) {
f := FARMap{
farmap: make(farmapInternal),
mu: sync.RWMutex{},
}
for _, far := range fars {
id, err := far.FARID()
if err != nil {
switch err {
case io.ErrUnexpectedEOF:
return nil, err, ie.CauseInvalidLength, ie.FARID
case ie.ErrIENotFound:
return nil, err, ie.CauseMandatoryIEMissing, ie.FARID
default:
return nil, err, ie.CauseMandatoryIEIncorrect, ie.CreateFAR
}
}
var ieaa *ie.IE = nil
aa, err := far.ApplyAction()
if err == nil {
ieaa = ie.NewApplyAction(aa...)
}
var iefp *ie.IE = nil
fp, err := far.UpdateForwardingParameters()
if err == nil {
iefp = ie.NewForwardingParameters(fp...)
}
f.Add(NewFAR(ie.NewFARID(id), ieaa, iefp))
}
return &f, nil, 0, 0

}

func (m *FARMap) IntoCreateFAR() []*ie.IE {
m.mu.RLock()
defer m.mu.RUnlock()
Expand All @@ -248,17 +199,3 @@ func (m *FARMap) IntoCreateFAR() []*ie.IE {
}
return r
}

func (m *FARMap) IntoUpdateFAR() []*ie.IE {
m.mu.RLock()
defer m.mu.RUnlock()
r := make([]*ie.IE, len(m.farmap))

// _ is farID, which is different from index
i := 0
for _, far := range m.farmap {
r[i] = far.NewUpdateFAR()
i++
}
return r
}
94 changes: 94 additions & 0 deletions pfcp/far_map_update.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
// Copyright Louis Royer and the NextMN contributors. All rights reserved.
// Use of this source code is governed by a MIT-style license that can be
// found in the LICENSE file.
// SPDX-License-Identifier: MIT

package pfcp_networking

import (
"fmt"
"io"
"sync"

"github.com/nextmn/go-pfcp-networking/pfcp/api"

"github.com/wmnsk/go-pfcp/ie"
)

type farmapUpdateInternal = map[api.FARID]api.FARUpdateInterface

type FARMapUpdate struct {
farmap farmapUpdateInternal
mu sync.RWMutex
}

func NewFARMapUpdate(fars []*ie.IE) (*FARMapUpdate, error, uint8, uint16) {
f := FARMapUpdate{
farmap: make(farmapUpdateInternal),
mu: sync.RWMutex{},
}
for _, far := range fars {
id, err := far.FARID()
if err != nil {
switch err {
case io.ErrUnexpectedEOF:
return nil, err, ie.CauseInvalidLength, ie.FARID
case ie.ErrIENotFound:
return nil, err, ie.CauseMandatoryIEMissing, ie.FARID
default:
return nil, err, ie.CauseMandatoryIEIncorrect, ie.CreateFAR
}
}
var ieaa *ie.IE = nil
aa, err := far.ApplyAction()
if err == nil {
ieaa = ie.NewApplyAction(aa...)
}
var iefp *ie.IE = nil
fp, err := far.UpdateForwardingParameters()
if err == nil {
iefp = ie.NewUpdateForwardingParameters(fp...)
}
f.Add(NewFARUpdate(ie.NewFARID(id), ieaa, iefp))
}
return &f, nil, 0, 0

}

func (m *FARMapUpdate) Add(far api.FARUpdateInterface) error {
id, err := far.ID()
if err != nil {
return err
}
m.mu.Lock()
defer m.mu.Unlock()
if _, exists := m.farmap[id]; exists {
return fmt.Errorf("FAR %d already exists.", id)
}
m.farmap[id] = far
return nil
}

func (m *FARMapUpdate) IntoUpdateFAR() []*ie.IE {
m.mu.RLock()
defer m.mu.RUnlock()
r := make([]*ie.IE, len(m.farmap))

// _ is farID, which is different from index
i := 0
for _, far := range m.farmap {
r[i] = far.NewUpdateFAR()
i++
}
return r
}

func (m *FARMapUpdate) Foreach(f func(api.FARUpdateInterface) error) error {
for _, far := range m.farmap {
err := f(far)
if err != nil {
return err
}
}
return nil
}
50 changes: 50 additions & 0 deletions pfcp/far_update.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// Copyright Louis Royer and the NextMN contributors. All rights reserved.
// Use of this source code is governed by a MIT-style license that can be
// found in the LICENSE file.
// SPDX-License-Identifier: MIT

package pfcp_networking

import (
"github.com/nextmn/go-pfcp-networking/pfcp/api"

"github.com/wmnsk/go-pfcp/ie"
)

type FARUpdate struct {
id *ie.IE
applyAction *ie.IE
updateForwardingParameters *ie.IE
}

func NewFARUpdate(id *ie.IE, applyAction *ie.IE, updateForwardingParameters *ie.IE) *FARUpdate {
return &FARUpdate{
id: id,
applyAction: applyAction,
updateForwardingParameters: updateForwardingParameters,
}
}

func (far *FARUpdate) ID() (api.FARID, error) {
return far.id.FARID()
}

func (far *FARUpdate) ApplyAction() *ie.IE {
return far.applyAction
}

func (far *FARUpdate) UpdateForwardingParameters() *ie.IE {
return far.updateForwardingParameters
}

func (far *FARUpdate) NewUpdateFAR() *ie.IE {
ies := make([]*ie.IE, 0)
ies = append(ies, far.id)
if far.applyAction != nil {
ies = append(ies, far.applyAction)
}
if far.updateForwardingParameters != nil {
ies = append(ies, far.updateForwardingParameters)
}
return ie.NewUpdateFAR(ies...)
}
Loading

0 comments on commit c34ba22

Please sign in to comment.