Search in sources :

Example 1 with BdpAnswerElement

use of org.batfish.datamodel.answers.BdpAnswerElement in project batfish by batfish.

the class BdpEngine method computeFixedPoint.

/**
 * Attempt to compute the fixed point of the data plane.
 *
 * @param nodes A dictionary of configuration-wrapping Bdp nodes keyed by name
 * @param topology The topology representing physical adjacencies between interface of the nodes
 * @param dp The output data plane
 * @param externalAdverts Optional external BGP advertisements fed into the data plane computation
 * @param ae The output answer element in which to store a report of the computation. Also
 *     contains the current recovery iteration.
 * @param recoveryIterationHashCodes Dependent-route computation iteration hash-code dictionaries,
 *     themselves keyed by outer recovery iteration.
 * @return true iff the computation is oscillating
 */
private boolean computeFixedPoint(SortedMap<String, Node> nodes, Topology topology, BdpDataPlane dp, Set<BgpAdvertisement> externalAdverts, BdpAnswerElement ae, SortedMap<Integer, SortedMap<Integer, Integer>> recoveryIterationHashCodes, SortedMap<Integer, SortedSet<Prefix>> iterationOscillatingPrefixes) {
    try (ActiveSpan computeFixedPointSpan = GlobalTracer.get().buildSpan("Computing fixed point").startActive()) {
        // avoid unused warning
        assert computeFixedPointSpan != null;
        SortedSet<Prefix> oscillatingPrefixes = ae.getOscillatingPrefixes();
        // BEGIN DONE ONCE (except main rib)
        // For each virtual router, setup the initial easy-to-do routes and init protocol-based RIBs:
        AtomicInteger initialCompleted = _newBatch.apply("Compute initial connected and static routes, ospf setup, bgp setup", nodes.size());
        try (ActiveSpan initRibsBdpSpan = GlobalTracer.get().buildSpan("Initializing easy routes for BDP").startActive()) {
            // avoid unused warning
            assert initRibsBdpSpan != null;
            nodes.values().parallelStream().forEach(n -> {
                for (VirtualRouter vr : n._virtualRouters.values()) {
                    vr.initRibsForBdp(dp.getIpOwners(), externalAdverts);
                }
                initialCompleted.incrementAndGet();
            });
        }
        // OSPF internal routes
        int numOspfInternalIterations;
        try (ActiveSpan ospfInternalRoutesSpan = GlobalTracer.get().buildSpan("Initializing OSPF internal routes").startActive()) {
            assert ospfInternalRoutesSpan != null;
            numOspfInternalIterations = initOspfInternalRoutes(nodes, topology);
        }
        // RIP internal routes
        try (ActiveSpan ripInternalRoutesSpan = GlobalTracer.get().buildSpan("Initializing RIP internal routes").startActive()) {
            assert ripInternalRoutesSpan != null;
            initRipInternalRoutes(nodes, topology);
        }
        // Prep for traceroutes
        nodes.values().parallelStream().forEach(n -> n._virtualRouters.values().forEach(vr -> {
            vr.importRib(vr._mainRib, vr._independentRib);
            // Needed for activateStaticRoutes
            vr._prevMainRib = vr._mainRib;
            vr.activateStaticRoutes();
        }));
        // Update bgp neighbors with reachability
        dp.setNodes(nodes);
        computeFibs(nodes);
        dp.setTopology(topology);
        initRemoteBgpNeighbors(nodes.entrySet().stream().collect(ImmutableMap.toImmutableMap(Entry::getKey, e -> e.getValue().getConfiguration())), dp.getIpOwners(), true, this, dp);
        // END DONE ONCE
        /*
       * Setup maps to track iterations. We need this for oscillation detection.
       * Specifically, if we detect that an iteration hashcode (a hash of all the nodes' RIBs)
       * has been previously encountered, we go into recovery mode.
       * Recovery mode means enabling "lockstep route propagation" for oscillating prefixes.
       *
       * Lockstep route propagation only allows one of the neighbors to propagate routes for
       * oscillating prefixes in a given iteration.
       * E.g., lexicographically lower neighbor propagates routes during
       * odd iterations, and lex-higher neighbor during even iterations.
       */
        Map<Integer, SortedSet<Integer>> iterationsByHashCode = new HashMap<>();
        SortedMap<Integer, Integer> iterationHashCodes = new TreeMap<>();
        Map<Integer, SortedSet<Route>> iterationRoutes = null;
        Map<Integer, SortedMap<String, SortedMap<String, SortedSet<AbstractRoute>>>> iterationAbstractRoutes = null;
        if (_settings.getBdpRecordAllIterations()) {
            if (_settings.getBdpDetail()) {
                iterationAbstractRoutes = new TreeMap<>();
            } else {
                iterationRoutes = new TreeMap<>();
            }
        } else if (_maxRecordedIterations > 0) {
            if (_settings.getBdpDetail()) {
                iterationAbstractRoutes = new LRUMap<>(_maxRecordedIterations);
            } else {
                iterationRoutes = new LRUMap<>(_maxRecordedIterations);
            }
        }
        AtomicBoolean dependentRoutesChanged = new AtomicBoolean(false);
        AtomicBoolean evenDependentRoutesChanged = new AtomicBoolean(false);
        AtomicBoolean oddDependentRoutesChanged = new AtomicBoolean(false);
        int numDependentRoutesIterations = 0;
        // Go into iteration mode, until the routes converge (or oscillation is detected)
        do {
            numDependentRoutesIterations++;
            AtomicBoolean currentChangedMonitor;
            if (oscillatingPrefixes.isEmpty()) {
                currentChangedMonitor = dependentRoutesChanged;
            } else if (numDependentRoutesIterations % 2 == 0) {
                currentChangedMonitor = evenDependentRoutesChanged;
            } else {
                currentChangedMonitor = oddDependentRoutesChanged;
            }
            currentChangedMonitor.set(false);
            computeDependentRoutesIteration(nodes, topology, dp, numDependentRoutesIterations, oscillatingPrefixes);
            /* Collect sizes of certain RIBs this iteration */
            computeIterationStatistics(nodes, ae, numDependentRoutesIterations);
            recordIterationDebugInfo(nodes, dp, iterationRoutes, iterationAbstractRoutes, numDependentRoutesIterations);
            // Check to see if hash has changed
            AtomicInteger checkFixedPointCompleted = _newBatch.apply("Iteration " + numDependentRoutesIterations + ": Check if fixed-point reached", nodes.size());
            // This hashcode uniquely identifies the iteration (i.e., network state)
            int iterationHashCode = computeIterationHashCode(nodes);
            SortedSet<Integer> iterationsWithThisHashCode = iterationsByHashCode.computeIfAbsent(iterationHashCode, h -> new TreeSet<>());
            iterationHashCodes.put(numDependentRoutesIterations, iterationHashCode);
            int minNumberOfUnchangedIterationsForConvergence = oscillatingPrefixes.isEmpty() ? 1 : 2;
            if (iterationsWithThisHashCode.isEmpty() || (!oscillatingPrefixes.isEmpty() && iterationsWithThisHashCode.equals(Collections.singleton(numDependentRoutesIterations - 1)))) {
                iterationsWithThisHashCode.add(numDependentRoutesIterations);
            } else if (!iterationsWithThisHashCode.contains(numDependentRoutesIterations - minNumberOfUnchangedIterationsForConvergence)) {
                int lowestIterationWithThisHashCode = iterationsWithThisHashCode.first();
                int completedOscillationRecoveryAttempts = ae.getCompletedOscillationRecoveryAttempts();
                if (!oscillatingPrefixes.isEmpty()) {
                    completedOscillationRecoveryAttempts++;
                    ae.setCompletedOscillationRecoveryAttempts(completedOscillationRecoveryAttempts);
                }
                recoveryIterationHashCodes.put(completedOscillationRecoveryAttempts, iterationHashCodes);
                handleOscillation(recoveryIterationHashCodes, iterationRoutes, iterationAbstractRoutes, lowestIterationWithThisHashCode, numDependentRoutesIterations, iterationOscillatingPrefixes, ae);
                return true;
            }
            compareToPreviousIteration(nodes, currentChangedMonitor, checkFixedPointCompleted);
            computeFibs(nodes);
            initRemoteBgpNeighbors(nodes.entrySet().stream().collect(ImmutableMap.toImmutableMap(Entry::getKey, e -> e.getValue().getConfiguration())), dp.getIpOwners(), true, this, dp);
        } while (checkDependentRoutesChanged(dependentRoutesChanged, evenDependentRoutesChanged, oddDependentRoutesChanged, oscillatingPrefixes, numDependentRoutesIterations));
        AtomicInteger computeBgpAdvertisementsToOutsideCompleted = _newBatch.apply("Compute BGP advertisements sent to outside", nodes.size());
        nodes.values().parallelStream().forEach(n -> {
            for (VirtualRouter vr : n._virtualRouters.values()) {
                vr.computeBgpAdvertisementsToOutside(dp.getIpOwners());
            }
            computeBgpAdvertisementsToOutsideCompleted.incrementAndGet();
        });
        // Set iteration stats in the answer
        ae.setOspfInternalIterations(numOspfInternalIterations);
        ae.setDependentRoutesIterations(numDependentRoutesIterations);
        return false;
    }
}
Also used : SortedSet(java.util.SortedSet) BiFunction(java.util.function.BiFunction) LRUMap(org.apache.commons.collections4.map.LRUMap) FlowTrace(org.batfish.datamodel.FlowTrace) InterfaceAddress(org.batfish.datamodel.InterfaceAddress) Edge(org.batfish.datamodel.Edge) Interface(org.batfish.datamodel.Interface) Flow(org.batfish.datamodel.Flow) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Topology(org.batfish.datamodel.Topology) CommonUtil.initRemoteBgpNeighbors(org.batfish.common.util.CommonUtil.initRemoteBgpNeighbors) Map(java.util.Map) DataPlane(org.batfish.datamodel.DataPlane) ImmutableMap(com.google.common.collect.ImmutableMap) FlowDisposition(org.batfish.datamodel.FlowDisposition) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) Set(java.util.Set) List(java.util.List) SourceNat(org.batfish.datamodel.SourceNat) Entry(java.util.Map.Entry) Optional(java.util.Optional) SortedMap(java.util.SortedMap) BatfishLogger(org.batfish.common.BatfishLogger) Ip(org.batfish.datamodel.Ip) RouteBuilder(org.batfish.datamodel.RouteBuilder) NodeInterfacePair(org.batfish.datamodel.collections.NodeInterfacePair) FilterResult(org.batfish.datamodel.FilterResult) RoutingProtocol(org.batfish.datamodel.RoutingProtocol) BdpAnswerElement(org.batfish.datamodel.answers.BdpAnswerElement) CommonUtil(org.batfish.common.util.CommonUtil) FlowTraceHop(org.batfish.datamodel.FlowTraceHop) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) HashMap(java.util.HashMap) BatfishException(org.batfish.common.BatfishException) BgpProcess(org.batfish.datamodel.BgpProcess) IpAccessList(org.batfish.datamodel.IpAccessList) TreeSet(java.util.TreeSet) ArrayList(java.util.ArrayList) BgpAdvertisement(org.batfish.datamodel.BgpAdvertisement) AbstractRoute(org.batfish.datamodel.AbstractRoute) Version(org.batfish.common.Version) FlowProcessor(org.batfish.common.plugin.FlowProcessor) Configuration(org.batfish.datamodel.Configuration) LineAction(org.batfish.datamodel.LineAction) LinkedHashSet(java.util.LinkedHashSet) Nullable(javax.annotation.Nullable) ImmutableSortedSet(com.google.common.collect.ImmutableSortedSet) Route(org.batfish.datamodel.Route) GlobalTracer(io.opentracing.util.GlobalTracer) BdpOscillationException(org.batfish.common.BdpOscillationException) TreeMap(java.util.TreeMap) ActiveSpan(io.opentracing.ActiveSpan) Collections(java.util.Collections) Prefix(org.batfish.datamodel.Prefix) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) Prefix(org.batfish.datamodel.Prefix) TreeMap(java.util.TreeMap) SortedSet(java.util.SortedSet) ImmutableSortedSet(com.google.common.collect.ImmutableSortedSet) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) Entry(java.util.Map.Entry) ActiveSpan(io.opentracing.ActiveSpan) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) LRUMap(org.apache.commons.collections4.map.LRUMap) SortedMap(java.util.SortedMap)

