[ONOS-4612]Update SFC flows inline with the Official OVS NSH patch

Change-Id: If58517841096a939860d88aa78eca7cae46b9935
diff --git a/drivers/default/src/main/java/org/onosproject/driver/extensions/DefaultMoveExtensionTreatment.java b/drivers/default/src/main/java/org/onosproject/driver/extensions/DefaultMoveExtensionTreatment.java
index d305e08..b1ba927 100644
--- a/drivers/default/src/main/java/org/onosproject/driver/extensions/DefaultMoveExtensionTreatment.java
+++ b/drivers/default/src/main/java/org/onosproject/driver/extensions/DefaultMoveExtensionTreatment.java
@@ -38,7 +38,6 @@
     private ExtensionTreatmentType type;
 
     private final KryoNamespace appKryo = new KryoNamespace.Builder()
-            .register(byte[].class)
             .register(Map.class)
             .build("DefaultMoveExtensionTreatment");
 
diff --git a/drivers/default/src/main/java/org/onosproject/driver/extensions/NiciraEncapEthDst.java b/drivers/default/src/main/java/org/onosproject/driver/extensions/NiciraEncapEthDst.java
new file mode 100644
index 0000000..1f98825
--- /dev/null
+++ b/drivers/default/src/main/java/org/onosproject/driver/extensions/NiciraEncapEthDst.java
@@ -0,0 +1,101 @@
+/*
+ * 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 java.util.Objects;
+
+import org.onlab.packet.MacAddress;
+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 org.onosproject.store.serializers.MacAddressSerializer;
+
+import com.google.common.base.MoreObjects;
+
+/**
+ * Nicira EncapEthDst extension instruction to set encapsulated eth destination.
+ */
+public class NiciraEncapEthDst extends AbstractExtension implements ExtensionTreatment {
+
+    private MacAddress encapEthDst;
+
+    private final KryoNamespace appKryo = new KryoNamespace.Builder()
+    .register(new MacAddressSerializer(), MacAddress.class).register(byte[].class).build();;
+
+    /**
+     * Creates a new nshEncapEthDst instruction.
+     */
+    NiciraEncapEthDst() {
+    }
+
+    /**
+     * Creates a new encapEthDst instruction with given mac address.
+     *
+     * @param encapEthDst encapsulated ethernet destination
+     */
+    public NiciraEncapEthDst(MacAddress encapEthDst) {
+        this.encapEthDst = encapEthDst;
+    }
+
+    /**
+     * Gets the encapEthDst.
+     *
+     * @return encapEthDst
+     */
+    public MacAddress encapEthDst() {
+        return encapEthDst;
+    }
+
+    @Override
+    public ExtensionTreatmentType type() {
+        return ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_ENCAP_ETH_DST.type();
+    }
+
+    @Override
+    public void deserialize(byte[] data) {
+        encapEthDst = appKryo.deserialize(data);
+    }
+
+    @Override
+    public byte[] serialize() {
+        return appKryo.serialize(encapEthDst);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(encapEthDst);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof NiciraEncapEthDst) {
+            NiciraEncapEthDst that = (NiciraEncapEthDst) obj;
+            return Objects.equals(encapEthDst, that.encapEthDst);
+
+        }
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass()).add("encapEthDst", encapEthDst).toString();
+    }
+}
diff --git a/drivers/default/src/main/java/org/onosproject/driver/extensions/NiciraEncapEthSrc.java b/drivers/default/src/main/java/org/onosproject/driver/extensions/NiciraEncapEthSrc.java
new file mode 100644
index 0000000..7ecc1e8
--- /dev/null
+++ b/drivers/default/src/main/java/org/onosproject/driver/extensions/NiciraEncapEthSrc.java
@@ -0,0 +1,101 @@
+/*
+ * 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 java.util.Objects;
+
+import org.onlab.packet.MacAddress;
+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 org.onosproject.store.serializers.MacAddressSerializer;
+
+import com.google.common.base.MoreObjects;
+
+/**
+ * Nicira EncapEthSrc extension instruction to set encapsulated eth source.
+ */
+public class NiciraEncapEthSrc extends AbstractExtension implements ExtensionTreatment {
+
+    private MacAddress encapEthSrc;
+
+    private final KryoNamespace appKryo = new KryoNamespace.Builder()
+    .register(new MacAddressSerializer(), MacAddress.class).register(byte[].class).build();;
+
+    /**
+     * Creates a new nshEncapEthSrc instruction.
+     */
+    NiciraEncapEthSrc() {
+    }
+
+    /**
+     * Creates a new encapEthSrc instruction with given mac address.
+     *
+     * @param encapEthSrc encapsulated ethernet source
+     */
+    public NiciraEncapEthSrc(MacAddress encapEthSrc) {
+        this.encapEthSrc = encapEthSrc;
+    }
+
+    /**
+     * Gets the encapEthSrc.
+     *
+     * @return encapEthSrc
+     */
+    public MacAddress encapEthSrc() {
+        return encapEthSrc;
+    }
+
+    @Override
+    public ExtensionTreatmentType type() {
+        return ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_ENCAP_ETH_SRC.type();
+    }
+
+    @Override
+    public void deserialize(byte[] data) {
+        encapEthSrc = appKryo.deserialize(data);
+    }
+
+    @Override
+    public byte[] serialize() {
+        return appKryo.serialize(encapEthSrc);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(encapEthSrc);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof NiciraEncapEthSrc) {
+            NiciraEncapEthSrc that = (NiciraEncapEthSrc) obj;
+            return Objects.equals(encapEthSrc, that.encapEthSrc);
+
+        }
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass()).add("encapEthSrc", encapEthSrc).toString();
+    }
+}
diff --git a/drivers/default/src/main/java/org/onosproject/driver/extensions/NiciraEncapEthType.java b/drivers/default/src/main/java/org/onosproject/driver/extensions/NiciraEncapEthType.java
new file mode 100644
index 0000000..8b7f194
--- /dev/null
+++ b/drivers/default/src/main/java/org/onosproject/driver/extensions/NiciraEncapEthType.java
@@ -0,0 +1,99 @@
+/*
+ * 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 java.util.Objects;
+
+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 com.google.common.base.MoreObjects;
+
+/**
+ * Nicira EncapEthType extension instruction to set encapsulated eth type.
+ */
+public class NiciraEncapEthType extends AbstractExtension implements ExtensionTreatment {
+
+    private short encapEthType;
+
+    private final KryoNamespace appKryo = new KryoNamespace.Builder().build();
+
+    /**
+     * Creates a new nshEncapEthType instruction.
+     */
+    NiciraEncapEthType() {
+        encapEthType = (short) 0;
+    }
+
+    /**
+     * Creates a new nshEncapEthType instruction with given eth type.
+     *
+     * @param encapEthType encapsulated ethernet type
+     */
+    public NiciraEncapEthType(short encapEthType) {
+        this.encapEthType = encapEthType;
+    }
+
+    /**
+     * Gets the encapEthType.
+     *
+     * @return encapEthType
+     */
+    public short encapEthType() {
+        return encapEthType;
+    }
+
+    @Override
+    public ExtensionTreatmentType type() {
+        return ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_ENCAP_ETH_TYPE.type();
+    }
+
+    @Override
+    public void deserialize(byte[] data) {
+        encapEthType = (short) (appKryo.deserialize(data));
+    }
+
+    @Override
+    public byte[] serialize() {
+        return appKryo.serialize(encapEthType);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(encapEthType);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof NiciraEncapEthType) {
+            NiciraEncapEthType that = (NiciraEncapEthType) obj;
+            return Objects.equals(encapEthType, that.encapEthType);
+
+        }
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass()).add("encapEthType", encapEthType).toString();
+    }
+}
diff --git a/drivers/default/src/main/java/org/onosproject/driver/extensions/NiciraExtensionSelectorInterpreter.java b/drivers/default/src/main/java/org/onosproject/driver/extensions/NiciraExtensionSelectorInterpreter.java
index 57f0a67..4bd1aa5 100644
--- a/drivers/default/src/main/java/org/onosproject/driver/extensions/NiciraExtensionSelectorInterpreter.java
+++ b/drivers/default/src/main/java/org/onosproject/driver/extensions/NiciraExtensionSelectorInterpreter.java
@@ -18,13 +18,22 @@
 
 import com.fasterxml.jackson.databind.node.ObjectNode;
 import org.onosproject.codec.CodecContext;
