[CORD-545] Adds MPLS L2 Port support in ONOS core

Change-Id: I61d9b2c14580b4995fdcc96571745bfd00ee586f
diff --git a/core/api/src/main/java/org/onosproject/net/flow/criteria/ExtensionSelectorType.java b/core/api/src/main/java/org/onosproject/net/flow/criteria/ExtensionSelectorType.java
index 5b9bb57..dd31d54 100644
--- a/core/api/src/main/java/org/onosproject/net/flow/criteria/ExtensionSelectorType.java
+++ b/core/api/src/main/java/org/onosproject/net/flow/criteria/ExtensionSelectorType.java
@@ -41,6 +41,7 @@
         NICIRA_MATCH_ENCAP_ETH_TYPE(6),
         OFDPA_MATCH_VLAN_VID(16),
         OFDPA_MATCH_OVID(17),
+        OFDPA_MATCH_MPLS_L2_PORT(18),
         BMV2_MATCH_PARAMS(128),
 
         UNRESOLVED_TYPE(200);
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 164d718..f21bb7f 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
@@ -51,6 +51,7 @@
         OFDPA_SET_VLAN_ID(64),
         OFDPA_SET_MPLS_TYPE(65),
         OFDPA_SET_OVID(66),
+        OFDPA_SET_MPLS_L2_PORT(67),
         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/Ofdpa3ExtensionSelectorInterpreter.java b/drivers/default/src/main/java/org/onosproject/driver/extensions/Ofdpa3ExtensionSelectorInterpreter.java
index 05c943c..388d0e6 100644
--- a/drivers/default/src/main/java/org/onosproject/driver/extensions/Ofdpa3ExtensionSelectorInterpreter.java
+++ b/drivers/default/src/main/java/org/onosproject/driver/extensions/Ofdpa3ExtensionSelectorInterpreter.java
@@ -26,11 +26,13 @@
 import org.projectfloodlight.openflow.protocol.OFFactory;
 import org.projectfloodlight.openflow.protocol.match.MatchField;
 import org.projectfloodlight.openflow.protocol.oxm.OFOxm;
+import org.projectfloodlight.openflow.protocol.oxm.OFOxmOfdpaMplsL2Port;
 import org.projectfloodlight.openflow.protocol.oxm.OFOxmOfdpaOvid;
 import org.projectfloodlight.openflow.protocol.oxm.OFOxmVlanVid;
 import org.projectfloodlight.openflow.protocol.oxm.OFOxmVlanVidMasked;
 import org.projectfloodlight.openflow.types.OFVlanVidMatch;
 import org.projectfloodlight.openflow.types.U16;
+import org.projectfloodlight.openflow.types.U32;
 import org.projectfloodlight.openflow.types.VlanVid;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -49,6 +51,8 @@
             return true;
         } else if (extensionSelectorType.equals(ExtensionSelectorTypes.OFDPA_MATCH_OVID.type())) {
             return true;
+        } else if (extensionSelectorType.equals(ExtensionSelectorTypes.OFDPA_MATCH_MPLS_L2_PORT.type())) {
+            return true;
         }
         return false;
     }
@@ -82,6 +86,18 @@
                 short oVid = (short) (mask | vlanId.toShort());
                 return factory.oxms().ofdpaOvid(U16.ofRaw(oVid));
             }
+        } else if (type.equals(ExtensionSelectorTypes.OFDPA_MATCH_MPLS_L2_PORT.type())) {
+            int mplsL2Port = ((Ofdpa3MatchMplsL2Port) extensionSelector).mplsL2Port();
+            /*
+             * 0x0000XXXX UNI Interface.
+             * 0x0002XXXX NNI Interface
+             */
+            if ((mplsL2Port >= 0 && mplsL2Port <= 0x0000FFFF) ||
+                    (mplsL2Port >= 0x00020000 && mplsL2Port <= 0x0002FFFF)) {
+                return factory.oxms().ofdpaMplsL2Port(U32.ofRaw(mplsL2Port));
+            }
+            throw new UnsupportedOperationException(
+                        "Unexpected ExtensionSelector: " + extensionSelector.toString());
         }
         throw new UnsupportedOperationException(
                 "Unexpected ExtensionSelector: " + extensionSelector.toString());
