Search in sources :

Example 1 with OspfType

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

the class TransferBDD method compute.

/*
   * Convert a list of statements into a Z3 boolean expression for the transfer function.
   */
private TransferResult<TransferReturn, BDD> compute(List<Statement> statements, TransferParam<BDDRoute> p) {
    boolean doesReturn = false;
    TransferResult<TransferReturn, BDD> result = new TransferResult<>();
    result = result.setReturnValue(new TransferReturn(p.getData(), factory.zero())).setFallthroughValue(factory.zero()).setReturnAssignedValue(factory.zero());
    for (Statement stmt : statements) {
        if (stmt instanceof StaticStatement) {
            StaticStatement ss = (StaticStatement) stmt;
            switch(ss.getType()) {
                case ExitAccept:
                    doesReturn = true;
                    p.debug("ExitAccept");
                    result = returnValue(result, true);
                    break;
                case ReturnTrue:
                    doesReturn = true;
                    p.debug("ReturnTrue");
                    result = returnValue(result, true);
                    break;
                case ExitReject:
                    doesReturn = true;
                    p.debug("ExitReject");
                    result = returnValue(result, false);
                    break;
                case ReturnFalse:
                    doesReturn = true;
                    p.debug("ReturnFalse");
                    result = returnValue(result, false);
                    break;
                case SetDefaultActionAccept:
                    p.debug("SetDefaulActionAccept");
                    p = p.setDefaultAccept(true);
                    break;
                case SetDefaultActionReject:
                    p.debug("SetDefaultActionReject");
                    p = p.setDefaultAccept(false);
                    break;
                case SetLocalDefaultActionAccept:
                    p.debug("SetLocalDefaultActionAccept");
                    p = p.setDefaultAcceptLocal(true);
                    break;
                case SetLocalDefaultActionReject:
                    p.debug("SetLocalDefaultActionReject");
                    p = p.setDefaultAcceptLocal(false);
                    break;
                case ReturnLocalDefaultAction:
                    p.debug("ReturnLocalDefaultAction");
                    // TODO: need to set local default action in an environment
                    if (p.getDefaultAcceptLocal()) {
                        result = returnValue(result, true);
                    } else {
                        result = returnValue(result, false);
                    }
                    break;
                case FallThrough:
                    p.debug("Fallthrough");
                    result = fallthrough(result);
                    break;
                case Return:
                    // TODO: assumming this happens at the end of the function, so it is ignored for now.
                    p.debug("Return");
                    break;
                case RemovePrivateAs:
                    p.debug("RemovePrivateAs");
                    // System.out.println("Warning: use of unimplemented feature RemovePrivateAs");
                    break;
                default:
                    throw new BatfishException("TODO: computeTransferFunction: " + ss.getType());
            }
        } else if (stmt instanceof If) {
            p.debug("If");
            If i = (If) stmt;
            TransferResult<TransferReturn, BDD> r = compute(i.getGuard(), p.indent());
            BDD guard = r.getReturnValue().getSecond();
            p.debug("guard: ");
            BDDRoute current = result.getReturnValue().getFirst();
            TransferParam<BDDRoute> pTrue = p.indent().setData(current.deepCopy());
            TransferParam<BDDRoute> pFalse = p.indent().setData(current.deepCopy());
            p.debug("True Branch");
            TransferResult<TransferReturn, BDD> trueBranch = compute(i.getTrueStatements(), pTrue);
            p.debug("True Branch: " + trueBranch.getReturnValue().getFirst().hashCode());
            p.debug("False Branch");
            TransferResult<TransferReturn, BDD> falseBranch = compute(i.getFalseStatements(), pFalse);
            p.debug("False Branch: " + trueBranch.getReturnValue().getFirst().hashCode());
            BDDRoute r1 = trueBranch.getReturnValue().getFirst();
            BDDRoute r2 = falseBranch.getReturnValue().getFirst();
            BDDRoute recordVal = ite(guard, r1, r2);
            // update return values
            BDD returnVal = ite(guard, trueBranch.getReturnValue().getSecond(), falseBranch.getReturnValue().getSecond());
            // p.debug("New Return Value (neg): " + returnVal.not());
            BDD returnAss = ite(guard, trueBranch.getReturnAssignedValue(), falseBranch.getReturnAssignedValue());
            // p.debug("New Return Assigned: " + returnAss);
            BDD fallThrough = ite(guard, trueBranch.getFallthroughValue(), falseBranch.getFallthroughValue());
            // p.debug("New fallthrough: " + fallThrough);
            result = result.setReturnValue(new TransferReturn(recordVal, returnVal)).setReturnAssignedValue(returnAss).setFallthroughValue(fallThrough);
            p.debug("If return: " + result.getReturnValue().getFirst().hashCode());
        } else if (stmt instanceof SetDefaultPolicy) {
            p.debug("SetDefaultPolicy");
            p = p.setDefaultPolicy((SetDefaultPolicy) stmt);
        } else if (stmt instanceof SetMetric) {
            p.debug("SetMetric");
            SetMetric sm = (SetMetric) stmt;
            LongExpr ie = sm.getMetric();
            BDD isBGP = p.getData().getProtocolHistory().value(Protocol.BGP);
            BDD updateMed = isBGP.and(result.getReturnAssignedValue());
            BDD updateMet = isBGP.not().and(result.getReturnAssignedValue());
            BDDInteger newValue = applyLongExprModification(p.indent(), p.getData().getMetric(), ie);
            BDDInteger med = ite(updateMed, p.getData().getMed(), newValue);
            BDDInteger met = ite(updateMet, p.getData().getMetric(), newValue);
            p.getData().setMetric(met);
            p.getData().setMetric(med);
        } else if (stmt instanceof SetOspfMetricType) {
            p.debug("SetOspfMetricType");
            SetOspfMetricType somt = (SetOspfMetricType) stmt;
            OspfMetricType mt = somt.getMetricType();
            BDDDomain<OspfType> current = result.getReturnValue().getFirst().getOspfMetric();
            BDDDomain<OspfType> newValue = new BDDDomain<>(current);
            if (mt == OspfMetricType.E1) {
                p.indent().debug("Value: E1");
                newValue.setValue(OspfType.E1);
            } else {
                p.indent().debug("Value: E2");
                newValue.setValue(OspfType.E1);
            }
            newValue = ite(result.getReturnAssignedValue(), p.getData().getOspfMetric(), newValue);
            p.getData().setOspfMetric(newValue);
        } else if (stmt instanceof SetLocalPreference) {
            p.debug("SetLocalPreference");
            SetLocalPreference slp = (SetLocalPreference) stmt;
            IntExpr ie = slp.getLocalPreference();
            BDDInteger newValue = applyIntExprModification(p.indent(), p.getData().getLocalPref(), ie);
            newValue = ite(result.getReturnAssignedValue(), p.getData().getLocalPref(), newValue);
            p.getData().setLocalPref(newValue);
        } else if (stmt instanceof AddCommunity) {
            p.debug("AddCommunity");
            AddCommunity ac = (AddCommunity) stmt;
            Set<CommunityVar> comms = _graph.findAllCommunities(_conf, ac.getExpr());
            for (CommunityVar cvar : comms) {
                if (!_policyQuotient.getCommsAssignedButNotMatched().contains(cvar)) {
                    p.indent().debug("Value: " + cvar);
                    BDD comm = p.getData().getCommunities().get(cvar);
                    BDD newValue = ite(result.getReturnAssignedValue(), comm, factory.one());
                    p.indent().debug("New Value: " + newValue);
                    p.getData().getCommunities().put(cvar, newValue);
                }
            }
        } else if (stmt instanceof SetCommunity) {
            p.debug("SetCommunity");
            SetCommunity sc = (SetCommunity) stmt;
            Set<CommunityVar> comms = _graph.findAllCommunities(_conf, sc.getExpr());
            for (CommunityVar cvar : comms) {
                if (!_policyQuotient.getCommsAssignedButNotMatched().contains(cvar)) {
                    p.indent().debug("Value: " + cvar);
                    BDD comm = p.getData().getCommunities().get(cvar);
                    BDD newValue = ite(result.getReturnAssignedValue(), comm, factory.one());
                    p.indent().debug("New Value: " + newValue);
                    p.getData().getCommunities().put(cvar, newValue);
                }
            }
        } else if (stmt instanceof DeleteCommunity) {
            p.debug("DeleteCommunity");
            DeleteCommunity ac = (DeleteCommunity) stmt;
            Set<CommunityVar> comms = _graph.findAllCommunities(_conf, ac.getExpr());
            Set<CommunityVar> toDelete = new HashSet<>();
            // Find comms to delete
            for (CommunityVar cvar : comms) {
                if (cvar.getType() == Type.REGEX) {
                    toDelete.addAll(_commDeps.get(cvar));
                } else {
                    toDelete.add(cvar);
                }
            }
            // Delete the comms
            for (CommunityVar cvar : toDelete) {
                if (!_policyQuotient.getCommsAssignedButNotMatched().contains(cvar)) {
                    p.indent().debug("Value: " + cvar.getValue() + ", " + cvar.getType());
                    BDD comm = p.getData().getCommunities().get(cvar);
                    BDD newValue = ite(result.getReturnAssignedValue(), comm, factory.zero());
                    p.indent().debug("New Value: " + newValue);
                    p.getData().getCommunities().put(cvar, newValue);
                }
            }
        } else if (stmt instanceof RetainCommunity) {
            p.debug("RetainCommunity");
        // no op
        } else if (stmt instanceof PrependAsPath) {
            p.debug("PrependAsPath");
            PrependAsPath pap = (PrependAsPath) stmt;
            Integer prependCost = prependLength(pap.getExpr());
            p.indent().debug("Cost: " + prependCost);
            BDDInteger met = p.getData().getMetric();
            BDDInteger newValue = met.add(BDDInteger.makeFromValue(met.getFactory(), 32, prependCost));
            newValue = ite(result.getReturnAssignedValue(), p.getData().getMetric(), newValue);
            p.getData().setMetric(newValue);
        } else if (stmt instanceof SetOrigin) {
            p.debug("SetOrigin");
        // System.out.println("Warning: use of unimplemented feature SetOrigin");
        // TODO: implement me
        } else if (stmt instanceof SetNextHop) {
            p.debug("SetNextHop");
        // System.out.println("Warning: use of unimplemented feature SetNextHop");
        // TODO: implement me
        } else {
            throw new BatfishException("TODO: statement transfer function: " + stmt);
        }
    }
    // If this is the outermost call, then we relate the variables
    if (p.getInitialCall()) {
        p.debug("InitialCall finalizing");
        // Apply the default action
        if (!doesReturn) {
            p.debug("Applying default action: " + p.getDefaultAccept());
            if (p.getDefaultAccept()) {
                result = returnValue(result, true);
            } else {
                result = returnValue(result, false);
            }
        }
        // Set all the values to 0 if the return is not true;
        TransferReturn ret = result.getReturnValue();
        BDDRoute retVal = ite(ret.getSecond(), ret.getFirst(), zeroedRecord());
        result = result.setReturnValue(new TransferReturn(retVal, ret.getSecond()));
    }
    return result;
}
Also used : BDD(net.sf.javabdd.BDD) MatchCommunitySet(org.batfish.datamodel.routing_policy.expr.MatchCommunitySet) MatchPrefix6Set(org.batfish.datamodel.routing_policy.expr.MatchPrefix6Set) InlineCommunitySet(org.batfish.datamodel.routing_policy.expr.InlineCommunitySet) Set(java.util.Set) NamedPrefixSet(org.batfish.datamodel.routing_policy.expr.NamedPrefixSet) HashSet(java.util.HashSet) ExplicitPrefixSet(org.batfish.datamodel.routing_policy.expr.ExplicitPrefixSet) MatchPrefixSet(org.batfish.datamodel.routing_policy.expr.MatchPrefixSet) NamedCommunitySet(org.batfish.datamodel.routing_policy.expr.NamedCommunitySet) TransferResult(org.batfish.symbolic.TransferResult) RetainCommunity(org.batfish.datamodel.routing_policy.statement.RetainCommunity) SetMetric(org.batfish.datamodel.routing_policy.statement.SetMetric) SetCommunity(org.batfish.datamodel.routing_policy.statement.SetCommunity) OspfType(org.batfish.symbolic.OspfType) SetNextHop(org.batfish.datamodel.routing_policy.statement.SetNextHop) LongExpr(org.batfish.datamodel.routing_policy.expr.LongExpr) HashSet(java.util.HashSet) BatfishException(org.batfish.common.BatfishException) StaticStatement(org.batfish.datamodel.routing_policy.statement.Statements.StaticStatement) Statement(org.batfish.datamodel.routing_policy.statement.Statement) StaticStatement(org.batfish.datamodel.routing_policy.statement.Statements.StaticStatement) SetOrigin(org.batfish.datamodel.routing_policy.statement.SetOrigin) DeleteCommunity(org.batfish.datamodel.routing_policy.statement.DeleteCommunity) SetDefaultPolicy(org.batfish.datamodel.routing_policy.statement.SetDefaultPolicy) AddCommunity(org.batfish.datamodel.routing_policy.statement.AddCommunity) CommunityVar(org.batfish.symbolic.CommunityVar) OspfMetricType(org.batfish.datamodel.OspfMetricType) SetOspfMetricType(org.batfish.datamodel.routing_policy.statement.SetOspfMetricType) SetLocalPreference(org.batfish.datamodel.routing_policy.statement.SetLocalPreference) TransferParam(org.batfish.symbolic.TransferParam) PrependAsPath(org.batfish.datamodel.routing_policy.statement.PrependAsPath) SetOspfMetricType(org.batfish.datamodel.routing_policy.statement.SetOspfMetricType) IntExpr(org.batfish.datamodel.routing_policy.expr.IntExpr) If(org.batfish.datamodel.routing_policy.statement.If)

