diff --git a/src/main/java/net/floodlightcontroller/core/IFloodlightProviderService.java b/src/main/java/net/floodlightcontroller/core/IFloodlightProviderService.java
index d61f753ef634f3750ff6936dc5ddbc43606d4fad..00adb103f0877ae3de6947da9c591433e01f3c0c 100644
--- a/src/main/java/net/floodlightcontroller/core/IFloodlightProviderService.java
+++ b/src/main/java/net/floodlightcontroller/core/IFloodlightProviderService.java
@@ -141,6 +141,8 @@ public interface IFloodlightProviderService extends
      */
     public Map<Long,IOFSwitch> getAllSwitchMap();
 
+    public IOFSwitch getSwitchByDpid(String dpid);
+
     /**
      * Get the current role of the controller
      */
diff --git a/src/main/java/net/floodlightcontroller/core/internal/Controller.java b/src/main/java/net/floodlightcontroller/core/internal/Controller.java
index e574cc711514b115cc2195d237bbba956b9ae9aa..3bdfdc21554276451193e0cce3afe14013e5e03e 100644
--- a/src/main/java/net/floodlightcontroller/core/internal/Controller.java
+++ b/src/main/java/net/floodlightcontroller/core/internal/Controller.java
@@ -1580,6 +1580,25 @@ public class Controller implements IFloodlightProviderService,
         messageListeners.remove(type);
     }
 
