Search in sources :

Example 81 with Context

use of com.google.cloud.dialogflow.v2.Context in project batfish by batfish.

the class PropertyAdder method instrumentLoad.

/*
   * Instruments the network with load balancing information to destination
   * port for graph edge ge. Each router will split load according to the
   * number of neighbors it actively uses to get to ge.
   */
Map<String, ArithExpr> instrumentLoad(Set<GraphEdge> ges) {
    Context ctx = _encoderSlice.getCtx();
    Solver solver = _encoderSlice.getSolver();
    String sliceName = _encoderSlice.getSliceName();
    Map<String, ArithExpr> loadVars = new HashMap<>();
    Graph graph = _encoderSlice.getGraph();
    for (String router : graph.getRouters()) {
        String name = _encoderSlice.getEncoder().getId() + "_" + sliceName + "_load_" + router;
        ArithExpr var = ctx.mkIntConst(name);
        loadVars.put(router, var);
        _encoderSlice.getAllVariables().put(var.toString(), var);
    }
    loadVars.forEach((name, var) -> solver.add(ctx.mkGe(var, ctx.mkInt(0))));
    ArithExpr zero = ctx.mkInt(0);
    ArithExpr one = ctx.mkInt(1);
    for (Entry<String, List<GraphEdge>> entry : graph.getEdgeMap().entrySet()) {
        String router = entry.getKey();
        List<GraphEdge> edges = entry.getValue();
        ArithExpr load = loadVars.get(router);
        BoolExpr hasDirectRoute = ctx.mkFalse();
        BoolExpr isAbsorbed = ctx.mkFalse();
        SymbolicRoute r = _encoderSlice.getBestNeighborPerProtocol(router, Protocol.CONNECTED);
        for (GraphEdge ge : edges) {
            if (!ge.isAbstract() && ges.contains(ge)) {
                // if we leave the network
                if (ge.getPeer() == null) {
                    BoolExpr fwdIface = _encoderSlice.getForwardsAcross().get(ge.getRouter(), ge);
                    assert (fwdIface != null);
                    hasDirectRoute = ctx.mkOr(hasDirectRoute, fwdIface);
                }
                // if connected route and we use it despite not forwarding
                if (r != null) {
                    BitVecExpr dstIp = _encoderSlice.getSymbolicPacket().getDstIp();
                    BitVecExpr ip = ctx.mkBV(ge.getStart().getAddress().getIp().asLong(), 32);
                    BoolExpr reach = ctx.mkAnd(r.getPermitted(), ctx.mkEq(dstIp, ip));
                    isAbsorbed = ctx.mkOr(isAbsorbed, reach);
                }
            }
        }
        ArithExpr acc = ctx.mkInt(0);
        for (GraphEdge edge : edges) {
            if (!edge.isAbstract()) {
                BoolExpr fwd = _encoderSlice.getForwardsAcross().get(router, edge);
                assert (fwd != null);
                if (edge.getPeer() != null) {
                    ArithExpr peerLoad = loadVars.get(edge.getPeer());
                    ArithExpr x = (ArithExpr) ctx.mkITE(fwd, peerLoad, zero);
                    acc = ctx.mkAdd(acc, x);
                }
            }
        }
        solver.add(ctx.mkEq(load, acc));
        BoolExpr guard = _encoderSlice.mkOr(hasDirectRoute, isAbsorbed);
        BoolExpr cond = _encoderSlice.mkIf(guard, ctx.mkEq(load, one), ctx.mkEq(load, acc));
        solver.add(cond);
    }
    return loadVars;
}
Also used : Context(com.microsoft.z3.Context) ArithExpr(com.microsoft.z3.ArithExpr) BoolExpr(com.microsoft.z3.BoolExpr) Solver(com.microsoft.z3.Solver) HashMap(java.util.HashMap) BitVecExpr(com.microsoft.z3.BitVecExpr) Graph(org.batfish.symbolic.Graph) List(java.util.List) GraphEdge(org.batfish.symbolic.GraphEdge)

Example 82 with Context

use of com.google.cloud.dialogflow.v2.Context in project batfish by batfish.

the class PropertyAdder method instrumentReachability.

/*
   * Also instruments reachability, but to a destination router
   * rather than a destination port.
   */
