Search in sources :

Example 51 with BoolExpr

use of com.microsoft.z3.BoolExpr in project batfish by batfish.

the class EncoderSlice method computeValidRange.

/*
   * Convert a set of ranges and a packet field to a symbolic boolean expression
   */
private BoolExpr computeValidRange(Set<SubRange> ranges, ArithExpr field) {
    BoolExpr acc = mkFalse();
    for (SubRange range : ranges) {
        int start = range.getStart();
        int end = range.getEnd();
        if (start == end) {
            BoolExpr val = mkEq(field, mkInt(start));
            acc = mkOr(acc, val);
        } else {
            BoolExpr val1 = mkGe(field, mkInt(start));
            BoolExpr val2 = mkLe(field, mkInt(end));
            acc = mkOr(acc, mkAnd(val1, val2));
        }
    }
    return (BoolExpr) acc.simplify();
}
Also used : BoolExpr(com.microsoft.z3.BoolExpr) SubRange(org.batfish.datamodel.SubRange)

Example 52 with BoolExpr

use of com.microsoft.z3.BoolExpr in project batfish by batfish.

the class EncoderSlice method addDataForwardingConstraints.

/*
   * Constraints for the final data plane forwarding behavior.
   * Forwarding occurs in the data plane if the control plane decides
   * to use an interface, and no ACL blocks the packet:
   *
   * data_fwd(iface) = control_fwd(iface) and not acl(iface)
   */
private void addDataForwardingConstraints() {
    for (Entry<String, List<GraphEdge>> entry : getGraph().getEdgeMap().entrySet()) {
        String router = entry.getKey();
        List<GraphEdge> edges = entry.getValue();
        for (GraphEdge ge : edges) {
            // setup forwarding for non-abstract edges
            if (!ge.isAbstract()) {
                BoolExpr fwd = mkFalse();
                BoolExpr cForward = _symbolicDecisions.getControlForwarding().get(router, ge);
                BoolExpr dForward = _symbolicDecisions.getDataForwarding().get(router, ge);
                assert (cForward != null);
                assert (dForward != null);
                // out the current edge ge, the we use ge.
                for (GraphEdge ge2 : getGraph().getEdgeMap().get(router)) {
                    if (ge2.isAbstract()) {
                        BoolExpr ctrlFwd = getSymbolicDecisions().getControlForwarding().get(router, ge2);
                        Graph.BgpSendType st = getGraph().peerType(ge2);
                        // If Route reflectors, then next hop based on ID
                        if (st == Graph.BgpSendType.TO_RR) {
                            SymbolicRoute record = getSymbolicDecisions().getBestNeighbor().get(router);
                            // adjust for iBGP in main slice
                            BoolExpr acc = mkFalse();
                            if (isMainSlice()) {
                                for (Entry<String, Integer> entry2 : getGraph().getOriginatorId().entrySet()) {
                                    String r = entry2.getKey();
                                    Integer id = entry2.getValue();
                                    EncoderSlice s = _encoder.getSlice(r);
                                    // Make sure
                                    if (otherSliceHasEdge(s, router, ge)) {
                                        BoolExpr outEdge = s.getSymbolicDecisions().getDataForwarding().get(router, ge);
                                        acc = mkOr(acc, mkAnd(record.getClientId().checkIfValue(id), outEdge));
                                    }
                                }
                            }
                            fwd = mkOr(fwd, mkAnd(ctrlFwd, acc));
                        } else {
                            // adjust for iBGP in main slice
                            if (isMainSlice()) {
                                EncoderSlice s = _encoder.getSlice(ge2.getPeer());
                                if (otherSliceHasEdge(s, router, ge)) {
                                    BoolExpr outEdge = s.getSymbolicDecisions().getDataForwarding().get(router, ge);
                                    fwd = mkOr(fwd, mkAnd(ctrlFwd, outEdge));
                                }
                            }
                        }
                    }
                }
                fwd = mkOr(fwd, cForward);
                BoolExpr acl = _outboundAcls.get(ge);
                if (acl == null) {
                    acl = mkTrue();
                }
                BoolExpr notBlocked = mkAnd(fwd, acl);
                add(mkEq(notBlocked, dForward));
            }
        }
    }
}
Also used : BoolExpr(com.microsoft.z3.BoolExpr) Graph(org.batfish.symbolic.Graph) IpAccessList(org.batfish.datamodel.IpAccessList) ArrayList(java.util.ArrayList) List(java.util.List) GraphEdge(org.batfish.symbolic.GraphEdge)

Example 53 with BoolExpr

use of com.microsoft.z3.BoolExpr in project batfish by batfish.

the class EncoderSlice method computeACL.

/*
   * Convert an Access Control List (ACL) to a symbolic boolean expression.
   * The default action in an ACL is to deny all traffic.
   */