+import org.onosproject.net.NshServiceIndex;
+import org.onosproject.net.NshServicePathId;
 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.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.OFOxmEncapEthType;
+import org.projectfloodlight.openflow.protocol.oxm.OFOxmNsi;
+import org.projectfloodlight.openflow.protocol.oxm.OFOxmNsp;
+import org.projectfloodlight.openflow.types.U16;
+import org.projectfloodlight.openflow.types.U32;
+import org.projectfloodlight.openflow.types.U8;
 
 /**
  * Interpreter for Nicira OpenFlow selector extensions.
@@ -53,17 +62,28 @@
         if (extensionSelectorType.equals(ExtensionSelectorType.ExtensionSelectorTypes.NICIRA_MATCH_NSH_CH4.type())) {
             return true;
         }
+        if (extensionSelectorType.equals(ExtensionSelectorType.ExtensionSelectorTypes.NICIRA_MATCH_ENCAP_ETH_TYPE
+                                         .type())) {
+            return true;
+        }
         return false;
     }
 
     @Override
     public OFOxm<?> mapSelector(OFFactory factory, ExtensionSelector extensionSelector) {
         ExtensionSelectorType type = extensionSelector.type();
+
         if (type.equals(ExtensionSelectorType.ExtensionSelectorTypes.NICIRA_MATCH_NSH_SPI.type())) {
-            // TODO
+            NiciraMatchNshSpi niciraNshSpi = (NiciraMatchNshSpi) extensionSelector;
+            return factory.oxms().nsp(U32.of(niciraNshSpi.nshSpi().servicePathId()));
         }
         if (type.equals(ExtensionSelectorType.ExtensionSelectorTypes.NICIRA_MATCH_NSH_SI.type())) {
-            // TODO
+            NiciraMatchNshSi niciraNshSi = (NiciraMatchNshSi) extensionSelector;
+            return factory.oxms().nsi(U8.of(niciraNshSi.nshSi().serviceIndex()));
+        }
+        if (type.equals(ExtensionSelectorType.ExtensionSelectorTypes.NICIRA_MATCH_ENCAP_ETH_TYPE.type())) {
+            NiciraMatchEncapEthType niciraEncapEthType = (NiciraMatchEncapEthType) extensionSelector;
+            return factory.oxms().encapEthType(U16.of(niciraEncapEthType.encapEthType()));
         }
         if (type.equals(ExtensionSelectorType.ExtensionSelectorTypes.NICIRA_MATCH_NSH_CH1.type())) {
             // TODO
@@ -82,6 +102,20 @@
 
     @Override
     public ExtensionSelector mapOxm(OFOxm<?> oxm) {
+
+        if (oxm.getMatchField() == MatchField.NSP) {
+            OFOxmNsp oxmField = (OFOxmNsp) oxm;
+            return new NiciraMatchNshSpi(NshServicePathId.of(oxmField.getValue().getRaw()));
+        }
+        if (oxm.getMatchField() == MatchField.NSI) {
+            OFOxmNsi oxmField = (OFOxmNsi) oxm;
+            return new NiciraMatchNshSi(NshServiceIndex.of(oxmField.getValue().getRaw()));
+        }
+        if (oxm.getMatchField() == MatchField.ENCAP_ETH_TYPE) {
+            OFOxmEncapEthType oxmField = (OFOxmEncapEthType) oxm;
+            return new NiciraMatchEncapEthType(oxmField.getValue().getRaw());
+        }
+
         return null;
     }
 
@@ -93,6 +127,9 @@
         if (type.equals(ExtensionSelectorType.ExtensionSelectorTypes.NICIRA_MATCH_NSH_SI.type())) {
             return new NiciraMatchNshSi();
         }
+        if (type.equals(ExtensionSelectorType.ExtensionSelectorTypes.NICIRA_MATCH_ENCAP_ETH_TYPE.type())) {
+            return new NiciraMatchEncapEthType();
+        }
         if (type.equals(ExtensionSelectorType.ExtensionSelectorTypes.NICIRA_MATCH_NSH_CH1.type())
                 || type.equals(ExtensionSelectorType.ExtensionSelectorTypes.NICIRA_MATCH_NSH_CH2.type())
                 || type.equals(ExtensionSelectorType.ExtensionSelectorTypes.NICIRA_MATCH_NSH_CH3.type())
diff --git a/drivers/default/src/main/java/org/onosproject/driver/extensions/NiciraExtensionTreatmentInterpreter.java b/drivers/default/src/main/java/org/onosproject/driver/extensions/NiciraExtensionTreatmentInterpreter.java
index 55f0c3e..3a0778e 100644
--- a/drivers/default/src/main/java/org/onosproject/driver/extensions/NiciraExtensionTreatmentInterpreter.java
+++ b/drivers/default/src/main/java/org/onosproject/driver/extensions/NiciraExtensionTreatmentInterpreter.java
@@ -16,9 +16,14 @@
 
 package org.onosproject.driver.extensions;
 
-import com.fasterxml.jackson.databind.node.ObjectNode;
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.onlab.util.Tools.nullIsIllegal;
+
 import org.onlab.packet.Ip4Address;
 import org.onosproject.codec.CodecContext;
+import org.onosproject.net.NshContextHeader;
+import org.onosproject.net.NshServiceIndex;
+import org.onosproject.net.NshServicePathId;
 import org.onosproject.net.PortNumber;
 import org.onosproject.net.behaviour.ExtensionTreatmentResolver;
 import org.onosproject.net.driver.AbstractHandlerBehaviour;
@@ -32,13 +37,29 @@
 import org.projectfloodlight.openflow.protocol.action.OFActionNicira;
 import org.projectfloodlight.openflow.protocol.action.OFActionNiciraMove;
 import org.projectfloodlight.openflow.protocol.action.OFActionNiciraResubmit;
+import org.projectfloodlight.openflow.protocol.action.OFActionNiciraResubmitTable;
 import org.projectfloodlight.openflow.protocol.action.OFActionSetField;
 import org.projectfloodlight.openflow.protocol.oxm.OFOxm;
+import org.projectfloodlight.openflow.protocol.oxm.OFOxmEncapEthDst;
+import org.projectfloodlight.openflow.protocol.oxm.OFOxmEncapEthSrc;
+import org.projectfloodlight.openflow.protocol.oxm.OFOxmEncapEthType;
+import org.projectfloodlight.openflow.protocol.oxm.OFOxmNshC1;
+import org.projectfloodlight.openflow.protocol.oxm.OFOxmNshC2;
+import org.projectfloodlight.openflow.protocol.oxm.OFOxmNshC3;
+import org.projectfloodlight.openflow.protocol.oxm.OFOxmNshC4;
+import org.projectfloodlight.openflow.protocol.oxm.OFOxmNshMdtype;
+import org.projectfloodlight.openflow.protocol.oxm.OFOxmNshNp;
+import org.projectfloodlight.openflow.protocol.oxm.OFOxmNsi;
+import org.projectfloodlight.openflow.protocol.oxm.OFOxmNsp;
+import org.projectfloodlight.openflow.protocol.oxm.OFOxmTunGpeNp;
 import org.projectfloodlight.openflow.protocol.oxm.OFOxmTunnelIpv4Dst;
 import org.projectfloodlight.openflow.types.IPv4Address;
+import org.projectfloodlight.openflow.types.MacAddress;
+import org.projectfloodlight.openflow.types.U16;
+import org.projectfloodlight.openflow.types.U32;
+import org.projectfloodlight.openflow.types.U8;
 
-import static com.google.common.base.Preconditions.checkNotNull;
-import static org.onlab.util.Tools.nullIsIllegal;
+import com.fasterxml.jackson.databind.node.ObjectNode;
 
 /**
  * Interpreter for Nicira OpenFlow treatment extensions.
@@ -52,8 +73,18 @@
     private static final int SRC_ETH = 0x00000406;
     private static final int SRC_IP = 0x00000e04;
 
+    private static final int NSH_C1 = 0x0001e604;
+    private static final int NSH_C2 = 0x0001e804;
+    private static final int NSH_C3 = 0x0001ea04;
+    private static final int NSH_C4 = 0x0001ec04;
+    private static final int TUN_IPV4_DST = 0x00014004;
+    private static final int TUN_ID = 0x12008;
+
     private static final int SUB_TYPE_RESUBMIT = 1;
+    private static final int SUB_TYPE_RESUBMIT_TABLE = 14;
     private static final int SUB_TYPE_MOVE = 6;
+    private static final int SUB_TYPE_PUSH_NSH = 38;
+    private static final int SUB_TYPE_POP_NSH = 39;
 
     private static final String TUNNEL_DST = "tunnelDst";
     private static final String RESUBMIT = "resubmit";
@@ -115,6 +146,59 @@
                 ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_MOV_IP_SRC_TO_DST.type())) {
             return true;
         }
+        if (extensionTreatmentType.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_NSH_MDTYPE.type())) {
+            return true;
+        }
+        if (extensionTreatmentType.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_NSH_NP.type())) {
+            return true;
+        }
+        if (extensionTreatmentType.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_ENCAP_ETH_SRC.type())) {
+            return true;
+        }
+        if (extensionTreatmentType.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_ENCAP_ETH_DST.type())) {
+            return true;
+        }
+        if (extensionTreatmentType.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_ENCAP_ETH_TYPE
+                .type())) {
+            return true;
+        }
+        if (extensionTreatmentType.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_PUSH_NSH.type())) {
+            return true;
+        }
+        if (extensionTreatmentType.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_POP_NSH.type())) {
+            return true;
+        }
+        if (extensionTreatmentType.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_TUN_GPE_NP.type())) {
+            return true;
+        }
+        if (extensionTreatmentType
+                .equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_MOV_NSH_C1_TO_C1.type())) {
+            return true;
+        }
+        if (extensionTreatmentType
+                .equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_MOV_NSH_C2_TO_C2.type())) {
+            return true;
+        }
+        if (extensionTreatmentType
+                .equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_MOV_NSH_C3_TO_C3.type())) {
+            return true;
+        }
+        if (extensionTreatmentType
+                .equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_MOV_NSH_C4_TO_C4.type())) {
+            return true;
+        }
+        if (extensionTreatmentType.equals(ExtensionTreatmentType.ExtensionTreatmentTypes
+                                          .NICIRA_MOV_TUN_IPV4_DST_TO_TUN_IPV4_DST.type())) {
+            return true;
+        }
+        if (extensionTreatmentType.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_MOV_TUN_ID_TO_TUN_ID
+                .type())) {
+            return true;
+        }
+        if (extensionTreatmentType.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_MOV_NSH_C2_TO_TUN_ID
+                                          .type())) {
+            return true;
+        }
         return false;
     }
 
@@ -136,10 +220,75 @@
             return factory.actions().niciraResubmitTable((int) resubmitTable.inPort().toLong(),
                                                          resubmitTable.table());
         }
+
+        if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_NSH_SPI.type())) {
+            NiciraSetNshSpi niciraNshSpi = (NiciraSetNshSpi) extensionTreatment;
+            return factory.actions().setField(factory.oxms().nsp(U32.of(niciraNshSpi.nshSpi().servicePathId())));
+        }
+        if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_NSH_SI.type())) {
+            NiciraSetNshSi niciraNshSi = (NiciraSetNshSi) extensionTreatment;
+            return factory.actions().setField(factory.oxms().nsi(U8.of(niciraNshSi.nshSi().serviceIndex())));
+        }
+        if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_NSH_CH1.type())) {
+            NiciraSetNshContextHeader niciraNshch = (NiciraSetNshContextHeader) extensionTreatment;
+            return factory.actions().setField(factory.oxms().nshC1(U32.of(niciraNshch.nshCh().nshContextHeader())));
+        }
+        if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_NSH_CH2.type())) {
+            NiciraSetNshContextHeader niciraNshch = (NiciraSetNshContextHeader) extensionTreatment;
+            return factory.actions().setField(factory.oxms().nshC2(U32.of(niciraNshch.nshCh().nshContextHeader())));
+        }
+        if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_NSH_CH3.type())) {
+            NiciraSetNshContextHeader niciraNshch = (NiciraSetNshContextHeader) extensionTreatment;
+            return factory.actions().setField(factory.oxms().nshC3(U32.of(niciraNshch.nshCh().nshContextHeader())));
+        }
+        if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_NSH_CH4.type())) {
+            NiciraSetNshContextHeader niciraNshch = (NiciraSetNshContextHeader) extensionTreatment;
+            return factory.actions().setField(factory.oxms().nshC4(U32.of(niciraNshch.nshCh().nshContextHeader())));
+        }
+        if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_NSH_MDTYPE.type())) {
+            NiciraNshMdType niciraNshMdType = (NiciraNshMdType) extensionTreatment;
+            return factory.actions().setField(factory.oxms().nshMdtype(U8.of(niciraNshMdType.nshMdType())));
+        }
+        if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_NSH_NP.type())) {
+            NiciraNshNp niciraNshNp = (NiciraNshNp) extensionTreatment;
+            return factory.actions().setField(factory.oxms().nshNp(U8.of(niciraNshNp.nshNp())));
+        }
+        if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_ENCAP_ETH_SRC.type())) {
+            NiciraEncapEthSrc niciraEncapEthSrc = (NiciraEncapEthSrc) extensionTreatment;
+            return factory.actions().setField(factory.oxms().encapEthSrc(MacAddress.of(niciraEncapEthSrc.encapEthSrc()
+                    .toBytes())));
+        }
+        if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_ENCAP_ETH_DST.type())) {
+            NiciraEncapEthDst niciraEncapEthDst = (NiciraEncapEthDst) extensionTreatment;
+            return factory.actions().setField(factory.oxms().encapEthDst(MacAddress.of(niciraEncapEthDst.encapEthDst()
+                    .toBytes())));
+        }
+        if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_ENCAP_ETH_TYPE.type())) {
+            NiciraEncapEthType niciraEncapEthType = (NiciraEncapEthType) extensionTreatment;
+            return factory.actions().setField(factory.oxms().encapEthType(U16.of(niciraEncapEthType.encapEthType())));
+        }
+        if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_PUSH_NSH.type())) {
+            return factory.actions().niciraPushNsh();
+        }
+        if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_POP_NSH.type())) {
+            return factory.actions().niciraPopNsh();
+        }
+        if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_TUN_GPE_NP.type())) {
+            NiciraTunGpeNp niciraTunGpeNp = (NiciraTunGpeNp) extensionTreatment;
+            return factory.actions().setField(factory.oxms().tunGpeNp(U8.of(niciraTunGpeNp.tunGpeNp())));
+        }
         if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_MOV_ARP_SHA_TO_THA.type())
                 || type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_MOV_ARP_SPA_TO_TPA.type())
                 || type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_MOV_ETH_SRC_TO_DST.type())
-                || type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_MOV_IP_SRC_TO_DST.type())) {
+                || type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_MOV_IP_SRC_TO_DST.type())
+                || type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_MOV_NSH_C1_TO_C1.type())
+                || type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_MOV_NSH_C2_TO_C2.type())
+                || type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_MOV_NSH_C3_TO_C3.type())
+                || type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_MOV_NSH_C4_TO_C4.type())
+                || type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_MOV_TUN_IPV4_DST_TO_TUN_IPV4_DST
+                        .type())
+                || type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_MOV_TUN_ID_TO_TUN_ID.type())
+                || type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_MOV_NSH_C2_TO_TUN_ID.type())) {
             MoveExtensionTreatment mov = (MoveExtensionTreatment) extensionTreatment;
             OFActionNiciraMove.Builder action = factory.actions()
                     .buildNiciraMove();
@@ -162,6 +311,50 @@
             case TUNNEL_IPV4_DST:
                 OFOxmTunnelIpv4Dst tunnelIpv4Dst = (OFOxmTunnelIpv4Dst) oxm;
                 return new NiciraSetTunnelDst(Ip4Address.valueOf(tunnelIpv4Dst.getValue().getInt()));
+            case NSP:
+                OFOxmNsp nsp = (OFOxmNsp) oxm;
+                return new NiciraSetNshSpi(NshServicePathId.of((nsp.getValue().getRaw())));
+            case NSI:
+                OFOxmNsi nsi = (OFOxmNsi) oxm;
+                return new NiciraSetNshSi(NshServiceIndex.of((nsi.getValue().getRaw())));
+            case NSH_C1:
+                OFOxmNshC1 nshC1 = (OFOxmNshC1) oxm;
+                return new NiciraSetNshContextHeader(NshContextHeader.of((nshC1.getValue().getRaw())),
+                                                     ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_NSH_CH1
+                                                     .type());
+            case NSH_C2:
+                OFOxmNshC2 nshC2 = (OFOxmNshC2) oxm;
+                return new NiciraSetNshContextHeader(NshContextHeader.of((nshC2.getValue().getRaw())),
+                                                     ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_NSH_CH2
+                                                     .type());
+            case NSH_C3:
+                OFOxmNshC3 nshC3 = (OFOxmNshC3) oxm;
+                return new NiciraSetNshContextHeader(NshContextHeader.of((nshC3.getValue().getRaw())),
+                                                     ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_NSH_CH3
+                                                     .type());
+            case NSH_C4:
+                OFOxmNshC4 nshC4 = (OFOxmNshC4) oxm;
+                return new NiciraSetNshContextHeader(NshContextHeader.of((nshC4.getValue().getRaw())),
+                                                     ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_NSH_CH4
+                                                     .type());
+            case NSH_MDTYPE:
+                OFOxmNshMdtype nshMdType = (OFOxmNshMdtype) oxm;
+                return new NiciraNshMdType((nshMdType.getValue().getRaw()));
+            case NSH_NP:
+                OFOxmNshNp nshNp = (OFOxmNshNp) oxm;
+                return new NiciraNshNp((nshNp.getValue().getRaw()));
+            case ENCAP_ETH_SRC:
+                OFOxmEncapEthSrc encapEthSrc = (OFOxmEncapEthSrc) oxm;
+                return new NiciraEncapEthSrc(org.onlab.packet.MacAddress.valueOf((encapEthSrc.getValue().getBytes())));
+            case ENCAP_ETH_DST:
+                OFOxmEncapEthDst encapEthDst = (OFOxmEncapEthDst) oxm;
+                return new NiciraEncapEthDst(org.onlab.packet.MacAddress.valueOf((encapEthDst.getValue().getBytes())));
+            case ENCAP_ETH_TYPE:
+                OFOxmEncapEthType encapEthType = (OFOxmEncapEthType) oxm;
+                return new NiciraEncapEthType((encapEthType.getValue().getRaw()));
+            case TUN_GPE_NP:
+                OFOxmTunGpeNp tunGpeNp = (OFOxmTunGpeNp) oxm;
+                return new NiciraTunGpeNp((tunGpeNp.getValue().getRaw()));
             default:
                 throw new UnsupportedOperationException(
                         "Driver does not support extension type " + oxm.getMatchField().id);
@@ -188,14 +381,37 @@
                             case SRC_ARP_SPA:
                                 return NiciraMoveTreatmentFactory
                                         .createNiciraMovArpSpaToTpa();
+                    case NSH_C1:
+                        return NiciraMoveTreatmentFactory.createNiciraMovNshC1ToC1();
+                    case NSH_C2:
+                        if (Long.valueOf(moveAction.getDst()).intValue() == TUN_ID) {
+                            return NiciraMoveTreatmentFactory.createNiciraMovNshC2ToTunId();
+                        }
+                        return NiciraMoveTreatmentFactory.createNiciraMovNshC2ToC2();
+                    case NSH_C3:
+                        return NiciraMoveTreatmentFactory.createNiciraMovNshC3ToC3();
+                    case NSH_C4:
+                        return NiciraMoveTreatmentFactory.createNiciraMovNshC4ToC4();
+                    case TUN_IPV4_DST:
+                        return NiciraMoveTreatmentFactory.createNiciraMovTunDstToTunDst();
+                    case TUN_ID:
+                        return NiciraMoveTreatmentFactory.createNiciraMovTunIdToTunId();
                             default:
                                 throw new UnsupportedOperationException("Driver does not support move from "
-                                        + moveAction.getSrc() + " to "
-                                        + moveAction.getDst());
+                                + moveAction.getSrc() + " to " + moveAction.getDst() + "of length "
+                                + moveAction.getNBits());
                         }
                     case SUB_TYPE_RESUBMIT:
                         OFActionNiciraResubmit resubmitAction = (OFActionNiciraResubmit) nicira;
                         return new NiciraResubmit(PortNumber.portNumber(resubmitAction.getInPort()));
+                case SUB_TYPE_PUSH_NSH:
+                    return new NiciraPushNsh();
+                case SUB_TYPE_POP_NSH:
+                    return new NiciraPopNsh();
+                case SUB_TYPE_RESUBMIT_TABLE:
+                    OFActionNiciraResubmitTable resubmitTable = (OFActionNiciraResubmitTable) nicira;
+                    return new NiciraResubmitTable(PortNumber.portNumber(resubmitTable.getInPort()),
+                                                   resubmitTable.getTable());
                     default:
                         throw new UnsupportedOperationException("Driver does not support extension subtype "
                                 + nicira.getSubtype());
@@ -228,6 +444,27 @@
                 || type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_NSH_CH4.type())) {
             return new NiciraSetNshContextHeader(type);
         }
+        if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_PUSH_NSH.type())) {
+            return new NiciraPushNsh();
+        }
+        if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_POP_NSH.type())) {
+            return new NiciraPopNsh();
+        }
+        if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_NSH_MDTYPE.type())) {
+            return new NiciraNshMdType();
+        }
+        if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_NSH_NP.type())) {
+            return new NiciraNshNp();
+        }
+        if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_ENCAP_ETH_SRC.type())) {
+            return new NiciraEncapEthSrc();
+        }
+        if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_ENCAP_ETH_DST.type())) {
+            return new NiciraEncapEthDst();
+        }
+        if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_ENCAP_ETH_TYPE.type())) {
+            return new NiciraEncapEthType();
+        }
         if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_MOV_ARP_SHA_TO_THA.type())) {
             return NiciraMoveTreatmentFactory.createNiciraMovArpShaToTha();
         }
@@ -240,8 +477,32 @@
         if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_MOV_IP_SRC_TO_DST.type())) {
             return NiciraMoveTreatmentFactory.createNiciraMovIpSrcToDst();
         }
-        throw new UnsupportedOperationException(
-                "Driver does not support extension type " + type.toString());
+        if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_TUN_GPE_NP.type())) {
+            return new NiciraTunGpeNp();
+        }
+        if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_MOV_NSH_C1_TO_C1.type())) {
+            return NiciraMoveTreatmentFactory.createNiciraMovNshC1ToC1();
+        }
+        if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_MOV_NSH_C2_TO_C2.type())) {
+            return NiciraMoveTreatmentFactory.createNiciraMovNshC2ToC2();
+        }
+        if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_MOV_NSH_C3_TO_C3.type())) {
+            return NiciraMoveTreatmentFactory.createNiciraMovNshC3ToC3();
+        }
+        if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_MOV_NSH_C4_TO_C4.type())) {
+            return NiciraMoveTreatmentFactory.createNiciraMovNshC4ToC4();
+        }
+        if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_MOV_TUN_IPV4_DST_TO_TUN_IPV4_DST
+                .type())) {
+            return NiciraMoveTreatmentFactory.createNiciraMovTunDstToTunDst();
+        }
+        if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_MOV_TUN_ID_TO_TUN_ID.type())) {
+            return NiciraMoveTreatmentFactory.createNiciraMovTunIdToTunId();
+        }
+        if (type.equals(ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_MOV_NSH_C2_TO_TUN_ID.type())) {
+            return NiciraMoveTreatmentFactory.createNiciraMovNshC2ToTunId();
+        }
+        throw new UnsupportedOperationException("Driver does not support extension type " + type.toString());
     }
 
     @Override
diff --git a/drivers/default/src/main/java/org/onosproject/driver/extensions/NiciraMatchEncapEthType.java b/drivers/default/src/main/java/org/onosproject/driver/extensions/NiciraMatchEncapEthType.java
new file mode 100644
index 0000000..e0ae08a
--- /dev/null
+++ b/drivers/default/src/main/java/org/onosproject/driver/extensions/NiciraMatchEncapEthType.java
@@ -0,0 +1,99 @@
+/*
+ * 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 java.util.Objects;
+
+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 com.google.common.base.MoreObjects;
+
+/**
+ * Nicira EncapEthType extension selector to set encapsulated eth type.
+ */
+public class NiciraMatchEncapEthType extends AbstractExtension implements ExtensionSelector {
+
+    private short encapEthType;
+
+    private final KryoNamespace appKryo = new KryoNamespace.Builder().build();
+
+    /**
+     * Creates a new nshEncapEthType selector.
+     */
+    NiciraMatchEncapEthType() {
+        encapEthType = (short) 0;
+    }
+
+    /**
+     * Creates a new nshEncapEthType selector with given eth type.
+     *
+     * @param encapEthType encapsulated ethernet type
+     */
+    public NiciraMatchEncapEthType(short encapEthType) {
+        this.encapEthType = encapEthType;
+    }
+
+    /**
+     * Gets the encapEthType.
+     *
+     * @return encapEthType
+     */
+    public short encapEthType() {
+        return encapEthType;
+    }
+
+    @Override
+    public ExtensionSelectorType type() {
+        return ExtensionSelectorType.ExtensionSelectorTypes.NICIRA_MATCH_ENCAP_ETH_TYPE.type();
+    }
+
+    @Override
+    public void deserialize(byte[] data) {
+        encapEthType = (short) (appKryo.deserialize(data));
+    }
+
+    @Override
+    public byte[] serialize() {
+        return appKryo.serialize(encapEthType);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(encapEthType);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof NiciraMatchEncapEthType) {
+            NiciraMatchEncapEthType that = (NiciraMatchEncapEthType) obj;
+            return Objects.equals(encapEthType, that.encapEthType);
+
+        }
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass()).add("encapEthType", encapEthType).toString();
+    }
+}
diff --git a/drivers/default/src/main/java/org/onosproject/driver/extensions/NiciraMoveTreatmentFactory.java b/drivers/default/src/main/java/org/onosproject/driver/extensions/NiciraMoveTreatmentFactory.java
index 2b861eb..57f6e8b 100644
--- a/drivers/default/src/main/java/org/onosproject/driver/extensions/NiciraMoveTreatmentFactory.java
+++ b/drivers/default/src/main/java/org/onosproject/driver/extensions/NiciraMoveTreatmentFactory.java
@@ -97,4 +97,88 @@
                                                  ExtensionTreatmentType.ExtensionTreatmentTypes
                                                  .NICIRA_MOV_IP_SRC_TO_DST.type());
     }