Map<String, BoolExpr> instrumentReachability(String router) {
    Context ctx = _encoderSlice.getCtx();
    Solver solver = _encoderSlice.getSolver();
    Map<String, BoolExpr> reachableVars = new HashMap<>();
    Map<String, ArithExpr> idVars = new HashMap<>();
    initializeReachabilityVars(_encoderSlice, ctx, solver, reachableVars, idVars);
    ArithExpr baseId = idVars.get(router);
    _encoderSlice.add(ctx.mkEq(baseId, ctx.mkInt(1)));
    Graph g = _encoderSlice.getGraph();
    for (Entry<String, List<GraphEdge>> entry : g.getEdgeMap().entrySet()) {
        String r = entry.getKey();
        List<GraphEdge> edges = entry.getValue();
        if (!r.equals(router)) {
            ArithExpr id = idVars.get(r);
            BoolExpr cond = recursiveReachability(ctx, _encoderSlice, edges, idVars, r, id);
            solver.add(cond);
        }
    }
    return reachableVars;
}
Also used : Context(com.microsoft.z3.Context) ArithExpr(com.microsoft.z3.ArithExpr) BoolExpr(com.microsoft.z3.BoolExpr) Solver(com.microsoft.z3.Solver) HashMap(java.util.HashMap) Graph(org.batfish.symbolic.Graph) List(java.util.List) GraphEdge(org.batfish.symbolic.GraphEdge)

Example 83 with Context

use of com.google.cloud.dialogflow.v2.Context in project batfish by batfish.

the class PropertyChecker method checkLocalEquivalence.

/*
   * Computes whether or not two routers are equivalent.
   * To be equivalent, each router must have identical intefaces.
   *
   * We then relate the environments on each interface for each router
   * so that they are required to be equal.
   *
   * We finally check that their forwarding decisions and exported messages
   * will be equal given their equal inputs.
   */
