Implemented the extension framework for selectors.

Change-Id: I577900141889fc70ca54e96cd5d54cfd5194b05d
diff --git a/core/api/src/main/java/org/onosproject/net/behaviour/ExtensionSelectorResolver.java b/core/api/src/main/java/org/onosproject/net/behaviour/ExtensionSelectorResolver.java
new file mode 100644
index 0000000..d45dd53
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/behaviour/ExtensionSelectorResolver.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.net.behaviour;
+
+import com.google.common.annotations.Beta;
+import org.onosproject.net.driver.HandlerBehaviour;
+import org.onosproject.net.flow.criteria.ExtensionSelector;
+import org.onosproject.net.flow.criteria.ExtensionSelectorType;
+
+/**
+ * Provides access to the extension selectors implemented by this driver.
+ */
+@Beta
+public interface ExtensionSelectorResolver extends HandlerBehaviour {
+
+    /**
+     * Gets an extension selector instance of the specified type, if supported
+     * by the driver.
+     *
+     * @param type type of extension to get
+     * @return extension selector
+     * @throws UnsupportedOperationException if the extension type is not
+     * supported by this driver
+     */
+    ExtensionSelector getExtensionSelector(ExtensionSelectorType type);
+}
diff --git a/core/api/src/main/java/org/onosproject/net/flow/instructions/AbstractExtensionTreatment.java b/core/api/src/main/java/org/onosproject/net/flow/AbstractExtension.java
similarity index 90%
rename from core/api/src/main/java/org/onosproject/net/flow/instructions/AbstractExtensionTreatment.java
rename to core/api/src/main/java/org/onosproject/net/flow/AbstractExtension.java
index ac7c771..b48d69c 100644
--- a/core/api/src/main/java/org/onosproject/net/flow/instructions/AbstractExtensionTreatment.java
+++ b/core/api/src/main/java/org/onosproject/net/flow/AbstractExtension.java
@@ -14,22 +14,25 @@
  * limitations under the License.
  */
 
-package org.onosproject.net.flow.instructions;
+package org.onosproject.net.flow;
+
+import org.onosproject.net.flow.instructions.ExtensionPropertyException;
 
 import java.lang.reflect.Field;
 import java.util.ArrayList;
 import java.util.List;
 
 /**
- * Abstract implementation of the set/get property methods of ExtensionInstruction.
+ * Abstract implementation of the set/get property methods of Extension.
  */
