aboutsummaryrefslogtreecommitdiffstats
path: root/framework/src/onos/apps/flowanalyzer/src/main/java/org/onosproject/flowanalyzer/FlowAnalyzer.java
diff options
context:
space:
mode:
Diffstat (limited to 'framework/src/onos/apps/flowanalyzer/src/main/java/org/onosproject/flowanalyzer/FlowAnalyzer.java')
-rw-r--r--framework/src/onos/apps/flowanalyzer/src/main/java/org/onosproject/flowanalyzer/FlowAnalyzer.java270
1 files changed, 0 insertions, 270 deletions
diff --git a/framework/src/onos/apps/flowanalyzer/src/main/java/org/onosproject/flowanalyzer/FlowAnalyzer.java b/framework/src/onos/apps/flowanalyzer/src/main/java/org/onosproject/flowanalyzer/FlowAnalyzer.java
deleted file mode 100644
index 86ab37fa..00000000
--- a/framework/src/onos/apps/flowanalyzer/src/main/java/org/onosproject/flowanalyzer/FlowAnalyzer.java
+++ /dev/null
@@ -1,270 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onosproject.flowanalyzer;
-
-import org.apache.felix.scr.annotations.Activate;
-import org.apache.felix.scr.annotations.Component;
-import org.apache.felix.scr.annotations.Deactivate;
-import org.apache.felix.scr.annotations.Reference;
-import org.apache.felix.scr.annotations.ReferenceCardinality;
-import org.apache.felix.scr.annotations.Service;
-import org.onosproject.net.ConnectPoint;
-import org.onosproject.net.PortNumber;
-import org.onosproject.net.flow.FlowEntry;
-import org.onosproject.net.flow.FlowRuleService;
-import org.onosproject.net.DeviceId;
-import org.onosproject.net.HostId;
-import org.onosproject.net.flow.criteria.Criteria;
-import org.onosproject.net.flow.criteria.Criterion;
-import org.onosproject.net.flow.criteria.PortCriterion;
-import org.onosproject.net.flow.instructions.Instruction;
-import org.onosproject.net.flow.instructions.Instructions;
-import org.onosproject.net.topology.TopologyService;
-import org.onosproject.net.topology.TopologyGraph;
-import org.onosproject.net.link.LinkService;
-import org.onosproject.net.Link;
-import org.onosproject.net.topology.TopologyVertex;
-import org.osgi.service.component.ComponentContext;
-import org.slf4j.Logger;
-
-import java.util.HashSet;
-import java.util.List;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Set;
-
-import static org.slf4j.LoggerFactory.getLogger;
-
-/**
- * Simple flow space analyzer app.
- */
-@Component(immediate = true)
-@Service(value = FlowAnalyzer.class)
-public class FlowAnalyzer {
-
- private final Logger log = getLogger(getClass());
-
- @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
- protected FlowRuleService flowRuleService;
-
- @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
- protected TopologyService topologyService;
-
- @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
- protected LinkService linkService;
-
- @Activate
- public void activate(ComponentContext context) {
- log.info("Started");
- }
-
- @Deactivate
- public void deactivate() {
- log.info("Stopped");
- }
-
- TopologyGraph graph;
- Map<FlowEntry, String> label = new HashMap<>();
- Set<FlowEntry> ignoredFlows = new HashSet<>();
-
- /**
- * Analyzes and prints out a report on the status of every flow entry inside
- * the network. The possible states are: Cleared (implying that the entry leads to
- * a host), Cycle (implying that it is part of cycle), and Black Hole (implying
- * that the entry does not lead to a single host).
- *
- * @return result string
- */
- public String analyze() {
- graph = topologyService.getGraph(topologyService.currentTopology());
- for (TopologyVertex v: graph.getVertexes()) {
- DeviceId srcDevice = v.deviceId();
- Iterable<FlowEntry> flowTable = flowRuleService.getFlowEntries(srcDevice);
- for (FlowEntry flow: flowTable) {
- dfs(flow);
- }
- }
-
- //analyze the cycles to look for "critical flows" that can be removed
- //to break the cycle
- Set<FlowEntry> critpts = new HashSet<>();
- for (FlowEntry flow: label.keySet()) {
- if ("Cycle".equals(label.get(flow))) {
- Map<FlowEntry, String> labelSaved = label;
- label = new HashMap<FlowEntry, String>();
- ignoredFlows.add(flow);
- for (TopologyVertex v: graph.getVertexes()) {
- DeviceId srcDevice = v.deviceId();
- Iterable<FlowEntry> flowTable = flowRuleService.getFlowEntries(srcDevice);
- for (FlowEntry flow1: flowTable) {
- dfs(flow1);
- }
- }
-
- boolean replacable = true;
- for (FlowEntry flow2: label.keySet()) {
- if ("Cleared".equals(labelSaved.get(flow2)) && !("Cleared".equals(label.get(flow2)))) {
- replacable = false;
- }
- }
- if (replacable) {
- critpts.add(flow);
- }
- label = labelSaved;
- }
- }
-
- for (FlowEntry flow: critpts) {
- label.put(flow, "Cycle Critical Point");
- }
-
- String s = "\n";
- for (FlowEntry flow: label.keySet()) {
- s += ("Flow Rule: " + flowEntryRepresentation(flow) + "\n");
- s += ("Analysis: " + label.get(flow) + "!\n\n");
- }
- s += ("Analyzed " + label.keySet().size() + " flows.");
- //log.info(s);
- return s;
- }
-
- public Map<FlowEntry, String> calcLabels() {
- analyze();
- return label;
- }
- public String analysisOutput() {
- analyze();
- String s = "\n";
- for (FlowEntry flow: label.keySet()) {
- s += ("Flow Rule: " + flowEntryRepresentation(flow) + "\n");
- s += ("Analysis: " + label.get(flow) + "!\n\n");
- }
- return s;
- }
-
- private boolean dfs(FlowEntry flow) {
- if (ignoredFlows.contains(flow)) {
- return false;
- }
- if ("Cycle".equals(label.get(flow)) ||
- "Black Hole".equals(label.get(flow)) ||
- "Cleared".equals(label.get(flow)) ||
- "NA".equals(label.get(flow)) ||
- "Cycle Critical Point".equals(label.get(flow))) {
-
- // This flow has already been analyzed and there is no need to analyze it further
- return !"Black Hole".equals(label.get(flow));
- }
-
- if ("Visiting".equals(label.get(flow))) {
- //you've detected a cycle because you reached the same entry again during your dfs
- //let it continue so you can label the whole cycle
- label.put(flow, "Cycle");
- } else {
- //otherwise, mark off the current flow entry as currently being visited
- label.put(flow, "Visiting");
- }
-
- boolean pointsToLiveEntry = false;
-
- List<Instruction> instructions = flow.treatment().allInstructions();
- for (Instruction i: instructions) {
- if (i instanceof Instructions.OutputInstruction) {
- pointsToLiveEntry |= analyzeInstruction(i, flow);
- }
- if ("NA".equals(label.get(flow))) {
- return pointsToLiveEntry;
- }
- }
-
- if (!pointsToLiveEntry) {
- //this entry does not point to any "live" entries thus must be a black hole
- label.put(flow, "Black Hole");
- } else if ("Visiting".equals(label.get(flow))) {
- //the flow is not in a cycle or in a black hole
- label.put(flow, "Cleared");
- }
- return pointsToLiveEntry;
- }
-
- private boolean analyzeInstruction(Instruction i, FlowEntry flow) {
- boolean pointsToLiveEntry = false;
- Instructions.OutputInstruction output = (Instructions.OutputInstruction) i;
- PortNumber port = output.port();
- PortNumber outPort = null;
-
- DeviceId egress = null;
- boolean hasHost = false;
-
- ConnectPoint portPt = new ConnectPoint(flow.deviceId(), port);
- for (Link l: linkService.getEgressLinks(portPt)) {
- if (l.dst().elementId() instanceof DeviceId) {
- egress = l.dst().deviceId();
- outPort = l.dst().port();
- } else if (l.dst().elementId() instanceof HostId) {
- //the port leads to a host: therefore it is not a dead link
- pointsToLiveEntry = true;
- hasHost = true;
- }
- }
- if (!topologyService.isInfrastructure(topologyService.currentTopology(), portPt) && egress == null) {
- pointsToLiveEntry = true;
- hasHost = true;
- }
- if (hasHost) {
- return pointsToLiveEntry;
- }
- if (egress == null) {
- //the port that the flow instructions tells you to send the packet
- //to doesn't exist or is a controller port
- label.put(flow, "NA");
- return pointsToLiveEntry;
- }
-
- Iterable<FlowEntry> dstFlowTable = flowRuleService.getFlowEntries(egress);
-
- Set<Criterion> flowCriteria = flow.selector().criteria();
-
- //filter the criteria in order to remove port dependency
- Set<Criterion> filteredCriteria = new HashSet<>();
- for (Criterion criterion : flowCriteria) {
- if (!(criterion instanceof PortCriterion)) {
- filteredCriteria.add(criterion);
- }
- }
-
- //ensure that the in port is equal to the port that it is coming in from
- filteredCriteria.add(Criteria.matchInPort(outPort));
-
- for (FlowEntry entry: dstFlowTable) {
- if (ignoredFlows.contains(entry)) {
- continue;
- }
- if (filteredCriteria.containsAll(entry.selector().criteria())) {
- dfs(entry);
-
- if (!"Black Hole".equals(label.get(entry))) {
- //this entry is "live" i.e not a black hole
- pointsToLiveEntry = true;
- }
- }
- }
- return pointsToLiveEntry;
- }
- public String flowEntryRepresentation(FlowEntry flow) {
- return "Device: " + flow.deviceId() + ", " + flow.selector().criteria() + ", " + flow.treatment().immediate();
- }
-}