Example 2 with BdpAnswerElement

use of org.batfish.datamodel.answers.BdpAnswerElement in project batfish by batfish.

the class RouteReflectionTest method generateRoutesTwoReflectors.

private SortedMap<String, SortedMap<String, SortedSet<AbstractRoute>>> generateRoutesTwoReflectors(boolean useSameClusterIds) {
    Ip as1PeeringIp = new Ip("10.12.11.1");
    Ip edge1EbgpIfaceIp = new Ip("10.12.11.2");
    Ip edge1IbgpIfaceIp = new Ip("10.1.12.1");
    Ip edge1LoopbackIp = new Ip("2.0.0.1");
    Ip rr1Edge1IfaceIp = new Ip("10.1.12.2");
    Ip rr1Rr2IfaceIp = new Ip("10.1.23.2");
    Ip rr1LoopbackIp = new Ip("2.0.0.2");
    Ip rr2IbgpIfaceIp = new Ip("10.1.23.3");
    Ip rr2LoopbackIp = new Ip("2.0.0.3");
    StaticRoute.Builder sb = StaticRoute.builder();
    Configuration edge1 = _cb.setHostname(EDGE1_NAME).build();
    Vrf vEdge1 = _vb.setOwner(edge1).build();
    _ib.setOwner(edge1).setVrf(vEdge1);
    _ib.setAddress(new InterfaceAddress(edge1EbgpIfaceIp, EDGE_PREFIX_LENGTH)).build();
    _ib.setAddress(new InterfaceAddress(edge1LoopbackIp, Prefix.MAX_PREFIX_LENGTH)).build();
    _ib.setAddress(new InterfaceAddress(edge1IbgpIfaceIp, EDGE_PREFIX_LENGTH)).build();
    vEdge1.setStaticRoutes(ImmutableSortedSet.of(sb.setNextHopIp(rr1Edge1IfaceIp).setNetwork(new Prefix(rr1LoopbackIp, Prefix.MAX_PREFIX_LENGTH)).build()));
    BgpProcess edge1Proc = _pb.setRouterId(edge1LoopbackIp).setVrf(vEdge1).build();
    RoutingPolicy edge1EbgpExportPolicy = _nullExportPolicyBuilder.setOwner(edge1).build();
    _nb.setOwner(edge1).setVrf(vEdge1).setBgpProcess(edge1Proc).setClusterId(edge1LoopbackIp.asLong()).setRemoteAs(1).setLocalIp(edge1EbgpIfaceIp).setPeerAddress(as1PeeringIp).setExportPolicy(edge1EbgpExportPolicy.getName()).build();
    RoutingPolicy edge1IbgpExportPolicy = _defaultExportPolicyBuilder.setOwner(edge1).build();
    _nb.setRemoteAs(2).setLocalIp(edge1LoopbackIp).setPeerAddress(rr1LoopbackIp).setExportPolicy(edge1IbgpExportPolicy.getName()).build();
    Configuration rr1 = _cb.setHostname(RR1_NAME).build();
    Vrf vRr1 = _vb.setOwner(rr1).build();
    _ib.setOwner(rr1).setVrf(vRr1);
    _ib.setAddress(new InterfaceAddress(rr1Edge1IfaceIp, EDGE_PREFIX_LENGTH)).build();
    _ib.setAddress(new InterfaceAddress(rr1LoopbackIp, Prefix.MAX_PREFIX_LENGTH)).build();
    _ib.setAddress(new InterfaceAddress(rr1Rr2IfaceIp, EDGE_PREFIX_LENGTH)).build();
    vRr1.setStaticRoutes(ImmutableSortedSet.of(sb.setNextHopIp(edge1IbgpIfaceIp).setNetwork(new Prefix(edge1LoopbackIp, Prefix.MAX_PREFIX_LENGTH)).build(), sb.setNextHopIp(rr2IbgpIfaceIp).setNetwork(new Prefix(rr2LoopbackIp, Prefix.MAX_PREFIX_LENGTH)).build()));
    BgpProcess rr1Proc = _pb.setRouterId(rr1LoopbackIp).setVrf(vRr1).build();
    RoutingPolicy rr1ExportPolicy = _defaultExportPolicyBuilder.setOwner(rr1).build();
    _nb.setOwner(rr1).setVrf(vRr1).setBgpProcess(rr1Proc).setClusterId(rr1LoopbackIp.asLong()).setRemoteAs(2).setLocalIp(rr1LoopbackIp).setExportPolicy(rr1ExportPolicy.getName()).setRouteReflectorClient(true).setPeerAddress(edge1LoopbackIp).build();
    _nb.setRouteReflectorClient(false).setPeerAddress(rr2LoopbackIp).build();
    Configuration rr2 = _cb.setHostname(RR2_NAME).build();
    Vrf vRr2 = _vb.setOwner(rr2).build();
    _ib.setOwner(rr2).setVrf(vRr2);
    _ib.setAddress(new InterfaceAddress(rr2LoopbackIp, Prefix.MAX_PREFIX_LENGTH)).build();
    _ib.setAddress(new InterfaceAddress(rr2IbgpIfaceIp, EDGE_PREFIX_LENGTH)).build();
    BgpProcess rr2Proc = _pb.setRouterId(rr2LoopbackIp).setVrf(vRr2).build();
    RoutingPolicy edge2IbgpExportPolicy = _defaultExportPolicyBuilder.setOwner(rr2).build();
    vRr2.setStaticRoutes(ImmutableSortedSet.of(sb.setNextHopIp(rr1Rr2IfaceIp).setNetwork(new Prefix(rr1LoopbackIp, Prefix.MAX_PREFIX_LENGTH)).build()));
    Ip rr2ClusterIdForRr1 = useSameClusterIds ? rr1LoopbackIp : rr2LoopbackIp;
    _nb.setOwner(rr2).setVrf(vRr2).setBgpProcess(rr2Proc).setClusterId(rr2ClusterIdForRr1.asLong()).setLocalIp(rr2LoopbackIp).setPeerAddress(rr1LoopbackIp).setRouteReflectorClient(true).setExportPolicy(edge2IbgpExportPolicy.getName()).build();
    SortedMap<String, Configuration> configurations = new ImmutableSortedMap.Builder<String, Configuration>(String::compareTo).put(edge1.getName(), edge1).put(rr1.getName(), rr1).put(rr2.getName(), rr2).build();
    BdpEngine engine = new BdpEngine(new MockBdpSettings(), new BatfishLogger(BatfishLogger.LEVELSTR_OUTPUT, false), (s, i) -> new AtomicInteger());
    Topology topology = CommonUtil.synthesizeTopology(configurations);
    BdpDataPlane dp = engine.computeDataPlane(false, configurations, topology, ImmutableSet.of(_ab.setAsPath(AsPath.ofSingletonAsSets(1)).setDstIp(edge1EbgpIfaceIp).setDstNode(edge1.getName()).setNetwork(AS1_PREFIX).setNextHopIp(as1PeeringIp).setOriginatorIp(as1PeeringIp).setSrcIp(as1PeeringIp).setSrcNode("as1Edge").build()), new BdpAnswerElement());
    return engine.getRoutes(dp);
}
Also used : StaticRoute(org.batfish.datamodel.StaticRoute) BdpAnswerElement(org.batfish.datamodel.answers.BdpAnswerElement) Configuration(org.batfish.datamodel.Configuration) BatfishLogger(org.batfish.common.BatfishLogger) BgpProcess(org.batfish.datamodel.BgpProcess) InterfaceAddress(org.batfish.datamodel.InterfaceAddress) Ip(org.batfish.datamodel.Ip) RoutingPolicy(org.batfish.datamodel.routing_policy.RoutingPolicy) Vrf(org.batfish.datamodel.Vrf) AbstractRouteMatchers.hasPrefix(org.batfish.datamodel.matchers.AbstractRouteMatchers.hasPrefix) Prefix(org.batfish.datamodel.Prefix) Topology(org.batfish.datamodel.Topology) AtomicInteger(java.util.concurrent.atomic.AtomicInteger)

