Search in sources :

Example 21 with BooleanExpr

use of org.batfish.datamodel.routing_policy.expr.BooleanExpr in project batfish by batfish.

the class TransferSSA method compute.

/*
   * Convert a Batfish AST boolean expression to a symbolic Z3 boolean expression
   * by performing inlining of stateful side effects.
   */
private TransferResult<BoolExpr, BoolExpr> compute(BooleanExpr expr, TransferParam<SymbolicRoute> p) {
    // TODO: right now everything is IPV4
    if (expr instanceof MatchIpv4) {
        p.debug("MatchIpv4");
        return fromExpr(_enc.mkTrue());
    }
    if (expr instanceof MatchIpv6) {
        p.debug("MatchIpv6");
        return fromExpr(_enc.mkFalse());
    }
    if (expr instanceof Conjunction) {
        p.debug("Conjunction");
        Conjunction c = (Conjunction) expr;
        BoolExpr acc = _enc.mkTrue();
        TransferResult<BoolExpr, BoolExpr> result = new TransferResult<>();
        for (BooleanExpr be : c.getConjuncts()) {
            TransferResult<BoolExpr, BoolExpr> r = compute(be, p.indent());
            result = result.addChangedVariables(r);
            acc = _enc.mkAnd(acc, r.getReturnValue());
        }
        p.debug("has changed variable");
        return result.setReturnValue(acc);
    }
    if (expr instanceof Disjunction) {
        p.debug("Disjunction");
        Disjunction d = (Disjunction) expr;
        BoolExpr acc = _enc.mkFalse();
        TransferResult<BoolExpr, BoolExpr> result = new TransferResult<>();
        for (BooleanExpr be : d.getDisjuncts()) {
            TransferResult<BoolExpr, BoolExpr> r = compute(be, p.indent());
            result = result.addChangedVariables(r);
            acc = _enc.mkOr(acc, r.getReturnValue());
        }
        p.debug("has changed variable");
        return result.setReturnValue(acc);
    }
    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) {
            return fromExpr(_enc.mkTrue());
        } else {
            TransferResult<BoolExpr, BoolExpr> result = new TransferResult<>();
            BoolExpr acc = _enc.mkFalse();
            for (int i = conjuncts.size() - 1; i >= 0; i--) {
                BooleanExpr conjunct = conjuncts.get(i);
                TransferParam<SymbolicRoute> param = p.setDefaultPolicy(null).setChainContext(TransferParam.ChainContext.CONJUNCTION);
                TransferResult<BoolExpr, BoolExpr> r = compute(conjunct, param);
                result = result.addChangedVariables(r);
                acc = _enc.mkIf(r.getFallthroughValue(), acc, r.getReturnValue());
            }
            p.debug("ConjunctionChain Result: " + acc);
            return result.setReturnValue(acc);
        }
    }
    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) {
            return fromExpr(_enc.mkTrue());
        } else {
            TransferResult<BoolExpr, BoolExpr> result = new TransferResult<>();
            BoolExpr acc = _enc.mkFalse();
            for (int i = disjuncts.size() - 1; i >= 0; i--) {
                BooleanExpr disjunct = disjuncts.get(i);
                TransferParam<SymbolicRoute> param = p.setDefaultPolicy(null).setChainContext(TransferParam.ChainContext.CONJUNCTION);
                TransferResult<BoolExpr, BoolExpr> r = compute(disjunct, param);
                result.addChangedVariables(r);
                acc = _enc.mkIf(r.getFallthroughValue(), acc, r.getReturnValue());
            }
            p.debug("DisjunctionChain Result: " + acc);
            return result.setReturnValue(acc);
        }
    }
    if (expr instanceof Not) {
        p.debug("mkNot");
        Not n = (Not) expr;
        TransferResult<BoolExpr, BoolExpr> result = compute(n.getExpr(), p);
        return result.setReturnValue(_enc.mkNot(result.getReturnValue()));
    }
    if (expr instanceof MatchProtocol) {
        MatchProtocol mp = (MatchProtocol) expr;
        Protocol proto = Protocol.fromRoutingProtocol(mp.getProtocol());
        if (proto == null) {
            p.debug("MatchProtocol(" + mp.getProtocol().protocolName() + "): false");
            return fromExpr(_enc.mkFalse());
        }
        if (_other.getProtocolHistory() == null) {
            BoolExpr protoMatch = _enc.mkBool(proto.equals(_proto));
            p.debug("MatchProtocol(" + mp.getProtocol().protocolName() + "): " + protoMatch);
            return fromExpr(protoMatch);
        }
        BoolExpr protoMatch = _other.getProtocolHistory().checkIfValue(proto);
        p.debug("MatchProtocol(" + mp.getProtocol().protocolName() + "): " + protoMatch);
        return fromExpr(protoMatch);
    }
    if (expr instanceof MatchPrefixSet) {
        p.debug("MatchPrefixSet");
        MatchPrefixSet m = (MatchPrefixSet) expr;
        // For BGP, may change prefix length
        TransferResult<BoolExpr, BoolExpr> result = matchPrefixSet(_conf, m.getPrefixSet(), p.getData());
        return result.setReturnAssignedValue(_enc.mkTrue());
    // TODO: implement me
    } else if (expr instanceof MatchPrefix6Set) {
        p.debug("MatchPrefix6Set");
        return fromExpr(_enc.mkFalse());
    } else if (expr instanceof CallExpr) {
        p.debug("CallExpr");
        // TODO: the call can modify certain fields, need to keep track of these variables
        CallExpr c = (CallExpr) expr;
        String name = c.getCalledPolicyName();
        RoutingPolicy pol = _conf.getRoutingPolicies().get(name);
        p = p.setCallContext(TransferParam.CallContext.EXPR_CALL);
        TransferResult<BoolExpr, BoolExpr> r = compute(pol.getStatements(), p.indent().enterScope(name), initialResult());
        p.debug("CallExpr (return): " + r.getReturnValue());
        p.debug("CallExpr (fallthrough): " + r.getFallthroughValue());
        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);
    } else if (expr instanceof MatchCommunitySet) {
        p.debug("MatchCommunitySet");
        MatchCommunitySet mcs = (MatchCommunitySet) expr;
        return fromExpr(matchCommunitySet(_conf, mcs.getExpr(), p.getData()));
    } else if (expr instanceof BooleanExprs.StaticBooleanExpr) {
        BooleanExprs.StaticBooleanExpr b = (BooleanExprs.StaticBooleanExpr) expr;
        switch(b.getType()) {
            case CallExprContext:
                p.debug("CallExprContext");
                return fromExpr(_enc.mkBool(p.getCallContext() == TransferParam.CallContext.EXPR_CALL));
            case CallStatementContext:
                p.debug("CallStmtContext");
                return fromExpr(_enc.mkBool(p.getCallContext() == TransferParam.CallContext.STMT_CALL));
            case True:
                p.debug("True");
                return fromExpr(_enc.mkTrue());
            case False:
                p.debug("False");
                return fromExpr(_enc.mkFalse());
            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");
        return fromExpr(_enc.mkFalse());
    }
    String s = (_isExport ? "export" : "import");
    String msg = String.format("Unimplemented feature %s for %s transfer function on interface %s", expr.toString(), s, _graphEdge.toString());
    throw new BatfishException(msg);
}
Also used : MatchPrefix6Set(org.batfish.datamodel.routing_policy.expr.MatchPrefix6Set) BoolExpr(com.microsoft.z3.BoolExpr) 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 22 with BooleanExpr

