Search in sources :

Example 36 with RoutingPolicy

use of org.batfish.datamodel.routing_policy.RoutingPolicy in project batfish by batfish.

the class Optimizations method isDefaultBgpExport.

/*
   * Determine if a BGP neighbor uses the default export policy
   */
private boolean isDefaultBgpExport(Configuration conf, BgpNeighbor n) {
    // Check if valid neighbor
    if (n == null || n.getExportPolicy() == null) {
        return true;
    }
    // Ensure a single if statement
    RoutingPolicy pol = conf.getRoutingPolicies().get(n.getExportPolicy());
    List<Statement> stmts = pol.getStatements();
    if (stmts.size() != 1) {
        return false;
    }
    Statement s = stmts.get(0);
    if (!(s instanceof If)) {
        return false;
    }
    // Ensure that the true branch accepts and the false branch rejects
    If i = (If) s;
    BooleanExpr be = i.getGuard();
    List<Statement> trueStmts = i.getTrueStatements();
    List<Statement> falseStmts = i.getFalseStatements();
    if (trueStmts.size() != 1 || falseStmts.size() != 1) {
        return false;
    }
    Statement s1 = trueStmts.get(0);
    Statement s2 = falseStmts.get(0);
    if (!(s1 instanceof Statements.StaticStatement) || !(s2 instanceof Statements.StaticStatement)) {
        return false;
    }
    Statements.StaticStatement x = (Statements.StaticStatement) s1;
    Statements.StaticStatement y = (Statements.StaticStatement) s2;
    if (x.getType() != Statements.ExitAccept || y.getType() != Statements.ExitReject) {
        return false;
    }
    // Ensure condition just hands off to the common export policy
    if (!(be instanceof CallExpr)) {
        return false;
    }
    CallExpr ce = (CallExpr) be;
    return ce.getCalledPolicyName().contains(Graph.BGP_COMMON_FILTER_LIST_NAME);
}
Also used : Statement(org.batfish.datamodel.routing_policy.statement.Statement) RoutingPolicy(org.batfish.datamodel.routing_policy.RoutingPolicy) CallExpr(org.batfish.datamodel.routing_policy.expr.CallExpr) Statements(org.batfish.datamodel.routing_policy.statement.Statements) If(org.batfish.datamodel.routing_policy.statement.If) BooleanExpr(org.batfish.datamodel.routing_policy.expr.BooleanExpr)

Example 37 with RoutingPolicy

use of org.batfish.datamodel.routing_policy.RoutingPolicy in project batfish by batfish.

the class Optimizations method computeCanMergeImportExportVars.

/*
   * Determine when import and export variables can be merged along an edge.
   * This will be safe when there is no peer-specific import filter
   */
private void computeCanMergeImportExportVars() {
    _encoderSlice.getGraph().getConfigurations().forEach((router, conf) -> {
        Map<Protocol, List<GraphEdge>> map = new HashMap<>();
        _sliceCanCombineImportExportVars.put(router, map);
        for (Protocol proto : getProtocols().get(router)) {
            List<GraphEdge> edges = new ArrayList<>();
            if (Optimizations.ENABLE_IMPORT_EXPORT_MERGE_OPTIMIZATION && !proto.isConnected() && !proto.isStatic() && !proto.isOspf()) {
                for (GraphEdge ge : _encoderSlice.getGraph().getEdgeMap().get(router)) {
                    // Don't merge when an abstract edge is used.
                    boolean safeMergeEdge = _encoderSlice.getGraph().isEdgeUsed(conf, proto, ge) && !ge.isAbstract();
                    // Don't merge when bgp internal/external can differ
                    boolean sameInternal = (ge.getPeer() == null) || (_needBgpInternal.contains(router) == _needBgpInternal.contains(ge.getPeer()));
                    // Check if there are any local modifications on import
                    boolean isPure = true;
                    RoutingPolicy pol = _encoderSlice.getGraph().findImportRoutingPolicy(router, proto, ge);
                    if (pol != null) {
                        isPure = false;
                    }
                    boolean noFailures = _encoderSlice.getEncoder().getFailures() == 0;
                    if (safeMergeEdge && sameInternal && isPure && noFailures && hasExportVariables(ge, proto)) {
                        edges.add(ge);
                    }
                }
            }
            map.put(proto, edges);
        }
    });
}
Also used : HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) ArrayList(java.util.ArrayList) List(java.util.List) RoutingPolicy(org.batfish.datamodel.routing_policy.RoutingPolicy) Protocol(org.batfish.symbolic.Protocol) GraphEdge(org.batfish.symbolic.GraphEdge)

