Search in sources :

Example 21 with GraphEdge

use of org.batfish.symbolic.GraphEdge in project batfish by batfish.

the class CounterExample method buildFailedLinks.

SortedSet<Edge> buildFailedLinks(Encoder enc) {
    Set<GraphEdge> failed = new HashSet<>();
    Graph g = enc.getMainSlice().getGraph();
    for (List<GraphEdge> edges : g.getEdgeMap().values()) {
        for (GraphEdge ge : edges) {
            ArithExpr e = enc.getSymbolicFailures().getFailedVariable(ge);
            assert e != null;
            if (intVal(e) != 0) {
                // Don't add both directions?
                GraphEdge other = g.getOtherEnd().get(ge);
                if (other == null || !failed.contains(other)) {
                    failed.add(ge);
                }
            }
        }
    }
    // Convert to Batfish Edge type
    SortedSet<Edge> failedEdges = new TreeSet<>();
    for (GraphEdge ge : failed) {
        failedEdges.add(fromGraphEdge(ge));
    }
    return failedEdges;
}
Also used : ArithExpr(com.microsoft.z3.ArithExpr) Graph(org.batfish.symbolic.Graph) TreeSet(java.util.TreeSet) GraphEdge(org.batfish.symbolic.GraphEdge) Edge(org.batfish.datamodel.Edge) GraphEdge(org.batfish.symbolic.GraphEdge) HashSet(java.util.HashSet)

Example 22 with GraphEdge

use of org.batfish.symbolic.GraphEdge in project batfish by batfish.

the class CounterExample method buildEnvRoutingTable.

SortedSet<BgpAdvertisement> buildEnvRoutingTable(Encoder enc) {
    SortedSet<BgpAdvertisement> routes = new TreeSet<>();
    EncoderSlice slice = enc.getMainSlice();
    LogicalGraph lg = slice.getLogicalGraph();
    for (Entry<LogicalEdge, SymbolicRoute> entry : lg.getEnvironmentVars().entrySet()) {
        LogicalEdge lge = entry.getKey();
        SymbolicRoute record = entry.getValue();
        // If there is an external advertisement
        if (boolVal(record.getPermitted())) {
            // If we actually use it
            GraphEdge ge = lge.getEdge();
            String router = ge.getRouter();
            SymbolicDecisions decisions = slice.getSymbolicDecisions();
            BoolExpr ctrFwd = decisions.getControlForwarding().get(router, ge);
            assert ctrFwd != null;
            if (boolVal(ctrFwd)) {
                SymbolicRoute r = decisions.getBestNeighbor().get(router);
                SymbolicPacket pkt = slice.getSymbolicPacket();
                Flow f = buildFlow(pkt, router);
                Prefix pfx = buildPrefix(r, f);
                int pathLength = intVal(r.getMetric());
                // Create dummy information
                BgpNeighbor n = slice.getGraph().getEbgpNeighbors().get(lge.getEdge());
                String srcNode = "as" + n.getRemoteAs();
                Ip zeroIp = new Ip(0);
                Ip dstIp = n.getLocalIp();
                // Recover AS path
                List<SortedSet<Integer>> asSets = new ArrayList<>();
                for (int i = 0; i < pathLength; i++) {
                    SortedSet<Integer> asSet = new TreeSet<>();
                    asSet.add(-1);
                    asSets.add(asSet);
                }
                AsPath path = new AsPath(asSets);
                // Recover communities
                SortedSet<Long> communities = new TreeSet<>();
                for (Entry<CommunityVar, BoolExpr> entry2 : r.getCommunities().entrySet()) {
                    CommunityVar cvar = entry2.getKey();
                    BoolExpr expr = entry2.getValue();
                    if (cvar.getType() == Type.EXACT && boolVal(expr)) {
                        communities.add(cvar.asLong());
                    }
                }
                BgpAdvertisement adv = new BgpAdvertisement(BgpAdvertisementType.EBGP_RECEIVED, pfx, zeroIp, srcNode, "default", zeroIp, router, "default", dstIp, RoutingProtocol.BGP, OriginType.EGP, 100, 80, zeroIp, path, communities, new TreeSet<>(), 0);
                routes.add(adv);
            }
        }
    }
    return routes;
}
Also used : BoolExpr(com.microsoft.z3.BoolExpr) Ip(org.batfish.datamodel.Ip) ArrayList(java.util.ArrayList) Prefix(org.batfish.datamodel.Prefix) SortedSet(java.util.SortedSet) BgpNeighbor(org.batfish.datamodel.BgpNeighbor) TreeSet(java.util.TreeSet) Flow(org.batfish.datamodel.Flow) CommunityVar(org.batfish.symbolic.CommunityVar) BgpAdvertisement(org.batfish.datamodel.BgpAdvertisement) AsPath(org.batfish.datamodel.AsPath) GraphEdge(org.batfish.symbolic.GraphEdge)

Example 23 with GraphEdge

