9
9
"os"
10
10
"path/filepath"
11
11
"slices"
12
+ "strings"
12
13
"time"
13
14
14
15
"github.com/blang/semver"
@@ -20,13 +21,15 @@ import (
20
21
localPkg "github.com/threefoldtech/zosbase/pkg"
21
22
"github.com/threefoldtech/zosbase/pkg/cache"
22
23
"github.com/threefoldtech/zosbase/pkg/gridtypes/zos"
24
+ "github.com/threefoldtech/zosbase/pkg/netbase/wireguard"
23
25
"github.com/threefoldtech/zosbase/pkg/netlight/bridge"
24
26
"github.com/threefoldtech/zosbase/pkg/netlight/ifaceutil"
25
27
"github.com/threefoldtech/zosbase/pkg/netlight/ipam"
26
28
"github.com/threefoldtech/zosbase/pkg/netlight/namespace"
27
29
"github.com/threefoldtech/zosbase/pkg/netlight/options"
28
30
"github.com/threefoldtech/zosbase/pkg/netlight/public"
29
31
"github.com/threefoldtech/zosbase/pkg/netlight/resource"
32
+ "github.com/threefoldtech/zosbase/pkg/set"
30
33
"github.com/threefoldtech/zosbase/pkg/versioned"
31
34
"github.com/vishvananda/netlink"
32
35
)
@@ -50,6 +53,7 @@ var NetworkSchemaLatestVersion = semver.MustParse("0.1.0")
50
53
type networker struct {
51
54
ipamLease string
52
55
networkDir string
56
+ portSet * set.UIntSet
53
57
}
54
58
55
59
var _ localPkg.NetworkerLight = (* networker )(nil )
@@ -63,13 +67,19 @@ func NewNetworker() (localPkg.NetworkerLight, error) {
63
67
ipamLease := filepath .Join (vd , ipamLeaseDir )
64
68
runtimeDir := filepath .Join (vd , networkDir )
65
69
66
- return & networker {
70
+ n := networker {
67
71
ipamLease : ipamLease ,
68
72
networkDir : runtimeDir ,
69
- }, nil
73
+ portSet : set .NewInt (),
74
+ }
75
+
76
+ if err := n .syncWGPorts (); err != nil {
77
+ return nil , err
78
+ }
79
+ return & n , nil
70
80
}
71
81
72
- func (n * networker ) Create (name string , privateNet net. IPNet , seed []byte ) error {
82
+ func (n * networker ) Create (name string , net zos. NetworkLight , seed []byte ) error {
73
83
b , err := bridge .Get (NDMZBridge )
74
84
if err != nil {
75
85
return err
@@ -79,7 +89,68 @@ func (n *networker) Create(name string, privateNet net.IPNet, seed []byte) error
79
89
return err
80
90
}
81
91
82
- _ , err = resource .Create (name , b , ip , NDMZGwIP , & privateNet , seed )
92
+ storedNR , err := n .networkOf (zos .NetID (name ))
93
+ if err != nil && ! os .IsNotExist (err ) {
94
+ return errors .Wrap (err , "failed to load previous network setup" )
95
+ }
96
+
97
+ if err == nil {
98
+ if err := n .releasePort (storedNR .WGListenPort ); err != nil {
99
+ return err
100
+ }
101
+ }
102
+
103
+ if err := n .reservePort (net .WGListenPort ); err != nil {
104
+ return err
105
+ }
106
+
107
+ // _, err = resource.Create(name, b, ip, NDMZGwIP, &privateNet, seed)
108
+ netr , err := resource .Create (name , b , ip , NDMZGwIP , & net .Subnet .IPNet , seed , net )
109
+ // netr, err := resource.Create(name, b, ip, NDMZGwIP, &net.Subnet.IPNet, net.Mycelium.Key, net.NetworkIPRange.IPNet, net)
110
+ if err != nil {
111
+ return err
112
+ }
113
+
114
+ cleanup := func () {
115
+ log .Error ().Msg ("clean up network resource" )
116
+ if err := resource .Delete (name ); err != nil {
117
+ log .Error ().Err (err ).Msg ("error during deletion of network resource after failed deployment" )
118
+ }
119
+ if err := n .releasePort (net .WGListenPort ); err != nil {
120
+ log .Error ().Err (err ).Msg ("release wireguard port failed" )
121
+ }
122
+ }
123
+
124
+ defer func () {
125
+ if err != nil {
126
+ cleanup ()
127
+ }
128
+ }()
129
+
130
+ wgName , err := netr .WGName ()
131
+ if err != nil {
132
+ return errors .Wrap (err , "failed to get wg interface name for network resource" )
133
+ }
134
+
135
+ exists , err := netr .HasWireguard ()
136
+ if err != nil {
137
+ return errors .Wrap (err , "failed to check if network resource has wireguard setup" )
138
+ }
139
+
140
+ if ! exists {
141
+ var wg * wireguard.Wireguard
142
+ wg , err = wireguard .New (wgName )
143
+ if err != nil {
144
+ return errors .Wrapf (err , "failed to create wg interface for network resource '%s'" , name )
145
+ }
146
+ if err = netr .SetWireguard (wg ); err != nil {
147
+ return errors .Wrap (err , "failed to setup wireguard interface for network resource" )
148
+ }
149
+ }
150
+
151
+ if err = netr .ConfigureWG (net .WGPrivateKey ); err != nil {
152
+ return errors .Wrap (err , "failed to configure network resource" )
153
+ }
83
154
return err
84
155
}
85
156
@@ -462,3 +533,72 @@ func createNDMZBridge(name string, gw string) (*netlink.Bridge, error) {
462
533
463
534
return link .(* netlink.Bridge ), nil
464
535
}
536
+
537
+ func (n * networker ) WireguardPorts () ([]uint , error ) {
538
+ return n .portSet .List ()
539
+ }
540
+
541
+ func (n * networker ) syncWGPorts () error {
542
+ names , err := namespace .List ("n-" )
543
+ if err != nil {
544
+ return err
545
+ }
546
+
547
+ readPort := func (name string ) (int , error ) {
548
+ netNS , err := namespace .GetByName (name )
549
+ if err != nil {
550
+ return 0 , err
551
+ }
552
+ defer netNS .Close ()
553
+
554
+ ifaceName := strings .Replace (name , "n-" , "w-" , 1 )
555
+
556
+ var port int
557
+ err = netNS .Do (func (_ ns.NetNS ) error {
558
+ link , err := wireguard .GetByName (ifaceName )
559
+ if err != nil {
560
+ return err
561
+ }
562
+ d , err := link .Device ()
563
+ if err != nil {
564
+ return err
565
+ }
566
+
567
+ port = d .ListenPort
568
+ return nil
569
+ })
570
+ if err != nil {
571
+ return 0 , err
572
+ }
573
+
574
+ return port , nil
575
+ }
576
+
577
+ for _ , name := range names {
578
+ port , err := readPort (name )
579
+ if err != nil {
580
+ log .Error ().Err (err ).Str ("namespace" , name ).Msgf ("failed to read port for network namespace" )
581
+ continue
582
+ }
583
+ // skip error cause we don't care if there are some duplicate at this point
584
+ _ = n .portSet .Add (uint (port ))
585
+ }
586
+
587
+ return nil
588
+ }
589
+
590
+ func (n * networker ) reservePort (port uint16 ) error {
591
+ log .Debug ().Uint16 ("port" , port ).Msg ("reserve wireguard port" )
592
+ err := n .portSet .Add (uint (port ))
593
+ if err != nil {
594
+ return errors .Wrap (err , "wireguard listen port already in use, pick another one" )
595
+ }
596
+
597
+ return nil
598
+ }
599
+
600
+ func (n * networker ) releasePort (port uint16 ) error {
601
+ log .Debug ().Uint16 ("port" , port ).Msg ("release wireguard port" )
602
+ n .portSet .Remove (uint (port ))
603
+ return nil
604
+ }
0 commit comments