public AnswerElement checkLocalEquivalence(Pattern n, boolean strict, boolean fullModel) {
    Graph graph = new Graph(_batfish);
    List<String> routers = PatternUtils.findMatchingNodes(graph, n, Pattern.compile(""));
    HeaderQuestion q = new HeaderQuestion();
    q.setFullModel(fullModel);
    q.setFailures(0);
    q.setBaseEnvironmentType(EnvironmentType.ANY);
    Collections.sort(routers);
    SortedMap<String, VerificationResult> result = new TreeMap<>();
    int len = routers.size();
    if (len <= 1) {
        return new SmtManyAnswerElement(new TreeMap<>());
    }
    for (int i = 0; i < len - 1; i++) {
        String r1 = routers.get(i);
        String r2 = routers.get(i + 1);
        // TODO: reorder to encode after checking if we can compare them
        // Create transfer function for router 1
        Set<String> toModel1 = new TreeSet<>();
        toModel1.add(r1);
        Graph g1 = new Graph(_batfish, null, toModel1);
        Encoder e1 = new Encoder(_settings, g1, q);
        e1.computeEncoding();
        Context ctx = e1.getCtx();
        // Create transfer function for router 2
        Set<String> toModel2 = new TreeSet<>();
        toModel2.add(r2);
        Graph g2 = new Graph(_batfish, null, toModel2);
        Encoder e2 = new Encoder(e1, g2);
        e2.computeEncoding();
        EncoderSlice slice1 = e1.getMainSlice();
        EncoderSlice slice2 = e2.getMainSlice();
        // Ensure that the two routers have the same interfaces for comparison
        Pattern p = Pattern.compile(".*");
        Pattern neg = Pattern.compile("");
        List<GraphEdge> edges1 = PatternUtils.findMatchingEdges(g1, p, neg, p, neg);
        List<GraphEdge> edges2 = PatternUtils.findMatchingEdges(g2, p, neg, p, neg);
        Set<String> ifaces1 = interfaces(edges1);
        Set<String> ifaces2 = interfaces(edges2);
        if (!(ifaces1.containsAll(ifaces2) && ifaces2.containsAll(ifaces1))) {
            String msg = String.format("Routers %s and %s have different interfaces", r1, r2);
            System.out.println(msg);
            return new SmtManyAnswerElement(new TreeMap<>());
        }
        // TODO: check running same protocols?
        Map<String, Map<Protocol, Map<String, EnumMap<EdgeType, LogicalEdge>>>> lgeMap2 = logicalEdgeMap(slice2);
        BoolExpr equalEnvs = ctx.mkBool(true);
        BoolExpr equalOutputs = ctx.mkBool(true);
        BoolExpr equalIncomingAcls = ctx.mkBool(true);
        Configuration conf1 = g1.getConfigurations().get(r1);
        Configuration conf2 = g2.getConfigurations().get(r2);
        // Set environments equal
        Set<String> communities = new HashSet<>();
        Set<SymbolicRoute> envRecords = new HashSet<>();
        for (Protocol proto1 : slice1.getProtocols().get(r1)) {
            for (ArrayList<LogicalEdge> es : slice1.getLogicalGraph().getLogicalEdges().get(r1).get(proto1)) {
                for (LogicalEdge lge1 : es) {
                    String ifaceName = lge1.getEdge().getStart().getName();
                    LogicalEdge lge2 = lgeMap2.get(r2).get(proto1).get(ifaceName).get(lge1.getEdgeType());
                    if (lge1.getEdgeType() == EdgeType.IMPORT) {
                        SymbolicRoute vars1 = slice1.getLogicalGraph().getEnvironmentVars().get(lge1);
                        SymbolicRoute vars2 = slice2.getLogicalGraph().getEnvironmentVars().get(lge2);
                        BoolExpr aclIn1 = slice1.getIncomingAcls().get(lge1.getEdge());
                        BoolExpr aclIn2 = slice2.getIncomingAcls().get(lge2.getEdge());
                        if (aclIn1 == null) {
                            aclIn1 = ctx.mkBool(true);
                        }
                        if (aclIn2 == null) {
                            aclIn2 = ctx.mkBool(true);
                        }
                        equalIncomingAcls = ctx.mkAnd(equalIncomingAcls, ctx.mkEq(aclIn1, aclIn2));
                        boolean hasEnv1 = (vars1 != null);
                        boolean hasEnv2 = (vars2 != null);
                        if (hasEnv1 && hasEnv2) {
                            BoolExpr samePermitted = ctx.mkEq(vars1.getPermitted(), vars2.getPermitted());
                            // Set communities equal
                            BoolExpr equalComms = e1.mkTrue();
                            for (Map.Entry<CommunityVar, BoolExpr> entry : vars1.getCommunities().entrySet()) {
                                CommunityVar cvar = entry.getKey();
                                BoolExpr ce1 = entry.getValue();
                                BoolExpr ce2 = vars2.getCommunities().get(cvar);
                                if (ce2 != null) {
                                    equalComms = e1.mkAnd(equalComms, e1.mkEq(ce1, ce2));
                                }
                            }
                            // Set communities belonging to one but not the other
                            // off, but give a warning of the difference
                            BoolExpr unsetComms = e1.mkTrue();
                            for (Map.Entry<CommunityVar, BoolExpr> entry : vars1.getCommunities().entrySet()) {
                                CommunityVar cvar = entry.getKey();
                                BoolExpr ce1 = entry.getValue();
                                BoolExpr ce2 = vars2.getCommunities().get(cvar);
                                if (ce2 == null) {
                                    if (!communities.contains(cvar.getValue())) {
                                        communities.add(cvar.getValue());
                                    /* String msg =
                       String.format(
                           "Warning: community %s found for router %s but not %s.",
                           cvar.getValue(), conf1.getEnvName(), conf2.getEnvName());
                      System.out.println(msg); */
                                    }
                                    unsetComms = e1.mkAnd(unsetComms, e1.mkNot(ce1));
                                }
                            }
                            // Do the same thing for communities missing from the other side
                            for (Map.Entry<CommunityVar, BoolExpr> entry : vars2.getCommunities().entrySet()) {
                                CommunityVar cvar = entry.getKey();
                                BoolExpr ce2 = entry.getValue();
                                BoolExpr ce1 = vars1.getCommunities().get(cvar);
                                if (ce1 == null) {
                                    if (!communities.contains(cvar.getValue())) {
                                        communities.add(cvar.getValue());
                                    /* String msg =
                       String.format(
                           "Warning: community %s found for router %s but not %s.",
                           cvar.getValue(), conf2.getEnvName(), conf1.getEnvName());
                      System.out.println(msg); */
                                    }
                                    unsetComms = e1.mkAnd(unsetComms, e1.mkNot(ce2));
                                }
                            }
                            envRecords.add(vars1);
                            BoolExpr equalVars = slice1.equal(conf1, proto1, vars1, vars2, lge1, true);
                            equalEnvs = ctx.mkAnd(equalEnvs, unsetComms, samePermitted, equalVars, equalComms);
                        } else if (hasEnv1 || hasEnv2) {
                            System.out.println("Edge1: " + lge1);
                            System.out.println("Edge2: " + lge2);
                            throw new BatfishException("one had environment");
                        }
                    } else {
                        SymbolicRoute out1 = lge1.getSymbolicRecord();
                        SymbolicRoute out2 = lge2.getSymbolicRecord();
                        equalOutputs = ctx.mkAnd(equalOutputs, slice1.equal(conf1, proto1, out1, out2, lge1, false));
                    }
                }
            }
        }
        // check the stronger version of local equivalence
        if (strict) {
            for (SymbolicRoute env1 : envRecords) {
                for (SymbolicRoute env2 : envRecords) {
                    if (!env1.equals(env2)) {
                        BoolExpr c = e2.mkImplies(env1.getPermitted(), e2.mkNot(env2.getPermitted()));
                        e2.add(c);
                    }
                }
            }
        }
        // TODO: check both have same environment vars (e.g., screw up configuring peer connection)
        // Create assumptions
        BoolExpr validDest;
        validDest = ignoredDestinations(ctx, slice1, r1, conf1);
        validDest = ctx.mkAnd(validDest, ignoredDestinations(ctx, slice2, r2, conf2));
        SymbolicPacket p1 = slice1.getSymbolicPacket();
        SymbolicPacket p2 = slice2.getSymbolicPacket();
        BoolExpr equalPackets = p1.mkEqual(p2);
        BoolExpr assumptions = ctx.mkAnd(equalEnvs, equalPackets, validDest);
        // Create the requirements
        // Best choices should be the same
        BoolExpr required;
        if (strict) {
            SymbolicRoute best1 = e1.getMainSlice().getSymbolicDecisions().getBestNeighbor().get(conf1.getName());
            SymbolicRoute best2 = e2.getMainSlice().getSymbolicDecisions().getBestNeighbor().get(conf2.getName());
            // Just pick some protocol for defaults, shouldn't matter for best choice
            required = equal(e2, conf2, best1, best2);
        } else {
            // Forwarding decisions should be the sames
            Map<String, GraphEdge> geMap2 = interfaceMap(edges2);
            BoolExpr sameForwarding = ctx.mkBool(true);
            for (GraphEdge ge1 : edges1) {
                GraphEdge ge2 = geMap2.get(ge1.getStart().getName());
                BoolExpr dataFwd1 = slice1.getSymbolicDecisions().getDataForwarding().get(r1, ge1);
                BoolExpr dataFwd2 = slice2.getSymbolicDecisions().getDataForwarding().get(r2, ge2);
                assert (dataFwd1 != null);
                assert (dataFwd2 != null);
                sameForwarding = ctx.mkAnd(sameForwarding, ctx.mkEq(dataFwd1, dataFwd2));
            }
            // equalOutputs, equalIncomingAcls);
            required = ctx.mkAnd(sameForwarding);
        }
        e2.add(assumptions);
        e2.add(ctx.mkNot(required));
        VerificationResult res = e2.verify().getFirst();
        String name = r1 + "<-->" + r2;
        result.put(name, res);
    }
    return new SmtManyAnswerElement(result);
}
Also used : BoolExpr(com.microsoft.z3.BoolExpr) Configuration(org.batfish.datamodel.Configuration) TreeSet(java.util.TreeSet) SmtManyAnswerElement(org.batfish.symbolic.answers.SmtManyAnswerElement) Protocol(org.batfish.symbolic.Protocol) EnumMap(java.util.EnumMap) HashSet(java.util.HashSet) Context(com.microsoft.z3.Context) Pattern(java.util.regex.Pattern) BatfishException(org.batfish.common.BatfishException) TreeMap(java.util.TreeMap) CommunityVar(org.batfish.symbolic.CommunityVar) Graph(org.batfish.symbolic.Graph) HeaderQuestion(org.batfish.datamodel.questions.smt.HeaderQuestion) GraphEdge(org.batfish.symbolic.GraphEdge) Map(java.util.Map) EnumMap(java.util.EnumMap) SortedMap(java.util.SortedMap) HashMap(java.util.HashMap) TreeMap(java.util.TreeMap)