+
+    public static ExtensionTreatment createNiciraMovNshC1ToC1() {
+        int srcOfs = 0;
+        int dstOfs = 0;
+        int nBits = 32;
+        int srcC1 = 0x0001e604;
+        int dstC1 = 0x0001e604;
+        return new DefaultMoveExtensionTreatment(srcOfs, dstOfs, nBits, srcC1,
+                                                 dstC1,
+                                                 ExtensionTreatmentType.ExtensionTreatmentTypes
+                                                 .NICIRA_MOV_NSH_C1_TO_C1.type());
+    }
+
+    public static ExtensionTreatment createNiciraMovNshC2ToC2() {
+        int srcOfs = 0;
+        int dstOfs = 0;
+        int nBits = 32;
+        int srcC2 = 0x0001e804;
+        int dstC2 = 0x0001e804;
+        return new DefaultMoveExtensionTreatment(srcOfs, dstOfs, nBits, srcC2,
+                                                 dstC2,
+                                                 ExtensionTreatmentType.ExtensionTreatmentTypes
+                                                 .NICIRA_MOV_NSH_C2_TO_C2.type());
+    }
+
+    public static ExtensionTreatment createNiciraMovNshC3ToC3() {
+        int srcOfs = 0;
+        int dstOfs = 0;
+        int nBits = 32;
+        int srcC3 = 0x0001ea04;
+        int dstC3 = 0x0001ea04;
+        return new DefaultMoveExtensionTreatment(srcOfs, dstOfs, nBits, srcC3,
+                                                 dstC3,
+                                                 ExtensionTreatmentType.ExtensionTreatmentTypes
+                                                 .NICIRA_MOV_NSH_C3_TO_C3.type());
+    }
+
+    public static ExtensionTreatment createNiciraMovNshC4ToC4() {
+        int srcOfs = 0;
+        int dstOfs = 0;
+        int nBits = 32;
+        int srcC4 = 0x0001ec04;
+        int dstC4 = 0x0001ec04;
+        return new DefaultMoveExtensionTreatment(srcOfs, dstOfs, nBits, srcC4,
+                                                 dstC4,
+                                                 ExtensionTreatmentType.ExtensionTreatmentTypes
+                                                 .NICIRA_MOV_NSH_C4_TO_C4.type());
+    }
+
+    public static ExtensionTreatment createNiciraMovTunDstToTunDst() {
+        int srcOfs = 0;
+        int dstOfs = 0;
+        int nBits = 32;
+        int srcTunIpv4Dst = 0x00014004;
+        int dstTunIpv4Dst = 0x00014004;
+        return new DefaultMoveExtensionTreatment(srcOfs, dstOfs, nBits, srcTunIpv4Dst,
+                                                 dstTunIpv4Dst,
+                                                 ExtensionTreatmentType.ExtensionTreatmentTypes
+                                                 .NICIRA_MOV_TUN_IPV4_DST_TO_TUN_IPV4_DST.type());
+    }
+
+    public static ExtensionTreatment createNiciraMovTunIdToTunId() {
+        int srcOfs = 0;
+        int dstOfs = 0;
+        int nBits = 64;
+        int srcTunId = 0x12008;
+        int dstTunId = 0x12008; // 0x80004c08;
+        return new DefaultMoveExtensionTreatment(srcOfs, dstOfs, nBits, srcTunId,
+                                                 dstTunId,
+                                                 ExtensionTreatmentType.ExtensionTreatmentTypes
+                                                 .NICIRA_MOV_TUN_ID_TO_TUN_ID.type());
+    }
+
+    public static ExtensionTreatment createNiciraMovNshC2ToTunId() {
+        int srcOfs = 0;
+        int dstOfs = 0;
+        int nBits = 32;
+        int srcC2 = 0x0001e804;
+        int dstTunId = 0x80004c08;
+        return new DefaultMoveExtensionTreatment(srcOfs, dstOfs, nBits, srcC2,
+                                                 dstTunId,
+                                                 ExtensionTreatmentType.ExtensionTreatmentTypes
+                                                 .NICIRA_MOV_NSH_C2_TO_TUN_ID.type());
+    }
 }
