Search in sources :

Example 6 with Flow

use of org.batfish.datamodel.Flow in project batfish by batfish.

the class CounterExample method buildFlowHistoryDiff.

/*
   * Create a trace-based counterexample demonstrating
   * the difference between two networks on a single packet.
   */
FlowHistory buildFlowHistoryDiff(String testRigName, Collection<String> sourceRouters, Encoder enc, Encoder enc2, Map<String, BoolExpr> reach, Map<String, BoolExpr> reach2) {
    FlowHistory fh = new FlowHistory();
    assert (reach2 != null);
    for (String source : sourceRouters) {
        BoolExpr sourceVar1 = reach.get(source);
        BoolExpr sourceVar2 = reach2.get(source);
        String val1 = evaluate(sourceVar1);
        String val2 = evaluate(sourceVar2);
        if (!Objects.equals(val1, val2)) {
            Tuple<Flow, FlowTrace> diff = buildFlowTrace(enc, source);
            Tuple<Flow, FlowTrace> base = buildFlowTrace(enc2, source);
            SortedSet<Edge> failedLinksDiff = buildFailedLinks(enc);
            SortedSet<Edge> failedLinksBase = buildFailedLinks(enc2);
            SortedSet<BgpAdvertisement> envRoutesDiff = buildEnvRoutingTable(enc);
            SortedSet<BgpAdvertisement> envRoutesBase = buildEnvRoutingTable(enc2);
            Environment baseEnv = new Environment("BASE", testRigName, failedLinksBase, null, null, null, null, envRoutesBase);
            Environment failedEnv = new Environment("DELTA", testRigName, failedLinksDiff, null, null, null, null, envRoutesDiff);
            fh.addFlowTrace(base.getFirst(), "BASE", baseEnv, base.getSecond());
            fh.addFlowTrace(diff.getFirst(), "DELTA", failedEnv, diff.getSecond());
        }
    }
    return fh;
}
Also used : BoolExpr(com.microsoft.z3.BoolExpr) BgpAdvertisement(org.batfish.datamodel.BgpAdvertisement) FlowHistory(org.batfish.datamodel.FlowHistory) FlowTrace(org.batfish.datamodel.FlowTrace) Environment(org.batfish.datamodel.pojo.Environment) Edge(org.batfish.datamodel.Edge) GraphEdge(org.batfish.symbolic.GraphEdge) Flow(org.batfish.datamodel.Flow)

Example 7 with Flow

use of org.batfish.datamodel.Flow in project batfish by batfish.

the class CounterExample method buildEnvRoutingTable.

SortedSet<BgpAdvertisement> buildEnvRoutingTable(Encoder enc) {
    SortedSet<BgpAdvertisement> routes = new TreeSet<>();
    EncoderSlice slice = enc.getMainSlice();
    LogicalGraph lg = slice.getLogicalGraph();
    for (Entry<LogicalEdge, SymbolicRoute> entry : lg.getEnvironmentVars().entrySet()) {
        LogicalEdge lge = entry.getKey();
        SymbolicRoute record = entry.getValue();
        // If there is an external advertisement
        if (boolVal(record.getPermitted())) {
            // If we actually use it
            GraphEdge ge = lge.getEdge();
            String router = ge.getRouter();
            SymbolicDecisions decisions = slice.getSymbolicDecisions();
            BoolExpr ctrFwd = decisions.getControlForwarding().get(router, ge);
            assert ctrFwd != null;
            if (boolVal(ctrFwd)) {
                SymbolicRoute r = decisions.getBestNeighbor().get(router);
                SymbolicPacket pkt = slice.getSymbolicPacket();
                Flow f = buildFlow(pkt, router);
                Prefix pfx = buildPrefix(r, f);
                int pathLength = intVal(r.getMetric());
                // Create dummy information
                BgpNeighbor n = slice.getGraph().getEbgpNeighbors().get(lge.getEdge());
                String srcNode = "as" + n.getRemoteAs();
                Ip zeroIp = new Ip(0);
                Ip dstIp = n.getLocalIp();
                // Recover AS path
                List<SortedSet<Integer>> asSets = new ArrayList<>();
                for (int i = 0; i < pathLength; i++) {
                    SortedSet<Integer> asSet = new TreeSet<>();
                    asSet.add(-1);
                    asSets.add(asSet);
                }
                AsPath path = new AsPath(asSets);
                // Recover communities
                SortedSet<Long> communities = new TreeSet<>();
                for (Entry<CommunityVar, BoolExpr> entry2 : r.getCommunities().entrySet()) {
                    CommunityVar cvar = entry2.getKey();
                    BoolExpr expr = entry2.getValue();
                    if (cvar.getType() == Type.EXACT && boolVal(expr)) {
                        communities.add(cvar.asLong());
                    }
                }
                BgpAdvertisement adv = new BgpAdvertisement(BgpAdvertisementType.EBGP_RECEIVED, pfx, zeroIp, srcNode, "default", zeroIp, router, "default", dstIp, RoutingProtocol.BGP, OriginType.EGP, 100, 80, zeroIp, path, communities, new TreeSet<>(), 0);
                routes.add(adv);
            }
        }
    }
    return routes;
}
Also used : BoolExpr(com.microsoft.z3.BoolExpr) Ip(org.batfish.datamodel.Ip) ArrayList(java.util.ArrayList) Prefix(org.batfish.datamodel.Prefix) SortedSet(java.util.SortedSet) BgpNeighbor(org.batfish.datamodel.BgpNeighbor) TreeSet(java.util.TreeSet) Flow(org.batfish.datamodel.Flow) CommunityVar(org.batfish.symbolic.CommunityVar) BgpAdvertisement(org.batfish.datamodel.BgpAdvertisement) AsPath(org.batfish.datamodel.AsPath) GraphEdge(org.batfish.symbolic.GraphEdge)

