Search in sources :

Example 1 with BDD

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

the class TransferBDD method ite.

private BDDRoute ite(BDD guard, BDDRoute r1, BDDRoute r2) {
    BDDRoute ret = new BDDRoute(_comms);
    BDDInteger x;
    BDDInteger y;
    // update integer values based on condition
    // x = r1.getPrefixLength();
    // y = r2.getPrefixLength();
    // ret.getPrefixLength().setValue(ite(guard, x, y));
    // x = r1.getIp();
    // y = r2.getIp();
    // ret.getIp().setValue(ite(guard, x, y));
    x = r1.getAdminDist();
    y = r2.getAdminDist();
    ret.getAdminDist().setValue(ite(guard, x, y));
    x = r1.getLocalPref();
    y = r2.getLocalPref();
    ret.getLocalPref().setValue(ite(guard, x, y));
    x = r1.getMetric();
    y = r2.getMetric();
    ret.getMetric().setValue(ite(guard, x, y));
    x = r1.getMed();
    y = r2.getMed();
    ret.getMed().setValue(ite(guard, x, y));
    r1.getCommunities().forEach((c, var1) -> {
        BDD var2 = r2.getCommunities().get(c);
        ret.getCommunities().put(c, ite(guard, var1, var2));
    });
    return ret;
}
Also used : BDD(net.sf.javabdd.BDD)

Example 2 with BDD

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

the class TransferBDD method compute.

/*
   * Convert a Batfish AST boolean expression to a symbolic Z3 boolean expression
   * by performing inlining of stateful side effects.
   */