use of org.batfish.datamodel.routing_policy.expr.BooleanExpr in project batfish by batfish.

the class AstVisitor method visit.

/*
   * Walk starting from an AST boolean expression
   */
public void visit(Configuration conf, BooleanExpr e, Consumer<Statement> fs, Consumer<BooleanExpr> fe) {
    fe.accept(e);
    if (e instanceof Conjunction) {
        Conjunction c = (Conjunction) e;
        for (BooleanExpr be : c.getConjuncts()) {
            visit(conf, be, fs, fe);
        }
    } else if (e instanceof Disjunction) {
        Disjunction d = (Disjunction) e;
        for (BooleanExpr be : d.getDisjuncts()) {
            visit(conf, be, fs, fe);
        }
    } else if (e instanceof ConjunctionChain) {
        ConjunctionChain c = (ConjunctionChain) e;
        for (BooleanExpr be : c.getSubroutines()) {
            visit(conf, be, fs, fe);
        }
    } else if (e instanceof DisjunctionChain) {
        DisjunctionChain d = (DisjunctionChain) e;
        for (BooleanExpr be : d.getSubroutines()) {
            visit(conf, be, fs, fe);
        }
    } else if (e instanceof Not) {
        Not n = (Not) e;
        visit(conf, n.getExpr(), fs, fe);
    } else if (e instanceof CallExpr) {
        CallExpr c = (CallExpr) e;
        RoutingPolicy rp = conf.getRoutingPolicies().get(c.getCalledPolicyName());
        visit(conf, rp.getStatements(), fs, fe);
    }
}
Also used : Disjunction(org.batfish.datamodel.routing_policy.expr.Disjunction) Not(org.batfish.datamodel.routing_policy.expr.Not) Conjunction(org.batfish.datamodel.routing_policy.expr.Conjunction) CallExpr(org.batfish.datamodel.routing_policy.expr.CallExpr) RoutingPolicy(org.batfish.datamodel.routing_policy.RoutingPolicy) ConjunctionChain(org.batfish.datamodel.routing_policy.expr.ConjunctionChain) DisjunctionChain(org.batfish.datamodel.routing_policy.expr.DisjunctionChain) BooleanExpr(org.batfish.datamodel.routing_policy.expr.BooleanExpr)