Example 3 with BdpAnswerElement

use of org.batfish.datamodel.answers.BdpAnswerElement in project batfish by batfish.

the class BdpDataPlanePlugin method computeDataPlane.

@Override
public ComputeDataPlaneResult computeDataPlane(boolean differentialContext, Map<String, Configuration> configurations, Topology topology) {
    BdpAnswerElement ae = new BdpAnswerElement();
    Set<BgpAdvertisement> externalAdverts = _batfish.loadExternalBgpAnnouncements(configurations);
    BdpDataPlane dp = _engine.computeDataPlane(differentialContext, configurations, topology, externalAdverts, ae);
    double averageRoutes = dp.getNodes().values().stream().flatMap(n -> n._virtualRouters.values().stream()).mapToInt(vr -> vr._mainRib.getRoutes().size()).average().orElse(0.00d);
    _logger.infof("Generated data plane for testrig:%s in container:%s; iterations:%s, total nodes:%s, " + "avg entries per node:%.2f, work-id:%s\n", _batfish.getTestrigName(), _batfish.getContainerName(), ae.getDependentRoutesIterations(), configurations.size(), averageRoutes, _batfish.getTaskId());
    return new ComputeDataPlaneResult(ae, dp);
}
Also used : Plugin(org.batfish.common.plugin.Plugin) DataPlane(org.batfish.datamodel.DataPlane) SortedSet(java.util.SortedSet) BdpAnswerElement(org.batfish.datamodel.answers.BdpAnswerElement) Set(java.util.Set) HashMap(java.util.HashMap) FlowTrace(org.batfish.datamodel.FlowTrace) DataPlanePlugin(org.batfish.common.plugin.DataPlanePlugin) ArrayList(java.util.ArrayList) BgpAdvertisement(org.batfish.datamodel.BgpAdvertisement) Flow(org.batfish.datamodel.Flow) List(java.util.List) AbstractRoute(org.batfish.datamodel.AbstractRoute) Topology(org.batfish.datamodel.Topology) IbgpTopology(org.batfish.datamodel.collections.IbgpTopology) AutoService(com.google.auto.service.AutoService) Map(java.util.Map) Configuration(org.batfish.datamodel.Configuration) LinkedHashSet(java.util.LinkedHashSet) SortedMap(java.util.SortedMap) BgpAdvertisement(org.batfish.datamodel.BgpAdvertisement) BdpAnswerElement(org.batfish.datamodel.answers.BdpAnswerElement)

