Search in sources :

Example 26 with GraphEdge

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

the class Encoder method buildCounterExample.

/*
   * Add the relevant variables in the counterexample to
   * display to the user in a human-readable fashion
   */
private void buildCounterExample(Encoder enc, Model m, SortedMap<String, String> model, SortedMap<String, String> packetModel, SortedSet<String> fwdModel, SortedMap<String, SortedMap<String, String>> envModel, SortedSet<String> failures) {
    SortedMap<Expr, String> valuation = new TreeMap<>();
    // If user asks for the full model
    for (Entry<String, Expr> entry : _allVariables.entrySet()) {
        String name = entry.getKey();
        Expr e = entry.getValue();
        Expr val = m.evaluate(e, true);
        if (!val.equals(e)) {
            String s = val.toString();
            if (_question.getFullModel()) {
                model.put(name, s);
            }
            valuation.put(e, s);
        }
    }
    // Packet model
    SymbolicPacket p = enc.getMainSlice().getSymbolicPacket();
    String dstIp = valuation.get(p.getDstIp());
    String srcIp = valuation.get(p.getSrcIp());
    String dstPt = valuation.get(p.getDstPort());
    String srcPt = valuation.get(p.getSrcPort());
    String icmpCode = valuation.get(p.getIcmpCode());
    String icmpType = valuation.get(p.getIcmpType());
    String ipProtocol = valuation.get(p.getIpProtocol());
    String tcpAck = valuation.get(p.getTcpAck());
    String tcpCwr = valuation.get(p.getTcpCwr());
    String tcpEce = valuation.get(p.getTcpEce());
    String tcpFin = valuation.get(p.getTcpFin());
    String tcpPsh = valuation.get(p.getTcpPsh());
    String tcpRst = valuation.get(p.getTcpRst());
    String tcpSyn = valuation.get(p.getTcpSyn());
    String tcpUrg = valuation.get(p.getTcpUrg());
    Ip dip = new Ip(Long.parseLong(dstIp));
    Ip sip = new Ip(Long.parseLong(srcIp));
    packetModel.put("dstIp", dip.toString());
    if (sip.asLong() != 0) {
        packetModel.put("srcIp", sip.toString());
    }
    if (dstPt != null && !dstPt.equals("0")) {
        packetModel.put("dstPort", dstPt);
    }
    if (srcPt != null && !srcPt.equals("0")) {
        packetModel.put("srcPort", srcPt);
    }
    if (icmpCode != null && !icmpCode.equals("0")) {
        packetModel.put("icmpCode", icmpCode);
    }
    if (icmpType != null && !icmpType.equals("0")) {
        packetModel.put("icmpType", icmpType);
    }
    if (ipProtocol != null && !ipProtocol.equals("0")) {
        Integer number = Integer.parseInt(ipProtocol);
        IpProtocol proto = IpProtocol.fromNumber(number);
        packetModel.put("protocol", proto.toString());
    }
    if ("true".equals(tcpAck)) {
        packetModel.put("tcpAck", "set");
    }
    if ("true".equals(tcpCwr)) {
        packetModel.put("tcpCwr", "set");
    }
    if ("true".equals(tcpEce)) {
        packetModel.put("tcpEce", "set");
    }
    if ("true".equals(tcpFin)) {
        packetModel.put("tcpFin", "set");
    }
    if ("true".equals(tcpPsh)) {
        packetModel.put("tcpPsh", "set");
    }
    if ("true".equals(tcpRst)) {
        packetModel.put("tcpRst", "set");
    }
    if ("true".equals(tcpSyn)) {
        packetModel.put("tcpSyn", "set");
    }
    if ("true".equals(tcpUrg)) {
        packetModel.put("tcpUrg", "set");
    }
    for (EncoderSlice slice : enc.getSlices().values()) {
        for (Entry<LogicalEdge, SymbolicRoute> entry2 : slice.getLogicalGraph().getEnvironmentVars().entrySet()) {
            LogicalEdge lge = entry2.getKey();
            SymbolicRoute r = entry2.getValue();
            if ("true".equals(valuation.get(r.getPermitted()))) {
                SortedMap<String, String> recordMap = new TreeMap<>();
                GraphEdge ge = lge.getEdge();
                String nodeIface = ge.getRouter() + "," + ge.getStart().getName() + " (BGP)";
                envModel.put(nodeIface, recordMap);
                if (r.getPrefixLength() != null) {
                    String x = valuation.get(r.getPrefixLength());
                    if (x != null) {
                        int len = Integer.parseInt(x);
                        Prefix p1 = new Prefix(dip, len);
                        recordMap.put("prefix", p1.toString());
                    }
                }
                if (r.getAdminDist() != null) {
                    String x = valuation.get(r.getAdminDist());
                    if (x != null) {
                        recordMap.put("admin distance", x);
                    }
                }
                if (r.getLocalPref() != null) {
                    String x = valuation.get(r.getLocalPref());
                    if (x != null) {
                        recordMap.put("local preference", x);
                    }
                }
                if (r.getMetric() != null) {
                    String x = valuation.get(r.getMetric());
                    if (x != null) {
                        recordMap.put("protocol metric", x);
                    }
                }
                if (r.getMed() != null) {
                    String x = valuation.get(r.getMed());
                    if (x != null) {
                        recordMap.put("multi-exit disc.", valuation.get(r.getMed()));
                    }
                }
                if (r.getOspfArea() != null && r.getOspfArea().getBitVec() != null) {
                    String x = valuation.get(r.getOspfArea().getBitVec());
                    if (x != null) {
                        Integer i = Integer.parseInt(x);
                        Long area = r.getOspfArea().value(i);
                        recordMap.put("OSPF Area", area.toString());
                    }
                }
                if (r.getOspfType() != null && r.getOspfType().getBitVec() != null) {
                    String x = valuation.get(r.getOspfType().getBitVec());
                    if (x != null) {
                        Integer i = Integer.parseInt(x);
                        OspfType type = r.getOspfType().value(i);
                        recordMap.put("OSPF Type", type.toString());
                    }
                }
                for (Entry<CommunityVar, BoolExpr> entry3 : r.getCommunities().entrySet()) {
                    CommunityVar cvar = entry3.getKey();
                    BoolExpr e = entry3.getValue();
                    String c = valuation.get(e);
                    // TODO: what about OTHER type?
                    if ("true".equals(c) && displayCommunity(cvar)) {
                        String s = cvar.getValue();
                        String t = slice.getNamedCommunities().get(cvar.getValue());
                        s = (t == null ? s : t);
                        recordMap.put("community " + s, "");
                    }
                }
            }
        }
    }
    // Forwarding Model
    enc.getMainSlice().getSymbolicDecisions().getDataForwarding().forEach((router, edge, e) -> {
        String s = valuation.get(e);
        if ("true".equals(s)) {
            SymbolicRoute r = enc.getMainSlice().getSymbolicDecisions().getBestNeighbor().get(router);
            if (r.getProtocolHistory() != null) {
                Protocol proto;
                List<Protocol> allProtocols = enc.getMainSlice().getProtocols().get(router);
                if (allProtocols.size() == 1) {
                    proto = allProtocols.get(0);
                } else {
                    s = valuation.get(r.getProtocolHistory().getBitVec());
                    int i = Integer.parseInt(s);
                    proto = r.getProtocolHistory().value(i);
                }
                fwdModel.add(edge + " (" + proto.name() + ")");
            } else {
                fwdModel.add(edge.toString());
            }
        }
    });
    _symbolicFailures.getFailedInternalLinks().forEach((x, y, e) -> {
        String s = valuation.get(e);
        if ("1".equals(s)) {
            String pair = (x.compareTo(y) < 0 ? x + "," + y : y + "," + x);
            failures.add("link(" + pair + ")");
        }
    });
    _symbolicFailures.getFailedEdgeLinks().forEach((ge, e) -> {
        String s = valuation.get(e);
        if ("1".equals(s)) {
            failures.add("link(" + ge.getRouter() + "," + ge.getStart().getName() + ")");
        }
    });
}
Also used : BoolExpr(com.microsoft.z3.BoolExpr) Ip(org.batfish.datamodel.Ip) Prefix(org.batfish.datamodel.Prefix) TreeMap(java.util.TreeMap) CommunityVar(org.batfish.symbolic.CommunityVar) BoolExpr(com.microsoft.z3.BoolExpr) ArithExpr(com.microsoft.z3.ArithExpr) BitVecExpr(com.microsoft.z3.BitVecExpr) Expr(com.microsoft.z3.Expr) IpProtocol(org.batfish.datamodel.IpProtocol) OspfType(org.batfish.symbolic.OspfType) IpProtocol(org.batfish.datamodel.IpProtocol) Protocol(org.batfish.symbolic.Protocol) GraphEdge(org.batfish.symbolic.GraphEdge)

