CORD-413 Implement MPLS Termination in OFDPA3 pipeliner
Additionally, this patch includes
- Minor refactoring
- Skip method length checkstyle for FlowEntryBuilder::hasSetField
Change-Id: I7887f454f552a9e346c323524f359929deadf427
diff --git a/core/api/src/main/java/org/onosproject/net/flow/instructions/ExtensionTreatmentType.java b/core/api/src/main/java/org/onosproject/net/flow/instructions/ExtensionTreatmentType.java
index f036638..ec7cb15 100644
--- a/core/api/src/main/java/org/onosproject/net/flow/instructions/ExtensionTreatmentType.java
+++ b/core/api/src/main/java/org/onosproject/net/flow/instructions/ExtensionTreatmentType.java
@@ -49,6 +49,7 @@
NICIRA_PUSH_NSH(38),
NICIRA_POP_NSH(39),
OFDPA_SET_VLAN_ID(64),
+ OFDPA_SET_MPLS_TYPE(65),
NICIRA_TUN_GPE_NP(111),
NICIRA_SET_NSH_SPI(113),
NICIRA_SET_NSH_SI(114),
diff --git a/drivers/default/src/main/java/org/onosproject/driver/extensions/Ofdpa3ExtensionTreatmentInterpreter.java b/drivers/default/src/main/java/org/onosproject/driver/extensions/Ofdpa3ExtensionTreatmentInterpreter.java
new file mode 100644
index 0000000..a07862e
--- /dev/null
+++ b/drivers/default/src/main/java/org/onosproject/driver/extensions/Ofdpa3ExtensionTreatmentInterpreter.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2016-present 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.driver.extensions;
+
+import org.onosproject.net.behaviour.ExtensionTreatmentResolver;
+import org.onosproject.net.driver.AbstractHandlerBehaviour;
+import org.onosproject.net.flow.instructions.ExtensionTreatment;
+import org.onosproject.net.flow.instructions.ExtensionTreatmentType;
+import org.onosproject.openflow.controller.ExtensionTreatmentInterpreter;
+import org.projectfloodlight.openflow.protocol.OFActionType;
+import org.projectfloodlight.openflow.protocol.OFFactory;
+import org.projectfloodlight.openflow.protocol.action.OFAction;
+import org.projectfloodlight.openflow.protocol.action.OFActionSetField;
+import org.projectfloodlight.openflow.protocol.oxm.OFOxm;
+import org.projectfloodlight.openflow.protocol.oxm.OFOxmOfdpaMplsType;
+import org.projectfloodlight.openflow.types.U16;
+
+/**
+ * Interpreter for OFDPA3 OpenFlow treatment extensions.
+ */
+public class Ofdpa3ExtensionTreatmentInterpreter extends AbstractHandlerBehaviour
+ implements ExtensionTreatmentInterpreter, ExtensionTreatmentResolver {
+ @Override
+ public boolean supported(ExtensionTreatmentType extensionTreatmentType) {
+ if (extensionTreatmentType.equals(
+ ExtensionTreatmentType.ExtensionTreatmentTypes.OFDPA_SET_MPLS_TYPE.type())) {
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public OFAction mapInstruction(OFFactory factory, ExtensionTreatment extensionTreatment) {
+ ExtensionTreatmentType type = extensionTreatment.type();
+ if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.OFDPA_SET_MPLS_TYPE.type())) {
+ short mplsType = ((Ofdpa3SetMplsType) extensionTreatment).mplsType();
+ return factory.actions().setField(factory.oxms().ofdpaMplsType(
+ U16.ofRaw(mplsType)));
+ }
+ throw new UnsupportedOperationException(
+ "Unexpected ExtensionTreatment: " + extensionTreatment.toString());
+ }
+
+ @Override
+ public ExtensionTreatment mapAction(OFAction action) throws UnsupportedOperationException {
+ if (action.getType().equals(OFActionType.SET_FIELD)) {
+ OFActionSetField setFieldAction = (OFActionSetField) action;
+ OFOxm<?> oxm = setFieldAction.getField();
+ switch (oxm.getMatchField().id) {
+ case OFDPA_MPLS_TYPE:
+ OFOxmOfdpaMplsType mplsType = (OFOxmOfdpaMplsType) oxm;
+ return new Ofdpa3SetMplsType(mplsType.getValue().getRaw());
+ default:
+ throw new UnsupportedOperationException(
+ "Driver does not support extension type " + oxm.getMatchField().id);
+ }
+ }
+ throw new UnsupportedOperationException(
+ "Unexpected OFAction: " + action.toString());
+ }
+
+ @Override
+ public ExtensionTreatment getExtensionInstruction(ExtensionTreatmentType type) {
+ if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.OFDPA_SET_MPLS_TYPE.type())) {
+ return new Ofdpa3SetMplsType();
+ }
+ throw new UnsupportedOperationException(
+ "Driver does not support extension type " + type.toString());
+ }
+}
diff --git a/drivers/default/src/main/java/org/onosproject/driver/extensions/Ofdpa3MplsType.java b/drivers/default/src/main/java/org/onosproject/driver/extensions/Ofdpa3MplsType.java
new file mode 100644
index 0000000..b4a9c56
--- /dev/null
+++ b/drivers/default/src/main/java/org/onosproject/driver/extensions/Ofdpa3MplsType.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2016-present 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.driver.extensions;
+
+/**
+ * OFDPA MPLS Type experimenter match fields.
+ */
+public enum Ofdpa3MplsType {
+ /**
+ * None.
+ */
+ NONE((short) 0),
+ /**
+ * Virtual Private Wire Service.
+ */
+ VPWS((short) 1),
+ /**
+ * Virtual Private LAN Service.
+ */
+ VPLS((short) 2),
+ /**
+ * MPLS-TP OAM (Operation, Administration and Maintenance).
+ */
+ OAM((short) 4),
+ /**
+ * L3 unicast.
+ */
+ L3_UNICAST ((short) 8),
+ /**
+ * L3 multicast.
+ */
+ L3_MULTICAST((short) 16),
+ /**
+ * L3 PHP (Penultimate Hop Popping).
+ */
+ L3_PHP((short) 32);
+
+ private short value;
+
+ Ofdpa3MplsType(short value) {
+ this.value = value;
+ }
+
+ /**
+ * Gets the value as an short.
+ *
+ * @return the value as an short
+ */
+ public short getValue() {
+ return this.value;
+ }
+}
\ No newline at end of file
diff --git a/drivers/default/src/main/java/org/onosproject/driver/extensions/Ofdpa3SetMplsType.java b/drivers/default/src/main/java/org/onosproject/driver/extensions/Ofdpa3SetMplsType.java
new file mode 100644
index 0000000..a9b6e87
--- /dev/null
+++ b/drivers/default/src/main/java/org/onosproject/driver/extensions/Ofdpa3SetMplsType.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright 2016-present 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.driver.extensions;
+
+import com.google.common.base.MoreObjects;
+import org.onlab.util.KryoNamespace;
+import org.onosproject.net.flow.AbstractExtension;
+import org.onosproject.net.flow.instructions.ExtensionTreatment;
+import org.onosproject.net.flow.instructions.ExtensionTreatmentType;
+
+import java.util.Objects;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * OFDPA set MPLS Type extension instruction.
+ */
+public class Ofdpa3SetMplsType extends AbstractExtension implements ExtensionTreatment {
+ private short mplsType;
+
+ private static final KryoNamespace APPKRYO = new KryoNamespace.Builder()
+ .register(Ofdpa3MplsType.class)
+ .build();
+
+ /**
+ * Constructs a new set MPLS type instruction.
+ */
+ protected Ofdpa3SetMplsType() {
+ mplsType = Ofdpa3MplsType.NONE.getValue();
+ }
+
+ /**
+ * Constructs a new set MPLS type instruction with given type.
+ *
+ * @param mplsType MPLS type in short
+ */
+ public Ofdpa3SetMplsType(short mplsType) {
+ checkNotNull(mplsType);
+ this.mplsType = mplsType;
+ }
+
+ /**
+ * Constructs a new set MPLS type instruction with given type.
+ *
+ * @param mplsType Ofdpa3MplsType
+ */
+ public Ofdpa3SetMplsType(Ofdpa3MplsType mplsType) {
+ checkNotNull(mplsType);
+ this.mplsType = mplsType.getValue();
+ }
+
+ /**
+ * Gets the MPLS type.
+ *
+ * @return MPLS type
+ */
+ public short mplsType() {
+ return mplsType;
+ }
+
+ @Override
+ public ExtensionTreatmentType type() {
+ return ExtensionTreatmentType.ExtensionTreatmentTypes.OFDPA_SET_MPLS_TYPE.type();
+ }
+
+ @Override
+ public void deserialize(byte[] data) {
+ mplsType = APPKRYO.deserialize(data);
+ }
+
+ @Override
+ public byte[] serialize() {
+ return APPKRYO.serialize(mplsType);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(mplsType);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj instanceof Ofdpa3SetMplsType) {
+ Ofdpa3SetMplsType that = (Ofdpa3SetMplsType) obj;
+ return Objects.equals(mplsType, that.mplsType);
+
+ }
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(getClass())
+ .add("mplsType", mplsType)
+ .toString();
+ }
+}
diff --git a/drivers/default/src/main/java/org/onosproject/driver/extensions/codec/Ofdpa3SetMplsTypeCodec.java b/drivers/default/src/main/java/org/onosproject/driver/extensions/codec/Ofdpa3SetMplsTypeCodec.java
new file mode 100644
index 0000000..9f3816a
--- /dev/null
+++ b/drivers/default/src/main/java/org/onosproject/driver/extensions/codec/Ofdpa3SetMplsTypeCodec.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2016-present 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.driver.extensions.codec;
+
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import org.onosproject.codec.CodecContext;
+import org.onosproject.codec.JsonCodec;
+import org.onosproject.driver.extensions.Ofdpa3SetMplsType;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.onlab.util.Tools.nullIsIllegal;
+
+/**
+ * JSON Codec for Ofdpa set mpls type class.
+ */
+public class Ofdpa3SetMplsTypeCodec extends JsonCodec<Ofdpa3SetMplsType> {
+
+ private static final String MPLS_TYPE = "mplsType";
+
+ private static final String MISSING_MEMBER_MESSAGE = " member is required in Ofdpa3SetMplsType";
+ private static final String MISSING_MPLS_TYPE_MESSAGE = "mplsType cannot be null";
+
+ @Override
+ public ObjectNode encode(Ofdpa3SetMplsType mplsType, CodecContext context) {
+ checkNotNull(mplsType, MISSING_MPLS_TYPE_MESSAGE);
+ return context.mapper().createObjectNode()
+ .put(MPLS_TYPE, mplsType.mplsType());
+ }
+
+ @Override
+ public Ofdpa3SetMplsType decode(ObjectNode json, CodecContext context) {
+ if (json == null || !json.isObject()) {
+ return null;
+ }
+
+ // parse ofdpa mpls type
+ short mplsType = (short) nullIsIllegal(json.get(MPLS_TYPE),
+ MPLS_TYPE + MISSING_MEMBER_MESSAGE).asInt();
+ return new Ofdpa3SetMplsType(mplsType);
+ }
+}
diff --git a/drivers/default/src/main/java/org/onosproject/driver/extensions/codec/OfdpaMatchVlanVidCodec.java b/drivers/default/src/main/java/org/onosproject/driver/extensions/codec/OfdpaMatchVlanVidCodec.java
index bc0e876..65ed92b 100644
--- a/drivers/default/src/main/java/org/onosproject/driver/extensions/codec/OfdpaMatchVlanVidCodec.java
+++ b/drivers/default/src/main/java/org/onosproject/driver/extensions/codec/OfdpaMatchVlanVidCodec.java
@@ -30,15 +30,14 @@
public class OfdpaMatchVlanVidCodec extends JsonCodec<OfdpaMatchVlanVid> {
private static final String VLAN_ID = "vlanId";
-
private static final String MISSING_MEMBER_MESSAGE = " member is required in OfdpaMatchVlanVid";
+ private static final String MISSING_VLAN_ID_MESSAGE = "Vlan ID cannot be null";
@Override
public ObjectNode encode(OfdpaMatchVlanVid vlanId, CodecContext context) {
- checkNotNull(vlanId, "Vlan ID cannot be null");
- ObjectNode root = context.mapper().createObjectNode()
+ checkNotNull(vlanId, MISSING_VLAN_ID_MESSAGE);
+ return context.mapper().createObjectNode()
.put(VLAN_ID, vlanId.vlanId().id());
- return root;
}
@Override
diff --git a/drivers/default/src/main/java/org/onosproject/driver/extensions/codec/OfdpaSetVlanVidCodec.java b/drivers/default/src/main/java/org/onosproject/driver/extensions/codec/OfdpaSetVlanVidCodec.java
index db5ee76..2009809 100644
--- a/drivers/default/src/main/java/org/onosproject/driver/extensions/codec/OfdpaSetVlanVidCodec.java
+++ b/drivers/default/src/main/java/org/onosproject/driver/extensions/codec/OfdpaSetVlanVidCodec.java
@@ -30,15 +30,14 @@
public class OfdpaSetVlanVidCodec extends JsonCodec<OfdpaSetVlanVid> {
private static final String VLAN_ID = "vlanId";
-
private static final String MISSING_MEMBER_MESSAGE = " member is required in OfdpaSetVlanVid";
+ private static final String MISSING_VLAN_ID_MESSAGE = "Vlan ID cannot be null";
@Override
public ObjectNode encode(OfdpaSetVlanVid vlanId, CodecContext context) {
- checkNotNull(vlanId, "Vlan ID cannot be null");
- ObjectNode root = context.mapper().createObjectNode()
+ checkNotNull(vlanId, MISSING_VLAN_ID_MESSAGE);
+ return context.mapper().createObjectNode()
.put(VLAN_ID, vlanId.vlanId().id());
- return root;
}
@Override
diff --git a/drivers/default/src/main/java/org/onosproject/driver/pipeline/CpqdOfdpa3Pipeline.java b/drivers/default/src/main/java/org/onosproject/driver/pipeline/CpqdOfdpa3Pipeline.java
index dbc3e39..9cf05d2 100644
--- a/drivers/default/src/main/java/org/onosproject/driver/pipeline/CpqdOfdpa3Pipeline.java
+++ b/drivers/default/src/main/java/org/onosproject/driver/pipeline/CpqdOfdpa3Pipeline.java
@@ -59,6 +59,6 @@
@Override
protected Collection<FlowRule> processEthTypeSpecific(ForwardingObjective fwd) {
- return processEthTypeSpecificInternal(fwd, true);
+ return processEthTypeSpecificInternal(fwd, true, ACL_TABLE);
}
}
diff --git a/drivers/default/src/main/java/org/onosproject/driver/pipeline/Ofdpa2Pipeline.java b/drivers/default/src/main/java/org/onosproject/driver/pipeline/Ofdpa2Pipeline.java
index b9d8d89..a72eea1 100644
--- a/drivers/default/src/main/java/org/onosproject/driver/pipeline/Ofdpa2Pipeline.java
+++ b/drivers/default/src/main/java/org/onosproject/driver/pipeline/Ofdpa2Pipeline.java
@@ -37,6 +37,8 @@
import org.onlab.util.KryoNamespace;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreService;
+import org.onosproject.driver.extensions.Ofdpa3MplsType;
+import org.onosproject.driver.extensions.Ofdpa3SetMplsType;
import org.onosproject.driver.extensions.OfdpaMatchVlanVid;
import org.onosproject.driver.extensions.OfdpaSetVlanVid;
import org.onosproject.net.DeviceId;
@@ -98,6 +100,7 @@
protected static final int MULTICAST_ROUTING_TABLE = 40;
protected static final int MPLS_TABLE_0 = 23;
protected static final int MPLS_TABLE_1 = 24;
+ protected static final int MPLS_L3_TYPE = 27;
protected static final int BRIDGING_TABLE = 50;
protected static final int ACL_TABLE = 60;
protected static final int MAC_LEARNING_TABLE = 254;
@@ -824,7 +827,7 @@
* @return A collection of flow rules, or an empty set
*/
protected Collection<FlowRule> processEthTypeSpecific(ForwardingObjective fwd) {
- return processEthTypeSpecificInternal(fwd, false);
+ return processEthTypeSpecificInternal(fwd, false, ACL_TABLE);
}
/**
@@ -840,7 +843,8 @@
* @return A collection of flow rules, or an empty set
*/
protected Collection<FlowRule> processEthTypeSpecificInternal(ForwardingObjective fwd,
- boolean allowDefaultRoute) {
+ boolean allowDefaultRoute,
+ int mplsNextTable) {
TrafficSelector selector = fwd.selector();
EthTypeCriterion ethType =
(EthTypeCriterion) selector.getCriterion(Criterion.Type.ETH_TYPE);
@@ -970,7 +974,17 @@
return Collections.emptySet();
}
}
- tb.transition(ACL_TABLE);
+
+ if (forTableId == MPLS_TABLE_1) {
+ if (mplsNextTable == MPLS_L3_TYPE) {
+ Ofdpa3SetMplsType setMplsType = new Ofdpa3SetMplsType(Ofdpa3MplsType.L3_PHP);
+ tb.extension(setMplsType, deviceId);
+ }
+ tb.transition(mplsNextTable);
+ } else {
+ tb.transition(ACL_TABLE);
+ }
+
FlowRule.Builder ruleBuilder = DefaultFlowRule.builder()
.fromApp(fwd.appId())
.withPriority(fwd.priority())
diff --git a/drivers/default/src/main/java/org/onosproject/driver/pipeline/Ofdpa3Pipeline.java b/drivers/default/src/main/java/org/onosproject/driver/pipeline/Ofdpa3Pipeline.java
index 68c42e0..4f9740c 100644
--- a/drivers/default/src/main/java/org/onosproject/driver/pipeline/Ofdpa3Pipeline.java
+++ b/drivers/default/src/main/java/org/onosproject/driver/pipeline/Ofdpa3Pipeline.java
@@ -68,6 +68,6 @@
@Override
protected Collection<FlowRule> processEthTypeSpecific(ForwardingObjective fwd) {
- return processEthTypeSpecificInternal(fwd, true);
+ return processEthTypeSpecificInternal(fwd, true, MPLS_L3_TYPE);
}
}
diff --git a/drivers/default/src/main/resources/onos-drivers.xml b/drivers/default/src/main/resources/onos-drivers.xml
index 6a69dda..b51f087 100644
--- a/drivers/default/src/main/resources/onos-drivers.xml
+++ b/drivers/default/src/main/resources/onos-drivers.xml
@@ -87,6 +87,10 @@
manufacturer="Broadcom Corp." hwVersion="OF-DPA 3.0" swVersion="OF-DPA 3.0">
<behaviour api="org.onosproject.net.behaviour.Pipeliner"
impl="org.onosproject.driver.pipeline.Ofdpa3Pipeline"/>
+ <behaviour api="org.onosproject.openflow.controller.ExtensionTreatmentInterpreter"
+ impl="org.onosproject.driver.extensions.Ofdpa3ExtensionTreatmentInterpreter" />
+ <behaviour api="org.onosproject.net.behaviour.ExtensionTreatmentResolver"
+ impl="org.onosproject.driver.extensions.Ofdpa3ExtensionTreatmentInterpreter" />
<behaviour api="org.onosproject.openflow.controller.ExtensionSelectorInterpreter"
impl="org.onosproject.driver.extensions.OfdpaExtensionSelectorInterpreter" />
<behaviour api="org.onosproject.net.behaviour.ExtensionSelectorResolver"
diff --git a/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/util/FlowEntryBuilder.java b/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/util/FlowEntryBuilder.java
index e40990e..d2ed633 100644
--- a/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/util/FlowEntryBuilder.java
+++ b/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/util/FlowEntryBuilder.java
@@ -427,7 +427,7 @@
return configureTreatmentBuilder(actions, builder, driverHandler, deviceId);
}
-
+ // CHECKSTYLE IGNORE MethodLength FOR NEXT 1 LINES
private static void handleSetField(TrafficTreatment.Builder builder,
OFActionSetField action,
DriverHandler driverHandler,
@@ -577,6 +577,16 @@
OFOxm<IPv4Address> arpspa = (OFOxm<IPv4Address>) oxm;
builder.setArpSpa(Ip4Address.valueOf(arpspa.getValue().getInt()));
break;
+ case OFDPA_MPLS_TYPE:
+ if (treatmentInterpreter != null) {
+ try {
+ builder.extension(treatmentInterpreter.mapAction(action), deviceId);
+ break;
+ } catch (UnsupportedOperationException e) {
+ log.warn("Unsupported action extension");
+ }
+ }
+ break;
case ARP_THA:
case ARP_TPA:
case BSN_EGR_PORT_GROUP_ID: