TUNNEL_ID field support in flow matching and actions
Change-Id: I886123a7c8d57dc4a3e12727ec8a9be4920da79e
diff --git a/core/api/src/main/java/org/onosproject/net/flow/DefaultTrafficSelector.java b/core/api/src/main/java/org/onosproject/net/flow/DefaultTrafficSelector.java
index 67e057e..09c6327 100644
--- a/core/api/src/main/java/org/onosproject/net/flow/DefaultTrafficSelector.java
+++ b/core/api/src/main/java/org/onosproject/net/flow/DefaultTrafficSelector.java
@@ -294,6 +294,11 @@
}
@Override
+ public TrafficSelector.Builder matchTunnelId(long tunnelId) {
+ return add(Criteria.matchTunnelId(tunnelId));
+ }
+
+ @Override
public Builder matchIPv6ExthdrFlags(short exthdrFlags) {
return add(Criteria.matchIPv6ExthdrFlags(exthdrFlags));
}
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 96abbe9..fe657e6 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
@@ -385,6 +385,11 @@
}
@Override
+ public Builder setTunnelId(long tunnelId) {
+ return add(Instructions.modTunnelId(tunnelId));
+ }
+
+ @Override
public TrafficTreatment build() {
//Don't add DROP instruction by default when instruction
//set is empty. This will be handled in DefaultSingleTablePipeline
diff --git a/core/api/src/main/java/org/onosproject/net/flow/TrafficSelector.java b/core/api/src/main/java/org/onosproject/net/flow/TrafficSelector.java
index 3b28093..6661cb6 100644
--- a/core/api/src/main/java/org/onosproject/net/flow/TrafficSelector.java
+++ b/core/api/src/main/java/org/onosproject/net/flow/TrafficSelector.java
@@ -301,6 +301,14 @@
Builder matchMplsLabel(MplsLabel mplsLabel);
/**
+ * Matches a tunnel id.
+ *
+ * @param tunnelId a tunnel id
+ * @return a selection builder
+ */
+ Builder matchTunnelId(long tunnelId);
+
+ /**
* Matches on IPv6 Extension Header pseudo-field flags.
*
* @param exthdrFlags the IPv6 Extension Header pseudo-field flags
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 3802bf2..35ef6d3 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
@@ -311,6 +311,14 @@
Builder writeMetadata(long value, long mask);
/**
+ * Sets the tunnel id.
+ *
+ * @param tunnelId a tunnel id.
+ * @return a treatment builder.
+ */
+ Builder setTunnelId(long tunnelId);
+
+ /**
* Builds an immutable traffic treatment descriptor.
* <p>
* If the treatment is empty when build() is called, it will add a default
diff --git a/core/api/src/main/java/org/onosproject/net/flow/criteria/Criteria.java b/core/api/src/main/java/org/onosproject/net/flow/criteria/Criteria.java
index 0347694..91221e2 100644
--- a/core/api/src/main/java/org/onosproject/net/flow/criteria/Criteria.java
+++ b/core/api/src/main/java/org/onosproject/net/flow/criteria/Criteria.java
@@ -356,6 +356,16 @@
}
/**
+ * Creates a match on Tunnel ID.
+ *
+ * @param tunnelId Tunnel ID (64 bits)
+ * @return match criterion
+ */
+ public static Criterion matchTunnelId(long tunnelId) {
+ return new TunnelIdCriterion(tunnelId);
+ }
+
+ /**
* Creates a match on IPv6 Extension Header pseudo-field fiags.
* Those are defined in Criterion.IPv6ExthdrFlags.
*
diff --git a/core/api/src/main/java/org/onosproject/net/flow/criteria/TunnelIdCriterion.java b/core/api/src/main/java/org/onosproject/net/flow/criteria/TunnelIdCriterion.java
new file mode 100644
index 0000000..3362c73
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/flow/criteria/TunnelIdCriterion.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * 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.criteria;
+
+import java.util.Objects;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+/**
+ * Implementation of Tunnel ID criterion.
+ */
+public class TunnelIdCriterion implements Criterion {
+ private final long tunnelId;
+
+ /**
+ * Constructor.
+ *
+ * @param tunnelId a Tunnel ID to match(64 bits)
+ */
+ TunnelIdCriterion(long tunnelId) {
+ this.tunnelId = tunnelId;
+ }
+
+ @Override
+ public Type type() {
+ return Type.TUNNEL_ID;
+ }
+
+ /**
+ * Gets the Tunnel ID to match.
+ *
+ * @return the Tunnel ID to match (64 bits)
+ */
+ public long tunnelId() {
+ return tunnelId;
+ }
+
+ @Override
+ public String toString() {
+ return toStringHelper(type().toString())
+ .add("tunnelId", Long.toHexString(tunnelId))
+ .toString();
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(type().ordinal(), tunnelId);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj instanceof TunnelIdCriterion) {
+ TunnelIdCriterion that = (TunnelIdCriterion) obj;
+ return Objects.equals(tunnelId, that.tunnelId) &&
+ Objects.equals(this.type(), that.type());
+ }
+ return false;
+ }
+}
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 e8101f1..0467a91 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
@@ -350,6 +350,17 @@
}
/**
+ * Creates a Tunnel ID modification.
+ *
+ * @param tunnelId the Tunnel ID to modify to
+ * @return a L2 modification
+ */
+ public static L2ModificationInstruction modTunnelId(long tunnelId) {
+ checkNotNull(tunnelId, "Tunnel id cannot be null");
+ return new L2ModificationInstruction.ModTunnelIdInstruction(tunnelId);
+ }
+
+ /**
* Drop instruction.
*/
public static final class DropInstruction implements Instruction {
diff --git a/core/api/src/main/java/org/onosproject/net/flow/instructions/L2ModificationInstruction.java b/core/api/src/main/java/org/onosproject/net/flow/instructions/L2ModificationInstruction.java
index 2fd809f..bfb6300 100644
--- a/core/api/src/main/java/org/onosproject/net/flow/instructions/L2ModificationInstruction.java
+++ b/core/api/src/main/java/org/onosproject/net/flow/instructions/L2ModificationInstruction.java
@@ -81,7 +81,12 @@
/**
* VLAN Push modification.
*/
- VLAN_PUSH
+ VLAN_PUSH,
+
+ /**
+ * Tunnle id modification.
+ */
+ TUNNEL_ID
}
// TODO: Create factory class 'Instructions' that will have various factory
@@ -401,4 +406,50 @@
return false;
}
}
+
+ /**
+ * Represents a Tunnel id modification.
+ */
+ public static final class ModTunnelIdInstruction
+ extends L2ModificationInstruction {
+
+ private final long tunnelId;
+
+ ModTunnelIdInstruction(long tunnelId) {
+ this.tunnelId = tunnelId;
+ }
+
+ public long tunnelId() {
+ return this.tunnelId;
+ }
+
+ @Override
+ public L2SubType subtype() {
+ return L2SubType.TUNNEL_ID;
+ }
+
+ @Override
+ public String toString() {
+ return toStringHelper(subtype().toString())
+ .add("id", Long.toHexString(tunnelId))
+ .toString();
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(type(), subtype(), tunnelId);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj instanceof ModTunnelIdInstruction) {
+ ModTunnelIdInstruction that = (ModTunnelIdInstruction) obj;
+ return Objects.equals(tunnelId, that.tunnelId);
+ }
+ return false;
+ }
+ }
}
diff --git a/core/api/src/test/java/org/onosproject/net/flow/criteria/CriteriaTest.java b/core/api/src/test/java/org/onosproject/net/flow/criteria/CriteriaTest.java
index 4733cb9..de60b69 100644
--- a/core/api/src/test/java/org/onosproject/net/flow/criteria/CriteriaTest.java
+++ b/core/api/src/test/java/org/onosproject/net/flow/criteria/CriteriaTest.java
@@ -198,6 +198,12 @@
Criterion sameAsMatchMpls1 = Criteria.matchMplsLabel(mpls1);
Criterion matchMpls2 = Criteria.matchMplsLabel(mpls2);
+ long tunnelId1 = 1;
+ long tunnelId2 = 2;
+ Criterion matchTunnelId1 = Criteria.matchTunnelId(tunnelId1);
+ Criterion sameAsMatchTunnelId1 = Criteria.matchTunnelId(tunnelId1);
+ Criterion matchTunnelId2 = Criteria.matchTunnelId(tunnelId2);
+
int ipv6ExthdrFlags1 =
Criterion.IPv6ExthdrFlags.NONEXT.getValue() |
Criterion.IPv6ExthdrFlags.ESP.getValue() |
@@ -992,6 +998,33 @@
.testEquals();
}
+ // TunnelIdCriterion class
+
+ /**
+ * Test the matchTunnelId method.
+ */
+ @Test
+ public void testMatchTunnelIdMethod() {
+ Criterion matchTunnelId = Criteria.matchTunnelId(tunnelId1);
+ TunnelIdCriterion tunnelIdCriterion =
+ checkAndConvert(matchTunnelId,
+ Criterion.Type.TUNNEL_ID,
+ TunnelIdCriterion.class);
+ assertThat(tunnelIdCriterion.tunnelId(), is(equalTo(tunnelId1)));
+
+ }
+
+ /**
+ * Test the equals() method of the TunnelIdCriterion class.
+ */
+ @Test
+ public void testTunnelIdCriterionEquals() {
+ new EqualsTester()
+ .addEqualityGroup(matchTunnelId1, sameAsMatchTunnelId1)
+ .addEqualityGroup(matchTunnelId2)
+ .testEquals();
+ }
+
// IPv6ExthdrFlagsCriterion class
/**
diff --git a/core/store/serializers/src/main/java/org/onosproject/store/serializers/KryoNamespaces.java b/core/store/serializers/src/main/java/org/onosproject/store/serializers/KryoNamespaces.java
index b81c5ad..b68e1d6 100644
--- a/core/store/serializers/src/main/java/org/onosproject/store/serializers/KryoNamespaces.java
+++ b/core/store/serializers/src/main/java/org/onosproject/store/serializers/KryoNamespaces.java
@@ -119,6 +119,7 @@
import org.onosproject.net.flow.criteria.PortCriterion;
import org.onosproject.net.flow.criteria.SctpPortCriterion;
import org.onosproject.net.flow.criteria.TcpPortCriterion;
+import org.onosproject.net.flow.criteria.TunnelIdCriterion;
import org.onosproject.net.flow.criteria.UdpPortCriterion;
import org.onosproject.net.flow.criteria.VlanIdCriterion;
import org.onosproject.net.flow.criteria.VlanPcpCriterion;
@@ -320,6 +321,7 @@
IPv6NDTargetAddressCriterion.class,
IPv6NDLinkLayerAddressCriterion.class,
MplsCriterion.class,
+ TunnelIdCriterion.class,
IPv6ExthdrFlagsCriterion.class,
LambdaCriterion.class,
IndexedLambdaCriterion.class,
@@ -346,6 +348,7 @@
L2ModificationInstruction.PopVlanInstruction.class,
L2ModificationInstruction.ModMplsLabelInstruction.class,
L2ModificationInstruction.ModMplsTtlInstruction.class,
+ L2ModificationInstruction.ModTunnelIdInstruction.class,
L3ModificationInstruction.class,
L3ModificationInstruction.L3SubType.class,
L3ModificationInstruction.ModIPInstruction.class,
diff --git a/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowEntryBuilder.java b/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowEntryBuilder.java
index 4605564..6760462 100644
--- a/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowEntryBuilder.java
+++ b/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowEntryBuilder.java
@@ -72,6 +72,7 @@
import org.projectfloodlight.openflow.types.Masked;
import org.projectfloodlight.openflow.types.OFVlanVidMatch;
import org.projectfloodlight.openflow.types.U32;
+import org.projectfloodlight.openflow.types.U64;
import org.projectfloodlight.openflow.types.U8;
import org.projectfloodlight.openflow.types.VlanPcp;
import org.slf4j.Logger;
@@ -402,6 +403,11 @@
OFOxm<U32> labelId = (OFOxm<U32>) oxm;
builder.setMpls(MplsLabel.mplsLabel((int) labelId.getValue().getValue()));
break;
+ case TUNNEL_ID:
+ @SuppressWarnings("unchecked")
+ OFOxm<U64> tunnelId = (OFOxm<U64>) oxm;
+ builder.setTunnelId(tunnelId.getValue().getValue());
+ break;
case ARP_OP:
case ARP_SHA:
case ARP_SPA:
@@ -451,7 +457,6 @@
case SCTP_SRC:
case TCP_DST:
case TCP_SRC:
- case TUNNEL_ID:
case UDP_DST:
case UDP_SRC:
default:
@@ -640,7 +645,7 @@
break;
case IPV6_EXTHDR:
builder.matchIPv6ExthdrFlags((short) match.get(MatchField.IPV6_EXTHDR)
- .getValue());
+ .getValue());
break;
case OCH_SIGID:
CircuitSignalID sigId = match.get(MatchField.OCH_SIGID);
@@ -653,13 +658,16 @@
U8 sigType = match.get(MatchField.OCH_SIGTYPE);
builder.add(matchOchSignalType(lookupOchSignalType((byte) sigType.getValue())));
break;
+ case TUNNEL_ID:
+ long tunnelId = match.get(MatchField.TUNNEL_ID).getValue();
+ builder.matchTunnelId(tunnelId);
+ break;
case ARP_OP:
case ARP_SHA:
case ARP_SPA:
case ARP_THA:
case ARP_TPA:
case MPLS_TC:
- case TUNNEL_ID:
default:
log.warn("Match type {} not yet implemented.", field.id);
}
diff --git a/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowModBuilder.java b/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowModBuilder.java
index d34fd5e..d9d02ff 100644
--- a/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowModBuilder.java
+++ b/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowModBuilder.java
@@ -44,6 +44,7 @@
import org.onosproject.net.flow.criteria.PortCriterion;
import org.onosproject.net.flow.criteria.SctpPortCriterion;
import org.onosproject.net.flow.criteria.TcpPortCriterion;
+import org.onosproject.net.flow.criteria.TunnelIdCriterion;
import org.onosproject.net.flow.criteria.UdpPortCriterion;
import org.onosproject.net.flow.criteria.VlanIdCriterion;
import org.onosproject.net.flow.criteria.VlanPcpCriterion;
@@ -72,6 +73,7 @@
import org.projectfloodlight.openflow.types.TransportPort;
import org.projectfloodlight.openflow.types.U16;
import org.projectfloodlight.openflow.types.U32;
+import org.projectfloodlight.openflow.types.U64;
import org.projectfloodlight.openflow.types.U8;
import org.projectfloodlight.openflow.types.VlanPcp;
import org.projectfloodlight.openflow.types.VlanVid;
@@ -392,6 +394,11 @@
byte signalType = OpenFlowValueMapper.lookupOchSignalType(sc.signalType());
mBuilder.setExact(MatchField.OCH_SIGTYPE, U8.of(signalType));
break;
+ case TUNNEL_ID:
+ TunnelIdCriterion tunnelId = (TunnelIdCriterion) c;
+ mBuilder.setExact(MatchField.TUNNEL_ID,
+ U64.of(tunnelId.tunnelId()));
+ break;
case ARP_OP:
case ARP_SHA:
case ARP_SPA:
@@ -400,7 +407,6 @@
case MPLS_BOS:
case MPLS_TC:
case PBB_ISID:
- case TUNNEL_ID:
default:
log.warn("Match type {} not yet implemented.", c.type());
}
diff --git a/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowModBuilderVer13.java b/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowModBuilderVer13.java
index 63fc63a..7bbc375 100644
--- a/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowModBuilderVer13.java
+++ b/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowModBuilderVer13.java
@@ -35,6 +35,7 @@
import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModVlanIdInstruction;
import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModVlanPcpInstruction;
import org.onosproject.net.flow.instructions.L2ModificationInstruction.PushHeaderInstructions;
+import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModTunnelIdInstruction;
import org.onosproject.net.flow.instructions.L3ModificationInstruction;
import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModIPInstruction;
import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModIPv6FlowLabelInstruction;
@@ -336,6 +337,10 @@
PushHeaderInstructions pushVlanInstruction = (PushHeaderInstructions) l2m;
return factory().actions().pushVlan(
EthType.of(pushVlanInstruction.ethernetType().toShort()));
+ case TUNNEL_ID:
+ ModTunnelIdInstruction tunnelId = (ModTunnelIdInstruction) l2m;
+ oxm = factory().oxms().tunnelId(U64.of(tunnelId.tunnelId()));
+ break;
default:
log.warn("Unimplemented action type {}.", l2m.subtype());
break;