@@ -126,6 +142,28 @@
                 vlanId = VlanId.vlanId(oVid);
                 }
             return new Ofdpa3MatchOvid(vlanId);
+        } else if (oxm.getMatchField().equals(MatchField.OFDPA_MPLS_L2_PORT)) {
+            Integer mplsL2Port;
+            /*
+             * Supported but not used for now.
+             */
+            if (oxm.isMasked()) {
+                throw new UnsupportedOperationException(
+                        "Unexpected OXM: " + oxm.toString());
+            } else {
+                OFOxmOfdpaMplsL2Port mplsl2port = ((OFOxmOfdpaMplsL2Port) oxm);
+                mplsL2Port = mplsl2port.getValue().getRaw();
+                /*
+                 * 0x0000XXXX UNI Interface.
+                 * 0x0002XXXX NNI Interface
+                 */
+                if ((mplsL2Port >= 0 && mplsL2Port <= 0x0000FFFF) ||
+                        (mplsL2Port >= 0x00020000 && mplsL2Port <= 0x0002FFFF)) {
+                    return new Ofdpa3MatchMplsL2Port(mplsL2Port);
+                }
+                throw new UnsupportedOperationException(
+                        "Unexpected OXM: " + oxm.toString());
+            }
         }
         throw new UnsupportedOperationException(
                 "Unexpected OXM: " + oxm.toString());
@@ -137,6 +175,8 @@
             return new OfdpaMatchVlanVid();
         } else if (type.equals(ExtensionSelectorTypes.OFDPA_MATCH_OVID.type())) {
             return new Ofdpa3MatchOvid();
+        } else if (type.equals(ExtensionSelectorTypes.OFDPA_MATCH_MPLS_L2_PORT.type())) {
+            return new Ofdpa3MatchMplsL2Port();
         }
         throw new UnsupportedOperationException(
                 "Driver does not support extension type " + type.toString());
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
index afdb29f..c449702 100644
--- a/drivers/default/src/main/java/org/onosproject/driver/extensions/Ofdpa3ExtensionTreatmentInterpreter.java
+++ b/drivers/default/src/main/java/org/onosproject/driver/extensions/Ofdpa3ExtensionTreatmentInterpreter.java
@@ -27,9 +27,11 @@
 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.OFOxmOfdpaMplsL2Port;
 import org.projectfloodlight.openflow.protocol.oxm.OFOxmOfdpaMplsType;
 import org.projectfloodlight.openflow.protocol.oxm.OFOxmOfdpaOvid;
 import org.projectfloodlight.openflow.types.U16;
+import org.projectfloodlight.openflow.types.U32;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -49,6 +51,9 @@
         } else if (extensionTreatmentType.equals(
                 ExtensionTreatmentType.ExtensionTreatmentTypes.OFDPA_SET_OVID.type())) {
             return true;
+        } else if (extensionTreatmentType.equals(
+                ExtensionTreatmentType.ExtensionTreatmentTypes.OFDPA_SET_MPLS_L2_PORT.type())) {
+            return true;
         }
         return false;
     }
@@ -67,6 +72,20 @@
             short oVid = (short) (mask | vlanId.toShort());
             return factory.actions().setField(factory.oxms().ofdpaOvid(
                     U16.ofRaw(oVid)));
+        } else if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.OFDPA_SET_MPLS_L2_PORT.type())) {
+            Integer mplsL2Port = ((Ofdpa3SetMplsL2Port) extensionTreatment).mplsL2Port();
+            /*
+             * 0x0000XXXX UNI Interface.
+             * 0x0002XXXX NNI Interface
+             */
+            if ((mplsL2Port >= 0 && mplsL2Port <= 0x0000FFFF) ||
+                    (mplsL2Port >= 0x00020000 && mplsL2Port <= 0x0002FFFF)) {
+                return factory.actions().setField(
+                        factory.oxms().ofdpaMplsL2Port(U32.ofRaw(mplsL2Port))
+                );
+            }
+            throw new UnsupportedOperationException(
+                    "Unexpected ExtensionTreatment: " + extensionTreatment.toString());
         }
         throw new UnsupportedOperationException(
                 "Unexpected ExtensionTreatment: " + extensionTreatment.toString());
