Search in sources :

Example 1 with NetworkSlice

use of org.batfish.symbolic.abstraction.NetworkSlice in project batfish by batfish.

the class PropertyChecker method checkForwarding.

/*
   * Compute the forwarding behavior for the network. This adds no
   * additional constraints on top of the base network encoding.
   * Forwarding will be determined only for a particular network
   * environment, failure scenario, and data plane packet.
   */
public AnswerElement checkForwarding(HeaderQuestion question) {
    long totalTime = System.currentTimeMillis();
    HeaderQuestion q = new HeaderQuestion(question);
    q.setFailures(0);
    Tuple<Stream<Supplier<NetworkSlice>>, Long> ecs = findAllNetworkSlices(q, null, true);
    Stream<Supplier<NetworkSlice>> stream = ecs.getFirst();
    Long timeAbstraction = ecs.getSecond();
    Optional<Supplier<NetworkSlice>> opt = stream.findFirst();
    if (!opt.isPresent()) {
        throw new BatfishException("Unexpected Error: checkForwarding");
    }
    long timeEc = System.currentTimeMillis();
    Supplier<NetworkSlice> sup = opt.get();
    NetworkSlice slice = sup.get();
    timeEc = System.currentTimeMillis() - timeEc;
    Graph g = slice.getGraph();
    q = new HeaderQuestion(q);
    q.setHeaderSpace(slice.getHeaderSpace());
    long timeEncoding = System.currentTimeMillis();
    Encoder encoder = new Encoder(_settings, g, q);
    encoder.computeEncoding();
    addEnvironmentConstraints(encoder, q.getBaseEnvironmentType());
    timeEncoding = System.currentTimeMillis() - timeEncoding;
    VerificationResult result = encoder.verify().getFirst();
    totalTime = System.currentTimeMillis() - totalTime;
    VerificationStats stats = result.getStats();
    if (q.getBenchmark()) {
        stats.setTimeCreateBdds((double) timeAbstraction);
        stats.setTotalTime(totalTime);
        stats.setAvgComputeEcTime(timeEc);
        stats.setMaxComputeEcTime(timeEc);
        stats.setMinComputeEcTime(timeEc);
        stats.setAvgEncodingTime(timeEncoding);
        stats.setMaxEncodingTime(timeEncoding);
        stats.setMinEncodingTime(timeEncoding);
        stats.setTimeCreateBdds((double) timeAbstraction);
    }
    return new SmtOneAnswerElement(result);
}
Also used : BatfishException(org.batfish.common.BatfishException) SmtOneAnswerElement(org.batfish.symbolic.answers.SmtOneAnswerElement) NetworkSlice(org.batfish.symbolic.abstraction.NetworkSlice) Graph(org.batfish.symbolic.Graph) HeaderQuestion(org.batfish.datamodel.questions.smt.HeaderQuestion) Stream(java.util.stream.Stream) Supplier(java.util.function.Supplier)

Example 2 with NetworkSlice

use of org.batfish.symbolic.abstraction.NetworkSlice in project batfish by batfish.

the class PropertyChecker method checkProperty.

/*
   * General purpose logic for checking a property that holds that
   * handles the various flags and parameters for a query with endpoints
   *
   * q is the question from the user.
   * instrument instruments each router in the graph as needed to check the property.
   * answer takes the result from Z3 and produces the answer for the user.
   *
   */
