ONOS Network Troubleshooting System
Newest Commit changes:
1. Add unit tests.
2. Fix review comments.
3. Add support to BUCK.
Could you please make a Code Review, we wish to hear anything from you :)
Thank you very much!
----------------------------------------------------
ONOS Network Troubleshooting System
Modularity design. In present, include these tow module:
1. Routing Loop Detection
Welcome your contribution for more modules in the future...
Beijing University of Posts and Telecommunications
new: withdraw blackhole tracing for redesign;
fix obvious checkstyle problem.
Change-Id: Id6d3aa0bc00c8da8ac046e6903f17cfdf954d919
diff --git a/apps/network-troubleshoot/api/src/main/java/org/onosproject/fnl/base/NetworkDiagnosticUtils.java b/apps/network-troubleshoot/api/src/main/java/org/onosproject/fnl/base/NetworkDiagnosticUtils.java
new file mode 100644
index 0000000..0a0d796
--- /dev/null
+++ b/apps/network-troubleshoot/api/src/main/java/org/onosproject/fnl/base/NetworkDiagnosticUtils.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright 2015-present 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.fnl.base;
+
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.HostId;
+import org.onosproject.net.flow.FlowEntry;
+import org.onosproject.net.flow.criteria.Criterion;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * Common utility functions and constants.
+ */
+public final class NetworkDiagnosticUtils {
+
+ private NetworkDiagnosticUtils() {
+ // no instantiation
+ }
+
+ /**
+ * Returns a list of flow entries sorted by priority in descending order.
+ *
+ * @param flowEntries flow entries to be sorted
+ * @return flow entries in descending order
+ */
+ public static List<FlowEntry> sortFlowTable(Iterable<FlowEntry> flowEntries) {
+
+ List<FlowEntry> flows = new ArrayList<>();
+ flowEntries.forEach(flows::add);
+
+ Collections.sort(flows,
+ (f1, f2) -> f2.priority() - f1.priority());
+ return flows;
+ }
+
+ /**
+ * Returns a list of match fields sorted by their types in ascending order.
+ *
+ * @param criterionSet the criteria to be sorted
+ * @return the list of criteria in ascending order
+ */
+ public static List<Criterion> sortCriteria(Set<Criterion> criterionSet) {
+
+ List<Criterion> array = new ArrayList<>(criterionSet);
+ Collections.sort(array,
+ (c1, c2) -> c1.type().compareTo(c2.type()));
+ return array;
+ }
+
+ /**
+ * Returns true if the given connect point is a device point.
+ *
+ * @param connectPoint the connect point to be checked
+ * @return true if the connect point is a device point
+ */
+ public static boolean isDevice(ConnectPoint connectPoint) {
+ return connectPoint.elementId() instanceof DeviceId;
+ }
+
+ /**
+ * Returns true if the given connect point is a host point.
+ *
+ * @param connectPoint the connect point to be checked
+ * @return true if the connect point is a host point
+ */
+ public static boolean isHost(ConnectPoint connectPoint) {
+ // TODO - not debug yet
+ return connectPoint.elementId() instanceof HostId;
+ }
+}
diff --git a/apps/network-troubleshoot/api/src/main/java/org/onosproject/fnl/base/TsLoopPacket.java b/apps/network-troubleshoot/api/src/main/java/org/onosproject/fnl/base/TsLoopPacket.java
new file mode 100644
index 0000000..cb7d455
--- /dev/null
+++ b/apps/network-troubleshoot/api/src/main/java/org/onosproject/fnl/base/TsLoopPacket.java
@@ -0,0 +1,409 @@
+/*
+ * Copyright 2015-present 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.fnl.base;
+
+import org.onosproject.fnl.intf.NetworkAnomaly;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Link;
+import org.onosproject.net.flow.FlowEntry;
+import org.onosproject.net.flow.criteria.Criterion;
+import org.onosproject.net.flow.criteria.EthCriterion;
+import org.onosproject.net.flow.criteria.EthTypeCriterion;
+import org.onosproject.net.flow.criteria.IPCriterion;
+import org.onosproject.net.flow.criteria.IPDscpCriterion;
+import org.onosproject.net.flow.criteria.IPEcnCriterion;
+import org.onosproject.net.flow.criteria.IPProtocolCriterion;
+import org.onosproject.net.flow.criteria.PortCriterion;
+import org.onosproject.net.flow.criteria.TcpPortCriterion;
+import org.onosproject.net.flow.criteria.UdpPortCriterion;
+import org.onosproject.net.flow.criteria.VlanIdCriterion;
+import org.onosproject.net.flow.criteria.VlanPcpCriterion;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Stack;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.Collections;
+
+import static org.onosproject.fnl.intf.NetworkAnomaly.Type.LOOP;
+import static org.onosproject.fnl.base.TsLoopPacket.SetHeaderResult.SETHEADER_FAILURE_NULL;
+import static org.onosproject.fnl.base.TsLoopPacket.SetHeaderResult.SETHEADER_OVERRIDE;
+import static org.onosproject.fnl.base.TsLoopPacket.SetHeaderResult.SETHEADER_SUCCESS;
+import static org.onosproject.net.flow.criteria.Criteria.*;
+
+/**
+ * Virtual packet for Default Loop Checking.
+ */
+public final class TsLoopPacket implements NetworkAnomaly {
+
+ private final Logger log = LoggerFactory.getLogger(getClass());
+
+ private static final String EOL = String.format("%n");
+ private static final String LINE =
+ EOL + "====================================================" + EOL;
+ private static final String HDR_FMT = EOL + "---------- %s ----------" + EOL;
+ private static final String LOOP_HEADER = makeHeader("Loop Header");
+ private static final String LOOP_FLOW_ENTRIES = makeHeader("Loop Flow Entries");
+ private static final String LOOP_LINKS = makeHeader("Loop Links");
+
+ private Map<Criterion.Type, Criterion> match;
+ private Stack<FlowEntry> pathFlow;
+ // when Upgrade, check to MAKE SURE it include just Link but not EdgeLink
+ private Stack<Link> pathLink;
+
+ /**
+ * Create an initial virtual packet inside for Loop Checking.
+ */
+ private TsLoopPacket() {
+ match = new HashMap<>();
+ pathFlow = new Stack<>();
+ pathLink = new Stack<>();
+ }
+
+ @Override
+ public Type type() {
+ return LOOP;
+ }
+
+ /**
+ * Represents the result of setting a header to virtual packet.
+ */
+ public enum SetHeaderResult {
+ /**
+ * Set header successfully.
+ */
+ SETHEADER_SUCCESS,
+
+ /**
+ * Set header successfully but override old value.
+ */
+ SETHEADER_OVERRIDE,
+
+ /**
+ * Fail to set Header because NULL value.
+ */
+ SETHEADER_FAILURE_NULL,
+
+ /**
+ * Fail to set Header, but reason is not defined, defined in advance.
+ */
+ SETHEADER_FAILURE
+ }
+
+ /**
+ * Creates and returns a new packet instance with the copied match fields.
+ *
+ * With hard-copied match fields, references to path flows and path links.
+ *
+ * @return new loop packet instance with the copied match fields
+ */
+ public TsLoopPacket copyPacketMatch() {
+
+ TsLoopPacket newOne = new TsLoopPacket();
+
+ newOne.pathFlow = this.pathFlow;
+ newOne.pathLink = this.pathLink;
+
+ Map<Criterion.Type, Criterion> m = newOne.match;
+
+ for (Map.Entry<Criterion.Type, Criterion> entry : this.match.entrySet()) {
+ Criterion.Type k = entry.getKey();
+ Criterion v = entry.getValue();
+
+ switch (k) {
+ case IN_PORT:
+ m.put(k, matchInPort(((PortCriterion) v).port()));
+ break;
+ case ETH_SRC: // At present, not support Ethernet mask (ONOS?)
+ m.put(k, matchEthSrc(((EthCriterion) v).mac()));
+ break;
+ case ETH_DST: // At present, not support Ethernet mask (ONOS?)
+ m.put(k, matchEthDst(((EthCriterion) v).mac()));
+ break;
+ case ETH_TYPE:
+ m.put(k, matchEthType(((EthTypeCriterion) v).ethType()));
+ break;
+ case VLAN_VID: // At present, not support VLAN mask (ONOS?)
+ m.put(k, matchVlanId(((VlanIdCriterion) v).vlanId()));
+ break;
+ case VLAN_PCP:
+ m.put(k, matchVlanPcp(((VlanPcpCriterion) v).priority()));
+ break;
+ case IPV4_SRC:
+ m.put(k, matchIPSrc(((IPCriterion) v).ip()));
+ break;
+ case IPV4_DST:
+ m.put(k, matchIPDst(((IPCriterion) v).ip()));
+ break;
+ case IP_PROTO:
+ m.put(k, matchIPProtocol(((IPProtocolCriterion) v).protocol()));
+ break;
+ case IP_DSCP: // can't be supported by now
+ m.put(k, matchIPDscp(((IPDscpCriterion) v).ipDscp()));
+ break;
+ case IP_ECN: // can't be supported by now
+ m.put(k, matchIPEcn(((IPEcnCriterion) v).ipEcn()));
+ break;
+ case TCP_SRC:
+ m.put(k, matchTcpSrc(((TcpPortCriterion) v).tcpPort()));
+ break;
+ case TCP_DST:
+ m.put(k, matchTcpDst(((TcpPortCriterion) v).tcpPort()));
+ break;
+ case UDP_SRC:
+ m.put(k, matchUdpSrc(((UdpPortCriterion) v).udpPort()));
+ break;
+ case UDP_DST:
+ m.put(k, matchUdpDst(((UdpPortCriterion) v).udpPort()));
+ break;
+ default: //can't be supported by OF1.0
+ log.debug("{} can't be supported by OF1.0", k);
+ break;
+ }
+ }
+ return newOne;
+ }
+
+ /**
+ * Sets the given criterion as a packet header field.
+ *
+ * @param criterion as packet header field
+ * @return the result of set action
+ */
+ public SetHeaderResult setHeader(Criterion criterion) {
+
+ if (criterion == null) {
+ return SETHEADER_FAILURE_NULL;
+ }
+
+ boolean hasKey = match.containsKey(criterion.type());
+
+ match.put(criterion.type(), criterion);
+
+ return hasKey ? SETHEADER_OVERRIDE : SETHEADER_SUCCESS;
+ }
+
+ /**
+ * Deletes a packet header field by the designated header type.
+ *
+ * @param criterionType as packet header type
+ * @return true, if packet contained the corresponding type of header;
+ * false, otherwise
+ */
+ public boolean delHeader(Criterion.Type criterionType) {
+ return match.remove(criterionType) != null;
+ }
+
+ /**
+ * Returns a packet header field value by the designated header type.
+ *
+ * Returns null if the field does not exist.
+ *
+ * @param criterionType as packet header type
+ * @return the packet header field value; may be null
+ */
+ public Criterion getHeader(Criterion.Type criterionType) {
+ return match.get(criterionType);
+ }
+
+ /**
+ * Returns true if there is the type of header field in the packet.
+ *
+ * @param criterionType packet header type
+ * @return true if the field exists; false otherwise
+ */
+ public boolean headerExists(Criterion.Type criterionType) {
+ return match.containsKey(criterionType);
+ }
+
+ /**
+ * Pushes the given flow entry onto the path flow stack.
+ * Packet matches this entry in specific switch hop.
+ *
+ * @param entry the matched entry
+ */
+ public void pushPathFlow(FlowEntry entry) {
+ pathFlow.push(entry);
+ }
+
+ /**
+ * Pops a FlowEntry from path flow entry stack.
+ */
+ public void popPathFlow() {
+ pathFlow.pop();
+ }
+
+ /**
+ * Returns links in the path which the packet passes through.
+ *
+ * @return an iterator over the set of links
+ */
+ public Iterator<Link> getPathLink() {
+ return pathLink.iterator();
+ }
+
+ /**
+ * Adds a Link to path link list.
+ * Packet goes through this link between two switches.
+ *
+ * @param link The link through which the packet go
+ */
+ public void pushPathLink(Link link) {
+ // TODO - need CPY link manual?
+ pathLink.push(link);
+ }
+
+ /**
+ * Removes a Link from path link list.
+ */
+ public void popPathLink() {
+ pathLink.pop();
+ }
+
+ /**
+ * Returns true if the packet passed through the specific device.
+ *
+ * @param deviceId identify of the divice to test
+ * @return true if packet passed through the specific device;
+ * false otherwise
+ */
+ public boolean isPassedDevice(DeviceId deviceId) {
+ for (Link linkTemp : pathLink) {
+ if (deviceId.equals(linkTemp.src().deviceId())) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Returns the IN_PORT header field of the packet.
+ *
+ * Attention:
+ * IN_PORT field will be changed when packet goes into the next switch hop.
+ *
+ * @return a port criterion object.
+ */
+ public PortCriterion getInport() {
+ // TODO - check IN_PORT or IN_PHY_PORT
+ return (PortCriterion) match.get(Criterion.Type.IN_PORT);
+ }
+
+ /**
+ * Creates and returns a loop packet instance with given Match Fields.
+ *
+ * Returns null,
+ * whenever SetHeader_FAILURE or SETHEADER_FAILURE_NULL happened.
+ *
+ * @param criteria match field of one flow entry
+ * @param collision as return value;
+ * true, if criteria contain multiple ones with same type
+ * @return a new loop packet instance; may be null
+ */
+ public static TsLoopPacket matchBuilder(Iterable<Criterion> criteria,
+ TsReturn<Boolean> collision) {
+
+ if (null != collision) {
+ collision.setValue(false);
+ }
+
+ TsLoopPacket pkt = new TsLoopPacket();
+
+ for (Criterion criterion : criteria) {
+
+ SetHeaderResult ret = pkt.setHeader(criterion);
+
+ if (SETHEADER_SUCCESS == ret) {
+ //TODO - in the future, we may need to resolve this condition
+ } else if (SETHEADER_OVERRIDE == ret) {
+ if (null != collision) {
+ collision.setValue(true);
+ }
+ } else { // SetHeader_FAILURE or SetHeader_FAILURE_NULL
+ pkt = null;
+ break;
+ }
+ }
+
+ return pkt;
+ }
+
+ /**
+ * Hands in the header of virtual packet one by one.
+ * Let the header go up through every layer of recursion.
+ * It is called when a loop is discovered.
+ *
+ * @param loopPkt virtual packet that will trigger Loop Storm
+ */
+ public void handInLoopMatch(TsLoopPacket loopPkt) {
+ match = loopPkt.match;
+ }
+
+ /**
+ * Resets the path link and path flow structures.
+ * And initializing the path flow with the gicen flow entry.
+ *
+ * @param firstEntry the flow entry from which this packet is built
+ */
+ public void resetLinkFlow(FlowEntry firstEntry) {
+ pathLink = new Stack<>();
+ pathFlow = new Stack<>();
+ pathFlow.push(firstEntry);
+ }
+
+ private static String makeHeader(String title) {
+ return String.format(HDR_FMT, title);
+ }
+
+ /**
+ * Returns a multi-line string representation of this loop packet instance.
+ *
+ * @return formatted string
+ */
+ @Override
+ public String toString() {
+ StringBuilder me = new StringBuilder();
+
+ me.append(LINE);
+
+ me.append(LOOP_HEADER);
+
+ List<Criterion> criteria = new ArrayList<>(match.values());
+ Collections.sort(criteria, (o1, o2) -> o1.type().compareTo(o2.type()));
+
+ for (Criterion c : criteria) {
+ me.append(c).append(EOL);
+ }
+
+ me.append(LOOP_FLOW_ENTRIES);
+
+ for (FlowEntry flow : pathFlow) {
+ me.append(flow).append(EOL);
+ }
+
+ me.append(LOOP_LINKS);
+
+ for (Link l : pathLink) {
+ me.append(l).append(EOL);
+ }
+
+ return me.toString();
+ }
+}
diff --git a/apps/network-troubleshoot/api/src/main/java/org/onosproject/fnl/base/TsReturn.java b/apps/network-troubleshoot/api/src/main/java/org/onosproject/fnl/base/TsReturn.java
new file mode 100644
index 0000000..f0f56d5
--- /dev/null
+++ b/apps/network-troubleshoot/api/src/main/java/org/onosproject/fnl/base/TsReturn.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2015-present 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.fnl.base;
+
+/**
+ * Represents an additional value that a caller may pass to a method.
+ * Be filled in by the called method.
+ *
+ * Used as an extra return value.
+ *
+ * @param <M> the class of expected return value
+ */
+public final class TsReturn<M> {
+ private M ret;
+
+ /**
+ * Sets the value of this instance.
+ *
+ * @param value the value to set
+ */
+ public void setValue(M value) {
+ ret = value;
+ }
+
+ /**
+ * Returns the value of this instance.
+ *
+ * @return the value
+ */
+ public M getValue() {
+ return ret;
+ }
+
+ /**
+ * Returns true if the value has been set.
+ * Generally, if setValue() has not been invoked,
+ * the value will not be present (i.e. null).
+ *
+ * @return true, if ret is present;
+ * false, otherwise
+ */
+ public boolean isPresent() {
+ return ret != null;
+ }
+}
diff --git a/apps/network-troubleshoot/api/src/main/java/org/onosproject/fnl/base/package-info.java b/apps/network-troubleshoot/api/src/main/java/org/onosproject/fnl/base/package-info.java
new file mode 100644
index 0000000..aca2d7b
--- /dev/null
+++ b/apps/network-troubleshoot/api/src/main/java/org/onosproject/fnl/base/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2016-present 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.
+ */
+
+/**
+ * Base and tool classes used in troubleshooting algorithms.
+ */
+package org.onosproject.fnl.base;
diff --git a/apps/network-troubleshoot/api/src/main/java/org/onosproject/fnl/intf/NetworkAnomaly.java b/apps/network-troubleshoot/api/src/main/java/org/onosproject/fnl/intf/NetworkAnomaly.java
new file mode 100644
index 0000000..aa754a7
--- /dev/null
+++ b/apps/network-troubleshoot/api/src/main/java/org/onosproject/fnl/intf/NetworkAnomaly.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2016-present 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.fnl.intf;
+
+/**
+ * Result of network anomaly diagnosis.
+ */
+public interface NetworkAnomaly {
+
+ /**
+ * Returns the type of anomaly result.
+ *
+ * @return the type of anomaly
+ */
+ Type type();
+
+ /**
+ * Represents anomaly types.
+ */
+ enum Type {
+
+ /**
+ * Packets round among several devices with several forwarding entries.
+ *
+ * Routing loops.
+ */
+ LOOP
+ }
+}
diff --git a/apps/network-troubleshoot/api/src/main/java/org/onosproject/fnl/intf/NetworkDiagnostic.java b/apps/network-troubleshoot/api/src/main/java/org/onosproject/fnl/intf/NetworkDiagnostic.java
new file mode 100644
index 0000000..55122f1
--- /dev/null
+++ b/apps/network-troubleshoot/api/src/main/java/org/onosproject/fnl/intf/NetworkDiagnostic.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2015-present 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.fnl.intf;
+
+import java.util.Set;
+
+/**
+ * Provide algorithms or methods to diagnose network.
+ *
+ * Strategy Pattern.
+ */
+public interface NetworkDiagnostic {
+
+ /**
+ * Checks for and returns all corresponding anomalies.
+ * An empty set is returned if there are no anomalies.
+ *
+ * @return the set of all corresponding anomalies; may be empty
+ */
+ Set<NetworkAnomaly> findAnomalies();
+
+ /**
+ * Returns the type of diagnostic.
+ *
+ * @return the type of diagnostic
+ */
+ Type type();
+
+ /**
+ * Represents diagnostic types.
+ */
+ enum Type {
+
+ /**
+ * Packets round among several devices with several forwarding entries.
+ *
+ * Routing loops.
+ */
+ LOOP
+ }
+}
diff --git a/apps/network-troubleshoot/api/src/main/java/org/onosproject/fnl/intf/NetworkDiagnosticService.java b/apps/network-troubleshoot/api/src/main/java/org/onosproject/fnl/intf/NetworkDiagnosticService.java
new file mode 100644
index 0000000..a3086ba
--- /dev/null
+++ b/apps/network-troubleshoot/api/src/main/java/org/onosproject/fnl/intf/NetworkDiagnosticService.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2015-present 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.fnl.intf;
+
+import org.onosproject.fnl.intf.NetworkDiagnostic.Type;
+
+import java.util.Set;
+
+/**
+ * Network Troubleshooting Core Service.
+ */
+public interface NetworkDiagnosticService {
+
+ /**
+ * Checks for and returns all registered kinds of network anomalies.
+ * An empty set is returned if there are no anomalies found.
+ *
+ * @return all discovered anomalies; may be empty
+ */
+ Set<NetworkAnomaly> findAnomalies();
+
+ /**
+ * Checks for and returns the specific kind of network anomalies.
+ * <p>
+ * An empty set is returned if there is no anomaly of specific type,
+ * or there is no diagnostic of specific type.
+ *
+ * @return the specific kind of anomalies; may be empty
+ */
+
+ /**
+ * Checks for and returns the specific type of network anomalies.
+ * <p>
+ * An empty set is returned if there is no anomaly of specific type,
+ * or there is no diagnostic of specific type.
+ *
+ * @param type the type of network anomalies
+ * @return the specific kind of anomalies; may be empty
+ */
+ Set<NetworkAnomaly> findAnomalies(Type type);
+
+ /**
+ * Registers the specified diagnostic module with the service.
+ *
+ * Each diagnostic type can have only one module,
+ * and previous one will be removed.
+ *
+ * @param diagnostic an instance of class implemented NetworkDiagnostic
+ */
+ void register(NetworkDiagnostic diagnostic);
+
+ /**
+ * Unregisters the specified diagnostic module form the service.
+ *
+ * @param diagnostic diagnostic module to be removed
+ * @return true if the module existed before and has been removed
+ * successfully; false otherwise
+ */
+ boolean unregister(NetworkDiagnostic diagnostic);
+}
diff --git a/apps/network-troubleshoot/api/src/main/java/org/onosproject/fnl/intf/package-info.java b/apps/network-troubleshoot/api/src/main/java/org/onosproject/fnl/intf/package-info.java
new file mode 100644
index 0000000..4f7a3b8
--- /dev/null
+++ b/apps/network-troubleshoot/api/src/main/java/org/onosproject/fnl/intf/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2016-present 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.
+ */
+
+/**
+ * Base interfaces for Network Troubleshooting SubSystem.
+ */
+package org.onosproject.fnl.intf;