use of org.batfish.datamodel.Flow in project batfish by batfish.
the class CounterExample method buildFlowHistoryDiff.
/*
* Create a trace-based counterexample demonstrating
* the difference between two networks on a single packet.
*/
FlowHistory buildFlowHistoryDiff(String testRigName, Collection<String> sourceRouters, Encoder enc, Encoder enc2, Map<String, BoolExpr> reach, Map<String, BoolExpr> reach2) {
FlowHistory fh = new FlowHistory();
assert (reach2 != null);
for (String source : sourceRouters) {
BoolExpr sourceVar1 = reach.get(source);
BoolExpr sourceVar2 = reach2.get(source);
String val1 = evaluate(sourceVar1);
String val2 = evaluate(sourceVar2);
if (!Objects.equals(val1, val2)) {
Tuple<Flow, FlowTrace> diff = buildFlowTrace(enc, source);
Tuple<Flow, FlowTrace> base = buildFlowTrace(enc2, source);
SortedSet<Edge> failedLinksDiff = buildFailedLinks(enc);
SortedSet<Edge> failedLinksBase = buildFailedLinks(enc2);
SortedSet<BgpAdvertisement> envRoutesDiff = buildEnvRoutingTable(enc);
SortedSet<BgpAdvertisement> envRoutesBase = buildEnvRoutingTable(enc2);
Environment baseEnv = new Environment("BASE", testRigName, failedLinksBase, null, null, null, null, envRoutesBase);
Environment failedEnv = new Environment("DELTA", testRigName, failedLinksDiff, null, null, null, null, envRoutesDiff);
fh.addFlowTrace(base.getFirst(), "BASE", baseEnv, base.getSecond());
fh.addFlowTrace(diff.getFirst(), "DELTA", failedEnv, diff.getSecond());
}
}
return fh;
}
use of org.batfish.datamodel.Flow in project batfish by batfish.
the class CounterExample method buildEnvRoutingTable.
SortedSet<BgpAdvertisement> buildEnvRoutingTable(Encoder enc) {
SortedSet<BgpAdvertisement> routes = new TreeSet<>();
EncoderSlice slice = enc.getMainSlice();
LogicalGraph lg = slice.getLogicalGraph();
for (Entry<LogicalEdge, SymbolicRoute> entry : lg.getEnvironmentVars().entrySet()) {
LogicalEdge lge = entry.getKey();
SymbolicRoute record = entry.getValue();
// If there is an external advertisement
if (boolVal(record.getPermitted())) {
// If we actually use it
GraphEdge ge = lge.getEdge();
String router = ge.getRouter();
SymbolicDecisions decisions = slice.getSymbolicDecisions();
BoolExpr ctrFwd = decisions.getControlForwarding().get(router, ge);
assert ctrFwd != null;
if (boolVal(ctrFwd)) {
SymbolicRoute r = decisions.getBestNeighbor().get(router);
SymbolicPacket pkt = slice.getSymbolicPacket();
Flow f = buildFlow(pkt, router);
Prefix pfx = buildPrefix(r, f);
int pathLength = intVal(r.getMetric());
// Create dummy information
BgpNeighbor n = slice.getGraph().getEbgpNeighbors().get(lge.getEdge());
String srcNode = "as" + n.getRemoteAs();
Ip zeroIp = new Ip(0);
Ip dstIp = n.getLocalIp();
// Recover AS path
List<SortedSet<Integer>> asSets = new ArrayList<>();
for (int i = 0; i < pathLength; i++) {
SortedSet<Integer> asSet = new TreeSet<>();
asSet.add(-1);
asSets.add(asSet);
}
AsPath path = new AsPath(asSets);
// Recover communities
SortedSet<Long> communities = new TreeSet<>();
for (Entry<CommunityVar, BoolExpr> entry2 : r.getCommunities().entrySet()) {
CommunityVar cvar = entry2.getKey();
BoolExpr expr = entry2.getValue();
if (cvar.getType() == Type.EXACT && boolVal(expr)) {
communities.add(cvar.asLong());
}
}
BgpAdvertisement adv = new BgpAdvertisement(BgpAdvertisementType.EBGP_RECEIVED, pfx, zeroIp, srcNode, "default", zeroIp, router, "default", dstIp, RoutingProtocol.BGP, OriginType.EGP, 100, 80, zeroIp, path, communities, new TreeSet<>(), 0);
routes.add(adv);
}
}
}
return routes;
}
use of org.batfish.datamodel.Flow in project batfish by batfish.
the class CounterExample method buildFlow.
Flow buildFlow(SymbolicPacket pkt, String router) {
Ip srcIp = ipVal(pkt.getSrcIp());
Ip dstIp = ipVal(pkt.getDstIp());
Integer srcPort = intVal(pkt.getSrcPort());
Integer dstPort = intVal(pkt.getDstPort());
IpProtocol ipProtocol = IpProtocol.fromNumber(intVal(pkt.getIpProtocol()));
Integer icmpType = intVal(pkt.getIcmpType());
Integer icmpCode = intVal(pkt.getIcmpCode());
Integer tcpFlagsCwr = isTrue(pkt.getTcpCwr()) ? 0 : 1;
Integer tcpFlagsEce = isTrue(pkt.getTcpEce()) ? 0 : 1;
Integer tcpFlagsUrg = isTrue(pkt.getTcpUrg()) ? 0 : 1;
Integer tcpFlagsAck = isTrue(pkt.getTcpAck()) ? 0 : 1;
Integer tcpFlagsPsh = isTrue(pkt.getTcpPsh()) ? 0 : 1;
Integer tcpFlagsRst = isTrue(pkt.getTcpRst()) ? 0 : 1;
Integer tcpFlagsSyn = isTrue(pkt.getTcpSyn()) ? 0 : 1;
Integer tcpFlagsFin = isTrue(pkt.getTcpFin()) ? 0 : 1;
Flow.Builder b = new Flow.Builder();
b.setIngressNode(router);
b.setSrcIp(srcIp);
b.setDstIp(dstIp);
b.setSrcPort(srcPort);
b.setDstPort(dstPort);
b.setIpProtocol(ipProtocol);
b.setIcmpType(icmpType);
b.setIcmpCode(icmpCode);
b.setTcpFlagsCwr(tcpFlagsCwr);
b.setTcpFlagsEce(tcpFlagsEce);
b.setTcpFlagsUrg(tcpFlagsUrg);
b.setTcpFlagsAck(tcpFlagsAck);
b.setTcpFlagsPsh(tcpFlagsPsh);
b.setTcpFlagsRst(tcpFlagsRst);
b.setTcpFlagsSyn(tcpFlagsSyn);
b.setTcpFlagsFin(tcpFlagsFin);
b.setTag("SMT");
return b.build();
}
use of org.batfish.datamodel.Flow in project batfish by batfish.
the class CounterExample method buildRoute.
/*
* Create a route from a graph edge
*/
String buildRoute(EncoderSlice slice, GraphEdge ge) {
String router = ge.getRouter();
SymbolicDecisions decisions = slice.getSymbolicDecisions();
SymbolicRoute r = decisions.getBestNeighbor().get(router);
SymbolicPacket pkt = slice.getSymbolicPacket();
Flow f = buildFlow(pkt, router);
Prefix pfx = buildPrefix(r, f);
Protocol proto = buildProcotol(r, slice, router);
return buildRoute(pfx, proto, ge);
}
use of org.batfish.datamodel.Flow in project batfish by batfish.
the class PropertyChecker method checkDeterminism.
/*
* Check if there exist multiple stable solutions to the network.
* If so, reports the forwarding differences between the two cases.
*/
public AnswerElement checkDeterminism(HeaderQuestion q) {
Graph graph = new Graph(_batfish);
Encoder enc1 = new Encoder(_settings, graph, q);
Encoder enc2 = new Encoder(enc1, graph, q);
enc1.computeEncoding();
enc2.computeEncoding();
addEnvironmentConstraints(enc1, q.getBaseEnvironmentType());
BoolExpr relatedFailures = relateFailures(enc1, enc2);
BoolExpr relatedEnvs = relateEnvironments(enc1, enc2);
BoolExpr relatedPkts = relatePackets(enc1, enc2);
BoolExpr related = enc1.mkAnd(relatedFailures, relatedEnvs, relatedPkts);
BoolExpr required = enc1.mkTrue();
for (GraphEdge ge : graph.getAllRealEdges()) {
SymbolicDecisions d1 = enc1.getMainSlice().getSymbolicDecisions();
SymbolicDecisions d2 = enc2.getMainSlice().getSymbolicDecisions();
BoolExpr dataFwd1 = d1.getDataForwarding().get(ge.getRouter(), ge);
BoolExpr dataFwd2 = d2.getDataForwarding().get(ge.getRouter(), ge);
assert dataFwd1 != null;
assert dataFwd2 != null;
required = enc1.mkAnd(required, enc1.mkEq(dataFwd1, dataFwd2));
}
enc1.add(related);
enc1.add(enc1.mkNot(required));
Tuple<VerificationResult, Model> tup = enc1.verify();
VerificationResult res = tup.getFirst();
Model model = tup.getSecond();
SortedSet<String> case1 = null;
SortedSet<String> case2 = null;
Flow flow = null;
CounterExample ce = new CounterExample(model);
if (!res.isVerified()) {
case1 = new TreeSet<>();
case2 = new TreeSet<>();
flow = ce.buildFlow(enc1.getMainSlice().getSymbolicPacket(), "(none)");
for (GraphEdge ge : graph.getAllRealEdges()) {
SymbolicDecisions d1 = enc1.getMainSlice().getSymbolicDecisions();
SymbolicDecisions d2 = enc2.getMainSlice().getSymbolicDecisions();
BoolExpr dataFwd1 = d1.getDataForwarding().get(ge.getRouter(), ge);
BoolExpr dataFwd2 = d2.getDataForwarding().get(ge.getRouter(), ge);
assert dataFwd1 != null;
assert dataFwd2 != null;
boolean b1 = ce.boolVal(dataFwd1);
boolean b2 = ce.boolVal(dataFwd2);
if (b1 != b2) {
if (b1) {
String route = ce.buildRoute(enc1.getMainSlice(), ge);
String msg = ge + " -- " + route;
case1.add(msg);
}
if (b2) {
String route = ce.buildRoute(enc2.getMainSlice(), ge);
String msg = ge + " -- " + route;
case2.add(msg);
}
}
}
}
// Ensure canonical order
boolean less = (case1 == null || (case1.first().compareTo(case2.first()) < 0));
if (less) {
return new SmtDeterminismAnswerElement(flow, case1, case2);
} else {
return new SmtDeterminismAnswerElement(flow, case2, case1);
}
}
Aggregations