Example 4 with BdpAnswerElement

use of org.batfish.datamodel.answers.BdpAnswerElement in project batfish by batfish.

the class BdpDataPlanePluginTest method testStaticInterfaceRoutesWithoutEdge.

@Test
public void testStaticInterfaceRoutesWithoutEdge() {
    NetworkFactory nf = new NetworkFactory();
    Configuration c = nf.configurationBuilder().setConfigurationFormat(ConfigurationFormat.CISCO_IOS).build();
    Vrf vrf = nf.vrfBuilder().setOwner(c).setName(DEFAULT_VRF_NAME).build();
    Interface i = nf.interfaceBuilder().setOwner(c).setVrf(vrf).setAddress(new InterfaceAddress("10.0.0.0/24")).setActive(true).build();
    StaticRoute srBoth = StaticRoute.builder().setNetwork(Prefix.parse("10.0.1.0/24")).setNextHopInterface(i.getName()).setNextHopIp(new Ip("10.0.0.1")).build();
    vrf.getStaticRoutes().add(srBoth);
    StaticRoute srJustInterface = StaticRoute.builder().setNetwork(Prefix.parse("10.0.2.0/24")).setNextHopInterface(i.getName()).build();
    vrf.getStaticRoutes().add(srJustInterface);
    BdpEngine engine = new BdpEngine(new MockBdpSettings(), new BatfishLogger(BatfishLogger.LEVELSTR_DEBUG, false), (a, b) -> new AtomicInteger());
    Topology topology = new Topology(Collections.emptySortedSet());
    BdpDataPlane dp = engine.computeDataPlane(false, ImmutableMap.of(c.getName(), c), topology, Collections.emptySet(), new BdpAnswerElement());
    // generating fibs should not crash
    dp.getFibs();
}
Also used : StaticRoute(org.batfish.datamodel.StaticRoute) BdpAnswerElement(org.batfish.datamodel.answers.BdpAnswerElement) Configuration(org.batfish.datamodel.Configuration) BatfishLogger(org.batfish.common.BatfishLogger) InterfaceAddress(org.batfish.datamodel.InterfaceAddress) Ip(org.batfish.datamodel.Ip) RoutesByVrf(org.batfish.datamodel.collections.RoutesByVrf) Vrf(org.batfish.datamodel.Vrf) Topology(org.batfish.datamodel.Topology) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) NetworkFactory(org.batfish.datamodel.NetworkFactory) Interface(org.batfish.datamodel.Interface) Test(org.junit.Test)