Example 8 with Flow

use of org.batfish.datamodel.Flow in project batfish by batfish.

the class CounterExample method buildFlow.

Flow buildFlow(SymbolicPacket pkt, String router) {
    Ip srcIp = ipVal(pkt.getSrcIp());
    Ip dstIp = ipVal(pkt.getDstIp());
    Integer srcPort = intVal(pkt.getSrcPort());
    Integer dstPort = intVal(pkt.getDstPort());
    IpProtocol ipProtocol = IpProtocol.fromNumber(intVal(pkt.getIpProtocol()));
    Integer icmpType = intVal(pkt.getIcmpType());
    Integer icmpCode = intVal(pkt.getIcmpCode());
    Integer tcpFlagsCwr = isTrue(pkt.getTcpCwr()) ? 0 : 1;
    Integer tcpFlagsEce = isTrue(pkt.getTcpEce()) ? 0 : 1;
    Integer tcpFlagsUrg = isTrue(pkt.getTcpUrg()) ? 0 : 1;
    Integer tcpFlagsAck = isTrue(pkt.getTcpAck()) ? 0 : 1;
    Integer tcpFlagsPsh = isTrue(pkt.getTcpPsh()) ? 0 : 1;
    Integer tcpFlagsRst = isTrue(pkt.getTcpRst()) ? 0 : 1;
    Integer tcpFlagsSyn = isTrue(pkt.getTcpSyn()) ? 0 : 1;
    Integer tcpFlagsFin = isTrue(pkt.getTcpFin()) ? 0 : 1;
    Flow.Builder b = new Flow.Builder();
    b.setIngressNode(router);
    b.setSrcIp(srcIp);
    b.setDstIp(dstIp);
    b.setSrcPort(srcPort);
    b.setDstPort(dstPort);
    b.setIpProtocol(ipProtocol);
    b.setIcmpType(icmpType);
    b.setIcmpCode(icmpCode);
    b.setTcpFlagsCwr(tcpFlagsCwr);
    b.setTcpFlagsEce(tcpFlagsEce);
    b.setTcpFlagsUrg(tcpFlagsUrg);
    b.setTcpFlagsAck(tcpFlagsAck);
    b.setTcpFlagsPsh(tcpFlagsPsh);
    b.setTcpFlagsRst(tcpFlagsRst);
    b.setTcpFlagsSyn(tcpFlagsSyn);
    b.setTcpFlagsFin(tcpFlagsFin);
    b.setTag("SMT");
    return b.build();
}
Also used : Ip(org.batfish.datamodel.Ip) IpProtocol(org.batfish.datamodel.IpProtocol) Flow(org.batfish.datamodel.Flow)

Example 9 with Flow

use of org.batfish.datamodel.Flow in project batfish by batfish.

the class CounterExample method buildRoute.

/*
   * Create a route from a graph edge
   */
String buildRoute(EncoderSlice slice, GraphEdge ge) {
    String router = ge.getRouter();
    SymbolicDecisions decisions = slice.getSymbolicDecisions();
    SymbolicRoute r = decisions.getBestNeighbor().get(router);
    SymbolicPacket pkt = slice.getSymbolicPacket();
    Flow f = buildFlow(pkt, router);
    Prefix pfx = buildPrefix(r, f);
    Protocol proto = buildProcotol(r, slice, router);
    return buildRoute(pfx, proto, ge);
}
Also used : Prefix(org.batfish.datamodel.Prefix) IpProtocol(org.batfish.datamodel.IpProtocol) RoutingProtocol(org.batfish.datamodel.RoutingProtocol) Protocol(org.batfish.symbolic.Protocol) Flow(org.batfish.datamodel.Flow)

Example 10 with Flow

use of org.batfish.datamodel.Flow in project batfish by batfish.

the class PropertyChecker method checkDeterminism.

/*
   * Check if there exist multiple stable solutions to the network.
   * If so, reports the forwarding differences between the two cases.
   */