Example 84 with Context

use of com.google.cloud.dialogflow.v2.Context in project batfish by batfish.

the class NodJobChunkingTest method testChunking.

@Test
public void testChunking() {
    NodJob nodJob = getNodJob();
    Context z3Context = new Context();
    SmtInput smtInput = nodJob.computeSmtInput(System.currentTimeMillis(), z3Context);
    Map<OriginateVrf, Map<String, Long>> fieldConstraintsByOriginateVrf = nodJob.getOriginateVrfConstraints(z3Context, smtInput);
    assertThat(fieldConstraintsByOriginateVrf.entrySet(), hasSize(2));
    assertThat(fieldConstraintsByOriginateVrf, hasKey(_originateVrf1));
    assertThat(fieldConstraintsByOriginateVrf, hasKey(_originateVrf2));
    Map<String, Long> fieldConstraints1 = fieldConstraintsByOriginateVrf.get(_originateVrf1);
    Map<String, Long> fieldConstraints2 = fieldConstraintsByOriginateVrf.get(_originateVrf2);
    assertThat(fieldConstraints1, hasEntry(OriginateVrfInstrumentation.ORIGINATE_VRF_FIELD_NAME, new Long(0)));
    assertThat(fieldConstraints1, hasEntry(BasicHeaderField.SRC_IP.getName(), new Ip("1.0.0.0").asLong()));
    assertThat(fieldConstraints2, hasEntry(OriginateVrfInstrumentation.ORIGINATE_VRF_FIELD_NAME, new Long(1)));
    assertThat(fieldConstraints2, hasEntry(BasicHeaderField.SRC_IP.getName(), new Ip("2.0.0.0").asLong()));
}
Also used : Context(com.microsoft.z3.Context) Ip(org.batfish.datamodel.Ip) OriginateVrf(org.batfish.z3.state.OriginateVrf) Map(java.util.Map) ImmutableSortedMap(com.google.common.collect.ImmutableSortedMap) ImmutableMap(com.google.common.collect.ImmutableMap) SortedMap(java.util.SortedMap) Test(org.junit.Test)