@@ -87,6 +106,13 @@
                     short oVid = (short) (mask & ovid.getValue().getRaw());
                     VlanId vlanId = VlanId.vlanId(oVid);
                     return new Ofdpa3SetOvid(vlanId);
+                case OFDPA_MPLS_L2_PORT:
+                    OFOxmOfdpaMplsL2Port mplsl2Port = ((OFOxmOfdpaMplsL2Port) oxm);
+                    Integer mplsL2Port = mplsl2Port.getValue().getRaw();
+                    if ((mplsL2Port >= 0 && mplsL2Port <= 0x0000FFFF) ||
+                            (mplsL2Port >= 0x00020000 && mplsL2Port <= 0x0002FFFF)) {
+                        return new Ofdpa3SetMplsL2Port(mplsL2Port);
+                    }
                 default:
                     throw new UnsupportedOperationException(
                             "Driver does not support extension type " + oxm.getMatchField().id);
@@ -102,6 +128,8 @@
             return new Ofdpa3SetMplsType();
         } else if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.OFDPA_SET_OVID.type())) {
             return new Ofdpa3SetOvid();
+        } else if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.OFDPA_SET_MPLS_L2_PORT.type())) {
+            return new Ofdpa3SetMplsL2Port();
         }
         throw new UnsupportedOperationException(
                 "Driver does not support extension type " + type.toString());
diff --git a/drivers/default/src/main/java/org/onosproject/driver/extensions/Ofdpa3MatchMplsL2Port.java b/drivers/default/src/main/java/org/onosproject/driver/extensions/Ofdpa3MatchMplsL2Port.java
new file mode 100644
index 0000000..6213120
--- /dev/null
+++ b/drivers/default/src/main/java/org/onosproject/driver/extensions/Ofdpa3MatchMplsL2Port.java
@@ -0,0 +1,105 @@
+/*
+ * 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.criteria.ExtensionSelector;
+import org.onosproject.net.flow.criteria.ExtensionSelectorType;
+
+import java.util.Objects;
+
+/**
+ * OFDPA MPLS L2 Port extension match. MPLS L2 Port
+ * is a logical port and it is represented with an
+ * integer.
+ */
+public class Ofdpa3MatchMplsL2Port extends AbstractExtension implements ExtensionSelector {
+    /**
+     * Integer representing the logical port.
+     */
+    private int mplsL2Port;
+
+    private static final KryoNamespace APPKRYO = new KryoNamespace.Builder()
+            .build();
+
+    /**
+     * OFDPA MPLS L2 Port extension match.
+     */
+    protected Ofdpa3MatchMplsL2Port() {
+        mplsL2Port = 0;
+    }
+
+    /**
+     * Constructs a new MPLS L2 Port match with a given Integer.
+     *
+     * @param mplsl2port the MPLS L2 Port
+     */
+    public Ofdpa3MatchMplsL2Port(int mplsl2port) {
+        this.mplsL2Port = mplsl2port;
+    }
+
+    /**
+     * Gets the MPLS L2 Port.
+     *
+     * @return MPLS L2 Port
+     */
+    public int mplsL2Port() {
+        return mplsL2Port;
+    }
+
+    @Override
+    public ExtensionSelectorType type() {
+        return ExtensionSelectorType.ExtensionSelectorTypes.OFDPA_MATCH_MPLS_L2_PORT.type();
+    }
+
+    @Override
+    public byte[] serialize() {
+        return APPKRYO.serialize(mplsL2Port);
+    }
+
+    @Override
+    public void deserialize(byte[] data) {
+        mplsL2Port = APPKRYO.deserialize(data);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(mplsL2Port);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof Ofdpa3MatchMplsL2Port) {
+            Ofdpa3MatchMplsL2Port that = (Ofdpa3MatchMplsL2Port) obj;
+            return Objects.equals(mplsL2Port, that.mplsL2Port);
+
+        }
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass())
+                .add("mplsL2Port", mplsL2Port)
+                .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
index b4a9c56..84677c9 100644
--- a/drivers/default/src/main/java/org/onosproject/driver/extensions/Ofdpa3MplsType.java
+++ b/drivers/default/src/main/java/org/onosproject/driver/extensions/Ofdpa3MplsType.java
@@ -39,7 +39,7 @@
     /**
      * L3 unicast.
      */