Example 27 with GraphEdge

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

the class EncoderSlice method addTransferFunction.

/*
   * Constraints that define relationships between various messages
   * in the network. The same transfer function abstraction is used
   * for both import and export constraints by relating different collections
   * of variables.
   */
private void addTransferFunction() {
    for (Entry<String, Configuration> entry : getGraph().getConfigurations().entrySet()) {
        String router = entry.getKey();
        Configuration conf = entry.getValue();
        for (Protocol proto : getProtocols().get(router)) {
            Boolean usedExport = false;
            boolean hasEdge = false;
            List<ArrayList<LogicalEdge>> les = _logicalGraph.getLogicalEdges().get(router, proto);
            assert (les != null);
            for (ArrayList<LogicalEdge> eList : les) {
                for (LogicalEdge e : eList) {
                    GraphEdge ge = e.getEdge();
                    if (!getGraph().isEdgeUsed(conf, proto, ge)) {
                        continue;
                    }
                    hasEdge = true;
                    SymbolicRoute varsOther;
                    switch(e.getEdgeType()) {
                        case IMPORT:
                            varsOther = _logicalGraph.findOtherVars(e);
                            addImportConstraint(e, varsOther, conf, proto, ge, router);
                            break;
                        case EXPORT:
                            // OSPF export is tricky because it does not depend on being
                            // in the FIB. So it can come from either a redistributed route
                            // or another OSPF route. We always take the direct OSPF
                            SymbolicRoute ospfRedistribVars = null;
                            SymbolicRoute overallBest = null;
                            if (proto.isOspf()) {
                                varsOther = getBestNeighborPerProtocol(router, proto);
                                if (_ospfRedistributed.containsKey(router)) {
                                    ospfRedistribVars = _ospfRedistributed.get(router);
                                    overallBest = _symbolicDecisions.getBestNeighbor().get(router);
                                }
                            } else {
                                varsOther = _symbolicDecisions.getBestNeighbor().get(router);
                            }
                            Set<Prefix> originations = _originatedNetworks.get(router, proto);
                            assert varsOther != null;
                            assert originations != null;
                            addExportConstraint(e, varsOther, ospfRedistribVars, overallBest, conf, proto, ge, router, usedExport, originations);
                            usedExport = true;
                            break;
                        default:
                            break;
                    }
                }
            }
            // If no edge used, then just set the best record to be false for that protocol
            if (!hasEdge) {
                SymbolicRoute protoBest;
                if (_optimizations.getSliceHasSingleProtocol().contains(router)) {
                    protoBest = _symbolicDecisions.getBestNeighbor().get(router);
                } else {
                    protoBest = _symbolicDecisions.getBestNeighborPerProtocol().get(router, proto);
                }
                assert protoBest != null;
                add(mkNot(protoBest.getPermitted()));
            }
        }
    }
}
Also used : Configuration(org.batfish.datamodel.Configuration) ArrayList(java.util.ArrayList) Prefix(org.batfish.datamodel.Prefix) 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 28 with GraphEdge

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