private AnswerElement checkProperty(HeaderLocationQuestion q, TriFunction<Encoder, Set<String>, Set<GraphEdge>, Map<String, BoolExpr>> instrument, Function<VerifyParam, AnswerElement> answer) {
    long totalTime = System.currentTimeMillis();
    PathRegexes p = new PathRegexes(q);
    Graph graph = new Graph(_batfish);
    Set<GraphEdge> destPorts = findFinalInterfaces(graph, p);
    List<String> sourceRouters = PatternUtils.findMatchingSourceNodes(graph, p);
    if (destPorts.isEmpty()) {
        throw new BatfishException("Set of valid destination interfaces is empty");
    }
    if (sourceRouters.isEmpty()) {
        throw new BatfishException("Set of valid ingress nodes is empty");
    }
    inferDestinationHeaderSpace(graph, destPorts, q);
    Set<GraphEdge> failOptions = failLinkSet(graph, q);
    Tuple<Stream<Supplier<NetworkSlice>>, Long> ecs = findAllNetworkSlices(q, graph, true);
    Stream<Supplier<NetworkSlice>> stream = ecs.getFirst();
    Long timeAbstraction = ecs.getSecond();
    AnswerElement[] answerElement = new AnswerElement[1];
    VerificationResult[] result = new VerificationResult[2];
    List<VerificationStats> ecStats = new ArrayList<>();
    // Checks ECs in parallel, but short circuits when a counterexample is found
    boolean hasCounterExample = stream.anyMatch(lazyEc -> {
        long timeEc = System.currentTimeMillis();
        NetworkSlice slice = lazyEc.get();
        timeEc = System.currentTimeMillis() - timeEc;
        synchronized (_lock) {
            // Make sure the headerspace is correct
            HeaderLocationQuestion question = new HeaderLocationQuestion(q);
            question.setHeaderSpace(slice.getHeaderSpace());
            // Get the EC graph and mapping
            Graph g = slice.getGraph();
            Set<String> srcRouters = mapConcreteToAbstract(slice, sourceRouters);
            long timeEncoding = System.currentTimeMillis();
            Encoder enc = new Encoder(_settings, g, question);
            enc.computeEncoding();
            timeEncoding = System.currentTimeMillis() - timeEncoding;
            // Add environment constraints for base case
            if (question.getDiffType() != null) {
                if (question.getEnvDiff()) {
                    addEnvironmentConstraints(enc, question.getDeltaEnvironmentType());
                }
            } else {
                addEnvironmentConstraints(enc, question.getBaseEnvironmentType());
            }
            Map<String, BoolExpr> prop = instrument.apply(enc, srcRouters, destPorts);
            // If this is a equivalence query, we create a second copy of the network
            Encoder enc2 = null;
            Map<String, BoolExpr> prop2 = null;
            if (question.getDiffType() != null) {
                HeaderLocationQuestion q2 = new HeaderLocationQuestion(question);
                q2.setFailures(0);
                long timeDiffEncoding = System.currentTimeMillis();
                enc2 = new Encoder(enc, g, q2);
                enc2.computeEncoding();
                timeDiffEncoding = System.currentTimeMillis() - timeDiffEncoding;
                timeEncoding += timeDiffEncoding;
            }
            if (question.getDiffType() != null) {
                assert (enc2 != null);
                // create a map for enc2 to lookup a related environment variable from enc
                Table2<GraphEdge, EdgeType, SymbolicRoute> relatedEnv = new Table2<>();
                enc2.getMainSlice().getLogicalGraph().getEnvironmentVars().forEach((lge, r) -> relatedEnv.put(lge.getEdge(), lge.getEdgeType(), r));
                BoolExpr related = enc.mkTrue();
                addEnvironmentConstraints(enc2, question.getBaseEnvironmentType());
                if (!question.getEnvDiff()) {
                    related = relateEnvironments(enc, enc2);
                }
                prop2 = instrument.apply(enc2, srcRouters, destPorts);
                // Add diff constraints
                BoolExpr required = enc.mkTrue();
                for (String source : srcRouters) {
                    BoolExpr sourceProp1 = prop.get(source);
                    BoolExpr sourceProp2 = prop2.get(source);
                    BoolExpr val;
                    switch(q.getDiffType()) {
                        case INCREASED:
                            val = enc.mkImplies(sourceProp1, sourceProp2);
                            break;
                        case REDUCED:
                            val = enc.mkImplies(sourceProp2, sourceProp1);
                            break;
                        case ANY:
                            val = enc.mkEq(sourceProp1, sourceProp2);
                            break;
                        default:
                            throw new BatfishException("Missing case: " + q.getDiffType());
                    }
                    required = enc.mkAnd(required, val);
                }
                related = enc.mkAnd(related, relatePackets(enc, enc2));
                enc.add(related);
                enc.add(enc.mkNot(required));
            } else {
                // Not a differential query; just a query on a single version of the network.
                BoolExpr allProp = enc.mkTrue();
                for (String router : srcRouters) {
                    BoolExpr r = prop.get(router);
                    if (q.getNegate()) {
                        r = enc.mkNot(r);
                    }
                    allProp = enc.mkAnd(allProp, r);
                }
                enc.add(enc.mkNot(allProp));
            }
            addFailureConstraints(enc, destPorts, failOptions);
            Tuple<VerificationResult, Model> tup = enc.verify();
            VerificationResult res = tup.getFirst();
            Model model = tup.getSecond();
            if (q.getBenchmark()) {
                VerificationStats stats = res.getStats();
                stats.setAvgComputeEcTime(timeEc);
                stats.setMaxComputeEcTime(timeEc);
                stats.setMinComputeEcTime(timeEc);
                stats.setAvgEncodingTime(timeEncoding);
                stats.setMaxEncodingTime(timeEncoding);
                stats.setMinEncodingTime(timeEncoding);
                stats.setTimeCreateBdds((double) timeAbstraction);
                synchronized (_lock) {
                    ecStats.add(stats);
                }
            }
            if (!res.isVerified()) {
                VerifyParam vp = new VerifyParam(res, model, srcRouters, enc, enc2, prop, prop2);
                AnswerElement ae = answer.apply(vp);
                synchronized (_lock) {
                    answerElement[0] = ae;
                    result[0] = res;
                }
                return true;
            }
            synchronized (_lock) {
                result[1] = res;
            }
            return false;
        }
    });
    totalTime = (System.currentTimeMillis() - totalTime);
    VerificationResult res;
    AnswerElement ae;
    if (hasCounterExample) {
        res = result[0];
        ae = answerElement[0];
    } else {
        res = result[1];
        VerifyParam vp = new VerifyParam(res, null, null, null, null, null, null);
        ae = answer.apply(vp);
    }
    if (q.getBenchmark()) {
        VerificationStats stats = VerificationStats.combineAll(ecStats, totalTime);
        res.setStats(stats);
    }
    return ae;
}
Also used : BoolExpr(com.microsoft.z3.BoolExpr) HeaderLocationQuestion(org.batfish.datamodel.questions.smt.HeaderLocationQuestion) ArrayList(java.util.ArrayList) PathRegexes(org.batfish.symbolic.utils.PathRegexes) NetworkSlice(org.batfish.symbolic.abstraction.NetworkSlice) Table2(org.batfish.symbolic.collections.Table2) Stream(java.util.stream.Stream) Supplier(java.util.function.Supplier) BatfishException(org.batfish.common.BatfishException) SmtOneAnswerElement(org.batfish.symbolic.answers.SmtOneAnswerElement) SmtDeterminismAnswerElement(org.batfish.symbolic.answers.SmtDeterminismAnswerElement) SmtReachabilityAnswerElement(org.batfish.symbolic.answers.SmtReachabilityAnswerElement) AnswerElement(org.batfish.datamodel.answers.AnswerElement) SmtManyAnswerElement(org.batfish.symbolic.answers.SmtManyAnswerElement) Graph(org.batfish.symbolic.Graph) Model(com.microsoft.z3.Model) GraphEdge(org.batfish.symbolic.GraphEdge)