private TransferResult<TransferReturn, BDD> compute(BooleanExpr expr, TransferParam<BDDRoute> p) {
    // TODO: right now everything is IPV4
    if (expr instanceof MatchIpv4) {
        p.debug("MatchIpv4");
        TransferReturn ret = new TransferReturn(p.getData(), factory.one());
        p.debug("MatchIpv4 Result: " + ret);
        return fromExpr(ret);
    }
    if (expr instanceof MatchIpv6) {
        p.debug("MatchIpv6");
        TransferReturn ret = new TransferReturn(p.getData(), factory.zero());
        return fromExpr(ret);
    }
    if (expr instanceof Conjunction) {
        p.debug("Conjunction");
        Conjunction c = (Conjunction) expr;
        BDD acc = factory.one();
        TransferResult<TransferReturn, BDD> result = new TransferResult<>();
        for (BooleanExpr be : c.getConjuncts()) {
            TransferResult<TransferReturn, BDD> r = compute(be, p.indent());
            acc = acc.and(r.getReturnValue().getSecond());
        }
        TransferReturn ret = new TransferReturn(p.getData(), acc);
        p.debug("Conjunction return: " + acc);
        return result.setReturnValue(ret);
    }
    if (expr instanceof Disjunction) {
        p.debug("Disjunction");
        Disjunction d = (Disjunction) expr;
        BDD acc = factory.zero();
        TransferResult<TransferReturn, BDD> result = new TransferResult<>();
        for (BooleanExpr be : d.getDisjuncts()) {
            TransferResult<TransferReturn, BDD> r = compute(be, p.indent());
            result = result.addChangedVariables(r);
            acc = acc.or(r.getReturnValue().getSecond());
        }
        TransferReturn ret = new TransferReturn(p.getData(), acc);
        p.debug("Disjunction return: " + acc);
        return result.setReturnValue(ret);
    }
    // TODO: thread the BDDRecord through calls
    if (expr instanceof ConjunctionChain) {
        p.debug("ConjunctionChain");
        ConjunctionChain d = (ConjunctionChain) expr;
        List<BooleanExpr> conjuncts = new ArrayList<>(d.getSubroutines());
        if (p.getDefaultPolicy() != null) {
            BooleanExpr be = new CallExpr(p.getDefaultPolicy().getDefaultPolicy());
            conjuncts.add(be);
        }
        if (conjuncts.size() == 0) {
            TransferReturn ret = new TransferReturn(p.getData(), factory.one());
            return fromExpr(ret);
        } else {
            TransferResult<TransferReturn, BDD> result = new TransferResult<>();
            TransferParam<BDDRoute> record = p;
            BDD acc = factory.zero();
            for (int i = conjuncts.size() - 1; i >= 0; i--) {
                BooleanExpr conjunct = conjuncts.get(i);
                TransferParam<BDDRoute> param = record.setDefaultPolicy(null).setChainContext(TransferParam.ChainContext.CONJUNCTION).indent();
                TransferResult<TransferReturn, BDD> r = compute(conjunct, param);
                record = record.setData(r.getReturnValue().getFirst());
                acc = ite(r.getFallthroughValue(), acc, r.getReturnValue().getSecond());
            }
            TransferReturn ret = new TransferReturn(record.getData(), acc);
            return result.setReturnValue(ret);
        }
    }
    if (expr instanceof DisjunctionChain) {
        p.debug("DisjunctionChain");
        DisjunctionChain d = (DisjunctionChain) expr;
        List<BooleanExpr> disjuncts = new ArrayList<>(d.getSubroutines());
        if (p.getDefaultPolicy() != null) {
            BooleanExpr be = new CallExpr(p.getDefaultPolicy().getDefaultPolicy());
            disjuncts.add(be);
        }
        if (disjuncts.size() == 0) {
            TransferReturn ret = new TransferReturn(p.getData(), factory.zero());
            return fromExpr(ret);
        } else {
            TransferResult<TransferReturn, BDD> result = new TransferResult<>();
            TransferParam<BDDRoute> record = p;
            BDD acc = factory.zero();
            for (int i = disjuncts.size() - 1; i >= 0; i--) {
                BooleanExpr disjunct = disjuncts.get(i);
                TransferParam<BDDRoute> param = record.setDefaultPolicy(null).setChainContext(TransferParam.ChainContext.CONJUNCTION).indent();
                TransferResult<TransferReturn, BDD> r = compute(disjunct, param);
                record = record.setData(r.getReturnValue().getFirst());
                acc = ite(r.getFallthroughValue(), acc, r.getReturnValue().getSecond());
            }
            TransferReturn ret = new TransferReturn(record.getData(), acc);
            return result.setReturnValue(ret);
        }
    }
    if (expr instanceof Not) {
        p.debug("mkNot");
        Not n = (Not) expr;
        TransferResult<TransferReturn, BDD> result = compute(n.getExpr(), p);
        TransferReturn r = result.getReturnValue();
        TransferReturn ret = new TransferReturn(r.getFirst(), r.getSecond().not());
        return result.setReturnValue(ret);
    }
    if (expr instanceof MatchProtocol) {
        MatchProtocol mp = (MatchProtocol) expr;
        Protocol proto = Protocol.fromRoutingProtocol(mp.getProtocol());
        if (proto == null) {
            p.debug("MatchProtocol(" + mp.getProtocol().protocolName() + "): false");
            TransferReturn ret = new TransferReturn(p.getData(), factory.zero());
            return fromExpr(ret);
        }
        BDD protoMatch = p.getData().getProtocolHistory().value(proto);
        p.debug("MatchProtocol(" + mp.getProtocol().protocolName() + "): " + protoMatch);
        TransferReturn ret = new TransferReturn(p.getData(), protoMatch);
        return fromExpr(ret);
    }
    if (expr instanceof MatchPrefixSet) {
        p.debug("MatchPrefixSet");
        MatchPrefixSet m = (MatchPrefixSet) expr;
        BDD r = matchPrefixSet(p.indent(), _conf, m.getPrefixSet(), p.getData());
        TransferReturn ret = new TransferReturn(p.getData(), r);
        return fromExpr(ret);
    // TODO: implement me
    } else if (expr instanceof MatchPrefix6Set) {
        p.debug("MatchPrefix6Set");
        TransferReturn ret = new TransferReturn(p.getData(), factory.zero());
        return fromExpr(ret);
    } else if (expr instanceof CallExpr) {
        p.debug("CallExpr");
        CallExpr c = (CallExpr) expr;
        String router = _conf.getName();
        String name = c.getCalledPolicyName();
        TransferResult<TransferReturn, BDD> r = CACHE.get(router, name);
        if (r != null) {
            return r;
        }
        RoutingPolicy pol = _conf.getRoutingPolicies().get(name);
        p = p.setCallContext(TransferParam.CallContext.EXPR_CALL);
        r = compute(pol.getStatements(), p.indent().enterScope(name));
        CACHE.put(router, name, r);
        return r;
    } else if (expr instanceof WithEnvironmentExpr) {
        p.debug("WithEnvironmentExpr");
        // TODO: this is not correct
        WithEnvironmentExpr we = (WithEnvironmentExpr) expr;
        // TODO: postStatements() and preStatements()
        return compute(we.getExpr(), p.deepCopy());
    } else if (expr instanceof MatchCommunitySet) {
        p.debug("MatchCommunitySet");
        MatchCommunitySet mcs = (MatchCommunitySet) expr;
        BDD c = matchCommunitySet(p.indent(), _conf, mcs.getExpr(), p.getData());
        TransferReturn ret = new TransferReturn(p.getData(), c);
        return fromExpr(ret);
    } else if (expr instanceof BooleanExprs.StaticBooleanExpr) {
        BooleanExprs.StaticBooleanExpr b = (BooleanExprs.StaticBooleanExpr) expr;
        TransferReturn ret;
        switch(b.getType()) {
            case CallExprContext:
                p.debug("CallExprContext");
                BDD x1 = mkBDD(p.getCallContext() == TransferParam.CallContext.EXPR_CALL);
                ret = new TransferReturn(p.getData(), x1);
                return fromExpr(ret);
            case CallStatementContext:
                p.debug("CallStmtContext");
                BDD x2 = mkBDD(p.getCallContext() == TransferParam.CallContext.STMT_CALL);
                ret = new TransferReturn(p.getData(), x2);
                return fromExpr(ret);
            case True:
                p.debug("True");
                ret = new TransferReturn(p.getData(), factory.one());
                return fromExpr(ret);
            case False:
                p.debug("False");
                ret = new TransferReturn(p.getData(), factory.zero());
                return fromExpr(ret);
            default:
                throw new BatfishException("Unhandled " + BooleanExprs.class.getCanonicalName() + ": " + b.getType());
        }
    } else if (expr instanceof MatchAsPath) {
        p.debug("MatchAsPath");
        // System.out.println("Warning: use of unimplemented feature MatchAsPath");
        TransferReturn ret = new TransferReturn(p.getData(), factory.one());
        return fromExpr(ret);
    }
    throw new BatfishException("TODO: compute expr transfer function: " + expr);
}
Also used : MatchPrefix6Set(org.batfish.datamodel.routing_policy.expr.MatchPrefix6Set) BDD(net.sf.javabdd.BDD) ArrayList(java.util.ArrayList) MatchCommunitySet(org.batfish.datamodel.routing_policy.expr.MatchCommunitySet) TransferResult(org.batfish.symbolic.TransferResult) WithEnvironmentExpr(org.batfish.datamodel.routing_policy.expr.WithEnvironmentExpr) BooleanExprs(org.batfish.datamodel.routing_policy.expr.BooleanExprs) Conjunction(org.batfish.datamodel.routing_policy.expr.Conjunction) CallExpr(org.batfish.datamodel.routing_policy.expr.CallExpr) DisjunctionChain(org.batfish.datamodel.routing_policy.expr.DisjunctionChain) MatchProtocol(org.batfish.datamodel.routing_policy.expr.MatchProtocol) Protocol(org.batfish.symbolic.Protocol) MatchAsPath(org.batfish.datamodel.routing_policy.expr.MatchAsPath) BooleanExpr(org.batfish.datamodel.routing_policy.expr.BooleanExpr) BatfishException(org.batfish.common.BatfishException) MatchPrefixSet(org.batfish.datamodel.routing_policy.expr.MatchPrefixSet) MatchIpv6(org.batfish.datamodel.routing_policy.expr.MatchIpv6) RoutingPolicy(org.batfish.datamodel.routing_policy.RoutingPolicy) ConjunctionChain(org.batfish.datamodel.routing_policy.expr.ConjunctionChain) MatchIpv4(org.batfish.datamodel.routing_policy.expr.MatchIpv4) MatchProtocol(org.batfish.datamodel.routing_policy.expr.MatchProtocol) Disjunction(org.batfish.datamodel.routing_policy.expr.Disjunction) Not(org.batfish.datamodel.routing_policy.expr.Not)