Example 23 with BooleanExpr

use of org.batfish.datamodel.routing_policy.expr.BooleanExpr in project batfish by batfish.

the class JuniperConfiguration method toRoutingPolicy.

private RoutingPolicy toRoutingPolicy(PolicyStatement ps) {
    String name = ps.getName();
    RoutingPolicy routingPolicy = new RoutingPolicy(name, _c);
    List<Statement> statements = routingPolicy.getStatements();
    boolean hasDefaultTerm = ps.getDefaultTerm().getFroms().size() > 0 || ps.getDefaultTerm().getThens().size() > 0;
    List<PsTerm> terms = new ArrayList<>();
    terms.addAll(ps.getTerms().values());
    if (hasDefaultTerm) {
        terms.add(ps.getDefaultTerm());
    }
    for (PsTerm term : terms) {
        List<Statement> thens = toStatements(term.getThens());
        if (!term.getFroms().isEmpty()) {
            If ifStatement = new If();
            ifStatement.setComment(term.getName());
            Conjunction conj = new Conjunction();
            List<BooleanExpr> subroutines = new ArrayList<>();
            for (PsFrom from : term.getFroms()) {
                if (from instanceof PsFromRouteFilter) {
                    int actionLineCounter = 0;
                    PsFromRouteFilter fromRouteFilter = (PsFromRouteFilter) from;
                    String routeFilterName = fromRouteFilter.getRouteFilterName();
                    RouteFilter rf = _routeFilters.get(routeFilterName);
                    for (RouteFilterLine line : rf.getLines()) {
                        if (line.getThens().size() > 0) {
                            String lineListName = name + "_ACTION_LINE_" + actionLineCounter;
                            RouteFilterList lineSpecificList = new RouteFilterList(lineListName);
                            line.applyTo(lineSpecificList);
                            actionLineCounter++;
                            _c.getRouteFilterLists().put(lineListName, lineSpecificList);
                            If lineSpecificIfStatement = new If();
                            String lineSpecificClauseName = routeFilterName + "_ACTION_LINE_" + actionLineCounter;
                            lineSpecificIfStatement.setComment(lineSpecificClauseName);
                            MatchPrefixSet mrf = new MatchPrefixSet(new DestinationNetwork(), new NamedPrefixSet(lineListName));
                            lineSpecificIfStatement.setGuard(mrf);
                            lineSpecificIfStatement.getTrueStatements().addAll(toStatements(line.getThens()));
                            statements.add(lineSpecificIfStatement);
                        }
                    }
                }
                BooleanExpr booleanExpr = from.toBooleanExpr(this, _c, _w);
                if (from instanceof PsFromPolicyStatement || from instanceof PsFromPolicyStatementConjunction) {
                    subroutines.add(booleanExpr);
                } else {
                    conj.getConjuncts().add(booleanExpr);
                }
            }
            if (!subroutines.isEmpty()) {
                ConjunctionChain chain = new ConjunctionChain(subroutines);
                conj.getConjuncts().add(chain);
            }
            BooleanExpr guard = conj.simplify();
            ifStatement.setGuard(guard);
            ifStatement.getTrueStatements().addAll(thens);
            statements.add(ifStatement);
        } else {
            statements.addAll(thens);
        }
    }
    If endOfPolicy = new If();
    endOfPolicy.setGuard(BooleanExprs.CallExprContext.toStaticBooleanExpr());
    endOfPolicy.setFalseStatements(Collections.singletonList(Statements.Return.toStaticStatement()));
    statements.add(endOfPolicy);
    return routingPolicy;
}
Also used : NamedPrefixSet(org.batfish.datamodel.routing_policy.expr.NamedPrefixSet) Statement(org.batfish.datamodel.routing_policy.statement.Statement) MatchPrefixSet(org.batfish.datamodel.routing_policy.expr.MatchPrefixSet) ArrayList(java.util.ArrayList) RoutingPolicy(org.batfish.datamodel.routing_policy.RoutingPolicy) ConjunctionChain(org.batfish.datamodel.routing_policy.expr.ConjunctionChain) DestinationNetwork(org.batfish.datamodel.routing_policy.expr.DestinationNetwork) RouteFilterList(org.batfish.datamodel.RouteFilterList) Conjunction(org.batfish.datamodel.routing_policy.expr.Conjunction) If(org.batfish.datamodel.routing_policy.statement.If) BooleanExpr(org.batfish.datamodel.routing_policy.expr.BooleanExpr)