+    @Override
+    @Override
+    public IOFSwitch getSwitchByDpid(String dpid) {
+        Map<Long, IOFSwitch> switches = getSwitches();
+        if (switches == null) return null;
+        Long switchid = HexString.toLong(dpid);
+
+        if (switchid != null && switches.containsKey(switchid)) {
+            return switches.get(switchid);
+        }
+
+        // TODO: This is a hack for the demo, which only has one switch
+        for (IOFSwitch sw : switches.values()) {
+            return sw;
+        }
+
+        return null;
+    }
+
     @Override
     public Map<OFType, List<IOFMessageListener>> getListeners() {
         Map<OFType, List<IOFMessageListener>> lers =
diff --git a/src/main/java/net/floodlightcontroller/devicemanager/IDeviceService.java b/src/main/java/net/floodlightcontroller/devicemanager/IDeviceService.java
index 5e8f221a9829bdcf25d0f37a41fd33047db3affe..eb3801344f73d68ab0c35e6db556c09edfa1ba68 100755
--- a/src/main/java/net/floodlightcontroller/devicemanager/IDeviceService.java
+++ b/src/main/java/net/floodlightcontroller/devicemanager/IDeviceService.java
@@ -20,6 +20,7 @@ package net.floodlightcontroller.devicemanager;
 import java.util.Collection;
 import java.util.EnumSet;
 import java.util.Iterator;
+import java.util.Set;
 
 import net.floodlightcontroller.core.FloodlightContextStore;
 import net.floodlightcontroller.core.module.IFloodlightService;
@@ -210,4 +211,6 @@ public interface IDeviceService extends IFloodlightService {
 
     public void removeSuppressAPs(long swId, short port);
 
+    public Set<SwitchPort> getSuppressAPs();
+
 }
diff --git a/src/main/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImpl.java b/src/main/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImpl.java
index 4d2868396c435472a56f0e93658f07ef008eb4bd..044829ac98022bfa9e6cfe9b92d493239a3fa8bc 100755
--- a/src/main/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImpl.java
+++ b/src/main/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImpl.java
@@ -603,6 +603,11 @@ IFlowReconcileListener, IInfoProvider {
         suppressAPs.remove(new SwitchPort(swId, port));
     }
 
+    @Override
+    public Set<SwitchPort> getSuppressAPs() {
+        return Collections.unmodifiableSet(suppressAPs);
+    }
+
     private void logListeners() {
         List<IDeviceListener> listeners = deviceListeners.getOrderedListeners();
         if (listeners != null) {
diff --git a/src/main/java/net/floodlightcontroller/routing/IRoutingService.java b/src/main/java/net/floodlightcontroller/routing/IRoutingService.java
index 63b5d1856b00820f5558315d068655b4f3fb459f..a3d77a83ba6309c02c6f99c19d2523eab2ecfa3b 100644
--- a/src/main/java/net/floodlightcontroller/routing/IRoutingService.java
+++ b/src/main/java/net/floodlightcontroller/routing/IRoutingService.java
@@ -1,7 +1,7 @@
 /**
-*    Copyright 2011, Big Switch Networks, Inc. 
+*    Copyright 2011, Big Switch Networks, Inc.
 *    Originally created by David Erickson, Stanford University
-* 
+*
 *    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
@@ -35,8 +35,8 @@ public interface IRoutingService extends IFloodlightService {
      */
     public Route getRoute(long src, long dst, long cookie);
 
-    /** 
-     * Provides a route between src and dst, with option to allow or 
+    /**
+     * Provides a route between src and dst, with option to allow or
      *  not allow tunnels in the path.
      * @param src Source switch DPID.
      * @param dst Destination switch DPID.
@@ -45,7 +45,7 @@ public interface IRoutingService extends IFloodlightService {
      */
     public Route getRoute(long src, long dst, long cookie, boolean tunnelEnabled);
 
-    /** 
+    /**
      * Provides a route between srcPort on src and dstPort on dst.
      * @param src Source switch DPID.
      * @param srcPort Source port on source switch.
@@ -53,10 +53,10 @@ public interface IRoutingService extends IFloodlightService {
      * @param dstPort dstPort on Destination switch.
      * @param cookie cookie (usage determined by implementation; ignored by topology instance now).
      */
-    public Route getRoute(long srcId, short srcPort, 
+    public Route getRoute(long srcId, short srcPort,
                              long dstId, short dstPort, long cookie);
 
-    /** 
+    /**
      * Provides a route between srcPort on src and dstPort on dst.
      * @param src Source switch DPID.
      * @param srcPort Source port on source switch.
@@ -65,7 +65,7 @@ public interface IRoutingService extends IFloodlightService {
      * @param cookie cookie (usage determined by implementation; ignored by topology instance now).
      * @param tunnelEnabled boolean option.
      */
-    public Route getRoute(long srcId, short srcPort, 
+    public Route getRoute(long srcId, short srcPort,
                              long dstId, short dstPort, long cookie,
                              boolean tunnelEnabled);
 
@@ -82,4 +82,4 @@ public interface IRoutingService extends IFloodlightService {
      */
     public boolean routeExists(long src, long dst, boolean tunnelEnabled);
 
-}
\ No newline at end of file
+}
diff --git a/src/main/java/net/floodlightcontroller/servicechaining/BITWServiceNode.java b/src/main/java/net/floodlightcontroller/servicechaining/BITWServiceNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..38752f0651b771a5662c7e91e26d9e538b16d9e1
--- /dev/null
+++ b/src/main/java/net/floodlightcontroller/servicechaining/BITWServiceNode.java
@@ -0,0 +1,28 @@
+package net.floodlightcontroller.servicechaining;
+
+import net.floodlightcontroller.topology.NodePortTuple;
+
+public class BITWServiceNode extends ServiceNode {
+    protected NodePortTuple ingressPort;
+    protected NodePortTuple egressPort;
+
+    public BITWServiceNode(String tenant, String name) {
+        super(tenant, name, InsertionType.BUMPINTHEWIRE);
+    }
+
+    public NodePortTuple getIngressPort() {
+        return ingressPort;
+    }
+
+    public void setIngressPort(NodePortTuple ingressPort) {
+        this.ingressPort = ingressPort;
+    }
+
+    public NodePortTuple getEgressPort() {
+        return egressPort;
+    }
+
+    public void setEgressPort(NodePortTuple egressPort) {
+        this.egressPort = egressPort;
+    }
+}
diff --git a/src/main/java/net/floodlightcontroller/servicechaining/IServiceChainingService.java b/src/main/java/net/floodlightcontroller/servicechaining/IServiceChainingService.java
new file mode 100644
index 0000000000000000000000000000000000000000..e72a5c84a7c78f861b0b2c1e81ed312b884d23fb
--- /dev/null
+++ b/src/main/java/net/floodlightcontroller/servicechaining/IServiceChainingService.java
@@ -0,0 +1,27 @@
+package net.floodlightcontroller.servicechaining;
+
+import net.floodlightcontroller.core.FloodlightContextStore;
+import net.floodlightcontroller.core.module.IFloodlightService;
+
+public interface IServiceChainingService extends IFloodlightService {
+    /**
+     * A FloodlightContextStore object that can be used to interact with the
+     * FloodlightContext information created by ServiceInsertion.
+     */
+    public static final FloodlightContextStore<String> scStore =
+        new FloodlightContextStore<String>();
+
+    /**
+     * Returns the service chain by source BVS.
+     * @param bvsName
+     * @return the ServiceChain, null is the requested service is not found.
+     */
+    public ServiceChain getServiceChainBySrcBVS(String bvsName);
+
+    /**
+     * Returns the service chain by destination BVS.
+     * @param bvsName
+     * @return the ServiceChain, null is the requested service is not found.
+     */
+    public ServiceChain getServiceChainByDstBVS(String bvsName);
+}
diff --git a/src/main/java/net/floodlightcontroller/servicechaining/ServiceChain.java b/src/main/java/net/floodlightcontroller/servicechaining/ServiceChain.java
new file mode 100644
index 0000000000000000000000000000000000000000..7e2a6d4bc2ca811646318e0aace05b01a66ec647
--- /dev/null
+++ b/src/main/java/net/floodlightcontroller/servicechaining/ServiceChain.java
@@ -0,0 +1,123 @@
+package net.floodlightcontroller.servicechaining;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * ServiceChaining module encapsulates properties of service chains and their member nodes
+ *
+ * @author kjiang
+ *
+ */
+public class ServiceChain {
+    // Tenant
+    private String tenant;
+
+    // Service Chain name
+    private String name;
+
+    // Source network
+    private String srcBvsName;
+
+    // Destination network
+    private String dstBvsName;
+
+    // Service Description
+    private String description;
+
+    // Ordered list of service Nodes
+    private List<ServiceNode> nodes;
+
+    /**
+     * Constructor to create a NetworkService
+     *
+     * @param name
+     * @param vMac
+     * @param vIp
+     */
+    public ServiceChain(String tenant, String name, String description,
+            String srcBvsName, String dstBvsName) {
+        this.tenant = tenant;
+        this.name = name;
+        this.description = description;
+        this.srcBvsName = srcBvsName;
+        this.dstBvsName = dstBvsName;
+        this.nodes = new ArrayList<ServiceNode>();
+    }
+
+    /**
+     * A getter for service tenant
+     * @return
+     */
+    public String getTenant() {
+        return tenant;
+    }
+
+    /**
+     * A getter for service name
+     * @return
+     */
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * A getter for service description
+     * @return
+     */
+    public String getDescription() {
+        return description;
+    }
+
+    /**
+     * A getter for source BVS
+     */
+    public String getSourceBvs() {
+        return srcBvsName;
+    }
+
+    /**
+     * A getter for destination BVS
+     */
+    public String getDestinationBvs() {
+        return dstBvsName;
+    }
+
+    /**
+     * A getter returns an unmodifiable map of service nodes.
+     * @return
+     */
+    public List<ServiceNode> getServiceNodes() {
+        return Collections.unmodifiableList(nodes);
+    }
+
+    /**
+     * Add a service node to the end of the node list
+     */
+    public boolean addNode(ServiceNode node) {
+        try {
+            return nodes.add(node);
+        } catch (Exception e) {
+            return false;
+        }
+    }
+
+    /**
+     * Remove a service node from the node list
+     */
+    public boolean removeNode(ServiceNode node) {
+        try {
+            return nodes.remove(node);
+        } catch (Exception e) {
+            return false;
+        }
+    }
+
+    @Override
+    public String toString() {
+        return "ServiceChain [tenant=" + tenant + ", name=" + name
+                + ", srcBvsName=" + srcBvsName + ", dstBvsName=" + dstBvsName
+                + ", description=" + description + "]";
+    }
+}
diff --git a/src/main/java/net/floodlightcontroller/servicechaining/ServiceNode.java b/src/main/java/net/floodlightcontroller/servicechaining/ServiceNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..dfceead4439b51c59c7bb3a0142797817cdbf7f8
--- /dev/null
+++ b/src/main/java/net/floodlightcontroller/servicechaining/ServiceNode.java
@@ -0,0 +1,67 @@
+package net.floodlightcontroller.servicechaining;
+
+public class ServiceNode {
+    public enum InsertionType {
+        L3, L2, BUMPINTHEWIRE, TAP, UNKNOWN
+    }
+
+    public enum Direction {
+        INGRESS, EGRESS, ANY
+    }
+
+    protected String name;
+    protected String tenant;
+    protected InsertionType type;
+
+    public ServiceNode(String tenant, String name, InsertionType type) {
+        this.tenant = tenant;
+        this.name = name;
+        this.type = type;
+    }
+
+    public String getTenant() {
+        return tenant;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public InsertionType getServiceType() {
+        return this.type;
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ((name == null) ? 0 : name.hashCode());
+        result = prime * result + ((tenant == null) ? 0 : tenant.hashCode());
+        result = prime * result + ((type == null) ? 0 : type.hashCode());
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+        if (obj == null)
+            return false;
+        if (getClass() != obj.getClass())
+            return false;
+        ServiceNode other = (ServiceNode) obj;
+        if (name == null) {
+            if (other.name != null)
+                return false;
+        } else if (!name.equals(other.name))
+            return false;
+        if (tenant == null) {
+            if (other.tenant != null)
+                return false;
+        } else if (!tenant.equals(other.tenant))
+            return false;
+        if (type != other.type)
+            return false;
+        return true;
+    }
+}
diff --git a/src/main/java/net/floodlightcontroller/topology/TopologyInstance.java b/src/main/java/net/floodlightcontroller/topology/TopologyInstance.java
index af49de70bbb6ca8f29426bc370d5b343fdc30442..893ab74e4d1e105fb3aa02b5bdf1fef2ac409716 100644
--- a/src/main/java/net/floodlightcontroller/topology/TopologyInstance.java
+++ b/src/main/java/net/floodlightcontroller/topology/TopologyInstance.java
@@ -36,6 +36,8 @@ import net.floodlightcontroller.routing.BroadcastTree;
 import net.floodlightcontroller.routing.Link;
 import net.floodlightcontroller.routing.Route;
 import net.floodlightcontroller.routing.RouteId;
+import net.floodlightcontroller.servicechaining.ServiceChain;
+
 import com.google.common.cache.*;
 
 /**
@@ -659,7 +661,7 @@ public class TopologyInstance {
         return true;
     }
 
-    protected Route getRoute(long srcId, short srcPort,
+    protected Route getRoute(ServiceChain sc, long srcId, short srcPort,
                              long dstId, short dstPort, long cookie) {
 
 
diff --git a/src/main/java/net/floodlightcontroller/topology/TopologyManager.java b/src/main/java/net/floodlightcontroller/topology/TopologyManager.java
index 9941e23c743592123ba9ea67c8ff93821f73df0a..523c63714894615f093430de8189f461bc5dc0f4 100644
--- a/src/main/java/net/floodlightcontroller/topology/TopologyManager.java
+++ b/src/main/java/net/floodlightcontroller/topology/TopologyManager.java
@@ -608,7 +608,7 @@ public class TopologyManager implements
     public Route getRoute(long src, short srcPort, long dst, short dstPort, long cookie,
                           boolean tunnelEnabled) {
         TopologyInstance ti = getCurrentInstance(tunnelEnabled);
-        return ti.getRoute(src, srcPort, dst, dstPort, cookie);
+        return ti.getRoute(null, src, srcPort, dst, dstPort, cookie);
     }
 
     @Override
diff --git a/src/test/java/net/floodlightcontroller/core/test/MockFloodlightProvider.java b/src/test/java/net/floodlightcontroller/core/test/MockFloodlightProvider.java
index c18340efbf6775748a9b576cc3658ac5d609509c..181bf9a4bc5b7197b642afcd46a8bf7c2040b648 100644
--- a/src/test/java/net/floodlightcontroller/core/test/MockFloodlightProvider.java
+++ b/src/test/java/net/floodlightcontroller/core/test/MockFloodlightProvider.java
@@ -55,6 +55,7 @@ import org.openflow.protocol.OFMessage;
 import org.openflow.protocol.OFPacketIn;
 import org.openflow.protocol.OFType;
 import org.openflow.protocol.factory.BasicFactory;
+import org.openflow.util.HexString;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -142,6 +143,19 @@ public class MockFloodlightProvider implements IFloodlightModule, IFloodlightPro
         return this.switches.get(dpid);
     }
 
+    @Override
+    public IOFSwitch getSwitchByDpid(String dpid) {
+        Map<Long, IOFSwitch> switches = getSwitches();
+        if (switches == null) return null;
+        Long switchid = HexString.toLong(dpid);
+
+        if (switchid != null && switches.containsKey(switchid)) {
+            return switches.get(switchid);
+        }
+
+        return null;
+    }
+
     public void setSwitches(Map<Long, IOFSwitch> switches) {
         this.switches = switches;
     }