-public abstract class AbstractExtensionTreatment implements ExtensionTreatment {
+public abstract class AbstractExtension implements Extension {
 
     private static final String INVALID_KEY = "Invalid property key: ";
     private static final String INVALID_TYPE = "Given type does not match field type: ";
 
     @Override
-    public <T> void setPropertyValue(String key, T value) throws ExtensionPropertyException {
+    public <T> void setPropertyValue(String key, T value) throws
+            ExtensionPropertyException {
         Class<?> clazz = this.getClass();
         try {
             Field field = clazz.getDeclaredField(key);
diff --git a/core/api/src/main/java/org/onosproject/net/flow/DefaultTrafficSelector.java b/core/api/src/main/java/org/onosproject/net/flow/DefaultTrafficSelector.java
index d3c2449..0525d8f 100644
--- a/core/api/src/main/java/org/onosproject/net/flow/DefaultTrafficSelector.java
+++ b/core/api/src/main/java/org/onosproject/net/flow/DefaultTrafficSelector.java
@@ -15,14 +15,8 @@
  */
 package org.onosproject.net.flow;
 
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Set;
-import java.util.TreeSet;
-
+import com.google.common.base.MoreObjects;
+import com.google.common.collect.ImmutableSet;
 import org.onlab.packet.Ip4Address;
 import org.onlab.packet.Ip6Address;
 import org.onlab.packet.IpPrefix;
@@ -30,12 +24,19 @@
 import org.onlab.packet.MplsLabel;
 import org.onlab.packet.TpPort;
 import org.onlab.packet.VlanId;
+import org.onosproject.net.DeviceId;
 import org.onosproject.net.PortNumber;
 import org.onosproject.net.flow.criteria.Criteria;
 import org.onosproject.net.flow.criteria.Criterion;
+import org.onosproject.net.flow.criteria.ExtensionSelector;
 
-import com.google.common.base.MoreObjects;
-import com.google.common.collect.ImmutableSet;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+import java.util.TreeSet;
 
 /**
  * Default traffic selector implementation.
@@ -379,6 +380,12 @@
         }
 
         @Override
+        public TrafficSelector.Builder extension(ExtensionSelector extensionSelector,
+                                                 DeviceId deviceId) {
+            return add(Criteria.extension(extensionSelector, deviceId));
+        }
+
+        @Override
         public TrafficSelector build() {
             return new DefaultTrafficSelector(ImmutableSet.copyOf(selector.values()));
         }
diff --git a/core/api/src/main/java/org/onosproject/net/flow/Extension.java b/core/api/src/main/java/org/onosproject/net/flow/Extension.java
new file mode 100644
index 0000000..1d61542
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/flow/Extension.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.net.flow;
+
+import org.onosproject.net.flow.instructions.ExtensionPropertyException;
+
+import java.util.List;
+
+/**
+ * An extension to the northbound APIs.
+ */
+public interface Extension {
+
+    /**
+     * Sets a property on the extension.
+     *
+     * @param key property key
+     * @param value value to set for the given key
+     * @param <T> class of the value
+     * @throws ExtensionPropertyException if the given key is not a valid
+     * property on this extension
+     */
+    <T> void setPropertyValue(String key, T value) throws ExtensionPropertyException;
+
+    /**
+     * Gets a property value of an extension.
+     *
+     * @param key property key
+     * @param <T> class of the value
+     * @return value of the property
+     * @throws ExtensionPropertyException if the given key is not a valid
+     * property on this extension
+     */
+    <T> T getPropertyValue(String key) throws ExtensionPropertyException;
+
+    /**
+     * Gets a list of all properties on the extension.
+     *
+     * @return list of properties
+     */
+    List<String> getProperties();
+
+    /**
+     * Serialize the extension to a byte array.
+     *
+     * @return byte array
+     */
+    byte[] serialize();
+
+    /**
+     * Deserialize the extension from a byte array. The properties
+     * of this object will be overwritten with the data in the byte array.
+     *
+     * @param data input byte array
+     */
+    void deserialize(byte[] data);
+}
diff --git a/core/api/src/main/java/org/onosproject/net/flow/TrafficSelector.java b/core/api/src/main/java/org/onosproject/net/flow/TrafficSelector.java
index b92281f..0d055ad 100644
--- a/core/api/src/main/java/org/onosproject/net/flow/TrafficSelector.java
+++ b/core/api/src/main/java/org/onosproject/net/flow/TrafficSelector.java
@@ -15,8 +15,6 @@
  */
 package org.onosproject.net.flow;
 
-import java.util.Set;
-
 import org.onlab.packet.Ip4Address;
 import org.onlab.packet.Ip6Address;
 import org.onlab.packet.IpPrefix;
@@ -24,8 +22,12 @@
 import org.onlab.packet.MplsLabel;
 import org.onlab.packet.TpPort;
 import org.onlab.packet.VlanId;
+import org.onosproject.net.DeviceId;
 import org.onosproject.net.PortNumber;
 import org.onosproject.net.flow.criteria.Criterion;
+import org.onosproject.net.flow.criteria.ExtensionSelector;
+
+import java.util.Set;
 
 /**
  * Abstraction of a slice of network traffic.
@@ -427,6 +429,15 @@
         Builder matchArpOp(int arpOp);
 
         /**
+         * Uses an extension selector.
+         *
+         * @param extensionSelector extension selector
+         * @param deviceId device ID
+         * @return a selection builder
+         */
+        Builder extension(ExtensionSelector extensionSelector, DeviceId deviceId);
+
+        /**
          * Builds an immutable traffic selector.
          *
          * @return traffic selector
diff --git a/core/api/src/main/java/org/onosproject/net/flow/criteria/Criteria.java b/core/api/src/main/java/org/onosproject/net/flow/criteria/Criteria.java
index a28a4ab..dd31ad4 100644
--- a/core/api/src/main/java/org/onosproject/net/flow/criteria/Criteria.java
+++ b/core/api/src/main/java/org/onosproject/net/flow/criteria/Criteria.java
@@ -23,6 +23,7 @@
 import org.onlab.packet.MplsLabel;
 import org.onlab.packet.TpPort;
 import org.onlab.packet.VlanId;
+import org.onosproject.net.DeviceId;
 import org.onosproject.net.IndexedLambda;
 import org.onosproject.net.Lambda;
 import org.onosproject.net.OchSignal;
@@ -579,6 +580,23 @@
         return new ArpOpCriterion(arpOp, Type.ARP_OP);
     }
 
+    /**
+     * Creates an extension criterion for the specified extension selector.
+     *
+     * @param extensionSelector extension selector
+     * @param deviceId device ID
+     * @return match criterion
+     */
+    public static Criterion extension(ExtensionSelector extensionSelector,
+                                      DeviceId deviceId) {
+        return new ExtensionCriterion(extensionSelector, deviceId);
+    }
+
+    /**
+     * Creates a dummy criterion.
+     *
+     * @return match criterion
+     */
     public static Criterion dummy() {
         return new DummyCriterion();
     }
diff --git a/core/api/src/main/java/org/onosproject/net/flow/criteria/Criterion.java b/core/api/src/main/java/org/onosproject/net/flow/criteria/Criterion.java
index 2666524..17557b9 100644
--- a/core/api/src/main/java/org/onosproject/net/flow/criteria/Criterion.java
+++ b/core/api/src/main/java/org/onosproject/net/flow/criteria/Criterion.java
@@ -177,6 +177,9 @@
         /** ODU (Optical channel Data Unit) signal type. */
         ODU_SIGTYPE,
 
+        /** Extension criterion. */
+        EXTENSION,
+
         /** An empty criterion. */
         DUMMY
     }
diff --git a/core/api/src/main/java/org/onosproject/net/flow/criteria/ExtensionCriterion.java b/core/api/src/main/java/org/onosproject/net/flow/criteria/ExtensionCriterion.java
new file mode 100644
index 0000000..646b418
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/flow/criteria/ExtensionCriterion.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.net.flow.criteria;
+
+import org.onosproject.net.DeviceId;
+
+import java.util.Objects;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+/**
+ * Criterion for implementing selector extensions.
+ */
+public class ExtensionCriterion implements Criterion {
+
+    private final ExtensionSelector extensionSelector;
+    private final DeviceId deviceId;
+
+    /**
+     * Constructor.
+     *
+     * @param extensionSelector extension selector
+     */
+    public ExtensionCriterion(ExtensionSelector extensionSelector, DeviceId deviceId) {
+        this.extensionSelector = extensionSelector;
+        this.deviceId = deviceId;
+    }
+
+    /**
+     * Returns the extension selector.
+     *
+     * @return extension selector
+     */
+    public ExtensionSelector extensionSelector() {
+        return extensionSelector;
+    }
+
+    /**
+     * Returns the device ID.
+     *
+     * @return device ID
+     */
+    public DeviceId deviceId() {
+        return deviceId;
+    }
+
+    @Override
+    public Type type() {
+        return Type.EXTENSION;
+    }
+
+    @Override
+    public String toString() {
+        return toStringHelper(type().toString())
+                .add("extensionSelector", extensionSelector.toString())
+                .add("deviceId", deviceId)
+                .toString();
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(type().ordinal(), extensionSelector, deviceId);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof ExtensionCriterion) {
+            ExtensionCriterion that = (ExtensionCriterion) obj;
+            return Objects.equals(extensionSelector, that.extensionSelector) &&
+                    Objects.equals(deviceId, that.deviceId) &&
+                    Objects.equals(this.type(), that.type());
+        }
+        return false;
+    }
+}
diff --git a/core/api/src/main/java/org/onosproject/net/flow/criteria/ExtensionSelector.java b/core/api/src/main/java/org/onosproject/net/flow/criteria/ExtensionSelector.java
new file mode 100644
index 0000000..d3cebb3
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/flow/criteria/ExtensionSelector.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.net.flow.criteria;
+
+import org.onosproject.net.flow.Extension;
+
+/**
+ * An extension for the selector API.
+ */
+public interface ExtensionSelector extends Extension {
+
+    /**
+     * Gets the type of the extension selector.
+     *
+     * @return type
+     */
+    ExtensionSelectorType type();
+}
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
new file mode 100644
index 0000000..982e5b1
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/flow/criteria/ExtensionSelectorType.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.net.flow.criteria;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.MoreObjects;
+
+import java.util.Objects;
+
+/**
+ * Type of selector extensions.
+ */
+@Beta
+public class ExtensionSelectorType {
+
+    /**
+     * A list of well-known named extension selector type codes.
+     * These numbers have no impact on the actual OF type id.
+     */
+    public enum ExtensionSelectorTypes {
+        PLACEHOLDER(0); // TODO remove when actual extensions are added
+
+        private ExtensionSelectorType type;
+
+        /**
+         * Creates a new named extension selector type.
+         *
+         * @param type type code
+         */
+        ExtensionSelectorTypes(int type) {
+            this.type = new ExtensionSelectorType(type);
+        }
+
+        /**
+         * Gets the extension type object for this named type code.
+         *
+         * @return extension type object
+         */
+        public ExtensionSelectorType type() {
+            return type;
+        }
+    }
+
+    private final int type;
+
+    /**
+     * Creates an extension type with the given int type code.
+     *
+     * @param type type code
+     */
+    public ExtensionSelectorType(int type) {
+        this.type = type;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(type);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof ExtensionSelectorType) {
+            final ExtensionSelectorType that = (ExtensionSelectorType) obj;
+            return this.type == that.type;
+        }
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(ExtensionSelectorType.class)
+                .add("type", type)
+                .toString();
+    }
+}
diff --git a/core/api/src/main/java/org/onosproject/net/flow/instructions/ExtensionTreatment.java b/core/api/src/main/java/org/onosproject/net/flow/instructions/ExtensionTreatment.java
index 0e8885e..35a2d12 100644
--- a/core/api/src/main/java/org/onosproject/net/flow/instructions/ExtensionTreatment.java
+++ b/core/api/src/main/java/org/onosproject/net/flow/instructions/ExtensionTreatment.java
@@ -16,12 +16,12 @@
 
 package org.onosproject.net.flow.instructions;
 
-import java.util.List;
+import org.onosproject.net.flow.Extension;
 
 /**
- * An extensible instruction type.
+ * An extenstion for the treatment API.
  */
-public interface ExtensionTreatment {
+public interface ExtensionTreatment extends Extension {
 
     /**
      * Gets the type of the extension instruction.
@@ -30,49 +30,4 @@
      */
     ExtensionTreatmentType type();
 
-    /**
-     * Sets a property on the extension instruction.
-     *
-     * @param key property key
-     * @param value value to set for the given key
-     * @param <T> class of the value
-     * @throws ExtensionPropertyException if the given key is not a valid
-     * property on this extension instruction
-     */
-    <T> void setPropertyValue(String key, T value) throws ExtensionPropertyException;
-
-    /**
-     * Gets a property value of an extension instruction.
-     *
-     * @param key property key
-     * @param <T> class of the value
-     * @return value of the property
-     * @throws ExtensionPropertyException if the given key is not a valid
-     * property on this extension instruction
-     */
-    <T> T getPropertyValue(String key) throws ExtensionPropertyException;
-
-    /**
-     * Gets a list of all properties on the extension instruction.
-     *
-     * @return list of properties
-     */
-    List<String> getProperties();
-
-    /**
-     * Serialize the extension instruction to a byte array.
-     *
-     * @return byte array
-     */
-    byte[] serialize();
-
-    /**
-     * Deserialize the extension instruction from a byte array. The properties
-     * of this object will be overwritten with the data in the byte array.
-     *
-     * @param data input byte array
-     */
-    void deserialize(byte[] data);
-
-
 }
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 821c1d9..9715fc0 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
@@ -22,7 +22,7 @@
 import java.util.Objects;
 
 /**
- * Type of extension instructions.
+ * Type of treatment extensions.
  */
 @Beta
 public final class ExtensionTreatmentType {
diff --git a/core/common/src/main/java/org/onosproject/codec/impl/EncodeCriterionCodecHelper.java b/core/common/src/main/java/org/onosproject/codec/impl/EncodeCriterionCodecHelper.java
index 33dd46a..1852ee2 100644
--- a/core/common/src/main/java/org/onosproject/codec/impl/EncodeCriterionCodecHelper.java
+++ b/core/common/src/main/java/org/onosproject/codec/impl/EncodeCriterionCodecHelper.java
@@ -127,6 +127,7 @@
         formatMap.put(Criterion.Type.TCP_FLAGS, new FormatUnknown());
         formatMap.put(Criterion.Type.ACTSET_OUTPUT, new FormatUnknown());
         formatMap.put(Criterion.Type.PACKET_TYPE, new FormatUnknown());
+        formatMap.put(Criterion.Type.EXTENSION, new FormatUnknown());
     }
 
     private interface CriterionTypeFormatter {
diff --git a/core/net/src/main/java/org/onosproject/net/flow/impl/FlowRuleManager.java b/core/net/src/main/java/org/onosproject/net/flow/impl/FlowRuleManager.java
index 5958d1f..63ee03e 100644
--- a/core/net/src/main/java/org/onosproject/net/flow/impl/FlowRuleManager.java
+++ b/core/net/src/main/java/org/onosproject/net/flow/impl/FlowRuleManager.java
@@ -436,7 +436,7 @@
                         log.debug("Adding rule in store, but not on switch {}", rule);
                         flowMissing(rule);
                     } catch (Exception e) {
-                        log.debug("Can't add missing flow rule {}", e.getMessage());
+                        log.debug("Can't add missing flow rule:", e);
                         continue;
                     }
                 }
diff --git a/drivers/src/main/java/org/onosproject/driver/extensions/NiciraExtensionSelectorInterpreter.java b/drivers/src/main/java/org/onosproject/driver/extensions/NiciraExtensionSelectorInterpreter.java
new file mode 100644
index 0000000..b1a3c68
--- /dev/null
+++ b/drivers/src/main/java/org/onosproject/driver/extensions/NiciraExtensionSelectorInterpreter.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.driver.extensions;
+
+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.oxm.OFOxm;
+
+/**
+ * Interpreter for Nicira OpenFlow selector extensions.
+ */
+public class NiciraExtensionSelectorInterpreter
+        extends AbstractHandlerBehaviour
+        implements ExtensionSelectorInterpreter, ExtensionSelectorResolver {
+
+    @Override
+    public boolean supported(ExtensionSelectorType extensionSelectorType) {
+        return false;
+    }
+
+    @Override
+    public OFOxm<?> mapSelector(OFFactory factory, ExtensionSelector extensionSelector) {
+        return null;
+    }
+
+    @Override
+    public ExtensionSelector mapOxm(OFOxm<?> oxm) {
+        return null;
+    }
+
+    @Override
+    public ExtensionSelector getExtensionSelector(ExtensionSelectorType type) {
+        return null;
+    }
+}
diff --git a/drivers/src/main/java/org/onosproject/driver/extensions/NiciraExtensionTreatmentInterpreter.java b/drivers/src/main/java/org/onosproject/driver/extensions/NiciraExtensionTreatmentInterpreter.java
index 2297906..bfca861 100644
--- a/drivers/src/main/java/org/onosproject/driver/extensions/NiciraExtensionTreatmentInterpreter.java
+++ b/drivers/src/main/java/org/onosproject/driver/extensions/NiciraExtensionTreatmentInterpreter.java
@@ -31,7 +31,7 @@
 import org.projectfloodlight.openflow.types.IPv4Address;
 
 /**
- * Interpreter for Nicira OpenFlow extensions.
+ * Interpreter for Nicira OpenFlow treatment extensions.
  */
 public class NiciraExtensionTreatmentInterpreter extends AbstractHandlerBehaviour
         implements ExtensionTreatmentInterpreter, ExtensionTreatmentResolver {
diff --git a/drivers/src/main/java/org/onosproject/driver/extensions/NiciraResubmit.java b/drivers/src/main/java/org/onosproject/driver/extensions/NiciraResubmit.java
index 481b6f9..b85af4f 100644
--- a/drivers/src/main/java/org/onosproject/driver/extensions/NiciraResubmit.java
+++ b/drivers/src/main/java/org/onosproject/driver/extensions/NiciraResubmit.java
@@ -19,7 +19,8 @@
 import com.google.common.base.MoreObjects;
 import org.onlab.util.KryoNamespace;
 import org.onosproject.net.PortNumber;
-import org.onosproject.net.flow.instructions.AbstractExtensionTreatment;
+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.PortNumberSerializer;
 
@@ -30,7 +31,7 @@
 /**
  * Nicira resubmit extension instruction.
  */
-public class NiciraResubmit extends AbstractExtensionTreatment {
+public class NiciraResubmit extends AbstractExtension implements ExtensionTreatment  {
 
     private PortNumber inPort;
 
diff --git a/drivers/src/main/java/org/onosproject/driver/extensions/NiciraResubmitTable.java b/drivers/src/main/java/org/onosproject/driver/extensions/NiciraResubmitTable.java
index 3c8dd0c..4743d21 100644
--- a/drivers/src/main/java/org/onosproject/driver/extensions/NiciraResubmitTable.java
+++ b/drivers/src/main/java/org/onosproject/driver/extensions/NiciraResubmitTable.java
@@ -20,7 +20,8 @@
 
 import org.onlab.util.KryoNamespace;
 import org.onosproject.net.PortNumber;
-import org.onosproject.net.flow.instructions.AbstractExtensionTreatment;
+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.PortNumberSerializer;
 
@@ -33,7 +34,8 @@
 /**
  * Nicira resubmit-table extension instruction.
  */
-public class NiciraResubmitTable extends AbstractExtensionTreatment {
+public class NiciraResubmitTable extends AbstractExtension implements
+        ExtensionTreatment {
 
     //the list of the in port number(PortNumber) and the table(short)
     private List<Object> inPortAndTable = new ArrayList<Object>();
@@ -109,4 +111,4 @@
         return MoreObjects.toStringHelper(getClass())
                 .add("inPortAndTable", inPortAndTable).toString();
     }
-}
\ No newline at end of file
+}
diff --git a/drivers/src/main/java/org/onosproject/driver/extensions/NiciraSetNshContextHeader.java b/drivers/src/main/java/org/onosproject/driver/extensions/NiciraSetNshContextHeader.java
index 0aa0f4d..c826798 100644
--- a/drivers/src/main/java/org/onosproject/driver/extensions/NiciraSetNshContextHeader.java
+++ b/drivers/src/main/java/org/onosproject/driver/extensions/NiciraSetNshContextHeader.java
@@ -16,18 +16,19 @@
 
 package org.onosproject.driver.extensions;
 
-import java.util.Objects;
-
+import com.google.common.base.MoreObjects;
 import org.onlab.util.KryoNamespace;
-import org.onosproject.net.flow.instructions.AbstractExtensionTreatment;
+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;
+import java.util.Objects;
 
 /**
  * Nicira set NSH Context header extension instruction.
  */
-public class NiciraSetNshContextHeader extends AbstractExtensionTreatment {
+public class NiciraSetNshContextHeader extends AbstractExtension implements
+        ExtensionTreatment {
 
     private int nshCh;
     private ExtensionTreatmentType type;
diff --git a/drivers/src/main/java/org/onosproject/driver/extensions/NiciraSetNshSi.java b/drivers/src/main/java/org/onosproject/driver/extensions/NiciraSetNshSi.java
index 53cf629..1480508 100644
--- a/drivers/src/main/java/org/onosproject/driver/extensions/NiciraSetNshSi.java
+++ b/drivers/src/main/java/org/onosproject/driver/extensions/NiciraSetNshSi.java
@@ -16,18 +16,19 @@
 
 package org.onosproject.driver.extensions;
 
-import java.util.Objects;
-
+import com.google.common.base.MoreObjects;
 import org.onlab.util.KryoNamespace;
-import org.onosproject.net.flow.instructions.AbstractExtensionTreatment;
+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;
+import java.util.Objects;
 
 /**
  * Nicira set NSH SI extension instruction.
  */
-public class NiciraSetNshSi extends AbstractExtensionTreatment {
+public class NiciraSetNshSi extends AbstractExtension implements
+        ExtensionTreatment {
 
     private byte nshSi;
 
diff --git a/drivers/src/main/java/org/onosproject/driver/extensions/NiciraSetNshSpi.java b/drivers/src/main/java/org/onosproject/driver/extensions/NiciraSetNshSpi.java
index 1a168d0..1a47173 100644
--- a/drivers/src/main/java/org/onosproject/driver/extensions/NiciraSetNshSpi.java
+++ b/drivers/src/main/java/org/onosproject/driver/extensions/NiciraSetNshSpi.java
@@ -16,18 +16,19 @@
 
 package org.onosproject.driver.extensions;
 
-import java.util.Objects;
-
+import com.google.common.base.MoreObjects;
 import org.onlab.util.KryoNamespace;
-import org.onosproject.net.flow.instructions.AbstractExtensionTreatment;
+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;
+import java.util.Objects;
 
 /**
  * Nicira set NSH SPI extension instruction.
  */
-public class NiciraSetNshSpi extends AbstractExtensionTreatment {
+public class NiciraSetNshSpi extends AbstractExtension implements
+        ExtensionTreatment {
 
     private int nshSpi;
 
diff --git a/drivers/src/main/java/org/onosproject/driver/extensions/NiciraSetTunnelDst.java b/drivers/src/main/java/org/onosproject/driver/extensions/NiciraSetTunnelDst.java
index ec23a9e..e28a1e2 100644
--- a/drivers/src/main/java/org/onosproject/driver/extensions/NiciraSetTunnelDst.java
+++ b/drivers/src/main/java/org/onosproject/driver/extensions/NiciraSetTunnelDst.java
@@ -19,7 +19,8 @@
 import com.google.common.base.MoreObjects;
 import org.onlab.packet.Ip4Address;
 import org.onlab.util.KryoNamespace;
-import org.onosproject.net.flow.instructions.AbstractExtensionTreatment;
+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.Ip4AddressSerializer;
 
@@ -30,7 +31,8 @@
 /**
  * Nicira set tunnel destination extension instruction.
  */
-public class NiciraSetTunnelDst extends AbstractExtensionTreatment {
+public class NiciraSetTunnelDst extends AbstractExtension implements
+        ExtensionTreatment {
 
     private Ip4Address tunnelDst;
 
diff --git a/drivers/src/main/resources/onos-drivers.xml b/drivers/src/main/resources/onos-drivers.xml
index a172c18..6989683 100644
--- a/drivers/src/main/resources/onos-drivers.xml
+++ b/drivers/src/main/resources/onos-drivers.xml
@@ -36,6 +36,10 @@
                    impl="org.onosproject.driver.extensions.NiciraExtensionTreatmentInterpreter" />
         <behaviour api="org.onosproject.net.behaviour.ExtensionTreatmentResolver"
                    impl="org.onosproject.driver.extensions.NiciraExtensionTreatmentInterpreter" />
+        <behaviour api="org.onosproject.openflow.controller.ExtensionSelectorInterpreter"
+                   impl="org.onosproject.driver.extensions.NiciraExtensionSelectorInterpreter" />
+        <behaviour api="org.onosproject.net.behaviour.ExtensionSelectorResolver"
+                   impl="org.onosproject.driver.extensions.NiciraExtensionSelectorInterpreter" />
     </driver>
     <!--This driver is for simulated NETCONF devices through of-config tool on top og OVSDB-->
     <driver name="ovs-netconf" extends="default"
diff --git a/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/ExtensionSelectorInterpreter.java b/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/ExtensionSelectorInterpreter.java
new file mode 100644
index 0000000..7336c3c
--- /dev/null
+++ b/protocols/openflow/api/src/main/java/org/onosproject/openflow/controller/ExtensionSelectorInterpreter.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.openflow.controller;
+
+import com.google.common.annotations.Beta;
+import org.onosproject.net.driver.HandlerBehaviour;
+import org.onosproject.net.flow.criteria.ExtensionSelector;
+import org.onosproject.net.flow.criteria.ExtensionSelectorType;
+import org.projectfloodlight.openflow.protocol.OFFactory;
+import org.projectfloodlight.openflow.protocol.oxm.OFOxm;
+
+/**
+ * Interprets extension selectors and converts them to/from OpenFlow objects.
+ */
+@Beta
+public interface ExtensionSelectorInterpreter extends HandlerBehaviour {
+
+    /**
+     * Returns true if the given extension selector is supported by this
+     * driver.
+     *
+     * @param extensionSelectorType extension selector type
+     * @return true if the instruction is supported, otherwise false
+     */
+    boolean supported(ExtensionSelectorType extensionSelectorType);
+
+    /**
+     * Maps an extension selector to an OpenFlow OXM.
+     *
+     * @param factory OpenFlow factory
+     * @param extensionSelector extension selector
+     * @return OpenFlow action
+     */
+    OFOxm<?> mapSelector(OFFactory factory, ExtensionSelector extensionSelector);
+
+    /**
+     * Maps an OpenFlow OXM to an extension selector.
+     *
+     * @param oxm OpenFlow OXM
+     * @return extension selector
+     */
+    ExtensionSelector mapOxm(OFOxm<?> oxm);
+}
diff --git a/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowModBuilder.java b/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowModBuilder.java
index 2a8d201..e6f2f74 100644
--- a/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowModBuilder.java
+++ b/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowModBuilder.java
@@ -20,7 +20,11 @@
 import org.onlab.packet.Ip6Address;
 import org.onlab.packet.Ip6Prefix;
 import org.onlab.packet.VlanId;
+import org.onosproject.net.DeviceId;
 import org.onosproject.net.OchSignal;
+import org.onosproject.net.driver.DefaultDriverData;
+import org.onosproject.net.driver.DefaultDriverHandler;
+import org.onosproject.net.driver.Driver;
 import org.onosproject.net.driver.DriverService;
 import org.onosproject.net.flow.FlowRule;
 import org.onosproject.net.flow.TrafficSelector;
@@ -30,6 +34,8 @@
 import org.onosproject.net.flow.criteria.Criterion;
 import org.onosproject.net.flow.criteria.EthCriterion;
 import org.onosproject.net.flow.criteria.EthTypeCriterion;
+import org.onosproject.net.flow.criteria.ExtensionCriterion;
+import org.onosproject.net.flow.criteria.ExtensionSelector;
 import org.onosproject.net.flow.criteria.IPCriterion;
 import org.onosproject.net.flow.criteria.IPDscpCriterion;
 import org.onosproject.net.flow.criteria.IPEcnCriterion;
@@ -54,12 +60,14 @@
 import org.onosproject.net.flow.criteria.UdpPortCriterion;
 import org.onosproject.net.flow.criteria.VlanIdCriterion;
 import org.onosproject.net.flow.criteria.VlanPcpCriterion;
+import org.onosproject.openflow.controller.ExtensionSelectorInterpreter;
 import org.projectfloodlight.openflow.protocol.OFFactory;
 import org.projectfloodlight.openflow.protocol.OFFlowAdd;
 import org.projectfloodlight.openflow.protocol.OFFlowDelete;
 import org.projectfloodlight.openflow.protocol.OFFlowMod;
 import org.projectfloodlight.openflow.protocol.match.Match;
 import org.projectfloodlight.openflow.protocol.match.MatchField;
+import org.projectfloodlight.openflow.protocol.oxm.OFOxm;
 import org.projectfloodlight.openflow.types.ArpOpcode;
 import org.projectfloodlight.openflow.types.CircuitSignalID;
 import org.projectfloodlight.openflow.types.EthType;
@@ -102,6 +110,7 @@
     private final TrafficSelector selector;
     protected final Long xid;
     protected final Optional<DriverService> driverService;
+    protected final DeviceId deviceId;
 
     /**
      * Creates a new flow mod builder.
@@ -142,6 +151,7 @@
         this.selector = flowRule.selector();
         this.xid = xid.orElse(0L);
         this.driverService = driverService;
+        this.deviceId = flowRule.deviceId();
     }
 
     /**
@@ -446,6 +456,21 @@
                 mBuilder.setExact(MatchField.ARP_TPA,
                                   IPv4Address.of(arpPaCriterion.ip().toInt()));
                 break;
+            case EXTENSION:
+                ExtensionCriterion extensionCriterion = (ExtensionCriterion) c;
+                OFOxm oxm = buildExtensionOxm(extensionCriterion.extensionSelector());
+                if (oxm == null) {
+                    log.warn("Unable to build extension selector");
+                    break;
+                }
+
+                if (oxm.isMasked()) {
+                    mBuilder.setMasked(oxm.getMatchField(), oxm.getValue(), oxm.getMask());
+                } else {
+                    mBuilder.setExact(oxm.getMatchField(), oxm.getValue());
+                }
+
+                break;
             case MPLS_TC:
             case PBB_ISID:
             default:
@@ -473,4 +498,21 @@
         return factory;
     }
 
+    private OFOxm buildExtensionOxm(ExtensionSelector extension) {
+        if (!driverService.isPresent()) {
+            log.error("No driver service present");
+            return null;
+        }
+        Driver driver = driverService.get().getDriver(deviceId);
+        if (driver.hasBehaviour(ExtensionSelectorInterpreter.class)) {
+            DefaultDriverHandler handler =
+                    new DefaultDriverHandler(new DefaultDriverData(driver, deviceId));
+            ExtensionSelectorInterpreter interpreter = handler.behaviour(ExtensionSelectorInterpreter.class);
+
+            return interpreter.mapSelector(factory(), extension);
+        }
+
+        return null;
+    }
+
 }
diff --git a/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowModBuilderVer13.java b/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowModBuilderVer13.java
index 90def43..f9da1c6 100644
--- a/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowModBuilderVer13.java
+++ b/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowModBuilderVer13.java
@@ -18,7 +18,6 @@
 import com.google.common.collect.Lists;
 import org.onlab.packet.Ip4Address;
 import org.onlab.packet.Ip6Address;
-import org.onosproject.net.DeviceId;
 import org.onosproject.net.OchSignal;
 import org.onosproject.net.PortNumber;
 import org.onosproject.net.driver.DefaultDriverData;
@@ -95,7 +94,6 @@
     private static final int OFPCML_NO_BUFFER = 0xffff;
 
     private final TrafficTreatment treatment;
-    private final DeviceId deviceId;
 
     /**
      * Constructor for a flow mod builder for OpenFlow 1.3.
@@ -110,7 +108,6 @@
         super(flowRule, factory, xid, driverService);
 
         this.treatment = flowRule.treatment();
-        this.deviceId = flowRule.deviceId();
     }
 
     @Override