use of org.batfish.datamodel.Prefix in project batfish by batfish.
the class CounterExample method buildFlowTrace.
/*
* Build flow information for a given hop along a path
*/
Tuple<Flow, FlowTrace> buildFlowTrace(Encoder enc, String router) {
EncoderSlice slice = enc.getMainSlice();
SymbolicPacket pkt = slice.getSymbolicPacket();
SymbolicDecisions decisions = slice.getSymbolicDecisions();
Flow f = buildFlow(pkt, router);
SortedSet<String> visited = new TreeSet<>();
List<FlowTraceHop> hops = new ArrayList<>();
String current = router;
while (true) {
visited.add(current);
// Get the forwarding variables
Map<GraphEdge, BoolExpr> dfwd = decisions.getDataForwarding().get(current);
Map<GraphEdge, BoolExpr> cfwd = decisions.getControlForwarding().get(current);
Map<GraphEdge, BoolExpr> across = enc.getMainSlice().getForwardsAcross().get(current);
// Find the route used
SymbolicRoute r = decisions.getBestNeighbor().get(current);
Protocol proto = buildProcotol(r, slice, current);
Prefix pfx = buildPrefix(r, f);
// pick the next router
boolean found = false;
for (Entry<GraphEdge, BoolExpr> entry : dfwd.entrySet()) {
GraphEdge ge = entry.getKey();
BoolExpr dexpr = entry.getValue();
BoolExpr cexpr = cfwd.get(ge);
BoolExpr aexpr = across.get(ge);
String route = buildRoute(pfx, proto, ge);
if (isTrue(dexpr)) {
hops.add(buildFlowTraceHop(ge, route));
if (ge.getPeer() != null && visited.contains(ge.getPeer())) {
FlowTrace ft = new FlowTrace(FlowDisposition.LOOP, hops, "LOOP");
return new Tuple<>(f, ft);
}
if (isFalse(aexpr)) {
Interface i = ge.getEnd();
IpAccessList acl = i.getIncomingFilter();
FilterResult fr = acl.filter(f);
String line = "default deny";
if (fr.getMatchLine() != null) {
line = acl.getLines().get(fr.getMatchLine()).getName();
}
String note = String.format("DENIED_IN{%s}{%s}", acl.getName(), line);
FlowTrace ft = new FlowTrace(FlowDisposition.DENIED_IN, hops, note);
return new Tuple<>(f, ft);
}
boolean isLoopback = slice.getGraph().isLoopback(ge);
if (isLoopback) {
FlowTrace ft = new FlowTrace(FlowDisposition.ACCEPTED, hops, "ACCEPTED");
return new Tuple<>(f, ft);
}
if (ge.getPeer() == null) {
boolean isBgpPeering = slice.getGraph().getEbgpNeighbors().get(ge) != null;
if (isBgpPeering) {
FlowTrace ft = new FlowTrace(FlowDisposition.ACCEPTED, hops, "ACCEPTED");
return new Tuple<>(f, ft);
} else {
FlowTrace ft = new FlowTrace(FlowDisposition.NEIGHBOR_UNREACHABLE_OR_EXITS_NETWORK, hops, "NEIGHBOR_UNREACHABLE_OR_EXITS_NETWORK");
return new Tuple<>(f, ft);
}
}
if (slice.getGraph().isHost(ge.getPeer())) {
FlowTrace ft = new FlowTrace(FlowDisposition.ACCEPTED, hops, "ACCEPTED");
return new Tuple<>(f, ft);
}
current = ge.getPeer();
found = true;
break;
} else if (isTrue(cexpr)) {
hops.add(buildFlowTraceHop(ge, route));
Interface i = ge.getStart();
IpAccessList acl = i.getOutgoingFilter();
FilterResult fr = acl.filter(f);
IpAccessListLine line = acl.getLines().get(fr.getMatchLine());
String note = String.format("DENIED_OUT{%s}{%s}", acl.getName(), line.getName());
FlowTrace ft = new FlowTrace(FlowDisposition.DENIED_OUT, hops, note);
return new Tuple<>(f, ft);
}
}
if (!found) {
BoolExpr permitted = r.getPermitted();
if (boolVal(permitted)) {
// Check if there is an accepting interface
for (GraphEdge ge : slice.getGraph().getEdgeMap().get(current)) {
Interface i = ge.getStart();
Ip ip = i.getAddress().getIp();
if (ip.equals(f.getDstIp())) {
FlowTrace ft = new FlowTrace(FlowDisposition.ACCEPTED, hops, "ACCEPTED");
return new Tuple<>(f, ft);
}
}
FlowTrace ft = new FlowTrace(FlowDisposition.NEIGHBOR_UNREACHABLE_OR_EXITS_NETWORK, hops, "NEIGHBOR_UNREACHABLE_OR_EXITS_NETWORK");
return new Tuple<>(f, ft);
}
FlowTrace ft = new FlowTrace(FlowDisposition.NO_ROUTE, hops, "NO_ROUTE");
return new Tuple<>(f, ft);
}
}
}
use of org.batfish.datamodel.Prefix 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.Prefix 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.Prefix in project batfish by batfish.
the class TransferSSA method aggregateRoutes.
/*
* Determines whether to model each aggregate route as
* suppressing a more specific, or including the more specific
*/
private Map<Prefix, Boolean> aggregateRoutes() {
Map<Prefix, Boolean> acc = new HashMap<>();
String name = _conf.getName();
List<GeneratedRoute> aggregates = _enc.getOptimizations().getRelevantAggregates().get(name);
Set<Prefix> suppressed = _enc.getOptimizations().getSuppressedAggregates().get(name);
for (GeneratedRoute gr : aggregates) {
Prefix p = gr.getNetwork();
acc.put(p, suppressed.contains(p));
}
return acc;
}
use of org.batfish.datamodel.Prefix in project batfish by batfish.
the class TransferSSA method computeIntermediatePrefixLen.
/*
* Create a new variable representing the new prefix length after
* applying the effect of aggregation.
*/
private void computeIntermediatePrefixLen(TransferParam<SymbolicRoute> param) {
ArithExpr prefixLen = param.getData().getPrefixLength();
if (_isExport && _proto.isBgp()) {
_aggregates = aggregateRoutes();
if (_aggregates.size() > 0) {
for (Map.Entry<Prefix, Boolean> entry : _aggregates.entrySet()) {
Prefix p = entry.getKey();
Boolean isSuppressed = entry.getValue();
ArithExpr len = _enc.mkInt(p.getPrefixLength());
BoolExpr relevantPfx = _enc.isRelevantFor(p, _enc.getSymbolicPacket().getDstIp());
BoolExpr relevantLen = _enc.mkGt(param.getData().getPrefixLength(), len);
BoolExpr relevant = _enc.mkAnd(relevantPfx, relevantLen, _enc.mkBool(isSuppressed));
prefixLen = _enc.mkIf(relevant, len, prefixLen);
}
ArithExpr i = createArithVariableWith(param, "PREFIX-LEN", prefixLen);
param.getData().setPrefixLength(i);
}
}
}
Aggregations