[CORD-545] Adds OVID support in ONOS core

Change-Id: Ib0c195825e86c245e626a11b0eac5d7003b561b0
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 94de7d9..5b9bb57 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
@@ -40,6 +40,7 @@
         NICIRA_MATCH_NSH_CH4(5),
         NICIRA_MATCH_ENCAP_ETH_TYPE(6),
         OFDPA_MATCH_VLAN_VID(16),
+        OFDPA_MATCH_OVID(17),
         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 ec7cb15..164d718 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
@@ -50,6 +50,7 @@
         NICIRA_POP_NSH(39),
         OFDPA_SET_VLAN_ID(64),
         OFDPA_SET_MPLS_TYPE(65),
+        OFDPA_SET_OVID(66),
         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
new file mode 100644
index 0000000..05c943c
--- /dev/null
+++ b/drivers/default/src/main/java/org/onosproject/driver/extensions/Ofdpa3ExtensionSelectorInterpreter.java
@@ -0,0 +1,144 @@
+/*
+ * 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.onlab.packet.VlanId;
+import org.onosproject.net.behaviour.ExtensionSelectorResolver;
+import org.onosproject.net.driver.AbstractHandlerBehaviour;
+import org.onosproject.net.flow.criteria.ExtensionSelector;
+import org.onosproject.net.flow.criteria.ExtensionSelectorType;
+import org.onosproject.net.flow.criteria.ExtensionSelectorType.ExtensionSelectorTypes;
+import org.onosproject.openflow.controller.ExtensionSelectorInterpreter;
+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.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.VlanVid;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Interpreter for OFDPA3 OpenFlow selector extensions.
+ */
+public class Ofdpa3ExtensionSelectorInterpreter extends AbstractHandlerBehaviour
+        implements ExtensionSelectorInterpreter, ExtensionSelectorResolver {
+
+    private final Logger log = LoggerFactory.getLogger(getClass());
+
+    @Override
+    public boolean supported(ExtensionSelectorType extensionSelectorType) {
+        if (extensionSelectorType.equals(ExtensionSelectorTypes.OFDPA_MATCH_VLAN_VID.type())) {
+            return true;
+        } else if (extensionSelectorType.equals(ExtensionSelectorTypes.OFDPA_MATCH_OVID.type())) {
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    public OFOxm<?> mapSelector(OFFactory factory, ExtensionSelector extensionSelector) {
+        ExtensionSelectorType type = extensionSelector.type();
+        if (type.equals(ExtensionSelectorType.ExtensionSelectorTypes.OFDPA_MATCH_VLAN_VID.type())) {
+            VlanId vlanId = ((OfdpaMatchVlanVid) extensionSelector).vlanId();
+            // Special VLAN 0x0000/0x1FFF required by OFDPA
+            if (vlanId.equals(VlanId.NONE)) {
+                OFVlanVidMatch vid = OFVlanVidMatch.ofRawVid((short) 0x0000);
+                OFVlanVidMatch mask = OFVlanVidMatch.ofRawVid((short) 0x1FFF);
+                return factory.oxms().vlanVidMasked(vid, mask);
+                // Normal case
+            } else if (vlanId.equals(VlanId.ANY)) {
+                return factory.oxms().vlanVidMasked(OFVlanVidMatch.PRESENT, OFVlanVidMatch.PRESENT);
+            } else {
+                return factory.oxms().vlanVid(OFVlanVidMatch.ofVlanVid(VlanVid.ofVlan(vlanId.toShort())));
+            }
+        } else if (type.equals(ExtensionSelectorTypes.OFDPA_MATCH_OVID.type())) {
+            VlanId vlanId = ((Ofdpa3MatchOvid) extensionSelector).vlanId();
+            if (vlanId.equals(VlanId.NONE)) {
+                throw new UnsupportedOperationException(
+                        "Unexpected ExtensionSelector: " + extensionSelector.toString());
+            } else if (vlanId.equals(VlanId.ANY)) {
+                throw new UnsupportedOperationException(
+                        "Unexpected ExtensionSelector: " + extensionSelector.toString());
+            } else {
+                short mask = (short) 0x1000;
+                short oVid = (short) (mask | vlanId.toShort());
+                return factory.oxms().ofdpaOvid(U16.ofRaw(oVid));
+            }
+        }
+        throw new UnsupportedOperationException(
+                "Unexpected ExtensionSelector: " + extensionSelector.toString());
+    }
+
+    @Override
+    public ExtensionSelector mapOxm(OFOxm<?> oxm) {
+
+        if (oxm.getMatchField().equals(MatchField.VLAN_VID)) {
+            VlanId vlanId;
+            if (oxm.isMasked()) {
+                OFVlanVidMatch vid = ((OFOxmVlanVidMasked) oxm).getValue();
+                OFVlanVidMatch mask = ((OFOxmVlanVidMasked) oxm).getMask();
+
+                if (vid.equals(OFVlanVidMatch.ofRawVid((short) 0))) {
+                    vlanId = VlanId.NONE;
+                } else if (vid.equals(OFVlanVidMatch.PRESENT) &&
+                        mask.equals(OFVlanVidMatch.PRESENT)) {
+                    vlanId = VlanId.ANY;
+                } else {
+                    vlanId = VlanId.vlanId(vid.getVlan());
+                }
+            } else {
+                OFVlanVidMatch vid = ((OFOxmVlanVid) oxm).getValue();
+
+                if (!vid.isPresentBitSet()) {
+                    vlanId = VlanId.NONE;
+                } else {
+                    vlanId = VlanId.vlanId(vid.getVlan());
+                }
+            }
+            return new OfdpaMatchVlanVid(vlanId);
+        } else if (oxm.getMatchField().equals(MatchField.OFDPA_OVID)) {
+            VlanId vlanId;
+            if (oxm.isMasked()) {
+                throw new UnsupportedOperationException(
+                        "Unexpected OXM: " + oxm.toString());
+            } else {
+                OFOxmOfdpaOvid ovid = ((OFOxmOfdpaOvid) oxm);
+                short mask = (short) 0x0FFF;
+                short oVid = (short) (mask & ovid.getValue().getRaw());
+                vlanId = VlanId.vlanId(oVid);
+                }
+            return new Ofdpa3MatchOvid(vlanId);
+        }
+        throw new UnsupportedOperationException(
+                "Unexpected OXM: " + oxm.toString());
+    }
+
+    @Override
+    public ExtensionSelector getExtensionSelector(ExtensionSelectorType type) {
+        if (type.equals(ExtensionSelectorType.ExtensionSelectorTypes.OFDPA_MATCH_VLAN_VID.type())) {
+            return new OfdpaMatchVlanVid();
+        } else if (type.equals(ExtensionSelectorTypes.OFDPA_MATCH_OVID.type())) {
+            return new Ofdpa3MatchOvid();
+        }
+        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 a07862e..afdb29f 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
@@ -16,6 +16,7 @@
 
 package org.onosproject.driver.extensions;
 
+import org.onlab.packet.VlanId;
 import org.onosproject.net.behaviour.ExtensionTreatmentResolver;
 import org.onosproject.net.driver.AbstractHandlerBehaviour;
 import org.onosproject.net.flow.instructions.ExtensionTreatment;
@@ -27,18 +28,27 @@
 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.protocol.oxm.OFOxmOfdpaOvid;
 import org.projectfloodlight.openflow.types.U16;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
  * Interpreter for OFDPA3 OpenFlow treatment extensions.
  */
 public class Ofdpa3ExtensionTreatmentInterpreter extends AbstractHandlerBehaviour
         implements ExtensionTreatmentInterpreter, ExtensionTreatmentResolver {
+
+    private final Logger log = LoggerFactory.getLogger(getClass());
+
     @Override
     public boolean supported(ExtensionTreatmentType extensionTreatmentType) {
         if (extensionTreatmentType.equals(
                 ExtensionTreatmentType.ExtensionTreatmentTypes.OFDPA_SET_MPLS_TYPE.type())) {
             return true;
+        } else if (extensionTreatmentType.equals(
+                ExtensionTreatmentType.ExtensionTreatmentTypes.OFDPA_SET_OVID.type())) {
+            return true;
         }
         return false;
     }
@@ -50,6 +60,13 @@
             short mplsType = ((Ofdpa3SetMplsType) extensionTreatment).mplsType();
             return factory.actions().setField(factory.oxms().ofdpaMplsType(
                     U16.ofRaw(mplsType)));
+        } else if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.OFDPA_SET_OVID.type())) {
+            // OFDPA requires isPresent bit set to 1 for OVID.
+            VlanId vlanId = ((Ofdpa3SetOvid) extensionTreatment).vlanId();
+            short mask = (short) 0x1000;
+            short oVid = (short) (mask | vlanId.toShort());
+            return factory.actions().setField(factory.oxms().ofdpaOvid(
+                    U16.ofRaw(oVid)));
         }
         throw new UnsupportedOperationException(
                 "Unexpected ExtensionTreatment: " + extensionTreatment.toString());
@@ -64,6 +81,12 @@
                 case OFDPA_MPLS_TYPE:
                     OFOxmOfdpaMplsType mplsType = (OFOxmOfdpaMplsType) oxm;
                     return new Ofdpa3SetMplsType(mplsType.getValue().getRaw());
+                case OFDPA_OVID:
+                    OFOxmOfdpaOvid ovid = ((OFOxmOfdpaOvid) oxm);
+                    short mask = (short) 0x0FFF;
+                    short oVid = (short) (mask & ovid.getValue().getRaw());
+                    VlanId vlanId = VlanId.vlanId(oVid);
+                    return new Ofdpa3SetOvid(vlanId);
                 default:
                     throw new UnsupportedOperationException(
                             "Driver does not support extension type " + oxm.getMatchField().id);
@@ -77,6 +100,8 @@
     public ExtensionTreatment getExtensionInstruction(ExtensionTreatmentType type) {
         if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.OFDPA_SET_MPLS_TYPE.type())) {
             return new Ofdpa3SetMplsType();
+        } else if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.OFDPA_SET_OVID.type())) {
+            return new Ofdpa3SetOvid();
         }
         throw new UnsupportedOperationException(
                 "Driver does not support extension type " + type.toString());
