@@ -438,6 +438,165 @@ func createFakeInternet(t *testing.T) fakeInternet {
438
438
return router
439
439
}
440
440
441
+ type fakeTriangleNetwork struct {
442
+ Net TestNetworking
443
+
444
+ NamePrefix string
445
+ ServerNetNS * os.File
446
+ Client1NetNS * os.File
447
+ Client2NetNS * os.File
448
+ ServerClient1VethPair vethPair
449
+ ServerClient2VethPair vethPair
450
+ Client1Client2VethPair vethPair
451
+ }
452
+
453
+ // createFakeTriangleNetwork creates multiple namespaces with veth pairs between them
454
+ // with the following topology:
455
+ // .
456
+ // . ┌─────────────────────────────────────────┐
457
+ // . │ Server │
458
+ // . └─────┬────────────────────────────────┬──┘
459
+ // . │10.0.2.3 │10.0.3.3
460
+ // . veth│ veth│
461
+ // . │10.0.2.1 │10.0.3.2
462
+ // . ┌───────┴──────┐ veth 10.0.1.2┌─────┴───────┐
463
+ // . │ Client 1 ├───────────────────┤ Client 2 │
464
+ // . └──────────────┘10.0.1.1 └─────────────┘
465
+ func createFakeTriangleNetwork (t * testing.T ) fakeTriangleNetwork {
466
+ t .Helper ()
467
+ const (
468
+ bridgePrefix = "10.0.0."
469
+ serverIP = bridgePrefix + "1"
470
+ client1Prefix = "10.0.2."
471
+ client2Prefix = "10.0.3."
472
+ )
473
+ var (
474
+ namePrefix = uniqNetName (t ) + "_"
475
+ network = fakeTriangleNetwork {
476
+ NamePrefix : namePrefix ,
477
+ }
478
+ )
479
+
480
+ // Create bridge namespace and bridge interface.
481
+ router .BridgeNetNS = createNetNS (t , router .BridgeName )
482
+ err := createBridge (router .BridgeNetNS , router .BridgeName )
483
+ require .NoError (t , err , "create bridge in netns" )
484
+
485
+ // Create server namespace and veth pair between bridge and server.
486
+ router .ServerNetNS = createNetNS (t , namePrefix + "s" )
487
+ router .ServerVethPair = vethPair {
488
+ Outer : namePrefix + "b-s" ,
489
+ Inner : namePrefix + "s-b" ,
490
+ }
491
+ err = joinBridge (joinBridgeOpts {
492
+ bridgeNetNS : router .BridgeNetNS ,
493
+ netNS : router .ServerNetNS ,
494
+ bridgeName : router .BridgeName ,
495
+ vethPair : router .ServerVethPair ,
496
+ ip : serverIP ,
497
+ })
498
+ require .NoError (t , err , "join bridge with server" )
499
+
500
+ leaves := []struct {
501
+ leaf * fakeRouterLeaf
502
+ routerName string
503
+ clientName string
504
+ routerBridgeIP string
505
+ routerClientIP string
506
+ clientIP string
507
+ }{
508
+ {
509
+ leaf : & router .Client1 ,
510
+ routerName : "c1r" ,
511
+ clientName : "c1" ,
512
+ routerBridgeIP : bridgePrefix + "2" ,
513
+ routerClientIP : client1Prefix + "1" ,
514
+ clientIP : client1Prefix + "2" ,
515
+ },
516
+ {
517
+ leaf : & router .Client2 ,
518
+ routerName : "c2r" ,
519
+ clientName : "c2" ,
520
+ routerBridgeIP : bridgePrefix + "3" ,
521
+ routerClientIP : client2Prefix + "1" ,
522
+ clientIP : client2Prefix + "2" ,
523
+ },
524
+ }
525
+
526
+ for _ , leaf := range leaves {
527
+ leaf .leaf .RouterIP = leaf .routerBridgeIP
528
+ leaf .leaf .ClientIP = leaf .clientIP
529
+
530
+ // Create two network namespaces for each leaf: one for the router and
531
+ // one for the "client".
532
+ leaf .leaf .RouterNetNS = createNetNS (t , namePrefix + leaf .routerName )
533
+ leaf .leaf .ClientNetNS = createNetNS (t , namePrefix + leaf .clientName )
534
+
535
+ // Join the bridge.
536
+ leaf .leaf .OuterVethPair = vethPair {
537
+ Outer : namePrefix + "b-" + leaf .routerName ,
538
+ Inner : namePrefix + leaf .routerName + "-b" ,
539
+ }
540
+ err = joinBridge (joinBridgeOpts {
541
+ bridgeNetNS : router .BridgeNetNS ,
542
+ netNS : leaf .leaf .RouterNetNS ,
543
+ bridgeName : router .BridgeName ,
544
+ vethPair : leaf .leaf .OuterVethPair ,
545
+ ip : leaf .routerBridgeIP ,
546
+ })
547
+ require .NoError (t , err , "join bridge with router" )
548
+
549
+ // Create inner veth pair between the router and the client.
550
+ leaf .leaf .InnerVethPair = vethPair {
551
+ Outer : namePrefix + leaf .routerName + "-" + leaf .clientName ,
552
+ Inner : namePrefix + leaf .clientName + "-" + leaf .routerName ,
553
+ }
554
+ err = createVethPair (leaf .leaf .InnerVethPair .Outer , leaf .leaf .InnerVethPair .Inner )
555
+ require .NoErrorf (t , err , "create veth pair %q <-> %q" , leaf .leaf .InnerVethPair .Outer , leaf .leaf .InnerVethPair .Inner )
556
+
557
+ // Move the network interfaces to the respective network namespaces.
558
+ err = setVethNetNS (leaf .leaf .InnerVethPair .Outer , int (leaf .leaf .RouterNetNS .Fd ()))
559
+ require .NoErrorf (t , err , "set veth %q to NetNS" , leaf .leaf .InnerVethPair .Outer )
560
+ err = setVethNetNS (leaf .leaf .InnerVethPair .Inner , int (leaf .leaf .ClientNetNS .Fd ()))
561
+ require .NoErrorf (t , err , "set veth %q to NetNS" , leaf .leaf .InnerVethPair .Inner )
562
+
563
+ // Set router's "local" IP on the veth.
564
+ err = setInterfaceIP (leaf .leaf .RouterNetNS , leaf .leaf .InnerVethPair .Outer , leaf .routerClientIP )
565
+ require .NoErrorf (t , err , "set IP %q on interface %q" , leaf .routerClientIP , leaf .leaf .InnerVethPair .Outer )
566
+ // Set client's IP on the veth.
567
+ err = setInterfaceIP (leaf .leaf .ClientNetNS , leaf .leaf .InnerVethPair .Inner , leaf .clientIP )
568
+ require .NoErrorf (t , err , "set IP %q on interface %q" , leaf .clientIP , leaf .leaf .InnerVethPair .Inner )
569
+
570
+ // Bring up the interfaces.
571
+ err = setInterfaceUp (leaf .leaf .RouterNetNS , leaf .leaf .InnerVethPair .Outer )
572
+ require .NoErrorf (t , err , "bring up interface %q" , leaf .leaf .OuterVethPair .Outer )
573
+ err = setInterfaceUp (leaf .leaf .ClientNetNS , leaf .leaf .InnerVethPair .Inner )
574
+ require .NoErrorf (t , err , "bring up interface %q" , leaf .leaf .InnerVethPair .Inner )
575
+
576
+ // We don't need to add a route from parent to peer since the kernel
577
+ // already adds a default route for the /24. We DO need to add a default
578
+ // route from peer to parent, however.
579
+ err = addRouteInNetNS (leaf .leaf .ClientNetNS , []string {"default" , "via" , leaf .routerClientIP , "dev" , leaf .leaf .InnerVethPair .Inner })
580
+ require .NoErrorf (t , err , "add peer default route to %q" , leaf .leaf .InnerVethPair .Inner )
581
+ }
582
+
583
+ router .Net = TestNetworking {
584
+ Server : TestNetworkingServer {
585
+ Process : TestNetworkingProcess {NetNS : router .ServerNetNS },
586
+ ListenAddr : serverIP + ":8080" ,
587
+ },
588
+ Client1 : TestNetworkingClient {
589
+ Process : TestNetworkingProcess {NetNS : router .Client1 .ClientNetNS },
590
+ ServerAccessURL : "http://" + serverIP + ":8080" ,
591
+ },
592
+ Client2 : TestNetworkingClient {
593
+ Process : TestNetworkingProcess {NetNS : router .Client2 .ClientNetNS },
594
+ ServerAccessURL : "http://" + serverIP + ":8080" ,
595
+ },
596
+ }
597
+ return router
598
+ }
599
+
441
600
func uniqNetName (t * testing.T ) string {
442
601
t .Helper ()
443
602
netNSName := "cdr_"
0 commit comments