Search in sources :

Example 46 with BoolExpr

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

the class EncoderSlice method addHeaderSpaceConstraint.

/*
   * Add constraints for the type of packets we will consider in the model.
   * This can include restrictions on any packet field such as dstIp, protocol etc.
   */
private void addHeaderSpaceConstraint() {
    BoolExpr acc;
    if (_headerSpace.getDstIps().size() > 0) {
        acc = mkFalse();
        for (IpWildcard ipWildcard : _headerSpace.getDstIps()) {
            BoolExpr bound = ipWildCardBound(_symbolicPacket.getDstIp(), ipWildcard);
            acc = mkOr(acc, bound);
        }
        add(acc);
    }
    if (_headerSpace.getNotDstIps().size() > 0) {
        acc = mkTrue();
        for (IpWildcard ipWildcard : _headerSpace.getNotDstIps()) {
            BoolExpr bound = ipWildCardBound(_symbolicPacket.getDstIp(), ipWildcard);
            acc = mkAnd(acc, mkNot(bound));
        }
        add(acc);
    }
    if (_headerSpace.getSrcIps().size() > 0) {
        acc = mkFalse();
        for (IpWildcard ipWildcard : _headerSpace.getSrcIps()) {
            BoolExpr bound = ipWildCardBound(_symbolicPacket.getSrcIp(), ipWildcard);
            acc = mkOr(acc, bound);
        }
        add(acc);
    }
    if (_headerSpace.getNotSrcIps().size() > 0) {
        acc = mkTrue();
        for (IpWildcard ipWildcard : _headerSpace.getNotSrcIps()) {
            BoolExpr bound = ipWildCardBound(_symbolicPacket.getSrcIp(), ipWildcard);
            acc = mkAnd(acc, mkNot(bound));
        }
        add(acc);
    }
    if (_headerSpace.getSrcOrDstIps().size() > 0) {
        acc = mkFalse();
        for (IpWildcard ipWildcard : _headerSpace.getSrcOrDstIps()) {
            BoolExpr bound1 = ipWildCardBound(_symbolicPacket.getDstIp(), ipWildcard);
            BoolExpr bound2 = ipWildCardBound(_symbolicPacket.getSrcIp(), ipWildcard);
            acc = mkOr(acc, bound1, bound2);
        }
        add(acc);
    }
    if (_headerSpace.getDstPorts().size() > 0) {
        acc = mkFalse();
        for (SubRange subRange : _headerSpace.getDstPorts()) {
            BoolExpr bound = subRangeBound(_symbolicPacket.getDstPort(), subRange);
            acc = mkOr(acc, bound);
        }
        add(acc);
    }
    if (_headerSpace.getNotDstPorts().size() > 0) {
        acc = mkTrue();
        for (SubRange subRange : _headerSpace.getNotDstPorts()) {
            BoolExpr bound = subRangeBound(_symbolicPacket.getDstPort(), subRange);
            acc = mkAnd(acc, mkNot(bound));
        }
        add(acc);
    }
    if (_headerSpace.getSrcPorts().size() > 0) {
        acc = mkFalse();
        for (SubRange subRange : _headerSpace.getSrcPorts()) {
            BoolExpr bound = subRangeBound(_symbolicPacket.getDstPort(), subRange);
            acc = mkOr(acc, bound);
        }
        add(acc);
    }
    if (_headerSpace.getNotSrcPorts().size() > 0) {
        acc = mkTrue();
        for (SubRange subRange : _headerSpace.getNotSrcPorts()) {
            BoolExpr bound = subRangeBound(_symbolicPacket.getDstPort(), subRange);
            acc = mkAnd(acc, mkNot(bound));
        }
        add(acc);
    }
    if (_headerSpace.getSrcOrDstPorts().size() > 0) {
        acc = mkFalse();
        for (SubRange subRange : _headerSpace.getSrcOrDstPorts()) {
            BoolExpr bound1 = subRangeBound(_symbolicPacket.getDstPort(), subRange);
            BoolExpr bound2 = subRangeBound(_symbolicPacket.getSrcPort(), subRange);
            acc = mkOr(acc, bound1, bound2);
        }
        add(acc);
    }
    if (_headerSpace.getIcmpTypes().size() > 0) {
        acc = mkFalse();
        for (SubRange subRange : _headerSpace.getIcmpTypes()) {
            BoolExpr bound = subRangeBound(_symbolicPacket.getIcmpType(), subRange);
            acc = mkOr(acc, bound);
        }
        add(acc);
    }
    if (_headerSpace.getNotIcmpTypes().size() > 0) {
        acc = mkTrue();
        for (SubRange subRange : _headerSpace.getNotIcmpTypes()) {
            BoolExpr bound = subRangeBound(_symbolicPacket.getIcmpType(), subRange);
            acc = mkAnd(acc, mkNot(bound));
        }
        add(acc);
    }
    if (_headerSpace.getIcmpCodes().size() > 0) {
        acc = mkFalse();
        for (SubRange subRange : _headerSpace.getIcmpCodes()) {
            BoolExpr bound = subRangeBound(_symbolicPacket.getIcmpCode(), subRange);
            acc = mkOr(acc, bound);
        }
        add(acc);
    }
    if (_headerSpace.getNotIcmpCodes().size() > 0) {
        acc = mkTrue();
        for (SubRange subRange : _headerSpace.getNotIcmpCodes()) {
            BoolExpr bound = subRangeBound(_symbolicPacket.getIcmpCode(), subRange);
            acc = mkAnd(acc, mkNot(bound));
        }
        add(acc);
    }
    if (_headerSpace.getIpProtocols().size() > 0) {
        acc = mkFalse();
        for (IpProtocol ipProtocol : _headerSpace.getIpProtocols()) {
            BoolExpr bound = mkEq(_symbolicPacket.getIpProtocol(), mkInt(ipProtocol.number()));
            acc = mkOr(acc, bound);
        }
        add(acc);
    }
    if (_headerSpace.getNotIpProtocols().size() > 0) {
        acc = mkTrue();
        for (IpProtocol ipProtocol : _headerSpace.getNotIpProtocols()) {
            BoolExpr bound = mkEq(_symbolicPacket.getIpProtocol(), mkInt(ipProtocol.number()));
            acc = mkAnd(acc, mkNot(bound));
        }
        add(acc);
    }
// TODO: need to implement fragment offsets, Ecns, states, etc
}
Also used : IpWildcard(org.batfish.datamodel.IpWildcard) BoolExpr(com.microsoft.z3.BoolExpr) IpProtocol(org.batfish.datamodel.IpProtocol) SubRange(org.batfish.datamodel.SubRange)