diff --git a/drivers/default/src/main/java/org/onosproject/driver/extensions/Ofdpa3MatchOvid.java b/drivers/default/src/main/java/org/onosproject/driver/extensions/Ofdpa3MatchOvid.java
new file mode 100644
index 0000000..168eed5
--- /dev/null
+++ b/drivers/default/src/main/java/org/onosproject/driver/extensions/Ofdpa3MatchOvid.java
@@ -0,0 +1,82 @@
+/*
+ * 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.packet.VlanId;
+import org.onosproject.net.flow.criteria.ExtensionSelectorType;
+
+import java.util.Objects;
+
+/**
+ * OFDPA OVID extension match. OVID is a meta-data of the OFDPA
+ * pipeline, but basically it is a VLAN ID.
+ */
+public class Ofdpa3MatchOvid extends OfdpaMatchVlanVid {
+
+    /**
+     * Constructs a new match OVID instruction.
+     */
+    protected Ofdpa3MatchOvid() {
+        super();
+    }
+
+    /**
+     * Constructs a new match OVID instruction with a given VLAN ID.
+     *
+     * @param vlanId VLAN ID
+     */
+    public Ofdpa3MatchOvid(VlanId vlanId) {
+        super(vlanId);
+    }
+
+    /**
+     * Returns the treatment type.
+     *
+     * @return the match OVID extension type
+     */
+    @Override
+    public ExtensionSelectorType type() {
+        return ExtensionSelectorType.ExtensionSelectorTypes.OFDPA_MATCH_OVID.type();
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(this.vlanId());
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof Ofdpa3MatchOvid) {
+            Ofdpa3MatchOvid that = (Ofdpa3MatchOvid) obj;
+            return Objects.equals(this.vlanId(), that.vlanId());
+
+        }
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass())
+                .add("oVid", this.vlanId())
+                .toString();
+    }
+
+}
diff --git a/drivers/default/src/main/java/org/onosproject/driver/extensions/Ofdpa3SetOvid.java b/drivers/default/src/main/java/org/onosproject/driver/extensions/Ofdpa3SetOvid.java
new file mode 100644
index 0000000..3a2b84d
--- /dev/null
+++ b/drivers/default/src/main/java/org/onosproject/driver/extensions/Ofdpa3SetOvid.java
@@ -0,0 +1,82 @@
+/*
+ * 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.packet.VlanId;
+import org.onosproject.net.flow.instructions.ExtensionTreatmentType;
+
+import java.util.Objects;
+
+/**
+ * OFDPA set OVID extension instruction. OVID is a meta-data of the OFDPA
+ * pipeline, but basically it is a VLAN ID.
+ */
+public class Ofdpa3SetOvid extends OfdpaSetVlanVid {
+
+    /**
+     * Constructs a new set OVID instruction.
+     */
+    protected Ofdpa3SetOvid() {
+        super();
+    }
+
+    /**
+     * Constructs a new set OVID instruction with a given VLAN ID.
+     *
+     * @param vlanId VLAN ID
+     */
+    public Ofdpa3SetOvid(VlanId vlanId) {
+        super(vlanId);
+    }
+
+    /**
+     * Returns the treatment type.
+     *
+     * @return the set OVID extension type
+     */
+    @Override
+    public ExtensionTreatmentType type() {
+        return ExtensionTreatmentType.ExtensionTreatmentTypes.OFDPA_SET_OVID.type();
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(this.vlanId());
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof Ofdpa3SetOvid) {
+            Ofdpa3SetOvid that = (Ofdpa3SetOvid) obj;
+            return Objects.equals(this.vlanId(), that.vlanId());
+
+        }
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass())
+                .add("oVid", this.vlanId())
+                .toString();
+    }
+
+}
diff --git a/drivers/default/src/main/java/org/onosproject/driver/extensions/codec/Ofdpa3MatchOvidCodec.java b/drivers/default/src/main/java/org/onosproject/driver/extensions/codec/Ofdpa3MatchOvidCodec.java
new file mode 100644
index 0000000..af7a14f
--- /dev/null
+++ b/drivers/default/src/main/java/org/onosproject/driver/extensions/codec/Ofdpa3MatchOvidCodec.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.onlab.packet.VlanId;
+import org.onosproject.codec.CodecContext;
+import org.onosproject.codec.JsonCodec;
+import org.onosproject.driver.extensions.Ofdpa3MatchOvid;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.onlab.util.Tools.nullIsIllegal;
+
+/**
+ * JSON Codec for Ofdpa match ovid class.
+ */
+public class Ofdpa3MatchOvidCodec extends JsonCodec<Ofdpa3MatchOvid> {
+
+    private static final String OVID = "oVid";
+    private static final String MISSING_MEMBER_MESSAGE = " member is required in Ofdpa3MatchOvid";
+    private static final String MISSING_OVID_MESSAGE = "OVID cannot be null";
+
+    @Override
+    public ObjectNode encode(Ofdpa3MatchOvid matchOvid, CodecContext context) {
+        checkNotNull(matchOvid, MISSING_OVID_MESSAGE);
+        return context.mapper().createObjectNode()
+                .put(OVID, matchOvid.vlanId().id());
+    }
+
+    @Override
+    public Ofdpa3MatchOvid decode(ObjectNode json, CodecContext context) {
+        if (json == null || !json.isObject()) {
+            return null;
+        }
+
+        // parse ofdpa match ovid
+        short vlanVid = (short) nullIsIllegal(json.get(OVID),
+                OVID + MISSING_MEMBER_MESSAGE).asInt();
+        return new Ofdpa3MatchOvid(VlanId.vlanId(vlanVid));
+    }
+}
diff --git a/drivers/default/src/main/java/org/onosproject/driver/extensions/codec/Ofdpa3SetOvidCodec.java b/drivers/default/src/main/java/org/onosproject/driver/extensions/codec/Ofdpa3SetOvidCodec.java
new file mode 100644
index 0000000..c6535f8
--- /dev/null
+++ b/drivers/default/src/main/java/org/onosproject/driver/extensions/codec/Ofdpa3SetOvidCodec.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.onlab.packet.VlanId;
+import org.onosproject.codec.CodecContext;
+import org.onosproject.codec.JsonCodec;
+import org.onosproject.driver.extensions.Ofdpa3SetOvid;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.onlab.util.Tools.nullIsIllegal;
+
+/**
+ * JSON Codec for Ofdpa set ovid class.
+ */
+public class Ofdpa3SetOvidCodec extends JsonCodec<Ofdpa3SetOvid> {
+
+    private static final String OVID = "oVid";
+    private static final String MISSING_MEMBER_MESSAGE = " member is required in Ofdpa3SetOvid";
+    private static final String MISSING_OVID_MESSAGE = "OVID cannot be null";
+
+    @Override
+    public ObjectNode encode(Ofdpa3SetOvid setOvid, CodecContext context) {
+        checkNotNull(setOvid, MISSING_OVID_MESSAGE);
+        return context.mapper().createObjectNode()
+                .put(OVID, setOvid.vlanId().id());
+    }
+
+    @Override
+    public Ofdpa3SetOvid decode(ObjectNode json, CodecContext context) {
+        if (json == null || !json.isObject()) {
+            return null;
+        }
+
+        // parse ofdpa set ovid
+        short vlanVid = (short) nullIsIllegal(json.get(OVID),
+                OVID + MISSING_MEMBER_MESSAGE).asInt();
+        return new Ofdpa3SetOvid(VlanId.vlanId(vlanVid));
+    }
+}
diff --git a/drivers/default/src/main/resources/onos-drivers.xml b/drivers/default/src/main/resources/onos-drivers.xml
index 78894e6..952c465 100644
--- a/drivers/default/src/main/resources/onos-drivers.xml
+++ b/drivers/default/src/main/resources/onos-drivers.xml
@@ -92,9 +92,9 @@
         <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" />
