@@ -12,6 +12,7 @@ import (
1212 "fmt"
1313 "net/http"
1414 "net/netip"
15+ "net/url"
1516 "sync"
1617
1718 pfcp_networking "github.com/nextmn/go-pfcp-networking/pfcp"
@@ -36,11 +37,18 @@ type RulesPusher struct {
3637}
3738
3839type ueInfos struct {
40+ sync.Mutex
41+
3942 UplinkFTeid jsonapi.Fteid
4043 DownlinkTeid uint32
4144 Gnb string
4245 Pushed bool
43- sync.Mutex
46+
47+ AnchorsRules []* url.URL
48+ AnchorsLock sync.Mutex
49+
50+ SRGWRules []* url.URL
51+ SRGWLock sync.Mutex
4452}
4553
4654func NewRulesPusher (config * config.CtrlConfig ) * RulesPusher {
@@ -51,32 +59,35 @@ func NewRulesPusher(config *config.CtrlConfig) *RulesPusher {
5159 }
5260}
5361
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 ) {
5563 req , err := http .NewRequestWithContext (ctx , http .MethodPost , uri .JoinPath ("rules" ).String (), bytes .NewBuffer (data ))
5664 if err != nil {
5765 logrus .WithError (err ).Error ("could not create http request" )
58- return err
66+ return nil , err
5967 }
6068 req .Header .Add ("User-Agent" , UserAgent )
6169 req .Header .Set ("Content-Type" , "application/json; charset=UTF-8" )
6270 resp , err := client .Do (req )
6371 if err != nil {
6472 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" )
6674 }
6775 defer resp .Body .Close ()
6876 if resp .StatusCode == 400 {
6977 logrus .WithError (err ).Error ("HTTP Bad Request" )
70- return fmt .Errorf ("HTTP Bad request" )
78+ return nil , fmt .Errorf ("HTTP Bad request" )
7179 } else if resp .StatusCode >= 500 {
7280 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
7489 }
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" )
8091}
8192
8293func (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
148159 wg .Add (1 )
149160 go func () error {
150161 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
152169 }()
153170
154171 }
@@ -202,7 +219,13 @@ func (pusher *RulesPusher) pushRTRRule(ctx context.Context, ue_ip string) error
202219 wg .Add (1 )
203220 go func () error {
204221 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
206229 }()
207230
208231 }
@@ -295,7 +318,7 @@ func (pusher *RulesPusher) updateRoutersRules(ctx context.Context, msgType pfcpu
295318 logrus .WithFields (logrus.Fields {
296319 "farid" : farid ,
297320 "pdrid" : pdrid ,
298- "ue" : ue ,
321+ "ue" : ue . IPv4Address . String () ,
299322 }).Debug ("UE identified for handover" )
300323 pusher .pushHandover (ctx , ue .IPv4Address .String (), handoverTo )
301324 handoverDone = true
@@ -345,7 +368,9 @@ func (pusher *RulesPusher) updateRoutersRules(ctx context.Context, msgType pfcpu
345368 return nil
346369 }
347370 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 ),
349374 }); loaded {
350375 logrus .WithFields (logrus.Fields {
351376 "teid-uplink" : fteid .TEID ,
@@ -380,6 +405,8 @@ func (pusher *RulesPusher) updateRoutersRules(ctx context.Context, msgType pfcpu
380405 if ue , loaded := pusher .ues .LoadOrStore (ue_ipv4 , & ueInfos {
381406 DownlinkTeid : teid_downlink ,
382407 Gnb : gnb_ipv4 ,
408+ AnchorsRules : make ([]* url.URL , 0 ),
409+ SRGWRules : make ([]* url.URL , 0 ),
383410 }); loaded {
384411 logrus .WithFields (logrus.Fields {
385412 "gnb-ipv4" : gnb_ipv4 ,
0 commit comments