use of org.batfish.symbolic.GraphEdge in project batfish by batfish.

the class PropertyChecker method checkDeterminism.

/*
   * Check if there exist multiple stable solutions to the network.
   * If so, reports the forwarding differences between the two cases.
   */
public AnswerElement checkDeterminism(HeaderQuestion q) {
    Graph graph = new Graph(_batfish);
    Encoder enc1 = new Encoder(_settings, graph, q);
    Encoder enc2 = new Encoder(enc1, graph, q);
    enc1.computeEncoding();
    enc2.computeEncoding();
    addEnvironmentConstraints(enc1, q.getBaseEnvironmentType());
    BoolExpr relatedFailures = relateFailures(enc1, enc2);
    BoolExpr relatedEnvs = relateEnvironments(enc1, enc2);
    BoolExpr relatedPkts = relatePackets(enc1, enc2);
    BoolExpr related = enc1.mkAnd(relatedFailures, relatedEnvs, relatedPkts);
    BoolExpr required = enc1.mkTrue();
    for (GraphEdge ge : graph.getAllRealEdges()) {
        SymbolicDecisions d1 = enc1.getMainSlice().getSymbolicDecisions();
        SymbolicDecisions d2 = enc2.getMainSlice().getSymbolicDecisions();
        BoolExpr dataFwd1 = d1.getDataForwarding().get(ge.getRouter(), ge);
        BoolExpr dataFwd2 = d2.getDataForwarding().get(ge.getRouter(), ge);
        assert dataFwd1 != null;
        assert dataFwd2 != null;
        required = enc1.mkAnd(required, enc1.mkEq(dataFwd1, dataFwd2));
    }
    enc1.add(related);
    enc1.add(enc1.mkNot(required));
    Tuple<VerificationResult, Model> tup = enc1.verify();
    VerificationResult res = tup.getFirst();
    Model model = tup.getSecond();
    SortedSet<String> case1 = null;
    SortedSet<String> case2 = null;
    Flow flow = null;
    CounterExample ce = new CounterExample(model);
    if (!res.isVerified()) {
        case1 = new TreeSet<>();
        case2 = new TreeSet<>();
        flow = ce.buildFlow(enc1.getMainSlice().getSymbolicPacket(), "(none)");
        for (GraphEdge ge : graph.getAllRealEdges()) {
            SymbolicDecisions d1 = enc1.getMainSlice().getSymbolicDecisions();
            SymbolicDecisions d2 = enc2.getMainSlice().getSymbolicDecisions();
            BoolExpr dataFwd1 = d1.getDataForwarding().get(ge.getRouter(), ge);
            BoolExpr dataFwd2 = d2.getDataForwarding().get(ge.getRouter(), ge);
            assert dataFwd1 != null;
            assert dataFwd2 != null;
            boolean b1 = ce.boolVal(dataFwd1);
            boolean b2 = ce.boolVal(dataFwd2);
            if (b1 != b2) {
                if (b1) {
                    String route = ce.buildRoute(enc1.getMainSlice(), ge);
                    String msg = ge + " -- " + route;
                    case1.add(msg);
                }
                if (b2) {
                    String route = ce.buildRoute(enc2.getMainSlice(), ge);
                    String msg = ge + " -- " + route;
                    case2.add(msg);
                }
            }
        }
    }
    // Ensure canonical order
    boolean less = (case1 == null || (case1.first().compareTo(case2.first()) < 0));
    if (less) {
        return new SmtDeterminismAnswerElement(flow, case1, case2);
    } else {
        return new SmtDeterminismAnswerElement(flow, case2, case1);
    }
}
Also used : BoolExpr(com.microsoft.z3.BoolExpr) Flow(org.batfish.datamodel.Flow) Graph(org.batfish.symbolic.Graph) Model(com.microsoft.z3.Model) SmtDeterminismAnswerElement(org.batfish.symbolic.answers.SmtDeterminismAnswerElement) GraphEdge(org.batfish.symbolic.GraphEdge)

Example 24 with GraphEdge

use of org.batfish.symbolic.GraphEdge in project batfish by batfish.

the class Encoder method initSlices.

/*
   * Initialize each encoding slice.
   * For iBGP, we also add reachability information for each pair of neighbors,
   * to determine if messages sent to/from a neighbor will arrive.
   */
