use of org.batfish.datamodel.HeaderSpace in project batfish by batfish.
the class Batfish method reducedReachability.
@Override
public AnswerElement reducedReachability(ReachabilitySettings reachabilitySettings) {
Settings settings = getSettings();
checkDifferentialDataPlaneQuestionDependencies();
String tag = getDifferentialFlowTag();
// load base configurations and generate base data plane
pushBaseEnvironment();
Map<String, Configuration> baseConfigurations = loadConfigurations();
Synthesizer baseDataPlaneSynthesizer = synthesizeDataPlane();
popEnvironment();
// load diff configurations and generate diff data plane
pushDeltaEnvironment();
Map<String, Configuration> diffConfigurations = loadConfigurations();
Synthesizer diffDataPlaneSynthesizer = synthesizeDataPlane();
popEnvironment();
Set<String> ingressNodes;
try {
ingressNodes = ImmutableSet.copyOf(Sets.intersection(reachabilitySettings.computeActiveIngressNodes(baseConfigurations), reachabilitySettings.computeActiveIngressNodes(diffConfigurations)));
} catch (InvalidReachabilitySettingsException e) {
return e.getInvalidSettingsAnswer();
}
pushDeltaEnvironment();
SortedSet<String> blacklistNodes = getNodeBlacklist();
Set<NodeInterfacePair> blacklistInterfaces = getInterfaceBlacklist();
SortedSet<Edge> blacklistEdges = getEdgeBlacklist();
popEnvironment();
BlacklistDstIpQuerySynthesizer blacklistQuery = new BlacklistDstIpQuerySynthesizer(null, blacklistNodes, blacklistInterfaces, blacklistEdges, baseConfigurations);
// compute composite program and flows
List<Synthesizer> synthesizers = ImmutableList.of(baseDataPlaneSynthesizer, diffDataPlaneSynthesizer, baseDataPlaneSynthesizer);
// generate base reachability and diff blackhole and blacklist queries
List<CompositeNodJob> jobs = ingressNodes.stream().flatMap(node -> baseConfigurations.get(node).getVrfs().keySet().stream().map(vrf -> {
Map<String, Set<String>> ingressNodeVrfs = ImmutableMap.of(node, ImmutableSet.of(vrf));
StandardReachabilityQuerySynthesizer acceptQuery = StandardReachabilityQuerySynthesizer.builder().setActions(ImmutableSet.of(ForwardingAction.ACCEPT, ForwardingAction.NEIGHBOR_UNREACHABLE_OR_EXITS_NETWORK)).setHeaderSpace(reachabilitySettings.getHeaderSpace()).setIngressNodeVrfs(ingressNodeVrfs).setFinalNodes(ImmutableSet.of()).setTransitNodes(ImmutableSet.of()).setNonTransitNodes(ImmutableSet.of()).setSrcNatted(reachabilitySettings.getSrcNatted()).build();
StandardReachabilityQuerySynthesizer notAcceptQuery = StandardReachabilityQuerySynthesizer.builder().setActions(ImmutableSet.of(ForwardingAction.ACCEPT, ForwardingAction.NEIGHBOR_UNREACHABLE_OR_EXITS_NETWORK)).setHeaderSpace(new HeaderSpace()).setIngressNodeVrfs(ingressNodeVrfs).setFinalNodes(ImmutableSet.of()).setTransitNodes(ImmutableSet.of()).setNonTransitNodes(ImmutableSet.of()).build();
notAcceptQuery.setNegate(true);
SortedSet<Pair<String, String>> nodes = ImmutableSortedSet.of(new Pair<>(node, vrf));
List<QuerySynthesizer> queries = ImmutableList.of(acceptQuery, notAcceptQuery, blacklistQuery);
return new CompositeNodJob(settings, synthesizers, queries, nodes, tag);
})).collect(Collectors.toList());
// TODO: maybe do something with nod answer element
Set<Flow> flows = computeCompositeNodOutput(jobs, new NodAnswerElement());
pushBaseEnvironment();
getDataPlanePlugin().processFlows(flows, loadDataPlane());
popEnvironment();
pushDeltaEnvironment();
getDataPlanePlugin().processFlows(flows, loadDataPlane());
popEnvironment();
AnswerElement answerElement = getHistory();
return answerElement;
}
use of org.batfish.datamodel.HeaderSpace in project batfish by batfish.
the class Batfish method singleReachability.
private AnswerElement singleReachability(ReachabilitySettings reachabilitySettings, ReachabilityQuerySynthesizer.Builder<?, ?> builder) {
Settings settings = getSettings();
String tag = getFlowTag(_testrigSettings);
Set<ForwardingAction> actions = reachabilitySettings.getActions();
boolean useCompression = reachabilitySettings.getUseCompression();
// specialized compression
/*
CompressDataPlaneResult compressionResult =
useCompression ? computeCompressedDataPlane(headerSpace) : null;
Map<String, Configuration> configurations =
useCompression ? compressionResult._compressedConfigs : loadConfigurations();
DataPlane dataPlane = useCompression ? compressionResult._compressedDataPlane : loadDataPlane();
*/
// general compression
Snapshot snapshot = getSnapshot();
Map<String, Configuration> configurations = useCompression ? loadCompressedConfigurations(snapshot) : loadConfigurations(snapshot);
DataPlane dataPlane = loadDataPlane(useCompression);
if (configurations == null) {
throw new BatfishException("error loading configurations");
}
if (dataPlane == null) {
throw new BatfishException("error loading data plane");
}
Set<String> activeIngressNodes;
Set<String> activeFinalNodes;
HeaderSpace headerSpace;
Set<String> transitNodes;
Set<String> nonTransitNodes;
int maxChunkSize;
try {
activeIngressNodes = reachabilitySettings.computeActiveIngressNodes(configurations);
activeFinalNodes = reachabilitySettings.computeActiveFinalNodes(configurations);
headerSpace = reachabilitySettings.getHeaderSpace();
transitNodes = reachabilitySettings.computeActiveTransitNodes(configurations);
nonTransitNodes = reachabilitySettings.computeActiveNonTransitNodes(configurations);
maxChunkSize = reachabilitySettings.getMaxChunkSize();
reachabilitySettings.validateTransitNodes(configurations);
} catch (InvalidReachabilitySettingsException e) {
return e.getInvalidSettingsAnswer();
}
List<Pair<String, String>> originateNodeVrfs = activeIngressNodes.stream().flatMap(ingressNode -> configurations.get(ingressNode).getVrfs().keySet().stream().map(ingressVrf -> new Pair<>(ingressNode, ingressVrf))).collect(Collectors.toList());
int chunkSize = Math.max(1, Math.min(maxChunkSize, originateNodeVrfs.size() / _settings.getAvailableThreads()));
// partition originateNodeVrfs into chunks
List<List<Pair<String, String>>> originateNodeVrfChunks = Lists.partition(originateNodeVrfs, chunkSize);
Synthesizer dataPlaneSynthesizer = synthesizeDataPlane(configurations, dataPlane, loadForwardingAnalysis(configurations, dataPlane), headerSpace, reachabilitySettings.getSpecialize());
// build query jobs
List<NodJob> jobs = originateNodeVrfChunks.stream().map(ImmutableSortedSet::copyOf).map(nodeVrfs -> {
SortedMap<String, Set<String>> vrfsByNode = new TreeMap<>();
nodeVrfs.forEach(nodeVrf -> {
String node = nodeVrf.getFirst();
String vrf = nodeVrf.getSecond();
vrfsByNode.computeIfAbsent(node, key -> new TreeSet<>());
vrfsByNode.get(node).add(vrf);
});
ReachabilityQuerySynthesizer query = builder.setActions(actions).setHeaderSpace(headerSpace).setFinalNodes(activeFinalNodes).setIngressNodeVrfs(vrfsByNode).setTransitNodes(transitNodes).setNonTransitNodes(nonTransitNodes).setSrcNatted(reachabilitySettings.getSrcNatted()).build();
return new NodJob(settings, dataPlaneSynthesizer, query, nodeVrfs, tag, reachabilitySettings.getSpecialize());
}).collect(Collectors.toList());
// run jobs and get resulting flows
Set<Flow> flows = computeNodOutput(jobs);
getDataPlanePlugin().processFlows(flows, loadDataPlane());
AnswerElement answerElement = getHistory();
return answerElement;
}
use of org.batfish.datamodel.HeaderSpace in project batfish by batfish.
the class Batfish method computeCompressedDataPlane.
private CompressDataPlaneResult computeCompressedDataPlane() {
CompressDataPlaneResult result = computeCompressedDataPlane(new HeaderSpace());
_cachedCompressedConfigurations.put(getSnapshot(), new TreeMap<>(result._compressedConfigs));
saveDataPlane(result._compressedDataPlane, result._answerElement, true);
return result;
}
use of org.batfish.datamodel.HeaderSpace in project batfish by batfish.
the class Encoder method initSlices.
/*
* Initialize each encoding slice.
* For iBGP, we also add reachability information for each pair of neighbors,
* to determine if messages sent to/from a neighbor will arrive.
*/
private void initSlices(HeaderSpace h, Graph g) {
if (g.getIbgpNeighbors().isEmpty() || !_modelIgp) {
_slices.put(MAIN_SLICE_NAME, new EncoderSlice(this, h, g, ""));
} else {
_slices.put(MAIN_SLICE_NAME, new EncoderSlice(this, h, g, MAIN_SLICE_NAME));
}
if (_modelIgp) {
SortedSet<Pair<String, Ip>> ibgpRouters = new TreeSet<>();
for (Entry<GraphEdge, BgpNeighbor> entry : g.getIbgpNeighbors().entrySet()) {
GraphEdge ge = entry.getKey();
BgpNeighbor n = entry.getValue();
String router = ge.getRouter();
Ip ip = n.getLocalIp();
Pair<String, Ip> pair = new Pair<>(router, ip);
// Add one slice per (router, source ip) pair
if (!ibgpRouters.contains(pair)) {
ibgpRouters.add(pair);
// Create a control plane slice only for this ip
HeaderSpace hs = new HeaderSpace();
// Make sure messages are sent to this destination IP
SortedSet<IpWildcard> ips = new TreeSet<>();
ips.add(new IpWildcard(n.getLocalIp()));
hs.setDstIps(ips);
// Make sure messages use TCP port 179
SortedSet<SubRange> dstPorts = new TreeSet<>();
dstPorts.add(new SubRange(179, 179));
hs.setDstPorts(dstPorts);
// Make sure messages use the TCP protocol
SortedSet<IpProtocol> protocols = new TreeSet<>();
protocols.add(IpProtocol.TCP);
hs.setIpProtocols(protocols);
// TODO: create domains once
Graph gNew = new Graph(g.getBatfish(), null, g.getDomain(router));
String sliceName = "SLICE-" + router + "_";
EncoderSlice slice = new EncoderSlice(this, hs, gNew, sliceName);
_slices.put(sliceName, slice);
PropertyAdder pa = new PropertyAdder(slice);
Map<String, BoolExpr> reachVars = pa.instrumentReachability(router);
_sliceReachability.put(router, reachVars);
}
}
}
}
use of org.batfish.datamodel.HeaderSpace in project batfish by batfish.
the class PropertyChecker method findAllNetworkSlices.
private Tuple<Stream<Supplier<NetworkSlice>>, Long> findAllNetworkSlices(HeaderQuestion q, @Nullable Graph graph, boolean useDefaultCase) {
if (q.getUseAbstraction()) {
HeaderSpace h = q.getHeaderSpace();
int numFailures = q.getFailures();
System.out.println("Start verification");
System.out.println("Using headerspace: " + h.getDstIps());
DestinationClasses dcs = DestinationClasses.create(_batfish, graph, h, useDefaultCase);
System.out.println("Number of edges: " + dcs.getGraph().getAllRealEdges().size());
System.out.println("Created destination classes");
System.out.println("Num Classes: " + dcs.getHeaderspaceMap().size());
long l = System.currentTimeMillis();
ArrayList<Supplier<NetworkSlice>> ecs = NetworkSlice.allSlices(dcs, numFailures);
l = System.currentTimeMillis() - l;
System.out.println("Created BDDs");
return new Tuple<>(ecs.parallelStream(), l);
} else {
List<Supplier<NetworkSlice>> singleEc = new ArrayList<>();
Graph g = graph == null ? new Graph(_batfish) : graph;
Abstraction a = new Abstraction(g, null);
NetworkSlice slice = new NetworkSlice(q.getHeaderSpace(), a, false);
Supplier<NetworkSlice> sup = () -> slice;
singleEc.add(sup);
return new Tuple<>(singleEc.stream(), 0L);
}
}
Aggregations