use of com.microsoft.z3.BoolExpr in project batfish by batfish.
the class EncoderSlice method computeValidRange.
/*
* Convert a set of ranges and a packet field to a symbolic boolean expression
*/
private BoolExpr computeValidRange(Set<SubRange> ranges, ArithExpr field) {
BoolExpr acc = mkFalse();
for (SubRange range : ranges) {
int start = range.getStart();
int end = range.getEnd();
if (start == end) {
BoolExpr val = mkEq(field, mkInt(start));
acc = mkOr(acc, val);
} else {
BoolExpr val1 = mkGe(field, mkInt(start));
BoolExpr val2 = mkLe(field, mkInt(end));
acc = mkOr(acc, mkAnd(val1, val2));
}
}
return (BoolExpr) acc.simplify();
}
use of com.microsoft.z3.BoolExpr in project batfish by batfish.
the class EncoderSlice method addDataForwardingConstraints.
/*
* Constraints for the final data plane forwarding behavior.
* Forwarding occurs in the data plane if the control plane decides
* to use an interface, and no ACL blocks the packet:
*
* data_fwd(iface) = control_fwd(iface) and not acl(iface)
*/
private void addDataForwardingConstraints() {
for (Entry<String, List<GraphEdge>> entry : getGraph().getEdgeMap().entrySet()) {
String router = entry.getKey();
List<GraphEdge> edges = entry.getValue();
for (GraphEdge ge : edges) {
// setup forwarding for non-abstract edges
if (!ge.isAbstract()) {
BoolExpr fwd = mkFalse();
BoolExpr cForward = _symbolicDecisions.getControlForwarding().get(router, ge);
BoolExpr dForward = _symbolicDecisions.getDataForwarding().get(router, ge);
assert (cForward != null);
assert (dForward != null);
// out the current edge ge, the we use ge.
for (GraphEdge ge2 : getGraph().getEdgeMap().get(router)) {
if (ge2.isAbstract()) {
BoolExpr ctrlFwd = getSymbolicDecisions().getControlForwarding().get(router, ge2);
Graph.BgpSendType st = getGraph().peerType(ge2);
// If Route reflectors, then next hop based on ID
if (st == Graph.BgpSendType.TO_RR) {
SymbolicRoute record = getSymbolicDecisions().getBestNeighbor().get(router);
// adjust for iBGP in main slice
BoolExpr acc = mkFalse();
if (isMainSlice()) {
for (Entry<String, Integer> entry2 : getGraph().getOriginatorId().entrySet()) {
String r = entry2.getKey();
Integer id = entry2.getValue();
EncoderSlice s = _encoder.getSlice(r);
// Make sure
if (otherSliceHasEdge(s, router, ge)) {
BoolExpr outEdge = s.getSymbolicDecisions().getDataForwarding().get(router, ge);
acc = mkOr(acc, mkAnd(record.getClientId().checkIfValue(id), outEdge));
}
}
}
fwd = mkOr(fwd, mkAnd(ctrlFwd, acc));
} else {
// adjust for iBGP in main slice
if (isMainSlice()) {
EncoderSlice s = _encoder.getSlice(ge2.getPeer());
if (otherSliceHasEdge(s, router, ge)) {
BoolExpr outEdge = s.getSymbolicDecisions().getDataForwarding().get(router, ge);
fwd = mkOr(fwd, mkAnd(ctrlFwd, outEdge));
}
}
}
}
}
fwd = mkOr(fwd, cForward);
BoolExpr acl = _outboundAcls.get(ge);
if (acl == null) {
acl = mkTrue();
}
BoolExpr notBlocked = mkAnd(fwd, acl);
add(mkEq(notBlocked, dForward));
}
}
}
}
use of com.microsoft.z3.BoolExpr in project batfish by batfish.
the class EncoderSlice method computeACL.
/*
* Convert an Access Control List (ACL) to a symbolic boolean expression.
* The default action in an ACL is to deny all traffic.
*/
private BoolExpr computeACL(IpAccessList acl) {
// Check if there is an ACL first
if (acl == null) {
return mkTrue();
}
BoolExpr acc = mkFalse();
List<IpAccessListLine> lines = new ArrayList<>(acl.getLines());
Collections.reverse(lines);
for (IpAccessListLine l : lines) {
BoolExpr local = null;
if (l.getDstIps() != null) {
BoolExpr val = computeWildcardMatch(l.getDstIps(), _symbolicPacket.getDstIp());
val = l.getDstIps().isEmpty() ? mkTrue() : val;
local = val;
}
if (l.getSrcIps() != null) {
BoolExpr val = computeWildcardMatch(l.getSrcIps(), _symbolicPacket.getSrcIp());
val = l.getDstIps().isEmpty() ? mkTrue() : val;
local = (local == null ? val : mkAnd(local, val));
}
if (l.getDscps() != null && !l.getDscps().isEmpty()) {
throw new BatfishException("detected dscps");
}
if (l.getDstPorts() != null) {
BoolExpr val = computeValidRange(l.getDstPorts(), _symbolicPacket.getDstPort());
val = l.getDstPorts().isEmpty() ? mkTrue() : val;
local = (local == null ? val : mkAnd(local, val));
}
if (l.getSrcPorts() != null) {
BoolExpr val = computeValidRange(l.getSrcPorts(), _symbolicPacket.getSrcPort());
val = l.getSrcPorts().isEmpty() ? mkTrue() : val;
local = (local == null ? val : mkAnd(local, val));
}
if (l.getEcns() != null && !l.getEcns().isEmpty()) {
throw new BatfishException("detected ecns");
}
if (l.getTcpFlags() != null) {
BoolExpr val = computeTcpFlags(l.getTcpFlags());
val = l.getTcpFlags().isEmpty() ? mkTrue() : val;
local = (local == null ? val : mkAnd(local, val));
}
if (l.getFragmentOffsets() != null && !l.getFragmentOffsets().isEmpty()) {
throw new BatfishException("detected fragment offsets");
}
if (l.getIcmpCodes() != null) {
BoolExpr val = computeValidRange(l.getIcmpCodes(), _symbolicPacket.getIcmpCode());
val = l.getIcmpCodes().isEmpty() ? mkTrue() : val;
local = (local == null ? val : mkAnd(local, val));
}
if (l.getIcmpTypes() != null) {
BoolExpr val = computeValidRange(l.getIcmpTypes(), _symbolicPacket.getIcmpType());
val = l.getIcmpTypes().isEmpty() ? mkTrue() : val;
local = (local == null ? val : mkAnd(local, val));
}
if (l.getStates() != null && !l.getStates().isEmpty()) {
throw new BatfishException("detected states");
}
if (l.getIpProtocols() != null) {
BoolExpr val = computeIpProtocols(l.getIpProtocols());
val = l.getIpProtocols().isEmpty() ? mkTrue() : val;
local = (local == null ? val : mkAnd(local, val));
}
if (l.getNotDscps() != null && !l.getNotDscps().isEmpty()) {
throw new BatfishException("detected NOT dscps");
}
if (l.getNotDstIps() != null && !l.getNotDstIps().isEmpty()) {
throw new BatfishException("detected NOT dst ip");
}
if (l.getNotSrcIps() != null && !l.getNotSrcIps().isEmpty()) {
throw new BatfishException("detected NOT src ip");
}
if (l.getNotDstPorts() != null && !l.getNotDstPorts().isEmpty()) {
throw new BatfishException("detected NOT dst port");
}
if (l.getNotSrcPorts() != null && !l.getNotSrcPorts().isEmpty()) {
throw new BatfishException("detected NOT src port");
}
if (l.getNotEcns() != null && !l.getNotEcns().isEmpty()) {
throw new BatfishException("detected NOT ecns");
}
if (l.getNotIcmpCodes() != null && !l.getNotIcmpCodes().isEmpty()) {
throw new BatfishException("detected NOT icmp codes");
}
if (l.getNotIcmpTypes() != null && !l.getNotIcmpTypes().isEmpty()) {
throw new BatfishException("detected NOT icmp types");
}
if (l.getNotFragmentOffsets() != null && !l.getNotFragmentOffsets().isEmpty()) {
throw new BatfishException("detected NOT fragment offset");
}
if (l.getNotIpProtocols() != null && !l.getNotIpProtocols().isEmpty()) {
throw new BatfishException("detected NOT ip protocols");
}
if (local != null) {
BoolExpr ret;
if (l.getAction() == LineAction.ACCEPT) {
ret = mkTrue();
} else {
ret = mkFalse();
}
if (l.getNegate()) {
local = mkNot(local);
}
acc = mkIf(local, ret, acc);
}
}
return acc;
}
use of com.microsoft.z3.BoolExpr 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 com.microsoft.z3.BoolExpr in project batfish by batfish.
the class EncoderSlice method ipWildCardBound.
/*
* Create a boolean expression for a variable being withing an IpWildCard bound
*/
private BoolExpr ipWildCardBound(BitVecExpr field, IpWildcard wc) {
BitVecExpr ip = getCtx().mkBV(wc.getIp().asLong(), 32);
BitVecExpr mask = getCtx().mkBV(~wc.getWildcard().asLong(), 32);
return mkEq(getCtx().mkBVAND(field, mask), getCtx().mkBVAND(ip, mask));
}
Aggregations