Example 47 with BoolExpr

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

the class EncoderSlice method addExportConstraint.

/*
   * Creates the transfer function to represent export filters
   * between two symbolic records. The import filter depends
   * heavily on the protocol.
   */
private void addExportConstraint(LogicalEdge e, SymbolicRoute varsOther, @Nullable SymbolicRoute ospfRedistribVars, @Nullable SymbolicRoute overallBest, Configuration conf, Protocol proto, GraphEdge ge, String router, boolean usedExport, Set<Prefix> originations) {
    SymbolicRoute vars = e.getSymbolicRecord();
    Interface iface = ge.getStart();
    ArithExpr failed = getSymbolicFailures().getFailedVariable(e.getEdge());
    assert (failed != null);
    BoolExpr notFailed = mkEq(failed, mkInt(0));
    // only add constraints once when using a single copy of export variables
    if (!_optimizations.getSliceCanKeepSingleExportVar().get(router).get(proto) || !usedExport) {
        if (proto.isConnected()) {
            BoolExpr val = mkNot(vars.getPermitted());
            add(val);
        }
        if (proto.isStatic()) {
            BoolExpr val = mkNot(vars.getPermitted());
            add(val);
        }
        if (proto.isOspf() || proto.isBgp()) {
            // BGP cost based on export
            Integer cost = proto.isBgp() ? addedCost(proto, ge) : 0;
            BoolExpr val = mkNot(vars.getPermitted());
            BoolExpr active = interfaceActive(iface, proto);
            // Apply BGP export policy and cost based on peer type
            // (1) EBGP --> ALL
            // (2) CLIENT --> ALL
            // (3) NONCLIENT --> EBGP, CLIENT
            boolean isNonClientEdge = proto.isBgp() && getGraph().peerType(ge) != Graph.BgpSendType.TO_EBGP;
            boolean isClientEdge = proto.isBgp() && getGraph().peerType(ge) == Graph.BgpSendType.TO_CLIENT;
            boolean isInternalExport = varsOther.isBest() && _optimizations.getNeedBgpInternal().contains(router);
            BoolExpr doExport = mkTrue();
            if (isInternalExport && proto.isBgp() && isNonClientEdge) {
                if (isClientEdge) {
                    cost = 0;
                } else {
                    // Lookup if we learned from iBGP, and if so, don't export the route
                    SymbolicRoute other = getBestNeighborPerProtocol(router, proto);
                    assert other != null;
                    assert other.getBgpInternal() != null;
                    if (other.getBgpInternal() != null) {
                        doExport = mkNot(other.getBgpInternal());
                        cost = 0;
                    }
                }
            }
            BoolExpr acc;
            RoutingPolicy pol = getGraph().findExportRoutingPolicy(router, proto, e.getEdge());
            if (Encoder.ENABLE_DEBUGGING && pol != null) {
                System.out.println("Export policy (" + _sliceName + "," + ge + "): " + pol.getName());
            }
            // We have to wrap this with the right thing for some reason
            List<Statement> statements;
            Statements.StaticStatement s1 = new Statements.StaticStatement(Statements.ExitAccept);
            Statements.StaticStatement s2 = new Statements.StaticStatement(Statements.ExitReject);
            if (proto.isOspf()) {
                If i = new If();
                List<Statement> stmts = (pol == null ? Collections.singletonList(s2) : pol.getStatements());
                i.setTrueStatements(Collections.singletonList(s1));
                i.setFalseStatements(stmts);
                BooleanExpr expr = new MatchProtocol(RoutingProtocol.OSPF);
                i.setGuard(expr);
                statements = Collections.singletonList(i);
            } else {
                statements = (pol == null ? Collections.singletonList(s1) : pol.getStatements());
            }
            TransferSSA f = new TransferSSA(this, conf, varsOther, vars, proto, statements, cost, ge, true);
            acc = f.compute();
            BoolExpr usable = mkAnd(active, doExport, varsOther.getPermitted(), notFailed);
            // will maintain the same preference when adding to the cost.
            if (ospfRedistribVars != null) {
                assert overallBest != null;
                f = new TransferSSA(this, conf, overallBest, ospfRedistribVars, proto, statements, cost, ge, true);
                BoolExpr acc2 = f.compute();
                // System.out.println("ADDING: \n" + acc2.simplify());
                add(acc2);
                BoolExpr usable2 = mkAnd(active, doExport, ospfRedistribVars.getPermitted(), notFailed);
                BoolExpr geq = greaterOrEqual(conf, proto, ospfRedistribVars, varsOther, e);
                BoolExpr isBetter = mkNot(mkAnd(ospfRedistribVars.getPermitted(), geq));
                BoolExpr usesOspf = mkAnd(varsOther.getPermitted(), isBetter);
                BoolExpr eq = equal(conf, proto, ospfRedistribVars, vars, e, false);
                BoolExpr eqPer = mkEq(ospfRedistribVars.getPermitted(), vars.getPermitted());
                acc = mkIf(usesOspf, mkIf(usable, acc, val), mkIf(usable2, mkAnd(eq, eqPer), val));
            } else {
                acc = mkIf(usable, acc, val);
            }
            for (Prefix p : originations) {
                // For OSPF, we need to explicitly initiate a route
                if (proto.isOspf()) {
                    BoolExpr ifaceUp = interfaceActive(iface, proto);
                    BoolExpr relevantPrefix = isRelevantFor(p, _symbolicPacket.getDstIp());
                    BoolExpr relevant = mkAnd(ifaceUp, relevantPrefix);
                    int adminDistance = defaultAdminDistance(conf, proto);
                    int prefixLength = p.getPrefixLength();
                    BoolExpr per = vars.getPermitted();
                    BoolExpr lp = safeEq(vars.getLocalPref(), mkInt(0));
                    BoolExpr ad = safeEq(vars.getAdminDist(), mkInt(adminDistance));
                    BoolExpr met = safeEq(vars.getMetric(), mkInt(cost));
                    BoolExpr med = safeEq(vars.getMed(), mkInt(100));
                    BoolExpr len = safeEq(vars.getPrefixLength(), mkInt(prefixLength));
                    BoolExpr type = safeEqEnum(vars.getOspfType(), OspfType.O);
                    BoolExpr area = safeEqEnum(vars.getOspfArea(), iface.getOspfAreaName());
                    BoolExpr internal = safeEq(vars.getBgpInternal(), mkFalse());
                    BoolExpr igpMet = safeEq(vars.getIgpMetric(), mkInt(0));
                    BoolExpr comms = mkTrue();
                    for (Map.Entry<CommunityVar, BoolExpr> entry : vars.getCommunities().entrySet()) {
                        comms = mkAnd(comms, mkNot(entry.getValue()));
                    }
                    BoolExpr values = mkAnd(per, lp, ad, met, med, len, type, area, internal, igpMet, comms);
                    // Don't originate OSPF route when there is a better redistributed route
                    if (ospfRedistribVars != null) {
                        BoolExpr betterLen = mkGt(ospfRedistribVars.getPrefixLength(), mkInt(prefixLength));
                        BoolExpr equalLen = mkEq(ospfRedistribVars.getPrefixLength(), mkInt(prefixLength));
                        BoolExpr betterAd = mkLt(ospfRedistribVars.getAdminDist(), mkInt(110));
                        BoolExpr better = mkOr(betterLen, mkAnd(equalLen, betterAd));
                        BoolExpr betterRedistributed = mkAnd(ospfRedistribVars.getPermitted(), better);
                        relevant = mkAnd(relevant, mkNot(betterRedistributed));
                    }
                    acc = mkIf(relevant, values, acc);
                }
            }
            add(acc);
            if (Encoder.ENABLE_DEBUGGING) {
                System.out.println("EXPORT: " + router + " " + varsOther.getName() + " " + ge);
                System.out.println(acc.simplify());
                System.out.println("\n\n");
            }
        }
    }
}
Also used : ArithExpr(com.microsoft.z3.ArithExpr) BoolExpr(com.microsoft.z3.BoolExpr) Statement(org.batfish.datamodel.routing_policy.statement.Statement) RoutingPolicy(org.batfish.datamodel.routing_policy.RoutingPolicy) Prefix(org.batfish.datamodel.Prefix) MatchProtocol(org.batfish.datamodel.routing_policy.expr.MatchProtocol) CommunityVar(org.batfish.symbolic.CommunityVar) Statements(org.batfish.datamodel.routing_policy.statement.Statements) If(org.batfish.datamodel.routing_policy.statement.If) HashMap(java.util.HashMap) Map(java.util.Map) Interface(org.batfish.datamodel.Interface) BooleanExpr(org.batfish.datamodel.routing_policy.expr.BooleanExpr)

