tom

Sketched out packet service and related abstractions.

......@@ -16,7 +16,7 @@ import static org.onlab.onos.net.topology.ClusterId.clusterId;
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 @@ public class ClusterLinksCommand extends ClustersListCommand {
return null;
}
}
......
......@@ -33,10 +33,10 @@ public class LinksListCommand extends AbstractShellCommand {
}
/**
* 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(),
......
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();
}
}
......@@ -12,6 +12,7 @@ import org.onlab.onos.net.topology.TopologyService;
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";
......
......@@ -9,8 +9,17 @@ import com.google.common.primitives.UnsignedLongs;
*/
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 @@ public final class PortNumber {
}
/**
* 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
......
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();
}
}
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();
}
}
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();
}
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();
}
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();
}
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);
}
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);
}
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);
}
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);
}
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();
}