@@ -668,21 +668,39 @@ func createVLABConfig(ctx context.Context, controls []fabapi.ControlNode, nodes
668
668
}
669
669
}
670
670
} else if conn .Spec .External != nil {
671
- // in hybrid environments we can have physical switches connected to
672
- // both virtual and hardware externals. Since a connection is not associated
673
- // with a specific external, we need to annotate the connection itself
674
- if isHardware (& conn ) {
675
- slog .Debug ("Skipping hardware external connection" , "connection" , conn .Name )
671
+ // check if the connection is for hardware or virtual externals
672
+ // (it cannot be both, complain if that is the case)
673
+ var hwExt , virtExt bool
674
+ for _ , extAttach := range externalAttachs .Items {
675
+ if extAttach .Spec .Connection != conn .Name {
676
+ continue
677
+ }
678
+ extName := extAttach .Spec .External
679
+ if hwExternals [extName ] {
680
+ hwExt = true
681
+ } else {
682
+ virtExt = true
683
+ }
684
+ }
685
+ // here we want to do a bunch of stuff only if there are virtual externals attached on this connection
686
+ switch {
687
+ case hwExt && virtExt :
688
+ return nil , fmt .Errorf ("external connection %q has both hardware and virtual external attachments" , conn .Name ) //nolint:goerr113
689
+ case ! hwExt && ! virtExt :
690
+ slog .Debug ("Skipping external connection as it has no attachments" , "connection" , conn .Name )
691
+
692
+ continue
693
+ case hwExt :
694
+ slog .Debug ("Skipping external connection as it is for hardware externals" , "connection" , conn .Name )
676
695
677
696
continue
678
697
}
698
+ // now that we know that the connection is for virtual externals, we can add a link towards them,
699
+ // which could be using a passthrough if the source is a hardware switch
679
700
if externalID > MaxExternalConns {
680
701
return nil , fmt .Errorf ("too many external connections" ) //nolint:goerr113
681
702
}
682
-
683
703
switchName := conn .Spec .External .Link .Switch .DeviceName ()
684
- // add the link representing the virtual external connection
685
- // note that if the switch is hardware, we will require passthrough annotations
686
704
nicName := fmt .Sprintf ("enp2s%d" , externalID )
687
705
externalID ++
688
706
toStr := fmt .Sprintf ("%s/%s" , ExternalVMName , nicName )
@@ -694,7 +712,7 @@ func createVLABConfig(ctx context.Context, controls []fabapi.ControlNode, nodes
694
712
Untagged : false ,
695
713
}
696
714
697
- // check if there is any external attachment using this connection
715
+ // iterate over the external attachments using this connection
698
716
// note that we have a limitation where we cannot support both untagged and tagged
699
717
// on the same connection, so complain if we notice that's the case
700
718
var tagged , untagged bool
@@ -703,9 +721,9 @@ func createVLABConfig(ctx context.Context, controls []fabapi.ControlNode, nodes
703
721
continue
704
722
}
705
723
extName := extAttach .Spec .External
706
- // nothing to do if the external is hardware
724
+ // just a paranoid extra safety (unreachable, we already checked)
707
725
if hwExternals [extName ] {
708
- continue
726
+ return nil , fmt . Errorf ( "external attachment %q is for hardware external %q" , extAttach . Name , extName ) //nolint:goerr113
709
727
}
710
728
extVrf , ok := cfg .Externals .VRFs [extName ]
711
729
if ! ok {
0 commit comments