@@ -24,6 +24,7 @@ import (
24
24
25
25
"github.com/sirupsen/logrus"
26
26
"github.com/wmnsk/go-pfcp/ie"
27
+ "github.com/wmnsk/go-pfcp/message"
27
28
)
28
29
29
30
const UserAgent = "go-github-nextmn-srv6-ctrl"
@@ -209,8 +210,104 @@ func (pusher *RulesPusher) pushRTRRule(ctx context.Context, ue_ip string) error
209
210
return nil
210
211
}
211
212
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 ) {
213
219
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
+ }
214
311
var wg0 sync.WaitGroup
215
312
for _ , session := range e .GetPFCPSessions () {
216
313
logrus .Trace ("In for loop…" )
0 commit comments