@@ -12,6 +12,7 @@ import (
12
12
"fmt"
13
13
"net/http"
14
14
"net/netip"
15
+ "net/url"
15
16
"sync"
16
17
17
18
pfcp_networking "github.com/nextmn/go-pfcp-networking/pfcp"
@@ -36,11 +37,18 @@ type RulesPusher struct {
36
37
}
37
38
38
39
type ueInfos struct {
40
+ sync.Mutex
41
+
39
42
UplinkFTeid jsonapi.Fteid
40
43
DownlinkTeid uint32
41
44
Gnb string
42
45
Pushed bool
43
- sync.Mutex
46
+
47
+ AnchorsRules []* url.URL
48
+ AnchorsLock sync.Mutex
49
+
50
+ SRGWRules []* url.URL
51
+ SRGWLock sync.Mutex
44
52
}
45
53
46
54
func NewRulesPusher (config * config.CtrlConfig ) * RulesPusher {
@@ -51,32 +59,35 @@ func NewRulesPusher(config *config.CtrlConfig) *RulesPusher {
51
59
}
52
60
}
53
61
54
- func (pusher * RulesPusher ) pushSingleRule (ctx context.Context , client http.Client , uri jsonapi.ControlURI , data []byte ) error {
62
+ func (pusher * RulesPusher ) pushSingleRule (ctx context.Context , client http.Client , uri jsonapi.ControlURI , data []byte ) ( * url. URL , error ) {
55
63
req , err := http .NewRequestWithContext (ctx , http .MethodPost , uri .JoinPath ("rules" ).String (), bytes .NewBuffer (data ))
56
64
if err != nil {
57
65
logrus .WithError (err ).Error ("could not create http request" )
58
- return err
66
+ return nil , err
59
67
}
60
68
req .Header .Add ("User-Agent" , UserAgent )
61
69
req .Header .Set ("Content-Type" , "application/json; charset=UTF-8" )
62
70
resp , err := client .Do (req )
63
71
if err != nil {
64
72
logrus .WithError (err ).Error ("Could not push rules: server not responding" )
65
- return fmt .Errorf ("Could not push rules: server not responding" )
73
+ return nil , fmt .Errorf ("Could not push rules: server not responding" )
66
74
}
67
75
defer resp .Body .Close ()
68
76
if resp .StatusCode == 400 {
69
77
logrus .WithError (err ).Error ("HTTP Bad Request" )
70
- return fmt .Errorf ("HTTP Bad request" )
78
+ return nil , fmt .Errorf ("HTTP Bad request" )
71
79
} else if resp .StatusCode >= 500 {
72
80
logrus .WithError (err ).Error ("HTTP internal error" )
73
- return fmt .Errorf ("HTTP internal error" )
81
+ return nil , fmt .Errorf ("HTTP internal error" )
82
+ } else if resp .StatusCode == 201 {
83
+ loc := resp .Header .Get ("Location" )
84
+ uloc , err := url .Parse (loc )
85
+ if err != nil {
86
+ return nil , err
87
+ }
88
+ return uri .ResolveReference (uloc ), nil
74
89
}
75
- //else if resp.StatusCode == 201{
76
- //OK: store resource
77
- //_ := resp.Header.Get("Location")
78
- //}
79
- return nil
90
+ return nil , fmt .Errorf ("No Location provided" )
80
91
}
81
92
82
93
func (pusher * RulesPusher ) pushRTRRule (ctx context.Context , ue_ip string ) error {
@@ -148,7 +159,13 @@ func (pusher *RulesPusher) pushRTRRule(ctx context.Context, ue_ip string) error
148
159
wg .Add (1 )
149
160
go func () error {
150
161
defer wg .Done ()
151
- return pusher .pushSingleRule (ctx , client , r .ControlURI , rule_json )
162
+ infos .SRGWLock .Lock ()
163
+ defer infos .SRGWLock .Unlock ()
164
+ url , err := pusher .pushSingleRule (ctx , client , r .ControlURI , rule_json )
165
+ if err == nil {
166
+ infos .SRGWRules = append (infos .SRGWRules , url )
167
+ }
168
+ return err
152
169
}()
153
170
154
171
}
@@ -202,7 +219,13 @@ func (pusher *RulesPusher) pushRTRRule(ctx context.Context, ue_ip string) error
202
219
wg .Add (1 )
203
220
go func () error {
204
221
defer wg .Done ()
205
- return pusher .pushSingleRule (ctx , client , r .ControlURI , rule_json )
222
+ infos .AnchorsLock .Lock ()
223
+ defer infos .AnchorsLock .Unlock ()
224
+ url , err := pusher .pushSingleRule (ctx , client , r .ControlURI , rule_json )
225
+ if err == nil {
226
+ infos .AnchorsRules = append (infos .AnchorsRules , url )
227
+ }
228
+ return err
206
229
}()
207
230
208
231
}
@@ -295,7 +318,7 @@ func (pusher *RulesPusher) updateRoutersRules(ctx context.Context, msgType pfcpu
295
318
logrus .WithFields (logrus.Fields {
296
319
"farid" : farid ,
297
320
"pdrid" : pdrid ,
298
- "ue" : ue ,
321
+ "ue" : ue . IPv4Address . String () ,
299
322
}).Debug ("UE identified for handover" )
300
323
pusher .pushHandover (ctx , ue .IPv4Address .String (), handoverTo )
301
324
handoverDone = true
@@ -345,7 +368,9 @@ func (pusher *RulesPusher) updateRoutersRules(ctx context.Context, msgType pfcpu
345
368
return nil
346
369
}
347
370
if ue , loaded := pusher .ues .LoadOrStore (ue_ipv4 , & ueInfos {
348
- UplinkFTeid : jsonapi.Fteid {Teid : fteid .TEID , Addr : addr },
371
+ UplinkFTeid : jsonapi.Fteid {Teid : fteid .TEID , Addr : addr },
372
+ AnchorsRules : make ([]* url.URL , 0 ),
373
+ SRGWRules : make ([]* url.URL , 0 ),
349
374
}); loaded {
350
375
logrus .WithFields (logrus.Fields {
351
376
"teid-uplink" : fteid .TEID ,
@@ -380,6 +405,8 @@ func (pusher *RulesPusher) updateRoutersRules(ctx context.Context, msgType pfcpu
380
405
if ue , loaded := pusher .ues .LoadOrStore (ue_ipv4 , & ueInfos {
381
406
DownlinkTeid : teid_downlink ,
382
407
Gnb : gnb_ipv4 ,
408
+ AnchorsRules : make ([]* url.URL , 0 ),
409
+ SRGWRules : make ([]* url.URL , 0 ),
383
410
}); loaded {
384
411
logrus .WithFields (logrus.Fields {
385
412
"gnb-ipv4" : gnb_ipv4 ,
0 commit comments