First set of changes to the Cpqd driver to remove hardcoding
and adding ECMP group support

Change-Id: Id34ecd3336ce702e7c151b486c4dd02a28ef1c76
diff --git a/src/main/java/net/floodlightcontroller/core/FloodlightProvider.java b/src/main/java/net/floodlightcontroller/core/FloodlightProvider.java
index 0ee2904..5dbdb3e 100644
--- a/src/main/java/net/floodlightcontroller/core/FloodlightProvider.java
+++ b/src/main/java/net/floodlightcontroller/core/FloodlightProvider.java
@@ -30,6 +30,7 @@
 import net.floodlightcontroller.debugevent.IDebugEventService;
 import net.floodlightcontroller.restserver.IRestApiService;
 import net.floodlightcontroller.threadpool.IThreadPoolService;
+import net.onrc.onos.core.configmanager.INetworkConfigService;
 import net.onrc.onos.core.linkdiscovery.ILinkDiscoveryService;
 import net.onrc.onos.core.registry.IControllerRegistryService;
 
@@ -83,6 +84,8 @@
                context.getServiceImpl(IControllerRegistryService.class));
        controller.setLinkDiscoveryService(
                context.getServiceImpl(ILinkDiscoveryService.class));
+        controller.setNetworkConfigService(
+                context.getServiceImpl(INetworkConfigService.class));
 
        controller.init(context.getConfigParams(this));
     }
diff --git a/src/main/java/net/floodlightcontroller/core/IFloodlightProviderService.java b/src/main/java/net/floodlightcontroller/core/IFloodlightProviderService.java
index 5f73d9a..4447b75 100644
--- a/src/main/java/net/floodlightcontroller/core/IFloodlightProviderService.java
+++ b/src/main/java/net/floodlightcontroller/core/IFloodlightProviderService.java
@@ -23,6 +23,7 @@
 
 import net.floodlightcontroller.core.internal.Controller.Counters;
 import net.floodlightcontroller.core.module.IFloodlightService;
+import net.onrc.onos.core.configmanager.INetworkConfigService;
 import net.onrc.onos.core.packet.Ethernet;
 import net.onrc.onos.core.util.OnosInstanceId;
 
@@ -186,6 +187,28 @@
     public void removeOFSwitchListener(IOFSwitchListener listener);
 
 
+    Set<Long> getAllSwitchDpids();
+
+    IOFSwitch getSwitch(long dpid);
+
+    /**
+     * Record a switch event in in-memory debug-event
+     * 
+     * @param switchDPID
+     * @param reason Reason for this event
+     * @param flushNow see debug-event flushing in IDebugEventService
+     */
+    public void addSwitchEvent(long switchDPID, String reason, boolean flushNow);
+
+    Set<Long> getAllMasterSwitchDpids();
+
+    Set<Long> getAllEqualSwitchDpids();
+
+    IOFSwitch getMasterSwitch(long dpid);
+
+    IOFSwitch getEqualSwitch(long dpid);
+
+    void setAlwaysClearFlowsOnSwActivate(boolean value);
 
     //************************
     //  Utility methods
@@ -235,29 +258,12 @@
      */
     public Counters getCounters();
 
-    void setAlwaysClearFlowsOnSwActivate(boolean value);
+
 
     Map<String, Long> getMemory();
 
     Long getUptime();
 
-    Set<Long> getAllSwitchDpids();
 
-    IOFSwitch getSwitch(long dpid);
-
-    /**
-     * Record a switch event in in-memory debug-event
-     * @param switchDPID
-     * @param reason Reason for this event
-     * @param flushNow see debug-event flushing in IDebugEventService
-     */
-    public void addSwitchEvent(long switchDPID, String reason, boolean flushNow);
-
-    Set<Long> getAllMasterSwitchDpids();
-
-    Set<Long> getAllEqualSwitchDpids();
-
-    IOFSwitch getMasterSwitch(long dpid);
-
-    IOFSwitch getEqualSwitch(long dpid);
+    public INetworkConfigService getNetworkConfigService();
 }
diff --git a/src/main/java/net/floodlightcontroller/core/IOF13Switch.java b/src/main/java/net/floodlightcontroller/core/IOF13Switch.java
index 425c6a9..8ac2912 100644
--- a/src/main/java/net/floodlightcontroller/core/IOF13Switch.java
+++ b/src/main/java/net/floodlightcontroller/core/IOF13Switch.java
@@ -1,5 +1,6 @@
 package net.floodlightcontroller.core;
 
+import java.io.IOException;
 import java.util.Collection;
 import java.util.HashSet;
 import java.util.Set;
@@ -22,17 +23,20 @@
      * by a switch implementing this interface. It is up to the implementation
      * to translate the 'matchActionOp' into a match-instruction with actions,
      * as expected by OF 1.3 switches.
-     *
+     * 
      * @param matchActionOp
+     * @throws IOException
      */
-    public void pushFlow(MatchActionOperationEntry matchActionOp);
+    public void pushFlow(MatchActionOperationEntry matchActionOp) throws IOException;
 
     /**
      * Pushes a collection of flows to the switch.
-     * 
+     *
      * @param matchActionOps
+     * @throws IOException
      */
-    public void pushFlows(Collection<MatchActionOperationEntry> matchActionOps);
+    public void pushFlows(Collection<MatchActionOperationEntry> matchActionOps)
+            throws IOException;
 
     // ****************************
     // Group related
