aboutsummaryrefslogtreecommitdiffstats
path: root/framework/src/onos/cli
diff options
context:
space:
mode:
Diffstat (limited to 'framework/src/onos/cli')
-rw-r--r--framework/src/onos/cli/src/main/java/org/onosproject/cli/Comparators.java10
-rw-r--r--framework/src/onos/cli/src/main/java/org/onosproject/cli/cfg/NetworkConfigCommand.java22
-rw-r--r--framework/src/onos/cli/src/main/java/org/onosproject/cli/cfg/NetworkConfigRegistryCommand.java2
-rw-r--r--framework/src/onos/cli/src/main/java/org/onosproject/cli/net/DeviceControllersCommand.java47
-rw-r--r--framework/src/onos/cli/src/main/java/org/onosproject/cli/net/DevicePortsListCommand.java44
-rw-r--r--framework/src/onos/cli/src/main/java/org/onosproject/cli/net/DeviceSetControllersCommand.java69
-rw-r--r--framework/src/onos/cli/src/main/java/org/onosproject/cli/net/GetFlowStatistics.java323
-rw-r--r--framework/src/onos/cli/src/main/java/org/onosproject/cli/net/InterfaceAddCommand.java79
-rw-r--r--framework/src/onos/cli/src/main/java/org/onosproject/cli/net/InterfaceRemoveCommand.java51
-rw-r--r--framework/src/onos/cli/src/main/java/org/onosproject/cli/net/PacketProcessorsListCommand.java10
-rw-r--r--framework/src/onos/cli/src/main/java/org/onosproject/cli/net/TableStatisticsCommand.java145
-rw-r--r--framework/src/onos/cli/src/main/resources/OSGI-INF/blueprint/shell-config.xml36
12 files changed, 813 insertions, 25 deletions
diff --git a/framework/src/onos/cli/src/main/java/org/onosproject/cli/Comparators.java b/framework/src/onos/cli/src/main/java/org/onosproject/cli/Comparators.java
index b0cbbdd6..1df2f049 100644
--- a/framework/src/onos/cli/src/main/java/org/onosproject/cli/Comparators.java
+++ b/framework/src/onos/cli/src/main/java/org/onosproject/cli/Comparators.java
@@ -25,6 +25,8 @@ import org.onosproject.net.ElementId;
import org.onosproject.net.Port;
import org.onosproject.net.flow.FlowRule;
import org.onosproject.net.group.Group;
+
+import org.onosproject.net.statistic.TypedFlowEntryWithLoad;
import org.onosproject.net.topology.TopologyCluster;
import java.util.Comparator;
@@ -115,4 +117,12 @@ public final class Comparators {
public static final Comparator<Interface> INTERFACES_COMPARATOR = (intf1, intf2) ->
CONNECT_POINT_COMPARATOR.compare(intf1.connectPoint(), intf2.connectPoint());
+ public static final Comparator<TypedFlowEntryWithLoad> TYPEFLOWENTRY_WITHLOAD_COMPARATOR =
+ new Comparator<TypedFlowEntryWithLoad>() {
+ @Override
+ public int compare(TypedFlowEntryWithLoad fe1, TypedFlowEntryWithLoad fe2) {
+ long delta = fe1.load().rate() - fe2.load().rate();
+ return delta == 0 ? 0 : (delta > 0 ? -1 : +1);
+ }
+ };
}
diff --git a/framework/src/onos/cli/src/main/java/org/onosproject/cli/cfg/NetworkConfigCommand.java b/framework/src/onos/cli/src/main/java/org/onosproject/cli/cfg/NetworkConfigCommand.java
index d99a1839..7ce56692 100644
--- a/framework/src/onos/cli/src/main/java/org/onosproject/cli/cfg/NetworkConfigCommand.java
+++ b/framework/src/onos/cli/src/main/java/org/onosproject/cli/cfg/NetworkConfigCommand.java
@@ -35,13 +35,13 @@ import static com.google.common.base.Strings.isNullOrEmpty;
description = "Manages network configuration")
public class NetworkConfigCommand extends AbstractShellCommand {
- @Argument(index = 0, name = "subjectKey", description = "Subject key",
+ @Argument(index = 0, name = "subjectClassKey", description = "Subject class key",
required = false, multiValued = false)
- String subjectKey = null;
+ String subjectClassKey = null;
- @Argument(index = 1, name = "subject", description = "Subject",
+ @Argument(index = 1, name = "subjectKey", description = "Subject key",
required = false, multiValued = false)
- String subject = null;
+ String subjectKey = null;
@Argument(index = 2, name = "configKey", description = "Config key",
required = false, multiValued = false)
@@ -54,18 +54,18 @@ public class NetworkConfigCommand extends AbstractShellCommand {
protected void execute() {
service = get(NetworkConfigService.class);
JsonNode root = mapper.createObjectNode();
- if (isNullOrEmpty(subjectKey)) {
+ if (isNullOrEmpty(subjectClassKey)) {
addAll((ObjectNode) root);
} else {
- SubjectFactory subjectFactory = service.getSubjectFactory(subjectKey);
- if (isNullOrEmpty(subject)) {
+ SubjectFactory subjectFactory = service.getSubjectFactory(subjectClassKey);
+ if (isNullOrEmpty(subjectKey)) {
addSubjectClass((ObjectNode) root, subjectFactory);
} else {
- Object s = subjectFactory.createSubject(subject);
+ Object s = subjectFactory.createSubject(subjectKey);
if (isNullOrEmpty(configKey)) {
addSubject((ObjectNode) root, s);
} else {
- root = getSubjectConfig(getConfig(s, subjectKey, configKey));
+ root = getSubjectConfig(getConfig(s, subjectClassKey, configKey));
}
}
}
@@ -82,14 +82,14 @@ public class NetworkConfigCommand extends AbstractShellCommand {
service.getSubjectClasses()
.forEach(sc -> {
SubjectFactory sf = service.getSubjectFactory(sc);
- addSubjectClass(newObject(root, sf.subjectKey()), sf);
+ addSubjectClass(newObject(root, sf.subjectClassKey()), sf);
});
}
@SuppressWarnings("unchecked")
private void addSubjectClass(ObjectNode root, SubjectFactory sf) {
service.getSubjects(sf.subjectClass())
- .forEach(s -> addSubject(newObject(root, s.toString()), s));
+ .forEach(s -> addSubject(newObject(root, sf.subjectKey(s)), s));
}
private void addSubject(ObjectNode root, Object s) {
diff --git a/framework/src/onos/cli/src/main/java/org/onosproject/cli/cfg/NetworkConfigRegistryCommand.java b/framework/src/onos/cli/src/main/java/org/onosproject/cli/cfg/NetworkConfigRegistryCommand.java
index f94967e1..cf588770 100644
--- a/framework/src/onos/cli/src/main/java/org/onosproject/cli/cfg/NetworkConfigRegistryCommand.java
+++ b/framework/src/onos/cli/src/main/java/org/onosproject/cli/cfg/NetworkConfigRegistryCommand.java
@@ -42,7 +42,7 @@ public class NetworkConfigRegistryCommand extends AbstractShellCommand {
private void print(ConfigFactory configFactory) {
print(shortOnly ? SHORT_FMT : FMT,
- configFactory.subjectFactory().subjectKey(),
+ configFactory.subjectFactory().subjectClassKey(),
configFactory.configKey(),
configFactory.subjectFactory().subjectClass().getName(),
configFactory.configClass().getName());
diff --git a/framework/src/onos/cli/src/main/java/org/onosproject/cli/net/DeviceControllersCommand.java b/framework/src/onos/cli/src/main/java/org/onosproject/cli/net/DeviceControllersCommand.java
new file mode 100644
index 00000000..328d4700
--- /dev/null
+++ b/framework/src/onos/cli/src/main/java/org/onosproject/cli/net/DeviceControllersCommand.java
@@ -0,0 +1,47 @@
+/*
+ * 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.cli.net;
+
+import org.apache.karaf.shell.commands.Argument;
+import org.apache.karaf.shell.commands.Command;
+import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.behaviour.ControllerConfig;
+import org.onosproject.net.driver.DriverHandler;
+import org.onosproject.net.driver.DriverService;
+
+/**
+ * Sets role of the controller node for the given infrastructure device.
+ */
+@Command(scope = "onos", name = "device-controllers",
+ description = "gets the list of controllers for the given infrastructure device")
+public class DeviceControllersCommand extends AbstractShellCommand {
+
+ @Argument(index = 0, name = "uri", description = "Device ID",
+ required = true, multiValued = false)
+ String uri = null;
+ private DeviceId deviceId;
+
+ @Override
+ protected void execute() {
+ DriverService service = get(DriverService.class);
+ deviceId = DeviceId.deviceId(uri);
+ DriverHandler h = service.createHandler(deviceId);
+ ControllerConfig config = h.behaviour(ControllerConfig.class);
+ config.getControllers().forEach(c -> print(c.target()));
+ }
+
+}
diff --git a/framework/src/onos/cli/src/main/java/org/onosproject/cli/net/DevicePortsListCommand.java b/framework/src/onos/cli/src/main/java/org/onosproject/cli/net/DevicePortsListCommand.java
index 494273cc..e2d3e6d6 100644
--- a/framework/src/onos/cli/src/main/java/org/onosproject/cli/net/DevicePortsListCommand.java
+++ b/framework/src/onos/cli/src/main/java/org/onosproject/cli/net/DevicePortsListCommand.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2014 Open Networking Laboratory
+ * 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.
@@ -22,8 +22,12 @@ import com.fasterxml.jackson.databind.node.ObjectNode;
import org.apache.karaf.shell.commands.Argument;
import org.apache.karaf.shell.commands.Command;
import org.apache.karaf.shell.commands.Option;
+import org.onlab.util.Frequency;
import org.onosproject.cli.Comparators;
import org.onosproject.net.Device;
+import org.onosproject.net.OchPort;
+import org.onosproject.net.OduCltPort;
+import org.onosproject.net.OmsPort;
import org.onosproject.net.Port;
import org.onosproject.net.PortNumber;
import org.onosproject.net.device.DeviceService;
@@ -41,7 +45,10 @@ import static org.onosproject.net.DeviceId.deviceId;
description = "Lists all ports or all ports of a device")
public class DevicePortsListCommand extends DevicesListCommand {
- private static final String FMT = " port=%s, state=%s, type=%s, speed=%s%s";
+ private static final String FMT = " port=%s, state=%s, type=%s, speed=%s %s";
+ private static final String FMT_OCH = " port=%s, state=%s, type=%s, signalType=%s, isTunable=%s %s";
+ private static final String FMT_ODUCLT = " port=%s, state=%s, type=%s, signalType=%s %s";
+ private static final String FMT_OMS = " port=%s, state=%s, type=%s, Freqs= %s / %s / %s GHz, totalChannels=%s %s";
@Option(name = "-e", aliases = "--enabled", description = "Show only enabled ports",
required = false, multiValued = false)
@@ -137,13 +144,34 @@ public class DevicePortsListCommand extends DevicesListCommand {
List<Port> ports = new ArrayList<>(service.getPorts(device.id()));
Collections.sort(ports, Comparators.PORT_COMPARATOR);
for (Port port : ports) {
- if (isIncluded(port)) {
- print(FMT, portName(port.number()),
- port.isEnabled() ? "enabled" : "disabled",
- port.type().toString().toLowerCase(), port.portSpeed(),
- annotations(port.annotations()));
+ if (!isIncluded(port)) {
+ continue;
+ }
+ String portName = portName(port.number());
+ Object portIsEnabled = port.isEnabled() ? "enabled" : "disabled";
+ String portType = port.type().toString().toLowerCase();
+ String annotations = annotations(port.annotations());
+ switch (port.type()) {
+ case OCH:
+ print(FMT_OCH, portName, portIsEnabled, portType,
+ ((OchPort) port).signalType().toString(),
+ ((OchPort) port).isTunable() ? "yes" : "no", annotations);
+ break;
+ case ODUCLT:
+ print(FMT_ODUCLT, portName, portIsEnabled, portType,
+ ((OduCltPort) port).signalType().toString(), annotations);
+ break;
+ case OMS:
+ print(FMT_OMS, portName, portIsEnabled, portType,
+ ((OmsPort) port).minFrequency().asHz() / Frequency.ofGHz(1).asHz(),
+ ((OmsPort) port).maxFrequency().asHz() / Frequency.ofGHz(1).asHz(),
+ ((OmsPort) port).grid().asHz() / Frequency.ofGHz(1).asHz(),
+ ((OmsPort) port).totalChannels(), annotations);
+ break;
+ default:
+ print(FMT, portName, portIsEnabled, portType, port.portSpeed(), annotations);
+ break;
}
}
}
-
}
diff --git a/framework/src/onos/cli/src/main/java/org/onosproject/cli/net/DeviceSetControllersCommand.java b/framework/src/onos/cli/src/main/java/org/onosproject/cli/net/DeviceSetControllersCommand.java
new file mode 100644
index 00000000..c3693799
--- /dev/null
+++ b/framework/src/onos/cli/src/main/java/org/onosproject/cli/net/DeviceSetControllersCommand.java
@@ -0,0 +1,69 @@
+/*
+ * 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.cli.net;
+
+import org.apache.karaf.shell.commands.Argument;
+import org.apache.karaf.shell.commands.Command;
+import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.behaviour.ControllerConfig;
+import org.onosproject.net.behaviour.ControllerInfo;
+import org.onosproject.net.driver.DriverHandler;
+import org.onosproject.net.driver.DriverService;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Sets role of the controller node for the given infrastructure device.
+ */
+@Command(scope = "onos", name = "device-setcontrollers",
+ description = "sets the list of controllers for the given infrastructure device")
+public class DeviceSetControllersCommand extends AbstractShellCommand {
+
+ @Argument(index = 0, name = "uri", description = "Device ID",
+ required = true, multiValued = false)
+ String uri = null;
+
+ @Argument(index = 1, name = "controllersListStrings", description = "list of " +
+ "controllers to set for the specified device",
+ required = true, multiValued = true)
+ String[] controllersListStrings = null;
+
+ private DeviceId deviceId;
+ private List<ControllerInfo> newControllers = new ArrayList<>();
+
+ @Override
+ protected void execute() {
+
+ Arrays.asList(controllersListStrings).forEach(
+ cInfoString -> newControllers.add(new ControllerInfo(cInfoString)));
+ DriverService service = get(DriverService.class);
+ deviceId = DeviceId.deviceId(uri);
+ DriverHandler h = service.createHandler(deviceId);
+ ControllerConfig config = h.behaviour(ControllerConfig.class);
+ print("before:");
+ config.getControllers().forEach(c -> print(c.target()));
+
+ config.setControllers(newControllers);
+ print("after:");
+ config.getControllers().forEach(c -> print(c.target()));
+ print("size %d", config.getControllers().size());
+ }
+
+}
diff --git a/framework/src/onos/cli/src/main/java/org/onosproject/cli/net/GetFlowStatistics.java b/framework/src/onos/cli/src/main/java/org/onosproject/cli/net/GetFlowStatistics.java
new file mode 100644
index 00000000..cafe87f9
--- /dev/null
+++ b/framework/src/onos/cli/src/main/java/org/onosproject/cli/net/GetFlowStatistics.java
@@ -0,0 +1,323 @@
+/*
+ * 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.cli.net;
+
+import org.apache.karaf.shell.commands.Argument;
+import org.apache.karaf.shell.commands.Command;
+import org.apache.karaf.shell.commands.Option;
+import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.Device;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Port;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.flow.TypedStoredFlowEntry;
+import org.onosproject.net.flow.instructions.Instruction;
+import org.onosproject.net.statistic.FlowStatisticService;
+import org.onosproject.net.statistic.SummaryFlowEntryWithLoad;
+import org.onosproject.net.statistic.TypedFlowEntryWithLoad;
+
+import java.util.List;
+import java.util.Map;
+
+import static org.onosproject.net.DeviceId.deviceId;
+import static org.onosproject.net.PortNumber.portNumber;
+
+/**
+ * Fetches flow statistics with a flow type and instruction type.
+ */
+@Command(scope = "onos", name = "get-flow-stats",
+ description = "Fetches flow stats for a connection point with given flow type and instruction type")
+public class GetFlowStatistics extends AbstractShellCommand {
+ @Argument(index = 0, name = "devicePort",
+ description = "Device[/Port] connectPoint Description",
+ required = true, multiValued = false)
+ String devicePort = null;
+
+ @Option(name = "-s", aliases = "--summary",
+ description = "Show flow stats summary",
+ required = false, multiValued = false)
+ boolean showSummary = true; // default summary
+
+ @Option(name = "-a", aliases = "--all",
+ description = "Show flow stats all",
+ required = false, multiValued = false)
+ boolean showAll = false;
+
+ @Option(name = "-t", aliases = "--topn",
+ description = "Show flow stats topn",
+ required = false, multiValued = false)
+ String showTopn = null;
+
+ @Option(name = "-f", aliases = "--flowType",
+ description = "Flow live type, It includes IMMEDIATE, SHORT, MID, LONG, UNKNOWN"
+ + ", and is valid with -a or -t option only",
+ required = false, multiValued = false)
+ String flowLiveType = null;
+
+ @Option(name = "-i", aliases = "--instructionType",
+ description = "Flow instruction type, It includes DROP, OUTPUT, GROUP, L0MODIFICATION, L2MODIFICATION,"
+ + " TABLE, L3MODIFICATION, METADATA"
+ + ", and is valid with -a or -t option only",
+ required = false, multiValued = false)
+ String instructionType = null;
+
+ @Override
+ protected void execute() {
+ DeviceService deviceService = get(DeviceService.class);
+ FlowStatisticService flowStatsService = get(FlowStatisticService.class);
+
+ String deviceURI = getDeviceId(devicePort);
+ String portURI = getPortNumber(devicePort);
+
+ DeviceId ingressDeviceId = deviceId(deviceURI);
+ PortNumber ingressPortNumber;
+ if (portURI.length() == 0) {
+ ingressPortNumber = null;
+ } else {
+ ingressPortNumber = portNumber(portURI);
+ }
+
+ Device device = deviceService.getDevice(ingressDeviceId);
+ if (device == null) {
+ error("No such device %s", ingressDeviceId.uri());
+ return;
+ }
+
+ if (ingressPortNumber != null) {
+ Port port = deviceService.getPort(ingressDeviceId, ingressPortNumber);
+ if (port == null) {
+ error("No such port %s on device %s", portURI, ingressDeviceId.uri());
+ return;
+ }
+ }
+
+ if (flowLiveType != null) {
+ flowLiveType = flowLiveType.toUpperCase();
+ }
+ if (instructionType != null) {
+ instructionType = instructionType.toUpperCase();
+ }
+
+ // convert String to FlowLiveType and check validity
+ TypedStoredFlowEntry.FlowLiveType inLiveType;
+ if (flowLiveType == null) {
+ inLiveType = null;
+ } else {
+ inLiveType = getFlowLiveType(flowLiveType);
+ if (inLiveType == null) {
+ error("Invalid flow live type [%s] error", flowLiveType);
+ return;
+ }
+ }
+ // convert String to InstructionType and check validity
+ Instruction.Type inInstructionType;
+ if (instructionType == null) {
+ inInstructionType = null;
+ } else {
+ inInstructionType = getInstructionType(instructionType);
+ if (inInstructionType == null) {
+ error("Invalid instruction type [%s] error", instructionType);
+ return;
+ }
+ }
+
+ if (showTopn != null) {
+ int topn = Integer.parseInt(showTopn);
+
+ if (topn <= 0) {
+ topn = 100; //default value
+ } else if (topn > 1000) {
+ topn = 1000; //max value
+ }
+
+ // print show topn head line with type
+ print("deviceId=%s, show TOPN=%s flows, live type=%s, instruction type=%s",
+ deviceURI,
+ Integer.toString(topn),
+ flowLiveType == null ? "ALL" : flowLiveType,
+ instructionType == null ? "ALL" : instructionType);
+ if (ingressPortNumber == null) {
+ Map<ConnectPoint, List<TypedFlowEntryWithLoad>> typedFlowLoadMap =
+ flowStatsService.loadTopnByType(device, inLiveType, inInstructionType, topn);
+ // print all ports topn flows load for a given device
+ for (ConnectPoint cp : typedFlowLoadMap.keySet()) {
+ printPortFlowsLoad(cp, typedFlowLoadMap.get(cp));
+ }
+ } else {
+ List<TypedFlowEntryWithLoad> typedFlowLoad =
+ flowStatsService.loadTopnByType(device, ingressPortNumber, inLiveType, inInstructionType, topn);
+ // print device/port topn flows load
+ ConnectPoint cp = new ConnectPoint(ingressDeviceId, ingressPortNumber);
+ printPortFlowsLoad(cp, typedFlowLoad);
+ }
+ } else if (showAll) { // is true?
+ // print show all head line with type
+ print("deviceId=%s, show ALL flows, live type=%s, instruction type=%s",
+ deviceURI,
+ flowLiveType == null ? "ALL" : flowLiveType,
+ instructionType == null ? "ALL" : instructionType);
+ if (ingressPortNumber == null) {
+ Map<ConnectPoint, List<TypedFlowEntryWithLoad>> typedFlowLoadMap =
+ flowStatsService.loadAllByType(device, inLiveType, inInstructionType);
+ // print all ports all flows load for a given device
+ for (ConnectPoint cp : typedFlowLoadMap.keySet()) {
+ printPortFlowsLoad(cp, typedFlowLoadMap.get(cp));
+ }
+ } else {
+ List<TypedFlowEntryWithLoad> typedFlowLoad =
+ flowStatsService.loadAllByType(device, ingressPortNumber, inLiveType, inInstructionType);
+ // print device/port all flows load
+ ConnectPoint cp = new ConnectPoint(ingressDeviceId, ingressPortNumber);
+ printPortFlowsLoad(cp, typedFlowLoad);
+ }
+ } else { // if (showSummary == true) //always is true
+ // print show summary head line
+ print("deviceId=%s, show SUMMARY flows", deviceURI);
+ if (ingressPortNumber == null) {
+ Map<ConnectPoint, SummaryFlowEntryWithLoad> summaryFlowLoadMap =
+ flowStatsService.loadSummary(device);
+ // print all ports flow load summary for a given device
+ for (ConnectPoint cp : summaryFlowLoadMap.keySet()) {
+ printPortSummaryLoad(cp, summaryFlowLoadMap.get(cp));
+ }
+ } else {
+ SummaryFlowEntryWithLoad summaryFlowLoad =
+ flowStatsService.loadSummary(device, ingressPortNumber);
+ // print device/port flow load summary
+ ConnectPoint cp = new ConnectPoint(ingressDeviceId, ingressPortNumber);
+ printPortSummaryLoad(cp, summaryFlowLoad);
+ }
+ }
+ }
+
+ /**
+ * Extracts the port number portion of the ConnectPoint.
+ *
+ * @param deviceString string representing the device/port
+ * @return port number as a string, empty string if the port is not found
+ */
+ private String getPortNumber(String deviceString) {
+ if (deviceString == null) {
+ return "";
+ }
+
+ int slash = deviceString.indexOf('/');
+ if (slash <= 0) {
+ return ""; // return when no port number
+ }
+ return deviceString.substring(slash + 1, deviceString.length());
+ }
+
+ /**
+ * Extracts the device ID portion of the ConnectPoint.
+ *
+ * @param deviceString string representing the device/port
+ * @return device ID string
+ */
+ private String getDeviceId(String deviceString) {
+ if (deviceString == null) {
+ return "";
+ }
+
+ int slash = deviceString.indexOf('/');
+ if (slash <= 0) {
+ return deviceString; // return only included device ID
+ }
+ return deviceString.substring(0, slash);
+ }
+
+ /**
+ * converts string of flow live type to FloeLiveType enum.
+ *
+ * @param liveType string representing the flow live type
+ * @return TypedStoredFlowEntry.FlowLiveType
+ */
+ private TypedStoredFlowEntry.FlowLiveType getFlowLiveType(String liveType) {
+ String liveTypeUC = liveType.toUpperCase();
+
+ if (liveTypeUC.equals("IMMEDIATE")) {
+ return TypedStoredFlowEntry.FlowLiveType.IMMEDIATE_FLOW;
+ } else if (liveTypeUC.equals("SHORT")) {
+ return TypedStoredFlowEntry.FlowLiveType.SHORT_FLOW;
+ } else if (liveTypeUC.equals("MID")) {
+ return TypedStoredFlowEntry.FlowLiveType.MID_FLOW;
+ } else if (liveTypeUC.equals("LONG")) {
+ return TypedStoredFlowEntry.FlowLiveType.LONG_FLOW;
+ } else if (liveTypeUC.equals("UNKNOWN")) {
+ return TypedStoredFlowEntry.FlowLiveType.UNKNOWN_FLOW;
+ } else {
+ return null; // flow live type error
+ }
+ }
+
+ /**
+ * converts string of instruction type to Instruction type enum.
+ *
+ * @param instType string representing the instruction type
+ * @return Instruction.Type
+ */
+ private Instruction.Type getInstructionType(String instType) {
+ String instTypeUC = instType.toUpperCase();
+
+ if (instTypeUC.equals("DROP")) {
+ return Instruction.Type.DROP;
+ } else if (instTypeUC.equals("OUTPUT")) {
+ return Instruction.Type.OUTPUT;
+ } else if (instTypeUC.equals("GROUP")) {
+ return Instruction.Type.GROUP;
+ } else if (instTypeUC.equals("L0MODIFICATION")) {
+ return Instruction.Type.L0MODIFICATION;
+ } else if (instTypeUC.equals("L2MODIFICATION")) {
+ return Instruction.Type.L2MODIFICATION;
+ } else if (instTypeUC.equals("TABLE")) {
+ return Instruction.Type.TABLE;
+ } else if (instTypeUC.equals("L3MODIFICATION")) {
+ return Instruction.Type.L3MODIFICATION;
+ } else if (instTypeUC.equals("METADATA")) {
+ return Instruction.Type.METADATA;
+ } else {
+ return null; // instruction type error
+ }
+ }
+
+ private void printPortFlowsLoad(ConnectPoint cp, List<TypedFlowEntryWithLoad> typedFlowLoad) {
+ print(" deviceId/Port=%s/%s, %s flows", cp.elementId(), cp.port(), typedFlowLoad.size());
+ for (TypedFlowEntryWithLoad tfel: typedFlowLoad) {
+ TypedStoredFlowEntry tfe = tfel.typedStoredFlowEntry();
+ print(" flowId=%s, state=%s, liveType=%s, life=%s -> %s",
+ Long.toHexString(tfe.id().value()),
+ tfe.state(),
+ tfe.flowLiveType(),
+ tfe.life(),
+ tfel.load().isValid() ? tfel.load() : "Load{rate=0, NOT VALID}");
+ }
+ }
+
+ private void printPortSummaryLoad(ConnectPoint cp, SummaryFlowEntryWithLoad summaryFlowLoad) {
+ print(" deviceId/Port=%s/%s, Total=%s, Immediate=%s, Short=%s, Mid=%s, Long=%s, Unknown=%s",
+ cp.elementId(),
+ cp.port(),
+ summaryFlowLoad.totalLoad().isValid() ? summaryFlowLoad.totalLoad() : "Load{rate=0, NOT VALID}",
+ summaryFlowLoad.immediateLoad().isValid() ? summaryFlowLoad.immediateLoad() : "Load{rate=0, NOT VALID}",
+ summaryFlowLoad.shortLoad().isValid() ? summaryFlowLoad.shortLoad() : "Load{rate=0, NOT VALID}",
+ summaryFlowLoad.midLoad().isValid() ? summaryFlowLoad.midLoad() : "Load{rate=0, NOT VALID}",
+ summaryFlowLoad.longLoad().isValid() ? summaryFlowLoad.longLoad() : "Load{rate=0, NOT VALID}",
+ summaryFlowLoad.unknownLoad().isValid() ? summaryFlowLoad.unknownLoad() : "Load{rate=0, NOT VALID}");
+ }
+}
diff --git a/framework/src/onos/cli/src/main/java/org/onosproject/cli/net/InterfaceAddCommand.java b/framework/src/onos/cli/src/main/java/org/onosproject/cli/net/InterfaceAddCommand.java
new file mode 100644
index 00000000..eefb711a
--- /dev/null
+++ b/framework/src/onos/cli/src/main/java/org/onosproject/cli/net/InterfaceAddCommand.java
@@ -0,0 +1,79 @@
+/*
+ * 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.cli.net;
+
+import com.google.common.collect.Sets;
+import org.apache.karaf.shell.commands.Command;
+import org.apache.karaf.shell.commands.Option;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.VlanId;
+import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.incubator.net.intf.Interface;
+import org.onosproject.incubator.net.intf.InterfaceAdminService;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.host.InterfaceIpAddress;
+
+import java.util.Set;
+
+/**
+ * Adds a new interface configuration.
+ */
+@Command(scope = "onos", name = "add-interface",
+ description = "Adds a new configured interface")
+public class InterfaceAddCommand extends AbstractShellCommand {
+
+ @Option(name = "-c", aliases = "--connectPoint",
+ description = "Device port that the interface is associated with",
+ required = true, multiValued = false)
+ private String connectPoint = null;
+
+ @Option(name = "-m", aliases = "--mac",
+ description = "MAC address of the interface",
+ required = true, multiValued = false)
+ private String mac = null;
+
+ @Option(name = "-i", aliases = "--ip",
+ description = "IP address configured on the interface\n" +
+ "(e.g. 10.0.1.1/24). Can be specified multiple times.",
+ required = false, multiValued = true)
+ private String[] ips = null;
+
+ @Option(name = "-v", aliases = "--vlan",
+ description = "VLAN configured on the interface",
+ required = false, multiValued = false)
+ private String vlan = null;
+
+ @Override
+ protected void execute() {
+ InterfaceAdminService interfaceService = get(InterfaceAdminService.class);
+
+ Set<InterfaceIpAddress> ipAddresses = Sets.newHashSet();
+ if (ips != null) {
+ for (String strIp : ips) {
+ ipAddresses.add(InterfaceIpAddress.valueOf(strIp));
+ }
+ }
+
+ VlanId vlanId = vlan == null ? VlanId.NONE : VlanId.vlanId(Short.parseShort(vlan));
+
+ Interface intf = new Interface(ConnectPoint.deviceConnectPoint(connectPoint),
+ ipAddresses, MacAddress.valueOf(mac), vlanId);
+
+ interfaceService.add(intf);
+ }
+
+}
diff --git a/framework/src/onos/cli/src/main/java/org/onosproject/cli/net/InterfaceRemoveCommand.java b/framework/src/onos/cli/src/main/java/org/onosproject/cli/net/InterfaceRemoveCommand.java
new file mode 100644
index 00000000..941a65db
--- /dev/null
+++ b/framework/src/onos/cli/src/main/java/org/onosproject/cli/net/InterfaceRemoveCommand.java
@@ -0,0 +1,51 @@
+/*
+ * 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.cli.net;
+
+import org.apache.karaf.shell.commands.Argument;
+import org.apache.karaf.shell.commands.Command;
+import org.onlab.packet.VlanId;
+import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.incubator.net.intf.InterfaceAdminService;
+import org.onosproject.net.ConnectPoint;
+
+/**
+ * Removes an interface configuration.
+ */
+@Command(scope = "onos", name = "remove-interface",
+ description = "Removes a configured interface")
+public class InterfaceRemoveCommand extends AbstractShellCommand {
+
+ @Argument(index = 0, name = "connectPoint",
+ description = "Connect point of the interface",
+ required = true, multiValued = false)
+ private String connectPoint = null;
+
+ @Argument(index = 1, name = "vlan",
+ description = "Interface vlan",
+ required = true, multiValued = false)
+ private String vlan = null;
+
+ @Override
+ protected void execute() {
+ InterfaceAdminService interfaceService = get(InterfaceAdminService.class);
+
+ interfaceService.remove(ConnectPoint.deviceConnectPoint(connectPoint),
+ VlanId.vlanId(Short.parseShort(vlan)));
+ }
+
+}
diff --git a/framework/src/onos/cli/src/main/java/org/onosproject/cli/net/PacketProcessorsListCommand.java b/framework/src/onos/cli/src/main/java/org/onosproject/cli/net/PacketProcessorsListCommand.java
index ff66b803..6b7d9336 100644
--- a/framework/src/onos/cli/src/main/java/org/onosproject/cli/net/PacketProcessorsListCommand.java
+++ b/framework/src/onos/cli/src/main/java/org/onosproject/cli/net/PacketProcessorsListCommand.java
@@ -17,7 +17,7 @@ package org.onosproject.cli.net;
import org.apache.karaf.shell.commands.Command;
import org.onosproject.cli.AbstractShellCommand;
-import org.onosproject.net.packet.PacketProcessor;
+import org.onosproject.net.packet.PacketProcessorEntry;
import org.onosproject.net.packet.PacketService;
import static org.onosproject.net.packet.PacketProcessor.ADVISOR_MAX;
@@ -30,7 +30,7 @@ import static org.onosproject.net.packet.PacketProcessor.DIRECTOR_MAX;
description = "Lists packet processors")
public class PacketProcessorsListCommand extends AbstractShellCommand {
- private static final String FMT = "priority=%s, class=%s";
+ private static final String FMT = "priority=%s, class=%s, packets=%d, avgNanos=%d";
@Override
protected void execute() {
@@ -43,8 +43,10 @@ public class PacketProcessorsListCommand extends AbstractShellCommand {
}
}
- private void print(int priority, PacketProcessor processor) {
- print(FMT, priorityFormat(priority), processor.getClass().getName());
+ private void print(PacketProcessorEntry entry) {
+ print(FMT, priorityFormat(entry.priority()),
+ entry.processor().getClass().getName(),
+ entry.invocations(), entry.averageNanos());
}
private String priorityFormat(int priority) {
diff --git a/framework/src/onos/cli/src/main/java/org/onosproject/cli/net/TableStatisticsCommand.java b/framework/src/onos/cli/src/main/java/org/onosproject/cli/net/TableStatisticsCommand.java
new file mode 100644
index 00000000..e0cd72fc
--- /dev/null
+++ b/framework/src/onos/cli/src/main/java/org/onosproject/cli/net/TableStatisticsCommand.java
@@ -0,0 +1,145 @@
+/*
+ * 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.cli.net;
+
+import static com.google.common.collect.Lists.newArrayList;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.SortedMap;
+import java.util.TreeMap;
+
+import org.apache.karaf.shell.commands.Argument;
+import org.apache.karaf.shell.commands.Command;
+import org.apache.karaf.shell.commands.Option;
+import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.cli.Comparators;
+import org.onosproject.net.Device;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.flow.FlowRuleService;
+import org.onosproject.net.flow.TableStatisticsEntry;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+
+/**
+ * Lists port statistic of all ports in the system.
+ */
+@Command(scope = "onos", name = "tablestats",
+ description = "Lists statistics of all tables in the device")
+public class TableStatisticsCommand extends AbstractShellCommand {
+
+ @Option(name = "-t", aliases = "--table", description = "Show human readable table format for statistics",
+ required = false, multiValued = false)
+ private boolean table = false;
+
+ @Argument(index = 0, name = "uri", description = "Device ID",
+ required = false, multiValued = false)
+ String uri = null;
+
+ private static final String FORMAT =
+ " table=%s, active=%s, lookedup=%s, matched=%s";
+
+ @Override
+ protected void execute() {
+ FlowRuleService flowService = get(FlowRuleService.class);
+ DeviceService deviceService = get(DeviceService.class);
+
+ SortedMap<Device, List<TableStatisticsEntry>> deviceTableStats =
+ getSortedTableStats(deviceService, flowService);
+
+ if (outputJson()) {
+ print("%s", json(deviceTableStats.keySet(), deviceTableStats));
+ } else {
+ deviceTableStats.forEach((device, tableStats) -> printTableStats(device, tableStats));
+ }
+ }
+
+ /**
+ * Produces a JSON array of table statistics grouped by the each device.
+ *
+ * @param devices collection of devices
+ * @param deviceTableStats collection of table statistics per each device
+ * @return JSON array
+ */
+ private JsonNode json(Iterable<Device> devices,
+ Map<Device, List<TableStatisticsEntry>> deviceTableStats) {
+ ObjectMapper mapper = new ObjectMapper();
+ ArrayNode result = mapper.createArrayNode();
+ for (Device device : devices) {
+ result.add(json(mapper, device, deviceTableStats.get(device)));
+ }
+ return result;
+ }
+
+ // Produces JSON object with the table statistics of the given device.
+ private ObjectNode json(ObjectMapper mapper,
+ Device device, List<TableStatisticsEntry> tableStats) {
+ ObjectNode result = mapper.createObjectNode();
+ ArrayNode array = mapper.createArrayNode();
+
+ tableStats.forEach(tableStat -> array.add(jsonForEntity(tableStat, TableStatisticsEntry.class)));
+
+ result.put("device", device.id().toString())
+ .put("tableCount", tableStats.size())
+ .set("tables", array);
+ return result;
+ }
+
+ /**
+ * Prints flow table statistics.
+ *
+ * @param d the device
+ * @param tableStats the set of flow table statistics for that device
+ */
+ protected void printTableStats(Device d,
+ List<TableStatisticsEntry> tableStats) {
+ boolean empty = tableStats == null || tableStats.isEmpty();
+ print("deviceId=%s, tableCount=%d", d.id(), empty ? 0 : tableStats.size());
+ if (!empty) {
+ for (TableStatisticsEntry t : tableStats) {
+ print(FORMAT, t.tableId(), t.activeFlowEntries(),
+ t.packetsLookedup(), t.packetsMatched());
+ }
+ }
+ }
+
+ /**
+ * Returns the list of table statistics sorted using the device ID URIs and table IDs.
+ *
+ * @param deviceService device service
+ * @param flowService flow rule service
+ * @return sorted table statistics list
+ */
+ protected SortedMap<Device, List<TableStatisticsEntry>> getSortedTableStats(DeviceService deviceService,
+ FlowRuleService flowService) {
+ SortedMap<Device, List<TableStatisticsEntry>> deviceTableStats = new TreeMap<>(Comparators.ELEMENT_COMPARATOR);
+ List<TableStatisticsEntry> tableStatsList;
+ Iterable<Device> devices = uri == null ? deviceService.getDevices() :
+ Collections.singletonList(deviceService.getDevice(DeviceId.deviceId(uri)));
+ for (Device d : devices) {
+ tableStatsList = newArrayList(flowService.getFlowTableStatistics(d.id()));
+ tableStatsList.sort((p1, p2) -> Integer.valueOf(p1.tableId()).compareTo(Integer.valueOf(p2.tableId())));
+ deviceTableStats.put(d, tableStatsList);
+ }
+ return deviceTableStats;
+ }
+
+}
diff --git a/framework/src/onos/cli/src/main/resources/OSGI-INF/blueprint/shell-config.xml b/framework/src/onos/cli/src/main/resources/OSGI-INF/blueprint/shell-config.xml
index 459ffa96..28461e27 100644
--- a/framework/src/onos/cli/src/main/resources/OSGI-INF/blueprint/shell-config.xml
+++ b/framework/src/onos/cli/src/main/resources/OSGI-INF/blueprint/shell-config.xml
@@ -105,6 +105,18 @@
</completers>
</command>
<command>
+ <action class="org.onosproject.cli.net.DeviceControllersCommand"/>
+ <completers>
+ <ref component-id="deviceIdCompleter"/>
+ </completers>
+ </command>
+ <command>
+ <action class="org.onosproject.cli.net.DeviceSetControllersCommand"/>
+ <completers>
+ <ref component-id="deviceIdCompleter"/>
+ </completers>
+ </command>
+ <command>
<action class="org.onosproject.cli.net.DeviceRemoveCommand"/>
<completers>
<ref component-id="deviceIdCompleter"/>
@@ -222,6 +234,12 @@
</completers>
</command>
<command>
+ <action class="org.onosproject.cli.net.GetFlowStatistics"/>
+ <completers>
+ <ref component-id="deviceIdCompleter"/>
+ </completers>
+ </command>
+ <command>
<action class="org.onosproject.cli.net.AddMultiPointToSinglePointIntentCommand"/>
<completers>
<ref component-id="connectPointCompleter"/>
@@ -333,7 +351,19 @@
<command>
<action class="org.onosproject.cli.net.InterfacesListCommand"/>
</command>
-
+ <command>
+ <action class="org.onosproject.cli.net.InterfaceAddCommand"/>
+ <optional-completers>
+ <entry key="-c" value-ref="connectPointCompleter"/>
+ <entry key="--connectPoint" value-ref="connectPointCompleter"/>
+ </optional-completers>
+ </command>
+ <command>
+ <action class="org.onosproject.cli.net.InterfaceRemoveCommand"/>
+ <completers>
+ <ref component-id="connectPointCompleter"/>
+ </completers>
+ </command>
<command>
<action class="org.onosproject.cli.net.GroupsListCommand"/>
</command>
@@ -343,6 +373,10 @@
</command>
<command>
+ <action class="org.onosproject.cli.net.TableStatisticsCommand"/>
+ </command>
+
+ <command>
<action class="org.onosproject.cli.net.FlowsListCommand"/>
<completers>
<ref component-id="flowRuleStatusCompleter"/>