@@ -390,33 +390,38 @@ func createFakeInternet(t *testing.T) fakeInternet {
390
390
}
391
391
392
392
type TriangleNetwork struct {
393
- InterClientMTU int
393
+ Client1MTU int
394
394
}
395
395
396
396
type fakeTriangleNetwork struct {
397
- NamePrefix string
398
- ServerNetNS * os.File
399
- Client1NetNS * os.File
400
- Client2NetNS * os.File
401
- ServerClient1VethPair vethPair
402
- ServerClient2VethPair vethPair
403
- Client1Client2VethPair vethPair
397
+ NamePrefix string
398
+ ServerNetNS * os.File
399
+ Client1NetNS * os.File
400
+ Client2NetNS * os.File
401
+ RouterNetNS * os.File
402
+ ServerVethPair vethPair
403
+ Client1VethPair vethPair
404
+ Client2VethPair vethPair
404
405
}
405
406
406
- // SetupNetworking creates multiple namespaces with veth pairs between them
407
- // with the following topology:
407
+ // SetupNetworking creates multiple namespaces with a central router in the following topology
408
408
// .
409
- // . ┌────────────────────────────────────────────┐
410
- // . │ Server │
411
- // . └─────┬───────────────────────────────────┬──┘
412
- // . │fdac:38fa:ffff:2::3 │fdac:38fa:ffff:3::3
413
- // . veth│ veth│
414
- // . │fdac:38fa:ffff:2::1 │fdac:38fa:ffff:3::2
415
- // . ┌───────┴──────┐ ┌─────┴───────┐
416
- // . │ │ fdac:38fa:ffff:1::2│ │
417
- // . │ Client 1 ├──────────────────────┤ Client 2 │
418
- // . │ │fdac:38fa:ffff:1::1 │ │
419
- // . └──────────────┘ └─────────────┘
409
+ // . ┌──────────────┐
410
+ // . │ │
411
+ // . │ Server ├─────────────────────────────────────┐
412
+ // . │ │fdac:38fa:ffff:3::2 │
413
+ // . └──────────────┘ │ fdac:38fa:ffff:3::1
414
+ // . ┌──────────────┐ ┌─────┴───────┐
415
+ // . │ │ fdac:38fa:ffff:1::1│ │
416
+ // . │ Client 1 ├───────────────────────────────┤ Router │
417
+ // . │ │fdac:38fa:ffff:1::2 │ │
418
+ // . └──────────────┘ └─────┬───────┘
419
+ // . ┌──────────────┐ │ fdac:38fa:ffff:2::1
420
+ // . │ │ │
421
+ // . │ Client 2 ├─────────────────────────────────────┘
422
+ // . │ │fdac:38fa:ffff:2::2
423
+ // . └──────────────┘
424
+ // The veth link between Client 1 and the router has a configurable MTU via Client1MTU.
420
425
func (n TriangleNetwork )SetupNetworking (t * testing.T ,l slog.Logger )TestNetworking {
421
426
logger := l .Named ("setup-networking" ).Leveled (slog .LevelDebug )
422
427
t .Helper ()
@@ -433,101 +438,109 @@ func (n TriangleNetwork) SetupNetworking(t *testing.T, l slog.Logger) TestNetwor
433
438
network .ServerNetNS = createNetNS (t ,namePrefix + "server" )
434
439
network .Client1NetNS = createNetNS (t ,namePrefix + "client1" )
435
440
network .Client2NetNS = createNetNS (t ,namePrefix + "client2" )
441
+ network .RouterNetNS = createNetNS (t ,namePrefix + "router" )
436
442
437
- // Create veth pair between server andclient1
438
- network .ServerClient1VethPair = vethPair {
439
- Outer :namePrefix + "s-1 " ,
440
- Inner :namePrefix + "1 -s" ,
443
+ // Create veth pair between server androuter
444
+ network .ServerVethPair = vethPair {
445
+ Outer :namePrefix + "s-r " ,
446
+ Inner :namePrefix + "r -s" ,
441
447
}
442
- err := createVethPair (network .ServerClient1VethPair .Outer ,network .ServerClient1VethPair .Inner )
448
+ err := createVethPair (network .ServerVethPair .Outer ,network .ServerVethPair .Inner )
443
449
require .NoErrorf (t ,err ,"create veth pair %q <-> %q" ,
444
- network .ServerClient1VethPair .Outer ,network .ServerClient1VethPair .Inner )
450
+ network .ServerVethPair .Outer ,network .ServerVethPair .Inner )
445
451
446
- // Move server-client1 veth ends to their respective namespaces
447
- err = setVethNetNS (network .ServerClient1VethPair .Outer ,int (network .ServerNetNS .Fd ()))
448
- require .NoErrorf (t ,err ,"set veth %q to server NetNS" ,network .ServerClient1VethPair .Outer )
449
- err = setVethNetNS (network .ServerClient1VethPair .Inner ,int (network .Client1NetNS .Fd ()))
450
- require .NoErrorf (t ,err ,"set veth %q toclient1 NetNS" ,network .ServerClient1VethPair .Inner )
452
+ // Move server-router veth ends to their respective namespaces
453
+ err = setVethNetNS (network .ServerVethPair .Outer ,int (network .ServerNetNS .Fd ()))
454
+ require .NoErrorf (t ,err ,"set veth %q to server NetNS" ,network .ServerVethPair .Outer )
455
+ err = setVethNetNS (network .ServerVethPair .Inner ,int (network .RouterNetNS .Fd ()))
456
+ require .NoErrorf (t ,err ,"set veth %q torouter NetNS" ,network .ServerVethPair .Inner )
451
457
452
- // Create veth pair betweenserver andclient2
453
- network .ServerClient2VethPair = vethPair {
454
- Outer :namePrefix + "s-2 " ,
455
- Inner :namePrefix + "2-s " ,
458
+ // Create veth pair betweenclient1 androuter
459
+ network .Client1VethPair = vethPair {
460
+ Outer :namePrefix + "1-r " ,
461
+ Inner :namePrefix + "r-1 " ,
456
462
}
457
- err = createVethPair (network .ServerClient2VethPair .Outer ,network .ServerClient2VethPair .Inner )
463
+ logger .Debug (context .Background (),"creating client1 link" ,slog .F ("mtu" ,n .Client1MTU ))
464
+ err = createVethPair (network .Client1VethPair .Outer ,network .Client1VethPair .Inner ,withMTU (n .Client1MTU ))
458
465
require .NoErrorf (t ,err ,"create veth pair %q <-> %q" ,
459
- network .ServerClient2VethPair .Outer ,network .ServerClient2VethPair .Inner )
466
+ network .Client1VethPair .Outer ,network .Client1VethPair .Inner )
460
467
461
- // Moveserver-client2 veth ends to their respective namespaces
462
- err = setVethNetNS (network .ServerClient2VethPair .Outer ,int (network .ServerNetNS .Fd ()))
463
- require .NoErrorf (t ,err ,"set veth %q to server NetNS" ,network .ServerClient2VethPair .Outer )
464
- err = setVethNetNS (network .ServerClient2VethPair .Inner ,int (network .Client2NetNS .Fd ()))
465
- require .NoErrorf (t ,err ,"set veth %q to client2 NetNS" ,network .ServerClient2VethPair .Inner )
468
+ // Moveclient1-router veth ends to their respective namespaces
469
+ err = setVethNetNS (network .Client1VethPair .Outer ,int (network .Client1NetNS .Fd ()))
470
+ require .NoErrorf (t ,err ,"set veth %q to server NetNS" ,network .Client1VethPair .Outer )
471
+ err = setVethNetNS (network .Client1VethPair .Inner ,int (network .RouterNetNS .Fd ()))
472
+ require .NoErrorf (t ,err ,"set veth %q to client2 NetNS" ,network .Client1VethPair .Inner )
466
473
467
474
// Create veth pair between client1 and client2
468
- network .Client1Client2VethPair = vethPair {
469
- Outer :namePrefix + "1-2 " ,
470
- Inner :namePrefix + "2-1 " ,
475
+ network .Client2VethPair = vethPair {
476
+ Outer :namePrefix + "2-r " ,
477
+ Inner :namePrefix + "r-2 " ,
471
478
}
472
- logger .Debug (context .Background (),"creating inter-client link" ,slog .F ("mtu" ,n .InterClientMTU ))
473
- err = createVethPair (network .Client1Client2VethPair .Outer ,network .Client1Client2VethPair .Inner ,
474
- withMTU (n .InterClientMTU ))
479
+
480
+ err = createVethPair (network .Client2VethPair .Outer ,network .Client2VethPair .Inner )
475
481
require .NoErrorf (t ,err ,"create veth pair %q <-> %q" ,
476
- network .Client1Client2VethPair .Outer ,network .Client1Client2VethPair .Inner )
482
+ network .Client2VethPair .Outer ,network .Client2VethPair .Inner )
477
483
478
484
// Move client1-client2 veth ends to their respective namespaces
479
- err = setVethNetNS (network .Client1Client2VethPair .Outer ,int (network .Client1NetNS .Fd ()))
480
- require .NoErrorf (t ,err ,"set veth %q to client1 NetNS" ,network .Client1Client2VethPair .Outer )
481
- err = setVethNetNS (network .Client1Client2VethPair .Inner ,int (network .Client2NetNS .Fd ()))
482
- require .NoErrorf (t ,err ,"set veth %q to client2 NetNS" ,network .Client1Client2VethPair .Inner )
485
+ err = setVethNetNS (network .Client2VethPair .Outer ,int (network .Client2NetNS .Fd ()))
486
+ require .NoErrorf (t ,err ,"set veth %q to client1 NetNS" ,network .Client2VethPair .Outer )
487
+ err = setVethNetNS (network .Client2VethPair .Inner ,int (network .RouterNetNS .Fd ()))
488
+ require .NoErrorf (t ,err ,"set veth %q to client2 NetNS" ,network .Client2VethPair .Inner )
483
489
484
490
// Set IP addresses according to the diagram:
485
- err = setInterfaceIP6 (network .ServerNetNS ,network .ServerClient1VethPair .Outer ,ula + "2::3" )
486
- require .NoErrorf (t ,err ,"set IP on server-client1 interface" )
487
- err = setInterfaceIP6 (network .ServerNetNS ,network .ServerClient2VethPair .Outer ,ula + "3::3" )
488
- require .NoErrorf (t ,err ,"set IP on server-client2 interface" )
489
-
490
- err = setInterfaceIP6 (network .Client1NetNS ,network .ServerClient1VethPair .Inner ,ula + "2::1" )
491
- require .NoErrorf (t ,err ,"set IP on client1-server interface" )
492
- err = setInterfaceIP6 (network .Client1NetNS ,network .Client1Client2VethPair .Outer ,ula + "1::1" )
493
- require .NoErrorf (t ,err ,"set IP on client1-client2 interface" )
494
-
495
- err = setInterfaceIP6 (network .Client2NetNS ,network .ServerClient2VethPair .Inner ,ula + "3::2" )
496
- require .NoErrorf (t ,err ,"set IP on client2-server interface" )
497
- err = setInterfaceIP6 (network .Client2NetNS ,network .Client1Client2VethPair .Inner ,ula + "1::2" )
498
- require .NoErrorf (t ,err ,"set IP on client2-client1 interface" )
491
+ err = setInterfaceIP6 (network .ServerNetNS ,network .ServerVethPair .Outer ,ula + "3::2" )
492
+ require .NoErrorf (t ,err ,"set IP on server interface" )
493
+ err = setInterfaceIP6 (network .Client1NetNS ,network .Client1VethPair .Outer ,ula + "1::2" )
494
+ require .NoErrorf (t ,err ,"set IP on client1 interface" )
495
+ err = setInterfaceIP6 (network .Client2NetNS ,network .Client2VethPair .Outer ,ula + "2::2" )
496
+ require .NoErrorf (t ,err ,"set IP on client2 interface" )
497
+
498
+ err = setInterfaceIP6 (network .RouterNetNS ,network .ServerVethPair .Inner ,ula + "3::1" )
499
+ require .NoErrorf (t ,err ,"set IP on router-server interface" )
500
+ err = setInterfaceIP6 (network .RouterNetNS ,network .Client1VethPair .Inner ,ula + "1::1" )
501
+ require .NoErrorf (t ,err ,"set IP on router-client1 interface" )
502
+ err = setInterfaceIP6 (network .RouterNetNS ,network .Client2VethPair .Inner ,ula + "2::1" )
503
+ require .NoErrorf (t ,err ,"set IP on router-client2 interface" )
499
504
500
505
// Bring up all interfaces
501
506
interfaces := []struct {
502
- netNS * os.File
503
- ifaceName string
507
+ netNS * os.File
508
+ ifaceName string
509
+ defaultRoute string
504
510
}{
505
- {network .ServerNetNS ,network .ServerClient1VethPair .Outer },
506
- {network .ServerNetNS ,network .ServerClient2VethPair .Outer },
507
- {network .Client1NetNS ,network .ServerClient1VethPair . Inner },
508
- {network .Client1NetNS ,network .Client1Client2VethPair . Outer },
509
- {network .Client2NetNS ,network .ServerClient2VethPair .Inner },
510
- {network .Client2NetNS ,network .Client1Client2VethPair .Inner },
511
+ {network .ServerNetNS ,network .ServerVethPair .Outer , ula + "3::1" },
512
+ {network .Client1NetNS ,network .Client1VethPair .Outer , ula + "1::1" },
513
+ {network .Client2NetNS ,network .Client2VethPair . Outer , ula + "2::1" },
514
+ {network .RouterNetNS ,network .ServerVethPair . Inner , "" },
515
+ {network .RouterNetNS ,network .Client1VethPair .Inner , "" },
516
+ {network .RouterNetNS ,network .Client2VethPair .Inner , "" },
511
517
}
512
518
for _ ,iface := range interfaces {
513
519
err = setInterfaceUp (iface .netNS ,iface .ifaceName )
514
520
require .NoErrorf (t ,err ,"bring up interface %q" ,iface .ifaceName )
515
- // Note: routes are not needed as we are fully connected, so nothing needs to forward IP to a further
516
- // destination.
521
+
522
+ if iface .defaultRoute != "" {
523
+ err = addRouteInNetNS (iface .netNS , []string {"default" ,"via" ,iface .defaultRoute ,"dev" ,iface .ifaceName })
524
+ require .NoErrorf (t ,err ,"add peer default route to %s" ,iface .defaultRoute )
525
+ }
517
526
}
518
527
528
+ // enable IP forwarding in the router
529
+ _ ,err = commandInNetNS (network .RouterNetNS ,"sysctl" , []string {"-w" ,"net.ipv6.conf.all.forwarding=1" }).Output ()
530
+ require .NoError (t ,wrapExitErr (err ),"enable IPv6 forwarding in router NetNS" )
531
+
519
532
return TestNetworking {
520
533
Server :TestNetworkingServer {
521
534
Process :TestNetworkingProcess {NetNS :network .ServerNetNS },
522
535
ListenAddr :"[::]:8080" ,// Server listens on all IPs
523
536
},
524
537
Client1 :TestNetworkingClient {
525
538
Process :TestNetworkingProcess {NetNS :network .Client1NetNS },
526
- ServerAccessURL :"http://[" + ula + "2::3 ]:8080" ,// Client1 accesses server directly
539
+ ServerAccessURL :"http://[" + ula + "3::2 ]:8080" ,
527
540
},
528
541
Client2 :TestNetworkingClient {
529
542
Process :TestNetworkingProcess {NetNS :network .Client2NetNS },
530
- ServerAccessURL :"http://[" + ula + "3::3 ]:8080" ,// Client2 accesses server directly
543
+ ServerAccessURL :"http://[" + ula + "3::2 ]:8080" ,
531
544
},
532
545
}
533
546
}