use of org.batfish.symbolic.GraphEdge in project batfish by batfish.
the class Optimizations method computeRouterIdNeeded.
/*
* Check if we need to model the router ID
*/
private void computeRouterIdNeeded() {
_encoderSlice.getGraph().getConfigurations().forEach((router, conf) -> {
// If iBGP is used, and no multipath, then we need the routerId
boolean usesIbgp = false;
for (GraphEdge ge : _encoderSlice.getGraph().getEdgeMap().get(router)) {
if (_encoderSlice.getGraph().getIbgpNeighbors().get(ge) != null) {
usesIbgp = true;
break;
}
}
// If eBGP is used, and no multipath, then we need the routerId
boolean usesEbgp = _encoderSlice.getProtocols().get(router).contains(Protocol.BGP);
// check if multipath is used
boolean ibgpMultipath = false;
boolean ebgpMultipath = false;
BgpProcess p = conf.getDefaultVrf().getBgpProcess();
if (p != null) {
ibgpMultipath = p.getMultipathIbgp();
ebgpMultipath = p.getMultipathEbgp();
}
if ((usesIbgp && !ibgpMultipath) || (usesEbgp && !ebgpMultipath)) {
_needRouterId.add(router);
}
});
}
use of org.batfish.symbolic.GraphEdge in project batfish by batfish.
the class Optimizations method hasExportVariables.
/*
* Check if a graph edge will have export variables for a given protocol.
* This will happen when the edge's interface is used in the protocol
* and the other end of the interface is internal.
*/
private boolean hasExportVariables(GraphEdge e, Protocol proto) {
if (e.getEnd() != null) {
String peer = e.getPeer();
List<Protocol> peerProtocols = getProtocols().get(peer);
if (peerProtocols.contains(proto)) {
Configuration peerConf = _encoderSlice.getGraph().getConfigurations().get(peer);
GraphEdge other = _encoderSlice.getGraph().getOtherEnd().get(e);
if (_encoderSlice.getGraph().isEdgeUsed(peerConf, proto, other)) {
return true;
}
}
}
return false;
}
use of org.batfish.symbolic.GraphEdge in project batfish by batfish.
the class Optimizations method computeCanMergeImportExportVars.
/*
* Determine when import and export variables can be merged along an edge.
* This will be safe when there is no peer-specific import filter
*/
private void computeCanMergeImportExportVars() {
_encoderSlice.getGraph().getConfigurations().forEach((router, conf) -> {
Map<Protocol, List<GraphEdge>> map = new HashMap<>();
_sliceCanCombineImportExportVars.put(router, map);
for (Protocol proto : getProtocols().get(router)) {
List<GraphEdge> edges = new ArrayList<>();
if (Optimizations.ENABLE_IMPORT_EXPORT_MERGE_OPTIMIZATION && !proto.isConnected() && !proto.isStatic() && !proto.isOspf()) {
for (GraphEdge ge : _encoderSlice.getGraph().getEdgeMap().get(router)) {
// Don't merge when an abstract edge is used.
boolean safeMergeEdge = _encoderSlice.getGraph().isEdgeUsed(conf, proto, ge) && !ge.isAbstract();
// Don't merge when bgp internal/external can differ
boolean sameInternal = (ge.getPeer() == null) || (_needBgpInternal.contains(router) == _needBgpInternal.contains(ge.getPeer()));
// Check if there are any local modifications on import
boolean isPure = true;
RoutingPolicy pol = _encoderSlice.getGraph().findImportRoutingPolicy(router, proto, ge);
if (pol != null) {
isPure = false;
}
boolean noFailures = _encoderSlice.getEncoder().getFailures() == 0;
if (safeMergeEdge && sameInternal && isPure && noFailures && hasExportVariables(ge, proto)) {
edges.add(ge);
}
}
}
map.put(proto, edges);
}
});
}
use of org.batfish.symbolic.GraphEdge 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;
}
use of org.batfish.symbolic.GraphEdge 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;
}
Aggregations