Example 3 with BDD

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

the class TransferBDD method isRelevantFor.

/*
   * Check if a prefix range match is applicable for the packet destination
   * Ip address, given the prefix length variable.
   *
   * Since aggregation is modelled separately, we assume that prefixLen
   * is not modified, and thus will contain only the underlying variables:
   * [var(0), ..., var(n)]
   */
private BDD isRelevantFor(BDDRoute record, PrefixRange range) {
    Prefix p = range.getPrefix();
    SubRange r = range.getLengthRange();
    int len = p.getPrefixLength();
    int lower = r.getStart();
    int upper = r.getEnd();
    BDD lowerBitsMatch = firstBitsEqual(record.getPrefix().getBitvec(), p, len);
    BDD acc = factory.zero();
    if (lower == 0 && upper == 32) {
        acc = factory.one();
    } else {
        for (int i = lower; i <= upper; i++) {
            BDD equalLen = record.getPrefixLength().value(i);
            acc = acc.or(equalLen);
        }
    }
    return acc.and(lowerBitsMatch);
}
Also used : BDD(net.sf.javabdd.BDD) Prefix(org.batfish.datamodel.Prefix) SubRange(org.batfish.datamodel.SubRange)

Example 4 with BDD

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

the class TransferBDD method matchPrefixSet.

