Merge branch 'master' of ssh://gerrit.onlab.us:29418/onos-next
diff --git a/cli/src/main/java/org/onlab/onos/cli/net/ClusterLinksCommand.java b/cli/src/main/java/org/onlab/onos/cli/net/ClusterLinksCommand.java
index 5285418..246c39e 100644
--- a/cli/src/main/java/org/onlab/onos/cli/net/ClusterLinksCommand.java
+++ b/cli/src/main/java/org/onlab/onos/cli/net/ClusterLinksCommand.java
@@ -16,7 +16,7 @@
public class ClusterLinksCommand extends ClustersListCommand {
@Argument(index = 0, name = "id", description = "Cluster ID",
- required = false, multiValued = false)
+ required = true, multiValued = false)
String id = null;
@Override
@@ -30,5 +30,4 @@
return null;
}
-
}
diff --git a/cli/src/main/java/org/onlab/onos/cli/net/LinksListCommand.java b/cli/src/main/java/org/onlab/onos/cli/net/LinksListCommand.java
index 6c3952d..e62fb05 100644
--- a/cli/src/main/java/org/onlab/onos/cli/net/LinksListCommand.java
+++ b/cli/src/main/java/org/onlab/onos/cli/net/LinksListCommand.java
@@ -33,10 +33,10 @@
}
/**
- * Returns a formated string representing the gien link.
+ * Returns a formatted string representing the given link.
*
* @param link infrastructure link
- * @return formated link string
+ * @return formatted link string
*/
public static String linkString(Link link) {
return String.format(FMT, link.src().deviceId(), link.src().port(),
diff --git a/cli/src/main/java/org/onlab/onos/cli/net/PathListCommand.java b/cli/src/main/java/org/onlab/onos/cli/net/PathListCommand.java
new file mode 100644
index 0000000..114d837
--- /dev/null
+++ b/cli/src/main/java/org/onlab/onos/cli/net/PathListCommand.java
@@ -0,0 +1,43 @@
+package org.onlab.onos.cli.net;
+
+import org.apache.karaf.shell.commands.Argument;
+import org.apache.karaf.shell.commands.Command;
+import org.onlab.onos.net.Path;
+
+import java.util.Set;
+
+import static org.onlab.onos.net.DeviceId.deviceId;
+
+/**
+ * Lists all shortest-paths paths between the specified source and
+ * destination devices.
+ */
+@Command(scope = "onos", name = "paths",
+ description = "Lists all shortest-paths paths between the specified source and destination devices")
+public class PathListCommand extends TopologyCommand {
+
+ private static final String FMT = "src=%s/%s, dst=%s/%s, type=%s";
+
+ @Argument(index = 0, name = "src", description = "Source device ID",
+ required = true, multiValued = false)
+ String src = null;
+
+ @Argument(index = 0, name = "dst", description = "Destination device ID",
+ required = true, multiValued = false)
+ String dst = null;
+
+ @Override
+ protected Object doExecute() throws Exception {
+ init();
+ Set<Path> paths = service.getPaths(topology, deviceId(src), deviceId(dst));
+ for (Path path : paths) {
+ print(pathString(path));
+ }
+ return null;
+ }
+
+ private String pathString(Path path) {
+ return path.toString();
+ }
+
+}
diff --git a/cli/src/main/java/org/onlab/onos/cli/net/TopologyCommand.java b/cli/src/main/java/org/onlab/onos/cli/net/TopologyCommand.java
index a390025..6c141ae 100644
--- a/cli/src/main/java/org/onlab/onos/cli/net/TopologyCommand.java
+++ b/cli/src/main/java/org/onlab/onos/cli/net/TopologyCommand.java
@@ -12,6 +12,7 @@
description = "Lists summary of the current topology")
public class TopologyCommand extends AbstractShellCommand {
+ // TODO: format the time-stamp
private static final String FMT =
"time=%s, devices=%d, links=%d, clusters=%d, paths=%d";
diff --git a/core/api/src/main/java/org/onlab/onos/net/PortNumber.java b/core/api/src/main/java/org/onlab/onos/net/PortNumber.java
index d5fc5f2..93ec91d 100644
--- a/core/api/src/main/java/org/onlab/onos/net/PortNumber.java
+++ b/core/api/src/main/java/org/onlab/onos/net/PortNumber.java
@@ -9,8 +9,17 @@
*/
public final class PortNumber {
+ // TODO: revisit the max and the logical port value assignments
+
private static final long MAX_NUMBER = (2L * Integer.MAX_VALUE) + 1;
+ public static final PortNumber FLOOD = new PortNumber(-1);
+ public static final PortNumber IN_PORT = new PortNumber(-2);
+ public static final PortNumber TABLE = new PortNumber(-3);
+ public static final PortNumber NORMAL = new PortNumber(-4);
+ public static final PortNumber ALL = new PortNumber(-4);
+ public static final PortNumber LOCAL = new PortNumber(-5);
+
private final long number;
// Public creation is prohibited
@@ -39,6 +48,16 @@
}
/**
+ * Indicates whether or not this port number is a reserved logical one or
+ * whether it corresponds to a normal physical port of a device or NIC.
+ *
+ * @return true if logical port number
+ */
+ public boolean isLogical() {
+ return number < 0 || number > MAX_NUMBER;
+ }
+
+ /**
* Returns the backing long value.
*
* @return port number as long
diff --git a/core/api/src/main/java/org/onlab/onos/net/packet/DefaultInboundPacket.java b/core/api/src/main/java/org/onlab/onos/net/packet/DefaultInboundPacket.java
new file mode 100644
index 0000000..8c57adc
--- /dev/null
+++ b/core/api/src/main/java/org/onlab/onos/net/packet/DefaultInboundPacket.java
@@ -0,0 +1,73 @@
+package org.onlab.onos.net.packet;
+
+import org.onlab.onos.net.ConnectPoint;
+import org.onlab.packet.Ethernet;
+
+import java.nio.ByteBuffer;
+import java.util.Objects;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+/**
+ * Default implementation of an immutable inbound packet.
+ */
+public class DefaultInboundPacket implements InboundPacket {
+
+ private final ConnectPoint receivedFrom;
+ private final Ethernet parsed;
+ private final ByteBuffer unparsed;
+
+ /**
+ * Creates an immutable inbound packet.
+ *
+ * @param receivedFrom connection point where received
+ * @param parsed parsed ethernet frame
+ * @param unparsed unparsed raw bytes
+ */
+ public DefaultInboundPacket(ConnectPoint receivedFrom, Ethernet parsed,
+ ByteBuffer unparsed) {
+ this.receivedFrom = receivedFrom;
+ this.parsed = parsed;
+ this.unparsed = unparsed;
+ }
+
+ @Override
+ public ConnectPoint receivedFrom() {
+ return receivedFrom;
+ }
+
+ @Override
+ public Ethernet parsed() {
+ return parsed;
+ }
+
+ @Override
+ public ByteBuffer unparsed() {
+ // FIXME: figure out immutability here
+ return unparsed;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(receivedFrom, parsed, unparsed);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj instanceof InboundPacket) {
+ final DefaultInboundPacket other = (DefaultInboundPacket) obj;
+ return Objects.equals(this.receivedFrom, other.receivedFrom) &&
+ Objects.equals(this.parsed, other.parsed) &&
+ Objects.equals(this.unparsed, other.unparsed);
+ }
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return toStringHelper(this)
+ .add("receivedFrom", receivedFrom)
+ .add("parsed", parsed)
+ .toString();
+ }
+}
diff --git a/core/api/src/main/java/org/onlab/onos/net/packet/DefaultOutboundPacket.java b/core/api/src/main/java/org/onlab/onos/net/packet/DefaultOutboundPacket.java
new file mode 100644
index 0000000..7a55f32
--- /dev/null
+++ b/core/api/src/main/java/org/onlab/onos/net/packet/DefaultOutboundPacket.java
@@ -0,0 +1,55 @@
+package org.onlab.onos.net.packet;
+
+import com.google.common.base.MoreObjects;
+import com.google.common.collect.ImmutableList;
+import org.onlab.onos.net.DeviceId;
+
+import java.nio.ByteBuffer;
+import java.util.List;
+
+/**
+ * Default implementation of an immutable outbound packet.
+ */
+public class DefaultOutboundPacket implements OutboundPacket {
+ private final DeviceId sendThrough;
+ private final List<Treatment> treatments;
+ private final ByteBuffer data;
+
+ /**
+ * Creates an immutable outbound packet.
+ *
+ * @param sendThrough identifier through which to send the packet
+ * @param treatments list of packet treatments
+ * @param data raw packet data
+ */
+ public DefaultOutboundPacket(DeviceId sendThrough,
+ List<Treatment> treatments, ByteBuffer data) {
+ this.sendThrough = sendThrough;
+ this.treatments = ImmutableList.copyOf(treatments);
+ this.data = data;
+ }
+
+ @Override
+ public DeviceId sendThrough() {
+ return sendThrough;
+ }
+
+ @Override
+ public List<Treatment> treatments() {
+ return treatments;
+ }
+
+ @Override
+ public ByteBuffer data() {
+ // FIXME: figure out immutability here
+ return data;
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(this)
+ .add("sendThrough", sendThrough)
+ .add("treatments", treatments)
+ .toString();
+ }
+}
diff --git a/core/api/src/main/java/org/onlab/onos/net/packet/InboundPacket.java b/core/api/src/main/java/org/onlab/onos/net/packet/InboundPacket.java
new file mode 100644
index 0000000..2931c3e
--- /dev/null
+++ b/core/api/src/main/java/org/onlab/onos/net/packet/InboundPacket.java
@@ -0,0 +1,35 @@
+package org.onlab.onos.net.packet;
+
+import org.onlab.onos.net.ConnectPoint;
+import org.onlab.packet.Ethernet;
+
+import java.nio.ByteBuffer;
+
+/**
+ * Represents a data packet intercepted from an infrastructure device.
+ */
+public interface InboundPacket {
+
+ /**
+ * Returns the device and port from where the packet was received.
+ *
+ * @return connection point where received
+ */
+ ConnectPoint receivedFrom();
+
+ /**
+ * Returns the parsed form of the packet.
+ *
+ * @return parsed Ethernet frame; null if the packet is not an Ethernet
+ * frame or one for which there is no parser
+ */
+ Ethernet parsed();
+
+ /**
+ * Unparsed packet data.
+ *
+ * @return raw packet bytes
+ */
+ ByteBuffer unparsed();
+
+}
diff --git a/core/api/src/main/java/org/onlab/onos/net/packet/OutboundPacket.java b/core/api/src/main/java/org/onlab/onos/net/packet/OutboundPacket.java
new file mode 100644
index 0000000..5307f00
--- /dev/null
+++ b/core/api/src/main/java/org/onlab/onos/net/packet/OutboundPacket.java
@@ -0,0 +1,36 @@
+package org.onlab.onos.net.packet;
+
+import org.onlab.onos.net.DeviceId;
+
+import java.nio.ByteBuffer;
+import java.util.List;
+
+/**
+ * Represents an outbound data packet that is to be emitted to network via
+ * an infrastructure device.
+ */
+public interface OutboundPacket {
+
+ /**
+ * Returns the identity of a device through which this packet should be
+ * sent.
+ *
+ * @return device identity
+ */
+ DeviceId sendThrough();
+
+ /**
+ * Returns list of treatments for the outbound packet.
+ *
+ * @return output treatment
+ */
+ List<Treatment> treatments();
+
+ /**
+ * Returns the raw data to be sent.
+ *
+ * @return data to emit
+ */
+ ByteBuffer data();
+
+}
diff --git a/core/api/src/main/java/org/onlab/onos/net/packet/PacketContext.java b/core/api/src/main/java/org/onlab/onos/net/packet/PacketContext.java
new file mode 100644
index 0000000..a9af312
--- /dev/null
+++ b/core/api/src/main/java/org/onlab/onos/net/packet/PacketContext.java
@@ -0,0 +1,55 @@
+package org.onlab.onos.net.packet;
+
+/**
+ * Represents context for processing an inbound packet, and (optionally)
+ * emitting a corresponding outbound packet.
+ */
+public interface PacketContext {
+
+ /**
+ * Returns the time when the packet was received.
+ *
+ * @return the time in millis since start of epoch
+ */
+ long time();
+
+ /**
+ * Returns the inbound packet being processed.
+ *
+ * @return inbound packet
+ */
+ InboundPacket inPacket();
+
+ /**
+ * Returns the view of the outbound packet.
+ *
+ * @return outbound packet
+ */
+ OutboundPacket outPacket();
+
+ /**
+ * Appends a new treatment to be applied to the outbound packet.
+ *
+ * @param treatment output treatment
+ */
+ void appendTreatment(Treatment treatment);
+
+ /**
+ * Triggers the outbound packet to be sent.
+ */
+ void send();
+
+ /**
+ * Blocks the outbound packet from being sent from this point onward.
+ */
+ void block();
+
+ /**
+ * Indicates whether the packet has already been handled, i.e. sent or
+ * blocked.
+ *
+ * @return true if sent or blocked
+ */
+ boolean isHandled();
+
+}
diff --git a/core/api/src/main/java/org/onlab/onos/net/packet/PacketProcessor.java b/core/api/src/main/java/org/onlab/onos/net/packet/PacketProcessor.java
new file mode 100644
index 0000000..a53a08c
--- /dev/null
+++ b/core/api/src/main/java/org/onlab/onos/net/packet/PacketProcessor.java
@@ -0,0 +1,15 @@
+package org.onlab.onos.net.packet;
+
+/**
+ * Abstraction of an inbound packet processor.
+ */
+public interface PacketProcessor {
+
+ /**
+ * Processes the inbound packet as specified in the given context.
+ *
+ * @param context packet processing context
+ */
+ void process(PacketContext context);
+
+}
diff --git a/core/api/src/main/java/org/onlab/onos/net/packet/PacketProvider.java b/core/api/src/main/java/org/onlab/onos/net/packet/PacketProvider.java
new file mode 100644
index 0000000..14597ee
--- /dev/null
+++ b/core/api/src/main/java/org/onlab/onos/net/packet/PacketProvider.java
@@ -0,0 +1,15 @@
+package org.onlab.onos.net.packet;
+
+/**
+ * Abstraction of a packet provider capable of emitting packets.
+ */
+public interface PacketProvider {
+
+ /**
+ * Emits the specified outbound packet onto the network.
+ *
+ * @param packet outbound packet
+ */
+ void emit(OutboundPacket packet);
+
+}
diff --git a/core/api/src/main/java/org/onlab/onos/net/packet/PacketProviderService.java b/core/api/src/main/java/org/onlab/onos/net/packet/PacketProviderService.java
new file mode 100644
index 0000000..1b58f3e
--- /dev/null
+++ b/core/api/src/main/java/org/onlab/onos/net/packet/PacketProviderService.java
@@ -0,0 +1,16 @@
+package org.onlab.onos.net.packet;
+
+/**
+ * Entity capable of processing inbound packets.
+ */
+public interface PacketProviderService {
+
+ /**
+ * Submits inbound packet context for processing. This processing will be
+ * done synchronously, i.e. run-to-completion.
+ *
+ * @param context inbound packet context
+ */
+ void processPacket(PacketContext context);
+
+}
diff --git a/core/api/src/main/java/org/onlab/onos/net/packet/PacketService.java b/core/api/src/main/java/org/onlab/onos/net/packet/PacketService.java
new file mode 100644
index 0000000..5debf1b
--- /dev/null
+++ b/core/api/src/main/java/org/onlab/onos/net/packet/PacketService.java
@@ -0,0 +1,37 @@
+package org.onlab.onos.net.packet;
+
+/**
+ * Service for intercepting data plane packets and for emitting synthetic
+ * outbound packets.
+ */
+public interface PacketService {
+
+ // TODO: ponder better ordering scheme that does not require absolute numbers
+
+ /**
+ * Adds the specified processor to the list of packet processors.
+ * It will be added into the list in the order of priority. The higher
+ * numbers will be processing the packets after the lower numbers.
+ *
+ * @param processor processor to be added
+ * @param priority priority in the reverse natural order
+ * @throws java.lang.IllegalArgumentException if a processor with the
+ * given priority already exists
+ */
+ void addProcessor(PacketProcessor processor, long priority);
+
+ /**
+ * Removes the specified processor from the processing pipeline.
+ *
+ * @param processor packet processor
+ */
+ void removeProcessor(PacketProcessor processor);
+
+ /**
+ * Emits the specified outbound packet onto the network.
+ *
+ * @param packet outbound packet
+ */
+ void emit(OutboundPacket packet);
+
+}
diff --git a/core/api/src/main/java/org/onlab/onos/net/packet/Treatment.java b/core/api/src/main/java/org/onlab/onos/net/packet/Treatment.java
new file mode 100644
index 0000000..411ec38
--- /dev/null
+++ b/core/api/src/main/java/org/onlab/onos/net/packet/Treatment.java
@@ -0,0 +1,21 @@
+package org.onlab.onos.net.packet;
+
+import org.onlab.onos.net.PortNumber;
+
+/**
+ * Abstraction of different kinds of treatment that can be applied to an
+ * outbound packet.
+ */
+public interface Treatment {
+
+ // TODO: implement these later: modifications, group
+ // TODO: elsewhere provide factory methods for some default treatments
+
+ /**
+ * Returns the port number where the packet should be emitted.
+ *
+ * @return output port number
+ */
+ PortNumber output();
+
+}