diff --git a/drivers/default/src/main/java/org/onosproject/driver/extensions/NiciraNshMdType.java b/drivers/default/src/main/java/org/onosproject/driver/extensions/NiciraNshMdType.java
new file mode 100644
index 0000000..333e470
--- /dev/null
+++ b/drivers/default/src/main/java/org/onosproject/driver/extensions/NiciraNshMdType.java
@@ -0,0 +1,99 @@
+/*
+ * 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 java.util.Objects;
+
+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 com.google.common.base.MoreObjects;
+
+/**
+ * Nicira nshMdType extension instruction.
+ */
+public class NiciraNshMdType extends AbstractExtension implements ExtensionTreatment {
+
+    private byte nshMdType;
+
+    private final KryoNamespace appKryo = new KryoNamespace.Builder().build();
+
+    /**
+     * Creates a new nshMdType instruction.
+     */
+    NiciraNshMdType() {
+        nshMdType = (byte) 0;
+    }
+
+    /**
+     * Creates a new nshMdType instruction with given nsh md type.
+     *
+     * @param nshMdType nsh md type
+     */
+    public NiciraNshMdType(byte nshMdType) {
+        this.nshMdType = nshMdType;
+    }
+
+    /**
+     * Gets the nsh md type.
+     *
+     * @return nshMdType
+     */
+    public byte nshMdType() {
+        return nshMdType;
+    }
+
+    @Override
+    public ExtensionTreatmentType type() {
+        return ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_NSH_MDTYPE.type();
+    }
+
+    @Override
+    public void deserialize(byte[] data) {
+        nshMdType = (byte) (appKryo.deserialize(data));
+    }
+
+    @Override
+    public byte[] serialize() {
+        return appKryo.serialize(nshMdType);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(nshMdType);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof NiciraNshMdType) {
+            NiciraNshMdType that = (NiciraNshMdType) obj;
+            return Objects.equals(nshMdType, that.nshMdType);
+
+        }
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass()).add("nshMdType", nshMdType).toString();
+    }
+}
diff --git a/drivers/default/src/main/java/org/onosproject/driver/extensions/NiciraNshNp.java b/drivers/default/src/main/java/org/onosproject/driver/extensions/NiciraNshNp.java
new file mode 100644
index 0000000..fc319c5
--- /dev/null
+++ b/drivers/default/src/main/java/org/onosproject/driver/extensions/NiciraNshNp.java
@@ -0,0 +1,99 @@
+/*
+ * 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 java.util.Objects;
+
+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 com.google.common.base.MoreObjects;
+
+/**
+ * Nicira nshNp extension instruction to set next protocol value in nsh header.
+ */
+public class NiciraNshNp extends AbstractExtension implements ExtensionTreatment {
+
+    private byte nshNp;
+
+    private final KryoNamespace appKryo = new KryoNamespace.Builder().build();
+
+    /**
+     * Creates a new nshNp instruction.
+     */
+    NiciraNshNp() {
+        nshNp = (byte) 0;
+    }
+
+    /**
+     * Creates a new nshNp instruction with given nsh np.
+     *
+     * @param nshNp nsh next protocol value
+     */
+    public NiciraNshNp(byte nshNp) {
+        this.nshNp = nshNp;
+    }
+
+    /**
+     * Gets the nsh np.
+     *
+     * @return nshNp
+     */
+    public byte nshNp() {
+        return nshNp;
+    }
+
+    @Override
+    public ExtensionTreatmentType type() {
+        return ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_NSH_NP.type();
+    }
+
+    @Override
+    public void deserialize(byte[] data) {
+        nshNp = (byte) (appKryo.deserialize(data));
+    }
+
+    @Override
+    public byte[] serialize() {
+        return appKryo.serialize(nshNp);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(nshNp);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof NiciraNshNp) {
+            NiciraNshNp that = (NiciraNshNp) obj;
+            return Objects.equals(nshNp, that.nshNp);
+
+        }
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass()).add("nshNp", nshNp).toString();
+    }
+}
diff --git a/drivers/default/src/main/java/org/onosproject/driver/extensions/NiciraPopNsh.java b/drivers/default/src/main/java/org/onosproject/driver/extensions/NiciraPopNsh.java
new file mode 100644
index 0000000..2e319f3
--- /dev/null
+++ b/drivers/default/src/main/java/org/onosproject/driver/extensions/NiciraPopNsh.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;
+
+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;
+
+/**
+ * Nicira pop nsh extension instruction.
+ */
+public class NiciraPopNsh extends AbstractExtension implements ExtensionTreatment {
+
+    private final KryoNamespace appKryo = new KryoNamespace.Builder().build();
+
+    /**
+     * Creates a new pop nsh instruction.
+     */
+    public NiciraPopNsh() {
+    }
+
+    @Override
+    public ExtensionTreatmentType type() {
+        return ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_POP_NSH.type();
+    }
+
+    @Override
+    public void deserialize(byte[] data) {
+    }
+
+    @Override
+    public byte[] serialize() {
+        return appKryo.serialize(0);
+    }
+
+    @Override
+    public int hashCode() {
+        return 1;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof NiciraPopNsh) {
+            return true;
+        }
+        return false;
+    }
+}
diff --git a/drivers/default/src/main/java/org/onosproject/driver/extensions/NiciraPushNsh.java b/drivers/default/src/main/java/org/onosproject/driver/extensions/NiciraPushNsh.java
new file mode 100644
index 0000000..8d3a96d
--- /dev/null
+++ b/drivers/default/src/main/java/org/onosproject/driver/extensions/NiciraPushNsh.java
@@ -0,0 +1,67 @@
+/*
+ * 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.util.KryoNamespace;
+import org.onosproject.net.flow.AbstractExtension;
+import org.onosproject.net.flow.instructions.ExtensionTreatment;
+import org.onosproject.net.flow.instructions.ExtensionTreatmentType;
+
+/**
+ * Nicira push nsh extension instruction.
+ */
+public class NiciraPushNsh extends AbstractExtension implements ExtensionTreatment {
+
+    private final KryoNamespace appKryo = new KryoNamespace.Builder().build();
+
+    /**
+     * Creates a new push nsh instruction.
+     */
+    public NiciraPushNsh() {
+
+    }
+
+    @Override
+    public ExtensionTreatmentType type() {
+        return ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_PUSH_NSH.type();
+    }
+
+    @Override
+    public void deserialize(byte[] data) {
+    }
+
+    @Override
+    public byte[] serialize() {
+        return appKryo.serialize(0);
+    }
+
+    @Override
+    public int hashCode() {
+        return 1;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof NiciraPushNsh) {
+            return true;
+        }
+        return false;
+    }
+}
diff --git a/drivers/default/src/main/java/org/onosproject/driver/extensions/NiciraSetNshContextHeader.java b/drivers/default/src/main/java/org/onosproject/driver/extensions/NiciraSetNshContextHeader.java
index ebf2382..65ebf28 100644
--- a/drivers/default/src/main/java/org/onosproject/driver/extensions/NiciraSetNshContextHeader.java
+++ b/drivers/default/src/main/java/org/onosproject/driver/extensions/NiciraSetNshContextHeader.java
@@ -16,6 +16,7 @@
 
 package org.onosproject.driver.extensions;
 