Example 48 with BoolExpr

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

the class EncoderSlice method addImportConstraint.

/*
   * Creates the transfer function to represent import filters
   * between two symbolic records. The import filter depends
   * heavily on the protocol.
   */
private void addImportConstraint(LogicalEdge e, SymbolicRoute varsOther, Configuration conf, Protocol proto, GraphEdge ge, String router) {
    SymbolicRoute vars = e.getSymbolicRecord();
    Interface iface = ge.getStart();
    ArithExpr failed = getSymbolicFailures().getFailedVariable(e.getEdge());
    assert (failed != null);
    BoolExpr notFailed = mkEq(failed, mkInt(0));
    if (vars.getIsUsed()) {
        if (proto.isConnected()) {
            Prefix p = iface.getAddress().getPrefix();
            BoolExpr relevant = mkAnd(interfaceActive(iface, proto), isRelevantFor(p, _symbolicPacket.getDstIp()), notFailed);
            BoolExpr per = vars.getPermitted();
            BoolExpr len = safeEq(vars.getPrefixLength(), mkInt(p.getPrefixLength()));
            BoolExpr ad = safeEq(vars.getAdminDist(), mkInt(1));
            BoolExpr lp = safeEq(vars.getLocalPref(), mkInt(0));
            BoolExpr met = safeEq(vars.getMetric(), mkInt(0));
            BoolExpr values = mkAnd(per, len, ad, lp, met);
            add(mkIf(relevant, values, mkNot(vars.getPermitted())));
        }
        if (proto.isStatic()) {
            List<StaticRoute> srs = getGraph().getStaticRoutes().get(router, iface.getName());
            assert (srs != null);
            BoolExpr acc = mkNot(vars.getPermitted());
            for (StaticRoute sr : srs) {
                Prefix p = sr.getNetwork();
                BoolExpr relevant = mkAnd(interfaceActive(iface, proto), isRelevantFor(p, _symbolicPacket.getDstIp()), notFailed);
                BoolExpr per = vars.getPermitted();
                BoolExpr len = safeEq(vars.getPrefixLength(), mkInt(p.getPrefixLength()));
                BoolExpr ad = safeEq(vars.getAdminDist(), mkInt(sr.getAdministrativeCost()));
                BoolExpr lp = safeEq(vars.getLocalPref(), mkInt(0));
                BoolExpr met = safeEq(vars.getMetric(), mkInt(0));
                BoolExpr values = mkAnd(per, len, ad, lp, met);
                acc = mkIf(relevant, values, acc);
            }
            add(acc);
        }
        if (proto.isOspf() || proto.isBgp()) {
            BoolExpr val = mkNot(vars.getPermitted());
            if (varsOther != null) {
                // BoolExpr isRoot = relevantOrigination(originations);
                BoolExpr active = interfaceActive(iface, proto);
                // Handle iBGP by checking reachability to the next hop to send messages
                boolean isNonClient = (proto.isBgp()) && (getGraph().peerType(ge) != Graph.BgpSendType.TO_EBGP);
                boolean isClient = (proto.isBgp()) && (getGraph().peerType(ge) == Graph.BgpSendType.TO_RR);
                BoolExpr receiveMessage;
                String currentRouter = ge.getRouter();
                String peerRouter = ge.getPeer();
                if (_encoder.getModelIgp() && isNonClient) {
                    // Lookup reachabilty based on peer next-hop
                    receiveMessage = _encoder.getSliceReachability().get(currentRouter).get(peerRouter);
                /* EncoderSlice peerSlice = _encoder.getSlice(peerRouter);
            BoolExpr srcPort = mkEq(peerSlice.getSymbolicPacket().getSrcPort(), mkInt(179));
            BoolExpr srcIp = mkEq(peerSlice.getSymbolicPacket().getSrcIp(), mkInt(0));
            BoolExpr tcpAck = mkEq(peerSlice.getSymbolicPacket().getTcpAck(), mkFalse());
            BoolExpr tcpCwr = mkEq(peerSlice.getSymbolicPacket().getTcpCwr(), mkFalse());
            BoolExpr tcpEce = mkEq(peerSlice.getSymbolicPacket().getTcpEce(), mkFalse());
            BoolExpr tcpFin = mkEq(peerSlice.getSymbolicPacket().getTcpFin(), mkFalse());
            BoolExpr tcpPsh = mkEq(peerSlice.getSymbolicPacket().getTcpPsh(), mkFalse());
            BoolExpr tcpRst = mkEq(peerSlice.getSymbolicPacket().getTcpRst(), mkFalse());
            BoolExpr tcpSyn = mkEq(peerSlice.getSymbolicPacket().getTcpSyn(), mkFalse());
            BoolExpr tcpUrg = mkEq(peerSlice.getSymbolicPacket().getTcpUrg(), mkFalse());
            BoolExpr icmpCode = mkEq(peerSlice.getSymbolicPacket().getIcmpCode(), mkInt(0));
            BoolExpr icmpType = mkEq(peerSlice.getSymbolicPacket().getIcmpType(), mkInt(0));
            BoolExpr all =
                mkAnd(srcPort, srcIp, tcpAck,
                    tcpCwr, tcpEce, tcpFin, tcpPsh, tcpRst, tcpSyn, tcpUrg, icmpCode, icmpType);
            receiveMessage = mkImplies(all, receiveMessage); */
                } else if (_encoder.getModelIgp() && isClient) {
                    // Lookup reachability based on client id tag to find next hop
                    BoolExpr acc = mkTrue();
                    for (Map.Entry<String, Integer> entry : getGraph().getOriginatorId().entrySet()) {
                        String r = entry.getKey();
                        Integer id = entry.getValue();
                        if (!r.equals(currentRouter)) {
                            BoolExpr reach = _encoder.getSliceReachability().get(currentRouter).get(r);
                            /* EncoderSlice peerSlice = _encoder.getSlice(r);
                BoolExpr srcPort = mkEq(peerSlice.getSymbolicPacket().getSrcPort(), mkInt(179));
                BoolExpr srcIp = mkEq(peerSlice.getSymbolicPacket().getSrcIp(), mkInt(0));
                BoolExpr tcpAck = mkEq(peerSlice.getSymbolicPacket().getTcpAck(), mkFalse());
                BoolExpr tcpCwr = mkEq(peerSlice.getSymbolicPacket().getTcpCwr(), mkFalse());
                BoolExpr tcpEce = mkEq(peerSlice.getSymbolicPacket().getTcpEce(), mkFalse());
                BoolExpr tcpFin = mkEq(peerSlice.getSymbolicPacket().getTcpFin(), mkFalse());
                BoolExpr tcpPsh = mkEq(peerSlice.getSymbolicPacket().getTcpPsh(), mkFalse());
                BoolExpr tcpRst = mkEq(peerSlice.getSymbolicPacket().getTcpRst(), mkFalse());
                BoolExpr tcpSyn = mkEq(peerSlice.getSymbolicPacket().getTcpSyn(), mkFalse());
                BoolExpr tcpUrg = mkEq(peerSlice.getSymbolicPacket().getTcpUrg(), mkFalse());
                BoolExpr icmpCode = mkEq(peerSlice.getSymbolicPacket().getIcmpCode(), mkInt(0));
                BoolExpr icmpType = mkEq(peerSlice.getSymbolicPacket().getIcmpType(), mkInt(0));
                BoolExpr all =
                    mkAnd(srcPort, srcIp, tcpAck,
                        tcpCwr, tcpEce, tcpFin, tcpPsh, tcpRst, tcpSyn, tcpUrg, icmpCode, icmpType);
                reach = mkImplies(all, reach); */
                            acc = mkAnd(acc, mkImplies(varsOther.getClientId().checkIfValue(id), reach));
                        }
                    }
                    receiveMessage = acc;
                // Just check if the link is failed
                } else {
                    receiveMessage = notFailed;
                }
                // Take into account BGP loop prevention
                // The path length will prevent any isolated loops
                BoolExpr loop = mkFalse();
                if (proto.isBgp() && ge.getPeer() != null) {
                    String peer = ge.getPeer();
                    GraphEdge gePeer = getGraph().getOtherEnd().get(ge);
                    loop = getSymbolicDecisions().getControlForwarding().get(peer, gePeer);
                }
                assert (loop != null);
                BoolExpr usable = mkAnd(mkNot(loop), active, varsOther.getPermitted(), receiveMessage);
                BoolExpr importFunction;
                RoutingPolicy pol = getGraph().findImportRoutingPolicy(router, proto, e.getEdge());
                if (Encoder.ENABLE_DEBUGGING && pol != null) {
                    System.out.println("Import Policy: " + pol.getName());
                }
                List<Statement> statements;
                if (pol == null) {
                    Statements.StaticStatement s = new Statements.StaticStatement(Statements.ExitAccept);
                    statements = Collections.singletonList(s);
                } else {
                    statements = pol.getStatements();
                }
                // OSPF cost calculated based on incoming interface
                Integer cost = proto.isOspf() ? addedCost(proto, ge) : 0;
                TransferSSA f = new TransferSSA(this, conf, varsOther, vars, proto, statements, cost, ge, false);
                importFunction = f.compute();
                BoolExpr acc = mkIf(usable, importFunction, val);
                if (Encoder.ENABLE_DEBUGGING) {
                    System.out.println("IMPORT FUNCTION: " + router + " " + varsOther.getName());
                    System.out.println(importFunction.simplify());
                    System.out.println("\n\n");
                }
                add(acc);
            } else {
                add(val);
            }
        }
    }
}
Also used : ArithExpr(com.microsoft.z3.ArithExpr) BoolExpr(com.microsoft.z3.BoolExpr) StaticRoute(org.batfish.datamodel.StaticRoute) Statement(org.batfish.datamodel.routing_policy.statement.Statement) RoutingPolicy(org.batfish.datamodel.routing_policy.RoutingPolicy) Prefix(org.batfish.datamodel.Prefix) Entry(java.util.Map.Entry) Statements(org.batfish.datamodel.routing_policy.statement.Statements) GraphEdge(org.batfish.symbolic.GraphEdge) Interface(org.batfish.datamodel.Interface)

