use of org.batfish.datamodel.Prefix in project batfish by batfish.
the class PropertyChecker method inferDestinationHeaderSpace.
private void inferDestinationHeaderSpace(Graph g, Collection<GraphEdge> destPorts, HeaderLocationQuestion q) {
// Skip inference if the destination IP headerspace does not need to be inferred.
if (!q.getHeaderSpace().getDstIps().isEmpty()) {
return;
}
// Infer relevant destination IP headerspace from interfaces
HeaderSpace headerSpace = q.getHeaderSpace();
for (GraphEdge ge : destPorts) {
// it can be any prefix, so we leave it unconstrained
if (g.isExternal(ge)) {
headerSpace.setDstIps(Collections.emptySet());
headerSpace.setNotDstIps(Collections.emptySet());
break;
}
// If we don't know what is on the other end
if (ge.getPeer() == null) {
Prefix pfx = ge.getStart().getAddress().getPrefix();
IpWildcard dst = new IpWildcard(pfx);
headerSpace.setDstIps(Iterables.concat(headerSpace.getDstIps(), Collections.singleton(dst)));
} else {
// If host, add the subnet but not the neighbor's address
if (g.isHost(ge.getRouter())) {
Prefix pfx = ge.getStart().getAddress().getPrefix();
IpWildcard dst = new IpWildcard(pfx);
headerSpace.setDstIps(Iterables.concat(headerSpace.getDstIps(), Collections.singleton(dst)));
Ip ip = ge.getEnd().getAddress().getIp();
IpWildcard dst2 = new IpWildcard(ip);
headerSpace.setNotDstIps(Iterables.concat(headerSpace.getNotDstIps(), Collections.singleton(dst2)));
} else {
// Otherwise, we add the exact address
Ip ip = ge.getStart().getAddress().getIp();
IpWildcard dst = new IpWildcard(ip);
headerSpace.setDstIps(Iterables.concat(headerSpace.getDstIps(), Collections.singleton(dst)));
}
}
}
}
use of org.batfish.datamodel.Prefix in project batfish by batfish.
the class PropertyChecker method checkRoutingLoop.
/*
* Checks for routing loops in the network. For efficiency reasons,
* we only check for loops with routers that use static routes since
* these can override the usual loop-prevention mechanisms.
*/
public AnswerElement checkRoutingLoop(HeaderQuestion q) {
Graph graph = new Graph(_batfish);
// Collect all relevant destinations
List<Prefix> prefixes = new ArrayList<>();
graph.getStaticRoutes().forEach((router, ifaceName, srs) -> {
for (StaticRoute sr : srs) {
prefixes.add(sr.getNetwork());
}
});
SortedSet<IpWildcard> pfxs = new TreeSet<>();
for (Prefix prefix : prefixes) {
pfxs.add(new IpWildcard(prefix));
}
q.getHeaderSpace().setDstIps(pfxs);
// Collect all routers that use static routes as a
// potential node along a loop
List<String> routers = new ArrayList<>();
for (Entry<String, Configuration> entry : graph.getConfigurations().entrySet()) {
String router = entry.getKey();
Configuration conf = entry.getValue();
if (conf.getDefaultVrf().getStaticRoutes().size() > 0) {
routers.add(router);
}
}
Encoder enc = new Encoder(_settings, graph, q);
enc.computeEncoding();
Context ctx = enc.getCtx();
EncoderSlice slice = enc.getMainSlice();
PropertyAdder pa = new PropertyAdder(slice);
BoolExpr someLoop = ctx.mkBool(false);
for (String router : routers) {
BoolExpr hasLoop = pa.instrumentLoop(router);
someLoop = ctx.mkOr(someLoop, hasLoop);
}
enc.add(someLoop);
VerificationResult result = enc.verify().getFirst();
return new SmtOneAnswerElement(result);
}
use of org.batfish.datamodel.Prefix in project batfish by batfish.
the class PropertyChecker method ignoredDestinations.
/*
* Creates a boolean variable representing destinations we don't want
* to consider due to local differences.
*/
private BoolExpr ignoredDestinations(Context ctx, EncoderSlice e1, String r1, Configuration conf1) {
BoolExpr validDest = ctx.mkBool(true);
for (Protocol proto1 : e1.getProtocols().get(r1)) {
Set<Prefix> prefixes = Graph.getOriginatedNetworks(conf1, proto1);
BoolExpr dest = e1.relevantOrigination(prefixes);
validDest = ctx.mkAnd(validDest, ctx.mkNot(dest));
}
return validDest;
}
use of org.batfish.datamodel.Prefix in project batfish by batfish.
the class TransferBDD method isRelevantFor.
/*
* Check if a prefix range match is applicable for the packet destination
* Ip address, given the prefix length variable.
*
* Since aggregation is modelled separately, we assume that prefixLen
* is not modified, and thus will contain only the underlying variables:
* [var(0), ..., var(n)]
*/
private BDD isRelevantFor(BDDRoute record, PrefixRange range) {
Prefix p = range.getPrefix();
SubRange r = range.getLengthRange();
int len = p.getPrefixLength();
int lower = r.getStart();
int upper = r.getEnd();
BDD lowerBitsMatch = firstBitsEqual(record.getPrefix().getBitvec(), p, len);
BDD acc = factory.zero();
if (lower == 0 && upper == 32) {
acc = factory.one();
} else {
for (int i = lower; i <= upper; i++) {
BDD equalLen = record.getPrefixLength().value(i);
acc = acc.or(equalLen);
}
}
return acc.and(lowerBitsMatch);
}
use of org.batfish.datamodel.Prefix in project batfish by batfish.
the class TransferBDD method matchFilterList.
/*
* Converts a route filter list to a boolean expression.
*/
private BDD matchFilterList(TransferParam<BDDRoute> p, RouteFilterList x, BDDRoute other) {
BDD acc = factory.zero();
List<RouteFilterLine> lines = new ArrayList<>(x.getLines());
Collections.reverse(lines);
for (RouteFilterLine line : lines) {
Prefix pfx = line.getPrefix();
if (!PrefixUtils.isContainedBy(pfx, _ignoredNetworks)) {
SubRange r = line.getLengthRange();
PrefixRange range = new PrefixRange(pfx, r);
p.debug("Prefix Range: " + range);
p.debug("Action: " + line.getAction());
BDD matches = isRelevantFor(other, range);
BDD action = mkBDD(line.getAction() == LineAction.ACCEPT);
acc = ite(matches, action, acc);
}
}
return acc;
}
Aggregations