Search in sources :

Example 6 with BDD

use of net.sf.javabdd.BDD in project batfish by batfish.

the class TransferBDD method matchCommunityList.

/*
   * Converts a community list to a boolean expression.
   */
private BDD matchCommunityList(TransferParam<BDDRoute> p, CommunityList cl, BDDRoute other) {
    List<CommunityListLine> lines = new ArrayList<>(cl.getLines());
    Collections.reverse(lines);
    BDD acc = factory.zero();
    for (CommunityListLine line : lines) {
        boolean action = (line.getAction() == LineAction.ACCEPT);
        CommunityVar cvar = new CommunityVar(CommunityVar.Type.REGEX, line.getRegex(), null);
        p.debug("Match Line: " + cvar);
        p.debug("Action: " + line.getAction());
        // Skip this match if it is irrelevant
        if (_policyQuotient.getCommsMatchedButNotAssigned().contains(cvar)) {
            continue;
        }
        List<CommunityVar> deps = _commDeps.get(cvar);
        for (CommunityVar dep : deps) {
            p.debug("Test for: " + dep);
            BDD c = other.getCommunities().get(dep);
            acc = ite(c, mkBDD(action), acc);
        }
    }
    return acc;
}
Also used : CommunityVar(org.batfish.symbolic.CommunityVar) BDD(net.sf.javabdd.BDD) CommunityListLine(org.batfish.datamodel.CommunityListLine) ArrayList(java.util.ArrayList)

Example 7 with BDD

use of net.sf.javabdd.BDD 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 8 with BDD

use of net.sf.javabdd.BDD in project batfish by batfish.

the class BDDAcl method computeTcpFlags.

/*
   * Convert a Tcp flag to a boolean expression on the symbolic packet
   */
private BDD computeTcpFlags(TcpFlags flags) {
    BDD acc = _factory.one();
    if (flags.getUseAck()) {
        BDD value = flags.getAck() ? _pkt.getTcpAck() : _pkt.getTcpAck().not();
        acc = acc.and(value);
    }
    if (flags.getUseCwr()) {
        BDD value = flags.getCwr() ? _pkt.getTcpCwr() : _pkt.getTcpCwr().not();
        acc = acc.and(value);
    }
    if (flags.getUseEce()) {
        BDD value = flags.getEce() ? _pkt.getTcpEce() : _pkt.getTcpEce().not();
        acc = acc.and(value);
    }
    if (flags.getUseFin()) {
        BDD value = flags.getFin() ? _pkt.getTcpFin() : _pkt.getTcpFin().not();
        acc = acc.and(value);
    }
    if (flags.getUsePsh()) {
        BDD value = flags.getPsh() ? _pkt.getTcpPsh() : _pkt.getTcpPsh().not();
        acc = acc.and(value);
    }
    if (flags.getUseRst()) {
        BDD value = flags.getRst() ? _pkt.getTcpRst() : _pkt.getTcpRst().not();
        acc = acc.and(value);
    }
    if (flags.getUseSyn()) {
        BDD value = flags.getSyn() ? _pkt.getTcpSyn() : _pkt.getTcpSyn().not();
        acc = acc.and(value);
    }
    if (flags.getUseUrg()) {
        BDD value = flags.getUrg() ? _pkt.getTcpUrg() : _pkt.getTcpUrg().not();
        acc = acc.and(value);
    }
    return acc;
}
Also used : BDD(net.sf.javabdd.BDD)

Example 9 with BDD

use of net.sf.javabdd.BDD in project batfish by batfish.

the class BDDAcl method computeWildcardMatch.

/*
   * Convert a set of wildcards and a packet field to a symbolic boolean expression
   */
private BDD computeWildcardMatch(Set<IpWildcard> wcs, BDDInteger field, @Nullable Set<Prefix> ignored) {
    BDD acc = _factory.zero();
    for (IpWildcard wc : wcs) {
        if (!wc.isPrefix()) {
            throw new BatfishException("ERROR: computeDstWildcards, non sequential mask detected");
        }
        Prefix p = wc.toPrefix();
        // if (!PrefixUtils.isContainedBy(p, ignored)) {
        acc = acc.or(isRelevantFor(p, field));
    // }
    }
    return acc;
}
Also used : IpWildcard(org.batfish.datamodel.IpWildcard) BatfishException(org.batfish.common.BatfishException) BDD(net.sf.javabdd.BDD) Prefix(org.batfish.datamodel.Prefix)

Example 10 with BDD

use of net.sf.javabdd.BDD in project batfish by batfish.

the class BDDAcl method firstBitsEqual.

/*
   * Check if the first length bits match the BDDInteger
   * representing the advertisement prefix.
   *
   * Note: We assume the prefix is never modified, so it will
   * be a bitvector containing only the underlying variables:
   * [var(0), ..., var(n)]
   */
private BDD firstBitsEqual(BDD[] bits, Prefix p, int length) {
    long b = p.getStartIp().asLong();
    BDD acc = _factory.one();
    for (int i = 0; i < length; i++) {
        boolean res = Ip.getBitAtPosition(b, i);
        if (res) {
            acc = acc.and(bits[i]);
        } else {
            acc = acc.and(bits[i].not());
        }
    }
    return acc;
}
Also used : BDD(net.sf.javabdd.BDD)

Aggregations

BDD (net.sf.javabdd.BDD)26 BatfishException (org.batfish.common.BatfishException)7 ArrayList (java.util.ArrayList)5 Prefix (org.batfish.datamodel.Prefix)4 SubRange (org.batfish.datamodel.SubRange)3 CommunityVar (org.batfish.symbolic.CommunityVar)3 HashSet (java.util.HashSet)2 Set (java.util.Set)2 BDDException (net.sf.javabdd.BDDException)2 PrefixRange (org.batfish.datamodel.PrefixRange)2 ExplicitPrefixSet (org.batfish.datamodel.routing_policy.expr.ExplicitPrefixSet)2 InlineCommunitySet (org.batfish.datamodel.routing_policy.expr.InlineCommunitySet)2 MatchCommunitySet (org.batfish.datamodel.routing_policy.expr.MatchCommunitySet)2 MatchPrefix6Set (org.batfish.datamodel.routing_policy.expr.MatchPrefix6Set)2 MatchPrefixSet (org.batfish.datamodel.routing_policy.expr.MatchPrefixSet)2 NamedCommunitySet (org.batfish.datamodel.routing_policy.expr.NamedCommunitySet)2 NamedPrefixSet (org.batfish.datamodel.routing_policy.expr.NamedPrefixSet)2 TransferResult (org.batfish.symbolic.TransferResult)2 HashMap (java.util.HashMap)1 List (java.util.List)1