+import java.util.Map;
 import java.util.Objects;
 
 import org.onlab.util.KryoNamespace;
@@ -25,6 +26,7 @@
 import org.onosproject.net.flow.instructions.ExtensionTreatmentType;
 
 import com.google.common.base.MoreObjects;
+import com.google.common.collect.Maps;
 
 /**
  * Nicira set NSH Context header extension instruction.
@@ -74,12 +76,17 @@
 
     @Override
     public void deserialize(byte[] data) {
-        nshCh = NshContextHeader.of(appKryo.deserialize(data));
+        Map<String, Object> values = appKryo.deserialize(data);
+        nshCh = (NshContextHeader) values.get("nshCh");
+        type = (ExtensionTreatmentType) values.get("type");
     }
 
     @Override
     public byte[] serialize() {
-        return appKryo.serialize(nshCh.nshContextHeader());
+        Map<String, Object> values = Maps.newHashMap();
+        values.put("nshCh", nshCh);
+        values.put("type", type);
+        return appKryo.serialize(values);
     }
 
     @Override
diff --git a/drivers/default/src/main/java/org/onosproject/driver/extensions/NiciraTunGpeNp.java b/drivers/default/src/main/java/org/onosproject/driver/extensions/NiciraTunGpeNp.java
new file mode 100644
index 0000000..de15948
--- /dev/null
+++ b/drivers/default/src/main/java/org/onosproject/driver/extensions/NiciraTunGpeNp.java
@@ -0,0 +1,99 @@
+/*
+ * 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 java.util.Objects;
+
+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 com.google.common.base.MoreObjects;
+
+/**
+ * Nicira tunnel gpe next protocol extension instruction to tunGpeNp value.
+ */
+public class NiciraTunGpeNp extends AbstractExtension implements ExtensionTreatment {
+
+    private byte tunGpeNp;
+
+    private final KryoNamespace appKryo = new KryoNamespace.Builder().build();
+
+    /**
+     * Creates a new NiciraTunGpeNp instruction.
+     */
+    NiciraTunGpeNp() {
+        tunGpeNp = (byte) 0;
+    }
+
+    /**
+     * Creates a new NiciraTunGpeNp instruction with given value.
+     *
+     * @param tunGpeNp tunnel gpe next protocol value
+     */
+    public NiciraTunGpeNp(byte tunGpeNp) {
+        this.tunGpeNp = tunGpeNp;
+    }
+
+    /**
+     * Gets the tunGpeNp.
+     *
+     * @return tunGpeNp
+     */
+    public byte tunGpeNp() {
+        return tunGpeNp;
+    }
+
+    @Override
+    public ExtensionTreatmentType type() {
+        return ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_TUN_GPE_NP.type();
+    }
+
+    @Override
+    public void deserialize(byte[] data) {
+        tunGpeNp = (byte) (appKryo.deserialize(data));
+    }
+
+    @Override
+    public byte[] serialize() {
+        return appKryo.serialize(tunGpeNp);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(tunGpeNp);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof NiciraTunGpeNp) {
+            NiciraTunGpeNp that = (NiciraTunGpeNp) obj;
+            return Objects.equals(tunGpeNp, that.tunGpeNp);
+
+        }
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass()).add("tunGpeNp", tunGpeNp).toString();
+    }
+}
diff --git a/drivers/default/src/main/java/org/onosproject/driver/pipeline/OpenVSwitchPipeline.java b/drivers/default/src/main/java/org/onosproject/driver/pipeline/OpenVSwitchPipeline.java
index 74cb756..0120e7e 100644
--- a/drivers/default/src/main/java/org/onosproject/driver/pipeline/OpenVSwitchPipeline.java
+++ b/drivers/default/src/main/java/org/onosproject/driver/pipeline/OpenVSwitchPipeline.java
@@ -70,6 +70,8 @@
     protected DeviceService deviceService;
     private static final int TIME_OUT = 0;
     private static final int CLASSIFIER_TABLE = 0;