-    L3_UNICAST ((short) 8),
+    L3_UNICAST((short) 8),
     /**
      * L3 multicast.
      */
diff --git a/drivers/default/src/main/java/org/onosproject/driver/extensions/Ofdpa3SetMplsL2Port.java b/drivers/default/src/main/java/org/onosproject/driver/extensions/Ofdpa3SetMplsL2Port.java
new file mode 100644
index 0000000..7073b15
--- /dev/null
+++ b/drivers/default/src/main/java/org/onosproject/driver/extensions/Ofdpa3SetMplsL2Port.java
@@ -0,0 +1,103 @@
+/*
+ * 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;
+
+/**
+ * OFDPA set MPLS L2 Port extension instruction.
+ */
+public class Ofdpa3SetMplsL2Port extends AbstractExtension implements ExtensionTreatment {
+    /**
+     * Integer representing the logical port.
+     */
+    private int mplsL2Port;
+
+    private static final KryoNamespace APPKRYO = new KryoNamespace.Builder()
+            .build();
+
+    /**
+     * Constructs a new set MPLS L2 Port instruction.
+     */
+    protected Ofdpa3SetMplsL2Port() {
+        mplsL2Port = 0;
+    }
+
+    /**
+     * Constructs a new set MPLS L2 Port instruction with a given integer.
+     *
+     * @param mplsl2port the MPLS L2 Port
+     */
+    public Ofdpa3SetMplsL2Port(Integer mplsl2port) {
+        this.mplsL2Port = mplsl2port;
+    }
+
+    /**
+     * Gets the MPLS L2 Port.
+     *
+     * @return MPLS L2 Port
+     */
+    public int mplsL2Port() {
+        return mplsL2Port;
+    }
+
+    @Override
+    public ExtensionTreatmentType type() {
+        return ExtensionTreatmentType.ExtensionTreatmentTypes.OFDPA_SET_MPLS_L2_PORT.type();
+    }
+
+    @Override
+    public void deserialize(byte[] data) {
+        mplsL2Port = APPKRYO.deserialize(data);
+    }
+
+    @Override
+    public byte[] serialize() {
+        return APPKRYO.serialize(mplsL2Port);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(mplsL2Port);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof Ofdpa3SetMplsL2Port) {
+            Ofdpa3SetMplsL2Port that = (Ofdpa3SetMplsL2Port) obj;
+            return Objects.equals(mplsL2Port, that.mplsL2Port);
+
+        }
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass())
+                .add("mplsL2Port", mplsL2Port)
+                .toString();
+    }
+}
diff --git a/drivers/default/src/main/java/org/onosproject/driver/extensions/codec/Ofdpa3MatchMplsL2PortCodec.java b/drivers/default/src/main/java/org/onosproject/driver/extensions/codec/Ofdpa3MatchMplsL2PortCodec.java
new file mode 100644
index 0000000..b32bd14
--- /dev/null
+++ b/drivers/default/src/main/java/org/onosproject/driver/extensions/codec/Ofdpa3MatchMplsL2PortCodec.java
@@ -0,0 +1,54 @@
+/*
+ * 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.Ofdpa3MatchMplsL2Port;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.onlab.util.Tools.nullIsIllegal;
+
+/**
+ * JSON Codec for Ofdpa match mpls l2 port class.
+ */
+public class Ofdpa3MatchMplsL2PortCodec extends JsonCodec<Ofdpa3MatchMplsL2Port> {
+
+    private static final String MPLS_L2_PORT = "mplsL2Port";
+    private static final String MISSING_MEMBER_MESSAGE = " member is required in Ofdpa3MatchMplsL2Port";
+    private static final String MISSING_MPLS_L2_PORT_MESSAGE = "MPLS L2 Port cannot be null";
+
+    @Override
+    public ObjectNode encode(Ofdpa3MatchMplsL2Port matchMplsL2Port, CodecContext context) {
+        checkNotNull(matchMplsL2Port, MISSING_MPLS_L2_PORT_MESSAGE);
+        return context.mapper().createObjectNode()
+                .put(MPLS_L2_PORT, matchMplsL2Port.mplsL2Port());
+    }
+
+    @Override
+    public Ofdpa3MatchMplsL2Port decode(ObjectNode json, CodecContext context) {
+        if (json == null || !json.isObject()) {
+            return null;
+        }
+
+        // parse ofdpa match mpls l2 port
+        int mplsL2Port = (int) nullIsIllegal(json.get(MPLS_L2_PORT),
+                MPLS_L2_PORT + MISSING_MEMBER_MESSAGE).asInt();
+        return new Ofdpa3MatchMplsL2Port(mplsL2Port);
+    }
+}
diff --git a/drivers/default/src/main/java/org/onosproject/driver/extensions/codec/Ofdpa3SetMplsL2PortCodec.java b/drivers/default/src/main/java/org/onosproject/driver/extensions/codec/Ofdpa3SetMplsL2PortCodec.java
new file mode 100644
index 0000000..9329a50
--- /dev/null
+++ b/drivers/default/src/main/java/org/onosproject/driver/extensions/codec/Ofdpa3SetMplsL2PortCodec.java
@@ -0,0 +1,54 @@
+/*
+ * 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.Ofdpa3SetMplsL2Port;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.onlab.util.Tools.nullIsIllegal;
+
+/**
+ * JSON Codec for Ofdpa set ovid class.
+ */
+public class Ofdpa3SetMplsL2PortCodec extends JsonCodec<Ofdpa3SetMplsL2Port> {
+
+    private static final String MPLS_L2_PORT = "mplsL2Port";
+    private static final String MISSING_MEMBER_MESSAGE = " member is required in Ofdpa3SetMplsL2Port";
+    private static final String MISSING_MPLS_L2_PORT_MESSAGE = "MPLS_L2_PORT cannot be null";
+
+    @Override
+    public ObjectNode encode(Ofdpa3SetMplsL2Port setMplsL2Port, CodecContext context) {
+        checkNotNull(setMplsL2Port, MISSING_MPLS_L2_PORT_MESSAGE);
+        return context.mapper().createObjectNode()
+                .put(MPLS_L2_PORT, setMplsL2Port.mplsL2Port());
+    }
+
+    @Override
+    public Ofdpa3SetMplsL2Port decode(ObjectNode json, CodecContext context) {
+        if (json == null || !json.isObject()) {
+            return null;
+        }
+
+        // parse ofdpa action set mpls l2 port
+        int mplsL2Port = (int) nullIsIllegal(json.get(MPLS_L2_PORT),
+                MPLS_L2_PORT + MISSING_MEMBER_MESSAGE).asInt();
+        return new Ofdpa3SetMplsL2Port(mplsL2Port);
+    }
+}
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 f85e790..5b6c2f3 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
@@ -581,6 +581,7 @@
             break;
         case OFDPA_MPLS_TYPE:
         case OFDPA_OVID:
+        case OFDPA_MPLS_L2_PORT:
             if (treatmentInterpreter != null) {
                 try {
                     builder.extension(treatmentInterpreter.mapAction(action), deviceId);
@@ -973,6 +974,18 @@
                     }
                 }
                 break;
+            case OFDPA_MPLS_L2_PORT:
+                if (selectorInterpreter != null &&
+                        selectorInterpreter.supported(ExtensionSelectorTypes.OFDPA_MATCH_MPLS_L2_PORT.type())) {
+                    if (match.getVersion().equals(OFVersion.OF_13)) {
+                        OFOxm oxm = ((OFMatchV3) match).getOxmList().get(MatchField.OFDPA_MPLS_L2_PORT);
+                        builder.extension(selectorInterpreter.mapOxm(oxm),
+                                          deviceId);
+                    } else {
+                        break;
+                    }
+                }
+                break;
             case MPLS_TC:
             default:
                 log.warn("Match type {} not yet implemented.", field.id);