@Test public void testComputeLayer2Topology_layer1() { String c1Name = "c1"; String c2Name = "c2"; String c3Name = "c3"; String c4Name = "c4"; String c1i1Name = "c1i1"; String c2i1Name = "c2i1"; String c3i1Name = "c3i1"; String c3i2Name = "c3i2"; String c4i1Name = "c4i1"; String c4i2Name = "c4i2"; Configuration c1 = _cb.setHostname(c1Name).build(); Vrf v1 = _vb.setOwner(c1).build(); _ib.setOwner(c1).setVrf(v1).setActive(true); _ib.setName(c1i1Name).build(); Configuration c2 = _cb.setHostname(c2Name).build(); Vrf v2 = _vb.setOwner(c2).build(); _ib.setOwner(c2).setVrf(v2); _ib.setName(c2i1Name).build(); { Map<String, Configuration> configs = ImmutableMap.of(c1Name, c1, c2Name, c2); Layer1Topology layer1Topology = layer1Topology(c1Name, c1i1Name, c2Name, c2i1Name); Layer2Topology layer2Topology = computeLayer2Topology(layer1Topology, VxlanTopology.EMPTY, configs); assertTrue( "c1:i1 and c2:i1 are in the same broadcast domain", layer2Topology.inSameBroadcastDomain(c1Name, c1i1Name, c2Name, c2i1Name)); } { Configuration c3 = _cb.setHostname(c3Name).build(); Vrf v3 = _vb.setOwner(c3).build(); _ib.setOwner(c3).setVrf(v3); Interface c3i1 = _ib.setName(c3i1Name).build(); c3i1.setSwitchport(true); c3i1.setSwitchportMode(SwitchportMode.ACCESS); c3i1.setAccessVlan(1); Interface c3i2 = _ib.setName(c3i2Name).build(); c3i2.setSwitchport(true); c3i2.setSwitchportMode(SwitchportMode.ACCESS); c3i2.setAccessVlan(1); Map<String, Configuration> configs = ImmutableMap.of(c1Name, c1, c2Name, c2, c3Name, c3); Layer1Topology layer1Topology = layer1Topology( c1Name, c1i1Name, c3Name, c3i1Name, c2Name, c2i1Name, c3Name, c3i2Name); Layer2Topology layer2Topology = computeLayer2Topology(layer1Topology, VxlanTopology.EMPTY, configs); assertTrue( "c1:i1 and c2:i1 are in the same broadcast domain", layer2Topology.inSameBroadcastDomain(c1Name, c1i1Name, c2Name, c2i1Name)); } { Configuration c3 = _cb.setHostname(c3Name).build(); Vrf v3 = _vb.setOwner(c3).build(); _ib.setOwner(c3).setVrf(v3); Interface c3i1 = _ib.setName(c3i1Name).build(); c3i1.setSwitchport(true); c3i1.setSwitchportMode(SwitchportMode.ACCESS); c3i1.setAccessVlan(1); Interface c3i2 = _ib.setName(c3i2Name).build(); c3i2.setSwitchport(true); c3i2.setSwitchportMode(SwitchportMode.ACCESS); c3i2.setAccessVlan(2); Map<String, Configuration> configs = ImmutableMap.of(c1Name, c1, c2Name, c2, c3Name, c3); Layer1Topology layer1Topology = layer1Topology( c1Name, c1i1Name, c3Name, c3i1Name, c2Name, c2i1Name, c3Name, c3i2Name); Layer2Topology layer2Topology = computeLayer2Topology(layer1Topology, VxlanTopology.EMPTY, configs); assertFalse( "c1:i1 and c2:i1 are not in the same broadcast domain", layer2Topology.inSameBroadcastDomain(c1Name, c1i1Name, c2Name, c2i1Name)); } { Configuration c3 = _cb.setHostname(c3Name).build(); Vrf v3 = _vb.setOwner(c3).build(); _ib.setOwner(c3).setVrf(v3); Interface c3i1 = _ib.setName(c3i1Name).build(); c3i1.setSwitchport(true); c3i1.setSwitchportMode(SwitchportMode.TRUNK); c3i1.setAllowedVlans(IntegerSpace.of(new SubRange(1, 3))); c3i1.setNativeVlan(1); Interface c3i2 = _ib.setName(c3i2Name).build(); c3i2.setSwitchport(true); c3i2.setSwitchportMode(SwitchportMode.ACCESS); c3i2.setAccessVlan(1); Map<String, Configuration> configs = ImmutableMap.of(c1Name, c1, c2Name, c2, c3Name, c3); Layer1Topology layer1Topology = layer1Topology( c1Name, c1i1Name, c3Name, c3i1Name, c2Name, c2i1Name, c3Name, c3i2Name); Layer2Topology layer2Topology = computeLayer2Topology(layer1Topology, VxlanTopology.EMPTY, configs); assertTrue( "c1:i1 and c2:i1 are in the same broadcast domain", layer2Topology.inSameBroadcastDomain(c1Name, c1i1Name, c2Name, c2i1Name)); } { Configuration c3 = _cb.setHostname(c3Name).build(); Vrf v3 = _vb.setOwner(c3).build(); _ib.setOwner(c3).setVrf(v3); Interface c3i1 = _ib.setName(c3i1Name).build(); c3i1.setSwitchport(true); c3i1.setSwitchportMode(SwitchportMode.TRUNK); c3i1.setAllowedVlans(IntegerSpace.of(new SubRange(1, 3))); c3i1.setNativeVlan(1); Interface c3i2 = _ib.setName(c3i2Name).build(); c3i2.setSwitchport(true); c3i2.setSwitchportMode(SwitchportMode.ACCESS); c3i2.setAccessVlan(2); Map<String, Configuration> configs = ImmutableMap.of(c1Name, c1, c2Name, c2, c3Name, c3); Layer1Topology layer1Topology = layer1Topology( c1Name, c1i1Name, c3Name, c3i1Name, c2Name, c2i1Name, c3Name, c3i2Name); Layer2Topology layer2Topology = computeLayer2Topology(layer1Topology, VxlanTopology.EMPTY, configs); assertFalse( "c1:i1 and c2:i1 are not in the same broadcast domain", layer2Topology.inSameBroadcastDomain(c1Name, c1i1Name, c2Name, c2i1Name)); } { Configuration c3 = _cb.setHostname(c3Name).build(); Vrf v3 = _vb.setOwner(c3).build(); _ib.setOwner(c3).setVrf(v3); Interface c3i1 = _ib.setName(c3i1Name).build(); c3i1.setSwitchport(true); c3i1.setSwitchportMode(SwitchportMode.TRUNK); c3i1.setAllowedVlans(IntegerSpace.of(new SubRange(1, 3))); c3i1.setNativeVlan(1); Interface c3i2 = _ib.setName(c3i2Name).build(); c3i2.setSwitchport(true); c3i2.setSwitchportMode(SwitchportMode.ACCESS); c3i2.setAccessVlan(4); Map<String, Configuration> configs = ImmutableMap.of(c1Name, c1, c2Name, c2, c3Name, c3); Layer1Topology layer1Topology = layer1Topology( c1Name, c1i1Name, c3Name, c3i1Name, c2Name, c2i1Name, c3Name, c3i2Name); Layer2Topology layer2Topology = computeLayer2Topology(layer1Topology, VxlanTopology.EMPTY, configs); assertFalse( "c1:i1 and c2:i1 are not in the same broadcast domain", layer2Topology.inSameBroadcastDomain(c1Name, c1i1Name, c2Name, c2i1Name)); } { Configuration c3 = _cb.setHostname(c3Name).build(); Vrf v3 = _vb.setOwner(c3).build(); _ib.setOwner(c3).setVrf(v3); Interface c3i1 = _ib.setName(c3i1Name).build(); c3i1.setSwitchport(true); c3i1.setSwitchportMode(SwitchportMode.ACCESS); c3i1.setAccessVlan(2); Interface c3i2 = _ib.setName(c3i2Name).build(); c3i2.setSwitchport(true); c3i2.setSwitchportMode(SwitchportMode.TRUNK); c3i2.setAllowedVlans(IntegerSpace.of(new SubRange(1, 3))); c3i2.setNativeVlan(1); Configuration c4 = _cb.setHostname(c4Name).build(); Vrf v4 = _vb.setOwner(c4).build(); _ib.setOwner(c4).setVrf(v4); Interface c4i1 = _ib.setName(c4i1Name).build(); c4i1.setSwitchport(true); c4i1.setSwitchportMode(SwitchportMode.TRUNK); c4i1.setAllowedVlans(IntegerSpace.of(new SubRange(1, 3))); c4i1.setNativeVlan(1); Interface c4i2 = _ib.setName(c4i2Name).build(); c4i2.setSwitchport(true); c4i2.setSwitchportMode(SwitchportMode.ACCESS); c4i2.setAccessVlan(2); Map<String, Configuration> configs = ImmutableMap.of(c1Name, c1, c2Name, c2, c3Name, c3, c4Name, c4); Layer1Topology layer1Topology = layer1Topology( c1Name, c1i1Name, c3Name, c3i1Name, c3Name, c3i2Name, c4Name, c4i1Name, c4Name, c4i2Name, c2Name, c2i1Name); Layer2Topology layer2Topology = computeLayer2Topology(layer1Topology, VxlanTopology.EMPTY, configs); assertTrue( "c1:i1 and c2:i1 are in the same broadcast domain", layer2Topology.inSameBroadcastDomain(c1Name, c1i1Name, c2Name, c2i1Name)); } { Configuration c3 = _cb.setHostname(c3Name).build(); Vrf v3 = _vb.setOwner(c3).build(); _ib.setOwner(c3).setVrf(v3); Interface c3i1 = _ib.setName(c3i1Name).build(); c3i1.setSwitchport(true); c3i1.setSwitchportMode(SwitchportMode.ACCESS); c3i1.setAccessVlan(2); Interface c3i2 = _ib.setName(c3i2Name).build(); c3i2.setSwitchport(true); c3i2.setSwitchportMode(SwitchportMode.TRUNK); c3i2.setAllowedVlans(IntegerSpace.of(new SubRange(1, 3))); c3i2.setNativeVlan(1); Configuration c4 = _cb.setHostname(c4Name).build(); Vrf v4 = _vb.setOwner(c4).build(); _ib.setOwner(c4).setVrf(v4); Interface c4i1 = _ib.setName(c4i1Name).build(); c4i1.setSwitchport(true); c4i1.setSwitchportMode(SwitchportMode.ACCESS); c4i1.setAccessVlan(2); Interface c4i2 = _ib.setName(c4i2Name).build(); c4i2.setSwitchport(true); c4i2.setSwitchportMode(SwitchportMode.ACCESS); c4i2.setAccessVlan(2); Map<String, Configuration> configs = ImmutableMap.of(c1Name, c1, c2Name, c2, c3Name, c3, c4Name, c4); Layer1Topology layer1Topology = layer1Topology( c1Name, c1i1Name, c3Name, c3i1Name, c3Name, c3i2Name, c4Name, c4i2Name, c4Name, c4i1Name, c2Name, c2i1Name); Layer2Topology layer2Topology = computeLayer2Topology(layer1Topology, VxlanTopology.EMPTY, configs); assertFalse( "c1:i1 and c2:i1 are not in the same broadcast domain", layer2Topology.inSameBroadcastDomain(c1Name, c1i1Name, c2Name, c2i1Name)); } }
public static @Nonnull Layer2Topology computeLayer2Topology( @Nonnull Layer1Topology layer1LogicalTopology, VxlanTopology vxlanTopology, @Nonnull Map<String, Configuration> configurations) { Layer2Topology.Builder l2TopologyBuilder = Layer2Topology.builder(); Map<Layer1Node, Set<Layer1Node>> parentChildrenMap = computeParentChildrenMap(configurations); layer1LogicalTopology .getGraph() .edges() .forEach( layer1Edge -> computeLayer2EdgesForLayer1Edge( layer1Edge, configurations, l2TopologyBuilder::addEdge, parentChildrenMap)); Set<String> nodesWithL1Edge = layer1LogicalTopology.getGraph().edges().stream() .flatMap(edge -> Stream.of(edge.getNode1(), edge.getNode2())) .map(Layer1Node::getHostname) .collect(ImmutableSet.toImmutableSet()); Set<String> nodesWithVxlan = vxlanTopology.getGraph().edges().stream() .flatMap(edge -> Stream.of(edge.nodeU(), edge.nodeV())) .map(VxlanNode::getHostname) .collect(ImmutableSet.toImmutableSet()); Set<String> nodesWithUsefulL2SelfEdges = ImmutableSet.<String>builder().addAll(nodesWithL1Edge).addAll(nodesWithVxlan).build(); configurations.values().stream() .filter(c -> nodesWithUsefulL2SelfEdges.contains(c.getHostname())) .forEach(c -> computeLayer2SelfEdges(c, l2TopologyBuilder::addEdge)); computeVniInterNodeEdges(vxlanTopology).forEach(l2TopologyBuilder::addEdge); return l2TopologyBuilder.build(); }
TopologyUtil { public static @Nonnull Layer2Topology computeLayer2Topology( @Nonnull Layer1Topology layer1LogicalTopology, VxlanTopology vxlanTopology, @Nonnull Map<String, Configuration> configurations) { Layer2Topology.Builder l2TopologyBuilder = Layer2Topology.builder(); Map<Layer1Node, Set<Layer1Node>> parentChildrenMap = computeParentChildrenMap(configurations); layer1LogicalTopology .getGraph() .edges() .forEach( layer1Edge -> computeLayer2EdgesForLayer1Edge( layer1Edge, configurations, l2TopologyBuilder::addEdge, parentChildrenMap)); Set<String> nodesWithL1Edge = layer1LogicalTopology.getGraph().edges().stream() .flatMap(edge -> Stream.of(edge.getNode1(), edge.getNode2())) .map(Layer1Node::getHostname) .collect(ImmutableSet.toImmutableSet()); Set<String> nodesWithVxlan = vxlanTopology.getGraph().edges().stream() .flatMap(edge -> Stream.of(edge.nodeU(), edge.nodeV())) .map(VxlanNode::getHostname) .collect(ImmutableSet.toImmutableSet()); Set<String> nodesWithUsefulL2SelfEdges = ImmutableSet.<String>builder().addAll(nodesWithL1Edge).addAll(nodesWithVxlan).build(); configurations.values().stream() .filter(c -> nodesWithUsefulL2SelfEdges.contains(c.getHostname())) .forEach(c -> computeLayer2SelfEdges(c, l2TopologyBuilder::addEdge)); computeVniInterNodeEdges(vxlanTopology).forEach(l2TopologyBuilder::addEdge); return l2TopologyBuilder.build(); } }
TopologyUtil { public static @Nonnull Layer2Topology computeLayer2Topology( @Nonnull Layer1Topology layer1LogicalTopology, VxlanTopology vxlanTopology, @Nonnull Map<String, Configuration> configurations) { Layer2Topology.Builder l2TopologyBuilder = Layer2Topology.builder(); Map<Layer1Node, Set<Layer1Node>> parentChildrenMap = computeParentChildrenMap(configurations); layer1LogicalTopology .getGraph() .edges() .forEach( layer1Edge -> computeLayer2EdgesForLayer1Edge( layer1Edge, configurations, l2TopologyBuilder::addEdge, parentChildrenMap)); Set<String> nodesWithL1Edge = layer1LogicalTopology.getGraph().edges().stream() .flatMap(edge -> Stream.of(edge.getNode1(), edge.getNode2())) .map(Layer1Node::getHostname) .collect(ImmutableSet.toImmutableSet()); Set<String> nodesWithVxlan = vxlanTopology.getGraph().edges().stream() .flatMap(edge -> Stream.of(edge.nodeU(), edge.nodeV())) .map(VxlanNode::getHostname) .collect(ImmutableSet.toImmutableSet()); Set<String> nodesWithUsefulL2SelfEdges = ImmutableSet.<String>builder().addAll(nodesWithL1Edge).addAll(nodesWithVxlan).build(); configurations.values().stream() .filter(c -> nodesWithUsefulL2SelfEdges.contains(c.getHostname())) .forEach(c -> computeLayer2SelfEdges(c, l2TopologyBuilder::addEdge)); computeVniInterNodeEdges(vxlanTopology).forEach(l2TopologyBuilder::addEdge); return l2TopologyBuilder.build(); } private  TopologyUtil(); }
TopologyUtil { public static @Nonnull Layer2Topology computeLayer2Topology( @Nonnull Layer1Topology layer1LogicalTopology, VxlanTopology vxlanTopology, @Nonnull Map<String, Configuration> configurations) { Layer2Topology.Builder l2TopologyBuilder = Layer2Topology.builder(); Map<Layer1Node, Set<Layer1Node>> parentChildrenMap = computeParentChildrenMap(configurations); layer1LogicalTopology .getGraph() .edges() .forEach( layer1Edge -> computeLayer2EdgesForLayer1Edge( layer1Edge, configurations, l2TopologyBuilder::addEdge, parentChildrenMap)); Set<String> nodesWithL1Edge = layer1LogicalTopology.getGraph().edges().stream() .flatMap(edge -> Stream.of(edge.getNode1(), edge.getNode2())) .map(Layer1Node::getHostname) .collect(ImmutableSet.toImmutableSet()); Set<String> nodesWithVxlan = vxlanTopology.getGraph().edges().stream() .flatMap(edge -> Stream.of(edge.nodeU(), edge.nodeV())) .map(VxlanNode::getHostname) .collect(ImmutableSet.toImmutableSet()); Set<String> nodesWithUsefulL2SelfEdges = ImmutableSet.<String>builder().addAll(nodesWithL1Edge).addAll(nodesWithVxlan).build(); configurations.values().stream() .filter(c -> nodesWithUsefulL2SelfEdges.contains(c.getHostname())) .forEach(c -> computeLayer2SelfEdges(c, l2TopologyBuilder::addEdge)); computeVniInterNodeEdges(vxlanTopology).forEach(l2TopologyBuilder::addEdge); return l2TopologyBuilder.build(); } private  TopologyUtil(); static @Nonnull Layer1Topology cleanLayer1PhysicalTopology(
      @Nonnull Layer1Topology rawLayer1Topology,
      @Nonnull Map<String, Configuration> configurations); static @Nonnull Optional<Layer1Topology> unionLayer1PhysicalTopologies(
      Optional<Layer1Topology> topology1, Optional<Layer1Topology> topology2); static @Nonnull Layer2Topology computeLayer2Topology(
      @Nonnull Layer1Topology layer1LogicalTopology,
      VxlanTopology vxlanTopology,
      @Nonnull Map<String, Configuration> configurations); static @Nonnull Topology computeRawLayer3Topology(
      @Nonnull Optional<Layer1Topology> rawLayer1PhysicalTopology,
      @Nonnull Optional<Layer1Topology> layer1LogicalTopology,
      @Nonnull Optional<Layer2Topology> layer2Topology,
      @Nonnull Map<String, Configuration> configurations); static @Nonnull Topology computeLayer3Topology(
      Topology rawLayer3Topology, Set<Edge> overlayEdges); static @Nullable Interface getInterface(
      @Nonnull Layer1Node layer1Node, @Nonnull Map<String, Configuration> configurations); static @Nullable Interface getInterface(
      @Nonnull Layer2Node layer2Node, @Nonnull Map<String, Configuration> configurations); static IpsecTopology computeIpsecTopology(Map<String, Configuration> configurations); static Map<String, Set<Interface>> computeNodeInterfaces(
      Map<String, Configuration> configurations); static Topology synthesizeL3Topology(Map<String, Configuration> configurations); static @Nonnull Layer1Topology computeLayer1LogicalTopology(
      Layer1Topology layer1PhysicalTopology, Map<String, Configuration> configurations); @Nonnull static TunnelTopology computeInitialTunnelTopology(
      Map<String, Configuration> configurations); @Nonnull static TunnelTopology pruneUnreachableTunnelEdges(
      TunnelTopology initialTunnelTopology,
      NetworkConfigurations configurations,
      TracerouteEngine tracerouteEngine); }
