Implemented simple config mechanism to allow different pipelines for the
CPqD software switch.

Default pipeline is 1.0 mode (send-to-controller table miss entry in first
table).
A more complex 1.3 pipeline can be enabled by setting the following in your
onos.properties file:
 net.floodlightcontroller.core.FloodlightProvider.cpqdUsePipeline13=true

Change-Id: I0a15bf04ac9c92e1e6241896d12052dd56449d3c
diff --git a/src/main/java/net/floodlightcontroller/core/internal/Controller.java b/src/main/java/net/floodlightcontroller/core/internal/Controller.java
index 8c7c589..69f706c 100644
--- a/src/main/java/net/floodlightcontroller/core/internal/Controller.java
+++ b/src/main/java/net/floodlightcontroller/core/internal/Controller.java
@@ -174,7 +174,7 @@
      * Switch updates are sent to all IOFSwitchListeners. A switch that is
      * connected to this controller instance, but not activated, is not
      * available for updates.
-     * 
+     *
      * In ONOS, each controller instance can simultaneously serve in a MASTER
      * role for some connected switches, and in a EQUAL role for other connected
      * switches. The EQUAL role can be treated as a SLAVE role, by ensuring that
@@ -183,10 +183,10 @@
      * are announced as updates. We also support announcements of controller
      * role transitions from MASTER --> EQUAL, and EQUAL --> MASTER, for an
      * individual switch.
-     * 
+     *
      * Disconnection of only activated switches are announced. Finally, changes
      * to switch ports are announced with a portChangeType (see @IOFSwitch)