Example 49 with BoolExpr

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

the class EncoderSlice method addForwardingVariables.

/*
   * Initalizes variables representing the control plane and
   * data plane final forwarding decisions
   */
private void addForwardingVariables() {
    for (Entry<String, List<GraphEdge>> entry : getGraph().getEdgeMap().entrySet()) {
        String router = entry.getKey();
        List<GraphEdge> edges = entry.getValue();
        for (GraphEdge edge : edges) {
            String iface = edge.getStart().getName();
            String cName = _encoder.getId() + "_" + _sliceName + "CONTROL-FORWARDING_" + router + "_" + iface;
            BoolExpr cForward = getCtx().mkBoolConst(cName);
            getAllVariables().put(cForward.toString(), cForward);
            _symbolicDecisions.getControlForwarding().put(router, edge, cForward);
            // Don't add data forwarding variable for abstract edge
            if (!edge.isAbstract()) {
                String dName = _encoder.getId() + "_" + _sliceName + "DATA-FORWARDING_" + router + "_" + iface;
                BoolExpr dForward = getCtx().mkBoolConst(dName);
                getAllVariables().put(dForward.toString(), dForward);
                _symbolicDecisions.getDataForwarding().put(router, edge, dForward);
            }
        }
    }
}
Also used : BoolExpr(com.microsoft.z3.BoolExpr) IpAccessList(org.batfish.datamodel.IpAccessList) ArrayList(java.util.ArrayList) List(java.util.List) GraphEdge(org.batfish.symbolic.GraphEdge)

