use of org.batfish.common.BatfishException in project batfish by batfish.
the class CommonUtil method writeStreamToFile.
public static void writeStreamToFile(InputStream inputStream, Path outputFile) {
try (OutputStream fileOutputStream = new FileOutputStream(outputFile.toFile())) {
int read = 0;
final byte[] bytes = new byte[STREAMED_FILE_BUFFER_SIZE];
while ((read = inputStream.read(bytes)) != -1) {
fileOutputStream.write(bytes, 0, read);
}
} catch (IOException e) {
throw new BatfishException("Failed to write input stream to output file: '" + outputFile + "'");
}
}
use of org.batfish.common.BatfishException in project batfish by batfish.
the class CommonUtil method initRemoteBgpNeighbors.
/**
* Initialize BGP neighbors for all nodes.
*
* @param configurations map of all configurations, keyed by hostname
* @param ipOwners mapping of Ips to a set of nodes (hostnames) that owns those IPs
* @param checkReachability whether bgp neighbor reachability should be checked
* @param flowProcessor dataplane plugin to use to check reachability. Must not be {@code null} if
* {@code checkReachability = true}
* @param dp dataplane to use to check reachability. Must not be {@code null} if {@code
* checkReachability = true}
*/
public static void initRemoteBgpNeighbors(Map<String, Configuration> configurations, Map<Ip, Set<String>> ipOwners, boolean checkReachability, @Nullable FlowProcessor flowProcessor, @Nullable DataPlane dp) {
// TODO: handle duplicate ips on different vrfs
Map<BgpNeighbor, Ip> remoteAddresses = new IdentityHashMap<>();
Map<Ip, Set<BgpNeighbor>> localAddresses = new HashMap<>();
/*
* Construct maps indicating which neighbor owns which Ip Address
*/
for (Configuration node : configurations.values()) {
String hostname = node.getHostname();
for (Vrf vrf : node.getVrfs().values()) {
BgpProcess proc = vrf.getBgpProcess();
if (proc == null) {
// nothing to do if no bgp process on this VRF
continue;
}
for (BgpNeighbor bgpNeighbor : proc.getNeighbors().values()) {
/*
* Begin by initializing candidate neighbors to an empty set
*/
bgpNeighbor.initCandidateRemoteBgpNeighbors();
// Skip things we don't handle
if (bgpNeighbor.getPrefix().getPrefixLength() < Prefix.MAX_PREFIX_LENGTH) {
throw new BatfishException(hostname + ": Do not support dynamic bgp sessions at this time: " + bgpNeighbor.getPrefix());
}
Ip remoteAddress = bgpNeighbor.getAddress();
if (remoteAddress == null) {
throw new BatfishException(hostname + ": Could not determine remote address of bgp neighbor: " + bgpNeighbor);
}
Ip localAddress = bgpNeighbor.getLocalIp();
if (localAddress == null || !ipOwners.containsKey(localAddress) || !ipOwners.get(localAddress).contains(hostname)) {
// Local address is not owned by anybody
continue;
}
remoteAddresses.put(bgpNeighbor, remoteAddress);
// Add this neighbor as owner of its local address
localAddresses.computeIfAbsent(localAddress, k -> Collections.newSetFromMap(new IdentityHashMap<>())).add(bgpNeighbor);
}
}
}
/*
* For each neighbor, construct the set of candidate neighbors, then filter out impossible
* sessions.
*/
for (Entry<BgpNeighbor, Ip> e : remoteAddresses.entrySet()) {
BgpNeighbor bgpNeighbor = e.getKey();
Ip remoteAddress = e.getValue();
Ip localAddress = bgpNeighbor.getLocalIp();
int localLocalAs = bgpNeighbor.getLocalAs();
int localRemoteAs = bgpNeighbor.getRemoteAs();
/*
* Let the set of candidate neighbors be set of neighbors that own the remoteAddress
*/
Set<BgpNeighbor> remoteBgpNeighborCandidates = localAddresses.get(remoteAddress);
if (remoteBgpNeighborCandidates == null) {
// No possible remote neighbors
continue;
}
/*
* Filter the set of candidate neighbors based on these checks:
* - Remote neighbor's remote address is the same as our local address
* - Remote neighbor's remote AS is the same as our local AS (and vice-versa)
*/
for (BgpNeighbor remoteBgpNeighborCandidate : remoteBgpNeighborCandidates) {
int remoteLocalAs = remoteBgpNeighborCandidate.getLocalAs();
int remoteRemoteAs = remoteBgpNeighborCandidate.getRemoteAs();
Ip reciprocalRemoteIp = remoteBgpNeighborCandidate.getAddress();
if (localAddress.equals(reciprocalRemoteIp) && localLocalAs == remoteRemoteAs && localRemoteAs == remoteLocalAs) {
/*
* Fairly confident establishing the session is possible here, but still check
* reachability if needed.
* We should check reachability only for eBgp multihop or iBgp
*/
if (checkReachability && (bgpNeighbor.getEbgpMultihop() || localLocalAs == remoteLocalAs)) {
/*
* Ensure that the session can be established by running traceroute in both directions
*/
if (flowProcessor == null || dp == null) {
throw new BatfishException("Cannot compute neighbor reachability without a dataplane");
}
Flow.Builder fb = new Flow.Builder();
fb.setIpProtocol(IpProtocol.TCP);
fb.setTag("neighbor-resolution");
fb.setIngressNode(bgpNeighbor.getOwner().getHostname());
fb.setSrcIp(localAddress);
fb.setDstIp(remoteAddress);
fb.setSrcPort(NamedPort.EPHEMERAL_LOWEST.number());
fb.setDstPort(NamedPort.BGP.number());
Flow forwardFlow = fb.build();
fb.setIngressNode(remoteBgpNeighborCandidate.getOwner().getHostname());
fb.setSrcIp(forwardFlow.getDstIp());
fb.setDstIp(forwardFlow.getSrcIp());
fb.setSrcPort(forwardFlow.getDstPort());
fb.setDstPort(forwardFlow.getSrcPort());
Flow backwardFlow = fb.build();
SortedMap<Flow, Set<FlowTrace>> traces = flowProcessor.processFlows(dp, ImmutableSet.of(forwardFlow, backwardFlow));
if (traces.values().stream().map(fts -> fts.stream().allMatch(ft -> ft.getDisposition() != FlowDisposition.ACCEPTED)).anyMatch(Predicate.isEqual(true))) {
/*
* If either flow has all traceroutes fail, do not consider the neighbor valid
*/
continue;
}
bgpNeighbor.getCandidateRemoteBgpNeighbors().add(remoteBgpNeighborCandidate);
} else {
bgpNeighbor.getCandidateRemoteBgpNeighbors().add(remoteBgpNeighborCandidate);
}
}
}
Set<BgpNeighbor> finalCandidates = bgpNeighbor.getCandidateRemoteBgpNeighbors();
if (finalCandidates.size() > 1) {
/* If we still have not narrowed it down to a single neighbor,
* pick based on sorted hostnames
*/
SortedMap<String, BgpNeighbor> hostnameToNeighbor = finalCandidates.stream().collect(ImmutableSortedMap.toImmutableSortedMap(String::compareTo, k -> k.getOwner().getHostname(), Function.identity()));
bgpNeighbor.setRemoteBgpNeighbor(hostnameToNeighbor.get(hostnameToNeighbor.firstKey()));
} else if (finalCandidates.size() == 1) {
bgpNeighbor.setRemoteBgpNeighbor(finalCandidates.iterator().next());
} else {
bgpNeighbor.setRemoteBgpNeighbor(null);
}
}
}
use of org.batfish.common.BatfishException in project batfish by batfish.
the class UnzipUtility method unzip.
/**
* Extracts a zip file specified by the zipFilePath to a directory specified by {@code
* destDirectory} (will be created if does not exists)
*
* @param zipFile The path to the input zip file
* @param destDirectory The output directory in which to extract the zip
*/
public static void unzip(Path zipFile, Path destDirectory) {
if (!Files.exists(destDirectory) && !destDirectory.toFile().mkdirs()) {
throw new BatfishException("Could not create zip output directory " + destDirectory);
}
try {
// :ratul:
// this lets us check if the zip file is proper
// for bad zip files this will throw an exception
ZipFile zipTest = new ZipFile(zipFile.toFile());
zipTest.close();
try (FileInputStream fis = new FileInputStream(zipFile.toFile());
ZipInputStream zipIn = new ZipInputStream(fis)) {
for (ZipEntry entry = zipIn.getNextEntry(); entry != null; entry = zipIn.getNextEntry()) {
Path outputPath = validatePath(Paths.get(destDirectory + File.separator + entry.getName()), destDirectory);
if (entry.isDirectory()) {
// Make the directory, including parent dirs.
if (!outputPath.toFile().mkdirs()) {
throw new IOException("Unable to make directory " + outputPath);
}
} else {
// Extract the file.
extractFile(zipIn, outputPath);
}
zipIn.closeEntry();
}
}
} catch (IOException e) {
throw new BatfishException("Could not unzip: '" + zipFile + "' into: '" + destDirectory + "'", e);
}
}
use of org.batfish.common.BatfishException in project batfish by batfish.
the class PluginConsumer method loadPlugins.
protected final void loadPlugins() {
SortedSet<Plugin> plugins;
try {
plugins = new TreeSet<>(Lists.newArrayList(ServiceLoader.load(Plugin.class, _currentClassLoader)));
} catch (ServiceConfigurationError e) {
throw new BatfishException("Failed to locate and/or instantiate plugins", e);
}
List<BatfishException> initializationExceptions = new ArrayList<>();
for (Plugin plugin : plugins) {
try {
plugin.initialize(this);
} catch (Exception e) {
initializationExceptions.add(new BatfishException("Failed to initialize plugin: " + plugin.getClass().getCanonicalName(), e));
}
}
if (!initializationExceptions.isEmpty()) {
BatfishException e = new BatfishException("Failed to initialize one or more plugins");
initializationExceptions.forEach(e::addSuppressed);
throw e;
}
}
use of org.batfish.common.BatfishException in project batfish by batfish.
the class PluginConsumer method serializeObject.
/**
* Serializes the given object to a file with the given output name.
*/
public void serializeObject(Serializable object, Path outputFile) {
try {
try (Closer closer = Closer.create()) {
OutputStream out = closer.register(Files.newOutputStream(outputFile));
BufferedOutputStream bout = closer.register(new BufferedOutputStream(out));
serializeToLz4Data(object, bout);
}
} catch (IOException e) {
throw new BatfishException("Failed to serialize object to output file: " + outputFile, e);
}
}
Aggregations