Example 2 with OspfType

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

the class Encoder method buildCounterExample.

/*
   * Add the relevant variables in the counterexample to
   * display to the user in a human-readable fashion
   */
private void buildCounterExample(Encoder enc, Model m, SortedMap<String, String> model, SortedMap<String, String> packetModel, SortedSet<String> fwdModel, SortedMap<String, SortedMap<String, String>> envModel, SortedSet<String> failures) {
    SortedMap<Expr, String> valuation = new TreeMap<>();
    // If user asks for the full model
    for (Entry<String, Expr> entry : _allVariables.entrySet()) {
        String name = entry.getKey();
        Expr e = entry.getValue();
        Expr val = m.evaluate(e, true);
        if (!val.equals(e)) {
            String s = val.toString();
            if (_question.getFullModel()) {
                model.put(name, s);
            }
            valuation.put(e, s);
        }
    }
    // Packet model
    SymbolicPacket p = enc.getMainSlice().getSymbolicPacket();
    String dstIp = valuation.get(p.getDstIp());
    String srcIp = valuation.get(p.getSrcIp());
    String dstPt = valuation.get(p.getDstPort());
    String srcPt = valuation.get(p.getSrcPort());
    String icmpCode = valuation.get(p.getIcmpCode());
    String icmpType = valuation.get(p.getIcmpType());
    String ipProtocol = valuation.get(p.getIpProtocol());
    String tcpAck = valuation.get(p.getTcpAck());
    String tcpCwr = valuation.get(p.getTcpCwr());
    String tcpEce = valuation.get(p.getTcpEce());
    String tcpFin = valuation.get(p.getTcpFin());
    String tcpPsh = valuation.get(p.getTcpPsh());
    String tcpRst = valuation.get(p.getTcpRst());
    String tcpSyn = valuation.get(p.getTcpSyn());
    String tcpUrg = valuation.get(p.getTcpUrg());
    Ip dip = new Ip(Long.parseLong(dstIp));
    Ip sip = new Ip(Long.parseLong(srcIp));
    packetModel.put("dstIp", dip.toString());
    if (sip.asLong() != 0) {
        packetModel.put("srcIp", sip.toString());
    }
    if (dstPt != null && !dstPt.equals("0")) {
        packetModel.put("dstPort", dstPt);
    }
    if (srcPt != null && !srcPt.equals("0")) {
        packetModel.put("srcPort", srcPt);
    }
    if (icmpCode != null && !icmpCode.equals("0")) {
        packetModel.put("icmpCode", icmpCode);
    }
    if (icmpType != null && !icmpType.equals("0")) {
        packetModel.put("icmpType", icmpType);
    }
    if (ipProtocol != null && !ipProtocol.equals("0")) {
        Integer number = Integer.parseInt(ipProtocol);
        IpProtocol proto = IpProtocol.fromNumber(number);
        packetModel.put("protocol", proto.toString());
    }
    if ("true".equals(tcpAck)) {
        packetModel.put("tcpAck", "set");
    }
    if ("true".equals(tcpCwr)) {
        packetModel.put("tcpCwr", "set");
    }
    if ("true".equals(tcpEce)) {
        packetModel.put("tcpEce", "set");
    }
    if ("true".equals(tcpFin)) {
        packetModel.put("tcpFin", "set");
    }
    if ("true".equals(tcpPsh)) {
        packetModel.put("tcpPsh", "set");
    }
    if ("true".equals(tcpRst)) {
        packetModel.put("tcpRst", "set");
    }
    if ("true".equals(tcpSyn)) {
        packetModel.put("tcpSyn", "set");
    }
    if ("true".equals(tcpUrg)) {
        packetModel.put("tcpUrg", "set");
    }
    for (EncoderSlice slice : enc.getSlices().values()) {
        for (Entry<LogicalEdge, SymbolicRoute> entry2 : slice.getLogicalGraph().getEnvironmentVars().entrySet()) {
            LogicalEdge lge = entry2.getKey();
            SymbolicRoute r = entry2.getValue();
            if ("true".equals(valuation.get(r.getPermitted()))) {
                SortedMap<String, String> recordMap = new TreeMap<>();
                GraphEdge ge = lge.getEdge();
                String nodeIface = ge.getRouter() + "," + ge.getStart().getName() + " (BGP)";
                envModel.put(nodeIface, recordMap);
                if (r.getPrefixLength() != null) {
                    String x = valuation.get(r.getPrefixLength());
                    if (x != null) {
                        int len = Integer.parseInt(x);
                        Prefix p1 = new Prefix(dip, len);
                        recordMap.put("prefix", p1.toString());
                    }
                }
                if (r.getAdminDist() != null) {
                    String x = valuation.get(r.getAdminDist());
                    if (x != null) {
                        recordMap.put("admin distance", x);
                    }
                }
                if (r.getLocalPref() != null) {
                    String x = valuation.get(r.getLocalPref());
                    if (x != null) {
                        recordMap.put("local preference", x);
                    }
                }
                if (r.getMetric() != null) {
                    String x = valuation.get(r.getMetric());
                    if (x != null) {
                        recordMap.put("protocol metric", x);
                    }
                }
                if (r.getMed() != null) {
                    String x = valuation.get(r.getMed());
                    if (x != null) {
                        recordMap.put("multi-exit disc.", valuation.get(r.getMed()));
                    }
                }
                if (r.getOspfArea() != null && r.getOspfArea().getBitVec() != null) {
                    String x = valuation.get(r.getOspfArea().getBitVec());
                    if (x != null) {
                        Integer i = Integer.parseInt(x);
                        Long area = r.getOspfArea().value(i);
                        recordMap.put("OSPF Area", area.toString());
                    }
                }
                if (r.getOspfType() != null && r.getOspfType().getBitVec() != null) {
                    String x = valuation.get(r.getOspfType().getBitVec());
                    if (x != null) {
                        Integer i = Integer.parseInt(x);
                        OspfType type = r.getOspfType().value(i);
                        recordMap.put("OSPF Type", type.toString());
                    }
                }
                for (Entry<CommunityVar, BoolExpr> entry3 : r.getCommunities().entrySet()) {
                    CommunityVar cvar = entry3.getKey();
                    BoolExpr e = entry3.getValue();
                    String c = valuation.get(e);
                    // TODO: what about OTHER type?
                    if ("true".equals(c) && displayCommunity(cvar)) {
                        String s = cvar.getValue();
                        String t = slice.getNamedCommunities().get(cvar.getValue());
                        s = (t == null ? s : t);
                        recordMap.put("community " + s, "");
                    }
                }
            }
        }
    }
    // Forwarding Model
    enc.getMainSlice().getSymbolicDecisions().getDataForwarding().forEach((router, edge, e) -> {
        String s = valuation.get(e);
        if ("true".equals(s)) {
            SymbolicRoute r = enc.getMainSlice().getSymbolicDecisions().getBestNeighbor().get(router);
            if (r.getProtocolHistory() != null) {
                Protocol proto;
                List<Protocol> allProtocols = enc.getMainSlice().getProtocols().get(router);
                if (allProtocols.size() == 1) {
                    proto = allProtocols.get(0);
                } else {
                    s = valuation.get(r.getProtocolHistory().getBitVec());
                    int i = Integer.parseInt(s);
                    proto = r.getProtocolHistory().value(i);
                }
                fwdModel.add(edge + " (" + proto.name() + ")");
            } else {
                fwdModel.add(edge.toString());
            }
        }
    });
    _symbolicFailures.getFailedInternalLinks().forEach((x, y, e) -> {
        String s = valuation.get(e);
        if ("1".equals(s)) {
            String pair = (x.compareTo(y) < 0 ? x + "," + y : y + "," + x);
            failures.add("link(" + pair + ")");
        }
    });
    _symbolicFailures.getFailedEdgeLinks().forEach((ge, e) -> {
        String s = valuation.get(e);
        if ("1".equals(s)) {
            failures.add("link(" + ge.getRouter() + "," + ge.getStart().getName() + ")");
        }
    });
}
Also used : BoolExpr(com.microsoft.z3.BoolExpr) Ip(org.batfish.datamodel.Ip) Prefix(org.batfish.datamodel.Prefix) TreeMap(java.util.TreeMap) CommunityVar(org.batfish.symbolic.CommunityVar) BoolExpr(com.microsoft.z3.BoolExpr) ArithExpr(com.microsoft.z3.ArithExpr) BitVecExpr(com.microsoft.z3.BitVecExpr) Expr(com.microsoft.z3.Expr) IpProtocol(org.batfish.datamodel.IpProtocol) OspfType(org.batfish.symbolic.OspfType) IpProtocol(org.batfish.datamodel.IpProtocol) Protocol(org.batfish.symbolic.Protocol) GraphEdge(org.batfish.symbolic.GraphEdge)