Example 24 with BooleanExpr

use of org.batfish.datamodel.routing_policy.expr.BooleanExpr in project batfish by batfish.

the class If method simplify.

@Override
public List<Statement> simplify() {
    if (_simplified != null) {
        return _simplified;
    }
    ImmutableList.Builder<Statement> simpleTrueStatementsBuilder = ImmutableList.builder();
    ImmutableList.Builder<Statement> simpleFalseStatementsBuilder = ImmutableList.builder();
    BooleanExpr simpleGuard = _guard.simplify();
    for (Statement trueStatement : _trueStatements) {
        simpleTrueStatementsBuilder.addAll(trueStatement.simplify());
    }
    List<Statement> simpleTrueStatements = simpleTrueStatementsBuilder.build();
    for (Statement falseStatement : _falseStatements) {
        simpleFalseStatementsBuilder.addAll(falseStatement.simplify());
    }
    List<Statement> simpleFalseStatements = simpleFalseStatementsBuilder.build();
    if (simpleGuard.equals(BooleanExprs.True.toStaticBooleanExpr())) {
        _simplified = simpleTrueStatements;
    } else if (simpleGuard.equals(BooleanExprs.False.toStaticBooleanExpr())) {
        _simplified = simpleFalseStatements;
    } else if (simpleTrueStatements.size() == 0 && simpleFalseStatements.size() == 0) {
        _simplified = Collections.emptyList();
    } else {
        If simple = new If();
        simple.setGuard(simpleGuard);
        simple.setTrueStatements(simpleTrueStatements);
        simple.setFalseStatements(simpleFalseStatements);
        simple.setComment(getComment());
        _simplified = ImmutableList.of(simple);
        simple._simplified = _simplified;
    }
    return _simplified;
}
Also used : ImmutableList(com.google.common.collect.ImmutableList) BooleanExpr(org.batfish.datamodel.routing_policy.expr.BooleanExpr)

Aggregations

BooleanExpr (org.batfish.datamodel.routing_policy.expr.BooleanExpr)24 Disjunction (org.batfish.datamodel.routing_policy.expr.Disjunction)18 RoutingPolicy (org.batfish.datamodel.routing_policy.RoutingPolicy)11 Conjunction (org.batfish.datamodel.routing_policy.expr.Conjunction)10 MatchPrefixSet (org.batfish.datamodel.routing_policy.expr.MatchPrefixSet)8 MatchProtocol (org.batfish.datamodel.routing_policy.expr.MatchProtocol)8 If (org.batfish.datamodel.routing_policy.statement.If)7 ArrayList (java.util.ArrayList)6 CallExpr (org.batfish.datamodel.routing_policy.expr.CallExpr)6 MatchPrefix6Set (org.batfish.datamodel.routing_policy.expr.MatchPrefix6Set)6 Not (org.batfish.datamodel.routing_policy.expr.Not)6 BatfishException (org.batfish.common.BatfishException)5 DestinationNetwork (org.batfish.datamodel.routing_policy.expr.DestinationNetwork)5 NamedPrefixSet (org.batfish.datamodel.routing_policy.expr.NamedPrefixSet)5 Statement (org.batfish.datamodel.routing_policy.statement.Statement)5 RouteFilterList (org.batfish.datamodel.RouteFilterList)4 DisjunctionChain (org.batfish.datamodel.routing_policy.expr.DisjunctionChain)4 MatchAsPath (org.batfish.datamodel.routing_policy.expr.MatchAsPath)4 BigInteger (java.math.BigInteger)3 HashMap (java.util.HashMap)3