private void initSlices(HeaderSpace h, Graph g) {
    if (g.getIbgpNeighbors().isEmpty() || !_modelIgp) {
        _slices.put(MAIN_SLICE_NAME, new EncoderSlice(this, h, g, ""));
    } else {
        _slices.put(MAIN_SLICE_NAME, new EncoderSlice(this, h, g, MAIN_SLICE_NAME));
    }
    if (_modelIgp) {
        SortedSet<Pair<String, Ip>> ibgpRouters = new TreeSet<>();
        for (Entry<GraphEdge, BgpNeighbor> entry : g.getIbgpNeighbors().entrySet()) {
            GraphEdge ge = entry.getKey();
            BgpNeighbor n = entry.getValue();
            String router = ge.getRouter();
            Ip ip = n.getLocalIp();
            Pair<String, Ip> pair = new Pair<>(router, ip);
            // Add one slice per (router, source ip) pair
            if (!ibgpRouters.contains(pair)) {
                ibgpRouters.add(pair);
                // Create a control plane slice only for this ip
                HeaderSpace hs = new HeaderSpace();
                // Make sure messages are sent to this destination IP
                SortedSet<IpWildcard> ips = new TreeSet<>();
                ips.add(new IpWildcard(n.getLocalIp()));
                hs.setDstIps(ips);
                // Make sure messages use TCP port 179
                SortedSet<SubRange> dstPorts = new TreeSet<>();
                dstPorts.add(new SubRange(179, 179));
                hs.setDstPorts(dstPorts);
                // Make sure messages use the TCP protocol
                SortedSet<IpProtocol> protocols = new TreeSet<>();
                protocols.add(IpProtocol.TCP);
                hs.setIpProtocols(protocols);
                // TODO: create domains once
                Graph gNew = new Graph(g.getBatfish(), null, g.getDomain(router));
                String sliceName = "SLICE-" + router + "_";
                EncoderSlice slice = new EncoderSlice(this, hs, gNew, sliceName);
                _slices.put(sliceName, slice);
                PropertyAdder pa = new PropertyAdder(slice);
                Map<String, BoolExpr> reachVars = pa.instrumentReachability(router);
                _sliceReachability.put(router, reachVars);
            }
        }
    }
}
Also used : BoolExpr(com.microsoft.z3.BoolExpr) Ip(org.batfish.datamodel.Ip) HeaderSpace(org.batfish.datamodel.HeaderSpace) BgpNeighbor(org.batfish.datamodel.BgpNeighbor) IpWildcard(org.batfish.datamodel.IpWildcard) Graph(org.batfish.symbolic.Graph) TreeSet(java.util.TreeSet) IpProtocol(org.batfish.datamodel.IpProtocol) SubRange(org.batfish.datamodel.SubRange) GraphEdge(org.batfish.symbolic.GraphEdge) Pair(org.batfish.common.Pair)

Example 25 with GraphEdge

use of org.batfish.symbolic.GraphEdge in project batfish by batfish.

the class Encoder method initFailedLinkVariables.

/*
   * Initialize symbolic variables to represent link failures.
   */
private void initFailedLinkVariables() {
    for (List<GraphEdge> edges : _graph.getEdgeMap().values()) {
        for (GraphEdge ge : edges) {
            if (ge.getPeer() == null) {
                Interface i = ge.getStart();
                String name = getId() + "_FAILED-EDGE_" + ge.getRouter() + "_" + i.getName();
                ArithExpr var = getCtx().mkIntConst(name);
                _symbolicFailures.getFailedEdgeLinks().put(ge, var);
                _allVariables.put(var.toString(), var);
            }
        }
    }
    for (Entry<String, Set<String>> entry : _graph.getNeighbors().entrySet()) {
        String router = entry.getKey();
        Set<String> peers = entry.getValue();
        for (String peer : peers) {
            // sort names for unique
            String pair = (router.compareTo(peer) < 0 ? router + "_" + peer : peer + "_" + router);
            String name = getId() + "_FAILED-EDGE_" + pair;
            ArithExpr var = _ctx.mkIntConst(name);
            _symbolicFailures.getFailedInternalLinks().put(router, peer, var);
            _allVariables.put(var.toString(), var);
        }
    }
}
Also used : ArithExpr(com.microsoft.z3.ArithExpr) SortedSet(java.util.SortedSet) TreeSet(java.util.TreeSet) HashSet(java.util.HashSet) Set(java.util.Set) GraphEdge(org.batfish.symbolic.GraphEdge) Interface(org.batfish.datamodel.Interface)

Aggregations

GraphEdge (org.batfish.symbolic.GraphEdge)47 BoolExpr (com.microsoft.z3.BoolExpr)23 HashMap (java.util.HashMap)19 ArrayList (java.util.ArrayList)16 List (java.util.List)16 Graph (org.batfish.symbolic.Graph)14 TreeSet (java.util.TreeSet)13 Prefix (org.batfish.datamodel.Prefix)12 ArithExpr (com.microsoft.z3.ArithExpr)10 Configuration (org.batfish.datamodel.Configuration)10 Protocol (org.batfish.symbolic.Protocol)10 HashSet (java.util.HashSet)8 Interface (org.batfish.datamodel.Interface)8 Context (com.microsoft.z3.Context)7 Map (java.util.Map)7 Ip (org.batfish.datamodel.Ip)7 IpAccessList (org.batfish.datamodel.IpAccessList)7 TreeMap (java.util.TreeMap)6 IpProtocol (org.batfish.datamodel.IpProtocol)6 BitVecExpr (com.microsoft.z3.BitVecExpr)5