Example 38 with RoutingPolicy

use of org.batfish.datamodel.routing_policy.RoutingPolicy 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 39 with RoutingPolicy

use of org.batfish.datamodel.routing_policy.RoutingPolicy in project batfish by batfish.

the class VyosConfiguration method convertRouteMaps.

private void convertRouteMaps() {
    for (Entry<String, RouteMap> e : _routeMaps.entrySet()) {
        String name = e.getKey();
        RouteMap routeMap = e.getValue();
        RoutingPolicy rp = toRoutingPolicy(routeMap);
        _c.getRoutingPolicies().put(name, rp);
    }
}
Also used : RoutingPolicy(org.batfish.datamodel.routing_policy.RoutingPolicy)

Example 40 with RoutingPolicy

use of org.batfish.datamodel.routing_policy.RoutingPolicy in project batfish by batfish.

the class VyosConfiguration method toRoutingPolicy.

private RoutingPolicy toRoutingPolicy(RouteMap routeMap) {
    String name = routeMap.getName();
    RoutingPolicy routingPolicy = new RoutingPolicy(name, _c);
    List<Statement> statements = routingPolicy.getStatements();
    for (Entry<Integer, RouteMapRule> e : routeMap.getRules().entrySet()) {
        String ruleName = Integer.toString(e.getKey());
        RouteMapRule rule = e.getValue();
        If ifStatement = new If();
        List<Statement> trueStatements = ifStatement.getTrueStatements();
        ifStatement.setComment(ruleName);
        Conjunction conj = new Conjunction();
        for (RouteMapMatch match : rule.getMatches()) {
            conj.getConjuncts().add(match.toBooleanExpr(this, _c, _w));
        }
        ifStatement.setGuard(conj.simplify());
        switch(rule.getAction()) {
            case ACCEPT:
                trueStatements.add(Statements.ExitAccept.toStaticStatement());
                break;
            case REJECT:
                trueStatements.add(Statements.ExitReject.toStaticStatement());
                break;
            default:
                throw new BatfishException("Invalid action");
        }
        statements.add(ifStatement);
    }
    statements.add(Statements.ExitReject.toStaticStatement());
    return routingPolicy;
}
Also used : BatfishException(org.batfish.common.BatfishException) Statement(org.batfish.datamodel.routing_policy.statement.Statement) Conjunction(org.batfish.datamodel.routing_policy.expr.Conjunction) RoutingPolicy(org.batfish.datamodel.routing_policy.RoutingPolicy) If(org.batfish.datamodel.routing_policy.statement.If)

Aggregations

RoutingPolicy (org.batfish.datamodel.routing_policy.RoutingPolicy)50 If (org.batfish.datamodel.routing_policy.statement.If)17 Prefix (org.batfish.datamodel.Prefix)16 BatfishException (org.batfish.common.BatfishException)12 Ip (org.batfish.datamodel.Ip)12 Conjunction (org.batfish.datamodel.routing_policy.expr.Conjunction)12 Statement (org.batfish.datamodel.routing_policy.statement.Statement)12 Configuration (org.batfish.datamodel.Configuration)11 BooleanExpr (org.batfish.datamodel.routing_policy.expr.BooleanExpr)11 MatchProtocol (org.batfish.datamodel.routing_policy.expr.MatchProtocol)11 InterfaceAddress (org.batfish.datamodel.InterfaceAddress)10 CallExpr (org.batfish.datamodel.routing_policy.expr.CallExpr)10 Disjunction (org.batfish.datamodel.routing_policy.expr.Disjunction)10 ArrayList (java.util.ArrayList)9 MatchPrefixSet (org.batfish.datamodel.routing_policy.expr.MatchPrefixSet)9 HashSet (java.util.HashSet)7 RouteFilterList (org.batfish.datamodel.RouteFilterList)7 SubRange (org.batfish.datamodel.SubRange)7 Not (org.batfish.datamodel.routing_policy.expr.Not)7 HashMap (java.util.HashMap)6