private BoolExpr computeACL(IpAccessList acl) {
    // Check if there is an ACL first
    if (acl == null) {
        return mkTrue();
    }
    BoolExpr acc = mkFalse();
    List<IpAccessListLine> lines = new ArrayList<>(acl.getLines());
    Collections.reverse(lines);
    for (IpAccessListLine l : lines) {
        BoolExpr local = null;
        if (l.getDstIps() != null) {
            BoolExpr val = computeWildcardMatch(l.getDstIps(), _symbolicPacket.getDstIp());
            val = l.getDstIps().isEmpty() ? mkTrue() : val;
            local = val;
        }
        if (l.getSrcIps() != null) {
            BoolExpr val = computeWildcardMatch(l.getSrcIps(), _symbolicPacket.getSrcIp());
            val = l.getDstIps().isEmpty() ? mkTrue() : val;
            local = (local == null ? val : mkAnd(local, val));
        }
        if (l.getDscps() != null && !l.getDscps().isEmpty()) {
            throw new BatfishException("detected dscps");
        }
        if (l.getDstPorts() != null) {
            BoolExpr val = computeValidRange(l.getDstPorts(), _symbolicPacket.getDstPort());
            val = l.getDstPorts().isEmpty() ? mkTrue() : val;
            local = (local == null ? val : mkAnd(local, val));
        }
        if (l.getSrcPorts() != null) {
            BoolExpr val = computeValidRange(l.getSrcPorts(), _symbolicPacket.getSrcPort());
            val = l.getSrcPorts().isEmpty() ? mkTrue() : val;
            local = (local == null ? val : mkAnd(local, val));
        }
        if (l.getEcns() != null && !l.getEcns().isEmpty()) {
            throw new BatfishException("detected ecns");
        }
        if (l.getTcpFlags() != null) {
            BoolExpr val = computeTcpFlags(l.getTcpFlags());
            val = l.getTcpFlags().isEmpty() ? mkTrue() : val;
            local = (local == null ? val : mkAnd(local, val));
        }
        if (l.getFragmentOffsets() != null && !l.getFragmentOffsets().isEmpty()) {
            throw new BatfishException("detected fragment offsets");
        }
        if (l.getIcmpCodes() != null) {
            BoolExpr val = computeValidRange(l.getIcmpCodes(), _symbolicPacket.getIcmpCode());
            val = l.getIcmpCodes().isEmpty() ? mkTrue() : val;
            local = (local == null ? val : mkAnd(local, val));
        }
        if (l.getIcmpTypes() != null) {
            BoolExpr val = computeValidRange(l.getIcmpTypes(), _symbolicPacket.getIcmpType());
            val = l.getIcmpTypes().isEmpty() ? mkTrue() : val;
            local = (local == null ? val : mkAnd(local, val));
        }
        if (l.getStates() != null && !l.getStates().isEmpty()) {
            throw new BatfishException("detected states");
        }
        if (l.getIpProtocols() != null) {
            BoolExpr val = computeIpProtocols(l.getIpProtocols());
            val = l.getIpProtocols().isEmpty() ? mkTrue() : val;
            local = (local == null ? val : mkAnd(local, val));
        }
        if (l.getNotDscps() != null && !l.getNotDscps().isEmpty()) {
            throw new BatfishException("detected NOT dscps");
        }
        if (l.getNotDstIps() != null && !l.getNotDstIps().isEmpty()) {
            throw new BatfishException("detected NOT dst ip");
        }
        if (l.getNotSrcIps() != null && !l.getNotSrcIps().isEmpty()) {
            throw new BatfishException("detected NOT src ip");
        }
        if (l.getNotDstPorts() != null && !l.getNotDstPorts().isEmpty()) {
            throw new BatfishException("detected NOT dst port");
        }
        if (l.getNotSrcPorts() != null && !l.getNotSrcPorts().isEmpty()) {
            throw new BatfishException("detected NOT src port");
        }
        if (l.getNotEcns() != null && !l.getNotEcns().isEmpty()) {
            throw new BatfishException("detected NOT ecns");
        }
        if (l.getNotIcmpCodes() != null && !l.getNotIcmpCodes().isEmpty()) {
            throw new BatfishException("detected NOT icmp codes");
        }
        if (l.getNotIcmpTypes() != null && !l.getNotIcmpTypes().isEmpty()) {
            throw new BatfishException("detected NOT icmp types");
        }
        if (l.getNotFragmentOffsets() != null && !l.getNotFragmentOffsets().isEmpty()) {
            throw new BatfishException("detected NOT fragment offset");
        }
        if (l.getNotIpProtocols() != null && !l.getNotIpProtocols().isEmpty()) {
            throw new BatfishException("detected NOT ip protocols");
        }
        if (local != null) {
            BoolExpr ret;
            if (l.getAction() == LineAction.ACCEPT) {
                ret = mkTrue();
            } else {
                ret = mkFalse();
            }
            if (l.getNegate()) {
                local = mkNot(local);
            }
            acc = mkIf(local, ret, acc);
        }
    }
    return acc;
}
Also used : BoolExpr(com.microsoft.z3.BoolExpr) BatfishException(org.batfish.common.BatfishException) ArrayList(java.util.ArrayList) IpAccessListLine(org.batfish.datamodel.IpAccessListLine)

