use of org.batfish.symbolic.Protocol in project batfish by batfish.
the class EncoderSlice method addChoicePerProtocolConstraints.
/*
* Constraints that define a choice for a given protocol
* to be when a particular import is equal to the best choice.
* For example:
*
* choice_bgp_Serial0 = (import_Serial0 = best_bgp)
*/
private void addChoicePerProtocolConstraints() {
for (Entry<String, Configuration> entry : getGraph().getConfigurations().entrySet()) {
String router = entry.getKey();
Configuration conf = entry.getValue();
for (Protocol proto : getProtocols().get(router)) {
SymbolicRoute bestVars = _symbolicDecisions.getBestVars(_optimizations, router, proto);
assert (bestVars != null);
for (LogicalEdge e : collectAllImportLogicalEdges(router, conf, proto)) {
SymbolicRoute vars = correctVars(e);
BoolExpr choice = _symbolicDecisions.getChoiceVariables().get(router, proto, e);
assert (choice != null);
BoolExpr isBest = equal(conf, proto, bestVars, vars, e, false);
add(mkEq(choice, mkAnd(vars.getPermitted(), isBest)));
}
}
}
}
use of org.batfish.symbolic.Protocol in project batfish by batfish.
the class EncoderSlice method addTransferFunction.
/*
* Constraints that define relationships between various messages
* in the network. The same transfer function abstraction is used
* for both import and export constraints by relating different collections
* of variables.
*/
private void addTransferFunction() {
for (Entry<String, Configuration> entry : getGraph().getConfigurations().entrySet()) {
String router = entry.getKey();
Configuration conf = entry.getValue();
for (Protocol proto : getProtocols().get(router)) {
Boolean usedExport = false;
boolean hasEdge = false;
List<ArrayList<LogicalEdge>> les = _logicalGraph.getLogicalEdges().get(router, proto);
assert (les != null);
for (ArrayList<LogicalEdge> eList : les) {
for (LogicalEdge e : eList) {
GraphEdge ge = e.getEdge();
if (!getGraph().isEdgeUsed(conf, proto, ge)) {
continue;
}
hasEdge = true;
SymbolicRoute varsOther;
switch(e.getEdgeType()) {
case IMPORT:
varsOther = _logicalGraph.findOtherVars(e);
addImportConstraint(e, varsOther, conf, proto, ge, router);
break;
case EXPORT:
// OSPF export is tricky because it does not depend on being
// in the FIB. So it can come from either a redistributed route
// or another OSPF route. We always take the direct OSPF
SymbolicRoute ospfRedistribVars = null;
SymbolicRoute overallBest = null;
if (proto.isOspf()) {
varsOther = getBestNeighborPerProtocol(router, proto);
if (_ospfRedistributed.containsKey(router)) {
ospfRedistribVars = _ospfRedistributed.get(router);
overallBest = _symbolicDecisions.getBestNeighbor().get(router);
}
} else {
varsOther = _symbolicDecisions.getBestNeighbor().get(router);
}
Set<Prefix> originations = _originatedNetworks.get(router, proto);
assert varsOther != null;
assert originations != null;
addExportConstraint(e, varsOther, ospfRedistribVars, overallBest, conf, proto, ge, router, usedExport, originations);
usedExport = true;
break;
default:
break;
}
}
}
// If no edge used, then just set the best record to be false for that protocol
if (!hasEdge) {
SymbolicRoute protoBest;
if (_optimizations.getSliceHasSingleProtocol().contains(router)) {
protoBest = _symbolicDecisions.getBestNeighbor().get(router);
} else {
protoBest = _symbolicDecisions.getBestNeighborPerProtocol().get(router, proto);
}
assert protoBest != null;
add(mkNot(protoBest.getPermitted()));
}
}
}
}
use of org.batfish.symbolic.Protocol in project batfish by batfish.
the class EncoderSlice method addControlForwardingConstraints.
/*
* Constraints that define control-plane forwarding.
* If there is some valid import, then control plane forwarding
* will occur out an interface when this is the best choice.
* Otherwise, it will not occur.
*/
private void addControlForwardingConstraints() {
for (Entry<String, Configuration> entry : getGraph().getConfigurations().entrySet()) {
String router = entry.getKey();
Configuration conf = entry.getValue();
boolean someEdge = false;
SymbolicRoute best = _symbolicDecisions.getBestNeighbor().get(router);
Map<GraphEdge, BoolExpr> cfExprs = new HashMap<>();
Set<GraphEdge> constrained = new HashSet<>();
for (Protocol proto : getProtocols().get(router)) {
for (LogicalEdge e : collectAllImportLogicalEdges(router, conf, proto)) {
someEdge = true;
constrained.add(e.getEdge());
SymbolicRoute vars = correctVars(e);
BoolExpr choice = _symbolicDecisions.getChoiceVariables().get(router, proto, e);
BoolExpr isBest = mkAnd(choice, equal(conf, proto, best, vars, e, false));
GraphEdge ge = e.getEdge();
// Connected routes should only forward if not absorbed by interface
GraphEdge other = getGraph().getOtherEnd().get(ge);
BoolExpr connectedWillSend;
if (other == null || getGraph().isHost(ge.getPeer())) {
Ip ip = ge.getStart().getAddress().getIp();
BitVecExpr val = getCtx().mkBV(ip.asLong(), 32);
connectedWillSend = mkNot(mkEq(_symbolicPacket.getDstIp(), val));
} else {
Ip ip = other.getStart().getAddress().getIp();
BitVecExpr val = getCtx().mkBV(ip.asLong(), 32);
connectedWillSend = mkEq(_symbolicPacket.getDstIp(), val);
}
BoolExpr canSend = (proto.isConnected() ? connectedWillSend : mkTrue());
BoolExpr sends = mkAnd(canSend, isBest);
BoolExpr cForward = _symbolicDecisions.getControlForwarding().get(router, ge);
assert (cForward != null);
add(mkImplies(sends, cForward));
// record the negation as well
cfExprs.merge(ge, sends, (a, b) -> mkOr(a, b));
}
}
// For edges that are never used, we constraint them to not be forwarded out of
for (GraphEdge ge : getGraph().getEdgeMap().get(router)) {
if (!constrained.contains(ge)) {
BoolExpr cForward = _symbolicDecisions.getControlForwarding().get(router, ge);
assert (cForward != null);
add(mkNot(cForward));
}
}
// Handle the case that the router has no protocol running
if (!someEdge) {
for (GraphEdge ge : getGraph().getEdgeMap().get(router)) {
BoolExpr cForward = _symbolicDecisions.getControlForwarding().get(router, ge);
assert (cForward != null);
add(mkNot(cForward));
}
} else {
// If no best route, then no forwarding
Map<Protocol, List<ArrayList<LogicalEdge>>> map = _logicalGraph.getLogicalEdges().get(router);
Set<GraphEdge> seen = new HashSet<>();
for (List<ArrayList<LogicalEdge>> eList : map.values()) {
for (ArrayList<LogicalEdge> edges : eList) {
for (LogicalEdge le : edges) {
GraphEdge ge = le.getEdge();
if (seen.contains(ge)) {
continue;
}
seen.add(ge);
BoolExpr expr = cfExprs.get(ge);
BoolExpr cForward = _symbolicDecisions.getControlForwarding().get(router, ge);
assert (cForward != null);
if (expr != null) {
add(mkImplies(mkNot(expr), mkNot(cForward)));
} else {
add(mkNot(cForward));
}
}
}
}
}
}
}
use of org.batfish.symbolic.Protocol in project batfish by batfish.
the class EncoderSlice method initRedistributionProtocols.
/*
* Initialize the map of redistributed protocols.
*/
private void initRedistributionProtocols() {
for (Entry<String, Configuration> entry : getGraph().getConfigurations().entrySet()) {
String router = entry.getKey();
Configuration conf = entry.getValue();
for (Protocol proto : getProtocols().get(router)) {
Set<Protocol> redistributed = new HashSet<>();
redistributed.add(proto);
_logicalGraph.getRedistributedProtocols().put(router, proto, redistributed);
RoutingPolicy pol = Graph.findCommonRoutingPolicy(conf, proto);
if (pol != null) {
Set<Protocol> ps = getGraph().findRedistributedProtocols(conf, pol, proto);
for (Protocol p : ps) {
// Make sure there is actually a routing process for the other protocol
// For example, it might get sliced away if not relevant
boolean isProto = getProtocols().get(router).contains(p);
if (isProto) {
redistributed.add(p);
}
}
}
}
}
}
use of org.batfish.symbolic.Protocol in project batfish by batfish.
the class EncoderSlice method addChoiceVariables.
/*
* Initialize variables representing if a router chooses
* to use a particular interface for control-plane forwarding
*/
private void addChoiceVariables() {
for (String router : getGraph().getRouters()) {
Configuration conf = getGraph().getConfigurations().get(router);
Map<Protocol, Map<LogicalEdge, BoolExpr>> map = new HashMap<>();
_symbolicDecisions.getChoiceVariables().put(router, map);
for (Protocol proto : getProtocols().get(router)) {
Map<LogicalEdge, BoolExpr> edgeMap = new HashMap<>();
map.put(proto, edgeMap);
for (LogicalEdge e : collectAllImportLogicalEdges(router, conf, proto)) {
String chName = e.getSymbolicRecord().getName() + "_choice";
BoolExpr choiceVar = getCtx().mkBoolConst(chName);
getAllVariables().put(choiceVar.toString(), choiceVar);
edgeMap.put(e, choiceVar);
}
}
}
}
Aggregations