diff --git a/apps/openstackswitching/app/src/main/java/org/onosproject/openstackswitching/OpenstackSwitchingManager.java b/apps/openstackswitching/app/src/main/java/org/onosproject/openstackswitching/OpenstackSwitchingManager.java
new file mode 100644
index 0000000..0e7ebac
--- /dev/null
+++ b/apps/openstackswitching/app/src/main/java/org/onosproject/openstackswitching/OpenstackSwitchingManager.java
@@ -0,0 +1,562 @@
+/*
+ * 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.openstackswitching;
+
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.apache.felix.scr.annotations.Service;
+import org.onlab.packet.Ethernet;
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.Ip4Prefix;
+import org.onlab.packet.MacAddress;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
+import org.onosproject.dhcp.DhcpService;
+import org.onosproject.net.Device;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Port;
+import org.onosproject.net.config.ConfigFactory;
+import org.onosproject.net.config.NetworkConfigEvent;
+import org.onosproject.net.config.NetworkConfigListener;
+import org.onosproject.net.config.NetworkConfigRegistry;
+import org.onosproject.net.device.DeviceEvent;
+import org.onosproject.net.device.DeviceListener;
+import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.flowobjective.FlowObjectiveService;
+import org.onosproject.net.packet.InboundPacket;
+import org.onosproject.net.packet.PacketContext;
+import org.onosproject.net.packet.PacketProcessor;
+import org.onosproject.net.packet.PacketService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import java.util.List;
+import java.util.Map;
+import java.util.Collection;
+import java.util.Set;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.stream.Collectors;
+
+import static org.onosproject.net.config.basics.SubjectFactories.APP_SUBJECT_FACTORY;
+
+@SuppressWarnings("ALL")
+@Service
+@Component(immediate = true)
+/**
+ * Populates forwarding rules for VMs created by Openstack.
+ */
+public class OpenstackSwitchingManager implements OpenstackSwitchingService {
+
+    private static Logger log = LoggerFactory
+            .getLogger(OpenstackSwitchingManager.class);
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected CoreService coreService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected PacketService packetService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected DeviceService deviceService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected FlowObjectiveService flowObjectiveService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected NetworkConfigRegistry cfgService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected DhcpService dhcpService;
+
+    public static final int DHCP_PORT = 67;
+
+    private ApplicationId appId;
+    private boolean doNotPushFlows;
+    private OpenstackArpHandler arpHandler;
+
+    private OpenstackSwitchingRulePopulator rulePopulator;
+    private ExecutorService deviceEventExcutorService = Executors.newFixedThreadPool(10);
+
+    private InternalPacketProcessor internalPacketProcessor = new InternalPacketProcessor();
+    private InternalDeviceListener internalDeviceListener = new InternalDeviceListener();
+    private InternalConfigListener internalConfigListener = new InternalConfigListener();
+    private final Set<ConfigFactory> factories = ImmutableSet.of(
+            new ConfigFactory<ApplicationId, OpenstackSwitchingConfig>(APP_SUBJECT_FACTORY,
+                    OpenstackSwitchingConfig.class,
+                    "openstackswitching") {
+                @Override
+                public OpenstackSwitchingConfig createConfig() {
+                    return new OpenstackSwitchingConfig();
+                }
+            }
+    );
+    // Map <port_id, OpenstackPort>
+    private Map<String, OpenstackPort> openstackPortMap;
+    // Map <network_id, OpenstackNetwork>
+    private Map<String, OpenstackNetwork> openstackNetworkMap;
+    // Map <subnet_id, OpenstackSubner>
+    private Map<String, OpenstackSubnet> openstackSubnetMap;
+    // Map <vni, List <Entry <portName, host ip>>
+    private Map<String, List<PortInfo>> vniPortMap;
+    private Map<Ip4Address, Port> tunnelPortMap;
+
+
+    @Activate
+    protected void activate() {
+        appId = coreService
+                .registerApplication("org.onosproject.openstackswitching");
+        packetService.addProcessor(internalPacketProcessor, PacketProcessor.director(1));
+        deviceService.addListener(internalDeviceListener);
+        cfgService.addListener(internalConfigListener);
+        factories.forEach(cfgService::registerConfigFactory);
+        OpenstackSwitchingConfig cfg =
+                cfgService.getConfig(appId, OpenstackSwitchingConfig.class);
+        if (cfg != null) {
+            doNotPushFlows = cfg.doNotPushFlows();
+        }
+        openstackPortMap = Maps.newHashMap();
+        openstackNetworkMap = Maps.newHashMap();
+        openstackSubnetMap = Maps.newHashMap();
+
+        vniPortMap = Maps.newHashMap();
+        tunnelPortMap = Maps.newHashMap();
+
+        arpHandler = new OpenstackArpHandler(openstackPortMap, packetService);
+
+        log.info("Started");
+    }
+
+    @Deactivate
+    protected void deactivate() {
+        packetService.removeProcessor(internalPacketProcessor);
+        deviceService.removeListener(internalDeviceListener);
+        cfgService.removeListener(internalConfigListener);
+
+        deviceEventExcutorService.shutdown();
+
+        log.info("Stopped");
+    }
+
+    @Override
+    public void createPorts(OpenstackPort openstackPort) {
+        registerDhcpInfo(openstackPort);
+        openstackPortMap.put(openstackPort.id(), openstackPort);
+    }
+
+    @Override
+    public void deletePorts() {
+
+    }
+
+    @Override
+    public void updatePorts() {
+
+    }
+
+    @Override
+    public void createNetwork(OpenstackNetwork openstackNetwork) {
+        openstackNetworkMap.put(openstackNetwork.id(), openstackNetwork);
+    }
+
+    @Override
+    public void createSubnet(OpenstackSubnet openstackSubnet) {
+        openstackSubnetMap.put(openstackSubnet.id(), openstackSubnet);
+        log.debug("Added Subnet Info {}", openstackNetworkMap.get(openstackSubnet.id()));
+    }
+
+    @Override
+    public Collection<OpenstackPort> ports(String networkId) {
+
+        List<OpenstackPort> portList = openstackPortMap.values().stream()
+                .filter(p -> p.networkId().equals(networkId))
+                .collect(Collectors.toList());
+
+        return portList;
+    }
+
+    @Override
+    public OpenstackPort port(String portName) {
+        String uuid = portName.substring(3);
+        return (OpenstackPort) openstackPortMap.values().stream()
+                .filter(p -> p.id().startsWith(uuid))
+                .findFirst().get().clone();
+    }
+
+    @Override
+    public OpenstackNetwork network(String networkId) {
+        OpenstackNetwork on = null;
+        try {
+            on = (OpenstackNetwork) openstackNetworkMap.get(networkId).clone();
+        } catch (CloneNotSupportedException e) {
+            log.error("Cloning is not supported {}", e);
+        }
+        return on;
+    }
+
+    private void processDeviceAdded(Device device) {
+        log.debug("device {} is added", device.id());
+        rulePopulator.populateDefaultRules(device.id());
+    }
+
+    private void processPortAdded(Device device, Port port) {
+        // TODO: Simplify the data structure to store the network info
+        // TODO: Make it stateless
+        // TODO: All the logics need to be processed inside of the rulePopulator class
+        synchronized (vniPortMap) {
+            log.debug("port {} is updated", port.toString());
+
+            updatePortMaps(device, port);
+            if (!port.annotations().value("portName").equals("vxlan")) {
+                populateFlowRulesForTrafficToSameCnode(device, port);
+                populateFlowRulesForTrafficToDifferentCnode(device, port);
+            }
+        }
+    }
+
+    private void processPortRemoved(Device device, Port port) {
+        log.debug("port {} is removed", port.toString());
+        // TODO: need to update the vniPortMap
+    }
+
+    private void registerDhcpInfo(OpenstackPort openstackPort) {
+        Ip4Address ip4Address;
+        Ip4Address subnetMask;
+        Ip4Address dhcpServer;
+        Ip4Address gatewayIPAddress;
+        Ip4Address domainServer;
+        OpenstackSubnet openstackSubnet;
+
+        ip4Address = (Ip4Address) openstackPort.fixedIps().values().toArray()[0];
+
+        openstackSubnet = openstackSubnetMap.values().stream()
+                .filter(n -> n.networkId().equals(openstackPort.networkId()))
+                .findFirst().get();
+
+        subnetMask = Ip4Address.valueOf(buildSubnetMask(openstackSubnet.cidr()));
+        gatewayIPAddress = Ip4Address.valueOf(openstackSubnet.gatewayIp());
+        dhcpServer = gatewayIPAddress;
+        // TODO: supports multiple DNS servers
+        if (openstackSubnet.dnsNameservers().isEmpty()) {
+            domainServer = Ip4Address.valueOf("8.8.8.8");
+        } else {
+            domainServer = openstackSubnet.dnsNameservers().get(0);
+        }
+        List<Ip4Address> options = Lists.newArrayList();
+        options.add(subnetMask);
+        options.add(dhcpServer);
+        options.add(gatewayIPAddress);
+        options.add(domainServer);
+
+        dhcpService.setStaticMapping(openstackPort.macAddress(), ip4Address, true, options);
+    }
+
+    private byte[] buildSubnetMask(String cidr) {
+        int prefix;
+        String[] parts = cidr.split("/");
+        prefix = Integer.parseInt(parts[1]);
+        int mask = 0xffffffff << (32 - prefix);
+        byte[] bytes = new byte[]{(byte) (mask >>> 24),
+                (byte) (mask >> 16 & 0xff), (byte) (mask >> 8 & 0xff), (byte) (mask & 0xff)};
+
+        return bytes;
+    }
+
+    /**
+     * Populates the flow rules for traffic to VMs in different Cnode using
+     * Nicira extention.
+     *
+     * @param device device to put rules
+     * @param port port information of the VM
+     */
+    private void populateFlowRulesForTrafficToDifferentCnode(Device device, Port port) {
+        String portName = port.annotations().value("portName");
+        String channelId = device.annotations().value("channelId");
+        Ip4Address hostIpAddress = Ip4Address.valueOf(channelId.split(":")[0]);
+        Ip4Address fixedIp = getFixedIpAddressForPort(portName);
+        // TODO: Avoid duplicate flow rule set up for VMs in other Cnode
+        //       (possibly avoided by flowrule subsystem?)
+        if (tunnelPortMap.get(hostIpAddress) == null) {
+            log.debug("There is no tunnel port information");
+            return;
+        }
+        String vni = getVniForPort(portName);
+        MacAddress vmMac = getVmMacAddressForPort(portName);
+        if (!vniPortMap.isEmpty() && vniPortMap.get(vni) != null) {
+            for (PortInfo portInfo : vniPortMap.get(vni)) {
+                if (!portInfo.portName.equals(portName) &&
+                        !portInfo.hostIp.equals(hostIpAddress)) {
+                    MacAddress vmMacx = getVmMacAddressForPort(portInfo.portName);
+                    rulePopulator.populateForwardingRuleForOtherCnode(vni,
+                            device.id(), portInfo.hostIp, portInfo.fixedIp, vmMacx,
+                            tunnelPortMap.get(hostIpAddress).number(),
+                            portInfo.deviceId, hostIpAddress, fixedIp, vmMac,
+                            tunnelPortMap.get(portInfo.hostIp).number());
+                }
+            }
+        }
+    }
+
+    /**
+     * Populates the flow rules for traffic to VMs in the same Cnode as the sender.
+     *
+     * @param device device to put the rules
+     * @param port port info of the VM
+     */
+    private void populateFlowRulesForTrafficToSameCnode(Device device, Port port) {
+        Ip4Prefix cidr = getCidrForPort(port.annotations().value("portName"));
+        Ip4Address vmIp = getFixedIpAddressForPort(port.annotations().value("portName"));
+        if (vmIp != null) {
+            rulePopulator.populateForwardingRule(vmIp, device.id(), port, cidr);
+        }
+    }
+
+    /**
+     * Updates the port maps using the port information.
+     *
+     * @param device device info
+     * @param port port of the VM
+     */
+    private void updatePortMaps(Device device, Port port) {
+        String portName = port.annotations().value("portName");
+        String channelId = device.annotations().value("channelId");
+        Ip4Address hostIpAddress = Ip4Address.valueOf(channelId.split(":")[0]);
+        if (portName.startsWith("vxlan")) {
+            tunnelPortMap.put(hostIpAddress, port);
+        } else {
+            String vni = getVniForPort(portName);
+            Ip4Address fixedIp = getFixedIpAddressForPort(portName);
+            if (vniPortMap.get(vni) == null) {
+                vniPortMap.put(vni, Lists.newArrayList());
+            }
+            vniPortMap.get(vni).add(new PortInfo(device.id(), portName, fixedIp, hostIpAddress));
+        }
+    }
+
+    /**
+     * Returns CIDR information from the subnet map for the port.
+     *
+     * @param portName port name of the port of the VM
+     * @return CIDR of the VNI of the VM
+     */
+    private Ip4Prefix getCidrForPort(String portName) {
+        String networkId = null;
+        String uuid = portName.substring(3);
+        OpenstackPort port = openstackPortMap.values().stream()
+                .filter(p -> p.id().startsWith(uuid))
+                .findFirst().get();
+        if (port == null) {
+            log.debug("No port information for port {}", portName);
+            return null;
+        }
+
+        OpenstackSubnet subnet = openstackSubnetMap.values().stream()
+                .filter(s -> s.networkId().equals(port.networkId()))
+                .findFirst().get();
+        if (subnet == null) {
+            log.debug("No subnet information for network {}", port.networkId());
+            return null;
+        }
+
+        return Ip4Prefix.valueOf(subnet.cidr());
+    }
+
+    /**
+     * Returns the VNI of the VM of the port.
+     *
+     * @param portName VM port
+     * @return VNI
+     */
+    private String getVniForPort(String portName) {
+        String networkId = null;
+        String uuid = portName.substring(3);
+        OpenstackPort port = openstackPortMap.values().stream()
+                .filter(p -> p.id().startsWith(uuid))
+                .findFirst().get();
+        if (port == null) {
+            log.debug("No port information for port {}", portName);
+            return null;
+        }
+        OpenstackNetwork network = openstackNetworkMap.values().stream()
+                .filter(n -> n.id().equals(port.networkId()))
+                .findFirst().get();
+        if (network == null) {
+            log.debug("No VNI information for network {}", network.id());
+            return null;
+        }
+
+        return network.segmentId();
+    }
+
+    /**
+     * Returns the Fixed IP address of the VM.
+     *
+     * @param portName VM port info
+     * @return IP address of the VM
+     */
+    private Ip4Address getFixedIpAddressForPort(String portName) {
+
+        // FIXME - For now we use the information stored from neutron Rest API call.
+        // TODO - Later, the information needs to be extracted from Neutron on-demand.
+        String uuid = portName.substring(3);
+        OpenstackPort port = openstackPortMap.values().stream()
+                        .filter(p -> p.id().startsWith(uuid))
+                        .findFirst().get();
+
+        if (port == null) {
+            log.error("There is no port information for port name {}", portName);
+            return null;
+        }
+
+        if (port.fixedIps().isEmpty()) {
+            log.error("There is no fixed IP info in the port information");
+            return null;
+        }
+
+        return (Ip4Address) port.fixedIps().values().toArray()[0];
+    }
+
+    /**
+     * Returns the MAC address of the VM of the port.
+     *
+     * @param portName VM port
+     * @return MAC address of the VM
+     */
+    private MacAddress getVmMacAddressForPort(String portName) {
+
+        String uuid = portName.substring(3);
+        OpenstackPort port = openstackPortMap.values().stream()
+                .filter(p -> p.id().startsWith(uuid))
+                .findFirst().get();
+
+        if (port == null) {
+            log.error("There is no mac information for port name {}", portName);
+            return null;
+        }
+
+        return port.macAddress();
+    }
+
+    private class InternalPacketProcessor implements PacketProcessor {
+
+        @Override
+        public void process(PacketContext context) {
+
+            if (context.isHandled()) {
+                return;
+            }
+
+            InboundPacket pkt = context.inPacket();
+            Ethernet ethernet = pkt.parsed();
+
+            if (ethernet.getEtherType() == Ethernet.TYPE_ARP) {
+                arpHandler.processPacketIn(pkt);
+            }
+        }
+    }
+
+    private class InternalDeviceListener implements DeviceListener {
+
+        @Override
+        public void event(DeviceEvent deviceEvent) {
+            deviceEventExcutorService.execute(new InternalEventHandler(deviceEvent));
+        }
+    }
+
+    private class InternalEventHandler implements Runnable {
+
+        volatile DeviceEvent deviceEvent;
+
+        InternalEventHandler(DeviceEvent deviceEvent) {
+            this.deviceEvent = deviceEvent;
+        }
+
+        @Override
+        public void run() {
+
+            if (doNotPushFlows) {
+                return;
+            }
+
+            switch (deviceEvent.type()) {
+                case DEVICE_ADDED:
+                    processDeviceAdded((Device) deviceEvent.subject());
+                    break;
+                case DEVICE_UPDATED:
+                    Port port = (Port) deviceEvent.subject();
+                    if (port.isEnabled()) {
+                        processPortAdded((Device) deviceEvent.subject(), deviceEvent.port());
+                    }
+                    break;
+                case DEVICE_AVAILABILITY_CHANGED:
+                    Device device = (Device) deviceEvent.subject();
+                    if (deviceService.isAvailable(device.id())) {
+                        processDeviceAdded(device);
+                    }
+                    break;
+                case PORT_ADDED:
+                    processPortAdded((Device) deviceEvent.subject(), deviceEvent.port());
+                    break;
+                case PORT_UPDATED:
+                    processPortAdded((Device) deviceEvent.subject(), deviceEvent.port());
+                    break;
+                case PORT_REMOVED:
+                    processPortRemoved((Device) deviceEvent.subject(), deviceEvent.port());
+                    break;
+                default:
+                    break;
+            }
+        }
+    }
+
+    private class InternalConfigListener implements NetworkConfigListener {
+
+        @Override
+        public void event(NetworkConfigEvent event) {
+            if (((event.type() == NetworkConfigEvent.Type.CONFIG_ADDED ||
+            event.type() == NetworkConfigEvent.Type.CONFIG_UPDATED)) &&
+                    event.configClass().equals(OpenstackSwitchingConfig.class)) {
+                OpenstackSwitchingConfig cfg = cfgService.getConfig(appId,
+                        OpenstackSwitchingConfig.class);
+                if (cfg != null) {
+                    doNotPushFlows = cfg.doNotPushFlows();
+                    log.info("Switching mode reconfigured");
+                }
+            }
+        }
+   }
+
+    private final class PortInfo {
+        DeviceId deviceId;
+        String portName;
+        Ip4Address fixedIp;
+        Ip4Address hostIp;
+
+        private PortInfo(DeviceId deviceId, String portName, Ip4Address fixedIp,
+                         Ip4Address hostIp) {
+            this.deviceId = deviceId;
+            this.portName = portName;
+            this.fixedIp = fixedIp;
+            this.hostIp = hostIp;
+        }
+    }
+
+}
\ No newline at end of file
