@@ -390,33 +390,38 @@ func createFakeInternet(t *testing.T) fakeInternet {
390390}
391391
392392type TriangleNetwork struct {
393- InterClientMTU int
393+ Client1MTU int
394394}
395395
396396type 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
404405}
405406
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
408408// .
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.
420425func (n TriangleNetwork ) SetupNetworking (t * testing.T , l slog.Logger ) TestNetworking {
421426 logger := l .Named ("setup-networking" ).Leveled (slog .LevelDebug )
422427 t .Helper ()
@@ -433,101 +438,109 @@ func (n TriangleNetwork) SetupNetworking(t *testing.T, l slog.Logger) TestNetwor
433438 network .ServerNetNS = createNetNS (t , namePrefix + "server" )
434439 network .Client1NetNS = createNetNS (t , namePrefix + "client1" )
435440 network .Client2NetNS = createNetNS (t , namePrefix + "client2" )
441+ network .RouterNetNS = createNetNS (t , namePrefix + "router" )
436442
437- // Create veth pair between server and client1
438- network .ServerClient1VethPair = vethPair {
439- Outer : namePrefix + "s-1 " ,
440- Inner : namePrefix + "1 -s" ,
443+ // Create veth pair between server and router
444+ network .ServerVethPair = vethPair {
445+ Outer : namePrefix + "s-r " ,
446+ Inner : namePrefix + "r -s" ,
441447 }
442- err := createVethPair (network .ServerClient1VethPair .Outer , network .ServerClient1VethPair .Inner )
448+ err := createVethPair (network .ServerVethPair .Outer , network .ServerVethPair .Inner )
443449 require .NoErrorf (t , err , "create veth pair %q <-> %q" ,
444- network .ServerClient1VethPair .Outer , network .ServerClient1VethPair .Inner )
450+ network .ServerVethPair .Outer , network .ServerVethPair .Inner )
445451
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 to client1 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 to router NetNS" , network .ServerVethPair .Inner )
451457
452- // Create veth pair between server and client2
453- network .ServerClient2VethPair = vethPair {
454- Outer : namePrefix + "s-2 " ,
455- Inner : namePrefix + "2-s " ,
458+ // Create veth pair between client1 and router
459+ network .Client1VethPair = vethPair {
460+ Outer : namePrefix + "1-r " ,
461+ Inner : namePrefix + "r-1 " ,
456462 }
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 ))
458465 require .NoErrorf (t , err , "create veth pair %q <-> %q" ,
459- network .ServerClient2VethPair .Outer , network .ServerClient2VethPair .Inner )
466+ network .Client1VethPair .Outer , network .Client1VethPair .Inner )
460467
461- // Move server-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+ // Move client1-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 )
466473
467474 // 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 " ,
471478 }
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 )
475481 require .NoErrorf (t , err , "create veth pair %q <-> %q" ,
476- network .Client1Client2VethPair .Outer , network .Client1Client2VethPair .Inner )
482+ network .Client2VethPair .Outer , network .Client2VethPair .Inner )
477483
478484 // 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 )
483489
484490 // 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" )
499504
500505 // Bring up all interfaces
501506 interfaces := []struct {
502- netNS * os.File
503- ifaceName string
507+ netNS * os.File
508+ ifaceName string
509+ defaultRoute string
504510 }{
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 , "" },
511517 }
512518 for _ , iface := range interfaces {
513519 err = setInterfaceUp (iface .netNS , iface .ifaceName )
514520 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+ }
517526 }
518527
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+
519532 return TestNetworking {
520533 Server : TestNetworkingServer {
521534 Process : TestNetworkingProcess {NetNS : network .ServerNetNS },
522535 ListenAddr : "[::]:8080" , // Server listens on all IPs
523536 },
524537 Client1 : TestNetworkingClient {
525538 Process : TestNetworkingProcess {NetNS : network .Client1NetNS },
526- ServerAccessURL : "http://[" + ula + "2::3 ]:8080" , // Client1 accesses server directly
539+ ServerAccessURL : "http://[" + ula + "3::2 ]:8080" ,
527540 },
528541 Client2 : TestNetworkingClient {
529542 Process : TestNetworkingProcess {NetNS : network .Client2NetNS },
530- ServerAccessURL : "http://[" + ula + "3::3 ]:8080" , // Client2 accesses server directly
543+ ServerAccessURL : "http://[" + ula + "3::2 ]:8080" ,
531544 },
532545 }
533546}
0 commit comments