[AETHER-599] Implement FabricPipelineTraceable
Core changes supporting fabric traceable implementation.
Includes minor fixes to the OFDPA traceable unit tests
Change-Id: I2f0d1172022a8fc725df9e96526092c59ddc0e0b
diff --git a/core/api/src/main/java/org/onosproject/net/PipelineTraceableHitChain.java b/core/api/src/main/java/org/onosproject/net/PipelineTraceableHitChain.java
index 4eb26b5..6e5f566 100644
--- a/core/api/src/main/java/org/onosproject/net/PipelineTraceableHitChain.java
+++ b/core/api/src/main/java/org/onosproject/net/PipelineTraceableHitChain.java
@@ -17,7 +17,6 @@
package org.onosproject.net;
import com.google.common.collect.Lists;
-import org.onosproject.net.flow.TrafficSelector;
import java.util.List;
import java.util.Objects;
@@ -25,11 +24,11 @@
/**
* Class to represent the pipeline hit chain and the result of the pipeline processing.
*/
-public class PipelineTraceableHitChain {
+public final class PipelineTraceableHitChain {
private ConnectPoint outputPort;
private List<DataPlaneEntity> hitChain;
- private TrafficSelector egressPacket;
+ private PipelineTraceablePacket egressPacket;
// By default packets are dropped
private boolean dropped = true;
@@ -42,10 +41,10 @@
*
* @param output the output connect point
* @param hits the hits in the pipeline (flows, groups and other abstractions)
- * @param packet the selector representing the final packet
+ * @param packet the traceable packet representing the final packet
*/
public PipelineTraceableHitChain(ConnectPoint output, List<DataPlaneEntity> hits,
- TrafficSelector packet) {
+ PipelineTraceablePacket packet) {
this.outputPort = output;
this.hitChain = hits;
this.egressPacket = packet;
@@ -65,7 +64,7 @@
*
* @return the connect point
*/
- public ConnectPoint getOutputPort() {
+ public ConnectPoint outputPort() {
return outputPort;
}
@@ -83,7 +82,7 @@
*
* @return flows and groups that matched.
*/
- public List<DataPlaneEntity> getHitChain() {
+ public List<DataPlaneEntity> hitChain() {
return hitChain;
}
@@ -113,9 +112,9 @@
/**
* Returns the egress packet after traversing the pipeline.
*
- * @return the selector representing the packet infos
+ * @return the traceable packet representing the packet infos
*/
- public TrafficSelector getEgressPacket() {
+ public PipelineTraceablePacket egressPacket() {
return egressPacket;
}
@@ -124,7 +123,7 @@
*
* @param egressPacket the egress packet
*/
- public void setEgressPacket(TrafficSelector egressPacket) {
+ public void setEgressPacket(PipelineTraceablePacket egressPacket) {
this.egressPacket = egressPacket;
}
@@ -164,7 +163,7 @@
if (obj instanceof PipelineTraceableHitChain) {
PipelineTraceableHitChain that = (PipelineTraceableHitChain) obj;
return Objects.equals(this.outputPort, that.outputPort) &&
- Objects.equals(this.hitChain, that.getHitChain()) &&
+ Objects.equals(this.hitChain, that.hitChain) &&
Objects.equals(this.egressPacket, that.egressPacket) &&
Objects.equals(this.dropped, that.dropped);
}
diff --git a/core/api/src/main/java/org/onosproject/net/PipelineTraceableInput.java b/core/api/src/main/java/org/onosproject/net/PipelineTraceableInput.java
index 2403c5e..8df5d95 100644
--- a/core/api/src/main/java/org/onosproject/net/PipelineTraceableInput.java
+++ b/core/api/src/main/java/org/onosproject/net/PipelineTraceableInput.java
@@ -20,7 +20,6 @@
import com.google.common.collect.Maps;
import org.onosproject.core.GroupId;
import org.onosproject.net.flow.FlowEntry;
-import org.onosproject.net.flow.TrafficSelector;
import org.onosproject.net.group.Group;
import java.util.List;
@@ -29,20 +28,29 @@
/**
* Represents the input of the pipeline traceable processing.
*/
-public class PipelineTraceableInput {
+public final class PipelineTraceableInput {
// Input state for the traceable behavior
- TrafficSelector ingressPacket;
- ConnectPoint ingressPort;
+ private PipelineTraceablePacket ingressPacket;
+ private ConnectPoint ingressPort;
// List here all possible device state using
// possibly an optimized reference
- List<FlowEntry> flows = Lists.newArrayList();
- Map<GroupId, Group> groups = Maps.newHashMap();
+ private List<FlowEntry> flows = Lists.newArrayList();
+ private Map<GroupId, Group> groups = Maps.newHashMap();
+ private List<DataPlaneEntity> deviceState;
- public PipelineTraceableInput(TrafficSelector ingressPacket, ConnectPoint ingressPort,
+ /**
+ * Builds a pipeline traceable input.
+ *
+ * @param ingressPacket the input packet
+ * @param ingressPort the input port
+ * @param deviceState the device state
+ */
+ public PipelineTraceableInput(PipelineTraceablePacket ingressPacket, ConnectPoint ingressPort,
List<DataPlaneEntity> deviceState) {
this.ingressPacket = ingressPacket;
this.ingressPort = ingressPort;
+ this.deviceState = deviceState;
processDeviceState(deviceState);
}
@@ -62,7 +70,7 @@
*
* @return the ingress packet
*/
- public TrafficSelector ingressPacket() {
+ public PipelineTraceablePacket ingressPacket() {
return ingressPacket;
}
@@ -76,6 +84,15 @@
}
/**
+ * Getter for the device state.
+ *
+ * @return the device state
+ */
+ public List<DataPlaneEntity> deviceState() {
+ return deviceState;
+ }
+
+ /**
* Getter for the flows.
*
* @return the flows
@@ -99,7 +116,7 @@
* @param groupId the group id
* @return the group, otherwise null.
*/
- public Group getGroup(GroupId groupId) {
+ public Group groupById(GroupId groupId) {
return groups.get(groupId);
}
diff --git a/core/api/src/main/java/org/onosproject/net/PipelineTraceableMetadata.java b/core/api/src/main/java/org/onosproject/net/PipelineTraceableMetadata.java
new file mode 100644
index 0000000..2c92afc
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/PipelineTraceableMetadata.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+ *
+ * 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.net;
+
+/**
+ * Stores traceable processing metadata.
+ */
+public interface PipelineTraceableMetadata {
+
+}
diff --git a/core/api/src/main/java/org/onosproject/net/PipelineTraceableOutput.java b/core/api/src/main/java/org/onosproject/net/PipelineTraceableOutput.java
index 21a9819..66a18c0 100644
--- a/core/api/src/main/java/org/onosproject/net/PipelineTraceableOutput.java
+++ b/core/api/src/main/java/org/onosproject/net/PipelineTraceableOutput.java
@@ -74,7 +74,7 @@
*
* @return the log message
*/
- public String getLog() {
+ public String log() {
return log;
}
@@ -83,7 +83,7 @@
*
* @return the pipeline hit chains
*/
- public List<PipelineTraceableHitChain> getHitChains() {
+ public List<PipelineTraceableHitChain> hitChains() {
return hitChains;
}
@@ -92,7 +92,7 @@
*
* @return the pipeline traceable result
*/
- public PipelineTraceableResult getResult() {
+ public PipelineTraceableResult result() {
return result;
}
@@ -106,6 +106,16 @@
}
/**
+ * Returns a new builder initialized with the traceable output.
+ *
+ * @param pipelineTraceableOutput the output used for the initialization
+ * @return an initialized builder
+ */
+ public static PipelineTraceableOutput.Builder builder(PipelineTraceableOutput pipelineTraceableOutput) {
+ return new PipelineTraceableOutput.Builder(pipelineTraceableOutput);
+ }
+
+ /**
* Builder of pipeline traceable entities.
*/
public static final class Builder {
@@ -114,6 +124,15 @@
private List<PipelineTraceableHitChain> hitChains = Lists.newArrayList();
private PipelineTraceableResult result = PipelineTraceableResult.SUCCESS;
+ private Builder() {
+ }
+
+ private Builder(PipelineTraceableOutput traceableOutput) {
+ appendToLog("\n" + traceableOutput.log());
+ setResult(traceableOutput.result());
+ traceableOutput.hitChains().forEach(this::addHitChain);
+ }
+
/**
* Appends a message to the log.
*
@@ -128,7 +147,7 @@
return this;
}
- private Builder setResult(PipelineTraceableResult result) {
+ public Builder setResult(PipelineTraceableResult result) {
// Do not override original failure
if (this.result == PipelineTraceableResult.SUCCESS) {
this.result = result;
diff --git a/core/api/src/main/java/org/onosproject/net/PipelineTraceablePacket.java b/core/api/src/main/java/org/onosproject/net/PipelineTraceablePacket.java
new file mode 100644
index 0000000..ffa2063
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/PipelineTraceablePacket.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+ *
+ * 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.net;
+
+import org.onosproject.net.flow.TrafficSelector;
+
+import java.util.Objects;
+
+/**
+ * Represents a traceable packet composed by a traffic selector and metadata.
+ */
+public final class PipelineTraceablePacket {
+
+ // stores metadata associated with the packet
+ private PipelineTraceableMetadata metadata;
+ // representation of the packet
+ private TrafficSelector packet;
+
+ /**
+ * Builds a traceable packet without metadata.
+ * Note this can be used for legacy device like ofdpa.
+ *
+ * @param packet the packet selector
+ */
+ public PipelineTraceablePacket(TrafficSelector packet) {
+ this.packet = packet;
+ }
+
+ /**
+ * Builds a traceable packet with metadata.
+ * @param packet the packet selector
+ * @param metadata the packet metadata
+ */
+ public PipelineTraceablePacket(TrafficSelector packet, PipelineTraceableMetadata metadata) {
+ this.packet = packet;
+ this.metadata = metadata;
+ }
+
+ /**
+ * Getter for the metadata.
+ *
+ * @return the packet metadata
+ */
+ public PipelineTraceableMetadata metadata() {
+ return metadata;
+ }
+
+ /**
+ * Getter for the packet selector.
+ *
+ * @return the packet selector
+ */
+ public TrafficSelector packet() {
+ return packet;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(metadata, packet);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj instanceof PipelineTraceablePacket) {
+ PipelineTraceablePacket that = (PipelineTraceablePacket) obj;
+ return Objects.equals(this.metadata, that.metadata) &&
+ Objects.equals(this.packet, that.packet);
+ }
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return "PipelineTraceablePacket{" +
+ "metadata=" + metadata +
+ ", packet=" + packet +
+ '}';
+ }
+}
diff --git a/core/api/src/main/java/org/onosproject/net/flow/criteria/PiCriterion.java b/core/api/src/main/java/org/onosproject/net/flow/criteria/PiCriterion.java
index a346927..17d1270 100644
--- a/core/api/src/main/java/org/onosproject/net/flow/criteria/PiCriterion.java
+++ b/core/api/src/main/java/org/onosproject/net/flow/criteria/PiCriterion.java
@@ -108,6 +108,16 @@
}
/**
+ * Returns the PiCriterion builder initialized by the given PiCriterion.
+ *
+ * @param piCriterion the input PiCriterion
+ * @return PiCriterion builder
+ */
+ public static Builder builder(PiCriterion piCriterion) {
+ return new Builder(piCriterion);
+ }
+
+ /**
* PiCriterion Builder.
*/
@Beta
@@ -120,6 +130,21 @@
// ban constructor.
}
+ private Builder(PiCriterion piCriterion) {
+ piCriterion.fieldMatchMap.forEach(((piMatchFieldId, piFieldMatch) -> add(piFieldMatch)));
+ }
+
+ /**
+ * Adds a match field to the builder.
+ *
+ * @param field the field value
+ * @return this
+ */
+ public Builder add(PiFieldMatch field) {
+ fieldMatchMapBuilder.put(field.fieldId(), field);
+ return this;
+ }
+
/**
* Adds an exact field match for the given fieldId and value.
*