use of org.batfish.datamodel.Configuration in project batfish by batfish.
the class Batfish method pathDiff.
@Override
public AnswerElement pathDiff(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();
Topology baseTopology = getEnvironmentTopology();
popEnvironment();
// load diff configurations and generate diff data plane
pushDeltaEnvironment();
Map<String, Configuration> diffConfigurations = loadConfigurations();
Synthesizer diffDataPlaneSynthesizer = synthesizeDataPlane();
Topology diffTopology = getEnvironmentTopology();
popEnvironment();
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> commonEdgeSynthesizers = ImmutableList.of(baseDataPlaneSynthesizer, diffDataPlaneSynthesizer, baseDataPlaneSynthesizer);
List<CompositeNodJob> jobs = new ArrayList<>();
// generate local edge reachability and black hole queries
SortedSet<Edge> diffEdges = diffTopology.getEdges();
for (Edge edge : diffEdges) {
String ingressNode = edge.getNode1();
String outInterface = edge.getInt1();
String vrf = diffConfigurations.get(ingressNode).getInterfaces().get(outInterface).getVrf().getName();
ReachEdgeQuerySynthesizer reachQuery = new ReachEdgeQuerySynthesizer(ingressNode, vrf, edge, true, reachabilitySettings.getHeaderSpace());
ReachEdgeQuerySynthesizer noReachQuery = new ReachEdgeQuerySynthesizer(ingressNode, vrf, edge, true, new HeaderSpace());
noReachQuery.setNegate(true);
List<QuerySynthesizer> queries = ImmutableList.of(reachQuery, noReachQuery, blacklistQuery);
SortedSet<Pair<String, String>> nodes = ImmutableSortedSet.of(new Pair<>(ingressNode, vrf));
CompositeNodJob job = new CompositeNodJob(settings, commonEdgeSynthesizers, queries, nodes, tag);
jobs.add(job);
}
// we also need queries for nodes next to edges that are now missing,
// in the case that those nodes still exist
List<Synthesizer> missingEdgeSynthesizers = ImmutableList.of(baseDataPlaneSynthesizer, baseDataPlaneSynthesizer);
SortedSet<Edge> baseEdges = baseTopology.getEdges();
SortedSet<Edge> missingEdges = ImmutableSortedSet.copyOf(Sets.difference(baseEdges, diffEdges));
for (Edge missingEdge : missingEdges) {
String ingressNode = missingEdge.getNode1();
String outInterface = missingEdge.getInt1();
if (diffConfigurations.containsKey(ingressNode) && diffConfigurations.get(ingressNode).getInterfaces().containsKey(outInterface)) {
String vrf = diffConfigurations.get(ingressNode).getInterfaces().get(outInterface).getVrf().getName();
ReachEdgeQuerySynthesizer reachQuery = new ReachEdgeQuerySynthesizer(ingressNode, vrf, missingEdge, true, reachabilitySettings.getHeaderSpace());
List<QuerySynthesizer> queries = ImmutableList.of(reachQuery, blacklistQuery);
SortedSet<Pair<String, String>> nodes = ImmutableSortedSet.of(new Pair<>(ingressNode, vrf));
CompositeNodJob job = new CompositeNodJob(settings, missingEdgeSynthesizers, queries, nodes, tag);
jobs.add(job);
}
}
// 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.Configuration in project batfish by batfish.
the class Batfish method disableUnusableVpnInterfaces.
private void disableUnusableVpnInterfaces(Map<String, Configuration> configurations) {
CommonUtil.initRemoteIpsecVpns(configurations);
for (Configuration c : configurations.values()) {
for (IpsecVpn vpn : c.getIpsecVpns().values()) {
IpsecVpn remoteVpn = vpn.getRemoteIpsecVpn();
if (remoteVpn == null || !vpn.compatibleIkeProposals(remoteVpn) || !vpn.compatibleIpsecProposals(remoteVpn) || !vpn.compatiblePreSharedKey(remoteVpn)) {
String hostname = c.getHostname();
Interface bindInterface = vpn.getBindInterface();
if (bindInterface != null) {
bindInterface.setActive(false);
bindInterface.setBlacklisted(true);
String bindInterfaceName = bindInterface.getName();
_logger.warnf("WARNING: Disabling unusable vpn interface because we cannot determine remote " + "endpoint: \"%s:%s\"\n", hostname, bindInterfaceName);
}
}
}
}
}
use of org.batfish.datamodel.Configuration in project batfish by batfish.
the class Batfish method checkTopology.
static void checkTopology(Map<String, Configuration> configurations, Topology topology) {
for (Edge edge : topology.getEdges()) {
if (!configurations.containsKey(edge.getNode1())) {
throw new BatfishException(String.format("Topology contains a non-existent node '%s'", edge.getNode1()));
}
if (!configurations.containsKey(edge.getNode2())) {
throw new BatfishException(String.format("Topology contains a non-existent node '%s'", edge.getNode2()));
}
// nodes are valid, now checking corresponding interfaces
Configuration config1 = configurations.get(edge.getNode1());
Configuration config2 = configurations.get(edge.getNode2());
if (!config1.getInterfaces().containsKey(edge.getInt1())) {
throw new BatfishException(String.format("Topology contains a non-existent interface '%s' on node '%s'", edge.getInt1(), edge.getNode1()));
}
if (!config2.getInterfaces().containsKey(edge.getInt2())) {
throw new BatfishException(String.format("Topology contains a non-existent interface '%s' on node '%s'", edge.getInt2(), edge.getNode2()));
}
}
}
use of org.batfish.datamodel.Configuration in project batfish by batfish.
the class Batfish method serializeHostConfigs.
private SortedMap<String, VendorConfiguration> serializeHostConfigs(Path testRigPath, Path outputPath, ParseVendorConfigurationAnswerElement answerElement) {
SortedMap<Path, String> configurationData = readConfigurationFiles(testRigPath, BfConsts.RELPATH_HOST_CONFIGS_DIR);
// read the host files
SortedMap<String, VendorConfiguration> allHostConfigurations;
try (ActiveSpan parseHostConfigsSpan = GlobalTracer.get().buildSpan("Parse host configs").startActive()) {
// avoid unused warning
assert parseHostConfigsSpan != null;
allHostConfigurations = parseVendorConfigurations(configurationData, answerElement, ConfigurationFormat.HOST);
}
if (allHostConfigurations == null) {
throw new BatfishException("Exiting due to parser errors");
}
_logger.infof("Testrig:%s in container:%s has total number of host configs:%d", getTestrigName(), getContainerName(), allHostConfigurations.size());
// split into hostConfigurations and overlayConfigurations
SortedMap<String, VendorConfiguration> overlayConfigurations = allHostConfigurations.entrySet().stream().filter(e -> ((HostConfiguration) e.getValue()).getOverlay()).collect(toMap(Entry::getKey, Entry::getValue, (v1, v2) -> v1, TreeMap::new));
SortedMap<String, VendorConfiguration> nonOverlayHostConfigurations = allHostConfigurations.entrySet().stream().filter(e -> !((HostConfiguration) e.getValue()).getOverlay()).collect(toMap(Entry::getKey, Entry::getValue, (v1, v2) -> v1, TreeMap::new));
// read and associate iptables files for specified hosts
SortedMap<Path, String> iptablesData = new TreeMap<>();
readIptableFiles(testRigPath, allHostConfigurations, iptablesData, answerElement);
SortedMap<String, VendorConfiguration> iptablesConfigurations = parseVendorConfigurations(iptablesData, answerElement, ConfigurationFormat.IPTABLES);
for (VendorConfiguration vc : allHostConfigurations.values()) {
HostConfiguration hostConfig = (HostConfiguration) vc;
if (hostConfig.getIptablesFile() != null) {
Path path = Paths.get(testRigPath.toString(), hostConfig.getIptablesFile());
String relativePathStr = _testrigSettings.getBasePath().relativize(path).toString();
if (iptablesConfigurations.containsKey(relativePathStr)) {
hostConfig.setIptablesVendorConfig((IptablesVendorConfiguration) iptablesConfigurations.get(relativePathStr));
}
}
}
// now, serialize
_logger.info("\n*** SERIALIZING VENDOR CONFIGURATION STRUCTURES ***\n");
_logger.resetTimer();
CommonUtil.createDirectories(outputPath);
Map<Path, VendorConfiguration> output = new TreeMap<>();
nonOverlayHostConfigurations.forEach((name, vc) -> {
Path currentOutputPath = outputPath.resolve(name);
output.put(currentOutputPath, vc);
});
serializeObjects(output);
// serialize warnings
serializeObject(answerElement, _testrigSettings.getParseAnswerPath());
_logger.printElapsedTime();
return overlayConfigurations;
}
use of org.batfish.datamodel.Configuration in project batfish by batfish.
the class Batfish method writeJsonTopology.
private void writeJsonTopology() {
try {
Map<String, Configuration> configs = loadConfigurations();
SortedSet<Edge> textEdges = CommonUtil.synthesizeTopology(configs).getEdges();
JSONArray jEdges = new JSONArray();
for (Edge textEdge : textEdges) {
Configuration node1 = configs.get(textEdge.getNode1());
Configuration node2 = configs.get(textEdge.getNode2());
Interface interface1 = node1.getInterfaces().get(textEdge.getInt1());
Interface interface2 = node2.getInterfaces().get(textEdge.getInt2());
JSONObject jEdge = new JSONObject();
jEdge.put("interface1", interface1.toJSONObject());
jEdge.put("interface2", interface2.toJSONObject());
jEdges.put(jEdge);
}
JSONObject master = new JSONObject();
JSONObject topology = new JSONObject();
topology.put("edges", jEdges);
master.put("topology", topology);
String text = master.toString(3);
_logger.output(text);
} catch (JSONException e) {
throw new BatfishException("Failed to synthesize JSON topology", e);
}
}
Aggregations