Example 3 with NetworkSlice

use of org.batfish.symbolic.abstraction.NetworkSlice in project batfish by batfish.

the class PropertyChecker method findAllNetworkSlices.

private Tuple<Stream<Supplier<NetworkSlice>>, Long> findAllNetworkSlices(HeaderQuestion q, @Nullable Graph graph, boolean useDefaultCase) {
    if (q.getUseAbstraction()) {
        HeaderSpace h = q.getHeaderSpace();
        int numFailures = q.getFailures();
        System.out.println("Start verification");
        System.out.println("Using headerspace: " + h.getDstIps());
        DestinationClasses dcs = DestinationClasses.create(_batfish, graph, h, useDefaultCase);
        System.out.println("Number of edges: " + dcs.getGraph().getAllRealEdges().size());
        System.out.println("Created destination classes");
        System.out.println("Num Classes: " + dcs.getHeaderspaceMap().size());
        long l = System.currentTimeMillis();
        ArrayList<Supplier<NetworkSlice>> ecs = NetworkSlice.allSlices(dcs, numFailures);
        l = System.currentTimeMillis() - l;
        System.out.println("Created BDDs");
        return new Tuple<>(ecs.parallelStream(), l);
    } else {
        List<Supplier<NetworkSlice>> singleEc = new ArrayList<>();
        Graph g = graph == null ? new Graph(_batfish) : graph;
        Abstraction a = new Abstraction(g, null);
        NetworkSlice slice = new NetworkSlice(q.getHeaderSpace(), a, false);
        Supplier<NetworkSlice> sup = () -> slice;
        singleEc.add(sup);
        return new Tuple<>(singleEc.stream(), 0L);
    }
}
Also used : ArrayList(java.util.ArrayList) HeaderSpace(org.batfish.datamodel.HeaderSpace) DestinationClasses(org.batfish.symbolic.abstraction.DestinationClasses) Abstraction(org.batfish.symbolic.abstraction.Abstraction) NetworkSlice(org.batfish.symbolic.abstraction.NetworkSlice) Graph(org.batfish.symbolic.Graph) Supplier(java.util.function.Supplier) Tuple(org.batfish.symbolic.utils.Tuple)

Aggregations

Supplier (java.util.function.Supplier)3 Graph (org.batfish.symbolic.Graph)3 NetworkSlice (org.batfish.symbolic.abstraction.NetworkSlice)3 ArrayList (java.util.ArrayList)2 Stream (java.util.stream.Stream)2 BatfishException (org.batfish.common.BatfishException)2 SmtOneAnswerElement (org.batfish.symbolic.answers.SmtOneAnswerElement)2 BoolExpr (com.microsoft.z3.BoolExpr)1 Model (com.microsoft.z3.Model)1 HeaderSpace (org.batfish.datamodel.HeaderSpace)1 AnswerElement (org.batfish.datamodel.answers.AnswerElement)1 HeaderLocationQuestion (org.batfish.datamodel.questions.smt.HeaderLocationQuestion)1 HeaderQuestion (org.batfish.datamodel.questions.smt.HeaderQuestion)1 GraphEdge (org.batfish.symbolic.GraphEdge)1 Abstraction (org.batfish.symbolic.abstraction.Abstraction)1 DestinationClasses (org.batfish.symbolic.abstraction.DestinationClasses)1 SmtDeterminismAnswerElement (org.batfish.symbolic.answers.SmtDeterminismAnswerElement)1 SmtManyAnswerElement (org.batfish.symbolic.answers.SmtManyAnswerElement)1 SmtReachabilityAnswerElement (org.batfish.symbolic.answers.SmtReachabilityAnswerElement)1 Table2 (org.batfish.symbolic.collections.Table2)1