Allows duplicating packets when requesting packet-in via PacketService
If false, the original packet is always sent to the controller.
If true, a copy of the packet is sent to the controller, as long as the packet can be duplicated.
If duplication is not supported, the original packet will be sent to the controller.
Change-Id: I566c799bb0afed03c3fae5815aa926b338cad953
diff --git a/core/api/src/main/java/org/onosproject/net/packet/DefaultPacketRequest.java b/core/api/src/main/java/org/onosproject/net/packet/DefaultPacketRequest.java
index 68427f8..2f3d88a 100644
--- a/core/api/src/main/java/org/onosproject/net/packet/DefaultPacketRequest.java
+++ b/core/api/src/main/java/org/onosproject/net/packet/DefaultPacketRequest.java
@@ -34,11 +34,11 @@
private final ApplicationId appId;
private final NodeId nodeId;
private final Optional<DeviceId> deviceId;
-
+ private final boolean copy;
/**
* Creates a new packet request.
- * @param selector traffic selector
+ * @param selector traffic selector
* @param priority intercept priority
* @param appId application id
* @param nodeId identifier of node where request originated
@@ -46,11 +46,27 @@
*/
public DefaultPacketRequest(TrafficSelector selector, PacketPriority priority,
ApplicationId appId, NodeId nodeId, Optional<DeviceId> deviceId) {
+ this(selector, priority, appId, nodeId, deviceId, false);
+ }
+
+ /**
+ * Creates a new packet request.
+ * @param selector traffic selector
+ * @param priority intercept priority
+ * @param appId application id
+ * @param nodeId identifier of node where request originated
+ * @param deviceId device id
+ * @param copy copy flag
+ */
+ public DefaultPacketRequest(TrafficSelector selector, PacketPriority priority,
+ ApplicationId appId, NodeId nodeId, Optional<DeviceId> deviceId,
+ boolean copy) {
this.selector = selector;
this.priority = priority;
this.appId = appId;
this.nodeId = nodeId;
this.deviceId = deviceId;
+ this.copy = copy;
}
@Override
@@ -78,8 +94,13 @@
}
@Override
+ public boolean copy() {
+ return copy;
+ }
+
+ @Override
public int hashCode() {
- return Objects.hash(selector, priority, appId, nodeId, deviceId);
+ return Objects.hash(selector, priority, appId, nodeId, deviceId, copy);
}
@Override
@@ -95,7 +116,8 @@
&& Objects.equals(this.priority, other.priority)
&& Objects.equals(this.appId, other.appId)
&& Objects.equals(this.nodeId, other.nodeId)
- && Objects.equals(this.deviceId, other.deviceId);
+ && Objects.equals(this.deviceId, other.deviceId)
+ && Objects.equals(this.copy, other.copy);
}
@Override
@@ -106,6 +128,7 @@
.add("appId", appId)
.add("nodeId", nodeId)
.add("applies to", deviceId.map(DeviceId::toString).orElse("all"))
+ .add("copy", copy)
.toString();
}
}
diff --git a/core/api/src/main/java/org/onosproject/net/packet/PacketRequest.java b/core/api/src/main/java/org/onosproject/net/packet/PacketRequest.java
index 01116d8..2249102 100644
--- a/core/api/src/main/java/org/onosproject/net/packet/PacketRequest.java
+++ b/core/api/src/main/java/org/onosproject/net/packet/PacketRequest.java
@@ -28,28 +28,28 @@
public interface PacketRequest {
/**
- * Obtain the traffic selector.
+ * Obtains the traffic selector.
*
* @return a traffic selector
*/
TrafficSelector selector();
/**
- * Obtain the priority.
+ * Obtains the priority.
*
* @return a PacketPriority
*/
PacketPriority priority();
/**
- * Obtain the application id.
+ * Obtains the application id.
*
* @return an application id
*/
ApplicationId appId();
/**
- * Obtain the node id.
+ * Obtains the node id.
*
* @return an node id
*/
@@ -62,4 +62,11 @@
*/
Optional<DeviceId> deviceId();
+ /**
+ * Obtains copy flag.
+ *
+ * @return true if copy flag is set
+ */
+ boolean copy();
+
}
diff --git a/core/api/src/main/java/org/onosproject/net/packet/PacketService.java b/core/api/src/main/java/org/onosproject/net/packet/PacketService.java
index adaea07..88bbbb5 100644
--- a/core/api/src/main/java/org/onosproject/net/packet/PacketService.java
+++ b/core/api/src/main/java/org/onosproject/net/packet/PacketService.java
@@ -69,6 +69,22 @@
void requestPackets(TrafficSelector selector, PacketPriority priority,
ApplicationId appId);
+ /**
+ * Requests that packets matching the given selector are punted from the
+ * dataplane to the controller.
+ *
+ * @param selector the traffic selector used to match packets
+ * @param priority the priority of the rule
+ * @param appId the application ID of the requester
+ * @param copy request a copy of the matching packet to be punted to the controller.
+ * <p>
+ * If false, the original packet is always sent to the controller.
+ * If true, a copy of the packet is sent to the controller,
+ * as long as the packet can be duplicated.
+ * If duplication is not supported, the original packet will be sent to the controller.
+ */
+ void requestPackets(TrafficSelector selector, PacketPriority priority,
+ ApplicationId appId, boolean copy);
/**
* Requests that packets matching the given selector are punted from the
@@ -97,6 +113,23 @@
/**
* Cancels previous packet requests for packets matching the given
+ * selector to be punted from the dataplane to the controller.
+ *
+ * @param selector the traffic selector used to match packets
+ * @param priority the priority of the rule
+ * @param appId the application ID of the requester
+ * @param copy request a copy of the matching packet to be punted to the controller.
+ * <p>
+ * If false, the original packet is always sent to the controller.
+ * If true, a copy of the packet is sent to the controller,
+ * as long as the packet can be duplicated.
+ * If duplication is not supported, the original packet will be sent to the controller.
+ */
+ void cancelPackets(TrafficSelector selector, PacketPriority priority,
+ ApplicationId appId, boolean copy);
+
+ /**
+ * Cancels previous packet requests for packets matching the given
* selector to be punted from the dataplane to the controller. If a
* deviceId is specified then the packet request is only withdrawn from
* the device represented by that deviceId.
diff --git a/core/api/src/test/java/org/onosproject/net/packet/PacketServiceAdapter.java b/core/api/src/test/java/org/onosproject/net/packet/PacketServiceAdapter.java
index 22d4940..7631c03 100644
--- a/core/api/src/test/java/org/onosproject/net/packet/PacketServiceAdapter.java
+++ b/core/api/src/test/java/org/onosproject/net/packet/PacketServiceAdapter.java
@@ -51,6 +51,11 @@
@Override
public void requestPackets(TrafficSelector selector, PacketPriority priority,
+ ApplicationId appId, boolean copy) {
+ }
+
+ @Override
+ public void requestPackets(TrafficSelector selector, PacketPriority priority,
ApplicationId appId, Optional<DeviceId> deviceId) {
}
@@ -62,6 +67,11 @@
@Override
public void cancelPackets(TrafficSelector selector, PacketPriority priority,
+ ApplicationId appId, boolean copy) {
+ }
+
+ @Override
+ public void cancelPackets(TrafficSelector selector, PacketPriority priority,
ApplicationId appId, Optional<DeviceId> deviceId) {
}
diff --git a/core/net/src/main/java/org/onosproject/net/packet/impl/PacketManager.java b/core/net/src/main/java/org/onosproject/net/packet/impl/PacketManager.java
index f809a1f..1fe10a5 100644
--- a/core/net/src/main/java/org/onosproject/net/packet/impl/PacketManager.java
+++ b/core/net/src/main/java/org/onosproject/net/packet/impl/PacketManager.java
@@ -34,6 +34,7 @@
import org.onosproject.net.device.DeviceService;
import org.onosproject.net.flow.DefaultTrafficTreatment;
import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.flow.TrafficTreatment;
import org.onosproject.net.flowobjective.DefaultForwardingObjective;
import org.onosproject.net.flowobjective.FlowObjectiveService;
import org.onosproject.net.flowobjective.ForwardingObjective;
@@ -180,12 +181,19 @@
@Override
public void requestPackets(TrafficSelector selector, PacketPriority priority,
ApplicationId appId) {
+ this.requestPackets(selector, priority, appId, false);
+ }
+
+ @Override
+ public void requestPackets(TrafficSelector selector, PacketPriority priority,
+ ApplicationId appId, boolean copy) {
checkPermission(PACKET_READ);
checkNotNull(selector, ERROR_NULL_SELECTOR);
checkNotNull(appId, ERROR_NULL_APP_ID);
PacketRequest request = new DefaultPacketRequest(selector, priority, appId,
- localNodeId, Optional.empty());
+ localNodeId, Optional.empty(), copy);
+
store.requestPackets(request);
}
@@ -202,19 +210,23 @@
localNodeId, deviceId);
store.requestPackets(request);
-
}
@Override
public void cancelPackets(TrafficSelector selector, PacketPriority priority,
ApplicationId appId) {
+ this.cancelPackets(selector, priority, appId, false);
+ }
+
+ @Override
+ public void cancelPackets(TrafficSelector selector, PacketPriority priority,
+ ApplicationId appId, boolean copy) {
checkPermission(PACKET_READ);
checkNotNull(selector, ERROR_NULL_SELECTOR);
checkNotNull(appId, ERROR_NULL_APP_ID);
-
PacketRequest request = new DefaultPacketRequest(selector, priority, appId,
- localNodeId, Optional.empty());
+ localNodeId, Optional.empty(), copy);
store.cancelPackets(request);
}
@@ -321,12 +333,18 @@
}
private DefaultForwardingObjective.Builder createBuilder(PacketRequest request) {
+ TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
+ tBuilder.punt();
+ if (!request.copy()) {
+ tBuilder.wipeDeferred();
+ }
+
return DefaultForwardingObjective.builder()
.withPriority(request.priority().priorityValue())
.withSelector(request.selector())
.fromApp(appId)
.withFlag(ForwardingObjective.Flag.VERSATILE)
- .withTreatment(DefaultTrafficTreatment.builder().punt().build())
+ .withTreatment(tBuilder.build())
.makePermanent();
}