+    private static final int ENCAP_OUTPUT_TABLE = 4;
+    private static final int TUN_SEND_TABLE = 7;
     private static final int ARP_TABLE = 10;
     private static final int DNAT_TABLE = 20;
     private static final int L3FWD_TABLE = 30;
@@ -278,7 +280,23 @@
 
     private Collection<FlowRule> processVersatile(ForwardingObjective fwd) {
         log.debug("Processing versatile forwarding objective");
-        return Collections.emptyList();
+        TrafficSelector selector = fwd.selector();
+        TrafficTreatment tb = fwd.treatment();
+        FlowRule.Builder ruleBuilder = DefaultFlowRule.builder().fromApp(fwd.appId()).withPriority(fwd.priority())
+                .forDevice(deviceId).withSelector(selector).withTreatment(tb).makeTemporary(TIME_OUT);
+        ruleBuilder.withPriority(fwd.priority());
+        if (fwd.priority() == 100) {
+            ruleBuilder.forTable(ENCAP_OUTPUT_TABLE);
+        } else if (fwd.priority() == 200) {
+            ruleBuilder.forTable(TUN_SEND_TABLE);
+        } else {
+            ruleBuilder.forTable(CLASSIFIER_TABLE);
+        }
+
+        if (fwd.permanent()) {
+            ruleBuilder.makePermanent();
+        }
+        return Collections.singletonList(ruleBuilder.build());
     }
 
     private Collection<FlowRule> processSpecific(ForwardingObjective fwd) {
diff --git a/drivers/default/src/test/java/org/onosproject/driver/extensions/NiciraEncapEthDstTest.java b/drivers/default/src/test/java/org/onosproject/driver/extensions/NiciraEncapEthDstTest.java
new file mode 100644
index 0000000..971a700
--- /dev/null
+++ b/drivers/default/src/test/java/org/onosproject/driver/extensions/NiciraEncapEthDstTest.java
@@ -0,0 +1,57 @@
+/*
+ * 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 static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.notNullValue;
+
+import org.junit.Test;
+import org.onlab.packet.MacAddress;
+
+import com.google.common.testing.EqualsTester;
+
+/**
+ * Unit tests for NiciraEncapEthDstTest class.
+ */
+public class NiciraEncapEthDstTest {
+
+    private final MacAddress mac1 = MacAddress.valueOf("fa:16:3e:da:45:23");
+    private final MacAddress mac2 = MacAddress.valueOf("fa:16:3e:f3:d1:fe");
+
+    /**
+     * Checks the operation of equals() methods.
+     */
+    @Test
+    public void testEquals() {
+        final NiciraEncapEthDst encapEthDst1 = new NiciraEncapEthDst(mac1);
+        final NiciraEncapEthDst sameAsEncapEthDst1 = new NiciraEncapEthDst(mac1);
+        final NiciraEncapEthDst encapEthDst2 = new NiciraEncapEthDst(mac2);
+
+        new EqualsTester().addEqualityGroup(encapEthDst1, sameAsEncapEthDst1).addEqualityGroup(encapEthDst2)
+        .testEquals();
+    }
+
+    /**
+     * Checks the construction of a NiciraEncapEthDstTest object.
+     */
+    @Test
+    public void testConstruction() {
+        final NiciraEncapEthDst encapEthDst1 = new NiciraEncapEthDst(mac1);
+        assertThat(encapEthDst1, is(notNullValue()));
+        assertThat(encapEthDst1.encapEthDst(), is(mac1));
+    }
+}
diff --git a/drivers/default/src/test/java/org/onosproject/driver/extensions/NiciraEncapEthSrcTest.java b/drivers/default/src/test/java/org/onosproject/driver/extensions/NiciraEncapEthSrcTest.java
new file mode 100644
index 0000000..f54f8b2
--- /dev/null
+++ b/drivers/default/src/test/java/org/onosproject/driver/extensions/NiciraEncapEthSrcTest.java
@@ -0,0 +1,58 @@
+/*
+ * 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 static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.notNullValue;
+
+import org.junit.Test;
+import org.onlab.packet.MacAddress;
+
+import com.google.common.testing.EqualsTester;
+
+/**
+ * Unit tests for NiciraEncapEthSrcTest class.
+ */
+public class NiciraEncapEthSrcTest {
+
+    private final MacAddress mac1 = MacAddress.valueOf("fa:16:3e:11:00:01");
+    private final MacAddress mac2 = MacAddress.valueOf("fa:16:3e:22:00:02");
+
+    /**
+     * Checks the operation of equals() methods.
+     */
+    @Test
+    public void testEquals() {
+        final NiciraEncapEthDst encapEthDst1 = new NiciraEncapEthDst(mac1);
+        final NiciraEncapEthDst sameAsEncapEthDst1 = new NiciraEncapEthDst(mac1);
+        final NiciraEncapEthDst encapEthDst2 = new NiciraEncapEthDst(mac2);
+
+        new EqualsTester().addEqualityGroup(encapEthDst1, sameAsEncapEthDst1).addEqualityGroup(encapEthDst2)
+                .testEquals();
+    }
+
+    /**
+     * Checks the construction of a NiciraEncapEthSrcTest object.
+     */
+    @Test
+    public void testConstruction() {
+
+        final NiciraEncapEthDst encapEthDst1 = new NiciraEncapEthDst(mac1);
+        assertThat(encapEthDst1, is(notNullValue()));
+        assertThat(encapEthDst1.encapEthDst(), is(mac1));
+    }
+}
diff --git a/drivers/default/src/test/java/org/onosproject/driver/extensions/NiciraEncapEthTypeTest.java b/drivers/default/src/test/java/org/onosproject/driver/extensions/NiciraEncapEthTypeTest.java
new file mode 100644
index 0000000..311c81c
--- /dev/null
+++ b/drivers/default/src/test/java/org/onosproject/driver/extensions/NiciraEncapEthTypeTest.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;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.notNullValue;
+
+import org.junit.Test;
+
+import com.google.common.testing.EqualsTester;
+
+/**
+ * Unit tests for NiciraEncapEthType class.
+ */
+public class NiciraEncapEthTypeTest {
+    final short ethType1 = (short) 0x894f;
+    final short ethType2 = (short) 0x800;
+
+    /**
+     * Checks the operation of equals() methods.
+     */
+    @Test
+    public void testEquals() {
+        final NiciraEncapEthType encapEthType1 = new NiciraEncapEthType(ethType1);
+        final NiciraEncapEthType sameAsEncapEthType1 = new NiciraEncapEthType(ethType1);
+        final NiciraEncapEthType encapEthType2 = new NiciraEncapEthType(ethType2);
+
+        new EqualsTester().addEqualityGroup(encapEthType1, sameAsEncapEthType1).addEqualityGroup(encapEthType2)
+                .testEquals();
+    }
+
+    /**
+     * Checks the construction of a NiciraEncapEthType object.
+     */
+    @Test
+    public void testConstruction() {
+        final NiciraEncapEthType encapEthType = new NiciraEncapEthType(ethType1);
+        assertThat(encapEthType, is(notNullValue()));
+        assertThat(encapEthType.encapEthType(), is(ethType1));
+    }
+}
diff --git a/drivers/default/src/test/java/org/onosproject/driver/extensions/NiciraMatchEncapEthTypeTest.java b/drivers/default/src/test/java/org/onosproject/driver/extensions/NiciraMatchEncapEthTypeTest.java
new file mode 100644
index 0000000..b4b38f8
--- /dev/null
+++ b/drivers/default/src/test/java/org/onosproject/driver/extensions/NiciraMatchEncapEthTypeTest.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;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.notNullValue;
+
+import org.junit.Test;
+
+import com.google.common.testing.EqualsTester;
+
+/**
+ * Unit tests for NiciraMatchEncapEthType class.
+ */
+public class NiciraMatchEncapEthTypeTest {
+    final short ethType1 = (short) 0x894f;
+    final short ethType2 = (short) 0x800;
+
+    /**
+     * Checks the operation of equals() methods.
+     */
+    @Test
+    public void testEquals() {
+        final NiciraMatchEncapEthType encapEthType1 = new NiciraMatchEncapEthType(ethType1);
+        final NiciraMatchEncapEthType sameAsEncapEthType1 = new NiciraMatchEncapEthType(ethType1);
+        final NiciraMatchEncapEthType encapEthType2 = new NiciraMatchEncapEthType(ethType2);
+
+        new EqualsTester().addEqualityGroup(encapEthType1, sameAsEncapEthType1).addEqualityGroup(encapEthType2)
+        .testEquals();
+    }
+
+    /**
+     * Checks the construction of a NiciraMatchEncapEthType object.
+     */
+    @Test
+    public void testConstruction() {
+        final NiciraMatchEncapEthType encapEthType = new NiciraMatchEncapEthType(ethType1);
+        assertThat(encapEthType, is(notNullValue()));
+        assertThat(encapEthType.encapEthType(), is(ethType1));
+    }
+}
diff --git a/drivers/default/src/test/java/org/onosproject/driver/extensions/NiciraNshMdTypeTest.java b/drivers/default/src/test/java/org/onosproject/driver/extensions/NiciraNshMdTypeTest.java
new file mode 100644
index 0000000..8c299bd
--- /dev/null
+++ b/drivers/default/src/test/java/org/onosproject/driver/extensions/NiciraNshMdTypeTest.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;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.notNullValue;
+
+import org.junit.Test;
+
+import com.google.common.testing.EqualsTester;
+
+/**
+ * Unit tests for NiciraNshMdType class.
+ */
+public class NiciraNshMdTypeTest {
+    final byte mdType1 = (byte) 1;
+    final byte mdType2 = (byte) 2;
+
+    /**
+     * Checks the operation of equals() methods.
+     */
+    @Test
+    public void testEquals() {
+        final NiciraNshMdType nshMdType1 = new NiciraNshMdType(mdType1);
+        final NiciraNshMdType sameAsnshMdType1 = new NiciraNshMdType(mdType1);
+        final NiciraNshMdType nshMdType2 = new NiciraNshMdType(mdType2);
+
+        new EqualsTester().addEqualityGroup(nshMdType1, sameAsnshMdType1).addEqualityGroup(nshMdType2)
+        .testEquals();
+    }
+
+    /**
+     * Checks the construction of a NiciraNshMdType object.
+     */
+    @Test
+    public void testConstruction() {
+        final NiciraNshMdType nshMdType = new NiciraNshMdType(mdType1);
+        assertThat(nshMdType, is(notNullValue()));
+        assertThat(nshMdType.nshMdType(), is(mdType1));
+    }
+}
diff --git a/drivers/default/src/test/java/org/onosproject/driver/extensions/NiciraNshNpTest.java b/drivers/default/src/test/java/org/onosproject/driver/extensions/NiciraNshNpTest.java
new file mode 100644
index 0000000..17ed7ae
--- /dev/null
+++ b/drivers/default/src/test/java/org/onosproject/driver/extensions/NiciraNshNpTest.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;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.notNullValue;
+
+import org.junit.Test;
+
+import com.google.common.testing.EqualsTester;
+
+/**
+ * Unit tests for NiciraNshNp class.
+ */
+public class NiciraNshNpTest {
+    final byte np1 = (byte) 1;
+    final byte np2 = (byte) 4;
+
+    /**
+     * Checks the operation of equals() methods.
+     */
+    @Test
+    public void testEquals() {
+        final NiciraNshNp nshNp1 = new NiciraNshNp(np1);
+        final NiciraNshNp sameAsNshNp1 = new NiciraNshNp(np1);
+        final NiciraNshNp nshNp2 = new NiciraNshNp(np2);
+
+        new EqualsTester().addEqualityGroup(nshNp1, sameAsNshNp1).addEqualityGroup(nshNp2)
+                .testEquals();
+    }
+
+    /**
+     * Checks the construction of a NiciraNshNp object.
+     */
+    @Test
+    public void testConstruction() {
+        final NiciraNshNp nshNp1 = new NiciraNshNp(np1);
+        assertThat(nshNp1, is(notNullValue()));
+        assertThat(nshNp1.nshNp(), is(np1));
+    }
+}
diff --git a/drivers/default/src/test/java/org/onosproject/driver/extensions/NiciraTunGpeNpTest.java b/drivers/default/src/test/java/org/onosproject/driver/extensions/NiciraTunGpeNpTest.java
new file mode 100644
index 0000000..259ebb5
--- /dev/null
+++ b/drivers/default/src/test/java/org/onosproject/driver/extensions/NiciraTunGpeNpTest.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;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.notNullValue;
+
+import org.junit.Test;
+
+import com.google.common.testing.EqualsTester;
+
+/**
+ * Unit tests for NiciraTunGpeNp class.
+ */
+public class NiciraTunGpeNpTest {
+    final byte np1 = (byte) 1;
+    final byte np2 = (byte) 2;
+
+    /**
+     * Checks the operation of equals() methods.
+     */
+    @Test
+    public void testEquals() {
+        final NiciraTunGpeNp tunGpeNp1 = new NiciraTunGpeNp(np1);
+        final NiciraTunGpeNp sameAsTunGpeNp1 = new NiciraTunGpeNp(np1);
+        final NiciraTunGpeNp tunGpeNp2 = new NiciraTunGpeNp(np2);
+
+        new EqualsTester().addEqualityGroup(tunGpeNp1, sameAsTunGpeNp1).addEqualityGroup(tunGpeNp2)
+        .testEquals();
+    }
+
+    /**
+     * Checks the construction of a NiciraTunGpeNp object.
+     */
+    @Test
+    public void testConstruction() {
+        final NiciraTunGpeNp tunGpeNp1 = new NiciraTunGpeNp(np1);
+        assertThat(tunGpeNp1, is(notNullValue()));
+        assertThat(tunGpeNp1.tunGpeNp(), is(np1));
+    }
+}