tom

Sketched out packet service and related abstractions.

...@@ -16,7 +16,7 @@ import static org.onlab.onos.net.topology.ClusterId.clusterId; ...@@ -16,7 +16,7 @@ import static org.onlab.onos.net.topology.ClusterId.clusterId;
16 public class ClusterLinksCommand extends ClustersListCommand { 16 public class ClusterLinksCommand extends ClustersListCommand {
17 17
18 @Argument(index = 0, name = "id", description = "Cluster ID", 18 @Argument(index = 0, name = "id", description = "Cluster ID",
19 - required = false, multiValued = false) 19 + required = true, multiValued = false)
20 String id = null; 20 String id = null;
21 21
22 @Override 22 @Override
...@@ -30,5 +30,4 @@ public class ClusterLinksCommand extends ClustersListCommand { ...@@ -30,5 +30,4 @@ public class ClusterLinksCommand extends ClustersListCommand {
30 return null; 30 return null;
31 } 31 }
32 32
33 -
34 } 33 }
......
...@@ -33,10 +33,10 @@ public class LinksListCommand extends AbstractShellCommand { ...@@ -33,10 +33,10 @@ public class LinksListCommand extends AbstractShellCommand {
33 } 33 }
34 34
35 /** 35 /**
36 - * Returns a formated string representing the gien link. 36 + * Returns a formatted string representing the given link.
37 * 37 *
38 * @param link infrastructure link 38 * @param link infrastructure link
39 - * @return formated link string 39 + * @return formatted link string
40 */ 40 */
41 public static String linkString(Link link) { 41 public static String linkString(Link link) {
42 return String.format(FMT, link.src().deviceId(), link.src().port(), 42 return String.format(FMT, link.src().deviceId(), link.src().port(),
......
1 +package org.onlab.onos.cli.net;
2 +
3 +import org.apache.karaf.shell.commands.Argument;
4 +import org.apache.karaf.shell.commands.Command;
5 +import org.onlab.onos.net.Path;
6 +
7 +import java.util.Set;
8 +
9 +import static org.onlab.onos.net.DeviceId.deviceId;
10 +
11 +/**
12 + * Lists all shortest-paths paths between the specified source and
13 + * destination devices.
14 + */
15 +@Command(scope = "onos", name = "paths",
16 + description = "Lists all shortest-paths paths between the specified source and destination devices")
17 +public class PathListCommand extends TopologyCommand {
18 +
19 + private static final String FMT = "src=%s/%s, dst=%s/%s, type=%s";
20 +
21 + @Argument(index = 0, name = "src", description = "Source device ID",
22 + required = true, multiValued = false)
23 + String src = null;
24 +
25 + @Argument(index = 0, name = "dst", description = "Destination device ID",
26 + required = true, multiValued = false)
27 + String dst = null;
28 +
29 + @Override
30 + protected Object doExecute() throws Exception {
31 + init();
32 + Set<Path> paths = service.getPaths(topology, deviceId(src), deviceId(dst));
33 + for (Path path : paths) {
34 + print(pathString(path));
35 + }
36 + return null;
37 + }
38 +
39 + private String pathString(Path path) {
40 + return path.toString();
41 + }
42 +
43 +}
...@@ -12,6 +12,7 @@ import org.onlab.onos.net.topology.TopologyService; ...@@ -12,6 +12,7 @@ import org.onlab.onos.net.topology.TopologyService;
12 description = "Lists summary of the current topology") 12 description = "Lists summary of the current topology")
13 public class TopologyCommand extends AbstractShellCommand { 13 public class TopologyCommand extends AbstractShellCommand {
14 14
15 + // TODO: format the time-stamp
15 private static final String FMT = 16 private static final String FMT =
16 "time=%s, devices=%d, links=%d, clusters=%d, paths=%d"; 17 "time=%s, devices=%d, links=%d, clusters=%d, paths=%d";
17 18
......
...@@ -9,8 +9,17 @@ import com.google.common.primitives.UnsignedLongs; ...@@ -9,8 +9,17 @@ import com.google.common.primitives.UnsignedLongs;
9 */ 9 */
10 public final class PortNumber { 10 public final class PortNumber {
11 11
12 + // TODO: revisit the max and the logical port value assignments
13 +
12 private static final long MAX_NUMBER = (2L * Integer.MAX_VALUE) + 1; 14 private static final long MAX_NUMBER = (2L * Integer.MAX_VALUE) + 1;
13 15
16 + public static final PortNumber FLOOD = new PortNumber(-1);
17 + public static final PortNumber IN_PORT = new PortNumber(-2);
18 + public static final PortNumber TABLE = new PortNumber(-3);
19 + public static final PortNumber NORMAL = new PortNumber(-4);
20 + public static final PortNumber ALL = new PortNumber(-4);
21 + public static final PortNumber LOCAL = new PortNumber(-5);
22 +
14 private final long number; 23 private final long number;
15 24
16 // Public creation is prohibited 25 // Public creation is prohibited
...@@ -39,6 +48,16 @@ public final class PortNumber { ...@@ -39,6 +48,16 @@ public final class PortNumber {
39 } 48 }
40 49
41 /** 50 /**
51 + * Indicates whether or not this port number is a reserved logical one or
52 + * whether it corresponds to a normal physical port of a device or NIC.
53 + *
54 + * @return true if logical port number
55 + */
56 + public boolean isLogical() {
57 + return number < 0 || number > MAX_NUMBER;
58 + }
59 +
60 + /**
42 * Returns the backing long value. 61 * Returns the backing long value.
43 * 62 *
44 * @return port number as long 63 * @return port number as long
......
1 +package org.onlab.onos.net.packet;
2 +
3 +import org.onlab.onos.net.ConnectPoint;
4 +import org.onlab.packet.Ethernet;
5 +
6 +import java.nio.ByteBuffer;
7 +import java.util.Objects;
8 +
9 +import static com.google.common.base.MoreObjects.toStringHelper;
10 +
11 +/**
12 + * Default implementation of an immutable inbound packet.
13 + */
14 +public class DefaultInboundPacket implements InboundPacket {
15 +
16 + private final ConnectPoint receivedFrom;
17 + private final Ethernet parsed;
18 + private final ByteBuffer unparsed;
19 +
20 + /**
21 + * Creates an immutable inbound packet.
22 + *
23 + * @param receivedFrom connection point where received
24 + * @param parsed parsed ethernet frame
25 + * @param unparsed unparsed raw bytes
26 + */
27 + public DefaultInboundPacket(ConnectPoint receivedFrom, Ethernet parsed,
28 + ByteBuffer unparsed) {
29 + this.receivedFrom = receivedFrom;
30 + this.parsed = parsed;
31 + this.unparsed = unparsed;
32 + }
33 +
34 + @Override
35 + public ConnectPoint receivedFrom() {
36 + return receivedFrom;
37 + }
38 +
39 + @Override
40 + public Ethernet parsed() {
41 + return parsed;
42 + }
43 +
44 + @Override
45 + public ByteBuffer unparsed() {
46 + // FIXME: figure out immutability here
47 + return unparsed;
48 + }
49 +
50 + @Override
51 + public int hashCode() {
52 + return Objects.hash(receivedFrom, parsed, unparsed);
53 + }
54 +
55 + @Override
56 + public boolean equals(Object obj) {
57 + if (obj instanceof InboundPacket) {
58 + final DefaultInboundPacket other = (DefaultInboundPacket) obj;
59 + return Objects.equals(this.receivedFrom, other.receivedFrom) &&
60 + Objects.equals(this.parsed, other.parsed) &&
61 + Objects.equals(this.unparsed, other.unparsed);
62 + }
63 + return false;
64 + }
65 +
66 + @Override
67 + public String toString() {
68 + return toStringHelper(this)
69 + .add("receivedFrom", receivedFrom)
70 + .add("parsed", parsed)
71 + .toString();
72 + }
73 +}
1 +package org.onlab.onos.net.packet;
2 +
3 +import com.google.common.base.MoreObjects;
4 +import com.google.common.collect.ImmutableList;
5 +import org.onlab.onos.net.DeviceId;
6 +
7 +import java.nio.ByteBuffer;
8 +import java.util.List;
9 +
10 +/**
11 + * Default implementation of an immutable outbound packet.
12 + */
13 +public class DefaultOutboundPacket implements OutboundPacket {
14 + private final DeviceId sendThrough;
15 + private final List<Treatment> treatments;
16 + private final ByteBuffer data;
17 +
18 + /**
19 + * Creates an immutable outbound packet.
20 + *
21 + * @param sendThrough identifier through which to send the packet
22 + * @param treatments list of packet treatments
23 + * @param data raw packet data
24 + */
25 + public DefaultOutboundPacket(DeviceId sendThrough,
26 + List<Treatment> treatments, ByteBuffer data) {
27 + this.sendThrough = sendThrough;
28 + this.treatments = ImmutableList.copyOf(treatments);
29 + this.data = data;
30 + }
31 +
32 + @Override
33 + public DeviceId sendThrough() {
34 + return sendThrough;
35 + }
36 +
37 + @Override
38 + public List<Treatment> treatments() {
39 + return treatments;
40 + }
41 +
42 + @Override
43 + public ByteBuffer data() {
44 + // FIXME: figure out immutability here
45 + return data;
46 + }
47 +
48 + @Override
49 + public String toString() {
50 + return MoreObjects.toStringHelper(this)
51 + .add("sendThrough", sendThrough)
52 + .add("treatments", treatments)
53 + .toString();
54 + }
55 +}
1 +package org.onlab.onos.net.packet;
2 +
3 +import org.onlab.onos.net.ConnectPoint;
4 +import org.onlab.packet.Ethernet;
5 +
6 +import java.nio.ByteBuffer;
7 +
8 +/**
9 + * Represents a data packet intercepted from an infrastructure device.
10 + */
11 +public interface InboundPacket {
12 +
13 + /**
14 + * Returns the device and port from where the packet was received.
15 + *
16 + * @return connection point where received
17 + */
18 + ConnectPoint receivedFrom();
19 +
20 + /**
21 + * Returns the parsed form of the packet.
22 + *
23 + * @return parsed Ethernet frame; null if the packet is not an Ethernet
24 + * frame or one for which there is no parser
25 + */
26 + Ethernet parsed();
27 +
28 + /**
29 + * Unparsed packet data.
30 + *
31 + * @return raw packet bytes
32 + */
33 + ByteBuffer unparsed();
34 +
35 +}
1 +package org.onlab.onos.net.packet;
2 +
3 +import org.onlab.onos.net.DeviceId;
4 +
5 +import java.nio.ByteBuffer;
6 +import java.util.List;
7 +
8 +/**
9 + * Represents an outbound data packet that is to be emitted to network via
10 + * an infrastructure device.
11 + */
12 +public interface OutboundPacket {
13 +
14 + /**
15 + * Returns the identity of a device through which this packet should be
16 + * sent.
17 + *
18 + * @return device identity
19 + */
20 + DeviceId sendThrough();
21 +
22 + /**
23 + * Returns list of treatments for the outbound packet.
24 + *
25 + * @return output treatment
26 + */
27 + List<Treatment> treatments();
28 +
29 + /**
30 + * Returns the raw data to be sent.
31 + *
32 + * @return data to emit
33 + */
34 + ByteBuffer data();
35 +
36 +}
1 +package org.onlab.onos.net.packet;
2 +
3 +/**
4 + * Represents context for processing an inbound packet, and (optionally)
5 + * emitting a corresponding outbound packet.
6 + */
7 +public interface PacketContext {
8 +
9 + /**
10 + * Returns the time when the packet was received.
11 + *
12 + * @return the time in millis since start of epoch
13 + */
14 + long time();
15 +
16 + /**
17 + * Returns the inbound packet being processed.
18 + *
19 + * @return inbound packet
20 + */
21 + InboundPacket inPacket();
22 +
23 + /**
24 + * Returns the view of the outbound packet.
25 + *
26 + * @return outbound packet
27 + */
28 + OutboundPacket outPacket();
29 +
30 + /**
31 + * Appends a new treatment to be applied to the outbound packet.
32 + *
33 + * @param treatment output treatment
34 + */
35 + void appendTreatment(Treatment treatment);
36 +
37 + /**
38 + * Triggers the outbound packet to be sent.
39 + */
40 + void send();
41 +
42 + /**
43 + * Blocks the outbound packet from being sent from this point onward.
44 + */
45 + void block();
46 +
47 + /**
48 + * Indicates whether the packet has already been handled, i.e. sent or
49 + * blocked.
50 + *
51 + * @return true if sent or blocked
52 + */
53 + boolean isHandled();
54 +
55 +}
1 +package org.onlab.onos.net.packet;
2 +
3 +/**
4 + * Abstraction of an inbound packet processor.
5 + */
6 +public interface PacketProcessor {
7 +
8 + /**
9 + * Processes the inbound packet as specified in the given context.
10 + *
11 + * @param context packet processing context
12 + */
13 + void process(PacketContext context);
14 +
15 +}
1 +package org.onlab.onos.net.packet;
2 +
3 +/**
4 + * Abstraction of a packet provider capable of emitting packets.
5 + */
6 +public interface PacketProvider {
7 +
8 + /**
9 + * Emits the specified outbound packet onto the network.
10 + *
11 + * @param packet outbound packet
12 + */
13 + void emit(OutboundPacket packet);
14 +
15 +}
1 +package org.onlab.onos.net.packet;
2 +
3 +/**
4 + * Entity capable of processing inbound packets.
5 + */
6 +public interface PacketProviderService {
7 +
8 + /**
9 + * Submits inbound packet context for processing. This processing will be
10 + * done synchronously, i.e. run-to-completion.
11 + *
12 + * @param context inbound packet context
13 + */
14 + void processPacket(PacketContext context);
15 +
16 +}
1 +package org.onlab.onos.net.packet;
2 +
3 +/**
4 + * Service for intercepting data plane packets and for emitting synthetic
5 + * outbound packets.
6 + */
7 +public interface PacketService {
8 +
9 + // TODO: ponder better ordering scheme that does not require absolute numbers
10 +
11 + /**
12 + * Adds the specified processor to the list of packet processors.
13 + * It will be added into the list in the order of priority. The higher
14 + * numbers will be processing the packets after the lower numbers.
15 + *
16 + * @param processor processor to be added
17 + * @param priority priority in the reverse natural order
18 + * @throws java.lang.IllegalArgumentException if a processor with the
19 + * given priority already exists
20 + */
21 + void addProcessor(PacketProcessor processor, long priority);
22 +
23 + /**
24 + * Removes the specified processor from the processing pipeline.
25 + *
26 + * @param processor packet processor
27 + */
28 + void removeProcessor(PacketProcessor processor);
29 +
30 + /**
31 + * Emits the specified outbound packet onto the network.
32 + *
33 + * @param packet outbound packet
34 + */
35 + void emit(OutboundPacket packet);
36 +
37 +}
1 +package org.onlab.onos.net.packet;
2 +
3 +import org.onlab.onos.net.PortNumber;
4 +
5 +/**
6 + * Abstraction of different kinds of treatment that can be applied to an
7 + * outbound packet.
8 + */
9 +public interface Treatment {
10 +
11 + // TODO: implement these later: modifications, group
12 + // TODO: elsewhere provide factory methods for some default treatments
13 +
14 + /**
15 + * Returns the port number where the packet should be emitted.
16 + *
17 + * @return output port number
18 + */
19 + PortNumber output();
20 +
21 +}