use of com.microsoft.z3.BoolExpr in project batfish by batfish.
the class PropertyAdder method instrumentLoop.
/*
* Instruments the network to check if a router will be part
* of a routing loop.
*/
BoolExpr instrumentLoop(String router) {
Context ctx = _encoderSlice.getCtx();
Solver solver = _encoderSlice.getSolver();
String sliceName = _encoderSlice.getSliceName();
// Add on-loop variables to track a loop
Map<String, BoolExpr> onLoop = new HashMap<>();
Graph graph = _encoderSlice.getGraph();
for (String r : graph.getRouters()) {
String name = _encoderSlice.getEncoder().getId() + "_" + sliceName + "_on-loop_" + router + "_" + r;
BoolExpr var = ctx.mkBoolConst(name);
onLoop.put(r, var);
_encoderSlice.getAllVariables().put(var.toString(), var);
}
for (Entry<String, List<GraphEdge>> entry : graph.getEdgeMap().entrySet()) {
String r = entry.getKey();
List<GraphEdge> edges = entry.getValue();
BoolExpr var = onLoop.get(r);
BoolExpr acc = ctx.mkBool(false);
for (GraphEdge edge : edges) {
if (!edge.isAbstract()) {
BoolExpr fwd = _encoderSlice.getForwardsAcross().get(r, edge);
String peer = edge.getPeer();
if (peer != null) {
if (peer.equals(router)) {
// If next hop is static route router, then on loop
acc = ctx.mkOr(acc, fwd);
} else {
// Otherwise check if next hop also is on the loop
BoolExpr peerOnLoop = onLoop.get(peer);
acc = ctx.mkOr(acc, ctx.mkAnd(fwd, peerOnLoop));
}
}
}
}
solver.add(ctx.mkEq(var, acc));
}
return onLoop.get(router);
}
use of com.microsoft.z3.BoolExpr in project batfish by batfish.
the class PropertyChecker method checkRoutingLoop.
/*
* Checks for routing loops in the network. For efficiency reasons,
* we only check for loops with routers that use static routes since
* these can override the usual loop-prevention mechanisms.
*/
public AnswerElement checkRoutingLoop(HeaderQuestion q) {
Graph graph = new Graph(_batfish);
// Collect all relevant destinations
List<Prefix> prefixes = new ArrayList<>();
graph.getStaticRoutes().forEach((router, ifaceName, srs) -> {
for (StaticRoute sr : srs) {
prefixes.add(sr.getNetwork());
}
});
SortedSet<IpWildcard> pfxs = new TreeSet<>();
for (Prefix prefix : prefixes) {
pfxs.add(new IpWildcard(prefix));
}
q.getHeaderSpace().setDstIps(pfxs);
// Collect all routers that use static routes as a
// potential node along a loop
List<String> routers = new ArrayList<>();
for (Entry<String, Configuration> entry : graph.getConfigurations().entrySet()) {
String router = entry.getKey();
Configuration conf = entry.getValue();
if (conf.getDefaultVrf().getStaticRoutes().size() > 0) {
routers.add(router);
}
}
Encoder enc = new Encoder(_settings, graph, q);
enc.computeEncoding();
Context ctx = enc.getCtx();
EncoderSlice slice = enc.getMainSlice();
PropertyAdder pa = new PropertyAdder(slice);
BoolExpr someLoop = ctx.mkBool(false);
for (String router : routers) {
BoolExpr hasLoop = pa.instrumentLoop(router);
someLoop = ctx.mkOr(someLoop, hasLoop);
}
enc.add(someLoop);
VerificationResult result = enc.verify().getFirst();
return new SmtOneAnswerElement(result);
}
use of com.microsoft.z3.BoolExpr in project batfish by batfish.
the class PropertyChecker method relateFailures.
private BoolExpr relateFailures(Encoder enc1, Encoder enc2) {
BoolExpr related = enc1.mkTrue();
for (GraphEdge ge : enc1.getMainSlice().getGraph().getAllRealEdges()) {
ArithExpr a1 = enc1.getSymbolicFailures().getFailedVariable(ge);
ArithExpr a2 = enc2.getSymbolicFailures().getFailedVariable(ge);
assert a1 != null;
assert a2 != null;
related = enc1.mkEq(a1, a2);
}
return related;
}
use of com.microsoft.z3.BoolExpr in project batfish by batfish.
the class PropertyChecker method checkBlackHole.
/*
* Compute if there can ever be a black hole for routers that are
* not at the edge of the network. This is almost certainly a bug.
*/
public AnswerElement checkBlackHole(HeaderQuestion q) {
Graph graph = new Graph(_batfish);
Encoder enc = new Encoder(_settings, graph, q);
enc.computeEncoding();
Context ctx = enc.getCtx();
EncoderSlice slice = enc.getMainSlice();
// Collect routers that have no host/environment edge
List<String> toCheck = new ArrayList<>();
for (Entry<String, List<GraphEdge>> entry : graph.getEdgeMap().entrySet()) {
String router = entry.getKey();
List<GraphEdge> edges = entry.getValue();
boolean check = true;
for (GraphEdge edge : edges) {
if (edge.getEnd() == null) {
check = false;
break;
}
}
if (check) {
toCheck.add(router);
}
}
// Ensure the router never receives traffic and then drops the traffic
BoolExpr someBlackHole = ctx.mkBool(false);
for (String router : toCheck) {
Map<GraphEdge, BoolExpr> edges = slice.getSymbolicDecisions().getDataForwarding().get(router);
BoolExpr doesNotFwd = ctx.mkBool(true);
for (Map.Entry<GraphEdge, BoolExpr> entry : edges.entrySet()) {
BoolExpr dataFwd = entry.getValue();
doesNotFwd = ctx.mkAnd(doesNotFwd, ctx.mkNot(dataFwd));
}
BoolExpr isFwdTo = ctx.mkBool(false);
Set<String> neighbors = graph.getNeighbors().get(router);
for (String n : neighbors) {
for (Map.Entry<GraphEdge, BoolExpr> entry : slice.getSymbolicDecisions().getDataForwarding().get(n).entrySet()) {
GraphEdge ge = entry.getKey();
BoolExpr fwd = entry.getValue();
if (router.equals(ge.getPeer())) {
isFwdTo = ctx.mkOr(isFwdTo, fwd);
}
}
}
someBlackHole = ctx.mkOr(someBlackHole, ctx.mkAnd(isFwdTo, doesNotFwd));
}
enc.add(someBlackHole);
VerificationResult result = enc.verify().getFirst();
return new SmtOneAnswerElement(result);
}
use of com.microsoft.z3.BoolExpr in project batfish by batfish.
the class PropertyChecker method ignoredDestinations.
/*
* Creates a boolean variable representing destinations we don't want
* to consider due to local differences.
*/
private BoolExpr ignoredDestinations(Context ctx, EncoderSlice e1, String r1, Configuration conf1) {
BoolExpr validDest = ctx.mkBool(true);
for (Protocol proto1 : e1.getProtocols().get(r1)) {
Set<Prefix> prefixes = Graph.getOriginatedNetworks(conf1, proto1);
BoolExpr dest = e1.relevantOrigination(prefixes);
validDest = ctx.mkAnd(validDest, ctx.mkNot(dest));
}
return validDest;
}
Aggregations