Example 85 with Context

use of com.google.cloud.dialogflow.v2.Context in project batfish by batfish.

the class NodJobTest method testNotNattedUnsat.

/**
 * Test that traffic originating from 3.0.0.1 that is expected NOT to be NATed returns UNSAT when
 * we constrain to only allow NATed results.
 */
@Test
public void testNotNattedUnsat() {
    HeaderSpace headerSpace = new HeaderSpace();
    headerSpace.setSrcIps(ImmutableList.of(new IpWildcard("3.0.0.1")));
    NodJob nodJob = getNodJob(headerSpace, true);
    Context z3Context = new Context();
    Status status = nodJob.computeNodSat(System.currentTimeMillis(), z3Context);
    assertThat(status, equalTo(Status.UNSATISFIABLE));
}
Also used : IpWildcard(org.batfish.datamodel.IpWildcard) Context(com.microsoft.z3.Context) Status(com.microsoft.z3.Status) HeaderSpace(org.batfish.datamodel.HeaderSpace) Test(org.junit.Test)

Aggregations

Context (org.eclipse.jst.server.tomcat.core.internal.xml.server40.Context)58 Context (com.microsoft.z3.Context)39 CoreException (org.eclipse.core.runtime.CoreException)34 Context (org.osate.aadl2.Context)31 BoolExpr (com.microsoft.z3.BoolExpr)25 ArrayList (java.util.ArrayList)18 HashMap (java.util.HashMap)18 Test (org.junit.Test)18 ServerInstance (org.eclipse.jst.server.tomcat.core.internal.xml.server40.ServerInstance)17 List (java.util.List)16 Map (java.util.Map)15 Solver (com.microsoft.z3.Solver)13 File (java.io.File)13 IOException (java.io.IOException)11 IPath (org.eclipse.core.runtime.IPath)11 IStatus (org.eclipse.core.runtime.IStatus)11 Status (org.eclipse.core.runtime.Status)11 Factory (org.eclipse.jst.server.tomcat.core.internal.xml.Factory)11 Feature (org.osate.aadl2.Feature)11 FileNotFoundException (java.io.FileNotFoundException)10