diff --git a/src/main/java/net/floodlightcontroller/core/IOFSwitch.java b/src/main/java/net/floodlightcontroller/core/IOFSwitch.java
index 40aa530..72ec404 100644
--- a/src/main/java/net/floodlightcontroller/core/IOFSwitch.java
+++ b/src/main/java/net/floodlightcontroller/core/IOFSwitch.java
@@ -624,4 +624,9 @@
      */
     public void setTableFull(boolean isFull);
 
+    /**
+     * Get the switch driver hanshake state
+     */
+    public String getSwitchDriverState();
+
 }
diff --git a/src/main/java/net/floodlightcontroller/core/internal/Controller.java b/src/main/java/net/floodlightcontroller/core/internal/Controller.java
index 3550297..72c536f 100644
--- a/src/main/java/net/floodlightcontroller/core/internal/Controller.java
+++ b/src/main/java/net/floodlightcontroller/core/internal/Controller.java
@@ -68,6 +68,7 @@
 import net.floodlightcontroller.restserver.IRestApiService;
 import net.floodlightcontroller.threadpool.IThreadPoolService;
 import net.floodlightcontroller.util.LoadMonitor;
+import net.onrc.onos.core.configmanager.INetworkConfigService;
 import net.onrc.onos.core.drivermanager.DriverManager;
 import net.onrc.onos.core.linkdiscovery.ILinkDiscoveryService;
 import net.onrc.onos.core.packet.Ethernet;
@@ -136,6 +137,7 @@
     protected IDebugEventService debugEvents;
 
     protected ILinkDiscoveryService linkDiscovery;
+    protected INetworkConfigService networkConfig;
 
     // Configuration options
     protected int openFlowPort = 6633;
@@ -483,6 +485,10 @@
         this.linkDiscovery = linkDiscovery;
     }
 
+    public void setNetworkConfigService(INetworkConfigService networkConfigService) {
+        this.networkConfig = networkConfigService;
+    }
+
     public void setDebugCounter(IDebugCounterService debugCounters) {
         this.debugCounters = debugCounters;
     }
@@ -993,6 +999,10 @@
         }
     }
 
+    public INetworkConfigService getNetworkConfigService() {
+        return networkConfig;
+    }
+
     // **************
     // Initialization
     // **************
diff --git a/src/main/java/net/floodlightcontroller/core/internal/OFChannelHandler.java b/src/main/java/net/floodlightcontroller/core/internal/OFChannelHandler.java
index d2e4156..b011e6b 100644
--- a/src/main/java/net/floodlightcontroller/core/internal/OFChannelHandler.java
+++ b/src/main/java/net/floodlightcontroller/core/internal/OFChannelHandler.java
@@ -1069,7 +1069,7 @@
          * controller. Next State: depends on the role of this controller for
          * this switch - either MASTER or EQUAL.
          */
-        WAIT_SWITCH_DRIVER_SUB_HANDSHAKE(true) {
+        WAIT_SWITCH_DRIVER_SUB_HANDSHAKE(false) {
 
             @Override
             void processOFError(OFChannelHandler h, OFErrorMsg m)
@@ -1871,7 +1871,14 @@
 
         void processOFRoleReply(OFChannelHandler h, OFRoleReply m)
                 throws SwitchStateException, IOException {
-            unhandledMessageReceived(h, m);
+            // A role reply message received by the default handler implies
+            // that the channel state-machine is in a state where it does not
+            // expect a role message. That in turn implies that role-request was
+            // sent out by this controller, as a result of a callback
+            // from the registry service, because the chosen master (some other
+            // instance) died, while this controller instance has not completed
+            // handshake yet. Best to disconnect switch and start over.
+            illegalMessageReceived(h, m);
         }
 
         void processOFGetAsyncReply(OFChannelHandler h,
@@ -1925,15 +1932,17 @@
          * controller that wins mastership. Once the registry API changes to
          * reply to every request, we would not need to wait for a timeout to
          * move to Role.EQUAL (or SLAVE).
-         * 
+         *
          * @param h the channel handler for this switch
          * @param ctx the netty channel handler context for the channel 'h'
          * @throws IOException
          */
         public void handleTimedOutHandshake(OFChannelHandler h,
                 ChannelHandlerContext ctx) throws IOException {
-            log.error("Disconnecting switch {}: failed to complete handshake",
-                    h.getSwitchInfoString());
+            log.error("Disconnecting switch {}: failed to complete handshake " +
+                    "in state {} (with driverState: {})",
+                    h.getSwitchInfoString(), h.getStateForTesting(),
+                    h.sw.getSwitchDriverState());
             h.counters.switchDisconnectHandshakeTimeout.updateCounterWithFlush();
             ctx.getChannel().close();
         }
diff --git a/src/main/java/net/floodlightcontroller/core/internal/OFSwitchImplBase.java b/src/main/java/net/floodlightcontroller/core/internal/OFSwitchImplBase.java
index 3e6d7b2..254e658 100644
--- a/src/main/java/net/floodlightcontroller/core/internal/OFSwitchImplBase.java
+++ b/src/main/java/net/floodlightcontroller/core/internal/OFSwitchImplBase.java
@@ -1286,4 +1286,9 @@
     public Lock getListenerWriteLock() {
         return listenerLock.writeLock();
     }
+
+    public String getSwitchDriverState() {
+        return "";
+    }
+
 }