-     * 
+     *
      * @author saurav
      */
     public enum SwitchUpdateType {
@@ -447,7 +447,7 @@
     /**
      * Indicates that ports on the given switch have changed. Enqueue a switch
      * update.
-     * 
+     *
      * @param sw
      */
     protected void notifyPortChanged(long dpid, OFPortDesc port,
@@ -600,16 +600,16 @@
 
     /**
      * Handle and dispatch a message to IOFMessageListeners.
-     * 
+     *
      * We only dispatch messages to listeners if the controller's role is
      * MASTER.
-     * 
+     *
      * @param sw The switch sending the message
      * @param m The message the switch sent
      * @param flContext The floodlight context to use for this message. If null,
      *        a new context will be allocated.
      * @throws IOException
-     * 
+     *
      *         FIXME: this method and the ChannelHandler disagree on which
      *         messages should be dispatched and which shouldn't
      */
@@ -942,7 +942,7 @@
 
     /**
      * Gets an OpenFlow message factory for version 1.0.
-     * 
+     *
      * @return an OpenFlow 1.0 message factory
      */
     public OFFactory getOFMessageFactory_10() {
@@ -951,7 +951,7 @@
 
     /**
      * Gets an OpenFlow message factory for version 1.3.
-     * 
+     *
      * @return an OpenFlow 1.3 message factory
      */
     public OFFactory getOFMessageFactory_13() {
@@ -1028,7 +1028,7 @@
      * specified by the "role.path" file. Then if floodlight restarts for some
      * reason it can get the correct current role of the controller from the
      * file.
-     * 
+     *
      * @param configParams The config params for the FloodlightProvider service
      * @return A valid role if role information is specified in the config
      *         params, otherwise null
@@ -1089,7 +1089,7 @@
 
     /**
      * Tell controller that we're ready to accept switches loop
-     * 
+     *
      * @throws IOException
      */
     @Override
@@ -1217,11 +1217,19 @@
             this.setAlwaysClearFlowsOnSwActivate(false);
             log.info("Flush switches on reconnect -- Disabled");
         }
+
+        option = configParams.get("cpqdUsePipeline13");
+        if (option != null && option.equalsIgnoreCase("true")) {
+            DriverManager.setConfigForCpqd(true);
+            log.info("Using OF1.3 pipeline for the CPqD software switch");
+        } else {
+            log.info("Using OF1.0 pipeline for the CPqD software switch");
+        }
     }
 
     /**
      * Startup all of the controller's components
-     * 
+     *
      * @throws FloodlightModuleException
      */
     @LogMessageDoc(message = "Waiting for storage source",
@@ -1775,7 +1783,7 @@
 
     /**
      * Forward to the driver-manager to get an IOFSwitch instance.
-     * 
+     *
      * @param desc
      * @return
      */
@@ -1791,7 +1799,7 @@
      * Part of the controller updates framework (see 'run()' method) Use this
      * method to add an IUpdate. A thread-pool will serve the update by
      * dispatching it to all listeners for that update.
-     * 
+     *
      * @param update
      */
     @LogMessageDoc(level = "WARN",
@@ -1817,7 +1825,7 @@
 
     /**
      * flcontext_free - Free the context to the current thread
-     * 
+     *
      * @param flcontext
      */
     protected void flcontext_free(FloodlightContext flcontext) {
@@ -1850,7 +1858,7 @@
     /**
      * flcontext_alloc - pop a context off the stack, if required create a new
      * one
-     * 
+     *
      * @return FloodlightContext
      */
     protected static FloodlightContext flcontext_alloc() {
diff --git a/src/main/java/net/onrc/onos/core/drivermanager/DriverManager.java b/src/main/java/net/onrc/onos/core/drivermanager/DriverManager.java
index fe86077..e212655 100644
--- a/src/main/java/net/onrc/onos/core/drivermanager/DriverManager.java
+++ b/src/main/java/net/onrc/onos/core/drivermanager/DriverManager.java
@@ -16,6 +16,10 @@
 
     private static final Logger log = LoggerFactory.getLogger(DriverManager.class);
 
+    // Whether to use an OF 1.3 configured TTP, or to use an OF 1.0-style
+    // single table with packet-ins.
+    private static boolean cpqdUsePipeline13 = false;
+
     /**
      * Return an IOFSwitch object based on switch's manufacturer description
      * from OFDescStatsReply.
@@ -30,7 +34,7 @@
         if (vendor.startsWith("Stanford University, Ericsson Research and CPqD Research")
                 &&
                 hw.startsWith("OpenFlow 1.3 Reference Userspace Switch")) {
-            return new OFSwitchImplCPqD13(desc);
+            return new OFSwitchImplCPqD13(desc, cpqdUsePipeline13);
         }
 
         if (vendor.startsWith("Nicira") &&
@@ -55,4 +59,16 @@
      */
     private DriverManager() {
     }
+
+    /**
+     * Sets the configuration parameter which determines how the CPqD switch
+     * is set up. If usePipeline13 is true, a 1.3 pipeline will be set up on
+     * the switch. Otherwise, the switch will be set up in a 1.0 style with
+     * a single table where missed packets are sent to the controller.
+     *
+     * @param usePipeline13 whether to use a 1.3 pipeline or not
+     */
+    public static void setConfigForCpqd(boolean usePipeline13) {
+        cpqdUsePipeline13 = usePipeline13;
+    }
 }
diff --git a/src/main/java/net/onrc/onos/core/drivermanager/OFSwitchImplCPqD13.java b/src/main/java/net/onrc/onos/core/drivermanager/OFSwitchImplCPqD13.java
index efeaf6e..7bdf041 100644
--- a/src/main/java/net/onrc/onos/core/drivermanager/OFSwitchImplCPqD13.java
+++ b/src/main/java/net/onrc/onos/core/drivermanager/OFSwitchImplCPqD13.java
@@ -93,12 +93,15 @@
 
     ConcurrentHashMap<Integer, OFGroup> l2groups;
 
-    public OFSwitchImplCPqD13(OFDescStatsReply desc) {
+    private final boolean usePipeline13;
+
+    public OFSwitchImplCPqD13(OFDescStatsReply desc, boolean usePipeline13) {
         super();
         driverHandshakeComplete = new AtomicBoolean(false);
         l2groups = new ConcurrentHashMap<Integer, OFGroup>();
         setSwitchDescription(desc);
 
+        this.usePipeline13 = usePipeline13;
     }
 
     /* (non-Javadoc)
@@ -119,7 +122,12 @@
         }
         startDriverHandshakeCalled = true;
         factory = getFactory();
-        // configureSwitch();
+        if (!usePipeline13) {
+            // Send packet-in to controller if a packet misses the first table
+            populateTableMissEntry(0, true, false, false, 0);
+        } //else {
+            // configureSwitch();
+        //}
         sendBarrier(true);
     }