Example 50 with BoolExpr

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

the class EncoderSlice method addBestPerProtocolConstraints.

/*
   * Constrains each protocol-best record similarly to the overall
   * best record. It will be better than all choices and equal to
   * at least one of them.
   */
private void addBestPerProtocolConstraints() {
    for (Entry<String, Configuration> entry : getGraph().getConfigurations().entrySet()) {
        String router = entry.getKey();
        Configuration conf = entry.getValue();
        for (Protocol proto : getProtocols().get(router)) {
            SymbolicRoute bestVars = _symbolicDecisions.getBestVars(_optimizations, router, proto);
            assert (bestVars != null);
            BoolExpr acc = null;
            BoolExpr somePermitted = null;
            for (LogicalEdge e : collectAllImportLogicalEdges(router, conf, proto)) {
                SymbolicRoute vars = correctVars(e);
                if (somePermitted == null) {
                    somePermitted = vars.getPermitted();
                } else {
                    somePermitted = mkOr(somePermitted, vars.getPermitted());
                }
                BoolExpr v = mkAnd(vars.getPermitted(), equal(conf, proto, bestVars, vars, e, true));
                if (acc == null) {
                    acc = v;
                } else {
                    acc = mkOr(acc, v);
                }
                add(mkImplies(vars.getPermitted(), greaterOrEqual(conf, proto, bestVars, vars, e)));
            }
            if (acc != null) {
                add(mkEq(somePermitted, bestVars.getPermitted()));
                add(mkImplies(somePermitted, acc));
            }
        }
    }
}
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)

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