@@ -20,7 +20,7 @@ import (
2020)
2121
2222func TestIntegrationClient (t * testing.T ) {
23- c , done := integrationClient (t )
23+ c , done := integrationClient (t , false )
2424 defer done ()
2525
2626 devices , err := c .Devices ()
@@ -43,6 +43,14 @@ func TestIntegrationClient(t *testing.T) {
4343 name : "configure" ,
4444 fn : testConfigure ,
4545 },
46+ {
47+ name : "remove many IPs" ,
48+ fn : func (t * testing.T , _ * wgctrl.Client , d * wgtypes.Device ) {
49+ c , done := integrationClient (t , true )
50+ defer done ()
51+ testRemoveManyIPs (t , c , d )
52+ },
53+ },
4654 {
4755 name : "configure many IPs" ,
4856 fn : testConfigureManyIPs ,
@@ -91,15 +99,15 @@ func TestIntegrationClient(t *testing.T) {
9199}
92100
93101func TestIntegrationClientIsNotExist (t * testing.T ) {
94- c , done := integrationClient (t )
102+ c , done := integrationClient (t , false )
95103 defer done ()
96104
97105 if _ , err := c .Device ("wgnotexist0" ); ! errors .Is (err , os .ErrNotExist ) {
98106 t .Fatalf ("expected is not exist error, but got: %v" , err )
99107 }
100108}
101109
102- func integrationClient (t * testing.T ) (* wgctrl.Client , func ()) {
110+ func integrationClient (t * testing.T , useShim bool ) (* wgctrl.Client , func ()) {
103111 t .Helper ()
104112
105113 const (
@@ -112,7 +120,12 @@ func integrationClient(t *testing.T) (*wgctrl.Client, func()) {
112120 env , confirm )
113121 }
114122
115- c , err := wgctrl .New ()
123+ var opts []wgctrl.Option
124+ if useShim {
125+ opts = append (opts , wgctrl .WithShim )
126+ }
127+
128+ c , err := wgctrl .New (opts ... )
116129 if err != nil {
117130 if errors .Is (err , os .ErrNotExist ) {
118131 t .Skip ("skipping, wgctrl is not available on this system" )
@@ -223,6 +236,95 @@ func testConfigure(t *testing.T, c *wgctrl.Client, d *wgtypes.Device) {
223236 t .Log (out )
224237}
225238
239+ func testRemoveManyIPs (t * testing.T , c * wgctrl.Client , d * wgtypes.Device ) {
240+ // Apply 511 IPs per peer.
241+ var (
242+ countIPs int
243+ peers []wgtypes.PeerConfig
244+ peersRemoveIPs []wgtypes.PeerConfig
245+ )
246+
247+ for i := 0 ; i < 2 ; i ++ {
248+ cidr := "2001:db8::/119"
249+ if i == 1 {
250+ cidr = "2001:db8:ffff::/119"
251+ }
252+
253+ cur , err := ipaddr .Parse (cidr )
254+ if err != nil {
255+ t .Fatalf ("failed to create cursor: %v" , err )
256+ }
257+
258+ var ips []net.IPNet
259+ for pos := cur .Next (); pos != nil ; pos = cur .Next () {
260+ bits := 128
261+ if pos .IP .To4 () != nil {
262+ bits = 32
263+ }
264+
265+ ips = append (ips , net.IPNet {
266+ IP : pos .IP ,
267+ Mask : net .CIDRMask (bits , bits ),
268+ })
269+ }
270+
271+ peers = append (peers , wgtypes.PeerConfig {
272+ PublicKey : wgtest .MustPublicKey (),
273+ ReplaceAllowedIPs : true ,
274+ AllowedIPs : ipsToAllowedIPConfig (ips ),
275+ })
276+
277+ peersRemoveIPs = append (peersRemoveIPs , wgtypes.PeerConfig {
278+ PublicKey : wgtest .MustPublicKey (),
279+ ReplaceAllowedIPs : true ,
280+ AllowedIPs : ipsToAllowedIPConfig (ips ),
281+ })
282+
283+ // Remove every other IP
284+ for i := range peersRemoveIPs [len (peersRemoveIPs )- 1 ].AllowedIPs {
285+ peersRemoveIPs [len (peersRemoveIPs )- 1 ].AllowedIPs [i ].Remove = i % 2 == 0
286+ }
287+
288+ countIPs += len (ips )
289+ }
290+
291+ cfg := wgtypes.Config {
292+ ReplacePeers : true ,
293+ Peers : peers ,
294+ }
295+ removeCfg := wgtypes.Config {
296+ Peers : peersRemoveIPs ,
297+ }
298+
299+ tryConfigure (t , c , d .Name , cfg )
300+
301+ dn , err := c .Device (d .Name )
302+ if err != nil {
303+ t .Fatalf ("failed to get %q by name: %v" , d .Name , err )
304+ }
305+
306+ peerIPs := countPeerIPs (dn )
307+ if diff := cmp .Diff (countIPs , peerIPs ); diff != "" {
308+ t .Fatalf ("unexpected number of configured peer IPs (-want +got):\n %s" , diff )
309+ }
310+
311+ t .Logf ("device: %s: %d IPs" , d .Name , peerIPs )
312+
313+ tryConfigure (t , c , d .Name , removeCfg )
314+
315+ dn , err = c .Device (d .Name )
316+ if err != nil {
317+ t .Fatalf ("failed to get %q by name: %v" , d .Name , err )
318+ }
319+
320+ peerIPs = countPeerIPs (dn )
321+ if diff := cmp .Diff (countIPs / 2 - 1 , peerIPs ); diff != "" {
322+ t .Fatalf ("unexpected number of configured peer IPs (-want +got):\n %s" , diff )
323+ }
324+
325+ t .Logf ("device: %s: %d IPs after remove" , d .Name , peerIPs )
326+ }
327+
226328func testConfigureManyIPs (t * testing.T , c * wgctrl.Client , d * wgtypes.Device ) {
227329 // Apply 511 IPs per peer.
228330 var (
0 commit comments