Search in sources :

Example 21 with Protocol

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

the class EncoderSlice method addEnvironmentVariables.

/*
   * Initialize all environment symbolic records for BGP.
   */
private void addEnvironmentVariables() {
    // If not the main slice, just use the main slice
    if (!isMainSlice()) {
        Map<LogicalEdge, SymbolicRoute> envs = _logicalGraph.getEnvironmentVars();
        EncoderSlice main = _encoder.getMainSlice();
        LogicalGraph lg = main.getLogicalGraph();
        Map<LogicalEdge, SymbolicRoute> existing = lg.getEnvironmentVars();
        envs.putAll(existing);
        return;
    }
    // Otherwise create it anew
    for (String router : getGraph().getRouters()) {
        for (Protocol proto : getProtocols().get(router)) {
            if (proto.isBgp()) {
                List<ArrayList<LogicalEdge>> les = _logicalGraph.getLogicalEdges().get(router, proto);
                assert (les != null);
                for (ArrayList<LogicalEdge> eList : les) {
                    for (LogicalEdge e : eList) {
                        if (e.getEdgeType() == EdgeType.IMPORT) {
                            GraphEdge ge = e.getEdge();
                            BgpNeighbor n = getGraph().getEbgpNeighbors().get(ge);
                            if (n != null && ge.getEnd() == null) {
                                if (!isMainSlice()) {
                                    LogicalGraph lg = _encoder.getMainSlice().getLogicalGraph();
                                    SymbolicRoute r = lg.getEnvironmentVars().get(e);
                                    _logicalGraph.getEnvironmentVars().put(e, r);
                                } else {
                                    String address;
                                    if (n.getAddress() == null) {
                                        address = "null";
                                    } else {
                                        address = n.getAddress().toString();
                                    }
                                    String ifaceName = "ENV-" + address;
                                    String name = String.format("%d_%s%s_%s_%s_%s", _encoder.getId(), _sliceName, router, proto.name(), "EXPORT", ifaceName);
                                    SymbolicRoute vars = new SymbolicRoute(this, name, router, proto, _optimizations, null, ge.isAbstract());
                                    getAllSymbolicRecords().add(vars);
                                    _logicalGraph.getEnvironmentVars().put(e, vars);
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
Also used : BgpNeighbor(org.batfish.datamodel.BgpNeighbor) ArrayList(java.util.ArrayList) IpProtocol(org.batfish.datamodel.IpProtocol) RoutingProtocol(org.batfish.datamodel.RoutingProtocol) Protocol(org.batfish.symbolic.Protocol) MatchProtocol(org.batfish.datamodel.routing_policy.expr.MatchProtocol) GraphEdge(org.batfish.symbolic.GraphEdge)

Example 22 with Protocol

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

the class EncoderSlice method addSymbolicRecords.

/*
   * Initialize all control-plane message symbolic records.
   * Also maps each logical graph edge to its opposite edge.
   */
private void addSymbolicRecords() {
    Map<String, Map<Protocol, Map<GraphEdge, ArrayList<LogicalEdge>>>> importInverseMap = new HashMap<>();
    Map<String, Map<Protocol, Map<GraphEdge, ArrayList<LogicalEdge>>>> exportInverseMap = new HashMap<>();
    Map<String, Map<Protocol, SymbolicRoute>> singleExportMap = new HashMap<>();
    // add edge EXPORT and IMPORT state variables
    for (Entry<String, List<GraphEdge>> entry : getGraph().getEdgeMap().entrySet()) {
        String router = entry.getKey();
        List<GraphEdge> edges = entry.getValue();
        Map<Protocol, SymbolicRoute> singleProtoMap;
        singleProtoMap = new HashMap<>();
        Map<Protocol, Map<GraphEdge, ArrayList<LogicalEdge>>> importEnumMap;
        importEnumMap = new HashMap<>();
        Map<Protocol, Map<GraphEdge, ArrayList<LogicalEdge>>> exportEnumMap;
        exportEnumMap = new HashMap<>();
        singleExportMap.put(router, singleProtoMap);
        importInverseMap.put(router, importEnumMap);
        exportInverseMap.put(router, exportEnumMap);
        for (Protocol proto : getProtocols().get(router)) {
            // Add redistribution variables
            Set<Protocol> r = _logicalGraph.getRedistributedProtocols().get(router, proto);
            assert r != null;
            if (proto.isOspf() && r.size() > 1) {
                // Add the ospf redistributed record if needed
                String rname = String.format("%d_%s%s_%s_%s", _encoder.getId(), _sliceName, router, proto.name(), "Redistributed");
                SymbolicRoute rec = new SymbolicRoute(this, rname, router, proto, _optimizations, null, false);
                _ospfRedistributed.put(router, rec);
                getAllSymbolicRecords().add(rec);
            }
            Boolean useSingleExport = _optimizations.getSliceCanKeepSingleExportVar().get(router, proto);
            assert (useSingleExport != null);
            Map<GraphEdge, ArrayList<LogicalEdge>> importGraphEdgeMap = new HashMap<>();
            Map<GraphEdge, ArrayList<LogicalEdge>> exportGraphEdgeMap = new HashMap<>();
            importEnumMap.put(proto, importGraphEdgeMap);
            exportEnumMap.put(proto, exportGraphEdgeMap);
            for (GraphEdge e : edges) {
                Configuration conf = getGraph().getConfigurations().get(router);
                if (getGraph().isEdgeUsed(conf, proto, e)) {
                    ArrayList<LogicalEdge> importEdgeList = new ArrayList<>();
                    ArrayList<LogicalEdge> exportEdgeList = new ArrayList<>();
                    importGraphEdgeMap.put(e, importEdgeList);
                    exportGraphEdgeMap.put(e, exportEdgeList);
                    for (int len = 0; len <= BITS; len++) {
                        String ifaceName = e.getStart().getName();
                        if (!proto.isConnected() && !proto.isStatic()) {
                            // to reuse the existing variables instead of creating new ones
                            if (useSingleExport) {
                                SymbolicRoute singleVars = singleExportMap.get(router).get(proto);
                                SymbolicRoute ev1;
                                if (singleVars == null) {
                                    String name = String.format("%d_%s%s_%s_%s_%s", _encoder.getId(), _sliceName, router, proto.name(), "SINGLE-EXPORT", "");
                                    ev1 = new SymbolicRoute(this, name, router, proto, _optimizations, null, e.isAbstract());
                                    singleProtoMap.put(proto, ev1);
                                    getAllSymbolicRecords().add(ev1);
                                } else {
                                    ev1 = singleVars;
                                }
                                LogicalEdge eExport = new LogicalEdge(e, EdgeType.EXPORT, ev1);
                                exportEdgeList.add(eExport);
                            } else {
                                String name = String.format("%d_%s%s_%s_%s_%s", _encoder.getId(), _sliceName, router, proto.name(), "EXPORT", ifaceName);
                                SymbolicRoute ev1 = new SymbolicRoute(this, name, router, proto, _optimizations, null, e.isAbstract());
                                LogicalEdge eExport = new LogicalEdge(e, EdgeType.EXPORT, ev1);
                                exportEdgeList.add(eExport);
                                getAllSymbolicRecords().add(ev1);
                            }
                        }
                        boolean notNeeded = _optimizations.getSliceCanCombineImportExportVars().get(router).get(proto).contains(e);
                        Interface i = e.getStart();
                        Prefix p = i.getAddress().getPrefix();
                        boolean doModel = !(proto.isConnected() && p != null && !relevantPrefix(p));
                        // PolicyQuotient: Don't model the connected interfaces that aren't relevant
                        if (doModel) {
                            if (notNeeded) {
                                String name = String.format("%d_%s%s_%s_%s_%s", _encoder.getId(), _sliceName, router, proto.name(), "IMPORT", ifaceName);
                                SymbolicRoute ev2 = new SymbolicRoute(name, proto);
                                LogicalEdge eImport = new LogicalEdge(e, EdgeType.IMPORT, ev2);
                                importEdgeList.add(eImport);
                            } else {
                                String name = String.format("%d_%s%s_%s_%s_%s", _encoder.getId(), _sliceName, router, proto.name(), "IMPORT", ifaceName);
                                SymbolicRoute ev2 = new SymbolicRoute(this, name, router, proto, _optimizations, null, e.isAbstract());
                                LogicalEdge eImport = new LogicalEdge(e, EdgeType.IMPORT, ev2);
                                importEdgeList.add(eImport);
                                getAllSymbolicRecords().add(ev2);
                            }
                        }
                    }
                    List<ArrayList<LogicalEdge>> es = _logicalGraph.getLogicalEdges().get(router, proto);
                    assert (es != null);
                    ArrayList<LogicalEdge> allEdges = new ArrayList<>();
                    allEdges.addAll(importEdgeList);
                    allEdges.addAll(exportEdgeList);
                    es.add(allEdges);
                }
            }
        }
    }
    // Build a map to find the opposite of a given edge
    _logicalGraph.getLogicalEdges().forEach((router, edgeLists) -> {
        for (Protocol proto : getProtocols().get(router)) {
            for (ArrayList<LogicalEdge> edgeList : edgeLists.get(proto)) {
                for (LogicalEdge e : edgeList) {
                    GraphEdge edge = e.getEdge();
                    Map<GraphEdge, ArrayList<LogicalEdge>> m;
                    if (edge.getPeer() != null) {
                        if (e.getEdgeType() == EdgeType.IMPORT) {
                            m = exportInverseMap.get(edge.getPeer()).get(proto);
                        } else {
                            m = importInverseMap.get(edge.getPeer()).get(proto);
                        }
                        if (m != null) {
                            GraphEdge otherEdge = getGraph().getOtherEnd().get(edge);
                            ArrayList<LogicalEdge> list = m.get(otherEdge);
                            if (list == null) {
                                m.put(otherEdge, new ArrayList<>());
                            } else if (list.size() > 0) {
                                LogicalEdge other = list.get(0);
                                _logicalGraph.getOtherEnd().put(e, other);
                            }
                        }
                    }
                }
            }
        }
    });
}
Also used : Configuration(org.batfish.datamodel.Configuration) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) Prefix(org.batfish.datamodel.Prefix) IpAccessList(org.batfish.datamodel.IpAccessList) ArrayList(java.util.ArrayList) List(java.util.List) IpProtocol(org.batfish.datamodel.IpProtocol) RoutingProtocol(org.batfish.datamodel.RoutingProtocol) Protocol(org.batfish.symbolic.Protocol) MatchProtocol(org.batfish.datamodel.routing_policy.expr.MatchProtocol) HashMap(java.util.HashMap) Map(java.util.Map) GraphEdge(org.batfish.symbolic.GraphEdge) Interface(org.batfish.datamodel.Interface)

Example 23 with Protocol

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

the class Optimizations method initProtocols.

/*
   * Determine which protocols need to be modeled given the range of
   * destination IPs specified by the encoder.
   */
private void initProtocols() {
    Graph g = _encoderSlice.getGraph();
    g.getConfigurations().forEach((router, conf) -> getProtocols().put(router, new ArrayList<>()));
    g.getConfigurations().forEach((router, conf) -> {
        List<Protocol> protos = getProtocols().get(router);
        if (conf.getDefaultVrf().getOspfProcess() != null) {
            protos.add(Protocol.OSPF);
        }
        // TODO: do we want to model BGP's impact on IGP in other slices?
        if (conf.getDefaultVrf().getBgpProcess() != null && _encoderSlice.isMainSlice()) {
            protos.add(Protocol.BGP);
        }
        if (needToModelConnected(conf)) {
            protos.add(Protocol.CONNECTED);
        }
        if (needToModelStatic(conf)) {
            protos.add(Protocol.STATIC);
        }
    });
}
Also used : Graph(org.batfish.symbolic.Graph) ArrayList(java.util.ArrayList) Protocol(org.batfish.symbolic.Protocol)

Example 24 with Protocol

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

the class Optimizations method hasExportVariables.

/*
   * Check if a graph edge will have export variables for a given protocol.
   * This will happen when the edge's interface is used in the protocol
   * and the other end of the interface is internal.
   */
private boolean hasExportVariables(GraphEdge e, Protocol proto) {
    if (e.getEnd() != null) {
        String peer = e.getPeer();
        List<Protocol> peerProtocols = getProtocols().get(peer);
        if (peerProtocols.contains(proto)) {
            Configuration peerConf = _encoderSlice.getGraph().getConfigurations().get(peer);
            GraphEdge other = _encoderSlice.getGraph().getOtherEnd().get(e);
            if (_encoderSlice.getGraph().isEdgeUsed(peerConf, proto, other)) {
                return true;
            }
        }
    }
    return false;
}
Also used : Configuration(org.batfish.datamodel.Configuration) Protocol(org.batfish.symbolic.Protocol) GraphEdge(org.batfish.symbolic.GraphEdge)

Example 25 with Protocol

use of org.batfish.symbolic.Protocol 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)

Aggregations

Protocol (org.batfish.symbolic.Protocol)27 IpProtocol (org.batfish.datamodel.IpProtocol)16 RoutingProtocol (org.batfish.datamodel.RoutingProtocol)15 Configuration (org.batfish.datamodel.Configuration)14 MatchProtocol (org.batfish.datamodel.routing_policy.expr.MatchProtocol)14 ArrayList (java.util.ArrayList)12 GraphEdge (org.batfish.symbolic.GraphEdge)11 BoolExpr (com.microsoft.z3.BoolExpr)10 Prefix (org.batfish.datamodel.Prefix)10 HashMap (java.util.HashMap)8 HashSet (java.util.HashSet)6 List (java.util.List)6 Map (java.util.Map)5 BatfishException (org.batfish.common.BatfishException)5 RoutingPolicy (org.batfish.datamodel.routing_policy.RoutingPolicy)5 Interface (org.batfish.datamodel.Interface)4 IpAccessList (org.batfish.datamodel.IpAccessList)4 Graph (org.batfish.symbolic.Graph)4 BgpNeighbor (org.batfish.datamodel.BgpNeighbor)3 Ip (org.batfish.datamodel.Ip)3