+                   impl="org.onosproject.driver.extensions.Ofdpa3ExtensionSelectorInterpreter" />
         <behaviour api="org.onosproject.net.behaviour.ExtensionSelectorResolver"
-                   impl="org.onosproject.driver.extensions.OfdpaExtensionSelectorInterpreter" />
+                   impl="org.onosproject.driver.extensions.Ofdpa3ExtensionSelectorInterpreter" />
     </driver>
     <!--  Emulation of the ofdpa pipeline using a CPqD OF 1.3 software switch.
        ~  Use this driver when MPLS functionality is required.
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 afa2eb2..2256a7f 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
@@ -579,6 +579,7 @@
             builder.setArpSpa(Ip4Address.valueOf(arpspa.getValue().getInt()));
             break;
         case OFDPA_MPLS_TYPE:
+        case OFDPA_OVID:
             if (treatmentInterpreter != null) {
                 try {
                     builder.extension(treatmentInterpreter.mapAction(action), deviceId);
@@ -959,6 +960,18 @@
                     }
                 }
                 break;
+            case OFDPA_OVID:
+                if (selectorInterpreter != null &&
+                        selectorInterpreter.supported(ExtensionSelectorTypes.OFDPA_MATCH_OVID.type())) {
+                    if (match.getVersion().equals(OFVersion.OF_13)) {
+                        OFOxm oxm = ((OFMatchV3) match).getOxmList().get(MatchField.OFDPA_OVID);
+                        builder.extension(selectorInterpreter.mapOxm(oxm),
+                                          deviceId);
+                    } else {
+                        break;
+                    }
+                }
+                break;
             case MPLS_TC:
             default:
                 log.warn("Match type {} not yet implemented.", field.id);