TopologyUtil { public static @Nonnull Layer2Topology computeLayer2Topology( @Nonnull Layer1Topology layer1LogicalTopology, VxlanTopology vxlanTopology, @Nonnull Map<String, Configuration> configurations) { Layer2Topology.Builder l2TopologyBuilder = Layer2Topology.builder(); Map<Layer1Node, Set<Layer1Node>> parentChildrenMap = computeParentChildrenMap(configurations); layer1LogicalTopology .getGraph() .edges() .forEach( layer1Edge -> computeLayer2EdgesForLayer1Edge( layer1Edge, configurations, l2TopologyBuilder::addEdge, parentChildrenMap)); Set<String> nodesWithL1Edge = layer1LogicalTopology.getGraph().edges().stream() .flatMap(edge -> Stream.of(edge.getNode1(), edge.getNode2())) .map(Layer1Node::getHostname) .collect(ImmutableSet.toImmutableSet()); Set<String> nodesWithVxlan = vxlanTopology.getGraph().edges().stream() .flatMap(edge -> Stream.of(edge.nodeU(), edge.nodeV())) .map(VxlanNode::getHostname) .collect(ImmutableSet.toImmutableSet()); Set<String> nodesWithUsefulL2SelfEdges = ImmutableSet.<String>builder().addAll(nodesWithL1Edge).addAll(nodesWithVxlan).build(); configurations.values().stream() .filter(c -> nodesWithUsefulL2SelfEdges.contains(c.getHostname())) .forEach(c -> computeLayer2SelfEdges(c, l2TopologyBuilder::addEdge)); computeVniInterNodeEdges(vxlanTopology).forEach(l2TopologyBuilder::addEdge); return l2TopologyBuilder.build(); } private  TopologyUtil(); static @Nonnull Layer1Topology cleanLayer1PhysicalTopology(
      @Nonnull Layer1Topology rawLayer1Topology,
      @Nonnull Map<String, Configuration> configurations); static @Nonnull Optional<Layer1Topology> unionLayer1PhysicalTopologies(
      Optional<Layer1Topology> topology1, Optional<Layer1Topology> topology2); static @Nonnull Layer2Topology computeLayer2Topology(
      @Nonnull Layer1Topology layer1LogicalTopology,
      VxlanTopology vxlanTopology,
      @Nonnull Map<String, Configuration> configurations); static @Nonnull Topology computeRawLayer3Topology(
      @Nonnull Optional<Layer1Topology> rawLayer1PhysicalTopology,
      @Nonnull Optional<Layer1Topology> layer1LogicalTopology,
      @Nonnull Optional<Layer2Topology> layer2Topology,
      @Nonnull Map<String, Configuration> configurations); static @Nonnull Topology computeLayer3Topology(
      Topology rawLayer3Topology, Set<Edge> overlayEdges); static @Nullable Interface getInterface(
      @Nonnull Layer1Node layer1Node, @Nonnull Map<String, Configuration> configurations); static @Nullable Interface getInterface(
      @Nonnull Layer2Node layer2Node, @Nonnull Map<String, Configuration> configurations); static IpsecTopology computeIpsecTopology(Map<String, Configuration> configurations); static Map<String, Set<Interface>> computeNodeInterfaces(
      Map<String, Configuration> configurations); static Topology synthesizeL3Topology(Map<String, Configuration> configurations); static @Nonnull Layer1Topology computeLayer1LogicalTopology(
      Layer1Topology layer1PhysicalTopology, Map<String, Configuration> configurations); @Nonnull static TunnelTopology computeInitialTunnelTopology(
      Map<String, Configuration> configurations); @Nonnull static TunnelTopology pruneUnreachableTunnelEdges(
      TunnelTopology initialTunnelTopology,
      NetworkConfigurations configurations,
      TracerouteEngine tracerouteEngine);  }