the class EncoderSlice method addControlForwardingConstraints.

/*
   * Constraints that define control-plane forwarding.
   * If there is some valid import, then control plane forwarding
   * will occur out an interface when this is the best choice.
   * Otherwise, it will not occur.
   */
private void addControlForwardingConstraints() {
    for (Entry<String, Configuration> entry : getGraph().getConfigurations().entrySet()) {
        String router = entry.getKey();
        Configuration conf = entry.getValue();
        boolean someEdge = false;
        SymbolicRoute best = _symbolicDecisions.getBestNeighbor().get(router);
        Map<GraphEdge, BoolExpr> cfExprs = new HashMap<>();
        Set<GraphEdge> constrained = new HashSet<>();
        for (Protocol proto : getProtocols().get(router)) {
            for (LogicalEdge e : collectAllImportLogicalEdges(router, conf, proto)) {
                someEdge = true;
                constrained.add(e.getEdge());
                SymbolicRoute vars = correctVars(e);
                BoolExpr choice = _symbolicDecisions.getChoiceVariables().get(router, proto, e);
                BoolExpr isBest = mkAnd(choice, equal(conf, proto, best, vars, e, false));
                GraphEdge ge = e.getEdge();
                // Connected routes should only forward if not absorbed by interface
                GraphEdge other = getGraph().getOtherEnd().get(ge);
                BoolExpr connectedWillSend;
                if (other == null || getGraph().isHost(ge.getPeer())) {
                    Ip ip = ge.getStart().getAddress().getIp();
                    BitVecExpr val = getCtx().mkBV(ip.asLong(), 32);
                    connectedWillSend = mkNot(mkEq(_symbolicPacket.getDstIp(), val));
                } else {
                    Ip ip = other.getStart().getAddress().getIp();
                    BitVecExpr val = getCtx().mkBV(ip.asLong(), 32);
                    connectedWillSend = mkEq(_symbolicPacket.getDstIp(), val);
                }
                BoolExpr canSend = (proto.isConnected() ? connectedWillSend : mkTrue());
                BoolExpr sends = mkAnd(canSend, isBest);
                BoolExpr cForward = _symbolicDecisions.getControlForwarding().get(router, ge);
                assert (cForward != null);
                add(mkImplies(sends, cForward));
                // record the negation as well
                cfExprs.merge(ge, sends, (a, b) -> mkOr(a, b));
            }
        }
        // For edges that are never used, we constraint them to not be forwarded out of
        for (GraphEdge ge : getGraph().getEdgeMap().get(router)) {
            if (!constrained.contains(ge)) {
                BoolExpr cForward = _symbolicDecisions.getControlForwarding().get(router, ge);
                assert (cForward != null);
                add(mkNot(cForward));
            }
        }
        // Handle the case that the router has no protocol running
        if (!someEdge) {
            for (GraphEdge ge : getGraph().getEdgeMap().get(router)) {
                BoolExpr cForward = _symbolicDecisions.getControlForwarding().get(router, ge);
                assert (cForward != null);
                add(mkNot(cForward));
            }
        } else {
            // If no best route, then no forwarding
            Map<Protocol, List<ArrayList<LogicalEdge>>> map = _logicalGraph.getLogicalEdges().get(router);
            Set<GraphEdge> seen = new HashSet<>();
            for (List<ArrayList<LogicalEdge>> eList : map.values()) {
                for (ArrayList<LogicalEdge> edges : eList) {
                    for (LogicalEdge le : edges) {
                        GraphEdge ge = le.getEdge();
                        if (seen.contains(ge)) {
                            continue;
                        }
                        seen.add(ge);
                        BoolExpr expr = cfExprs.get(ge);
                        BoolExpr cForward = _symbolicDecisions.getControlForwarding().get(router, ge);
                        assert (cForward != null);
                        if (expr != null) {
                            add(mkImplies(mkNot(expr), mkNot(cForward)));
                        } else {
                            add(mkNot(cForward));
                        }
                    }
                }
            }
        }
    }
}
Also used : BoolExpr(com.microsoft.z3.BoolExpr) Configuration(org.batfish.datamodel.Configuration) HashMap(java.util.HashMap) Ip(org.batfish.datamodel.Ip) ArrayList(java.util.ArrayList) BitVecExpr(com.microsoft.z3.BitVecExpr) 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) GraphEdge(org.batfish.symbolic.GraphEdge) HashSet(java.util.HashSet)

Example 29 with GraphEdge

use of org.batfish.symbolic.GraphEdge 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 30 with GraphEdge

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

Aggregations

GraphEdge (org.batfish.symbolic.GraphEdge)47 BoolExpr (com.microsoft.z3.BoolExpr)23 HashMap (java.util.HashMap)19 ArrayList (java.util.ArrayList)16 List (java.util.List)16 Graph (org.batfish.symbolic.Graph)14 TreeSet (java.util.TreeSet)13 Prefix (org.batfish.datamodel.Prefix)12 ArithExpr (com.microsoft.z3.ArithExpr)10 Configuration (org.batfish.datamodel.Configuration)10 Protocol (org.batfish.symbolic.Protocol)10 HashSet (java.util.HashSet)8 Interface (org.batfish.datamodel.Interface)8 Context (com.microsoft.z3.Context)7 Map (java.util.Map)7 Ip (org.batfish.datamodel.Ip)7 IpAccessList (org.batfish.datamodel.IpAccessList)7 TreeMap (java.util.TreeMap)6 IpProtocol (org.batfish.datamodel.IpProtocol)6 BitVecExpr (com.microsoft.z3.BitVecExpr)5