public AnswerElement checkDeterminism(HeaderQuestion q) {
    Graph graph = new Graph(_batfish);
    Encoder enc1 = new Encoder(_settings, graph, q);
    Encoder enc2 = new Encoder(enc1, graph, q);
    enc1.computeEncoding();
    enc2.computeEncoding();
    addEnvironmentConstraints(enc1, q.getBaseEnvironmentType());
    BoolExpr relatedFailures = relateFailures(enc1, enc2);
    BoolExpr relatedEnvs = relateEnvironments(enc1, enc2);
    BoolExpr relatedPkts = relatePackets(enc1, enc2);
    BoolExpr related = enc1.mkAnd(relatedFailures, relatedEnvs, relatedPkts);
    BoolExpr required = enc1.mkTrue();
    for (GraphEdge ge : graph.getAllRealEdges()) {
        SymbolicDecisions d1 = enc1.getMainSlice().getSymbolicDecisions();
        SymbolicDecisions d2 = enc2.getMainSlice().getSymbolicDecisions();
        BoolExpr dataFwd1 = d1.getDataForwarding().get(ge.getRouter(), ge);
        BoolExpr dataFwd2 = d2.getDataForwarding().get(ge.getRouter(), ge);
        assert dataFwd1 != null;
        assert dataFwd2 != null;
        required = enc1.mkAnd(required, enc1.mkEq(dataFwd1, dataFwd2));
    }
    enc1.add(related);
    enc1.add(enc1.mkNot(required));
    Tuple<VerificationResult, Model> tup = enc1.verify();
    VerificationResult res = tup.getFirst();
    Model model = tup.getSecond();
    SortedSet<String> case1 = null;
    SortedSet<String> case2 = null;
    Flow flow = null;
    CounterExample ce = new CounterExample(model);
    if (!res.isVerified()) {
        case1 = new TreeSet<>();
        case2 = new TreeSet<>();
        flow = ce.buildFlow(enc1.getMainSlice().getSymbolicPacket(), "(none)");
        for (GraphEdge ge : graph.getAllRealEdges()) {
            SymbolicDecisions d1 = enc1.getMainSlice().getSymbolicDecisions();
            SymbolicDecisions d2 = enc2.getMainSlice().getSymbolicDecisions();
            BoolExpr dataFwd1 = d1.getDataForwarding().get(ge.getRouter(), ge);
            BoolExpr dataFwd2 = d2.getDataForwarding().get(ge.getRouter(), ge);
            assert dataFwd1 != null;
            assert dataFwd2 != null;
            boolean b1 = ce.boolVal(dataFwd1);
            boolean b2 = ce.boolVal(dataFwd2);
            if (b1 != b2) {
                if (b1) {
                    String route = ce.buildRoute(enc1.getMainSlice(), ge);
                    String msg = ge + " -- " + route;
                    case1.add(msg);
                }
                if (b2) {
                    String route = ce.buildRoute(enc2.getMainSlice(), ge);
                    String msg = ge + " -- " + route;
                    case2.add(msg);
                }
            }
        }
    }
    // Ensure canonical order
    boolean less = (case1 == null || (case1.first().compareTo(case2.first()) < 0));
    if (less) {
        return new SmtDeterminismAnswerElement(flow, case1, case2);
    } else {
        return new SmtDeterminismAnswerElement(flow, case2, case1);
    }
}
Also used : BoolExpr(com.microsoft.z3.BoolExpr) Flow(org.batfish.datamodel.Flow) Graph(org.batfish.symbolic.Graph) Model(com.microsoft.z3.Model) SmtDeterminismAnswerElement(org.batfish.symbolic.answers.SmtDeterminismAnswerElement) GraphEdge(org.batfish.symbolic.GraphEdge)

Aggregations

Flow (org.batfish.datamodel.Flow)25 Ip (org.batfish.datamodel.Ip)16 FlowTrace (org.batfish.datamodel.FlowTrace)11 TreeSet (java.util.TreeSet)8 Edge (org.batfish.datamodel.Edge)8 ImmutableMap (com.google.common.collect.ImmutableMap)7 ArrayList (java.util.ArrayList)7 Map (java.util.Map)7 BatfishException (org.batfish.common.BatfishException)7 SortedMap (java.util.SortedMap)6 BgpAdvertisement (org.batfish.datamodel.BgpAdvertisement)6 ImmutableSortedMap (com.google.common.collect.ImmutableSortedMap)5 Prefix (org.batfish.datamodel.Prefix)5 SourceNat (org.batfish.datamodel.SourceNat)5 Test (org.junit.Test)5 ImmutableSortedSet (com.google.common.collect.ImmutableSortedSet)4 BoolExpr (com.microsoft.z3.BoolExpr)4 GlobalTracer (io.opentracing.util.GlobalTracer)4 Collections (java.util.Collections)4 SortedSet (java.util.SortedSet)4