ONOS-7077 Openflow 1.5 OXS and stat trigger support
Change-Id: I006bcd3d8eac451a780c7e5c69a12298ead14281
diff --git a/core/api/src/main/java/org/onosproject/net/flow/DefaultTrafficTreatment.java b/core/api/src/main/java/org/onosproject/net/flow/DefaultTrafficTreatment.java
index 6c720c8..8bde2f6 100644
--- a/core/api/src/main/java/org/onosproject/net/flow/DefaultTrafficTreatment.java
+++ b/core/api/src/main/java/org/onosproject/net/flow/DefaultTrafficTreatment.java
@@ -17,6 +17,7 @@
import java.util.ArrayList;
import java.util.List;
+import java.util.Map;
import java.util.Objects;
import org.onlab.packet.EthType;
@@ -49,6 +50,7 @@
private final List<Instruction> all;
private final Instructions.TableTypeTransition table;
private final Instructions.MetadataInstruction meta;
+ private final Instructions.StatTriggerInstruction statTrigger;
private final boolean hasClear;
@@ -69,6 +71,7 @@
this.table = null;
this.meta = null;
this.meter = null;
+ this.statTrigger = null;
}
/**
@@ -80,11 +83,13 @@
* @param clear instruction to clear the deferred actions list
*/
private DefaultTrafficTreatment(List<Instruction> deferred,
- List<Instruction> immediate,
- Instructions.TableTypeTransition table,
- boolean clear,
- Instructions.MetadataInstruction meta,
- Instructions.MeterInstruction meter) {
+ List<Instruction> immediate,
+ Instructions.TableTypeTransition table,
+ boolean clear,
+ Instructions.MetadataInstruction meta,
+ Instructions.MeterInstruction meter,
+ Instructions.StatTriggerInstruction statTrigger
+ ) {
this.immediate = ImmutableList.copyOf(checkNotNull(immediate));
this.deferred = ImmutableList.copyOf(checkNotNull(deferred));
this.all = new ImmutableList.Builder<Instruction>()
@@ -95,6 +100,7 @@
this.meta = meta;
this.hasClear = clear;
this.meter = meter;
+ this.statTrigger = statTrigger;
}
@Override
@@ -128,6 +134,11 @@
}
@Override
+ public Instructions.StatTriggerInstruction statTrigger() {
+ return statTrigger;
+ }
+
+ @Override
public Instructions.MeterInstruction metered() {
return meter;
}
@@ -191,6 +202,7 @@
.add("transition", table == null ? "None" : table.toString())
.add("meter", meter == null ? "None" : meter.toString())
.add("cleared", hasClear)
+ .add("StatTrigger", statTrigger)
.add("metadata", meta)
.toString();
}
@@ -209,6 +221,8 @@
Instructions.MeterInstruction meter;
+ Instructions.StatTriggerInstruction statTrigger;
+
List<Instruction> deferred = new ArrayList<>();
List<Instruction> immediate = new ArrayList<>();
@@ -259,6 +273,9 @@
case METER:
meter = (Instructions.MeterInstruction) instruction;
break;
+ case STAT_TRIGGER:
+ statTrigger = (Instructions.StatTriggerInstruction) instruction;
+ break;
default:
throw new IllegalArgumentException("Unknown instruction type: " +
instruction.type());
@@ -493,6 +510,12 @@
}
@Override
+ public TrafficTreatment.Builder statTrigger(Map<StatTriggerField, Long> statTriggerFieldMap,
+ StatTriggerFlag statTriggerFlag) {
+ return add(Instructions.statTrigger(statTriggerFieldMap, statTriggerFlag));
+ }
+
+ @Override
public TrafficTreatment.Builder addTreatment(TrafficTreatment treatment) {
List<Instruction> previous = current;
deferred();
@@ -516,7 +539,7 @@
immediate();
noAction();
}
- return new DefaultTrafficTreatment(deferred, immediate, table, clear, meta, meter);
+ return new DefaultTrafficTreatment(deferred, immediate, table, clear, meta, meter, statTrigger);
}
}
diff --git a/core/api/src/main/java/org/onosproject/net/flow/StatTriggerField.java b/core/api/src/main/java/org/onosproject/net/flow/StatTriggerField.java
new file mode 100644
index 0000000..f946542
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/flow/StatTriggerField.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2017-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.flow;
+
+/**
+ * Stat fields are supported default by OXS.
+ */
+public enum StatTriggerField {
+ /** Time flow entry has been alive. Unit indicates nanoseconds. */
+ DURATION,
+ /** Time flow entry has been idle. Unit indicates nanoseconds. */
+ IDLE_TIME,
+ /** Number of aggregated flow entries. */
+ FLOW_COUNT,
+ /** Number of packets in flow entry. */
+ PACKET_COUNT,
+ /** Number of bytes in flow entry. */
+ BYTE_COUNT
+}
\ No newline at end of file
diff --git a/core/api/src/main/java/org/onosproject/net/flow/StatTriggerFlag.java b/core/api/src/main/java/org/onosproject/net/flow/StatTriggerFlag.java
new file mode 100644
index 0000000..7ed650c
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/flow/StatTriggerFlag.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2017-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.flow;
+
+/**
+ * Stat Trigger Flags.
+ */
+public enum StatTriggerFlag {
+ /** Trigger for all multiples of thresholds. */
+ PERIODIC,
+ /** Trigger on only first reach threshold. */
+ ONLY_FIRST
+}
diff --git a/core/api/src/main/java/org/onosproject/net/flow/TrafficTreatment.java b/core/api/src/main/java/org/onosproject/net/flow/TrafficTreatment.java
index 9ddabe1..057f0f8 100644
--- a/core/api/src/main/java/org/onosproject/net/flow/TrafficTreatment.java
+++ b/core/api/src/main/java/org/onosproject/net/flow/TrafficTreatment.java
@@ -16,6 +16,7 @@
package org.onosproject.net.flow;
import java.util.List;
+import java.util.Map;
import com.google.common.annotations.Beta;
import org.onlab.packet.EthType;
@@ -81,6 +82,12 @@
Instructions.MetadataInstruction writeMetadata();
/**
+ * Returns the stat trigger instruction if there is one.
+ * @return a stat trigger instruction; may be null.
+ */
+ Instructions.StatTriggerInstruction statTrigger();
+
+ /**
* Returns the meter instruction if there is one.
*
* @return a meter instruction that may be null
@@ -422,6 +429,16 @@
Builder extension(ExtensionTreatment extension, DeviceId deviceId);
/**
+ * Add stat trigger instruction.
+ *
+ * @param statTriggerFieldMap defines stat trigger constraints
+ * @param statTriggerFlag describes which circumstances that start will be triggered
+ * @return a treatment builder
+ */
+ Builder statTrigger(Map<StatTriggerField, Long> statTriggerFieldMap,
+ StatTriggerFlag statTriggerFlag);
+
+ /**
* Add all instructions from another treatment.
*
* @param treatment another treatment
diff --git a/core/api/src/main/java/org/onosproject/net/flow/instructions/Instruction.java b/core/api/src/main/java/org/onosproject/net/flow/instructions/Instruction.java
index c3c9b60..66fbb18 100644
--- a/core/api/src/main/java/org/onosproject/net/flow/instructions/Instruction.java
+++ b/core/api/src/main/java/org/onosproject/net/flow/instructions/Instruction.java
@@ -96,7 +96,12 @@
/**
* Signifies that an extension instruction will be used.
*/
- EXTENSION
+ EXTENSION,
+
+ /**
+ * Signifies that statistics will be triggered.
+ */
+ STAT_TRIGGER
}
/**
diff --git a/core/api/src/main/java/org/onosproject/net/flow/instructions/Instructions.java b/core/api/src/main/java/org/onosproject/net/flow/instructions/Instructions.java
index 460976a..9bd7df5 100644
--- a/core/api/src/main/java/org/onosproject/net/flow/instructions/Instructions.java
+++ b/core/api/src/main/java/org/onosproject/net/flow/instructions/Instructions.java
@@ -16,6 +16,7 @@
package org.onosproject.net.flow.instructions;
import com.google.common.base.MoreObjects;
+import com.google.common.collect.ImmutableMap;
import org.onlab.packet.EthType;
import org.onlab.packet.IpAddress;
import org.onlab.packet.MacAddress;
@@ -28,6 +29,8 @@
import org.onosproject.net.OchSignal;
import org.onosproject.net.OduSignalId;
import org.onosproject.net.PortNumber;
+import org.onosproject.net.flow.StatTriggerField;
+import org.onosproject.net.flow.StatTriggerFlag;
import org.onosproject.net.flow.instructions.L0ModificationInstruction.ModOchSignalInstruction;
import org.onosproject.net.flow.instructions.L1ModificationInstruction.ModOduSignalIdInstruction;
import org.onosproject.net.flow.instructions.L3ModificationInstruction.L3SubType;
@@ -42,6 +45,7 @@
import org.onosproject.net.meter.MeterId;
import org.onosproject.net.pi.runtime.PiTableAction;
+import java.util.Map;
import java.util.Objects;
import static com.google.common.base.MoreObjects.toStringHelper;
@@ -498,6 +502,20 @@
}
/**
+ * Creates a stat trigger instruction.
+ *
+ * @param statTriggerMap map keeps stat trigger threshold
+ * @param flag stat trigger flag
+ * @return stat trigger instruction
+ */
+ public static StatTriggerInstruction statTrigger(Map<StatTriggerField, Long> statTriggerMap,
+ StatTriggerFlag flag) {
+ checkNotNull(statTriggerMap, "Stat trigger map cannot be null");
+ checkNotNull(flag, "Stat trigger flag cannot be null");
+ return new StatTriggerInstruction(statTriggerMap, flag);
+ }
+
+ /**
* No Action instruction.
*/
public static final class NoActionInstruction implements Instruction {
@@ -865,6 +883,68 @@
}
}
+ public static class StatTriggerInstruction implements Instruction {
+ private Map<StatTriggerField, Long> statTriggerFieldMap;
+ private StatTriggerFlag statTriggerFlag;
+
+
+ StatTriggerInstruction(Map<StatTriggerField, Long> statTriggerMap,
+ StatTriggerFlag flag) {
+ this.statTriggerFieldMap = ImmutableMap.copyOf(statTriggerMap);
+ this.statTriggerFlag = flag;
+ }
+
+ public Map<StatTriggerField, Long> getStatTriggerFieldMap() {
+ return statTriggerFieldMap;
+ }
+
+ public StatTriggerFlag getStatTriggerFlag() {
+ return statTriggerFlag;
+ }
+
+ public Long getStatValue(StatTriggerField field) {
+ return statTriggerFieldMap.get(field);
+ }
+
+ @Override
+ public Type type() {
+ return Type.STAT_TRIGGER;
+ }
+
+ @Override
+ public String toString() {
+ return "StatTriggerInstruction{" +
+ "statTriggerFieldMap=" + statTriggerFieldMap +
+ ", statTriggerFlag=" + statTriggerFlag +
+ '}';
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+
+ StatTriggerInstruction that = (StatTriggerInstruction) o;
+
+ if (!Objects.equals(statTriggerFieldMap, that.statTriggerFieldMap)) {
+ return false;
+ }
+
+ return statTriggerFlag == that.statTriggerFlag;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = statTriggerFieldMap != null ? statTriggerFieldMap.hashCode() : 0;
+ result = 31 * result + (statTriggerFlag != null ? statTriggerFlag.hashCode() : 0);
+ return result;
+ }
+ }
+
}
diff --git a/core/api/src/test/java/org/onosproject/net/flow/instructions/InstructionsTest.java b/core/api/src/test/java/org/onosproject/net/flow/instructions/InstructionsTest.java
index 9eada31..ddf6500 100644
--- a/core/api/src/test/java/org/onosproject/net/flow/instructions/InstructionsTest.java
+++ b/core/api/src/test/java/org/onosproject/net/flow/instructions/InstructionsTest.java
@@ -31,6 +31,8 @@
import org.onosproject.net.Lambda;
import org.onosproject.net.OduSignalId;
import org.onosproject.net.PortNumber;
+import org.onosproject.net.flow.StatTriggerField;
+import org.onosproject.net.flow.StatTriggerFlag;
import org.onosproject.net.meter.MeterId;
import org.onosproject.net.pi.runtime.PiAction;
import org.onosproject.net.pi.runtime.PiActionId;
@@ -38,7 +40,9 @@
import org.onosproject.net.pi.runtime.PiActionParamId;
import org.onosproject.net.pi.runtime.PiTableAction;
+import java.util.EnumMap;
import java.util.List;
+import java.util.Map;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
@@ -829,6 +833,49 @@
meterInstruction2);
}
+ private long packetCountValue1 = 5L;
+ private long byteCountValue1 = 10L;
+ private long packetCountValue2 = 10L;
+ private long byteCountValue2 = 5L;
+ private StatTriggerFlag flag1 = StatTriggerFlag.ONLY_FIRST;
+ private StatTriggerFlag flag2 = StatTriggerFlag.PERIODIC;
+ Map<StatTriggerField, Long> statTriggerFieldMap1 = new EnumMap<StatTriggerField, Long>(StatTriggerField.class) {
+ {
+ put(StatTriggerField.BYTE_COUNT, packetCountValue1);
+ put(StatTriggerField.PACKET_COUNT, byteCountValue1);
+ }
+ };
+ Map<StatTriggerField, Long> statTriggerFieldMap2 = new EnumMap<StatTriggerField, Long>(StatTriggerField.class) {
+ {
+ put(StatTriggerField.BYTE_COUNT, packetCountValue2);
+ put(StatTriggerField.PACKET_COUNT, byteCountValue2);
+ }
+ };
+
+ final Instruction statInstruction1 = Instructions.statTrigger(statTriggerFieldMap1, flag1);
+ final Instruction statInstruction1Same = Instructions.statTrigger(statTriggerFieldMap1, flag1);
+ final Instruction statInstruction2 = Instructions.statTrigger(statTriggerFieldMap2, flag2);
+
+ @Test
+ public void testStatTriggerTrafficMethod() {
+ final Instruction instruction = Instructions.statTrigger(statTriggerFieldMap1, flag1);
+ final Instructions.StatTriggerInstruction statTriggerInstruction =
+ checkAndConvert(instruction,
+ Instruction.Type.STAT_TRIGGER,
+ Instructions.StatTriggerInstruction.class);
+ assertThat(statTriggerInstruction.getStatTriggerFieldMap(), is(equalTo(statTriggerFieldMap1)));
+ assertThat(statTriggerInstruction.getStatTriggerFlag(), is(equalTo(flag1)));
+ assertThat(statTriggerInstruction.getStatTriggerFieldMap(), is(not(equalTo(statTriggerFieldMap2))));
+ assertThat(statTriggerInstruction.getStatTriggerFlag(), is(not(equalTo(flag2))));
+ }
+
+ @Test
+ public void testStatTriggerTrafficInstructionEquals() {
+ checkEqualsAndToString(statInstruction1,
+ statInstruction1Same,
+ statInstruction2);
+ }
+
// TableTypeTransition
private final Instruction transitionInstruction1 = Instructions.transition(1);
diff --git a/core/api/src/test/java/org/onosproject/net/intent/IntentTestsMocks.java b/core/api/src/test/java/org/onosproject/net/intent/IntentTestsMocks.java
index 352e2f5..a05745c 100644
--- a/core/api/src/test/java/org/onosproject/net/intent/IntentTestsMocks.java
+++ b/core/api/src/test/java/org/onosproject/net/intent/IntentTestsMocks.java
@@ -113,6 +113,11 @@
}
@Override
+ public Instructions.StatTriggerInstruction statTrigger() {
+ return null;
+ }
+
+ @Override
public Instructions.MeterInstruction metered() {
return null;
}