Example 54 with BoolExpr

use of com.microsoft.z3.BoolExpr in project batfish by batfish.

the class EncoderSlice method addBestOverallConstraints.

/*
   * Constraints that specify that the best choice is
   * better than all alternatives, and is at least one of the choices:
   *
   * (1) if no options are valid, then best is not valid
   * (2) if some option is valid, then we have the following:
   *
   * (best <= best_prot1) and ... and (best <= best_protn)
   * (best =  best_prot1) or  ... or  (best =  best_protn)
   */
private void addBestOverallConstraints() {
    for (Entry<String, Configuration> entry : getGraph().getConfigurations().entrySet()) {
        String router = entry.getKey();
        Configuration conf = entry.getValue();
        // These constraints will be added at the protocol-level when a single protocol
        if (!_optimizations.getSliceHasSingleProtocol().contains(router)) {
            boolean someProto = false;
            BoolExpr acc = null;
            BoolExpr somePermitted = null;
            SymbolicRoute best = _symbolicDecisions.getBestNeighbor().get(router);
            for (Protocol proto : getProtocols().get(router)) {
                someProto = true;
                SymbolicRoute bestVars = _symbolicDecisions.getBestVars(_optimizations, router, proto);
                assert (bestVars != null);
                if (somePermitted == null) {
                    somePermitted = bestVars.getPermitted();
                } else {
                    somePermitted = mkOr(somePermitted, bestVars.getPermitted());
                }
                BoolExpr val = mkAnd(bestVars.getPermitted(), equal(conf, proto, best, bestVars, null, true));
                if (acc == null) {
                    acc = val;
                } else {
                    acc = mkOr(acc, val);
                }
                add(mkImplies(bestVars.getPermitted(), greaterOrEqual(conf, proto, best, bestVars, null)));
            }
            if (someProto) {
                if (acc != null) {
                    add(mkEq(somePermitted, best.getPermitted()));
                    add(mkImplies(somePermitted, acc));
                }
            } else {
                add(mkNot(best.getPermitted()));
            }
        }
    }
}
Also used : BoolExpr(com.microsoft.z3.BoolExpr) Configuration(org.batfish.datamodel.Configuration) IpProtocol(org.batfish.datamodel.IpProtocol) RoutingProtocol(org.batfish.datamodel.RoutingProtocol) Protocol(org.batfish.symbolic.Protocol) MatchProtocol(org.batfish.datamodel.routing_policy.expr.MatchProtocol)

Example 55 with BoolExpr

use of com.microsoft.z3.BoolExpr in project batfish by batfish.

the class EncoderSlice method ipWildCardBound.

/*
   * Create a boolean expression for a variable being withing an IpWildCard bound
   */
private BoolExpr ipWildCardBound(BitVecExpr field, IpWildcard wc) {
    BitVecExpr ip = getCtx().mkBV(wc.getIp().asLong(), 32);
    BitVecExpr mask = getCtx().mkBV(~wc.getWildcard().asLong(), 32);
    return mkEq(getCtx().mkBVAND(field, mask), getCtx().mkBVAND(ip, mask));
}
Also used : BitVecExpr(com.microsoft.z3.BitVecExpr)

Aggregations

BoolExpr (com.microsoft.z3.BoolExpr)141 Status (com.microsoft.z3.Status)55 Test (org.junit.Test)51 ArithExpr (com.microsoft.z3.ArithExpr)27 GraphEdge (org.batfish.symbolic.GraphEdge)25 Context (com.microsoft.z3.Context)24 HashMap (java.util.HashMap)22 Expr (com.microsoft.z3.Expr)21 Set (java.util.Set)20 Collectors (java.util.stream.Collectors)18 BitVecExpr (com.microsoft.z3.BitVecExpr)17 Event (dartagnan.program.Event)17 MemEvent (dartagnan.program.MemEvent)17 Program (dartagnan.program.Program)16 Map (java.util.Map)16 Local (dartagnan.program.Local)15 ArrayList (java.util.ArrayList)15 BatfishException (org.batfish.common.BatfishException)14 Graph (org.batfish.symbolic.Graph)14 com.microsoft.z3 (com.microsoft.z3)12