Example 5 with BdpAnswerElement

use of org.batfish.datamodel.answers.BdpAnswerElement in project batfish by batfish.

the class OspfTest method getOspfRoutes.

/*
   * Int:1/2   2/1      2/3   3/2      3/4   4/3
   * R1 <=========> R2 <=========> R3 <=========> R4
   *  A      B       C      D       E      F       G
   *
   *  Areas:
   *  A: R1 Loopback0
   *  B: R1 E1/2, R2 E2/1
   *  C: R2 Loopback0
   *  D: R2 E2/3, R3 E3/2
   *  E: R3 Loopback0
   *  F: R3 E3/4, R4 E4/3
   *  G: R4 Loopback0
   */
private SortedMap<String, SortedMap<String, SortedSet<AbstractRoute>>> getOspfRoutes(long areaA, long areaB, long areaC, long areaD, long areaE, long areaF, long areaG, Long maxMetricExternalNetworks, Long maxMetricStubNetworks, Long maxMetricSummaryNetworks, Long maxMetricTransitLinks) {
    String l0Name = "Loopback0";
    String l1Name = "Loopback1";
    String c1E1To2Name = "Ethernet1/2";
    String c2E2To1Name = "Ethernet2/1";
    String c2E2To3Name = "Ethernet2/3";
    String c3E3To2Name = "Ethernet3/2";
    String c3E3To4Name = "Ethernet3/4";
    String c4E4To3Name = "Ethernet4/3";
    RoutingPolicy.Builder rpb = _nf.routingPolicyBuilder();
    OspfArea.Builder oaba = _nf.ospfAreaBuilder().setNumber(areaA);
    OspfArea.Builder oabb = _nf.ospfAreaBuilder().setNumber(areaB);
    OspfArea.Builder oabc = _nf.ospfAreaBuilder().setNumber(areaC);
    OspfArea.Builder oabd = _nf.ospfAreaBuilder().setNumber(areaD);
    OspfArea.Builder oabe = _nf.ospfAreaBuilder().setNumber(areaE);
    OspfArea.Builder oabf = _nf.ospfAreaBuilder().setNumber(areaF);
    OspfArea.Builder oabg = _nf.ospfAreaBuilder().setNumber(areaG);
    Configuration c1 = _cb.setHostname(C1_NAME).build();
    Vrf v1 = _vb.setOwner(c1).build();
    RoutingPolicy c1ExportPolicy = rpb.setOwner(c1).setStatements(getExportPolicyStatements(C1_L1_ADDRESS)).build();
    OspfProcess op1 = _opb.setVrf(v1).setExportPolicy(c1ExportPolicy).build();
    OspfArea oa1a = oaba.setOspfProcess(op1).build();
    OspfArea oa1b = areaA == areaB ? oa1a : oabb.setOspfProcess(op1).build();
    _ib.setOwner(c1).setVrf(v1).setOspfArea(oa1a);
    _ib.setOspfPassive(true).setName(l0Name).setAddress(C1_L0_ADDRESS).build();
    _ib.setOspfEnabled(false).setOspfPassive(false).setOspfArea(null).setName(l1Name).setAddress(C1_L1_ADDRESS).build();
    _ib.setOspfEnabled(true).setOspfArea(oa1b);
    _ib.setName(c1E1To2Name).setAddress(C1_E1_2_ADDRESS).build();
    Configuration c2 = _cb.setHostname(C2_NAME).build();
    Vrf v2 = _vb.setOwner(c2).build();
    RoutingPolicy c2ExportPolicy = rpb.setOwner(c2).setStatements(getExportPolicyStatements(C2_L1_ADDRESS)).build();
    OspfProcess op2 = _opb.setVrf(v2).setMaxMetricExternalNetworks(maxMetricExternalNetworks).setMaxMetricStubNetworks(maxMetricStubNetworks).setMaxMetricSummaryNetworks(maxMetricSummaryNetworks).setMaxMetricTransitLinks(maxMetricTransitLinks).setExportPolicy(c2ExportPolicy).build();
    _opb.setMaxMetricExternalNetworks(null).setMaxMetricStubNetworks(null).setMaxMetricSummaryNetworks(null).setMaxMetricTransitLinks(null);
    OspfArea oa2b = oabb.setOspfProcess(op2).build();
    OspfArea oa2c = areaB == areaC ? oa2b : oabc.setOspfProcess(op2).build();
    OspfArea oa2d = areaB == areaD ? oa2b : areaC == areaD ? oa2c : oabd.setOspfProcess(op2).build();
    _ib.setOwner(c2).setVrf(v2).setOspfArea(oa2c);
    _ib.setOspfPassive(true).setName(l0Name).setAddress(C2_L0_ADDRESS).build();
    _ib.setOspfEnabled(false).setOspfPassive(false).setOspfArea(null).setName(l1Name).setAddress(C2_L1_ADDRESS).build();
    _ib.setOspfEnabled(true).setOspfArea(oa2b);
    _ib.setName(c2E2To1Name).setAddress(C2_E2_1_ADDRESS).setOspfPointToPoint(true).build();
    _ib.setOspfPointToPoint(false).setOspfArea(oa2d);
    _ib.setName(c2E2To3Name).setAddress(C2_E2_3_ADDRESS).build();
    Configuration c3 = _cb.setHostname(C3_NAME).build();
    Vrf v3 = _vb.setOwner(c3).build();
    RoutingPolicy c3ExportPolicy = rpb.setOwner(c3).setStatements(getExportPolicyStatements(C3_L1_ADDRESS)).build();
    OspfProcess op3 = _opb.setVrf(v3).setExportPolicy(c3ExportPolicy).build();
    OspfArea oa3d = oabd.setOspfProcess(op3).build();
    OspfArea oa3e = areaD == areaE ? oa3d : oabe.setOspfProcess(op3).build();
    OspfArea oa3f = areaD == areaF ? oa3d : areaE == areaF ? oa3e : oabf.setOspfProcess(op3).build();
    _ib.setOwner(c3).setVrf(v3).setOspfArea(oa3e);
    _ib.setOspfPassive(true).setName(l0Name).setAddress(C3_L0_ADDRESS).build();
    _ib.setOspfEnabled(false).setOspfPassive(false).setOspfArea(null).setName(l1Name).setAddress(C3_L1_ADDRESS).build();
    _ib.setOspfEnabled(true).setOspfArea(oa3d);
    _ib.setName(c3E3To2Name).setAddress(C3_E3_2_ADDRESS).build();
    _ib.setName(c3E3To4Name).setAddress(C3_E3_4_ADDRESS).setOspfArea(oa3f).build();
    Configuration c4 = _cb.setHostname(C4_NAME).build();
    Vrf v4 = _vb.setOwner(c4).build();
    RoutingPolicy c4ExportPolicy = rpb.setOwner(c4).setStatements(getExportPolicyStatements(C4_L1_ADDRESS)).build();
    OspfProcess op4 = _opb.setVrf(v4).setExportPolicy(c4ExportPolicy).build();
    OspfArea oa4f = oabf.setOspfProcess(op4).build();
    OspfArea oa4g = areaF == areaG ? oa4f : oabg.setOspfProcess(op4).build();
    _ib.setOwner(c4).setVrf(v4).setOspfArea(oa4g);
    _ib.setOspfPassive(true).setName(l0Name).setAddress(C4_L0_ADDRESS).build();
    _ib.setOspfEnabled(false).setOspfPassive(false).setOspfArea(null).setName(l1Name).setAddress(C4_L1_ADDRESS).build();
    _ib.setOspfEnabled(true).setOspfArea(oa4f);
    _ib.setName(c4E4To3Name).setAddress(C4_E4_3_ADDRESS).build();
    SortedMap<String, Configuration> configurations = new ImmutableSortedMap.Builder<String, Configuration>(String::compareTo).put(c1.getName(), c1).put(c2.getName(), c2).put(c3.getName(), c3).put(c4.getName(), c4).build();
    BdpEngine engine = new BdpEngine(new MockBdpSettings(), new BatfishLogger(BatfishLogger.LEVELSTR_OUTPUT, false), (s, i) -> new AtomicInteger());
    Topology topology = CommonUtil.synthesizeTopology(configurations);
    BdpDataPlane dp = engine.computeDataPlane(false, configurations, topology, Collections.emptySet(), new BdpAnswerElement());
    return engine.getRoutes(dp);
}
Also used : OspfArea(org.batfish.datamodel.OspfArea) BdpAnswerElement(org.batfish.datamodel.answers.BdpAnswerElement) Configuration(org.batfish.datamodel.Configuration) BatfishLogger(org.batfish.common.BatfishLogger) ImmutableSortedMap(com.google.common.collect.ImmutableSortedMap) RoutingPolicy(org.batfish.datamodel.routing_policy.RoutingPolicy) OspfProcess(org.batfish.datamodel.OspfProcess) Vrf(org.batfish.datamodel.Vrf) Topology(org.batfish.datamodel.Topology) AtomicInteger(java.util.concurrent.atomic.AtomicInteger)

Aggregations

Configuration (org.batfish.datamodel.Configuration)6 Topology (org.batfish.datamodel.Topology)6 BdpAnswerElement (org.batfish.datamodel.answers.BdpAnswerElement)6 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)5 BatfishLogger (org.batfish.common.BatfishLogger)5 InterfaceAddress (org.batfish.datamodel.InterfaceAddress)4 Ip (org.batfish.datamodel.Ip)4 BgpProcess (org.batfish.datamodel.BgpProcess)3 Prefix (org.batfish.datamodel.Prefix)3 Vrf (org.batfish.datamodel.Vrf)3 ArrayList (java.util.ArrayList)2 HashMap (java.util.HashMap)2 LinkedHashSet (java.util.LinkedHashSet)2 List (java.util.List)2 Map (java.util.Map)2 Set (java.util.Set)2 SortedMap (java.util.SortedMap)2 SortedSet (java.util.SortedSet)2 AbstractRoute (org.batfish.datamodel.AbstractRoute)2 BgpAdvertisement (org.batfish.datamodel.BgpAdvertisement)2