Skip to content

Commit 9b071a0

Browse files
committed
[wip] Handover srv6
1 parent d0b44e3 commit 9b071a0

File tree

1 file changed

+98
-1
lines changed

1 file changed

+98
-1
lines changed

internal/app/rules-pusher.go

Lines changed: 98 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import (
2424

2525
"github.com/sirupsen/logrus"
2626
"github.com/wmnsk/go-pfcp/ie"
27+
"github.com/wmnsk/go-pfcp/message"
2728
)
2829

2930
const UserAgent = "go-github-nextmn-srv6-ctrl"
@@ -209,8 +210,104 @@ func (pusher *RulesPusher) pushRTRRule(ctx context.Context, ue_ip string) error
209210
return nil
210211
}
211212

212-
func (pusher *RulesPusher) updateRoutersRules(ctx context.Context, msgType pfcputil.MessageType, message pfcp_networking.ReceivedMessage, e *pfcp_networking.PFCPEntityUP) {
213+
func (pusher *RulesPusher) pushHandover(ctx context.Context, ue string, handoverTo jsonapi.Fteid) {
214+
//TODO Handover
215+
216+
}
217+
218+
func (pusher *RulesPusher) updateRoutersRules(ctx context.Context, msgType pfcputil.MessageType, msg pfcp_networking.ReceivedMessage, e *pfcp_networking.PFCPEntityUP) {
213219
logrus.Debug("Into updateRoutersRules")
220+
if msgType == message.MsgTypeSessionModificationRequest {
221+
logrus.Debug("session modification request")
222+
// check if handover
223+
msgMod, ok := msg.Message.(*message.SessionModificationRequest)
224+
if !ok {
225+
logrus.Error("could not cast to sessionModifationRequest")
226+
return
227+
}
228+
logrus.Debug("checking session modification request for handover")
229+
if (len(msgMod.CreatePDR) == 0) && (len(msgMod.UpdatePDR) == 0) && (len(msgMod.CreateFAR) == 0) && (len(msgMod.UpdateFAR) == 1) {
230+
// this is only a far update, so it is probably an handover…
231+
updateFpIes, err := msgMod.UpdateFAR[0].UpdateForwardingParameters()
232+
if err != nil {
233+
logrus.WithError(err).Debug("No Update Forwarding parameters: not a valid handover")
234+
return
235+
}
236+
updateFp := ie.NewUpdateForwardingParameters(updateFpIes...)
237+
238+
if dest_interface, err := updateFp.DestinationInterface(); err != nil {
239+
logrus.Debug("No destination interface: not a valid handover")
240+
return
241+
} else if dest_interface != ie.DstInterfaceAccess {
242+
logrus.Debug("Destination interface is not access: not a valid handover")
243+
return
244+
}
245+
farid, err := msgMod.UpdateFAR[0].FARID()
246+
if err != nil {
247+
logrus.Debug("No FARID: not a valid handover")
248+
return
249+
}
250+
logrus.WithFields(logrus.Fields{
251+
"farid": farid,
252+
}).Debug("handover detected")
253+
254+
ohc, err := updateFp.OuterHeaderCreation()
255+
if err != nil {
256+
return
257+
}
258+
addr, ok := netip.AddrFromSlice(ohc.IPv4Address.To4())
259+
if !ok {
260+
return
261+
}
262+
handoverTo := jsonapi.Fteid{
263+
Teid: ohc.TEID,
264+
Addr: addr,
265+
}
266+
267+
handoverDone := false
268+
// looking for a pdr with this farid to find ue ip address
269+
for _, session := range e.GetPFCPSessions() {
270+
if handoverDone {
271+
break
272+
}
273+
s := make(chan struct{})
274+
go func() { // in a goroutine to trigger the defer
275+
session.RLock()
276+
defer session.RUnlock()
277+
session.ForeachUnsortedPDR(func(pdr pfcpapi.PDRInterface) error {
278+
id, err := pdr.FARID()
279+
if err != nil {
280+
// skip
281+
return nil
282+
}
283+
if id != farid {
284+
// skip
285+
return nil
286+
}
287+
pdrid, err := pdr.ID()
288+
if err != nil {
289+
return nil
290+
}
291+
ue, err := pdr.UEIPAddress()
292+
if err != nil {
293+
return nil
294+
}
295+
logrus.WithFields(logrus.Fields{
296+
"farid": farid,
297+
"pdrid": pdrid,
298+
"ue": ue,
299+
}).Debug("UE identified for handover")
300+
pusher.pushHandover(ctx, ue.IPv4Address.String(), handoverTo)
301+
handoverDone = true
302+
return nil
303+
})
304+
s <- struct{}{}
305+
}()
306+
<-s
307+
}
308+
return
309+
}
310+
}
214311
var wg0 sync.WaitGroup
215312
for _, session := range e.GetPFCPSessions() {
216313
logrus.Trace("In for loop…")

0 commit comments

Comments
 (0)