/*
   * Converts a prefix set to a boolean expression.
   */
private BDD matchPrefixSet(TransferParam<BDDRoute> p, Configuration conf, PrefixSetExpr e, BDDRoute other) {
    if (e instanceof ExplicitPrefixSet) {
        ExplicitPrefixSet x = (ExplicitPrefixSet) e;
        Set<PrefixRange> ranges = x.getPrefixSpace().getPrefixRanges();
        if (ranges.isEmpty()) {
            p.debug("empty");
            return factory.one();
        }
        BDD acc = factory.zero();
        for (PrefixRange range : ranges) {
            p.debug("Prefix Range: " + range);
            if (!PrefixUtils.isContainedBy(range.getPrefix(), _ignoredNetworks)) {
                acc = acc.or(isRelevantFor(other, range));
            }
        }
        return acc;
    } else if (e instanceof NamedPrefixSet) {
        NamedPrefixSet x = (NamedPrefixSet) e;
        p.debug("Named: " + x.getName());
        String name = x.getName();
        RouteFilterList fl = conf.getRouteFilterLists().get(name);
        return matchFilterList(p, fl, other);
    } else {
        throw new BatfishException("TODO: match prefix set: " + e);
    }
}
Also used : BatfishException(org.batfish.common.BatfishException) PrefixRange(org.batfish.datamodel.PrefixRange) BDD(net.sf.javabdd.BDD) ExplicitPrefixSet(org.batfish.datamodel.routing_policy.expr.ExplicitPrefixSet) NamedPrefixSet(org.batfish.datamodel.routing_policy.expr.NamedPrefixSet) RouteFilterList(org.batfish.datamodel.RouteFilterList)

Example 5 with BDD

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

the class TransferBDD method matchFilterList.

/*
   * Converts a route filter list to a boolean expression.
   */
private BDD matchFilterList(TransferParam<BDDRoute> p, RouteFilterList x, BDDRoute other) {
    BDD acc = factory.zero();
    List<RouteFilterLine> lines = new ArrayList<>(x.getLines());
    Collections.reverse(lines);
    for (RouteFilterLine line : lines) {
        Prefix pfx = line.getPrefix();
        if (!PrefixUtils.isContainedBy(pfx, _ignoredNetworks)) {
            SubRange r = line.getLengthRange();
            PrefixRange range = new PrefixRange(pfx, r);
            p.debug("Prefix Range: " + range);
            p.debug("Action: " + line.getAction());
            BDD matches = isRelevantFor(other, range);
            BDD action = mkBDD(line.getAction() == LineAction.ACCEPT);
            acc = ite(matches, action, acc);
        }
    }
    return acc;
}
Also used : PrefixRange(org.batfish.datamodel.PrefixRange) BDD(net.sf.javabdd.BDD) ArrayList(java.util.ArrayList) Prefix(org.batfish.datamodel.Prefix) SubRange(org.batfish.datamodel.SubRange) RouteFilterLine(org.batfish.datamodel.RouteFilterLine)

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