use of org.batfish.symbolic.Protocol in project batfish by batfish.
the class EncoderSlice method addHistoryConstraints.
/*
* Constraints that ensure the protocol choosen by the best choice is accurate.
* This is important because redistribution depends on the protocol used
* in the actual FIB.
*/
private void addHistoryConstraints() {
for (Entry<String, SymbolicRoute> entry : _symbolicDecisions.getBestNeighbor().entrySet()) {
String router = entry.getKey();
SymbolicRoute vars = entry.getValue();
if (_optimizations.getSliceHasSingleProtocol().contains(router)) {
Protocol proto = getProtocols().get(router).get(0);
add(mkImplies(vars.getPermitted(), vars.getProtocolHistory().checkIfValue(proto)));
}
}
}
use of org.batfish.symbolic.Protocol in project batfish by batfish.
the class EncoderSlice method addBestOverallConstraints.
/*
* Constraints that specify that the best choice is
* better than all alternatives, and is at least one of the choices:
*
* (1) if no options are valid, then best is not valid
* (2) if some option is valid, then we have the following:
*
* (best <= best_prot1) and ... and (best <= best_protn)
* (best = best_prot1) or ... or (best = best_protn)
*/
private void addBestOverallConstraints() {
for (Entry<String, Configuration> entry : getGraph().getConfigurations().entrySet()) {
String router = entry.getKey();
Configuration conf = entry.getValue();
// These constraints will be added at the protocol-level when a single protocol
if (!_optimizations.getSliceHasSingleProtocol().contains(router)) {
boolean someProto = false;
BoolExpr acc = null;
BoolExpr somePermitted = null;
SymbolicRoute best = _symbolicDecisions.getBestNeighbor().get(router);
for (Protocol proto : getProtocols().get(router)) {
someProto = true;
SymbolicRoute bestVars = _symbolicDecisions.getBestVars(_optimizations, router, proto);
assert (bestVars != null);
if (somePermitted == null) {
somePermitted = bestVars.getPermitted();
} else {
somePermitted = mkOr(somePermitted, bestVars.getPermitted());
}
BoolExpr val = mkAnd(bestVars.getPermitted(), equal(conf, proto, best, bestVars, null, true));
if (acc == null) {
acc = val;
} else {
acc = mkOr(acc, val);
}
add(mkImplies(bestVars.getPermitted(), greaterOrEqual(conf, proto, best, bestVars, null)));
}
if (someProto) {
if (acc != null) {
add(mkEq(somePermitted, best.getPermitted()));
add(mkImplies(somePermitted, acc));
}
} else {
add(mkNot(best.getPermitted()));
}
}
}
}
use of org.batfish.symbolic.Protocol in project batfish by batfish.
the class Optimizations method computeCanMergeExportVars.
/*
* Determines when we can merge export variables into a single copy.
* This will be safe when there is no peer-specific export filter.
*/
private void computeCanMergeExportVars() {
Graph g = _encoderSlice.getGraph();
HeaderQuestion q = _encoderSlice.getEncoder().getQuestion();
boolean noFailures = q.getFailures() == 0;
_encoderSlice.getGraph().getConfigurations().forEach((router, conf) -> {
HashMap<Protocol, Boolean> map = new HashMap<>();
_sliceCanKeepSingleExportVar.put(router, map);
// the neighbor already being the root of the tree.
for (Protocol proto : getProtocols().get(router)) {
if (proto.isConnected() || proto.isStatic()) {
map.put(proto, noFailures && Optimizations.ENABLE_EXPORT_MERGE_OPTIMIZATION);
} else if (proto.isOspf()) {
// Ensure all interfaces are active
boolean allIfacesActive = true;
for (GraphEdge edge : g.getEdgeMap().get(router)) {
if (g.isEdgeUsed(conf, proto, edge)) {
Interface iface = edge.getStart();
allIfacesActive = allIfacesActive && g.isInterfaceActive(proto, iface);
}
}
// Ensure single area for this router
Set<Long> areas = _encoderSlice.getGraph().getAreaIds().get(router);
boolean singleArea = areas.size() <= 1;
map.put(proto, noFailures && allIfacesActive && singleArea && ENABLE_EXPORT_MERGE_OPTIMIZATION);
} else if (proto.isBgp()) {
boolean acc = true;
BgpProcess p = conf.getDefaultVrf().getBgpProcess();
for (Map.Entry<Prefix, BgpNeighbor> e : p.getNeighbors().entrySet()) {
BgpNeighbor n = e.getValue();
// If iBGP used, then don't merge
if (n.getLocalAs().equals(n.getRemoteAs())) {
acc = false;
break;
}
// If not the default export policy, then don't merge
if (!isDefaultBgpExport(conf, n)) {
acc = false;
break;
}
}
map.put(proto, noFailures && acc && ENABLE_EXPORT_MERGE_OPTIMIZATION);
} else {
throw new BatfishException("Error: unkown protocol: " + proto.name());
}
}
});
}
use of org.batfish.symbolic.Protocol in project batfish by batfish.
the class Optimizations method computeKeepAdminDistance.
/*
* Check if administrative distance needs to be kept for
* every single message. If it is never set with a custom
* value, then it can be inferred for the best choice based
* on the default protocol value.
*/
private boolean computeKeepAdminDistance() {
if (!Optimizations.ENABLE_SLICING_OPTIMIZATION) {
return true;
}
AstVisitor v = new AstVisitor();
Boolean[] val = new Boolean[1];
val[0] = false;
_encoderSlice.getGraph().getConfigurations().forEach((router, conf) -> conf.getRoutingPolicies().forEach((name, pol) -> v.visit(conf, pol.getStatements(), stmt -> {
if (stmt instanceof SetOspfMetricType) {
val[0] = true;
}
}, expr -> {
})));
return val[0];
}
use of org.batfish.symbolic.Protocol 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