Aggregations

CommunityVar (org.batfish.symbolic.CommunityVar)2 OspfType (org.batfish.symbolic.OspfType)2 ArithExpr (com.microsoft.z3.ArithExpr)1 BitVecExpr (com.microsoft.z3.BitVecExpr)1 BoolExpr (com.microsoft.z3.BoolExpr)1 Expr (com.microsoft.z3.Expr)1 HashSet (java.util.HashSet)1 Set (java.util.Set)1 TreeMap (java.util.TreeMap)1 BDD (net.sf.javabdd.BDD)1 BatfishException (org.batfish.common.BatfishException)1 Ip (org.batfish.datamodel.Ip)1 IpProtocol (org.batfish.datamodel.IpProtocol)1 OspfMetricType (org.batfish.datamodel.OspfMetricType)1 Prefix (org.batfish.datamodel.Prefix)1 ExplicitPrefixSet (org.batfish.datamodel.routing_policy.expr.ExplicitPrefixSet)1 InlineCommunitySet (org.batfish.datamodel.routing_policy.expr.InlineCommunitySet)1 IntExpr (org.batfish.datamodel.routing_policy.expr.IntExpr)1 LongExpr (org.batfish.datamodel.routing_policy.expr.LongExpr)1 MatchCommunitySet (org.batfish.datamodel.routing_policy.expr.MatchCommunitySet)1