use of org.kie.workbench.common.dmn.api.definition.v1_1.Context 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 org.kie.workbench.common.dmn.api.definition.v1_1.Context 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 org.kie.workbench.common.dmn.api.definition.v1_1.Context in project batfish by batfish.
the class PropertyChecker method addEnvironmentConstraints.
private void addEnvironmentConstraints(Encoder enc, EnvironmentType t) {
LogicalGraph lg = enc.getMainSlice().getLogicalGraph();
Context ctx = enc.getCtx();
switch(t) {
case ANY:
break;
case NONE:
for (SymbolicRoute vars : lg.getEnvironmentVars().values()) {
enc.add(ctx.mkNot(vars.getPermitted()));
}
break;
case SANE:
for (SymbolicRoute vars : lg.getEnvironmentVars().values()) {
enc.add(ctx.mkLe(vars.getMetric(), ctx.mkInt(50)));
}
break;
default:
break;
}
}
use of org.kie.workbench.common.dmn.api.definition.v1_1.Context 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 org.kie.workbench.common.dmn.api.definition.v1_1.Context in project batfish by batfish.
the class NodFirstUnsatJob method call.
@Override
public NodFirstUnsatResult<KeyT, ResultT> call() {
long startTime = System.currentTimeMillis();
try (Context ctx = new Context()) {
ReachabilityProgram baseProgram = _query.synthesizeBaseProgram(_synthesizer);
ReachabilityProgram queryProgram = _query.getReachabilityProgram(_synthesizer.getInput());
NodProgram program = new NodProgram(ctx, baseProgram, queryProgram);
Fixedpoint fix = mkFixedpoint(program, false);
KeyT key = _query.getKey();
for (int queryNum = 0; queryNum < program.getQueries().size(); queryNum++) {
BoolExpr query = program.getQueries().get(queryNum);
Status status = fix.query(query);
switch(status) {
case SATISFIABLE:
break;
case UNKNOWN:
return new NodFirstUnsatResult<>(startTime, _logger.getHistory(), new BatfishException("Query satisfiability unknown"));
case UNSATISFIABLE:
return new NodFirstUnsatResult<>(key, queryNum, _query.getResultsByQueryIndex().get(queryNum), _logger.getHistory(), startTime);
default:
return new NodFirstUnsatResult<>(startTime, _logger.getHistory(), new BatfishException("invalid status"));
}
}
return new NodFirstUnsatResult<>(key, null, null, _logger.getHistory(), startTime);
} catch (Z3Exception e) {
return new NodFirstUnsatResult<>(startTime, _logger.getHistory(), new BatfishException("Error running NoD on concatenated data plane", e));
}
}
Aggregations